Merge pull request #515 from TES3MP/0.7.0-alpha

0.7.0 alpha
pull/517/head
David Cernat 6 years ago committed by GitHub
commit d35026bbf5
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23

@ -537,7 +537,7 @@ void ActorFunctions::InitializeActorList(unsigned short pid) noexcept
void ActorFunctions::CopyLastActorListToStore() noexcept void ActorFunctions::CopyLastActorListToStore() noexcept
{ {
CopyLastActorListToStore(); CopyReceivedActorListToStore();
} }
unsigned int ActorFunctions::GetActorRefNumIndex(unsigned int index) noexcept unsigned int ActorFunctions::GetActorRefNumIndex(unsigned int index) noexcept

@ -1,38 +1,12 @@
#include "Miscellaneous.hpp" #include "Miscellaneous.hpp"
#include <components/misc/stringops.hpp>
#include <components/openmw-mp/Log.hpp> #include <components/openmw-mp/Log.hpp>
#include <apps/openmw-mp/Script/ScriptFunctions.hpp>
#include <apps/openmw-mp/Networking.hpp> #include <apps/openmw-mp/Networking.hpp>
#include <iostream> #include <iostream>
using namespace std; using namespace std;
static std::string tempFilename;
bool MiscellaneousFunctions::DoesFileExist(const char *filePath) noexcept
{
return boost::filesystem::exists(filePath);
}
const char *MiscellaneousFunctions::GetCaseInsensitiveFilename(const char *folderPath, const char *filename) noexcept
{
if (!boost::filesystem::exists(folderPath)) return "invalid";
boost::filesystem::directory_iterator end_itr; // default construction yields past-the-end
for (boost::filesystem::directory_iterator itr(folderPath); itr != end_itr; ++itr)
{
if (Misc::StringUtils::ciEqual(itr->path().filename().string(), filename))
{
tempFilename = itr->path().filename().string();
return tempFilename.c_str();
}
}
return "invalid";
}
unsigned int MiscellaneousFunctions::GetLastPlayerId() noexcept unsigned int MiscellaneousFunctions::GetLastPlayerId() noexcept
{ {
return Players::getLastPlayerId(); return Players::getLastPlayerId();
@ -47,13 +21,3 @@ void MiscellaneousFunctions::SetCurrentMpNum(int mpNum) noexcept
{ {
mwmp::Networking::getPtr()->setCurrentMpNum(mpNum); mwmp::Networking::getPtr()->setCurrentMpNum(mpNum);
} }
void MiscellaneousFunctions::LogMessage(unsigned short level, const char *message) noexcept
{
LOG_MESSAGE_SIMPLE(level, "[Script]: %s", message);
}
void MiscellaneousFunctions::LogAppend(unsigned short level, const char *message) noexcept
{
LOG_APPEND(level, "[Script]: %s", message);
}

@ -4,42 +4,15 @@
#include "../Types.hpp" #include "../Types.hpp"
#define MISCELLANEOUSAPI \ #define MISCELLANEOUSAPI \
{"DoesFileExist", MiscellaneousFunctions::DoesFileExist},\
{"GetCaseInsensitiveFilename", MiscellaneousFunctions::GetCaseInsensitiveFilename},\
\
{"GetLastPlayerId", MiscellaneousFunctions::GetLastPlayerId},\ {"GetLastPlayerId", MiscellaneousFunctions::GetLastPlayerId},\
\ \
{"GetCurrentMpNum", MiscellaneousFunctions::GetCurrentMpNum},\ {"GetCurrentMpNum", MiscellaneousFunctions::GetCurrentMpNum},\
{"SetCurrentMpNum", MiscellaneousFunctions::SetCurrentMpNum},\ {"SetCurrentMpNum", MiscellaneousFunctions::SetCurrentMpNum}
\
{"LogMessage", MiscellaneousFunctions::LogMessage},\
{"LogAppend", MiscellaneousFunctions::LogAppend}
class MiscellaneousFunctions class MiscellaneousFunctions
{ {
public: public:
/**
* \brief Check whether a certain file exists.
*
* This will be a case sensitive check on case sensitive filesystems.
*
* Whenever you want to enforce case insensitivity, use GetCaseInsensitiveFilename() instead.
*
* \return Whether the file exists or not.
*/
static bool DoesFileExist(const char *filePath) noexcept;
/**
* \brief Get the first filename in a folder that has a case insensitive match with the filename
* argument.
*
* This is used to retain case insensitivity when opening data files on Linux.
*
* \return The filename that matches.
*/
static const char *GetCaseInsensitiveFilename(const char *folderPath, const char *filename) noexcept;
/** /**
* \brief Get the last player ID currently connected to the server. * \brief Get the last player ID currently connected to the server.
* *
@ -75,30 +48,6 @@ public:
* \return void * \return void
*/ */
static void SetCurrentMpNum(int mpNum) noexcept; static void SetCurrentMpNum(int mpNum) noexcept;
/**
* \brief Write a log message with its own timestamp.
*
* It will have "[Script]:" prepended to it so as to mark it as a script-generated log message.
*
* \param level The logging level used (0 for LOG_VERBOSE, 1 for LOG_INFO, 2 for LOG_WARN,
* 3 for LOG_ERROR, 4 for LOG_FATAL).
* \param message The message logged.
* \return void
*/
static void LogMessage(unsigned short level, const char *message) noexcept;
/**
* \brief Write a log message without its own timestamp.
*
* It will have "[Script]:" prepended to it so as to mark it as a script-generated log message.
*
* \param level The logging level used (0 for LOG_VERBOSE, 1 for LOG_INFO, 2 for LOG_WARN,
* 3 for LOG_ERROR, 4 for LOG_FATAL).
* \param message The message logged.
* \return void
*/
static void LogAppend(unsigned short level, const char *message) noexcept;
}; };
#endif //OPENMW_MISCELLANEOUSAPI_HPP #endif //OPENMW_MISCELLANEOUSAPI_HPP

@ -1,5 +1,6 @@
#include "Server.hpp" #include "Server.hpp"
#include <components/misc/stringops.hpp>
#include <components/openmw-mp/NetworkMessages.hpp> #include <components/openmw-mp/NetworkMessages.hpp>
#include <components/openmw-mp/Log.hpp> #include <components/openmw-mp/Log.hpp>
#include <components/openmw-mp/Version.hpp> #include <components/openmw-mp/Version.hpp>
@ -9,6 +10,17 @@
#include <apps/openmw-mp/MasterClient.hpp> #include <apps/openmw-mp/MasterClient.hpp>
#include <Script/Script.hpp> #include <Script/Script.hpp>
static std::string tempFilename;
void ServerFunctions::LogMessage(unsigned short level, const char *message) noexcept
{
LOG_MESSAGE_SIMPLE(level, "[Script]: %s", message);
}
void ServerFunctions::LogAppend(unsigned short level, const char *message) noexcept
{
LOG_APPEND(level, "[Script]: %s", message);
}
void ServerFunctions::StopServer(int code) noexcept void ServerFunctions::StopServer(int code) noexcept
{ {
@ -35,6 +47,33 @@ void ServerFunctions::UnbanAddress(const char *ipAddress) noexcept
mwmp::Networking::getPtr()->unbanAddress(ipAddress); mwmp::Networking::getPtr()->unbanAddress(ipAddress);
} }
bool ServerFunctions::DoesFilePathExist(const char *filePath) noexcept
{
return boost::filesystem::exists(filePath);
}
const char *ServerFunctions::GetCaseInsensitiveFilename(const char *folderPath, const char *filename) noexcept
{
if (!boost::filesystem::exists(folderPath)) return "invalid";
boost::filesystem::directory_iterator end_itr; // default construction yields past-the-end
for (boost::filesystem::directory_iterator itr(folderPath); itr != end_itr; ++itr)
{
if (Misc::StringUtils::ciEqual(itr->path().filename().string(), filename))
{
tempFilename = itr->path().filename().string();
return tempFilename.c_str();
}
}
return "invalid";
}
const char* ServerFunctions::GetDataPath() noexcept
{
return Script::GetModDir();
}
const char *ServerFunctions::GetOperatingSystemType() noexcept const char *ServerFunctions::GetOperatingSystemType() noexcept
{ {
return Utils::getOperatingSystemType().c_str(); return Utils::getOperatingSystemType().c_str();
@ -137,34 +176,46 @@ void ServerFunctions::SetRuleValue(const char *key, double value) noexcept
mc->SetRuleValue(key, value); mc->SetRuleValue(key, value);
} }
void ServerFunctions::AddPluginHash(const char *pluginName, const char *hashStr) noexcept void ServerFunctions::AddDataFileRequirement(const char *dataFilename, const char *checksumString) noexcept
{ {
auto &samples = mwmp::Networking::getPtr()->getSamples(); auto &samples = mwmp::Networking::getPtr()->getSamples();
auto it = std::find_if(samples.begin(), samples.end(), [&pluginName](mwmp::PacketPreInit::PluginPair &item) { auto it = std::find_if(samples.begin(), samples.end(), [&dataFilename](mwmp::PacketPreInit::PluginPair &item) {
return item.first == pluginName; return item.first == dataFilename;
}); });
if (it != samples.end()) if (it != samples.end())
it->second.push_back((unsigned) std::stoul(hashStr)); it->second.push_back((unsigned) std::stoul(checksumString));
else else
{ {
mwmp::PacketPreInit::HashList hashList; mwmp::PacketPreInit::HashList checksumList;
unsigned hash = 0; unsigned checksum = 0;
if (strlen(hashStr) != 0) if (strlen(checksumString) != 0)
{ {
hash = (unsigned) std::stoul(hashStr); checksum = (unsigned) std::stoul(checksumString);
hashList.push_back(hash); checksumList.push_back(checksum);
} }
samples.emplace_back(pluginName, hashList); samples.emplace_back(dataFilename, checksumList);
auto mclient = mwmp::Networking::getPtr()->getMasterClient(); auto mclient = mwmp::Networking::getPtr()->getMasterClient();
if (mclient) if (mclient)
mclient->PushPlugin({pluginName, hash}); mclient->PushPlugin({dataFilename, checksum});
} }
} }
// All methods below are deprecated versions of methods from above
bool ServerFunctions::DoesFileExist(const char *filePath) noexcept
{
return DoesFilePathExist(filePath);
}
const char* ServerFunctions::GetModDir() noexcept const char* ServerFunctions::GetModDir() noexcept
{ {
return Script::GetModDir(); return GetDataPath();
}
void ServerFunctions::AddPluginHash(const char *pluginName, const char *checksumString) noexcept
{
AddDataFileRequirement(pluginName, checksumString);
} }

@ -4,12 +4,18 @@
#include "../Types.hpp" #include "../Types.hpp"
#define SERVERAPI \ #define SERVERAPI \
{"LogMessage", ServerFunctions::LogMessage},\
{"LogAppend", ServerFunctions::LogAppend},\
\
{"StopServer", ServerFunctions::StopServer},\ {"StopServer", ServerFunctions::StopServer},\
\ \
{"Kick", ServerFunctions::Kick},\ {"Kick", ServerFunctions::Kick},\
{"BanAddress", ServerFunctions::BanAddress},\ {"BanAddress", ServerFunctions::BanAddress},\
{"UnbanAddress", ServerFunctions::UnbanAddress},\ {"UnbanAddress", ServerFunctions::UnbanAddress},\
\ \
{"DoesFilePathExist", ServerFunctions::DoesFilePathExist},\
{"GetCaseInsensitiveFilename", ServerFunctions::GetCaseInsensitiveFilename},\
{"GetDataPath", ServerFunctions::GetDataPath},\
{"GetOperatingSystemType", ServerFunctions::GetOperatingSystemType},\ {"GetOperatingSystemType", ServerFunctions::GetOperatingSystemType},\
{"GetArchitectureType", ServerFunctions::GetArchitectureType},\ {"GetArchitectureType", ServerFunctions::GetArchitectureType},\
{"GetServerVersion", ServerFunctions::GetServerVersion},\ {"GetServerVersion", ServerFunctions::GetServerVersion},\
@ -29,13 +35,41 @@
{"SetScriptErrorIgnoringState", ServerFunctions::SetScriptErrorIgnoringState},\ {"SetScriptErrorIgnoringState", ServerFunctions::SetScriptErrorIgnoringState},\
{"SetRuleString", ServerFunctions::SetRuleString},\ {"SetRuleString", ServerFunctions::SetRuleString},\
{"SetRuleValue", ServerFunctions::SetRuleValue},\ {"SetRuleValue", ServerFunctions::SetRuleValue},\
{"AddPluginHash", ServerFunctions::AddPluginHash},\ \
{"GetModDir", ServerFunctions::GetModDir} {"AddDataFileRequirement", ServerFunctions::AddDataFileRequirement},\
\
{"DoesFileExist", ServerFunctions::DoesFileExist},\
{"GetModDir", ServerFunctions::GetModDir},\
{"AddPluginHash", ServerFunctions::AddPluginHash}
class ServerFunctions class ServerFunctions
{ {
public: public:
/**
* \brief Write a log message with its own timestamp.
*
* It will have "[Script]:" prepended to it so as to mark it as a script-generated log message.
*
* \param level The logging level used (0 for LOG_VERBOSE, 1 for LOG_INFO, 2 for LOG_WARN,
* 3 for LOG_ERROR, 4 for LOG_FATAL).
* \param message The message logged.
* \return void
*/
static void LogMessage(unsigned short level, const char *message) noexcept;
/**
* \brief Write a log message without its own timestamp.
*
* It will have "[Script]:" prepended to it so as to mark it as a script-generated log message.
*
* \param level The logging level used (0 for LOG_VERBOSE, 1 for LOG_INFO, 2 for LOG_WARN,
* 3 for LOG_ERROR, 4 for LOG_FATAL).
* \param message The message logged.
* \return void
*/
static void LogAppend(unsigned short level, const char *message) noexcept;
/** /**
* \brief Shut down the server. * \brief Shut down the server.
* *
@ -68,6 +102,34 @@ public:
*/ */
static void UnbanAddress(const char *ipAddress) noexcept; static void UnbanAddress(const char *ipAddress) noexcept;
/**
* \brief Check whether a certain file path exists.
*
* This will be a case sensitive check on case sensitive filesystems.
*
* Whenever you want to enforce case insensitivity, use GetCaseInsensitiveFilename() instead.
*
* \return Whether the file exists or not.
*/
static bool DoesFilePathExist(const char *filePath) noexcept;
/**
* \brief Get the first filename in a folder that has a case insensitive match with the filename
* argument.
*
* This is used to retain case insensitivity when opening data files on Linux.
*
* \return The filename that matches.
*/
static const char *GetCaseInsensitiveFilename(const char *folderPath, const char *filename) noexcept;
/**
* \brief Get the path of the server's data folder.
*
* \return The data path.
*/
static const char *GetDataPath() noexcept;
/** /**
* \brief Get the type of the operating system used by the server. * \brief Get the type of the operating system used by the server.
* *
@ -119,7 +181,7 @@ public:
/** /**
* \brief Get the port used by the server. * \brief Get the port used by the server.
* *
* \return Port * \return The port.
*/ */
static unsigned short GetPort() noexcept; static unsigned short GetPort() noexcept;
@ -220,13 +282,24 @@ public:
static void SetRuleValue(const char *key, double value) noexcept; static void SetRuleValue(const char *key, double value) noexcept;
/** /**
* \brief Adds plugins to the internal server structure to validate players. * \brief Add a data file and a corresponding CRC32 checksum to the data file loadout
* @param pluginName Name with extension of the plugin or master file. * that connecting clients need to match.
* @param hash Hash string *
* It can be used multiple times to set multiple checksums for the same data file.
*
* Note: If an empty string is provided for the checksum, a checksum will not be
* required for that data file.
*
* @param dataFilename The filename of the data file.
* @param checksumString A string with the CRC32 checksum required.
*/ */
static void AddPluginHash(const char *pluginName, const char *hash) noexcept; static void AddDataFileRequirement(const char *dataFilename, const char *checksumString) noexcept;
// All methods below are deprecated versions of methods from above
static bool DoesFileExist(const char *filePath) noexcept;
static const char *GetModDir() noexcept; static const char *GetModDir() noexcept;
static void AddPluginHash(const char *pluginName, const char *checksumString) noexcept;
}; };
#endif //OPENMW_SERVERAPI_HPP #endif //OPENMW_SERVERAPI_HPP

@ -201,6 +201,17 @@ int StatsFunctions::GetAttributeModifier(unsigned short pid, unsigned short attr
return player->creatureStats.mAttributes[attributeId].mMod; return player->creatureStats.mAttributes[attributeId].mMod;
} }
double StatsFunctions::GetAttributeDamage(unsigned short pid, unsigned short attributeId) noexcept
{
Player *player;
GET_PLAYER(pid, player, 0);
if (attributeId >= Attribute::Length)
return 0;
return player->creatureStats.mAttributes[attributeId].mDamage;
}
int StatsFunctions::GetSkillBase(unsigned short pid, unsigned short skillId) noexcept int StatsFunctions::GetSkillBase(unsigned short pid, unsigned short skillId) noexcept
{ {
Player *player; Player *player;
@ -223,6 +234,17 @@ int StatsFunctions::GetSkillModifier(unsigned short pid, unsigned short skillId)
return player->npcStats.mSkills[skillId].mMod; return player->npcStats.mSkills[skillId].mMod;
} }
double StatsFunctions::GetSkillDamage(unsigned short pid, unsigned short skillId) noexcept
{
Player *player;
GET_PLAYER(pid, player, 0);
if (skillId >= Skill::Length)
return 0;
return player->npcStats.mSkills[skillId].mDamage;
}
double StatsFunctions::GetSkillProgress(unsigned short pid, unsigned short skillId) noexcept double StatsFunctions::GetSkillProgress(unsigned short pid, unsigned short skillId) noexcept
{ {
Player *player; Player *player;
@ -437,6 +459,20 @@ void StatsFunctions::ClearAttributeModifier(unsigned short pid, unsigned short a
player->attributeIndexChanges.push_back(attributeId); player->attributeIndexChanges.push_back(attributeId);
} }
void StatsFunctions::SetAttributeDamage(unsigned short pid, unsigned short attributeId, double value) noexcept
{
Player *player;
GET_PLAYER(pid, player, );
if (attributeId >= Attribute::Length)
return;
player->creatureStats.mAttributes[attributeId].mDamage = value;
if (!Utils::vectorContains(player->attributeIndexChanges, attributeId))
player->attributeIndexChanges.push_back(attributeId);
}
void StatsFunctions::SetSkillBase(unsigned short pid, unsigned short skillId, int value) noexcept void StatsFunctions::SetSkillBase(unsigned short pid, unsigned short skillId, int value) noexcept
{ {
Player *player; Player *player;
@ -465,6 +501,20 @@ void StatsFunctions::ClearSkillModifier(unsigned short pid, unsigned short skill
player->skillIndexChanges.push_back(skillId); player->skillIndexChanges.push_back(skillId);
} }
void StatsFunctions::SetSkillDamage(unsigned short pid, unsigned short skillId, double value) noexcept
{
Player *player;
GET_PLAYER(pid, player, );
if (skillId >= Skill::Length)
return;
player->npcStats.mSkills[skillId].mDamage = value;
if (!Utils::vectorContains(player->skillIndexChanges, skillId))
player->skillIndexChanges.push_back(skillId);
}
void StatsFunctions::SetSkillProgress(unsigned short pid, unsigned short skillId, double value) noexcept void StatsFunctions::SetSkillProgress(unsigned short pid, unsigned short skillId, double value) noexcept
{ {
Player *player; Player *player;

@ -30,9 +30,11 @@
\ \
{"GetAttributeBase", StatsFunctions::GetAttributeBase},\ {"GetAttributeBase", StatsFunctions::GetAttributeBase},\
{"GetAttributeModifier", StatsFunctions::GetAttributeModifier},\ {"GetAttributeModifier", StatsFunctions::GetAttributeModifier},\
{"GetAttributeDamage", StatsFunctions::GetAttributeDamage},\
\ \
{"GetSkillBase", StatsFunctions::GetSkillBase},\ {"GetSkillBase", StatsFunctions::GetSkillBase},\
{"GetSkillModifier", StatsFunctions::GetSkillModifier},\ {"GetSkillModifier", StatsFunctions::GetSkillModifier},\
{"GetSkillDamage", StatsFunctions::GetSkillDamage},\
{"GetSkillProgress", StatsFunctions::GetSkillProgress},\ {"GetSkillProgress", StatsFunctions::GetSkillProgress},\
{"GetSkillIncrease", StatsFunctions::GetSkillIncrease},\ {"GetSkillIncrease", StatsFunctions::GetSkillIncrease},\
\ \
@ -58,9 +60,11 @@
\ \
{"SetAttributeBase", StatsFunctions::SetAttributeBase},\ {"SetAttributeBase", StatsFunctions::SetAttributeBase},\
{"ClearAttributeModifier", StatsFunctions::ClearAttributeModifier},\ {"ClearAttributeModifier", StatsFunctions::ClearAttributeModifier},\
{"SetAttributeDamage", StatsFunctions::SetAttributeDamage},\
\ \
{"SetSkillBase", StatsFunctions::SetSkillBase},\ {"SetSkillBase", StatsFunctions::SetSkillBase},\
{"ClearSkillModifier", StatsFunctions::ClearSkillModifier},\ {"ClearSkillModifier", StatsFunctions::ClearSkillModifier},\
{"SetSkillDamage", StatsFunctions::SetSkillDamage},\
{"SetSkillProgress", StatsFunctions::SetSkillProgress},\ {"SetSkillProgress", StatsFunctions::SetSkillProgress},\
{"SetSkillIncrease", StatsFunctions::SetSkillIncrease},\ {"SetSkillIncrease", StatsFunctions::SetSkillIncrease},\
\ \
@ -267,6 +271,16 @@ public:
*/ */
static int GetAttributeModifier(unsigned short pid, unsigned short attributeId) noexcept; static int GetAttributeModifier(unsigned short pid, unsigned short attributeId) noexcept;
/**
* \brief Get the amount of damage (as caused through the Damage Attribute effect)
* to a player's attribute.
*
* \param pid The player ID.
* \param attributeId The attribute ID.
* \return The amount of damage to the attribute.
*/
static double GetAttributeDamage(unsigned short pid, unsigned short attributeId) noexcept;
/** /**
* \brief Get the base value of a player's skill. * \brief Get the base value of a player's skill.
* *
@ -285,6 +299,16 @@ public:
*/ */
static int GetSkillModifier(unsigned short pid, unsigned short skillId) noexcept; static int GetSkillModifier(unsigned short pid, unsigned short skillId) noexcept;
/**
* \brief Get the amount of damage (as caused through the Damage Skill effect)
* to a player's skill.
*
* \param pid The player ID.
* \param skillId The skill ID.
* \return The amount of damage to the skill.
*/
static double GetSkillDamage(unsigned short pid, unsigned short skillId) noexcept;
/** /**
* \brief Get the progress the player has made towards increasing a certain skill by 1. * \brief Get the progress the player has made towards increasing a certain skill by 1.
* *
@ -477,6 +501,17 @@ public:
*/ */
static void ClearAttributeModifier(unsigned short pid, unsigned short attributeId) noexcept; static void ClearAttributeModifier(unsigned short pid, unsigned short attributeId) noexcept;
/**
* \brief Set the amount of damage (as caused through the Damage Attribute effect) to
* a player's attribute.
*
* \param pid The player ID.
* \param attributeId The attribute ID.
* \param value The amount of damage to the player's attribute.
* \return void
*/
static void SetAttributeDamage(unsigned short pid, unsigned short attributeId, double value) noexcept;
/** /**
* \brief Set the base value of a player's skill. * \brief Set the base value of a player's skill.
* *
@ -501,6 +536,17 @@ public:
*/ */
static void ClearSkillModifier(unsigned short pid, unsigned short skillId) noexcept; static void ClearSkillModifier(unsigned short pid, unsigned short skillId) noexcept;
/**
* \brief Set the amount of damage (as caused through the Damage Skill effect) to
* a player's skill.
*
* \param pid The player ID.
* \param skillId The skill ID.
* \param value The amount of damage to the player's skill.
* \return void
*/
static void SetSkillDamage(unsigned short pid, unsigned short skillId, double value) noexcept;
/** /**
* \brief Set the progress the player has made towards increasing a certain skill by 1. * \brief Set the progress the player has made towards increasing a certain skill by 1.
* *

@ -284,6 +284,7 @@ void LocalPlayer::updateAttributes(bool forceUpdate)
{ {
if (ptrNpcStats.getAttribute(i).getBase() != creatureStats.mAttributes[i].mBase || 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.getAttribute(i).getDamage() != creatureStats.mAttributes[i].mDamage ||
ptrNpcStats.getSkillIncrease(i) != npcStats.mSkillIncrease[i] || ptrNpcStats.getSkillIncrease(i) != npcStats.mSkillIncrease[i] ||
forceUpdate) forceUpdate)
{ {
@ -318,6 +319,7 @@ void LocalPlayer::updateSkills(bool forceUpdate)
// Update a skill if its base value has changed at all or its progress has changed enough // 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 || if (ptrNpcStats.getSkill(i).getBase() != npcStats.mSkills[i].mBase ||
ptrNpcStats.getSkill(i).getModifier() != npcStats.mSkills[i].mMod || ptrNpcStats.getSkill(i).getModifier() != npcStats.mSkills[i].mMod ||
ptrNpcStats.getSkill(i).getDamage() != npcStats.mSkills[i].mDamage ||
abs(ptrNpcStats.getSkill(i).getProgress() - npcStats.mSkills[i].mProgress) > 0.75 || abs(ptrNpcStats.getSkill(i).getProgress() - npcStats.mSkills[i].mProgress) > 0.75 ||
forceUpdate) forceUpdate)
{ {

Loading…
Cancel
Save