1
0
Fork 1
mirror of https://github.com/TES3MP/openmw-tes3mp.git synced 2025-01-30 16:15:31 +00:00

[General] Implement PlayerCooldowns packet

Although this packet may be used for other kinds of cooldowns in the future, it currently only handles cooldowns for magical powers.
This commit is contained in:
David Cernat 2021-07-10 22:15:19 +02:00
parent a4b180f65a
commit 3222afc8b7
20 changed files with 366 additions and 23 deletions

View file

@ -97,18 +97,18 @@ set(PROCESSORS_PLAYER
processors/player/ProcessorPlayerBook.hpp processors/player/ProcessorPlayerBounty.hpp processors/player/ProcessorPlayerBook.hpp processors/player/ProcessorPlayerBounty.hpp
processors/player/ProcessorPlayerCast.hpp processors/player/ProcessorPlayerCellChange.hpp processors/player/ProcessorPlayerCast.hpp processors/player/ProcessorPlayerCellChange.hpp
processors/player/ProcessorPlayerCellState.hpp processors/player/ProcessorPlayerCharClass.hpp processors/player/ProcessorPlayerCellState.hpp processors/player/ProcessorPlayerCharClass.hpp
processors/player/ProcessorPlayerCharGen.hpp processors/player/ProcessorPlayerDeath.hpp processors/player/ProcessorPlayerCharGen.hpp processors/player/ProcessorPlayerCooldowns.hpp
processors/player/ProcessorPlayerDisposition.hpp processors/player/ProcessorPlayerEquipment.hpp processors/player/ProcessorPlayerDeath.hpp processors/player/ProcessorPlayerDisposition.hpp
processors/player/ProcessorPlayerFaction.hpp processors/player/ProcessorPlayerInput.hpp processors/player/ProcessorPlayerEquipment.hpp processors/player/ProcessorPlayerFaction.hpp
processors/player/ProcessorPlayerInventory.hpp processors/player/ProcessorPlayerItemUse.hpp processors/player/ProcessorPlayerInput.hpp processors/player/ProcessorPlayerInventory.hpp
processors/player/ProcessorPlayerJournal.hpp processors/player/ProcessorPlayerPlaceholder.hpp processors/player/ProcessorPlayerItemUse.hpp processors/player/ProcessorPlayerJournal.hpp
processors/player/ProcessorPlayerLevel.hpp processors/player/ProcessorPlayerMiscellaneous.hpp processors/player/ProcessorPlayerPlaceholder.hpp processors/player/ProcessorPlayerLevel.hpp
processors/player/ProcessorPlayerPosition.hpp processors/player/ProcessorPlayerQuickKeys.hpp processors/player/ProcessorPlayerMiscellaneous.hpp processors/player/ProcessorPlayerPosition.hpp
processors/player/ProcessorPlayerRest.hpp processors/player/ProcessorPlayerResurrect.hpp processors/player/ProcessorPlayerQuickKeys.hpp processors/player/ProcessorPlayerRest.hpp
processors/player/ProcessorPlayerShapeshift.hpp processors/player/ProcessorPlayerSkill.hpp processors/player/ProcessorPlayerResurrect.hpp processors/player/ProcessorPlayerShapeshift.hpp
processors/player/ProcessorPlayerSpeech.hpp processors/player/ProcessorPlayerSpellbook.hpp processors/player/ProcessorPlayerSkill.hpp processors/player/ProcessorPlayerSpeech.hpp
processors/player/ProcessorPlayerSpellsActive.hpp processors/player/ProcessorPlayerStatsDynamic.hpp processors/player/ProcessorPlayerSpellbook.hpp processors/player/ProcessorPlayerSpellsActive.hpp
processors/player/ProcessorPlayerTopic.hpp processors/player/ProcessorPlayerStatsDynamic.hpp processors/player/ProcessorPlayerTopic.hpp
) )
source_group(tes3mp-server\\processors\\player FILES ${PROCESSORS_PLAYER}) source_group(tes3mp-server\\processors\\player FILES ${PROCESSORS_PLAYER})

View file

@ -26,6 +26,14 @@ void SpellFunctions::ClearSpellsActiveChanges(unsigned short pid) noexcept
player->spellsActiveChanges.activeSpells.clear(); player->spellsActiveChanges.activeSpells.clear();
} }
void SpellFunctions::ClearCooldownChanges(unsigned short pid) noexcept
{
Player* player;
GET_PLAYER(pid, player, );
player->cooldownChanges.clear();
}
unsigned int SpellFunctions::GetSpellbookChangesSize(unsigned short pid) noexcept unsigned int SpellFunctions::GetSpellbookChangesSize(unsigned short pid) noexcept
{ {
Player *player; Player *player;
@ -58,6 +66,14 @@ unsigned int SpellFunctions::GetSpellsActiveChangesAction(unsigned short pid) no
return player->spellsActiveChanges.action; return player->spellsActiveChanges.action;
} }
unsigned int SpellFunctions::GetCooldownChangesSize(unsigned short pid) noexcept
{
Player* player;
GET_PLAYER(pid, player, 0);
return player->cooldownChanges.size();
}
void SpellFunctions::SetSpellbookChangesAction(unsigned short pid, unsigned char action) noexcept void SpellFunctions::SetSpellbookChangesAction(unsigned short pid, unsigned char action) noexcept
{ {
Player *player; Player *player;
@ -115,6 +131,19 @@ void SpellFunctions::AddSpellActiveEffect(unsigned short pid, int effectId, doub
storedActiveEffects.push_back(effect); storedActiveEffects.push_back(effect);
} }
void SpellFunctions::AddCooldownSpell(unsigned short pid, const char* spellId, unsigned int startDay, double startHour) noexcept
{
Player* player;
GET_PLAYER(pid, player, );
mwmp::SpellCooldown spellCooldown;
spellCooldown.id = spellId;
spellCooldown.startTimestampDay = startDay;
spellCooldown.startTimestampHour = startHour;
player->cooldownChanges.push_back(spellCooldown);
}
const char *SpellFunctions::GetSpellId(unsigned short pid, unsigned int index) noexcept const char *SpellFunctions::GetSpellId(unsigned short pid, unsigned int index) noexcept
{ {
Player *player; Player *player;
@ -225,6 +254,39 @@ double SpellFunctions::GetSpellsActiveEffectTimeLeft(unsigned short pid, unsigne
return player->spellsActiveChanges.activeSpells.at(spellIndex).params.mEffects.at(effectIndex).mTimeLeft; return player->spellsActiveChanges.activeSpells.at(spellIndex).params.mEffects.at(effectIndex).mTimeLeft;
} }
const char* SpellFunctions::GetCooldownSpellId(unsigned short pid, unsigned int index) noexcept
{
Player* player;
GET_PLAYER(pid, player, "");
if (index >= player->cooldownChanges.size())
return "invalid";
return player->cooldownChanges.at(index).id.c_str();
}
unsigned int SpellFunctions::GetCooldownStartDay(unsigned short pid, unsigned int index) noexcept
{
Player* player;
GET_PLAYER(pid, player, 0);
if (index >= player->cooldownChanges.size())
return 0;
return player->cooldownChanges.at(index).startTimestampDay;
}
double SpellFunctions::GetCooldownStartHour(unsigned short pid, unsigned int index) noexcept
{
Player* player;
GET_PLAYER(pid, player, 0.0);
if (index >= player->cooldownChanges.size())
return 0.0;
return player->cooldownChanges.at(index).startTimestampHour;
}
void SpellFunctions::SendSpellbookChanges(unsigned short pid, bool sendToOtherPlayers, bool skipAttachedPlayer) noexcept void SpellFunctions::SendSpellbookChanges(unsigned short pid, bool sendToOtherPlayers, bool skipAttachedPlayer) noexcept
{ {
Player *player; Player *player;
@ -253,6 +315,16 @@ void SpellFunctions::SendSpellsActiveChanges(unsigned short pid, bool sendToOthe
packet->Send(true); packet->Send(true);
} }
void SpellFunctions::SendCooldownChanges(unsigned short pid) noexcept
{
Player* player;
GET_PLAYER(pid, player, );
mwmp::PlayerPacket* packet = mwmp::Networking::get().getPlayerPacketController()->GetPacket(ID_PLAYER_COOLDOWNS);
packet->setPlayer(player);
packet->Send(false);
}
// All methods below are deprecated versions of methods from above // All methods below are deprecated versions of methods from above
void SpellFunctions::InitializeSpellbookChanges(unsigned short pid) noexcept void SpellFunctions::InitializeSpellbookChanges(unsigned short pid) noexcept

View file

@ -4,11 +4,13 @@
#define SPELLAPI \ #define SPELLAPI \
{"ClearSpellbookChanges", SpellFunctions::ClearSpellbookChanges},\ {"ClearSpellbookChanges", SpellFunctions::ClearSpellbookChanges},\
{"ClearSpellsActiveChanges", SpellFunctions::ClearSpellsActiveChanges},\ {"ClearSpellsActiveChanges", SpellFunctions::ClearSpellsActiveChanges},\
{"ClearCooldownChanges", SpellFunctions::ClearCooldownChanges},\
\ \
{"GetSpellbookChangesSize", SpellFunctions::GetSpellbookChangesSize},\ {"GetSpellbookChangesSize", SpellFunctions::GetSpellbookChangesSize},\
{"GetSpellbookChangesAction", SpellFunctions::GetSpellbookChangesAction},\ {"GetSpellbookChangesAction", SpellFunctions::GetSpellbookChangesAction},\
{"GetSpellsActiveChangesSize", SpellFunctions::GetSpellsActiveChangesSize},\ {"GetSpellsActiveChangesSize", SpellFunctions::GetSpellsActiveChangesSize},\
{"GetSpellsActiveChangesAction", SpellFunctions::GetSpellsActiveChangesAction},\ {"GetSpellsActiveChangesAction", SpellFunctions::GetSpellsActiveChangesAction},\
{"GetCooldownChangesSize", SpellFunctions::GetCooldownChangesSize},\
\ \
{"SetSpellbookChangesAction", SpellFunctions::SetSpellbookChangesAction},\ {"SetSpellbookChangesAction", SpellFunctions::SetSpellbookChangesAction},\
{"SetSpellsActiveChangesAction", SpellFunctions::SetSpellsActiveChangesAction},\ {"SetSpellsActiveChangesAction", SpellFunctions::SetSpellsActiveChangesAction},\
@ -16,6 +18,7 @@
{"AddSpell", SpellFunctions::AddSpell},\ {"AddSpell", SpellFunctions::AddSpell},\
{"AddSpellActive", SpellFunctions::AddSpellActive},\ {"AddSpellActive", SpellFunctions::AddSpellActive},\
{"AddSpellActiveEffect", SpellFunctions::AddSpellActiveEffect},\ {"AddSpellActiveEffect", SpellFunctions::AddSpellActiveEffect},\
{"AddCooldownSpell", SpellFunctions::AddCooldownSpell},\
\ \
{"GetSpellId", SpellFunctions::GetSpellId},\ {"GetSpellId", SpellFunctions::GetSpellId},\
{"GetSpellsActiveId", SpellFunctions::GetSpellsActiveId},\ {"GetSpellsActiveId", SpellFunctions::GetSpellsActiveId},\
@ -28,8 +31,13 @@
{"GetSpellsActiveEffectDuration", SpellFunctions::GetSpellsActiveEffectDuration},\ {"GetSpellsActiveEffectDuration", SpellFunctions::GetSpellsActiveEffectDuration},\
{"GetSpellsActiveEffectTimeLeft", SpellFunctions::GetSpellsActiveEffectTimeLeft},\ {"GetSpellsActiveEffectTimeLeft", SpellFunctions::GetSpellsActiveEffectTimeLeft},\
\ \
{"GetCooldownSpellId", SpellFunctions::GetCooldownSpellId},\
{"GetCooldownStartDay", SpellFunctions::GetCooldownStartDay},\
{"GetCooldownStartHour", SpellFunctions::GetCooldownStartHour},\
\
{"SendSpellbookChanges", SpellFunctions::SendSpellbookChanges},\ {"SendSpellbookChanges", SpellFunctions::SendSpellbookChanges},\
{"SendSpellsActiveChanges", SpellFunctions::SendSpellsActiveChanges},\ {"SendSpellsActiveChanges", SpellFunctions::SendSpellsActiveChanges},\
{"SendCooldownChanges", SpellFunctions::SendCooldownChanges},\
\ \
{"InitializeSpellbookChanges", SpellFunctions::InitializeSpellbookChanges} {"InitializeSpellbookChanges", SpellFunctions::InitializeSpellbookChanges}
@ -57,6 +65,16 @@ public:
*/ */
static void ClearSpellsActiveChanges(unsigned short pid) noexcept; static void ClearSpellsActiveChanges(unsigned short pid) noexcept;
/**
* \brief Clear the last recorded cooldown changes for a player.
*
* This is used to initialize the sending of new PlayerCooldown packets.
*
* \param pid The player ID whose cooldown changes should be used.
* \return void
*/
static void ClearCooldownChanges(unsigned short pid) noexcept;
/** /**
* \brief Get the number of indexes in a player's latest spellbook changes. * \brief Get the number of indexes in a player's latest spellbook changes.
* *
@ -89,6 +107,14 @@ public:
*/ */
static unsigned int GetSpellsActiveChangesAction(unsigned short pid) noexcept; static unsigned int GetSpellsActiveChangesAction(unsigned short pid) noexcept;
/**
* \brief Get the number of indexes in a player's latest cooldown changes.
*
* \param pid The player ID whose cooldown changes should be used.
* \return The number of indexes.
*/
static unsigned int GetCooldownChangesSize(unsigned short pid) noexcept;
/** /**
* \brief Set the action type in a player's spellbook changes. * \brief Set the action type in a player's spellbook changes.
* *
@ -141,6 +167,17 @@ public:
*/ */
static void AddSpellActiveEffect(unsigned short pid, int effectId, double magnitude, double duration, double timeLeft, int arg) noexcept; static void AddSpellActiveEffect(unsigned short pid, int effectId, double magnitude, double duration, double timeLeft, int arg) noexcept;
/**
* \brief Add a new cooldown spell to the cooldown changes for a player.
*
* \param pid The player ID whose cooldown changes should be used.
* \param spellId The spellId of the spell.
* \param startDay The day on which the cooldown starts.
* \param startHour The hour at which the cooldown starts.
* \return void
*/
static void AddCooldownSpell(unsigned short pid, const char* spellId, unsigned int startDay, double startHour) noexcept;
/** /**
* \brief Get the spell id at a certain index in a player's latest spellbook changes. * \brief Get the spell id at a certain index in a player's latest spellbook changes.
* *
@ -236,6 +273,33 @@ public:
*/ */
static double GetSpellsActiveEffectTimeLeft(unsigned short pid, unsigned int spellIndex, unsigned int effectIndex) noexcept; static double GetSpellsActiveEffectTimeLeft(unsigned short pid, unsigned int spellIndex, unsigned int effectIndex) noexcept;
/**
* \brief Get the spell id at a certain index in a player's latest cooldown changes.
*
* \param pid The player ID whose cooldown changes should be used.
* \param index The index of the cooldown spell.
* \return The spell id.
*/
static const char* GetCooldownSpellId(unsigned short pid, unsigned int index) noexcept;
/**
* \brief Get the starting day of the cooldown at a certain index in a player's latest cooldown changes.
*
* \param pid The player ID whose cooldown changes should be used.
* \param index The index of the cooldown spell.
* \return The starting day of the cooldown.
*/
static unsigned int GetCooldownStartDay(unsigned short pid, unsigned int index) noexcept;
/**
* \brief Get the starting hour of the cooldown at a certain index in a player's latest cooldown changes.
*
* \param pid The player ID whose cooldown changes should be used.
* \param index The index of the cooldown spell.
* \return The starting hour of the cooldown.
*/
static double GetCooldownStartHour(unsigned short pid, unsigned int index) noexcept;
/** /**
* \brief Send a PlayerSpellbook packet with a player's recorded spellbook changes. * \brief Send a PlayerSpellbook packet with a player's recorded spellbook changes.
* *
@ -260,6 +324,14 @@ public:
*/ */
static void SendSpellsActiveChanges(unsigned short pid, bool sendToOtherPlayers, bool skipAttachedPlayer) noexcept; static void SendSpellsActiveChanges(unsigned short pid, bool sendToOtherPlayers, bool skipAttachedPlayer) noexcept;
/**
* \brief Send a PlayerCooldowns packet with a player's recorded cooldown changes.
*
* \param pid The player ID whose cooldown changes should be used.
* \return void
*/
static void SendCooldownChanges(unsigned short pid) noexcept;
// All methods below are deprecated versions of methods from above // All methods below are deprecated versions of methods from above
static void InitializeSpellbookChanges(unsigned short pid) noexcept; static void InitializeSpellbookChanges(unsigned short pid) noexcept;

View file

@ -174,6 +174,7 @@ public:
{"OnPlayerShapeshift", Callback<unsigned short>()}, {"OnPlayerShapeshift", Callback<unsigned short>()},
{"OnPlayerSpellbook", Callback<unsigned short>()}, {"OnPlayerSpellbook", Callback<unsigned short>()},
{"OnPlayerSpellsActive", Callback<unsigned short>()}, {"OnPlayerSpellsActive", Callback<unsigned short>()},
{"OnPlayerCooldowns", Callback<unsigned short>()},
{"OnPlayerQuickKeys", Callback<unsigned short>()}, {"OnPlayerQuickKeys", Callback<unsigned short>()},
{"OnPlayerTopic", Callback<unsigned short>()}, {"OnPlayerTopic", Callback<unsigned short>()},
{"OnPlayerDisposition", Callback<unsigned short>()}, {"OnPlayerDisposition", Callback<unsigned short>()},

View file

@ -17,6 +17,7 @@
#include "player/ProcessorPlayerCellChange.hpp" #include "player/ProcessorPlayerCellChange.hpp"
#include "player/ProcessorPlayerCellState.hpp" #include "player/ProcessorPlayerCellState.hpp"
#include "player/ProcessorPlayerCharClass.hpp" #include "player/ProcessorPlayerCharClass.hpp"
#include "player/ProcessorPlayerCooldowns.hpp"
#include "player/ProcessorPlayerDeath.hpp" #include "player/ProcessorPlayerDeath.hpp"
#include "player/ProcessorPlayerDisposition.hpp" #include "player/ProcessorPlayerDisposition.hpp"
#include "player/ProcessorPlayerEquipment.hpp" #include "player/ProcessorPlayerEquipment.hpp"
@ -103,6 +104,7 @@ void ProcessorInitializer()
PlayerProcessor::AddProcessor(new ProcessorPlayerCellChange()); PlayerProcessor::AddProcessor(new ProcessorPlayerCellChange());
PlayerProcessor::AddProcessor(new ProcessorPlayerCellState()); PlayerProcessor::AddProcessor(new ProcessorPlayerCellState());
PlayerProcessor::AddProcessor(new ProcessorPlayerCharClass()); PlayerProcessor::AddProcessor(new ProcessorPlayerCharClass());
PlayerProcessor::AddProcessor(new ProcessorPlayerCooldowns());
PlayerProcessor::AddProcessor(new ProcessorPlayerDeath()); PlayerProcessor::AddProcessor(new ProcessorPlayerDeath());
PlayerProcessor::AddProcessor(new ProcessorPlayerDisposition()); PlayerProcessor::AddProcessor(new ProcessorPlayerDisposition());
PlayerProcessor::AddProcessor(new ProcessorPlayerEquipment()); PlayerProcessor::AddProcessor(new ProcessorPlayerEquipment());

View file

@ -0,0 +1,26 @@
#ifndef OPENMW_PROCESSORPLAYERCOOLDOWNS_HPP
#define OPENMW_PROCESSORPLAYERCOOLDOWNS_HPP
#include "../PlayerProcessor.hpp"
namespace mwmp
{
class ProcessorPlayerCooldowns : public PlayerProcessor
{
public:
ProcessorPlayerCooldowns()
{
BPP_INIT(ID_PLAYER_COOLDOWNS)
}
void Do(PlayerPacket &packet, Player &player) override
{
DEBUG_PRINTF(strPacketID.c_str());
Script::Call<Script::CallbackIdentity("OnPlayerCooldowns")>(player.getId());
}
};
}
#endif //OPENMW_PROCESSORPLAYERCOOLDOWNS_HPP

View file

@ -123,11 +123,12 @@ add_openmw_dir (mwmp/processors/player ProcessorChatMessage ProcessorGUIMessageB
ProcessorUserMyID ProcessorGameSettings ProcessorPlayerAlly ProcessorPlayerAnimFlags ProcessorPlayerAnimPlay ProcessorUserMyID ProcessorGameSettings ProcessorPlayerAlly ProcessorPlayerAnimFlags ProcessorPlayerAnimPlay
ProcessorPlayerAttack ProcessorPlayerAttribute ProcessorPlayerBaseInfo ProcessorPlayerBehavior ProcessorPlayerBook ProcessorPlayerAttack ProcessorPlayerAttribute ProcessorPlayerBaseInfo ProcessorPlayerBehavior ProcessorPlayerBook
ProcessorPlayerBounty ProcessorPlayerCast ProcessorPlayerCellChange ProcessorPlayerCellState ProcessorPlayerCharClass ProcessorPlayerBounty ProcessorPlayerCast ProcessorPlayerCellChange ProcessorPlayerCellState ProcessorPlayerCharClass
ProcessorPlayerCharGen ProcessorPlayerDeath ProcessorPlayerDisposition ProcessorPlayerEquipment ProcessorPlayerFaction ProcessorPlayerCharGen ProcessorPlayerCooldowns ProcessorPlayerDeath ProcessorPlayerDisposition ProcessorPlayerEquipment
ProcessorPlayerInput ProcessorPlayerInventory ProcessorPlayerItemUse ProcessorPlayerJail ProcessorPlayerJournal ProcessorPlayerFaction ProcessorPlayerInput ProcessorPlayerInventory ProcessorPlayerItemUse ProcessorPlayerJail
ProcessorPlayerLevel ProcessorPlayerMiscellaneous ProcessorPlayerMomentum ProcessorPlayerPosition ProcessorPlayerQuickKeys ProcessorPlayerJournal ProcessorPlayerLevel ProcessorPlayerMiscellaneous ProcessorPlayerMomentum ProcessorPlayerPosition
ProcessorPlayerReputation ProcessorPlayerResurrect ProcessorPlayerShapeshift ProcessorPlayerSkill ProcessorPlayerSpeech ProcessorPlayerQuickKeys ProcessorPlayerReputation ProcessorPlayerResurrect ProcessorPlayerShapeshift
ProcessorPlayerSpellbook ProcessorPlayerSpellsActive ProcessorPlayerStatsDynamic ProcessorPlayerTopic ProcessorPlayerSkill ProcessorPlayerSpeech ProcessorPlayerSpellbook ProcessorPlayerSpellsActive
ProcessorPlayerStatsDynamic ProcessorPlayerTopic
) )
add_openmw_dir (mwmp/processors/object BaseObjectProcessor add_openmw_dir (mwmp/processors/object BaseObjectProcessor

View file

@ -380,8 +380,36 @@ namespace MWMechanics
void Spells::usePower(const ESM::Spell* spell) void Spells::usePower(const ESM::Spell* spell)
{ {
mUsedPowers[spell] = MWBase::Environment::get().getWorld()->getTimeStamp(); mUsedPowers[spell] = MWBase::Environment::get().getWorld()->getTimeStamp();
/*
Start of tes3mp addition
Send an ID_PLAYER_COOLDOWN packet every time a cooldown is recorded here
*/
mwmp::Main::get().getLocalPlayer()->sendCooldownChange(spell->mId, MWBase::Environment::get().getWorld()->getTimeStamp().getDay(),
MWBase::Environment::get().getWorld()->getTimeStamp().getHour());
/*
End of tes3mp addition
*/
} }
/*
Start of tes3mp addition
Make it possible to set timestamps for power cooldowns, necessary for ID_PLAYER_COOLDOWNS packets
*/
void Spells::setPowerUseTimestamp(const ESM::Spell* spell, int startDay, float startHour)
{
ESM::TimeStamp timestamp;
timestamp.mDay = startDay;
timestamp.mHour = startHour;
mUsedPowers[spell] = MWWorld::TimeStamp(timestamp);
}
/*
End of tes3mp addition
*/
void Spells::readState(const ESM::SpellState &state, CreatureStats* creatureStats) void Spells::readState(const ESM::SpellState &state, CreatureStats* creatureStats)
{ {
const auto& baseSpells = mSpellList->getSpells(); const auto& baseSpells = mSpellList->getSpells();

View file

@ -70,6 +70,16 @@ namespace MWMechanics
bool canUsePower (const ESM::Spell* spell) const; bool canUsePower (const ESM::Spell* spell) const;
void usePower (const ESM::Spell* spell); void usePower (const ESM::Spell* spell);
/*
Start of tes3mp addition
Make it possible to set timestamps for power cooldowns, necessary for ID_PLAYER_COOLDOWNS packets
*/
void setPowerUseTimestamp(const ESM::Spell* spell, int startDay, float startHour);
/*
End of tes3mp addition
*/
void purgeCommonDisease(); void purgeCommonDisease();
void purgeBlightDisease(); void purgeBlightDisease();
void purgeCorprusDisease(); void purgeCorprusDisease();

View file

@ -1266,6 +1266,23 @@ void LocalPlayer::setSpellsActive()
addSpellsActive(); addSpellsActive();
} }
void LocalPlayer::setCooldowns()
{
MWBase::World* world = MWBase::Environment::get().getWorld();
MWWorld::Ptr ptrPlayer = getPlayerPtr();
MWMechanics::Spells& ptrSpells = ptrPlayer.getClass().getCreatureStats(ptrPlayer).getSpells();
for (const auto& cooldown : cooldownChanges)
{
if (world->getStore().get<ESM::Spell>().search(cooldown.id))
{
const ESM::Spell* spell = world->getStore().get<ESM::Spell>().search(cooldown.id);
ptrSpells.setPowerUseTimestamp(spell, cooldown.startTimestampDay, cooldown.startTimestampHour);
}
}
}
void LocalPlayer::setQuickKeys() void LocalPlayer::setQuickKeys()
{ {
MWWorld::Ptr ptrPlayer = getPlayerPtr(); MWWorld::Ptr ptrPlayer = getPlayerPtr();
@ -1647,6 +1664,25 @@ void LocalPlayer::sendSpellsActiveRemoval(const std::string id, bool isStackingS
getNetworking()->getPlayerPacket(ID_PLAYER_SPELLS_ACTIVE)->Send(); getNetworking()->getPlayerPacket(ID_PLAYER_SPELLS_ACTIVE)->Send();
} }
void LocalPlayer::sendCooldownChange(std::string id, int startTimestampDay, float startTimestampHour)
{
// Skip any bugged spells that somehow have clientside-only dynamic IDs
if (id.find("$dynamic") != std::string::npos)
return;
cooldownChanges.clear();
SpellCooldown spellCooldown;
spellCooldown.id = id;
spellCooldown.startTimestampDay = startTimestampDay;
spellCooldown.startTimestampHour = startTimestampHour;
cooldownChanges.push_back(spellCooldown);
;
getNetworking()->getPlayerPacket(ID_PLAYER_COOLDOWNS)->setPlayer(this);
getNetworking()->getPlayerPacket(ID_PLAYER_COOLDOWNS)->Send();
}
void LocalPlayer::sendQuickKey(unsigned short slot, int type, const std::string& itemId) void LocalPlayer::sendQuickKey(unsigned short slot, int type, const std::string& itemId)
{ {
quickKeyChanges.clear(); quickKeyChanges.clear();

View file

@ -75,6 +75,7 @@ namespace mwmp
void setInventory(); void setInventory();
void setSpellbook(); void setSpellbook();
void setSpellsActive(); void setSpellsActive();
void setCooldowns();
void setQuickKeys(); void setQuickKeys();
void setFactions(); void setFactions();
void setBooks(); void setBooks();
@ -94,6 +95,7 @@ namespace mwmp
void sendSpellsActive(); void sendSpellsActive();
void sendSpellsActiveAddition(const std::string id, bool isStackingSpell, ESM::ActiveSpells::ActiveSpellParams params, MWWorld::TimeStamp timestamp); void sendSpellsActiveAddition(const std::string id, bool isStackingSpell, ESM::ActiveSpells::ActiveSpellParams params, MWWorld::TimeStamp timestamp);
void sendSpellsActiveRemoval(const std::string id, bool isStackingSpell, MWWorld::TimeStamp timestamp); void sendSpellsActiveRemoval(const std::string id, bool isStackingSpell, MWWorld::TimeStamp timestamp);
void sendCooldownChange(std::string id, int startTimestampDay, float startTimestampHour);
void sendQuickKey(unsigned short slot, int type, const std::string& itemId = ""); void sendQuickKey(unsigned short slot, int type, const std::string& itemId = "");
void sendJournalEntry(const std::string& quest, int index, const MWWorld::Ptr& actor); void sendJournalEntry(const std::string& quest, int index, const MWWorld::Ptr& actor);
void sendJournalIndex(const std::string& quest, int index); void sendJournalIndex(const std::string& quest, int index);

View file

@ -22,6 +22,7 @@
#include "player/ProcessorPlayerCellState.hpp" #include "player/ProcessorPlayerCellState.hpp"
#include "player/ProcessorPlayerCharClass.hpp" #include "player/ProcessorPlayerCharClass.hpp"
#include "player/ProcessorPlayerCharGen.hpp" #include "player/ProcessorPlayerCharGen.hpp"
#include "player/ProcessorPlayerCooldowns.hpp"
#include "player/ProcessorPlayerDeath.hpp" #include "player/ProcessorPlayerDeath.hpp"
#include "player/ProcessorPlayerDisposition.hpp" #include "player/ProcessorPlayerDisposition.hpp"
#include "player/ProcessorPlayerEquipment.hpp" #include "player/ProcessorPlayerEquipment.hpp"
@ -128,6 +129,7 @@ void ProcessorInitializer()
PlayerProcessor::AddProcessor(new ProcessorPlayerCellState()); PlayerProcessor::AddProcessor(new ProcessorPlayerCellState());
PlayerProcessor::AddProcessor(new ProcessorPlayerCharClass()); PlayerProcessor::AddProcessor(new ProcessorPlayerCharClass());
PlayerProcessor::AddProcessor(new ProcessorPlayerCharGen()); PlayerProcessor::AddProcessor(new ProcessorPlayerCharGen());
PlayerProcessor::AddProcessor(new ProcessorPlayerCooldowns());
PlayerProcessor::AddProcessor(new ProcessorPlayerDeath()); PlayerProcessor::AddProcessor(new ProcessorPlayerDeath());
PlayerProcessor::AddProcessor(new ProcessorPlayerDisposition()); PlayerProcessor::AddProcessor(new ProcessorPlayerDisposition());
PlayerProcessor::AddProcessor(new ProcessorPlayerEquipment()); PlayerProcessor::AddProcessor(new ProcessorPlayerEquipment());

View file

@ -0,0 +1,29 @@
#ifndef OPENMW_PROCESSORPLAYERCOOLDOWNS_HPP
#define OPENMW_PROCESSORPLAYERCOOLDOWNS_HPP
#include "../PlayerProcessor.hpp"
namespace mwmp
{
class ProcessorPlayerCooldowns final: public PlayerProcessor
{
public:
ProcessorPlayerCooldowns()
{
BPP_INIT(ID_PLAYER_COOLDOWNS)
}
virtual void Do(PlayerPacket &packet, BasePlayer *player)
{
if (!isLocal()) return;
LOG_MESSAGE_SIMPLE(TimedLog::LOG_INFO, "Received ID_PLAYER_COOLDOWNS about LocalPlayer from server");
LocalPlayer &localPlayer = static_cast<LocalPlayer&>(*player);
localPlayer.setCooldowns();
}
};
}
#endif //OPENMW_PROCESSORPLAYERCOOLDOWNS_HPP

View file

@ -192,12 +192,12 @@ add_component_dir (openmw-mp/Packets/Player
PacketPlayerBaseInfo PacketPlayerCharGen PacketPlayerAlly PacketPlayerAnimFlags PacketPlayerAnimPlay PacketPlayerBaseInfo PacketPlayerCharGen PacketPlayerAlly PacketPlayerAnimFlags PacketPlayerAnimPlay
PacketPlayerAttack PacketPlayerAttribute PacketPlayerBehavior PacketPlayerBook PacketPlayerBounty PacketPlayerAttack PacketPlayerAttribute PacketPlayerBehavior PacketPlayerBook PacketPlayerBounty
PacketPlayerCast PacketPlayerCellChange PacketPlayerCellState PacketPlayerClass PacketPlayerDeath PacketPlayerCast PacketPlayerCellChange PacketPlayerCellState PacketPlayerClass PacketPlayerCooldowns
PacketPlayerEquipment PacketPlayerFaction PacketPlayerInput PacketPlayerInventory PacketPlayerItemUse PacketPlayerDeath PacketPlayerEquipment PacketPlayerFaction PacketPlayerInput PacketPlayerInventory
PacketPlayerJail PacketPlayerJournal PacketPlayerLevel PacketPlayerMiscellaneous PacketPlayerMomentum PacketPlayerItemUse PacketPlayerJail PacketPlayerJournal PacketPlayerLevel PacketPlayerMiscellaneous
PacketPlayerPosition PacketPlayerQuickKeys PacketPlayerReputation PacketPlayerRest PacketPlayerResurrect PacketPlayerMomentum PacketPlayerPosition PacketPlayerQuickKeys PacketPlayerReputation PacketPlayerRest
PacketPlayerShapeshift PacketPlayerSkill PacketPlayerSpeech PacketPlayerSpellbook PacketPlayerSpellsActive PacketPlayerResurrect PacketPlayerShapeshift PacketPlayerSkill PacketPlayerSpeech PacketPlayerSpellbook
PacketPlayerStatsDynamic PacketPlayerTopic PacketPlayerSpellsActive PacketPlayerStatsDynamic PacketPlayerTopic
) )
add_component_dir (openmw-mp/Packets/Object add_component_dir (openmw-mp/Packets/Object

View file

@ -208,6 +208,7 @@ namespace mwmp
InventoryChanges inventoryChanges; InventoryChanges inventoryChanges;
SpellbookChanges spellbookChanges; SpellbookChanges spellbookChanges;
std::vector<SpellCooldown> cooldownChanges;
SpellsActiveChanges spellsActiveChanges; SpellsActiveChanges spellsActiveChanges;
std::vector<QuickKey> quickKeyChanges; std::vector<QuickKey> quickKeyChanges;
std::vector<JournalItem> journalChanges; std::vector<JournalItem> journalChanges;

View file

@ -157,6 +157,13 @@ namespace mwmp
bool shouldSend; bool shouldSend;
}; };
struct SpellCooldown
{
std::string id;
int startTimestampDay;
double startTimestampHour;
};
struct ActiveSpell struct ActiveSpell
{ {
std::string id; std::string id;

View file

@ -18,6 +18,7 @@
#include "../Packets/Player/PacketPlayerCellChange.hpp" #include "../Packets/Player/PacketPlayerCellChange.hpp"
#include "../Packets/Player/PacketPlayerCellState.hpp" #include "../Packets/Player/PacketPlayerCellState.hpp"
#include "../Packets/Player/PacketPlayerClass.hpp" #include "../Packets/Player/PacketPlayerClass.hpp"
#include "../Packets/Player/PacketPlayerCooldowns.hpp"
#include "../Packets/Player/PacketPlayerDeath.hpp" #include "../Packets/Player/PacketPlayerDeath.hpp"
#include "../Packets/Player/PacketPlayerEquipment.hpp" #include "../Packets/Player/PacketPlayerEquipment.hpp"
#include "../Packets/Player/PacketPlayerFaction.hpp" #include "../Packets/Player/PacketPlayerFaction.hpp"
@ -74,6 +75,7 @@ mwmp::PlayerPacketController::PlayerPacketController(RakNet::RakPeerInterface *p
AddPacket<PacketPlayerCellState>(&packets, peer); AddPacket<PacketPlayerCellState>(&packets, peer);
AddPacket<PacketPlayerCharGen>(&packets, peer); AddPacket<PacketPlayerCharGen>(&packets, peer);
AddPacket<PacketPlayerClass>(&packets, peer); AddPacket<PacketPlayerClass>(&packets, peer);
AddPacket<PacketPlayerCooldowns>(&packets, peer);
AddPacket<PacketPlayerDeath>(&packets, peer); AddPacket<PacketPlayerDeath>(&packets, peer);
AddPacket<PacketPlayerEquipment>(&packets, peer); AddPacket<PacketPlayerEquipment>(&packets, peer);
AddPacket<PacketPlayerFaction>(&packets, peer); AddPacket<PacketPlayerFaction>(&packets, peer);

View file

@ -112,6 +112,7 @@ enum GameMessages
ID_PLAYER_ALLY, ID_PLAYER_ALLY,
ID_WORLD_DESTINATION_OVERRIDE, ID_WORLD_DESTINATION_OVERRIDE,
ID_ACTOR_SPELLS_ACTIVE, ID_ACTOR_SPELLS_ACTIVE,
ID_PLAYER_COOLDOWNS,
ID_PLACEHOLDER ID_PLACEHOLDER
}; };

View file

@ -0,0 +1,34 @@
#include <components/openmw-mp/NetworkMessages.hpp>
#include "PacketPlayerCooldowns.hpp"
using namespace mwmp;
PacketPlayerCooldowns::PacketPlayerCooldowns(RakNet::RakPeerInterface *peer) : PlayerPacket(peer)
{
packetID = ID_PLAYER_COOLDOWNS;
}
void PacketPlayerCooldowns::Packet(RakNet::BitStream *newBitstream, bool send)
{
PlayerPacket::Packet(newBitstream, send);
uint32_t count;
if (send)
count = static_cast<uint32_t>(player->cooldownChanges.size());
RW(count, send);
if (!send)
{
player->cooldownChanges.clear();
player->cooldownChanges.resize(count);
}
for (auto &&spell : player->cooldownChanges)
{
RW(spell.id, send, true);
RW(spell.startTimestampDay, send);
RW(spell.startTimestampHour, send);
}
}

View file

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