mirror of
https://github.com/TES3MP/openmw-tes3mp.git
synced 2025-01-16 18:19:55 +00:00
[General] Implement PlayerSpellsActive packet, part 1
Additions and removals of the local player's active spells can now be saved to and loaded from the server.
This commit is contained in:
parent
3a8831dc15
commit
c56cd7c221
15 changed files with 620 additions and 44 deletions
|
@ -107,7 +107,8 @@ set(PROCESSORS_PLAYER
|
|||
processors/player/ProcessorPlayerRest.hpp processors/player/ProcessorPlayerResurrect.hpp
|
||||
processors/player/ProcessorPlayerShapeshift.hpp processors/player/ProcessorPlayerSkill.hpp
|
||||
processors/player/ProcessorPlayerSpeech.hpp processors/player/ProcessorPlayerSpellbook.hpp
|
||||
processors/player/ProcessorPlayerStatsDynamic.hpp processors/player/ProcessorPlayerTopic.hpp
|
||||
processors/player/ProcessorPlayerSpellsActive.hpp processors/player/ProcessorPlayerStatsDynamic.hpp
|
||||
processors/player/ProcessorPlayerTopic.hpp
|
||||
)
|
||||
|
||||
source_group(tes3mp-server\\processors\\player FILES ${PROCESSORS_PLAYER})
|
||||
|
|
|
@ -8,6 +8,8 @@
|
|||
|
||||
using namespace mwmp;
|
||||
|
||||
std::vector<ESM::ActiveEffect> storedActiveEffects;
|
||||
|
||||
void SpellFunctions::ClearSpellbookChanges(unsigned short pid) noexcept
|
||||
{
|
||||
Player *player;
|
||||
|
@ -16,6 +18,14 @@ void SpellFunctions::ClearSpellbookChanges(unsigned short pid) noexcept
|
|||
player->spellbookChanges.spells.clear();
|
||||
}
|
||||
|
||||
void SpellFunctions::ClearSpellsActiveChanges(unsigned short pid) noexcept
|
||||
{
|
||||
Player* player;
|
||||
GET_PLAYER(pid, player, );
|
||||
|
||||
player->spellsActiveChanges.activeSpells.clear();
|
||||
}
|
||||
|
||||
unsigned int SpellFunctions::GetSpellbookChangesSize(unsigned short pid) noexcept
|
||||
{
|
||||
Player *player;
|
||||
|
@ -32,6 +42,22 @@ unsigned int SpellFunctions::GetSpellbookChangesAction(unsigned short pid) noexc
|
|||
return player->spellbookChanges.action;
|
||||
}
|
||||
|
||||
unsigned int SpellFunctions::GetSpellsActiveChangesSize(unsigned short pid) noexcept
|
||||
{
|
||||
Player* player;
|
||||
GET_PLAYER(pid, player, 0);
|
||||
|
||||
return player->spellsActiveChanges.activeSpells.size();
|
||||
}
|
||||
|
||||
unsigned int SpellFunctions::GetSpellsActiveChangesAction(unsigned short pid) noexcept
|
||||
{
|
||||
Player* player;
|
||||
GET_PLAYER(pid, player, 0);
|
||||
|
||||
return player->spellsActiveChanges.action;
|
||||
}
|
||||
|
||||
void SpellFunctions::SetSpellbookChangesAction(unsigned short pid, unsigned char action) noexcept
|
||||
{
|
||||
Player *player;
|
||||
|
@ -40,6 +66,14 @@ void SpellFunctions::SetSpellbookChangesAction(unsigned short pid, unsigned char
|
|||
player->spellbookChanges.action = action;
|
||||
}
|
||||
|
||||
void SpellFunctions::SetSpellsActiveChangesAction(unsigned short pid, unsigned char action) noexcept
|
||||
{
|
||||
Player* player;
|
||||
GET_PLAYER(pid, player, );
|
||||
|
||||
player->spellsActiveChanges.action = action;
|
||||
}
|
||||
|
||||
void SpellFunctions::AddSpell(unsigned short pid, const char* spellId) noexcept
|
||||
{
|
||||
Player *player;
|
||||
|
@ -51,6 +85,36 @@ void SpellFunctions::AddSpell(unsigned short pid, const char* spellId) noexcept
|
|||
player->spellbookChanges.spells.push_back(spell);
|
||||
}
|
||||
|
||||
void SpellFunctions::AddSpellActive(unsigned short pid, const char* spellId, const char* displayName) noexcept
|
||||
{
|
||||
Player* player;
|
||||
GET_PLAYER(pid, player, );
|
||||
|
||||
mwmp::ActiveSpell spell;
|
||||
spell.id = spellId;
|
||||
spell.params.mDisplayName = displayName;
|
||||
spell.params.mEffects = storedActiveEffects;
|
||||
|
||||
player->spellsActiveChanges.activeSpells.push_back(spell);
|
||||
|
||||
storedActiveEffects.clear();
|
||||
}
|
||||
|
||||
void SpellFunctions::AddSpellActiveEffect(unsigned short pid, int effectId, int arg, double magnitude, double duration, double timeLeft) noexcept
|
||||
{
|
||||
Player* player;
|
||||
GET_PLAYER(pid, player, );
|
||||
|
||||
ESM::ActiveEffect effect;
|
||||
effect.mEffectId = effectId;
|
||||
effect.mArg = arg;
|
||||
effect.mMagnitude = magnitude;
|
||||
effect.mDuration = duration;
|
||||
effect.mTimeLeft = timeLeft;
|
||||
|
||||
storedActiveEffects.push_back(effect);
|
||||
}
|
||||
|
||||
const char *SpellFunctions::GetSpellId(unsigned short pid, unsigned int index) noexcept
|
||||
{
|
||||
Player *player;
|
||||
|
@ -62,6 +126,94 @@ const char *SpellFunctions::GetSpellId(unsigned short pid, unsigned int index) n
|
|||
return player->spellbookChanges.spells.at(index).mId.c_str();
|
||||
}
|
||||
|
||||
const char* SpellFunctions::GetSpellsActiveId(unsigned short pid, unsigned int index) noexcept
|
||||
{
|
||||
Player* player;
|
||||
GET_PLAYER(pid, player, "");
|
||||
|
||||
if (index >= player->spellsActiveChanges.activeSpells.size())
|
||||
return "invalid";
|
||||
|
||||
return player->spellsActiveChanges.activeSpells.at(index).id.c_str();
|
||||
}
|
||||
|
||||
const char* SpellFunctions::GetSpellsActiveDisplayName(unsigned short pid, unsigned int index) noexcept
|
||||
{
|
||||
Player* player;
|
||||
GET_PLAYER(pid, player, "");
|
||||
|
||||
if (index >= player->spellsActiveChanges.activeSpells.size())
|
||||
return "invalid";
|
||||
|
||||
return player->spellsActiveChanges.activeSpells.at(index).params.mDisplayName.c_str();
|
||||
}
|
||||
|
||||
unsigned int SpellFunctions::GetSpellsActiveEffectCount(unsigned short pid, unsigned int index) noexcept
|
||||
{
|
||||
Player* player;
|
||||
GET_PLAYER(pid, player, 0);
|
||||
|
||||
if (index >= player->spellsActiveChanges.activeSpells.size())
|
||||
return 0;
|
||||
|
||||
return player->spellsActiveChanges.activeSpells.at(index).params.mEffects.size();
|
||||
}
|
||||
|
||||
unsigned int SpellFunctions::GetSpellsActiveEffectId(unsigned short pid, unsigned int spellIndex, unsigned int effectIndex) noexcept
|
||||
{
|
||||
Player* player;
|
||||
GET_PLAYER(pid, player, 0);
|
||||
|
||||
if (spellIndex >= player->spellsActiveChanges.activeSpells.size())
|
||||
return 0;
|
||||
|
||||
return player->spellsActiveChanges.activeSpells.at(spellIndex).params.mEffects.at(effectIndex).mEffectId;
|
||||
}
|
||||
|
||||
unsigned int SpellFunctions::GetSpellsActiveEffectArg(unsigned short pid, unsigned int spellIndex, unsigned int effectIndex) noexcept
|
||||
{
|
||||
Player* player;
|
||||
GET_PLAYER(pid, player, 0);
|
||||
|
||||
if (spellIndex >= player->spellsActiveChanges.activeSpells.size())
|
||||
return 0;
|
||||
|
||||
return player->spellsActiveChanges.activeSpells.at(spellIndex).params.mEffects.at(effectIndex).mArg;
|
||||
}
|
||||
|
||||
double SpellFunctions::GetSpellsActiveEffectMagnitude(unsigned short pid, unsigned int spellIndex, unsigned int effectIndex) noexcept
|
||||
{
|
||||
Player* player;
|
||||
GET_PLAYER(pid, player, 0);
|
||||
|
||||
if (spellIndex >= player->spellsActiveChanges.activeSpells.size())
|
||||
return 0;
|
||||
|
||||
return player->spellsActiveChanges.activeSpells.at(spellIndex).params.mEffects.at(effectIndex).mMagnitude;
|
||||
}
|
||||
|
||||
double SpellFunctions::GetSpellsActiveEffectDuration(unsigned short pid, unsigned int spellIndex, unsigned int effectIndex) noexcept
|
||||
{
|
||||
Player* player;
|
||||
GET_PLAYER(pid, player, 0);
|
||||
|
||||
if (spellIndex >= player->spellsActiveChanges.activeSpells.size())
|
||||
return 0;
|
||||
|
||||
return player->spellsActiveChanges.activeSpells.at(spellIndex).params.mEffects.at(effectIndex).mDuration;
|
||||
}
|
||||
|
||||
double SpellFunctions::GetSpellsActiveEffectTimeLeft(unsigned short pid, unsigned int spellIndex, unsigned int effectIndex) noexcept
|
||||
{
|
||||
Player* player;
|
||||
GET_PLAYER(pid, player, 0);
|
||||
|
||||
if (spellIndex >= player->spellsActiveChanges.activeSpells.size())
|
||||
return 0;
|
||||
|
||||
return player->spellsActiveChanges.activeSpells.at(spellIndex).params.mEffects.at(effectIndex).mTimeLeft;
|
||||
}
|
||||
|
||||
void SpellFunctions::SendSpellbookChanges(unsigned short pid, bool sendToOtherPlayers, bool skipAttachedPlayer) noexcept
|
||||
{
|
||||
Player *player;
|
||||
|
@ -76,6 +228,20 @@ void SpellFunctions::SendSpellbookChanges(unsigned short pid, bool sendToOtherPl
|
|||
packet->Send(true);
|
||||
}
|
||||
|
||||
void SpellFunctions::SendSpellsActiveChanges(unsigned short pid, bool sendToOtherPlayers, bool skipAttachedPlayer) noexcept
|
||||
{
|
||||
Player* player;
|
||||
GET_PLAYER(pid, player, );
|
||||
|
||||
mwmp::PlayerPacket* packet = mwmp::Networking::get().getPlayerPacketController()->GetPacket(ID_PLAYER_SPELLS_ACTIVE);
|
||||
packet->setPlayer(player);
|
||||
|
||||
if (!skipAttachedPlayer)
|
||||
packet->Send(false);
|
||||
if (sendToOtherPlayers)
|
||||
packet->Send(true);
|
||||
}
|
||||
|
||||
// All methods below are deprecated versions of methods from above
|
||||
|
||||
void SpellFunctions::InitializeSpellbookChanges(unsigned short pid) noexcept
|
||||
|
|
|
@ -2,19 +2,35 @@
|
|||
#define OPENMW_SPELLAPI_HPP
|
||||
|
||||
#define SPELLAPI \
|
||||
{"ClearSpellbookChanges", SpellFunctions::ClearSpellbookChanges},\
|
||||
{"ClearSpellbookChanges", SpellFunctions::ClearSpellbookChanges},\
|
||||
{"ClearSpellsActiveChanges", SpellFunctions::ClearSpellsActiveChanges},\
|
||||
\
|
||||
{"GetSpellbookChangesSize", SpellFunctions::GetSpellbookChangesSize},\
|
||||
{"GetSpellbookChangesAction", SpellFunctions::GetSpellbookChangesAction},\
|
||||
{"GetSpellbookChangesSize", SpellFunctions::GetSpellbookChangesSize},\
|
||||
{"GetSpellbookChangesAction", SpellFunctions::GetSpellbookChangesAction},\
|
||||
{"GetSpellsActiveChangesSize", SpellFunctions::GetSpellsActiveChangesSize},\
|
||||
{"GetSpellsActiveChangesAction", SpellFunctions::GetSpellsActiveChangesAction},\
|
||||
\
|
||||
{"SetSpellbookChangesAction", SpellFunctions::SetSpellbookChangesAction},\
|
||||
{"AddSpell", SpellFunctions::AddSpell},\
|
||||
{"SetSpellbookChangesAction", SpellFunctions::SetSpellbookChangesAction},\
|
||||
{"SetSpellsActiveChangesAction", SpellFunctions::SetSpellsActiveChangesAction},\
|
||||
\
|
||||
{"GetSpellId", SpellFunctions::GetSpellId},\
|
||||
{"AddSpell", SpellFunctions::AddSpell},\
|
||||
{"AddSpellActive", SpellFunctions::AddSpellActive},\
|
||||
{"AddSpellActiveEffect", SpellFunctions::AddSpellActiveEffect},\
|
||||
\
|
||||
{"SendSpellbookChanges", SpellFunctions::SendSpellbookChanges},\
|
||||
{"GetSpellId", SpellFunctions::GetSpellId},\
|
||||
{"GetSpellsActiveId", SpellFunctions::GetSpellsActiveId},\
|
||||
{"GetSpellsActiveDisplayName", SpellFunctions::GetSpellsActiveDisplayName},\
|
||||
{"GetSpellsActiveEffectCount", SpellFunctions::GetSpellsActiveEffectCount},\
|
||||
{"GetSpellsActiveEffectId", SpellFunctions::GetSpellsActiveEffectId},\
|
||||
{"GetSpellsActiveEffectArg", SpellFunctions::GetSpellsActiveEffectArg},\
|
||||
{"GetSpellsActiveEffectMagnitude", SpellFunctions::GetSpellsActiveEffectMagnitude},\
|
||||
{"GetSpellsActiveEffectDuration", SpellFunctions::GetSpellsActiveEffectDuration},\
|
||||
{"GetSpellsActiveEffectTimeLeft", SpellFunctions::GetSpellsActiveEffectTimeLeft},\
|
||||
\
|
||||
{"InitializeSpellbookChanges", SpellFunctions::InitializeSpellbookChanges}
|
||||
{"SendSpellbookChanges", SpellFunctions::SendSpellbookChanges},\
|
||||
{"SendSpellsActiveChanges", SpellFunctions::SendSpellsActiveChanges},\
|
||||
\
|
||||
{"InitializeSpellbookChanges", SpellFunctions::InitializeSpellbookChanges}
|
||||
|
||||
class SpellFunctions
|
||||
{
|
||||
|
@ -30,6 +46,16 @@ public:
|
|||
*/
|
||||
static void ClearSpellbookChanges(unsigned short pid) noexcept;
|
||||
|
||||
/**
|
||||
* \brief Clear the last recorded spells active changes for a player.
|
||||
*
|
||||
* This is used to initialize the sending of new PlayerSpellsActive packets.
|
||||
*
|
||||
* \param pid The player ID whose spells active changes should be used.
|
||||
* \return void
|
||||
*/
|
||||
static void ClearSpellsActiveChanges(unsigned short pid) noexcept;
|
||||
|
||||
/**
|
||||
* \brief Get the number of indexes in a player's latest spellbook changes.
|
||||
*
|
||||
|
@ -46,6 +72,22 @@ public:
|
|||
*/
|
||||
static unsigned int GetSpellbookChangesAction(unsigned short pid) noexcept;
|
||||
|
||||
/**
|
||||
* \brief Get the action type used in a player's latest spells active changes.
|
||||
*
|
||||
* \param pid The player ID whose spells active changes should be used.
|
||||
* \return The action type (0 for SET, 1 for ADD, 2 for REMOVE).
|
||||
*/
|
||||
static unsigned int GetSpellsActiveChangesAction(unsigned short pid) noexcept;
|
||||
|
||||
/**
|
||||
* \brief Get the number of indexes in a player's latest spells active changes.
|
||||
*
|
||||
* \param pid The player ID whose spells active changes should be used.
|
||||
* \return The number of indexes.
|
||||
*/
|
||||
static unsigned int GetSpellsActiveChangesSize(unsigned short pid) noexcept;
|
||||
|
||||
/**
|
||||
* \brief Set the action type in a player's spellbook changes.
|
||||
*
|
||||
|
@ -55,6 +97,15 @@ public:
|
|||
*/
|
||||
static void SetSpellbookChangesAction(unsigned short pid, unsigned char action) noexcept;
|
||||
|
||||
/**
|
||||
* \brief Set the action type in a player's spells active changes.
|
||||
*
|
||||
* \param pid The player ID whose spells active changes should be used.
|
||||
* \param action The action (0 for SET, 1 for ADD, 2 for REMOVE).
|
||||
* \return void
|
||||
*/
|
||||
static void SetSpellsActiveChangesAction(unsigned short pid, unsigned char action) noexcept;
|
||||
|
||||
/**
|
||||
* \brief Add a new spell to the spellbook changes for a player.
|
||||
*
|
||||
|
@ -65,14 +116,115 @@ public:
|
|||
static void AddSpell(unsigned short pid, const char* spellId) noexcept;
|
||||
|
||||
/**
|
||||
* \brief Get the spellId at a certain index in a player's latest spellbook changes.
|
||||
* \brief Add a new active spell to the spells active changes for a player,
|
||||
* using the temporary effect times stored so far.
|
||||
*
|
||||
* \param pid The player ID whose spells active changes should be used.
|
||||
* \param spellId The spellId of the spell.
|
||||
* \param displayName The displayName of the spell.
|
||||
* \return void
|
||||
*/
|
||||
static void AddSpellActive(unsigned short pid, const char* spellId, const char* displayName) noexcept;
|
||||
|
||||
/**
|
||||
* \brief Add a new effect to the next active spell that will be added to a player.
|
||||
*
|
||||
* \param pid The player ID whose spells active changes should be used.
|
||||
* \param effectId The id of the effect.
|
||||
* \param arg The arg of the effect.
|
||||
* \param magnitude The magnitude of the effect.
|
||||
* \param duration The duration of the effect.
|
||||
* \param timeLeft The timeLeft for the effect.
|
||||
* \return void
|
||||
*/
|
||||
static void AddSpellActiveEffect(unsigned short pid, int effectId, int arg, double magnitude, double duration, double timeLeft) noexcept;
|
||||
|
||||
/**
|
||||
* \brief Get the spell id at a certain index in a player's latest spellbook changes.
|
||||
*
|
||||
* \param pid The player ID whose spellbook changes should be used.
|
||||
* \param index The index of the spell.
|
||||
* \return The spellId.
|
||||
* \return The spell id.
|
||||
*/
|
||||
static const char *GetSpellId(unsigned short pid, unsigned int index) noexcept;
|
||||
|
||||
/**
|
||||
* \brief Get the spell id at a certain index in a player's latest spells active changes.
|
||||
*
|
||||
* \param pid The player ID whose spells active changes should be used.
|
||||
* \param index The index of the spell.
|
||||
* \return The spell id.
|
||||
*/
|
||||
static const char* GetSpellsActiveId(unsigned short pid, unsigned int index) noexcept;
|
||||
|
||||
/**
|
||||
* \brief Get the spell display name at a certain index in a player's latest spells active changes.
|
||||
*
|
||||
* \param pid The player ID whose spells active changes should be used.
|
||||
* \param index The index of the spell.
|
||||
* \return The spell display name.
|
||||
*/
|
||||
static const char* GetSpellsActiveDisplayName(unsigned short pid, unsigned int index) noexcept;
|
||||
|
||||
/**
|
||||
* \brief Get the number of effects at an index in a player's latest spells active changes.
|
||||
*
|
||||
* \param pid The player ID whose spells active changes should be used.
|
||||
* \param index The index of the spell.
|
||||
* \return The number of effects.
|
||||
*/
|
||||
static unsigned int GetSpellsActiveEffectCount(unsigned short pid, unsigned int index) noexcept;
|
||||
|
||||
/**
|
||||
* \brief Get the id for an effect index at a spell index in a player's latest spells active changes.
|
||||
*
|
||||
* \param pid The player ID whose spells active changes should be used.
|
||||
* \param spellIndex The index of the spell.
|
||||
* \param effectIndex The index of the effect.
|
||||
* \return The id of the effect.
|
||||
*/
|
||||
static unsigned int GetSpellsActiveEffectId(unsigned short pid, unsigned int spellIndex, unsigned int effectIndex) noexcept;
|
||||
|
||||
/**
|
||||
* \brief Get the arg for an effect index at a spell index in a player's latest spells active changes.
|
||||
*
|
||||
* \param pid The player ID whose spells active changes should be used.
|
||||
* \param spellIndex The index of the spell.
|
||||
* \param effectIndex The index of the effect.
|
||||
* \return The arg of the effect.
|
||||
*/
|
||||
static unsigned int GetSpellsActiveEffectArg(unsigned short pid, unsigned int spellIndex, unsigned int effectIndex) noexcept;
|
||||
|
||||
/**
|
||||
* \brief Get the magnitude for an effect index at a spell index in a player's latest spells active changes.
|
||||
*
|
||||
* \param pid The player ID whose spells active changes should be used.
|
||||
* \param spellIndex The index of the spell.
|
||||
* \param effectIndex The index of the effect.
|
||||
* \return The magnitude of the effect.
|
||||
*/
|
||||
static double GetSpellsActiveEffectMagnitude(unsigned short pid, unsigned int spellIndex, unsigned int effectIndex) noexcept;
|
||||
|
||||
/**
|
||||
* \brief Get the duration for an effect index at a spell index in a player's latest spells active changes.
|
||||
*
|
||||
* \param pid The player ID whose spells active changes should be used.
|
||||
* \param spellIndex The index of the spell.
|
||||
* \param effectIndex The index of the effect.
|
||||
* \return The duration of the effect.
|
||||
*/
|
||||
static double GetSpellsActiveEffectDuration(unsigned short pid, unsigned int spellIndex, unsigned int effectIndex) noexcept;
|
||||
|
||||
/**
|
||||
* \brief Get the time left for an effect index at a spell index in a player's latest spells active changes.
|
||||
*
|
||||
* \param pid The player ID whose spells active changes should be used.
|
||||
* \param spellIndex The index of the spell.
|
||||
* \param effectIndex The index of the effect.
|
||||
* \return The time left for the effect.
|
||||
*/
|
||||
static double GetSpellsActiveEffectTimeLeft(unsigned short pid, unsigned int spellIndex, unsigned int effectIndex) noexcept;
|
||||
|
||||
/**
|
||||
* \brief Send a PlayerSpellbook packet with a player's recorded spellbook changes.
|
||||
*
|
||||
|
@ -85,6 +237,18 @@ public:
|
|||
*/
|
||||
static void SendSpellbookChanges(unsigned short pid, bool sendToOtherPlayers, bool skipAttachedPlayer) noexcept;
|
||||
|
||||
/**
|
||||
* \brief Send a PlayerSpellsActive packet with a player's recorded spells active changes.
|
||||
*
|
||||
* \param pid The player ID whose spells active changes should be used.
|
||||
* \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 SendSpellsActiveChanges(unsigned short pid, bool sendToOtherPlayers, bool skipAttachedPlayer) noexcept;
|
||||
|
||||
// All methods below are deprecated versions of methods from above
|
||||
|
||||
static void InitializeSpellbookChanges(unsigned short pid) noexcept;
|
||||
|
|
|
@ -173,6 +173,7 @@ public:
|
|||
{"OnPlayerFaction", Callback<unsigned short>()},
|
||||
{"OnPlayerShapeshift", Callback<unsigned short>()},
|
||||
{"OnPlayerSpellbook", Callback<unsigned short>()},
|
||||
{"OnPlayerSpellsActive", Callback<unsigned short>()},
|
||||
{"OnPlayerQuickKeys", Callback<unsigned short>()},
|
||||
{"OnPlayerTopic", Callback<unsigned short>()},
|
||||
{"OnPlayerDisposition", Callback<unsigned short>()},
|
||||
|
|
|
@ -37,6 +37,7 @@
|
|||
#include "player/ProcessorPlayerSkill.hpp"
|
||||
#include "player/ProcessorPlayerSpeech.hpp"
|
||||
#include "player/ProcessorPlayerSpellbook.hpp"
|
||||
#include "player/ProcessorPlayerSpellsActive.hpp"
|
||||
#include "player/ProcessorPlayerStatsDynamic.hpp"
|
||||
#include "player/ProcessorPlayerTopic.hpp"
|
||||
#include "ActorProcessor.hpp"
|
||||
|
@ -120,6 +121,7 @@ void ProcessorInitializer()
|
|||
PlayerProcessor::AddProcessor(new ProcessorPlayerSkill());
|
||||
PlayerProcessor::AddProcessor(new ProcessorPlayerSpeech());
|
||||
PlayerProcessor::AddProcessor(new ProcessorPlayerSpellbook());
|
||||
PlayerProcessor::AddProcessor(new ProcessorPlayerSpellsActive());
|
||||
PlayerProcessor::AddProcessor(new ProcessorPlayerStatsDynamic());
|
||||
PlayerProcessor::AddProcessor(new ProcessorPlayerTopic());
|
||||
|
||||
|
|
|
@ -0,0 +1,26 @@
|
|||
#ifndef OPENMW_PROCESSORPLAYERSPELLSACTIVE_HPP
|
||||
#define OPENMW_PROCESSORPLAYERSPELLSACTIVE_HPP
|
||||
|
||||
#include "../PlayerProcessor.hpp"
|
||||
|
||||
namespace mwmp
|
||||
{
|
||||
class ProcessorPlayerSpellsActive : public PlayerProcessor
|
||||
{
|
||||
public:
|
||||
ProcessorPlayerSpellsActive()
|
||||
{
|
||||
BPP_INIT(ID_PLAYER_SPELLS_ACTIVE)
|
||||
}
|
||||
|
||||
void Do(PlayerPacket &packet, Player &player) override
|
||||
{
|
||||
DEBUG_PRINTF(strPacketID.c_str());
|
||||
|
||||
Script::Call<Script::CallbackIdentity("OnPlayerSpellsActive")>(player.getId());
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
|
||||
#endif //OPENMW_PROCESSORPLAYERSPELLSACTIVE_HPP
|
|
@ -126,7 +126,7 @@ add_openmw_dir (mwmp/processors/player ProcessorChatMessage ProcessorGUIMessageB
|
|||
ProcessorPlayerInput ProcessorPlayerInventory ProcessorPlayerItemUse ProcessorPlayerJail ProcessorPlayerJournal
|
||||
ProcessorPlayerLevel ProcessorPlayerMiscellaneous ProcessorPlayerMomentum ProcessorPlayerPosition ProcessorPlayerQuickKeys
|
||||
ProcessorPlayerReputation ProcessorPlayerResurrect ProcessorPlayerShapeshift ProcessorPlayerSkill ProcessorPlayerSpeech
|
||||
ProcessorPlayerSpellbook ProcessorPlayerStatsDynamic ProcessorPlayerTopic
|
||||
ProcessorPlayerSpellbook ProcessorPlayerSpellsActive ProcessorPlayerStatsDynamic ProcessorPlayerTopic
|
||||
)
|
||||
|
||||
add_openmw_dir (mwmp/processors/object BaseObjectProcessor
|
||||
|
|
|
@ -5,6 +5,20 @@
|
|||
|
||||
#include <components/esm/loadmgef.hpp>
|
||||
|
||||
/*
|
||||
Start of tes3mp addition
|
||||
|
||||
Include additional headers for multiplayer purposes
|
||||
*/
|
||||
#include "../mwmechanics/actorutil.hpp"
|
||||
#include "../mwmechanics/creaturestats.hpp"
|
||||
#include "../mwworld/class.hpp"
|
||||
#include "../mwmp/Main.hpp"
|
||||
#include "../mwmp/LocalPlayer.hpp"
|
||||
/*
|
||||
End of tes3mp addition
|
||||
*/
|
||||
|
||||
#include "../mwbase/environment.hpp"
|
||||
#include "../mwbase/world.hpp"
|
||||
|
||||
|
@ -24,6 +38,16 @@ namespace MWMechanics
|
|||
{
|
||||
if (!timeToExpire (iter))
|
||||
{
|
||||
/*
|
||||
Start of tes3mp addition
|
||||
|
||||
Whenever a player loses an active spell, send an ID_PLAYER_SPELLS_ACTIVE packet to the server with it
|
||||
*/
|
||||
mwmp::Main::get().getLocalPlayer()->sendSpellsActiveRemoval(iter->first);
|
||||
/*
|
||||
End of tes3mp addition
|
||||
*/
|
||||
|
||||
mSpells.erase (iter++);
|
||||
rebuild = true;
|
||||
}
|
||||
|
@ -164,6 +188,24 @@ namespace MWMechanics
|
|||
it->second = params;
|
||||
}
|
||||
|
||||
/*
|
||||
Start of tes3mp addition
|
||||
|
||||
Whenever a player gains an active spell, send an ID_PLAYER_SPELLS_ACTIVE packet to the server with it
|
||||
*/
|
||||
ESM::ActiveSpells::ActiveSpellParams esmParams;
|
||||
esmParams.mEffects = effects;
|
||||
esmParams.mDisplayName = displayName;
|
||||
esmParams.mCasterActorId = casterActorId;
|
||||
|
||||
if (this == &MWMechanics::getPlayer().getClass().getCreatureStats(MWMechanics::getPlayer()).getActiveSpells())
|
||||
{
|
||||
mwmp::Main::get().getLocalPlayer()->sendSpellsActiveAddition(id, esmParams);
|
||||
}
|
||||
/*
|
||||
End of tes3mp addition
|
||||
*/
|
||||
|
||||
mSpellsChanged = true;
|
||||
}
|
||||
|
||||
|
|
|
@ -712,6 +712,23 @@ void LocalPlayer::addSpells()
|
|||
LOG_APPEND(TimedLog::LOG_INFO, "- Ignored addition of invalid spell %s", spell.mId.c_str());
|
||||
}
|
||||
|
||||
void LocalPlayer::addSpellsActive()
|
||||
{
|
||||
MWWorld::Ptr ptrPlayer = getPlayerPtr();
|
||||
MWMechanics::ActiveSpells& activeSpells = ptrPlayer.getClass().getCreatureStats(ptrPlayer).getActiveSpells();
|
||||
|
||||
for (const auto& activeSpell : spellsActiveChanges.activeSpells)
|
||||
{
|
||||
// Only add spells that are ensured to exist
|
||||
if (MWBase::Environment::get().getWorld()->getStore().get<ESM::Spell>().search(activeSpell.id))
|
||||
{
|
||||
activeSpells.addSpell(activeSpell.id, false, activeSpell.params.mEffects, activeSpell.params.mDisplayName, 1);
|
||||
}
|
||||
else
|
||||
LOG_APPEND(TimedLog::LOG_INFO, "- Ignored addition of invalid spell %s", activeSpell.id.c_str());
|
||||
}
|
||||
}
|
||||
|
||||
void LocalPlayer::addJournalItems()
|
||||
{
|
||||
for (const auto &journalItem : journalChanges)
|
||||
|
@ -803,6 +820,17 @@ void LocalPlayer::removeSpells()
|
|||
}
|
||||
}
|
||||
|
||||
void LocalPlayer::removeSpellsActive()
|
||||
{
|
||||
MWWorld::Ptr ptrPlayer = getPlayerPtr();
|
||||
MWMechanics::ActiveSpells& activeSpells = ptrPlayer.getClass().getCreatureStats(ptrPlayer).getActiveSpells();
|
||||
|
||||
for (const auto& activeSpell : spellsActiveChanges.activeSpells)
|
||||
{
|
||||
activeSpells.removeEffects(activeSpell.id);
|
||||
}
|
||||
}
|
||||
|
||||
void LocalPlayer::resurrect()
|
||||
{
|
||||
creatureStats.mDead = false;
|
||||
|
@ -1210,6 +1238,16 @@ void LocalPlayer::setSpellbook()
|
|||
addSpells();
|
||||
}
|
||||
|
||||
void LocalPlayer::setSpellsActive()
|
||||
{
|
||||
MWWorld::Ptr ptrPlayer = getPlayerPtr();
|
||||
MWMechanics::ActiveSpells& activeSpells = ptrPlayer.getClass().getCreatureStats(ptrPlayer).getActiveSpells();
|
||||
activeSpells.clear();
|
||||
|
||||
// Proceed by adding spells active
|
||||
addSpellsActive();
|
||||
}
|
||||
|
||||
void LocalPlayer::setQuickKeys()
|
||||
{
|
||||
MWWorld::Ptr ptrPlayer = getPlayerPtr();
|
||||
|
@ -1522,6 +1560,63 @@ void LocalPlayer::sendSpellChange(std::string id, unsigned int action)
|
|||
getNetworking()->getPlayerPacket(ID_PLAYER_SPELLBOOK)->Send();
|
||||
}
|
||||
|
||||
void LocalPlayer::sendSpellsActive()
|
||||
{
|
||||
MWWorld::Ptr ptrPlayer = getPlayerPtr();
|
||||
MWMechanics::ActiveSpells& activeSpells = ptrPlayer.getClass().getCreatureStats(ptrPlayer).getActiveSpells();
|
||||
|
||||
spellsActiveChanges.activeSpells.clear();
|
||||
|
||||
// Send spells in spellbook, while ignoring abilities, powers, etc.
|
||||
for (const auto& ptrSpell : activeSpells)
|
||||
{
|
||||
mwmp::ActiveSpell packetSpell;
|
||||
packetSpell.id = ptrSpell.first;
|
||||
packetSpell.params.mDisplayName = ptrSpell.second.mDisplayName;
|
||||
packetSpell.params.mEffects = ptrSpell.second.mEffects;
|
||||
spellsActiveChanges.activeSpells.push_back(packetSpell);
|
||||
}
|
||||
|
||||
spellsActiveChanges.action = mwmp::SpellsActiveChanges::SET;
|
||||
getNetworking()->getPlayerPacket(ID_PLAYER_SPELLS_ACTIVE)->setPlayer(this);
|
||||
getNetworking()->getPlayerPacket(ID_PLAYER_SPELLS_ACTIVE)->Send();
|
||||
}
|
||||
|
||||
void LocalPlayer::sendSpellsActiveAddition(const std::string id, ESM::ActiveSpells::ActiveSpellParams params)
|
||||
{
|
||||
// Skip any bugged spells that somehow have clientside-only dynamic IDs
|
||||
if (id.find("$dynamic") != string::npos)
|
||||
return;
|
||||
|
||||
spellsActiveChanges.activeSpells.clear();
|
||||
|
||||
mwmp::ActiveSpell spell;
|
||||
spell.id = id;
|
||||
spell.params = params;
|
||||
spellsActiveChanges.activeSpells.push_back(spell);
|
||||
|
||||
spellsActiveChanges.action = mwmp::SpellsActiveChanges::ADD;
|
||||
getNetworking()->getPlayerPacket(ID_PLAYER_SPELLS_ACTIVE)->setPlayer(this);
|
||||
getNetworking()->getPlayerPacket(ID_PLAYER_SPELLS_ACTIVE)->Send();
|
||||
}
|
||||
|
||||
void LocalPlayer::sendSpellsActiveRemoval(const std::string id)
|
||||
{
|
||||
// Skip any bugged spells that somehow have clientside-only dynamic IDs
|
||||
if (id.find("$dynamic") != string::npos)
|
||||
return;
|
||||
|
||||
spellsActiveChanges.activeSpells.clear();
|
||||
|
||||
mwmp::ActiveSpell spell;
|
||||
spell.id = id;
|
||||
spellsActiveChanges.activeSpells.push_back(spell);
|
||||
|
||||
spellsActiveChanges.action = mwmp::SpellsActiveChanges::REMOVE;
|
||||
getNetworking()->getPlayerPacket(ID_PLAYER_SPELLS_ACTIVE)->setPlayer(this);
|
||||
getNetworking()->getPlayerPacket(ID_PLAYER_SPELLS_ACTIVE)->Send();
|
||||
}
|
||||
|
||||
void LocalPlayer::sendQuickKey(unsigned short slot, int type, const std::string& itemId)
|
||||
{
|
||||
quickKeyChanges.clear();
|
||||
|
|
|
@ -45,11 +45,13 @@ namespace mwmp
|
|||
|
||||
void addItems();
|
||||
void addSpells();
|
||||
void addSpellsActive();
|
||||
void addJournalItems();
|
||||
void addTopics();
|
||||
|
||||
void removeItems();
|
||||
void removeSpells();
|
||||
void removeSpellsActive();
|
||||
|
||||
void resurrect();
|
||||
|
||||
|
@ -70,6 +72,7 @@ namespace mwmp
|
|||
void setEquipment();
|
||||
void setInventory();
|
||||
void setSpellbook();
|
||||
void setSpellsActive();
|
||||
void setQuickKeys();
|
||||
void setFactions();
|
||||
void setBooks();
|
||||
|
@ -86,6 +89,9 @@ namespace mwmp
|
|||
void sendStoredItemRemovals();
|
||||
void sendSpellbook();
|
||||
void sendSpellChange(std::string id, unsigned int action);
|
||||
void sendSpellsActive();
|
||||
void sendSpellsActiveAddition(const std::string id, ESM::ActiveSpells::ActiveSpellParams params);
|
||||
void sendSpellsActiveRemoval(const std::string id);
|
||||
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);
|
||||
|
|
|
@ -43,6 +43,7 @@
|
|||
#include "player/ProcessorPlayerSkill.hpp"
|
||||
#include "player/ProcessorPlayerSpeech.hpp"
|
||||
#include "player/ProcessorPlayerSpellbook.hpp"
|
||||
#include "player/ProcessorPlayerSpellsActive.hpp"
|
||||
#include "player/ProcessorPlayerStatsDynamic.hpp"
|
||||
#include "player/ProcessorPlayerTopic.hpp"
|
||||
|
||||
|
@ -146,6 +147,7 @@ void ProcessorInitializer()
|
|||
PlayerProcessor::AddProcessor(new ProcessorPlayerSkill());
|
||||
PlayerProcessor::AddProcessor(new ProcessorPlayerSpeech());
|
||||
PlayerProcessor::AddProcessor(new ProcessorPlayerSpellbook());
|
||||
PlayerProcessor::AddProcessor(new ProcessorPlayerSpellsActive());
|
||||
PlayerProcessor::AddProcessor(new ProcessorPlayerStatsDynamic());
|
||||
PlayerProcessor::AddProcessor(new ProcessorPlayerTopic());
|
||||
|
||||
|
|
|
@ -0,0 +1,42 @@
|
|||
#ifndef OPENMW_PROCESSORPLAYERSPELLSACTIVE_HPP
|
||||
#define OPENMW_PROCESSORPLAYERSPELLSACTIVE_HPP
|
||||
|
||||
|
||||
#include "../PlayerProcessor.hpp"
|
||||
|
||||
namespace mwmp
|
||||
{
|
||||
class ProcessorPlayerSpellsActive final: public PlayerProcessor
|
||||
{
|
||||
public:
|
||||
ProcessorPlayerSpellsActive()
|
||||
{
|
||||
BPP_INIT(ID_PLAYER_SPELLS_ACTIVE)
|
||||
}
|
||||
|
||||
virtual void Do(PlayerPacket &packet, BasePlayer *player)
|
||||
{
|
||||
if (!isLocal()) return;
|
||||
|
||||
LOG_MESSAGE_SIMPLE(TimedLog::LOG_INFO, "Received ID_PLAYER_SPELLS_ACTIVE about LocalPlayer from server");
|
||||
|
||||
if (isRequest())
|
||||
static_cast<LocalPlayer*>(player)->sendSpellsActive();
|
||||
else
|
||||
{
|
||||
LocalPlayer &localPlayer = static_cast<LocalPlayer&>(*player);
|
||||
|
||||
int spellsActiveAction = localPlayer.spellsActiveChanges.action;
|
||||
|
||||
if (spellsActiveAction == SpellsActiveChanges::ADD)
|
||||
localPlayer.addSpellsActive();
|
||||
else if (spellsActiveAction == SpellsActiveChanges::REMOVE)
|
||||
localPlayer.removeSpellsActive();
|
||||
else // SpellsActiveChanges::SET
|
||||
localPlayer.setSpellsActive();
|
||||
}
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
#endif //OPENMW_PROCESSORPLAYERSPELLSACTIVE_HPP
|
|
@ -75,6 +75,12 @@ namespace mwmp
|
|||
int type;
|
||||
};
|
||||
|
||||
struct ActiveSpell
|
||||
{
|
||||
std::string id;
|
||||
ESM::ActiveSpells::ActiveSpellParams params;
|
||||
};
|
||||
|
||||
struct CellState
|
||||
{
|
||||
ESM::Cell cell;
|
||||
|
@ -126,6 +132,18 @@ namespace mwmp
|
|||
int action; // 0 - Clear and set in entirety, 1 - Add spell, 2 - Remove spell
|
||||
};
|
||||
|
||||
struct SpellsActiveChanges
|
||||
{
|
||||
std::vector<ActiveSpell> activeSpells;
|
||||
enum ACTION_TYPE
|
||||
{
|
||||
SET = 0,
|
||||
ADD,
|
||||
REMOVE
|
||||
};
|
||||
int action; // 0 - Clear and set in entirety, 1 - Add spell, 2 - Remove spell
|
||||
};
|
||||
|
||||
enum RESURRECT_TYPE
|
||||
{
|
||||
REGULAR = 0,
|
||||
|
@ -208,6 +226,7 @@ namespace mwmp
|
|||
|
||||
InventoryChanges inventoryChanges;
|
||||
SpellbookChanges spellbookChanges;
|
||||
SpellsActiveChanges spellsActiveChanges;
|
||||
std::vector<QuickKey> quickKeyChanges;
|
||||
std::vector<JournalItem> journalChanges;
|
||||
FactionChanges factionChanges;
|
||||
|
@ -215,7 +234,6 @@ namespace mwmp
|
|||
std::vector<Book> bookChanges;
|
||||
std::vector<CellState> cellStateChanges;
|
||||
|
||||
ESM::ActiveSpells activeSpells;
|
||||
std::vector<RakNet::RakNetGUID> alliedPlayers;
|
||||
CurrentContainer currentContainer;
|
||||
|
||||
|
|
|
@ -12,43 +12,51 @@ void PacketPlayerSpellsActive::Packet(RakNet::BitStream *newBitstream, bool send
|
|||
{
|
||||
PlayerPacket::Packet(newBitstream, send);
|
||||
|
||||
uint32_t spells = 0;
|
||||
RW(player->spellsActiveChanges.action, send);
|
||||
|
||||
uint32_t count;
|
||||
|
||||
if (send)
|
||||
spells = player->activeSpells.mSpells.size();
|
||||
count = static_cast<uint32_t>(player->spellsActiveChanges.activeSpells.size());
|
||||
|
||||
RW(spells, send);
|
||||
RW(count, send);
|
||||
|
||||
if (send)
|
||||
for (ESM::ActiveSpells::TContainer::const_iterator spell = player->activeSpells.mSpells.begin();
|
||||
spell != player->activeSpells.mSpells.end(); ++spell)
|
||||
if (!send)
|
||||
{
|
||||
player->spellsActiveChanges.activeSpells.clear();
|
||||
player->spellsActiveChanges.activeSpells.resize(count);
|
||||
}
|
||||
|
||||
for (auto&& activeSpell : player->spellsActiveChanges.activeSpells)
|
||||
{
|
||||
RW(activeSpell.id, send, true);
|
||||
RW(activeSpell.params.mDisplayName, send, true);
|
||||
|
||||
uint32_t effectCount;
|
||||
|
||||
if (send)
|
||||
effectCount = static_cast<uint32_t>(activeSpell.params.mEffects.size());
|
||||
|
||||
RW(effectCount, send);
|
||||
|
||||
if (effectCount > maxEffects)
|
||||
{
|
||||
RW(spell->first, true);
|
||||
//RW(spell->second.mTimeStamp, true);
|
||||
uint32_t effects = spell->second.mEffects.size();
|
||||
RW(effects, true);
|
||||
|
||||
for (std::vector<ESM::ActiveEffect>::const_iterator effect = spell->second.mEffects.begin();
|
||||
effect != spell->second.mEffects.end(); ++effect)
|
||||
RW(effect, true);
|
||||
|
||||
return;
|
||||
}
|
||||
else
|
||||
for (uint32_t i = 0; i < spells; i++)
|
||||
|
||||
if (!send)
|
||||
{
|
||||
ESM::ActiveSpells::TContainer::value_type spell;
|
||||
|
||||
RW(spell.first, false);
|
||||
//RW(spell.second.mTimeStamp, false);
|
||||
uint32_t effects;
|
||||
RW(effects, false);
|
||||
|
||||
ESM::ActiveEffect effect;
|
||||
for (uint32_t j = 0; j < effects; j++)
|
||||
{
|
||||
RW(effect, false);
|
||||
spell.second.mEffects.push_back(effect);
|
||||
}
|
||||
player->activeSpells.mSpells.insert(spell);
|
||||
activeSpell.params.mEffects.clear();
|
||||
activeSpell.params.mEffects.resize(effectCount);
|
||||
}
|
||||
|
||||
for (auto&& effect : activeSpell.params.mEffects)
|
||||
{
|
||||
RW(effect.mEffectId, send);
|
||||
RW(effect.mArg, send);
|
||||
RW(effect.mMagnitude, send);
|
||||
RW(effect.mDuration, send);
|
||||
RW(effect.mTimeLeft, send);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -11,6 +11,9 @@ namespace mwmp
|
|||
PacketPlayerSpellsActive(RakNet::RakPeerInterface *peer);
|
||||
|
||||
virtual void Packet(RakNet::BitStream *newBitstream, bool send);
|
||||
|
||||
protected:
|
||||
static const int maxEffects = 20;
|
||||
};
|
||||
}
|
||||
|
||||
|
|
Loading…
Reference in a new issue