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

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

@ -1,16 +1,16 @@
#ifndef OPENMW_PROCESSORACTORINTERACTION_HPP
#define OPENMW_PROCESSORACTORINTERACTION_HPP
#ifndef OPENMW_PROCESSORACTORCAST_HPP
#define OPENMW_PROCESSORACTORCAST_HPP
#include "../ActorProcessor.hpp"
namespace mwmp
{
class ProcessorActorInteraction : public ActorProcessor
class ProcessorActorCast : public ActorProcessor
{
public:
ProcessorActorInteraction()
ProcessorActorCast()
{
BPP_INIT(ID_ACTOR_INTERACTION)
BPP_INIT(ID_ACTOR_CAST)
}
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
ProcessorActorAuthority ProcessorActorCellChange ProcessorActorDeath ProcessorActorEquipment ProcessorActorInteraction
ProcessorActorAuthority ProcessorActorCast ProcessorActorCellChange ProcessorActorDeath ProcessorActorEquipment
ProcessorActorList ProcessorActorPosition ProcessorActorSpeech ProcessorActorStatsDynamic ProcessorActorTest
)
add_openmw_dir (mwmp/processors/player ProcessorChatMessage ProcessorGUIMessageBox ProcessorHandshake
ProcessorUserDisconnected ProcessorUserMyID ProcessorGameSettings ProcessorPlayerAnimFlags ProcessorPlayerAnimPlay
ProcessorPlayerAttack ProcessorPlayerAttribute ProcessorPlayerBaseInfo ProcessorPlayerBehavior ProcessorPlayerBook
ProcessorPlayerBounty ProcessorPlayerCellChange ProcessorPlayerCellState ProcessorPlayerCharClass ProcessorPlayerCharGen
ProcessorPlayerDeath ProcessorPlayerDisposition ProcessorPlayerEquipment ProcessorPlayerFaction ProcessorPlayerInput
ProcessorPlayerInventory ProcessorPlayerItemUse ProcessorPlayerJail ProcessorPlayerJournal ProcessorWorldKillCount
ProcessorPlayerLevel ProcessorPlayerMiscellaneous ProcessorPlayerMomentum ProcessorPlayerPosition ProcessorPlayerQuickKeys
ProcessorPlayerReputation ProcessorPlayerResurrect ProcessorPlayerShapeshift ProcessorPlayerSkill ProcessorPlayerSpeech
ProcessorPlayerSpellbook ProcessorPlayerStatsDynamic ProcessorPlayerTopic
ProcessorPlayerBounty ProcessorPlayerCast ProcessorPlayerCellChange ProcessorPlayerCellState ProcessorPlayerCharClass
ProcessorPlayerCharGen ProcessorPlayerDeath ProcessorPlayerDisposition ProcessorPlayerEquipment ProcessorPlayerFaction
ProcessorPlayerInput ProcessorPlayerInventory ProcessorPlayerItemUse ProcessorPlayerJail ProcessorPlayerJournal
ProcessorWorldKillCount ProcessorPlayerLevel ProcessorPlayerMiscellaneous ProcessorPlayerMomentum ProcessorPlayerPosition
ProcessorPlayerQuickKeys ProcessorPlayerReputation ProcessorPlayerResurrect ProcessorPlayerShapeshift ProcessorPlayerSkill
ProcessorPlayerSpeech ProcessorPlayerSpellbook ProcessorPlayerStatsDynamic ProcessorPlayerTopic
)
add_openmw_dir (mwmp/processors/object BaseObjectProcessor

@ -1609,7 +1609,21 @@ namespace MWMechanics
mwmp::Attack *dedicatedAttack = MechanicsHelper::getDedicatedAttack(iter->first);
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
*/

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

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

@ -39,6 +39,7 @@ void ActorList::reset()
equipmentActors.clear();
aiActors.clear();
attackActors.clear();
castActors.clear();
cellChangeActors.clear();
guid = mwmp::Main::get().getNetworking()->getLocalPlayer()->guid;
}
@ -118,6 +119,11 @@ void ActorList::addAttackActor(BaseActor baseActor)
attackActors.push_back(baseActor);
}
void ActorList::addCastActor(BaseActor baseActor)
{
castActors.push_back(baseActor);
}
void ActorList::addCellChangeActor(BaseActor 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()
{
if (cellChangeActors.size() > 0)

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

@ -99,6 +99,7 @@ void Cell::updateLocal(bool forceUpdate)
actorList->sendStatsDynamicActors();
actorList->sendEquipmentActors();
actorList->sendAttackActors();
actorList->sendCastActors();
actorList->sendCellChangeActors();
}
@ -314,14 +315,35 @@ void Cell::readAttack(ActorList& actorList)
actor->drawState = MWMechanics::DrawState_::DrawState_Weapon;
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->setAnimFlags();
}
MechanicsHelper::processAttack(actor->attack, actor->getPtr());
MechanicsHelper::processCast(actor->cast, actor->getPtr());
}
}
}

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

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

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

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

@ -44,7 +44,8 @@ using namespace std;
DedicatedPlayer::DedicatedPlayer(RakNet::RakNetGUID guid) : BasePlayer(guid)
{
reference = 0;
attack.pressed = 0;
attack.pressed = false;
cast.pressed = false;
creatureStats.mDead = false;
// 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;
}
DedicatedPlayer::~DedicatedPlayer()
{

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

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

@ -65,6 +65,12 @@ LocalPlayer::LocalPlayer()
ignoreJailSkillIncreases = false;
attack.shouldSend = false;
attack.instant = false;
attack.pressed = false;
cast.shouldSend = false;
cast.instant = false;
cast.pressed = false;
killer.isPlayer = false;
killer.refId = "";
@ -110,7 +116,7 @@ void LocalPlayer::update()
updateCell();
updatePosition();
updateAnimFlags();
updateAttack();
updateAttackOrCast();
updateEquipment();
updateStatsDynamic();
updateAttributes();
@ -592,22 +598,29 @@ void LocalPlayer::updateInventory(bool forceUpdate)
sendInventory();
}
void LocalPlayer::updateAttack()
void LocalPlayer::updateAttackOrCast()
{
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)
attack.success = MechanicsHelper::getSpellSuccess(attack.spellId, getPlayerPtr());
if (cast.pressed)
cast.success = MechanicsHelper::getSpellSuccess(cast.spellId, getPlayerPtr());
}
getNetworking()->getPlayerPacket(ID_PLAYER_ATTACK)->setPlayer(this);
getNetworking()->getPlayerPacket(ID_PLAYER_ATTACK)->Send();
getNetworking()->getPlayerPacket(ID_PLAYER_CAST)->setPlayer(this);
getNetworking()->getPlayerPacket(ID_PLAYER_CAST)->Send();
attack.shouldSend = false;
cast.shouldSend = false;
}
}

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

@ -115,6 +115,26 @@ Attack *MechanicsHelper::getDedicatedAttack(const MWWorld::Ptr& ptr)
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)
{
if (target.guid == mwmp::Main::get().getLocalPlayer()->guid)
@ -233,6 +253,16 @@ void MechanicsHelper::resetAttack(Attack* attack)
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)
{
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();
}
if (attack.isHit && (attack.type == attack.MELEE || attack.type == attack.RANGED))
if (attack.isHit)
{
bool isRanged = attack.type == attack.RANGED;
@ -385,38 +415,71 @@ void MechanicsHelper::processAttack(Attack attack, const MWWorld::Ptr& 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);
attack.instant = false;
MWBase::Environment::get().getWorld()->castSpell(caster);
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();
for (; it != inventoryStore.end(); ++it)
{
if (Misc::StringUtils::ciEqual(it->getCellRef().getRefId(), attack.itemId))
if (Misc::StringUtils::ciEqual(it->getCellRef().getRefId(), cast.itemId))
break;
}
// Add the item if it's missing
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);
LOG_APPEND(TimedLog::LOG_VERBOSE, "- itemId: %s", attack.itemId.c_str());
MWBase::Environment::get().getWorld()->castSpell(attacker);
LOG_APPEND(TimedLog::LOG_VERBOSE, "- itemId: %s", cast.itemId.c_str());
MWBase::Environment::get().getWorld()->castSpell(caster);
inventoryStore.setSelectedEnchantItem(inventoryStore.end());
}
}

@ -20,6 +20,9 @@ namespace MechanicsHelper
mwmp::Attack *getLocalAttack(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);
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 resetAttack(mwmp::Attack* attack);
void resetCast(mwmp::Cast* cast);
bool getSpellSuccess(std::string spellId, const MWWorld::Ptr& caster);
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);
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/ProcessorPlayerBook.hpp"
#include "player/ProcessorPlayerBounty.hpp"
#include "player/ProcessorPlayerCast.hpp"
#include "player/ProcessorPlayerCellChange.hpp"
#include "player/ProcessorPlayerCellState.hpp"
#include "player/ProcessorPlayerCharClass.hpp"
@ -77,10 +78,10 @@
#include "actor/ProcessorActorAnimPlay.hpp"
#include "actor/ProcessorActorAttack.hpp"
#include "actor/ProcessorActorAuthority.hpp"
#include "actor/ProcessorActorCast.hpp"
#include "actor/ProcessorActorCellChange.hpp"
#include "actor/ProcessorActorDeath.hpp"
#include "actor/ProcessorActorEquipment.hpp"
#include "actor/ProcessorActorInteraction.hpp"
#include "actor/ProcessorActorList.hpp"
#include "actor/ProcessorActorPosition.hpp"
#include "actor/ProcessorActorSpeech.hpp"
@ -114,6 +115,7 @@ void ProcessorInitializer()
PlayerProcessor::AddProcessor(new ProcessorPlayerBehavior());
PlayerProcessor::AddProcessor(new ProcessorPlayerBook());
PlayerProcessor::AddProcessor(new ProcessorPlayerBounty());
PlayerProcessor::AddProcessor(new ProcessorPlayerCast());
PlayerProcessor::AddProcessor(new ProcessorPlayerCellChange());
PlayerProcessor::AddProcessor(new ProcessorPlayerCellState());
PlayerProcessor::AddProcessor(new ProcessorPlayerCharClass());
@ -175,10 +177,10 @@ void ProcessorInitializer()
ActorProcessor::AddProcessor(new ProcessorActorAnimPlay());
ActorProcessor::AddProcessor(new ProcessorActorAttack());
ActorProcessor::AddProcessor(new ProcessorActorAuthority());
ActorProcessor::AddProcessor(new ProcessorActorCast());
ActorProcessor::AddProcessor(new ProcessorActorCellChange());
ActorProcessor::AddProcessor(new ProcessorActorDeath());
ActorProcessor::AddProcessor(new ProcessorActorEquipment());
ActorProcessor::AddProcessor(new ProcessorActorInteraction());
ActorProcessor::AddProcessor(new ProcessorActorList());
ActorProcessor::AddProcessor(new ProcessorActorPosition());
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)
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
Set the attack details before going through with the casting, in case it's
a one use item that would get removed through the casting (like a scroll)
Set the cast details before going forward, in case it's a one use item that
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);
localAttack->type = mwmp::Attack::ITEM_MAGIC;
localAttack->itemId = inv.getSelectedEnchantItem()->getCellRef().getRefId();
localAttack->shouldSend = true;
MechanicsHelper::resetCast(localCast);
localCast->type = mwmp::Cast::ITEM;
localCast->itemId = inv.getSelectedEnchantItem()->getCellRef().getRefId();
localCast->shouldSend = true;
}
cast.cast(*inv.getSelectedEnchantItem());

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

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

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

@ -65,19 +65,13 @@ namespace mwmp
Target target;
char type; // 0 - melee, 1 - magic, 2 - item magic, 3 - throwable
char type; // 0 - melee, 1 - ranged
enum TYPE
{
MELEE = 0,
RANGED,
MAGIC,
ITEM_MAGIC,
THROWABLE
RANGED
};
std::string spellId; // id of spell (e.g. "fireball")
std::string itemId;
std::string rangedWeaponId;
std::string rangedAmmoId;
@ -99,6 +93,32 @@ namespace mwmp
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
{
std::string groupname;

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

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

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

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