forked from mirror/openmw-tes3mp
commit
d35026bbf5
8 changed files with 243 additions and 108 deletions
|
@ -537,7 +537,7 @@ void ActorFunctions::InitializeActorList(unsigned short pid) noexcept
|
|||
|
||||
void ActorFunctions::CopyLastActorListToStore() noexcept
|
||||
{
|
||||
CopyLastActorListToStore();
|
||||
CopyReceivedActorListToStore();
|
||||
}
|
||||
|
||||
unsigned int ActorFunctions::GetActorRefNumIndex(unsigned int index) noexcept
|
||||
|
|
|
@ -1,38 +1,12 @@
|
|||
#include "Miscellaneous.hpp"
|
||||
|
||||
#include <components/misc/stringops.hpp>
|
||||
#include <components/openmw-mp/Log.hpp>
|
||||
|
||||
#include <apps/openmw-mp/Script/ScriptFunctions.hpp>
|
||||
#include <apps/openmw-mp/Networking.hpp>
|
||||
|
||||
#include <iostream>
|
||||
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
|
||||
{
|
||||
return Players::getLastPlayerId();
|
||||
|
@ -47,13 +21,3 @@ void MiscellaneousFunctions::SetCurrentMpNum(int mpNum) noexcept
|
|||
{
|
||||
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"
|
||||
|
||||
#define MISCELLANEOUSAPI \
|
||||
{"DoesFileExist", MiscellaneousFunctions::DoesFileExist},\
|
||||
{"GetCaseInsensitiveFilename", MiscellaneousFunctions::GetCaseInsensitiveFilename},\
|
||||
\
|
||||
{"GetLastPlayerId", MiscellaneousFunctions::GetLastPlayerId},\
|
||||
\
|
||||
{"GetCurrentMpNum", MiscellaneousFunctions::GetCurrentMpNum},\
|
||||
{"SetCurrentMpNum", MiscellaneousFunctions::SetCurrentMpNum},\
|
||||
\
|
||||
{"LogMessage", MiscellaneousFunctions::LogMessage},\
|
||||
{"LogAppend", MiscellaneousFunctions::LogAppend}
|
||||
{"SetCurrentMpNum", MiscellaneousFunctions::SetCurrentMpNum}
|
||||
|
||||
class MiscellaneousFunctions
|
||||
{
|
||||
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.
|
||||
*
|
||||
|
@ -75,30 +48,6 @@ public:
|
|||
* \return void
|
||||
*/
|
||||
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
|
||||
|
|
|
@ -1,5 +1,6 @@
|
|||
#include "Server.hpp"
|
||||
|
||||
#include <components/misc/stringops.hpp>
|
||||
#include <components/openmw-mp/NetworkMessages.hpp>
|
||||
#include <components/openmw-mp/Log.hpp>
|
||||
#include <components/openmw-mp/Version.hpp>
|
||||
|
@ -9,6 +10,17 @@
|
|||
#include <apps/openmw-mp/MasterClient.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
|
||||
{
|
||||
|
@ -35,6 +47,33 @@ void ServerFunctions::UnbanAddress(const char *ipAddress) noexcept
|
|||
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
|
||||
{
|
||||
return Utils::getOperatingSystemType().c_str();
|
||||
|
@ -137,34 +176,46 @@ void ServerFunctions::SetRuleValue(const char *key, double value) noexcept
|
|||
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 it = std::find_if(samples.begin(), samples.end(), [&pluginName](mwmp::PacketPreInit::PluginPair &item) {
|
||||
return item.first == pluginName;
|
||||
auto it = std::find_if(samples.begin(), samples.end(), [&dataFilename](mwmp::PacketPreInit::PluginPair &item) {
|
||||
return item.first == dataFilename;
|
||||
});
|
||||
if (it != samples.end())
|
||||
it->second.push_back((unsigned) std::stoul(hashStr));
|
||||
it->second.push_back((unsigned) std::stoul(checksumString));
|
||||
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);
|
||||
hashList.push_back(hash);
|
||||
checksum = (unsigned) std::stoul(checksumString);
|
||||
checksumList.push_back(checksum);
|
||||
}
|
||||
samples.emplace_back(pluginName, hashList);
|
||||
samples.emplace_back(dataFilename, checksumList);
|
||||
|
||||
auto mclient = mwmp::Networking::getPtr()->getMasterClient();
|
||||
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
|
||||
{
|
||||
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"
|
||||
|
||||
#define SERVERAPI \
|
||||
{"LogMessage", ServerFunctions::LogMessage},\
|
||||
{"LogAppend", ServerFunctions::LogAppend},\
|
||||
\
|
||||
{"StopServer", ServerFunctions::StopServer},\
|
||||
\
|
||||
{"Kick", ServerFunctions::Kick},\
|
||||
{"BanAddress", ServerFunctions::BanAddress},\
|
||||
{"UnbanAddress", ServerFunctions::UnbanAddress},\
|
||||
\
|
||||
{"DoesFilePathExist", ServerFunctions::DoesFilePathExist},\
|
||||
{"GetCaseInsensitiveFilename", ServerFunctions::GetCaseInsensitiveFilename},\
|
||||
{"GetDataPath", ServerFunctions::GetDataPath},\
|
||||
{"GetOperatingSystemType", ServerFunctions::GetOperatingSystemType},\
|
||||
{"GetArchitectureType", ServerFunctions::GetArchitectureType},\
|
||||
{"GetServerVersion", ServerFunctions::GetServerVersion},\
|
||||
|
@ -29,13 +35,41 @@
|
|||
{"SetScriptErrorIgnoringState", ServerFunctions::SetScriptErrorIgnoringState},\
|
||||
{"SetRuleString", ServerFunctions::SetRuleString},\
|
||||
{"SetRuleValue", ServerFunctions::SetRuleValue},\
|
||||
{"AddPluginHash", ServerFunctions::AddPluginHash},\
|
||||
{"GetModDir", ServerFunctions::GetModDir}
|
||||
\
|
||||
{"AddDataFileRequirement", ServerFunctions::AddDataFileRequirement},\
|
||||
\
|
||||
{"DoesFileExist", ServerFunctions::DoesFileExist},\
|
||||
{"GetModDir", ServerFunctions::GetModDir},\
|
||||
{"AddPluginHash", ServerFunctions::AddPluginHash}
|
||||
|
||||
class ServerFunctions
|
||||
{
|
||||
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.
|
||||
*
|
||||
|
@ -68,6 +102,34 @@ public:
|
|||
*/
|
||||
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.
|
||||
*
|
||||
|
@ -119,7 +181,7 @@ public:
|
|||
/**
|
||||
* \brief Get the port used by the server.
|
||||
*
|
||||
* \return Port
|
||||
* \return The port.
|
||||
*/
|
||||
static unsigned short GetPort() noexcept;
|
||||
|
||||
|
@ -220,13 +282,24 @@ public:
|
|||
static void SetRuleValue(const char *key, double value) noexcept;
|
||||
|
||||
/**
|
||||
* \brief Adds plugins to the internal server structure to validate players.
|
||||
* @param pluginName Name with extension of the plugin or master file.
|
||||
* @param hash Hash string
|
||||
* \brief Add a data file and a corresponding CRC32 checksum to the data file loadout
|
||||
* that connecting clients need to match.
|
||||
*
|
||||
* 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 void AddPluginHash(const char *pluginName, const char *checksumString) noexcept;
|
||||
};
|
||||
|
||||
#endif //OPENMW_SERVERAPI_HPP
|
||||
|
|
|
@ -201,6 +201,17 @@ int StatsFunctions::GetAttributeModifier(unsigned short pid, unsigned short attr
|
|||
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
|
||||
{
|
||||
Player *player;
|
||||
|
@ -223,6 +234,17 @@ int StatsFunctions::GetSkillModifier(unsigned short pid, unsigned short skillId)
|
|||
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
|
||||
{
|
||||
Player *player;
|
||||
|
@ -437,6 +459,20 @@ void StatsFunctions::ClearAttributeModifier(unsigned short pid, unsigned short a
|
|||
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
|
||||
{
|
||||
Player *player;
|
||||
|
@ -465,6 +501,20 @@ void StatsFunctions::ClearSkillModifier(unsigned short pid, unsigned short skill
|
|||
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
|
||||
{
|
||||
Player *player;
|
||||
|
|
|
@ -30,9 +30,11 @@
|
|||
\
|
||||
{"GetAttributeBase", StatsFunctions::GetAttributeBase},\
|
||||
{"GetAttributeModifier", StatsFunctions::GetAttributeModifier},\
|
||||
{"GetAttributeDamage", StatsFunctions::GetAttributeDamage},\
|
||||
\
|
||||
{"GetSkillBase", StatsFunctions::GetSkillBase},\
|
||||
{"GetSkillModifier", StatsFunctions::GetSkillModifier},\
|
||||
{"GetSkillDamage", StatsFunctions::GetSkillDamage},\
|
||||
{"GetSkillProgress", StatsFunctions::GetSkillProgress},\
|
||||
{"GetSkillIncrease", StatsFunctions::GetSkillIncrease},\
|
||||
\
|
||||
|
@ -58,9 +60,11 @@
|
|||
\
|
||||
{"SetAttributeBase", StatsFunctions::SetAttributeBase},\
|
||||
{"ClearAttributeModifier", StatsFunctions::ClearAttributeModifier},\
|
||||
{"SetAttributeDamage", StatsFunctions::SetAttributeDamage},\
|
||||
\
|
||||
{"SetSkillBase", StatsFunctions::SetSkillBase},\
|
||||
{"ClearSkillModifier", StatsFunctions::ClearSkillModifier},\
|
||||
{"SetSkillDamage", StatsFunctions::SetSkillDamage},\
|
||||
{"SetSkillProgress", StatsFunctions::SetSkillProgress},\
|
||||
{"SetSkillIncrease", StatsFunctions::SetSkillIncrease},\
|
||||
\
|
||||
|
@ -267,6 +271,16 @@ public:
|
|||
*/
|
||||
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.
|
||||
*
|
||||
|
@ -285,6 +299,16 @@ public:
|
|||
*/
|
||||
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.
|
||||
*
|
||||
|
@ -477,6 +501,17 @@ public:
|
|||
*/
|
||||
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.
|
||||
*
|
||||
|
@ -501,6 +536,17 @@ public:
|
|||
*/
|
||||
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.
|
||||
*
|
||||
|
|
|
@ -284,6 +284,7 @@ void LocalPlayer::updateAttributes(bool forceUpdate)
|
|||
{
|
||||
if (ptrNpcStats.getAttribute(i).getBase() != creatureStats.mAttributes[i].mBase ||
|
||||
ptrNpcStats.getAttribute(i).getModifier() != creatureStats.mAttributes[i].mMod ||
|
||||
ptrNpcStats.getAttribute(i).getDamage() != creatureStats.mAttributes[i].mDamage ||
|
||||
ptrNpcStats.getSkillIncrease(i) != npcStats.mSkillIncrease[i] ||
|
||||
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
|
||||
if (ptrNpcStats.getSkill(i).getBase() != npcStats.mSkills[i].mBase ||
|
||||
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 ||
|
||||
forceUpdate)
|
||||
{
|
||||
|
|
Loading…
Reference in a new issue