[General] Split up Attack packets into Attack and Cast ones

Create an entirely new PlayerCast packet for that purpose, but rename the already existing but unused ActorInteraction into ActorCast.
pull/541/head
David Cernat 5 years ago
parent 353e7d530a
commit 9350e1d484

@ -79,8 +79,8 @@ source_group(tes3mp-server FILES ${SERVER} ${SERVER_HEADER})
set(PROCESSORS_ACTOR set(PROCESSORS_ACTOR
processors/actor/ProcessorActorAI.hpp processors/actor/ProcessorActorAnimFlags.hpp processors/actor/ProcessorActorAI.hpp processors/actor/ProcessorActorAnimFlags.hpp
processors/actor/ProcessorActorAnimPlay.hpp processors/actor/ProcessorActorAttack.hpp processors/actor/ProcessorActorAnimPlay.hpp processors/actor/ProcessorActorAttack.hpp
processors/actor/ProcessorActorCellChange.hpp processors/actor/ProcessorActorDeath.hpp processors/actor/ProcessorActorCast.hpp processors/actor/ProcessorActorCellChange.hpp
processors/actor/ProcessorActorEquipment.hpp processors/actor/ProcessorActorInteraction.hpp processors/actor/ProcessorActorDeath.hpp processors/actor/ProcessorActorEquipment.hpp
processors/actor/ProcessorActorList.hpp processors/actor/ProcessorActorPosition.hpp processors/actor/ProcessorActorList.hpp processors/actor/ProcessorActorPosition.hpp
processors/actor/ProcessorActorSpeech.hpp processors/actor/ProcessorActorStatsDynamic.hpp processors/actor/ProcessorActorSpeech.hpp processors/actor/ProcessorActorStatsDynamic.hpp
processors/actor/ProcessorActorTest.hpp processors/actor/ProcessorActorTest.hpp
@ -93,19 +93,19 @@ set(PROCESSORS_PLAYER
processors/player/ProcessorPlayerAnimFlags.hpp processors/player/ProcessorPlayerAnimPlay.hpp processors/player/ProcessorPlayerAnimFlags.hpp processors/player/ProcessorPlayerAnimPlay.hpp
processors/player/ProcessorPlayerAttack.hpp processors/player/ProcessorPlayerAttribute.hpp processors/player/ProcessorPlayerAttack.hpp processors/player/ProcessorPlayerAttribute.hpp
processors/player/ProcessorPlayerBook.hpp processors/player/ProcessorPlayerBounty.hpp processors/player/ProcessorPlayerBook.hpp processors/player/ProcessorPlayerBounty.hpp
processors/player/ProcessorPlayerCellChange.hpp processors/player/ProcessorPlayerCellState.hpp processors/player/ProcessorPlayerCast.hpp processors/player/ProcessorPlayerCellChange.hpp
processors/player/ProcessorPlayerCharClass.hpp processors/player/ProcessorPlayerCharGen.hpp processors/player/ProcessorPlayerCellState.hpp processors/player/ProcessorPlayerCharClass.hpp
processors/player/ProcessorPlayerDeath.hpp processors/player/ProcessorPlayerDisposition.hpp processors/player/ProcessorPlayerCharGen.hpp processors/player/ProcessorPlayerDeath.hpp
processors/player/ProcessorPlayerEquipment.hpp processors/player/ProcessorPlayerFaction.hpp processors/player/ProcessorPlayerDisposition.hpp processors/player/ProcessorPlayerEquipment.hpp
processors/player/ProcessorPlayerInput.hpp processors/player/ProcessorPlayerInventory.hpp processors/player/ProcessorPlayerFaction.hpp processors/player/ProcessorPlayerInput.hpp
processors/player/ProcessorPlayerItemUse.hpp processors/player/ProcessorPlayerJournal.hpp processors/player/ProcessorPlayerInventory.hpp processors/player/ProcessorPlayerItemUse.hpp
processors/player/ProcessorWorldKillCount.hpp processors/player/ProcessorPlayerLevel.hpp processors/player/ProcessorPlayerJournal.hpp processors/player/ProcessorWorldKillCount.hpp
processors/player/ProcessorPlayerMiscellaneous.hpp processors/player/ProcessorPlayerPosition.hpp processors/player/ProcessorPlayerLevel.hpp processors/player/ProcessorPlayerMiscellaneous.hpp
processors/player/ProcessorPlayerQuickKeys.hpp processors/player/ProcessorPlayerRest.hpp processors/player/ProcessorPlayerPosition.hpp processors/player/ProcessorPlayerQuickKeys.hpp
processors/player/ProcessorPlayerResurrect.hpp processors/player/ProcessorPlayerShapeshift.hpp processors/player/ProcessorPlayerRest.hpp processors/player/ProcessorPlayerResurrect.hpp
processors/player/ProcessorPlayerSkill.hpp processors/player/ProcessorPlayerSpeech.hpp processors/player/ProcessorPlayerShapeshift.hpp processors/player/ProcessorPlayerSkill.hpp
processors/player/ProcessorPlayerSpellbook.hpp processors/player/ProcessorPlayerStatsDynamic.hpp processors/player/ProcessorPlayerSpeech.hpp processors/player/ProcessorPlayerSpellbook.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})

@ -13,6 +13,7 @@
#include "player/ProcessorPlayerAttribute.hpp" #include "player/ProcessorPlayerAttribute.hpp"
#include "player/ProcessorPlayerBook.hpp" #include "player/ProcessorPlayerBook.hpp"
#include "player/ProcessorPlayerBounty.hpp" #include "player/ProcessorPlayerBounty.hpp"
#include "player/ProcessorPlayerCast.hpp"
#include "player/ProcessorPlayerCellChange.hpp" #include "player/ProcessorPlayerCellChange.hpp"
#include "player/ProcessorPlayerCellState.hpp" #include "player/ProcessorPlayerCellState.hpp"
#include "player/ProcessorPlayerCharClass.hpp" #include "player/ProcessorPlayerCharClass.hpp"
@ -45,10 +46,10 @@
#include "actor/ProcessorActorAnimFlags.hpp" #include "actor/ProcessorActorAnimFlags.hpp"
#include "actor/ProcessorActorAnimPlay.hpp" #include "actor/ProcessorActorAnimPlay.hpp"
#include "actor/ProcessorActorAttack.hpp" #include "actor/ProcessorActorAttack.hpp"
#include "actor/ProcessorActorCast.hpp"
#include "actor/ProcessorActorCellChange.hpp" #include "actor/ProcessorActorCellChange.hpp"
#include "actor/ProcessorActorDeath.hpp" #include "actor/ProcessorActorDeath.hpp"
#include "actor/ProcessorActorEquipment.hpp" #include "actor/ProcessorActorEquipment.hpp"
#include "actor/ProcessorActorInteraction.hpp"
#include "actor/ProcessorActorStatsDynamic.hpp" #include "actor/ProcessorActorStatsDynamic.hpp"
#include "actor/ProcessorActorPosition.hpp" #include "actor/ProcessorActorPosition.hpp"
#include "actor/ProcessorActorSpeech.hpp" #include "actor/ProcessorActorSpeech.hpp"
@ -92,6 +93,7 @@ void ProcessorInitializer()
PlayerProcessor::AddProcessor(new ProcessorPlayerAttribute()); PlayerProcessor::AddProcessor(new ProcessorPlayerAttribute());
PlayerProcessor::AddProcessor(new ProcessorPlayerBook()); PlayerProcessor::AddProcessor(new ProcessorPlayerBook());
PlayerProcessor::AddProcessor(new ProcessorPlayerBounty()); PlayerProcessor::AddProcessor(new ProcessorPlayerBounty());
PlayerProcessor::AddProcessor(new ProcessorPlayerCast());
PlayerProcessor::AddProcessor(new ProcessorPlayerCellChange()); PlayerProcessor::AddProcessor(new ProcessorPlayerCellChange());
PlayerProcessor::AddProcessor(new ProcessorPlayerCellState()); PlayerProcessor::AddProcessor(new ProcessorPlayerCellState());
PlayerProcessor::AddProcessor(new ProcessorPlayerCharClass()); PlayerProcessor::AddProcessor(new ProcessorPlayerCharClass());
@ -123,10 +125,10 @@ void ProcessorInitializer()
ActorProcessor::AddProcessor(new ProcessorActorAnimFlags()); ActorProcessor::AddProcessor(new ProcessorActorAnimFlags());
ActorProcessor::AddProcessor(new ProcessorActorAnimPlay()); ActorProcessor::AddProcessor(new ProcessorActorAnimPlay());
ActorProcessor::AddProcessor(new ProcessorActorAttack()); ActorProcessor::AddProcessor(new ProcessorActorAttack());
ActorProcessor::AddProcessor(new ProcessorActorCast());
ActorProcessor::AddProcessor(new ProcessorActorCellChange()); ActorProcessor::AddProcessor(new ProcessorActorCellChange());
ActorProcessor::AddProcessor(new ProcessorActorDeath()); ActorProcessor::AddProcessor(new ProcessorActorDeath());
ActorProcessor::AddProcessor(new ProcessorActorEquipment()); ActorProcessor::AddProcessor(new ProcessorActorEquipment());
ActorProcessor::AddProcessor(new ProcessorActorInteraction());
ActorProcessor::AddProcessor(new ProcessorActorPosition()); ActorProcessor::AddProcessor(new ProcessorActorPosition());
ActorProcessor::AddProcessor(new ProcessorActorSpeech()); ActorProcessor::AddProcessor(new ProcessorActorSpeech());
ActorProcessor::AddProcessor(new ProcessorActorStatsDynamic()); ActorProcessor::AddProcessor(new ProcessorActorStatsDynamic());

@ -1,16 +1,16 @@
#ifndef OPENMW_PROCESSORACTORINTERACTION_HPP #ifndef OPENMW_PROCESSORACTORCAST_HPP
#define OPENMW_PROCESSORACTORINTERACTION_HPP #define OPENMW_PROCESSORACTORCAST_HPP
#include "../ActorProcessor.hpp" #include "../ActorProcessor.hpp"
namespace mwmp namespace mwmp
{ {
class ProcessorActorInteraction : public ActorProcessor class ProcessorActorCast : public ActorProcessor
{ {
public: public:
ProcessorActorInteraction() ProcessorActorCast()
{ {
BPP_INIT(ID_ACTOR_INTERACTION) BPP_INIT(ID_ACTOR_CAST)
} }
void Do(ActorPacket &packet, Player &player, BaseActorList &actorList) override void Do(ActorPacket &packet, Player &player, BaseActorList &actorList) override
@ -24,4 +24,4 @@ namespace mwmp
}; };
} }
#endif //OPENMW_PROCESSORACTORINTERACTION_HPP #endif //OPENMW_PROCESSORACTORCAST_HPP

@ -0,0 +1,30 @@
#ifndef OPENMW_PROCESSORPLAYERCAST_HPP
#define OPENMW_PROCESSORPLAYERCAST_HPP
#include "../PlayerProcessor.hpp"
namespace mwmp
{
class ProcessorPlayerCast : public PlayerProcessor
{
PlayerPacketController *playerController;
public:
ProcessorPlayerCast()
{
BPP_INIT(ID_PLAYER_CAST)
playerController = Networking::get().getPlayerPacketController();
}
void Do(PlayerPacket &packet, Player &player) override
{
DEBUG_PRINTF(strPacketID.c_str());
if (!player.creatureStats.mDead)
{
player.sendToLoaded(&packet);
}
}
};
}
#endif //OPENMW_PROCESSORPLAYERCAST_HPP

@ -107,19 +107,19 @@ add_openmw_dir(mwmp/processors BaseClientPacketProcessor PlayerProcessor ObjectP
) )
add_openmw_dir (mwmp/processors/actor ProcessorActorAI ProcessorActorAnimFlags ProcessorActorAnimPlay ProcessorActorAttack add_openmw_dir (mwmp/processors/actor ProcessorActorAI ProcessorActorAnimFlags ProcessorActorAnimPlay ProcessorActorAttack
ProcessorActorAuthority ProcessorActorCellChange ProcessorActorDeath ProcessorActorEquipment ProcessorActorInteraction ProcessorActorAuthority ProcessorActorCast ProcessorActorCellChange ProcessorActorDeath ProcessorActorEquipment
ProcessorActorList ProcessorActorPosition ProcessorActorSpeech ProcessorActorStatsDynamic ProcessorActorTest ProcessorActorList ProcessorActorPosition ProcessorActorSpeech ProcessorActorStatsDynamic ProcessorActorTest
) )
add_openmw_dir (mwmp/processors/player ProcessorChatMessage ProcessorGUIMessageBox ProcessorHandshake add_openmw_dir (mwmp/processors/player ProcessorChatMessage ProcessorGUIMessageBox ProcessorHandshake
ProcessorUserDisconnected ProcessorUserMyID ProcessorGameSettings ProcessorPlayerAnimFlags ProcessorPlayerAnimPlay ProcessorUserDisconnected ProcessorUserMyID ProcessorGameSettings ProcessorPlayerAnimFlags ProcessorPlayerAnimPlay
ProcessorPlayerAttack ProcessorPlayerAttribute ProcessorPlayerBaseInfo ProcessorPlayerBehavior ProcessorPlayerBook ProcessorPlayerAttack ProcessorPlayerAttribute ProcessorPlayerBaseInfo ProcessorPlayerBehavior ProcessorPlayerBook
ProcessorPlayerBounty ProcessorPlayerCellChange ProcessorPlayerCellState ProcessorPlayerCharClass ProcessorPlayerCharGen ProcessorPlayerBounty ProcessorPlayerCast ProcessorPlayerCellChange ProcessorPlayerCellState ProcessorPlayerCharClass
ProcessorPlayerDeath ProcessorPlayerDisposition ProcessorPlayerEquipment ProcessorPlayerFaction ProcessorPlayerInput ProcessorPlayerCharGen ProcessorPlayerDeath ProcessorPlayerDisposition ProcessorPlayerEquipment ProcessorPlayerFaction
ProcessorPlayerInventory ProcessorPlayerItemUse ProcessorPlayerJail ProcessorPlayerJournal ProcessorWorldKillCount ProcessorPlayerInput ProcessorPlayerInventory ProcessorPlayerItemUse ProcessorPlayerJail ProcessorPlayerJournal
ProcessorPlayerLevel ProcessorPlayerMiscellaneous ProcessorPlayerMomentum ProcessorPlayerPosition ProcessorPlayerQuickKeys ProcessorWorldKillCount ProcessorPlayerLevel ProcessorPlayerMiscellaneous ProcessorPlayerMomentum ProcessorPlayerPosition
ProcessorPlayerReputation ProcessorPlayerResurrect ProcessorPlayerShapeshift ProcessorPlayerSkill ProcessorPlayerSpeech ProcessorPlayerQuickKeys ProcessorPlayerReputation ProcessorPlayerResurrect ProcessorPlayerShapeshift ProcessorPlayerSkill
ProcessorPlayerSpellbook ProcessorPlayerStatsDynamic ProcessorPlayerTopic ProcessorPlayerSpeech ProcessorPlayerSpellbook ProcessorPlayerStatsDynamic ProcessorPlayerTopic
) )
add_openmw_dir (mwmp/processors/object BaseObjectProcessor add_openmw_dir (mwmp/processors/object BaseObjectProcessor

@ -1609,7 +1609,21 @@ namespace MWMechanics
mwmp::Attack *dedicatedAttack = MechanicsHelper::getDedicatedAttack(iter->first); mwmp::Attack *dedicatedAttack = MechanicsHelper::getDedicatedAttack(iter->first);
if (dedicatedAttack) if (dedicatedAttack)
iter->second->getCharacterController()->setAttackingOrSpell(dedicatedAttack->pressed); {
bool attackingOrSpellState = false;
if (dedicatedAttack->pressed)
attackingOrSpellState = true;
else
{
mwmp::Cast *dedicatedCast = MechanicsHelper::getDedicatedCast(iter->first);
if (dedicatedCast->pressed)
attackingOrSpellState = true;
}
iter->second->getCharacterController()->setAttackingOrSpell(attackingOrSpellState);
}
/* /*
End of tes3mp addition End of tes3mp addition
*/ */

@ -1166,14 +1166,14 @@ bool CharacterController::updateCreatureState()
If this mPtr belongs to a LocalPlayer or LocalActor, get their Attack and prepare If this mPtr belongs to a LocalPlayer or LocalActor, get their Attack and prepare
it for sending it for sending
*/ */
mwmp::Attack *localAttack = MechanicsHelper::getLocalAttack(mPtr); mwmp::Cast *localCast = MechanicsHelper::getLocalCast(mPtr);
if (localAttack) if (localCast)
{ {
MechanicsHelper::resetAttack(localAttack); MechanicsHelper::resetCast(localCast);
localAttack->type = mwmp::Attack::MAGIC; localCast->type = mwmp::Cast::REGULAR;
localAttack->pressed = true; localCast->pressed = true;
localAttack->shouldSend = true; localCast->shouldSend = true;
} }
/* /*
End of tes3mp addition End of tes3mp addition
@ -1188,7 +1188,7 @@ bool CharacterController::updateCreatureState()
Mark the attack as instant if there is no spellcast animation Mark the attack as instant if there is no spellcast animation
*/ */
if (!mAnimation->hasAnimation("spellcast")) if (!mAnimation->hasAnimation("spellcast"))
localAttack->instant = true; localCast->instant = true;
/* /*
End of tes3mp addition End of tes3mp addition
*/ */
@ -1536,14 +1536,14 @@ bool CharacterController::updateWeaponState(CharacterState& idle)
If this mPtr belongs to a LocalPlayer or LocalActor, get their Attack and prepare If this mPtr belongs to a LocalPlayer or LocalActor, get their Attack and prepare
it for sending it for sending
*/ */
mwmp::Attack *localAttack = MechanicsHelper::getLocalAttack(mPtr); mwmp::Cast *localCast = MechanicsHelper::getLocalCast(mPtr);
if (localAttack) if (localCast)
{ {
MechanicsHelper::resetAttack(localAttack); MechanicsHelper::resetCast(localCast);
localAttack->type = mwmp::Attack::MAGIC; localCast->type = mwmp::Cast::REGULAR;
localAttack->pressed = true; localCast->pressed = true;
localAttack->shouldSend = true; localCast->shouldSend = true;
} }
/* /*
End of tes3mp addition End of tes3mp addition

@ -1059,17 +1059,17 @@ namespace MWMechanics
Make spell casting fail based on the attack success rated determined Make spell casting fail based on the attack success rated determined
in LocalPlayer and LocalActor's updateAttack() in LocalPlayer and LocalActor's updateAttack()
*/ */
mwmp::Attack *localAttack = NULL; mwmp::Cast *localCast = NULL;
mwmp::Attack *dedicatedAttack = MechanicsHelper::getDedicatedAttack(mCaster); mwmp::Cast *dedicatedCast = MechanicsHelper::getDedicatedCast(mCaster);
if (dedicatedAttack) if (dedicatedCast)
dedicatedAttack->pressed = false; dedicatedCast->pressed = false;
else else
localAttack = MechanicsHelper::getLocalAttack(mCaster); localCast = MechanicsHelper::getLocalCast(mCaster);
// Check success // Check success
if ((localAttack && localAttack->success == false) || if ((localCast && localCast->success == false) ||
(dedicatedAttack && dedicatedAttack->success == false)) (dedicatedCast && dedicatedCast->success == false))
{ {
if (mCaster == getPlayer()) if (mCaster == getPlayer())
MWBase::Environment::get().getWindowManager()->messageBox("#{sMagicSkillFail}"); MWBase::Environment::get().getWindowManager()->messageBox("#{sMagicSkillFail}");

@ -39,6 +39,7 @@ void ActorList::reset()
equipmentActors.clear(); equipmentActors.clear();
aiActors.clear(); aiActors.clear();
attackActors.clear(); attackActors.clear();
castActors.clear();
cellChangeActors.clear(); cellChangeActors.clear();
guid = mwmp::Main::get().getNetworking()->getLocalPlayer()->guid; guid = mwmp::Main::get().getNetworking()->getLocalPlayer()->guid;
} }
@ -118,6 +119,11 @@ void ActorList::addAttackActor(BaseActor baseActor)
attackActors.push_back(baseActor); attackActors.push_back(baseActor);
} }
void ActorList::addCastActor(BaseActor baseActor)
{
castActors.push_back(baseActor);
}
void ActorList::addCellChangeActor(BaseActor baseActor) void ActorList::addCellChangeActor(BaseActor baseActor)
{ {
cellChangeActors.push_back(baseActor); cellChangeActors.push_back(baseActor);
@ -213,6 +219,16 @@ void ActorList::sendAttackActors()
} }
} }
void ActorList::sendCastActors()
{
if (castActors.size() > 0)
{
baseActors = castActors;
Main::get().getNetworking()->getActorPacket(ID_ACTOR_CAST)->setActorList(this);
Main::get().getNetworking()->getActorPacket(ID_ACTOR_CAST)->Send();
}
}
void ActorList::sendCellChangeActors() void ActorList::sendCellChangeActors()
{ {
if (cellChangeActors.size() > 0) if (cellChangeActors.size() > 0)

@ -30,6 +30,7 @@ namespace mwmp
void addAiActor(BaseActor baseActor); void addAiActor(BaseActor baseActor);
void addAiActor(const MWWorld::Ptr& actorPtr, const MWWorld::Ptr& targetPtr, unsigned int aiAction); void addAiActor(const MWWorld::Ptr& actorPtr, const MWWorld::Ptr& targetPtr, unsigned int aiAction);
void addAttackActor(BaseActor baseActor); void addAttackActor(BaseActor baseActor);
void addCastActor(BaseActor baseActor);
void addCellChangeActor(BaseActor baseActor); void addCellChangeActor(BaseActor baseActor);
void sendPositionActors(); void sendPositionActors();
@ -41,6 +42,7 @@ namespace mwmp
void sendEquipmentActors(); void sendEquipmentActors();
void sendAiActors(); void sendAiActors();
void sendAttackActors(); void sendAttackActors();
void sendCastActors();
void sendCellChangeActors(); void sendCellChangeActors();
void sendActorsInCell(MWWorld::CellStore* cellStore); void sendActorsInCell(MWWorld::CellStore* cellStore);
@ -57,6 +59,7 @@ namespace mwmp
std::vector<BaseActor> equipmentActors; std::vector<BaseActor> equipmentActors;
std::vector<BaseActor> aiActors; std::vector<BaseActor> aiActors;
std::vector<BaseActor> attackActors; std::vector<BaseActor> attackActors;
std::vector<BaseActor> castActors;
std::vector<BaseActor> cellChangeActors; std::vector<BaseActor> cellChangeActors;
}; };
} }

@ -99,6 +99,7 @@ void Cell::updateLocal(bool forceUpdate)
actorList->sendStatsDynamicActors(); actorList->sendStatsDynamicActors();
actorList->sendEquipmentActors(); actorList->sendEquipmentActors();
actorList->sendAttackActors(); actorList->sendAttackActors();
actorList->sendCastActors();
actorList->sendCellChangeActors(); actorList->sendCellChangeActors();
} }
@ -314,14 +315,35 @@ void Cell::readAttack(ActorList& actorList)
actor->drawState = MWMechanics::DrawState_::DrawState_Weapon; actor->drawState = MWMechanics::DrawState_::DrawState_Weapon;
actor->setAnimFlags(); actor->setAnimFlags();
} }
else if (actor->drawState != MWMechanics::DrawState_::DrawState_Spell &&
(actor->attack.type == mwmp::Attack::MAGIC || actor->attack.type == mwmp::Attack::ITEM_MAGIC)) MechanicsHelper::processAttack(actor->attack, actor->getPtr());
}
}
}
void Cell::readCast(ActorList& actorList)
{
for (const auto &baseActor : actorList.baseActors)
{
std::string mapIndex = Main::get().getCellController()->generateMapIndex(baseActor);
if (dedicatedActors.count(mapIndex) > 0)
{
LOG_MESSAGE_SIMPLE(TimedLog::LOG_INFO, "Reading ActorCast about %s", mapIndex.c_str());
DedicatedActor *actor = dedicatedActors[mapIndex];
actor->cast = baseActor.cast;
// Set the correct drawState here if we've somehow we've missed a previous
// AnimFlags packet
if (actor->drawState != MWMechanics::DrawState_::DrawState_Spell &&
(actor->attack.type == mwmp::Cast::REGULAR || actor->cast.type == mwmp::Cast::ITEM))
{ {
actor->drawState = MWMechanics::DrawState_::DrawState_Spell; actor->drawState = MWMechanics::DrawState_::DrawState_Spell;
actor->setAnimFlags(); actor->setAnimFlags();
} }
MechanicsHelper::processAttack(actor->attack, actor->getPtr()); MechanicsHelper::processCast(actor->cast, actor->getPtr());
} }
} }
} }

@ -26,6 +26,7 @@ namespace mwmp
void readSpeech(ActorList& actorList); void readSpeech(ActorList& actorList);
void readAi(ActorList& actorList); void readAi(ActorList& actorList);
void readAttack(ActorList& actorList); void readAttack(ActorList& actorList);
void readCast(ActorList& actorList);
void readCellChange(ActorList& actorList); void readCellChange(ActorList& actorList);
void initializeLocalActor(const MWWorld::Ptr& ptr); void initializeLocalActor(const MWWorld::Ptr& ptr);

@ -178,6 +178,17 @@ void CellController::readAttack(ActorList& actorList)
cellsInitialized[mapIndex]->readAttack(actorList); cellsInitialized[mapIndex]->readAttack(actorList);
} }
void CellController::readCast(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]->readCast(actorList);
}
void CellController::readCellChange(ActorList& actorList) void CellController::readCellChange(ActorList& actorList)
{ {
std::string mapIndex = actorList.cell.getDescription(); std::string mapIndex = actorList.cell.getDescription();

@ -29,6 +29,7 @@ namespace mwmp
void readSpeech(mwmp::ActorList& actorList); void readSpeech(mwmp::ActorList& actorList);
void readAi(mwmp::ActorList& actorList); void readAi(mwmp::ActorList& actorList);
void readAttack(mwmp::ActorList& actorList); void readAttack(mwmp::ActorList& actorList);
void readCast(mwmp::ActorList& actorList);
void readCellChange(mwmp::ActorList& actorList); void readCellChange(mwmp::ActorList& actorList);
void setLocalActorRecord(std::string actorIndex, std::string cellIndex); void setLocalActorRecord(std::string actorIndex, std::string cellIndex);

@ -45,6 +45,7 @@ DedicatedActor::DedicatedActor()
hasChangedCell = true; hasChangedCell = true;
attack.pressed = false; attack.pressed = false;
cast.pressed = false;
} }
DedicatedActor::~DedicatedActor() DedicatedActor::~DedicatedActor()

@ -44,7 +44,8 @@ using namespace std;
DedicatedPlayer::DedicatedPlayer(RakNet::RakNetGUID guid) : BasePlayer(guid) DedicatedPlayer::DedicatedPlayer(RakNet::RakNetGUID guid) : BasePlayer(guid)
{ {
reference = 0; reference = 0;
attack.pressed = 0; attack.pressed = false;
cast.pressed = false;
creatureStats.mDead = false; creatureStats.mDead = false;
// Give this new character a temporary high fatigue so it doesn't spawn on // Give this new character a temporary high fatigue so it doesn't spawn on
@ -65,6 +66,7 @@ DedicatedPlayer::DedicatedPlayer(RakNet::RakNetGUID guid) : BasePlayer(guid)
hasFinishedInitialTeleportation = false; hasFinishedInitialTeleportation = false;
} }
DedicatedPlayer::~DedicatedPlayer() DedicatedPlayer::~DedicatedPlayer()
{ {

@ -36,6 +36,12 @@ LocalActor::LocalActor()
attack.type = Attack::MELEE; attack.type = Attack::MELEE;
attack.shouldSend = false; attack.shouldSend = false;
attack.instant = false; attack.instant = false;
attack.pressed = false;
cast.type = Cast::REGULAR;
cast.shouldSend = false;
cast.instant = false;
cast.pressed = false;
killer.isPlayer = false; killer.isPlayer = false;
killer.refId = ""; killer.refId = "";
@ -60,7 +66,7 @@ void LocalActor::update(bool forceUpdate)
updateAnimFlags(forceUpdate); updateAnimFlags(forceUpdate);
updateAnimPlay(); updateAnimPlay();
updateSpeech(); updateSpeech();
updateAttack(); updateAttackOrCast();
} }
hasSentData = true; hasSentData = true;
@ -250,21 +256,26 @@ void LocalActor::updateEquipment(bool forceUpdate)
} }
} }
void LocalActor::updateAttack() void LocalActor::updateAttackOrCast()
{ {
if (attack.shouldSend) if (attack.shouldSend)
{ {
if (attack.type == Attack::MAGIC) mwmp::Main::get().getNetworking()->getActorList()->addAttackActor(*this);
attack.shouldSend = false;
}
else if (cast.shouldSend)
{
if (cast.type == Cast::REGULAR)
{ {
MWMechanics::CreatureStats &attackerStats = ptr.getClass().getCreatureStats(ptr); MWMechanics::CreatureStats &casterStats = ptr.getClass().getCreatureStats(ptr);
attack.spellId = attackerStats.getSpells().getSelectedSpell(); cast.spellId = casterStats.getSpells().getSelectedSpell();
if (attack.pressed) if (cast.pressed)
attack.success = MechanicsHelper::getSpellSuccess(attack.spellId, ptr); cast.success = MechanicsHelper::getSpellSuccess(cast.spellId, ptr);
} }
mwmp::Main::get().getNetworking()->getActorList()->addAttackActor(*this); mwmp::Main::get().getNetworking()->getActorList()->addCastActor(*this);
attack.shouldSend = false; cast.shouldSend = false;
} }
} }

@ -23,7 +23,7 @@ namespace mwmp
void updateSpeech(); void updateSpeech();
void updateStatsDynamic(bool forceUpdate); void updateStatsDynamic(bool forceUpdate);
void updateEquipment(bool forceUpdate); void updateEquipment(bool forceUpdate);
void updateAttack(); void updateAttackOrCast();
MWWorld::Ptr getPtr(); MWWorld::Ptr getPtr();
void setPtr(const MWWorld::Ptr& newPtr); void setPtr(const MWWorld::Ptr& newPtr);

@ -65,6 +65,12 @@ LocalPlayer::LocalPlayer()
ignoreJailSkillIncreases = false; ignoreJailSkillIncreases = false;
attack.shouldSend = false; attack.shouldSend = false;
attack.instant = false;
attack.pressed = false;
cast.shouldSend = false;
cast.instant = false;
cast.pressed = false;
killer.isPlayer = false; killer.isPlayer = false;
killer.refId = ""; killer.refId = "";
@ -110,7 +116,7 @@ void LocalPlayer::update()
updateCell(); updateCell();
updatePosition(); updatePosition();
updateAnimFlags(); updateAnimFlags();
updateAttack(); updateAttackOrCast();
updateEquipment(); updateEquipment();
updateStatsDynamic(); updateStatsDynamic();
updateAttributes(); updateAttributes();
@ -592,22 +598,29 @@ void LocalPlayer::updateInventory(bool forceUpdate)
sendInventory(); sendInventory();
} }
void LocalPlayer::updateAttack() void LocalPlayer::updateAttackOrCast()
{ {
if (attack.shouldSend) if (attack.shouldSend)
{ {
if (attack.type == Attack::MAGIC) getNetworking()->getPlayerPacket(ID_PLAYER_ATTACK)->setPlayer(this);
getNetworking()->getPlayerPacket(ID_PLAYER_ATTACK)->Send();
attack.shouldSend = false;
}
else if (cast.shouldSend)
{
if (cast.type == Cast::REGULAR)
{ {
attack.spellId = MWBase::Environment::get().getWindowManager()->getSelectedSpell(); cast.spellId = MWBase::Environment::get().getWindowManager()->getSelectedSpell();
if (attack.pressed) if (cast.pressed)
attack.success = MechanicsHelper::getSpellSuccess(attack.spellId, getPlayerPtr()); cast.success = MechanicsHelper::getSpellSuccess(cast.spellId, getPlayerPtr());
} }
getNetworking()->getPlayerPacket(ID_PLAYER_ATTACK)->setPlayer(this); getNetworking()->getPlayerPacket(ID_PLAYER_CAST)->setPlayer(this);
getNetworking()->getPlayerPacket(ID_PLAYER_ATTACK)->Send(); getNetworking()->getPlayerPacket(ID_PLAYER_CAST)->Send();
attack.shouldSend = false; cast.shouldSend = false;
} }
} }

@ -38,7 +38,7 @@ namespace mwmp
void updateCell(bool forceUpdate = false); void updateCell(bool forceUpdate = false);
void updateEquipment(bool forceUpdate = false); void updateEquipment(bool forceUpdate = false);
void updateInventory(bool forceUpdate = false); void updateInventory(bool forceUpdate = false);
void updateAttack(); void updateAttackOrCast();
void updateAnimFlags(bool forceUpdate = false); void updateAnimFlags(bool forceUpdate = false);
void addItems(); void addItems();

@ -115,6 +115,26 @@ Attack *MechanicsHelper::getDedicatedAttack(const MWWorld::Ptr& ptr)
return nullptr; return nullptr;
} }
Cast *MechanicsHelper::getLocalCast(const MWWorld::Ptr& ptr)
{
if (ptr == MWBase::Environment::get().getWorld()->getPlayerPtr())
return &mwmp::Main::get().getLocalPlayer()->cast;
else if (mwmp::Main::get().getCellController()->isLocalActor(ptr))
return &mwmp::Main::get().getCellController()->getLocalActor(ptr)->cast;
return nullptr;
}
Cast *MechanicsHelper::getDedicatedCast(const MWWorld::Ptr& ptr)
{
if (mwmp::PlayerList::isDedicatedPlayer(ptr))
return &mwmp::PlayerList::getPlayer(ptr)->cast;
else if (mwmp::Main::get().getCellController()->isDedicatedActor(ptr))
return &mwmp::Main::get().getCellController()->getDedicatedActor(ptr)->cast;
return nullptr;
}
MWWorld::Ptr MechanicsHelper::getPlayerPtr(const Target& target) MWWorld::Ptr MechanicsHelper::getPlayerPtr(const Target& target)
{ {
if (target.guid == mwmp::Main::get().getLocalPlayer()->guid) if (target.guid == mwmp::Main::get().getLocalPlayer()->guid)
@ -233,6 +253,16 @@ void MechanicsHelper::resetAttack(Attack* attack)
attack->target.mpNum = 0; attack->target.mpNum = 0;
} }
void MechanicsHelper::resetCast(Cast* cast)
{
cast->isHit = false;
cast->success = false;
cast->target.guid = RakNet::RakNetGUID();
cast->target.refId.clear();
cast->target.refNum = 0;
cast->target.mpNum = 0;
}
bool MechanicsHelper::getSpellSuccess(std::string spellId, const MWWorld::Ptr& caster) bool MechanicsHelper::getSpellSuccess(std::string spellId, const MWWorld::Ptr& caster)
{ {
return Misc::Rng::roll0to99() < MWMechanics::getSpellSuccessChance(spellId, caster, nullptr, true, false); return Misc::Rng::roll0to99() < MWMechanics::getSpellSuccessChance(spellId, caster, nullptr, true, false);
@ -272,7 +302,7 @@ void MechanicsHelper::processAttack(Attack attack, const MWWorld::Ptr& attacker)
victim = controller->getDedicatedActor(attack.target.refNum, attack.target.mpNum)->getPtr(); victim = controller->getDedicatedActor(attack.target.refNum, attack.target.mpNum)->getPtr();
} }
if (attack.isHit && (attack.type == attack.MELEE || attack.type == attack.RANGED)) if (attack.isHit)
{ {
bool isRanged = attack.type == attack.RANGED; bool isRanged = attack.type == attack.RANGED;
@ -385,38 +415,71 @@ void MechanicsHelper::processAttack(Attack attack, const MWWorld::Ptr& attacker)
inventoryStore.remove(ammoPtr, 1, attacker); inventoryStore.remove(ammoPtr, 1, attacker);
} }
} }
else if (attack.type == attack.MAGIC) }
void MechanicsHelper::processCast(Cast cast, const MWWorld::Ptr& caster)
{
LOG_MESSAGE_SIMPLE(TimedLog::LOG_VERBOSE, "Processing cast from %s of type %i",
caster.getClass().getName(caster).c_str(), cast.type);
if (!cast.pressed)
{
LOG_APPEND(TimedLog::LOG_VERBOSE, "- success: %s", cast.success ? "true" : "false");
}
LOG_APPEND(TimedLog::LOG_VERBOSE, "- pressed: %s", cast.pressed ? "true" : "false");
MWMechanics::CreatureStats &casterStats = caster.getClass().getCreatureStats(caster);
MWWorld::Ptr victim;
if (cast.target.isPlayer)
{
if (cast.target.guid == mwmp::Main::get().getLocalPlayer()->guid)
victim = MWBase::Environment::get().getWorld()->getPlayerPtr();
else if (PlayerList::getPlayer(cast.target.guid) != nullptr)
victim = PlayerList::getPlayer(cast.target.guid)->getPtr();
}
else
{
auto controller = mwmp::Main::get().getCellController();
if (controller->isLocalActor(cast.target.refNum, cast.target.mpNum))
victim = controller->getLocalActor(cast.target.refNum, cast.target.mpNum)->getPtr();
else if (controller->isDedicatedActor(cast.target.refNum, cast.target.mpNum))
victim = controller->getDedicatedActor(cast.target.refNum, cast.target.mpNum)->getPtr();
}
if (cast.type == cast.REGULAR)
{ {
attackerStats.getSpells().setSelectedSpell(attack.spellId); casterStats.getSpells().setSelectedSpell(cast.spellId);
if (attack.instant) if (cast.instant)
{ {
MWBase::Environment::get().getWorld()->castSpell(attacker); MWBase::Environment::get().getWorld()->castSpell(caster);
attack.instant = false; cast.instant = false;
} }
LOG_APPEND(TimedLog::LOG_VERBOSE, "- spellId: %s", attack.spellId.c_str()); LOG_APPEND(TimedLog::LOG_VERBOSE, "- spellId: %s", cast.spellId.c_str());
} }
else if (attack.type == attack.ITEM_MAGIC) else if (cast.type == cast.ITEM)
{ {
attackerStats.getSpells().setSelectedSpell(""); casterStats.getSpells().setSelectedSpell("");
MWWorld::InventoryStore& inventoryStore = attacker.getClass().getInventoryStore(attacker); MWWorld::InventoryStore& inventoryStore = caster.getClass().getInventoryStore(caster);
MWWorld::ContainerStoreIterator it = inventoryStore.begin(); MWWorld::ContainerStoreIterator it = inventoryStore.begin();
for (; it != inventoryStore.end(); ++it) for (; it != inventoryStore.end(); ++it)
{ {
if (Misc::StringUtils::ciEqual(it->getCellRef().getRefId(), attack.itemId)) if (Misc::StringUtils::ciEqual(it->getCellRef().getRefId(), cast.itemId))
break; break;
} }
// Add the item if it's missing // Add the item if it's missing
if (it == inventoryStore.end()) if (it == inventoryStore.end())
it = attacker.getClass().getContainerStore(attacker).add(attack.itemId, 1, attacker); it = caster.getClass().getContainerStore(caster).add(cast.itemId, 1, caster);
inventoryStore.setSelectedEnchantItem(it); inventoryStore.setSelectedEnchantItem(it);
LOG_APPEND(TimedLog::LOG_VERBOSE, "- itemId: %s", attack.itemId.c_str()); LOG_APPEND(TimedLog::LOG_VERBOSE, "- itemId: %s", cast.itemId.c_str());
MWBase::Environment::get().getWorld()->castSpell(attacker); MWBase::Environment::get().getWorld()->castSpell(caster);
inventoryStore.setSelectedEnchantItem(inventoryStore.end()); inventoryStore.setSelectedEnchantItem(inventoryStore.end());
} }
} }

@ -20,6 +20,9 @@ namespace MechanicsHelper
mwmp::Attack *getLocalAttack(const MWWorld::Ptr& ptr); mwmp::Attack *getLocalAttack(const MWWorld::Ptr& ptr);
mwmp::Attack *getDedicatedAttack(const MWWorld::Ptr& ptr); mwmp::Attack *getDedicatedAttack(const MWWorld::Ptr& ptr);
mwmp::Cast *getLocalCast(const MWWorld::Ptr& ptr);
mwmp::Cast *getDedicatedCast(const MWWorld::Ptr& ptr);
MWWorld::Ptr getPlayerPtr(const mwmp::Target& target); MWWorld::Ptr getPlayerPtr(const mwmp::Target& target);
mwmp::Item getItem(const MWWorld::Ptr& itemPtr, int count); mwmp::Item getItem(const MWWorld::Ptr& itemPtr, int count);
@ -29,10 +32,12 @@ namespace MechanicsHelper
void assignAttackTarget(mwmp::Attack* attack, const MWWorld::Ptr& target); void assignAttackTarget(mwmp::Attack* attack, const MWWorld::Ptr& target);
void resetAttack(mwmp::Attack* attack); void resetAttack(mwmp::Attack* attack);
void resetCast(mwmp::Cast* cast);
bool getSpellSuccess(std::string spellId, const MWWorld::Ptr& caster); bool getSpellSuccess(std::string spellId, const MWWorld::Ptr& caster);
void processAttack(mwmp::Attack attack, const MWWorld::Ptr& attacker); void processAttack(mwmp::Attack attack, const MWWorld::Ptr& attacker);
void processCast(mwmp::Cast cast, const MWWorld::Ptr& caster);
bool doesEffectListContainEffect(const ESM::EffectList& effectList, short effectId, short attributeId = -1, short skillId = -1); bool doesEffectListContainEffect(const ESM::EffectList& effectList, short effectId, short attributeId = -1, short skillId = -1);
void unequipItemsByEffect(const MWWorld::Ptr& ptr, short enchantmentType, short effectId, short attributeId = -1, short skillId = -1); void unequipItemsByEffect(const MWWorld::Ptr& ptr, short enchantmentType, short effectId, short attributeId = -1, short skillId = -1);

@ -14,6 +14,7 @@
#include "player/ProcessorPlayerBehavior.hpp" #include "player/ProcessorPlayerBehavior.hpp"
#include "player/ProcessorPlayerBook.hpp" #include "player/ProcessorPlayerBook.hpp"
#include "player/ProcessorPlayerBounty.hpp" #include "player/ProcessorPlayerBounty.hpp"
#include "player/ProcessorPlayerCast.hpp"
#include "player/ProcessorPlayerCellChange.hpp" #include "player/ProcessorPlayerCellChange.hpp"
#include "player/ProcessorPlayerCellState.hpp" #include "player/ProcessorPlayerCellState.hpp"
#include "player/ProcessorPlayerCharClass.hpp" #include "player/ProcessorPlayerCharClass.hpp"
@ -77,10 +78,10 @@
#include "actor/ProcessorActorAnimPlay.hpp" #include "actor/ProcessorActorAnimPlay.hpp"
#include "actor/ProcessorActorAttack.hpp" #include "actor/ProcessorActorAttack.hpp"
#include "actor/ProcessorActorAuthority.hpp" #include "actor/ProcessorActorAuthority.hpp"
#include "actor/ProcessorActorCast.hpp"
#include "actor/ProcessorActorCellChange.hpp" #include "actor/ProcessorActorCellChange.hpp"
#include "actor/ProcessorActorDeath.hpp" #include "actor/ProcessorActorDeath.hpp"
#include "actor/ProcessorActorEquipment.hpp" #include "actor/ProcessorActorEquipment.hpp"
#include "actor/ProcessorActorInteraction.hpp"
#include "actor/ProcessorActorList.hpp" #include "actor/ProcessorActorList.hpp"
#include "actor/ProcessorActorPosition.hpp" #include "actor/ProcessorActorPosition.hpp"
#include "actor/ProcessorActorSpeech.hpp" #include "actor/ProcessorActorSpeech.hpp"
@ -114,6 +115,7 @@ void ProcessorInitializer()
PlayerProcessor::AddProcessor(new ProcessorPlayerBehavior()); PlayerProcessor::AddProcessor(new ProcessorPlayerBehavior());
PlayerProcessor::AddProcessor(new ProcessorPlayerBook()); PlayerProcessor::AddProcessor(new ProcessorPlayerBook());
PlayerProcessor::AddProcessor(new ProcessorPlayerBounty()); PlayerProcessor::AddProcessor(new ProcessorPlayerBounty());
PlayerProcessor::AddProcessor(new ProcessorPlayerCast());
PlayerProcessor::AddProcessor(new ProcessorPlayerCellChange()); PlayerProcessor::AddProcessor(new ProcessorPlayerCellChange());
PlayerProcessor::AddProcessor(new ProcessorPlayerCellState()); PlayerProcessor::AddProcessor(new ProcessorPlayerCellState());
PlayerProcessor::AddProcessor(new ProcessorPlayerCharClass()); PlayerProcessor::AddProcessor(new ProcessorPlayerCharClass());
@ -175,10 +177,10 @@ void ProcessorInitializer()
ActorProcessor::AddProcessor(new ProcessorActorAnimPlay()); ActorProcessor::AddProcessor(new ProcessorActorAnimPlay());
ActorProcessor::AddProcessor(new ProcessorActorAttack()); ActorProcessor::AddProcessor(new ProcessorActorAttack());
ActorProcessor::AddProcessor(new ProcessorActorAuthority()); ActorProcessor::AddProcessor(new ProcessorActorAuthority());
ActorProcessor::AddProcessor(new ProcessorActorCast());
ActorProcessor::AddProcessor(new ProcessorActorCellChange()); ActorProcessor::AddProcessor(new ProcessorActorCellChange());
ActorProcessor::AddProcessor(new ProcessorActorDeath()); ActorProcessor::AddProcessor(new ProcessorActorDeath());
ActorProcessor::AddProcessor(new ProcessorActorEquipment()); ActorProcessor::AddProcessor(new ProcessorActorEquipment());
ActorProcessor::AddProcessor(new ProcessorActorInteraction());
ActorProcessor::AddProcessor(new ProcessorActorList()); ActorProcessor::AddProcessor(new ProcessorActorList());
ActorProcessor::AddProcessor(new ProcessorActorPosition()); ActorProcessor::AddProcessor(new ProcessorActorPosition());
ActorProcessor::AddProcessor(new ProcessorActorSpeech()); ActorProcessor::AddProcessor(new ProcessorActorSpeech());

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

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

@ -0,0 +1,27 @@
#ifndef OPENMW_PROCESSORPLAYERCAST_HPP
#define OPENMW_PROCESSORPLAYERCAST_HPP
#include "apps/openmw/mwmp/Main.hpp"
#include "../PlayerProcessor.hpp"
#include "apps/openmw/mwmp/MechanicsHelper.hpp"
namespace mwmp
{
class ProcessorPlayerCast : public PlayerProcessor
{
public:
ProcessorPlayerCast()
{
BPP_INIT(ID_PLAYER_CAST)
}
virtual void Do(PlayerPacket &packet, BasePlayer *player)
{
if (player != 0)
MechanicsHelper::processCast(player->cast, static_cast<DedicatedPlayer*>(player)->getPtr());
}
};
}
#endif //OPENMW_PROCESSORPLAYERCAST_HPP

@ -3474,21 +3474,21 @@ namespace MWWorld
/* /*
Start of tes3mp change (minor) Start of tes3mp change (minor)
If this actor is a LocalPlayer or LocalActor, get their Attack and prepare If this actor is a LocalPlayer or LocalActor, get their Cast and prepare
it for sending it for sending
Set the attack details before going through with the casting, in case it's Set the cast details before going forward, in case it's a one use item that
a one use item that would get removed through the casting (like a scroll) will get removed (like a scroll)
*/ */
{ {
mwmp::Attack *localAttack = MechanicsHelper::getLocalAttack(actor); mwmp::Cast *localCast = MechanicsHelper::getLocalCast(actor);
if (localAttack) if (localCast)
{ {
MechanicsHelper::resetAttack(localAttack); MechanicsHelper::resetCast(localCast);
localAttack->type = mwmp::Attack::ITEM_MAGIC; localCast->type = mwmp::Cast::ITEM;
localAttack->itemId = inv.getSelectedEnchantItem()->getCellRef().getRefId(); localCast->itemId = inv.getSelectedEnchantItem()->getCellRef().getRefId();
localAttack->shouldSend = true; localCast->shouldSend = true;
} }
cast.cast(*inv.getSelectedEnchantItem()); cast.cast(*inv.getSelectedEnchantItem());

@ -174,7 +174,7 @@ add_component_dir (openmw-mp/Packets/Actor
ActorPacket ActorPacket
PacketActorList PacketActorAuthority PacketActorTest PacketActorAI PacketActorAnimFlags PacketActorAnimPlay PacketActorList PacketActorAuthority PacketActorTest PacketActorAI PacketActorAnimFlags PacketActorAnimPlay
PacketActorAttack PacketActorCellChange PacketActorDeath PacketActorEquipment PacketActorInteraction PacketActorPosition PacketActorAttack PacketActorCast PacketActorCellChange PacketActorDeath PacketActorEquipment PacketActorPosition
PacketActorSpeech PacketActorStatsDynamic PacketActorSpeech PacketActorStatsDynamic
) )
@ -185,12 +185,12 @@ add_component_dir (openmw-mp/Packets/Player
PacketPlayerBaseInfo PacketPlayerCharGen PacketPlayerActiveSkills PacketPlayerAnimFlags PacketPlayerAnimPlay PacketPlayerBaseInfo PacketPlayerCharGen PacketPlayerActiveSkills PacketPlayerAnimFlags PacketPlayerAnimPlay
PacketPlayerAttack PacketPlayerAttribute PacketPlayerBehavior PacketPlayerBook PacketPlayerBounty PacketPlayerAttack PacketPlayerAttribute PacketPlayerBehavior PacketPlayerBook PacketPlayerBounty
PacketPlayerCellChange PacketPlayerCellState PacketPlayerClass PacketPlayerDeath PacketPlayerEquipment PacketPlayerCast PacketPlayerCellChange PacketPlayerCellState PacketPlayerClass PacketPlayerDeath
PacketPlayerFaction PacketPlayerInput PacketPlayerInventory PacketPlayerItemUse PacketPlayerJail PacketPlayerEquipment PacketPlayerFaction PacketPlayerInput PacketPlayerInventory PacketPlayerItemUse
PacketPlayerJournal PacketWorldKillCount PacketPlayerLevel PacketPlayerMiscellaneous PacketPlayerMomentum PacketPlayerJail PacketPlayerJournal PacketWorldKillCount PacketPlayerLevel PacketPlayerMiscellaneous
PacketPlayerPosition PacketPlayerQuickKeys PacketPlayerReputation PacketPlayerRest PacketPlayerResurrect PacketPlayerMomentum PacketPlayerPosition PacketPlayerQuickKeys PacketPlayerReputation PacketPlayerRest
PacketPlayerShapeshift PacketPlayerSkill PacketPlayerSpeech PacketPlayerSpellbook PacketPlayerStatsDynamic PacketPlayerResurrect PacketPlayerShapeshift PacketPlayerSkill PacketPlayerSpeech PacketPlayerSpellbook
PacketPlayerTopic PacketPlayerStatsDynamic PacketPlayerTopic
) )
add_component_dir (openmw-mp/Packets/Object add_component_dir (openmw-mp/Packets/Object

@ -38,6 +38,7 @@ namespace mwmp
Animation animation; Animation animation;
Attack attack; Attack attack;
Cast cast;
Target killer; Target killer;

@ -294,6 +294,7 @@ namespace mwmp
ESM::Class charClass; ESM::Class charClass;
Item equipmentItems[19]; Item equipmentItems[19];
Attack attack; Attack attack;
Cast cast;
std::string birthsign; std::string birthsign;
std::string chatMessage; std::string chatMessage;
CharGenState charGenState; CharGenState charGenState;

@ -65,19 +65,13 @@ namespace mwmp
Target target; Target target;
char type; // 0 - melee, 1 - magic, 2 - item magic, 3 - throwable char type; // 0 - melee, 1 - ranged
enum TYPE enum TYPE
{ {
MELEE = 0, MELEE = 0,
RANGED, RANGED
MAGIC,
ITEM_MAGIC,
THROWABLE
}; };
std::string spellId; // id of spell (e.g. "fireball")
std::string itemId;
std::string rangedWeaponId; std::string rangedWeaponId;
std::string rangedAmmoId; std::string rangedAmmoId;
@ -99,6 +93,32 @@ namespace mwmp
bool shouldSend; bool shouldSend;
}; };
class Cast
{
public:
Target target;
char type; // 0 - regular magic, 1 - item magic
enum TYPE
{
REGULAR = 0,
ITEM
};
std::string spellId; // id of spell (e.g. "fireball")
std::string itemId;
ESM::Position hitPosition;
bool isHit;
bool success;
bool pressed;
bool instant;
bool shouldSend;
};
struct Animation struct Animation
{ {
std::string groupname; std::string groupname;

@ -5,10 +5,10 @@
#include "../Packets/Actor/PacketActorAnimFlags.hpp" #include "../Packets/Actor/PacketActorAnimFlags.hpp"
#include "../Packets/Actor/PacketActorAnimPlay.hpp" #include "../Packets/Actor/PacketActorAnimPlay.hpp"
#include "../Packets/Actor/PacketActorAttack.hpp" #include "../Packets/Actor/PacketActorAttack.hpp"
#include "../Packets/Actor/PacketActorCast.hpp"
#include "../Packets/Actor/PacketActorCellChange.hpp" #include "../Packets/Actor/PacketActorCellChange.hpp"
#include "../Packets/Actor/PacketActorDeath.hpp" #include "../Packets/Actor/PacketActorDeath.hpp"
#include "../Packets/Actor/PacketActorEquipment.hpp" #include "../Packets/Actor/PacketActorEquipment.hpp"
#include "../Packets/Actor/PacketActorInteraction.hpp"
#include "../Packets/Actor/PacketActorPosition.hpp" #include "../Packets/Actor/PacketActorPosition.hpp"
#include "../Packets/Actor/PacketActorStatsDynamic.hpp" #include "../Packets/Actor/PacketActorStatsDynamic.hpp"
#include "../Packets/Actor/PacketActorSpeech.hpp" #include "../Packets/Actor/PacketActorSpeech.hpp"
@ -33,10 +33,10 @@ mwmp::ActorPacketController::ActorPacketController(RakNet::RakPeerInterface *pee
AddPacket<PacketActorAnimFlags>(&packets, peer); AddPacket<PacketActorAnimFlags>(&packets, peer);
AddPacket<PacketActorAnimPlay>(&packets, peer); AddPacket<PacketActorAnimPlay>(&packets, peer);
AddPacket<PacketActorAttack>(&packets, peer); AddPacket<PacketActorAttack>(&packets, peer);
AddPacket<PacketActorCast>(&packets, peer);
AddPacket<PacketActorCellChange>(&packets, peer); AddPacket<PacketActorCellChange>(&packets, peer);
AddPacket<PacketActorDeath>(&packets, peer); AddPacket<PacketActorDeath>(&packets, peer);
AddPacket<PacketActorEquipment>(&packets, peer); AddPacket<PacketActorEquipment>(&packets, peer);
AddPacket<PacketActorInteraction>(&packets, peer);
AddPacket<PacketActorPosition>(&packets, peer); AddPacket<PacketActorPosition>(&packets, peer);
AddPacket<PacketActorSpeech>(&packets, peer); AddPacket<PacketActorSpeech>(&packets, peer);
AddPacket<PacketActorStatsDynamic>(&packets, peer); AddPacket<PacketActorStatsDynamic>(&packets, peer);

@ -14,6 +14,7 @@
#include "../Packets/Player/PacketPlayerBehavior.hpp" #include "../Packets/Player/PacketPlayerBehavior.hpp"
#include "../Packets/Player/PacketPlayerBook.hpp" #include "../Packets/Player/PacketPlayerBook.hpp"
#include "../Packets/Player/PacketPlayerBounty.hpp" #include "../Packets/Player/PacketPlayerBounty.hpp"
#include "../Packets/Player/PacketPlayerCast.hpp"
#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"
@ -69,6 +70,7 @@ mwmp::PlayerPacketController::PlayerPacketController(RakNet::RakPeerInterface *p
AddPacket<PacketPlayerBehavior>(&packets, peer); AddPacket<PacketPlayerBehavior>(&packets, peer);
AddPacket<PacketPlayerBook>(&packets, peer); AddPacket<PacketPlayerBook>(&packets, peer);
AddPacket<PacketPlayerBounty>(&packets, peer); AddPacket<PacketPlayerBounty>(&packets, peer);
AddPacket<PacketPlayerCast>(&packets, peer);
AddPacket<PacketPlayerCellChange>(&packets, peer); AddPacket<PacketPlayerCellChange>(&packets, peer);
AddPacket<PacketPlayerCellState>(&packets, peer); AddPacket<PacketPlayerCellState>(&packets, peer);
AddPacket<PacketPlayerCharGen>(&packets, peer); AddPacket<PacketPlayerCharGen>(&packets, peer);

@ -66,7 +66,7 @@ enum GameMessages
ID_ACTOR_CELL_CHANGE, ID_ACTOR_CELL_CHANGE,
ID_ACTOR_DEATH, ID_ACTOR_DEATH,
ID_ACTOR_EQUIPMENT, ID_ACTOR_EQUIPMENT,
ID_ACTOR_INTERACTION, ID_ACTOR_CAST,
ID_ACTOR_POSITION, ID_ACTOR_POSITION,
ID_ACTOR_SPEECH, ID_ACTOR_SPEECH,
ID_ACTOR_STATS_DYNAMIC, ID_ACTOR_STATS_DYNAMIC,
@ -111,7 +111,8 @@ enum GameMessages
ID_WORLD_TIME, ID_WORLD_TIME,
ID_WORLD_WEATHER, ID_WORLD_WEATHER,
ID_PLAYER_ITEM_USE ID_PLAYER_ITEM_USE,
ID_PLAYER_CAST
}; };
enum OrderingChannel enum OrderingChannel

@ -26,43 +26,30 @@ void PacketActorAttack::Actor(BaseActor &actor, bool send)
RW(actor.attack.type, send); RW(actor.attack.type, send);
if (actor.attack.type == mwmp::Attack::ITEM_MAGIC) RW(actor.attack.pressed, send);
RW(actor.attack.itemId, send, true); RW(actor.attack.success, send);
else
{
RW(actor.attack.pressed, send);
RW(actor.attack.success, send);
if (actor.attack.type == mwmp::Attack::MAGIC) RW(actor.attack.isHit, send);
{
RW(actor.attack.instant, send);
RW(actor.attack.spellId, send, true);
}
else
{
RW(actor.attack.isHit, send);
if (actor.attack.type == mwmp::Attack::RANGED) if (actor.attack.type == mwmp::Attack::RANGED)
{ {
RW(actor.attack.attackStrength, send); RW(actor.attack.attackStrength, send);
RW(actor.attack.rangedWeaponId, send); RW(actor.attack.rangedWeaponId, send);
RW(actor.attack.rangedAmmoId, send); RW(actor.attack.rangedAmmoId, send);
} }
if (actor.attack.isHit) if (actor.attack.isHit)
{ {
RW(actor.attack.damage, send); RW(actor.attack.damage, send);
RW(actor.attack.block, send); RW(actor.attack.block, send);
RW(actor.attack.knockdown, send); RW(actor.attack.knockdown, send);
RW(actor.attack.applyWeaponEnchantment, send); RW(actor.attack.applyWeaponEnchantment, send);
if (actor.attack.type == mwmp::Attack::RANGED) if (actor.attack.type == mwmp::Attack::RANGED)
RW(actor.attack.applyAmmoEnchantment, send); RW(actor.attack.applyAmmoEnchantment, send);
RW(actor.attack.hitPosition.pos[0], send); RW(actor.attack.hitPosition.pos[0], send);
RW(actor.attack.hitPosition.pos[1], send); RW(actor.attack.hitPosition.pos[1], send);
RW(actor.attack.hitPosition.pos[2], send); RW(actor.attack.hitPosition.pos[2], send);
}
}
} }
} }

@ -0,0 +1,39 @@
#include <components/openmw-mp/NetworkMessages.hpp>
#include <components/openmw-mp/TimedLog.hpp>
#include "PacketActorCast.hpp"
using namespace mwmp;
PacketActorCast::PacketActorCast(RakNet::RakPeerInterface *peer) : ActorPacket(peer)
{
packetID = ID_ACTOR_ATTACK;
}
void PacketActorCast::Actor(BaseActor &actor, bool send)
{
RW(actor.cast.target.isPlayer, send);
if (actor.cast.target.isPlayer)
{
RW(actor.cast.target.guid, send);
}
else
{
RW(actor.cast.target.refId, send, true);
RW(actor.cast.target.refNum, send);
RW(actor.cast.target.mpNum, send);
}
RW(actor.cast.type, send);
if (actor.cast.type == mwmp::Cast::ITEM)
RW(actor.cast.itemId, send, true);
else
{
RW(actor.cast.pressed, send);
RW(actor.cast.success, send);
RW(actor.cast.instant, send);
RW(actor.cast.spellId, send, true);
}
}

@ -0,0 +1,17 @@
#ifndef OPENMW_PACKETACTORCAST_HPP
#define OPENMW_PACKETACTORCAST_HPP
#include <components/openmw-mp/Packets/Actor/ActorPacket.hpp>
namespace mwmp
{
class PacketActorCast : public ActorPacket
{
public:
PacketActorCast(RakNet::RakPeerInterface *peer);
virtual void Actor(BaseActor &actor, bool send);
};
}
#endif //OPENMW_PACKETACTORCAST_HPP

@ -27,43 +27,30 @@ void PacketPlayerAttack::Packet(RakNet::BitStream *bs, bool send)
RW(player->attack.type, send); RW(player->attack.type, send);
if (player->attack.type == mwmp::Attack::ITEM_MAGIC) RW(player->attack.pressed, send);
RW(player->attack.itemId, send, true); RW(player->attack.success, send);
else
{
RW(player->attack.pressed, send);
RW(player->attack.success, send);
if (player->attack.type == mwmp::Attack::MAGIC) RW(player->attack.isHit, send);
{
RW(player->attack.instant, send);
RW(player->attack.spellId, send, true);
}
else
{
RW(player->attack.isHit, send);
if (player->attack.type == mwmp::Attack::RANGED) if (player->attack.type == mwmp::Attack::RANGED)
{ {
RW(player->attack.attackStrength, send); RW(player->attack.attackStrength, send);
RW(player->attack.rangedWeaponId, send); RW(player->attack.rangedWeaponId, send);
RW(player->attack.rangedAmmoId, send); RW(player->attack.rangedAmmoId, send);
} }
if (player->attack.isHit) if (player->attack.isHit)
{ {
RW(player->attack.damage, send); RW(player->attack.damage, send);
RW(player->attack.block, send); RW(player->attack.block, send);
RW(player->attack.knockdown, send); RW(player->attack.knockdown, send);
RW(player->attack.applyWeaponEnchantment, send); RW(player->attack.applyWeaponEnchantment, send);
if (player->attack.type == mwmp::Attack::RANGED) if (player->attack.type == mwmp::Attack::RANGED)
RW(player->attack.applyAmmoEnchantment, send); RW(player->attack.applyAmmoEnchantment, send);
RW(player->attack.hitPosition.pos[0], send); RW(player->attack.hitPosition.pos[0], send);
RW(player->attack.hitPosition.pos[1], send); RW(player->attack.hitPosition.pos[1], send);
RW(player->attack.hitPosition.pos[2], send); RW(player->attack.hitPosition.pos[2], send);
}
}
} }
} }

@ -0,0 +1,42 @@
#include <components/openmw-mp/NetworkMessages.hpp>
#include "PacketPlayerCast.hpp"
#include <components/openmw-mp/TimedLog.hpp>
using namespace mwmp;
PacketPlayerCast::PacketPlayerCast(RakNet::RakPeerInterface *peer) : PlayerPacket(peer)
{
packetID = ID_PLAYER_CAST;
}
void PacketPlayerCast::Packet(RakNet::BitStream *bs, bool send)
{
PlayerPacket::Packet(bs, send);
RW(player->cast.target.isPlayer, send);
if (player->cast.target.isPlayer)
{
RW(player->cast.target.guid, send);
}
else
{
RW(player->cast.target.refId, send, true);
RW(player->cast.target.refNum, send);
RW(player->cast.target.mpNum, send);
}
RW(player->cast.type, send);
if (player->cast.type == mwmp::Cast::ITEM)
RW(player->cast.itemId, send, true);
else
{
RW(player->cast.pressed, send);
RW(player->cast.success, send);
RW(player->cast.instant, send);
RW(player->cast.spellId, send, true);
}
}

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