From 20e010070677137eb848e97a440db95ef1c45fac Mon Sep 17 00:00:00 2001 From: David Cernat Date: Sat, 21 Jul 2018 14:41:27 +0300 Subject: [PATCH] [General] Rework Attack packets and add synchronization for item magic --- apps/openmw/mwmechanics/spellcasting.cpp | 19 ++++++++++++ apps/openmw/mwmp/MechanicsHelper.cpp | 30 ++++++++++++++++-- components/openmw-mp/Base/BaseStructs.hpp | 4 ++- .../Packets/Actor/PacketActorAttack.cpp | 24 ++++++++------ .../Packets/Player/PacketPlayerAttack.cpp | 31 +++++++++++++------ 5 files changed, 87 insertions(+), 21 deletions(-) diff --git a/apps/openmw/mwmechanics/spellcasting.cpp b/apps/openmw/mwmechanics/spellcasting.cpp index d6a0d961e..615c745e0 100644 --- a/apps/openmw/mwmechanics/spellcasting.cpp +++ b/apps/openmw/mwmechanics/spellcasting.cpp @@ -936,6 +936,25 @@ namespace MWMechanics else if (isProjectile || !mTarget.isEmpty()) inflict(mTarget, mCaster, enchantment->mEffects, ESM::RT_Target); + /* + Start of tes3mp addition + + If this mPtr belongs to a LocalPlayer or LocalActor, get their Attack and prepare + it for sending + */ + mwmp::Attack *localAttack = MechanicsHelper::getLocalAttack(mCaster); + + if (localAttack) + { + MechanicsHelper::resetAttack(localAttack); + localAttack->type = mwmp::Attack::ITEM_MAGIC; + localAttack->itemId = item.getCellRef().getRefId(); + localAttack->shouldSend = true; + } + /* + End of tes3mp addition + */ + return true; } diff --git a/apps/openmw/mwmp/MechanicsHelper.cpp b/apps/openmw/mwmp/MechanicsHelper.cpp index a547968f2..89aaf0fc7 100644 --- a/apps/openmw/mwmp/MechanicsHelper.cpp +++ b/apps/openmw/mwmp/MechanicsHelper.cpp @@ -201,8 +201,6 @@ void MechanicsHelper::processAttack(Attack attack, const MWWorld::Ptr& attacker) } MWMechanics::CreatureStats &attackerStats = attacker.getClass().getCreatureStats(attacker); - attackerStats.getSpells().setSelectedSpell(attack.spellId); - MWWorld::Ptr victim; if (attack.target.isPlayer) @@ -282,6 +280,8 @@ void MechanicsHelper::processAttack(Attack attack, const MWWorld::Ptr& attacker) } else if (attack.type == attack.MAGIC) { + attackerStats.getSpells().setSelectedSpell(attack.spellId); + if (attack.instant) { MWBase::Environment::get().getWorld()->castSpell(attacker); @@ -290,6 +290,32 @@ void MechanicsHelper::processAttack(Attack attack, const MWWorld::Ptr& attacker) LOG_APPEND(Log::LOG_VERBOSE, "- spellId: %s, success: %s", attack.spellId.c_str(), attack.success ? "true" : "false"); } + else if (attack.type == attack.ITEM_MAGIC) + { + attackerStats.getSpells().setSelectedSpell(""); + + MWWorld::InventoryStore& inventoryStore = attacker.getClass().getInventoryStore(attacker); + + MWWorld::ContainerStoreIterator it = inventoryStore.begin(); + for (; it != inventoryStore.end(); ++it) + { + if (Misc::StringUtils::ciEqual(it->getCellRef().getRefId(), attack.itemId)) + break; + } + + if (it != inventoryStore.end()) + { + inventoryStore.setSelectedEnchantItem(it); + LOG_APPEND(Log::LOG_VERBOSE, "- itemId: %s", attack.itemId.c_str()); + MWBase::Environment::get().getWorld()->castSpell(attacker); + inventoryStore.setSelectedEnchantItem(inventoryStore.end()); + } + else + { + LOG_MESSAGE_SIMPLE(Log::LOG_ERROR, "Could not find item %s used by %s to cast item spell!", + attack.itemId.c_str(), attacker.getCellRef().getRefId().c_str()); + } + } } bool MechanicsHelper::doesEffectListContainEffect(const ESM::EffectList& effectList, short effectId, short attributeId, short skillId) diff --git a/components/openmw-mp/Base/BaseStructs.hpp b/components/openmw-mp/Base/BaseStructs.hpp index 25d8106a4..8672fee9f 100644 --- a/components/openmw-mp/Base/BaseStructs.hpp +++ b/components/openmw-mp/Base/BaseStructs.hpp @@ -41,15 +41,17 @@ namespace mwmp Target target; - char type; // 0 - melee, 1 - magic, 2 - throwable + char type; // 0 - melee, 1 - magic, 2 - item magic, 3 - throwable enum TYPE { MELEE = 0, MAGIC, + ITEM_MAGIC, THROWABLE }; std::string spellId; // id of spell (e.g. "fireball") + std::string itemId; float damage; diff --git a/components/openmw-mp/Packets/Actor/PacketActorAttack.cpp b/components/openmw-mp/Packets/Actor/PacketActorAttack.cpp index 7349f72e5..23b06e11b 100644 --- a/components/openmw-mp/Packets/Actor/PacketActorAttack.cpp +++ b/components/openmw-mp/Packets/Actor/PacketActorAttack.cpp @@ -24,16 +24,22 @@ void PacketActorAttack::Actor(BaseActor &actor, bool send) RW(actor.attack.target.mpNum, send); } - RW(actor.attack.spellId, send); - RW(actor.attack.type, send); + RW(actor.attack.pressed, send); + RW(actor.attack.instant, send); RW(actor.attack.success, send); - RW(actor.attack.damage, send); + RW(actor.attack.type, send); - RW(actor.attack.pressed, send); - RW(actor.attack.knockdown, send); - RW(actor.attack.block, send); + if (actor.attack.type == mwmp::Attack::MELEE) + { + RW(actor.attack.damage, send); + RW(actor.attack.block, send); + RW(actor.attack.knockdown, send); - RW(actor.attack.instant, send); - RW(actor.attack.applyWeaponEnchantment, send); - RW(actor.attack.applyProjectileEnchantment, send); + RW(actor.attack.applyWeaponEnchantment, send); + RW(actor.attack.applyProjectileEnchantment, send); + } + else if (actor.attack.type == mwmp::Attack::MAGIC) + RW(actor.attack.spellId, send, true); + else if (actor.attack.type == mwmp::Attack::ITEM_MAGIC) + RW(actor.attack.itemId, send, true); } diff --git a/components/openmw-mp/Packets/Player/PacketPlayerAttack.cpp b/components/openmw-mp/Packets/Player/PacketPlayerAttack.cpp index f956de5af..356cd983f 100644 --- a/components/openmw-mp/Packets/Player/PacketPlayerAttack.cpp +++ b/components/openmw-mp/Packets/Player/PacketPlayerAttack.cpp @@ -25,15 +25,28 @@ void PacketPlayerAttack::Packet(RakNet::BitStream *bs, bool send) RW(player->attack.target.mpNum, send); } - RW(player->attack.spellId, send, true); RW(player->attack.type, send); - RW(player->attack.success, send); - RW(player->attack.damage, send, false); // never compress damage - RW(player->attack.pressed, send); - RW(player->attack.knockdown, send); - RW(player->attack.block, send); - - RW(player->attack.applyWeaponEnchantment, send); - RW(player->attack.applyProjectileEnchantment, send); + if (player->attack.type == mwmp::Attack::MELEE || player->attack.type == mwmp::Attack::MAGIC) + { + RW(player->attack.pressed, send); + RW(player->attack.success, send); + + if (player->attack.type == mwmp::Attack::MELEE) + { + RW(player->attack.damage, send); + RW(player->attack.block, send); + RW(player->attack.knockdown, send); + + RW(player->attack.applyWeaponEnchantment, send); + RW(player->attack.applyProjectileEnchantment, send); + } + else if (player->attack.type == mwmp::Attack::MAGIC) + { + RW(player->attack.instant, send); + RW(player->attack.spellId, send, true); + } + } + else if (player->attack.type == mwmp::Attack::ITEM_MAGIC) + RW(player->attack.itemId, send), true; }