forked from mirror/openmw-tes3mp
Merge pull request #413 from TES3MP/0.6.3 while resolving conflicts
Conflicts: apps/openmw-mp/processors/player/ProcessorPlayerCellChange.hpp components/openmw-mp/Base/BasePlayer.hpp components/openmw-mp/Packets/Player/PacketPlayerEquipment.hpp components/openmw-mp/Packets/Player/PacketPlayerSkill.cpp
This commit is contained in:
commit
502751cae0
18 changed files with 205 additions and 113 deletions
|
@ -103,6 +103,10 @@ To be able to merge PRs, commit priviledges are required. If you do not have the
|
|||
|
||||
The person to merge the PR may either use github's Merge button or if using the command line, use the ```--no-ff``` flag (so a merge commit is created, just like with Github's merge button) and include the pull request number in the commit description.
|
||||
|
||||
Dealing with regressions
|
||||
========================
|
||||
|
||||
The master branch should always be in a working state that is not worse than the previous release in any way. If a regression is found, the first and foremost priority should be to get the regression fixed quickly, either by reverting the change that caused it or finding a better solution. Please avoid leaving the project in the 'broken' state for an extensive period of time while proper solutions are found. If the solution takes more than a day or so then it is usually better to revert the offending change first and reapply it later when fixed.
|
||||
|
||||
Other resources
|
||||
===============
|
||||
|
|
|
@ -29,10 +29,14 @@ namespace mwmp
|
|||
{
|
||||
LOG_APPEND(Log::LOG_INFO, "- Moved to %s", player->cell.getDescription().c_str());
|
||||
|
||||
player->exchangeFullInfo = true;
|
||||
|
||||
player->forEachLoaded([this](Player *pl, Player *other) {
|
||||
|
||||
LOG_APPEND(Log::LOG_INFO, "- Started information exchange with %s", other->npc.mName.c_str());
|
||||
|
||||
other->exchangeFullInfo = true;
|
||||
|
||||
playerController->GetPacket(ID_PLAYER_STATS_DYNAMIC)->setPlayer(other);
|
||||
playerController->GetPacket(ID_PLAYER_ATTRIBUTE)->setPlayer(other);
|
||||
playerController->GetPacket(ID_PLAYER_POSITION)->setPlayer(other);
|
||||
|
@ -63,6 +67,8 @@ namespace mwmp
|
|||
playerController->GetPacket(ID_PLAYER_ANIM_FLAGS)->Send(other->guid);
|
||||
playerController->GetPacket(ID_PLAYER_SHAPESHIFT)->Send(other->guid);
|
||||
|
||||
other->exchangeFullInfo = false;
|
||||
|
||||
LOG_APPEND(Log::LOG_INFO, "- Finished information exchange with %s", other->npc.mName.c_str());
|
||||
});
|
||||
|
||||
|
@ -74,6 +80,8 @@ namespace mwmp
|
|||
Networking::get().getState().getEventCtrl().Call<CoreEvent::ON_PLAYER_CELLCHANGE>(player.get());
|
||||
|
||||
LOG_APPEND(Log::LOG_INFO, "- Finished processing ID_PLAYER_CELL_CHANGE");
|
||||
|
||||
player->exchangeFullInfo = false;
|
||||
}
|
||||
else
|
||||
LOG_APPEND(Log::LOG_INFO, "- Ignored because %s is dead", player->npc.mName.c_str());
|
||||
|
|
|
@ -404,7 +404,12 @@ namespace MWGui
|
|||
MWMechanics::CreatureStats& stats = player.getClass().getCreatureStats(player);
|
||||
MWMechanics::Spells& spells = stats.getSpells();
|
||||
if (!spells.hasSpell(spellId))
|
||||
{
|
||||
const ESM::Spell* spell = MWBase::Environment::get().getWorld()->getStore().get<ESM::Spell>().find(spellId);
|
||||
MWBase::Environment::get().getWindowManager()->messageBox (
|
||||
"#{sQuickMenu5} " + spell->mName);
|
||||
return;
|
||||
}
|
||||
store.setSelectedEnchantItem(store.end());
|
||||
MWBase::Environment::get().getWindowManager()->setSelectedSpell(spellId, int(MWMechanics::getSpellSuccessChance(spellId, player)));
|
||||
MWBase::Environment::get().getWorld()->getPlayer().setDrawState(MWMechanics::DrawState_Spell);
|
||||
|
|
|
@ -302,7 +302,7 @@ void CharacterController::refreshHitRecoilAnims()
|
|||
}
|
||||
else if (recovery)
|
||||
{
|
||||
std::string anim = isSwimming ? chooseRandomGroup("swimhit") : chooseRandomGroup("hit");
|
||||
std::string anim = chooseRandomGroup("swimhit");
|
||||
if (isSwimming && mAnimation->hasAnimation(anim))
|
||||
{
|
||||
mHitState = CharState_SwimHit;
|
||||
|
|
|
@ -194,6 +194,9 @@ bool LocalPlayer::hasFinishedCharGen()
|
|||
|
||||
void LocalPlayer::updateStatsDynamic(bool forceUpdate)
|
||||
{
|
||||
if (statsDynamicIndexChanges.size() > 0)
|
||||
statsDynamicIndexChanges.clear();
|
||||
|
||||
MWWorld::Ptr ptrPlayer = getPlayerPtr();
|
||||
|
||||
MWMechanics::CreatureStats *ptrCreatureStats = &ptrPlayer.getClass().getCreatureStats(ptrPlayer);
|
||||
|
@ -231,9 +234,9 @@ void LocalPlayer::updateStatsDynamic(bool forceUpdate)
|
|||
magicka.writeState(creatureStats.mDynamic[1]);
|
||||
fatigue.writeState(creatureStats.mDynamic[2]);
|
||||
|
||||
exchangeFullInfo = false;
|
||||
getNetworking()->getPlayerPacket(ID_PLAYER_STATS_DYNAMIC)->setPlayer(this);
|
||||
getNetworking()->getPlayerPacket(ID_PLAYER_STATS_DYNAMIC)->Send();
|
||||
statsDynamicIndexChanges.clear();
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -243,6 +246,9 @@ void LocalPlayer::updateAttributes(bool forceUpdate)
|
|||
// overwritten by the werewolf ones
|
||||
if (isWerewolf) return;
|
||||
|
||||
if (attributeIndexChanges.size() > 0)
|
||||
attributeIndexChanges.clear();
|
||||
|
||||
MWWorld::Ptr ptrPlayer = getPlayerPtr();
|
||||
const MWMechanics::NpcStats &ptrNpcStats = ptrPlayer.getClass().getNpcStats(ptrPlayer);
|
||||
|
||||
|
@ -261,9 +267,9 @@ void LocalPlayer::updateAttributes(bool forceUpdate)
|
|||
|
||||
if (attributeIndexChanges.size() > 0)
|
||||
{
|
||||
exchangeFullInfo = false;
|
||||
getNetworking()->getPlayerPacket(ID_PLAYER_ATTRIBUTE)->setPlayer(this);
|
||||
getNetworking()->getPlayerPacket(ID_PLAYER_ATTRIBUTE)->Send();
|
||||
attributeIndexChanges.clear();
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -273,6 +279,9 @@ void LocalPlayer::updateSkills(bool forceUpdate)
|
|||
// overwritten by the werewolf ones
|
||||
if (isWerewolf) return;
|
||||
|
||||
if (skillIndexChanges.size() > 0)
|
||||
skillIndexChanges.clear();
|
||||
|
||||
MWWorld::Ptr ptrPlayer = getPlayerPtr();
|
||||
const MWMechanics::NpcStats &ptrNpcStats = ptrPlayer.getClass().getNpcStats(ptrPlayer);
|
||||
|
||||
|
@ -291,9 +300,9 @@ void LocalPlayer::updateSkills(bool forceUpdate)
|
|||
|
||||
if (skillIndexChanges.size() > 0)
|
||||
{
|
||||
exchangeFullInfo = false;
|
||||
getNetworking()->getPlayerPacket(ID_PLAYER_SKILL)->setPlayer(this);
|
||||
getNetworking()->getPlayerPacket(ID_PLAYER_SKILL)->Send();
|
||||
skillIndexChanges.clear();
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -432,6 +441,9 @@ void LocalPlayer::updateCell(bool forceUpdate)
|
|||
|
||||
void LocalPlayer::updateEquipment(bool forceUpdate)
|
||||
{
|
||||
if (equipmentIndexChanges.size() > 0)
|
||||
equipmentIndexChanges.clear();
|
||||
|
||||
MWWorld::Ptr ptrPlayer = getPlayerPtr();
|
||||
|
||||
MWWorld::InventoryStore &invStore = ptrPlayer.getClass().getInventoryStore(ptrPlayer);
|
||||
|
@ -442,7 +454,11 @@ void LocalPlayer::updateEquipment(bool forceUpdate)
|
|||
|
||||
if (it != invStore.end())
|
||||
{
|
||||
if (!::Misc::StringUtils::ciEqual(it->getCellRef().getRefId(), equipmentItems[slot].refId) || forceUpdate)
|
||||
if (!::Misc::StringUtils::ciEqual(it->getCellRef().getRefId(), equipmentItems[slot].refId) ||
|
||||
it->getCellRef().getCharge() != item.charge ||
|
||||
it->getCellRef().getEnchantmentCharge() != item.enchantmentCharge ||
|
||||
it->getRefData().getCount() != item.count ||
|
||||
forceUpdate)
|
||||
{
|
||||
equipmentIndexChanges.push_back(slot);
|
||||
item.refId = it->getCellRef().getRefId();
|
||||
|
@ -463,9 +479,9 @@ void LocalPlayer::updateEquipment(bool forceUpdate)
|
|||
|
||||
if (!equipmentIndexChanges.empty())
|
||||
{
|
||||
exchangeFullInfo = false;
|
||||
getNetworking()->getPlayerPacket(ID_PLAYER_EQUIPMENT)->setPlayer(this);
|
||||
getNetworking()->getPlayerPacket(ID_PLAYER_EQUIPMENT)->Send();
|
||||
equipmentIndexChanges.clear();
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -574,6 +574,7 @@ namespace MWScript
|
|||
MWWorld::ManualRef ref(MWBase::Environment::get().getWorld()->getStore(), itemID, 1);
|
||||
|
||||
MWWorld::Ptr ptr = MWBase::Environment::get().getWorld()->safePlaceObject(ref.getPtr(), actor, actor.getCell(), direction, distance);
|
||||
MWBase::Environment::get().getWorld()->scaleObject(ptr, actor.getCellRef().getScale());
|
||||
|
||||
/*
|
||||
Start of tes3mp addition
|
||||
|
|
|
@ -393,32 +393,8 @@ namespace MWSound
|
|||
|
||||
void SoundManager::startRandomTitle()
|
||||
{
|
||||
std::vector<std::string> filelist;
|
||||
const std::vector<std::string> &filelist = mMusicFiles[mCurrentPlaylist];
|
||||
auto &tracklist = mMusicToPlay[mCurrentPlaylist];
|
||||
if (mMusicFiles.find(mCurrentPlaylist) == mMusicFiles.end())
|
||||
{
|
||||
const std::map<std::string, VFS::File*>& index = mVFS->getIndex();
|
||||
|
||||
std::string pattern = "Music/" + mCurrentPlaylist;
|
||||
mVFS->normalizeFilename(pattern);
|
||||
|
||||
std::map<std::string, VFS::File*>::const_iterator found = index.lower_bound(pattern);
|
||||
while (found != index.end())
|
||||
{
|
||||
if (found->first.size() >= pattern.size() && found->first.substr(0, pattern.size()) == pattern)
|
||||
filelist.push_back(found->first);
|
||||
else
|
||||
break;
|
||||
++found;
|
||||
}
|
||||
|
||||
mMusicFiles[mCurrentPlaylist] = filelist;
|
||||
}
|
||||
else
|
||||
filelist = mMusicFiles[mCurrentPlaylist];
|
||||
|
||||
if(filelist.empty())
|
||||
return;
|
||||
|
||||
// Do a Fisher-Yates shuffle
|
||||
|
||||
|
@ -454,6 +430,33 @@ namespace MWSound
|
|||
|
||||
void SoundManager::playPlaylist(const std::string &playlist)
|
||||
{
|
||||
if (mCurrentPlaylist == playlist)
|
||||
return;
|
||||
|
||||
if (mMusicFiles.find(playlist) == mMusicFiles.end())
|
||||
{
|
||||
std::vector<std::string> filelist;
|
||||
const std::map<std::string, VFS::File*>& index = mVFS->getIndex();
|
||||
|
||||
std::string pattern = "Music/" + playlist;
|
||||
mVFS->normalizeFilename(pattern);
|
||||
|
||||
std::map<std::string, VFS::File*>::const_iterator found = index.lower_bound(pattern);
|
||||
while (found != index.end())
|
||||
{
|
||||
if (found->first.size() >= pattern.size() && found->first.substr(0, pattern.size()) == pattern)
|
||||
filelist.push_back(found->first);
|
||||
else
|
||||
break;
|
||||
++found;
|
||||
}
|
||||
|
||||
mMusicFiles[playlist] = filelist;
|
||||
}
|
||||
|
||||
if (mMusicFiles[playlist].empty())
|
||||
return;
|
||||
|
||||
mCurrentPlaylist = playlist;
|
||||
startRandomTitle();
|
||||
}
|
||||
|
|
|
@ -1,7 +1,5 @@
|
|||
#include "fallback.hpp"
|
||||
|
||||
#include <iostream>
|
||||
|
||||
#include <boost/lexical_cast.hpp>
|
||||
|
||||
|
||||
|
@ -19,7 +17,6 @@ namespace Fallback
|
|||
std::map<std::string,std::string>::const_iterator it;
|
||||
if((it = mFallbackMap.find(fall)) == mFallbackMap.end())
|
||||
{
|
||||
std::cerr << "Warning: fallback value " << fall << " not found." << std::endl;
|
||||
return "";
|
||||
}
|
||||
return it->second;
|
||||
|
|
|
@ -63,28 +63,16 @@ std::string Misc::ResourceHelpers::correctResourcePath(const std::string &topLev
|
|||
|
||||
std::string origExt = correctedPath;
|
||||
|
||||
// since we know all (GOTY edition or less) textures end
|
||||
// in .dds, we change the extension
|
||||
bool changedToDds = changeExtensionToDds(correctedPath);
|
||||
if (vfs->exists(correctedPath))
|
||||
if (vfs->exists(origExt)
|
||||
|| (changeExtensionToDds(correctedPath) && vfs->exists(correctedPath)))
|
||||
return correctedPath;
|
||||
// if it turns out that the above wasn't true in all cases (not for vanilla, but maybe mods)
|
||||
// verify, and revert if false (this call succeeds quickly, but fails slowly)
|
||||
if (changedToDds && vfs->exists(origExt))
|
||||
return origExt;
|
||||
|
||||
// fall back to a resource in the top level directory if it exists
|
||||
std::string fallback = topLevelDirectory + "\\" + getBasename(correctedPath);
|
||||
if (vfs->exists(fallback))
|
||||
std::string fallback = topLevelDirectory + "\\" + getBasename(origExt);
|
||||
if (vfs->exists(fallback)
|
||||
|| (changeExtensionToDds(fallback) && vfs->exists(fallback)))
|
||||
return fallback;
|
||||
|
||||
if (changedToDds)
|
||||
{
|
||||
fallback = topLevelDirectory + "\\" + getBasename(origExt);
|
||||
if (vfs->exists(fallback))
|
||||
return fallback;
|
||||
}
|
||||
|
||||
return correctedPath;
|
||||
}
|
||||
|
||||
|
|
|
@ -1,28 +1,31 @@
|
|||
#include "rng.hpp"
|
||||
#include <cstdlib>
|
||||
#include <ctime>
|
||||
|
||||
#include <chrono>
|
||||
#include <random>
|
||||
|
||||
namespace Misc
|
||||
{
|
||||
|
||||
std::mt19937 Rng::generator = std::mt19937();
|
||||
|
||||
void Rng::init()
|
||||
{
|
||||
std::srand(static_cast<unsigned int>(std::time(NULL)));
|
||||
generator.seed(static_cast<unsigned int>(std::chrono::high_resolution_clock::now().time_since_epoch().count()));
|
||||
}
|
||||
|
||||
float Rng::rollProbability()
|
||||
{
|
||||
return static_cast<float>(std::rand() / (static_cast<double>(RAND_MAX)+1.0));
|
||||
return std::uniform_real_distribution<float>(0, 1 - std::numeric_limits<float>::epsilon())(generator);
|
||||
}
|
||||
|
||||
float Rng::rollClosedProbability()
|
||||
{
|
||||
return static_cast<float>(std::rand() / static_cast<double>(RAND_MAX));
|
||||
return std::uniform_real_distribution<float>(0, 1)(generator);
|
||||
}
|
||||
|
||||
int Rng::rollDice(int max)
|
||||
{
|
||||
return static_cast<int>((std::rand() / (static_cast<double>(RAND_MAX)+1.0)) * (max));
|
||||
return max > 0 ? std::uniform_int_distribution<int>(0, max - 1)(generator) : 0;
|
||||
}
|
||||
|
||||
}
|
||||
|
|
|
@ -2,6 +2,7 @@
|
|||
#define OPENMW_COMPONENTS_MISC_RNG_H
|
||||
|
||||
#include <cassert>
|
||||
#include <random>
|
||||
|
||||
namespace Misc
|
||||
{
|
||||
|
@ -13,6 +14,9 @@ class Rng
|
|||
{
|
||||
public:
|
||||
|
||||
/// create a RNG
|
||||
static std::mt19937 generator;
|
||||
|
||||
/// seed the RNG
|
||||
static void init();
|
||||
|
||||
|
|
|
@ -256,6 +256,7 @@ namespace mwmp
|
|||
{
|
||||
spellbookChanges.action = SpellbookChanges::Type::None;
|
||||
isWerewolf = false;
|
||||
exchangeFullInfo = false;
|
||||
displayCreatureName = false;
|
||||
resetStats = false;
|
||||
enforcedLogLevel = -1;
|
||||
|
@ -286,6 +287,8 @@ namespace mwmp
|
|||
// with the skill values themselves being stored in npcStats.mSkills
|
||||
std::vector<int> skillIndexChanges;
|
||||
|
||||
bool exchangeFullInfo;
|
||||
|
||||
SpellbookChanges spellbookChanges;
|
||||
QuickKeyChanges quickKeyChanges;
|
||||
JournalChanges journalChanges;
|
||||
|
|
|
@ -13,23 +13,34 @@ void PacketPlayerAttribute::Packet(RakNet::BitStream *bs, bool send)
|
|||
{
|
||||
PlayerPacket::Packet(bs, send);
|
||||
|
||||
uint32_t count;
|
||||
if (send)
|
||||
count = static_cast<uint32_t>(player->attributeIndexChanges.size());
|
||||
RW(player->exchangeFullInfo, send);
|
||||
|
||||
RW(count, send);
|
||||
|
||||
if (!send)
|
||||
if (player->exchangeFullInfo)
|
||||
{
|
||||
player->attributeIndexChanges.clear();
|
||||
player->attributeIndexChanges.resize(count);
|
||||
RW(player->creatureStats.mAttributes, send);
|
||||
RW(player->npcStats.mSkillIncrease, send);
|
||||
}
|
||||
|
||||
for (auto &&attributeIndex : player->attributeIndexChanges)
|
||||
else
|
||||
{
|
||||
RW(attributeIndex, send);
|
||||
uint32_t count;
|
||||
|
||||
RW(player->creatureStats.mAttributes[attributeIndex], send);
|
||||
RW(player->npcStats.mSkillIncrease[attributeIndex], send);
|
||||
if (send)
|
||||
count = static_cast<uint32_t>(player->attributeIndexChanges.size());
|
||||
|
||||
RW(count, send);
|
||||
|
||||
if (!send)
|
||||
{
|
||||
player->attributeIndexChanges.clear();
|
||||
player->attributeIndexChanges.resize(count);
|
||||
}
|
||||
|
||||
for (auto &&attributeIndex : player->attributeIndexChanges)
|
||||
{
|
||||
RW(attributeIndex, send);
|
||||
|
||||
RW(player->creatureStats.mAttributes[attributeIndex], send);
|
||||
RW(player->npcStats.mSkillIncrease[attributeIndex], send);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -1,4 +1,5 @@
|
|||
#include "PacketPlayerEquipment.hpp"
|
||||
|
||||
#include <components/openmw-mp/NetworkMessages.hpp>
|
||||
|
||||
using namespace mwmp;
|
||||
|
@ -12,25 +13,42 @@ void PacketPlayerEquipment::Packet(RakNet::BitStream *bs, bool send)
|
|||
{
|
||||
PlayerPacket::Packet(bs, send);
|
||||
|
||||
uint32_t count;
|
||||
if (send)
|
||||
count = static_cast<uint32_t>(player->equipmentIndexChanges.size());
|
||||
RW(player->exchangeFullInfo, send);
|
||||
|
||||
RW(count, send);
|
||||
|
||||
if (!send)
|
||||
if (player->exchangeFullInfo)
|
||||
{
|
||||
player->equipmentIndexChanges.clear();
|
||||
player->equipmentIndexChanges.resize(count);
|
||||
for (auto &&equipmentItem : player->equipmentItems)
|
||||
{
|
||||
ExchangeItemInformation(equipmentItem, send);
|
||||
}
|
||||
}
|
||||
|
||||
for (auto &&equipmentIndex : player->equipmentIndexChanges)
|
||||
else
|
||||
{
|
||||
RW(equipmentIndex, send);
|
||||
uint32_t count;
|
||||
if (send)
|
||||
count = static_cast<uint32_t>(player->equipmentIndexChanges.size());
|
||||
|
||||
RW(player->equipmentItems[equipmentIndex].refId, send);
|
||||
RW(player->equipmentItems[equipmentIndex].count, send);
|
||||
RW(player->equipmentItems[equipmentIndex].charge, send);
|
||||
RW(player->equipmentItems[equipmentIndex].enchantmentCharge, send);
|
||||
RW(count, send);
|
||||
|
||||
if (!send)
|
||||
{
|
||||
player->equipmentIndexChanges.clear();
|
||||
player->equipmentIndexChanges.resize(count);
|
||||
}
|
||||
|
||||
for (auto &&equipmentIndex : player->equipmentIndexChanges)
|
||||
{
|
||||
RW(equipmentIndex, send);
|
||||
ExchangeItemInformation(player->equipmentItems[equipmentIndex], send);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void PacketPlayerEquipment::ExchangeItemInformation(Item &item, bool send)
|
||||
{
|
||||
RW(item.refId, send);
|
||||
RW(item.count, send);
|
||||
RW(item.charge, send);
|
||||
RW(item.enchantmentCharge, send);
|
||||
}
|
||||
|
||||
|
|
|
@ -15,6 +15,7 @@ namespace mwmp
|
|||
PacketPlayerEquipment(RakNet::RakPeerInterface *peer);
|
||||
|
||||
void Packet(RakNet::BitStream *bs, bool send) override;
|
||||
void ExchangeItemInformation(Item &item, bool send);
|
||||
};
|
||||
}
|
||||
|
||||
|
|
|
@ -13,23 +13,32 @@ PacketPlayerSkill::PacketPlayerSkill(RakNet::RakPeerInterface *peer) : PlayerPac
|
|||
void PacketPlayerSkill::Packet(RakNet::BitStream *bs, bool send)
|
||||
{
|
||||
PlayerPacket::Packet(bs, send);
|
||||
|
||||
uint32_t count;
|
||||
|
||||
if (send)
|
||||
count = static_cast<uint32_t>(player->skillIndexChanges.size());
|
||||
RW(player->exchangeFullInfo, send);
|
||||
|
||||
RW(count, send);
|
||||
|
||||
if (!send)
|
||||
if (player->exchangeFullInfo)
|
||||
{
|
||||
player->skillIndexChanges.clear();
|
||||
player->skillIndexChanges.resize(count);
|
||||
RW(player->npcStats.mSkills, send);
|
||||
}
|
||||
|
||||
for (auto &&skillId : player->skillIndexChanges)
|
||||
else
|
||||
{
|
||||
RW(skillId, send);
|
||||
RW(player->npcStats.mSkills[skillId], send);
|
||||
uint32_t count;
|
||||
|
||||
if (send)
|
||||
count = static_cast<uint32_t>(player->skillIndexChanges.size());
|
||||
|
||||
RW(count, send);
|
||||
|
||||
if (!send)
|
||||
{
|
||||
player->skillIndexChanges.clear();
|
||||
player->skillIndexChanges.resize(count);
|
||||
}
|
||||
|
||||
for (auto &&skillId : player->skillIndexChanges)
|
||||
{
|
||||
RW(skillId, send);
|
||||
RW(player->npcStats.mSkills[skillId], send);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -1,4 +1,5 @@
|
|||
#include "PacketPlayerStatsDynamic.hpp"
|
||||
|
||||
#include <components/openmw-mp/NetworkMessages.hpp>
|
||||
|
||||
using namespace mwmp;
|
||||
|
@ -12,22 +13,32 @@ void PacketPlayerStatsDynamic::Packet(RakNet::BitStream *bs, bool send)
|
|||
{
|
||||
PlayerPacket::Packet(bs, send);
|
||||
|
||||
uint32_t count;
|
||||
if (send)
|
||||
count = static_cast<uint32_t>(player->statsDynamicIndexChanges.size());
|
||||
RW(player->exchangeFullInfo, send);
|
||||
|
||||
RW(count, send);
|
||||
|
||||
if (!send)
|
||||
if (player->exchangeFullInfo)
|
||||
{
|
||||
player->statsDynamicIndexChanges.clear();
|
||||
player->statsDynamicIndexChanges.resize(count);
|
||||
RW(player->creatureStats.mDynamic, send);
|
||||
}
|
||||
|
||||
for (auto &&statsDynamicIndex : player->statsDynamicIndexChanges)
|
||||
else
|
||||
{
|
||||
RW(statsDynamicIndex, send);
|
||||
uint32_t count;
|
||||
|
||||
RW(player->creatureStats.mDynamic[statsDynamicIndex], send);
|
||||
if (send)
|
||||
count = static_cast<uint32_t>(player->statsDynamicIndexChanges.size());
|
||||
|
||||
RW(count, send);
|
||||
|
||||
if (!send)
|
||||
{
|
||||
player->statsDynamicIndexChanges.clear();
|
||||
player->statsDynamicIndexChanges.resize(count);
|
||||
}
|
||||
|
||||
for (auto &&statsDynamicIndex : player->statsDynamicIndexChanges)
|
||||
{
|
||||
RW(statsDynamicIndex, send);
|
||||
|
||||
RW(player->creatureStats.mDynamic[statsDynamicIndex], send);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -3,10 +3,10 @@
|
|||
Copyright 2015 Alexandre Moine <nobrakal@gmail.com>
|
||||
Copyright 2017 Bret Curtis <psi29a@gmail.com>
|
||||
-->
|
||||
<component>
|
||||
<component type="desktop">
|
||||
<id>org.openmw.desktop</id>
|
||||
<metadata_license>CC0-1.0</metadata_license>
|
||||
<project_license> GPL-3.0 and MIT</project_license>
|
||||
<project_license>GPL-3.0 and MIT</project_license>
|
||||
<name>OpenMW</name>
|
||||
<summary>Unofficial open source engine re-implementation of the game Morrowind</summary>
|
||||
<description>
|
||||
|
@ -20,7 +20,6 @@ Copyright 2017 Bret Curtis <psi29a@gmail.com>
|
|||
You will still need the original game data to play OpenMW.
|
||||
</p>
|
||||
</description>
|
||||
|
||||
<screenshots>
|
||||
<screenshot type="default">
|
||||
<image>https://wiki.openmw.org/images/b/b2/Openmw_0.11.1_launcher_1.png</image>
|
||||
|
@ -34,7 +33,18 @@ Copyright 2017 Bret Curtis <psi29a@gmail.com>
|
|||
<image>https://wiki.openmw.org/images/5/5b/Screenshot_Vivec_seen_from_Ebonheart_0.35.png</image>
|
||||
<caption>Vivec seen from Ebonheart on OpenMW</caption>
|
||||
</screenshot>
|
||||
<screenshot>
|
||||
<image>http://wiki.openmw.org/images/a/a3/0.40_Screenshot-Balmora_3.png</image>
|
||||
<caption>Balmora at morning on OpenMW</caption>
|
||||
</screenshot>
|
||||
</screenshots>
|
||||
<categories>
|
||||
<category>Game</category>
|
||||
<category>RolePlaying</category>
|
||||
</categories>
|
||||
<releases>
|
||||
<release version="0.43.0" date="2017-12-05"/>
|
||||
</releases>
|
||||
<url type="homepage">https://openmw.org</url>
|
||||
<url type="bugtracker">https://bugs.openmw.org/</url>
|
||||
<url type="faq">https://openmw.org/faq/</url>
|
||||
|
|
Loading…
Reference in a new issue