mirror of
https://github.com/EQEmu/Server.git
synced 2026-05-24 18:22:29 +00:00
Compare commits
39 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
| caae34ac5e | |||
| 56c7db4cbf | |||
| 043eeced6f | |||
| e9a0c79301 | |||
| dc48c45421 | |||
| d7a8fb8691 | |||
| 3a5381d38a | |||
| e64f03fcc0 | |||
| d77966797e | |||
| 048aad437b | |||
| b2d9de8d96 | |||
| 42bfa4bb2e | |||
| 72ce7c8e91 | |||
| e306c86875 | |||
| 3ae7979a67 | |||
| b638795f9b | |||
| 9e3bf91374 | |||
| cd89926435 | |||
| e19f72f021 | |||
| df1dc5d1e4 | |||
| e11286164f | |||
| b946b800fb | |||
| ab8ac81df6 | |||
| 109940fc0c | |||
| a87496b0cf | |||
| f905ee70e4 | |||
| 52417023f8 | |||
| 20d9417628 | |||
| 4692799677 | |||
| cf7f0f4321 | |||
| 823a5956de | |||
| 6a8bd3c5d6 | |||
| 523ba30d81 | |||
| d7ea290b6b | |||
| 036309ebec | |||
| b400700d81 | |||
| 21cec87ac4 | |||
| abdec39cdd | |||
| d2372de982 |
@@ -29,6 +29,8 @@
|
||||
#include "../../common/content/world_content_service.h"
|
||||
#include "../../common/zone_store.h"
|
||||
#include "../../common/path_manager.h"
|
||||
#include "../../common/repositories/skill_caps_repository.h"
|
||||
#include "../../common/file.h"
|
||||
|
||||
EQEmuLogSys LogSys;
|
||||
WorldContentService content_service;
|
||||
@@ -164,81 +166,76 @@ void ExportSpells(SharedDatabase *db)
|
||||
fclose(f);
|
||||
}
|
||||
|
||||
bool SkillUsable(SharedDatabase *db, int skill_id, int class_id)
|
||||
bool SkillUsable(SharedDatabase* db, int skill_id, int class_id)
|
||||
{
|
||||
|
||||
bool res = false;
|
||||
|
||||
std::string query = StringFormat(
|
||||
"SELECT max(cap) FROM skill_caps WHERE class=%d AND skillID=%d",
|
||||
class_id, skill_id
|
||||
const auto& l = SkillCapsRepository::GetWhere(
|
||||
*db,
|
||||
fmt::format(
|
||||
"`class_id` = {} AND `skill_id` = {} ORDER BY `cap` DESC LIMIT 1",
|
||||
class_id,
|
||||
skill_id
|
||||
)
|
||||
);
|
||||
auto results = db->QueryDatabase(query);
|
||||
if (!results.Success()) {
|
||||
return false;
|
||||
}
|
||||
|
||||
if (results.RowCount() == 0) {
|
||||
return false;
|
||||
}
|
||||
|
||||
auto row = results.begin();
|
||||
if (row[0] && Strings::ToInt(row[0]) > 0) {
|
||||
return true;
|
||||
}
|
||||
|
||||
return false;
|
||||
return !l.empty();
|
||||
}
|
||||
|
||||
int GetSkill(SharedDatabase *db, int skill_id, int class_id, int level)
|
||||
uint32 GetSkill(SharedDatabase* db, int skill_id, int class_id, int level)
|
||||
{
|
||||
|
||||
std::string query = StringFormat(
|
||||
"SELECT cap FROM skill_caps WHERE class=%d AND skillID=%d AND level=%d",
|
||||
class_id, skill_id, level
|
||||
const auto& l = SkillCapsRepository::GetWhere(
|
||||
*db,
|
||||
fmt::format(
|
||||
"`class_id` = {} AND `skill_id` = {} AND `level` = {}",
|
||||
class_id,
|
||||
skill_id,
|
||||
level
|
||||
)
|
||||
);
|
||||
auto results = db->QueryDatabase(query);
|
||||
if (!results.Success()) {
|
||||
|
||||
if (l.empty()) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
if (results.RowCount() == 0) {
|
||||
return 0;
|
||||
}
|
||||
auto e = l.front();
|
||||
|
||||
auto row = results.begin();
|
||||
return Strings::ToInt(row[0]);
|
||||
return e.cap;
|
||||
}
|
||||
|
||||
void ExportSkillCaps(SharedDatabase *db)
|
||||
void ExportSkillCaps(SharedDatabase* db)
|
||||
{
|
||||
LogInfo("Exporting Skill Caps");
|
||||
|
||||
std::string file = fmt::format("{}/export/SkillCaps.txt", path.GetServerPath());
|
||||
FILE *f = fopen(file.c_str(), "w");
|
||||
if (!f) {
|
||||
std::ofstream file(fmt::format("{}/export/SkillCaps.txt", path.GetServerPath()));
|
||||
if (!file || !file.is_open()) {
|
||||
LogError("Unable to open export/SkillCaps.txt to write, skipping.");
|
||||
return;
|
||||
}
|
||||
|
||||
for (int cl = 1; cl <= 16; ++cl) {
|
||||
for (int skill = 0; skill <= 77; ++skill) {
|
||||
if (SkillUsable(db, skill, cl)) {
|
||||
int previous_cap = 0;
|
||||
for (int level = 1; level <= 100; ++level) {
|
||||
int cap = GetSkill(db, skill, cl, level);
|
||||
const uint8 skill_cap_max_level = (
|
||||
RuleI(Character, SkillCapMaxLevel) > 0 ?
|
||||
RuleI(Character, SkillCapMaxLevel) :
|
||||
RuleI(Character, MaxLevel)
|
||||
);
|
||||
|
||||
for (uint8 class_id = Class::Warrior; class_id <= Class::Berserker; class_id++) {
|
||||
for (uint8 skill_id = EQ::skills::Skill1HBlunt; skill_id <= EQ::skills::Skill2HPiercing; skill_id++) {
|
||||
if (SkillUsable(db, skill_id, class_id)) {
|
||||
uint32 previous_cap = 0;
|
||||
for (uint8 level = 1; level <= skill_cap_max_level; level++) {
|
||||
uint32 cap = GetSkill(db, skill_id, class_id, level);
|
||||
if (cap < previous_cap) {
|
||||
cap = previous_cap;
|
||||
}
|
||||
|
||||
fprintf(f, "%d^%d^%d^%d^0\n", cl, skill, level, cap);
|
||||
file << fmt::format("{}^{}^{}^{}^0", class_id, skill_id, level, cap) << std::endl;
|
||||
|
||||
previous_cap = cap;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
fclose(f);
|
||||
file.close();
|
||||
}
|
||||
|
||||
void ExportBaseData(SharedDatabase *db)
|
||||
|
||||
+11
-9
@@ -83,6 +83,7 @@ SET(common_sources
|
||||
shared_tasks.cpp
|
||||
shareddb.cpp
|
||||
skills.cpp
|
||||
skill_caps.cpp
|
||||
spdat.cpp
|
||||
strings.cpp
|
||||
struct_strategy.cpp
|
||||
@@ -492,7 +493,7 @@ SET(repositories
|
||||
repositories/zone_repository.h
|
||||
repositories/zone_points_repository.h
|
||||
|
||||
)
|
||||
)
|
||||
|
||||
SET(common_headers
|
||||
additive_lagged_fibonacci_engine.h
|
||||
@@ -592,7 +593,7 @@ SET(common_headers
|
||||
ptimer.h
|
||||
queue.h
|
||||
races.h
|
||||
raid.h
|
||||
raid.h
|
||||
random.h
|
||||
rdtsc.h
|
||||
rulesys.h
|
||||
@@ -606,6 +607,7 @@ SET(common_headers
|
||||
shared_tasks.h
|
||||
shareddb.h
|
||||
skills.h
|
||||
skill_caps.h
|
||||
spdat.h
|
||||
strings.h
|
||||
struct_strategy.h
|
||||
@@ -681,13 +683,13 @@ SOURCE_GROUP(Event FILES
|
||||
event/event_loop.h
|
||||
event/timer.h
|
||||
event/task.h
|
||||
)
|
||||
)
|
||||
|
||||
SOURCE_GROUP(Json FILES
|
||||
json/json.h
|
||||
json/jsoncpp.cpp
|
||||
json/json-forwards.h
|
||||
)
|
||||
)
|
||||
|
||||
SOURCE_GROUP(Net FILES
|
||||
net/console_server.cpp
|
||||
@@ -724,7 +726,7 @@ SOURCE_GROUP(Net FILES
|
||||
net/websocket_server.h
|
||||
net/websocket_server_connection.cpp
|
||||
net/websocket_server_connection.h
|
||||
)
|
||||
)
|
||||
|
||||
SOURCE_GROUP(Patches FILES
|
||||
patches/patches.h
|
||||
@@ -768,12 +770,12 @@ SOURCE_GROUP(Patches FILES
|
||||
patches/titanium_limits.cpp
|
||||
patches/uf.cpp
|
||||
patches/uf_limits.cpp
|
||||
)
|
||||
)
|
||||
|
||||
SOURCE_GROUP(StackWalker FILES
|
||||
StackWalker/StackWalker.h
|
||||
StackWalker/StackWalker.cpp
|
||||
)
|
||||
)
|
||||
|
||||
SOURCE_GROUP(Util FILES
|
||||
util/memory_stream.h
|
||||
@@ -781,7 +783,7 @@ SOURCE_GROUP(Util FILES
|
||||
util/directory.h
|
||||
util/uuid.cpp
|
||||
util/uuid.h
|
||||
)
|
||||
)
|
||||
|
||||
INCLUDE_DIRECTORIES(Patches SocketLib StackWalker)
|
||||
|
||||
@@ -794,6 +796,6 @@ ENDIF (UNIX)
|
||||
|
||||
IF (WIN32 AND EQEMU_BUILD_PCH)
|
||||
TARGET_PRECOMPILE_HEADERS(common PRIVATE pch/pch.h)
|
||||
ENDIF()
|
||||
ENDIF ()
|
||||
|
||||
SET(LIBRARY_OUTPUT_PATH ${PROJECT_BINARY_DIR}/bin)
|
||||
|
||||
+995
-1287
File diff suppressed because it is too large
Load Diff
+144
-140
@@ -18,8 +18,8 @@
|
||||
#ifndef EQEMU_DATABASE_H
|
||||
#define EQEMU_DATABASE_H
|
||||
|
||||
#define AUTHENTICATION_TIMEOUT 60
|
||||
#define INVALID_ID 0xFFFFFFFF
|
||||
#define AUTHENTICATION_TIMEOUT 60
|
||||
#define INVALID_ID 0xFFFFFFFF
|
||||
|
||||
#include "global_define.h"
|
||||
#include "eqemu_logsys.h"
|
||||
@@ -38,8 +38,7 @@
|
||||
class MySQLRequestResult;
|
||||
class Client;
|
||||
|
||||
namespace EQ
|
||||
{
|
||||
namespace EQ {
|
||||
class InventoryProfile;
|
||||
}
|
||||
|
||||
@@ -52,10 +51,11 @@ struct npcDecayTimes_Struct {
|
||||
|
||||
struct VarCache_Struct {
|
||||
std::map<std::string, std::string> m_cache;
|
||||
uint32 last_update;
|
||||
uint32 last_update;
|
||||
VarCache_Struct() : last_update(0) { }
|
||||
void Add(const std::string &key, const std::string &value) { m_cache[key] = value; }
|
||||
const std::string *Get(const std::string &key) {
|
||||
void Add(const std::string& key, const std::string& value) { m_cache[key] = value; }
|
||||
const std::string* Get(const std::string& key)
|
||||
{
|
||||
auto it = m_cache.find(key);
|
||||
return (it != m_cache.end() ? &it->second : nullptr);
|
||||
}
|
||||
@@ -76,37 +76,33 @@ class PTimerList;
|
||||
|
||||
#define SQL(...) #__VA_ARGS__
|
||||
|
||||
class LogSettings;
|
||||
class Database : public DBcore {
|
||||
public:
|
||||
Database();
|
||||
Database(const char* host, const char* user, const char* passwd, const char* database,uint32 port);
|
||||
bool Connect(const char* host, const char* user, const char* passwd, const char* database, uint32 port, std::string connection_label = "default");
|
||||
Database(
|
||||
const std::string& host,
|
||||
const std::string& user,
|
||||
const std::string& password,
|
||||
const std::string& database,
|
||||
uint32 port
|
||||
);
|
||||
bool Connect(
|
||||
const std::string& host,
|
||||
const std::string& user,
|
||||
const std::string& password,
|
||||
const std::string& database,
|
||||
uint32 port,
|
||||
std::string connection_label = "default"
|
||||
);
|
||||
~Database();
|
||||
|
||||
/* Character Creation */
|
||||
|
||||
bool CreateCharacter(
|
||||
uint32 account_id,
|
||||
char *name,
|
||||
uint16 gender,
|
||||
uint16 race,
|
||||
uint16 class_,
|
||||
uint8 str,
|
||||
uint8 sta,
|
||||
uint8 cha,
|
||||
uint8 dex,
|
||||
uint8 int_,
|
||||
uint8 agi,
|
||||
uint8 wis,
|
||||
uint8 face
|
||||
);
|
||||
bool DeleteCharacter(char *character_name);
|
||||
bool MoveCharacterToZone(const char *charname, uint32 zone_id);
|
||||
bool DeleteCharacter(const std::string& name);
|
||||
bool MoveCharacterToZone(const std::string& name, uint32 zone_id);
|
||||
bool MoveCharacterToZone(uint32 character_id, uint32 zone_id);
|
||||
bool ReserveName(uint32 account_id, char *name);
|
||||
bool SaveCharacterCreate(uint32 character_id, uint32 account_id, PlayerProfile_Struct *pp);
|
||||
bool UpdateName(const char *oldname, const char *newname);
|
||||
bool ReserveName(uint32 account_id, const std::string& name);
|
||||
bool SaveCharacterCreate(uint32 character_id, uint32 account_id, PlayerProfile_Struct* pp);
|
||||
bool UpdateName(const std::string& old_name, const std::string& new_name);
|
||||
bool CopyCharacter(
|
||||
const std::string& source_character_name,
|
||||
const std::string& destination_character_name,
|
||||
@@ -114,163 +110,171 @@ public:
|
||||
);
|
||||
|
||||
/* General Information Queries */
|
||||
bool AddBannedIP(const std::string& banned_ip, const std::string& notes); //Add IP address to the banned_ips table.
|
||||
bool AddToNameFilter(const std::string& name);
|
||||
bool CheckBannedIPs(const std::string& login_ip); //Check incoming connection against banned IP table.
|
||||
bool CheckGMIPs(const std::string& login_ip, uint32 account_id);
|
||||
bool CheckNameFilter(const std::string& name, bool surname = false);
|
||||
bool IsNameUsed(const std::string& name);
|
||||
|
||||
bool AddBannedIP(std::string banned_ip, std::string notes); //Add IP address to the banned_ips table.
|
||||
bool AddToNameFilter(std::string name);
|
||||
bool CheckBannedIPs(std::string login_ip); //Check incoming connection against banned IP table.
|
||||
bool CheckGMIPs(std::string login_ip, uint32 account_id);
|
||||
bool CheckNameFilter(std::string name, bool surname = false);
|
||||
bool CheckUsedName(std::string name);
|
||||
uint32 GetAccountIDByChar(const std::string& name, uint32* character_id = 0);
|
||||
uint32 GetAccountIDByChar(uint32 character_id);
|
||||
uint32 GetAccountIDByName(const std::string& account_name, const std::string& loginserver, int16* status = 0, uint32* lsid = 0);
|
||||
uint32 GetCharacterID(const std::string& name);
|
||||
uint32 GetGuildIDByCharID(uint32 character_id);
|
||||
uint32 GetGroupIDByCharID(uint32 character_id);
|
||||
uint32 GetRaidIDByCharID(uint32 character_id);
|
||||
|
||||
uint32 GetAccountIDByChar(const char* charname, uint32* oCharID = 0);
|
||||
uint32 GetAccountIDByChar(uint32 char_id);
|
||||
uint32 GetAccountIDByName(std::string account_name, std::string loginserver, int16* status = 0, uint32* lsid = 0);
|
||||
uint32 GetCharacterID(const std::string& name);
|
||||
uint32 GetCharacterInfo(std::string character_name, uint32 *account_id, uint32 *zone_id, uint32 *instance_id);
|
||||
uint32 GetGuildIDByCharID(uint32 char_id);
|
||||
uint32 GetGroupIDByCharID(uint32 char_id);
|
||||
uint32 GetRaidIDByCharID(uint32 char_id);
|
||||
|
||||
void GetAccountName(uint32 accountid, char* name, uint32* oLSAccountID = 0);
|
||||
void GetCharName(uint32 char_id, char* name);
|
||||
std::string GetCharNameByID(uint32 char_id);
|
||||
std::string GetNPCNameByID(uint32 npc_id);
|
||||
std::string GetCleanNPCNameByID(uint32 npc_id);
|
||||
void LoginIP(uint32 account_id, std::string login_ip);
|
||||
const std::string GetAccountName(uint32 account_id, uint32* lsaccount_id = 0);
|
||||
const std::string GetCharName(uint32 character_id);
|
||||
const std::string GetCharNameByID(uint32 character_id);
|
||||
const std::string GetNPCNameByID(uint32 npc_id);
|
||||
const std::string GetCleanNPCNameByID(uint32 npc_id);
|
||||
void LoginIP(uint32 account_id, const std::string& login_ip);
|
||||
|
||||
/* Instancing */
|
||||
|
||||
bool AddClientToInstance(uint16 instance_id, uint32 character_id);
|
||||
bool CheckInstanceByCharID(uint16 instance_id, uint32 character_id);
|
||||
bool CheckInstanceExists(uint16 instance_id);
|
||||
bool CheckInstanceExpired(uint16 instance_id);
|
||||
bool CreateInstance(uint16 instance_id, uint32 zone_id, uint32 version, uint32 duration);
|
||||
bool GetUnusedInstanceID(uint16 &instance_id);
|
||||
bool GetUnusedInstanceID(uint16& instance_id);
|
||||
bool IsGlobalInstance(uint16 instance_id);
|
||||
bool RemoveClientFromInstance(uint16 instance_id, uint32 char_id);
|
||||
bool RemoveClientsFromInstance(uint16 instance_id);
|
||||
bool VerifyInstanceAlive(uint16 instance_id, uint32 character_id);
|
||||
bool VerifyZoneInstance(uint32 zone_id, uint16 instance_id);
|
||||
|
||||
uint16 GetInstanceID(uint32 zone, uint32 charid, int16 version);
|
||||
uint16 GetInstanceID(uint32 zone, uint32 character_id, int16 version);
|
||||
std::vector<uint16> GetInstanceIDs(uint32 zone_id, uint32 character_id);
|
||||
uint8_t GetInstanceVersion(uint16 instance_id);
|
||||
uint32 GetTimeRemainingInstance(uint16 instance_id, bool &is_perma);
|
||||
uint32 GetTimeRemainingInstance(uint16 instance_id, bool& is_perma);
|
||||
uint32 GetInstanceZoneID(uint16 instance_id);
|
||||
|
||||
void AssignGroupToInstance(uint32 gid, uint32 instance_id);
|
||||
void AssignRaidToInstance(uint32 rid, uint32 instance_id);
|
||||
void AssignGroupToInstance(uint32 group_id, uint32 instance_id);
|
||||
void AssignRaidToInstance(uint32 raid_id, uint32 instance_id);
|
||||
void DeleteInstance(uint16 instance_id);
|
||||
void FlagInstanceByGroupLeader(uint32 zone_id, int16 version, uint32 charid, uint32 group_id);
|
||||
void FlagInstanceByRaidLeader(uint32 zone_id, int16 version, uint32 charid, uint32 raid_id);
|
||||
void GetCharactersInInstance(uint16 instance_id, std::list<uint32> &character_ids);
|
||||
void FlagInstanceByGroupLeader(uint32 zone_id, int16 version, uint32 character_id, uint32 group_id);
|
||||
void FlagInstanceByRaidLeader(uint32 zone_id, int16 version, uint32 character_id, uint32 raid_id);
|
||||
void GetCharactersInInstance(uint16 instance_id, std::list<uint32>& character_ids);
|
||||
void PurgeExpiredInstances();
|
||||
void SetInstanceDuration(uint16 instance_id, uint32 new_duration);
|
||||
void CleanupInstanceCorpses();
|
||||
|
||||
/* Adventure related. */
|
||||
|
||||
void UpdateAdventureStatsEntry(uint32 char_id, uint8 theme, bool win = false, bool remove = false);
|
||||
bool GetAdventureStats(uint32 char_id, AdventureStats_Struct *as);
|
||||
void UpdateAdventureStatsEntry(uint32 character_id, uint8 theme_id, bool is_win = false, bool is_remove = false);
|
||||
bool GetAdventureStats(uint32 character_id, AdventureStats_Struct* as);
|
||||
|
||||
/* Account Related */
|
||||
const std::string GetLiveChar(uint32 account_id);
|
||||
bool SetAccountStatus(const std::string& account_name, int16 status);
|
||||
bool SetLocalPassword(uint32 account_id, const std::string& password);
|
||||
bool UpdateLiveChar(const std::string& name, uint32 account_id);
|
||||
int16 CheckStatus(uint32 account_id);
|
||||
void SetAccountCRCField(uint32 account_id, const std::string& field_name, uint64 checksum);
|
||||
uint32 CheckLogin(const std::string& name, const std::string& password, const std::string& loginserver, int16* status = 0);
|
||||
uint32 CreateAccount(
|
||||
const std::string& name,
|
||||
const std::string& password,
|
||||
int16 status,
|
||||
const std::string& loginserver,
|
||||
uint32 lsaccount_id
|
||||
);
|
||||
uint32 GetAccountIDFromLSID(
|
||||
const std::string& in_loginserver_id,
|
||||
uint32 in_loginserver_account_id,
|
||||
char* in_account_name = 0,
|
||||
int16* in_status = 0
|
||||
);
|
||||
|
||||
bool DeleteAccount(const char *name, const char* loginserver);
|
||||
bool GetLiveChar(uint32 account_id, char* cname);
|
||||
bool SetAccountStatus(const char* name, int16 status);
|
||||
bool SetAccountStatus(const std::string& account_name, int16 status);
|
||||
bool SetLocalPassword(uint32 accid, const char* password);
|
||||
bool UpdateLiveChar(char* charname, uint32 account_id);
|
||||
uint8 GetAgreementFlag(uint32 account_id);
|
||||
void SetAgreementFlag(uint32 account_id);
|
||||
|
||||
int16 CheckStatus(uint32 account_id);
|
||||
int GetIPExemption(const std::string& account_ip);
|
||||
void SetIPExemption(const std::string& account_ip, int exemption_amount);
|
||||
|
||||
void SetAccountCRCField(uint32 account_id, std::string field_name, uint64 checksum);
|
||||
|
||||
uint32 CheckLogin(const char* name, const char* password, const char *loginserver, int16* oStatus = 0);
|
||||
uint32 CreateAccount(const char* name, const char* password, int16 status, const char* loginserver, uint32 lsaccount_id);
|
||||
uint32 GetAccountIDFromLSID(const std::string& in_loginserver_id, uint32 in_loginserver_account_id, char* in_account_name = 0, int16* in_status = 0);
|
||||
uint8 GetAgreementFlag(uint32 account_id);
|
||||
|
||||
void GetAccountFromID(uint32 id, char* oAccountName, int16* oStatus);
|
||||
void SetAgreementFlag(uint32 account_id);
|
||||
|
||||
int GetIPExemption(std::string account_ip);
|
||||
void SetIPExemption(std::string account_ip, int exemption_amount);
|
||||
|
||||
int GetInstanceID(uint32 char_id, uint32 zone_id);
|
||||
int GetInstanceID(uint32 character_id, uint32 zone_id);
|
||||
|
||||
|
||||
/* Groups */
|
||||
|
||||
std::string GetGroupLeaderForLogin(std::string character_name);
|
||||
char* GetGroupLeadershipInfo(uint32 gid, char* leaderbuf, char* maintank = nullptr, char* assist = nullptr, char* puller = nullptr, char *marknpc = nullptr, char *mentoree = nullptr, int *mentor_percent = nullptr, GroupLeadershipAA_Struct* GLAA = nullptr);
|
||||
|
||||
std::string GetGroupLeaderForLogin(const std::string& character_name);
|
||||
char* GetGroupLeadershipInfo(
|
||||
uint32 group_id,
|
||||
char* leaderbuf,
|
||||
char* maintank = nullptr,
|
||||
char* assist = nullptr,
|
||||
char* puller = nullptr,
|
||||
char* marknpc = nullptr,
|
||||
char* mentoree = nullptr,
|
||||
int* mentor_percent = nullptr,
|
||||
GroupLeadershipAA_Struct* GLAA = nullptr
|
||||
);
|
||||
std::string GetGroupLeaderName(uint32 group_id);
|
||||
|
||||
uint32 GetGroupID(const char* name);
|
||||
|
||||
void ClearGroup(uint32 gid = 0);
|
||||
void ClearGroupLeader(uint32 gid = 0);
|
||||
void SetGroupID(const char* name, uint32 id, uint32 charid, uint32 ismerc = false);
|
||||
void SetGroupLeaderName(uint32 gid, const char* name);
|
||||
uint32 GetGroupID(const std::string& name);
|
||||
void ClearGroup(uint32 group_id = 0);
|
||||
void ClearGroupLeader(uint32 group_id = 0);
|
||||
void SetGroupLeaderName(uint32 group_id, const std::string& name);
|
||||
|
||||
/* Raids */
|
||||
const std::string GetRaidLeaderName(uint32 raid_id);
|
||||
uint32 GetRaidID(const std::string& name);
|
||||
void ClearRaid(uint32 raid_id = 0);
|
||||
void ClearRaidDetails(uint32 raid_id = 0);
|
||||
void ClearRaidLeader(uint32 group_id = std::numeric_limits<uint32>::max(), uint32 raid_id = 0);
|
||||
void GetGroupLeadershipInfo(
|
||||
uint32 group_id,
|
||||
uint32 raid_id,
|
||||
char* maintank = nullptr,
|
||||
char* assist = nullptr,
|
||||
char* puller = nullptr,
|
||||
char* marknpc = nullptr,
|
||||
char* mentoree = nullptr,
|
||||
int* mentor_percent = nullptr,
|
||||
GroupLeadershipAA_Struct* GLAA = nullptr
|
||||
);
|
||||
void GetRaidLeadershipInfo(
|
||||
uint32 raid_id,
|
||||
char* maintank = nullptr,
|
||||
char* assist = nullptr,
|
||||
char* puller = nullptr,
|
||||
char* marknpc = nullptr,
|
||||
RaidLeadershipAA_Struct* RLAA = nullptr
|
||||
);
|
||||
void SetRaidGroupLeaderInfo(uint32 group_id, uint32 raid_id);
|
||||
|
||||
const char *GetRaidLeaderName(uint32 rid);
|
||||
|
||||
uint32 GetRaidID(const char* name);
|
||||
|
||||
void ClearRaid(uint32 rid = 0);
|
||||
void ClearRaidDetails(uint32 rid = 0);
|
||||
void ClearRaidLeader(uint32 gid = 0xFFFFFFFF, uint32 rid = 0);
|
||||
void GetGroupLeadershipInfo(uint32 gid, uint32 rid, char* maintank = nullptr, char* assist = nullptr, char* puller = nullptr, char *marknpc = nullptr, char *mentoree = nullptr, int *mentor_percent = nullptr, GroupLeadershipAA_Struct* GLAA = nullptr);
|
||||
void GetRaidLeadershipInfo(uint32 rid, char* maintank = nullptr, char* assist = nullptr, char* puller = nullptr, char *marknpc = nullptr, RaidLeadershipAA_Struct* RLAA = nullptr);
|
||||
void SetRaidGroupLeaderInfo(uint32 gid, uint32 rid);
|
||||
|
||||
void PurgeAllDeletedDataBuckets();
|
||||
void PurgeAllDeletedDataBuckets();
|
||||
|
||||
|
||||
/* Database Variables */
|
||||
bool GetVariable(const std::string& name, std::string& value);
|
||||
bool SetVariable(const std::string& name, const std::string& value);
|
||||
bool LoadVariables();
|
||||
|
||||
bool GetVariable(std::string varname, std::string &varvalue);
|
||||
bool SetVariable(const std::string& varname, const std::string &varvalue);
|
||||
bool LoadVariables();
|
||||
uint8 GetPEQZone(uint32 zone_id, uint32 version);
|
||||
uint32 GetServerType();
|
||||
void AddReport(const std::string& who, const std::string& against, const std::string& lines);
|
||||
struct TimeOfDay_Struct LoadTime(time_t& realtime);
|
||||
bool SaveTime(int8 minute, int8 hour, int8 day, int8 month, int16 year);
|
||||
void ClearMerchantTemp();
|
||||
void ClearPTimers(uint32 character_id);
|
||||
void SetFirstLogon(uint32 character_id, uint8 first_logon);
|
||||
void SetLFG(uint32 character_id, bool is_lfg);
|
||||
void SetLFP(uint32 character_id, bool is_lfp);
|
||||
void SetLoginFlags(uint32 character_id, bool is_lfp, bool is_lfg, uint8 first_logon);
|
||||
|
||||
/* General Queries */
|
||||
int64 CountInvSnapshots();
|
||||
void ClearInvSnapshots(bool from_now = false);
|
||||
|
||||
bool GetZoneGraveyard(const uint32 graveyard_id, uint32* graveyard_zoneid = 0, float* graveyard_x = 0, float* graveyard_y = 0, float* graveyard_z = 0, float* graveyard_heading = 0);
|
||||
bool LoadPTimers(uint32 charid, PTimerList &into);
|
||||
|
||||
uint8 GetPEQZone(uint32 zone_id, uint32 version);
|
||||
uint8 GetMinStatus(uint32 zone_id, uint32 instance_version);
|
||||
uint8 GetRaceSkill(uint8 skillid, uint8 in_race);
|
||||
uint8 GetServerType();
|
||||
uint8 GetSkillCap(uint8 skillid, uint8 in_race, uint8 in_class, uint16 in_level);
|
||||
|
||||
void AddReport(std::string who, std::string against, std::string lines);
|
||||
struct TimeOfDay_Struct LoadTime(time_t &realtime);
|
||||
bool SaveTime(int8 minute, int8 hour, int8 day, int8 month, int16 year);
|
||||
void ClearMerchantTemp();
|
||||
void ClearPTimers(uint32 charid);
|
||||
void SetFirstLogon(uint32 CharID, uint8 firstlogon);
|
||||
void SetLFG(uint32 CharID, bool LFG);
|
||||
void SetLFP(uint32 CharID, bool LFP);
|
||||
void SetLoginFlags(uint32 CharID, bool LFP, bool LFG, uint8 firstlogon);
|
||||
|
||||
int CountInvSnapshots();
|
||||
void ClearInvSnapshots(bool from_now = false);
|
||||
|
||||
void SourceDatabaseTableFromUrl(std::string table_name, std::string url);
|
||||
void SourceSqlFromUrl(std::string url);
|
||||
void SourceDatabaseTableFromUrl(const std::string& table_name, const std::string& url);
|
||||
void SourceSqlFromUrl(const std::string& url);
|
||||
|
||||
private:
|
||||
|
||||
Mutex Mvarcache;
|
||||
Mutex Mvarcache;
|
||||
VarCache_Struct varcache;
|
||||
|
||||
/* Groups, utility methods. */
|
||||
void ClearAllGroupLeaders();
|
||||
void ClearAllGroups();
|
||||
void ClearAllGroupLeaders();
|
||||
void ClearAllGroups();
|
||||
|
||||
/* Raid, utility methods. */
|
||||
void ClearAllRaids();
|
||||
|
||||
@@ -5433,6 +5433,42 @@ ADD PRIMARY KEY (`id`);
|
||||
ALTER TABLE `rule_values`
|
||||
MODIFY COLUMN `rule_value` text CHARACTER SET latin1 COLLATE latin1_swedish_ci NULL DEFAULT NULL AFTER `rule_name`;
|
||||
)"
|
||||
},
|
||||
ManifestEntry{
|
||||
.version = 9267,
|
||||
.description = "2024_02_18_group_id_bot_id.sql",
|
||||
.check = "SHOW COLUMNS FROM `group_id` LIKE 'bot_id'",
|
||||
.condition = "empty",
|
||||
.match = "",
|
||||
.sql = R"(
|
||||
ALTER TABLE `group_id`
|
||||
CHANGE COLUMN `groupid` `group_id` int(11) UNSIGNED NOT NULL DEFAULT 0 FIRST,
|
||||
CHANGE COLUMN `charid` `character_id` int(11) UNSIGNED NOT NULL DEFAULT 0 AFTER `group_id`,
|
||||
CHANGE COLUMN `ismerc` `merc_id` int(11) UNSIGNED NOT NULL DEFAULT 0 AFTER `name`,
|
||||
ADD COLUMN `bot_id` int(11) UNSIGNED NOT NULL DEFAULT 0 AFTER `character_id`,
|
||||
MODIFY COLUMN `name` varchar(64) NOT NULL DEFAULT '' AFTER `character_id`,
|
||||
DROP PRIMARY KEY,
|
||||
ADD PRIMARY KEY (`group_id`, `character_id`, `bot_id`, `merc_id`) USING BTREE;
|
||||
ALTER TABLE `group_id`
|
||||
MODIFY COLUMN `character_id` int(11) UNSIGNED NOT NULL DEFAULT 0 AFTER `name`;
|
||||
)"
|
||||
},
|
||||
ManifestEntry{
|
||||
.version = 9268,
|
||||
.description = "2024_03_23_skill_caps.sql",
|
||||
.check = "SHOW COLUMNS FROM `skill_caps` LIKE 'skill_id'",
|
||||
.condition = "empty",
|
||||
.match = "",
|
||||
.sql = R"(
|
||||
ALTER TABLE `skill_caps`
|
||||
CHANGE COLUMN `skillID` `skill_id` tinyint(3) UNSIGNED NOT NULL DEFAULT 0 FIRST,
|
||||
CHANGE COLUMN `class` `class_id` tinyint(3) UNSIGNED NOT NULL DEFAULT 0 AFTER `skill_id`,
|
||||
ADD COLUMN `id` int(3) UNSIGNED NOT NULL AUTO_INCREMENT FIRST,
|
||||
DROP PRIMARY KEY,
|
||||
ADD PRIMARY KEY (`id`) USING BTREE,
|
||||
ADD INDEX `level_skill_cap`(`skill_id`, `class_id`, `level`, `cap`);
|
||||
)",
|
||||
.content_schema_update = true,
|
||||
}
|
||||
// -- template; copy/paste this when you need to create a new entry
|
||||
// ManifestEntry{
|
||||
|
||||
@@ -421,20 +421,25 @@ void Database::AssignGroupToInstance(uint32 group_id, uint32 instance_id)
|
||||
auto zone_id = GetInstanceZoneID(instance_id);
|
||||
auto version = GetInstanceVersion(instance_id);
|
||||
|
||||
auto l = GroupIdRepository::GetWhere(
|
||||
const auto& l = GroupIdRepository::GetWhere(
|
||||
*this,
|
||||
fmt::format(
|
||||
"groupid = {}",
|
||||
"`group_id` = {}",
|
||||
group_id
|
||||
)
|
||||
);
|
||||
|
||||
if (l.empty()) {
|
||||
return;
|
||||
}
|
||||
|
||||
for (const auto& e : l) {
|
||||
if (!GetInstanceID(zone_id, e.charid, version)) {
|
||||
AddClientToInstance(instance_id, e.charid);
|
||||
if (!e.character_id) {
|
||||
continue;
|
||||
}
|
||||
|
||||
if (!GetInstanceID(zone_id, e.character_id, version)) {
|
||||
AddClientToInstance(instance_id, e.character_id);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -504,7 +509,7 @@ void Database::FlagInstanceByRaidLeader(uint32 zone_id, int16 version, uint32 ch
|
||||
return;
|
||||
}
|
||||
|
||||
auto raid_leader_id = GetCharacterID(GetRaidLeaderName(raid_id));
|
||||
auto raid_leader_id = GetCharacterID(GetRaidLeaderName(raid_id).c_str());
|
||||
auto raid_leader_instance_id = GetInstanceID(zone_id, raid_leader_id, version);
|
||||
|
||||
if (!raid_leader_instance_id) {
|
||||
|
||||
@@ -89,6 +89,8 @@ namespace EQ
|
||||
using RoF2::invslot::SLOT_INVALID;
|
||||
using RoF2::invslot::SLOT_BEGIN;
|
||||
|
||||
using RoF2::invslot::SLOT_QUEST;
|
||||
|
||||
using Titanium::invslot::SLOT_TRADESKILL_EXPERIMENT_COMBINE;
|
||||
|
||||
const int16 SLOT_AUGMENT_GENERIC_RETURN = 1001; // clients don't appear to use this method... (internal inventory return value)
|
||||
|
||||
@@ -130,6 +130,11 @@ enum CrystalReclaimTypes
|
||||
Radiant = 4,
|
||||
};
|
||||
|
||||
namespace ItemStackSizeConstraint {
|
||||
constexpr int16 Minimum = 1;
|
||||
constexpr int16 Maximum = 1000;
|
||||
}
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
|
||||
|
||||
@@ -82,6 +82,10 @@ Zone extensions and features
|
||||
#define QUEST_GLOBAL_DIRECTORY "global"
|
||||
#endif
|
||||
|
||||
// Number of quest items a Quest NPC can hold
|
||||
#define MAX_NPC_QUEST_INVENTORY 24
|
||||
|
||||
|
||||
//the min ratio at which a mob's speed is reduced
|
||||
#define FLEE_HP_MINSPEED 22
|
||||
//number of tics to try to run straight away before looking again
|
||||
@@ -111,6 +115,7 @@ Zone extensions and features
|
||||
|
||||
#define SKILL_MAX_LEVEL 75
|
||||
|
||||
|
||||
/*
|
||||
|
||||
Zone Numerical configuration
|
||||
|
||||
@@ -25,6 +25,8 @@ struct LootItem {
|
||||
uint16 trivial_max_level;
|
||||
uint16 npc_min_level;
|
||||
uint16 npc_max_level;
|
||||
uint8 quest;
|
||||
uint8 pet;
|
||||
};
|
||||
|
||||
typedef std::list<LootItem*> LootItems;
|
||||
|
||||
@@ -165,6 +165,8 @@ namespace RoF2
|
||||
const int16 SLOT_INVALID = IINVALID;
|
||||
const int16 SLOT_BEGIN = INULL;
|
||||
|
||||
const int16 SLOT_QUEST = 9999;
|
||||
|
||||
const int16 POSSESSIONS_BEGIN = slotCharm;
|
||||
const int16 POSSESSIONS_END = slotCursor;
|
||||
const int16 POSSESSIONS_COUNT = (POSSESSIONS_END - POSSESSIONS_BEGIN) + 1;
|
||||
|
||||
@@ -162,6 +162,8 @@ namespace RoF
|
||||
const int16 SLOT_INVALID = IINVALID;
|
||||
const int16 SLOT_BEGIN = INULL;
|
||||
|
||||
const int16 SLOT_QUEST = 9999;
|
||||
|
||||
const int16 POSSESSIONS_BEGIN = slotCharm;
|
||||
const int16 POSSESSIONS_END = slotCursor;
|
||||
const int16 POSSESSIONS_COUNT = (POSSESSIONS_END - POSSESSIONS_BEGIN) + 1;
|
||||
|
||||
@@ -152,6 +152,8 @@ namespace SoD
|
||||
|
||||
const int16 SLOT_TRADESKILL_EXPERIMENT_COMBINE = 1000;
|
||||
|
||||
const int16 SLOT_QUEST = 9999;
|
||||
|
||||
const int16 POSSESSIONS_BEGIN = slotCharm;
|
||||
const int16 POSSESSIONS_END = slotCursor;
|
||||
const int16 POSSESSIONS_COUNT = (POSSESSIONS_END - POSSESSIONS_BEGIN) + 1;
|
||||
|
||||
@@ -152,6 +152,8 @@ namespace SoF
|
||||
|
||||
const int16 SLOT_TRADESKILL_EXPERIMENT_COMBINE = 1000;
|
||||
|
||||
const int16 SLOT_QUEST = 9999;
|
||||
|
||||
const int16 POSSESSIONS_BEGIN = slotCharm;
|
||||
const int16 POSSESSIONS_END = slotCursor;
|
||||
const int16 POSSESSIONS_COUNT = (POSSESSIONS_END - POSSESSIONS_BEGIN) + 1;
|
||||
|
||||
@@ -151,6 +151,8 @@ namespace Titanium
|
||||
|
||||
const int16 SLOT_TRADESKILL_EXPERIMENT_COMBINE = 1000;
|
||||
|
||||
const int16 SLOT_QUEST = 9999;
|
||||
|
||||
const int16 POSSESSIONS_BEGIN = slotCharm;
|
||||
const int16 POSSESSIONS_END = slotCursor;
|
||||
const int16 POSSESSIONS_COUNT = (POSSESSIONS_END - POSSESSIONS_BEGIN) + 1;
|
||||
|
||||
@@ -152,6 +152,8 @@ namespace UF
|
||||
|
||||
const int16 SLOT_TRADESKILL_EXPERIMENT_COMBINE = 1000;
|
||||
|
||||
const int16 SLOT_QUEST = 9999;
|
||||
|
||||
const int16 POSSESSIONS_BEGIN = slotCharm;
|
||||
const int16 POSSESSIONS_END = slotCursor;
|
||||
const int16 POSSESSIONS_COUNT = (POSSESSIONS_END - POSSESSIONS_BEGIN) + 1;
|
||||
|
||||
+1
-1
@@ -1379,7 +1379,7 @@ uint32 GetPlayerRaceValue(uint16 race_id) {
|
||||
}
|
||||
}
|
||||
|
||||
uint32 GetPlayerRaceBit(uint16 race_id) {
|
||||
uint16 GetPlayerRaceBit(uint16 race_id) {
|
||||
switch (race_id) {
|
||||
case HUMAN:
|
||||
return PLAYER_RACE_HUMAN_BIT;
|
||||
|
||||
+1
-1
@@ -124,7 +124,7 @@ bool IsPlayerRace(uint16 race_id);
|
||||
const std::string GetPlayerRaceAbbreviation(uint16 race_id);
|
||||
|
||||
uint32 GetPlayerRaceValue(uint16 race_id);
|
||||
uint32 GetPlayerRaceBit(uint16 race_id);
|
||||
uint16 GetPlayerRaceBit(uint16 race_id);
|
||||
|
||||
uint16 GetRaceIDFromPlayerRaceValue(uint32 player_race_value);
|
||||
uint16 GetRaceIDFromPlayerRaceBit(uint32 player_race_bit);
|
||||
|
||||
@@ -44,7 +44,51 @@ public:
|
||||
*/
|
||||
|
||||
// Custom extended repository methods here
|
||||
static int16 GetAccountStatus(Database& db, const uint32 account_id)
|
||||
{
|
||||
auto results = db.QueryDatabase(
|
||||
fmt::format(
|
||||
"SELECT `status`, TIMESTAMPDIFF(SECOND, NOW(), `suspendeduntil`) FROM `{}` WHERE `{}` = {}",
|
||||
TableName(),
|
||||
PrimaryKey(),
|
||||
account_id
|
||||
)
|
||||
);
|
||||
|
||||
if (!results.Success() || !results.RowCount()) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
auto row = results.begin();
|
||||
|
||||
int16 status = static_cast<int16>(Strings::ToInt(row[0]));
|
||||
int date_diff = 0;
|
||||
|
||||
if (row[1]) {
|
||||
date_diff = Strings::ToInt(row[1]);
|
||||
}
|
||||
|
||||
if (date_diff > 0) {
|
||||
status = -1;
|
||||
}
|
||||
|
||||
return status;
|
||||
}
|
||||
|
||||
static bool UpdatePassword(Database& db, const uint32 account_id, const std::string& password)
|
||||
{
|
||||
auto results = db.QueryDatabase(
|
||||
fmt::format(
|
||||
"UPDATE `{}` SET `password` = MD5('{}') WHERE `{}` = {}",
|
||||
TableName(),
|
||||
password,
|
||||
PrimaryKey(),
|
||||
account_id
|
||||
)
|
||||
);
|
||||
|
||||
return results.Success();
|
||||
}
|
||||
};
|
||||
|
||||
#endif //EQEMU_ACCOUNT_REPOSITORY_H
|
||||
|
||||
@@ -44,7 +44,65 @@ public:
|
||||
*/
|
||||
|
||||
// Custom extended repository methods here
|
||||
static void UpdateAdventureStatsEntry(Database& db, uint32 character_id, uint8 theme_id, bool is_win, bool is_remove)
|
||||
{
|
||||
std::string field;
|
||||
|
||||
switch (theme_id) {
|
||||
case LDoNThemes::GUK: {
|
||||
field = "guk_";
|
||||
break;
|
||||
}
|
||||
case LDoNThemes::MIR: {
|
||||
field = "mir_";
|
||||
break;
|
||||
}
|
||||
case LDoNThemes::MMC: {
|
||||
field = "mmc_";
|
||||
break;
|
||||
}
|
||||
case LDoNThemes::RUJ: {
|
||||
field = "ruj_";
|
||||
break;
|
||||
}
|
||||
case LDoNThemes::TAK: {
|
||||
field = "tak_";
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
field += is_win ? "wins" : "losses";
|
||||
|
||||
auto e = FindOne(db, character_id);
|
||||
|
||||
if (!e.player_id && !is_remove) {
|
||||
const std::string& query = fmt::format(
|
||||
"INSERT INTO `{}` SET `{}` = 1, `{}` = {}",
|
||||
TableName(),
|
||||
field,
|
||||
PrimaryKey(),
|
||||
character_id
|
||||
);
|
||||
|
||||
db.QueryDatabase(query);
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
const std::string& field_operation = is_remove ? "-" : "+";
|
||||
|
||||
const std::string& query = fmt::format(
|
||||
"UPDATE `{}` SET `{}` = {} {} 1 WHERE `{}` = {}",
|
||||
TableName(),
|
||||
field,
|
||||
field,
|
||||
field_operation,
|
||||
PrimaryKey(),
|
||||
character_id
|
||||
);
|
||||
|
||||
db.QueryDatabase(query);
|
||||
}
|
||||
};
|
||||
|
||||
#endif //EQEMU_ADVENTURE_STATS_REPOSITORY_H
|
||||
|
||||
@@ -22,7 +22,7 @@ public:
|
||||
int32_t accid;
|
||||
std::string ip;
|
||||
int32_t count;
|
||||
std::string lastused;
|
||||
time_t lastused;
|
||||
};
|
||||
|
||||
static std::string PrimaryKey()
|
||||
@@ -46,7 +46,7 @@ public:
|
||||
"accid",
|
||||
"ip",
|
||||
"count",
|
||||
"lastused",
|
||||
"UNIX_TIMESTAMP(lastused)",
|
||||
};
|
||||
}
|
||||
|
||||
@@ -130,7 +130,7 @@ public:
|
||||
e.accid = row[0] ? static_cast<int32_t>(atoi(row[0])) : 0;
|
||||
e.ip = row[1] ? row[1] : "";
|
||||
e.count = row[2] ? static_cast<int32_t>(atoi(row[2])) : 1;
|
||||
e.lastused = row[3] ? row[3] : std::time(nullptr);
|
||||
e.lastused = strtoll(row[3] ? row[3] : "-1", nullptr, 10);
|
||||
|
||||
return e;
|
||||
}
|
||||
@@ -167,7 +167,7 @@ public:
|
||||
v.push_back(columns[0] + " = " + std::to_string(e.accid));
|
||||
v.push_back(columns[1] + " = '" + Strings::Escape(e.ip) + "'");
|
||||
v.push_back(columns[2] + " = " + std::to_string(e.count));
|
||||
v.push_back(columns[3] + " = '" + Strings::Escape(e.lastused) + "'");
|
||||
v.push_back(columns[3] + " = FROM_UNIXTIME(" + (e.lastused > 0 ? std::to_string(e.lastused) : "null") + ")");
|
||||
|
||||
auto results = db.QueryDatabase(
|
||||
fmt::format(
|
||||
@@ -192,7 +192,7 @@ public:
|
||||
v.push_back(std::to_string(e.accid));
|
||||
v.push_back("'" + Strings::Escape(e.ip) + "'");
|
||||
v.push_back(std::to_string(e.count));
|
||||
v.push_back("'" + Strings::Escape(e.lastused) + "'");
|
||||
v.push_back("FROM_UNIXTIME(" + (e.lastused > 0 ? std::to_string(e.lastused) : "null") + ")");
|
||||
|
||||
auto results = db.QueryDatabase(
|
||||
fmt::format(
|
||||
@@ -225,7 +225,7 @@ public:
|
||||
v.push_back(std::to_string(e.accid));
|
||||
v.push_back("'" + Strings::Escape(e.ip) + "'");
|
||||
v.push_back(std::to_string(e.count));
|
||||
v.push_back("'" + Strings::Escape(e.lastused) + "'");
|
||||
v.push_back("FROM_UNIXTIME(" + (e.lastused > 0 ? std::to_string(e.lastused) : "null") + ")");
|
||||
|
||||
insert_chunks.push_back("(" + Strings::Implode(",", v) + ")");
|
||||
}
|
||||
@@ -262,7 +262,7 @@ public:
|
||||
e.accid = row[0] ? static_cast<int32_t>(atoi(row[0])) : 0;
|
||||
e.ip = row[1] ? row[1] : "";
|
||||
e.count = row[2] ? static_cast<int32_t>(atoi(row[2])) : 1;
|
||||
e.lastused = row[3] ? row[3] : std::time(nullptr);
|
||||
e.lastused = strtoll(row[3] ? row[3] : "-1", nullptr, 10);
|
||||
|
||||
all_entries.push_back(e);
|
||||
}
|
||||
@@ -290,7 +290,7 @@ public:
|
||||
e.accid = row[0] ? static_cast<int32_t>(atoi(row[0])) : 0;
|
||||
e.ip = row[1] ? row[1] : "";
|
||||
e.count = row[2] ? static_cast<int32_t>(atoi(row[2])) : 1;
|
||||
e.lastused = row[3] ? row[3] : std::time(nullptr);
|
||||
e.lastused = strtoll(row[3] ? row[3] : "-1", nullptr, 10);
|
||||
|
||||
all_entries.push_back(e);
|
||||
}
|
||||
@@ -368,7 +368,7 @@ public:
|
||||
v.push_back(std::to_string(e.accid));
|
||||
v.push_back("'" + Strings::Escape(e.ip) + "'");
|
||||
v.push_back(std::to_string(e.count));
|
||||
v.push_back("'" + Strings::Escape(e.lastused) + "'");
|
||||
v.push_back("FROM_UNIXTIME(" + (e.lastused > 0 ? std::to_string(e.lastused) : "null") + ")");
|
||||
|
||||
auto results = db.QueryDatabase(
|
||||
fmt::format(
|
||||
@@ -394,7 +394,7 @@ public:
|
||||
v.push_back(std::to_string(e.accid));
|
||||
v.push_back("'" + Strings::Escape(e.ip) + "'");
|
||||
v.push_back(std::to_string(e.count));
|
||||
v.push_back("'" + Strings::Escape(e.lastused) + "'");
|
||||
v.push_back("FROM_UNIXTIME(" + (e.lastused > 0 ? std::to_string(e.lastused) : "null") + ")");
|
||||
|
||||
insert_chunks.push_back("(" + Strings::Implode(",", v) + ")");
|
||||
}
|
||||
|
||||
@@ -19,34 +19,37 @@
|
||||
class BaseGroupIdRepository {
|
||||
public:
|
||||
struct GroupId {
|
||||
int32_t groupid;
|
||||
int32_t charid;
|
||||
uint32_t group_id;
|
||||
std::string name;
|
||||
int8_t ismerc;
|
||||
uint32_t character_id;
|
||||
uint32_t bot_id;
|
||||
uint32_t merc_id;
|
||||
};
|
||||
|
||||
static std::string PrimaryKey()
|
||||
{
|
||||
return std::string("groupid");
|
||||
return std::string("group_id");
|
||||
}
|
||||
|
||||
static std::vector<std::string> Columns()
|
||||
{
|
||||
return {
|
||||
"groupid",
|
||||
"charid",
|
||||
"group_id",
|
||||
"name",
|
||||
"ismerc",
|
||||
"character_id",
|
||||
"bot_id",
|
||||
"merc_id",
|
||||
};
|
||||
}
|
||||
|
||||
static std::vector<std::string> SelectColumns()
|
||||
{
|
||||
return {
|
||||
"groupid",
|
||||
"charid",
|
||||
"group_id",
|
||||
"name",
|
||||
"ismerc",
|
||||
"character_id",
|
||||
"bot_id",
|
||||
"merc_id",
|
||||
};
|
||||
}
|
||||
|
||||
@@ -87,10 +90,11 @@ public:
|
||||
{
|
||||
GroupId e{};
|
||||
|
||||
e.groupid = 0;
|
||||
e.charid = 0;
|
||||
e.name = "";
|
||||
e.ismerc = 0;
|
||||
e.group_id = 0;
|
||||
e.name = "";
|
||||
e.character_id = 0;
|
||||
e.bot_id = 0;
|
||||
e.merc_id = 0;
|
||||
|
||||
return e;
|
||||
}
|
||||
@@ -101,7 +105,7 @@ public:
|
||||
)
|
||||
{
|
||||
for (auto &group_id : group_ids) {
|
||||
if (group_id.groupid == group_id_id) {
|
||||
if (group_id.group_id == group_id_id) {
|
||||
return group_id;
|
||||
}
|
||||
}
|
||||
@@ -127,10 +131,11 @@ public:
|
||||
if (results.RowCount() == 1) {
|
||||
GroupId e{};
|
||||
|
||||
e.groupid = row[0] ? static_cast<int32_t>(atoi(row[0])) : 0;
|
||||
e.charid = row[1] ? static_cast<int32_t>(atoi(row[1])) : 0;
|
||||
e.name = row[2] ? row[2] : "";
|
||||
e.ismerc = row[3] ? static_cast<int8_t>(atoi(row[3])) : 0;
|
||||
e.group_id = row[0] ? static_cast<uint32_t>(strtoul(row[0], nullptr, 10)) : 0;
|
||||
e.name = row[1] ? row[1] : "";
|
||||
e.character_id = row[2] ? static_cast<uint32_t>(strtoul(row[2], nullptr, 10)) : 0;
|
||||
e.bot_id = row[3] ? static_cast<uint32_t>(strtoul(row[3], nullptr, 10)) : 0;
|
||||
e.merc_id = row[4] ? static_cast<uint32_t>(strtoul(row[4], nullptr, 10)) : 0;
|
||||
|
||||
return e;
|
||||
}
|
||||
@@ -164,10 +169,11 @@ public:
|
||||
|
||||
auto columns = Columns();
|
||||
|
||||
v.push_back(columns[0] + " = " + std::to_string(e.groupid));
|
||||
v.push_back(columns[1] + " = " + std::to_string(e.charid));
|
||||
v.push_back(columns[2] + " = '" + Strings::Escape(e.name) + "'");
|
||||
v.push_back(columns[3] + " = " + std::to_string(e.ismerc));
|
||||
v.push_back(columns[0] + " = " + std::to_string(e.group_id));
|
||||
v.push_back(columns[1] + " = '" + Strings::Escape(e.name) + "'");
|
||||
v.push_back(columns[2] + " = " + std::to_string(e.character_id));
|
||||
v.push_back(columns[3] + " = " + std::to_string(e.bot_id));
|
||||
v.push_back(columns[4] + " = " + std::to_string(e.merc_id));
|
||||
|
||||
auto results = db.QueryDatabase(
|
||||
fmt::format(
|
||||
@@ -175,7 +181,7 @@ public:
|
||||
TableName(),
|
||||
Strings::Implode(", ", v),
|
||||
PrimaryKey(),
|
||||
e.groupid
|
||||
e.group_id
|
||||
)
|
||||
);
|
||||
|
||||
@@ -189,10 +195,11 @@ public:
|
||||
{
|
||||
std::vector<std::string> v;
|
||||
|
||||
v.push_back(std::to_string(e.groupid));
|
||||
v.push_back(std::to_string(e.charid));
|
||||
v.push_back(std::to_string(e.group_id));
|
||||
v.push_back("'" + Strings::Escape(e.name) + "'");
|
||||
v.push_back(std::to_string(e.ismerc));
|
||||
v.push_back(std::to_string(e.character_id));
|
||||
v.push_back(std::to_string(e.bot_id));
|
||||
v.push_back(std::to_string(e.merc_id));
|
||||
|
||||
auto results = db.QueryDatabase(
|
||||
fmt::format(
|
||||
@@ -203,7 +210,7 @@ public:
|
||||
);
|
||||
|
||||
if (results.Success()) {
|
||||
e.groupid = results.LastInsertedID();
|
||||
e.group_id = results.LastInsertedID();
|
||||
return e;
|
||||
}
|
||||
|
||||
@@ -222,10 +229,11 @@ public:
|
||||
for (auto &e: entries) {
|
||||
std::vector<std::string> v;
|
||||
|
||||
v.push_back(std::to_string(e.groupid));
|
||||
v.push_back(std::to_string(e.charid));
|
||||
v.push_back(std::to_string(e.group_id));
|
||||
v.push_back("'" + Strings::Escape(e.name) + "'");
|
||||
v.push_back(std::to_string(e.ismerc));
|
||||
v.push_back(std::to_string(e.character_id));
|
||||
v.push_back(std::to_string(e.bot_id));
|
||||
v.push_back(std::to_string(e.merc_id));
|
||||
|
||||
insert_chunks.push_back("(" + Strings::Implode(",", v) + ")");
|
||||
}
|
||||
@@ -259,10 +267,11 @@ public:
|
||||
for (auto row = results.begin(); row != results.end(); ++row) {
|
||||
GroupId e{};
|
||||
|
||||
e.groupid = row[0] ? static_cast<int32_t>(atoi(row[0])) : 0;
|
||||
e.charid = row[1] ? static_cast<int32_t>(atoi(row[1])) : 0;
|
||||
e.name = row[2] ? row[2] : "";
|
||||
e.ismerc = row[3] ? static_cast<int8_t>(atoi(row[3])) : 0;
|
||||
e.group_id = row[0] ? static_cast<uint32_t>(strtoul(row[0], nullptr, 10)) : 0;
|
||||
e.name = row[1] ? row[1] : "";
|
||||
e.character_id = row[2] ? static_cast<uint32_t>(strtoul(row[2], nullptr, 10)) : 0;
|
||||
e.bot_id = row[3] ? static_cast<uint32_t>(strtoul(row[3], nullptr, 10)) : 0;
|
||||
e.merc_id = row[4] ? static_cast<uint32_t>(strtoul(row[4], nullptr, 10)) : 0;
|
||||
|
||||
all_entries.push_back(e);
|
||||
}
|
||||
@@ -287,10 +296,11 @@ public:
|
||||
for (auto row = results.begin(); row != results.end(); ++row) {
|
||||
GroupId e{};
|
||||
|
||||
e.groupid = row[0] ? static_cast<int32_t>(atoi(row[0])) : 0;
|
||||
e.charid = row[1] ? static_cast<int32_t>(atoi(row[1])) : 0;
|
||||
e.name = row[2] ? row[2] : "";
|
||||
e.ismerc = row[3] ? static_cast<int8_t>(atoi(row[3])) : 0;
|
||||
e.group_id = row[0] ? static_cast<uint32_t>(strtoul(row[0], nullptr, 10)) : 0;
|
||||
e.name = row[1] ? row[1] : "";
|
||||
e.character_id = row[2] ? static_cast<uint32_t>(strtoul(row[2], nullptr, 10)) : 0;
|
||||
e.bot_id = row[3] ? static_cast<uint32_t>(strtoul(row[3], nullptr, 10)) : 0;
|
||||
e.merc_id = row[4] ? static_cast<uint32_t>(strtoul(row[4], nullptr, 10)) : 0;
|
||||
|
||||
all_entries.push_back(e);
|
||||
}
|
||||
@@ -365,10 +375,11 @@ public:
|
||||
{
|
||||
std::vector<std::string> v;
|
||||
|
||||
v.push_back(std::to_string(e.groupid));
|
||||
v.push_back(std::to_string(e.charid));
|
||||
v.push_back(std::to_string(e.group_id));
|
||||
v.push_back("'" + Strings::Escape(e.name) + "'");
|
||||
v.push_back(std::to_string(e.ismerc));
|
||||
v.push_back(std::to_string(e.character_id));
|
||||
v.push_back(std::to_string(e.bot_id));
|
||||
v.push_back(std::to_string(e.merc_id));
|
||||
|
||||
auto results = db.QueryDatabase(
|
||||
fmt::format(
|
||||
@@ -391,10 +402,11 @@ public:
|
||||
for (auto &e: entries) {
|
||||
std::vector<std::string> v;
|
||||
|
||||
v.push_back(std::to_string(e.groupid));
|
||||
v.push_back(std::to_string(e.charid));
|
||||
v.push_back(std::to_string(e.group_id));
|
||||
v.push_back("'" + Strings::Escape(e.name) + "'");
|
||||
v.push_back(std::to_string(e.ismerc));
|
||||
v.push_back(std::to_string(e.character_id));
|
||||
v.push_back(std::to_string(e.bot_id));
|
||||
v.push_back(std::to_string(e.merc_id));
|
||||
|
||||
insert_chunks.push_back("(" + Strings::Implode(",", v) + ")");
|
||||
}
|
||||
|
||||
@@ -105,7 +105,7 @@ public:
|
||||
e.gid = 0;
|
||||
e.leadername = "";
|
||||
e.marknpc = "";
|
||||
e.leadershipaa = 0;
|
||||
e.leadershipaa = "";
|
||||
e.maintank = "";
|
||||
e.assist = "";
|
||||
e.puller = "";
|
||||
@@ -150,7 +150,7 @@ public:
|
||||
e.gid = row[0] ? static_cast<int32_t>(atoi(row[0])) : 0;
|
||||
e.leadername = row[1] ? row[1] : "";
|
||||
e.marknpc = row[2] ? row[2] : "";
|
||||
e.leadershipaa = row[3] ? row[3] : 0;
|
||||
e.leadershipaa = row[3] ? row[3] : "";
|
||||
e.maintank = row[4] ? row[4] : "";
|
||||
e.assist = row[5] ? row[5] : "";
|
||||
e.puller = row[6] ? row[6] : "";
|
||||
@@ -302,7 +302,7 @@ public:
|
||||
e.gid = row[0] ? static_cast<int32_t>(atoi(row[0])) : 0;
|
||||
e.leadername = row[1] ? row[1] : "";
|
||||
e.marknpc = row[2] ? row[2] : "";
|
||||
e.leadershipaa = row[3] ? row[3] : 0;
|
||||
e.leadershipaa = row[3] ? row[3] : "";
|
||||
e.maintank = row[4] ? row[4] : "";
|
||||
e.assist = row[5] ? row[5] : "";
|
||||
e.puller = row[6] ? row[6] : "";
|
||||
@@ -335,7 +335,7 @@ public:
|
||||
e.gid = row[0] ? static_cast<int32_t>(atoi(row[0])) : 0;
|
||||
e.leadername = row[1] ? row[1] : "";
|
||||
e.marknpc = row[2] ? row[2] : "";
|
||||
e.leadershipaa = row[3] ? row[3] : 0;
|
||||
e.leadershipaa = row[3] ? row[3] : "";
|
||||
e.maintank = row[4] ? row[4] : "";
|
||||
e.assist = row[5] ? row[5] : "";
|
||||
e.puller = row[6] ? row[6] : "";
|
||||
|
||||
@@ -19,8 +19,9 @@
|
||||
class BaseSkillCapsRepository {
|
||||
public:
|
||||
struct SkillCaps {
|
||||
uint8_t skillID;
|
||||
uint8_t class_;
|
||||
uint32_t id;
|
||||
uint8_t skill_id;
|
||||
uint8_t class_id;
|
||||
uint8_t level;
|
||||
uint32_t cap;
|
||||
uint8_t class_;
|
||||
@@ -28,14 +29,15 @@ public:
|
||||
|
||||
static std::string PrimaryKey()
|
||||
{
|
||||
return std::string("skillID");
|
||||
return std::string("id");
|
||||
}
|
||||
|
||||
static std::vector<std::string> Columns()
|
||||
{
|
||||
return {
|
||||
"skillID",
|
||||
"`class`",
|
||||
"id",
|
||||
"skill_id",
|
||||
"class_id",
|
||||
"level",
|
||||
"cap",
|
||||
"class_",
|
||||
@@ -45,8 +47,9 @@ public:
|
||||
static std::vector<std::string> SelectColumns()
|
||||
{
|
||||
return {
|
||||
"skillID",
|
||||
"`class`",
|
||||
"id",
|
||||
"skill_id",
|
||||
"class_id",
|
||||
"level",
|
||||
"cap",
|
||||
"class_",
|
||||
@@ -90,11 +93,12 @@ public:
|
||||
{
|
||||
SkillCaps e{};
|
||||
|
||||
e.skillID = 0;
|
||||
e.class_ = 0;
|
||||
e.level = 0;
|
||||
e.cap = 0;
|
||||
e.class_ = 0;
|
||||
e.id = 0;
|
||||
e.skill_id = 0;
|
||||
e.class_id = 0;
|
||||
e.level = 0;
|
||||
e.cap = 0;
|
||||
e.class_ = 0;
|
||||
|
||||
return e;
|
||||
}
|
||||
@@ -105,7 +109,7 @@ public:
|
||||
)
|
||||
{
|
||||
for (auto &skill_caps : skill_capss) {
|
||||
if (skill_caps.skillID == skill_caps_id) {
|
||||
if (skill_caps.id == skill_caps_id) {
|
||||
return skill_caps;
|
||||
}
|
||||
}
|
||||
@@ -131,11 +135,12 @@ public:
|
||||
if (results.RowCount() == 1) {
|
||||
SkillCaps e{};
|
||||
|
||||
e.skillID = row[0] ? static_cast<uint8_t>(strtoul(row[0], nullptr, 10)) : 0;
|
||||
e.class_ = row[1] ? static_cast<uint8_t>(strtoul(row[1], nullptr, 10)) : 0;
|
||||
e.level = row[2] ? static_cast<uint8_t>(strtoul(row[2], nullptr, 10)) : 0;
|
||||
e.cap = row[3] ? static_cast<uint32_t>(strtoul(row[3], nullptr, 10)) : 0;
|
||||
e.class_ = row[4] ? static_cast<uint8_t>(strtoul(row[4], nullptr, 10)) : 0;
|
||||
e.id = row[0] ? static_cast<uint32_t>(strtoul(row[0], nullptr, 10)) : 0;
|
||||
e.skill_id = row[1] ? static_cast<uint8_t>(strtoul(row[1], nullptr, 10)) : 0;
|
||||
e.class_id = row[2] ? static_cast<uint8_t>(strtoul(row[2], nullptr, 10)) : 0;
|
||||
e.level = row[3] ? static_cast<uint8_t>(strtoul(row[3], nullptr, 10)) : 0;
|
||||
e.cap = row[4] ? static_cast<uint32_t>(strtoul(row[4], nullptr, 10)) : 0;
|
||||
e.class_ = row[5] ? static_cast<uint8_t>(strtoul(row[5], nullptr, 10)) : 0;
|
||||
|
||||
return e;
|
||||
}
|
||||
@@ -169,11 +174,11 @@ public:
|
||||
|
||||
auto columns = Columns();
|
||||
|
||||
v.push_back(columns[0] + " = " + std::to_string(e.skillID));
|
||||
v.push_back(columns[1] + " = " + std::to_string(e.class_));
|
||||
v.push_back(columns[2] + " = " + std::to_string(e.level));
|
||||
v.push_back(columns[3] + " = " + std::to_string(e.cap));
|
||||
v.push_back(columns[4] + " = " + std::to_string(e.class_));
|
||||
v.push_back(columns[1] + " = " + std::to_string(e.skill_id));
|
||||
v.push_back(columns[2] + " = " + std::to_string(e.class_id));
|
||||
v.push_back(columns[3] + " = " + std::to_string(e.level));
|
||||
v.push_back(columns[4] + " = " + std::to_string(e.cap));
|
||||
v.push_back(columns[5] + " = " + std::to_string(e.class_));
|
||||
|
||||
auto results = db.QueryDatabase(
|
||||
fmt::format(
|
||||
@@ -181,7 +186,7 @@ public:
|
||||
TableName(),
|
||||
Strings::Implode(", ", v),
|
||||
PrimaryKey(),
|
||||
e.skillID
|
||||
e.id
|
||||
)
|
||||
);
|
||||
|
||||
@@ -195,8 +200,9 @@ public:
|
||||
{
|
||||
std::vector<std::string> v;
|
||||
|
||||
v.push_back(std::to_string(e.skillID));
|
||||
v.push_back(std::to_string(e.class_));
|
||||
v.push_back(std::to_string(e.id));
|
||||
v.push_back(std::to_string(e.skill_id));
|
||||
v.push_back(std::to_string(e.class_id));
|
||||
v.push_back(std::to_string(e.level));
|
||||
v.push_back(std::to_string(e.cap));
|
||||
v.push_back(std::to_string(e.class_));
|
||||
@@ -210,7 +216,7 @@ public:
|
||||
);
|
||||
|
||||
if (results.Success()) {
|
||||
e.skillID = results.LastInsertedID();
|
||||
e.id = results.LastInsertedID();
|
||||
return e;
|
||||
}
|
||||
|
||||
@@ -229,8 +235,9 @@ public:
|
||||
for (auto &e: entries) {
|
||||
std::vector<std::string> v;
|
||||
|
||||
v.push_back(std::to_string(e.skillID));
|
||||
v.push_back(std::to_string(e.class_));
|
||||
v.push_back(std::to_string(e.id));
|
||||
v.push_back(std::to_string(e.skill_id));
|
||||
v.push_back(std::to_string(e.class_id));
|
||||
v.push_back(std::to_string(e.level));
|
||||
v.push_back(std::to_string(e.cap));
|
||||
v.push_back(std::to_string(e.class_));
|
||||
@@ -267,11 +274,12 @@ public:
|
||||
for (auto row = results.begin(); row != results.end(); ++row) {
|
||||
SkillCaps e{};
|
||||
|
||||
e.skillID = row[0] ? static_cast<uint8_t>(strtoul(row[0], nullptr, 10)) : 0;
|
||||
e.class_ = row[1] ? static_cast<uint8_t>(strtoul(row[1], nullptr, 10)) : 0;
|
||||
e.level = row[2] ? static_cast<uint8_t>(strtoul(row[2], nullptr, 10)) : 0;
|
||||
e.cap = row[3] ? static_cast<uint32_t>(strtoul(row[3], nullptr, 10)) : 0;
|
||||
e.class_ = row[4] ? static_cast<uint8_t>(strtoul(row[4], nullptr, 10)) : 0;
|
||||
e.id = row[0] ? static_cast<uint32_t>(strtoul(row[0], nullptr, 10)) : 0;
|
||||
e.skill_id = row[1] ? static_cast<uint8_t>(strtoul(row[1], nullptr, 10)) : 0;
|
||||
e.class_id = row[2] ? static_cast<uint8_t>(strtoul(row[2], nullptr, 10)) : 0;
|
||||
e.level = row[3] ? static_cast<uint8_t>(strtoul(row[3], nullptr, 10)) : 0;
|
||||
e.cap = row[4] ? static_cast<uint32_t>(strtoul(row[4], nullptr, 10)) : 0;
|
||||
e.class_ = row[5] ? static_cast<uint8_t>(strtoul(row[5], nullptr, 10)) : 0;
|
||||
|
||||
all_entries.push_back(e);
|
||||
}
|
||||
@@ -296,11 +304,12 @@ public:
|
||||
for (auto row = results.begin(); row != results.end(); ++row) {
|
||||
SkillCaps e{};
|
||||
|
||||
e.skillID = row[0] ? static_cast<uint8_t>(strtoul(row[0], nullptr, 10)) : 0;
|
||||
e.class_ = row[1] ? static_cast<uint8_t>(strtoul(row[1], nullptr, 10)) : 0;
|
||||
e.level = row[2] ? static_cast<uint8_t>(strtoul(row[2], nullptr, 10)) : 0;
|
||||
e.cap = row[3] ? static_cast<uint32_t>(strtoul(row[3], nullptr, 10)) : 0;
|
||||
e.class_ = row[4] ? static_cast<uint8_t>(strtoul(row[4], nullptr, 10)) : 0;
|
||||
e.id = row[0] ? static_cast<uint32_t>(strtoul(row[0], nullptr, 10)) : 0;
|
||||
e.skill_id = row[1] ? static_cast<uint8_t>(strtoul(row[1], nullptr, 10)) : 0;
|
||||
e.class_id = row[2] ? static_cast<uint8_t>(strtoul(row[2], nullptr, 10)) : 0;
|
||||
e.level = row[3] ? static_cast<uint8_t>(strtoul(row[3], nullptr, 10)) : 0;
|
||||
e.cap = row[4] ? static_cast<uint32_t>(strtoul(row[4], nullptr, 10)) : 0;
|
||||
e.class_ = row[5] ? static_cast<uint8_t>(strtoul(row[5], nullptr, 10)) : 0;
|
||||
|
||||
all_entries.push_back(e);
|
||||
}
|
||||
@@ -375,8 +384,9 @@ public:
|
||||
{
|
||||
std::vector<std::string> v;
|
||||
|
||||
v.push_back(std::to_string(e.skillID));
|
||||
v.push_back(std::to_string(e.class_));
|
||||
v.push_back(std::to_string(e.id));
|
||||
v.push_back(std::to_string(e.skill_id));
|
||||
v.push_back(std::to_string(e.class_id));
|
||||
v.push_back(std::to_string(e.level));
|
||||
v.push_back(std::to_string(e.cap));
|
||||
v.push_back(std::to_string(e.class_));
|
||||
@@ -402,8 +412,9 @@ public:
|
||||
for (auto &e: entries) {
|
||||
std::vector<std::string> v;
|
||||
|
||||
v.push_back(std::to_string(e.skillID));
|
||||
v.push_back(std::to_string(e.class_));
|
||||
v.push_back(std::to_string(e.id));
|
||||
v.push_back(std::to_string(e.skill_id));
|
||||
v.push_back(std::to_string(e.class_id));
|
||||
v.push_back(std::to_string(e.level));
|
||||
v.push_back(std::to_string(e.cap));
|
||||
v.push_back(std::to_string(e.class_));
|
||||
|
||||
@@ -23,7 +23,7 @@ public:
|
||||
std::string varname;
|
||||
std::string value;
|
||||
std::string information;
|
||||
std::string ts;
|
||||
time_t ts;
|
||||
};
|
||||
|
||||
static std::string PrimaryKey()
|
||||
@@ -49,7 +49,7 @@ public:
|
||||
"varname",
|
||||
"value",
|
||||
"information",
|
||||
"ts",
|
||||
"UNIX_TIMESTAMP(ts)",
|
||||
};
|
||||
}
|
||||
|
||||
@@ -135,7 +135,7 @@ public:
|
||||
e.varname = row[1] ? row[1] : "";
|
||||
e.value = row[2] ? row[2] : "";
|
||||
e.information = row[3] ? row[3] : "";
|
||||
e.ts = row[4] ? row[4] : std::time(nullptr);
|
||||
e.ts = strtoll(row[4] ? row[4] : "-1", nullptr, 10);
|
||||
|
||||
return e;
|
||||
}
|
||||
@@ -172,7 +172,7 @@ public:
|
||||
v.push_back(columns[1] + " = '" + Strings::Escape(e.varname) + "'");
|
||||
v.push_back(columns[2] + " = '" + Strings::Escape(e.value) + "'");
|
||||
v.push_back(columns[3] + " = '" + Strings::Escape(e.information) + "'");
|
||||
v.push_back(columns[4] + " = '" + Strings::Escape(e.ts) + "'");
|
||||
v.push_back(columns[4] + " = FROM_UNIXTIME(" + (e.ts > 0 ? std::to_string(e.ts) : "null") + ")");
|
||||
|
||||
auto results = db.QueryDatabase(
|
||||
fmt::format(
|
||||
@@ -198,7 +198,7 @@ public:
|
||||
v.push_back("'" + Strings::Escape(e.varname) + "'");
|
||||
v.push_back("'" + Strings::Escape(e.value) + "'");
|
||||
v.push_back("'" + Strings::Escape(e.information) + "'");
|
||||
v.push_back("'" + Strings::Escape(e.ts) + "'");
|
||||
v.push_back("FROM_UNIXTIME(" + (e.ts > 0 ? std::to_string(e.ts) : "null") + ")");
|
||||
|
||||
auto results = db.QueryDatabase(
|
||||
fmt::format(
|
||||
@@ -232,7 +232,7 @@ public:
|
||||
v.push_back("'" + Strings::Escape(e.varname) + "'");
|
||||
v.push_back("'" + Strings::Escape(e.value) + "'");
|
||||
v.push_back("'" + Strings::Escape(e.information) + "'");
|
||||
v.push_back("'" + Strings::Escape(e.ts) + "'");
|
||||
v.push_back("FROM_UNIXTIME(" + (e.ts > 0 ? std::to_string(e.ts) : "null") + ")");
|
||||
|
||||
insert_chunks.push_back("(" + Strings::Implode(",", v) + ")");
|
||||
}
|
||||
@@ -270,7 +270,7 @@ public:
|
||||
e.varname = row[1] ? row[1] : "";
|
||||
e.value = row[2] ? row[2] : "";
|
||||
e.information = row[3] ? row[3] : "";
|
||||
e.ts = row[4] ? row[4] : std::time(nullptr);
|
||||
e.ts = strtoll(row[4] ? row[4] : "-1", nullptr, 10);
|
||||
|
||||
all_entries.push_back(e);
|
||||
}
|
||||
@@ -299,7 +299,7 @@ public:
|
||||
e.varname = row[1] ? row[1] : "";
|
||||
e.value = row[2] ? row[2] : "";
|
||||
e.information = row[3] ? row[3] : "";
|
||||
e.ts = row[4] ? row[4] : std::time(nullptr);
|
||||
e.ts = strtoll(row[4] ? row[4] : "-1", nullptr, 10);
|
||||
|
||||
all_entries.push_back(e);
|
||||
}
|
||||
@@ -378,7 +378,7 @@ public:
|
||||
v.push_back("'" + Strings::Escape(e.varname) + "'");
|
||||
v.push_back("'" + Strings::Escape(e.value) + "'");
|
||||
v.push_back("'" + Strings::Escape(e.information) + "'");
|
||||
v.push_back("'" + Strings::Escape(e.ts) + "'");
|
||||
v.push_back("FROM_UNIXTIME(" + (e.ts > 0 ? std::to_string(e.ts) : "null") + ")");
|
||||
|
||||
auto results = db.QueryDatabase(
|
||||
fmt::format(
|
||||
@@ -405,7 +405,7 @@ public:
|
||||
v.push_back("'" + Strings::Escape(e.varname) + "'");
|
||||
v.push_back("'" + Strings::Escape(e.value) + "'");
|
||||
v.push_back("'" + Strings::Escape(e.information) + "'");
|
||||
v.push_back("'" + Strings::Escape(e.ts) + "'");
|
||||
v.push_back("FROM_UNIXTIME(" + (e.ts > 0 ? std::to_string(e.ts) : "null") + ")");
|
||||
|
||||
insert_chunks.push_back("(" + Strings::Implode(",", v) + ")");
|
||||
}
|
||||
|
||||
@@ -44,7 +44,15 @@ public:
|
||||
*/
|
||||
|
||||
// Custom extended repository methods here
|
||||
|
||||
static void ClearAllGroups(Database& db)
|
||||
{
|
||||
db.QueryDatabase(
|
||||
fmt::format(
|
||||
"DELETE FROM `{}`",
|
||||
TableName()
|
||||
)
|
||||
);
|
||||
}
|
||||
};
|
||||
|
||||
#endif //EQEMU_GROUP_ID_REPOSITORY_H
|
||||
|
||||
@@ -44,7 +44,15 @@ public:
|
||||
*/
|
||||
|
||||
// Custom extended repository methods here
|
||||
|
||||
static void ClearAllGroupLeaders(Database& db)
|
||||
{
|
||||
db.QueryDatabase(
|
||||
fmt::format(
|
||||
"DELETE FROM `{}`",
|
||||
TableName()
|
||||
)
|
||||
);
|
||||
}
|
||||
};
|
||||
|
||||
#endif //EQEMU_GROUP_LEADERS_REPOSITORY_H
|
||||
|
||||
@@ -191,4 +191,5 @@ public:
|
||||
return UpdateOne(db, m);
|
||||
}
|
||||
};
|
||||
|
||||
#endif //EQEMU_GUILD_MEMBERS_REPOSITORY_H
|
||||
|
||||
@@ -44,7 +44,30 @@ public:
|
||||
*/
|
||||
|
||||
// Custom extended repository methods here
|
||||
static int64 CountInventorySnapshots(Database& db)
|
||||
{
|
||||
const std::string& query = "SELECT COUNT(*) FROM (SELECT * FROM `inventory_snapshots` a GROUP BY `charid`, `time_index`) b";
|
||||
|
||||
auto results = db.QueryDatabase(query);
|
||||
|
||||
if (!results.Success() || !results.RowCount()) {
|
||||
return -1;
|
||||
}
|
||||
|
||||
auto row = results.begin();
|
||||
|
||||
const int64 count = Strings::ToBigInt(row[0]);
|
||||
|
||||
if (count > std::numeric_limits<int>::max()) {
|
||||
return -2;
|
||||
}
|
||||
|
||||
if (count < 0) {
|
||||
return -3;
|
||||
}
|
||||
|
||||
return count;
|
||||
}
|
||||
};
|
||||
|
||||
#endif //EQEMU_INVENTORY_SNAPSHOTS_REPOSITORY_H
|
||||
|
||||
@@ -66,6 +66,16 @@ public:
|
||||
|
||||
return results.Success() ? results.RowsAffected() : 0;
|
||||
}
|
||||
|
||||
static void ClearAllRaidDetails(Database& db)
|
||||
{
|
||||
db.QueryDatabase(
|
||||
fmt::format(
|
||||
"DELETE FROM `{}`",
|
||||
TableName()
|
||||
)
|
||||
);
|
||||
}
|
||||
};
|
||||
|
||||
#endif //EQEMU_RAID_DETAILS_REPOSITORY_H
|
||||
|
||||
@@ -1,297 +0,0 @@
|
||||
#ifndef EQEMU_RAID_LEADERS_REPOSITORY_H
|
||||
#define EQEMU_RAID_LEADERS_REPOSITORY_H
|
||||
|
||||
#include "../database.h"
|
||||
#include "../strings.h"
|
||||
|
||||
class RaidLeadersRepository {
|
||||
public:
|
||||
struct RaidLeaders {
|
||||
int gid;
|
||||
int rid;
|
||||
std::string marknpc;
|
||||
std::string maintank;
|
||||
std::string assist;
|
||||
std::string puller;
|
||||
std::string leadershipaa;
|
||||
std::string mentoree;
|
||||
int mentor_percent;
|
||||
};
|
||||
|
||||
static std::string PrimaryKey()
|
||||
{
|
||||
return std::string("");
|
||||
}
|
||||
|
||||
static std::vector<std::string> Columns()
|
||||
{
|
||||
return {
|
||||
"gid",
|
||||
"rid",
|
||||
"marknpc",
|
||||
"maintank",
|
||||
"assist",
|
||||
"puller",
|
||||
"leadershipaa",
|
||||
"mentoree",
|
||||
"mentor_percent",
|
||||
};
|
||||
}
|
||||
|
||||
static std::string ColumnsRaw()
|
||||
{
|
||||
return std::string(Strings::Implode(", ", Columns()));
|
||||
}
|
||||
|
||||
static std::string InsertColumnsRaw()
|
||||
{
|
||||
std::vector<std::string> insert_columns;
|
||||
|
||||
for (auto &column : Columns()) {
|
||||
if (column == PrimaryKey()) {
|
||||
continue;
|
||||
}
|
||||
|
||||
insert_columns.push_back(column);
|
||||
}
|
||||
|
||||
return std::string(Strings::Implode(", ", insert_columns));
|
||||
}
|
||||
|
||||
static std::string TableName()
|
||||
{
|
||||
return std::string("raid_leaders");
|
||||
}
|
||||
|
||||
static std::string BaseSelect()
|
||||
{
|
||||
return fmt::format(
|
||||
"SELECT {} FROM {}",
|
||||
ColumnsRaw(),
|
||||
TableName()
|
||||
);
|
||||
}
|
||||
|
||||
static std::string BaseInsert()
|
||||
{
|
||||
return fmt::format(
|
||||
"INSERT INTO {} ({}) ",
|
||||
TableName(),
|
||||
InsertColumnsRaw()
|
||||
);
|
||||
}
|
||||
|
||||
static RaidLeaders NewEntity()
|
||||
{
|
||||
RaidLeaders entry{};
|
||||
|
||||
entry.gid = 0;
|
||||
entry.rid = 0;
|
||||
entry.marknpc = "";
|
||||
entry.maintank = "";
|
||||
entry.assist = "";
|
||||
entry.puller = "";
|
||||
entry.leadershipaa = 0;
|
||||
entry.mentoree = "";
|
||||
entry.mentor_percent = 0;
|
||||
|
||||
return entry;
|
||||
}
|
||||
|
||||
static RaidLeaders GetRaidLeadersEntry(
|
||||
const std::vector<RaidLeaders> &raid_leaderss,
|
||||
int raid_leaders_id
|
||||
)
|
||||
{
|
||||
for (auto &raid_leaders : raid_leaderss) {
|
||||
if (raid_leaders. == raid_leaders_id) {
|
||||
return raid_leaders;
|
||||
}
|
||||
}
|
||||
|
||||
return NewEntity();
|
||||
}
|
||||
|
||||
static RaidLeaders FindOne(
|
||||
int raid_leaders_id
|
||||
)
|
||||
{
|
||||
auto results = database.QueryDatabase(
|
||||
fmt::format(
|
||||
"{} WHERE id = {} LIMIT 1",
|
||||
BaseSelect(),
|
||||
raid_leaders_id
|
||||
)
|
||||
);
|
||||
|
||||
auto row = results.begin();
|
||||
if (results.RowCount() == 1) {
|
||||
RaidLeaders entry{};
|
||||
|
||||
entry.gid = atoi(row[0]);
|
||||
entry.rid = atoi(row[1]);
|
||||
entry.marknpc = row[2];
|
||||
entry.maintank = row[3];
|
||||
entry.assist = row[4];
|
||||
entry.puller = row[5];
|
||||
entry.leadershipaa = row[6];
|
||||
entry.mentoree = row[7];
|
||||
entry.mentor_percent = atoi(row[8]);
|
||||
|
||||
return entry;
|
||||
}
|
||||
|
||||
return NewEntity();
|
||||
}
|
||||
|
||||
static int DeleteOne(
|
||||
int raid_leaders_id
|
||||
)
|
||||
{
|
||||
auto results = database.QueryDatabase(
|
||||
fmt::format(
|
||||
"DELETE FROM {} WHERE {} = {}",
|
||||
TableName(),
|
||||
PrimaryKey(),
|
||||
raid_leaders_id
|
||||
)
|
||||
);
|
||||
|
||||
return (results.Success() ? results.RowsAffected() : 0);
|
||||
}
|
||||
|
||||
static int UpdateOne(
|
||||
RaidLeaders raid_leaders_entry
|
||||
)
|
||||
{
|
||||
std::vector<std::string> update_values;
|
||||
|
||||
auto columns = Columns();
|
||||
|
||||
update_values.push_back(columns[0] + " = " + std::to_string(raid_leaders_entry.gid));
|
||||
update_values.push_back(columns[1] + " = " + std::to_string(raid_leaders_entry.rid));
|
||||
update_values.push_back(columns[2] + " = '" + Strings::Escape(raid_leaders_entry.marknpc) + "'");
|
||||
update_values.push_back(columns[3] + " = '" + Strings::Escape(raid_leaders_entry.maintank) + "'");
|
||||
update_values.push_back(columns[4] + " = '" + Strings::Escape(raid_leaders_entry.assist) + "'");
|
||||
update_values.push_back(columns[5] + " = '" + Strings::Escape(raid_leaders_entry.puller) + "'");
|
||||
update_values.push_back(columns[6] + " = '" + Strings::Escape(raid_leaders_entry.leadershipaa) + "'");
|
||||
update_values.push_back(columns[7] + " = '" + Strings::Escape(raid_leaders_entry.mentoree) + "'");
|
||||
update_values.push_back(columns[8] + " = " + std::to_string(raid_leaders_entry.mentor_percent));
|
||||
|
||||
auto results = database.QueryDatabase(
|
||||
fmt::format(
|
||||
"UPDATE {} SET {} WHERE {} = {}",
|
||||
TableName(),
|
||||
Strings::Implode(", ", update_values),
|
||||
PrimaryKey(),
|
||||
raid_leaders_entry.
|
||||
)
|
||||
);
|
||||
|
||||
return (results.Success() ? results.RowsAffected() : 0);
|
||||
}
|
||||
|
||||
static RaidLeaders InsertOne(
|
||||
RaidLeaders raid_leaders_entry
|
||||
)
|
||||
{
|
||||
std::vector<std::string> insert_values;
|
||||
|
||||
insert_values.push_back(std::to_string(raid_leaders_entry.gid));
|
||||
insert_values.push_back(std::to_string(raid_leaders_entry.rid));
|
||||
insert_values.push_back("'" + Strings::Escape(raid_leaders_entry.marknpc) + "'");
|
||||
insert_values.push_back("'" + Strings::Escape(raid_leaders_entry.maintank) + "'");
|
||||
insert_values.push_back("'" + Strings::Escape(raid_leaders_entry.assist) + "'");
|
||||
insert_values.push_back("'" + Strings::Escape(raid_leaders_entry.puller) + "'");
|
||||
insert_values.push_back("'" + Strings::Escape(raid_leaders_entry.leadershipaa) + "'");
|
||||
insert_values.push_back("'" + Strings::Escape(raid_leaders_entry.mentoree) + "'");
|
||||
insert_values.push_back(std::to_string(raid_leaders_entry.mentor_percent));
|
||||
|
||||
auto results = database.QueryDatabase(
|
||||
fmt::format(
|
||||
"{} VALUES ({})",
|
||||
BaseInsert(),
|
||||
Strings::Implode(",", insert_values)
|
||||
)
|
||||
);
|
||||
|
||||
if (results.Success()) {
|
||||
raid_leaders_entry.id = results.LastInsertedID();
|
||||
return raid_leaders_entry;
|
||||
}
|
||||
|
||||
raid_leaders_entry = InstanceListRepository::NewEntity();
|
||||
|
||||
return raid_leaders_entry;
|
||||
}
|
||||
|
||||
static int InsertMany(
|
||||
std::vector<RaidLeaders> raid_leaders_entries
|
||||
)
|
||||
{
|
||||
std::vector<std::string> insert_chunks;
|
||||
|
||||
for (auto &raid_leaders_entry: raid_leaders_entries) {
|
||||
std::vector<std::string> insert_values;
|
||||
|
||||
insert_values.push_back(std::to_string(raid_leaders_entry.gid));
|
||||
insert_values.push_back(std::to_string(raid_leaders_entry.rid));
|
||||
insert_values.push_back("'" + Strings::Escape(raid_leaders_entry.marknpc) + "'");
|
||||
insert_values.push_back("'" + Strings::Escape(raid_leaders_entry.maintank) + "'");
|
||||
insert_values.push_back("'" + Strings::Escape(raid_leaders_entry.assist) + "'");
|
||||
insert_values.push_back("'" + Strings::Escape(raid_leaders_entry.puller) + "'");
|
||||
insert_values.push_back("'" + Strings::Escape(raid_leaders_entry.leadershipaa) + "'");
|
||||
insert_values.push_back("'" + Strings::Escape(raid_leaders_entry.mentoree) + "'");
|
||||
insert_values.push_back(std::to_string(raid_leaders_entry.mentor_percent));
|
||||
|
||||
insert_chunks.push_back("(" + Strings::Implode(",", insert_values) + ")");
|
||||
}
|
||||
|
||||
std::vector<std::string> insert_values;
|
||||
|
||||
auto results = database.QueryDatabase(
|
||||
fmt::format(
|
||||
"{} VALUES {}",
|
||||
BaseInsert(),
|
||||
Strings::Implode(",", insert_chunks)
|
||||
)
|
||||
);
|
||||
|
||||
return (results.Success() ? results.RowsAffected() : 0);
|
||||
}
|
||||
|
||||
static std::vector<RaidLeaders> All()
|
||||
{
|
||||
std::vector<RaidLeaders> all_entries;
|
||||
|
||||
auto results = database.QueryDatabase(
|
||||
fmt::format(
|
||||
"{}",
|
||||
BaseSelect()
|
||||
)
|
||||
);
|
||||
|
||||
all_entries.reserve(results.RowCount());
|
||||
|
||||
for (auto row = results.begin(); row != results.end(); ++row) {
|
||||
RaidLeaders entry{};
|
||||
|
||||
entry.gid = atoi(row[0]);
|
||||
entry.rid = atoi(row[1]);
|
||||
entry.marknpc = row[2];
|
||||
entry.maintank = row[3];
|
||||
entry.assist = row[4];
|
||||
entry.puller = row[5];
|
||||
entry.leadershipaa = row[6];
|
||||
entry.mentoree = row[7];
|
||||
entry.mentor_percent = atoi(row[8]);
|
||||
|
||||
all_entries.push_back(entry);
|
||||
}
|
||||
|
||||
return all_entries;
|
||||
}
|
||||
|
||||
};
|
||||
|
||||
#endif //EQEMU_RAID_LEADERS_REPOSITORY_H
|
||||
@@ -60,7 +60,7 @@ public:
|
||||
);
|
||||
return results.Success() ? results.RowsAffected() : 0;
|
||||
}
|
||||
|
||||
|
||||
static int UpdateRaidAssister(
|
||||
Database& db,
|
||||
int32_t raid_id,
|
||||
@@ -98,5 +98,15 @@ public:
|
||||
|
||||
return results.Success() ? results.RowsAffected() : 0;
|
||||
}
|
||||
|
||||
static void ClearAllRaids(Database& db)
|
||||
{
|
||||
db.QueryDatabase(
|
||||
fmt::format(
|
||||
"DELETE FROM `{}`",
|
||||
TableName()
|
||||
)
|
||||
);
|
||||
}
|
||||
};
|
||||
#endif //EQEMU_RAID_MEMBERS_REPOSITORY_H
|
||||
|
||||
+3
-1
@@ -355,6 +355,7 @@ RULE_INT(Zone, GlobalLootMultiplier, 1, "Sets Global Loot drop multiplier for da
|
||||
RULE_BOOL(Zone, KillProcessOnDynamicShutdown, true, "When process has booted a zone and has hit its zone shut down timer, it will hard kill the process to free memory back to the OS")
|
||||
RULE_INT(Zone, SpawnEventMin, 3, "When strict is set in spawn_events, specifies the max EQ minutes into the trigger hour a spawn_event will fire. Going below 3 may cause the spawn_event to not fire.")
|
||||
RULE_INT(Zone, ForageChance, 25, "Chance of foraging from zone table vs global table")
|
||||
RULE_INT(Zone, FishingChance, 399, "Chance of fishing from zone table vs global table")
|
||||
RULE_BOOL(Zone, AllowCrossZoneSpellsOnBots, false, "Set to true to allow cross zone spells (cast/remove) to affect bots")
|
||||
RULE_BOOL(Zone, AllowCrossZoneSpellsOnMercs, false, "Set to true to allow cross zone spells (cast/remove) to affect mercenaries")
|
||||
RULE_BOOL(Zone, AllowCrossZoneSpellsOnPets, false, "Set to true to allow cross zone spells (cast/remove) to affect pets")
|
||||
@@ -450,7 +451,8 @@ RULE_BOOL(Spells, Jun182014HundredHandsRevamp, false, "This should be true for i
|
||||
RULE_BOOL(Spells, SwarmPetTargetLock, false, "Use old method of swarm pets target locking till target dies then despawning")
|
||||
RULE_BOOL(Spells, NPC_UseFocusFromSpells, true, "Allow NPC to use most spell derived focus effects")
|
||||
RULE_BOOL(Spells, NPC_UseFocusFromItems, false, "Allow NPC to use most item derived focus effects")
|
||||
RULE_BOOL(Spells, UseAdditiveFocusFromWornSlot, false, "Allows an additive focus effect to be calculated from worn slot")
|
||||
RULE_BOOL(Spells, UseAdditiveFocusFromWornSlot, false, "Allows an additive focus effect to be calculated from worn slot. Does not apply limits checks. Can only have one additive focus rule be true.")
|
||||
RULE_BOOL(Spells, UseAdditiveFocusFromWornSlotWithLimits, false, "Allows an additive focus effect to be calculated from worn slot. Applies normal limit checks. Can only have one additive focus rule be true.")
|
||||
RULE_BOOL(Spells, AlwaysSendTargetsBuffs, false, "Ignore Leadership Alternate Abilities level if true")
|
||||
RULE_BOOL(Spells, FlatItemExtraSpellAmt, false, "Allow SpellDmg stat to affect all spells, regardless of cast time/cooldown/etc")
|
||||
RULE_BOOL(Spells, IgnoreSpellDmgLvlRestriction, false, "Ignore the 5 level spread on applying SpellDmg")
|
||||
|
||||
@@ -273,6 +273,7 @@
|
||||
#define ServerOP_ReloadFactions 0x4126
|
||||
#define ServerOP_ReloadLoot 0x4127
|
||||
#define ServerOP_ReloadBaseData 0x4128
|
||||
#define ServerOP_ReloadSkillCaps 0x4129
|
||||
|
||||
#define ServerOP_CZDialogueWindow 0x4500
|
||||
#define ServerOP_CZLDoNUpdate 0x4501
|
||||
|
||||
@@ -60,7 +60,7 @@ SharedTaskRequest SharedTask::GetRequestCharacters(Database &db, uint32_t reques
|
||||
request.group_type = SharedTaskRequestGroupType::Group;
|
||||
auto characters = CharacterDataRepository::GetWhere(
|
||||
db, fmt::format(
|
||||
"id IN (select charid from group_id where groupid = (select groupid from group_id where charid = {}))",
|
||||
"id IN (select character_id from group_id where group_id = (select group_id from group_id where character_id = {}))",
|
||||
requested_character_id
|
||||
)
|
||||
);
|
||||
|
||||
+4
-134
@@ -45,6 +45,7 @@
|
||||
#include "repositories/loottable_repository.h"
|
||||
#include "repositories/character_item_recast_repository.h"
|
||||
#include "repositories/character_corpses_repository.h"
|
||||
#include "repositories/skill_caps_repository.h"
|
||||
|
||||
namespace ItemField
|
||||
{
|
||||
@@ -793,8 +794,7 @@ bool SharedDatabase::GetInventory(uint32 char_id, EQ::InventoryProfile *inv)
|
||||
}
|
||||
|
||||
if (cv_conflict) {
|
||||
char char_name[64] = "";
|
||||
GetCharName(char_id, char_name);
|
||||
const std::string& char_name = GetCharName(char_id);
|
||||
LogError("ClientVersion/Expansion conflict during inventory load at zone entry for [{}] (charid: [{}], inver: [{}], gmi: [{}])",
|
||||
char_name,
|
||||
char_id,
|
||||
@@ -1626,136 +1626,6 @@ bool SharedDatabase::GetCommandSubSettings(std::vector<CommandSubsettingsReposit
|
||||
return true;
|
||||
}
|
||||
|
||||
|
||||
bool SharedDatabase::LoadSkillCaps(const std::string &prefix) {
|
||||
skill_caps_mmf.reset(nullptr);
|
||||
|
||||
try {
|
||||
const auto Config = EQEmuConfig::get();
|
||||
EQ::IPCMutex mutex("skill_caps");
|
||||
mutex.Lock();
|
||||
std::string file_name = fmt::format("{}/{}{}", path.GetSharedMemoryPath(), prefix, std::string("skill_caps"));
|
||||
LogInfo("Loading [{}]", file_name);
|
||||
skill_caps_mmf = std::make_unique<EQ::MemoryMappedFile>(file_name);
|
||||
|
||||
LogInfo("Loaded skill caps via shared memory");
|
||||
|
||||
mutex.Unlock();
|
||||
} catch(std::exception &ex) {
|
||||
LogError("Error loading skill caps: {}", ex.what());
|
||||
return false;
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
void SharedDatabase::LoadSkillCaps(void *data) {
|
||||
const uint32 class_count = Class::PLAYER_CLASS_COUNT;
|
||||
const uint32 skill_count = EQ::skills::HIGHEST_SKILL + 1;
|
||||
const uint32 level_count = HARD_LEVEL_CAP + 1;
|
||||
uint16 *skill_caps_table = static_cast<uint16*>(data);
|
||||
|
||||
const std::string query = "SELECT skillID, class, level, cap FROM skill_caps ORDER BY skillID, class, level";
|
||||
auto results = QueryDatabase(query);
|
||||
if (!results.Success()) {
|
||||
LogError("Error loading skill caps from database: {}", results.ErrorMessage().c_str());
|
||||
return;
|
||||
}
|
||||
|
||||
for(auto& row = results.begin(); row != results.end(); ++row) {
|
||||
const uint8 skillID = Strings::ToUnsignedInt(row[0]);
|
||||
const uint8 class_ = Strings::ToUnsignedInt(row[1]) - 1;
|
||||
const uint8 level = Strings::ToUnsignedInt(row[2]);
|
||||
const uint16 cap = Strings::ToUnsignedInt(row[3]);
|
||||
|
||||
if(skillID >= skill_count || class_ >= class_count || level >= level_count)
|
||||
continue;
|
||||
|
||||
const uint32 index = (((class_ * skill_count) + skillID) * level_count) + level;
|
||||
skill_caps_table[index] = cap;
|
||||
}
|
||||
}
|
||||
|
||||
uint16 SharedDatabase::GetSkillCap(uint8 Class_, EQ::skills::SkillType Skill, uint8 Level) const
|
||||
{
|
||||
if(!skill_caps_mmf) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
if(Class_ == 0)
|
||||
return 0;
|
||||
|
||||
int SkillMaxLevel = RuleI(Character, SkillCapMaxLevel);
|
||||
if(SkillMaxLevel < 1) {
|
||||
SkillMaxLevel = RuleI(Character, MaxLevel);
|
||||
}
|
||||
|
||||
const uint32 class_count = Class::PLAYER_CLASS_COUNT;
|
||||
const uint32 skill_count = EQ::skills::HIGHEST_SKILL + 1;
|
||||
const uint32 level_count = HARD_LEVEL_CAP + 1;
|
||||
if(Class_ > class_count || static_cast<uint32>(Skill) > skill_count || Level > level_count) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
if(Level > static_cast<uint8>(SkillMaxLevel)){
|
||||
Level = static_cast<uint8>(SkillMaxLevel);
|
||||
}
|
||||
|
||||
const uint32 index = ((((Class_ - 1) * skill_count) + Skill) * level_count) + Level;
|
||||
const uint16 *skill_caps_table = static_cast<uint16*>(skill_caps_mmf->Get());
|
||||
return skill_caps_table[index];
|
||||
}
|
||||
|
||||
uint8 SharedDatabase::GetTrainLevel(uint8 Class_, EQ::skills::SkillType Skill, uint8 Level) const
|
||||
{
|
||||
if(!skill_caps_mmf) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
if(Class_ == 0)
|
||||
return 0;
|
||||
|
||||
int SkillMaxLevel = RuleI(Character, SkillCapMaxLevel);
|
||||
if (SkillMaxLevel < 1) {
|
||||
SkillMaxLevel = RuleI(Character, MaxLevel);
|
||||
}
|
||||
|
||||
const uint32 class_count = Class::PLAYER_CLASS_COUNT;
|
||||
const uint32 skill_count = EQ::skills::HIGHEST_SKILL + 1;
|
||||
const uint32 level_count = HARD_LEVEL_CAP + 1;
|
||||
if(Class_ > class_count || static_cast<uint32>(Skill) > skill_count || Level > level_count) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
uint8 ret = 0;
|
||||
if(Level > static_cast<uint8>(SkillMaxLevel)) {
|
||||
const uint32 index = ((((Class_ - 1) * skill_count) + Skill) * level_count);
|
||||
const uint16 *skill_caps_table = static_cast<uint16*>(skill_caps_mmf->Get());
|
||||
for(uint8 x = 0; x < Level; x++){
|
||||
if(skill_caps_table[index + x]){
|
||||
ret = x;
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
const uint32 index = ((((Class_ - 1) * skill_count) + Skill) * level_count);
|
||||
const uint16 *skill_caps_table = static_cast<uint16*>(skill_caps_mmf->Get());
|
||||
for(int x = 0; x < SkillMaxLevel; x++){
|
||||
if(skill_caps_table[index + x]){
|
||||
ret = x;
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if(ret > GetSkillCap(Class_, Skill, Level))
|
||||
ret = static_cast<uint8>(GetSkillCap(Class_, Skill, Level));
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
void SharedDatabase::LoadDamageShieldTypes(SPDat_Spell_Struct* sp, int32 iMaxSpellID) {
|
||||
const std::string query = StringFormat("SELECT `spellid`, `type` FROM `damageshieldtypes` WHERE `spellid` > 0 "
|
||||
"AND `spellid` <= %i", iMaxSpellID);
|
||||
@@ -1984,9 +1854,9 @@ void SharedDatabase::LoadSpells(void *data, int max_spells) {
|
||||
sp[tempid].min_range = Strings::ToFloat(row[231]);
|
||||
sp[tempid].no_remove = Strings::ToBool(row[232]);
|
||||
sp[tempid].damage_shield_type = 0;
|
||||
}
|
||||
}
|
||||
|
||||
LoadDamageShieldTypes(sp, max_spells);
|
||||
LoadDamageShieldTypes(sp, max_spells);
|
||||
}
|
||||
|
||||
void SharedDatabase::LoadCharacterInspectMessage(uint32 character_id, InspectMessage_Struct* message) {
|
||||
|
||||
@@ -160,14 +160,6 @@ public:
|
||||
uint32 GetSharedItemsCount() { return m_shared_items_count; }
|
||||
uint32 GetItemsCount();
|
||||
|
||||
/**
|
||||
* skills
|
||||
*/
|
||||
void LoadSkillCaps(void *data);
|
||||
bool LoadSkillCaps(const std::string &prefix);
|
||||
uint16 GetSkillCap(uint8 Class_, EQ::skills::SkillType Skill, uint8 Level) const;
|
||||
uint8 GetTrainLevel(uint8 Class_, EQ::skills::SkillType Skill, uint8 Level) const;
|
||||
|
||||
/**
|
||||
* spells
|
||||
*/
|
||||
|
||||
@@ -0,0 +1,91 @@
|
||||
#include "skill_caps.h"
|
||||
|
||||
SkillCaps *SkillCaps::SetContentDatabase(Database *db)
|
||||
{
|
||||
m_content_database = db;
|
||||
|
||||
return this;
|
||||
}
|
||||
|
||||
SkillCapsRepository::SkillCaps SkillCaps::GetSkillCap(uint8 class_id, EQ::skills::SkillType skill_id, uint8 level)
|
||||
{
|
||||
if (!IsPlayerClass(class_id)) {
|
||||
return SkillCapsRepository::NewEntity();
|
||||
}
|
||||
|
||||
for (const auto &e: m_skill_caps) {
|
||||
if (
|
||||
e.class_id == class_id &&
|
||||
e.level == level &&
|
||||
static_cast<EQ::skills::SkillType>(e.skill_id) == skill_id
|
||||
) {
|
||||
return e;
|
||||
}
|
||||
}
|
||||
|
||||
return SkillCapsRepository::NewEntity();
|
||||
}
|
||||
|
||||
uint8 SkillCaps::GetTrainLevel(uint8 class_id, EQ::skills::SkillType skill_id, uint8 level)
|
||||
{
|
||||
if (
|
||||
!IsPlayerClass(class_id) ||
|
||||
class_id > Class::PLAYER_CLASS_COUNT ||
|
||||
static_cast<uint32>(skill_id) > (EQ::skills::HIGHEST_SKILL + 1)
|
||||
) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
const uint8 skill_cap_max_level = (
|
||||
RuleI(Character, SkillCapMaxLevel) > 0 ?
|
||||
RuleI(Character, SkillCapMaxLevel) :
|
||||
RuleI(Character, MaxLevel)
|
||||
);
|
||||
|
||||
const uint8 max_level = level > skill_cap_max_level ? level : skill_cap_max_level;
|
||||
|
||||
for (const auto &e: m_skill_caps) {
|
||||
for (uint8 current_level = 1; current_level <= max_level; current_level++) {
|
||||
if (
|
||||
e.class_id == class_id &&
|
||||
static_cast<EQ::skills::SkillType>(e.skill_id) == skill_id &&
|
||||
e.level == current_level
|
||||
) {
|
||||
return current_level;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
void SkillCaps::LoadSkillCaps()
|
||||
{
|
||||
const auto &l = SkillCapsRepository::All(*m_content_database);
|
||||
|
||||
m_skill_caps.reserve(l.size());
|
||||
|
||||
for (const auto &e: l) {
|
||||
if (
|
||||
e.level < 1 ||
|
||||
!IsPlayerClass(e.class_id) ||
|
||||
static_cast<EQ::skills::SkillType>(e.skill_id) >= EQ::skills::SkillCount
|
||||
) {
|
||||
continue;
|
||||
}
|
||||
|
||||
m_skill_caps.emplace_back(e);
|
||||
}
|
||||
|
||||
LogInfo(
|
||||
"Loaded [{}] Skill Cap Entr{}",
|
||||
l.size(),
|
||||
l.size() != 1 ? "ies" : "y"
|
||||
);
|
||||
}
|
||||
|
||||
void SkillCaps::ReloadSkillCaps()
|
||||
{
|
||||
ClearSkillCaps();
|
||||
LoadSkillCaps();
|
||||
}
|
||||
@@ -0,0 +1,26 @@
|
||||
#ifndef CODE_SKILL_CAPS_H
|
||||
#define CODE_SKILL_CAPS_H
|
||||
|
||||
#include "repositories/skill_caps_repository.h"
|
||||
#include "types.h"
|
||||
#include "classes.h"
|
||||
#include "skills.h"
|
||||
|
||||
class SkillCaps {
|
||||
public:
|
||||
inline void ClearSkillCaps() { m_skill_caps.clear(); }
|
||||
SkillCapsRepository::SkillCaps GetSkillCap(uint8 class_id, EQ::skills::SkillType skill_id, uint8 level);
|
||||
uint8 GetTrainLevel(uint8 class_id, EQ::skills::SkillType skill_id, uint8 level);
|
||||
void LoadSkillCaps();
|
||||
void ReloadSkillCaps();
|
||||
|
||||
SkillCaps *SetContentDatabase(Database *db);
|
||||
private:
|
||||
Database *m_content_database{};
|
||||
std::vector<SkillCapsRepository::SkillCaps> m_skill_caps = {};
|
||||
};
|
||||
|
||||
extern SkillCaps skill_caps;
|
||||
|
||||
|
||||
#endif //CODE_SKILL_CAPS_H
|
||||
+1
-1
@@ -18,10 +18,10 @@
|
||||
*/
|
||||
|
||||
#include "skills.h"
|
||||
#include "classes.h"
|
||||
|
||||
#include <string.h>
|
||||
|
||||
|
||||
bool EQ::skills::IsTradeskill(SkillType skill)
|
||||
{
|
||||
switch (skill) {
|
||||
|
||||
@@ -26,7 +26,6 @@
|
||||
#include <map>
|
||||
#include <vector>
|
||||
|
||||
|
||||
namespace EQ
|
||||
{
|
||||
namespace skills {
|
||||
|
||||
+1
-1
@@ -1257,7 +1257,7 @@ typedef enum {
|
||||
#define SE_Ff_Override_NotFocusable 460 // implemented, @Fc, Allow spell to be focused event if flagged with 'not_focusable' in spell table, base: 1
|
||||
#define SE_ImprovedDamage2 461 // implemented, @Fc, On Caster, spell damage mod pct, base: min pct, limit: max pct
|
||||
#define SE_FcDamageAmt2 462 // implemented, @Fc, On Caster, spell damage mod flat amt, base: amt
|
||||
//#define SE_Shield_Target 463 //
|
||||
#define SE_Shield_Target 463 // implemented, Base1 % damage shielded on target
|
||||
#define SE_PC_Pet_Rampage 464 // implemented - Base1 % chance to do rampage for base2 % of damage each melee round
|
||||
#define SE_PC_Pet_AE_Rampage 465 // implemented - Base1 % chance to do AE rampage for base2 % of damage each melee round
|
||||
#define SE_PC_Pet_Flurry_Chance 466 // implemented - Base1 % chance to do flurry from double attack hit.
|
||||
|
||||
+1
-1
@@ -42,7 +42,7 @@
|
||||
* Manifest: https://github.com/EQEmu/Server/blob/master/utils/sql/db_update_manifest.txt
|
||||
*/
|
||||
|
||||
#define CURRENT_BINARY_DATABASE_VERSION 9266
|
||||
#define CURRENT_BINARY_DATABASE_VERSION 9268
|
||||
#define CURRENT_BINARY_BOTS_DATABASE_VERSION 9043
|
||||
|
||||
#endif
|
||||
|
||||
@@ -0,0 +1,28 @@
|
||||
# Description
|
||||
|
||||
Please include a summary of the changes and the related issue (Why is this change necessary). Please also include relevant motivation and context. List any dependencies that are required for this change.
|
||||
|
||||
Fixes # (issue)
|
||||
|
||||
## Type of change
|
||||
|
||||
Please delete options that are not relevant.
|
||||
|
||||
- [ ] Bug fix (non-breaking change which fixes an issue)
|
||||
- [ ] New feature (non-breaking change which adds functionality)
|
||||
- [ ] Breaking change (fix or feature that would cause existing functionality to not work as expected)
|
||||
- [ ] This change requires a documentation update
|
||||
|
||||
# Testing
|
||||
|
||||
Attach images and describe testing done to validate functionality.
|
||||
|
||||
Clients tested:
|
||||
|
||||
# Checklist
|
||||
|
||||
- [ ] I have tested my changes
|
||||
- [ ] I have performed a self-review of my code. Ensuring variables, functions and methods are named in a human-readable way, comments are added only where naming of variables, functions and methods can't give enough context.
|
||||
- [ ] I have made corresponding changes to the documentation (if applicable, if not delete this line)
|
||||
- [ ] I own the changes of my code and take responsibility for the potential issues that occur
|
||||
- [ ] If my changes make database schema changes, I have tested the changes on a local database (attach image). Updated version.h CURRENT_BINARY_DATABASE_VERSION to the new version. (Delete this if not applicable)
|
||||
@@ -4,13 +4,11 @@ SET(shared_memory_sources
|
||||
items.cpp
|
||||
main.cpp
|
||||
spells.cpp
|
||||
skill_caps.cpp
|
||||
)
|
||||
|
||||
SET(shared_memory_headers
|
||||
items.h
|
||||
spells.h
|
||||
skill_caps.h
|
||||
)
|
||||
|
||||
ADD_EXECUTABLE(shared_memory ${shared_memory_sources} ${shared_memory_headers})
|
||||
|
||||
+1
-17
@@ -28,7 +28,6 @@
|
||||
#include "../common/eqemu_exception.h"
|
||||
#include "../common/strings.h"
|
||||
#include "items.h"
|
||||
#include "skill_caps.h"
|
||||
#include "spells.h"
|
||||
#include "../common/content/world_content_service.h"
|
||||
#include "../common/zone_store.h"
|
||||
@@ -183,7 +182,6 @@ int main(int argc, char **argv)
|
||||
bool load_all = true;
|
||||
bool load_items = false;
|
||||
bool load_loot = false;
|
||||
bool load_skill_caps = false;
|
||||
bool load_spells = false;
|
||||
|
||||
if (argc > 1) {
|
||||
@@ -197,11 +195,7 @@ int main(int argc, char **argv)
|
||||
break;
|
||||
|
||||
case 's':
|
||||
if (strcasecmp("skill_caps", argv[i]) == 0) {
|
||||
load_skill_caps = true;
|
||||
load_all = false;
|
||||
}
|
||||
else if (strcasecmp("spells", argv[i]) == 0) {
|
||||
if (strcasecmp("spells", argv[i]) == 0) {
|
||||
load_spells = true;
|
||||
load_all = false;
|
||||
}
|
||||
@@ -236,16 +230,6 @@ int main(int argc, char **argv)
|
||||
}
|
||||
}
|
||||
|
||||
if (load_all || load_skill_caps) {
|
||||
LogInfo("Loading skill caps");
|
||||
try {
|
||||
LoadSkillCaps(&content_db, hotfix_name);
|
||||
} catch (std::exception &ex) {
|
||||
LogError("{}", ex.what());
|
||||
return 1;
|
||||
}
|
||||
}
|
||||
|
||||
if (load_all || load_spells) {
|
||||
LogInfo("Loading spells");
|
||||
try {
|
||||
|
||||
@@ -1,45 +0,0 @@
|
||||
/* EQEMu: Everquest Server Emulator
|
||||
Copyright (C) 2001-2013 EQEMu Development Team (http://eqemulator.net)
|
||||
|
||||
This program is free software; you can redistribute it and/or modify
|
||||
it under the terms of the GNU General Public License as published by
|
||||
the Free Software Foundation; version 2 of the License.
|
||||
|
||||
This program is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY except by those people which sell it, which
|
||||
are required to give you total support for your newly bought product;
|
||||
without even the implied warranty of MERCHANTABILITY or FITNESS FOR
|
||||
A PARTICULAR PURPOSE. See the GNU General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU General Public License
|
||||
along with this program; if not, write to the Free Software
|
||||
Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
|
||||
*/
|
||||
|
||||
#include "skill_caps.h"
|
||||
#include "../common/global_define.h"
|
||||
#include "../common/shareddb.h"
|
||||
#include "../common/ipc_mutex.h"
|
||||
#include "../common/memory_mapped_file.h"
|
||||
#include "../common/eqemu_exception.h"
|
||||
#include "../common/classes.h"
|
||||
#include "../common/features.h"
|
||||
|
||||
void LoadSkillCaps(SharedDatabase *database, const std::string &prefix) {
|
||||
EQ::IPCMutex mutex("skill_caps");
|
||||
mutex.Lock();
|
||||
|
||||
uint32 class_count = Class::PLAYER_CLASS_COUNT;
|
||||
uint32 skill_count = EQ::skills::HIGHEST_SKILL + 1;
|
||||
uint32 level_count = HARD_LEVEL_CAP + 1;
|
||||
uint32 size = (class_count * skill_count * level_count * sizeof(uint16));
|
||||
|
||||
auto Config = EQEmuConfig::get();
|
||||
std::string file_name = Config->SharedMemDir + prefix + std::string("skill_caps");
|
||||
EQ::MemoryMappedFile mmf(file_name, size);
|
||||
mmf.ZeroFile();
|
||||
|
||||
void *ptr = mmf.Get();
|
||||
database->LoadSkillCaps(ptr);
|
||||
mutex.Unlock();
|
||||
}
|
||||
@@ -1,29 +0,0 @@
|
||||
/* EQEMu: Everquest Server Emulator
|
||||
Copyright (C) 2001-2013 EQEMu Development Team (http://eqemulator.net)
|
||||
|
||||
This program is free software; you can redistribute it and/or modify
|
||||
it under the terms of the GNU General Public License as published by
|
||||
the Free Software Foundation; version 2 of the License.
|
||||
|
||||
This program is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY except by those people which sell it, which
|
||||
are required to give you total support for your newly bought product;
|
||||
without even the implied warranty of MERCHANTABILITY or FITNESS FOR
|
||||
A PARTICULAR PURPOSE. See the GNU General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU General Public License
|
||||
along with this program; if not, write to the Free Software
|
||||
Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
|
||||
*/
|
||||
|
||||
#ifndef __EQEMU_SHARED_MEMORY_SKILL_CAPS_H
|
||||
#define __EQEMU_SHARED_MEMORY_SKILL_CAPS_H
|
||||
|
||||
#include <string>
|
||||
#include "../common/eqemu_config.h"
|
||||
|
||||
class SharedDatabase;
|
||||
void LoadSkillCaps(SharedDatabase *database, const std::string &prefix);
|
||||
|
||||
#endif
|
||||
|
||||
@@ -280,7 +280,7 @@ foreach my $table_to_generate (@tables) {
|
||||
|
||||
# column names (string)
|
||||
$column_names_quoted .= sprintf("\t\t\t\"%s\",\n", format_column_name_for_mysql($column_name));
|
||||
if ($data_type =~ /datetime/) {
|
||||
if ($data_type =~ /datetime|timestamp/) {
|
||||
$select_column_names_quoted .= sprintf("\t\t\t\"UNIX_TIMESTAMP(%s)\",\n", format_column_name_for_mysql($column_name));
|
||||
}
|
||||
else {
|
||||
@@ -293,7 +293,7 @@ foreach my $table_to_generate (@tables) {
|
||||
if ($data_type =~ /int|float|double|decimal/) {
|
||||
$query_value = sprintf('" + std::to_string(e.%s));', $column_name_formatted);
|
||||
}
|
||||
elsif ($data_type =~ /datetime/) {
|
||||
elsif ($data_type =~ /datetime|timestamp/) {
|
||||
$query_value = sprintf('FROM_UNIXTIME(" + (e.%s > 0 ? std::to_string(e.%s) : "null") + ")");', $column_name_formatted, $column_name_formatted);
|
||||
}
|
||||
|
||||
@@ -309,7 +309,7 @@ foreach my $table_to_generate (@tables) {
|
||||
if ($data_type =~ /int|float|double|decimal/) {
|
||||
$value = sprintf('std::to_string(e.%s)', $column_name_formatted);
|
||||
}
|
||||
elsif ($data_type =~ /datetime/) {
|
||||
elsif ($data_type =~ /datetime|timestamp/) {
|
||||
$value = sprintf('"FROM_UNIXTIME(" + (e.%s > 0 ? std::to_string(e.%s) : "null") + ")"', $column_name_formatted, $column_name_formatted);
|
||||
}
|
||||
|
||||
@@ -332,7 +332,7 @@ foreach my $table_to_generate (@tables) {
|
||||
$all_entries .= sprintf("\t\t\te.%-${longest_column_length}s = row[%s] ? strtoll(row[%s], nullptr, 10) : %s;\n", $column_name_formatted, $index, $index, $default_value);
|
||||
$find_one_entries .= sprintf("\t\t\te.%-${longest_column_length}s = row[%s] ? strtoll(row[%s], nullptr, 10) : %s;\n", $column_name_formatted, $index, $index, $default_value);
|
||||
}
|
||||
elsif ($data_type =~ /datetime/) {
|
||||
elsif ($data_type =~ /datetime|timestamp/) {
|
||||
$all_entries .= sprintf("\t\t\te.%-${longest_column_length}s = strtoll(row[%s] ? row[%s] : \"-1\", nullptr, 10);\n", $column_name_formatted, $index, $index);
|
||||
$find_one_entries .= sprintf("\t\t\te.%-${longest_column_length}s = strtoll(row[%s] ? row[%s] : \"-1\", nullptr, 10);\n", $column_name_formatted, $index, $index);
|
||||
}
|
||||
@@ -591,7 +591,7 @@ sub translate_mysql_data_type_to_c
|
||||
elsif ($mysql_data_type =~ /double/) {
|
||||
$struct_data_type = 'double';
|
||||
}
|
||||
elsif ($mysql_data_type =~ /datetime/) {
|
||||
elsif ($mysql_data_type =~ /datetime|timestamp/) {
|
||||
$struct_data_type = 'time_t';
|
||||
}
|
||||
|
||||
|
||||
+40
-12
@@ -53,6 +53,9 @@
|
||||
#include "../common/repositories/inventory_repository.h"
|
||||
#include "../common/events/player_event_logs.h"
|
||||
#include "../common/content/world_content_service.h"
|
||||
#include "../common/repositories/group_id_repository.h"
|
||||
#include "../common/repositories/character_data_repository.h"
|
||||
#include "../common/skill_caps.h"
|
||||
|
||||
#include <iostream>
|
||||
#include <iomanip>
|
||||
@@ -190,9 +193,10 @@ bool Client::CanTradeFVNoDropItem()
|
||||
|
||||
void Client::SendEnterWorld(std::string name)
|
||||
{
|
||||
char char_name[64] = { 0 };
|
||||
if (is_player_zoning && database.GetLiveChar(GetAccountID(), char_name)) {
|
||||
if(database.GetAccountIDByChar(char_name) != GetAccountID()) {
|
||||
std::string live_name {};
|
||||
if (is_player_zoning) {
|
||||
live_name = database.GetLiveChar(GetAccountID());
|
||||
if(database.GetAccountIDByChar(live_name) != GetAccountID()) {
|
||||
eqs->Close();
|
||||
return;
|
||||
} else {
|
||||
@@ -200,8 +204,8 @@ void Client::SendEnterWorld(std::string name)
|
||||
}
|
||||
}
|
||||
|
||||
auto outapp = new EQApplicationPacket(OP_EnterWorld, strlen(char_name) + 1);
|
||||
memcpy(outapp->pBuffer,char_name,strlen(char_name)+1);
|
||||
auto outapp = new EQApplicationPacket(OP_EnterWorld, live_name.length() + 1);
|
||||
memcpy(outapp->pBuffer, live_name.c_str(), live_name.length() + 1);
|
||||
QueuePacket(outapp);
|
||||
safe_delete(outapp);
|
||||
}
|
||||
@@ -764,9 +768,15 @@ bool Client::HandleEnterWorldPacket(const EQApplicationPacket *app) {
|
||||
auto ew = (EnterWorld_Struct *) app->pBuffer;
|
||||
strn0cpy(char_name, ew->name, sizeof(char_name));
|
||||
|
||||
uint32 temporary_account_id = 0;
|
||||
charid = database.GetCharacterInfo(char_name, &temporary_account_id, &zone_id, &instance_id);
|
||||
if (!charid) {
|
||||
const auto& l = CharacterDataRepository::GetWhere(
|
||||
database,
|
||||
fmt::format(
|
||||
"`name` = '{}' LIMIT 1",
|
||||
Strings::Escape(char_name)
|
||||
)
|
||||
);
|
||||
|
||||
if (l.empty()) {
|
||||
LogInfo("Could not get CharInfo for [{}]", char_name);
|
||||
eqs->Close();
|
||||
return true;
|
||||
@@ -784,13 +794,24 @@ bool Client::HandleEnterWorldPacket(const EQApplicationPacket *app) {
|
||||
instance_id = r.instance.id;
|
||||
}
|
||||
|
||||
const auto& e = l.front();
|
||||
|
||||
// Make sure this account owns this character
|
||||
if (temporary_account_id != account_id) {
|
||||
LogInfo("Account [{}] does not own the character named [{}] from account [{}]", account_id, char_name, temporary_account_id);
|
||||
if (e.account_id != account_id) {
|
||||
LogInfo(
|
||||
"Account [{}] does not own the character named [{}] from account [{}]",
|
||||
account_id,
|
||||
char_name,
|
||||
e.account_id
|
||||
);
|
||||
eqs->Close();
|
||||
return true;
|
||||
}
|
||||
|
||||
charid = e.id;
|
||||
zone_id = e.zone_id;
|
||||
instance_id = e.zone_instance;
|
||||
|
||||
// This can probably be moved outside and have another method return requested info (don't forget to remove the #include "../common/shareddb.h" above)
|
||||
// (This is a literal translation of the original process..I don't see why it can't be changed to a single-target query over account iteration)
|
||||
if (!is_player_zoning) {
|
||||
@@ -881,7 +902,14 @@ bool Client::HandleEnterWorldPacket(const EQApplicationPacket *app) {
|
||||
}
|
||||
|
||||
if(!is_player_zoning) {
|
||||
database.SetGroupID(char_name, 0, charid);
|
||||
GroupIdRepository::DeleteWhere(
|
||||
database,
|
||||
fmt::format(
|
||||
"`character_id` = {} AND `name` = '{}'",
|
||||
charid,
|
||||
Strings::Escape(char_name)
|
||||
)
|
||||
);
|
||||
database.SetLoginFlags(charid, false, false, 1);
|
||||
} else {
|
||||
auto group_id = database.GetGroupID(char_name);
|
||||
@@ -2107,7 +2135,7 @@ void Client::SetClassStartingSkills(PlayerProfile_Struct *pp)
|
||||
i == EQ::skills::SkillAlcoholTolerance || i == EQ::skills::SkillBindWound)
|
||||
continue;
|
||||
|
||||
pp->skills[i] = content_db.GetSkillCap(pp->class_, (EQ::skills::SkillType)i, 1);
|
||||
pp->skills[i] = skill_caps.GetSkillCap(pp->class_, (EQ::skills::SkillType)i, 1).cap;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -344,7 +344,7 @@ bool ClientListEntry::CheckAuth(uint32 loginserver_account_id, const char *key_p
|
||||
|
||||
paccountid = database.CreateAccount(
|
||||
loginserver_account_name,
|
||||
0,
|
||||
std::string(),
|
||||
default_account_status,
|
||||
source_loginserver,
|
||||
LSID()
|
||||
|
||||
+1
-2
@@ -57,8 +57,7 @@ struct EQ::Net::ConsoleLoginStatus CheckLogin(const std::string &username, const
|
||||
return ret;
|
||||
}
|
||||
|
||||
char account_name[64];
|
||||
database.GetAccountName(ret.account_id, account_name);
|
||||
const std::string& account_name = database.GetAccountName(ret.account_id);
|
||||
|
||||
ret.account_name = account_name;
|
||||
ret.status = database.CheckStatus(ret.account_id);
|
||||
|
||||
@@ -156,6 +156,7 @@ std::vector<Reload> reload_types = {
|
||||
Reload{.command = "opcodes", .opcode = ServerOP_ReloadOpcodes, .desc = "Opcodes"},
|
||||
Reload{.command = "perl_export", .opcode = ServerOP_ReloadPerlExportSettings, .desc = "Perl Event Export Settings"},
|
||||
Reload{.command = "rules", .opcode = ServerOP_ReloadRules, .desc = "Rules"},
|
||||
Reload{.command = "skill_caps", .opcode = ServerOP_ReloadSkillCaps, .desc = "Skill Caps"},
|
||||
Reload{.command = "static", .opcode = ServerOP_ReloadStaticZoneData, .desc = "Static Zone Data"},
|
||||
Reload{.command = "tasks", .opcode = ServerOP_ReloadTasks, .desc = "Tasks"},
|
||||
Reload{.command = "titles", .opcode = ServerOP_ReloadTitles, .desc = "Titles"},
|
||||
|
||||
+4
-1
@@ -86,8 +86,9 @@
|
||||
#include "world_boot.h"
|
||||
#include "../common/path_manager.h"
|
||||
#include "../common/events/player_event_logs.h"
|
||||
#include "../common/skill_caps.h"
|
||||
|
||||
|
||||
SkillCaps skill_caps;
|
||||
ZoneStore zone_store;
|
||||
ClientList client_list;
|
||||
GroupLFPList LFPGroupList;
|
||||
@@ -193,6 +194,8 @@ int main(int argc, char **argv)
|
||||
->SetExpansionContext()
|
||||
->ReloadContentFlags();
|
||||
|
||||
skill_caps.SetContentDatabase(&content_db)->LoadSkillCaps();
|
||||
|
||||
std::unique_ptr<EQ::Net::ServertalkServer> server_connection;
|
||||
server_connection = std::make_unique<EQ::Net::ServertalkServer>();
|
||||
|
||||
|
||||
@@ -292,10 +292,6 @@ bool WorldBoot::DatabaseLoadRoutines(int argc, char **argv)
|
||||
LogError("Error: Could not load item data. But ignoring");
|
||||
}
|
||||
|
||||
if (!content_db.LoadSkillCaps(std::string(hotfix_name))) {
|
||||
LogError("Error: Could not load skill cap data. But ignoring");
|
||||
}
|
||||
|
||||
guild_mgr.LoadGuilds();
|
||||
guild_mgr.LoadTributes();
|
||||
|
||||
|
||||
@@ -49,6 +49,7 @@ Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
|
||||
#include "../common/patches/patches.h"
|
||||
#include "../zone/data_bucket.h"
|
||||
#include "../common/repositories/guild_tributes_repository.h"
|
||||
#include "../common/skill_caps.h"
|
||||
|
||||
extern ClientList client_list;
|
||||
extern GroupLFPList LFPGroupList;
|
||||
@@ -1436,6 +1437,11 @@ void ZoneServer::HandleMessage(uint16 opcode, const EQ::Net::Packet &p) {
|
||||
zoneserver_list.SendPacket(pack);
|
||||
break;
|
||||
}
|
||||
case ServerOP_ReloadSkillCaps: {
|
||||
zoneserver_list.SendPacket(pack);
|
||||
skill_caps.ReloadSkillCaps();
|
||||
break;
|
||||
}
|
||||
case ServerOP_ReloadRules: {
|
||||
zoneserver_list.SendPacket(pack);
|
||||
RuleManager::Instance()->LoadRules(&database, "default", true);
|
||||
@@ -1496,11 +1502,6 @@ void ZoneServer::HandleMessage(uint16 opcode, const EQ::Net::Packet &p) {
|
||||
LogInfo("Error: Could not load item data. But ignoring");
|
||||
}
|
||||
|
||||
LogInfo("Loading skill caps");
|
||||
if (!content_db.LoadSkillCaps(hotfix_name)) {
|
||||
LogInfo("Error: Could not load skill cap data. But ignoring");
|
||||
}
|
||||
|
||||
zoneserver_list.SendPacket(pack);
|
||||
break;
|
||||
}
|
||||
|
||||
@@ -57,9 +57,7 @@ EQ::Net::WebsocketLoginStatus CheckLogin(
|
||||
return ret;
|
||||
}
|
||||
|
||||
char account_name[64];
|
||||
database.GetAccountName(static_cast<uint32>(ret.account_id), account_name);
|
||||
ret.account_name = account_name;
|
||||
ret.account_name = database.GetAccountName(static_cast<uint32>(ret.account_id));
|
||||
ret.logged_in = true;
|
||||
ret.status = database.CheckStatus(ret.account_id);
|
||||
return ret;
|
||||
|
||||
+97
-4
@@ -2816,6 +2816,9 @@ bool NPC::Death(Mob* killer_mob, int64 damage, uint16 spell, EQ::skills::SkillTy
|
||||
|
||||
entity_list.RemoveFromAutoXTargets(this);
|
||||
|
||||
// Here we create the corpse.
|
||||
DeleteInvalidQuestLoot();
|
||||
|
||||
corpse = new Corpse(
|
||||
this,
|
||||
&m_loot_items,
|
||||
@@ -3964,6 +3967,18 @@ bool Mob::CheckDoubleAttack()
|
||||
}
|
||||
|
||||
void Mob::CommonDamage(Mob* attacker, int64 &damage, const uint16 spell_id, const EQ::skills::SkillType skill_used, bool &avoidable, const int8 buffslot, const bool iBuffTic, eSpecialAttacks special) {
|
||||
#ifdef LUA_EQEMU
|
||||
int64 lua_ret = 0;
|
||||
bool ignore_default = false;
|
||||
lua_ret = LuaParser::Instance()->CommonDamage(this, attacker, damage, spell_id, static_cast<int>(skill_used), avoidable, buffslot, iBuffTic, static_cast<int>(special), ignore_default);
|
||||
if (lua_ret != 0) {
|
||||
damage = lua_ret;
|
||||
}
|
||||
|
||||
if (ignore_default) {
|
||||
//return lua_ret;
|
||||
}
|
||||
#endif
|
||||
// This method is called with skill_used=ABJURE for Damage Shield damage.
|
||||
bool FromDamageShield = (skill_used == EQ::skills::SkillAbjuration);
|
||||
bool ignore_invul = false;
|
||||
@@ -4691,6 +4706,19 @@ void Mob::CommonDamage(Mob* attacker, int64 &damage, const uint16 spell_id, cons
|
||||
|
||||
void Mob::HealDamage(uint64 amount, Mob* caster, uint16 spell_id)
|
||||
{
|
||||
#ifdef LUA_EQEMU
|
||||
uint64 lua_ret = 0;
|
||||
bool ignore_default = false;
|
||||
|
||||
lua_ret = LuaParser::Instance()->HealDamage(this, caster, amount, spell_id, ignore_default);
|
||||
if (lua_ret != 0) {
|
||||
amount = lua_ret;
|
||||
}
|
||||
|
||||
if (ignore_default) {
|
||||
//return lua_ret;
|
||||
}
|
||||
#endif
|
||||
int64 maxhp = GetMaxHP();
|
||||
int64 curhp = GetHP();
|
||||
uint64 acthealed = 0;
|
||||
@@ -6285,9 +6313,24 @@ void Mob::CommonOutgoingHitSuccess(Mob* defender, DamageHitInfo &hit, ExtraAttac
|
||||
|
||||
hit.damage_done += (hit.damage_done * pct_damage_reduction / 100) + defender->GetPositionalDmgTakenAmt(this);
|
||||
|
||||
if (defender->GetShielderID()) {
|
||||
DoShieldDamageOnShielder(defender, hit.damage_done, hit.skill);
|
||||
hit.damage_done -= hit.damage_done * defender->GetShieldTargetMitigation() / 100; //Default shielded takes 50 pct damage
|
||||
if (defender->GetShielderID() || defender->spellbonuses.ShieldTargetSpa[SBIndex::SHIELD_TARGET_MITIGATION_PERCENT]) {
|
||||
bool use_shield_ability = true;
|
||||
//If defender is being shielded by an ability AND has a shield spell effect buff use highest mitigation value.
|
||||
if ((defender->GetShieldTargetMitigation() && defender->spellbonuses.ShieldTargetSpa[SBIndex::SHIELD_TARGET_MITIGATION_PERCENT]) &&
|
||||
(defender->spellbonuses.ShieldTargetSpa[SBIndex::SHIELD_TARGET_MITIGATION_PERCENT] >= defender->GetShieldTargetMitigation())){
|
||||
bool use_shield_ability = false;
|
||||
}
|
||||
|
||||
//use targeted /shield ability values
|
||||
if (defender->GetShielderID() && use_shield_ability) {
|
||||
DoShieldDamageOnShielder(defender, hit.damage_done, hit.skill);
|
||||
hit.damage_done -= hit.damage_done * defender->GetShieldTargetMitigation() / 100; //Default shielded takes 50 pct damage
|
||||
}
|
||||
//use spell effect SPA 463 values
|
||||
else if (defender->spellbonuses.ShieldTargetSpa[SBIndex::SHIELD_TARGET_MITIGATION_PERCENT]){
|
||||
DoShieldDamageOnShielderSpellEffect(defender, hit.damage_done, hit.skill);
|
||||
hit.damage_done -= hit.damage_done * defender->spellbonuses.ShieldTargetSpa[SBIndex::SHIELD_TARGET_MITIGATION_PERCENT] / 100;
|
||||
}
|
||||
}
|
||||
|
||||
CheckNumHitsRemaining(NumHit::OutgoingHitSuccess);
|
||||
@@ -6330,7 +6373,57 @@ void Mob::DoShieldDamageOnShielder(Mob *shield_target, int64 hit_damage_done, EQ
|
||||
|
||||
hit_damage_done -= hit_damage_done * mitigation / 100;
|
||||
shielder->Damage(this, hit_damage_done, SPELL_UNKNOWN, skillInUse, true, -1, false, m_specialattacks);
|
||||
shielder->CheckNumHitsRemaining(NumHit::OutgoingHitSuccess);
|
||||
}
|
||||
|
||||
void Mob::DoShieldDamageOnShielderSpellEffect(Mob* shield_target, int64 hit_damage_done, EQ::skills::SkillType skillInUse)
|
||||
{
|
||||
if (!shield_target) {
|
||||
return;
|
||||
}
|
||||
/*
|
||||
SPA 463 SE_SHIELD_TARGET
|
||||
|
||||
Live description: "Shields your target, taking a percentage of their damage".
|
||||
Only example spell on live is an NPC who uses it during a raid event "Laurion's Song" expansion. SPA 54492 'Guardian Stance' Described as 100% Melee Shielding
|
||||
|
||||
Example of mechanic. Base value = 70. Caster puts buff on target. Each melee hit Buff Target takes 70% less damage, Buff Caster receives 30% of the melee damage.
|
||||
Added mechanic to cause buff to fade if target or caster are seperated by a distance greater than the casting range of the spell. This allows similiar mechanics
|
||||
to the /shield ability, without a range removal mechanic it would be too easy to abuse if put on a player spell. *can not confirm live does this currently
|
||||
|
||||
Can not be cast on self.
|
||||
*/
|
||||
|
||||
if (shield_target->spellbonuses.ShieldTargetSpa[SBIndex::SHIELD_TARGET_MITIGATION_PERCENT])
|
||||
{
|
||||
if (shield_target->spellbonuses.ShieldTargetSpa[SBIndex::SHIELD_TARGET_BUFFSLOT] >= 0)
|
||||
{
|
||||
Mob *shielder = entity_list.GetMob(shield_target->buffs[shield_target->spellbonuses.ShieldTargetSpa[SBIndex::SHIELD_TARGET_BUFFSLOT]].casterid);
|
||||
if (!shielder) {
|
||||
shield_target->BuffFadeBySlot(shield_target->spellbonuses.ShieldTargetSpa[SBIndex::SHIELD_TARGET_BUFFSLOT]);
|
||||
return;
|
||||
}
|
||||
|
||||
int shield_spell_id = shield_target->buffs[shield_target->spellbonuses.ShieldTargetSpa[SBIndex::SHIELD_TARGET_BUFFSLOT]].spellid;
|
||||
if (!IsValidSpell(shield_spell_id)) {
|
||||
return;
|
||||
}
|
||||
|
||||
float max_range = spells[shield_spell_id].range;
|
||||
if (spells[shield_spell_id].aoe_range > max_range) {
|
||||
max_range = spells[shield_spell_id].aoe_range;
|
||||
}
|
||||
max_range += 5.0f; //small buffer in case casted at exactly max range.
|
||||
|
||||
if (shield_target->CalculateDistance(shielder->GetX(), shielder->GetY(), shielder->GetZ()) > max_range) {
|
||||
shield_target->BuffFadeBySlot(shield_target->spellbonuses.ShieldTargetSpa[SBIndex::SHIELD_TARGET_BUFFSLOT]);
|
||||
return;
|
||||
}
|
||||
|
||||
int mitigation = 100 - shield_target->spellbonuses.ShieldTargetSpa[SBIndex::SHIELD_TARGET_MITIGATION_PERCENT];
|
||||
hit_damage_done -= hit_damage_done * mitigation / 100;
|
||||
shielder->Damage(this, hit_damage_done, SPELL_UNKNOWN, skillInUse, true, -1, false, m_specialattacks);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void Mob::CommonBreakInvisibleFromCombat()
|
||||
|
||||
+24
-1
@@ -2090,7 +2090,10 @@ void Mob::ApplySpellsBonuses(uint16 spell_id, uint8 casterlevel, StatBonuses *ne
|
||||
if (focus)
|
||||
{
|
||||
if (WornType){
|
||||
if (RuleB(Spells, UseAdditiveFocusFromWornSlot)) {
|
||||
if (RuleB(Spells, UseAdditiveFocusFromWornSlotWithLimits)) {
|
||||
new_bonus->FocusEffectsWornWithLimits[focus] = spells[spell_id].effect_id[i];
|
||||
}
|
||||
else if (RuleB(Spells, UseAdditiveFocusFromWornSlot)) {
|
||||
new_bonus->FocusEffectsWorn[focus] += spells[spell_id].base_value[i];
|
||||
}
|
||||
}
|
||||
@@ -3298,6 +3301,15 @@ void Mob::ApplySpellsBonuses(uint16 spell_id, uint8 casterlevel, StatBonuses *ne
|
||||
break;
|
||||
}
|
||||
|
||||
case SE_Shield_Target:
|
||||
{
|
||||
if (new_bonus->ShieldTargetSpa[SBIndex::SHIELD_TARGET_MITIGATION_PERCENT] < effect_value) {
|
||||
new_bonus->ShieldTargetSpa[SBIndex::SHIELD_TARGET_MITIGATION_PERCENT] = effect_value;
|
||||
new_bonus->ShieldTargetSpa[SBIndex::SHIELD_TARGET_BUFFSLOT] = buffslot;
|
||||
}
|
||||
break;
|
||||
}
|
||||
|
||||
case SE_TriggerMeleeThreshold:
|
||||
new_bonus->TriggerMeleeThreshold = true;
|
||||
break;
|
||||
@@ -4989,6 +5001,7 @@ void Mob::NegateSpellEffectBonuses(uint16 spell_id)
|
||||
case SE_MaxHPChange:
|
||||
if (negate_spellbonus) { spellbonuses.MaxHPChange = effect_value; }
|
||||
if (negate_aabonus) { aabonuses.MaxHPChange = effect_value; }
|
||||
if (negate_aabonus) { aabonuses.MaxHP = effect_value; }
|
||||
if (negate_itembonus) { itembonuses.MaxHPChange = effect_value; }
|
||||
break;
|
||||
|
||||
@@ -5916,6 +5929,7 @@ void Mob::NegateSpellEffectBonuses(uint16 spell_id)
|
||||
if (negate_itembonus) { itembonuses.SkillProcSuccess[e] = effect_value; }
|
||||
if (negate_aabonus) { aabonuses.SkillProcSuccess[e] = effect_value; }
|
||||
}
|
||||
break;
|
||||
}
|
||||
|
||||
case SE_SkillProcAttempt: {
|
||||
@@ -5925,6 +5939,15 @@ void Mob::NegateSpellEffectBonuses(uint16 spell_id)
|
||||
if (negate_itembonus) { itembonuses.SkillProc[e] = effect_value; }
|
||||
if (negate_aabonus) { aabonuses.SkillProc[e] = effect_value; }
|
||||
}
|
||||
break;
|
||||
}
|
||||
|
||||
case SE_Shield_Target: {
|
||||
if (negate_spellbonus) {
|
||||
spellbonuses.ShieldTargetSpa[SBIndex::SHIELD_TARGET_MITIGATION_PERCENT] = effect_value;
|
||||
spellbonuses.ShieldTargetSpa[SBIndex::SHIELD_TARGET_BUFFSLOT] = effect_value;
|
||||
}
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
+122
-107
@@ -27,6 +27,7 @@
|
||||
#include "../common/repositories/bot_starting_items_repository.h"
|
||||
#include "../common/data_verification.h"
|
||||
#include "../common/repositories/criteria/content_filter_criteria.h"
|
||||
#include "../common/skill_caps.h"
|
||||
|
||||
// This constructor is used during the bot create command
|
||||
Bot::Bot(NPCType *npcTypeData, Client* botOwner) : NPC(npcTypeData, nullptr, glm::vec4(), Ground, false), rest_timer(1), ping_timer(1) {
|
||||
@@ -1171,7 +1172,7 @@ uint16 Bot::GetPrimarySkillValue() {
|
||||
}
|
||||
|
||||
uint16 Bot::MaxSkill(EQ::skills::SkillType skillid, uint16 class_, uint16 level) const {
|
||||
return(content_db.GetSkillCap(class_, skillid, level));
|
||||
return skill_caps.GetSkillCap(class_, skillid, level).cap;
|
||||
}
|
||||
|
||||
uint32 Bot::GetTotalATK() {
|
||||
@@ -2287,7 +2288,7 @@ bool Bot::TryMeditate() {
|
||||
if (!IsMoving() && !spellend_timer.Enabled()) {
|
||||
if (GetTarget() && AI_EngagedCastCheck()) {
|
||||
BotMeditate(false);
|
||||
} else if (GetArchetype() == ARCHETYPE_CASTER) {
|
||||
} else if (GetArchetype() == Archetype::Caster) {
|
||||
BotMeditate(true);
|
||||
}
|
||||
|
||||
@@ -2755,7 +2756,7 @@ Mob* Bot::GetBotTarget(Client* bot_owner)
|
||||
}
|
||||
}
|
||||
|
||||
if (GetArchetype() == ARCHETYPE_CASTER) {
|
||||
if (GetArchetype() == Archetype::Caster) {
|
||||
BotMeditate(true);
|
||||
}
|
||||
}
|
||||
@@ -3343,7 +3344,7 @@ void Bot::LoadAndSpawnAllZonedBots(Client* bot_owner) {
|
||||
}
|
||||
|
||||
if (bot_spawn_limit >= 0 && spawned_bots_count >= bot_spawn_limit) {
|
||||
database.SetGroupID(b->GetCleanName(), 0, b->GetBotID());
|
||||
Group::RemoveFromGroup(b);
|
||||
g->UpdatePlayer(bot_owner);
|
||||
continue;
|
||||
}
|
||||
@@ -3355,7 +3356,7 @@ void Bot::LoadAndSpawnAllZonedBots(Client* bot_owner) {
|
||||
bot_spawn_limit_class >= 0 &&
|
||||
spawned_bot_count_class >= bot_spawn_limit_class
|
||||
) {
|
||||
database.SetGroupID(b->GetCleanName(), 0, b->GetBotID());
|
||||
Group::RemoveFromGroup(b);
|
||||
g->UpdatePlayer(bot_owner);
|
||||
continue;
|
||||
}
|
||||
@@ -3375,7 +3376,7 @@ void Bot::LoadAndSpawnAllZonedBots(Client* bot_owner) {
|
||||
}
|
||||
|
||||
if (!bot_owner->HasGroup()) {
|
||||
database.SetGroupID(b->GetCleanName(), 0, b->GetBotID());
|
||||
Group::RemoveFromGroup(b);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -3632,7 +3633,7 @@ bool Bot::RemoveBotFromGroup(Bot* bot, Group* group) {
|
||||
bot->SetFollowID(0);
|
||||
if (group->DelMember(bot)) {
|
||||
group->DelMemberOOZ(bot->GetName());
|
||||
database.SetGroupID(bot->GetCleanName(), 0, bot->GetBotID());
|
||||
Group::RemoveFromGroup(bot);
|
||||
if (group->GroupCount() < 2) {
|
||||
group->DisbandGroup();
|
||||
}
|
||||
@@ -3646,7 +3647,7 @@ bool Bot::RemoveBotFromGroup(Bot* bot, Group* group) {
|
||||
group->members[i]->SetFollowID(0);
|
||||
}
|
||||
group->DisbandGroup();
|
||||
database.SetGroupID(bot->GetCleanName(), 0, bot->GetBotID());
|
||||
Group::RemoveFromGroup(bot);
|
||||
}
|
||||
Result = true;
|
||||
}
|
||||
@@ -5189,31 +5190,26 @@ void Bot::ProcessBotOwnerRefDelete(Mob* botOwner) {
|
||||
}
|
||||
}
|
||||
|
||||
int64 Bot::CalcMaxMana() {
|
||||
switch(GetCasterClass()) {
|
||||
case 'I':
|
||||
max_mana = (GenerateBaseManaPoints() + itembonuses.Mana + spellbonuses.Mana + aabonuses.Mana + GroupLeadershipAAManaEnhancement());
|
||||
max_mana += itembonuses.heroic_max_mana;
|
||||
case 'W': {
|
||||
max_mana = (GenerateBaseManaPoints() + itembonuses.Mana + spellbonuses.Mana + aabonuses.Mana + GroupLeadershipAAManaEnhancement());
|
||||
max_mana += itembonuses.heroic_max_mana;
|
||||
break;
|
||||
}
|
||||
case 'N': {
|
||||
max_mana = 0;
|
||||
break;
|
||||
}
|
||||
default: {
|
||||
LogDebug("Invalid Class [{}] in CalcMaxMana", GetCasterClass());
|
||||
max_mana = 0;
|
||||
break;
|
||||
}
|
||||
int64 Bot::CalcMaxMana()
|
||||
{
|
||||
if (IsIntelligenceCasterClass() || IsWisdomCasterClass()) {
|
||||
max_mana = (
|
||||
GenerateBaseManaPoints() +
|
||||
itembonuses.Mana +
|
||||
spellbonuses.Mana +
|
||||
aabonuses.Mana +
|
||||
GroupLeadershipAAManaEnhancement()
|
||||
);
|
||||
max_mana += itembonuses.heroic_max_mana;
|
||||
} else {
|
||||
max_mana = 0;
|
||||
}
|
||||
|
||||
if (current_mana > max_mana)
|
||||
if (current_mana > max_mana) {
|
||||
current_mana = max_mana;
|
||||
else if (max_mana < 0)
|
||||
} else if (max_mana < 0) {
|
||||
max_mana = 0;
|
||||
}
|
||||
|
||||
return max_mana;
|
||||
}
|
||||
@@ -5528,87 +5524,107 @@ bool Bot::DoCastSpell(uint16 spell_id, uint16 target_id, EQ::spells::CastingSlot
|
||||
return Result;
|
||||
}
|
||||
|
||||
int32 Bot::GenerateBaseManaPoints() {
|
||||
int32 bot_mana = 0;
|
||||
int32 WisInt = 0;
|
||||
int32 Bot::GenerateBaseManaPoints()
|
||||
{
|
||||
int32 bot_mana = 0;
|
||||
int32 WisInt = 0;
|
||||
int32 MindLesserFactor, MindFactor;
|
||||
int wisint_mana = 0;
|
||||
int base_mana = 0;
|
||||
int ConvertedWisInt = 0;
|
||||
switch(GetCasterClass()) {
|
||||
case 'I':
|
||||
WisInt = INT;
|
||||
if (GetOwner() && GetOwner()->CastToClient() && GetOwner()->CastToClient()->ClientVersion() >= EQ::versions::ClientVersion::SoD && RuleB(Character, SoDClientUseSoDHPManaEnd)) {
|
||||
if (WisInt > 100) {
|
||||
ConvertedWisInt = (((WisInt - 100) * 5 / 2) + 100);
|
||||
if (WisInt > 201)
|
||||
ConvertedWisInt -= ((WisInt - 201) * 5 / 4);
|
||||
}
|
||||
else
|
||||
ConvertedWisInt = WisInt;
|
||||
int wisint_mana = 0;
|
||||
int base_mana = 0;
|
||||
int ConvertedWisInt = 0;
|
||||
|
||||
if (GetLevel() < 41) {
|
||||
wisint_mana = (GetLevel() * 75 * ConvertedWisInt / 1000);
|
||||
base_mana = (GetLevel() * 15);
|
||||
} else if (GetLevel() < 81) {
|
||||
wisint_mana = ((3 * ConvertedWisInt) + ((GetLevel() - 40) * 15 * ConvertedWisInt / 100));
|
||||
base_mana = (600 + ((GetLevel() - 40) * 30));
|
||||
} else {
|
||||
wisint_mana = (9 * ConvertedWisInt);
|
||||
base_mana = (1800 + ((GetLevel() - 80) * 18));
|
||||
if (IsIntelligenceCasterClass()) {
|
||||
WisInt = INT;
|
||||
|
||||
if (
|
||||
GetOwner() &&
|
||||
GetOwner()->CastToClient() &&
|
||||
GetOwner()->CastToClient()->ClientVersion() >= EQ::versions::ClientVersion::SoD &&
|
||||
RuleB(Character, SoDClientUseSoDHPManaEnd)
|
||||
) {
|
||||
if (WisInt > 100) {
|
||||
ConvertedWisInt = (((WisInt - 100) * 5 / 2) + 100);
|
||||
if (WisInt > 201) {
|
||||
ConvertedWisInt -= ((WisInt - 201) * 5 / 4);
|
||||
}
|
||||
bot_mana = (base_mana + wisint_mana);
|
||||
} else {
|
||||
if (((WisInt - 199) / 2) > 0)
|
||||
MindLesserFactor = ((WisInt - 199) / 2);
|
||||
else
|
||||
MindLesserFactor = 0;
|
||||
|
||||
MindFactor = WisInt - MindLesserFactor;
|
||||
if (WisInt > 100)
|
||||
bot_mana = (((5 * (MindFactor + 20)) / 2) * 3 * GetLevel() / 40);
|
||||
else
|
||||
bot_mana = (((5 * (MindFactor + 200)) / 2) * 3 * GetLevel() / 100);
|
||||
ConvertedWisInt = WisInt;
|
||||
}
|
||||
break;
|
||||
case 'W':
|
||||
WisInt = WIS;
|
||||
if (GetOwner() && GetOwner()->CastToClient() && GetOwner()->CastToClient()->ClientVersion() >= EQ::versions::ClientVersion::SoD && RuleB(Character, SoDClientUseSoDHPManaEnd)) {
|
||||
if (WisInt > 100) {
|
||||
ConvertedWisInt = (((WisInt - 100) * 5 / 2) + 100);
|
||||
if (WisInt > 201)
|
||||
ConvertedWisInt -= ((WisInt - 201) * 5 / 4);
|
||||
} else
|
||||
ConvertedWisInt = WisInt;
|
||||
|
||||
if (GetLevel() < 41) {
|
||||
wisint_mana = (GetLevel() * 75 * ConvertedWisInt / 1000);
|
||||
base_mana = (GetLevel() * 15);
|
||||
} else if (GetLevel() < 81) {
|
||||
wisint_mana = ((3 * ConvertedWisInt) + ((GetLevel() - 40) * 15 * ConvertedWisInt / 100));
|
||||
base_mana = (600 + ((GetLevel() - 40) * 30));
|
||||
} else {
|
||||
wisint_mana = (9 * ConvertedWisInt);
|
||||
base_mana = (1800 + ((GetLevel() - 80) * 18));
|
||||
}
|
||||
bot_mana = (base_mana + wisint_mana);
|
||||
if (GetLevel() < 41) {
|
||||
wisint_mana = (GetLevel() * 75 * ConvertedWisInt / 1000);
|
||||
base_mana = (GetLevel() * 15);
|
||||
} else if (GetLevel() < 81) {
|
||||
wisint_mana = ((3 * ConvertedWisInt) + ((GetLevel() - 40) * 15 * ConvertedWisInt / 100));
|
||||
base_mana = (600 + ((GetLevel() - 40) * 30));
|
||||
} else {
|
||||
if (((WisInt - 199) / 2) > 0)
|
||||
MindLesserFactor = ((WisInt - 199) / 2);
|
||||
else
|
||||
MindLesserFactor = 0;
|
||||
|
||||
MindFactor = (WisInt - MindLesserFactor);
|
||||
if (WisInt > 100)
|
||||
bot_mana = (((5 * (MindFactor + 20)) / 2) * 3 * GetLevel() / 40);
|
||||
else
|
||||
bot_mana = (((5 * (MindFactor + 200)) / 2) * 3 * GetLevel() / 100);
|
||||
wisint_mana = (9 * ConvertedWisInt);
|
||||
base_mana = (1800 + ((GetLevel() - 80) * 18));
|
||||
}
|
||||
break;
|
||||
default:
|
||||
bot_mana = 0;
|
||||
break;
|
||||
|
||||
bot_mana = (base_mana + wisint_mana);
|
||||
} else {
|
||||
if (((WisInt - 199) / 2) > 0) {
|
||||
MindLesserFactor = ((WisInt - 199) / 2);
|
||||
} else {
|
||||
MindLesserFactor = 0;
|
||||
}
|
||||
|
||||
MindFactor = WisInt - MindLesserFactor;
|
||||
if (WisInt > 100) {
|
||||
bot_mana = (((5 * (MindFactor + 20)) / 2) * 3 * GetLevel() / 40);
|
||||
} else {
|
||||
bot_mana = (((5 * (MindFactor + 200)) / 2) * 3 * GetLevel() / 100);
|
||||
}
|
||||
}
|
||||
} else if (IsWisdomCasterClass()) {
|
||||
WisInt = WIS;
|
||||
|
||||
if (
|
||||
GetOwner() &&
|
||||
GetOwner()->CastToClient() &&
|
||||
GetOwner()->CastToClient()->ClientVersion() >= EQ::versions::ClientVersion::SoD &&
|
||||
RuleB(Character, SoDClientUseSoDHPManaEnd)
|
||||
) {
|
||||
if (WisInt > 100) {
|
||||
ConvertedWisInt = (((WisInt - 100) * 5 / 2) + 100);
|
||||
if (WisInt > 201) {
|
||||
ConvertedWisInt -= ((WisInt - 201) * 5 / 4);
|
||||
}
|
||||
} else {
|
||||
ConvertedWisInt = WisInt;
|
||||
}
|
||||
|
||||
if (GetLevel() < 41) {
|
||||
wisint_mana = (GetLevel() * 75 * ConvertedWisInt / 1000);
|
||||
base_mana = (GetLevel() * 15);
|
||||
} else if (GetLevel() < 81) {
|
||||
wisint_mana = ((3 * ConvertedWisInt) + ((GetLevel() - 40) * 15 * ConvertedWisInt / 100));
|
||||
base_mana = (600 + ((GetLevel() - 40) * 30));
|
||||
} else {
|
||||
wisint_mana = (9 * ConvertedWisInt);
|
||||
base_mana = (1800 + ((GetLevel() - 80) * 18));
|
||||
}
|
||||
|
||||
bot_mana = (base_mana + wisint_mana);
|
||||
} else {
|
||||
if (((WisInt - 199) / 2) > 0) {
|
||||
MindLesserFactor = ((WisInt - 199) / 2);
|
||||
} else {
|
||||
MindLesserFactor = 0;
|
||||
}
|
||||
|
||||
MindFactor = (WisInt - MindLesserFactor);
|
||||
if (WisInt > 100) {
|
||||
bot_mana = (((5 * (MindFactor + 20)) / 2) * 3 * GetLevel() / 40);
|
||||
} else {
|
||||
bot_mana = (((5 * (MindFactor + 200)) / 2) * 3 * GetLevel() / 100);
|
||||
}
|
||||
}
|
||||
} else {
|
||||
bot_mana = 0;
|
||||
}
|
||||
|
||||
max_mana = bot_mana;
|
||||
return bot_mana;
|
||||
}
|
||||
@@ -6219,11 +6235,10 @@ int64 Bot::CalcMaxHP() {
|
||||
uint32 nd = 10000;
|
||||
bot_hp += (GenerateBaseHitPoints() + itembonuses.HP);
|
||||
bot_hp += itembonuses.heroic_max_hp;
|
||||
nd += aabonuses.MaxHP;
|
||||
nd += aabonuses.MaxHP + spellbonuses.MaxHPChange + itembonuses.MaxHPChange;
|
||||
bot_hp = ((float)bot_hp * (float)nd / (float)10000);
|
||||
bot_hp += (spellbonuses.HP + aabonuses.HP);
|
||||
bot_hp += GroupLeadershipAAHealthEnhancement();
|
||||
bot_hp += (bot_hp * ((spellbonuses.MaxHPChange + itembonuses.MaxHPChange) / 10000.0f));
|
||||
max_hp = bot_hp;
|
||||
if (current_hp > max_hp)
|
||||
current_hp = max_hp;
|
||||
@@ -6585,14 +6600,14 @@ void Bot::ProcessBotGroupInvite(Client* c, std::string const& botName) {
|
||||
entity_list.AddGroup(g);
|
||||
database.SetGroupLeaderName(g->GetID(), c->GetName());
|
||||
g->SaveGroupLeaderAA();
|
||||
database.SetGroupID(c->GetName(), g->GetID(), c->CharacterID());
|
||||
database.SetGroupID(invitedBot->GetCleanName(), g->GetID(), invitedBot->GetBotID());
|
||||
g->AddToGroup(c);
|
||||
g->AddToGroup(invitedBot);
|
||||
} else {
|
||||
delete g;
|
||||
}
|
||||
} else {
|
||||
if (AddBotToGroup(invitedBot, c->GetGroup())) {
|
||||
database.SetGroupID(invitedBot->GetCleanName(), c->GetGroup()->GetID(), invitedBot->GetBotID());
|
||||
c->GetGroup()->AddToGroup(invitedBot);
|
||||
}
|
||||
}
|
||||
} else if (invitedBot->HasGroup()) {
|
||||
@@ -6743,7 +6758,7 @@ void Bot::CalcBotStats(bool showtext) {
|
||||
SetLevel(GetBotOwner()->GetLevel());
|
||||
|
||||
for (int sindex = 0; sindex <= EQ::skills::HIGHEST_SKILL; ++sindex) {
|
||||
skills[sindex] = content_db.GetSkillCap(GetClass(), (EQ::skills::SkillType)sindex, GetLevel());
|
||||
skills[sindex] = skill_caps.GetSkillCap(GetClass(), (EQ::skills::SkillType)sindex, GetLevel()).cap;
|
||||
}
|
||||
|
||||
taunt_timer.Start(1000);
|
||||
|
||||
+3
-31
@@ -184,35 +184,11 @@ bool BotDatabase::QueryNameAvailablity(const std::string& bot_name, bool& availa
|
||||
if (
|
||||
bot_name.empty() ||
|
||||
bot_name.size() > 60 ||
|
||||
!database.CheckUsedName(bot_name)
|
||||
database.IsNameUsed(bot_name)
|
||||
) {
|
||||
return false;
|
||||
}
|
||||
|
||||
const auto& bot_data = BotDataRepository::GetWhere(
|
||||
database,
|
||||
fmt::format(
|
||||
"`name` LIKE '{}' LIMIT 1",
|
||||
bot_name
|
||||
)
|
||||
);
|
||||
|
||||
if (!bot_data.empty()) {
|
||||
return false;
|
||||
}
|
||||
|
||||
const auto& character_data = CharacterDataRepository::GetWhere(
|
||||
database,
|
||||
fmt::format(
|
||||
"`name` LIKE '{}' LIMIT 1",
|
||||
bot_name
|
||||
)
|
||||
);
|
||||
|
||||
if (!character_data.empty()) {
|
||||
return false;
|
||||
}
|
||||
|
||||
available_flag = true;
|
||||
|
||||
return true;
|
||||
@@ -1922,18 +1898,14 @@ bool BotDatabase::LoadGroupedBotsByGroupID(const uint32 owner_id, const uint32 g
|
||||
const auto& l = GroupIdRepository::GetWhere(
|
||||
database,
|
||||
fmt::format(
|
||||
"`groupid` = {} AND `name` IN (SELECT `name` FROM `bot_data` WHERE `owner_id` = {})",
|
||||
"`group_id` = {} AND `bot_id` != 0 AND `name` IN (SELECT `name` FROM `bot_data` WHERE `owner_id` = {})",
|
||||
group_id,
|
||||
owner_id
|
||||
)
|
||||
);
|
||||
|
||||
if (l.empty()) {
|
||||
return true;
|
||||
}
|
||||
|
||||
for (const auto& e : l) {
|
||||
group_list.push_back(e.charid);
|
||||
group_list.emplace_back(e.bot_id);
|
||||
}
|
||||
|
||||
return true;
|
||||
|
||||
+1
-1
@@ -98,7 +98,7 @@ void Raid::HandleBotGroupDisband(uint32 owner, uint32 gid)
|
||||
auto r_group_members = GetRaidGroupMembers(GetGroup(b->GetName()));
|
||||
auto g = new Group(b);
|
||||
entity_list.AddGroup(g);
|
||||
database.SetGroupID(b->GetCleanName(), g->GetID(), b->GetBotID());
|
||||
g->AddToGroup(b);
|
||||
database.SetGroupLeaderName(g->GetID(), b->GetName());
|
||||
|
||||
for (auto m: r_group_members) {
|
||||
|
||||
@@ -591,7 +591,7 @@ bool Bot::BotCastCombatBuff(Mob* tar, uint8 botLevel, uint8 botClass) {
|
||||
//Only check archetype if spell is not a group spell
|
||||
//Hybrids get all buffs
|
||||
switch (tar->GetArchetype()) {
|
||||
case ARCHETYPE_CASTER:
|
||||
case Archetype::Caster:
|
||||
//TODO: probably more caster specific spell effects in here
|
||||
if (
|
||||
(
|
||||
@@ -606,7 +606,7 @@ bool Bot::BotCastCombatBuff(Mob* tar, uint8 botLevel, uint8 botClass) {
|
||||
continue;
|
||||
}
|
||||
break;
|
||||
case ARCHETYPE_MELEE:
|
||||
case Archetype::Melee:
|
||||
if (
|
||||
(
|
||||
IsEffectInSpell(s.SpellId, SE_IncreaseSpellHaste) ||
|
||||
@@ -899,7 +899,7 @@ bool Bot::BotCastBuff(Mob* tar, uint8 botLevel, uint8 botClass) {
|
||||
|
||||
switch (tar->GetArchetype())
|
||||
{
|
||||
case ARCHETYPE_CASTER:
|
||||
case Archetype::Caster:
|
||||
//TODO: probably more caster specific spell effects in here
|
||||
if (IsEffectInSpell(s.SpellId, SE_AttackSpeed) || IsEffectInSpell(s.SpellId, SE_ATK) ||
|
||||
IsEffectInSpell(s.SpellId, SE_STR) || IsEffectInSpell(s.SpellId, SE_ReverseDS))
|
||||
@@ -907,7 +907,7 @@ bool Bot::BotCastBuff(Mob* tar, uint8 botLevel, uint8 botClass) {
|
||||
continue;
|
||||
}
|
||||
break;
|
||||
case ARCHETYPE_MELEE:
|
||||
case Archetype::Melee:
|
||||
if (IsEffectInSpell(s.SpellId, SE_IncreaseSpellHaste) || IsEffectInSpell(s.SpellId, SE_ManaPool) ||
|
||||
IsEffectInSpell(s.SpellId, SE_CastingLevel) || IsEffectInSpell(s.SpellId, SE_ManaRegen_v2) ||
|
||||
IsEffectInSpell(s.SpellId, SE_CurrentMana))
|
||||
|
||||
+65
-27
@@ -57,6 +57,7 @@ extern volatile bool RunLoops;
|
||||
#include "queryserv.h"
|
||||
#include "mob_movement_manager.h"
|
||||
#include "cheat_manager.h"
|
||||
#include "lua_parser.h"
|
||||
|
||||
#include "../common/repositories/character_alternate_abilities_repository.h"
|
||||
#include "../common/repositories/account_flags_repository.h"
|
||||
@@ -73,6 +74,7 @@ extern volatile bool RunLoops;
|
||||
#include "../common/events/player_event_logs.h"
|
||||
#include "dialogue_window.h"
|
||||
#include "../common/zone_store.h"
|
||||
#include "../common/skill_caps.h"
|
||||
|
||||
|
||||
extern QueryServ* QServ;
|
||||
@@ -2226,8 +2228,8 @@ void Client::ChangeLastName(std::string last_name) {
|
||||
bool Client::ChangeFirstName(const char* in_firstname, const char* gmname)
|
||||
{
|
||||
// check duplicate name
|
||||
bool usedname = database.CheckUsedName((const char*) in_firstname);
|
||||
if (!usedname) {
|
||||
bool used_name = database.IsNameUsed((const char*) in_firstname);
|
||||
if (used_name) {
|
||||
return false;
|
||||
}
|
||||
|
||||
@@ -2756,31 +2758,48 @@ void Client::CheckLanguageSkillIncrease(uint8 language_id, uint8 teacher_skill)
|
||||
}
|
||||
}
|
||||
|
||||
bool Client::HasSkill(EQ::skills::SkillType skill_id) const {
|
||||
return((GetSkill(skill_id) > 0) && CanHaveSkill(skill_id));
|
||||
}
|
||||
|
||||
bool Client::CanHaveSkill(EQ::skills::SkillType skill_id) const {
|
||||
if (ClientVersion() < EQ::versions::ClientVersion::RoF2 && class_ == Class::Berserker && skill_id == EQ::skills::Skill1HPiercing)
|
||||
skill_id = EQ::skills::Skill2HPiercing;
|
||||
|
||||
return(content_db.GetSkillCap(GetClass(), skill_id, RuleI(Character, MaxLevel)) > 0);
|
||||
//if you don't have it by max level, then odds are you never will?
|
||||
}
|
||||
|
||||
uint16 Client::MaxSkill(EQ::skills::SkillType skillid, uint16 class_, uint16 level) const {
|
||||
if (ClientVersion() < EQ::versions::ClientVersion::RoF2 && class_ == Class::Berserker && skillid == EQ::skills::Skill1HPiercing)
|
||||
skillid = EQ::skills::Skill2HPiercing;
|
||||
|
||||
return(content_db.GetSkillCap(class_, skillid, level));
|
||||
}
|
||||
|
||||
uint8 Client::SkillTrainLevel(EQ::skills::SkillType skillid, uint16 class_)
|
||||
bool Client::HasSkill(EQ::skills::SkillType skill_id) const
|
||||
{
|
||||
if (ClientVersion() < EQ::versions::ClientVersion::RoF2 && class_ == Class::Berserker && skillid == EQ::skills::Skill1HPiercing)
|
||||
skillid = EQ::skills::Skill2HPiercing;
|
||||
return GetSkill(skill_id) > 0 && CanHaveSkill(skill_id);
|
||||
}
|
||||
|
||||
return(content_db.GetTrainLevel(class_, skillid, RuleI(Character, MaxLevel)));
|
||||
bool Client::CanHaveSkill(EQ::skills::SkillType skill_id) const
|
||||
{
|
||||
if (
|
||||
ClientVersion() < EQ::versions::ClientVersion::RoF2 &&
|
||||
class_ == Class::Berserker &&
|
||||
skill_id == EQ::skills::Skill1HPiercing
|
||||
) {
|
||||
skill_id = EQ::skills::Skill2HPiercing;
|
||||
}
|
||||
|
||||
return skill_caps.GetSkillCap(GetClass(), skill_id, RuleI(Character, MaxLevel)).cap > 0;
|
||||
}
|
||||
|
||||
uint16 Client::MaxSkill(EQ::skills::SkillType skill_id, uint8 class_id, uint8 level) const
|
||||
{
|
||||
if (
|
||||
ClientVersion() < EQ::versions::ClientVersion::RoF2 &&
|
||||
class_id == Class::Berserker &&
|
||||
skill_id == EQ::skills::Skill1HPiercing
|
||||
) {
|
||||
skill_id = EQ::skills::Skill2HPiercing;
|
||||
}
|
||||
|
||||
return skill_caps.GetSkillCap(class_id, skill_id, level).cap;
|
||||
}
|
||||
|
||||
uint8 Client::SkillTrainLevel(EQ::skills::SkillType skill_id, uint8 class_id)
|
||||
{
|
||||
if (
|
||||
ClientVersion() < EQ::versions::ClientVersion::RoF2 &&
|
||||
class_id == Class::Berserker &&
|
||||
skill_id == EQ::skills::Skill1HPiercing
|
||||
) {
|
||||
skill_id = EQ::skills::Skill2HPiercing;
|
||||
}
|
||||
|
||||
return skill_caps.GetTrainLevel(class_id, skill_id, RuleI(Character, MaxLevel));
|
||||
}
|
||||
|
||||
uint16 Client::GetMaxSkillAfterSpecializationRules(EQ::skills::SkillType skillid, uint16 maxSkill)
|
||||
@@ -4442,7 +4461,7 @@ bool Client::GroupFollow(Client* inviter) {
|
||||
}
|
||||
|
||||
//now we have a group id, can set inviter's id
|
||||
database.SetGroupID(inviter->GetName(), group->GetID(), inviter->CharacterID(), false);
|
||||
group->AddToGroup(inviter);
|
||||
database.SetGroupLeaderName(group->GetID(), inviter->GetName());
|
||||
group->UpdateGroupAAs();
|
||||
|
||||
@@ -9226,6 +9245,7 @@ void Client::ShowDevToolsMenu()
|
||||
menu_reload_six += " | " + Saylink::Silent("#reload quest", "Quests");
|
||||
|
||||
menu_reload_seven += Saylink::Silent("#reload rules", "Rules");
|
||||
menu_reload_seven += " | " + Saylink::Silent("#reload skill_caps", "Skill Caps");
|
||||
menu_reload_seven += " | " + Saylink::Silent("#reload static", "Static Zone Data");
|
||||
menu_reload_seven += " | " + Saylink::Silent("#reload tasks", "Tasks");
|
||||
|
||||
@@ -11353,6 +11373,16 @@ void Client::SendReloadCommandMessages() {
|
||||
).c_str()
|
||||
);
|
||||
|
||||
auto skill_caps_link = Saylink::Silent("#reload skill_caps");
|
||||
|
||||
Message(
|
||||
Chat::White,
|
||||
fmt::format(
|
||||
"Usage: {} - Reloads Skill Caps globally",
|
||||
skill_caps_link
|
||||
).c_str()
|
||||
);
|
||||
|
||||
auto static_link = Saylink::Silent("#reload static");
|
||||
|
||||
Message(
|
||||
@@ -11618,6 +11648,14 @@ void Client::RegisterBug(BugReport_Struct* r) {
|
||||
b.bug_report = r->bug_report;
|
||||
b.system_info = r->system_info;
|
||||
|
||||
#ifdef LUA_EQEMU
|
||||
bool ignore_default = false;
|
||||
LuaParser::Instance()->RegisterBug(this, b, ignore_default);
|
||||
if (ignore_default) {
|
||||
return;
|
||||
}
|
||||
#endif
|
||||
|
||||
auto n = BugReportsRepository::InsertOne(database, b);
|
||||
if (!n.id) {
|
||||
Message(Chat::White, "Failed to created your bug report."); // Client sends success message
|
||||
@@ -11767,7 +11805,7 @@ void Client::MaxSkills()
|
||||
auto current_skill_value = (
|
||||
EQ::skills::IsSpecializedSkill(s.first) ?
|
||||
MAX_SPECIALIZED_SKILL :
|
||||
content_db.GetSkillCap(GetClass(), s.first, GetLevel())
|
||||
skill_caps.GetSkillCap(GetClass(), s.first, GetLevel()).cap
|
||||
);
|
||||
|
||||
if (GetSkill(s.first) < current_skill_value) {
|
||||
|
||||
+3
-3
@@ -815,9 +815,9 @@ public:
|
||||
void SetHoTT(uint32 mobid);
|
||||
void ShowSkillsWindow();
|
||||
|
||||
uint16 MaxSkill(EQ::skills::SkillType skillid, uint16 class_, uint16 level) const;
|
||||
inline uint16 MaxSkill(EQ::skills::SkillType skillid) const { return MaxSkill(skillid, GetClass(), GetLevel()); }
|
||||
uint8 SkillTrainLevel(EQ::skills::SkillType skillid, uint16 class_);
|
||||
uint16 MaxSkill(EQ::skills::SkillType skill_id, uint8 class_id, uint8 level) const;
|
||||
inline uint16 MaxSkill(EQ::skills::SkillType skill_id) const { return MaxSkill(skill_id, GetClass(), GetLevel()); }
|
||||
uint8 SkillTrainLevel(EQ::skills::SkillType skill_id, uint8 class_id);
|
||||
void MaxSkills();
|
||||
|
||||
void SendTradeskillSearchResults(const std::string &query, unsigned long objtype, unsigned long someid);
|
||||
|
||||
+86
-93
@@ -322,11 +322,12 @@ int64 Client::CalcMaxHP()
|
||||
//but the actual effect sent on live causes the client
|
||||
//to apply it to (basehp + itemhp).. I will oblige to the client's whims over
|
||||
//the aa description
|
||||
nd += aabonuses.MaxHP; //Natural Durability, Physical Enhancement, Planar Durability
|
||||
|
||||
nd += aabonuses.MaxHP + spellbonuses.MaxHPChange + itembonuses.MaxHPChange; //Natural Durability, Physical Enhancement, Planar Durability (MaxHP and MaxHPChange are SPA214)
|
||||
max_hp = (float)max_hp * (float)nd / (float)10000; //this is to fix the HP-above-495k issue
|
||||
max_hp += spellbonuses.HP + aabonuses.HP;
|
||||
|
||||
max_hp += GroupLeadershipAAHealthEnhancement();
|
||||
max_hp += max_hp * ((spellbonuses.MaxHPChange + itembonuses.MaxHPChange) / 10000.0f);
|
||||
if (current_hp > max_hp) {
|
||||
current_hp = max_hp;
|
||||
}
|
||||
@@ -523,28 +524,26 @@ int32 Client::GetRawItemAC()
|
||||
|
||||
int64 Client::CalcMaxMana()
|
||||
{
|
||||
switch (GetCasterClass()) {
|
||||
case 'I':
|
||||
case 'W': {
|
||||
max_mana = (CalcBaseMana() + itembonuses.Mana + spellbonuses.Mana + aabonuses.Mana + GroupLeadershipAAManaEnhancement());
|
||||
break;
|
||||
}
|
||||
case 'N': {
|
||||
max_mana = 0;
|
||||
break;
|
||||
}
|
||||
default: {
|
||||
LogSpells("Invalid Class [{}] in CalcMaxMana", GetCasterClass());
|
||||
max_mana = 0;
|
||||
break;
|
||||
}
|
||||
if (IsIntelligenceCasterClass() || IsWisdomCasterClass()) {
|
||||
max_mana = (
|
||||
CalcBaseMana() +
|
||||
itembonuses.Mana +
|
||||
spellbonuses.Mana +
|
||||
aabonuses.Mana +
|
||||
GroupLeadershipAAManaEnhancement()
|
||||
);
|
||||
} else {
|
||||
max_mana = 0;
|
||||
}
|
||||
|
||||
if (max_mana < 0) {
|
||||
max_mana = 0;
|
||||
}
|
||||
|
||||
if (current_mana > max_mana) {
|
||||
current_mana = max_mana;
|
||||
}
|
||||
|
||||
int mana_perc_cap = spellbonuses.ManaPercCap[SBIndex::RESOURCE_PERCENT_CAP];
|
||||
if (mana_perc_cap) {
|
||||
int curMana_cap = (max_mana * mana_perc_cap) / 100;
|
||||
@@ -552,96 +551,90 @@ int64 Client::CalcMaxMana()
|
||||
current_mana = curMana_cap;
|
||||
}
|
||||
}
|
||||
|
||||
LogSpells("for [{}] returning [{}]", GetName(), max_mana);
|
||||
return max_mana;
|
||||
}
|
||||
|
||||
int64 Client::CalcBaseMana()
|
||||
{
|
||||
int ConvertedWisInt = 0;
|
||||
int MindLesserFactor, MindFactor;
|
||||
int WisInt = 0;
|
||||
int64 base_mana = 0;
|
||||
int wisint_mana = 0;
|
||||
int64 max_m = 0;
|
||||
switch (GetCasterClass()) {
|
||||
case 'I':
|
||||
WisInt = GetINT();
|
||||
if (ClientVersion() >= EQ::versions::ClientVersion::SoF && RuleB(Character, SoDClientUseSoDHPManaEnd)) {
|
||||
ConvertedWisInt = WisInt;
|
||||
int over200 = WisInt;
|
||||
if (WisInt > 100) {
|
||||
if (WisInt > 200) {
|
||||
over200 = (WisInt - 200) / -2 + WisInt;
|
||||
}
|
||||
ConvertedWisInt = (3 * over200 - 300) / 2 + over200;
|
||||
}
|
||||
auto base_data = zone->GetBaseData(GetLevel(), GetClass());
|
||||
if (base_data.level == GetLevel()) {
|
||||
max_m = base_data.mana + (ConvertedWisInt * base_data.mana_fac) + itembonuses.heroic_max_mana;
|
||||
int ConvertedWisInt = 0;
|
||||
int MindLesserFactor, MindFactor;
|
||||
int WisInt = 0;
|
||||
int64 base_mana = 0;
|
||||
int wisint_mana = 0;
|
||||
int64 max_m = 0;
|
||||
|
||||
if (IsIntelligenceCasterClass()) {
|
||||
WisInt = GetINT();
|
||||
|
||||
if (ClientVersion() >= EQ::versions::ClientVersion::SoF && RuleB(Character, SoDClientUseSoDHPManaEnd)) {
|
||||
ConvertedWisInt = WisInt;
|
||||
|
||||
int over200 = WisInt;
|
||||
if (WisInt > 100) {
|
||||
if (WisInt > 200) {
|
||||
over200 = (WisInt - 200) / -2 + WisInt;
|
||||
}
|
||||
ConvertedWisInt = (3 * over200 - 300) / 2 + over200;
|
||||
}
|
||||
else {
|
||||
if ((( WisInt - 199 ) / 2) > 0) {
|
||||
MindLesserFactor = ( WisInt - 199 ) / 2;
|
||||
}
|
||||
else {
|
||||
MindLesserFactor = 0;
|
||||
}
|
||||
MindFactor = WisInt - MindLesserFactor;
|
||||
if (WisInt > 100) {
|
||||
max_m = (((5 * (MindFactor + 20)) / 2) * 3 * GetLevel() / 40);
|
||||
}
|
||||
else {
|
||||
max_m = (((5 * (MindFactor + 200)) / 2) * 3 * GetLevel() / 100);
|
||||
}
|
||||
|
||||
auto base_data = zone->GetBaseData(GetLevel(), GetClass());
|
||||
if (base_data.level == GetLevel()) {
|
||||
max_m = base_data.mana + (ConvertedWisInt * base_data.mana_fac) + itembonuses.heroic_max_mana;
|
||||
}
|
||||
break;
|
||||
case 'W':
|
||||
WisInt = GetWIS();
|
||||
if (ClientVersion() >= EQ::versions::ClientVersion::SoF && RuleB(Character, SoDClientUseSoDHPManaEnd)) {
|
||||
ConvertedWisInt = WisInt;
|
||||
int over200 = WisInt;
|
||||
if (WisInt > 100) {
|
||||
if (WisInt > 200) {
|
||||
over200 = (WisInt - 200) / -2 + WisInt;
|
||||
}
|
||||
ConvertedWisInt = (3 * over200 - 300) / 2 + over200;
|
||||
}
|
||||
auto base_data = zone->GetBaseData(GetLevel(), GetClass());
|
||||
if (base_data.level == GetLevel()) {
|
||||
max_m = base_data.mana + (ConvertedWisInt * base_data.mana_fac) + itembonuses.heroic_max_mana;
|
||||
}
|
||||
} else {
|
||||
if (((WisInt - 199) / 2) > 0) {
|
||||
MindLesserFactor = (WisInt - 199) / 2;
|
||||
} else {
|
||||
MindLesserFactor = 0;
|
||||
}
|
||||
else {
|
||||
if ((( WisInt - 199 ) / 2) > 0) {
|
||||
MindLesserFactor = ( WisInt - 199 ) / 2;
|
||||
}
|
||||
else {
|
||||
MindLesserFactor = 0;
|
||||
}
|
||||
MindFactor = WisInt - MindLesserFactor;
|
||||
if (WisInt > 100) {
|
||||
max_m = (((5 * (MindFactor + 20)) / 2) * 3 * GetLevel() / 40);
|
||||
}
|
||||
else {
|
||||
max_m = (((5 * (MindFactor + 200)) / 2) * 3 * GetLevel() / 100);
|
||||
}
|
||||
|
||||
MindFactor = WisInt - MindLesserFactor;
|
||||
|
||||
if (WisInt > 100) {
|
||||
max_m = (((5 * (MindFactor + 20)) / 2) * 3 * GetLevel() / 40);
|
||||
} else {
|
||||
max_m = (((5 * (MindFactor + 200)) / 2) * 3 * GetLevel() / 100);
|
||||
}
|
||||
break;
|
||||
case 'N': {
|
||||
max_m = 0;
|
||||
break;
|
||||
}
|
||||
} else if (IsWisdomCasterClass()) {
|
||||
WisInt = GetWIS();
|
||||
|
||||
if (ClientVersion() >= EQ::versions::ClientVersion::SoF && RuleB(Character, SoDClientUseSoDHPManaEnd)) {
|
||||
ConvertedWisInt = WisInt;
|
||||
|
||||
int over200 = WisInt;
|
||||
if (WisInt > 100) {
|
||||
if (WisInt > 200) {
|
||||
over200 = (WisInt - 200) / -2 + WisInt;
|
||||
}
|
||||
ConvertedWisInt = (3 * over200 - 300) / 2 + over200;
|
||||
}
|
||||
default: {
|
||||
LogDebug("Invalid Class [{}] in CalcMaxMana", GetCasterClass());
|
||||
max_m = 0;
|
||||
break;
|
||||
|
||||
auto base_data = zone->GetBaseData(GetLevel(), GetClass());
|
||||
if (base_data.level == GetLevel()) {
|
||||
max_m = base_data.mana + (ConvertedWisInt * base_data.mana_fac) + itembonuses.heroic_max_mana;
|
||||
}
|
||||
} else {
|
||||
if (((WisInt - 199) / 2) > 0) {
|
||||
MindLesserFactor = (WisInt - 199) / 2;
|
||||
} else {
|
||||
MindLesserFactor = 0;
|
||||
}
|
||||
|
||||
MindFactor = WisInt - MindLesserFactor;
|
||||
|
||||
if (WisInt > 100) {
|
||||
max_m = (((5 * (MindFactor + 20)) / 2) * 3 * GetLevel() / 40);
|
||||
} else {
|
||||
max_m = (((5 * (MindFactor + 200)) / 2) * 3 * GetLevel() / 100);
|
||||
}
|
||||
}
|
||||
} else {
|
||||
max_m = 0;
|
||||
}
|
||||
#if EQDEBUG >= 11
|
||||
LogDebug("Client::CalcBaseMana() called for [{}] - returning [{}]", GetName(), max_m);
|
||||
#endif
|
||||
|
||||
return max_m;
|
||||
}
|
||||
|
||||
|
||||
+18
-6
@@ -1530,8 +1530,9 @@ void Client::Handle_Connect_OP_ZoneEntry(const EQApplicationPacket *app)
|
||||
}
|
||||
} //else, somebody from our group is already here...
|
||||
|
||||
if (!group)
|
||||
database.SetGroupID(GetName(), 0, CharacterID(), false); //cannot re-establish group, kill it
|
||||
if (!group) { //cannot re-establish group, kill it
|
||||
Group::RemoveFromGroup(this);
|
||||
}
|
||||
|
||||
}
|
||||
else { //no group id
|
||||
@@ -5596,9 +5597,20 @@ void Client::Handle_OP_CrystalCreate(const EQApplicationPacket *app)
|
||||
}
|
||||
|
||||
// Prevent the client from creating more than they have.
|
||||
const uint32 amount = EQ::ClampUpper(quantity, current_quantity);
|
||||
uint32 amount = EQ::ClampUpper(quantity, current_quantity);
|
||||
const uint32 item_id = is_radiant ? RuleI(Zone, RadiantCrystalItemID) : RuleI(Zone, EbonCrystalItemID);
|
||||
|
||||
const auto item = database.GetItem(item_id);
|
||||
// Prevent pulling more than max stack size or 1,000 (if stackable), whichever is lesser
|
||||
const uint32 max_reclaim_amount = EQ::Clamp(
|
||||
item && item->Stackable ? item->StackSize : ItemStackSizeConstraint::Minimum,
|
||||
ItemStackSizeConstraint::Minimum,
|
||||
ItemStackSizeConstraint::Maximum
|
||||
);
|
||||
if (amount > max_reclaim_amount) {
|
||||
amount = max_reclaim_amount;
|
||||
}
|
||||
|
||||
const bool success = SummonItem(item_id, amount);
|
||||
if (!success) {
|
||||
return;
|
||||
@@ -6863,7 +6875,7 @@ void Client::Handle_OP_GMNameChange(const EQApplicationPacket *app)
|
||||
Client *c = entity_list.GetClientByName(gmn->oldname);
|
||||
LogInfo("GM([{}]) changeing players name. Old:[{}] New:[{}]", GetName(), gmn->oldname, gmn->newname);
|
||||
|
||||
const bool used_name = database.CheckUsedName(gmn->newname);
|
||||
const bool used_name = database.IsNameUsed(gmn->newname);
|
||||
if (!c) {
|
||||
Message(Chat::Red, fmt::format("{} not found for name change. Operation failed!", gmn->oldname).c_str());
|
||||
return;
|
||||
@@ -6874,7 +6886,7 @@ void Client::Handle_OP_GMNameChange(const EQApplicationPacket *app)
|
||||
return;
|
||||
}
|
||||
|
||||
if (!used_name) {
|
||||
if (used_name) {
|
||||
Message(Chat::Red, fmt::format("{} is already in use. Operation failed!", gmn->newname).c_str());
|
||||
return;
|
||||
}
|
||||
@@ -7178,7 +7190,7 @@ void Client::Handle_OP_GroupCancelInvite(const EQApplicationPacket *app)
|
||||
|
||||
if (!GetMerc())
|
||||
{
|
||||
database.SetGroupID(GetName(), 0, CharacterID(), false);
|
||||
Group::RemoveFromGroup(this);
|
||||
}
|
||||
return;
|
||||
}
|
||||
|
||||
+12
-6
@@ -19,9 +19,11 @@
|
||||
#define HEAD_POSITION 0.9f //ratio of GetSize() where NPCs see from
|
||||
#define SEE_POSITION 0.5f //ratio of GetSize() where NPCs try to see for LOS
|
||||
|
||||
#define ARCHETYPE_HYBRID 1
|
||||
#define ARCHETYPE_CASTER 2
|
||||
#define ARCHETYPE_MELEE 3
|
||||
namespace Archetype {
|
||||
constexpr uint8 Hybrid = 1;
|
||||
constexpr uint8 Caster = 2;
|
||||
constexpr uint8 Melee = 3;
|
||||
};
|
||||
|
||||
#define CON_GREEN 2
|
||||
#define CON_LIGHTBLUE 18
|
||||
@@ -285,7 +287,7 @@ struct StatBonuses {
|
||||
int32 AC;
|
||||
int64 HP;
|
||||
int64 HPRegen;
|
||||
int64 MaxHP;
|
||||
int64 MaxHP; //same bonus as MaxHPChange when applied to spells and item bonuses
|
||||
int64 ManaRegen;
|
||||
int64 EnduranceRegen;
|
||||
int64 Mana;
|
||||
@@ -411,7 +413,7 @@ struct StatBonuses {
|
||||
int32 MeleeLifetap; //i
|
||||
int32 Vampirism; //i
|
||||
int32 HealRate; // Spell effect that influences effectiveness of heals
|
||||
int32 MaxHPChange; // Spell Effect
|
||||
int32 MaxHPChange; // percent change in hit points (aabonuses use variable MaxHP)
|
||||
int16 SkillDmgTaken[EQ::skills::HIGHEST_SKILL + 2]; // All Skills + -1
|
||||
int32 HealAmt; // Item Effect
|
||||
int32 SpellDmg; // Item Effect
|
||||
@@ -443,7 +445,8 @@ struct StatBonuses {
|
||||
int32 SongRange; // increases range of beneficial bard songs
|
||||
uint32 HPToManaConvert; // Uses HP to cast spells at specific conversion
|
||||
int32 FocusEffects[HIGHEST_FOCUS+1]; // Stores the focus effectid for each focustype you have.
|
||||
int16 FocusEffectsWorn[HIGHEST_FOCUS+1]; // Optional to allow focus effects to be applied additively from worn slot
|
||||
int16 FocusEffectsWorn[HIGHEST_FOCUS+1]; // Optional to allow focus effects to be applied additively from worn slot, limits do not apply
|
||||
int32 FocusEffectsWornWithLimits[HIGHEST_FOCUS + 1];// Optional to allow focus effects to be applied additively from worn slot, limits apply
|
||||
bool NegateEffects; // Check if you contain a buff with negate effect. (only spellbonuses)
|
||||
int32 SkillDamageAmount2[EQ::skills::HIGHEST_SKILL + 2]; // Adds skill specific damage
|
||||
uint32 NegateAttacks[3]; // 0 = bool HasEffect 1 = Buff Slot 2 = Max damage absorbed per hit
|
||||
@@ -509,6 +512,7 @@ struct StatBonuses {
|
||||
uint8 invisibility; // invisibility level
|
||||
uint8 invisibility_verse_undead; // IVU level
|
||||
uint8 invisibility_verse_animal; // IVA level
|
||||
int32 ShieldTargetSpa[2]; // [0] base = % mitigation amount, [1] buff slot
|
||||
|
||||
// AAs
|
||||
int32 TrapCircumvention; // reduce chance to trigger a trap.
|
||||
@@ -654,6 +658,8 @@ namespace SBIndex {
|
||||
constexpr uint16 COMBAT_PROC_SPELL_ID = 1; // SPA
|
||||
constexpr uint16 COMBAT_PROC_RATE_MOD = 2; // SPA
|
||||
constexpr uint16 COMBAT_PROC_REUSE_TIMER = 3; // SPA
|
||||
constexpr uint16 SHIELD_TARGET_MITIGATION_PERCENT = 0; // SPA 463
|
||||
constexpr uint16 SHIELD_TARGET_BUFFSLOT = 1; // SPA 463
|
||||
};
|
||||
|
||||
|
||||
|
||||
@@ -202,6 +202,7 @@ const char* QuestEventSubroutines[_LargestEventID] = {
|
||||
"EVENT_ENTITY_VARIABLE_SET",
|
||||
"EVENT_ENTITY_VARIABLE_UPDATE",
|
||||
"EVENT_AA_LOSS",
|
||||
"EVENT_SPELL_BLOCKED",
|
||||
|
||||
// Add new events before these or Lua crashes
|
||||
"EVENT_SPELL_EFFECT_BOT",
|
||||
@@ -1937,6 +1938,25 @@ void PerlembParser::ExportEventVariables(
|
||||
break;
|
||||
}
|
||||
|
||||
case EVENT_SPELL_BLOCKED: {
|
||||
Seperator sep(data);
|
||||
const uint32 blocking_spell_id = Strings::ToUnsignedInt(sep.arg[0]);
|
||||
const uint32 cast_spell_id = Strings::ToUnsignedInt(sep.arg[1]);
|
||||
|
||||
ExportVar(package_name.c_str(), "blocking_spell_id", blocking_spell_id);
|
||||
ExportVar(package_name.c_str(), "cast_spell_id", cast_spell_id);
|
||||
|
||||
if (IsValidSpell(blocking_spell_id)) {
|
||||
ExportVar(package_name.c_str(), "blocking_spell", "Spell", (void*) &spells[blocking_spell_id]);
|
||||
}
|
||||
|
||||
if (IsValidSpell(cast_spell_id)) {
|
||||
ExportVar(package_name.c_str(), "cast_spell", "Spell", (void*) &spells[cast_spell_id]);
|
||||
}
|
||||
|
||||
break;
|
||||
}
|
||||
|
||||
//tradeskill events
|
||||
case EVENT_COMBINE_SUCCESS:
|
||||
case EVENT_COMBINE_FAILURE: {
|
||||
|
||||
+19
-3
@@ -1579,9 +1579,7 @@ std::string Perl__GetCharactersInInstance(uint16 instance_id)
|
||||
char_id_string = fmt::format("{} player(s) in instance: ", character_ids.size());
|
||||
auto iter = character_ids.begin();
|
||||
while (iter != character_ids.end()) {
|
||||
char char_name[64];
|
||||
database.GetCharName(*iter, char_name);
|
||||
char_id_string += char_name;
|
||||
char_id_string += database.GetCharName(*iter);
|
||||
char_id_string += "(";
|
||||
char_id_string += itoa(*iter);
|
||||
char_id_string += ")";
|
||||
@@ -5842,6 +5840,21 @@ std::string Perl__silent_saylink(std::string text, std::string link_name)
|
||||
return Saylink::Silent(text, link_name);
|
||||
}
|
||||
|
||||
uint16 Perl__get_class_bitmask(uint8 class_id)
|
||||
{
|
||||
return GetPlayerClassBit(class_id);
|
||||
}
|
||||
|
||||
uint32 Perl__get_deity_bitmask(uint16 deity_id)
|
||||
{
|
||||
return static_cast<uint32>(EQ::deity::GetDeityBitmask(static_cast<EQ::deity::DeityType>(deity_id)));
|
||||
}
|
||||
|
||||
uint16 Perl__get_race_bitmask(uint16 race_id)
|
||||
{
|
||||
return GetPlayerRaceBit(race_id);
|
||||
}
|
||||
|
||||
void perl_register_quest()
|
||||
{
|
||||
perl::interpreter perl(PERL_GET_THX);
|
||||
@@ -6488,9 +6501,11 @@ void perl_register_quest()
|
||||
package.add("getconsiderlevelname", &Perl__getconsiderlevelname);
|
||||
package.add("gethexcolorcode", &Perl__gethexcolorcode);
|
||||
package.add("getcurrencyid", &Perl__getcurrencyid);
|
||||
package.add("get_class_bitmask", &Perl__get_class_bitmask);
|
||||
package.add("get_data", &Perl__get_data);
|
||||
package.add("get_data_expires", &Perl__get_data_expires);
|
||||
package.add("get_data_remaining", &Perl__get_data_remaining);
|
||||
package.add("get_deity_bitmask", &Perl__get_deity_bitmask);
|
||||
package.add("get_dz_task_id", &Perl__get_dz_task_id);
|
||||
package.add("getexpmodifierbycharid", (double(*)(uint32, uint32))&Perl__getexpmodifierbycharid);
|
||||
package.add("getexpmodifierbycharid", (double(*)(uint32, uint32, int16))&Perl__getexpmodifierbycharid);
|
||||
@@ -6523,6 +6538,7 @@ void perl_register_quest()
|
||||
package.add("getgroupidbycharid", &Perl__getgroupidbycharid);
|
||||
package.add("getinventoryslotname", &Perl__getinventoryslotname);
|
||||
package.add("getraididbycharid", &Perl__getraididbycharid);
|
||||
package.add("get_race_bitmask", &Perl__get_race_bitmask);
|
||||
package.add("get_recipe_component_item_ids", &Perl__GetRecipeComponentItemIDs);
|
||||
package.add("get_recipe_container_item_ids", &Perl__GetRecipeContainerItemIDs);
|
||||
package.add("get_recipe_fail_item_ids", &Perl__GetRecipeFailItemIDs);
|
||||
|
||||
@@ -2675,6 +2675,10 @@ void EntityList::RemoveAllMobs()
|
||||
{
|
||||
auto it = mob_list.begin();
|
||||
while (it != mob_list.end()) {
|
||||
if (!it->second) {
|
||||
++it;
|
||||
continue;
|
||||
}
|
||||
safe_delete(it->second);
|
||||
free_ids.push(it->first);
|
||||
it = mob_list.erase(it);
|
||||
@@ -2812,6 +2816,9 @@ bool EntityList::RemoveMob(uint16 delete_id)
|
||||
|
||||
auto it = mob_list.find(delete_id);
|
||||
if (it != mob_list.end()) {
|
||||
if (!it->second) {
|
||||
return false;
|
||||
}
|
||||
if (npc_list.count(delete_id)) {
|
||||
entity_list.RemoveNPC(delete_id);
|
||||
}
|
||||
|
||||
@@ -143,6 +143,7 @@ typedef enum {
|
||||
EVENT_ENTITY_VARIABLE_SET,
|
||||
EVENT_ENTITY_VARIABLE_UPDATE,
|
||||
EVENT_AA_LOSS,
|
||||
EVENT_SPELL_BLOCKED,
|
||||
|
||||
// Add new events before these or Lua crashes
|
||||
EVENT_SPELL_EFFECT_BOT,
|
||||
|
||||
+32
-37
@@ -44,17 +44,14 @@ extern WorldServer worldserver;
|
||||
|
||||
struct NPCType;
|
||||
|
||||
//max number of items which can be in the foraging table
|
||||
//for a given zone.
|
||||
#define FORAGE_ITEM_LIMIT 50
|
||||
//max number of items which can be in the foraging
|
||||
// and fishing tables for a given zone.
|
||||
constexpr uint8 FORAGE_ITEM_LIMIT = 50;
|
||||
constexpr uint8 FISHING_ITEM_LIMIT = 50;
|
||||
|
||||
uint32 ZoneDatabase::LoadForage(uint32 zone_id, uint8 skill_level)
|
||||
{
|
||||
uint32 forage_items[FORAGE_ITEM_LIMIT];
|
||||
|
||||
for (uint16 slot_id = 0; slot_id < FORAGE_ITEM_LIMIT; slot_id++) {
|
||||
forage_items[slot_id] = 0;
|
||||
}
|
||||
uint32 forage_items[FORAGE_ITEM_LIMIT] = {};
|
||||
|
||||
const auto& l = ForageRepository::GetWhere(
|
||||
*this,
|
||||
@@ -77,7 +74,7 @@ uint32 ZoneDatabase::LoadForage(uint32 zone_id, uint8 skill_level)
|
||||
l.size() != 1 ? "s" : ""
|
||||
);
|
||||
|
||||
int forage_chances[FORAGE_ITEM_LIMIT];
|
||||
int forage_chances[FORAGE_ITEM_LIMIT] = {};
|
||||
|
||||
int current_chance = 0;
|
||||
uint32 item_id = 0;
|
||||
@@ -118,13 +115,8 @@ uint32 ZoneDatabase::LoadForage(uint32 zone_id, uint8 skill_level)
|
||||
|
||||
uint32 ZoneDatabase::LoadFishing(uint32 zone_id, uint8 skill_level, uint32 &npc_id, uint8 &npc_chance)
|
||||
{
|
||||
uint32 fishing_items[50];
|
||||
int fishing_chances[50];
|
||||
|
||||
for (uint16 slot_id = 0; slot_id < 50; slot_id++) {
|
||||
fishing_items[slot_id] = 0;
|
||||
fishing_chances[slot_id] = 0;
|
||||
}
|
||||
uint32 fishing_items[FISHING_ITEM_LIMIT] = {};
|
||||
int fishing_chances[FISHING_ITEM_LIMIT] = {};
|
||||
|
||||
const auto& l = FishingRepository::GetWhere(
|
||||
*this,
|
||||
@@ -146,15 +138,15 @@ uint32 ZoneDatabase::LoadFishing(uint32 zone_id, uint8 skill_level, uint32 &npc_
|
||||
l.size() != 1 ? "s" : ""
|
||||
);
|
||||
|
||||
uint32 npc_ids[50];
|
||||
uint32 npc_chances[50];
|
||||
uint32 npc_ids[FISHING_ITEM_LIMIT] = {};
|
||||
uint32 npc_chances[FISHING_ITEM_LIMIT] = {};
|
||||
|
||||
int current_chance = 0;
|
||||
uint32 item_id = 0;
|
||||
uint8 count = 0;
|
||||
|
||||
for (const auto &e: l) {
|
||||
if (count >= 50) {
|
||||
if (count >= FISHING_ITEM_LIMIT) {
|
||||
break;
|
||||
}
|
||||
|
||||
@@ -164,6 +156,8 @@ uint32 ZoneDatabase::LoadFishing(uint32 zone_id, uint8 skill_level, uint32 &npc_
|
||||
npc_chances[count] = e.npc_chance;
|
||||
|
||||
current_chance = fishing_chances[count];
|
||||
|
||||
count++;
|
||||
}
|
||||
|
||||
npc_id = 0;
|
||||
@@ -175,7 +169,7 @@ uint32 ZoneDatabase::LoadFishing(uint32 zone_id, uint8 skill_level, uint32 &npc_
|
||||
|
||||
const int roll = zone->random.Int(1, current_chance);
|
||||
|
||||
for (uint16 i = 0; i < count; i++) {
|
||||
for (uint8 i = 0; i < count; i++) {
|
||||
if (roll > fishing_chances[i]) {
|
||||
continue;
|
||||
}
|
||||
@@ -269,32 +263,33 @@ void Client::GoFish(bool guarantee, bool use_bait)
|
||||
fishing_timer.Disable();
|
||||
|
||||
//we're doing this a second time (1st in Client::Handle_OP_Fishing) to make sure that, between when we started fishing & now, we're still able to fish (in case we move, change equip, etc)
|
||||
if (!CanFish()) //if we can't fish here, we don't need to bother with the rest
|
||||
if (!CanFish()) { //if we can't fish here, we don't need to bother with the rest
|
||||
return;
|
||||
}
|
||||
|
||||
//multiple entries yeilds higher probability of dropping...
|
||||
uint32 common_fish_ids[MAX_COMMON_FISH_IDS] = {
|
||||
1038, // Tattered Cloth Sandals
|
||||
1038, // Tattered Cloth Sandals
|
||||
1038, // Tattered Cloth Sandals
|
||||
1038, // Tattered Cloth Sandals
|
||||
1038, // Tattered Cloth Sandals
|
||||
1038, // Tattered Cloth Sandals
|
||||
13019, // Fresh Fish
|
||||
13076, // Fish Scales
|
||||
13076, // Fish Scales
|
||||
7007, // Rusty Dagger
|
||||
7007, // Rusty Dagger
|
||||
7007 // Rusty Dagger
|
||||
|
||||
7007, // Rusty Dagger
|
||||
7007, // Rusty Dagger
|
||||
7007 // Rusty Dagger
|
||||
};
|
||||
|
||||
//success formula is not researched at all
|
||||
|
||||
int fishing_skill = GetSkill(EQ::skills::SkillFishing); //will take into account skill bonuses on pole & bait
|
||||
uint16 fishing_skill = GetSkill(EQ::skills::SkillFishing); //will take into account skill bonuses on pole & bait
|
||||
|
||||
//make sure we still have a fishing pole on:
|
||||
int32 bslot = m_inv.HasItemByUse(EQ::item::ItemTypeFishingBait, 1, invWhereWorn | invWherePersonal);
|
||||
int16 bslot = m_inv.HasItemByUse(EQ::item::ItemTypeFishingBait, 1, invWhereWorn | invWherePersonal);
|
||||
const EQ::ItemInstance* Bait = nullptr;
|
||||
if (bslot != INVALID_INDEX)
|
||||
if (bslot != INVALID_INDEX) {
|
||||
Bait = m_inv.GetItem(bslot);
|
||||
}
|
||||
|
||||
//if the bait isnt equipped, need to add its skill bonus
|
||||
if (bslot >= EQ::invslot::GENERAL_BEGIN && Bait != nullptr && Bait->GetItem()->SkillModType == EQ::skills::SkillFishing) {
|
||||
@@ -309,8 +304,8 @@ void Client::GoFish(bool guarantee, bool use_bait)
|
||||
if (guarantee || zone->random.Int(0,175) < fishing_skill) {
|
||||
uint32 food_id = 0;
|
||||
|
||||
//25% chance to fish an item.
|
||||
if (zone->random.Int(0, 399) <= fishing_skill ) {
|
||||
//chance to fish a zone item.
|
||||
if (zone->random.Int(0, RuleI(Zone, FishingChance)) <= fishing_skill ) {
|
||||
uint32 npc_id = 0;
|
||||
uint8 npc_chance = 0;
|
||||
food_id = content_db.LoadFishing(m_pp.zone_id, fishing_skill, npc_id, npc_chance);
|
||||
@@ -348,7 +343,7 @@ void Client::GoFish(bool guarantee, bool use_bait)
|
||||
DeleteItemInInventory(bslot, 1, true); //do we need client update?
|
||||
}
|
||||
|
||||
if(food_id == 0) {
|
||||
if (food_id == 0) {
|
||||
int index = zone->random.Int(0, MAX_COMMON_FISH_IDS-1);
|
||||
food_id = (RuleB(Character, UseNoJunkFishing) ? 13019 : common_fish_ids[index]);
|
||||
}
|
||||
@@ -449,9 +444,9 @@ void Client::ForageItem(bool guarantee) {
|
||||
13419, // Vegetables
|
||||
13048, // Rabbit Meat
|
||||
13047, // Roots
|
||||
13044, // Pod Of Water
|
||||
14905, // mushroom
|
||||
13106 // Fishing Grubs
|
||||
13044, // Pod of Water
|
||||
14905, // Mushroom
|
||||
13106 // Fishing Grubs
|
||||
};
|
||||
|
||||
// these may need to be fine tuned, I am just guessing here
|
||||
|
||||
@@ -53,7 +53,7 @@ void command_movechar(Client *c, const Seperator *sep)
|
||||
return;
|
||||
}
|
||||
|
||||
const bool moved = database.MoveCharacterToZone(character_name.c_str(), zone_id);
|
||||
const bool moved = database.MoveCharacterToZone(character_name, zone_id);
|
||||
std::string moved_string = moved ? "Succeeded" : "Failed";
|
||||
c->Message(
|
||||
Chat::White,
|
||||
|
||||
@@ -34,6 +34,7 @@ void command_reload(Client *c, const Seperator *sep)
|
||||
bool is_perl_export = !strcasecmp(sep->arg[1], "perl_export");
|
||||
bool is_quest = !strcasecmp(sep->arg[1], "quest") || (is_rq_alias);
|
||||
bool is_rules = !strcasecmp(sep->arg[1], "rules");
|
||||
bool is_skill_caps = !strcasecmp(sep->arg[1], "skill_caps");
|
||||
bool is_static = !strcasecmp(sep->arg[1], "static");
|
||||
bool is_tasks = !strcasecmp(sep->arg[1], "tasks");
|
||||
bool is_titles = !strcasecmp(sep->arg[1], "titles");
|
||||
@@ -66,6 +67,7 @@ void command_reload(Client *c, const Seperator *sep)
|
||||
!is_perl_export &&
|
||||
!is_quest &&
|
||||
!is_rules &&
|
||||
!is_skill_caps &&
|
||||
!is_static &&
|
||||
!is_tasks &&
|
||||
!is_titles &&
|
||||
@@ -161,6 +163,9 @@ void command_reload(Client *c, const Seperator *sep)
|
||||
} else if (is_rules) {
|
||||
c->Message(Chat::White, "Attempting to reload Rules globally.");
|
||||
pack = new ServerPacket(ServerOP_ReloadRules, 0);
|
||||
} else if (is_skill_caps) {
|
||||
c->Message(Chat::White, "Attempting to reload Skill Caps globally.");
|
||||
pack = new ServerPacket(ServerOP_ReloadSkillCaps, 0);
|
||||
} else if (is_static) {
|
||||
c->Message(Chat::White, "Attempting to reload Static Zone Data globally.");
|
||||
pack = new ServerPacket(ServerOP_ReloadStaticZoneData, 0);
|
||||
|
||||
+176
-126
@@ -203,155 +203,141 @@ void Group::SplitMoney(uint32 copper, uint32 silver, uint32 gold, uint32 platinu
|
||||
}
|
||||
}
|
||||
|
||||
bool Group::AddMember(Mob* newmember, const char *NewMemberName, uint32 CharacterID, bool ismerc)
|
||||
bool Group::AddMember(Mob* new_member, std::string new_member_name, uint32 character_id, bool is_merc)
|
||||
{
|
||||
bool InZone = true;
|
||||
bool in_zone = true;
|
||||
|
||||
// This method should either be passed a Mob*, if the new member is in this zone, or a nullptr Mob*
|
||||
// and the name and CharacterID of the new member, if they are out of zone.
|
||||
if(!newmember && !NewMemberName)
|
||||
{
|
||||
// and the name and character_id of the new member, if they are out of zone.
|
||||
if (!new_member && new_member_name.empty()) {
|
||||
return false;
|
||||
}
|
||||
|
||||
if(GroupCount() >= MAX_GROUP_MEMBERS) //Sanity check for merging groups together.
|
||||
{
|
||||
if (GroupCount() >= MAX_GROUP_MEMBERS) { //Sanity check for merging groups together.
|
||||
return false;
|
||||
}
|
||||
|
||||
if(!newmember)
|
||||
{
|
||||
InZone = false;
|
||||
}
|
||||
else
|
||||
{
|
||||
NewMemberName = newmember->GetCleanName();
|
||||
if (!new_member) {
|
||||
in_zone = false;
|
||||
} else {
|
||||
new_member_name = new_member->GetCleanName();
|
||||
|
||||
if(newmember->IsClient())
|
||||
{
|
||||
CharacterID = newmember->CastToClient()->CharacterID();
|
||||
if (new_member->IsClient()) {
|
||||
character_id = new_member->CastToClient()->CharacterID();
|
||||
}
|
||||
if(newmember->IsMerc())
|
||||
{
|
||||
Client* owner = newmember->CastToMerc()->GetMercenaryOwner();
|
||||
if(owner)
|
||||
{
|
||||
CharacterID = owner->CastToClient()->CharacterID();
|
||||
|
||||
if (new_member->IsMerc()) {
|
||||
Client* o = new_member->CastToMerc()->GetMercenaryOwner();
|
||||
if (o) {
|
||||
character_id = o->CastToClient()->CharacterID();
|
||||
}
|
||||
ismerc = true;
|
||||
|
||||
is_merc = true;
|
||||
}
|
||||
}
|
||||
|
||||
// See if they are already in the group
|
||||
uint32 i = 0;
|
||||
for (i = 0; i < MAX_GROUP_MEMBERS; ++i)
|
||||
{
|
||||
if (!strcasecmp(membername[i], NewMemberName))
|
||||
{
|
||||
for (const auto& m : membername) {
|
||||
if (Strings::EqualFold(m, new_member_name)) {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
// Put them in the group
|
||||
for (i = 0; i < MAX_GROUP_MEMBERS; ++i)
|
||||
{
|
||||
if (membername[i][0] == '\0')
|
||||
{
|
||||
if(InZone)
|
||||
{
|
||||
members[i] = newmember;
|
||||
for (int slot_id = 0; slot_id < MAX_GROUP_MEMBERS; ++slot_id) {
|
||||
if (membername[slot_id][0] == '\0') {
|
||||
if (in_zone) {
|
||||
members[slot_id] = new_member;
|
||||
}
|
||||
strcpy(membername[i], NewMemberName);
|
||||
MemberRoles[i] = 0;
|
||||
|
||||
strcpy(membername[slot_id], new_member_name.c_str());
|
||||
MemberRoles[slot_id] = 0;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
// Is this even possible based on the above loops? Remove?
|
||||
if (i == MAX_GROUP_MEMBERS)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
int x=1;
|
||||
int x = 1;
|
||||
|
||||
//build the template join packet
|
||||
auto outapp = new EQApplicationPacket(OP_GroupUpdate, sizeof(GroupJoin_Struct));
|
||||
GroupJoin_Struct* gj = (GroupJoin_Struct*) outapp->pBuffer;
|
||||
strcpy(gj->membername, NewMemberName);
|
||||
gj->action = groupActJoin;
|
||||
|
||||
auto gj = (GroupJoin_Struct*) outapp->pBuffer;
|
||||
|
||||
strcpy(gj->membername, new_member_name.c_str());
|
||||
|
||||
gj->action = groupActJoin;
|
||||
gj->leader_aas = LeaderAbilities;
|
||||
|
||||
for (i = 0;i < MAX_GROUP_MEMBERS; i++)
|
||||
{
|
||||
if (members[i] != nullptr && members[i] != newmember)
|
||||
{
|
||||
for (int slot_id = 0; slot_id < MAX_GROUP_MEMBERS; slot_id++) {
|
||||
if (members[slot_id] && members[slot_id] != new_member) {
|
||||
//fill in group join & send it
|
||||
strcpy(gj->yourname, members[i]->GetCleanName());
|
||||
if(members[i]->IsClient())
|
||||
{
|
||||
members[i]->CastToClient()->QueuePacket(outapp);
|
||||
strcpy(gj->yourname, members[slot_id]->GetCleanName());
|
||||
if (members[slot_id]->IsClient()) {
|
||||
members[slot_id]->CastToClient()->QueuePacket(outapp);
|
||||
|
||||
//put new member into existing group members' list(s)
|
||||
strcpy(members[i]->CastToClient()->GetPP().groupMembers[GroupCount()-1], NewMemberName);
|
||||
strcpy(
|
||||
members[slot_id]->CastToClient()->GetPP().groupMembers[GroupCount() - 1],
|
||||
new_member_name.c_str()
|
||||
);
|
||||
}
|
||||
|
||||
//put existing group member(s) into the new member's list
|
||||
if(InZone && newmember && newmember->IsClient())
|
||||
{
|
||||
if(IsLeader(members[i]))
|
||||
{
|
||||
strcpy(newmember->CastToClient()->GetPP().groupMembers[0], members[i]->GetCleanName());
|
||||
}
|
||||
else
|
||||
{
|
||||
strcpy(newmember->CastToClient()->GetPP().groupMembers[x], members[i]->GetCleanName());
|
||||
if (in_zone && new_member && new_member->IsClient()) {
|
||||
if (IsLeader(members[slot_id])) {
|
||||
strcpy(new_member->CastToClient()->GetPP().groupMembers[0], members[slot_id]->GetCleanName());
|
||||
} else {
|
||||
strcpy(new_member->CastToClient()->GetPP().groupMembers[x], members[slot_id]->GetCleanName());
|
||||
++x;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if(InZone && newmember)
|
||||
{
|
||||
if (in_zone && new_member) {
|
||||
//put new member in his own list.
|
||||
newmember->SetGrouped(true);
|
||||
new_member->SetGrouped(true);
|
||||
|
||||
if(newmember->IsClient())
|
||||
{
|
||||
strcpy(newmember->CastToClient()->GetPP().groupMembers[x], NewMemberName);
|
||||
newmember->CastToClient()->Save();
|
||||
database.SetGroupID(NewMemberName, GetID(), newmember->CastToClient()->CharacterID(), false);
|
||||
SendMarkedNPCsToMember(newmember->CastToClient());
|
||||
if (new_member->IsClient()) {
|
||||
strcpy(new_member->CastToClient()->GetPP().groupMembers[x], new_member_name.c_str());
|
||||
|
||||
NotifyMainTank(newmember->CastToClient(), 1);
|
||||
NotifyMainAssist(newmember->CastToClient(), 1);
|
||||
NotifyPuller(newmember->CastToClient(), 1);
|
||||
new_member->CastToClient()->Save();
|
||||
|
||||
AddToGroup(new_member);
|
||||
|
||||
SendMarkedNPCsToMember(new_member->CastToClient());
|
||||
|
||||
NotifyMainTank(new_member->CastToClient(), 1);
|
||||
NotifyMainAssist(new_member->CastToClient(), 1);
|
||||
NotifyPuller(new_member->CastToClient(), 1);
|
||||
}
|
||||
|
||||
if(newmember->IsMerc())
|
||||
{
|
||||
Client* owner = newmember->CastToMerc()->GetMercenaryOwner();
|
||||
if(owner)
|
||||
{
|
||||
database.SetGroupID(NewMemberName, GetID(), owner->CharacterID(), true);
|
||||
if (new_member->IsMerc()) {
|
||||
Client* o = new_member->CastToMerc()->GetMercenaryOwner();
|
||||
if (o) {
|
||||
AddToGroup(new_member);
|
||||
}
|
||||
}
|
||||
|
||||
Group* group = newmember->CastToClient()->GetGroup();
|
||||
if (group) {
|
||||
group->SendHPManaEndPacketsTo(newmember);
|
||||
group->SendHPPacketsFrom(newmember);
|
||||
Group* g = new_member->CastToClient()->GetGroup();
|
||||
if (g) {
|
||||
g->SendHPManaEndPacketsTo(new_member);
|
||||
g->SendHPPacketsFrom(new_member);
|
||||
}
|
||||
|
||||
}
|
||||
else
|
||||
{
|
||||
database.SetGroupID(NewMemberName, GetID(), CharacterID, ismerc);
|
||||
} else {
|
||||
AddToGroup(
|
||||
AddToGroupRequest{
|
||||
.mob = nullptr,
|
||||
.member_name = new_member_name,
|
||||
.character_id = character_id,
|
||||
}
|
||||
);
|
||||
}
|
||||
|
||||
if (newmember && newmember->IsClient())
|
||||
newmember->CastToClient()->JoinGroupXTargets(this);
|
||||
if (new_member && new_member->IsClient()) {
|
||||
new_member->CastToClient()->JoinGroupXTargets(this);
|
||||
}
|
||||
|
||||
safe_delete(outapp);
|
||||
|
||||
@@ -362,20 +348,18 @@ bool Group::AddMember(Mob* newmember, const char *NewMemberName, uint32 Characte
|
||||
return true;
|
||||
}
|
||||
|
||||
void Group::AddMember(const char *NewMemberName)
|
||||
void Group::AddMember(const std::string& new_member_name)
|
||||
{
|
||||
// This method should be called when both the new member and the group leader are in a different zone to this one.
|
||||
for (uint32 i = 0; i < MAX_GROUP_MEMBERS; ++i)
|
||||
if(!strcasecmp(membername[i], NewMemberName))
|
||||
{
|
||||
for (const auto& m : membername) {
|
||||
if (Strings::EqualFold(m, new_member_name)) {
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
for (uint32 i = 0; i < MAX_GROUP_MEMBERS; ++i)
|
||||
{
|
||||
if (membername[i][0] == '\0')
|
||||
{
|
||||
strcpy(membername[i], NewMemberName);
|
||||
for (uint32 i = 0; i < MAX_GROUP_MEMBERS; ++i) {
|
||||
if (membername[i][0] == '\0') {
|
||||
strcpy(membername[i], new_member_name.c_str());
|
||||
MemberRoles[i] = 0;
|
||||
break;
|
||||
}
|
||||
@@ -752,7 +736,7 @@ bool Group::DelMember(Mob* oldmember, bool ignoresender)
|
||||
|
||||
if(oldmember->IsClient())
|
||||
{
|
||||
database.SetGroupID(oldmember->GetCleanName(), 0, oldmember->CastToClient()->CharacterID(), false);
|
||||
RemoveFromGroup(oldmember);
|
||||
}
|
||||
|
||||
if(oldmember->IsMerc())
|
||||
@@ -760,7 +744,7 @@ bool Group::DelMember(Mob* oldmember, bool ignoresender)
|
||||
Client* owner = oldmember->CastToMerc()->GetMercenaryOwner();
|
||||
if(owner)
|
||||
{
|
||||
database.SetGroupID(oldmember->GetCleanName(), 0, owner->CharacterID(), true);
|
||||
RemoveFromGroup(oldmember);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -943,7 +927,7 @@ void Group::DisbandGroup(bool joinraid) {
|
||||
}
|
||||
|
||||
strcpy(gu->yourname, members[i]->GetCleanName());
|
||||
database.SetGroupID(members[i]->GetCleanName(), 0, members[i]->CastToClient()->CharacterID(), false);
|
||||
RemoveFromGroup(members[i]);
|
||||
members[i]->CastToClient()->QueuePacket(outapp);
|
||||
SendMarkedNPCsToMember(members[i]->CastToClient(), true);
|
||||
if (!joinraid)
|
||||
@@ -955,7 +939,7 @@ void Group::DisbandGroup(bool joinraid) {
|
||||
Client* owner = members[i]->CastToMerc()->GetMercenaryOwner();
|
||||
if(owner)
|
||||
{
|
||||
database.SetGroupID(members[i]->GetCleanName(), 0, owner->CharacterID(), true);
|
||||
RemoveFromGroup(members[i]);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1148,31 +1132,30 @@ void Group::TeleportGroup(Mob* sender, uint32 zoneID, uint16 instance_id, float
|
||||
|
||||
bool Group::LearnMembers() {
|
||||
|
||||
auto rows = GroupIdRepository::GetWhere(
|
||||
const auto& l = GroupIdRepository::GetWhere(
|
||||
database,
|
||||
fmt::format(
|
||||
"groupid = {}",
|
||||
"`group_id` = {}",
|
||||
GetID()
|
||||
)
|
||||
);
|
||||
|
||||
if (rows.empty()) {
|
||||
if (l.empty()) {
|
||||
LogError(
|
||||
"Error getting group members for group [{}]",
|
||||
GetID()
|
||||
);
|
||||
}
|
||||
|
||||
for(int i = 0; i < MAX_GROUP_MEMBERS; ++i)
|
||||
{
|
||||
for (int i = 0; i < MAX_GROUP_MEMBERS; ++i) {
|
||||
members[i] = nullptr;
|
||||
memset(membername[i],0,64);
|
||||
memset(membername[i], 0, 64);
|
||||
MemberRoles[i] = 0;
|
||||
}
|
||||
|
||||
int memberIndex = 0;
|
||||
for (const auto& member : rows) {
|
||||
if (memberIndex >= MAX_GROUP_MEMBERS) {
|
||||
int member_index = 0;
|
||||
for (const auto& e : l) {
|
||||
if (member_index >= MAX_GROUP_MEMBERS) {
|
||||
LogError(
|
||||
"Too many members in group [{}]",
|
||||
GetID()
|
||||
@@ -1180,14 +1163,15 @@ bool Group::LearnMembers() {
|
||||
break;
|
||||
}
|
||||
|
||||
if (member.name.empty()) {
|
||||
members[memberIndex] = nullptr;
|
||||
membername[memberIndex][0] = '\0';
|
||||
if (e.name.empty()) {
|
||||
members[member_index] = nullptr;
|
||||
membername[member_index][0] = '\0';
|
||||
} else {
|
||||
members[memberIndex] = nullptr;
|
||||
strn0cpy(membername[memberIndex], member.name.c_str(), 64);
|
||||
members[member_index] = nullptr;
|
||||
strn0cpy(membername[member_index], e.name.c_str(), 64);
|
||||
}
|
||||
++memberIndex;
|
||||
|
||||
++member_index;
|
||||
}
|
||||
|
||||
VerifyGroup();
|
||||
@@ -1264,10 +1248,10 @@ void Client::LeaveGroup() {
|
||||
else
|
||||
{
|
||||
//force things a little
|
||||
database.SetGroupID(GetCleanName(), 0, CharacterID(), false);
|
||||
if (GetMerc())
|
||||
{
|
||||
database.SetGroupID(GetMerc()->GetCleanName(), 0, CharacterID(), true);
|
||||
Group::RemoveFromGroup(this);
|
||||
|
||||
if (GetMerc()) {
|
||||
Group::RemoveFromGroup(GetMerc());
|
||||
}
|
||||
}
|
||||
|
||||
@@ -2514,3 +2498,69 @@ bool Group::IsLeader(const char* name) {
|
||||
std::string Group::GetLeaderName() {
|
||||
return database.GetGroupLeaderName(GetID());
|
||||
}
|
||||
|
||||
void Group::RemoveFromGroup(Mob* m)
|
||||
{
|
||||
uint32 bot_id = 0;
|
||||
uint32 character_id = 0;
|
||||
uint32 merc_id = 0;
|
||||
|
||||
if (m->IsBot()) {
|
||||
bot_id = m->CastToBot()->GetBotID();
|
||||
} else if (m->IsClient()) {
|
||||
character_id = m->CastToClient()->CharacterID();
|
||||
} else if (m->IsMerc()) {
|
||||
merc_id = m->CastToMerc()->GetMercenaryID();
|
||||
}
|
||||
|
||||
GroupIdRepository::DeleteWhere(
|
||||
database,
|
||||
fmt::format(
|
||||
"`character_id` = {} AND `bot_id` = {} AND `merc_id` = {}",
|
||||
character_id,
|
||||
bot_id,
|
||||
merc_id
|
||||
)
|
||||
);
|
||||
}
|
||||
|
||||
void Group::AddToGroup(Mob* m)
|
||||
{
|
||||
AddToGroup(
|
||||
AddToGroupRequest{
|
||||
.mob = m
|
||||
}
|
||||
);
|
||||
}
|
||||
|
||||
// Handles database-side, should eventually be consolidated to handle memory-based group stuff as well
|
||||
void Group::AddToGroup(AddToGroupRequest r)
|
||||
{
|
||||
uint32 bot_id = 0;
|
||||
uint32 character_id = r.character_id;
|
||||
uint32 merc_id = 0;
|
||||
std::string name = r.member_name;
|
||||
|
||||
if (r.mob) {
|
||||
if (r.mob->IsBot()) {
|
||||
bot_id = r.mob->CastToBot()->GetBotID();
|
||||
} else if (r.mob->IsClient()) {
|
||||
character_id = r.mob->CastToClient()->CharacterID();
|
||||
} else if (r.mob->IsMerc()) {
|
||||
merc_id = r.mob->CastToMerc()->GetMercenaryID();
|
||||
}
|
||||
|
||||
name = r.mob->GetCleanName();
|
||||
}
|
||||
|
||||
GroupIdRepository::ReplaceOne(
|
||||
database,
|
||||
GroupIdRepository::GroupId{
|
||||
.group_id = GetID(),
|
||||
.name = name,
|
||||
.character_id = character_id,
|
||||
.bot_id = bot_id,
|
||||
.merc_id = merc_id
|
||||
}
|
||||
);
|
||||
}
|
||||
|
||||
+12
-2
@@ -52,8 +52,15 @@ public:
|
||||
Group(uint32 gid);
|
||||
~Group();
|
||||
|
||||
bool AddMember(Mob* newmember, const char* NewMemberName = nullptr, uint32 CharacterID = 0, bool ismerc = false);
|
||||
void AddMember(const char* NewMemberName);
|
||||
struct AddToGroupRequest {
|
||||
Mob* mob = nullptr;
|
||||
// Only used cross-zone, otherwise use Mob* mob
|
||||
std::string member_name = std::string();
|
||||
uint32 character_id = 0;
|
||||
};
|
||||
|
||||
bool AddMember(Mob* new_member, std::string new_member_name = std::string(), uint32 character_id = 0, bool is_merc = false);
|
||||
void AddMember(const std::string& new_member_name);
|
||||
void SendUpdate(uint32 type,Mob* member);
|
||||
void SendLeadershipAAUpdate();
|
||||
void SendWorldGroup(uint32 zone_id,Mob* zoningmember);
|
||||
@@ -145,6 +152,9 @@ public:
|
||||
void SetDirtyAutoHaters();
|
||||
inline XTargetAutoHaters *GetXTargetAutoMgr() { return &m_autohatermgr; }
|
||||
void JoinRaidXTarget(Raid *raid, bool first = false);
|
||||
void AddToGroup(AddToGroupRequest r);
|
||||
void AddToGroup(Mob* m);
|
||||
static void RemoveFromGroup(Mob* m);
|
||||
|
||||
void SetGroupMentor(int percent, char *name);
|
||||
void ClearGroupMentor();
|
||||
|
||||
+32
-30
@@ -108,46 +108,48 @@ void HateList::SetHateAmountOnEnt(Mob* other, int64 in_hate, uint64 in_damage)
|
||||
|
||||
Mob* HateList::GetDamageTopOnHateList(Mob* hater)
|
||||
{
|
||||
Mob* current = nullptr;
|
||||
Group* grp = nullptr;
|
||||
Raid* r = nullptr;
|
||||
uint64 dmg_amt = 0;
|
||||
Mob* c = nullptr;
|
||||
Mob* m = nullptr;
|
||||
Group* g = nullptr;
|
||||
Raid* r = nullptr;
|
||||
|
||||
auto iterator = list.begin();
|
||||
while (iterator != list.end())
|
||||
{
|
||||
grp = nullptr;
|
||||
uint64 damage = 0;
|
||||
|
||||
for (const auto& e : list) {
|
||||
c = e->entity_on_hatelist;
|
||||
|
||||
if (!c) {
|
||||
continue;
|
||||
}
|
||||
|
||||
g = nullptr;
|
||||
r = nullptr;
|
||||
|
||||
if ((*iterator)->entity_on_hatelist && (*iterator)->entity_on_hatelist->IsClient()){
|
||||
r = entity_list.GetRaidByClient((*iterator)->entity_on_hatelist->CastToClient());
|
||||
if (c->IsBot()) {
|
||||
r = entity_list.GetRaidByBot(c->CastToBot());
|
||||
} else if (c->IsClient()) {
|
||||
r = entity_list.GetRaidByClient(c->CastToClient());
|
||||
}
|
||||
|
||||
grp = entity_list.GetGroupByMob((*iterator)->entity_on_hatelist);
|
||||
g = entity_list.GetGroupByMob(c);
|
||||
|
||||
if ((*iterator)->entity_on_hatelist && r){
|
||||
if (r->GetTotalRaidDamage(hater) >= dmg_amt)
|
||||
{
|
||||
current = (*iterator)->entity_on_hatelist;
|
||||
dmg_amt = r->GetTotalRaidDamage(hater);
|
||||
if (r) {
|
||||
if (r->GetTotalRaidDamage(hater) >= damage) {
|
||||
m = c;
|
||||
damage = r->GetTotalRaidDamage(hater);
|
||||
}
|
||||
}
|
||||
else if ((*iterator)->entity_on_hatelist != nullptr && grp != nullptr)
|
||||
{
|
||||
if (grp->GetTotalGroupDamage(hater) >= dmg_amt)
|
||||
{
|
||||
current = (*iterator)->entity_on_hatelist;
|
||||
dmg_amt = grp->GetTotalGroupDamage(hater);
|
||||
} else if (g) {
|
||||
if (g->GetTotalGroupDamage(hater) >= damage) {
|
||||
m = c;
|
||||
damage = g->GetTotalGroupDamage(hater);
|
||||
}
|
||||
} else if (static_cast<uint64>(e->hatelist_damage) >= damage) {
|
||||
m = c;
|
||||
damage = static_cast<uint64>(e->hatelist_damage);
|
||||
}
|
||||
else if ((*iterator)->entity_on_hatelist != nullptr && (uint64)(*iterator)->hatelist_damage >= dmg_amt)
|
||||
{
|
||||
current = (*iterator)->entity_on_hatelist;
|
||||
dmg_amt = (*iterator)->hatelist_damage;
|
||||
}
|
||||
++iterator;
|
||||
}
|
||||
return current;
|
||||
|
||||
return m;
|
||||
}
|
||||
|
||||
Mob* HateList::GetClosestEntOnHateList(Mob *hater, bool skip_mezzed, EntityFilterType filter_type) {
|
||||
|
||||
+29
-1
@@ -601,7 +601,7 @@ bool Client::SummonItem(uint32 item_id, int16 charges, uint32 aug1, uint32 aug2,
|
||||
inst->SetOrnamentHeroModel(ornament_hero_model);
|
||||
|
||||
// check to see if item is usable in requested slot
|
||||
if (enforce_usable && (to_slot >= EQ::invslot::EQUIPMENT_BEGIN && to_slot <= EQ::invslot::EQUIPMENT_END)) {
|
||||
if (enforce_usable && to_slot != EQ::invslot::SLOT_QUEST && (to_slot >= EQ::invslot::EQUIPMENT_BEGIN && to_slot <= EQ::invslot::EQUIPMENT_END)) {
|
||||
uint32 slottest = to_slot;
|
||||
if(!(slots & ((uint32)1 << slottest))) {
|
||||
Message(
|
||||
@@ -648,6 +648,34 @@ bool Client::SummonItem(uint32 item_id, int16 charges, uint32 aug1, uint32 aug2,
|
||||
|
||||
RecordPlayerEventLog(PlayerEvent::ITEM_CREATION, e);
|
||||
}
|
||||
//We're coming from a quest method.
|
||||
if (to_slot == EQ::invslot::SLOT_QUEST) {
|
||||
bool stacking = TryStacking(inst);
|
||||
if (stacking) {
|
||||
safe_delete(inst);
|
||||
return true;
|
||||
}
|
||||
else {
|
||||
bool bag = false;
|
||||
if (inst->IsClassBag()) {
|
||||
bag = true;
|
||||
}
|
||||
to_slot = m_inv.FindFreeSlot(bag, true, item->Size);
|
||||
|
||||
//make sure we are not completely full...
|
||||
if (to_slot == EQ::invslot::slotCursor || to_slot == INVALID_INDEX) {
|
||||
if (inst->GetItem()->NoDrop == 0) {
|
||||
//If it's no drop, force it to the cursor. This carries the risk of deletion if the player already has this item on their cursor
|
||||
// or if the cursor queue is full. But in this situation, we have little other recourse.
|
||||
PushItemOnCursor(*inst);
|
||||
LogInventory("{} has a full inventory and {} is a no drop item. Forcing to cursor", GetName(), inst->GetItem()->Name);
|
||||
safe_delete(inst);
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
// put item into inventory
|
||||
if (to_slot == EQ::invslot::slotCursor) {
|
||||
|
||||
+378
-3
@@ -285,6 +285,8 @@ void NPC::AddLootDrop(
|
||||
const EQ::ItemData *item2,
|
||||
LootdropEntriesRepository::LootdropEntries loot_drop,
|
||||
bool wear_change,
|
||||
bool quest,
|
||||
bool pet,
|
||||
uint32 augment_one,
|
||||
uint32 augment_two,
|
||||
uint32 augment_three,
|
||||
@@ -297,6 +299,10 @@ void NPC::AddLootDrop(
|
||||
return;
|
||||
}
|
||||
|
||||
if (CountQuestItems() >= MAX_NPC_QUEST_INVENTORY) {
|
||||
return;
|
||||
}
|
||||
|
||||
auto item = new LootItem;
|
||||
|
||||
if (LogSys.log_settings[Logs::Loot].is_category_enabled == 1) {
|
||||
@@ -318,6 +324,10 @@ void NPC::AddLootDrop(
|
||||
);
|
||||
}
|
||||
|
||||
if (quest || pet) {
|
||||
LogLoot("Adding {} to npc: {}. Wearchange: {} Multiquest: {} Pet: {}", item2->Name, GetName(), wear_change, quest, pet);
|
||||
}
|
||||
|
||||
EQApplicationPacket *outapp = nullptr;
|
||||
WearChange_Struct *p_wear_change_struct = nullptr;
|
||||
if (wear_change) {
|
||||
@@ -339,6 +349,8 @@ void NPC::AddLootDrop(
|
||||
item->trivial_min_level = loot_drop.trivial_min_level;
|
||||
item->trivial_max_level = loot_drop.trivial_max_level;
|
||||
item->equip_slot = EQ::invslot::SLOT_INVALID;
|
||||
item->quest = quest;
|
||||
item->pet = pet;
|
||||
|
||||
// unsure if required to equip, YOLO for now
|
||||
if (item2->ItemType == EQ::item::ItemTypeBow) {
|
||||
@@ -349,6 +361,11 @@ void NPC::AddLootDrop(
|
||||
SetArrowEquipped(true);
|
||||
}
|
||||
|
||||
if (pet && quest) {
|
||||
LogLoot("Error: Item {} is being added to {} as both a pet and a quest.", item2->Name, GetName());
|
||||
item->pet = 0;
|
||||
}
|
||||
|
||||
bool found = false; // track if we found an empty slot we fit into
|
||||
|
||||
int found_slot = INVALID_INDEX; // for multi-slot items
|
||||
@@ -541,20 +558,21 @@ void NPC::AddLootDrop(
|
||||
safe_delete(inst);
|
||||
}
|
||||
|
||||
void NPC::AddItem(const EQ::ItemData *item, uint16 charges, bool equip_item)
|
||||
void NPC::AddItem(const EQ::ItemData *item, uint16 charges, bool equip_item, bool quest)
|
||||
{
|
||||
auto l = LootdropEntriesRepository::NewNpcEntity();
|
||||
|
||||
l.equip_item = static_cast<uint8>(equip_item ? 1 : 0);
|
||||
l.item_charges = charges;
|
||||
|
||||
AddLootDrop(item, l, true);
|
||||
AddLootDrop(item, l, equip_item, quest);
|
||||
}
|
||||
|
||||
void NPC::AddItem(
|
||||
uint32 item_id,
|
||||
uint16 charges,
|
||||
bool equip_item,
|
||||
bool quest,
|
||||
uint32 augment_one,
|
||||
uint32 augment_two,
|
||||
uint32 augment_three,
|
||||
@@ -576,7 +594,8 @@ void NPC::AddItem(
|
||||
AddLootDrop(
|
||||
item,
|
||||
l,
|
||||
true,
|
||||
equip_item,
|
||||
quest,
|
||||
augment_one,
|
||||
augment_two,
|
||||
augment_three,
|
||||
@@ -695,6 +714,50 @@ LootItem *NPC::GetItem(int slot_id)
|
||||
return (nullptr);
|
||||
}
|
||||
|
||||
LootItem *NPC::GetItemByItemID(int16 item_id)
|
||||
{
|
||||
LootItems::iterator cur, end;
|
||||
cur = m_loot_items.begin();
|
||||
end = m_loot_items.end();
|
||||
for (; cur != end; ++cur) {
|
||||
LootItem *item = *cur;
|
||||
if (item->item_id == item_id) {
|
||||
return item;
|
||||
}
|
||||
}
|
||||
return(nullptr);
|
||||
}
|
||||
|
||||
void NPC::RemoveItem(LootItem *item_data, uint8 quantity) {
|
||||
if (!item_data) {
|
||||
return;
|
||||
}
|
||||
|
||||
LootItems::iterator cur, end;
|
||||
cur = m_loot_items.begin();
|
||||
end = m_loot_items.end();
|
||||
for (; cur != end; ++cur) {
|
||||
LootItem *item = *cur;
|
||||
if (item != item_data) { continue; }
|
||||
|
||||
if (!item) {
|
||||
return;
|
||||
}
|
||||
|
||||
if (item->charges <= quantity) {
|
||||
m_loot_items.erase(cur);
|
||||
UpdateEquipmentLight();
|
||||
if (UpdateActiveLight()) { SendAppearancePacket(AppearanceType::Light, GetActiveLightType()); }
|
||||
}
|
||||
else {
|
||||
item->charges -= quantity;
|
||||
}
|
||||
return;
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
void NPC::RemoveItem(uint32 item_id, uint16 quantity, uint16 slot)
|
||||
{
|
||||
LootItems::iterator cur, end;
|
||||
@@ -941,3 +1004,315 @@ void NPC::RemoveLootCash()
|
||||
m_loot_gold = 0;
|
||||
m_loot_platinum = 0;
|
||||
}
|
||||
|
||||
bool NPC::HasQuestLootItem(int16 itemid)
|
||||
{
|
||||
LootItems::iterator cur, end;
|
||||
cur = m_loot_items.begin();
|
||||
end = m_loot_items.end();
|
||||
for (; cur != end; ++cur) {
|
||||
LootItem *quest_item = *cur;
|
||||
if (quest_item && quest_item->quest == 1 && quest_item->item_id == itemid) {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
bool NPC::HasQuestLoot()
|
||||
{
|
||||
LootItems::iterator cur, end;
|
||||
cur = m_loot_items.begin();
|
||||
end = m_loot_items.end();
|
||||
for (; cur != end; ++cur) {
|
||||
LootItem *quest_loot = *cur;
|
||||
if (quest_loot && quest_loot->quest == 1) {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
bool NPC::RemoveQuestLootItems(int16 itemid)
|
||||
{
|
||||
LootItems::iterator cur, end;
|
||||
cur = m_loot_items.begin();
|
||||
end = m_loot_items.end();
|
||||
for (; cur != end; ++cur) {
|
||||
LootItem *quest_item = *cur;
|
||||
if (quest_item && quest_item->quest == 1) {
|
||||
if (itemid == 0 || itemid == quest_item->item_id) {
|
||||
RemoveItem(quest_item);
|
||||
return true;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
bool NPC::HasRequiredQuestLoot(int16 itemid1, int16 itemid2, int16 itemid3, int16 itemid4)
|
||||
{
|
||||
if (itemid2 == 0 && itemid3 == 0 && itemid4 == 0) {
|
||||
return true;
|
||||
}
|
||||
|
||||
uint8 item2count = 0, item3count = 0, item4count = 0, item1npc = 0, item2npc = 0, item3npc = 0, item4npc = 0;
|
||||
uint8 item1count = 1;
|
||||
if (itemid2 > 0) {
|
||||
item2count = 1;
|
||||
}
|
||||
if (itemid3 > 0) {
|
||||
item3count = 1;
|
||||
}
|
||||
if (itemid4 > 0) {
|
||||
item4count = 1;
|
||||
}
|
||||
|
||||
if (itemid1 == itemid2 && itemid2 > 0) {
|
||||
item2count = item1count;
|
||||
++item1count;
|
||||
++item2count;
|
||||
}
|
||||
if (itemid1 == itemid3 && itemid3 > 0) {
|
||||
item3count = item1count;
|
||||
++item1count;
|
||||
++item3count;
|
||||
}
|
||||
if (itemid1 == itemid4 && itemid4 > 0) {
|
||||
item4count = item1count;
|
||||
++item1count;
|
||||
++item4count;
|
||||
}
|
||||
if (itemid2 == itemid3 && itemid2 > 0 && itemid3 > 0) {
|
||||
item3count = item2count;
|
||||
++item2count;
|
||||
++item3count;
|
||||
}
|
||||
if (itemid2 == itemid4 && itemid2 > 0 && itemid4 > 0) {
|
||||
item4count = item2count;
|
||||
++item2count;
|
||||
++item4count;
|
||||
}
|
||||
if (itemid3 == itemid4 && itemid3 > 0 && itemid4 > 0) {
|
||||
item4count = item3count;
|
||||
++item3count;
|
||||
++item4count;
|
||||
}
|
||||
|
||||
LootItems::iterator cur, end;
|
||||
cur = m_loot_items.begin();
|
||||
end = m_loot_items.end();
|
||||
for (; cur != end; ++cur) {
|
||||
LootItem *sitem = *cur;
|
||||
if (sitem && sitem->quest == 1) {
|
||||
if (sitem->item_id == itemid1) {
|
||||
++item1npc;
|
||||
}
|
||||
|
||||
if (sitem->item_id == itemid2 && itemid2 > 0) {
|
||||
++item2npc;
|
||||
}
|
||||
|
||||
if (sitem->item_id == itemid3 && itemid3 > 0) {
|
||||
++item3npc;
|
||||
}
|
||||
|
||||
if (sitem->item_id == itemid4 && itemid4 > 0) {
|
||||
++item4npc;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (item1npc < item1count) {
|
||||
return false;
|
||||
}
|
||||
|
||||
if (itemid2 > 0 && item2npc < item2count) {
|
||||
return false;
|
||||
}
|
||||
|
||||
if (itemid3 > 0 && item3npc < item3count) {
|
||||
return false;
|
||||
}
|
||||
|
||||
if (itemid4 > 0 && item4npc < item4count) {
|
||||
return false;
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
void NPC::CleanQuestLootItems()
|
||||
{
|
||||
//Removes nodrop or multiple quest loot items from a NPC before sending the corpse items to the client.
|
||||
|
||||
LootItems::iterator cur, end;
|
||||
cur = m_loot_items.begin();
|
||||
end = m_loot_items.end();
|
||||
uint8 count = 0;
|
||||
for (; cur != end; ++cur) {
|
||||
LootItem *quest_item = *cur;
|
||||
if (quest_item && (quest_item->quest == 1 || quest_item->pet == 1)) {
|
||||
uint8 count = CountQuestItem(quest_item->item_id);
|
||||
if (count > 1 && quest_item->pet != 1) {
|
||||
RemoveItem(quest_item);
|
||||
return;
|
||||
}
|
||||
else {
|
||||
const EQ::ItemData *item = database.GetItem(quest_item->item_id);
|
||||
if (item && item->NoDrop == 0) {
|
||||
RemoveItem(quest_item);
|
||||
return;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
uint8 NPC::CountQuestItem(uint16 itemid)
|
||||
{
|
||||
LootItems::iterator cur, end;
|
||||
cur = m_loot_items.begin();
|
||||
end = m_loot_items.end();
|
||||
uint8 count = 0;
|
||||
for (; cur != end; ++cur) {
|
||||
LootItem *quest_item = *cur;
|
||||
if (quest_item && quest_item->item_id == itemid) {
|
||||
++count;
|
||||
}
|
||||
}
|
||||
|
||||
return count;
|
||||
}
|
||||
|
||||
uint8 NPC::CountQuestItems()
|
||||
{
|
||||
LootItems::iterator cur, end;
|
||||
cur = m_loot_items.begin();
|
||||
end = m_loot_items.end();
|
||||
uint8 count = 0;
|
||||
for (; cur != end; ++cur) {
|
||||
LootItem *quest_item = *cur;
|
||||
if (quest_item && quest_item->quest == 1) {
|
||||
++count;
|
||||
}
|
||||
}
|
||||
|
||||
return count;
|
||||
}
|
||||
|
||||
bool NPC::AddQuestLoot(int16 itemid, int8 charges) {
|
||||
auto l = LootdropEntriesRepository::NewNpcEntity();
|
||||
|
||||
const EQ::ItemData *item = database.GetItem(itemid);
|
||||
if (item) {
|
||||
l.item_charges = charges;
|
||||
l.equip_item = 0;
|
||||
AddLootDrop(item, l, false, false, true);
|
||||
LogLoot("Adding item {} to the NPC's loot marked as quest.", itemid);
|
||||
if (itemid > 0 && HasPetLootItem(itemid)) {
|
||||
LogLoot("Deleting quest item {} from NPC's pet loot.", itemid);
|
||||
RemovePetLootItems(itemid);
|
||||
}
|
||||
}
|
||||
else
|
||||
return false;
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
void NPC::DeleteQuestLoot(int16 itemid1, int16 itemid2, int16 itemid3, int16 itemid4)
|
||||
{
|
||||
int16 items = m_loot_items.size();
|
||||
for (int i = 0; i < items; ++i) {
|
||||
if (itemid1 == 0) {
|
||||
if (!RemoveQuestLootItems(itemid1))
|
||||
break;
|
||||
}
|
||||
else {
|
||||
if (itemid1 != 0) {
|
||||
RemoveQuestLootItems(itemid1);
|
||||
}
|
||||
if (itemid2 != 0) {
|
||||
RemoveQuestLootItems(itemid2);
|
||||
}
|
||||
if (itemid3 != 0) {
|
||||
RemoveQuestLootItems(itemid3);
|
||||
}
|
||||
if (itemid4 != 0) {
|
||||
RemoveQuestLootItems(itemid4);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void NPC::DeleteInvalidQuestLoot()
|
||||
{
|
||||
int16 items = m_loot_items.size();
|
||||
for (int i = 0; i < items; ++i) {
|
||||
CleanQuestLootItems();
|
||||
}
|
||||
}
|
||||
|
||||
bool NPC::AddPetLoot(int16 itemid, int8 charges, bool fromquest) {
|
||||
auto l = LootdropEntriesRepository::NewNpcEntity();
|
||||
|
||||
const EQ::ItemData *item = database.GetItem(itemid);
|
||||
bool IsCharmedPet = IsPet() && IsCharmed();
|
||||
|
||||
if (!item) {
|
||||
return false;
|
||||
}
|
||||
|
||||
bool valid = (item->NoDrop != 0 && ( !IsCharmedPet || (IsCharmedPet && CountQuestItem(item->ID) == 0)));
|
||||
if (!fromquest || valid) {
|
||||
if (item) {
|
||||
l.item_charges = charges;
|
||||
AddLootDrop(item, l, true, true, false, true);
|
||||
LogLoot("Adding item {} to the NPC's loot marked as pet.", itemid);
|
||||
return true;
|
||||
}
|
||||
}
|
||||
else {
|
||||
LogLoot("Item {} is a duplicate or no drop. Deleting...", itemid);
|
||||
return false;
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
bool NPC::HasPetLootItem(int16 itemid)
|
||||
{
|
||||
LootItems::iterator cur, end;
|
||||
cur = m_loot_items.begin();
|
||||
end = m_loot_items.end();
|
||||
for (; cur != end; ++cur) {
|
||||
LootItem *quest_item = *cur;
|
||||
if (quest_item && quest_item->pet == 1 && quest_item->item_id == itemid) {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
bool NPC::RemovePetLootItems(int16 itemid)
|
||||
{
|
||||
LootItems::iterator cur, end;
|
||||
cur = m_loot_items.begin();
|
||||
end = m_loot_items.end();
|
||||
for (; cur != end; ++cur) {
|
||||
LootItem *quest_item = *cur;
|
||||
if (quest_item && quest_item->pet == 1) {
|
||||
if (itemid == 0 || itemid == quest_item->item_id) {
|
||||
RemoveItem(quest_item);
|
||||
return true;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
+22
-10
@@ -150,12 +150,17 @@ void Lua_Client::SetBaseGender(int v) {
|
||||
self->SetBaseGender(v);
|
||||
}
|
||||
|
||||
int Lua_Client::GetClassBitmask() {
|
||||
uint16 Lua_Client::GetClassBitmask() {
|
||||
Lua_Safe_Call_Int();
|
||||
return GetPlayerClassBit(self->GetClass());
|
||||
}
|
||||
|
||||
int Lua_Client::GetRaceBitmask() {
|
||||
uint32 Lua_Client::GetDeityBitmask() {
|
||||
Lua_Safe_Call_Int();
|
||||
return static_cast<uint32>(EQ::deity::GetDeityBitmask(static_cast<EQ::deity::DeityType>(GetDeity())));
|
||||
}
|
||||
|
||||
uint16 Lua_Client::GetRaceBitmask() {
|
||||
Lua_Safe_Call_Int();
|
||||
return GetPlayerRaceBit(self->GetBaseRace());
|
||||
}
|
||||
@@ -950,14 +955,19 @@ void Lua_Client::SummonItem(uint32 item_id, int charges, uint32 aug1, uint32 aug
|
||||
self->SummonItem(item_id, charges, aug1, aug2, aug3, aug4, aug5);
|
||||
}
|
||||
|
||||
void Lua_Client::SummonItem(uint32 item_id, int charges, uint32 aug1, uint32 aug2, uint32 aug3, uint32 aug4, uint32 aug5, bool attuned) {
|
||||
void Lua_Client::SummonItem(uint32 item_id, int charges, uint32 aug1, uint32 aug2, uint32 aug3, uint32 aug4, uint32 aug5, uint32 aug6) {
|
||||
Lua_Safe_Call_Void();
|
||||
self->SummonItem(item_id, charges, aug1, aug2, aug3, aug4, aug5, 0, attuned);
|
||||
self->SummonItem(item_id, charges, aug1, aug2, aug3, aug4, aug5, aug6);
|
||||
}
|
||||
|
||||
void Lua_Client::SummonItem(uint32 item_id, int charges, uint32 aug1, uint32 aug2, uint32 aug3, uint32 aug4, uint32 aug5, bool attuned, int to_slot) {
|
||||
void Lua_Client::SummonItem(uint32 item_id, int charges, uint32 aug1, uint32 aug2, uint32 aug3, uint32 aug4, uint32 aug5, uint32 aug6, bool attuned) {
|
||||
Lua_Safe_Call_Void();
|
||||
self->SummonItem(item_id, charges, aug1, aug2, aug3, aug4, aug5, 0, attuned, to_slot);
|
||||
self->SummonItem(item_id, charges, aug1, aug2, aug3, aug4, aug5, aug6, 0, attuned);
|
||||
}
|
||||
|
||||
void Lua_Client::SummonItem(uint32 item_id, int charges, uint32 aug1, uint32 aug2, uint32 aug3, uint32 aug4, uint32 aug5, uint32 aug6, bool attuned, int to_slot) {
|
||||
Lua_Safe_Call_Void();
|
||||
self->SummonItem(item_id, charges, aug1, aug2, aug3, aug4, aug5, aug6, 0, attuned, to_slot);
|
||||
}
|
||||
|
||||
void Lua_Client::SetStats(int type, int value) {
|
||||
@@ -3507,13 +3517,14 @@ luabind::scope lua_register_client() {
|
||||
.def("GetCarriedPlatinum", (uint32(Lua_Client::*)(void))&Lua_Client::GetCarriedPlatinum)
|
||||
.def("GetCharacterFactionLevel", (int(Lua_Client::*)(int))&Lua_Client::GetCharacterFactionLevel)
|
||||
.def("GetClassAbbreviation", (std::string(Lua_Client::*)(void))&Lua_Client::GetClassAbbreviation)
|
||||
.def("GetClassBitmask", (int(Lua_Client::*)(void))&Lua_Client::GetClassBitmask)
|
||||
.def("GetClassBitmask", (uint16(Lua_Client::*)(void))&Lua_Client::GetClassBitmask)
|
||||
.def("GetClientMaxLevel", (int(Lua_Client::*)(void))&Lua_Client::GetClientMaxLevel)
|
||||
.def("GetClientVersion", (int(Lua_Client::*)(void))&Lua_Client::GetClientVersion)
|
||||
.def("GetClientVersionBit", (uint32(Lua_Client::*)(void))&Lua_Client::GetClientVersionBit)
|
||||
.def("GetCorpseCount", (int64(Lua_Client::*)(void))&Lua_Client::GetCorpseCount)
|
||||
.def("GetCorpseID", (int(Lua_Client::*)(int))&Lua_Client::GetCorpseID)
|
||||
.def("GetCorpseItemAt", (int(Lua_Client::*)(int,int))&Lua_Client::GetCorpseItemAt)
|
||||
.def("GetDeityBitmask", (uint32(Lua_Client::*)(void))&Lua_Client::GetDeityBitmask)
|
||||
.def("GetDiscSlotBySpellID", (int(Lua_Client::*)(int32))&Lua_Client::GetDiscSlotBySpellID)
|
||||
.def("GetDisciplineTimer", (uint32(Lua_Client::*)(uint32))&Lua_Client::GetDisciplineTimer)
|
||||
.def("GetDuelTarget", (int(Lua_Client::*)(void))&Lua_Client::GetDuelTarget)
|
||||
@@ -3571,7 +3582,7 @@ luabind::scope lua_register_client() {
|
||||
.def("GetNextAvailableSpellBookSlot", (int(Lua_Client::*)(void))&Lua_Client::GetNextAvailableSpellBookSlot)
|
||||
.def("GetPVP", (bool(Lua_Client::*)(void))&Lua_Client::GetPVP)
|
||||
.def("GetPVPPoints", (uint32(Lua_Client::*)(void))&Lua_Client::GetPVPPoints)
|
||||
.def("GetRaceBitmask", (int(Lua_Client::*)(void))&Lua_Client::GetRaceBitmask)
|
||||
.def("GetRaceBitmask", (uint16(Lua_Client::*)(void))&Lua_Client::GetRaceBitmask)
|
||||
.def("GetRadiantCrystals", (uint32(Lua_Client::*)(void))&Lua_Client::GetRadiantCrystals)
|
||||
.def("GetRaid", (Lua_Raid(Lua_Client::*)(void))&Lua_Client::GetRaid)
|
||||
.def("GetRaidOrGroupOrSelf", (luabind::object(Lua_Client::*)(lua_State*))&Lua_Client::GetRaidOrGroupOrSelf)
|
||||
@@ -3857,8 +3868,9 @@ luabind::scope lua_register_client() {
|
||||
.def("SummonItem", (void(Lua_Client::*)(uint32,int,uint32,uint32,uint32))&Lua_Client::SummonItem)
|
||||
.def("SummonItem", (void(Lua_Client::*)(uint32,int,uint32,uint32,uint32,uint32))&Lua_Client::SummonItem)
|
||||
.def("SummonItem", (void(Lua_Client::*)(uint32,int,uint32,uint32,uint32,uint32,uint32))&Lua_Client::SummonItem)
|
||||
.def("SummonItem", (void(Lua_Client::*)(uint32,int,uint32,uint32,uint32,uint32,uint32,bool))&Lua_Client::SummonItem)
|
||||
.def("SummonItem", (void(Lua_Client::*)(uint32,int,uint32,uint32,uint32,uint32,uint32,bool,int))&Lua_Client::SummonItem)
|
||||
.def("SummonItem", (void(Lua_Client::*)(uint32,int,uint32,uint32,uint32,uint32,uint32,uint32))&Lua_Client::SummonItem)
|
||||
.def("SummonItem", (void(Lua_Client::*)(uint32,int,uint32,uint32,uint32,uint32,uint32,uint32,bool))&Lua_Client::SummonItem)
|
||||
.def("SummonItem", (void(Lua_Client::*)(uint32,int,uint32,uint32,uint32,uint32,uint32,uint32,bool,int))&Lua_Client::SummonItem)
|
||||
.def("SummonItemIntoInventory", (void(Lua_Client::*)(luabind::adl::object))&Lua_Client::SummonItemIntoInventory)
|
||||
.def("TGB", (bool(Lua_Client::*)(void))&Lua_Client::TGB)
|
||||
.def("TakeMoneyFromPP", (bool(Lua_Client::*)(uint64))&Lua_Client::TakeMoneyFromPP)
|
||||
|
||||
+6
-4
@@ -57,8 +57,9 @@ public:
|
||||
void SetBaseClass(int v);
|
||||
void SetBaseRace(int v);
|
||||
void SetBaseGender(int v);
|
||||
int GetClassBitmask();
|
||||
int GetRaceBitmask();
|
||||
uint16 GetClassBitmask();
|
||||
uint32 GetDeityBitmask();
|
||||
uint16 GetRaceBitmask();
|
||||
int GetBaseFace();
|
||||
int GetLanguageSkill(int skill_id);
|
||||
int GetLDoNPointsTheme(int theme);
|
||||
@@ -250,9 +251,10 @@ public:
|
||||
void SummonItem(uint32 item_id, int charges, uint32 aug1, uint32 aug2, uint32 aug3);
|
||||
void SummonItem(uint32 item_id, int charges, uint32 aug1, uint32 aug2, uint32 aug3, uint32 aug4);
|
||||
void SummonItem(uint32 item_id, int charges, uint32 aug1, uint32 aug2, uint32 aug3, uint32 aug4, uint32 aug5);
|
||||
void SummonItem(uint32 item_id, int charges, uint32 aug1, uint32 aug2, uint32 aug3, uint32 aug4, uint32 aug5,
|
||||
void SummonItem(uint32 item_id, int charges, uint32 aug1, uint32 aug2, uint32 aug3, uint32 aug4, uint32 aug5, uint32 aug6);
|
||||
void SummonItem(uint32 item_id, int charges, uint32 aug1, uint32 aug2, uint32 aug3, uint32 aug4, uint32 aug5, uint32 aug6,
|
||||
bool attuned);
|
||||
void SummonItem(uint32 item_id, int charges, uint32 aug1, uint32 aug2, uint32 aug3, uint32 aug4, uint32 aug5,
|
||||
void SummonItem(uint32 item_id, int charges, uint32 aug1, uint32 aug2, uint32 aug3, uint32 aug4, uint32 aug5, uint32 aug6,
|
||||
bool attuned, int to_slot);
|
||||
void SummonBaggedItems(uint32 bag_item_id, luabind::adl::object bag_items_table);
|
||||
void SetStats(int type, int value);
|
||||
|
||||
@@ -41,6 +41,8 @@ struct MessageTypes { };
|
||||
struct Rule { };
|
||||
struct Journal_SpeakMode { };
|
||||
struct Journal_Mode { };
|
||||
struct ZoneIDs { };
|
||||
struct LanguageIDs { };
|
||||
|
||||
struct lua_registered_event {
|
||||
std::string encounter_name;
|
||||
@@ -5474,6 +5476,18 @@ std::string lua_silent_say_link(std::string text, std::string link_name) {
|
||||
return Saylink::Silent(text, link_name);
|
||||
}
|
||||
|
||||
uint16 lua_get_class_bitmask(uint8 class_id) {
|
||||
return GetPlayerClassBit(class_id);
|
||||
}
|
||||
|
||||
uint32 lua_get_deity_bitmask(uint16 deity_id) {
|
||||
return static_cast<uint32>(EQ::deity::GetDeityBitmask(static_cast<EQ::deity::DeityType>(deity_id)));
|
||||
}
|
||||
|
||||
uint16 lua_get_race_bitmask(uint16 race_id) {
|
||||
return GetPlayerRaceBit(race_id);
|
||||
}
|
||||
|
||||
#define LuaCreateNPCParse(name, c_type, default_value) do { \
|
||||
cur = table[#name]; \
|
||||
if(luabind::type(cur) != LUA_TNIL) { \
|
||||
@@ -6270,6 +6284,9 @@ luabind::scope lua_register_general() {
|
||||
luabind::def("get_bot_race_by_id", &lua_get_bot_race_by_id),
|
||||
luabind::def("silent_say_link", (std::string(*)(std::string))&lua_silent_say_link),
|
||||
luabind::def("silent_say_link", (std::string(*)(std::string,std::string))&lua_silent_say_link),
|
||||
luabind::def("get_class_bitmask", &lua_get_class_bitmask),
|
||||
luabind::def("get_deity_bitmask", &lua_get_deity_bitmask),
|
||||
luabind::def("get_race_bitmask", &lua_get_race_bitmask),
|
||||
/*
|
||||
Cross Zone
|
||||
*/
|
||||
@@ -7233,6 +7250,530 @@ luabind::scope lua_register_message_types() {
|
||||
)];
|
||||
}
|
||||
|
||||
luabind::scope lua_register_zone_types() {
|
||||
return luabind::class_<ZoneIDs>("Zone")
|
||||
.enum_("constants")
|
||||
[(
|
||||
luabind::value("qeynos", Zones::QEYNOS),
|
||||
luabind::value("qeynos2", Zones::QEYNOS2),
|
||||
luabind::value("qrg", Zones::QRG),
|
||||
luabind::value("qeytoqrg", Zones::QEYTOQRG),
|
||||
luabind::value("highpass", Zones::HIGHPASS),
|
||||
luabind::value("highkeep", Zones::HIGHKEEP),
|
||||
luabind::value("freportn", Zones::FREPORTN),
|
||||
luabind::value("freportw", Zones::FREPORTW),
|
||||
luabind::value("freporte", Zones::FREPORTE),
|
||||
luabind::value("runnyeye", Zones::RUNNYEYE),
|
||||
luabind::value("qey2hh1", Zones::QEY2HH1),
|
||||
luabind::value("northkarana", Zones::NORTHKARANA),
|
||||
luabind::value("southkarana", Zones::SOUTHKARANA),
|
||||
luabind::value("eastkarana", Zones::EASTKARANA),
|
||||
luabind::value("beholder", Zones::BEHOLDER),
|
||||
luabind::value("blackburrow", Zones::BLACKBURROW),
|
||||
luabind::value("paw", Zones::PAW),
|
||||
luabind::value("rivervale", Zones::RIVERVALE),
|
||||
luabind::value("kithicor", Zones::KITHICOR),
|
||||
luabind::value("commons", Zones::COMMONS),
|
||||
luabind::value("ecommons", Zones::ECOMMONS),
|
||||
luabind::value("erudnint", Zones::ERUDNINT),
|
||||
luabind::value("erudnext", Zones::ERUDNEXT),
|
||||
luabind::value("nektulos", Zones::NEKTULOS),
|
||||
luabind::value("cshome", Zones::CSHOME),
|
||||
luabind::value("lavastorm", Zones::LAVASTORM),
|
||||
luabind::value("nektropos", Zones::NEKTROPOS),
|
||||
luabind::value("halas", Zones::HALAS),
|
||||
luabind::value("everfrost", Zones::EVERFROST),
|
||||
luabind::value("soldunga", Zones::SOLDUNGA),
|
||||
luabind::value("soldungb", Zones::SOLDUNGB),
|
||||
luabind::value("misty", Zones::MISTY),
|
||||
luabind::value("nro", Zones::NRO),
|
||||
luabind::value("sro", Zones::SRO),
|
||||
luabind::value("befallen", Zones::BEFALLEN),
|
||||
luabind::value("oasis", Zones::OASIS),
|
||||
luabind::value("tox", Zones::TOX),
|
||||
luabind::value("hole", Zones::HOLE),
|
||||
luabind::value("neriaka", Zones::NERIAKA),
|
||||
luabind::value("neriakb", Zones::NERIAKB),
|
||||
luabind::value("neriakc", Zones::NERIAKC),
|
||||
luabind::value("neriakd", Zones::NERIAKD),
|
||||
luabind::value("najena", Zones::NAJENA),
|
||||
luabind::value("qcat", Zones::QCAT),
|
||||
luabind::value("innothule", Zones::INNOTHULE),
|
||||
luabind::value("feerrott", Zones::FEERROTT),
|
||||
luabind::value("cazicthule", Zones::CAZICTHULE),
|
||||
luabind::value("oggok", Zones::OGGOK),
|
||||
luabind::value("rathemtn", Zones::RATHEMTN),
|
||||
luabind::value("lakerathe", Zones::LAKERATHE),
|
||||
luabind::value("grobb", Zones::GROBB),
|
||||
luabind::value("aviak", Zones::AVIAK),
|
||||
luabind::value("gfaydark", Zones::GFAYDARK),
|
||||
luabind::value("akanon", Zones::AKANON),
|
||||
luabind::value("steamfont", Zones::STEAMFONT),
|
||||
luabind::value("lfaydark", Zones::LFAYDARK),
|
||||
luabind::value("crushbone", Zones::CRUSHBONE),
|
||||
luabind::value("mistmoore", Zones::MISTMOORE),
|
||||
luabind::value("kaladima", Zones::KALADIMA),
|
||||
luabind::value("felwithea", Zones::FELWITHEA),
|
||||
luabind::value("felwitheb", Zones::FELWITHEB),
|
||||
luabind::value("unrest", Zones::UNREST),
|
||||
luabind::value("kedge", Zones::KEDGE),
|
||||
luabind::value("guktop", Zones::GUKTOP),
|
||||
luabind::value("gukbottom", Zones::GUKBOTTOM),
|
||||
luabind::value("kaladimb", Zones::KALADIMB),
|
||||
luabind::value("butcher", Zones::BUTCHER),
|
||||
luabind::value("oot", Zones::OOT),
|
||||
luabind::value("cauldron", Zones::CAULDRON),
|
||||
luabind::value("airplane", Zones::AIRPLANE),
|
||||
luabind::value("fearplane", Zones::FEARPLANE),
|
||||
luabind::value("permafrost", Zones::PERMAFROST),
|
||||
luabind::value("kerraridge", Zones::KERRARIDGE),
|
||||
luabind::value("paineel", Zones::PAINEEL),
|
||||
luabind::value("hateplane", Zones::HATEPLANE),
|
||||
luabind::value("arena", Zones::ARENA),
|
||||
luabind::value("fieldofbone", Zones::FIELDOFBONE),
|
||||
luabind::value("warslikswood", Zones::WARSLIKSWOOD),
|
||||
luabind::value("soltemple", Zones::SOLTEMPLE),
|
||||
luabind::value("droga", Zones::DROGA),
|
||||
luabind::value("cabwest", Zones::CABWEST),
|
||||
luabind::value("swampofnohope", Zones::SWAMPOFNOHOPE),
|
||||
luabind::value("firiona", Zones::FIRIONA),
|
||||
luabind::value("lakeofillomen", Zones::LAKEOFILLOMEN),
|
||||
luabind::value("dreadlands", Zones::DREADLANDS),
|
||||
luabind::value("burningwood", Zones::BURNINGWOOD),
|
||||
luabind::value("kaesora", Zones::KAESORA),
|
||||
luabind::value("sebilis", Zones::SEBILIS),
|
||||
luabind::value("citymist", Zones::CITYMIST),
|
||||
luabind::value("skyfire", Zones::SKYFIRE),
|
||||
luabind::value("frontiermtns", Zones::FRONTIERMTNS),
|
||||
luabind::value("overthere", Zones::OVERTHERE),
|
||||
luabind::value("emeraldjungle", Zones::EMERALDJUNGLE),
|
||||
luabind::value("trakanon", Zones::TRAKANON),
|
||||
luabind::value("timorous", Zones::TIMOROUS),
|
||||
luabind::value("kurn", Zones::KURN),
|
||||
luabind::value("erudsxing", Zones::ERUDSXING),
|
||||
luabind::value("stonebrunt", Zones::STONEBRUNT),
|
||||
luabind::value("warrens", Zones::WARRENS),
|
||||
luabind::value("karnor", Zones::KARNOR),
|
||||
luabind::value("chardok", Zones::CHARDOK),
|
||||
luabind::value("dalnir", Zones::DALNIR),
|
||||
luabind::value("charasis", Zones::CHARASIS),
|
||||
luabind::value("cabeast", Zones::CABEAST),
|
||||
luabind::value("nurga", Zones::NURGA),
|
||||
luabind::value("veeshan", Zones::VEESHAN),
|
||||
luabind::value("veksar", Zones::VEKSAR),
|
||||
luabind::value("iceclad", Zones::ICECLAD),
|
||||
luabind::value("frozenshadow", Zones::FROZENSHADOW),
|
||||
luabind::value("velketor", Zones::VELKETOR),
|
||||
luabind::value("kael", Zones::KAEL),
|
||||
luabind::value("skyshrine", Zones::SKYSHRINE),
|
||||
luabind::value("thurgadina", Zones::THURGADINA),
|
||||
luabind::value("eastwastes", Zones::EASTWASTES),
|
||||
luabind::value("cobaltscar", Zones::COBALTSCAR),
|
||||
luabind::value("greatdivide", Zones::GREATDIVIDE),
|
||||
luabind::value("wakening", Zones::WAKENING),
|
||||
luabind::value("westwastes", Zones::WESTWASTES),
|
||||
luabind::value("crystal", Zones::CRYSTAL),
|
||||
luabind::value("necropolis", Zones::NECROPOLIS),
|
||||
luabind::value("templeveeshan", Zones::TEMPLEVEESHAN),
|
||||
luabind::value("sirens", Zones::SIRENS),
|
||||
luabind::value("mischiefplane", Zones::MISCHIEFPLANE),
|
||||
luabind::value("growthplane", Zones::GROWTHPLANE),
|
||||
luabind::value("sleeper", Zones::SLEEPER),
|
||||
luabind::value("thurgadinb", Zones::THURGADINB),
|
||||
luabind::value("erudsxing2", Zones::ERUDSXING2),
|
||||
luabind::value("shadowhaven", Zones::SHADOWHAVEN),
|
||||
luabind::value("bazaar", Zones::BAZAAR),
|
||||
luabind::value("nexus", Zones::NEXUS),
|
||||
luabind::value("echo_", Zones::ECHO_),
|
||||
luabind::value("acrylia", Zones::ACRYLIA),
|
||||
luabind::value("sharvahl", Zones::SHARVAHL),
|
||||
luabind::value("paludal", Zones::PALUDAL),
|
||||
luabind::value("fungusgrove", Zones::FUNGUSGROVE),
|
||||
luabind::value("vexthal", Zones::VEXTHAL),
|
||||
luabind::value("sseru", Zones::SSERU),
|
||||
luabind::value("katta", Zones::KATTA),
|
||||
luabind::value("netherbian", Zones::NETHERBIAN),
|
||||
luabind::value("ssratemple", Zones::SSRATEMPLE),
|
||||
luabind::value("griegsend", Zones::GRIEGSEND),
|
||||
luabind::value("thedeep", Zones::THEDEEP),
|
||||
luabind::value("shadeweaver", Zones::SHADEWEAVER),
|
||||
luabind::value("hollowshade", Zones::HOLLOWSHADE),
|
||||
luabind::value("grimling", Zones::GRIMLING),
|
||||
luabind::value("mseru", Zones::MSERU),
|
||||
luabind::value("letalis", Zones::LETALIS),
|
||||
luabind::value("twilight", Zones::TWILIGHT),
|
||||
luabind::value("thegrey", Zones::THEGREY),
|
||||
luabind::value("tenebrous", Zones::TENEBROUS),
|
||||
luabind::value("maiden", Zones::MAIDEN),
|
||||
luabind::value("dawnshroud", Zones::DAWNSHROUD),
|
||||
luabind::value("scarlet", Zones::SCARLET),
|
||||
luabind::value("umbral", Zones::UMBRAL),
|
||||
luabind::value("akheva", Zones::AKHEVA),
|
||||
luabind::value("arena2", Zones::ARENA2),
|
||||
luabind::value("jaggedpine", Zones::JAGGEDPINE),
|
||||
luabind::value("nedaria", Zones::NEDARIA),
|
||||
luabind::value("tutorial", Zones::TUTORIAL),
|
||||
luabind::value("load", Zones::LOAD),
|
||||
luabind::value("load2", Zones::LOAD2),
|
||||
luabind::value("hateplaneb", Zones::HATEPLANEB),
|
||||
luabind::value("shadowrest", Zones::SHADOWREST),
|
||||
luabind::value("tutoriala", Zones::TUTORIALA),
|
||||
luabind::value("tutorialb", Zones::TUTORIALB),
|
||||
luabind::value("clz", Zones::CLZ),
|
||||
luabind::value("codecay", Zones::CODECAY),
|
||||
luabind::value("pojustice", Zones::POJUSTICE),
|
||||
luabind::value("poknowledge", Zones::POKNOWLEDGE),
|
||||
luabind::value("potranquility", Zones::POTRANQUILITY),
|
||||
luabind::value("ponightmare", Zones::PONIGHTMARE),
|
||||
luabind::value("podisease", Zones::PODISEASE),
|
||||
luabind::value("poinnovation", Zones::POINNOVATION),
|
||||
luabind::value("potorment", Zones::POTORMENT),
|
||||
luabind::value("povalor", Zones::POVALOR),
|
||||
luabind::value("bothunder", Zones::BOTHUNDER),
|
||||
luabind::value("postorms", Zones::POSTORMS),
|
||||
luabind::value("hohonora", Zones::HOHONORA),
|
||||
luabind::value("solrotower", Zones::SOLROTOWER),
|
||||
luabind::value("powar", Zones::POWAR),
|
||||
luabind::value("potactics", Zones::POTACTICS),
|
||||
luabind::value("poair", Zones::POAIR),
|
||||
luabind::value("powater", Zones::POWATER),
|
||||
luabind::value("pofire", Zones::POFIRE),
|
||||
luabind::value("poeartha", Zones::POEARTHA),
|
||||
luabind::value("potimea", Zones::POTIMEA),
|
||||
luabind::value("hohonorb", Zones::HOHONORB),
|
||||
luabind::value("nightmareb", Zones::NIGHTMAREB),
|
||||
luabind::value("poearthb", Zones::POEARTHB),
|
||||
luabind::value("potimeb", Zones::POTIMEB),
|
||||
luabind::value("gunthak", Zones::GUNTHAK),
|
||||
luabind::value("dulak", Zones::DULAK),
|
||||
luabind::value("torgiran", Zones::TORGIRAN),
|
||||
luabind::value("nadox", Zones::NADOX),
|
||||
luabind::value("hatesfury", Zones::HATESFURY),
|
||||
luabind::value("guka", Zones::GUKA),
|
||||
luabind::value("ruja", Zones::RUJA),
|
||||
luabind::value("taka", Zones::TAKA),
|
||||
luabind::value("mira", Zones::MIRA),
|
||||
luabind::value("mmca", Zones::MMCA),
|
||||
luabind::value("gukb", Zones::GUKB),
|
||||
luabind::value("rujb", Zones::RUJB),
|
||||
luabind::value("takb", Zones::TAKB),
|
||||
luabind::value("mirb", Zones::MIRB),
|
||||
luabind::value("mmcb", Zones::MMCB),
|
||||
luabind::value("gukc", Zones::GUKC),
|
||||
luabind::value("rujc", Zones::RUJC),
|
||||
luabind::value("takc", Zones::TAKC),
|
||||
luabind::value("mirc", Zones::MIRC),
|
||||
luabind::value("mmcc", Zones::MMCC),
|
||||
luabind::value("gukd", Zones::GUKD),
|
||||
luabind::value("rujd", Zones::RUJD),
|
||||
luabind::value("takd", Zones::TAKD),
|
||||
luabind::value("mird", Zones::MIRD),
|
||||
luabind::value("mmcd", Zones::MMCD),
|
||||
luabind::value("guke", Zones::GUKE),
|
||||
luabind::value("ruje", Zones::RUJE),
|
||||
luabind::value("take", Zones::TAKE),
|
||||
luabind::value("mire", Zones::MIRE),
|
||||
luabind::value("mmce", Zones::MMCE),
|
||||
luabind::value("gukf", Zones::GUKF),
|
||||
luabind::value("rujf", Zones::RUJF),
|
||||
luabind::value("takf", Zones::TAKF),
|
||||
luabind::value("mirf", Zones::MIRF),
|
||||
luabind::value("mmcf", Zones::MMCF),
|
||||
luabind::value("gukg", Zones::GUKG),
|
||||
luabind::value("rujg", Zones::RUJG),
|
||||
luabind::value("takg", Zones::TAKG),
|
||||
luabind::value("mirg", Zones::MIRG),
|
||||
luabind::value("mmcg", Zones::MMCG),
|
||||
luabind::value("gukh", Zones::GUKH),
|
||||
luabind::value("rujh", Zones::RUJH),
|
||||
luabind::value("takh", Zones::TAKH),
|
||||
luabind::value("mirh", Zones::MIRH),
|
||||
luabind::value("mmch", Zones::MMCH),
|
||||
luabind::value("ruji", Zones::RUJI),
|
||||
luabind::value("taki", Zones::TAKI),
|
||||
luabind::value("miri", Zones::MIRI),
|
||||
luabind::value("mmci", Zones::MMCI),
|
||||
luabind::value("rujj", Zones::RUJJ),
|
||||
luabind::value("takj", Zones::TAKJ),
|
||||
luabind::value("mirj", Zones::MIRJ),
|
||||
luabind::value("mmcj", Zones::MMCJ),
|
||||
luabind::value("chardokb", Zones::CHARDOKB),
|
||||
luabind::value("soldungc", Zones::SOLDUNGC),
|
||||
luabind::value("abysmal", Zones::ABYSMAL),
|
||||
luabind::value("natimbi", Zones::NATIMBI),
|
||||
luabind::value("qinimi", Zones::QINIMI),
|
||||
luabind::value("riwwi", Zones::RIWWI),
|
||||
luabind::value("barindu", Zones::BARINDU),
|
||||
luabind::value("ferubi", Zones::FERUBI),
|
||||
luabind::value("snpool", Zones::SNPOOL),
|
||||
luabind::value("snlair", Zones::SNLAIR),
|
||||
luabind::value("snplant", Zones::SNPLANT),
|
||||
luabind::value("sncrematory", Zones::SNCREMATORY),
|
||||
luabind::value("tipt", Zones::TIPT),
|
||||
luabind::value("vxed", Zones::VXED),
|
||||
luabind::value("yxtta", Zones::YXTTA),
|
||||
luabind::value("uqua", Zones::UQUA),
|
||||
luabind::value("kodtaz", Zones::KODTAZ),
|
||||
luabind::value("ikkinz", Zones::IKKINZ),
|
||||
luabind::value("qvic", Zones::QVIC),
|
||||
luabind::value("inktuta", Zones::INKTUTA),
|
||||
luabind::value("txevu", Zones::TXEVU),
|
||||
luabind::value("tacvi", Zones::TACVI),
|
||||
luabind::value("qvicb", Zones::QVICB),
|
||||
luabind::value("wallofslaughter", Zones::WALLOFSLAUGHTER),
|
||||
luabind::value("bloodfields", Zones::BLOODFIELDS),
|
||||
luabind::value("draniksscar", Zones::DRANIKSSCAR),
|
||||
luabind::value("causeway", Zones::CAUSEWAY),
|
||||
luabind::value("chambersa", Zones::CHAMBERSA),
|
||||
luabind::value("chambersb", Zones::CHAMBERSB),
|
||||
luabind::value("chambersc", Zones::CHAMBERSC),
|
||||
luabind::value("chambersd", Zones::CHAMBERSD),
|
||||
luabind::value("chamberse", Zones::CHAMBERSE),
|
||||
luabind::value("chambersf", Zones::CHAMBERSF),
|
||||
luabind::value("provinggrounds", Zones::PROVINGGROUNDS),
|
||||
luabind::value("anguish", Zones::ANGUISH),
|
||||
luabind::value("dranikhollowsa", Zones::DRANIKHOLLOWSA),
|
||||
luabind::value("dranikhollowsb", Zones::DRANIKHOLLOWSB),
|
||||
luabind::value("dranikhollowsc", Zones::DRANIKHOLLOWSC),
|
||||
luabind::value("dranikcatacombsa", Zones::DRANIKCATACOMBSA),
|
||||
luabind::value("dranikcatacombsb", Zones::DRANIKCATACOMBSB),
|
||||
luabind::value("dranikcatacombsc", Zones::DRANIKCATACOMBSC),
|
||||
luabind::value("draniksewersa", Zones::DRANIKSEWERSA),
|
||||
luabind::value("draniksewersb", Zones::DRANIKSEWERSB),
|
||||
luabind::value("draniksewersc", Zones::DRANIKSEWERSC),
|
||||
luabind::value("riftseekers", Zones::RIFTSEEKERS),
|
||||
luabind::value("harbingers", Zones::HARBINGERS),
|
||||
luabind::value("dranik", Zones::DRANIK),
|
||||
luabind::value("broodlands", Zones::BROODLANDS),
|
||||
luabind::value("stillmoona", Zones::STILLMOONA),
|
||||
luabind::value("stillmoonb", Zones::STILLMOONB),
|
||||
luabind::value("thundercrest", Zones::THUNDERCREST),
|
||||
luabind::value("delvea", Zones::DELVEA),
|
||||
luabind::value("delveb", Zones::DELVEB),
|
||||
luabind::value("thenest", Zones::THENEST),
|
||||
luabind::value("guildlobby", Zones::GUILDLOBBY),
|
||||
luabind::value("guildhall", Zones::GUILDHALL),
|
||||
luabind::value("barter", Zones::BARTER),
|
||||
luabind::value("illsalin", Zones::ILLSALIN),
|
||||
luabind::value("illsalina", Zones::ILLSALINA),
|
||||
luabind::value("illsalinb", Zones::ILLSALINB),
|
||||
luabind::value("illsalinc", Zones::ILLSALINC),
|
||||
luabind::value("dreadspire", Zones::DREADSPIRE),
|
||||
luabind::value("drachnidhive", Zones::DRACHNIDHIVE),
|
||||
luabind::value("drachnidhivea", Zones::DRACHNIDHIVEA),
|
||||
luabind::value("drachnidhiveb", Zones::DRACHNIDHIVEB),
|
||||
luabind::value("drachnidhivec", Zones::DRACHNIDHIVEC),
|
||||
luabind::value("westkorlach", Zones::WESTKORLACH),
|
||||
luabind::value("westkorlacha", Zones::WESTKORLACHA),
|
||||
luabind::value("westkorlachb", Zones::WESTKORLACHB),
|
||||
luabind::value("westkorlachc", Zones::WESTKORLACHC),
|
||||
luabind::value("eastkorlach", Zones::EASTKORLACH),
|
||||
luabind::value("eastkorlacha", Zones::EASTKORLACHA),
|
||||
luabind::value("shadowspine", Zones::SHADOWSPINE),
|
||||
luabind::value("corathus", Zones::CORATHUS),
|
||||
luabind::value("corathusa", Zones::CORATHUSA),
|
||||
luabind::value("corathusb", Zones::CORATHUSB),
|
||||
luabind::value("nektulosa", Zones::NEKTULOSA),
|
||||
luabind::value("arcstone", Zones::ARCSTONE),
|
||||
luabind::value("relic", Zones::RELIC),
|
||||
luabind::value("skylance", Zones::SKYLANCE),
|
||||
luabind::value("devastation", Zones::DEVASTATION),
|
||||
luabind::value("devastationa", Zones::DEVASTATIONA),
|
||||
luabind::value("rage", Zones::RAGE),
|
||||
luabind::value("ragea", Zones::RAGEA),
|
||||
luabind::value("takishruins", Zones::TAKISHRUINS),
|
||||
luabind::value("takishruinsa", Zones::TAKISHRUINSA),
|
||||
luabind::value("elddar", Zones::ELDDAR),
|
||||
luabind::value("elddara", Zones::ELDDARA),
|
||||
luabind::value("theater", Zones::THEATER),
|
||||
luabind::value("theatera", Zones::THEATERA),
|
||||
luabind::value("freeporteast", Zones::FREEPORTEAST),
|
||||
luabind::value("freeportwest", Zones::FREEPORTWEST),
|
||||
luabind::value("freeportsewers", Zones::FREEPORTSEWERS),
|
||||
luabind::value("freeportacademy", Zones::FREEPORTACADEMY),
|
||||
luabind::value("freeporttemple", Zones::FREEPORTTEMPLE),
|
||||
luabind::value("freeportmilitia", Zones::FREEPORTMILITIA),
|
||||
luabind::value("freeportarena", Zones::FREEPORTARENA),
|
||||
luabind::value("freeportcityhall", Zones::FREEPORTCITYHALL),
|
||||
luabind::value("freeporttheater", Zones::FREEPORTTHEATER),
|
||||
luabind::value("freeporthall", Zones::FREEPORTHALL),
|
||||
luabind::value("northro", Zones::NORTHRO),
|
||||
luabind::value("southro", Zones::SOUTHRO),
|
||||
luabind::value("crescent", Zones::CRESCENT),
|
||||
luabind::value("moors", Zones::MOORS),
|
||||
luabind::value("stonehive", Zones::STONEHIVE),
|
||||
luabind::value("mesa", Zones::MESA),
|
||||
luabind::value("roost", Zones::ROOST),
|
||||
luabind::value("steppes", Zones::STEPPES),
|
||||
luabind::value("icefall", Zones::ICEFALL),
|
||||
luabind::value("valdeholm", Zones::VALDEHOLM),
|
||||
luabind::value("frostcrypt", Zones::FROSTCRYPT),
|
||||
luabind::value("sunderock", Zones::SUNDEROCK),
|
||||
luabind::value("vergalid", Zones::VERGALID),
|
||||
luabind::value("direwind", Zones::DIREWIND),
|
||||
luabind::value("ashengate", Zones::ASHENGATE),
|
||||
luabind::value("highpasshold", Zones::HIGHPASSHOLD),
|
||||
luabind::value("commonlands", Zones::COMMONLANDS),
|
||||
luabind::value("oceanoftears", Zones::OCEANOFTEARS),
|
||||
luabind::value("kithforest", Zones::KITHFOREST),
|
||||
luabind::value("befallenb", Zones::BEFALLENB),
|
||||
luabind::value("highpasskeep", Zones::HIGHPASSKEEP),
|
||||
luabind::value("innothuleb", Zones::INNOTHULEB),
|
||||
luabind::value("toxxulia", Zones::TOXXULIA),
|
||||
luabind::value("mistythicket", Zones::MISTYTHICKET),
|
||||
luabind::value("kattacastrum", Zones::KATTACASTRUM),
|
||||
luabind::value("thalassius", Zones::THALASSIUS),
|
||||
luabind::value("atiiki", Zones::ATIIKI),
|
||||
luabind::value("zhisza", Zones::ZHISZA),
|
||||
luabind::value("silyssar", Zones::SILYSSAR),
|
||||
luabind::value("solteris", Zones::SOLTERIS),
|
||||
luabind::value("barren", Zones::BARREN),
|
||||
luabind::value("buriedsea", Zones::BURIEDSEA),
|
||||
luabind::value("jardelshook", Zones::JARDELSHOOK),
|
||||
luabind::value("monkeyrock", Zones::MONKEYROCK),
|
||||
luabind::value("suncrest", Zones::SUNCREST),
|
||||
luabind::value("deadbone", Zones::DEADBONE),
|
||||
luabind::value("blacksail", Zones::BLACKSAIL),
|
||||
luabind::value("maidensgrave", Zones::MAIDENSGRAVE),
|
||||
luabind::value("redfeather", Zones::REDFEATHER),
|
||||
luabind::value("shipmvp", Zones::SHIPMVP),
|
||||
luabind::value("shipmvu", Zones::SHIPMVU),
|
||||
luabind::value("shippvu", Zones::SHIPPVU),
|
||||
luabind::value("shipuvu", Zones::SHIPUVU),
|
||||
luabind::value("shipmvm", Zones::SHIPMVM),
|
||||
luabind::value("mechanotus", Zones::MECHANOTUS),
|
||||
luabind::value("mansion", Zones::MANSION),
|
||||
luabind::value("steamfactory", Zones::STEAMFACTORY),
|
||||
luabind::value("shipworkshop", Zones::SHIPWORKSHOP),
|
||||
luabind::value("gyrospireb", Zones::GYROSPIREB),
|
||||
luabind::value("gyrospirez", Zones::GYROSPIREZ),
|
||||
luabind::value("dragonscale", Zones::DRAGONSCALE),
|
||||
luabind::value("lopingplains", Zones::LOPINGPLAINS),
|
||||
luabind::value("hillsofshade", Zones::HILLSOFSHADE),
|
||||
luabind::value("bloodmoon", Zones::BLOODMOON),
|
||||
luabind::value("crystallos", Zones::CRYSTALLOS),
|
||||
luabind::value("guardian", Zones::GUARDIAN),
|
||||
luabind::value("steamfontmts", Zones::STEAMFONTMTS),
|
||||
luabind::value("cryptofshade", Zones::CRYPTOFSHADE),
|
||||
luabind::value("dragonscaleb", Zones::DRAGONSCALEB),
|
||||
luabind::value("oldfieldofbone", Zones::OLDFIELDOFBONE),
|
||||
luabind::value("oldkaesoraa", Zones::OLDKAESORAA),
|
||||
luabind::value("oldkaesorab", Zones::OLDKAESORAB),
|
||||
luabind::value("oldkurn", Zones::OLDKURN),
|
||||
luabind::value("oldkithicor", Zones::OLDKITHICOR),
|
||||
luabind::value("oldcommons", Zones::OLDCOMMONS),
|
||||
luabind::value("oldhighpass", Zones::OLDHIGHPASS),
|
||||
luabind::value("thevoida", Zones::THEVOIDA),
|
||||
luabind::value("thevoidb", Zones::THEVOIDB),
|
||||
luabind::value("thevoidc", Zones::THEVOIDC),
|
||||
luabind::value("thevoidd", Zones::THEVOIDD),
|
||||
luabind::value("thevoide", Zones::THEVOIDE),
|
||||
luabind::value("thevoidf", Zones::THEVOIDF),
|
||||
luabind::value("thevoidg", Zones::THEVOIDG),
|
||||
luabind::value("oceangreenhills", Zones::OCEANGREENHILLS),
|
||||
luabind::value("oceangreenvillage", Zones::OCEANGREENVILLAGE),
|
||||
luabind::value("oldblackburrow", Zones::OLDBLACKBURROW),
|
||||
luabind::value("bertoxtemple", Zones::BERTOXTEMPLE),
|
||||
luabind::value("discord", Zones::DISCORD),
|
||||
luabind::value("discordtower", Zones::DISCORDTOWER),
|
||||
luabind::value("oldbloodfield", Zones::OLDBLOODFIELD),
|
||||
luabind::value("precipiceofwar", Zones::PRECIPICEOFWAR),
|
||||
luabind::value("olddranik", Zones::OLDDRANIK),
|
||||
luabind::value("toskirakk", Zones::TOSKIRAKK),
|
||||
luabind::value("korascian", Zones::KORASCIAN),
|
||||
luabind::value("rathechamber", Zones::RATHECHAMBER),
|
||||
luabind::value("brellsrest", Zones::BRELLSREST),
|
||||
luabind::value("fungalforest", Zones::FUNGALFOREST),
|
||||
luabind::value("underquarry", Zones::UNDERQUARRY),
|
||||
luabind::value("coolingchamber", Zones::COOLINGCHAMBER),
|
||||
luabind::value("shiningcity", Zones::SHININGCITY),
|
||||
luabind::value("arthicrex", Zones::ARTHICREX),
|
||||
luabind::value("foundation", Zones::FOUNDATION),
|
||||
luabind::value("lichencreep", Zones::LICHENCREEP),
|
||||
luabind::value("pellucid", Zones::PELLUCID),
|
||||
luabind::value("stonesnake", Zones::STONESNAKE),
|
||||
luabind::value("brellstemple", Zones::BRELLSTEMPLE),
|
||||
luabind::value("convorteum", Zones::CONVORTEUM),
|
||||
luabind::value("brellsarena", Zones::BRELLSARENA),
|
||||
luabind::value("weddingchapel", Zones::WEDDINGCHAPEL),
|
||||
luabind::value("weddingchapeldark", Zones::WEDDINGCHAPELDARK),
|
||||
luabind::value("dragoncrypt", Zones::DRAGONCRYPT),
|
||||
luabind::value("feerrott2", Zones::FEERROTT2),
|
||||
luabind::value("thulehouse1", Zones::THULEHOUSE1),
|
||||
luabind::value("thulehouse2", Zones::THULEHOUSE2),
|
||||
luabind::value("housegarden", Zones::HOUSEGARDEN),
|
||||
luabind::value("thulelibrary", Zones::THULELIBRARY),
|
||||
luabind::value("well", Zones::WELL),
|
||||
luabind::value("fallen", Zones::FALLEN),
|
||||
luabind::value("morellcastle", Zones::MORELLCASTLE),
|
||||
luabind::value("somnium", Zones::SOMNIUM),
|
||||
luabind::value("alkabormare", Zones::ALKABORMARE),
|
||||
luabind::value("miragulmare", Zones::MIRAGULMARE),
|
||||
luabind::value("thuledream", Zones::THULEDREAM),
|
||||
luabind::value("neighborhood", Zones::NEIGHBORHOOD),
|
||||
luabind::value("argath", Zones::ARGATH),
|
||||
luabind::value("arelis", Zones::ARELIS),
|
||||
luabind::value("sarithcity", Zones::SARITHCITY),
|
||||
luabind::value("rubak", Zones::RUBAK),
|
||||
luabind::value("beastdomain", Zones::BEASTDOMAIN),
|
||||
luabind::value("resplendent", Zones::RESPLENDENT),
|
||||
luabind::value("pillarsalra", Zones::PILLARSALRA),
|
||||
luabind::value("windsong", Zones::WINDSONG),
|
||||
luabind::value("cityofbronze", Zones::CITYOFBRONZE),
|
||||
luabind::value("sepulcher", Zones::SEPULCHER),
|
||||
luabind::value("eastsepulcher", Zones::EASTSEPULCHER),
|
||||
luabind::value("westsepulcher", Zones::WESTSEPULCHER),
|
||||
luabind::value("shardslanding", Zones::SHARDSLANDING),
|
||||
luabind::value("xorbb", Zones::XORBB),
|
||||
luabind::value("kaelshard", Zones::KAELSHARD),
|
||||
luabind::value("eastwastesshard", Zones::EASTWASTESSHARD),
|
||||
luabind::value("crystalshard", Zones::CRYSTALSHARD),
|
||||
luabind::value("breedinggrounds", Zones::BREEDINGGROUNDS),
|
||||
luabind::value("eviltree", Zones::EVILTREE),
|
||||
luabind::value("grelleth", Zones::GRELLETH),
|
||||
luabind::value("chapterhouse", Zones::CHAPTERHOUSE),
|
||||
luabind::value("arttest", Zones::ARTTEST),
|
||||
luabind::value("fhalls", Zones::FHALLS),
|
||||
luabind::value("apprentice", Zones::APPRENTICE)
|
||||
)];
|
||||
}
|
||||
|
||||
luabind::scope lua_register_languages() {
|
||||
return luabind::class_<LanguageIDs>("Language")
|
||||
.enum_("constants")
|
||||
[(
|
||||
luabind::value("CommonTongue", Language::CommonTongue),
|
||||
luabind::value("Barbarian", Language::Barbarian),
|
||||
luabind::value("Erudian", Language::Erudian),
|
||||
luabind::value("Elvish", Language::Elvish),
|
||||
luabind::value("DarkElvish", Language::DarkElvish),
|
||||
luabind::value("Dwarvish", Language::Dwarvish),
|
||||
luabind::value("Troll", Language::Troll),
|
||||
luabind::value("Ogre", Language::Ogre),
|
||||
luabind::value("Gnomish", Language::Gnomish),
|
||||
luabind::value("Halfling", Language::Halfling),
|
||||
luabind::value("ThievesCant", Language::ThievesCant),
|
||||
luabind::value("OldErudian", Language::OldErudian),
|
||||
luabind::value("ElderElvish", Language::ElderElvish),
|
||||
luabind::value("Froglok", Language::Froglok),
|
||||
luabind::value("Goblin", Language::Goblin),
|
||||
luabind::value("Gnoll", Language::Gnoll),
|
||||
luabind::value("CombineTongue", Language::CombineTongue),
|
||||
luabind::value("ElderTeirDal", Language::ElderTeirDal),
|
||||
luabind::value("Lizardman", Language::Lizardman),
|
||||
luabind::value("Orcish", Language::Orcish),
|
||||
luabind::value("Faerie", Language::Faerie),
|
||||
luabind::value("Dragon", Language::Dragon),
|
||||
luabind::value("ElderDragon", Language::ElderDragon),
|
||||
luabind::value("DarkSpeech", Language::DarkSpeech),
|
||||
luabind::value("VahShir", Language::VahShir),
|
||||
luabind::value("Alaran", Language::Alaran),
|
||||
luabind::value("Hadal", Language::Hadal),
|
||||
luabind::value("Unknown27", Language::Unknown27),
|
||||
luabind::value("MaxValue", Language::MaxValue)
|
||||
)];
|
||||
}
|
||||
|
||||
luabind::scope lua_register_rules_const() {
|
||||
return luabind::class_<Rule>("Rule")
|
||||
.enum_("constants")
|
||||
|
||||
@@ -15,6 +15,8 @@ luabind::scope lua_register_skills();
|
||||
luabind::scope lua_register_bodytypes();
|
||||
luabind::scope lua_register_filters();
|
||||
luabind::scope lua_register_message_types();
|
||||
luabind::scope lua_register_zone_types();
|
||||
luabind::scope lua_register_languages();
|
||||
luabind::scope lua_register_rules_const();
|
||||
luabind::scope lua_register_rulei();
|
||||
luabind::scope lua_register_ruler();
|
||||
|
||||
@@ -3333,6 +3333,30 @@ void Lua_Mob::RestoreMana()
|
||||
self->RestoreMana();
|
||||
}
|
||||
|
||||
std::string Lua_Mob::GetArchetypeName()
|
||||
{
|
||||
Lua_Safe_Call_String();
|
||||
return self->GetArchetypeName();
|
||||
}
|
||||
|
||||
bool Lua_Mob::IsIntelligenceCasterClass()
|
||||
{
|
||||
Lua_Safe_Call_Bool();
|
||||
return self->IsIntelligenceCasterClass();
|
||||
}
|
||||
|
||||
bool Lua_Mob::IsPureMeleeClass()
|
||||
{
|
||||
Lua_Safe_Call_Bool();
|
||||
return self->IsPureMeleeClass();
|
||||
}
|
||||
|
||||
bool Lua_Mob::IsWisdomCasterClass()
|
||||
{
|
||||
Lua_Safe_Call_Bool();
|
||||
return self->IsWisdomCasterClass();
|
||||
}
|
||||
|
||||
luabind::scope lua_register_mob() {
|
||||
return luabind::class_<Lua_Mob, Lua_Entity>("Mob")
|
||||
.def(luabind::constructor<>())
|
||||
@@ -3524,6 +3548,7 @@ luabind::scope lua_register_mob() {
|
||||
.def("GetAggroRange", (float(Lua_Mob::*)(void))&Lua_Mob::GetAggroRange)
|
||||
.def("GetAllowBeneficial", (bool(Lua_Mob::*)(void))&Lua_Mob::GetAllowBeneficial)
|
||||
.def("GetAppearance", (uint32(Lua_Mob::*)(void))&Lua_Mob::GetAppearance)
|
||||
.def("GetArchetypeName", &Lua_Mob::GetArchetypeName)
|
||||
.def("GetAssistRange", (float(Lua_Mob::*)(void))&Lua_Mob::GetAssistRange)
|
||||
.def("GetBaseGender", &Lua_Mob::GetBaseGender)
|
||||
.def("GetBaseRace", &Lua_Mob::GetBaseRace)
|
||||
@@ -3732,6 +3757,7 @@ luabind::scope lua_register_mob() {
|
||||
.def("IsFindable", (bool(Lua_Mob::*)(void))&Lua_Mob::IsFindable)
|
||||
.def("IsHorse", &Lua_Mob::IsHorse)
|
||||
.def("IsImmuneToSpell", (bool(Lua_Mob::*)(int,Lua_Mob))&Lua_Mob::IsImmuneToSpell)
|
||||
.def("IsIntelligenceCasterClass", &Lua_Mob::IsIntelligenceCasterClass)
|
||||
.def("IsInvisible", (bool(Lua_Mob::*)(Lua_Mob))&Lua_Mob::IsInvisible)
|
||||
.def("IsInvisible", (bool(Lua_Mob::*)(void))&Lua_Mob::IsInvisible)
|
||||
.def("IsMeleeDisabled", (bool(Lua_Mob::*)(void))&Lua_Mob::IsMeleeDisabled)
|
||||
@@ -3742,6 +3768,7 @@ luabind::scope lua_register_mob() {
|
||||
.def("IsPetOwnerBot", &Lua_Mob::IsPetOwnerBot)
|
||||
.def("IsPetOwnerClient", &Lua_Mob::IsPetOwnerClient)
|
||||
.def("IsPetOwnerNPC", &Lua_Mob::IsPetOwnerNPC)
|
||||
.def("IsPureMeleeClass", &Lua_Mob::IsPureMeleeClass)
|
||||
.def("IsRoamer", (bool(Lua_Mob::*)(void))&Lua_Mob::IsRoamer)
|
||||
.def("IsRooted", (bool(Lua_Mob::*)(void))&Lua_Mob::IsRooted)
|
||||
.def("IsRunning", (bool(Lua_Mob::*)(void))&Lua_Mob::IsRunning)
|
||||
@@ -3753,6 +3780,7 @@ luabind::scope lua_register_mob() {
|
||||
.def("IsTemporaryPet", &Lua_Mob::IsTemporaryPet)
|
||||
.def("IsTrackable", (bool(Lua_Mob::*)(void))&Lua_Mob::IsTrackable)
|
||||
.def("IsWarriorClass", &Lua_Mob::IsWarriorClass)
|
||||
.def("IsWisdomCasterClass", &Lua_Mob::IsWisdomCasterClass)
|
||||
.def("Kill", (void(Lua_Mob::*)(void))&Lua_Mob::Kill)
|
||||
.def("Mesmerize", (void(Lua_Mob::*)(void))&Lua_Mob::Mesmerize)
|
||||
.def("Message", &Lua_Mob::Message)
|
||||
|
||||
@@ -586,6 +586,10 @@ public:
|
||||
void RestoreEndurance();
|
||||
void RestoreHealth();
|
||||
void RestoreMana();
|
||||
std::string GetArchetypeName();
|
||||
bool IsIntelligenceCasterClass();
|
||||
bool IsPureMeleeClass();
|
||||
bool IsWisdomCasterClass();
|
||||
};
|
||||
|
||||
#endif
|
||||
|
||||
@@ -37,6 +37,7 @@ void LuaMod::Init()
|
||||
m_has_get_experience_for_kill = parser_->HasFunction("GetExperienceForKill", package_name_);
|
||||
m_has_common_outgoing_hit_success = parser_->HasFunction("CommonOutgoingHitSuccess", package_name_);
|
||||
m_has_calc_spell_effect_value_formula = parser_->HasFunction("CalcSpellEffectValue_formula", package_name_);
|
||||
m_has_register_bug = parser_->HasFunction("RegisterBug", package_name_);
|
||||
}
|
||||
|
||||
void PutDamageHitInfo(lua_State *L, luabind::adl::object &e, DamageHitInfo &hit) {
|
||||
@@ -678,4 +679,187 @@ void LuaMod::CalcSpellEffectValue_formula(Mob *self, uint32 formula, int64 base_
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
void LuaMod::RegisterBug(Client *self, BaseBugReportsRepository::BugReports bug, bool &ignore_default)
|
||||
{
|
||||
int start = lua_gettop(L);
|
||||
|
||||
try {
|
||||
if (!m_has_register_bug) {
|
||||
return;
|
||||
}
|
||||
|
||||
lua_getfield(L, LUA_REGISTRYINDEX, package_name_.c_str());
|
||||
lua_getfield(L, -1, "RegisterBug");
|
||||
|
||||
Lua_Client l_self(self);
|
||||
luabind::adl::object e = luabind::newtable(L);
|
||||
e["self"] = l_self;
|
||||
e["zone"] = bug.zone;
|
||||
e["client_version_id"] = bug.client_version_id;
|
||||
e["client_version_name"] = bug.client_version_name;
|
||||
e["account_id"] = bug.account_id;
|
||||
e["character_id"] = bug.character_id;
|
||||
e["character_name"] = bug.character_name;
|
||||
e["reporter_spoof"] = bug.reporter_spoof;
|
||||
e["category_id"] = bug.category_id;
|
||||
e["category_name"] = bug.category_name;
|
||||
e["reporter_name"] = bug.reporter_name;
|
||||
e["ui_path"] = bug.ui_path;
|
||||
e["pos_x"] = bug.pos_x;
|
||||
e["pos_y"] = bug.pos_y;
|
||||
e["pos_z"] = bug.pos_z;
|
||||
e["heading"] = bug.heading;
|
||||
e["time_played"] = bug.time_played;
|
||||
e["target_id"] = bug.target_id;
|
||||
e["target_name"] = bug.target_name;
|
||||
e["optional_info_mask"] = bug.optional_info_mask;
|
||||
e["_can_duplicate"] = bug._can_duplicate;
|
||||
e["_crash_bug"] = bug._crash_bug;
|
||||
e["_target_info"] = bug._target_info;
|
||||
e["_character_flags"] = bug._character_flags;
|
||||
e["_unknown_value"] = bug._unknown_value;
|
||||
e["bug_report"] = bug.bug_report;
|
||||
e["system_info"] = bug.system_info;
|
||||
|
||||
e.push(L);
|
||||
|
||||
if (lua_pcall(L, 1, 1, 0)) {
|
||||
std::string error = lua_tostring(L, -1);
|
||||
parser_->AddError(error);
|
||||
lua_pop(L, 2);
|
||||
return;
|
||||
}
|
||||
|
||||
if (lua_type(L, -1) == LUA_TTABLE) {
|
||||
luabind::adl::object ret(luabind::from_stack(L, -1));
|
||||
auto ignore_default_obj = ret["ignore_default"];
|
||||
if (luabind::type(ignore_default_obj) == LUA_TBOOLEAN) {
|
||||
ignore_default = ignore_default || luabind::object_cast<bool>(ignore_default_obj);
|
||||
}
|
||||
}
|
||||
}
|
||||
catch (std::exception &ex) {
|
||||
parser_->AddError(ex.what());
|
||||
}
|
||||
|
||||
int end = lua_gettop(L);
|
||||
int n = end - start;
|
||||
if (n > 0) {
|
||||
lua_pop(L, n);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
void LuaMod::CommonDamage(Mob *self, Mob* attacker, int64 value, uint16 spell_id, int skill_used, bool avoidable, int8 buff_slot, bool buff_tic, int special, int64 &return_value, bool &ignore_default)
|
||||
{
|
||||
int start = lua_gettop(L);
|
||||
|
||||
try {
|
||||
if (!m_has_common_damage) {
|
||||
return;
|
||||
}
|
||||
|
||||
lua_getfield(L, LUA_REGISTRYINDEX, package_name_.c_str());
|
||||
lua_getfield(L, -1, "CommonDamage");
|
||||
|
||||
Lua_Mob l_self(self);
|
||||
Lua_Mob l_other(attacker);
|
||||
luabind::adl::object e = luabind::newtable(L);
|
||||
e["self"] = l_self;
|
||||
e["attacker"] = l_other;
|
||||
e["value"] = value;
|
||||
e["spell_id"] = spell_id;
|
||||
e["skill_used"] = skill_used;
|
||||
e["avoidable"] = avoidable;
|
||||
e["buff_slot"] = buff_slot;
|
||||
e["buff_tic"] = buff_tic;
|
||||
e["special"] = special;
|
||||
|
||||
e.push(L);
|
||||
|
||||
if (lua_pcall(L, 1, 1, 0)) {
|
||||
std::string error = lua_tostring(L, -1);
|
||||
parser_->AddError(error);
|
||||
lua_pop(L, 2);
|
||||
return;
|
||||
}
|
||||
|
||||
if (lua_type(L, -1) == LUA_TTABLE) {
|
||||
luabind::adl::object ret(luabind::from_stack(L, -1));
|
||||
auto ignore_default_obj = ret["ignore_default"];
|
||||
if (luabind::type(ignore_default_obj) == LUA_TBOOLEAN) {
|
||||
ignore_default = ignore_default || luabind::object_cast<bool>(ignore_default_obj);
|
||||
}
|
||||
|
||||
auto return_value_obj = ret["return_value"];
|
||||
if (luabind::type(return_value_obj) == LUA_TNUMBER) {
|
||||
return_value = luabind::object_cast<int64>(return_value_obj);
|
||||
}
|
||||
}
|
||||
}
|
||||
catch (std::exception &ex) {
|
||||
parser_->AddError(ex.what());
|
||||
}
|
||||
|
||||
int end = lua_gettop(L);
|
||||
int n = end - start;
|
||||
if (n > 0) {
|
||||
lua_pop(L, n);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
void LuaMod::HealDamage(Mob *self, Mob* caster, uint64 value, uint16 spell_id, uint64 &return_value, bool &ignore_default)
|
||||
{
|
||||
int start = lua_gettop(L);
|
||||
|
||||
try {
|
||||
if (!m_has_heal_damage) {
|
||||
return;
|
||||
}
|
||||
|
||||
lua_getfield(L, LUA_REGISTRYINDEX, package_name_.c_str());
|
||||
lua_getfield(L, -1, "HealDamage");
|
||||
|
||||
Lua_Mob l_self(self);
|
||||
Lua_Mob l_other(caster);
|
||||
luabind::adl::object e = luabind::newtable(L);
|
||||
e["self"] = l_self;
|
||||
e["caster"] = l_other;
|
||||
e["value"] = value;
|
||||
e["spell_id"] = spell_id;
|
||||
|
||||
e.push(L);
|
||||
|
||||
if (lua_pcall(L, 1, 1, 0)) {
|
||||
std::string error = lua_tostring(L, -1);
|
||||
parser_->AddError(error);
|
||||
lua_pop(L, 2);
|
||||
return;
|
||||
}
|
||||
|
||||
if (lua_type(L, -1) == LUA_TTABLE) {
|
||||
luabind::adl::object ret(luabind::from_stack(L, -1));
|
||||
auto ignore_default_obj = ret["ignore_default"];
|
||||
if (luabind::type(ignore_default_obj) == LUA_TBOOLEAN) {
|
||||
ignore_default = ignore_default || luabind::object_cast<bool>(ignore_default_obj);
|
||||
}
|
||||
|
||||
auto return_value_obj = ret["return_value"];
|
||||
if (luabind::type(return_value_obj) == LUA_TNUMBER) {
|
||||
return_value = luabind::object_cast<int64>(return_value_obj);
|
||||
}
|
||||
}
|
||||
}
|
||||
catch (std::exception &ex) {
|
||||
parser_->AddError(ex.what());
|
||||
}
|
||||
|
||||
int end = lua_gettop(L);
|
||||
int n = end - start;
|
||||
if (n > 0) {
|
||||
lua_pop(L, n);
|
||||
}
|
||||
}
|
||||
#endif
|
||||
|
||||
@@ -1,6 +1,7 @@
|
||||
#pragma once
|
||||
|
||||
#include <string>
|
||||
#include "../common/repositories/bug_reports_repository.h"
|
||||
|
||||
struct lua_State;
|
||||
|
||||
@@ -27,6 +28,9 @@ public:
|
||||
void GetEXPForLevel(Client *self, uint16 level, uint32 &returnValue, bool &ignoreDefault);
|
||||
void GetExperienceForKill(Client *self, Mob *against, uint64 &returnValue, bool &ignoreDefault);
|
||||
void CalcSpellEffectValue_formula(Mob *self, uint32 formula, int64 base_value, int64 max_value, int caster_level, uint16 spell_id, int ticsremaining, int64 &returnValue, bool &ignoreDefault);
|
||||
void RegisterBug(Client *self, BaseBugReportsRepository::BugReports bug, bool &ignore_default);
|
||||
void CommonDamage(Mob *self, Mob* attacker, int64 value, uint16 spell_id, int skill_used, bool avoidable, int8 buff_slot, bool buff_tic, int special, int64 &return_value, bool &ignore_default);
|
||||
void HealDamage(Mob *self, Mob* caster, uint64 value, uint16 spell_id, uint64 &return_value, bool &ignore_default);
|
||||
private:
|
||||
LuaParser *parser_;
|
||||
lua_State *L;
|
||||
@@ -42,4 +46,7 @@ private:
|
||||
bool m_has_get_exp_for_level;
|
||||
bool m_has_get_experience_for_kill;
|
||||
bool m_has_calc_spell_effect_value_formula;
|
||||
bool m_has_register_bug;
|
||||
bool m_has_common_damage;
|
||||
bool m_has_heal_damage;
|
||||
};
|
||||
|
||||
+129
-18
@@ -32,34 +32,39 @@ void Lua_NPC::AddItem(int item_id, int charges, bool equip) {
|
||||
self->AddItem(item_id, charges, equip);
|
||||
}
|
||||
|
||||
void Lua_NPC::AddItem(int item_id, int charges, bool equip, int aug1) {
|
||||
void Lua_NPC::AddItem(int item_id, int charges, bool equip, bool quest) {
|
||||
Lua_Safe_Call_Void();
|
||||
self->AddItem(item_id, charges, equip, aug1);
|
||||
self->AddItem(item_id, charges, equip, quest);
|
||||
}
|
||||
|
||||
void Lua_NPC::AddItem(int item_id, int charges, bool equip, int aug1, int aug2) {
|
||||
void Lua_NPC::AddItem(int item_id, int charges, bool equip, bool quest, int aug1) {
|
||||
Lua_Safe_Call_Void();
|
||||
self->AddItem(item_id, charges, equip, aug1, aug2);
|
||||
self->AddItem(item_id, charges, equip, quest, aug1);
|
||||
}
|
||||
|
||||
void Lua_NPC::AddItem(int item_id, int charges, bool equip, int aug1, int aug2, int aug3) {
|
||||
void Lua_NPC::AddItem(int item_id, int charges, bool equip, bool quest, int aug1, int aug2) {
|
||||
Lua_Safe_Call_Void();
|
||||
self->AddItem(item_id, charges, equip, aug1, aug2, aug3);
|
||||
self->AddItem(item_id, charges, equip, quest, aug1, aug2);
|
||||
}
|
||||
|
||||
void Lua_NPC::AddItem(int item_id, int charges, bool equip, int aug1, int aug2, int aug3, int aug4) {
|
||||
void Lua_NPC::AddItem(int item_id, int charges, bool equip, bool quest, int aug1, int aug2, int aug3) {
|
||||
Lua_Safe_Call_Void();
|
||||
self->AddItem(item_id, charges, equip, aug1, aug2, aug3, aug4);
|
||||
self->AddItem(item_id, charges, equip, quest, aug1, aug2, aug3);
|
||||
}
|
||||
|
||||
void Lua_NPC::AddItem(int item_id, int charges, bool equip, int aug1, int aug2, int aug3, int aug4, int aug5) {
|
||||
void Lua_NPC::AddItem(int item_id, int charges, bool equip, bool quest, int aug1, int aug2, int aug3, int aug4) {
|
||||
Lua_Safe_Call_Void();
|
||||
self->AddItem(item_id, charges, equip, aug1, aug2, aug3, aug4, aug5);
|
||||
self->AddItem(item_id, charges, equip, quest, aug1, aug2, aug3, aug4);
|
||||
}
|
||||
|
||||
void Lua_NPC::AddItem(int item_id, int charges, bool equip, int aug1, int aug2, int aug3, int aug4, int aug5, int aug6) {
|
||||
void Lua_NPC::AddItem(int item_id, int charges, bool equip, bool quest, int aug1, int aug2, int aug3, int aug4, int aug5) {
|
||||
Lua_Safe_Call_Void();
|
||||
self->AddItem(item_id, charges, equip, aug1, aug2, aug3, aug4, aug5, aug6);
|
||||
self->AddItem(item_id, charges, equip, quest, aug1, aug2, aug3, aug4, aug5);
|
||||
}
|
||||
|
||||
void Lua_NPC::AddItem(int item_id, int charges, bool equip, bool quest, int aug1, int aug2, int aug3, int aug4, int aug5, int aug6) {
|
||||
Lua_Safe_Call_Void();
|
||||
self->AddItem(item_id, charges, equip, quest, aug1, aug2, aug3, aug4, aug5, aug6);
|
||||
}
|
||||
|
||||
void Lua_NPC::AddLootTable() {
|
||||
@@ -831,6 +836,96 @@ uint32 Lua_NPC::GetNPCSpellsEffectsID()
|
||||
return self->GetNPCSpellsEffectsID();
|
||||
}
|
||||
|
||||
void Lua_NPC::AddQuestLoot(int itemid)
|
||||
{
|
||||
Lua_Safe_Call_Void();
|
||||
self->AddQuestLoot(itemid);
|
||||
}
|
||||
|
||||
void Lua_NPC::AddQuestLoot(int itemid, int charges)
|
||||
{
|
||||
Lua_Safe_Call_Void();
|
||||
self->AddQuestLoot(itemid, charges);
|
||||
}
|
||||
|
||||
bool Lua_NPC::GetQuestLoot(int itemid)
|
||||
{
|
||||
Lua_Safe_Call_Bool();
|
||||
return self->HasQuestLootItem(itemid);
|
||||
}
|
||||
|
||||
bool Lua_NPC::HasQuestLoot()
|
||||
{
|
||||
Lua_Safe_Call_Bool();
|
||||
return self->HasQuestLoot();
|
||||
}
|
||||
|
||||
void Lua_NPC::AddPetLoot(int itemid)
|
||||
{
|
||||
Lua_Safe_Call_Void();
|
||||
self->AddPetLoot(itemid, 1, true);
|
||||
}
|
||||
|
||||
void Lua_NPC::AddPetLoot(int itemid, int charges)
|
||||
{
|
||||
Lua_Safe_Call_Void();
|
||||
self->AddPetLoot(itemid, charges, true);
|
||||
}
|
||||
|
||||
bool Lua_NPC::GetPetLoot(int itemid)
|
||||
{
|
||||
Lua_Safe_Call_Bool();
|
||||
return self->HasPetLootItem(itemid);
|
||||
}
|
||||
|
||||
void Lua_NPC::DeleteQuestLoot()
|
||||
{
|
||||
Lua_Safe_Call_Void();
|
||||
self->DeleteQuestLoot(0);
|
||||
}
|
||||
|
||||
void Lua_NPC::DeleteQuestLoot(int itemid1)
|
||||
{
|
||||
Lua_Safe_Call_Void();
|
||||
self->DeleteQuestLoot(itemid1);
|
||||
}
|
||||
|
||||
void Lua_NPC::DeleteQuestLoot(int itemid1, int itemid2)
|
||||
{
|
||||
Lua_Safe_Call_Void();
|
||||
self->DeleteQuestLoot(itemid1, itemid2);
|
||||
}
|
||||
|
||||
void Lua_NPC::DeleteQuestLoot(int itemid1, int itemid2, int itemid3)
|
||||
{
|
||||
Lua_Safe_Call_Void();
|
||||
self->DeleteQuestLoot(itemid1, itemid2, itemid3);
|
||||
}
|
||||
|
||||
void Lua_NPC::DeleteQuestLoot(int itemid1, int itemid2, int itemid3, int itemid4)
|
||||
{
|
||||
Lua_Safe_Call_Void();
|
||||
self->DeleteQuestLoot(itemid1, itemid2, itemid3, itemid4);
|
||||
}
|
||||
|
||||
bool Lua_NPC::HasRequiredQuestLoot(int itemid1, int itemid2, int itemid3, int itemid4)
|
||||
{
|
||||
Lua_Safe_Call_Bool();
|
||||
return self->HasRequiredQuestLoot(itemid1, itemid2, itemid3, itemid4);
|
||||
}
|
||||
|
||||
int Lua_NPC::QuestLootCount(int itemid)
|
||||
{
|
||||
Lua_Safe_Call_Int();
|
||||
return self->CountQuestItem(itemid);
|
||||
}
|
||||
|
||||
bool Lua_NPC::CanTalk()
|
||||
{
|
||||
Lua_Safe_Call_Bool();
|
||||
return self->CanTalk();
|
||||
}
|
||||
|
||||
luabind::scope lua_register_npc() {
|
||||
return luabind::class_<Lua_NPC, Lua_Mob>("NPC")
|
||||
.def(luabind::constructor<>())
|
||||
@@ -842,16 +937,22 @@ luabind::scope lua_register_npc() {
|
||||
.def("AddCash", (void(Lua_NPC::*)(uint32,uint32,uint32,uint32))&Lua_NPC::AddLootCash)
|
||||
.def("AddItem", (void(Lua_NPC::*)(int,int))&Lua_NPC::AddItem)
|
||||
.def("AddItem", (void(Lua_NPC::*)(int,int,bool))&Lua_NPC::AddItem)
|
||||
.def("AddItem", (void(Lua_NPC::*)(int,int,bool,int))&Lua_NPC::AddItem)
|
||||
.def("AddItem", (void(Lua_NPC::*)(int,int,bool,int,int))&Lua_NPC::AddItem)
|
||||
.def("AddItem", (void(Lua_NPC::*)(int,int,bool,int,int,int))&Lua_NPC::AddItem)
|
||||
.def("AddItem", (void(Lua_NPC::*)(int,int,bool,int,int,int,int))&Lua_NPC::AddItem)
|
||||
.def("AddItem", (void(Lua_NPC::*)(int,int,bool,int,int,int,int,int))&Lua_NPC::AddItem)
|
||||
.def("AddItem", (void(Lua_NPC::*)(int,int,bool,int,int,int,int,int,int))&Lua_NPC::AddItem)
|
||||
.def("AddItem", (void(Lua_NPC::*)(int,int,bool,bool)) & Lua_NPC::AddItem)
|
||||
.def("AddItem", (void(Lua_NPC::*)(int,int,bool,bool,int))&Lua_NPC::AddItem)
|
||||
.def("AddItem", (void(Lua_NPC::*)(int,int,bool,bool,int,int))&Lua_NPC::AddItem)
|
||||
.def("AddItem", (void(Lua_NPC::*)(int,int,bool,bool,int,int,int))&Lua_NPC::AddItem)
|
||||
.def("AddItem", (void(Lua_NPC::*)(int,int,bool,bool,int,int,int,int))&Lua_NPC::AddItem)
|
||||
.def("AddItem", (void(Lua_NPC::*)(int,int,bool,bool,int,int,int,int,int))&Lua_NPC::AddItem)
|
||||
.def("AddItem", (void(Lua_NPC::*)(int,int,bool,bool,int,int,int,int,int,int))&Lua_NPC::AddItem)
|
||||
.def("AddLootTable", (void(Lua_NPC::*)(int))&Lua_NPC::AddLootTable)
|
||||
.def("AddLootTable", (void(Lua_NPC::*)(void))&Lua_NPC::AddLootTable)
|
||||
.def("AddQuestLoot", (void(Lua_NPC::*)(int)) & Lua_NPC::AddQuestLoot)
|
||||
.def("AddQuestLoot", (void(Lua_NPC::*)(int,int)) & Lua_NPC::AddQuestLoot)
|
||||
.def("AddPetLoot", (void(Lua_NPC:: *)(int)) & Lua_NPC::AddPetLoot)
|
||||
.def("AddPetLoot", (void(Lua_NPC:: *)(int, int)) & Lua_NPC::AddPetLoot)
|
||||
.def("AssignWaypoints", (void(Lua_NPC::*)(int))&Lua_NPC::AssignWaypoints)
|
||||
.def("CalculateNewWaypoint", (void(Lua_NPC::*)(void))&Lua_NPC::CalculateNewWaypoint)
|
||||
.def("CanTalk", (bool(Lua_NPC:: *)(void)) & Lua_NPC::CanTalk)
|
||||
.def("ChangeLastName", (void(Lua_NPC::*)(std::string))&Lua_NPC::ChangeLastName)
|
||||
.def("CheckNPCFactionAlly", (int(Lua_NPC::*)(int))&Lua_NPC::CheckNPCFactionAlly)
|
||||
.def("ClearItemList", (void(Lua_NPC::*)(void))&Lua_NPC::ClearLootItems)
|
||||
@@ -859,6 +960,11 @@ luabind::scope lua_register_npc() {
|
||||
.def("CountItem", (uint16(Lua_NPC::*)(uint32))&Lua_NPC::CountItem)
|
||||
.def("CountLoot", (int(Lua_NPC::*)(void))&Lua_NPC::CountLoot)
|
||||
.def("DeleteBucket", (void(Lua_NPC::*)(std::string))&Lua_NPC::DeleteBucket)
|
||||
.def("DeleteQuestLoot", (void(Lua_NPC:: *)(void)) & Lua_NPC::DeleteQuestLoot)
|
||||
.def("DeleteQuestLoot", (void(Lua_NPC:: *)(int)) & Lua_NPC::DeleteQuestLoot)
|
||||
.def("DeleteQuestLoot", (void(Lua_NPC:: *)(int, int)) & Lua_NPC::DeleteQuestLoot)
|
||||
.def("DeleteQuestLoot", (void(Lua_NPC:: *)(int, int, int)) & Lua_NPC::DeleteQuestLoot)
|
||||
.def("DeleteQuestLoot", (void(Lua_NPC:: *)(int, int, int, int)) & Lua_NPC::DeleteQuestLoot)
|
||||
.def("DisplayWaypointInfo", (void(Lua_NPC::*)(Lua_Client))&Lua_NPC::DisplayWaypointInfo)
|
||||
.def("DoClassAttacks", (void(Lua_NPC::*)(Lua_Mob))&Lua_NPC::DoClassAttacks)
|
||||
.def("GetAccuracyRating", (int(Lua_NPC::*)(void))&Lua_NPC::GetAccuracyRating)
|
||||
@@ -896,10 +1002,12 @@ luabind::scope lua_register_npc() {
|
||||
.def("GetNPCSpellsEffectsID", (uint32(Lua_NPC::*)(void))&Lua_NPC::GetNPCSpellsEffectsID)
|
||||
.def("GetNPCSpellsID", (uint32(Lua_NPC::*)(void))&Lua_NPC::GetNPCSpellsID)
|
||||
.def("GetNPCStat", (float(Lua_NPC::*)(std::string))&Lua_NPC::GetNPCStat)
|
||||
.def("GetPetLoot", (bool(Lua_NPC:: *)(int)) & Lua_NPC::GetPetLoot)
|
||||
.def("GetPetSpellID", (int(Lua_NPC::*)(void))&Lua_NPC::GetPetSpellID)
|
||||
.def("GetPlatinum", (uint32(Lua_NPC::*)(void))&Lua_NPC::GetPlatinum)
|
||||
.def("GetPrimSkill", (int(Lua_NPC::*)(void))&Lua_NPC::GetPrimSkill)
|
||||
.def("GetPrimaryFaction", (int(Lua_NPC::*)(void))&Lua_NPC::GetPrimaryFaction)
|
||||
.def("GetQuestLoot", (bool(Lua_NPC:: *)(int)) & Lua_NPC::GetQuestLoot)
|
||||
.def("GetRawAC", (int(Lua_NPC::*)(void))&Lua_NPC::GetRawAC)
|
||||
.def("GetScore", (int(Lua_NPC::*)(void))&Lua_NPC::GetScore)
|
||||
.def("GetSecSkill", (int(Lua_NPC::*)(void))&Lua_NPC::GetSecSkill)
|
||||
@@ -920,6 +1028,8 @@ luabind::scope lua_register_npc() {
|
||||
.def("GetWaypointMax", (int(Lua_NPC::*)(void))&Lua_NPC::GetWaypointMax)
|
||||
.def("HasAISpellEffect", (bool(Lua_NPC::*)(int))&Lua_NPC::HasAISpellEffect)
|
||||
.def("HasItem", (bool(Lua_NPC::*)(uint32))&Lua_NPC::HasItem)
|
||||
.def("HasQuestLoot", (bool(Lua_NPC::*)(void)) & Lua_NPC::HasQuestLoot)
|
||||
.def("HasRequiredQuestLoot", (bool(Lua_NPC::*)(int,int,int,int)) &Lua_NPC::HasRequiredQuestLoot)
|
||||
.def("IsAnimal", (bool(Lua_NPC::*)(void))&Lua_NPC::IsAnimal)
|
||||
.def("IsGuarding", (bool(Lua_NPC::*)(void))&Lua_NPC::IsGuarding)
|
||||
.def("IsLDoNLocked", (bool(Lua_NPC::*)(void))&Lua_NPC::IsLDoNLocked)
|
||||
@@ -937,6 +1047,7 @@ luabind::scope lua_register_npc() {
|
||||
.def("NextGuardPosition", (void(Lua_NPC::*)(void))&Lua_NPC::NextGuardPosition)
|
||||
.def("PauseWandering", (void(Lua_NPC::*)(int))&Lua_NPC::PauseWandering)
|
||||
.def("PickPocket", (void(Lua_NPC::*)(Lua_Client))&Lua_NPC::PickPocket)
|
||||
.def("QuestLootCount", (int(Lua_NPC::*)(int)) &Lua_NPC::QuestLootCount)
|
||||
.def("RecalculateSkills", (void(Lua_NPC::*)(void))&Lua_NPC::RecalculateSkills)
|
||||
.def("ReloadSpells", (void(Lua_NPC::*)(void))&Lua_NPC::ReloadSpells)
|
||||
.def("RemoveAISpell", (void(Lua_NPC::*)(int))&Lua_NPC::RemoveAISpell)
|
||||
|
||||
+22
-6
@@ -33,12 +33,13 @@ public:
|
||||
int CheckNPCFactionAlly(int faction);
|
||||
void AddItem(int item_id, int charges);
|
||||
void AddItem(int item_id, int charges, bool equip);
|
||||
void AddItem(int item_id, int charges, bool equip, int aug1);
|
||||
void AddItem(int item_id, int charges, bool equip, int aug1, int aug2);
|
||||
void AddItem(int item_id, int charges, bool equip, int aug1, int aug2, int aug3);
|
||||
void AddItem(int item_id, int charges, bool equip, int aug1, int aug2, int aug3, int aug4);
|
||||
void AddItem(int item_id, int charges, bool equip, int aug1, int aug2, int aug3, int aug4, int aug5);
|
||||
void AddItem(int item_id, int charges, bool equip, int aug1, int aug2, int aug3, int aug4, int aug5, int aug6);
|
||||
void AddItem(int item_id, int charges, bool equip, bool quest);
|
||||
void AddItem(int item_id, int charges, bool equip, bool quest, int aug1);
|
||||
void AddItem(int item_id, int charges, bool equip, bool quest, int aug1, int aug2);
|
||||
void AddItem(int item_id, int charges, bool equip, bool quest, int aug1, int aug2, int aug3);
|
||||
void AddItem(int item_id, int charges, bool equip, bool quest, int aug1, int aug2, int aug3, int aug4);
|
||||
void AddItem(int item_id, int charges, bool equip, bool quest, int aug1, int aug2, int aug3, int aug4, int aug5);
|
||||
void AddItem(int item_id, int charges, bool equip, bool quest, int aug1, int aug2, int aug3, int aug4, int aug5, int aug6);
|
||||
void AddLootTable();
|
||||
void AddLootTable(int id);
|
||||
void RemoveItem(int item_id);
|
||||
@@ -185,6 +186,21 @@ public:
|
||||
bool GetNPCAggro();
|
||||
void SetNPCAggro(bool in_npc_aggro);
|
||||
uint32 GetNPCSpellsEffectsID();
|
||||
void AddQuestLoot(int itemid); //
|
||||
void AddQuestLoot(int itemid, int charges); //
|
||||
void AddPetLoot(int itemid); //
|
||||
void AddPetLoot(int itemid, int charges); //
|
||||
bool GetQuestLoot(int itemid); //
|
||||
bool GetPetLoot(int itemid); //
|
||||
bool HasQuestLoot(); //
|
||||
void DeleteQuestLoot();
|
||||
void DeleteQuestLoot(int itemid1);
|
||||
void DeleteQuestLoot(int itemid1, int itemid2);
|
||||
void DeleteQuestLoot(int itemid1, int itemid2, int itemid3);
|
||||
void DeleteQuestLoot(int itemid1, int itemid2, int itemid3, int itemid4);
|
||||
bool HasRequiredQuestLoot(int itemid1, int itemid2, int itemid3, int itemid4);
|
||||
int QuestLootCount(int itemid);
|
||||
bool CanTalk();
|
||||
};
|
||||
|
||||
#endif
|
||||
|
||||
+33
-1
@@ -183,7 +183,8 @@ const char *LuaEvents[_LargestEventID] = {
|
||||
"event_entity_variable_delete",
|
||||
"event_entity_variable_set",
|
||||
"event_entity_variable_update",
|
||||
"event_aa_loss"
|
||||
"event_aa_loss",
|
||||
"event_spell_blocked"
|
||||
};
|
||||
|
||||
extern Zone *zone;
|
||||
@@ -257,6 +258,7 @@ LuaParser::LuaParser() {
|
||||
NPCArgumentDispatch[EVENT_ENTITY_VARIABLE_DELETE] = handle_npc_entity_variable;
|
||||
NPCArgumentDispatch[EVENT_ENTITY_VARIABLE_SET] = handle_npc_entity_variable;
|
||||
NPCArgumentDispatch[EVENT_ENTITY_VARIABLE_UPDATE] = handle_npc_entity_variable;
|
||||
NPCArgumentDispatch[EVENT_SPELL_BLOCKED] = handle_npc_spell_blocked;
|
||||
|
||||
PlayerArgumentDispatch[EVENT_SAY] = handle_player_say;
|
||||
PlayerArgumentDispatch[EVENT_ENVIRONMENTAL_DAMAGE] = handle_player_environmental_damage;
|
||||
@@ -345,6 +347,7 @@ LuaParser::LuaParser() {
|
||||
PlayerArgumentDispatch[EVENT_ENTITY_VARIABLE_SET] = handle_player_entity_variable;
|
||||
PlayerArgumentDispatch[EVENT_ENTITY_VARIABLE_UPDATE] = handle_player_entity_variable;
|
||||
PlayerArgumentDispatch[EVENT_AA_LOSS] = handle_player_aa_loss;
|
||||
PlayerArgumentDispatch[EVENT_SPELL_BLOCKED] = handle_player_spell_blocked;
|
||||
|
||||
ItemArgumentDispatch[EVENT_ITEM_CLICK] = handle_item_click;
|
||||
ItemArgumentDispatch[EVENT_ITEM_CLICK_CAST] = handle_item_click;
|
||||
@@ -399,6 +402,7 @@ LuaParser::LuaParser() {
|
||||
BotArgumentDispatch[EVENT_ENTITY_VARIABLE_DELETE] = handle_bot_entity_variable;
|
||||
BotArgumentDispatch[EVENT_ENTITY_VARIABLE_SET] = handle_bot_entity_variable;
|
||||
BotArgumentDispatch[EVENT_ENTITY_VARIABLE_UPDATE] = handle_bot_entity_variable;
|
||||
BotArgumentDispatch[EVENT_SPELL_BLOCKED] = handle_bot_spell_blocked;
|
||||
#endif
|
||||
|
||||
L = nullptr;
|
||||
@@ -1264,6 +1268,8 @@ void LuaParser::MapFunctions(lua_State *L) {
|
||||
lua_register_bodytypes(),
|
||||
lua_register_filters(),
|
||||
lua_register_message_types(),
|
||||
lua_register_zone_types(),
|
||||
lua_register_languages(),
|
||||
lua_register_entity(),
|
||||
lua_register_encounter(),
|
||||
lua_register_mob(),
|
||||
@@ -1577,6 +1583,25 @@ uint64 LuaParser::GetExperienceForKill(Client *self, Mob *against, bool &ignoreD
|
||||
return retval;
|
||||
}
|
||||
|
||||
|
||||
int64 LuaParser::CommonDamage(Mob *self, Mob* attacker, int64 value, uint16 spell_id, int skill_used, bool avoidable, int8 buff_slot, bool buff_tic, int special, bool &ignore_default)
|
||||
{
|
||||
int64 retval = 0;
|
||||
for (auto &mod : mods_) {
|
||||
mod.CommonDamage(self, attacker, value, spell_id, skill_used, avoidable, buff_slot, buff_tic, special, retval, ignore_default);
|
||||
}
|
||||
return retval;
|
||||
}
|
||||
|
||||
uint64 LuaParser::HealDamage(Mob *self, Mob* caster, uint64 value, uint16 spell_id, bool &ignore_default)
|
||||
{
|
||||
uint64 retval = 0;
|
||||
for (auto &mod : mods_) {
|
||||
mod.HealDamage(self, caster, value, spell_id, retval, ignore_default);
|
||||
}
|
||||
return retval;
|
||||
}
|
||||
|
||||
int64 LuaParser::CalcSpellEffectValue_formula(Mob *self, uint32 formula, int64 base_value, int64 max_value, int caster_level, uint16 spell_id, int ticsremaining, bool &ignoreDefault)
|
||||
{
|
||||
int64 retval = 0;
|
||||
@@ -1586,6 +1611,13 @@ int64 LuaParser::CalcSpellEffectValue_formula(Mob *self, uint32 formula, int64 b
|
||||
return retval;
|
||||
}
|
||||
|
||||
void LuaParser::RegisterBug(Client *self, BaseBugReportsRepository::BugReports bug, bool &ignore_default)
|
||||
{
|
||||
for (auto &mod : mods_) {
|
||||
mod.RegisterBug(self, bug, ignore_default);
|
||||
}
|
||||
}
|
||||
|
||||
int LuaParser::EventBot(
|
||||
QuestEventID evt,
|
||||
Bot *bot,
|
||||
|
||||
+6
-1
@@ -12,6 +12,8 @@
|
||||
#include "zone_config.h"
|
||||
#include "lua_mod.h"
|
||||
|
||||
#include "../common/repositories/bug_reports_repository.h"
|
||||
|
||||
extern const ZoneConfig *Config;
|
||||
|
||||
struct lua_State;
|
||||
@@ -196,7 +198,10 @@ public:
|
||||
uint32 GetEXPForLevel(Client *self, uint16 level, bool &ignoreDefault);
|
||||
uint64 GetExperienceForKill(Client *self, Mob *against, bool &ignoreDefault);
|
||||
int64 CalcSpellEffectValue_formula(Mob *self, uint32 formula, int64 base_value, int64 max_value, int caster_level, uint16 spell_id, int ticsremaining, bool &ignoreDefault);
|
||||
|
||||
void RegisterBug(Client *self, BaseBugReportsRepository::BugReports bug, bool &ignore_default);
|
||||
int64 CommonDamage(Mob *self, Mob* attacker, int64 value, uint16 spell_id, int skill_used, bool avoidable, int8 buff_slot, bool buff_tic, int special, bool &ignore_default);
|
||||
uint64 HealDamage(Mob *self, Mob* caster, uint64 value, uint16 spell_id, bool &ignore_default);
|
||||
|
||||
private:
|
||||
LuaParser();
|
||||
LuaParser(const LuaParser&);
|
||||
|
||||
+103
-4
@@ -626,6 +626,39 @@ void handle_npc_entity_variable(
|
||||
}
|
||||
}
|
||||
|
||||
void handle_npc_spell_blocked(
|
||||
QuestInterface *parse,
|
||||
lua_State* L,
|
||||
NPC* npc,
|
||||
Mob *init,
|
||||
std::string data,
|
||||
uint32 extra_data,
|
||||
std::vector<std::any> *extra_pointers
|
||||
)
|
||||
{
|
||||
Seperator sep(data.c_str());
|
||||
|
||||
lua_pushinteger(L, Strings::ToUnsignedInt(sep.arg[0]));
|
||||
lua_setfield(L, -2, "blocking_spell_id");
|
||||
|
||||
lua_pushinteger(L, Strings::ToUnsignedInt(sep.arg[1]));
|
||||
lua_setfield(L, -2, "cast_spell_id");
|
||||
|
||||
const uint32 blocking_spell_id = Strings::ToUnsignedInt(sep.arg[0]);
|
||||
|
||||
Lua_Spell l_spell_one(IsValidSpell(blocking_spell_id) ? &spells[blocking_spell_id] : nullptr);
|
||||
luabind::adl::object l_spell_one_o = luabind::adl::object(L, l_spell_one);
|
||||
l_spell_one_o.push(L);
|
||||
lua_setfield(L, -2, "blocking_spell");
|
||||
|
||||
const uint32 cast_spell_id = Strings::ToUnsignedInt(sep.arg[0]);
|
||||
|
||||
Lua_Spell l_spell_two(IsValidSpell(cast_spell_id) ? &spells[cast_spell_id] : nullptr);
|
||||
luabind::adl::object l_spell_two_o = luabind::adl::object(L, l_spell_two);
|
||||
l_spell_two_o.push(L);
|
||||
lua_setfield(L, -2, "cast_spell");
|
||||
}
|
||||
|
||||
// Player
|
||||
void handle_player_say(
|
||||
QuestInterface *parse,
|
||||
@@ -1245,9 +1278,9 @@ void handle_player_consider(
|
||||
lua_setfield(L, -2, "entity_id");
|
||||
|
||||
if (extra_pointers && extra_pointers->size() == 1) {
|
||||
Lua_NPC l_npc(std::any_cast<NPC*>(extra_pointers->at(0)));
|
||||
luabind::adl::object l_npc_o = luabind::adl::object(L, l_npc);
|
||||
l_npc_o.push(L);
|
||||
Lua_Mob l_mob(std::any_cast<Mob*>(extra_pointers->at(0)));
|
||||
luabind::adl::object l_mob_o = luabind::adl::object(L, l_mob);
|
||||
l_mob_o.push(L);
|
||||
lua_setfield(L, -2, "other");
|
||||
}
|
||||
}
|
||||
@@ -1674,11 +1707,44 @@ void handle_player_aa_loss(
|
||||
std::string data,
|
||||
uint32 extra_data,
|
||||
std::vector<std::any> *extra_pointers
|
||||
) {
|
||||
)
|
||||
{
|
||||
lua_pushinteger(L, Strings::ToInt(data));
|
||||
lua_setfield(L, -2, "aa_lost");
|
||||
}
|
||||
|
||||
void handle_player_spell_blocked(
|
||||
QuestInterface *parse,
|
||||
lua_State* L,
|
||||
Client* client,
|
||||
std::string data,
|
||||
uint32 extra_data,
|
||||
std::vector<std::any> *extra_pointers
|
||||
)
|
||||
{
|
||||
Seperator sep(data.c_str());
|
||||
|
||||
lua_pushinteger(L, Strings::ToUnsignedInt(sep.arg[0]));
|
||||
lua_setfield(L, -2, "blocking_spell_id");
|
||||
|
||||
lua_pushinteger(L, Strings::ToUnsignedInt(sep.arg[1]));
|
||||
lua_setfield(L, -2, "cast_spell_id");
|
||||
|
||||
const uint32 blocking_spell_id = Strings::ToUnsignedInt(sep.arg[0]);
|
||||
|
||||
Lua_Spell l_spell_one(IsValidSpell(blocking_spell_id) ? &spells[blocking_spell_id] : nullptr);
|
||||
luabind::adl::object l_spell_one_o = luabind::adl::object(L, l_spell_one);
|
||||
l_spell_one_o.push(L);
|
||||
lua_setfield(L, -2, "blocking_spell");
|
||||
|
||||
const uint32 cast_spell_id = Strings::ToUnsignedInt(sep.arg[0]);
|
||||
|
||||
Lua_Spell l_spell_two(IsValidSpell(cast_spell_id) ? &spells[cast_spell_id] : nullptr);
|
||||
luabind::adl::object l_spell_two_o = luabind::adl::object(L, l_spell_two);
|
||||
l_spell_two_o.push(L);
|
||||
lua_setfield(L, -2, "cast_spell");
|
||||
}
|
||||
|
||||
// Item
|
||||
void handle_item_click(
|
||||
QuestInterface *parse,
|
||||
@@ -2690,4 +2756,37 @@ void handle_bot_entity_variable(
|
||||
}
|
||||
}
|
||||
|
||||
void handle_bot_spell_blocked(
|
||||
QuestInterface *parse,
|
||||
lua_State* L,
|
||||
Bot* bot,
|
||||
Mob *init,
|
||||
std::string data,
|
||||
uint32 extra_data,
|
||||
std::vector<std::any> *extra_pointers
|
||||
)
|
||||
{
|
||||
Seperator sep(data.c_str());
|
||||
|
||||
lua_pushinteger(L, Strings::ToUnsignedInt(sep.arg[0]));
|
||||
lua_setfield(L, -2, "blocking_spell_id");
|
||||
|
||||
lua_pushinteger(L, Strings::ToUnsignedInt(sep.arg[1]));
|
||||
lua_setfield(L, -2, "cast_spell_id");
|
||||
|
||||
const uint32 blocking_spell_id = Strings::ToUnsignedInt(sep.arg[0]);
|
||||
|
||||
Lua_Spell l_spell_one(IsValidSpell(blocking_spell_id) ? &spells[blocking_spell_id] : nullptr);
|
||||
luabind::adl::object l_spell_one_o = luabind::adl::object(L, l_spell_one);
|
||||
l_spell_one_o.push(L);
|
||||
lua_setfield(L, -2, "blocking_spell");
|
||||
|
||||
const uint32 cast_spell_id = Strings::ToUnsignedInt(sep.arg[0]);
|
||||
|
||||
Lua_Spell l_spell_two(IsValidSpell(cast_spell_id) ? &spells[cast_spell_id] : nullptr);
|
||||
luabind::adl::object l_spell_two_o = luabind::adl::object(L, l_spell_two);
|
||||
l_spell_two_o.push(L);
|
||||
lua_setfield(L, -2, "cast_spell");
|
||||
}
|
||||
|
||||
#endif
|
||||
|
||||
@@ -250,6 +250,16 @@ void handle_npc_entity_variable(
|
||||
std::vector<std::any> *extra_pointers
|
||||
);
|
||||
|
||||
void handle_npc_spell_blocked(
|
||||
QuestInterface *parse,
|
||||
lua_State* L,
|
||||
NPC* npc,
|
||||
Mob *init,
|
||||
std::string data,
|
||||
uint32 extra_data,
|
||||
std::vector<std::any> *extra_pointers
|
||||
);
|
||||
|
||||
// Player
|
||||
void handle_player_say(
|
||||
QuestInterface *parse,
|
||||
@@ -836,6 +846,15 @@ void handle_player_aa_loss(
|
||||
std::vector<std::any> *extra_pointers
|
||||
);
|
||||
|
||||
void handle_player_spell_blocked(
|
||||
QuestInterface *parse,
|
||||
lua_State* L,
|
||||
Client* client,
|
||||
std::string data,
|
||||
uint32 extra_data,
|
||||
std::vector<std::any> *extra_pointers
|
||||
);
|
||||
|
||||
// Item
|
||||
void handle_item_click(
|
||||
QuestInterface *parse,
|
||||
@@ -1230,5 +1249,15 @@ void handle_bot_entity_variable(
|
||||
std::vector<std::any> *extra_pointers
|
||||
);
|
||||
|
||||
void handle_bot_spell_blocked(
|
||||
QuestInterface *parse,
|
||||
lua_State* L,
|
||||
Bot* bot,
|
||||
Mob* init,
|
||||
std::string data,
|
||||
uint32 extra_data,
|
||||
std::vector<std::any> *extra_pointers
|
||||
);
|
||||
|
||||
#endif
|
||||
#endif
|
||||
|
||||
+4
-4
@@ -86,6 +86,7 @@ extern volatile bool is_zone_loaded;
|
||||
#include "../common/events/player_event_logs.h"
|
||||
#include "../common/path_manager.h"
|
||||
#include "../common/database/database_update.h"
|
||||
#include "../common/skill_caps.h"
|
||||
#include "zone_event_scheduler.h"
|
||||
#include "zone_cli.h"
|
||||
|
||||
@@ -108,6 +109,7 @@ WorldContentService content_service;
|
||||
PathManager path;
|
||||
PlayerEventLogs player_event_logs;
|
||||
DatabaseUpdate database_update;
|
||||
SkillCaps skill_caps;
|
||||
|
||||
const SPDat_Spell_Struct* spells;
|
||||
int32 SPDAT_RECORDS = -1;
|
||||
@@ -307,6 +309,8 @@ int main(int argc, char **argv)
|
||||
|
||||
player_event_logs.SetDatabase(&database)->Init();
|
||||
|
||||
skill_caps.SetContentDatabase(&content_db)->LoadSkillCaps();
|
||||
|
||||
const auto c = EQEmuConfig::get();
|
||||
if (c->auto_database_updates) {
|
||||
if (database_update.SetDatabase(&database)->HasPendingUpdates()) {
|
||||
@@ -372,10 +376,6 @@ int main(int argc, char **argv)
|
||||
LogError("Failed. But ignoring error and going on..");
|
||||
}
|
||||
|
||||
if (!content_db.LoadSkillCaps(std::string(hotfix_name))) {
|
||||
LogError("Loading skill caps failed!");
|
||||
return 1;
|
||||
}
|
||||
if (!database.LoadSpells(hotfix_name, &SPDAT_RECORDS, &spells)) {
|
||||
LogError("Loading spells failed!");
|
||||
return 1;
|
||||
|
||||
+24
-38
@@ -8,6 +8,7 @@
|
||||
|
||||
#include "zone.h"
|
||||
#include "string_ids.h"
|
||||
#include "../common/skill_caps.h"
|
||||
|
||||
extern volatile bool is_zone_loaded;
|
||||
|
||||
@@ -65,7 +66,7 @@ Merc::Merc(const NPCType* d, float x, float y, float z, float heading)
|
||||
|
||||
int r;
|
||||
for (r = 0; r <= EQ::skills::HIGHEST_SKILL; r++) {
|
||||
skills[r] = content_db.GetSkillCap(GetClass(), (EQ::skills::SkillType)r, GetLevel());
|
||||
skills[r] = skill_caps.GetSkillCap(GetClass(), (EQ::skills::SkillType)r, GetLevel()).cap;
|
||||
}
|
||||
|
||||
size = d->size;
|
||||
@@ -460,15 +461,13 @@ int64 Merc::CalcMaxHP() {
|
||||
//but the actual effect sent on live causes the client
|
||||
//to apply it to (basehp + itemhp).. I will oblige to the client's whims over
|
||||
//the aa description
|
||||
nd += aabonuses.MaxHP; //Natural Durability, Physical Enhancement, Planar Durability
|
||||
nd += aabonuses.MaxHP + spellbonuses.MaxHPChange + itembonuses.MaxHPChange; //Natural Durability, Physical Enhancement, Planar Durability
|
||||
|
||||
max_hp = (float)max_hp * (float)nd / (float)10000; //this is to fix the HP-above-495k issue
|
||||
max_hp += spellbonuses.HP + aabonuses.HP;
|
||||
|
||||
max_hp += GroupLeadershipAAHealthEnhancement();
|
||||
|
||||
max_hp += max_hp * ((spellbonuses.MaxHPChange + itembonuses.MaxHPChange) / 10000.0f);
|
||||
|
||||
if (current_hp > max_hp)
|
||||
current_hp = max_hp;
|
||||
|
||||
@@ -489,23 +488,12 @@ int64 Merc::CalcBaseHP()
|
||||
|
||||
int64 Merc::CalcMaxMana()
|
||||
{
|
||||
switch(GetCasterClass())
|
||||
{
|
||||
case 'I':
|
||||
case 'W': {
|
||||
if (IsIntelligenceCasterClass() || IsWisdomCasterClass()) {
|
||||
max_mana = (CalcBaseMana() + itembonuses.Mana + spellbonuses.Mana + GroupLeadershipAAManaEnhancement());
|
||||
break;
|
||||
}
|
||||
case 'N': {
|
||||
} else {
|
||||
max_mana = 0;
|
||||
break;
|
||||
}
|
||||
default: {
|
||||
LogDebug("Invalid Class [{}] in CalcMaxMana", GetCasterClass());
|
||||
max_mana = 0;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if (max_mana < 0) {
|
||||
max_mana = 0;
|
||||
}
|
||||
@@ -565,12 +553,13 @@ int64 Merc::CalcManaRegen()
|
||||
regen = mana_regen + spellbonuses.ManaRegen + itembonuses.ManaRegen;
|
||||
}
|
||||
|
||||
if(GetCasterClass() == 'I')
|
||||
if (IsIntelligenceCasterClass()) {
|
||||
regen += (itembonuses.HeroicINT / 25);
|
||||
else if(GetCasterClass() == 'W')
|
||||
} else if (IsWisdomCasterClass()) {
|
||||
regen += (itembonuses.HeroicWIS / 25);
|
||||
else
|
||||
} else {
|
||||
regen = 0;
|
||||
}
|
||||
|
||||
//AAs
|
||||
regen += aabonuses.ManaRegen;
|
||||
@@ -581,14 +570,11 @@ int64 Merc::CalcManaRegen()
|
||||
int64 Merc::CalcManaRegenCap()
|
||||
{
|
||||
int64 cap = RuleI(Character, ItemManaRegenCap) + aabonuses.ItemManaRegenCap;
|
||||
switch(GetCasterClass())
|
||||
{
|
||||
case 'I':
|
||||
|
||||
if (IsIntelligenceCasterClass()) {
|
||||
cap += (itembonuses.HeroicINT / 25);
|
||||
break;
|
||||
case 'W':
|
||||
} else if (IsWisdomCasterClass()) {
|
||||
cap += (itembonuses.HeroicWIS / 25);
|
||||
break;
|
||||
}
|
||||
|
||||
return (cap * RuleI(Character, ManaRegenMultiplier) / 100);
|
||||
@@ -783,16 +769,16 @@ void Merc::CalcRestState() {
|
||||
}
|
||||
|
||||
bool Merc::HasSkill(EQ::skills::SkillType skill_id) const {
|
||||
return((GetSkill(skill_id) > 0) && CanHaveSkill(skill_id));
|
||||
return ((GetSkill(skill_id) > 0) && CanHaveSkill(skill_id));
|
||||
}
|
||||
|
||||
bool Merc::CanHaveSkill(EQ::skills::SkillType skill_id) const {
|
||||
return(content_db.GetSkillCap(GetClass(), skill_id, RuleI(Character, MaxLevel)) > 0);
|
||||
return skill_caps.GetSkillCap(GetClass(), skill_id, RuleI(Character, MaxLevel)).cap > 0;
|
||||
//if you don't have it by max level, then odds are you never will?
|
||||
}
|
||||
|
||||
uint16 Merc::MaxSkill(EQ::skills::SkillType skillid, uint16 class_, uint16 level) const {
|
||||
return(content_db.GetSkillCap(class_, skillid, level));
|
||||
return skill_caps.GetSkillCap(class_, skillid, level).cap;
|
||||
}
|
||||
|
||||
void Merc::FillSpawnStruct(NewSpawn_Struct* ns, Mob* ForWho) {
|
||||
@@ -1166,7 +1152,7 @@ void Merc::AI_Process() {
|
||||
float newX = 0;
|
||||
float newY = 0;
|
||||
float newZ = 0;
|
||||
if (PlotPositionAroundTarget(GetTarget(), newX, newY, newZ, false) && GetArchetype() != ARCHETYPE_CASTER) {
|
||||
if (PlotPositionAroundTarget(GetTarget(), newX, newY, newZ, false) && GetArchetype() != Archetype::Caster) {
|
||||
RunTo(newX, newY, newZ);
|
||||
return;
|
||||
}
|
||||
@@ -1314,7 +1300,7 @@ void Merc::AI_Process() {
|
||||
if(AI_EngagedCastCheck()) {
|
||||
MercMeditate(false);
|
||||
}
|
||||
else if(GetArchetype() == ARCHETYPE_CASTER)
|
||||
else if(GetArchetype() == Archetype::Caster)
|
||||
MercMeditate(true);
|
||||
}
|
||||
}
|
||||
@@ -1337,7 +1323,7 @@ void Merc::AI_Process() {
|
||||
//TODO: Implement passive stances.
|
||||
//if(GetStance() != MercStancePassive) {
|
||||
if(!AI_IdleCastCheck() && !IsCasting()) {
|
||||
if(GetArchetype() == ARCHETYPE_CASTER) {
|
||||
if(GetArchetype() == Archetype::Caster) {
|
||||
MercMeditate(true);
|
||||
}
|
||||
}
|
||||
@@ -1792,7 +1778,7 @@ bool Merc::AICastSpell(int8 iChance, uint32 iSpellTypes) {
|
||||
if( !IsImmuneToSpell(selectedMercSpell.spellid, this)
|
||||
&& (CanBuffStack(selectedMercSpell.spellid, mercLevel, true) >= 0)) {
|
||||
|
||||
if( GetArchetype() == ARCHETYPE_MELEE && IsEffectInSpell(selectedMercSpell.spellid, SE_IncreaseSpellHaste)) {
|
||||
if( GetArchetype() == Archetype::Melee && IsEffectInSpell(selectedMercSpell.spellid, SE_IncreaseSpellHaste)) {
|
||||
continue;
|
||||
}
|
||||
|
||||
@@ -1819,7 +1805,7 @@ bool Merc::AICastSpell(int8 iChance, uint32 iSpellTypes) {
|
||||
if( !tar->IsImmuneToSpell(selectedMercSpell.spellid, this)
|
||||
&& (tar->CanBuffStack(selectedMercSpell.spellid, mercLevel, true) >= 0)) {
|
||||
|
||||
if( tar->GetArchetype() == ARCHETYPE_MELEE && IsEffectInSpell(selectedMercSpell.spellid, SE_IncreaseSpellHaste)) {
|
||||
if( tar->GetArchetype() == Archetype::Melee && IsEffectInSpell(selectedMercSpell.spellid, SE_IncreaseSpellHaste)) {
|
||||
continue;
|
||||
}
|
||||
|
||||
@@ -4215,7 +4201,7 @@ const char* Merc::GetRandomName(){
|
||||
//name must begin with an upper-case letter.
|
||||
valid = false;
|
||||
}
|
||||
else if (database.CheckUsedName(rndname)) {
|
||||
else if (!database.IsNameUsed(rndname)) {
|
||||
valid = true;
|
||||
}
|
||||
else {
|
||||
@@ -5390,7 +5376,7 @@ bool Merc::RemoveMercFromGroup(Merc* merc, Group* group) {
|
||||
{
|
||||
if(merc->GetMercenaryCharacterID() != 0)
|
||||
{
|
||||
database.SetGroupID(merc->GetName(), 0, merc->GetMercenaryCharacterID(), true);
|
||||
Group::RemoveFromGroup(merc);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -5475,7 +5461,7 @@ bool Merc::MercJoinClientGroup() {
|
||||
|
||||
if (AddMercToGroup(this, g))
|
||||
{
|
||||
database.SetGroupID(mercOwner->GetName(), g->GetID(), mercOwner->CharacterID(), false);
|
||||
g->AddToGroup(mercOwner);
|
||||
database.SetGroupLeaderName(g->GetID(), mercOwner->GetName());
|
||||
database.RefreshGroupFromDB(mercOwner);
|
||||
g->SaveGroupLeaderAA();
|
||||
|
||||
+154
-125
@@ -940,19 +940,16 @@ int Mob::_GetFearSpeed() const {
|
||||
return speed_mod;
|
||||
}
|
||||
|
||||
int64 Mob::CalcMaxMana() {
|
||||
switch (GetCasterClass()) {
|
||||
case 'I':
|
||||
max_mana = (((GetINT()/2)+1) * GetLevel()) + spellbonuses.Mana + itembonuses.Mana;
|
||||
break;
|
||||
case 'W':
|
||||
max_mana = (((GetWIS()/2)+1) * GetLevel()) + spellbonuses.Mana + itembonuses.Mana;
|
||||
break;
|
||||
case 'N':
|
||||
default:
|
||||
max_mana = 0;
|
||||
break;
|
||||
int64 Mob::CalcMaxMana()
|
||||
{
|
||||
if (IsIntelligenceCasterClass()) {
|
||||
max_mana = (((GetINT() / 2) + 1) * GetLevel()) + spellbonuses.Mana + itembonuses.Mana;
|
||||
} else if (IsWisdomCasterClass()) {
|
||||
max_mana = (((GetWIS() / 2) + 1) * GetLevel()) + spellbonuses.Mana + itembonuses.Mana;
|
||||
} else {
|
||||
max_mana = 0;
|
||||
}
|
||||
|
||||
if (max_mana < 0) {
|
||||
max_mana = 0;
|
||||
}
|
||||
@@ -981,90 +978,155 @@ int64 Mob::GetSpellHPBonuses() {
|
||||
return spell_hp;
|
||||
}
|
||||
|
||||
char Mob::GetCasterClass() const {
|
||||
switch(class_)
|
||||
{
|
||||
case Class::Cleric:
|
||||
case Class::Paladin:
|
||||
case Class::Ranger:
|
||||
case Class::Druid:
|
||||
case Class::Shaman:
|
||||
case Class::Beastlord:
|
||||
case Class::ClericGM:
|
||||
case Class::PaladinGM:
|
||||
case Class::RangerGM:
|
||||
case Class::DruidGM:
|
||||
case Class::ShamanGM:
|
||||
case Class::BeastlordGM:
|
||||
return 'W';
|
||||
break;
|
||||
|
||||
case Class::ShadowKnight:
|
||||
case Class::Bard:
|
||||
case Class::Necromancer:
|
||||
case Class::Wizard:
|
||||
case Class::Magician:
|
||||
case Class::Enchanter:
|
||||
case Class::ShadowKnightGM:
|
||||
case Class::BardGM:
|
||||
case Class::NecromancerGM:
|
||||
case Class::WizardGM:
|
||||
case Class::MagicianGM:
|
||||
case Class::EnchanterGM:
|
||||
return 'I';
|
||||
break;
|
||||
|
||||
default:
|
||||
return 'N';
|
||||
break;
|
||||
bool Mob::IsIntelligenceCasterClass() const
|
||||
{
|
||||
switch (GetClass()) {
|
||||
case Class::ShadowKnight:
|
||||
case Class::Bard:
|
||||
case Class::Necromancer:
|
||||
case Class::Wizard:
|
||||
case Class::Magician:
|
||||
case Class::Enchanter:
|
||||
case Class::ShadowKnightGM:
|
||||
case Class::BardGM:
|
||||
case Class::NecromancerGM:
|
||||
case Class::WizardGM:
|
||||
case Class::MagicianGM:
|
||||
case Class::EnchanterGM:
|
||||
return true;
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
uint8 Mob::GetArchetype() const {
|
||||
switch(class_)
|
||||
{
|
||||
case Class::Paladin:
|
||||
case Class::Ranger:
|
||||
case Class::ShadowKnight:
|
||||
case Class::Bard:
|
||||
case Class::Beastlord:
|
||||
case Class::PaladinGM:
|
||||
case Class::RangerGM:
|
||||
case Class::ShadowKnightGM:
|
||||
case Class::BardGM:
|
||||
case Class::BeastlordGM:
|
||||
return ARCHETYPE_HYBRID;
|
||||
break;
|
||||
case Class::Cleric:
|
||||
case Class::Druid:
|
||||
case Class::Shaman:
|
||||
case Class::Necromancer:
|
||||
case Class::Wizard:
|
||||
case Class::Magician:
|
||||
case Class::Enchanter:
|
||||
case Class::ClericGM:
|
||||
case Class::DruidGM:
|
||||
case Class::ShamanGM:
|
||||
case Class::NecromancerGM:
|
||||
case Class::WizardGM:
|
||||
case Class::MagicianGM:
|
||||
case Class::EnchanterGM:
|
||||
return ARCHETYPE_CASTER;
|
||||
break;
|
||||
case Class::Warrior:
|
||||
case Class::Monk:
|
||||
case Class::Rogue:
|
||||
case Class::Berserker:
|
||||
case Class::WarriorGM:
|
||||
case Class::MonkGM:
|
||||
case Class::RogueGM:
|
||||
case Class::BerserkerGM:
|
||||
return ARCHETYPE_MELEE;
|
||||
break;
|
||||
default:
|
||||
return ARCHETYPE_HYBRID;
|
||||
break;
|
||||
bool Mob::IsPureMeleeClass() const
|
||||
{
|
||||
switch (GetClass()) {
|
||||
case Class::Warrior:
|
||||
case Class::Monk:
|
||||
case Class::Rogue:
|
||||
case Class::Berserker:
|
||||
case Class::WarriorGM:
|
||||
case Class::MonkGM:
|
||||
case Class::RogueGM:
|
||||
case Class::BerserkerGM:
|
||||
return true;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
bool Mob::IsWarriorClass() const
|
||||
{
|
||||
switch (GetClass()) {
|
||||
case Class::Warrior:
|
||||
case Class::Paladin:
|
||||
case Class::Ranger:
|
||||
case Class::ShadowKnight:
|
||||
case Class::Monk:
|
||||
case Class::Bard:
|
||||
case Class::Rogue:
|
||||
case Class::Beastlord:
|
||||
case Class::Berserker:
|
||||
case Class::WarriorGM:
|
||||
case Class::PaladinGM:
|
||||
case Class::RangerGM:
|
||||
case Class::ShadowKnightGM:
|
||||
case Class::MonkGM:
|
||||
case Class::BardGM:
|
||||
case Class::RogueGM:
|
||||
case Class::BeastlordGM:
|
||||
case Class::BerserkerGM:
|
||||
return true;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
bool Mob::IsWisdomCasterClass() const
|
||||
{
|
||||
switch (GetClass()) {
|
||||
case Class::Cleric:
|
||||
case Class::Paladin:
|
||||
case Class::Ranger:
|
||||
case Class::Druid:
|
||||
case Class::Shaman:
|
||||
case Class::Beastlord:
|
||||
case Class::ClericGM:
|
||||
case Class::PaladinGM:
|
||||
case Class::RangerGM:
|
||||
case Class::DruidGM:
|
||||
case Class::ShamanGM:
|
||||
case Class::BeastlordGM:
|
||||
return true;
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
uint8 Mob::GetArchetype() const
|
||||
{
|
||||
switch (GetClass()) {
|
||||
case Class::Paladin:
|
||||
case Class::Ranger:
|
||||
case Class::ShadowKnight:
|
||||
case Class::Bard:
|
||||
case Class::Beastlord:
|
||||
case Class::PaladinGM:
|
||||
case Class::RangerGM:
|
||||
case Class::ShadowKnightGM:
|
||||
case Class::BardGM:
|
||||
case Class::BeastlordGM:
|
||||
return Archetype::Hybrid;
|
||||
case Class::Cleric:
|
||||
case Class::Druid:
|
||||
case Class::Shaman:
|
||||
case Class::Necromancer:
|
||||
case Class::Wizard:
|
||||
case Class::Magician:
|
||||
case Class::Enchanter:
|
||||
case Class::ClericGM:
|
||||
case Class::DruidGM:
|
||||
case Class::ShamanGM:
|
||||
case Class::NecromancerGM:
|
||||
case Class::WizardGM:
|
||||
case Class::MagicianGM:
|
||||
case Class::EnchanterGM:
|
||||
return Archetype::Caster;
|
||||
case Class::Warrior:
|
||||
case Class::Monk:
|
||||
case Class::Rogue:
|
||||
case Class::Berserker:
|
||||
case Class::WarriorGM:
|
||||
case Class::MonkGM:
|
||||
case Class::RogueGM:
|
||||
case Class::BerserkerGM:
|
||||
return Archetype::Melee;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
|
||||
return Archetype::Hybrid;
|
||||
}
|
||||
|
||||
const std::string Mob::GetArchetypeName()
|
||||
{
|
||||
switch (GetArchetype()) {
|
||||
case Archetype::Hybrid:
|
||||
return "Hybrid";
|
||||
case Archetype::Caster:
|
||||
return "Caster";
|
||||
case Archetype::Melee:
|
||||
return "Melee";
|
||||
default:
|
||||
break;
|
||||
}
|
||||
|
||||
return "Hybrid";
|
||||
}
|
||||
|
||||
void Mob::SetSpawnLastNameByClass(NewSpawn_Struct* ns)
|
||||
@@ -4586,39 +4648,6 @@ bool Mob::CanThisClassTripleAttack() const
|
||||
}
|
||||
}
|
||||
|
||||
bool Mob::IsWarriorClass(void) const
|
||||
{
|
||||
switch(GetClass())
|
||||
{
|
||||
case Class::Warrior:
|
||||
case Class::WarriorGM:
|
||||
case Class::Rogue:
|
||||
case Class::RogueGM:
|
||||
case Class::Monk:
|
||||
case Class::MonkGM:
|
||||
case Class::Paladin:
|
||||
case Class::PaladinGM:
|
||||
case Class::ShadowKnight:
|
||||
case Class::ShadowKnightGM:
|
||||
case Class::Ranger:
|
||||
case Class::RangerGM:
|
||||
case Class::Beastlord:
|
||||
case Class::BeastlordGM:
|
||||
case Class::Berserker:
|
||||
case Class::BerserkerGM:
|
||||
case Class::Bard:
|
||||
case Class::BardGM:
|
||||
{
|
||||
return true;
|
||||
}
|
||||
default:
|
||||
{
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
bool Mob::CanThisClassParry(void) const
|
||||
{
|
||||
if(!IsClient()) {
|
||||
|
||||
+5
-1
@@ -838,8 +838,11 @@ public:
|
||||
virtual void MakePet(uint16 spell_id, const char* pettype, const char *petname = nullptr);
|
||||
virtual void MakePoweredPet(uint16 spell_id, const char* pettype, int16 petpower, const char *petname = nullptr, float in_size = 0.0f);
|
||||
bool IsWarriorClass() const;
|
||||
char GetCasterClass() const;
|
||||
bool IsIntelligenceCasterClass() const;
|
||||
bool IsPureMeleeClass() const;
|
||||
bool IsWisdomCasterClass() const;
|
||||
uint8 GetArchetype() const;
|
||||
const std::string GetArchetypeName();
|
||||
void SetZone(uint32 zone_id, uint32 instance_id);
|
||||
void SendStatsWindow(Client* c, bool use_window);
|
||||
void ShowStats(Client* client);
|
||||
@@ -992,6 +995,7 @@ public:
|
||||
inline void SetDualWieldingSameDelayWeapons(int32 val) { dw_same_delay = val; }
|
||||
bool IsTargetedFocusEffect(int focus_type);
|
||||
bool HasPersistDeathIllusion(int32 spell_id);
|
||||
void DoShieldDamageOnShielderSpellEffect(Mob* shield_target, int64 hit_damage_done, EQ::skills::SkillType skillInUse);
|
||||
|
||||
|
||||
bool TryDoubleMeleeRoundEffect();
|
||||
|
||||
+18
-24
@@ -48,6 +48,7 @@
|
||||
#include "npc_scale_manager.h"
|
||||
|
||||
#include "bot.h"
|
||||
#include "../common/skill_caps.h"
|
||||
|
||||
#include <stdio.h>
|
||||
#include <string>
|
||||
@@ -363,7 +364,7 @@ NPC::NPC(const NPCType *npc_type_data, Spawn2 *in_respawn, const glm::vec4 &posi
|
||||
//give NPCs skill values...
|
||||
int r;
|
||||
for (r = 0; r <= EQ::skills::HIGHEST_SKILL; r++) {
|
||||
skills[r] = content_db.GetSkillCap(GetClass(), (EQ::skills::SkillType)r, moblevel);
|
||||
skills[r] = skill_caps.GetSkillCap(GetClass(), (EQ::skills::SkillType)r, moblevel).cap;
|
||||
}
|
||||
// some overrides -- really we need to be able to set skills for mobs in the DB
|
||||
// There are some known low level SHM/BST pets that do not follow this, which supports
|
||||
@@ -2756,35 +2757,28 @@ void NPC::SetSwarmTarget(int target_id)
|
||||
int64 NPC::CalcMaxMana()
|
||||
{
|
||||
if (npc_mana == 0) {
|
||||
switch (GetCasterClass()) {
|
||||
case 'I':
|
||||
max_mana = (((GetINT() / 2) + 1) * GetLevel()) + spellbonuses.Mana + itembonuses.Mana;
|
||||
break;
|
||||
case 'W':
|
||||
max_mana = (((GetWIS() / 2) + 1) * GetLevel()) + spellbonuses.Mana + itembonuses.Mana;
|
||||
break;
|
||||
default:
|
||||
max_mana = 0;
|
||||
break;
|
||||
if (IsIntelligenceCasterClass()) {
|
||||
max_mana = (((GetINT() / 2) + 1) * GetLevel()) + spellbonuses.Mana + itembonuses.Mana;
|
||||
} else if (IsWisdomCasterClass()) {
|
||||
max_mana = (((GetWIS() / 2) + 1) * GetLevel()) + spellbonuses.Mana + itembonuses.Mana;
|
||||
} else {
|
||||
max_mana = 0;
|
||||
}
|
||||
|
||||
if (max_mana < 0) {
|
||||
max_mana = 0;
|
||||
}
|
||||
|
||||
return max_mana;
|
||||
}
|
||||
else {
|
||||
switch (GetCasterClass()) {
|
||||
case 'I':
|
||||
max_mana = npc_mana + spellbonuses.Mana + itembonuses.Mana;
|
||||
break;
|
||||
case 'W':
|
||||
max_mana = npc_mana + spellbonuses.Mana + itembonuses.Mana;
|
||||
break;
|
||||
default:
|
||||
max_mana = 0;
|
||||
break;
|
||||
} else {
|
||||
if (IsIntelligenceCasterClass()) {
|
||||
max_mana = npc_mana + spellbonuses.Mana + itembonuses.Mana;
|
||||
} else if (IsWisdomCasterClass()) {
|
||||
max_mana = npc_mana + spellbonuses.Mana + itembonuses.Mana;
|
||||
} else {
|
||||
max_mana = 0;
|
||||
}
|
||||
|
||||
if (max_mana < 0) {
|
||||
max_mana = 0;
|
||||
}
|
||||
@@ -3444,7 +3438,7 @@ void NPC::RecalculateSkills()
|
||||
{
|
||||
int r;
|
||||
for (r = 0; r <= EQ::skills::HIGHEST_SKILL; r++) {
|
||||
skills[r] = content_db.GetSkillCap(GetClass(), (EQ::skills::SkillType)r, level);
|
||||
skills[r] = skill_caps.GetSkillCap(GetClass(), (EQ::skills::SkillType)r, level).cap;
|
||||
}
|
||||
|
||||
// some overrides -- really we need to be able to set skills for mobs in the DB
|
||||
|
||||
+22
-1
@@ -197,11 +197,12 @@ public:
|
||||
virtual void FillSpawnStruct(NewSpawn_Struct* ns, Mob* ForWho);
|
||||
|
||||
// loot
|
||||
void AddItem(const EQ::ItemData *item, uint16 charges, bool equip_item = true);
|
||||
void AddItem(const EQ::ItemData *item, uint16 charges, bool equip_item = true, bool quest = false);
|
||||
void AddItem(
|
||||
uint32 item_id,
|
||||
uint16 charges,
|
||||
bool equip_item = true,
|
||||
bool quest = false,
|
||||
uint32 augment_one = 0,
|
||||
uint32 augment_two = 0,
|
||||
uint32 augment_three = 0,
|
||||
@@ -214,10 +215,12 @@ public:
|
||||
void AddLootDropTable(uint32 lootdrop_id, uint8 drop_limit, uint8 min_drop);
|
||||
void CheckGlobalLootTables();
|
||||
void RemoveItem(uint32 item_id, uint16 quantity = 0, uint16 slot = 0);
|
||||
void RemoveItem(LootItem *item_data, uint8 quantity = 0);
|
||||
void CheckTrivialMinMaxLevelDrop(Mob *killer);
|
||||
void ClearLootItems();
|
||||
inline const LootItems &GetLootItems() { return m_loot_items; }
|
||||
LootItem *GetItem(int slot_id);
|
||||
LootItem *GetItemByItemID(int16 itemid);
|
||||
void AddLootCash(uint32 in_copper, uint32 in_silver, uint32 in_gold, uint32 in_platinum);
|
||||
void RemoveLootCash();
|
||||
void QueryLoot(Client *to, bool is_pet_query = false);
|
||||
@@ -238,6 +241,22 @@ public:
|
||||
inline void SetGold(uint32 amt) { m_loot_gold = amt; }
|
||||
inline void SetPlatinum(uint32 amt) { m_loot_platinum = amt; }
|
||||
|
||||
// MultiQuest
|
||||
bool HasQuestLootItem(int16 itemid);
|
||||
bool HasQuestLoot();
|
||||
bool RemoveQuestLootItems(int16 itemid);
|
||||
bool HasRequiredQuestLoot(int16 itemid1, int16 itemid2, int16 itemid3, int16 itemid4);
|
||||
void CleanQuestLootItems();
|
||||
uint8 CountQuestItem(uint16 itemid);
|
||||
uint8 CountQuestItems();
|
||||
bool AddQuestLoot(int16 itemid, int8 charges = 1);
|
||||
void DeleteQuestLoot(int16 itemid1, int16 itemid2 = 0, int16 itemid3 = 0, int16 itemid4 = 0);
|
||||
void DeleteInvalidQuestLoot();
|
||||
|
||||
bool AddPetLoot(int16 itemid, int8 charges = 1, bool fromquest = false);
|
||||
bool HasPetLootItem(int16 itemid);
|
||||
bool RemovePetLootItems(int16 itemid);
|
||||
|
||||
void DescribeAggro(Client *to_who, Mob *mob, bool verbose);
|
||||
virtual void UpdateEquipmentLight();
|
||||
virtual int64 CalcMaxMana();
|
||||
@@ -326,6 +345,8 @@ public:
|
||||
const EQ::ItemData *item2,
|
||||
LootdropEntriesRepository::LootdropEntries loot_drop,
|
||||
bool wear_change = false,
|
||||
bool quest = false,
|
||||
bool pet = false,
|
||||
uint32 augment_one = 0,
|
||||
uint32 augment_two = 0,
|
||||
uint32 augment_three = 0,
|
||||
|
||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user