diff --git a/apps/openmw-mp/Player.cpp b/apps/openmw-mp/Player.cpp index 05719e637..d077acfde 100644 --- a/apps/openmw-mp/Player.cpp +++ b/apps/openmw-mp/Player.cpp @@ -172,6 +172,8 @@ void Player::update() packet->setPlayer(basePlayer); packet->Send(false); packet->Send(true); + + skillChanges.skillIndexes.clear(); } if (inventory.isEquipmentChanged()) @@ -443,7 +445,7 @@ int Player::getLevelProgress() const void Player::setLevelProgress(int progress) { npcStats.mLevelProgress = progress; - skillsChanged = true; + levelChanged = true; } std::string Player::getCreatureModel() const @@ -506,6 +508,8 @@ void Player::setSkill(unsigned short id, int base, int current, float progress) skill.mCurrent = current; skill.mProgress = progress; + skillChanges.skillIndexes.push_back(id); + skillsChanged = true; } @@ -521,7 +525,7 @@ void Player::setSkillIncrease(unsigned short attributeId, int increase) npcStats.mSkillIncrease[attributeId] = increase; - skillsChanged = true; + attributesChanged = true; } CharClass &Player::getCharClass(sol::this_state thisState) diff --git a/apps/openmw/mwmp/LocalPlayer.cpp b/apps/openmw/mwmp/LocalPlayer.cpp index fe905cd69..0e43a4c6f 100644 --- a/apps/openmw/mwmp/LocalPlayer.cpp +++ b/apps/openmw/mwmp/LocalPlayer.cpp @@ -237,6 +237,12 @@ void LocalPlayer::updateAttributes(bool 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; + } } if (attributesChanged || forceUpdate) @@ -255,52 +261,39 @@ void LocalPlayer::updateSkills(bool forceUpdate) MWWorld::Ptr ptrPlayer = getPlayerPtr(); const MWMechanics::NpcStats &ptrNpcStats = ptrPlayer.getClass().getNpcStats(ptrPlayer); - // Track whether skills have changed their values, but not whether - // progress towards skill increases has changed (to not spam server - // with packets every time tiny progress is made) - bool skillsChanged = false; - for (int i = 0; i < 27; ++i) { - if (ptrNpcStats.getSkill(i).getBase() != npcStats.mSkills[i].mBase) + // Update a skill if its base value has changed at all or its progress has changed enough + if (ptrNpcStats.getSkill(i).getBase() != npcStats.mSkills[i].mBase || + ptrNpcStats.getSkill(i).getProgress() != npcStats.mSkills[i].mProgress || + forceUpdate) { ptrNpcStats.getSkill(i).writeState(npcStats.mSkills[i]); - skillsChanged = true; + skillChanges.skillIndexes.push_back(i); } - // If we only have skill progress, remember it for future packets, - // but don't send a packet just because of this - else if (ptrNpcStats.getSkill(i).getProgress() != npcStats.mSkills[i].mProgress) - ptrNpcStats.getSkill(i).writeState(npcStats.mSkills[i]); - } - - for (int i = 0; i < 8; i++) - { - if (ptrNpcStats.getSkillIncrease(i) != npcStats.mSkillIncrease[i]) - npcStats.mSkillIncrease[i] = ptrNpcStats.getSkillIncrease(i); } - if (skillsChanged || forceUpdate) + if (skillChanges.skillIndexes.size() > 0) { - npcStats.mLevelProgress = ptrNpcStats.getLevelProgress(); getNetworking()->getPlayerPacket(ID_PLAYER_SKILL)->setPlayer(this); getNetworking()->getPlayerPacket(ID_PLAYER_SKILL)->Send(); + skillChanges.skillIndexes.clear(); } } void LocalPlayer::updateLevel(bool forceUpdate) { MWWorld::Ptr ptrPlayer = getPlayerPtr(); - const MWMechanics::CreatureStats &ptrCreatureStats = ptrPlayer.getClass().getCreatureStats(ptrPlayer); + const MWMechanics::NpcStats &ptrNpcStats = ptrPlayer.getClass().getNpcStats(ptrPlayer); - if (ptrCreatureStats.getLevel() != creatureStats.mLevel || forceUpdate) + if (ptrNpcStats.getLevel() != creatureStats.mLevel || + ptrNpcStats.getLevelProgress() != npcStats.mLevelProgress || + forceUpdate) { - creatureStats.mLevel = ptrCreatureStats.getLevel(); + creatureStats.mLevel = ptrNpcStats.getLevel(); + npcStats.mLevelProgress = ptrNpcStats.getLevelProgress(); getNetworking()->getPlayerPacket(ID_PLAYER_LEVEL)->setPlayer(this); getNetworking()->getPlayerPacket(ID_PLAYER_LEVEL)->Send(); - - // Also update skills to refresh level progress and attribute bonuses - // for next level up - updateSkills(true); } } diff --git a/components/openmw-mp/Base/BasePlayer.hpp b/components/openmw-mp/Base/BasePlayer.hpp index 8f8b58606..de54314e7 100644 --- a/components/openmw-mp/Base/BasePlayer.hpp +++ b/components/openmw-mp/Base/BasePlayer.hpp @@ -79,6 +79,14 @@ namespace mwmp int type; // 0 - Cell load, 1 - Cell unload }; + // Track only the indexes of the skills that have been changed, + // with the skill values themselves being stored in npcStats.mSkills + struct SkillChanges + { + std::vector skillIndexes; + unsigned int count; + }; + struct JournalChanges { std::vector journalItems; @@ -205,6 +213,8 @@ namespace mwmp int day; double hour; + SkillChanges skillChanges; + SpellbookChanges spellbookChanges; JournalChanges journalChanges; FactionChanges factionChanges; diff --git a/components/openmw-mp/Packets/Player/PacketPlayerAttribute.cpp b/components/openmw-mp/Packets/Player/PacketPlayerAttribute.cpp index bdab8abe5..089212d7a 100644 --- a/components/openmw-mp/Packets/Player/PacketPlayerAttribute.cpp +++ b/components/openmw-mp/Packets/Player/PacketPlayerAttribute.cpp @@ -17,4 +17,6 @@ void PacketPlayerAttribute::Packet(RakNet::BitStream *bs, bool send) PlayerPacket::Packet(bs, send); RW(player->creatureStats.mAttributes, send); + + RW(player->npcStats.mSkillIncrease, send); } diff --git a/components/openmw-mp/Packets/Player/PacketPlayerLevel.cpp b/components/openmw-mp/Packets/Player/PacketPlayerLevel.cpp index 9e83d6398..22256489f 100644 --- a/components/openmw-mp/Packets/Player/PacketPlayerLevel.cpp +++ b/components/openmw-mp/Packets/Player/PacketPlayerLevel.cpp @@ -13,4 +13,6 @@ void PacketPlayerLevel::Packet(RakNet::BitStream *bs, bool send) PlayerPacket::Packet(bs, send); RW(player->creatureStats.mLevel, send); + + RW(player->npcStats.mLevelProgress, send); } diff --git a/components/openmw-mp/Packets/Player/PacketPlayerSkill.cpp b/components/openmw-mp/Packets/Player/PacketPlayerSkill.cpp index ea25463ec..f293e9e27 100644 --- a/components/openmw-mp/Packets/Player/PacketPlayerSkill.cpp +++ b/components/openmw-mp/Packets/Player/PacketPlayerSkill.cpp @@ -18,10 +18,21 @@ void PacketPlayerSkill::Packet(RakNet::BitStream *bs, bool send) { PlayerPacket::Packet(bs, send); - RW(player->npcStats.mSkills, send); - - - RW(player->npcStats.mSkillIncrease, send); - - RW(player->npcStats.mLevelProgress, send); + if (send) + player->skillChanges.count = (unsigned int)(player->skillChanges.skillIndexes.size()); + else + player->skillChanges.skillIndexes.clear(); + + RW(player->skillChanges.count, send); + + for (unsigned int i = 0; i < player->skillChanges.count; i++) + { + int skillId; + + if (send) + skillId = player->skillChanges.skillIndexes.at(i); + + RW(skillId, send); + RW(player->npcStats.mSkills[skillId], send); + } }