diff --git a/apps/openmw-mp/Script/Functions/Stats.cpp b/apps/openmw-mp/Script/Functions/Stats.cpp index 894887292..4d88fdfbd 100644 --- a/apps/openmw-mp/Script/Functions/Stats.cpp +++ b/apps/openmw-mp/Script/Functions/Stats.cpp @@ -408,6 +408,10 @@ void StatsFunctions::SetAttributeBase(unsigned short pid, unsigned short attribu return; player->creatureStats.mAttributes[attributeId].mBase = value; + + if (std::find(player->attributeChanges.attributeIndexes.begin(), player->attributeChanges.attributeIndexes.end(), attributeId) == + player->attributeChanges.attributeIndexes.end()) + player->attributeChanges.attributeIndexes.push_back(attributeId); } void StatsFunctions::ClearAttributeModifier(unsigned short pid, unsigned short attributeId) noexcept @@ -419,6 +423,10 @@ void StatsFunctions::ClearAttributeModifier(unsigned short pid, unsigned short a return; player->creatureStats.mAttributes[attributeId].mMod = 0; + + if (std::find(player->attributeChanges.attributeIndexes.begin(), player->attributeChanges.attributeIndexes.end(), attributeId) == + player->attributeChanges.attributeIndexes.end()) + player->attributeChanges.attributeIndexes.push_back(attributeId); } void StatsFunctions::SetSkillBase(unsigned short pid, unsigned short skillId, int value) noexcept @@ -469,6 +477,10 @@ void StatsFunctions::SetSkillIncrease(unsigned short pid, unsigned int attribute return; player->npcStats.mSkillIncrease[attributeId] = value; + + if (std::find(player->attributeChanges.attributeIndexes.begin(), player->attributeChanges.attributeIndexes.end(), attributeId) == + player->attributeChanges.attributeIndexes.end()) + player->attributeChanges.attributeIndexes.push_back(attributeId); } void StatsFunctions::SetBounty(unsigned short pid, int value) noexcept @@ -520,6 +532,8 @@ void StatsFunctions::SendAttributes(unsigned short pid) noexcept mwmp::Networking::get().getPlayerPacketController()->GetPacket(ID_PLAYER_ATTRIBUTE)->setPlayer(player); mwmp::Networking::get().getPlayerPacketController()->GetPacket(ID_PLAYER_ATTRIBUTE)->Send(false); mwmp::Networking::get().getPlayerPacketController()->GetPacket(ID_PLAYER_ATTRIBUTE)->Send(true); + + player->attributeChanges.attributeIndexes.clear(); } void StatsFunctions::SendSkills(unsigned short pid) noexcept diff --git a/apps/openmw/mwmp/LocalPlayer.cpp b/apps/openmw/mwmp/LocalPlayer.cpp index a6b8670ac..c086b6b57 100644 --- a/apps/openmw/mwmp/LocalPlayer.cpp +++ b/apps/openmw/mwmp/LocalPlayer.cpp @@ -237,28 +237,25 @@ void LocalPlayer::updateAttributes(bool forceUpdate) MWWorld::Ptr ptrPlayer = getPlayerPtr(); const MWMechanics::NpcStats &ptrNpcStats = ptrPlayer.getClass().getNpcStats(ptrPlayer); - bool attributesChanged = false; for (int i = 0; i < 8; ++i) { if (ptrNpcStats.getAttribute(i).getBase() != creatureStats.mAttributes[i].mBase || - ptrNpcStats.getAttribute(i).getModifier() != creatureStats.mAttributes[i].mMod) + ptrNpcStats.getAttribute(i).getModifier() != creatureStats.mAttributes[i].mMod || + ptrNpcStats.getSkillIncrease(i) != npcStats.mSkillIncrease[i] || + forceUpdate) { ptrNpcStats.getAttribute(i).writeState(creatureStats.mAttributes[i]); - attributesChanged = true; - } - - if (ptrNpcStats.getSkillIncrease(i) != npcStats.mSkillIncrease[i]) - { npcStats.mSkillIncrease[i] = ptrNpcStats.getSkillIncrease(i); - attributesChanged = true; + attributeChanges.attributeIndexes.push_back(i); } } - if (attributesChanged || forceUpdate) + if (attributeChanges.attributeIndexes.size() > 0) { getNetworking()->getPlayerPacket(ID_PLAYER_ATTRIBUTE)->setPlayer(this); getNetworking()->getPlayerPacket(ID_PLAYER_ATTRIBUTE)->Send(); + attributeChanges.attributeIndexes.clear(); } } diff --git a/components/openmw-mp/Base/BasePlayer.hpp b/components/openmw-mp/Base/BasePlayer.hpp index a0076c6dd..2b4bf75b2 100644 --- a/components/openmw-mp/Base/BasePlayer.hpp +++ b/components/openmw-mp/Base/BasePlayer.hpp @@ -95,6 +95,14 @@ namespace mwmp int type; // 0 - Cell load, 1 - Cell unload }; + // Track only the indexes of the attributes that have been changed, + // with the attribute values themselves being stored in creatureStats.mAttributes + struct AttributeChanges + { + std::vector attributeIndexes; + unsigned int count; + }; + // Track only the indexes of the skills that have been changed, // with the skill values themselves being stored in npcStats.mSkills struct SkillChanges @@ -249,6 +257,7 @@ namespace mwmp int day; double hour; + AttributeChanges attributeChanges; SkillChanges skillChanges; InventoryChanges inventoryChanges; diff --git a/components/openmw-mp/Packets/Player/PacketPlayerAttribute.cpp b/components/openmw-mp/Packets/Player/PacketPlayerAttribute.cpp index 089212d7a..0ba1fc1db 100644 --- a/components/openmw-mp/Packets/Player/PacketPlayerAttribute.cpp +++ b/components/openmw-mp/Packets/Player/PacketPlayerAttribute.cpp @@ -1,8 +1,5 @@ -// -// Created by koncord on 08.03.16. -// - #include "PacketPlayerAttribute.hpp" + #include using namespace mwmp; @@ -16,7 +13,23 @@ void PacketPlayerAttribute::Packet(RakNet::BitStream *bs, bool send) { PlayerPacket::Packet(bs, send); - RW(player->creatureStats.mAttributes, send); + if (send) + player->attributeChanges.count = (unsigned int)(player->attributeChanges.attributeIndexes.size()); + else + player->attributeChanges.attributeIndexes.clear(); + + RW(player->attributeChanges.count, send); + + for (unsigned int i = 0; i < player->attributeChanges.count; i++) + { + int attributeId; + + if (send) + attributeId = player->attributeChanges.attributeIndexes.at(i); + + RW(attributeId, send); - RW(player->npcStats.mSkillIncrease, send); + RW(player->creatureStats.mAttributes[attributeId], send); + RW(player->npcStats.mSkillIncrease[attributeId], send); + } }