mirror of
https://github.com/EQEmu/Server.git
synced 2026-06-26 07:17:16 +00:00
Compare commits
26 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
| d3ca636a70 | |||
| 01855d40df | |||
| 748602b04e | |||
| a97a9a0d1c | |||
| a78c754c0e | |||
| ef214f91e9 | |||
| 04a74df0b2 | |||
| c15bfe12eb | |||
| 5702f7bcd1 | |||
| 9a5bf53e11 | |||
| 69c6a7b89a | |||
| 2f0dbc5d15 | |||
| 93c79817cd | |||
| 3296287d70 | |||
| 774a7fa779 | |||
| 1ff4541a9f | |||
| 3448758c03 | |||
| ff4ccfa98f | |||
| d2c3c14ae0 | |||
| a470931fdd | |||
| 078db3460d | |||
| 0980a780d0 | |||
| 7f01bb509c | |||
| 4bb189cbf4 | |||
| b03e8ff0fb | |||
| 6179b7481e |
@@ -1,3 +1,45 @@
|
|||||||
|
## [22.4.5] - 03/03/2023
|
||||||
|
|
||||||
|
### Bots
|
||||||
|
|
||||||
|
* Add additional Heroic Sta/Wis/Int bonuses for Bots. ([#3013](https://github.com/EQEmu/Server/pull/3013)) @Aeadoin 2023-03-01
|
||||||
|
* Cleanup AI_IdleCastCheck Logic ([#3004](https://github.com/EQEmu/Server/pull/3004)) @Aeadoin 2023-02-26
|
||||||
|
|
||||||
|
### Code
|
||||||
|
|
||||||
|
* Delete unused zone/skills.h ([#3007](https://github.com/EQEmu/Server/pull/3007)) @Kinglykrab 2023-02-27
|
||||||
|
* Remove DumpPacketProfile() from client.h ([#3000](https://github.com/EQEmu/Server/pull/3000)) @Kinglykrab 2023-02-26
|
||||||
|
* Remove GetCombinedAC_TEST() from client.h ([#2999](https://github.com/EQEmu/Server/pull/2999)) @Kinglykrab 2023-02-26
|
||||||
|
* Remove GetDamageMultiplier() from client.h ([#3001](https://github.com/EQEmu/Server/pull/3001)) @Kinglykrab 2023-02-26
|
||||||
|
* Remove NumberOfAvailableTitles() from titles.h ([#3006](https://github.com/EQEmu/Server/pull/3006)) @Kinglykrab 2023-02-27
|
||||||
|
* Remove ReturnItemPacket from client.h/inventory.cpp ([#3002](https://github.com/EQEmu/Server/pull/3002)) @Kinglykrab 2023-02-26
|
||||||
|
* Remove class EGNode from mob.h ([#3003](https://github.com/EQEmu/Server/pull/3003)) @Kinglykrab 2023-02-26
|
||||||
|
* Remove unused ClientFactory in client.h ([#2998](https://github.com/EQEmu/Server/pull/2998)) @Kinglykrab 2023-02-26
|
||||||
|
* Remove unused iterator from LoadCharacterDisciplines ([#3012](https://github.com/EQEmu/Server/pull/3012)) @Aeadoin 2023-03-02
|
||||||
|
|
||||||
|
### Crash
|
||||||
|
|
||||||
|
* Fix crash in CheckTradeskillLoreConflict ([#3009](https://github.com/EQEmu/Server/pull/3009)) @Aeadoin 2023-02-28
|
||||||
|
|
||||||
|
### Fixes
|
||||||
|
|
||||||
|
* Account for bad data in Tradeskill Recipe Entries ([#2991](https://github.com/EQEmu/Server/pull/2991)) @Aeadoin 2023-02-25
|
||||||
|
* Fix DoAnim quest method default speed ([#3016](https://github.com/EQEmu/Server/pull/3016)) @Kinglykrab 2023-03-01
|
||||||
|
* Fix an issue where EVENT_TIMER timers would not be cleaned up after zone ([#3018](https://github.com/EQEmu/Server/pull/3018)) @noudess 2023-03-03
|
||||||
|
* Fix for Discipline Loading from Database causing issues with slot_ids ([#3008](https://github.com/EQEmu/Server/pull/3008)) @Aeadoin 2023-02-28
|
||||||
|
* Fix for Lore Components where component is returned. ([#3005](https://github.com/EQEmu/Server/pull/3005)) @Aeadoin 2023-02-27
|
||||||
|
* Fix issue where quest saylink responses would occur before the NPC's response ([#3010](https://github.com/EQEmu/Server/pull/3010)) @Akkadius 2023-03-01
|
||||||
|
* Fix log messages when players join channel ([#2992](https://github.com/EQEmu/Server/pull/2992)) @Valorith 2023-03-03
|
||||||
|
* Fix npcfeature and playerfeature ([#3017](https://github.com/EQEmu/Server/pull/3017)) @Kinglykrab 2023-03-02
|
||||||
|
|
||||||
|
### Quest API
|
||||||
|
|
||||||
|
* Add GetDefaultRaceSize() to Perl/Lua ([#2993](https://github.com/EQEmu/Server/pull/2993)) @Kinglykrab 2023-02-27
|
||||||
|
* Add HasSpecialAbilities() to Perl/Lua ([#2994](https://github.com/EQEmu/Server/pull/2994)) @Kinglykrab 2023-02-27
|
||||||
|
* Add IsBerserk() to Perl/Lua ([#2997](https://github.com/EQEmu/Server/pull/2997)) @Kinglykrab 2023-03-01
|
||||||
|
* Add IsFindable() and IsTrackable() to Perl/Lua ([#2996](https://github.com/EQEmu/Server/pull/2996)) @Kinglykrab 2023-03-01
|
||||||
|
* Add IsUnderwaterOnly() to Perl/Lua ([#2995](https://github.com/EQEmu/Server/pull/2995)) @Kinglykrab 2023-03-01
|
||||||
|
|
||||||
## [22.4.4] - 02/24/2023
|
## [22.4.4] - 02/24/2023
|
||||||
|
|
||||||
### Bots
|
### Bots
|
||||||
|
|||||||
+1
-1
@@ -25,7 +25,7 @@
|
|||||||
|
|
||||||
// Build variables
|
// Build variables
|
||||||
// these get injected during the build pipeline
|
// these get injected during the build pipeline
|
||||||
#define CURRENT_VERSION "22.4.4-dev" // always append -dev to the current version for custom-builds
|
#define CURRENT_VERSION "22.4.5-dev" // always append -dev to the current version for custom-builds
|
||||||
#define LOGIN_VERSION "0.8.0"
|
#define LOGIN_VERSION "0.8.0"
|
||||||
#define COMPILE_DATE __DATE__
|
#define COMPILE_DATE __DATE__
|
||||||
#define COMPILE_TIME __TIME__
|
#define COMPILE_TIME __TIME__
|
||||||
|
|||||||
+1
-1
@@ -1,6 +1,6 @@
|
|||||||
{
|
{
|
||||||
"name": "eqemu-server",
|
"name": "eqemu-server",
|
||||||
"version": "22.4.4",
|
"version": "22.4.5",
|
||||||
"repository": {
|
"repository": {
|
||||||
"type": "git",
|
"type": "git",
|
||||||
"url": "https://github.com/EQEmu/Server.git"
|
"url": "https://github.com/EQEmu/Server.git"
|
||||||
|
|||||||
+5
-5
@@ -48,10 +48,10 @@ ChatChannel::ChatChannel(std::string inName, std::string inOwner, std::string in
|
|||||||
m_moderated = false;
|
m_moderated = false;
|
||||||
|
|
||||||
LogDebug(
|
LogDebug(
|
||||||
"New ChatChannel created: Name: [{}], Owner: [{}], Password: [{}], MinStatus: [{}]",
|
"New ChatChannel created: Name: [{}] Owner: [{}] Password: [{}] MinStatus: [{}]",
|
||||||
m_name.c_str(),
|
m_name,
|
||||||
m_owner.c_str(),
|
m_owner,
|
||||||
m_password.c_str(),
|
m_password,
|
||||||
m_minimum_status
|
m_minimum_status
|
||||||
);
|
);
|
||||||
|
|
||||||
@@ -667,7 +667,7 @@ ChatChannel *ChatChannelList::RemoveClientFromChannel(const std::string& in_chan
|
|||||||
}
|
}
|
||||||
|
|
||||||
LogDebug("Client [{}] removed from channel [{}]. Channel is owned by {}. Command directed: {}", c->GetName(), channel_name, required_channel->GetOwnerName(), command_directed);
|
LogDebug("Client [{}] removed from channel [{}]. Channel is owned by {}. Command directed: {}", c->GetName(), channel_name, required_channel->GetOwnerName(), command_directed);
|
||||||
if (c->GetName() == required_channel->GetOwnerName() && command_directed) { // Check if the client that is leaving is the the channel owner
|
if (c->GetName() == required_channel->GetOwnerName() && command_directed) { // Check if the client that is leaving is the channel owner
|
||||||
LogDebug("Owner left the channel [{}], removing channel from database...", channel_name);
|
LogDebug("Owner left the channel [{}], removing channel from database...", channel_name);
|
||||||
database.DeleteChatChannel(channel_name); // Remove the channel from the database.
|
database.DeleteChatChannel(channel_name); // Remove the channel from the database.
|
||||||
LogDebug("Flagging [{}] channel as temporary...", channel_name);
|
LogDebug("Flagging [{}] channel as temporary...", channel_name);
|
||||||
|
|||||||
+4
-1
@@ -793,7 +793,10 @@ void Clientlist::ProcessOPMailCommand(Client *c, std::string command_string, boo
|
|||||||
case CommandJoin:
|
case CommandJoin:
|
||||||
if (!command_directed) {
|
if (!command_directed) {
|
||||||
//Append saved channels to params
|
//Append saved channels to params
|
||||||
parameters = parameters + ", " + database.CurrentPlayerChannels(c->GetName());
|
const auto saved_channels = database.CurrentPlayerChannels(c->GetName());
|
||||||
|
if (!saved_channels.empty()) {
|
||||||
|
parameters += fmt::format(", {}", Strings::Join(saved_channels, ", "));
|
||||||
|
}
|
||||||
parameters = RemoveDuplicateChannels(parameters);
|
parameters = RemoveDuplicateChannels(parameters);
|
||||||
}
|
}
|
||||||
c->JoinChannels(parameters, command_directed);
|
c->JoinChannels(parameters, command_directed);
|
||||||
|
|||||||
+10
-9
@@ -336,16 +336,17 @@ void UCSDatabase::DeleteChatChannel(const std::string& channel_name)
|
|||||||
LogInfo("Deleting channel [{}] from the database.", channel_name);
|
LogInfo("Deleting channel [{}] from the database.", channel_name);
|
||||||
}
|
}
|
||||||
|
|
||||||
std::string UCSDatabase::CurrentPlayerChannels(const std::string& player_name) {
|
std::vector<std::string> UCSDatabase::CurrentPlayerChannels(const std::string& player_name) {
|
||||||
int current_player_channel_count = CurrentPlayerChannelCount(player_name);
|
auto rows = ChatchannelsRepository::GetWhere(*this, fmt::format("`owner` = '{}'", Strings::Escape(player_name)));
|
||||||
if (current_player_channel_count == 0) {
|
if (rows.empty()) {
|
||||||
return "";
|
return {};
|
||||||
}
|
}
|
||||||
const auto rquery = fmt::format("SELECT GROUP_CONCAT(`name` SEPARATOR ', ') FROM chatchannels WHERE `owner` = '{}'; ", Strings::Escape(player_name));
|
std::vector<std::string> channels = {};
|
||||||
auto results = QueryDatabase(rquery);
|
channels.reserve(rows.size());
|
||||||
auto row = results.begin();
|
for (auto &e: rows) {
|
||||||
std::string channels = row[0];
|
channels.emplace_back(e.name);
|
||||||
LogDebug("Player [{}] has the following permanent channels saved to the database: [{}].", player_name, channels);
|
}
|
||||||
|
LogDebug("Player [{}] has the following [{}] permanent channels saved to the database: [{}].", player_name, rows.size(), Strings::Join(channels, ", "));
|
||||||
return channels;
|
return channels;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
+1
-1
@@ -52,7 +52,7 @@ public:
|
|||||||
void SaveChatChannel(const std::string& channel_name, const std::string& channel_owner, const std::string& channel_password, const uint16& min_status);
|
void SaveChatChannel(const std::string& channel_name, const std::string& channel_owner, const std::string& channel_password, const uint16& min_status);
|
||||||
void DeleteChatChannel(const std::string& channel_name);
|
void DeleteChatChannel(const std::string& channel_name);
|
||||||
int CurrentPlayerChannelCount(const std::string& player_name);
|
int CurrentPlayerChannelCount(const std::string& player_name);
|
||||||
std::string CurrentPlayerChannels(const std::string& player_name);
|
std::vector<std::string> CurrentPlayerChannels(const std::string& player_name);
|
||||||
void GetAccountStatus(Client *c);
|
void GetAccountStatus(Client *c);
|
||||||
void SetChannelPassword(const std::string& channel_name, const std::string& password);
|
void SetChannelPassword(const std::string& channel_name, const std::string& password);
|
||||||
void SetChannelOwner(const std::string& channel_name, const std::string& owner);
|
void SetChannelOwner(const std::string& channel_name, const std::string& owner);
|
||||||
|
|||||||
@@ -255,7 +255,6 @@ SET(zone_headers
|
|||||||
quest_parser_collection.h
|
quest_parser_collection.h
|
||||||
raids.h
|
raids.h
|
||||||
raycast_mesh.h
|
raycast_mesh.h
|
||||||
skills.h
|
|
||||||
shared_task_zone_messaging.h
|
shared_task_zone_messaging.h
|
||||||
spawn2.cpp
|
spawn2.cpp
|
||||||
spawn2.h
|
spawn2.h
|
||||||
|
|||||||
@@ -2470,6 +2470,7 @@ void Bot::AI_Process()
|
|||||||
}
|
}
|
||||||
|
|
||||||
// We also need a leash owner and follow mob (subset of primary AI criteria)
|
// We also need a leash owner and follow mob (subset of primary AI criteria)
|
||||||
|
bot_group->VerifyGroup();
|
||||||
Client* leash_owner = (bot_group->GetLeader() && bot_group->GetLeader()->IsClient() ? bot_group->GetLeader()->CastToClient() : bot_owner);
|
Client* leash_owner = (bot_group->GetLeader() && bot_group->GetLeader()->IsClient() ? bot_group->GetLeader()->CastToClient() : bot_owner);
|
||||||
if (!leash_owner) {
|
if (!leash_owner) {
|
||||||
return;
|
return;
|
||||||
@@ -6133,8 +6134,11 @@ void Bot::ProcessBotOwnerRefDelete(Mob* botOwner) {
|
|||||||
int64 Bot::CalcMaxMana() {
|
int64 Bot::CalcMaxMana() {
|
||||||
switch(GetCasterClass()) {
|
switch(GetCasterClass()) {
|
||||||
case 'I':
|
case 'I':
|
||||||
|
max_mana = (GenerateBaseManaPoints() + itembonuses.Mana + spellbonuses.Mana + GroupLeadershipAAManaEnhancement());
|
||||||
|
max_mana += (GetHeroicINT() * 10);
|
||||||
case 'W': {
|
case 'W': {
|
||||||
max_mana = (GenerateBaseManaPoints() + itembonuses.Mana + spellbonuses.Mana + GroupLeadershipAAManaEnhancement());
|
max_mana = (GenerateBaseManaPoints() + itembonuses.Mana + spellbonuses.Mana + GroupLeadershipAAManaEnhancement());
|
||||||
|
max_mana += (GetHeroicWIS() * 10);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
case 'N': {
|
case 'N': {
|
||||||
@@ -7084,6 +7088,7 @@ int32 Bot::LevelRegen() {
|
|||||||
|
|
||||||
int64 Bot::CalcHPRegen() {
|
int64 Bot::CalcHPRegen() {
|
||||||
int32 regen = (LevelRegen() + itembonuses.HPRegen + spellbonuses.HPRegen);
|
int32 regen = (LevelRegen() + itembonuses.HPRegen + spellbonuses.HPRegen);
|
||||||
|
regen += GetHeroicSTA() / 20;
|
||||||
regen += (aabonuses.HPRegen + GroupLeadershipAAHealthRegeneration());
|
regen += (aabonuses.HPRegen + GroupLeadershipAAHealthRegeneration());
|
||||||
regen = ((regen * RuleI(Character, HPRegenMultiplier)) / 100);
|
regen = ((regen * RuleI(Character, HPRegenMultiplier)) / 100);
|
||||||
return regen;
|
return regen;
|
||||||
@@ -7155,6 +7160,7 @@ int64 Bot::CalcMaxHP() {
|
|||||||
int32 bot_hp = 0;
|
int32 bot_hp = 0;
|
||||||
uint32 nd = 10000;
|
uint32 nd = 10000;
|
||||||
bot_hp += (GenerateBaseHitPoints() + itembonuses.HP);
|
bot_hp += (GenerateBaseHitPoints() + itembonuses.HP);
|
||||||
|
bot_hp += (GetHeroicSTA() * 10);
|
||||||
nd += aabonuses.MaxHP;
|
nd += aabonuses.MaxHP;
|
||||||
bot_hp = ((float)bot_hp * (float)nd / (float)10000);
|
bot_hp = ((float)bot_hp * (float)nd / (float)10000);
|
||||||
bot_hp += (spellbonuses.HP + aabonuses.HP);
|
bot_hp += (spellbonuses.HP + aabonuses.HP);
|
||||||
|
|||||||
+40
-21
@@ -1303,8 +1303,7 @@ bool Bot::AI_IdleCastCheck() {
|
|||||||
|
|
||||||
if (HasGroup() && GetGroup()->GetLeader() && GetGroup()->GetLeader()->IsClient()) {
|
if (HasGroup() && GetGroup()->GetLeader() && GetGroup()->GetLeader()->IsClient()) {
|
||||||
test_against = GetGroup()->GetLeader()->CastToClient();
|
test_against = GetGroup()->GetLeader()->CastToClient();
|
||||||
}
|
} else if (GetOwner() && GetOwner()->IsClient()) {
|
||||||
else if (GetOwner() && GetOwner()->IsClient()) {
|
|
||||||
test_against = GetOwner()->CastToClient();
|
test_against = GetOwner()->CastToClient();
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -1317,17 +1316,12 @@ bool Bot::AI_IdleCastCheck() {
|
|||||||
// Healers WITHOUT pets will check if a heal is needed before buffing.
|
// Healers WITHOUT pets will check if a heal is needed before buffing.
|
||||||
case CLERIC:
|
case CLERIC:
|
||||||
case PALADIN:
|
case PALADIN:
|
||||||
case RANGER:
|
case RANGER: {
|
||||||
case MONK:
|
|
||||||
case ROGUE:
|
|
||||||
case WARRIOR:
|
|
||||||
case BERSERKER: {
|
|
||||||
if (!entity_list.Bot_AICheckCloseBeneficialSpells(this, 100, BotAISpellRange, SpellType_Cure)) {
|
if (!entity_list.Bot_AICheckCloseBeneficialSpells(this, 100, BotAISpellRange, SpellType_Cure)) {
|
||||||
if (!AICastSpell(this, 100, SpellType_Heal)) {
|
if (!AICastSpell(this, 100, SpellType_Heal)) {
|
||||||
if (!entity_list.Bot_AICheckCloseBeneficialSpells(this, 100, BotAISpellRange, SpellType_Heal)) {
|
if (!entity_list.Bot_AICheckCloseBeneficialSpells(this, 100, BotAISpellRange, SpellType_Heal)) {
|
||||||
if (!AICastSpell(this, 100, SpellType_Buff)) {
|
if (!AICastSpell(this, 100, SpellType_Buff)) {
|
||||||
if (!entity_list.Bot_AICheckCloseBeneficialSpells(this, 100, BotAISpellRange, SpellType_Buff)) {
|
if (!entity_list.Bot_AICheckCloseBeneficialSpells(this, 100, BotAISpellRange, SpellType_Buff)) {
|
||||||
//
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -1337,13 +1331,46 @@ bool Bot::AI_IdleCastCheck() {
|
|||||||
result = true;
|
result = true;
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
case MONK:
|
||||||
|
case ROGUE:
|
||||||
|
case WARRIOR:
|
||||||
|
case BERSERKER: {
|
||||||
|
if (!AICastSpell(this, 100, SpellType_Cure)) {
|
||||||
|
if (!AICastSpell(this, 100, SpellType_Heal)) {
|
||||||
|
if (!AICastSpell(this, 100, SpellType_Buff)) {
|
||||||
|
if (!entity_list.Bot_AICheckCloseBeneficialSpells(this, 100, BotAISpellRange, SpellType_Buff)) {
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
result = true;
|
||||||
|
break;
|
||||||
|
}
|
||||||
// Pets class will first cast their pet, then buffs
|
// Pets class will first cast their pet, then buffs
|
||||||
case DRUID:
|
|
||||||
case MAGICIAN:
|
case MAGICIAN:
|
||||||
case SHADOWKNIGHT:
|
case SHADOWKNIGHT:
|
||||||
case SHAMAN:
|
|
||||||
case NECROMANCER:
|
case NECROMANCER:
|
||||||
case ENCHANTER:
|
case ENCHANTER: {
|
||||||
|
if (!AICastSpell(this, 100, SpellType_Pet)) {
|
||||||
|
if (!AICastSpell(this, 100, SpellType_Cure)) {
|
||||||
|
if (!AICastSpell(GetPet(), 100, SpellType_Cure)) {
|
||||||
|
if (!AICastSpell(this, 100, SpellType_Buff)) {
|
||||||
|
if (!AICastSpell(GetPet(), 100, SpellType_Heal)) {
|
||||||
|
if (!entity_list.Bot_AICheckCloseBeneficialSpells(this, 100, BotAISpellRange, SpellType_Buff)) {
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
result = true;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
case DRUID:
|
||||||
|
case SHAMAN:
|
||||||
case BEASTLORD: {
|
case BEASTLORD: {
|
||||||
if (!entity_list.Bot_AICheckCloseBeneficialSpells(this, 100, BotAISpellRange, SpellType_Cure)) {
|
if (!entity_list.Bot_AICheckCloseBeneficialSpells(this, 100, BotAISpellRange, SpellType_Cure)) {
|
||||||
if (!AICastSpell(this, 100, SpellType_Pet)) {
|
if (!AICastSpell(this, 100, SpellType_Pet)) {
|
||||||
@@ -1365,12 +1392,10 @@ bool Bot::AI_IdleCastCheck() {
|
|||||||
}
|
}
|
||||||
case WIZARD: { // This can eventually be move into the BEASTLORD case handler once pre-combat is fully implemented
|
case WIZARD: { // This can eventually be move into the BEASTLORD case handler once pre-combat is fully implemented
|
||||||
if (pre_combat) {
|
if (pre_combat) {
|
||||||
if (!entity_list.Bot_AICheckCloseBeneficialSpells(this, 100, BotAISpellRange, SpellType_Cure)) {
|
|
||||||
if (!AICastSpell(this, 100, SpellType_Pet)) {
|
if (!AICastSpell(this, 100, SpellType_Pet)) {
|
||||||
|
if (!AICastSpell(this, 100, SpellType_Cure)) {
|
||||||
if (!AICastSpell(this, 100, SpellType_Heal)) {
|
if (!AICastSpell(this, 100, SpellType_Heal)) {
|
||||||
if (!entity_list.Bot_AICheckCloseBeneficialSpells(this, 100, BotAISpellRange, SpellType_Heal)) {
|
|
||||||
if (!AICastSpell(this, 100, SpellType_Buff)) {
|
if (!AICastSpell(this, 100, SpellType_Buff)) {
|
||||||
if (!AICastSpell(GetPet(), 100, SpellType_Heal)) {
|
|
||||||
if (!entity_list.Bot_AICheckCloseBeneficialSpells(this, 100, BotAISpellRange, SpellType_PreCombatBuff)) {
|
if (!entity_list.Bot_AICheckCloseBeneficialSpells(this, 100, BotAISpellRange, SpellType_PreCombatBuff)) {
|
||||||
if (!entity_list.Bot_AICheckCloseBeneficialSpells(this, 100, BotAISpellRange, SpellType_Buff)) {
|
if (!entity_list.Bot_AICheckCloseBeneficialSpells(this, 100, BotAISpellRange, SpellType_Buff)) {
|
||||||
}
|
}
|
||||||
@@ -1380,15 +1405,11 @@ bool Bot::AI_IdleCastCheck() {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
|
||||||
}
|
|
||||||
else {
|
else {
|
||||||
if (!entity_list.Bot_AICheckCloseBeneficialSpells(this, 100, BotAISpellRange, SpellType_Cure)) {
|
if (!AICastSpell(this, 100, SpellType_Cure)) {
|
||||||
if (!AICastSpell(this, 100, SpellType_Pet)) {
|
if (!AICastSpell(this, 100, SpellType_Pet)) {
|
||||||
if (!AICastSpell(this, 100, SpellType_Heal)) {
|
if (!AICastSpell(this, 100, SpellType_Heal)) {
|
||||||
if (!entity_list.Bot_AICheckCloseBeneficialSpells(this, 100, BotAISpellRange, SpellType_Heal)) {
|
|
||||||
if (!AICastSpell(this, 100, SpellType_Buff)) {
|
if (!AICastSpell(this, 100, SpellType_Buff)) {
|
||||||
if (!AICastSpell(GetPet(), 100, SpellType_Heal)) {
|
|
||||||
if (!entity_list.Bot_AICheckCloseBeneficialSpells(this, 100, BotAISpellRange, SpellType_Buff)) {
|
if (!entity_list.Bot_AICheckCloseBeneficialSpells(this, 100, BotAISpellRange, SpellType_Buff)) {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -1396,8 +1417,6 @@ bool Bot::AI_IdleCastCheck() {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
result = true;
|
result = true;
|
||||||
break;
|
break;
|
||||||
|
|||||||
@@ -218,11 +218,6 @@ struct ClientReward
|
|||||||
uint32 amount;
|
uint32 amount;
|
||||||
};
|
};
|
||||||
|
|
||||||
class ClientFactory {
|
|
||||||
public:
|
|
||||||
Client *MakeClient(std::shared_ptr<EQStreamInterface> ieqs);
|
|
||||||
};
|
|
||||||
|
|
||||||
class Client : public Mob
|
class Client : public Mob
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
@@ -343,8 +338,6 @@ public:
|
|||||||
bool HasRecipeLearned(uint32 recipe_id);
|
bool HasRecipeLearned(uint32 recipe_id);
|
||||||
bool CanIncreaseTradeskill(EQ::skills::SkillType tradeskill);
|
bool CanIncreaseTradeskill(EQ::skills::SkillType tradeskill);
|
||||||
|
|
||||||
EQApplicationPacket* ReturnItemPacket(int16 slot_id, const EQ::ItemInstance* inst, ItemPacketType packet_type);
|
|
||||||
|
|
||||||
bool GetRevoked() const { return revoked; }
|
bool GetRevoked() const { return revoked; }
|
||||||
void SetRevoked(bool rev) { revoked = rev; }
|
void SetRevoked(bool rev) { revoked = rev; }
|
||||||
inline uint32 GetIP() const { return ip; }
|
inline uint32 GetIP() const { return ip; }
|
||||||
@@ -697,7 +690,6 @@ public:
|
|||||||
void SetFactionLevel(uint32 char_id, uint32 npc_id, uint8 char_class, uint8 char_race, uint8 char_deity, bool quest = false);
|
void SetFactionLevel(uint32 char_id, uint32 npc_id, uint8 char_class, uint8 char_race, uint8 char_deity, bool quest = false);
|
||||||
void SetFactionLevel2(uint32 char_id, int32 faction_id, uint8 char_class, uint8 char_race, uint8 char_deity, int32 value, uint8 temp);
|
void SetFactionLevel2(uint32 char_id, int32 faction_id, uint8 char_class, uint8 char_race, uint8 char_deity, int32 value, uint8 temp);
|
||||||
int32 GetRawItemAC();
|
int32 GetRawItemAC();
|
||||||
uint16 GetCombinedAC_TEST();
|
|
||||||
|
|
||||||
inline uint32 LSAccountID() const { return lsaccountid; }
|
inline uint32 LSAccountID() const { return lsaccountid; }
|
||||||
inline uint32 GetWID() const { return WID; }
|
inline uint32 GetWID() const { return WID; }
|
||||||
@@ -851,9 +843,6 @@ public:
|
|||||||
inline void SetBecomeNPC(bool flag) { npcflag = flag; }
|
inline void SetBecomeNPC(bool flag) { npcflag = flag; }
|
||||||
inline void SetBecomeNPCLevel(uint8 level) { npclevel = level; }
|
inline void SetBecomeNPCLevel(uint8 level) { npclevel = level; }
|
||||||
EQStreamInterface* Connection() { return eqs; }
|
EQStreamInterface* Connection() { return eqs; }
|
||||||
#ifdef PACKET_PROFILER
|
|
||||||
void DumpPacketProfile() { if(eqs) eqs->DumpPacketProfile(); }
|
|
||||||
#endif
|
|
||||||
uint32 GetEquippedItemFromTextureSlot(uint8 material_slot) const; // returns item id
|
uint32 GetEquippedItemFromTextureSlot(uint8 material_slot) const; // returns item id
|
||||||
uint32 GetEquipmentColor(uint8 material_slot) const;
|
uint32 GetEquipmentColor(uint8 material_slot) const;
|
||||||
virtual void UpdateEquipmentLight() { m_Light.Type[EQ::lightsource::LightEquipment] = m_inv.FindBrightestLightType(); m_Light.Level[EQ::lightsource::LightEquipment] = EQ::lightsource::TypeToLevel(m_Light.Type[EQ::lightsource::LightEquipment]); }
|
virtual void UpdateEquipmentLight() { m_Light.Type[EQ::lightsource::LightEquipment] = m_inv.FindBrightestLightType(); m_Light.Level[EQ::lightsource::LightEquipment] = EQ::lightsource::TypeToLevel(m_Light.Type[EQ::lightsource::LightEquipment]); }
|
||||||
@@ -1595,7 +1584,6 @@ public:
|
|||||||
void SetAccountFlag(std::string flag, std::string val);
|
void SetAccountFlag(std::string flag, std::string val);
|
||||||
std::string GetAccountFlag(std::string flag);
|
std::string GetAccountFlag(std::string flag);
|
||||||
void SetGMStatus(int16 new_status);
|
void SetGMStatus(int16 new_status);
|
||||||
float GetDamageMultiplier(EQ::skills::SkillType how_long_has_this_been_missing);
|
|
||||||
void Consume(const EQ::ItemData *item, uint8 type, int16 slot, bool auto_consume);
|
void Consume(const EQ::ItemData *item, uint8 type, int16 slot, bool auto_consume);
|
||||||
void PlayMP3(const char* fname);
|
void PlayMP3(const char* fname);
|
||||||
void ExpeditionSay(const char *str, int ExpID);
|
void ExpeditionSay(const char *str, int ExpID);
|
||||||
|
|||||||
@@ -8737,12 +8737,12 @@ void Client::Handle_OP_ItemLinkClick(const EQApplicationPacket *app)
|
|||||||
}
|
}
|
||||||
|
|
||||||
if (!response.empty()) {
|
if (!response.empty()) {
|
||||||
ChannelMessageReceived(ChatChannel_Say, 0, 100, response.c_str(), nullptr, true);
|
|
||||||
|
|
||||||
if (!silentsaylink) {
|
if (!silentsaylink) {
|
||||||
Message(Chat::LightGray, "You say, '%s'", response.c_str());
|
Message(Chat::LightGray, "You say, '%s'", response.c_str());
|
||||||
}
|
}
|
||||||
|
|
||||||
|
ChannelMessageReceived(ChatChannel_Say, 0, 100, response.c_str(), nullptr, true);
|
||||||
|
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
|
|||||||
@@ -1063,12 +1063,12 @@ void Perl__playertexture(int texture_id)
|
|||||||
quest_manager.playertexture(texture_id);
|
quest_manager.playertexture(texture_id);
|
||||||
}
|
}
|
||||||
|
|
||||||
void Perl__playerfeature(char* feature, int value)
|
void Perl__playerfeature(const char* feature, int value)
|
||||||
{
|
{
|
||||||
quest_manager.playerfeature(feature, value);
|
quest_manager.playerfeature(feature, value);
|
||||||
}
|
}
|
||||||
|
|
||||||
void Perl__npcfeature(char* feature, int value)
|
void Perl__npcfeature(const char* feature, int value)
|
||||||
{
|
{
|
||||||
quest_manager.npcfeature(feature, value);
|
quest_manager.npcfeature(feature, value);
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -3376,31 +3376,6 @@ void Client::SendItemPacket(int16 slot_id, const EQ::ItemInstance* inst, ItemPac
|
|||||||
FastQueuePacket(&outapp);
|
FastQueuePacket(&outapp);
|
||||||
}
|
}
|
||||||
|
|
||||||
EQApplicationPacket* Client::ReturnItemPacket(int16 slot_id, const EQ::ItemInstance* inst, ItemPacketType packet_type)
|
|
||||||
{
|
|
||||||
if (!inst)
|
|
||||||
return nullptr;
|
|
||||||
|
|
||||||
// Serialize item into |-delimited string
|
|
||||||
std::string packet = inst->Serialize(slot_id);
|
|
||||||
|
|
||||||
EmuOpcode opcode = OP_Unknown;
|
|
||||||
EQApplicationPacket* outapp = nullptr;
|
|
||||||
BulkItemPacket_Struct* itempacket = nullptr;
|
|
||||||
|
|
||||||
// Construct packet
|
|
||||||
opcode = OP_ItemPacket;
|
|
||||||
outapp = new EQApplicationPacket(opcode, packet.length()+1);
|
|
||||||
itempacket = (BulkItemPacket_Struct*)outapp->pBuffer;
|
|
||||||
memcpy(itempacket->SerializedItem, packet.c_str(), packet.length());
|
|
||||||
|
|
||||||
#if EQDEBUG >= 9
|
|
||||||
DumpPacket(outapp);
|
|
||||||
#endif
|
|
||||||
|
|
||||||
return outapp;
|
|
||||||
}
|
|
||||||
|
|
||||||
static int16 BandolierSlotToWeaponSlot(int BandolierSlot)
|
static int16 BandolierSlotToWeaponSlot(int BandolierSlot)
|
||||||
{
|
{
|
||||||
switch (BandolierSlot)
|
switch (BandolierSlot)
|
||||||
|
|||||||
@@ -3049,7 +3049,6 @@ bool Lua_Client::IsAutoFireEnabled()
|
|||||||
{
|
{
|
||||||
Lua_Safe_Call_Bool();
|
Lua_Safe_Call_Bool();
|
||||||
return self->AutoFireEnabled();
|
return self->AutoFireEnabled();
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
luabind::scope lua_register_client() {
|
luabind::scope lua_register_client() {
|
||||||
|
|||||||
@@ -2823,6 +2823,22 @@ Lua_HateList Lua_Mob::GetHateListBots(uint32 distance) {
|
|||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
bool Lua_Mob::IsFindable() {
|
||||||
|
Lua_Safe_Call_Bool();
|
||||||
|
return self->IsFindable();
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
bool Lua_Mob::IsTrackable() {
|
||||||
|
Lua_Safe_Call_Bool();
|
||||||
|
return self->IsTrackable();
|
||||||
|
}
|
||||||
|
|
||||||
|
float Lua_Mob::GetDefaultRaceSize() {
|
||||||
|
Lua_Safe_Call_Real();
|
||||||
|
return self->GetDefaultRaceSize();
|
||||||
|
}
|
||||||
|
|
||||||
luabind::scope lua_register_mob() {
|
luabind::scope lua_register_mob() {
|
||||||
return luabind::class_<Lua_Mob, Lua_Entity>("Mob")
|
return luabind::class_<Lua_Mob, Lua_Entity>("Mob")
|
||||||
.def(luabind::constructor<>())
|
.def(luabind::constructor<>())
|
||||||
@@ -3022,6 +3038,7 @@ luabind::scope lua_register_mob() {
|
|||||||
.def("GetDEX", &Lua_Mob::GetDEX)
|
.def("GetDEX", &Lua_Mob::GetDEX)
|
||||||
.def("GetDR", &Lua_Mob::GetDR)
|
.def("GetDR", &Lua_Mob::GetDR)
|
||||||
.def("GetDamageAmount", (uint32(Lua_Mob::*)(Lua_Mob))&Lua_Mob::GetDamageAmount)
|
.def("GetDamageAmount", (uint32(Lua_Mob::*)(Lua_Mob))&Lua_Mob::GetDamageAmount)
|
||||||
|
.def("GetDefaultRaceSize", &Lua_Mob::GetDefaultRaceSize)
|
||||||
.def("GetDeity", &Lua_Mob::GetDeity)
|
.def("GetDeity", &Lua_Mob::GetDeity)
|
||||||
.def("GetDisplayAC", &Lua_Mob::GetDisplayAC)
|
.def("GetDisplayAC", &Lua_Mob::GetDisplayAC)
|
||||||
.def("GetDrakkinDetails", &Lua_Mob::GetDrakkinDetails)
|
.def("GetDrakkinDetails", &Lua_Mob::GetDrakkinDetails)
|
||||||
@@ -3164,6 +3181,7 @@ luabind::scope lua_register_mob() {
|
|||||||
.def("IsEngaged", (bool(Lua_Mob::*)(void))&Lua_Mob::IsEngaged)
|
.def("IsEngaged", (bool(Lua_Mob::*)(void))&Lua_Mob::IsEngaged)
|
||||||
.def("IsEnraged", (bool(Lua_Mob::*)(void))&Lua_Mob::IsEnraged)
|
.def("IsEnraged", (bool(Lua_Mob::*)(void))&Lua_Mob::IsEnraged)
|
||||||
.def("IsFeared", (bool(Lua_Mob::*)(void))&Lua_Mob::IsFeared)
|
.def("IsFeared", (bool(Lua_Mob::*)(void))&Lua_Mob::IsFeared)
|
||||||
|
.def("IsFindable", (bool(Lua_Mob::*)(void))&Lua_Mob::IsFindable)
|
||||||
.def("IsHorse", &Lua_Mob::IsHorse)
|
.def("IsHorse", &Lua_Mob::IsHorse)
|
||||||
.def("IsImmuneToSpell", (bool(Lua_Mob::*)(int,Lua_Mob))&Lua_Mob::IsImmuneToSpell)
|
.def("IsImmuneToSpell", (bool(Lua_Mob::*)(int,Lua_Mob))&Lua_Mob::IsImmuneToSpell)
|
||||||
.def("IsInvisible", (bool(Lua_Mob::*)(Lua_Mob))&Lua_Mob::IsInvisible)
|
.def("IsInvisible", (bool(Lua_Mob::*)(Lua_Mob))&Lua_Mob::IsInvisible)
|
||||||
@@ -3179,6 +3197,7 @@ luabind::scope lua_register_mob() {
|
|||||||
.def("IsStunned", (bool(Lua_Mob::*)(void))&Lua_Mob::IsStunned)
|
.def("IsStunned", (bool(Lua_Mob::*)(void))&Lua_Mob::IsStunned)
|
||||||
.def("IsTargetable", (bool(Lua_Mob::*)(void))&Lua_Mob::IsTargetable)
|
.def("IsTargetable", (bool(Lua_Mob::*)(void))&Lua_Mob::IsTargetable)
|
||||||
.def("IsTargeted", &Lua_Mob::IsTargeted)
|
.def("IsTargeted", &Lua_Mob::IsTargeted)
|
||||||
|
.def("IsTrackable", (bool(Lua_Mob::*)(void))&Lua_Mob::IsTrackable)
|
||||||
.def("IsWarriorClass", &Lua_Mob::IsWarriorClass)
|
.def("IsWarriorClass", &Lua_Mob::IsWarriorClass)
|
||||||
.def("Kill", (void(Lua_Mob::*)(void))&Lua_Mob::Kill)
|
.def("Kill", (void(Lua_Mob::*)(void))&Lua_Mob::Kill)
|
||||||
.def("Mesmerize", (void(Lua_Mob::*)(void))&Lua_Mob::Mesmerize)
|
.def("Mesmerize", (void(Lua_Mob::*)(void))&Lua_Mob::Mesmerize)
|
||||||
|
|||||||
@@ -513,6 +513,9 @@ public:
|
|||||||
void CopyHateList(Lua_Mob to);
|
void CopyHateList(Lua_Mob to);
|
||||||
bool IsAttackAllowed(Lua_Mob target);
|
bool IsAttackAllowed(Lua_Mob target);
|
||||||
bool IsAttackAllowed(Lua_Mob target, bool is_spell_attack);
|
bool IsAttackAllowed(Lua_Mob target, bool is_spell_attack);
|
||||||
|
bool IsFindable();
|
||||||
|
bool IsTrackable();
|
||||||
|
float GetDefaultRaceSize();
|
||||||
};
|
};
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
|||||||
@@ -767,6 +767,16 @@ void Lua_NPC::ScaleNPC(uint8 npc_level, bool override_special_abilities)
|
|||||||
self->ScaleNPC(npc_level, true, override_special_abilities);
|
self->ScaleNPC(npc_level, true, override_special_abilities);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
bool Lua_NPC::IsUnderwaterOnly() {
|
||||||
|
Lua_Safe_Call_Bool();
|
||||||
|
return self->IsUnderwaterOnly();
|
||||||
|
}
|
||||||
|
|
||||||
|
bool Lua_NPC::HasSpecialAbilities() {
|
||||||
|
Lua_Safe_Call_Bool();
|
||||||
|
return self->HasSpecialAbilities();
|
||||||
|
}
|
||||||
|
|
||||||
luabind::scope lua_register_npc() {
|
luabind::scope lua_register_npc() {
|
||||||
return luabind::class_<Lua_NPC, Lua_Mob>("NPC")
|
return luabind::class_<Lua_NPC, Lua_Mob>("NPC")
|
||||||
.def(luabind::constructor<>())
|
.def(luabind::constructor<>())
|
||||||
@@ -860,6 +870,7 @@ luabind::scope lua_register_npc() {
|
|||||||
.def("IsRaidTarget", (bool(Lua_NPC::*)(void))&Lua_NPC::IsRaidTarget)
|
.def("IsRaidTarget", (bool(Lua_NPC::*)(void))&Lua_NPC::IsRaidTarget)
|
||||||
.def("IsRareSpawn", (bool(Lua_NPC::*)(void))&Lua_NPC::IsRareSpawn)
|
.def("IsRareSpawn", (bool(Lua_NPC::*)(void))&Lua_NPC::IsRareSpawn)
|
||||||
.def("IsTaunting", (bool(Lua_NPC::*)(void))&Lua_NPC::IsTaunting)
|
.def("IsTaunting", (bool(Lua_NPC::*)(void))&Lua_NPC::IsTaunting)
|
||||||
|
.def("IsUnderwaterOnly", (bool(Lua_NPC::*)(void))&Lua_NPC::IsUnderwaterOnly)
|
||||||
.def("MerchantCloseShop", (void(Lua_NPC::*)(void))&Lua_NPC::MerchantCloseShop)
|
.def("MerchantCloseShop", (void(Lua_NPC::*)(void))&Lua_NPC::MerchantCloseShop)
|
||||||
.def("MerchantOpenShop", (void(Lua_NPC::*)(void))&Lua_NPC::MerchantOpenShop)
|
.def("MerchantOpenShop", (void(Lua_NPC::*)(void))&Lua_NPC::MerchantOpenShop)
|
||||||
.def("ModifyNPCStat", (void(Lua_NPC::*)(std::string,std::string))&Lua_NPC::ModifyNPCStat)
|
.def("ModifyNPCStat", (void(Lua_NPC::*)(std::string,std::string))&Lua_NPC::ModifyNPCStat)
|
||||||
|
|||||||
@@ -174,6 +174,8 @@ public:
|
|||||||
void SetLDoNTrapDetected(bool is_detected);
|
void SetLDoNTrapDetected(bool is_detected);
|
||||||
void ScaleNPC(uint8 npc_level);
|
void ScaleNPC(uint8 npc_level);
|
||||||
void ScaleNPC(uint8 npc_level, bool override_special_abilities);
|
void ScaleNPC(uint8 npc_level, bool override_special_abilities);
|
||||||
|
bool IsUnderwaterOnly();
|
||||||
|
bool HasSpecialAbilities();
|
||||||
};
|
};
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
|||||||
@@ -519,6 +519,8 @@ Mob::Mob(
|
|||||||
|
|
||||||
Mob::~Mob()
|
Mob::~Mob()
|
||||||
{
|
{
|
||||||
|
quest_manager.stopalltimers(this);
|
||||||
|
|
||||||
mMovementManager->RemoveMob(this);
|
mMovementManager->RemoveMob(this);
|
||||||
|
|
||||||
AI_Stop();
|
AI_Stop();
|
||||||
|
|||||||
@@ -42,7 +42,6 @@ char* strn0cpy(char* dest, const char* source, uint32 size);
|
|||||||
|
|
||||||
#define MAX_SPECIAL_ATTACK_PARAMS 8
|
#define MAX_SPECIAL_ATTACK_PARAMS 8
|
||||||
|
|
||||||
class EGNode;
|
|
||||||
class Client;
|
class Client;
|
||||||
class EQApplicationPacket;
|
class EQApplicationPacket;
|
||||||
class Group;
|
class Group;
|
||||||
|
|||||||
@@ -2786,6 +2786,26 @@ Bot* Perl_Mob_GetHateRandomBot(Mob* self) // @categories Hate and Aggro
|
|||||||
return self->GetHateRandomBot();
|
return self->GetHateRandomBot();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
bool Perl_Mob_IsFindable(Mob* self) // @categories Script Utility
|
||||||
|
{
|
||||||
|
return self->IsFindable();
|
||||||
|
}
|
||||||
|
|
||||||
|
bool Perl_Mob_IsTrackable(Mob* self) // @categories Script Utility
|
||||||
|
{
|
||||||
|
return self->IsTrackable();
|
||||||
|
}
|
||||||
|
|
||||||
|
bool Perl_Mob_IsBerserk(Mob* self) // @categories Script Utility
|
||||||
|
{
|
||||||
|
return self->IsBerserk();
|
||||||
|
}
|
||||||
|
|
||||||
|
float Perl_Mob_GetDefaultRaceSize(Mob* self) // @categories Script Utility
|
||||||
|
{
|
||||||
|
return self->GetDefaultRaceSize();
|
||||||
|
}
|
||||||
|
|
||||||
void perl_register_mob()
|
void perl_register_mob()
|
||||||
{
|
{
|
||||||
perl::interpreter perl(PERL_GET_THX);
|
perl::interpreter perl(PERL_GET_THX);
|
||||||
@@ -2970,6 +2990,7 @@ void perl_register_mob()
|
|||||||
package.add("GetClassName", &Perl_Mob_GetClassName);
|
package.add("GetClassName", &Perl_Mob_GetClassName);
|
||||||
package.add("GetCleanName", &Perl_Mob_GetCleanName);
|
package.add("GetCleanName", &Perl_Mob_GetCleanName);
|
||||||
package.add("GetCorruption", &Perl_Mob_GetCorruption);
|
package.add("GetCorruption", &Perl_Mob_GetCorruption);
|
||||||
|
package.add("GetDefaultRaceSize", &Perl_Mob_GetDefaultRaceSize);
|
||||||
package.add("GetDEX", &Perl_Mob_GetDEX);
|
package.add("GetDEX", &Perl_Mob_GetDEX);
|
||||||
package.add("GetDR", &Perl_Mob_GetDR);
|
package.add("GetDR", &Perl_Mob_GetDR);
|
||||||
package.add("GetDamageAmount", &Perl_Mob_GetDamageAmount);
|
package.add("GetDamageAmount", &Perl_Mob_GetDamageAmount);
|
||||||
@@ -3112,6 +3133,7 @@ void perl_register_mob()
|
|||||||
package.add("IsAttackAllowed", (bool(*)(Mob*, Mob*, bool))&Perl_Mob_IsAttackAllowed);
|
package.add("IsAttackAllowed", (bool(*)(Mob*, Mob*, bool))&Perl_Mob_IsAttackAllowed);
|
||||||
package.add("IsBeacon", &Perl_Mob_IsBeacon);
|
package.add("IsBeacon", &Perl_Mob_IsBeacon);
|
||||||
package.add("IsBeneficialAllowed", &Perl_Mob_IsBeneficialAllowed);
|
package.add("IsBeneficialAllowed", &Perl_Mob_IsBeneficialAllowed);
|
||||||
|
package.add("IsBerserk", &Perl_Mob_IsBerserk);
|
||||||
package.add("IsBlind", &Perl_Mob_IsBlind);
|
package.add("IsBlind", &Perl_Mob_IsBlind);
|
||||||
package.add("IsBot", &Perl_Mob_IsBot);
|
package.add("IsBot", &Perl_Mob_IsBot);
|
||||||
package.add("IsCasting", &Perl_Mob_IsCasting);
|
package.add("IsCasting", &Perl_Mob_IsCasting);
|
||||||
@@ -3122,6 +3144,7 @@ void perl_register_mob()
|
|||||||
package.add("IsEngaged", &Perl_Mob_IsEngaged);
|
package.add("IsEngaged", &Perl_Mob_IsEngaged);
|
||||||
package.add("IsEnraged", &Perl_Mob_IsEnraged);
|
package.add("IsEnraged", &Perl_Mob_IsEnraged);
|
||||||
package.add("IsFeared", &Perl_Mob_IsFeared);
|
package.add("IsFeared", &Perl_Mob_IsFeared);
|
||||||
|
package.add("IsFindable", &Perl_Mob_IsFindable);
|
||||||
package.add("IsHorse", &Perl_Mob_IsHorse);
|
package.add("IsHorse", &Perl_Mob_IsHorse);
|
||||||
package.add("IsImmuneToSpell", &Perl_Mob_IsImmuneToSpell);
|
package.add("IsImmuneToSpell", &Perl_Mob_IsImmuneToSpell);
|
||||||
package.add("IsInvisible", (bool(*)(Mob*))&Perl_Mob_IsInvisible);
|
package.add("IsInvisible", (bool(*)(Mob*))&Perl_Mob_IsInvisible);
|
||||||
@@ -3142,6 +3165,7 @@ void perl_register_mob()
|
|||||||
package.add("IsStunned", &Perl_Mob_IsStunned);
|
package.add("IsStunned", &Perl_Mob_IsStunned);
|
||||||
package.add("IsTargetable", &Perl_Mob_IsTargetable);
|
package.add("IsTargetable", &Perl_Mob_IsTargetable);
|
||||||
package.add("IsTargeted", &Perl_Mob_IsTargeted);
|
package.add("IsTargeted", &Perl_Mob_IsTargeted);
|
||||||
|
package.add("IsTrackable", &Perl_Mob_IsTrackable);
|
||||||
package.add("IsTrap", &Perl_Mob_IsTrap);
|
package.add("IsTrap", &Perl_Mob_IsTrap);
|
||||||
package.add("IsWarriorClass", &Perl_Mob_IsWarriorClass);
|
package.add("IsWarriorClass", &Perl_Mob_IsWarriorClass);
|
||||||
package.add("Kill", &Perl_Mob_Kill);
|
package.add("Kill", &Perl_Mob_Kill);
|
||||||
|
|||||||
@@ -765,6 +765,16 @@ void Perl_NPC_ScaleNPC(NPC* self, uint8 npc_level, bool override_special_abiliti
|
|||||||
return self->ScaleNPC(npc_level, override_special_abilities);
|
return self->ScaleNPC(npc_level, override_special_abilities);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
bool Perl_NPC_IsUnderwaterOnly(NPC* self) // @categories Script Utility
|
||||||
|
{
|
||||||
|
return self->IsUnderwaterOnly();
|
||||||
|
}
|
||||||
|
|
||||||
|
bool Perl_NPC_HasSpecialAbilities(NPC* self) // @categories Script Utility
|
||||||
|
{
|
||||||
|
return self->HasSpecialAbilities();
|
||||||
|
}
|
||||||
|
|
||||||
void perl_register_npc()
|
void perl_register_npc()
|
||||||
{
|
{
|
||||||
perl::interpreter perl(PERL_GET_THX);
|
perl::interpreter perl(PERL_GET_THX);
|
||||||
@@ -852,6 +862,7 @@ void perl_register_npc()
|
|||||||
package.add("GetSwarmTarget", &Perl_NPC_GetSwarmTarget);
|
package.add("GetSwarmTarget", &Perl_NPC_GetSwarmTarget);
|
||||||
package.add("GetWaypointMax", &Perl_NPC_GetWaypointMax);
|
package.add("GetWaypointMax", &Perl_NPC_GetWaypointMax);
|
||||||
package.add("HasAISpellEffect", &Perl_NPC_HasAISpellEffect);
|
package.add("HasAISpellEffect", &Perl_NPC_HasAISpellEffect);
|
||||||
|
package.add("HasSpecialAbilities", &Perl_NPC_HasSpecialAbilities);
|
||||||
package.add("HasItem", &Perl_NPC_HasItem);
|
package.add("HasItem", &Perl_NPC_HasItem);
|
||||||
package.add("IsAnimal", &Perl_NPC_IsAnimal);
|
package.add("IsAnimal", &Perl_NPC_IsAnimal);
|
||||||
package.add("IsGuarding", &Perl_NPC_IsGuarding);
|
package.add("IsGuarding", &Perl_NPC_IsGuarding);
|
||||||
@@ -862,6 +873,7 @@ void perl_register_npc()
|
|||||||
package.add("IsRaidTarget", &Perl_NPC_IsRaidTarget);
|
package.add("IsRaidTarget", &Perl_NPC_IsRaidTarget);
|
||||||
package.add("IsRareSpawn", &Perl_NPC_IsRareSpawn);
|
package.add("IsRareSpawn", &Perl_NPC_IsRareSpawn);
|
||||||
package.add("IsTaunting", &Perl_NPC_IsTaunting);
|
package.add("IsTaunting", &Perl_NPC_IsTaunting);
|
||||||
|
package.add("IsUnderwaterOnly", (bool(*)(NPC*))&Perl_NPC_IsUnderwaterOnly);
|
||||||
package.add("MerchantCloseShop", &Perl_NPC_MerchantCloseShop);
|
package.add("MerchantCloseShop", &Perl_NPC_MerchantCloseShop);
|
||||||
package.add("MerchantOpenShop", &Perl_NPC_MerchantOpenShop);
|
package.add("MerchantOpenShop", &Perl_NPC_MerchantOpenShop);
|
||||||
package.add("ModifyNPCStat", &Perl_NPC_ModifyNPCStat);
|
package.add("ModifyNPCStat", &Perl_NPC_ModifyNPCStat);
|
||||||
|
|||||||
+3
-3
@@ -88,7 +88,7 @@ void QuestManager::Process() {
|
|||||||
end = QTimerList.end();
|
end = QTimerList.end();
|
||||||
while (cur != end) {
|
while (cur != end) {
|
||||||
if (cur->Timer_.Enabled() && cur->Timer_.Check()) {
|
if (cur->Timer_.Enabled() && cur->Timer_.Check()) {
|
||||||
if (cur->mob && entity_list.IsMobInZone(cur->mob)) {
|
if (cur->mob) {
|
||||||
if (cur->mob->IsNPC()) {
|
if (cur->mob->IsNPC()) {
|
||||||
if (parse->HasQuestSub(cur->mob->GetNPCTypeID(), EVENT_TIMER)) {
|
if (parse->HasQuestSub(cur->mob->GetNPCTypeID(), EVENT_TIMER)) {
|
||||||
parse->EventNPC(EVENT_TIMER, cur->mob->CastToNPC(), nullptr, cur->name, 0);
|
parse->EventNPC(EVENT_TIMER, cur->mob->CastToNPC(), nullptr, cur->name, 0);
|
||||||
@@ -2130,7 +2130,7 @@ void QuestManager::playertexture(int newtexture)
|
|||||||
initiator->SendIllusionPacket(initiator->GetRace(), 0xFF, newtexture);
|
initiator->SendIllusionPacket(initiator->GetRace(), 0xFF, newtexture);
|
||||||
}
|
}
|
||||||
|
|
||||||
void QuestManager::playerfeature(char *feature, int setting)
|
void QuestManager::playerfeature(const char* feature, int setting)
|
||||||
{
|
{
|
||||||
QuestManagerCurrentQuestVars();
|
QuestManagerCurrentQuestVars();
|
||||||
uint16 Race = initiator->GetRace();
|
uint16 Race = initiator->GetRace();
|
||||||
@@ -2187,7 +2187,7 @@ void QuestManager::playerfeature(char *feature, int setting)
|
|||||||
DrakkinHeritage, DrakkinTattoo, DrakkinDetails, Size);
|
DrakkinHeritage, DrakkinTattoo, DrakkinDetails, Size);
|
||||||
}
|
}
|
||||||
|
|
||||||
void QuestManager::npcfeature(char *feature, int setting)
|
void QuestManager::npcfeature(const char* feature, int setting)
|
||||||
{
|
{
|
||||||
QuestManagerCurrentQuestVars();
|
QuestManagerCurrentQuestVars();
|
||||||
uint16 Race = owner->GetRace();
|
uint16 Race = owner->GetRace();
|
||||||
|
|||||||
+3
-3
@@ -140,7 +140,7 @@ public:
|
|||||||
void movepc(int zone_id, float x, float y, float z, float heading);
|
void movepc(int zone_id, float x, float y, float z, float heading);
|
||||||
void gmmove(float x, float y, float z);
|
void gmmove(float x, float y, float z);
|
||||||
void movegrp(int zoneid, float x, float y, float z);
|
void movegrp(int zoneid, float x, float y, float z);
|
||||||
void doanim(int animation_id, int animation_speed = 1, bool ackreq = true, eqFilterType filter = FilterNone);
|
void doanim(int animation_id, int animation_speed = 0, bool ackreq = true, eqFilterType filter = FilterNone);
|
||||||
void addskill(int skill_id, int value);
|
void addskill(int skill_id, int value);
|
||||||
void setlanguage(int skill_id, int value);
|
void setlanguage(int skill_id, int value);
|
||||||
void setskill(int skill_id, int value);
|
void setskill(int skill_id, int value);
|
||||||
@@ -208,8 +208,8 @@ public:
|
|||||||
void playergender(int gender_id);
|
void playergender(int gender_id);
|
||||||
void playersize(int newsize);
|
void playersize(int newsize);
|
||||||
void playertexture(int newtexture);
|
void playertexture(int newtexture);
|
||||||
void playerfeature(char *feature, int setting);
|
void playerfeature(const char* feature, int setting);
|
||||||
void npcfeature(char *feature, int setting);
|
void npcfeature(const char* feature, int setting);
|
||||||
void popup(const char *title, const char *text, uint32 popupid, uint32 buttons, uint32 Duration);
|
void popup(const char *title, const char *text, uint32 popupid, uint32 buttons, uint32 Duration);
|
||||||
void taskselector(const std::vector<int>& tasks, bool ignore_cooldown = false);
|
void taskselector(const std::vector<int>& tasks, bool ignore_cooldown = false);
|
||||||
void tasksetselector(int tasksettid, bool ignore_cooldown = false);
|
void tasksetselector(int tasksettid, bool ignore_cooldown = false);
|
||||||
|
|||||||
-101
@@ -1,101 +0,0 @@
|
|||||||
/* EQEMu: Everquest Server Emulator
|
|
||||||
Copyright (C) 2001-2002 EQEMu Development Team (http://eqemu.org)
|
|
||||||
|
|
||||||
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 SKILLS_H
|
|
||||||
#define SKILLS_H
|
|
||||||
|
|
||||||
#define HIGHEST_SKILL_UNUSED 74
|
|
||||||
|
|
||||||
|
|
||||||
// Correct Skill Numbers as of 4-14-2002
|
|
||||||
#define _1H_BLUNT_UNUSED 0
|
|
||||||
#define _1H_SLASHING_UNUSED 1
|
|
||||||
#define _2H_BLUNT_UNUSED 2
|
|
||||||
#define _2H_SLASHING_UNUSED 3
|
|
||||||
#define ABJURE_UNUSED 4
|
|
||||||
#define ALTERATION_UNUSED 5
|
|
||||||
#define APPLY_POISON_UNUSED 6
|
|
||||||
#define ARCHERY_UNUSED 7
|
|
||||||
#define BACKSTAB_UNUSED 8
|
|
||||||
#define BIND_WOUND_UNUSED 9
|
|
||||||
#define BASH_UNUSED 10
|
|
||||||
#define BLOCKSKILL_UNUSED 11
|
|
||||||
#define BRASS_INSTRUMENTS_UNUSED 12
|
|
||||||
#define CHANNELING_UNUSED 13
|
|
||||||
#define CONJURATION_UNUSED 14
|
|
||||||
#define DEFENSE_UNUSED 15
|
|
||||||
#define DISARM_UNUSED 16
|
|
||||||
#define DISARM_TRAPS_UNUSED 17
|
|
||||||
#define DIVINATION_UNUSED 18
|
|
||||||
#define DODGE_UNUSED 19
|
|
||||||
#define DOUBLE_ATTACK_UNUSED 20
|
|
||||||
#define DRAGON_PUNCH_UNUSED 21
|
|
||||||
#define DUAL_WIELD_UNUSED 22
|
|
||||||
#define EAGLE_STRIKE_UNUSED 23
|
|
||||||
#define EVOCATION_UNUSED 24
|
|
||||||
#define FEIGN_DEATH_UNUSED 25
|
|
||||||
#define FLYING_KICK_UNUSED 26
|
|
||||||
#define FORAGE_UNUSED 27
|
|
||||||
#define HAND_TO_HAND_UNUSED 28
|
|
||||||
#define HIDE_UNUSED 29
|
|
||||||
#define KICK_UNUSED 30
|
|
||||||
#define MEDITATE_UNUSED 31
|
|
||||||
#define MEND_UNUSED 32
|
|
||||||
#define OFFENSE_UNUSED 33
|
|
||||||
#define PARRY_UNUSED 34
|
|
||||||
#define PICK_LOCK_UNUSED 35
|
|
||||||
#define PIERCING_UNUSED 36
|
|
||||||
#define RIPOSTE_UNUSED 37
|
|
||||||
#define ROUND_KICK_UNUSED 38
|
|
||||||
#define SAFE_FALL_UNUSED 39
|
|
||||||
#define SENSE_HEADING_UNUSED 40
|
|
||||||
#define SINGING_UNUSED 41
|
|
||||||
#define SNEAK_UNUSED 42
|
|
||||||
#define SPECIALIZE_ABJURE_UNUSED 43
|
|
||||||
#define SPECIALIZE_ALTERATION_UNUSED 44
|
|
||||||
#define SPECIALIZE_CONJURATION_UNUSED 45
|
|
||||||
#define SPECIALIZE_DIVINATION_UNUSED 46
|
|
||||||
#define SPECIALIZE_EVOCATION_UNUSED 47
|
|
||||||
#define PICK_POCKETS_UNUSED 48
|
|
||||||
#define STRINGED_INSTRUMENTS_UNUSED 49
|
|
||||||
#define SWIMMING_UNUSED 50
|
|
||||||
#define THROWING_UNUSED 51
|
|
||||||
#define TIGER_CLAW_UNUSED 52
|
|
||||||
#define TRACKING_UNUSED 53
|
|
||||||
#define WIND_INSTRUMENTS_UNUSED 54
|
|
||||||
#define FISHING_UNUSED 55
|
|
||||||
#define MAKE_POISON_UNUSED 56
|
|
||||||
#define TINKERING_UNUSED 57
|
|
||||||
#define RESEARCH_UNUSED 58
|
|
||||||
#define ALCHEMY_UNUSED 59
|
|
||||||
#define BAKING_UNUSED 60
|
|
||||||
#define TAILORING_UNUSED 61
|
|
||||||
#define SENSE_TRAPS_UNUSED 62
|
|
||||||
#define BLACKSMITHING_UNUSED 63
|
|
||||||
#define FLETCHING_UNUSED 64
|
|
||||||
#define BREWING_UNUSED 65
|
|
||||||
#define ALCOHOL_TOLERANCE_UNUSED 66
|
|
||||||
#define BEGGING_UNUSED 67
|
|
||||||
#define JEWELRY_MAKING_UNUSED 68
|
|
||||||
#define POTTERY_UNUSED 69
|
|
||||||
#define PERCUSSION_INSTRUMENTS_UNUSED 70
|
|
||||||
#define INTIMIDATION_UNUSED 71
|
|
||||||
#define BERSERKING_UNUSED 72
|
|
||||||
#define TAUNT_UNUSED 73
|
|
||||||
#define FRENZY_UNUSED 74
|
|
||||||
|
|
||||||
#endif
|
|
||||||
@@ -93,18 +93,6 @@ EQApplicationPacket *TitleManager::MakeTitlesPacket(Client *client)
|
|||||||
return(outapp);
|
return(outapp);
|
||||||
}
|
}
|
||||||
|
|
||||||
int TitleManager::NumberOfAvailableTitles(Client *client)
|
|
||||||
{
|
|
||||||
int count = 0;
|
|
||||||
for (const auto& title : titles) {
|
|
||||||
if (IsClientEligibleForTitle(client, title)) {
|
|
||||||
++count;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
return count;
|
|
||||||
}
|
|
||||||
|
|
||||||
std::string TitleManager::GetPrefix(int title_id)
|
std::string TitleManager::GetPrefix(int title_id)
|
||||||
{
|
{
|
||||||
if (!title_id) {
|
if (!title_id) {
|
||||||
|
|||||||
@@ -51,7 +51,6 @@ public:
|
|||||||
EQApplicationPacket *MakeTitlesPacket(Client *client);
|
EQApplicationPacket *MakeTitlesPacket(Client *client);
|
||||||
std::string GetPrefix(int title_id);
|
std::string GetPrefix(int title_id);
|
||||||
std::string GetSuffix(int title_id);
|
std::string GetSuffix(int title_id);
|
||||||
int NumberOfAvailableTitles(Client *client);
|
|
||||||
bool IsClientEligibleForTitle(Client *client, TitleEntry title);
|
bool IsClientEligibleForTitle(Client *client, TitleEntry title);
|
||||||
bool IsNewAATitleAvailable(int aa_points, int class_id);
|
bool IsNewAATitleAvailable(int aa_points, int class_id);
|
||||||
bool IsNewTradeSkillTitleAvailable(int skill_id, int skill_value);
|
bool IsNewTradeSkillTitleAvailable(int skill_id, int skill_value);
|
||||||
|
|||||||
+39
-8
@@ -1865,10 +1865,10 @@ bool ZoneDatabase::DisableRecipe(uint32 recipe_id)
|
|||||||
|
|
||||||
bool Client::CheckTradeskillLoreConflict(int32 recipe_id)
|
bool Client::CheckTradeskillLoreConflict(int32 recipe_id)
|
||||||
{
|
{
|
||||||
const auto& recipe_entries = TradeskillRecipeEntriesRepository::GetWhere(
|
auto recipe_entries = TradeskillRecipeEntriesRepository::GetWhere(
|
||||||
content_db,
|
content_db,
|
||||||
fmt::format(
|
fmt::format(
|
||||||
"recipe_id = {} ORDER BY id ASC",
|
"recipe_id = {} ORDER BY componentcount DESC",
|
||||||
recipe_id
|
recipe_id
|
||||||
)
|
)
|
||||||
);
|
);
|
||||||
@@ -1876,21 +1876,52 @@ bool Client::CheckTradeskillLoreConflict(int32 recipe_id)
|
|||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
for (auto& e : recipe_entries) {
|
// validate which items from the recipe we will call CheckLoreConflict on
|
||||||
auto item_inst = database.GetItem(e.item_id);
|
for (const auto &tre : recipe_entries) {
|
||||||
if (item_inst) {
|
if (tre.item_id) {
|
||||||
if (item_inst->LoreGroup == 0 || e.componentcount > 0 || e.iscontainer) {
|
auto tre_inst = database.GetItem(tre.item_id);
|
||||||
|
|
||||||
|
// To compare items we iterate against each item in the recipe that have a loregroup.
|
||||||
|
for (auto &tre_update_item : recipe_entries) {
|
||||||
|
bool fi_is_valid = tre_update_item.item_id && tre_inst && tre_inst->LoreGroup != 0;
|
||||||
|
|
||||||
|
if (fi_is_valid) {
|
||||||
|
auto tre_update_item_inst = database.GetItem(tre_update_item.item_id);
|
||||||
|
bool ei_is_valid = tre_update_item_inst && tre_update_item_inst->LoreGroup != 0;
|
||||||
|
|
||||||
|
if (ei_is_valid) {
|
||||||
|
bool unique_lore_group_match = tre_inst->LoreGroup > 0 && tre_inst->LoreGroup == tre_update_item_inst->LoreGroup;
|
||||||
|
bool component_count_is_valid = tre_update_item.componentcount == 0 && tre.componentcount > 0;
|
||||||
|
|
||||||
|
// If the recipe item is a component, and matches a unique lore group (> 0) or the item_id matches another entry in the recipe
|
||||||
|
// zero out the item_id, this will prevent us from doing a lore check inadvertently where
|
||||||
|
// the item is a component, and returned on success, fail, salvage.
|
||||||
|
// or uses an item that is part of a unique loregroup that returns an item of the same unique loregroup
|
||||||
|
if (ei_is_valid && (tre_update_item.item_id == tre.item_id || unique_lore_group_match) && component_count_is_valid) {
|
||||||
|
tre_update_item.item_id = 0;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (tre_inst) {
|
||||||
|
if (tre_inst->LoreGroup == 0 || tre.componentcount > 0 || tre.iscontainer) {
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
if (CheckLoreConflict(item_inst)) {
|
|
||||||
|
if (CheckLoreConflict(tre_inst)) {
|
||||||
EQ::SayLinkEngine linker;
|
EQ::SayLinkEngine linker;
|
||||||
linker.SetLinkType(EQ::saylink::SayLinkItemData);
|
linker.SetLinkType(EQ::saylink::SayLinkItemData);
|
||||||
linker.SetItemData(item_inst);
|
linker.SetItemData(tre_inst);
|
||||||
auto item_link = linker.GenerateLink();
|
auto item_link = linker.GenerateLink();
|
||||||
MessageString(Chat::Red, TRADESKILL_COMBINE_LORE, item_link.c_str());
|
MessageString(Chat::Red, TRADESKILL_COMBINE_LORE, item_link.c_str());
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|||||||
+16
-12
@@ -13,6 +13,7 @@
|
|||||||
#include "zonedb.h"
|
#include "zonedb.h"
|
||||||
#include "aura.h"
|
#include "aura.h"
|
||||||
#include "../common/repositories/criteria/content_filter_criteria.h"
|
#include "../common/repositories/criteria/content_filter_criteria.h"
|
||||||
|
#include "../common/repositories/character_disciplines_repository.h"
|
||||||
#include "../common/repositories/npc_types_repository.h"
|
#include "../common/repositories/npc_types_repository.h"
|
||||||
|
|
||||||
#include <ctime>
|
#include <ctime>
|
||||||
@@ -814,21 +815,24 @@ bool ZoneDatabase::LoadCharacterLeadershipAA(uint32 character_id, PlayerProfile_
|
|||||||
}
|
}
|
||||||
|
|
||||||
bool ZoneDatabase::LoadCharacterDisciplines(uint32 character_id, PlayerProfile_Struct* pp){
|
bool ZoneDatabase::LoadCharacterDisciplines(uint32 character_id, PlayerProfile_Struct* pp){
|
||||||
std::string query = StringFormat(
|
|
||||||
"SELECT "
|
auto character_disciplines = CharacterDisciplinesRepository::GetWhere(
|
||||||
"disc_id "
|
database, fmt::format(
|
||||||
"FROM "
|
"`id` = {} ORDER BY `slot_id`",
|
||||||
"`character_disciplines`"
|
character_id
|
||||||
"WHERE `id` = %u ORDER BY `slot_id`", character_id);
|
)
|
||||||
auto results = database.QueryDatabase(query);
|
);
|
||||||
int i = 0;
|
|
||||||
|
if (character_disciplines.empty()) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
/* Initialize Disciplines */
|
/* Initialize Disciplines */
|
||||||
memset(pp->disciplines.values, 0, (sizeof(pp->disciplines.values[0]) * MAX_PP_DISCIPLINES));
|
memset(pp->disciplines.values, 0, (sizeof(pp->disciplines.values[0]) * MAX_PP_DISCIPLINES));
|
||||||
for (auto& row = results.begin(); row != results.end(); ++row) {
|
for (auto& row : character_disciplines) {
|
||||||
if (i < MAX_PP_DISCIPLINES)
|
if (row.slot_id < MAX_PP_DISCIPLINES && IsValidSpell(row.disc_id)) {
|
||||||
pp->disciplines.values[i] = atoi(row[0]);
|
pp->disciplines.values[row.slot_id] = row.disc_id;
|
||||||
++i;
|
}
|
||||||
}
|
}
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user