Merge branch 'master' into web_interface

This commit is contained in:
KimLS 2014-08-18 18:36:31 -07:00
commit a602640188
35 changed files with 2650 additions and 2604 deletions

View File

@ -28,7 +28,7 @@ Further instructions on building the source can be found on the
Bug reports
---
Please use the [issue tracker](issue-tracker) provided by GitHub to send us bug
Please use the [issue tracker](https://github.com/EQEmu/Server/issues) provided by GitHub to send us bug
reports or feature requests.
The [EQEmu Forums](http://www.eqemulator.org/forums/) also have forums to submit

View File

@ -1,5 +1,20 @@
EQEMu Changelog (Started on Sept 24, 2003 15:50)
-------------------------------------------------------
== 08/16/2014 ==
KLS: (addmoreice) Trying out some unstable DB changes. Do backup your database before trying them as master will be considered unstable for a few days at least.
Uleat (Noudness): Fixed a floating-point comparison error that led to the notorious 'client bounce' (this is not related to the
'mob falling' due to not having maps installed.) This fix also eliminates a sizeable amount of unnecessary out-going packets due
to invalid orientation corrections.
Note: This patch is probably of significant enough importance that admins may wish to manually apply this to older server builds.
The number of packets reduced per second should be approximately (num_stationary_close_clients * (num_close_clients - 1)). This will
likely have the most effect in zones like: Nexus, Bazaar, Guilds (Halls) and RAID INSTANCES - where players don't move around a lot.
== 08/15/2014 ==
Uleat: Reactivated the Bot::Spawn() code for sending post-spawn wear change updates..temporary until I can sort out the proper usage.
== 08/13/2014 ==
Uleat (Kingly_Krab): Fix for bot chest armor graphic glitch. (fix also caused RoF #wc to work properly)
== 08/02/2014 ==
Kayen: Implemented spell_news fields
- npc_no_los (check if LOS is required for spells)

View File

@ -175,14 +175,14 @@ void ImportSkillCaps(SharedDatabase *db) {
continue;
}
std::string sql;
int class_id, skill_id, level, cap;
class_id = atoi(split[0].c_str());
skill_id = atoi(split[1].c_str());
level = atoi(split[2].c_str());
cap = atoi(split[3].c_str());
StringFormat(sql, "INSERT INTO skill_caps(class, skillID, level, cap) VALUES(%d, %d, %d, %d)",
std::string sql = StringFormat("INSERT INTO skill_caps(class, skillID, level, cap) VALUES(%d, %d, %d, %d)",
class_id, skill_id, level, cap);
db->RunQuery(sql.c_str(), (uint32)sql.length());
@ -226,7 +226,7 @@ void ImportBaseData(SharedDatabase *db) {
mana_fac = atof(split[8].c_str());
end_fac = atof(split[9].c_str());
StringFormat(sql, "INSERT INTO base_data(level, class, hp, mana, end, unk1, unk2, hp_fac, "
sql = StringFormat("INSERT INTO base_data(level, class, hp, mana, end, unk1, unk2, hp_fac, "
"mana_fac, end_fac) VALUES(%d, %d, %f, %f, %f, %f, %f, %f, %f, %f)",
level, class_id, hp, mana, end, unk1, unk2, hp_fac, mana_fac, end_fac);

View File

@ -916,8 +916,7 @@ void Inventory::dumpItemCollection(const std::map<int16, ItemInst*> &collection)
if (!inst || !inst->GetItem())
continue;
std::string slot;
StringFormat(slot, "Slot %d: %s (%d)", it->first, it->second->GetItem()->Name, (inst->GetCharges() <= 0) ? 1 : inst->GetCharges());
std::string slot = StringFormat("Slot %d: %s (%d)", it->first, it->second->GetItem()->Name, (inst->GetCharges() <= 0) ? 1 : inst->GetCharges());
std::cout << slot << std::endl;
dumpBagContents(inst, &it);
@ -936,8 +935,7 @@ void Inventory::dumpBagContents(ItemInst *inst, iter_inst *it) {
if (!baginst || !baginst->GetItem())
continue;
std::string subSlot;
StringFormat(subSlot, " Slot %d: %s (%d)", Inventory::CalcSlotId((*it)->first, itb->first),
std::string subSlot = StringFormat(" Slot %d: %s (%d)", Inventory::CalcSlotId((*it)->first, itb->first),
baginst->GetItem()->Name, (baginst->GetCharges() <= 0) ? 1 : baginst->GetCharges());
std::cout << subSlot << std::endl;
}

View File

@ -103,7 +103,8 @@ int NewFloatToEQ13(float d);
int FloatToEQ19(float d);
int FloatToEQH(float d);
// macro to catch fp errors (provided by noudness)
#define FCMP(a,b) (fabs(a-b) < FLT_EPSILON)
#define _ITOA_BUFLEN 25
const char *itoa(int num); //not thread safe

View File

@ -10,35 +10,24 @@ MySQLRequestResult::MySQLRequestResult()
MySQLRequestResult::MySQLRequestResult(MYSQL_RES* result, uint32 rowsAffected, uint32 rowCount, uint32 columnCount, uint32 lastInsertedID, uint32 errorNumber, char *errorBuffer)
: m_CurrentRow(result), m_OneBeyondRow()
{
if (errorBuffer != nullptr)
m_Success = false;
else if (errorBuffer == nullptr && result == nullptr)
{
m_Success = false;
#ifdef _EQDEBUG
std::cout << "DB Query Error: No Result" << std::endl;
#endif
m_ErrorNumber = UINT_MAX;
m_ErrorBuffer = new char[MYSQL_ERRMSG_SIZE];
strcpy(m_ErrorBuffer, "DBcore::RunQuery: No Result");
}
else
m_Success = true;
m_Result = result;
m_ErrorBuffer = errorBuffer;
m_Result = result;
m_RowsAffected = rowsAffected;
m_RowCount = rowCount;
m_ColumnCount = columnCount;
// If we actually need the column length / fields it will be
// requested at that time, no need to pull it in just to cache it.
// Normal usage would have it as nullptr most likely anyways.
m_ColumnLengths = nullptr;
m_Fields = nullptr;
m_LastInsertedID = lastInsertedID;
m_ErrorNumber = errorNumber;
// If we actually need the column length / fields it will be
// requested at that time, no need to pull it in just to cache it.
// Normal usage would have it as nullptr most likely anyways.
m_ColumnLengths = nullptr;
m_Fields = nullptr;
if (errorBuffer != nullptr)
m_Success = false;
m_Success = true;
m_ErrorNumber = errorNumber;
m_ErrorBuffer = errorBuffer;
}
void MySQLRequestResult::FreeInternals()
@ -113,7 +102,7 @@ MySQLRequestResult::MySQLRequestResult(MySQLRequestResult&& moveItem)
m_ColumnLengths = moveItem.m_ColumnLengths;
m_Fields = moveItem.m_Fields;
// Keeps deconstructor from double freeing
// Keeps deconstructor from double freeing
// pre move instance.
moveItem.ZeroOut();
}
@ -140,8 +129,8 @@ MySQLRequestResult& MySQLRequestResult::operator=(MySQLRequestResult&& other)
m_ColumnLengths = other.m_ColumnLengths;
m_Fields = other.m_Fields;
// Keeps deconstructor from double freeing
// Keeps deconstructor from double freeing
// pre move instance.
other.ZeroOut();
return *this;
}
}

View File

@ -1,6 +1,6 @@
#include "MySQLRequestRow.h"
MySQLRequestRow::MySQLRequestRow(const MySQLRequestRow& row)
MySQLRequestRow::MySQLRequestRow(const MySQLRequestRow& row)
: m_Result(row.m_Result), m_MySQLRow(row.m_MySQLRow)
{
}
@ -26,13 +26,17 @@ MySQLRequestRow& MySQLRequestRow::operator=(MySQLRequestRow& moveItem)
moveItem.m_Result = nullptr;
moveItem.m_MySQLRow = nullptr;
return *this;
}
MySQLRequestRow::MySQLRequestRow(MYSQL_RES *result)
: m_Result(result), m_MySQLRow(mysql_fetch_row(m_Result))
: m_Result(result)
{
if (result != nullptr)
m_MySQLRow = mysql_fetch_row(result);
else
m_MySQLRow = nullptr;
}
MySQLRequestRow& MySQLRequestRow::operator++()
@ -41,19 +45,19 @@ MySQLRequestRow& MySQLRequestRow::operator++()
return *this;
}
MySQLRequestRow MySQLRequestRow::operator++(int)
MySQLRequestRow MySQLRequestRow::operator++(int)
{
MySQLRequestRow tmp(*this);
operator++();
MySQLRequestRow tmp(*this);
operator++();
return tmp;
}
bool MySQLRequestRow::operator==(const MySQLRequestRow& rhs)
bool MySQLRequestRow::operator==(const MySQLRequestRow& rhs)
{
return m_MySQLRow == rhs.m_MySQLRow;
}
bool MySQLRequestRow::operator!=(const MySQLRequestRow& rhs)
bool MySQLRequestRow::operator!=(const MySQLRequestRow& rhs)
{
return m_MySQLRow != rhs.m_MySQLRow;
}

View File

@ -38,8 +38,9 @@
// original source:
// https://github.com/facebook/folly/blob/master/folly/String.cpp
//
void vStringFormat(std::string& output, const char* format, va_list args)
const std::string vStringFormat(const char* format, va_list args)
{
std::string output;
va_list tmpargs;
va_copy(tmpargs,args);
@ -48,11 +49,8 @@ void vStringFormat(std::string& output, const char* format, va_list args)
if (characters_used < 0) {
// Looks like we have an invalid format string.
// error out.
std::string errorMessage("Invalid format string; snprintf returned negative with format string: ");
errorMessage.append(format);
throw std::runtime_error(errorMessage);
// return empty string.
return "";
}
else if ((unsigned int)characters_used > output.capacity()) {
output.resize(characters_used+1);
@ -62,12 +60,10 @@ void vStringFormat(std::string& output, const char* format, va_list args)
if (characters_used < 0) {
// We shouldn't have a format error by this point, but I can't imagine what error we
// could have by this point. Still, error out and report it.
std::string errorMessage("Invalid format string or unknown vsnprintf error; vsnprintf returned negative with format string: ");
errorMessage.append(format);
throw std::runtime_error(errorMessage);
// could have by this point. Still, return empty string;
return "";
}
return std::move(output);
}
else {
output.resize(characters_used + 1);
@ -78,24 +74,23 @@ void vStringFormat(std::string& output, const char* format, va_list args)
if (characters_used < 0) {
// We shouldn't have a format error by this point, but I can't imagine what error we
// could have by this point. still error out and report it.
std::string errorMessage("Invalid format string or unknown vsnprintf error; vsnprintf returned negative with format string: ");
errorMessage.append(format);
throw std::runtime_error(errorMessage);
// could have by this point. Still, return empty string;
return "";
}
return std::move(output);
}
}
void StringFormat(std::string& output, const char* format, ...)
const std::string StringFormat(const char* format, ...)
{
va_list args;
va_start(args, format);
vStringFormat(output,format,args);
std::string output = vStringFormat(format,args);
va_end(args);
return std::move(output);
}
// normal strncpy doesnt put a null term on copied strings, this one does
// ref: http://msdn.microsoft.com/library/default.asp?url=/library/en-us/wcecrt/htm/_wcecrt_strncpy_wcsncpy.asp
char* strn0cpy(char* dest, const char* source, uint32 size) {
@ -384,3 +379,15 @@ std::string EscapeString(const std::string &s) {
return ret;
}
bool isAlphaNumeric(const char *text)
{
for (unsigned int charIndex=0; charIndex<strlen(text); charIndex++) {
if ((text[charIndex] < 'a' || text[charIndex] > 'z') &&
(text[charIndex] < 'A' || text[charIndex] > 'Z') &&
(text[charIndex] < '0' || text[charIndex] > '9'))
return false;
}
return true;
}

View File

@ -19,11 +19,12 @@
#include <sstream>
#include <vector>
#include <cstdarg>
#include <string.h>
#include "types.h"
void vStringFormat(std::string& output, const char* format, va_list args);
void StringFormat(std::string& output, const char* format, ...);
const std::string vStringFormat(const char* format, va_list args);
const std::string StringFormat(const char* format, ...);
std::string EscapeString(const std::string &s);
const char *MakeLowerString(const char *source);
@ -51,4 +52,6 @@ char *RemoveApostrophes(const char *s);
std::vector<std::string> SplitString(const std::string &s, char delim);
bool isAlphaNumeric(const char *text);
#endif

File diff suppressed because it is too large Load Diff

View File

@ -130,7 +130,7 @@ public:
uint32 GetAccountIDByChar(const char* charname, uint32* oCharID = 0);
uint32 GetAccountIDByChar(uint32 char_id);
uint32 GetAccountIDByName(const char* accname, int16* status = 0, uint32* lsid = 0);
uint32 GetGuildDBIDByCharID(uint32 char_id);
uint32 GetGuildIDByCharID(uint32 char_id);
void GetAccountName(uint32 accountid, char* name, uint32* oLSAccountID = 0);
void GetCharName(uint32 char_id, char* name);
uint32 GetCharacterInfo(const char* iName, uint32* oAccID = 0, uint32* oZoneID = 0, uint32* oInstanceID = 0,float* oX = 0, float* oY = 0, float* oZ = 0);
@ -207,6 +207,7 @@ public:
char* GetGroupLeadershipInfo(uint32 gid, char* leaderbuf, char* maintank = nullptr, char* assist = nullptr, char* puller = nullptr, char *marknpc = nullptr,
GroupLeadershipAA_Struct* GLAA = nullptr);
void ClearGroupLeader(uint32 gid = 0);
/*
* Raids
@ -223,7 +224,7 @@ public:
bool SetVariable(const char* varname, const char* varvalue);
bool LoadVariables();
uint32 LoadVariables_MQ(char** query);
bool LoadVariables_result(MYSQL_RES* result);
bool LoadVariables_result(MySQLRequestResult results);
/*
* General Queries
@ -262,7 +263,20 @@ private:
uint32 varcache_max;
VarCache_Struct** varcache_array;
uint32 varcache_lastupdate;
/*
* Groups, utility methods.
*/
void ClearAllGroupLeaders();
void ClearAllGroups();
/*
* Raid, utility methods.
*/
void ClearAllRaids();
void ClearAllRaidDetails();
};
bool FetchRowMap(MYSQL_RES *result, std::map<std::string,std::string> &rowmap);
#endif

View File

@ -80,10 +80,10 @@ MySQLRequestResult DBcore::QueryDatabase(const char* query, uint32 querylen, boo
pStatus = Error;
// error appears to be a disconnect error, may need to try again.
if (errorNumber == CR_SERVER_LOST || errorNumber == CR_SERVER_GONE_ERROR)
if (errorNumber == CR_SERVER_LOST || errorNumber == CR_SERVER_GONE_ERROR)
{
if (retryOnFailureOnce)
if (retryOnFailureOnce)
{
std::cout << "Database Error: Lost connection, attempting to recover...." << std::endl;
MySQLRequestResult requestResult = QueryDatabase(query, querylen, false);
@ -95,18 +95,18 @@ MySQLRequestResult DBcore::QueryDatabase(const char* query, uint32 querylen, boo
}
}
pStatus = Error;
char *errorBuffer = new char[MYSQL_ERRMSG_SIZE];
snprintf(errorBuffer, MYSQL_ERRMSG_SIZE, "#%i: %s", mysql_errno(&mysql), mysql_error(&mysql));
std::cout << "DB Query Error #" << mysql_errno(&mysql) << ": " << mysql_error(&mysql) << std::endl;
return MySQLRequestResult(nullptr, 0, 0, 0, 0, (uint32)mysql_errno(&mysql), errorBuffer);
}
}
char *errorBuffer = new char[MYSQL_ERRMSG_SIZE];
snprintf(errorBuffer, MYSQL_ERRMSG_SIZE, "#%i: %s", mysql_errno(&mysql), mysql_error(&mysql));
@ -114,21 +114,26 @@ MySQLRequestResult DBcore::QueryDatabase(const char* query, uint32 querylen, boo
std::cout << "DB Query Error #" << mysql_errno(&mysql) << ": " << mysql_error(&mysql) << std::endl;
#endif
return MySQLRequestResult(nullptr, 0, 0, 0, 0, mysql_errno(&mysql),errorBuffer);
}
// successful query. get results.
MYSQL_RES* res = mysql_store_result(&mysql);
MySQLRequestResult requestResult(res, (uint32)mysql_affected_rows(&mysql), (uint32)mysql_num_rows(res), (uint32)mysql_field_count(&mysql), (uint32)mysql_insert_id(&mysql));
uint32 rowCount = 0;
if (res != nullptr)
rowCount = (uint32)mysql_num_rows(res);
MySQLRequestResult requestResult(res, (uint32)mysql_affected_rows(&mysql), rowCount, (uint32)mysql_field_count(&mysql), (uint32)mysql_insert_id(&mysql));
#if DEBUG_MYSQL_QUERIES >= 1
if (requestResult.Success())
if (requestResult.Success())
{
std::cout << "query successful";
if (requestResult.Result())
std::cout << ", " << (int) mysql_num_rows(requestResult.Result()) << " rows returned";
std::cout << ", " << requestResult.RowCount() << " rows affected";
std::cout<< std::endl;
}

View File

@ -237,7 +237,7 @@ std::string EmuConstants::InventorySubName(int16 sub) {
return "Unknown Sub";
std::string ret_str;
StringFormat(ret_str, "Container %i", (sub + 1)); // zero-based index..but, count starts at one
ret_str = StringFormat("Container %i", (sub + 1)); // zero-based index..but, count starts at one
return ret_str;
}
@ -250,7 +250,7 @@ std::string EmuConstants::InventoryAugName(int16 aug) {
return "Unknown Aug";
std::string ret_str;
StringFormat(ret_str, "Augment %i", (aug + 1)); // zero-based index..but, count starts at one
ret_str = StringFormat("Augment %i", (aug + 1)); // zero-based index..but, count starts at one
return ret_str;
}
@ -929,7 +929,7 @@ uint64 EQLimits::PossessionsBitmask(uint32 version) {
/*Underfoot*/ 0x000000027FFFFFFF,
/*RoF*/ 0x00000003FFFFFFFF,
/*RoF2*/ 0,
/*NPC*/ 0,
/*Merc*/ 0,
/*Bot*/ 0,
@ -950,7 +950,7 @@ uint64 EQLimits::EquipmentBitmask(uint32 version) {
/*Underfoot*/ 0x00000000007FFFFF,
/*RoF*/ 0x00000000007FFFFF,
/*RoF2*/ 0,
/*NPC*/ 0,
/*Merc*/ 0,
/*Bot*/ 0,
@ -971,7 +971,7 @@ uint64 EQLimits::GeneralBitmask(uint32 version) {
/*Underfoot*/ 0x000000007F800000,
/*RoF*/ 0x00000001FF800000,
/*RoF2*/ 0,
/*NPC*/ 0,
/*Merc*/ 0,
/*Bot*/ 0,
@ -992,7 +992,7 @@ uint64 EQLimits::CursorBitmask(uint32 version) {
/*Underfoot*/ 0x0000000200000000,
/*RoF*/ 0x0000000200000000,
/*RoF2*/ 0,
/*NPC*/ 0,
/*Merc*/ 0,
/*Bot*/ 0,
@ -1013,13 +1013,13 @@ bool EQLimits::AllowsEmptyBagInBag(uint32 version) {
/*Underfoot*/ Underfoot::limits::ALLOWS_EMPTY_BAG_IN_BAG,
/*RoF*/ RoF::limits::ALLOWS_EMPTY_BAG_IN_BAG,
/*RoF2*/ false,
/*NPC*/ false,
/*Merc*/ false,
/*Bot*/ false,
/*Pet*/ false
};
return false; // not implemented
//return local[ValidateMobVersion(version)];
}
@ -1035,7 +1035,7 @@ uint16 EQLimits::ItemCommonSize(uint32 version) {
/*Underfoot*/ EmuConstants::ITEM_COMMON_SIZE,
/*RoF*/ EmuConstants::ITEM_COMMON_SIZE,
/*RoF2*/ 0,
/*NPC*/ EmuConstants::ITEM_COMMON_SIZE,
/*Merc*/ EmuConstants::ITEM_COMMON_SIZE,
/*Bot*/ EmuConstants::ITEM_COMMON_SIZE,
@ -1055,7 +1055,7 @@ uint16 EQLimits::ItemContainerSize(uint32 version) {
/*Underfoot*/ EmuConstants::ITEM_CONTAINER_SIZE,
/*RoF*/ EmuConstants::ITEM_CONTAINER_SIZE,
/*RoF2*/ 0,
/*NPC*/ EmuConstants::ITEM_CONTAINER_SIZE,
/*Merc*/ EmuConstants::ITEM_CONTAINER_SIZE,
/*Bot*/ EmuConstants::ITEM_CONTAINER_SIZE,
@ -1075,7 +1075,7 @@ bool EQLimits::CoinHasWeight(uint32 version) {
/*Underfoot*/ Underfoot::limits::COIN_HAS_WEIGHT,
/*RoF*/ RoF::limits::COIN_HAS_WEIGHT,
/*RoF2*/ true,
/*NPC*/ true,
/*Merc*/ true,
/*Bot*/ true,
@ -1095,7 +1095,7 @@ uint32 EQLimits::BandoliersCount(uint32 version) {
/*Underfoot*/ EmuConstants::BANDOLIERS_COUNT,
/*RoF*/ EmuConstants::BANDOLIERS_COUNT,
/*RoF2*/ 0,
/*NPC*/ NOT_USED,
/*Merc*/ NOT_USED,
/*Bot*/ NOT_USED,
@ -1115,7 +1115,7 @@ uint32 EQLimits::BandolierSize(uint32 version) {
/*Underfoot*/ EmuConstants::BANDOLIER_SIZE,
/*RoF*/ EmuConstants::BANDOLIER_SIZE,
/*RoF2*/ 0,
/*NPC*/ NOT_USED,
/*Merc*/ NOT_USED,
/*Bot*/ NOT_USED,
@ -1135,7 +1135,7 @@ uint32 EQLimits::PotionBeltSize(uint32 version) {
/*Underfoot*/ EmuConstants::POTION_BELT_SIZE,
/*RoF*/ EmuConstants::POTION_BELT_SIZE,
/*RoF2*/ 0,
/*NPC*/ NOT_USED,
/*Merc*/ NOT_USED,
/*Bot*/ NOT_USED,

View File

@ -33,9 +33,7 @@ void log_message(LogType type, const char *fmt, ...) {
}
void log_messageVA(LogType type, const char *fmt, va_list args) {
std::string prefix_buffer;
StringFormat(prefix_buffer, "[%s] ", log_type_info[type].name);
std::string prefix_buffer = StringFormat("[%s] ", log_type_info[type].name);
LogFile->writePVA(EQEMuLog::Debug, prefix_buffer.c_str(), fmt, args);
}

View File

@ -76,6 +76,7 @@ RULE_BOOL ( Character, SharedBankPlat, false) //off by default to prevent duping
RULE_BOOL ( Character, BindAnywhere, false)
RULE_INT ( Character, RestRegenPercent, 0) // Set to >0 to enable rest state bonus HP and mana regen.
RULE_INT ( Character, RestRegenTimeToActivate, 30) // Time in seconds for rest state regen to kick in.
RULE_INT ( Character, RestRegenRaidTimeToActivate, 300) // Time in seconds for rest state regen to kick in with a raid target.
RULE_BOOL ( Character, RestRegenEndurance, false) // Whether rest regen will work for endurance or not.
RULE_INT ( Character, KillsPerGroupLeadershipAA, 250) // Number of dark blues or above per Group Leadership AA
RULE_INT ( Character, KillsPerRaidLeadershipAA, 250) // Number of dark blues or above per Raid Leadership AA

File diff suppressed because it is too large Load Diff

View File

@ -0,0 +1 @@
INSERT INTO `rule_values` (`ruleset_id`, `rule_name`, `rule_value`, `notes`) VALUES (1, 'Character:RestRegenRaidTimeToActivate', 300, 'Time in seconds for rest state regen to kick in with a raid target.');

View File

@ -0,0 +1,34 @@
-- AA MGB update
UPDATE altadv_vars SET spellid = 5228 WHERE skill_id = 128;
UPDATE aa_actions SET spell_id = 5228, nonspell_action = 0 WHERE aaid = 128;
-- AA Project Illusion update
UPDATE altadv_vars SET spellid = 5227 WHERE skill_id = 643;
UPDATE aa_actions SET spell_id = 5227, nonspell_action = 0 WHERE aaid = 643;
-- AA Improved Reclaim Energy
INSERT INTO `aa_effects` (`aaid`, `slot`, `effectid`, `base1`, `base2`) VALUES ('180', '1', '241', '95', '0');
-- AA Headshot
INSERT INTO `aa_effects` (`aaid`, `slot`, `effectid`, `base1`, `base2`) VALUES ('644', '1', '217', '0', '32000');
INSERT INTO `aa_effects` (`aaid`, `slot`, `effectid`, `base1`, `base2`) VALUES ('644', '2', '346', '46', '0');
-- AA Anatomy (Rogue Assassinate)
INSERT INTO `altadv_vars` (`skill_id`, `name`, `cost`, `max_level`, `hotkey_sid`, `hotkey_sid2`, `title_sid`, `desc_sid`, `type`, `spellid`, `prereq_skill`, `prereq_minpoints`, `spell_type`, `spell_refresh`, `classes`, `berserker`, `class_type`, `cost_inc`, `aa_expansion`, `special_category`, `sof_type`, `sof_cost_inc`, `sof_max_level`, `sof_next_skill`, `clientver`, `account_time_required`, `sof_current_level`,`sof_next_id`,`level_inc`) VALUES ('1604', 'Anatomy', '5', '3', '4294967295', '4294967295', '1604', '1604', '1', '4294967295', '0', '0', '0', '0', '512', '0', '60', '1', '10', '4294967295', '3', '0', '3', '1604', '1', '0', '0', '0', '0');
INSERT INTO `aa_effects` (`aaid`, `slot`, `effectid`, `base1`, `base2`) VALUES ('1604', '1', '439', '0', '32000');
INSERT INTO `aa_effects` (`aaid`, `slot`, `effectid`, `base1`, `base2`) VALUES ('1604', '2', '345', '48', '0');
INSERT INTO `aa_effects` (`aaid`, `slot`, `effectid`, `base1`, `base2`) VALUES ('1605', '1', '439', '0', '32000');
INSERT INTO `aa_effects` (`aaid`, `slot`, `effectid`, `base1`, `base2`) VALUES ('1605', '2', '345', '51', '0');
INSERT INTO `aa_effects` (`aaid`, `slot`, `effectid`, `base1`, `base2`) VALUES ('1606', '1', '439', '0', '32000');
INSERT INTO `aa_effects` (`aaid`, `slot`, `effectid`, `base1`, `base2`) VALUES ('1606', '2', '345', '53', '0');
-- AA Finishing Blow Fix
DELETE FROM aa_effects WHERE aaid = 199 AND slot = 2;
DELETE FROM aa_effects WHERE aaid = 200 AND slot = 2;
DELETE FROM aa_effects WHERE aaid = 201 AND slot = 2;
INSERT INTO `aa_effects` (`aaid`, `slot`, `effectid`, `base1`, `base2`) VALUES ('119', '1', '278', '500', '32000');
INSERT INTO `aa_effects` (`aaid`, `slot`, `effectid`, `base1`, `base2`) VALUES ('119', '2', '440', '50', '200');
INSERT INTO `aa_effects` (`aaid`, `slot`, `effectid`, `base1`, `base2`) VALUES ('120', '1', '278', '500', '32000');
INSERT INTO `aa_effects` (`aaid`, `slot`, `effectid`, `base1`, `base2`) VALUES ('120', '2', '440', '52', '200');
INSERT INTO `aa_effects` (`aaid`, `slot`, `effectid`, `base1`, `base2`) VALUES ('121', '1', '278', '500', '32000');
INSERT INTO `aa_effects` (`aaid`, `slot`, `effectid`, `base1`, `base2`) VALUES ('121', '2', '440', '54', '200');

View File

@ -0,0 +1 @@
ALTER TABLE `npc_types` ADD `raid_target` TINYINT(1) UNSIGNED NOT NULL DEFAULT '0' AFTER `no_target_hotkey`;

View File

@ -12,8 +12,7 @@
void log_message_clientVA(LogType type, Client *who, const char *fmt, va_list args) {
std::string prefix_buffer;
StringFormat(prefix_buffer,"[%s] %s: ", log_type_info[type].name, who->GetAccountName());
std::string prefix_buffer = StringFormat("[%s] %s: ", log_type_info[type].name, who->GetAccountName());
LogFile->writePVA(EQEMuLog::Debug, prefix_buffer.c_str(), fmt, args);
}
@ -31,11 +30,11 @@ void log_message_zoneVA(LogType type, ZoneServer *who, const char *fmt, va_list
const char *zone_name=who->GetZoneName();
if (zone_name == nullptr)
StringFormat(zone_tag,"[%d]", who->GetID());
zone_tag = StringFormat("[%d]", who->GetID());
else
StringFormat(zone_tag,"[%d] [%s]",who->GetID(),zone_name);
zone_tag = StringFormat("[%d] [%s]",who->GetID(),zone_name);
StringFormat(prefix_buffer, "[%s] %s ", log_type_info[type].name, zone_tag.c_str());
prefix_buffer = StringFormat("[%s] %s ", log_type_info[type].name, zone_tag.c_str());
LogFile->writePVA(EQEMuLog::Debug, prefix_buffer.c_str(), fmt, args);
}

View File

@ -4303,8 +4303,9 @@ void Bot::Spawn(Client* botCharacterOwner, std::string* errorMessage) {
// Get the zone id this bot spawned in
_lastZoneId = GetZoneID();
this->helmtexture = 0xFF;
this->texture = 0xFF;
// this change propagates to Bot::FillSpawnStruct()
this->helmtexture = 0; //0xFF;
this->texture = 0; //0xFF;
if(this->Save())
this->GetBotOwner()->CastToClient()->Message(0, "%s saved.", this->GetCleanName());
@ -4329,18 +4330,18 @@ void Bot::Spawn(Client* botCharacterOwner, std::string* errorMessage) {
this->SendPosition();
/* // fillspawnstruct now properly handles this -U
// there is something askew with spawn struct appearance fields...
// I re-enabled this until I can sort it out -U
uint32 itemID = 0;
uint8 materialFromSlot = 0xFF;
for(int i=EmuConstants::EQUIPMENT_BEGIN; i<=EmuConstants::EQUIPMENT_END; ++i) {
for(int i = EmuConstants::EQUIPMENT_BEGIN; i <= EmuConstants::EQUIPMENT_END; ++i) {
itemID = GetBotItemBySlot(i);
if(itemID != 0) {
materialFromSlot = Inventory::CalcMaterialFromSlot(i);
if(materialFromSlot != 0xFF) {
if(materialFromSlot != 0xFF)
this->SendWearChange(materialFromSlot);
}
}
}*/
}
}
}
@ -4586,8 +4587,8 @@ void Bot::FillSpawnStruct(NewSpawn_Struct* ns, Mob* ForWho) {
ns->spawn.size = 0;
ns->spawn.NPC = 0; // 0=player,1=npc,2=pc corpse,3=npc corpse
ns->spawn.helm = 0xFF;
ns->spawn.equip_chest2 = 0xFF;
ns->spawn.helm = helmtexture; //0xFF;
ns->spawn.equip_chest2 = texture; //0xFF;
const Item_Struct* item = 0;
const ItemInst* inst = 0;

View File

@ -324,6 +324,9 @@ Client::Client(EQStreamInterface* ieqs)
initial_respawn_selection = 0;
alternate_currency_loaded = false;
EngagedRaidTarget = false;
SavedRaidRestTimer = 0;
}
Client::~Client() {
@ -4330,12 +4333,16 @@ void Client::IncrementAggroCount() {
if(!RuleI(Character, RestRegenPercent))
return;
// If we already had aggro before this method was called, the combat indicator should already be up for SoF clients,
// so we don't need to send it again.
//
if(AggroCount > 1)
return;
// Pause the rest timer
if (AggroCount == 1)
SavedRaidRestTimer = rest_timer.GetRemainingTime();
if(GetClientVersion() >= EQClientSoF) {
@ -4367,14 +4374,27 @@ void Client::DecrementAggroCount() {
// Something else is still aggro on us, can't rest yet.
if(AggroCount) return;
rest_timer.Start(RuleI(Character, RestRegenTimeToActivate) * 1000);
uint32 time_until_rest;
if (GetEngagedRaidTarget()) {
time_until_rest = RuleI(Character, RestRegenRaidTimeToActivate) * 1000;
SetEngagedRaidTarget(false);
} else {
if (SavedRaidRestTimer > (RuleI(Character, RestRegenTimeToActivate) * 1000)) {
time_until_rest = SavedRaidRestTimer;
SavedRaidRestTimer = 0;
} else {
time_until_rest = RuleI(Character, RestRegenTimeToActivate) * 1000;
}
}
rest_timer.Start(time_until_rest);
if(GetClientVersion() >= EQClientSoF) {
EQApplicationPacket *outapp = new EQApplicationPacket(OP_RestState, 5);
char *Buffer = (char *)outapp->pBuffer;
VARSTRUCT_ENCODE_TYPE(uint8, Buffer, 0x00);
VARSTRUCT_ENCODE_TYPE(uint32, Buffer, RuleI(Character, RestRegenTimeToActivate));
VARSTRUCT_ENCODE_TYPE(uint32, Buffer, (uint32)(time_until_rest / 1000));
QueuePacket(outapp);
safe_delete(outapp);
}

View File

@ -789,8 +789,8 @@ public:
void SetTint(int16 slot_id, Color_Struct& color);
void SetMaterial(int16 slot_id, uint32 item_id);
void Undye();
uint32 GetItemIDAt(int16 slot_id);
uint32 GetAugmentIDAt(int16 slot_id, uint8 augslot);
int32 GetItemIDAt(int16 slot_id);
int32 GetAugmentIDAt(int16 slot_id, uint8 augslot);
bool PutItemInInventory(int16 slot_id, const ItemInst& inst, bool client_update = false);
bool PushItemOnCursor(const ItemInst& inst, bool client_update = false);
void DeleteItemInInventory(int16 slot_id, int8 quantity = 0, bool client_update = false, bool update_db = true);
@ -1198,6 +1198,9 @@ public:
int mod_food_value(const Item_Struct *item, int change);
int mod_drink_value(const Item_Struct *item, int change);
void SetEngagedRaidTarget(bool value) { EngagedRaidTarget = value; }
bool GetEngagedRaidTarget() const { return EngagedRaidTarget; }
protected:
friend class Mob;
void CalcItemBonuses(StatBonuses* newbon);
@ -1442,6 +1445,9 @@ private:
unsigned int RestRegenHP;
unsigned int RestRegenMana;
unsigned int RestRegenEndurance;
bool EngagedRaidTarget;
uint32 SavedRaidRestTimer;
std::set<uint32> zone_flags;

View File

@ -1248,7 +1248,6 @@ void Client::Handle_OP_ClientUpdate(const EQApplicationPacket *app)
delta_y = ppu->delta_y;
delta_z = ppu->delta_z;
delta_heading = ppu->delta_heading;
heading = EQ19toFloat(ppu->heading);
if(IsTracking() && ((x_pos!=ppu->x_pos) || (y_pos!=ppu->y_pos))){
if(MakeRandomFloat(0, 100) < 70)//should be good
@ -1274,12 +1273,15 @@ void Client::Handle_OP_ClientUpdate(const EQApplicationPacket *app)
}
// Outgoing client packet
if (ppu->y_pos != y_pos || ppu->x_pos != x_pos || ppu->heading != heading || ppu->animation != animation)
float tmpheading = EQ19toFloat(ppu->heading);
if (!FCMP(ppu->y_pos, y_pos) || !FCMP(ppu->x_pos, x_pos) || !FCMP(tmpheading, heading) || ppu->animation != animation)
{
x_pos = ppu->x_pos;
y_pos = ppu->y_pos;
z_pos = ppu->z_pos;
animation = ppu->animation;
heading = tmpheading;
EQApplicationPacket* outapp = new EQApplicationPacket(OP_ClientUpdate, sizeof(PlayerPositionUpdateServer_Struct));
PlayerPositionUpdateServer_Struct* ppu = (PlayerPositionUpdateServer_Struct*)outapp->pBuffer;
@ -9157,7 +9159,8 @@ bool Client::FinishConnState2(DBAsyncWork* dbaw) {
m_pp.timeentitledonaccount = database.GetTotalTimeEntitledOnAccount(AccountID()) / 1440;
if(m_pp.RestTimer > RuleI(Character, RestRegenTimeToActivate))
// Reset rest timer if the durations have been lowered in the database
if ((m_pp.RestTimer > RuleI(Character, RestRegenTimeToActivate)) && (m_pp.RestTimer > RuleI(Character, RestRegenRaidTimeToActivate)))
m_pp.RestTimer = 0;
//This checksum should disappear once dynamic structs are in... each struct strategy will do it

View File

@ -198,8 +198,11 @@ void HateList::Add(Mob *ent, int32 in_hate, int32 in_dam, bool bFrenzy, bool iAd
list.push_back(p);
parse->EventNPC(EVENT_HATE_LIST, owner->CastToNPC(), ent, "1", 0);
if(ent->IsClient())
if (ent->IsClient()) {
if (owner->CastToNPC()->IsRaidTarget())
ent->CastToClient()->SetEngagedRaidTarget(true);
ent->CastToClient()->IncrementAggroCount();
}
}
}

View File

@ -659,7 +659,7 @@ void Client::DropInst(const ItemInst* inst)
}
// Returns a slot's item ID (returns INVALID_ID if not found)
uint32 Client::GetItemIDAt(int16 slot_id) {
int32 Client::GetItemIDAt(int16 slot_id) {
const ItemInst* inst = m_inv[slot_id];
if (inst)
return inst->GetItem()->ID;
@ -670,7 +670,7 @@ uint32 Client::GetItemIDAt(int16 slot_id) {
// Returns an augment's ID that's in an item (returns INVALID_ID if not found)
// Pass in the slot ID of the item and which augslot you want to check (0-4)
uint32 Client::GetAugmentIDAt(int16 slot_id, uint8 augslot) {
int32 Client::GetAugmentIDAt(int16 slot_id, uint8 augslot) {
const ItemInst* inst = m_inv[slot_id];
if (inst)
if (inst->GetAugmentItemID(augslot))

View File

@ -3551,7 +3551,7 @@ void Mob::TrySympatheticProc(Mob *target, uint32 spell_id)
}
}
uint32 Mob::GetItemStat(uint32 itemid, const char *identifier)
int32 Mob::GetItemStat(uint32 itemid, const char *identifier)
{
const ItemInst* inst = database.CreateItem(itemid);
if (!inst)
@ -3564,7 +3564,7 @@ uint32 Mob::GetItemStat(uint32 itemid, const char *identifier)
if (!identifier)
return 0;
uint32 stat = 0;
int32 stat = 0;
std::string id = identifier;
for(int i = 0; i < id.length(); ++i)
@ -3573,316 +3573,318 @@ uint32 Mob::GetItemStat(uint32 itemid, const char *identifier)
}
if (id == "itemclass")
stat = uint32(item->ItemClass);
stat = int32(item->ItemClass);
if (id == "id")
stat = uint32(item->ID);
stat = int32(item->ID);
if (id == "idfile")
stat = atoi(&item->IDFile[2]);
if (id == "weight")
stat = uint32(item->Weight);
stat = int32(item->Weight);
if (id == "norent")
stat = uint32(item->NoRent);
stat = int32(item->NoRent);
if (id == "nodrop")
stat = uint32(item->NoDrop);
stat = int32(item->NoDrop);
if (id == "size")
stat = uint32(item->Size);
stat = int32(item->Size);
if (id == "slots")
stat = uint32(item->Slots);
stat = int32(item->Slots);
if (id == "price")
stat = uint32(item->Price);
stat = int32(item->Price);
if (id == "icon")
stat = uint32(item->Icon);
stat = int32(item->Icon);
if (id == "loregroup")
stat = uint32(item->LoreGroup);
stat = int32(item->LoreGroup);
if (id == "loreflag")
stat = uint32(item->LoreFlag);
stat = int32(item->LoreFlag);
if (id == "pendingloreflag")
stat = uint32(item->PendingLoreFlag);
stat = int32(item->PendingLoreFlag);
if (id == "artifactflag")
stat = uint32(item->ArtifactFlag);
stat = int32(item->ArtifactFlag);
if (id == "summonedflag")
stat = uint32(item->SummonedFlag);
stat = int32(item->SummonedFlag);
if (id == "fvnodrop")
stat = uint32(item->FVNoDrop);
stat = int32(item->FVNoDrop);
if (id == "favor")
stat = uint32(item->Favor);
stat = int32(item->Favor);
if (id == "guildfavor")
stat = uint32(item->GuildFavor);
stat = int32(item->GuildFavor);
if (id == "pointtype")
stat = uint32(item->PointType);
stat = int32(item->PointType);
if (id == "bagtype")
stat = uint32(item->BagType);
stat = int32(item->BagType);
if (id == "bagslots")
stat = uint32(item->BagSlots);
stat = int32(item->BagSlots);
if (id == "bagsize")
stat = uint32(item->BagSize);
stat = int32(item->BagSize);
if (id == "bagwr")
stat = uint32(item->BagWR);
stat = int32(item->BagWR);
if (id == "benefitflag")
stat = uint32(item->BenefitFlag);
stat = int32(item->BenefitFlag);
if (id == "tradeskills")
stat = uint32(item->Tradeskills);
stat = int32(item->Tradeskills);
if (id == "cr")
stat = uint32(item->CR);
stat = int32(item->CR);
if (id == "dr")
stat = uint32(item->DR);
stat = int32(item->DR);
if (id == "pr")
stat = uint32(item->PR);
stat = int32(item->PR);
if (id == "mr")
stat = uint32(item->MR);
stat = int32(item->MR);
if (id == "fr")
stat = uint32(item->FR);
stat = int32(item->FR);
if (id == "astr")
stat = uint32(item->AStr);
stat = int32(item->AStr);
if (id == "asta")
stat = uint32(item->ASta);
stat = int32(item->ASta);
if (id == "aagi")
stat = uint32(item->AAgi);
stat = int32(item->AAgi);
if (id == "adex")
stat = uint32(item->ADex);
stat = int32(item->ADex);
if (id == "acha")
stat = uint32(item->ACha);
stat = int32(item->ACha);
if (id == "aint")
stat = uint32(item->AInt);
stat = int32(item->AInt);
if (id == "awis")
stat = uint32(item->AWis);
stat = int32(item->AWis);
if (id == "hp")
stat = uint32(item->HP);
stat = int32(item->HP);
if (id == "mana")
stat = uint32(item->Mana);
stat = int32(item->Mana);
if (id == "ac")
stat = uint32(item->AC);
stat = int32(item->AC);
if (id == "deity")
stat = uint32(item->Deity);
stat = int32(item->Deity);
if (id == "skillmodvalue")
stat = uint32(item->SkillModValue);
stat = int32(item->SkillModValue);
if (id == "skillmodtype")
stat = uint32(item->SkillModType);
stat = int32(item->SkillModType);
if (id == "banedmgrace")
stat = uint32(item->BaneDmgRace);
stat = int32(item->BaneDmgRace);
if (id == "banedmgamt")
stat = uint32(item->BaneDmgAmt);
stat = int32(item->BaneDmgAmt);
if (id == "banedmgbody")
stat = uint32(item->BaneDmgBody);
stat = int32(item->BaneDmgBody);
if (id == "magic")
stat = uint32(item->Magic);
stat = int32(item->Magic);
if (id == "casttime_")
stat = uint32(item->CastTime_);
stat = int32(item->CastTime_);
if (id == "reqlevel")
stat = uint32(item->ReqLevel);
stat = int32(item->ReqLevel);
if (id == "bardtype")
stat = uint32(item->BardType);
stat = int32(item->BardType);
if (id == "bardvalue")
stat = uint32(item->BardValue);
stat = int32(item->BardValue);
if (id == "light")
stat = uint32(item->Light);
stat = int32(item->Light);
if (id == "delay")
stat = uint32(item->Delay);
stat = int32(item->Delay);
if (id == "reclevel")
stat = uint32(item->RecLevel);
stat = int32(item->RecLevel);
if (id == "recskill")
stat = uint32(item->RecSkill);
stat = int32(item->RecSkill);
if (id == "elemdmgtype")
stat = uint32(item->ElemDmgType);
stat = int32(item->ElemDmgType);
if (id == "elemdmgamt")
stat = uint32(item->ElemDmgAmt);
stat = int32(item->ElemDmgAmt);
if (id == "range")
stat = uint32(item->Range);
stat = int32(item->Range);
if (id == "damage")
stat = uint32(item->Damage);
stat = int32(item->Damage);
if (id == "color")
stat = uint32(item->Color);
stat = int32(item->Color);
if (id == "classes")
stat = uint32(item->Classes);
stat = int32(item->Classes);
if (id == "races")
stat = uint32(item->Races);
stat = int32(item->Races);
if (id == "maxcharges")
stat = uint32(item->MaxCharges);
stat = int32(item->MaxCharges);
if (id == "itemtype")
stat = uint32(item->ItemType);
stat = int32(item->ItemType);
if (id == "material")
stat = uint32(item->Material);
stat = int32(item->Material);
if (id == "casttime")
stat = uint32(item->CastTime);
stat = int32(item->CastTime);
if (id == "elitematerial")
stat = uint32(item->EliteMaterial);
stat = int32(item->EliteMaterial);
if (id == "procrate")
stat = uint32(item->ProcRate);
stat = int32(item->ProcRate);
if (id == "combateffects")
stat = uint32(item->CombatEffects);
stat = int32(item->CombatEffects);
if (id == "shielding")
stat = uint32(item->Shielding);
stat = int32(item->Shielding);
if (id == "stunresist")
stat = uint32(item->StunResist);
stat = int32(item->StunResist);
if (id == "strikethrough")
stat = uint32(item->StrikeThrough);
stat = int32(item->StrikeThrough);
if (id == "extradmgskill")
stat = uint32(item->ExtraDmgSkill);
stat = int32(item->ExtraDmgSkill);
if (id == "extradmgamt")
stat = uint32(item->ExtraDmgAmt);
stat = int32(item->ExtraDmgAmt);
if (id == "spellshield")
stat = uint32(item->SpellShield);
stat = int32(item->SpellShield);
if (id == "avoidance")
stat = uint32(item->Avoidance);
stat = int32(item->Avoidance);
if (id == "accuracy")
stat = uint32(item->Accuracy);
stat = int32(item->Accuracy);
if (id == "charmfileid")
stat = uint32(item->CharmFileID);
stat = int32(item->CharmFileID);
if (id == "factionmod1")
stat = uint32(item->FactionMod1);
stat = int32(item->FactionMod1);
if (id == "factionmod2")
stat = uint32(item->FactionMod2);
stat = int32(item->FactionMod2);
if (id == "factionmod3")
stat = uint32(item->FactionMod3);
stat = int32(item->FactionMod3);
if (id == "factionmod4")
stat = uint32(item->FactionMod4);
stat = int32(item->FactionMod4);
if (id == "factionamt1")
stat = uint32(item->FactionAmt1);
stat = int32(item->FactionAmt1);
if (id == "factionamt2")
stat = uint32(item->FactionAmt2);
stat = int32(item->FactionAmt2);
if (id == "factionamt3")
stat = uint32(item->FactionAmt3);
stat = int32(item->FactionAmt3);
if (id == "factionamt4")
stat = uint32(item->FactionAmt4);
stat = int32(item->FactionAmt4);
if (id == "augtype")
stat = uint32(item->AugType);
stat = int32(item->AugType);
if (id == "ldontheme")
stat = uint32(item->LDoNTheme);
stat = int32(item->LDoNTheme);
if (id == "ldonprice")
stat = uint32(item->LDoNPrice);
stat = int32(item->LDoNPrice);
if (id == "ldonsold")
stat = uint32(item->LDoNSold);
stat = int32(item->LDoNSold);
if (id == "banedmgraceamt")
stat = uint32(item->BaneDmgRaceAmt);
stat = int32(item->BaneDmgRaceAmt);
if (id == "augrestrict")
stat = uint32(item->AugRestrict);
stat = int32(item->AugRestrict);
if (id == "endur")
stat = uint32(item->Endur);
stat = int32(item->Endur);
if (id == "dotshielding")
stat = uint32(item->DotShielding);
stat = int32(item->DotShielding);
if (id == "attack")
stat = uint32(item->Attack);
stat = int32(item->Attack);
if (id == "regen")
stat = uint32(item->Regen);
stat = int32(item->Regen);
if (id == "manaregen")
stat = uint32(item->ManaRegen);
stat = int32(item->ManaRegen);
if (id == "enduranceregen")
stat = uint32(item->EnduranceRegen);
stat = int32(item->EnduranceRegen);
if (id == "haste")
stat = uint32(item->Haste);
stat = int32(item->Haste);
if (id == "damageshield")
stat = uint32(item->DamageShield);
stat = int32(item->DamageShield);
if (id == "recastdelay")
stat = uint32(item->RecastDelay);
stat = int32(item->RecastDelay);
if (id == "recasttype")
stat = uint32(item->RecastType);
stat = int32(item->RecastType);
if (id == "augdistiller")
stat = uint32(item->AugDistiller);
stat = int32(item->AugDistiller);
if (id == "attuneable")
stat = uint32(item->Attuneable);
stat = int32(item->Attuneable);
if (id == "nopet")
stat = uint32(item->NoPet);
stat = int32(item->NoPet);
if (id == "potionbelt")
stat = uint32(item->PotionBelt);
stat = int32(item->PotionBelt);
if (id == "stackable")
stat = uint32(item->Stackable);
stat = int32(item->Stackable);
if (id == "notransfer")
stat = uint32(item->NoTransfer);
stat = int32(item->NoTransfer);
if (id == "questitemflag")
stat = uint32(item->QuestItemFlag);
stat = int32(item->QuestItemFlag);
if (id == "stacksize")
stat = uint32(item->StackSize);
stat = int32(item->StackSize);
if (id == "potionbeltslots")
stat = uint32(item->PotionBeltSlots);
stat = int32(item->PotionBeltSlots);
if (id == "book")
stat = uint32(item->Book);
stat = int32(item->Book);
if (id == "booktype")
stat = uint32(item->BookType);
stat = int32(item->BookType);
if (id == "svcorruption")
stat = uint32(item->SVCorruption);
stat = int32(item->SVCorruption);
if (id == "purity")
stat = uint32(item->Purity);
stat = int32(item->Purity);
if (id == "backstabdmg")
stat = uint32(item->BackstabDmg);
stat = int32(item->BackstabDmg);
if (id == "dsmitigation")
stat = uint32(item->DSMitigation);
stat = int32(item->DSMitigation);
if (id == "heroicstr")
stat = uint32(item->HeroicStr);
stat = int32(item->HeroicStr);
if (id == "heroicint")
stat = uint32(item->HeroicInt);
stat = int32(item->HeroicInt);
if (id == "heroicwis")
stat = uint32(item->HeroicWis);
stat = int32(item->HeroicWis);
if (id == "heroicagi")
stat = uint32(item->HeroicAgi);
stat = int32(item->HeroicAgi);
if (id == "heroicdex")
stat = uint32(item->HeroicDex);
stat = int32(item->HeroicDex);
if (id == "heroicsta")
stat = uint32(item->HeroicSta);
stat = int32(item->HeroicSta);
if (id == "heroiccha")
stat = uint32(item->HeroicCha);
stat = int32(item->HeroicCha);
if (id == "heroicmr")
stat = uint32(item->HeroicMR);
stat = int32(item->HeroicMR);
if (id == "heroicfr")
stat = uint32(item->HeroicFR);
stat = int32(item->HeroicFR);
if (id == "heroiccr")
stat = uint32(item->HeroicCR);
stat = int32(item->HeroicCR);
if (id == "heroicdr")
stat = uint32(item->HeroicDR);
stat = int32(item->HeroicDR);
if (id == "heroicpr")
stat = uint32(item->HeroicPR);
stat = int32(item->HeroicPR);
if (id == "heroicsvcorrup")
stat = uint32(item->HeroicSVCorrup);
stat = int32(item->HeroicSVCorrup);
if (id == "healamt")
stat = uint32(item->HealAmt);
stat = int32(item->HealAmt);
if (id == "spelldmg")
stat = uint32(item->SpellDmg);
stat = int32(item->SpellDmg);
if (id == "ldonsellbackrate")
stat = uint32(item->LDoNSellBackRate);
stat = int32(item->LDoNSellBackRate);
if (id == "scriptfileid")
stat = uint32(item->ScriptFileID);
stat = int32(item->ScriptFileID);
if (id == "expendablearrow")
stat = uint32(item->ExpendableArrow);
stat = int32(item->ExpendableArrow);
if (id == "clairvoyance")
stat = uint32(item->Clairvoyance);
stat = int32(item->Clairvoyance);
// Begin Effects
if (id == "clickeffect")
stat = uint32(item->Click.Effect);
stat = int32(item->Click.Effect);
if (id == "clicktype")
stat = uint32(item->Click.Type);
stat = int32(item->Click.Type);
if (id == "clicklevel")
stat = uint32(item->Click.Level);
stat = int32(item->Click.Level);
if (id == "clicklevel2")
stat = uint32(item->Click.Level2);
stat = int32(item->Click.Level2);
if (id == "proceffect")
stat = uint32(item->Proc.Effect);
stat = int32(item->Proc.Effect);
if (id == "proctype")
stat = uint32(item->Proc.Type);
stat = int32(item->Proc.Type);
if (id == "proclevel")
stat = uint32(item->Proc.Level);
stat = int32(item->Proc.Level);
if (id == "proclevel2")
stat = uint32(item->Proc.Level2);
stat = int32(item->Proc.Level2);
if (id == "worneffect")
stat = uint32(item->Worn.Effect);
stat = int32(item->Worn.Effect);
if (id == "worntype")
stat = uint32(item->Worn.Type);
stat = int32(item->Worn.Type);
if (id == "wornlevel")
stat = uint32(item->Worn.Level);
stat = int32(item->Worn.Level);
if (id == "wornlevel2")
stat = uint32(item->Worn.Level2);
stat = int32(item->Worn.Level2);
if (id == "focuseffect")
stat = uint32(item->Focus.Effect);
stat = int32(item->Focus.Effect);
if (id == "focustype")
stat = uint32(item->Focus.Type);
stat = int32(item->Focus.Type);
if (id == "focuslevel")
stat = uint32(item->Focus.Level);
stat = int32(item->Focus.Level);
if (id == "focuslevel2")
stat = uint32(item->Focus.Level2);
stat = int32(item->Focus.Level2);
if (id == "scrolleffect")
stat = uint32(item->Scroll.Effect);
stat = int32(item->Scroll.Effect);
if (id == "scrolltype")
stat = uint32(item->Scroll.Type);
stat = int32(item->Scroll.Type);
if (id == "scrolllevel")
stat = uint32(item->Scroll.Level);
stat = int32(item->Scroll.Level);
if (id == "scrolllevel2")
stat = uint32(item->Scroll.Level2);
stat = int32(item->Scroll.Level2);
safe_delete(inst);
return stat;

View File

@ -524,6 +524,7 @@ public:
//More stuff to sort:
virtual bool IsRaidTarget() { return false; };
virtual bool IsAttackAllowed(Mob *target, bool isSpellAttack = false);
bool IsTargeted() const { return (targeted > 0); }
inline void IsTargeted(int in_tar) { targeted += in_tar; if(targeted < 0) targeted = 0;}
@ -552,7 +553,7 @@ public:
void Shout(const char *format, ...);
void Emote(const char *format, ...);
void QuestJournalledSay(Client *QuestInitiator, const char *str);
uint32 GetItemStat(uint32 itemid, const char *identifier);
int32 GetItemStat(uint32 itemid, const char *identifier);
int16 CalcFocusEffect(focusType type, uint16 focus_id, uint16 spell_id, bool best_focus=false);
uint8 IsFocusEffect(uint16 spellid, int effect_index, bool AA=false,uint32 aa_effect=0);

View File

@ -358,6 +358,7 @@ NPC::NPC(const NPCType* d, Spawn2* in_respawn, float x, float y, float z, float
SetEmoteID(d->emoteid);
InitializeBuffSlots();
CalcBonuses();
raid_target = d->raid_target;
}
NPC::~NPC()

View File

@ -395,6 +395,8 @@ public:
void mod_npc_killed_merit(Mob* c);
void mod_npc_killed(Mob* oos);
void AISpellsList(Client *c);
bool IsRaidTarget() const { return raid_target; };
protected:
@ -500,6 +502,8 @@ protected:
//mercenary stuff
std::list<MercType> mercTypeList;
std::list<MercData> mercDataList;
bool raid_target;
private:
uint32 loottable_id;

View File

@ -2955,7 +2955,7 @@ XS(XS_Client_GetItemIDAt)
Perl_croak(aTHX_ "Usage: Client::GetItemIDAt(THIS, slot_id)");
{
Client * THIS;
uint32 RETVAL;
int32 RETVAL;
dXSTARG;
int16 slot_id = (int16)SvIV(ST(1));
@ -2969,7 +2969,7 @@ XS(XS_Client_GetItemIDAt)
Perl_croak(aTHX_ "THIS is nullptr, avoiding crash.");
RETVAL = THIS->GetItemIDAt(slot_id);
XSprePUSH; PUSHu((UV)RETVAL);
XSprePUSH; PUSHi((IV)RETVAL);
}
XSRETURN(1);
}
@ -2982,7 +2982,7 @@ XS(XS_Client_GetAugmentIDAt)
Perl_croak(aTHX_ "Usage: Client::GetAugmentIDAt(THIS, slot_id, augslot)");
{
Client * THIS;
uint32 RETVAL;
int32 RETVAL;
dXSTARG;
int16 slot_id = (int16)SvIV(ST(1));
int16 augslot = (uint8)SvIV(ST(2));
@ -2997,7 +2997,7 @@ XS(XS_Client_GetAugmentIDAt)
Perl_croak(aTHX_ "THIS is nullptr, avoiding crash.");
RETVAL = THIS->GetAugmentIDAt(slot_id, augslot);
XSprePUSH; PUSHu((UV)RETVAL);
XSprePUSH; PUSHi((IV)RETVAL);
}
XSRETURN(1);
}

View File

@ -7298,7 +7298,7 @@ XS(XS_Mob_GetItemStat)
Perl_croak(aTHX_ "Usage: Mob::GetItemStat(THIS, itemid, stat)");
{
Mob * THIS;
uint32 RETVAL;
int32 RETVAL;
uint32 itemid = (uint32)SvUV(ST(1));
Const_char * stat = (Const_char *)SvPV_nolen(ST(2));
dXSTARG;
@ -7313,7 +7313,7 @@ XS(XS_Mob_GetItemStat)
Perl_croak(aTHX_ "THIS is nullptr, avoiding crash.");
RETVAL = THIS->GetItemStat(itemid, stat);
XSprePUSH; PUSHu((UV)RETVAL);
XSprePUSH; PUSHi((IV)RETVAL);
}
XSRETURN(1);
}

View File

@ -2015,7 +2015,7 @@ float Mob::GetSpecialProcChances(uint16 hand)
ProcBonus += static_cast<float>(mydex/35) + static_cast<float>(itembonuses.HeroicDEX / 25);
ProcChance += ProcChance * ProcBonus / 100.0f;
} else {
/*PRE 2014 CHANGE Dev Quote - "Elidroth SOE:Proc chance is a function of your base hardcapped Dexterity / 35 + Heroic Dexterity / 25.
/*PRE 2014 CHANGE Dev Quote - "Elidroth SOE:Proc chance is a function of your base hardcapped Dexterity / 35 + Heroic Dexterity / 25.”
Kayen: Most reports suggest a ~ 6% chance to Headshot which consistent with above.*/
ProcChance = (static_cast<float>(mydex/35) + static_cast<float>(itembonuses.HeroicDEX / 25))/100.0f;

View File

@ -1115,7 +1115,8 @@ const NPCType* ZoneDatabase::GetNPCType (uint32 id) {
"npc_types.emoteid,"
"npc_types.spellscale,"
"npc_types.healscale,"
"npc_types.no_target_hotkey";
"npc_types.no_target_hotkey,"
"npc_types.raid_target";
MakeAnyLenString(&query, "%s FROM npc_types WHERE id=%d", basic_query, id);
@ -1302,6 +1303,7 @@ const NPCType* ZoneDatabase::GetNPCType (uint32 id) {
tmpNPCType->spellscale = atoi(row[r++]);
tmpNPCType->healscale = atoi(row[r++]);
tmpNPCType->no_target_hotkey = atoi(row[r++]) == 1 ? true : false;
tmpNPCType->raid_target = atoi(row[r++]) == 0 ? false : true;
// If NPC with duplicate NPC id already in table,
// free item we attempted to add.

View File

@ -125,6 +125,7 @@ struct NPCType
float spellscale;
float healscale;
bool no_target_hotkey;
bool raid_target;
};
/*