[General] Implement ActorSpellsActive packet, part 1

The packet can now set the active spells of DedicatedActors.
pull/593/head
David Cernat 4 years ago
parent f6887559f6
commit bf0a42fdad

@ -84,8 +84,8 @@ set(PROCESSORS_ACTOR
processors/actor/ProcessorActorCast.hpp processors/actor/ProcessorActorCellChange.hpp
processors/actor/ProcessorActorDeath.hpp processors/actor/ProcessorActorEquipment.hpp
processors/actor/ProcessorActorList.hpp processors/actor/ProcessorActorPosition.hpp
processors/actor/ProcessorActorSpeech.hpp processors/actor/ProcessorActorStatsDynamic.hpp
processors/actor/ProcessorActorTest.hpp
processors/actor/ProcessorActorSpeech.hpp processors/actor/ProcessorActorSpellsActive.hpp
processors/actor/ProcessorActorStatsDynamic.hpp processors/actor/ProcessorActorTest.hpp
)
source_group(tes3mp-server\\processors\\actor FILES ${PROCESSORS_ACTOR})

@ -207,6 +207,7 @@ public:
{"OnActorEquipment", Callback<unsigned short, const char*>()},
{"OnActorAI", Callback<unsigned short, const char*>()},
{"OnActorDeath", Callback<unsigned short, const char*>()},
{"OnActorSpellsActive", Callback<unsigned short, const char*>()},
{"OnActorCellChange", Callback<unsigned short, const char*>()},
{"OnActorTest", Callback<unsigned short, const char*>()},
{"OnPlayerSendMessage", Callback<unsigned short, const char*>()},

@ -51,9 +51,10 @@
#include "actor/ProcessorActorCellChange.hpp"
#include "actor/ProcessorActorDeath.hpp"
#include "actor/ProcessorActorEquipment.hpp"
#include "actor/ProcessorActorStatsDynamic.hpp"
#include "actor/ProcessorActorPosition.hpp"
#include "actor/ProcessorActorSpeech.hpp"
#include "actor/ProcessorActorSpellsActive.hpp"
#include "actor/ProcessorActorStatsDynamic.hpp"
#include "ObjectProcessor.hpp"
#include "object/ProcessorConsoleCommand.hpp"
#include "object/ProcessorContainer.hpp"
@ -137,6 +138,7 @@ void ProcessorInitializer()
ActorProcessor::AddProcessor(new ProcessorActorEquipment());
ActorProcessor::AddProcessor(new ProcessorActorPosition());
ActorProcessor::AddProcessor(new ProcessorActorSpeech());
ActorProcessor::AddProcessor(new ProcessorActorSpellsActive());
ActorProcessor::AddProcessor(new ProcessorActorStatsDynamic());
ActorProcessor::AddProcessor(new ProcessorActorTest());

@ -0,0 +1,31 @@
#ifndef OPENMW_PROCESSORACTORSPELLSACTIVE_HPP
#define OPENMW_PROCESSORACTORSPELLSACTIVE_HPP
#include "../ActorProcessor.hpp"
namespace mwmp
{
class ProcessorActorSpellsActive : public ActorProcessor
{
public:
ProcessorActorSpellsActive()
{
BPP_INIT(ID_ACTOR_SPELLS_ACTIVE)
}
void Do(ActorPacket &packet, Player &player, BaseActorList &actorList) override
{
// Send only to players who have the cell loaded
Cell *serverCell = CellController::get()->getCell(&actorList.cell);
if (serverCell != nullptr && *serverCell->getAuthority() == actorList.guid)
{
Script::Call<Script::CallbackIdentity("OnActorSpellsActive")>(player.getId(), actorList.cell.getDescription().c_str());
serverCell->sendToLoaded(&packet, &actorList);
}
}
};
}
#endif //OPENMW_PROCESSORACTORSPELLSACTIVE_HPP

@ -115,7 +115,8 @@ add_openmw_dir (mwmp/processors/system ProcessorSystemHandshake
add_openmw_dir (mwmp/processors/actor ProcessorActorAI ProcessorActorAnimFlags ProcessorActorAnimPlay ProcessorActorAttack
ProcessorActorAuthority ProcessorActorCast ProcessorActorCellChange ProcessorActorDeath ProcessorActorEquipment
ProcessorActorList ProcessorActorPosition ProcessorActorSpeech ProcessorActorStatsDynamic ProcessorActorTest
ProcessorActorList ProcessorActorPosition ProcessorActorSpeech ProcessorActorSpellsActive ProcessorActorStatsDynamic
ProcessorActorTest
)
add_openmw_dir (mwmp/processors/player ProcessorChatMessage ProcessorGUIMessageBox ProcessorUserDisconnected

@ -15,6 +15,8 @@
#include "../mwworld/class.hpp"
#include "../mwmp/Main.hpp"
#include "../mwmp/LocalPlayer.hpp"
#include "../mwmp/CellController.hpp"
#include "../mwmp/MechanicsHelper.hpp"
/*
End of tes3mp addition
*/
@ -47,6 +49,10 @@ namespace MWMechanics
{
mwmp::Main::get().getLocalPlayer()->sendSpellsActiveRemoval(iter->first);
}
else if (mwmp::Main::get().getCellController()->isLocalActor(MechanicsHelper::getCurrentActor()))
{
mwmp::Main::get().getCellController()->getLocalActor(MechanicsHelper::getCurrentActor())->sendSpellsActiveRemoval(iter->first);
}
/*
End of tes3mp addition
*/
@ -205,6 +211,10 @@ namespace MWMechanics
{
mwmp::Main::get().getLocalPlayer()->sendSpellsActiveAddition(id, esmParams);
}
else if (mwmp::Main::get().getCellController()->isLocalActor(MechanicsHelper::getCurrentActor()))
{
mwmp::Main::get().getCellController()->getLocalActor(MechanicsHelper::getCurrentActor())->sendSpellsActiveAddition(id, esmParams);
}
/*
End of tes3mp addition
*/

@ -2123,6 +2123,16 @@ namespace MWMechanics
End of tes3mp change (major)
*/
/*
Start of tes3mp addition
Store the current actor's Ptr so it can be retrieved from inside ActiveSpells for
multiplayer logic purposes
*/
MechanicsHelper::storeCurrentActor(iter->first);
/*
End of tes3mp addition
*/
iter->first.getClass().getCreatureStats(iter->first).getActiveSpells().update(duration);
const Misc::TimerStatus engageCombatTimerStatus = iter->second->updateEngageCombatTimer(duration);
@ -2528,6 +2538,16 @@ namespace MWMechanics
{
if (iter->first.getClass().getCreatureStats(iter->first).isDead())
{
/*
Start of tes3mp addition
Store the current actor's Ptr so it can be retrieved from inside ActiveSpells for
multiplayer logic purposes
*/
MechanicsHelper::storeCurrentActor(iter->first);
/*
End of tes3mp addition
*/
iter->first.getClass().getCreatureStats(iter->first).getActiveSpells().update(duration);
continue;
}
@ -2547,6 +2567,17 @@ namespace MWMechanics
if (iter->first.getClass().isNpc())
calculateNpcStatModifiers(iter->first, duration);
/*
Start of tes3mp addition
Store the current actor's Ptr so it can be retrieved from inside ActiveSpells for
multiplayer logic purposes
*/
MechanicsHelper::storeCurrentActor(iter->first);
/*
End of tes3mp addition
*/
iter->first.getClass().getCreatureStats(iter->first).getActiveSpells().update(duration);
MWRender::Animation* animation = MWBase::Environment::get().getWorld()->getAnimation(iter->first);

@ -286,6 +286,36 @@ void Cell::readSpeech(ActorList& actorList)
uninitializeDedicatedActors(actorList);
}
void Cell::readSpellsActive(ActorList& actorList)
{
initializeDedicatedActors(actorList);
if (dedicatedActors.empty()) return;
for (const auto& baseActor : actorList.baseActors)
{
std::string mapIndex = Main::get().getCellController()->generateMapIndex(baseActor);
if (dedicatedActors.count(mapIndex) > 0)
{
DedicatedActor* actor = dedicatedActors[mapIndex];
actor->spellsActiveChanges = baseActor.spellsActiveChanges;
int spellsActiveAction = baseActor.spellsActiveChanges.action;
if (spellsActiveAction == SpellsActiveChanges::ADD)
actor->addSpellsActive();
else if (spellsActiveAction == SpellsActiveChanges::REMOVE)
actor->removeSpellsActive();
else
actor->setSpellsActive();
}
}
if (hasLocalAuthority())
uninitializeDedicatedActors(actorList);
}
void Cell::readAi(ActorList& actorList)
{
initializeDedicatedActors(actorList);

@ -25,6 +25,7 @@ namespace mwmp
void readDeath(ActorList& actorList);
void readEquipment(ActorList& actorList);
void readSpeech(ActorList& actorList);
void readSpellsActive(ActorList& actorList);
void readAi(ActorList& actorList);
void readAttack(ActorList& actorList);
void readCast(ActorList& actorList);

@ -211,6 +211,17 @@ void CellController::readSpeech(ActorList& actorList)
cellsInitialized[mapIndex]->readSpeech(actorList);
}
void CellController::readSpellsActive(ActorList& actorList)
{
std::string mapIndex = actorList.cell.getDescription();
initializeCell(actorList.cell);
// If this now exists, send it the data
if (cellsInitialized.count(mapIndex) > 0)
cellsInitialized[mapIndex]->readSpellsActive(actorList);
}
void CellController::readAi(ActorList& actorList)
{
std::string mapIndex = actorList.cell.getDescription();

@ -30,6 +30,7 @@ namespace mwmp
void readDeath(mwmp::ActorList& actorList);
void readEquipment(mwmp::ActorList& actorList);
void readSpeech(mwmp::ActorList& actorList);
void readSpellsActive(mwmp::ActorList& actorList);
void readAi(mwmp::ActorList& actorList);
void readAttack(mwmp::ActorList& actorList);
void readCast(mwmp::ActorList& actorList);

@ -359,6 +359,41 @@ void DedicatedActor::equipItem(std::string itemId, int charge, bool noSound)
}
}
void DedicatedActor::addSpellsActive()
{
MWMechanics::ActiveSpells& activeSpells = getPtr().getClass().getCreatureStats(getPtr()).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 DedicatedActor::removeSpellsActive()
{
MWMechanics::ActiveSpells& activeSpells = getPtr().getClass().getCreatureStats(getPtr()).getActiveSpells();
for (const auto& activeSpell : spellsActiveChanges.activeSpells)
{
activeSpells.removeEffects(activeSpell.id);
}
}
void DedicatedActor::setSpellsActive()
{
MWMechanics::ActiveSpells& activeSpells = getPtr().getClass().getCreatureStats(getPtr()).getActiveSpells();
activeSpells.clear();
// Proceed by adding spells active
addSpellsActive();
}
MWWorld::Ptr DedicatedActor::getPtr()
{
return ptr;

@ -29,6 +29,10 @@ namespace mwmp
bool hasItem(std::string itemId, int charge);
void equipItem(std::string itemId, int charge, bool noSound = false);
void addSpellsActive();
void removeSpellsActive();
void setSpellsActive();
MWWorld::Ptr getPtr();
void setPtr(const MWWorld::Ptr& newPtr);

@ -285,6 +285,49 @@ void LocalActor::sendEquipment()
Main::get().getNetworking()->getActorPacket(ID_ACTOR_EQUIPMENT)->Send();
}
void LocalActor::sendSpellsActiveAddition(const std::string id, ESM::ActiveSpells::ActiveSpellParams params)
{
// Skip any bugged spells that somehow have clientside-only dynamic IDs
if (id.find("$dynamic") != std::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;
ActorList actorList;
actorList.cell = cell;
actorList.addActor(*this);
Main::get().getNetworking()->getActorPacket(ID_ACTOR_SPELLS_ACTIVE)->setActorList(&actorList);
Main::get().getNetworking()->getActorPacket(ID_ACTOR_SPELLS_ACTIVE)->Send();
}
void LocalActor::sendSpellsActiveRemoval(const std::string id)
{
// Skip any bugged spells that somehow have clientside-only dynamic IDs
if (id.find("$dynamic") != std::string::npos)
return;
spellsActiveChanges.activeSpells.clear();
mwmp::ActiveSpell spell;
spell.id = id;
spellsActiveChanges.activeSpells.push_back(spell);
spellsActiveChanges.action = mwmp::SpellsActiveChanges::REMOVE;
ActorList actorList;
actorList.cell = cell;
actorList.addActor(*this);
Main::get().getNetworking()->getActorPacket(ID_ACTOR_SPELLS_ACTIVE)->setActorList(&actorList);
Main::get().getNetworking()->getActorPacket(ID_ACTOR_SPELLS_ACTIVE)->Send();
}
void LocalActor::sendDeath(char newDeathState)
{
deathState = newDeathState;

@ -26,6 +26,8 @@ namespace mwmp
void updateAttackOrCast();
void sendEquipment();
void sendSpellsActiveAddition(const std::string id, ESM::ActiveSpells::ActiveSpellParams params);
void sendSpellsActiveRemoval(const std::string id);
void sendDeath(char newDeathState);
MWWorld::Ptr getPtr();

@ -589,3 +589,13 @@ MWWorld::Ptr MechanicsHelper::getItemPtrFromStore(const mwmp::Item& item, MWWorl
return closestPtr;
}
MWWorld::Ptr MechanicsHelper::getCurrentActor()
{
return currentActor;
}
void MechanicsHelper::storeCurrentActor(const MWWorld::Ptr& actor)
{
currentActor = actor;
}

@ -49,6 +49,11 @@ namespace MechanicsHelper
void unequipItemsByEffect(const MWWorld::Ptr& ptr, short enchantmentType, short effectId, short attributeId = -1, short skillId = -1);
MWWorld::Ptr getItemPtrFromStore(const mwmp::Item& item, MWWorld::ContainerStore& store);
MWWorld::Ptr getCurrentActor();
void storeCurrentActor(const MWWorld::Ptr& actor);
static MWWorld::Ptr currentActor;
}

@ -87,6 +87,7 @@
#include "actor/ProcessorActorList.hpp"
#include "actor/ProcessorActorPosition.hpp"
#include "actor/ProcessorActorSpeech.hpp"
#include "actor/ProcessorActorSpellsActive.hpp"
#include "actor/ProcessorActorStatsDynamic.hpp"
#include "actor/ProcessorActorTest.hpp"
@ -190,6 +191,7 @@ void ProcessorInitializer()
ActorProcessor::AddProcessor(new ProcessorActorList());
ActorProcessor::AddProcessor(new ProcessorActorPosition());
ActorProcessor::AddProcessor(new ProcessorActorSpeech());
ActorProcessor::AddProcessor(new ProcessorActorSpellsActive());
ActorProcessor::AddProcessor(new ProcessorActorStatsDynamic());
ActorProcessor::AddProcessor(new ProcessorActorTest());

@ -0,0 +1,25 @@
#ifndef OPENMW_PROCESSORACTORSPELLSACTIVE_HPP
#define OPENMW_PROCESSORACTORSPELLSACTIVE_HPP
#include "../ActorProcessor.hpp"
#include "apps/openmw/mwmp/Main.hpp"
#include "apps/openmw/mwmp/CellController.hpp"
namespace mwmp
{
class ProcessorActorSpellsActive final: public ActorProcessor
{
public:
ProcessorActorSpellsActive()
{
BPP_INIT(ID_ACTOR_SPELLS_ACTIVE);
}
virtual void Do(ActorPacket &packet, ActorList &actorList)
{
Main::get().getCellController()->readSpellsActive(actorList);
}
};
}
#endif //OPENMW_PROCESSORACTORSPELLSACTIVE_HPP

@ -58,6 +58,7 @@ namespace mwmp
bool hasStatsDynamicData;
Item equipmentItems[19];
SpellsActiveChanges spellsActiveChanges;
};
class BaseActorList

@ -11,5 +11,51 @@ PacketActorSpellsActive::PacketActorSpellsActive(RakNet::RakPeerInterface *peer)
void PacketActorSpellsActive::Actor(BaseActor &actor, bool send)
{
// Placeholder
RW(actor.spellsActiveChanges.action, send);
uint32_t count;
if (send)
count = static_cast<uint32_t>(actor.spellsActiveChanges.activeSpells.size());
RW(count, send);
if (!send)
{
actor.spellsActiveChanges.activeSpells.clear();
actor.spellsActiveChanges.activeSpells.resize(count);
}
for (auto&& activeSpell : actor.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)
{
return;
}
if (!send)
{
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
PacketActorSpellsActive(RakNet::RakPeerInterface *peer);
virtual void Actor(BaseActor &actor, bool send);
protected:
static const int maxEffects = 20;
};
}

Loading…
Cancel
Save