From 3a20bbd834acba48d361119dad98b1b057c1db51 Mon Sep 17 00:00:00 2001 From: Luke Wahlmeier Date: Tue, 5 Jan 2016 14:16:29 -0700 Subject: [PATCH 01/56] fixed else error case for eqtime table --- common/database.cpp | 22 +++++++++++----------- 1 file changed, 11 insertions(+), 11 deletions(-) diff --git a/common/database.cpp b/common/database.cpp index 932aa4229..b8889fa06 100644 --- a/common/database.cpp +++ b/common/database.cpp @@ -2185,8 +2185,7 @@ struct TimeOfDay_Struct Database::LoadTime(time_t &realtime) std::string query = StringFormat("SELECT minute,hour,day,month,year,realtime FROM eqtime limit 1"); auto results = QueryDatabase(query); - if (!results.Success() || results.RowCount() == 0) - { + if (!results.Success() || results.RowCount() == 0){ Log.Out(Logs::Detail, Logs::World_Server, "Loading EQ time of day failed. Using defaults."); eqTime.minute = 0; eqTime.hour = 9; @@ -2195,15 +2194,16 @@ struct TimeOfDay_Struct Database::LoadTime(time_t &realtime) eqTime.year = 3100; realtime = time(0); } + else{ + auto row = results.begin(); - auto row = results.begin(); - - eqTime.minute = atoi(row[0]); - eqTime.hour = atoi(row[1]); - eqTime.day = atoi(row[2]); - eqTime.month = atoi(row[3]); - eqTime.year = atoi(row[4]); - realtime = atoi(row[5]); + eqTime.minute = atoi(row[0]); + eqTime.hour = atoi(row[1]); + eqTime.day = atoi(row[2]); + eqTime.month = atoi(row[3]); + eqTime.year = atoi(row[4]); + realtime = atoi(row[5]); + } return eqTime; } @@ -2215,4 +2215,4 @@ bool Database::SaveTime(int8 minute, int8 hour, int8 day, int8 month, int16 year return results.Success(); -} \ No newline at end of file +} From 2b0ee55752d320644d182d43e806054b341d347b Mon Sep 17 00:00:00 2001 From: Uleat Date: Fri, 8 Jan 2016 17:19:10 -0500 Subject: [PATCH 02/56] Add command #findaliases --- common/version.h | 2 +- utils/sql/db_update_manifest.txt | 1 + .../2016_01_08_command_find_aliases.sql | 1 + zone/command.cpp | 33 +++++++++++++++++++ zone/command.h | 1 + 5 files changed, 37 insertions(+), 1 deletion(-) create mode 100644 utils/sql/git/required/2016_01_08_command_find_aliases.sql diff --git a/common/version.h b/common/version.h index 00a999add..b1be73905 100644 --- a/common/version.h +++ b/common/version.h @@ -30,7 +30,7 @@ Manifest: https://github.com/EQEmu/Server/blob/master/utils/sql/db_update_manifest.txt */ -#define CURRENT_BINARY_DATABASE_VERSION 9094 +#define CURRENT_BINARY_DATABASE_VERSION 9095 #ifdef BOTS #define CURRENT_BINARY_BOTS_DATABASE_VERSION 9000 #else diff --git a/utils/sql/db_update_manifest.txt b/utils/sql/db_update_manifest.txt index 86f7ebe7c..952698c6a 100644 --- a/utils/sql/db_update_manifest.txt +++ b/utils/sql/db_update_manifest.txt @@ -348,6 +348,7 @@ 9092|2015_12_17_eqtime.sql|SHOW TABLES LIKE 'eqtime'|empty| 9093|2015_12_21_items_updates_evoitem.sql|SHOW COLUMNS FROM `items` LIKE 'evoitem'|empty| 9094|2015_12_29_quest_zone_events.sql|SELECT * FROM perl_event_export_settings WHERE event_description = 'EVENT_SPAWN_ZONE'|empty| +9095|2016_01_08_command_find_aliases|SELECT * FROM `command_settings` WHERE `command` LIKE 'findaliases'|empty| # Upgrade conditions: # This won't be needed after this system is implemented, but it is used database that are not diff --git a/utils/sql/git/required/2016_01_08_command_find_aliases.sql b/utils/sql/git/required/2016_01_08_command_find_aliases.sql new file mode 100644 index 000000000..ad798dd6a --- /dev/null +++ b/utils/sql/git/required/2016_01_08_command_find_aliases.sql @@ -0,0 +1 @@ +INSERT INTO `command_settings` VALUES ('findaliases', 0, 'fa'); diff --git a/zone/command.cpp b/zone/command.cpp index 5eede229f..3f466fd04 100644 --- a/zone/command.cpp +++ b/zone/command.cpp @@ -194,6 +194,7 @@ int command_init(void) command_add("enablerecipe", "[recipe_id] - Enables a recipe using the recipe id.", 80, command_enablerecipe) || command_add("equipitem", "[slotid(0-21)] - Equip the item on your cursor into the specified slot", 50, command_equipitem) || command_add("face", "- Change the face of your target", 80, command_face) || + command_add("findaliases", "[search term]- Searches for available command aliases, by alias or command", 0, command_findaliases) || command_add("findnpctype", "[search criteria] - Search database NPC types", 100, command_findnpctype) || command_add("findspell", "[searchstring] - Search for a spell", 50, command_findspell) || command_add("findzone", "[search criteria] - Search database zones", 100, command_findzone) || @@ -4945,6 +4946,38 @@ void command_face(Client *c, const Seperator *sep) } } +void command_findaliases(Client *c, const Seperator *sep) +{ + if (!sep->arg[1][0]) { + c->Message(0, "Usage: #findaliases [alias | command]"); + return; + } + + std::map::iterator find_iter = commandaliases.find(sep->arg[1]); + if (find_iter == commandaliases.end()) { + c->Message(15, "No commands or aliases match '%s'", sep->arg[1]); + return; + } + + std::map::iterator command_iter = commandlist.find(find_iter->second); + if (find_iter->second.empty() || command_iter == commandlist.end()) { + c->Message(0, "An unknown condition occurred..."); + return; + } + + c->Message(0, "Available command aliases for '%s':", command_iter->first.c_str()); + + int commandaliasesshown = 0; + for (std::map::iterator alias_iter = commandaliases.begin(); alias_iter != commandaliases.end(); ++alias_iter) { + if (strcasecmp(find_iter->second.c_str(), alias_iter->second.c_str()) || c->Admin() < command_iter->second->access) + continue; + + c->Message(0, "%c%s", COMMAND_CHAR, alias_iter->first.c_str()); + ++commandaliasesshown; + } + c->Message(0, "%d command alias%s listed.", commandaliasesshown, commandaliasesshown != 1 ? "es" : ""); +} + void command_details(Client *c, const Seperator *sep) { Mob *target=c->GetTarget(); diff --git a/zone/command.h b/zone/command.h index 45aa31fa6..eb3633f57 100644 --- a/zone/command.h +++ b/zone/command.h @@ -94,6 +94,7 @@ void command_emoteview(Client* c, const Seperator *sep); void command_enablerecipe(Client *c, const Seperator *sep); void command_equipitem(Client *c, const Seperator *sep); void command_face(Client *c, const Seperator *sep); +void command_findaliases(Client *c, const Seperator *sep); void command_findnpctype(Client *c, const Seperator *sep); void command_findspell(Client *c, const Seperator *sep); void command_findzone(Client *c, const Seperator *sep); From 1aa98d34ca26c176087d30aa64fa32fe5b46426f Mon Sep 17 00:00:00 2001 From: Uleat Date: Fri, 8 Jan 2016 17:35:50 -0500 Subject: [PATCH 03/56] Fix for manifest boo-boo --- utils/sql/db_update_manifest.txt | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/utils/sql/db_update_manifest.txt b/utils/sql/db_update_manifest.txt index 952698c6a..31f3d2ccf 100644 --- a/utils/sql/db_update_manifest.txt +++ b/utils/sql/db_update_manifest.txt @@ -348,7 +348,7 @@ 9092|2015_12_17_eqtime.sql|SHOW TABLES LIKE 'eqtime'|empty| 9093|2015_12_21_items_updates_evoitem.sql|SHOW COLUMNS FROM `items` LIKE 'evoitem'|empty| 9094|2015_12_29_quest_zone_events.sql|SELECT * FROM perl_event_export_settings WHERE event_description = 'EVENT_SPAWN_ZONE'|empty| -9095|2016_01_08_command_find_aliases|SELECT * FROM `command_settings` WHERE `command` LIKE 'findaliases'|empty| +9095|2016_01_08_command_find_aliases.sql|SELECT * FROM `command_settings` WHERE `command` LIKE 'findaliases'|empty| # Upgrade conditions: # This won't be needed after this system is implemented, but it is used database that are not From 6fc5f8fba23885a423bb7060e5cd566e735a4d8f Mon Sep 17 00:00:00 2001 From: "Michael Cook (mackal)" Date: Sun, 10 Jan 2016 15:31:04 -0500 Subject: [PATCH 04/56] Fix stacking issues with SE_DamageModifier and SE_MinDamageModifier --- zone/bonuses.cpp | 34 ++++++++++++++++++++-------------- 1 file changed, 20 insertions(+), 14 deletions(-) diff --git a/zone/bonuses.cpp b/zone/bonuses.cpp index f8edee26d..9e2461bd6 100644 --- a/zone/bonuses.cpp +++ b/zone/bonuses.cpp @@ -1555,9 +1555,12 @@ void Mob::CalcSpellBonuses(StatBonuses* newbon) NegateSpellsBonuses(buffs[i].spellid); } } + + // THIS IS WRONG, leaving for now //this prolly suffer from roundoff error slightly... - newbon->AC = newbon->AC * 10 / 34; //ratio determined impirically from client. - if (GetClass() == BARD) newbon->ManaRegen = 0; // Bards do not get mana regen from spells. + newbon->AC = newbon->AC * 10 / 34; //ratio determined impirically from client. + if (GetClass() == BARD) + newbon->ManaRegen = 0; // Bards do not get mana regen from spells. } void Mob::ApplySpellsBonuses(uint16 spell_id, uint8 casterlevel, StatBonuses *new_bonus, uint16 casterId, @@ -2209,10 +2212,11 @@ void Mob::ApplySpellsBonuses(uint16 spell_id, uint8 casterlevel, StatBonuses *ne // Bad data or unsupported new skill if (base2 > HIGHEST_SKILL) break; - if(base2 == ALL_SKILLS) - new_bonus->DamageModifier[HIGHEST_SKILL+1] += effect_value; - else - new_bonus->DamageModifier[base2] += effect_value; + int skill = base2 == ALL_SKILLS ? HIGHEST_SKILL + 1 : base2; + if (effect_value < 0 && new_bonus->DamageModifier[skill] > effect_value) + new_bonus->DamageModifier[skill] = effect_value; + else if (effect_value > 0 && new_bonus->DamageModifier[skill] < effect_value) + new_bonus->DamageModifier[skill] = effect_value; break; } @@ -2221,10 +2225,11 @@ void Mob::ApplySpellsBonuses(uint16 spell_id, uint8 casterlevel, StatBonuses *ne // Bad data or unsupported new skill if (base2 > HIGHEST_SKILL) break; - if(base2 == ALL_SKILLS) - new_bonus->DamageModifier2[HIGHEST_SKILL+1] += effect_value; - else - new_bonus->DamageModifier2[base2] += effect_value; + int skill = base2 == ALL_SKILLS ? HIGHEST_SKILL + 1 : base2; + if (effect_value < 0 && new_bonus->DamageModifier2[skill] > effect_value) + new_bonus->DamageModifier2[skill] = effect_value; + else if (effect_value > 0 && new_bonus->DamageModifier2[skill] < effect_value) + new_bonus->DamageModifier2[skill] = effect_value; break; } @@ -2233,10 +2238,11 @@ void Mob::ApplySpellsBonuses(uint16 spell_id, uint8 casterlevel, StatBonuses *ne // Bad data or unsupported new skill if (base2 > HIGHEST_SKILL) break; - if(base2 == ALL_SKILLS) - new_bonus->MinDamageModifier[HIGHEST_SKILL+1] += effect_value; - else - new_bonus->MinDamageModifier[base2] += effect_value; + int skill = base2 == ALL_SKILLS ? HIGHEST_SKILL + 1 : base2; + if (effect_value < 0 && new_bonus->MinDamageModifier[skill] > effect_value) + new_bonus->MinDamageModifier[skill] = effect_value; + else if (effect_value > 0 && new_bonus->MinDamageModifier[skill] < effect_value) + new_bonus->MinDamageModifier[skill] = effect_value; break; } From 1711b06836168fa12d5ef69991e0dd5290e0ffa8 Mon Sep 17 00:00:00 2001 From: Tim DeLong Date: Mon, 11 Jan 2016 09:11:38 -0500 Subject: [PATCH 05/56] * LightProfile_Struct::TypeToLevel. The case statement for lightLevelCandle should be lightTypeCandle as the check is on light types, not light levels. Light levels are used for the return value. --- common/item.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/common/item.cpp b/common/item.cpp index 8e8ec6f1a..7ce8e730d 100644 --- a/common/item.cpp +++ b/common/item.cpp @@ -2416,7 +2416,7 @@ uint8 LightProfile_Struct::TypeToLevel(uint8 lightType) return lightLevelSmallMagic; // 3 case lightTypeTorch: return lightLevelTorch; // 2 - case lightLevelCandle: + case lightTypeCandle: return lightLevelCandle; // 1 default: return lightLevelUnlit; // 0 From acb1d14fbd0d75ddac3b65797fffff990f75b8ad Mon Sep 17 00:00:00 2001 From: Natedog2012 Date: Mon, 11 Jan 2016 13:30:23 -0800 Subject: [PATCH 06/56] Cap Underfoot material / IDFile in the spawn packet to 99,9999 MAX. Anything higher will crash client --- common/patches/uf.cpp | 20 +++++++++++++++++--- 1 file changed, 17 insertions(+), 3 deletions(-) diff --git a/common/patches/uf.cpp b/common/patches/uf.cpp index 3535503a0..0efa502c0 100644 --- a/common/patches/uf.cpp +++ b/common/patches/uf.cpp @@ -3048,11 +3048,21 @@ namespace UF VARSTRUCT_ENCODE_TYPE(uint32, Buffer, 0); VARSTRUCT_ENCODE_TYPE(uint32, Buffer, 0); - VARSTRUCT_ENCODE_TYPE(uint32, Buffer, emu->equipment[MaterialPrimary].Material); + if (emu->equipment[MaterialPrimary].Material > 99999) { + VARSTRUCT_ENCODE_TYPE(uint32, Buffer, 63); + } else { + VARSTRUCT_ENCODE_TYPE(uint32, Buffer, emu->equipment[MaterialPrimary].Material); + } + VARSTRUCT_ENCODE_TYPE(uint32, Buffer, 0); VARSTRUCT_ENCODE_TYPE(uint32, Buffer, 0); - VARSTRUCT_ENCODE_TYPE(uint32, Buffer, emu->equipment[MaterialSecondary].Material); + if (emu->equipment[MaterialSecondary].Material > 99999) { + VARSTRUCT_ENCODE_TYPE(uint32, Buffer, 63); + } else { + VARSTRUCT_ENCODE_TYPE(uint32, Buffer, emu->equipment[MaterialSecondary].Material); + } + VARSTRUCT_ENCODE_TYPE(uint32, Buffer, 0); VARSTRUCT_ENCODE_TYPE(uint32, Buffer, 0); } @@ -3062,7 +3072,11 @@ namespace UF structs::EquipStruct *Equipment = (structs::EquipStruct *)Buffer; for (k = 0; k < 9; k++) { - Equipment[k].Material = emu->equipment[k].Material; + if (emu->equipment[k].Material > 99999) { + Equipment[k].Material = 63; + } else { + Equipment[k].Material = emu->equipment[k].Material; + } Equipment[k].Unknown1 = emu->equipment[k].Unknown1; Equipment[k].EliteMaterial = emu->equipment[k].EliteMaterial; } From 21fc487c335cdd0324093b0e3571e222dc5c60e1 Mon Sep 17 00:00:00 2001 From: Uleat Date: Tue, 12 Jan 2016 18:44:51 -0500 Subject: [PATCH 07/56] World tradeskill objects should now exhibit pre-RoF behavior to all clients --- changelog.txt | 3 +++ zone/client_packet.cpp | 12 ++++-------- zone/object.cpp | 32 +++++++++++++++++++------------- 3 files changed, 26 insertions(+), 21 deletions(-) diff --git a/changelog.txt b/changelog.txt index f8ca4c917..899bcc22c 100644 --- a/changelog.txt +++ b/changelog.txt @@ -1,5 +1,8 @@ EQEMu Changelog (Started on Sept 24, 2003 15:50) ------------------------------------------------------- +== 01/12/2016 == +Uleat: Fix for tradeskill containers remaining locked after a RoF+ client leaves. Intermediary fix for RoF+ clients accessing tradeskill containers when in use by another player. + == 12/29/2015 == Akkadius: Implemented standardized zone controller scripts (Rule Zone, UseZoneController) Defaulted to true - When a zone boots, it will spawn an invisible npc by the name of zone_controller diff --git a/zone/client_packet.cpp b/zone/client_packet.cpp index f20ffb5f4..58381db62 100644 --- a/zone/client_packet.cpp +++ b/zone/client_packet.cpp @@ -4253,15 +4253,11 @@ void Client::Handle_OP_ClickObjectAction(const EQApplicationPacket *app) EQApplicationPacket end_trade2(OP_FinishWindow2, 0); QueuePacket(&end_trade2); - return; - // RoF sends a 0 sized packet for closing objects - /* - Object* object = GetTradeskillObject(); - if (object) { - object->CastToObject()->Close(); - } - */ + if (GetTradeskillObject() && GetClientVersion() >= ClientVersion::RoF) + GetTradeskillObject()->CastToObject()->Close(); + + return; } else { diff --git a/zone/object.cpp b/zone/object.cpp index 7255cd9e9..d06a311c0 100644 --- a/zone/object.cpp +++ b/zone/object.cpp @@ -533,20 +533,26 @@ bool Object::HandleClick(Client* sender, const ClickObject_Struct* click_object) ClickObjectAction_Struct* coa = (ClickObjectAction_Struct*)outapp->pBuffer; //TODO: there is prolly a better way to do this. - //if this is not the main user, send them a close and a message - if(user == nullptr || user == sender) - coa->open = 0x01; - else { - coa->open = 0x00; - //sender->Message(13, "Somebody is allready using that container."); - } - m_inuse = true; - coa->type = m_type; - coa->unknown16 = 0x0a; + m_inuse = true; + coa->type = m_type; + coa->unknown16 = 0x0a; - coa->drop_id = click_object->drop_id; - coa->player_id = click_object->player_id; - coa->icon = m_icon; + coa->drop_id = click_object->drop_id; + coa->player_id = click_object->player_id; + coa->icon = m_icon; + + //if this is not the main user, send them a close and a message + if (user == nullptr || user == sender) { + coa->open = 0x01; + } + else { + coa->open = 0x00; + + if (sender->GetClientVersion() >= ClientVersion::RoF) { + coa->drop_id = 0xFFFFFFFF; + sender->Message(0, "Someone else is using that. Try again later."); + } + } if(sender->IsLooting()) { From edeb7d79d174f9c625520ea949d3d896a10a9ce8 Mon Sep 17 00:00:00 2001 From: Athrogate Date: Tue, 12 Jan 2016 19:08:10 -0800 Subject: [PATCH 08/56] Add Lua_Client::ClearCompassMark(). --- changelog.txt | 4 ++++ zone/lua_client.cpp | 6 ++++++ zone/lua_client.h | 1 + 3 files changed, 11 insertions(+) diff --git a/changelog.txt b/changelog.txt index 899bcc22c..2adec24ba 100644 --- a/changelog.txt +++ b/changelog.txt @@ -1,5 +1,9 @@ EQEMu Changelog (Started on Sept 24, 2003 15:50) ------------------------------------------------------- +== 01/12/2016 == +Athrogate: Adding ClearCompassMark() to Lua. + - Lua didn't have ClearCompassMark(). Perl already had this. + == 01/12/2016 == Uleat: Fix for tradeskill containers remaining locked after a RoF+ client leaves. Intermediary fix for RoF+ clients accessing tradeskill containers when in use by another player. diff --git a/zone/lua_client.cpp b/zone/lua_client.cpp index 1e785ce9b..82167c85b 100644 --- a/zone/lua_client.cpp +++ b/zone/lua_client.cpp @@ -1067,6 +1067,11 @@ void Lua_Client::MarkSingleCompassLoc(float in_x, float in_y, float in_z, int co self->MarkSingleCompassLoc(in_x, in_y, in_z, count); } +void Lua_Client::ClearCompassMark() { + Lua_Safe_Call_Void(); + self->MarkSingleCompassLoc(0,0,0,0); +} + int Lua_Client::GetNextAvailableSpellBookSlot() { Lua_Safe_Call_Int(); return self->GetNextAvailableSpellBookSlot(); @@ -1548,6 +1553,7 @@ luabind::scope lua_register_client() { .def("GrantAlternateAdvancementAbility", (bool(Lua_Client::*)(int, int, bool))&Lua_Client::GrantAlternateAdvancementAbility) .def("MarkSingleCompassLoc", (void(Lua_Client::*)(float,float,float))&Lua_Client::MarkSingleCompassLoc) .def("MarkSingleCompassLoc", (void(Lua_Client::*)(float,float,float,int))&Lua_Client::MarkSingleCompassLoc) + .def("ClearCompassMark",(void(Lua_Client::*)(void))&Lua_Client::ClearCompassMark) .def("GetNextAvailableSpellBookSlot", (int(Lua_Client::*)(void))&Lua_Client::GetNextAvailableSpellBookSlot) .def("GetNextAvailableSpellBookSlot", (int(Lua_Client::*)(int))&Lua_Client::GetNextAvailableSpellBookSlot) .def("FindSpellBookSlotBySpellID", (int(Lua_Client::*)(int))&Lua_Client::FindSpellBookSlotBySpellID) diff --git a/zone/lua_client.h b/zone/lua_client.h index 4584edfd0..5353996c2 100644 --- a/zone/lua_client.h +++ b/zone/lua_client.h @@ -240,6 +240,7 @@ public: bool GrantAlternateAdvancementAbility(int aa_id, int points, bool ignore_cost); void MarkSingleCompassLoc(float in_x, float in_y, float in_z); void MarkSingleCompassLoc(float in_x, float in_y, float in_z, int count); + void ClearCompassMark(); int GetNextAvailableSpellBookSlot(); int GetNextAvailableSpellBookSlot(int start); int FindSpellBookSlotBySpellID(int spell_id); From 09b6adf7267efb3cdf25299e4e9f5797c636720f Mon Sep 17 00:00:00 2001 From: Athrogate Date: Tue, 12 Jan 2016 19:08:10 -0800 Subject: [PATCH 09/56] Add Lua_Client::ClearCompassMark(). --- zone/lua_client.cpp | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/zone/lua_client.cpp b/zone/lua_client.cpp index 82167c85b..34906bc00 100644 --- a/zone/lua_client.cpp +++ b/zone/lua_client.cpp @@ -1058,8 +1058,8 @@ bool Lua_Client::GrantAlternateAdvancementAbility(int aa_id, int points, bool ig } void Lua_Client::MarkSingleCompassLoc(float in_x, float in_y, float in_z) { - Lua_Safe_Call_Void(); - self->MarkSingleCompassLoc(in_x, in_y, in_z); + Lua_Safe_Call_Void(); + self->MarkSingleCompassLoc(in_x, in_y, in_z); } void Lua_Client::MarkSingleCompassLoc(float in_x, float in_y, float in_z, int count) { From 0fec2fdfdd37ed882c70f4a1f0154a724bec3fe9 Mon Sep 17 00:00:00 2001 From: Athrogate Date: Tue, 12 Jan 2016 19:08:10 -0800 Subject: [PATCH 10/56] Add Lua_Client::ClearCompassMark(). --- zone/lua_client.cpp | 6 +++--- zone/lua_client.h | 2 +- 2 files changed, 4 insertions(+), 4 deletions(-) diff --git a/zone/lua_client.cpp b/zone/lua_client.cpp index 82167c85b..d77b83c9f 100644 --- a/zone/lua_client.cpp +++ b/zone/lua_client.cpp @@ -1068,8 +1068,8 @@ void Lua_Client::MarkSingleCompassLoc(float in_x, float in_y, float in_z, int co } void Lua_Client::ClearCompassMark() { - Lua_Safe_Call_Void(); - self->MarkSingleCompassLoc(0,0,0,0); + Lua_Safe_Call_Void(); + self->MarkSingleCompassLoc(0,0,0,0); } int Lua_Client::GetNextAvailableSpellBookSlot() { @@ -1553,7 +1553,7 @@ luabind::scope lua_register_client() { .def("GrantAlternateAdvancementAbility", (bool(Lua_Client::*)(int, int, bool))&Lua_Client::GrantAlternateAdvancementAbility) .def("MarkSingleCompassLoc", (void(Lua_Client::*)(float,float,float))&Lua_Client::MarkSingleCompassLoc) .def("MarkSingleCompassLoc", (void(Lua_Client::*)(float,float,float,int))&Lua_Client::MarkSingleCompassLoc) - .def("ClearCompassMark",(void(Lua_Client::*)(void))&Lua_Client::ClearCompassMark) + .def("ClearCompassMark",(void(Lua_Client::*)(void))&Lua_Client::ClearCompassMark) .def("GetNextAvailableSpellBookSlot", (int(Lua_Client::*)(void))&Lua_Client::GetNextAvailableSpellBookSlot) .def("GetNextAvailableSpellBookSlot", (int(Lua_Client::*)(int))&Lua_Client::GetNextAvailableSpellBookSlot) .def("FindSpellBookSlotBySpellID", (int(Lua_Client::*)(int))&Lua_Client::FindSpellBookSlotBySpellID) diff --git a/zone/lua_client.h b/zone/lua_client.h index 5353996c2..36ea2b8a4 100644 --- a/zone/lua_client.h +++ b/zone/lua_client.h @@ -240,7 +240,7 @@ public: bool GrantAlternateAdvancementAbility(int aa_id, int points, bool ignore_cost); void MarkSingleCompassLoc(float in_x, float in_y, float in_z); void MarkSingleCompassLoc(float in_x, float in_y, float in_z, int count); - void ClearCompassMark(); + void ClearCompassMark(); int GetNextAvailableSpellBookSlot(); int GetNextAvailableSpellBookSlot(int start); int FindSpellBookSlotBySpellID(int spell_id); From f8ce556acb834d0c6a3dd860016150b9ced5906e Mon Sep 17 00:00:00 2001 From: Kinglykrab Date: Wed, 13 Jan 2016 07:58:36 -0500 Subject: [PATCH 11/56] Modified #flag functionality for target-based account status refresh. --- changelog.txt | 4 ++++ zone/command.cpp | 10 ++++++++-- 2 files changed, 12 insertions(+), 2 deletions(-) diff --git a/changelog.txt b/changelog.txt index 2adec24ba..4db0256cc 100644 --- a/changelog.txt +++ b/changelog.txt @@ -1,5 +1,9 @@ EQEMu Changelog (Started on Sept 24, 2003 15:50) ------------------------------------------------------- +== 01/13/2016 == +Kinglykrab: Modified #flag so you can refresh your target's account status (GM status level) without them having to relog. + - Just target the person whose flag you want to refresh and type #flag. + == 01/12/2016 == Athrogate: Adding ClearCompassMark() to Lua. - Lua didn't have ClearCompassMark(). Perl already had this. diff --git a/zone/command.cpp b/zone/command.cpp index 3f466fd04..8d4df2b46 100644 --- a/zone/command.cpp +++ b/zone/command.cpp @@ -4395,8 +4395,14 @@ void command_uptime(Client *c, const Seperator *sep) void command_flag(Client *c, const Seperator *sep) { if(sep->arg[2][0] == 0) { - c->UpdateAdmin(); - c->Message(0, "Refreshed your admin flag from DB."); + if (!c->GetTarget() || (c->GetTarget() && c->GetTarget() == c)) { + c->UpdateAdmin(); + c->Message(0, "Refreshed your admin flag from DB."); + } else if (c->GetTarget() && c->GetTarget() != c && c->GetTarget()->IsClient()) { + c->GetTarget()->CastToClient()->UpdateAdmin(); + c->Message(0, "%s's admin flag has been refreshed.", c->GetTarget()->GetName()); + c->GetTarget()->Message(0, "%s refreshed your admin flag.", c->GetName()); + } } else if (!sep->IsNumber(1) || atoi(sep->arg[1]) < -2 || atoi(sep->arg[1]) > 255 || strlen(sep->arg[2]) == 0) c->Message(0, "Usage: #flag [status] [acctname]"); From 6db397f07d71cd8526d5aa8fd0f020cd40b28e23 Mon Sep 17 00:00:00 2001 From: Uleat Date: Wed, 13 Jan 2016 15:10:21 -0500 Subject: [PATCH 12/56] Added item link functionality to #summonitem (thanks Kinglykrab!) --- changelog.txt | 2 +- zone/command.cpp | 74 ++++++++++++++++++++++++++++++------------------ 2 files changed, 47 insertions(+), 29 deletions(-) diff --git a/changelog.txt b/changelog.txt index 4db0256cc..e23ef39c9 100644 --- a/changelog.txt +++ b/changelog.txt @@ -9,7 +9,7 @@ Athrogate: Adding ClearCompassMark() to Lua. - Lua didn't have ClearCompassMark(). Perl already had this. == 01/12/2016 == -Uleat: Fix for tradeskill containers remaining locked after a RoF+ client leaves. Intermediary fix for RoF+ clients accessing tradeskill containers when in use by another player. +Uleat: Fix for tradeskill containers remaining locked after a RoF+ client leaves. Intermediary fix for RoF+ clients accessing tradeskill containers when in use by another player (thanks Natedog!) == 12/29/2015 == Akkadius: Implemented standardized zone controller scripts (Rule Zone, UseZoneController) Defaulted to true diff --git a/zone/command.cpp b/zone/command.cpp index 8d4df2b46..4c25b25d2 100644 --- a/zone/command.cpp +++ b/zone/command.cpp @@ -5484,36 +5484,54 @@ void command_interrupt(Client *c, const Seperator *sep) void command_summonitem(Client *c, const Seperator *sep) { - if (!sep->IsNumber(1)) - c->Message(0, "Usage: #summonitem [item id] [charges], charges are optional"); - else { - uint32 itemid = atoi(sep->arg[1]); - int16 item_status = 0; - const Item_Struct* item = database.GetItem(itemid); - if(item) { - item_status = static_cast(item->MinStatus); - } + uint32 itemid = 0; - if (item_status > c->Admin()) - c->Message(13, "Error: Insufficient status to summon this item."); - else if (sep->argnum==2 && sep->IsNumber(2)) - c->SummonItem(itemid, atoi(sep->arg[2])); - else if (sep->argnum==3) - c->SummonItem(itemid, atoi(sep->arg[2]), atoi(sep->arg[3])); - else if (sep->argnum==4) - c->SummonItem(itemid, atoi(sep->arg[2]), atoi(sep->arg[3]), atoi(sep->arg[4])); - else if (sep->argnum==5) - c->SummonItem(itemid, atoi(sep->arg[2]), atoi(sep->arg[3]), atoi(sep->arg[4]), atoi(sep->arg[5])); - else if (sep->argnum==6) - c->SummonItem(itemid, atoi(sep->arg[2]), atoi(sep->arg[3]), atoi(sep->arg[4]), atoi(sep->arg[5]), atoi(sep->arg[6])); - else if (sep->argnum==7) - c->SummonItem(itemid, atoi(sep->arg[2]), atoi(sep->arg[3]), atoi(sep->arg[4]), atoi(sep->arg[5]), atoi(sep->arg[6]), atoi(sep->arg[7])); - else if (sep->argnum==8) - c->SummonItem(itemid, atoi(sep->arg[2]), atoi(sep->arg[3]), atoi(sep->arg[4]), atoi(sep->arg[5]), atoi(sep->arg[6]), atoi(sep->arg[7]), atoi(sep->arg[8])); - else { - c->SummonItem(itemid); - } + std::string cmd_msg = sep->msg; + size_t link_open = cmd_msg.find('\x12'); + size_t link_close = cmd_msg.find_last_of('\x12'); + if (link_open != link_close && (cmd_msg.length() - link_open) > EmuConstants::TEXT_LINK_BODY_LENGTH) { + TextLinkBody_Struct link_body; + Client::TextLink::DegenerateLinkBody(link_body, cmd_msg.substr(link_open + 1, EmuConstants::TEXT_LINK_BODY_LENGTH)); + itemid = link_body.item_id; } + else if (!sep->IsNumber(1)) { + c->Message(0, "Usage: #summonitem [item id | link] [charges], charges are optional"); + return; + } + else { + itemid = atoi(sep->arg[1]); + } + if (!itemid) { + c->Message(0, "A valid item id number is required (derived: 0)"); + return; + } + + int16 item_status = 0; + const Item_Struct* item = database.GetItem(itemid); + if (item) { + item_status = static_cast(item->MinStatus); + } + + if (item_status > c->Admin()) + c->Message(13, "Error: Insufficient status to summon this item."); + else if (sep->argnum == 2 && sep->IsNumber(2)) + c->SummonItem(itemid, atoi(sep->arg[2])); + else if (sep->argnum == 3) + c->SummonItem(itemid, atoi(sep->arg[2]), atoi(sep->arg[3])); + else if (sep->argnum == 4) + c->SummonItem(itemid, atoi(sep->arg[2]), atoi(sep->arg[3]), atoi(sep->arg[4])); + else if (sep->argnum == 5) + c->SummonItem(itemid, atoi(sep->arg[2]), atoi(sep->arg[3]), atoi(sep->arg[4]), atoi(sep->arg[5])); + else if (sep->argnum == 6) + c->SummonItem(itemid, atoi(sep->arg[2]), atoi(sep->arg[3]), atoi(sep->arg[4]), atoi(sep->arg[5]), atoi(sep->arg[6])); + else if (sep->argnum == 7) + c->SummonItem(itemid, atoi(sep->arg[2]), atoi(sep->arg[3]), atoi(sep->arg[4]), atoi(sep->arg[5]), atoi(sep->arg[6]), atoi(sep->arg[7])); + else if (sep->argnum == 8) + c->SummonItem(itemid, atoi(sep->arg[2]), atoi(sep->arg[3]), atoi(sep->arg[4]), atoi(sep->arg[5]), atoi(sep->arg[6]), atoi(sep->arg[7]), atoi(sep->arg[8])); + else { + c->SummonItem(itemid); + } + } void command_giveitem(Client *c, const Seperator *sep) From e161805bc9f978324719e9aa1178195aeb4dff6a Mon Sep 17 00:00:00 2001 From: Uleat Date: Wed, 13 Jan 2016 15:25:22 -0500 Subject: [PATCH 13/56] Added changelog entry for #summonitem [itemlink] change --- changelog.txt | 2 ++ 1 file changed, 2 insertions(+) diff --git a/changelog.txt b/changelog.txt index e23ef39c9..6bc29becc 100644 --- a/changelog.txt +++ b/changelog.txt @@ -3,6 +3,8 @@ EQEMu Changelog (Started on Sept 24, 2003 15:50) == 01/13/2016 == Kinglykrab: Modified #flag so you can refresh your target's account status (GM status level) without them having to relog. - Just target the person whose flag you want to refresh and type #flag. +Uleat: Added itemlink functionality to the #summonitem command. Current use is limited to extracting the item id from the link. + - Invoking by item link '#summonitem Arrow' produces the same result as by item id '#summonitem 8005' == 01/12/2016 == Athrogate: Adding ClearCompassMark() to Lua. From f33f3bd4f552b2e6126ef7a3d17743842b90a2ee Mon Sep 17 00:00:00 2001 From: "Michael Cook (mackal)" Date: Fri, 15 Jan 2016 16:09:23 -0500 Subject: [PATCH 14/56] Fix Drakkin base resists and some missing class bonuses --- zone/client_mods.cpp | 57 ++++++++++++++++++++++++++++++++++++++++---- 1 file changed, 53 insertions(+), 4 deletions(-) diff --git a/zone/client_mods.cpp b/zone/client_mods.cpp index 06c267fd4..162bffbf8 100644 --- a/zone/client_mods.cpp +++ b/zone/client_mods.cpp @@ -1633,13 +1633,19 @@ int32 Client::CalcMR() MR = 30; break; case DRAKKIN: - MR = 35; + { + MR = 25; + if (GetDrakkinHeritage() == 2) + MR += 10; + else if (GetDrakkinHeritage() == 5) + MR += 2; break; + } default: MR = 20; } MR += itembonuses.MR + spellbonuses.MR + aabonuses.MR; - if (GetClass() == WARRIOR) { + if (GetClass() == WARRIOR || GetClass() == BERSERKER) { MR += GetLevel() / 2; } if (MR < 1) { @@ -1701,8 +1707,14 @@ int32 Client::CalcFR() FR = 25; break; case DRAKKIN: + { FR = 25; + if (GetDrakkinHeritage() == 0) + FR += 10; + else if (GetDrakkinHeritage() == 5) + FR += 2; break; + } default: FR = 20; } @@ -1714,6 +1726,13 @@ int32 Client::CalcFR() FR += l - 49; } } + if (c == MONK) { + FR += 8; + int l = GetLevel(); + if (l > 49) { + FR += l - 49; + } + } FR += itembonuses.FR + spellbonuses.FR + aabonuses.FR; if (FR < 1) { FR = 1; @@ -1774,12 +1793,24 @@ int32 Client::CalcDR() DR = 15; break; case DRAKKIN: + { DR = 15; + if (GetDrakkinHeritage() == 1) + DR += 10; + else if (GetDrakkinHeritage() == 5) + DR += 2; break; + } default: DR = 15; } int c = GetClass(); + // the monk one is part of base resist + if (c == MONK) { + int l = GetLevel(); + if (l > 50) + DR += l - 50; + } if (c == PALADIN) { DR += 8; int l = GetLevel(); @@ -1787,7 +1818,7 @@ int32 Client::CalcDR() DR += l - 49; } } - else if (c == SHADOWKNIGHT) { + else if (c == SHADOWKNIGHT || c == BEASTLORD) { DR += 4; int l = GetLevel(); if (l > 49) { @@ -1854,12 +1885,24 @@ int32 Client::CalcPR() PR = 30; break; case DRAKKIN: + { PR = 15; + if (GetDrakkinHeritage() == 3) + PR += 10; + else if (GetDrakkinHeritage() == 5) + PR += 2; break; + } default: PR = 15; } int c = GetClass(); + // this monk bonus is part of the base + if (c == MONK) { + int l = GetLevel(); + if (l > 50) + PR += l = 50; + } if (c == ROGUE) { PR += 8; int l = GetLevel(); @@ -1934,13 +1977,19 @@ int32 Client::CalcCR() CR = 25; break; case DRAKKIN: + { CR = 25; + if (GetDrakkinHeritage() == 4) + CR += 10; + else if (GetDrakkinHeritage() == 5) + CR += 2; break; + } default: CR = 25; } int c = GetClass(); - if (c == RANGER) { + if (c == RANGER || c == BEASTLORD) { CR += 4; int l = GetLevel(); if (l > 49) { From 42f7e03b040f44107b635feb359ceccfd7e1e1a9 Mon Sep 17 00:00:00 2001 From: "Michael Cook (mackal)" Date: Fri, 15 Jan 2016 17:00:10 -0500 Subject: [PATCH 15/56] Fix typo in last commit --- zone/client_mods.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/zone/client_mods.cpp b/zone/client_mods.cpp index 162bffbf8..9fc36a57e 100644 --- a/zone/client_mods.cpp +++ b/zone/client_mods.cpp @@ -1901,7 +1901,7 @@ int32 Client::CalcPR() if (c == MONK) { int l = GetLevel(); if (l > 50) - PR += l = 50; + PR += l - 50; } if (c == ROGUE) { PR += 8; From d7e44643b53045064de4454e409bb1db3815b30a Mon Sep 17 00:00:00 2001 From: "Michael Cook (mackal)" Date: Fri, 15 Jan 2016 17:20:48 -0500 Subject: [PATCH 16/56] Fix resist display issue for RoF/RoF2 These need to be found for the other clients They are most likely a similar amount of bytes away from the potionbelt in all clients --- common/patches/rof.cpp | 15 ++++++++------- common/patches/rof2.cpp | 15 ++++++++------- 2 files changed, 16 insertions(+), 14 deletions(-) diff --git a/common/patches/rof.cpp b/common/patches/rof.cpp index 76d62e3a4..988eba916 100644 --- a/common/patches/rof.cpp +++ b/common/patches/rof.cpp @@ -2392,13 +2392,14 @@ namespace RoF outapp->WriteSInt32(234); // Endurance Total ? outapp->WriteSInt32(345); // Mana Total ? - outapp->WriteUInt32(0); // Unknown - outapp->WriteUInt32(0); // Unknown - outapp->WriteUInt32(0); // Unknown - outapp->WriteUInt32(0); // Unknown - outapp->WriteUInt32(0); // Unknown - outapp->WriteUInt32(0); // Unknown - outapp->WriteUInt32(0); // Unknown + // these are needed to fix display bugs + outapp->WriteUInt32(0x19); // base CR + outapp->WriteUInt32(0x19); // base FR + outapp->WriteUInt32(0x19); // base MR + outapp->WriteUInt32(0xf); // base DR + outapp->WriteUInt32(0xf); // base PR + outapp->WriteUInt32(0xf); // base PhR? + outapp->WriteUInt32(0xf); // base Corrup outapp->WriteUInt32(0); // Unknown outapp->WriteUInt32(0); // Unknown outapp->WriteUInt32(0); // Unknown diff --git a/common/patches/rof2.cpp b/common/patches/rof2.cpp index a8b231300..e0e8f307f 100644 --- a/common/patches/rof2.cpp +++ b/common/patches/rof2.cpp @@ -2471,13 +2471,14 @@ namespace RoF2 outapp->WriteSInt32(234); // Endurance Total ? outapp->WriteSInt32(345); // Mana Total ? - outapp->WriteUInt32(0); // Unknown - outapp->WriteUInt32(0); // Unknown - outapp->WriteUInt32(0); // Unknown - outapp->WriteUInt32(0); // Unknown - outapp->WriteUInt32(0); // Unknown - outapp->WriteUInt32(0); // Unknown - outapp->WriteUInt32(0); // Unknown + // these are needed to fix display bugs + outapp->WriteUInt32(0x19); // base CR + outapp->WriteUInt32(0x19); // base FR + outapp->WriteUInt32(0x19); // base MR + outapp->WriteUInt32(0xf); // base DR + outapp->WriteUInt32(0xf); // base PR + outapp->WriteUInt32(0xf); // base PhR? + outapp->WriteUInt32(0xf); // base Corrup outapp->WriteUInt32(0); // Unknown outapp->WriteUInt32(0); // Unknown outapp->WriteUInt32(0); // Unknown From 281344b0499ee48f2862750ddbf483fc31038118 Mon Sep 17 00:00:00 2001 From: "Michael Cook (mackal)" Date: Sat, 16 Jan 2016 17:10:11 -0500 Subject: [PATCH 17/56] Add various GetItemStat totallers to ItemInst The intent of these functions is to simplify various locations in the code where we need to get a total of some stat on an item, including augs and we can not just grab the total from the itembonuses struct. This will also centralize where we need to add the powersource aug scaling when we implement them. Since they will need the Purity stat from the item it is in. Notes: - These functions recurse if the augments flag is true, which is false by default to make it so you have to be explicit about recursing or not - These functions don't take into account if you can equip or if you are below recommended level, you will have to do that where you call these functions. --- common/item.cpp | 702 ++++++++++++++++++++++++++++++++++++++++++++++++ common/item.h | 53 ++++ 2 files changed, 755 insertions(+) diff --git a/common/item.cpp b/common/item.cpp index 7ce8e730d..a7b6987de 100644 --- a/common/item.cpp +++ b/common/item.cpp @@ -2322,6 +2322,708 @@ void ItemInst::ClearTimers() { m_timers.clear(); } +int ItemInst::GetItemArmorClass(bool augments) const +{ + int ac = 0; + const auto item = GetItem(); + if (item) { + ac = item->AC; + if (augments) + for (int i = AUG_BEGIN; i < EmuConstants::ITEM_COMMON_SIZE; ++i) + if (GetAugment(i)) + ac += GetAugment(i)->GetItemArmorClass(); + } + return ac; +} + +int ItemInst::GetItemElementalDamage(int &magic, int &fire, int &cold, int &poison, int &disease, int &chromatic, int &prismatic, int &physical, int &corruption, bool augments) const +{ + const auto item = GetItem(); + if (item) { + switch (item->ElemDmgType) { + case RESIST_MAGIC: + magic = item->ElemDmgAmt; + break; + case RESIST_FIRE: + fire = item->ElemDmgAmt; + break; + case RESIST_COLD: + cold = item->ElemDmgAmt; + break; + case RESIST_POISON: + poison = item->ElemDmgAmt; + break; + case RESIST_DISEASE: + disease = item->ElemDmgAmt; + break; + case RESIST_CHROMATIC: + chromatic = item->ElemDmgAmt; + break; + case RESIST_PRISMATIC: + prismatic = item->ElemDmgAmt; + break; + case RESIST_PHYSICAL: + physical = item->ElemDmgAmt; + break; + case RESIST_CORRUPTION: + corruption = item->ElemDmgAmt; + break; + } + + if (augments) + for (int i = AUG_BEGIN; i < EmuConstants::ITEM_COMMON_SIZE; ++i) + if (GetAugment(i)) + GetAugment(i)->GetItemElementalDamage(magic, fire, cold, poison, disease, chromatic, prismatic, physical, corruption); + } + return magic + fire + cold + poison + disease + chromatic + prismatic + physical + corruption; +} + +int ItemInst::GetItemElementalFlag(bool augments) const +{ + int flag = 0; + const auto item = GetItem(); + if (item) { + flag = item->ElemDmgType; + if (flag) + return flag; + + if (augments) { + for (int i = AUG_BEGIN; i < EmuConstants::ITEM_COMMON_SIZE; ++i) { + if (GetAugment(i)) + flag = GetAugment(i)->GetItemElementalFlag(); + if (flag) + return flag; + } + } + } + return flag; +} + +int ItemInst::GetItemElementalDamage(bool augments) const +{ + int damage = 0; + const auto item = GetItem(); + if (item) { + damage = item->ElemDmgAmt; + if (damage) + return damage; + + if (augments) { + for (int i = AUG_BEGIN; i < EmuConstants::ITEM_COMMON_SIZE; ++i) { + if (GetAugment(i)) + damage = GetAugment(i)->GetItemElementalDamage(); + if (damage) + return damage; + } + } + } + return damage; +} + +int ItemInst::GetItemRecommendedLevel(bool augments) const +{ + int level = 0; + const auto item = GetItem(); + if (item) { + level = item->RecLevel; + + if (augments) { + for (int i = AUG_BEGIN; i < EmuConstants::ITEM_COMMON_SIZE; ++i) { + int temp = 0; + if (GetAugment(i)) { + temp = GetAugment(i)->GetItemRecommendedLevel(); + if (temp > level) + level = temp; + } + } + } + } + + return level; +} + +int ItemInst::GetItemRequiredLevel(bool augments) const +{ + int level = 0; + const auto item = GetItem(); + if (item) { + level = item->ReqLevel; + + if (augments) { + for (int i = AUG_BEGIN; i < EmuConstants::ITEM_COMMON_SIZE; ++i) { + int temp = 0; + if (GetAugment(i)) { + temp = GetAugment(i)->GetItemRequiredLevel(); + if (temp > level) + level = temp; + } + } + } + } + + return level; +} + +int ItemInst::GetItemWeaponDamage(bool augments) const +{ + int damage = 0; + const auto item = GetItem(); + if (item) { + damage = item->Damage; + + if (augments) { + for (int i = AUG_BEGIN; i < EmuConstants::ITEM_COMMON_SIZE; ++i) + if (GetAugment(i)) + damage += GetAugment(i)->GetItemWeaponDamage(); + } + } + return damage; +} + +int ItemInst::GetItemBackstabDamage(bool augments) const +{ + int damage = 0; + const auto item = GetItem(); + if (item) { + damage = item->BackstabDmg; + + if (augments) { + for (int i = AUG_BEGIN; i < EmuConstants::ITEM_COMMON_SIZE; ++i) + if (GetAugment(i)) + damage += GetAugment(i)->GetItemBackstabDamage(); + } + } + return damage; +} + +int ItemInst::GetItemBaneDamageBody(bool augments) const +{ + int body = 0; + const auto item = GetItem(); + if (item) { + body = item->BaneDmgBody; + if (body) + return body; + + if (augments) { + for (int i = AUG_BEGIN; i < EmuConstants::ITEM_COMMON_SIZE; ++i) + if (GetAugment(i)) { + body = GetAugment(i)->GetItemBaneDamageBody(); + if (body) + return body; + } + } + } + return body; +} + +int ItemInst::GetItemBaneDamageRace(bool augments) const +{ + int race = 0; + const auto item = GetItem(); + if (item) { + race = item->BaneDmgRace; + if (race) + return race; + + if (augments) { + for (int i = AUG_BEGIN; i < EmuConstants::ITEM_COMMON_SIZE; ++i) + if (GetAugment(i)) { + race = GetAugment(i)->GetItemBaneDamageRace(); + if (race) + return race; + } + } + } + return race; +} + +int ItemInst::GetItemBaneDamageBody(bodyType against, bool augments) const +{ + int damage = 0; + const auto item = GetItem(); + if (item) { + if (item->BaneDmgBody == against) + damage += item->BaneDmgAmt; + + if (augments) { + for (int i = AUG_BEGIN; i < EmuConstants::ITEM_COMMON_SIZE; ++i) + if (GetAugment(i)) + damage += GetAugment(i)->GetItemBaneDamageBody(against); + } + } + return damage; +} + +int ItemInst::GetItemBaneDamageRace(uint16 against, bool augments) const +{ + int damage = 0; + const auto item = GetItem(); + if (item) { + if (item->BaneDmgRace == against) + damage += item->BaneDmgRaceAmt; + + if (augments) { + for (int i = AUG_BEGIN; i < EmuConstants::ITEM_COMMON_SIZE; ++i) + if (GetAugment(i)) + damage += GetAugment(i)->GetItemBaneDamageRace(against); + } + } + return damage; +} + +int ItemInst::GetItemMagical(bool augments) const +{ + const auto item = GetItem(); + if (item) { + if (item->Magic) + return 1; + + if (augments) { + for (int i = AUG_BEGIN; i < EmuConstants::ITEM_COMMON_SIZE; ++i) + if (GetAugment(i) && GetAugment(i)->GetItemMagical()) + return 1; + } + } + return 0; +} + +int ItemInst::GetItemHP(bool augments) const +{ + int hp = 0; + const auto item = GetItem(); + if (item) { + hp = item->HP; + if (augments) + for (int i = AUG_BEGIN; i < EmuConstants::ITEM_COMMON_SIZE; ++i) + if (GetAugment(i)) + hp += GetAugment(i)->GetItemHP(); + } + return hp; +} + +int ItemInst::GetItemMana(bool augments) const +{ + int mana = 0; + const auto item = GetItem(); + if (item) { + mana = item->Mana; + if (augments) + for (int i = AUG_BEGIN; i < EmuConstants::ITEM_COMMON_SIZE; ++i) + if (GetAugment(i)) + mana += GetAugment(i)->GetItemMana(); + } + return mana; +} + +int ItemInst::GetItemEndur(bool augments) const +{ + int endur = 0; + const auto item = GetItem(); + if (item) { + endur = item->Endur; + if (augments) + for (int i = AUG_BEGIN; i < EmuConstants::ITEM_COMMON_SIZE; ++i) + if (GetAugment(i)) + endur += GetAugment(i)->GetItemEndur(); + } + return endur; +} + +int ItemInst::GetItemAttack(bool augments) const +{ + int atk = 0; + const auto item = GetItem(); + if (item) { + atk = item->Attack; + if (augments) + for (int i = AUG_BEGIN; i < EmuConstants::ITEM_COMMON_SIZE; ++i) + if (GetAugment(i)) + atk += GetAugment(i)->GetItemAttack(); + } + return atk; +} + +int ItemInst::GetItemStr(bool augments) const +{ + int str = 0; + const auto item = GetItem(); + if (item) { + str = item->AStr; + if (augments) + for (int i = AUG_BEGIN; i < EmuConstants::ITEM_COMMON_SIZE; ++i) + if (GetAugment(i)) + str += GetAugment(i)->GetItemStr(); + } + return str; +} + +int ItemInst::GetItemSta(bool augments) const +{ + int sta = 0; + const auto item = GetItem(); + if (item) { + sta = item->ASta; + if (augments) + for (int i = AUG_BEGIN; i < EmuConstants::ITEM_COMMON_SIZE; ++i) + if (GetAugment(i)) + sta += GetAugment(i)->GetItemSta(); + } + return sta; +} + +int ItemInst::GetItemDex(bool augments) const +{ + int total = 0; + const auto item = GetItem(); + if (item) { + total = item->ADex; + if (augments) + for (int i = AUG_BEGIN; i < EmuConstants::ITEM_COMMON_SIZE; ++i) + if (GetAugment(i)) + total += GetAugment(i)->GetItemDex(); + } + return total; +} + +int ItemInst::GetItemAgi(bool augments) const +{ + int total = 0; + const auto item = GetItem(); + if (item) { + total = item->AAgi; + if (augments) + for (int i = AUG_BEGIN; i < EmuConstants::ITEM_COMMON_SIZE; ++i) + if (GetAugment(i)) + total += GetAugment(i)->GetItemAgi(); + } + return total; +} + +int ItemInst::GetItemInt(bool augments) const +{ + int total = 0; + const auto item = GetItem(); + if (item) { + total = item->AInt; + if (augments) + for (int i = AUG_BEGIN; i < EmuConstants::ITEM_COMMON_SIZE; ++i) + if (GetAugment(i)) + total += GetAugment(i)->GetItemInt(); + } + return total; +} + +int ItemInst::GetItemWis(bool augments) const +{ + int total = 0; + const auto item = GetItem(); + if (item) { + total = item->AWis; + if (augments) + for (int i = AUG_BEGIN; i < EmuConstants::ITEM_COMMON_SIZE; ++i) + if (GetAugment(i)) + total += GetAugment(i)->GetItemWis(); + } + return total; +} + +int ItemInst::GetItemCha(bool augments) const +{ + int total = 0; + const auto item = GetItem(); + if (item) { + total = item->ACha; + if (augments) + for (int i = AUG_BEGIN; i < EmuConstants::ITEM_COMMON_SIZE; ++i) + if (GetAugment(i)) + total += GetAugment(i)->GetItemCha(); + } + return total; +} + +int ItemInst::GetItemMR(bool augments) const +{ + int total = 0; + const auto item = GetItem(); + if (item) { + total = item->MR; + if (augments) + for (int i = AUG_BEGIN; i < EmuConstants::ITEM_COMMON_SIZE; ++i) + if (GetAugment(i)) + total += GetAugment(i)->GetItemMR(); + } + return total; +} + +int ItemInst::GetItemFR(bool augments) const +{ + int total = 0; + const auto item = GetItem(); + if (item) { + total = item->FR; + if (augments) + for (int i = AUG_BEGIN; i < EmuConstants::ITEM_COMMON_SIZE; ++i) + if (GetAugment(i)) + total += GetAugment(i)->GetItemFR(); + } + return total; +} + +int ItemInst::GetItemCR(bool augments) const +{ + int total = 0; + const auto item = GetItem(); + if (item) { + total = item->CR; + if (augments) + for (int i = AUG_BEGIN; i < EmuConstants::ITEM_COMMON_SIZE; ++i) + if (GetAugment(i)) + total += GetAugment(i)->GetItemCR(); + } + return total; +} + +int ItemInst::GetItemPR(bool augments) const +{ + int total = 0; + const auto item = GetItem(); + if (item) { + total = item->PR; + if (augments) + for (int i = AUG_BEGIN; i < EmuConstants::ITEM_COMMON_SIZE; ++i) + if (GetAugment(i)) + total += GetAugment(i)->GetItemPR(); + } + return total; +} + +int ItemInst::GetItemDR(bool augments) const +{ + int total = 0; + const auto item = GetItem(); + if (item) { + total = item->DR; + if (augments) + for (int i = AUG_BEGIN; i < EmuConstants::ITEM_COMMON_SIZE; ++i) + if (GetAugment(i)) + total += GetAugment(i)->GetItemDR(); + } + return total; +} + +int ItemInst::GetItemCorrup(bool augments) const +{ + int total = 0; + const auto item = GetItem(); + if (item) { + total = item->SVCorruption; + if (augments) + for (int i = AUG_BEGIN; i < EmuConstants::ITEM_COMMON_SIZE; ++i) + if (GetAugment(i)) + total += GetAugment(i)->GetItemCorrup(); + } + return total; +} + +int ItemInst::GetItemHeroicStr(bool augments) const +{ + int total = 0; + const auto item = GetItem(); + if (item) { + total = item->HeroicStr; + if (augments) + for (int i = AUG_BEGIN; i < EmuConstants::ITEM_COMMON_SIZE; ++i) + if (GetAugment(i)) + total += GetAugment(i)->GetItemHeroicStr(); + } + return total; +} + +int ItemInst::GetItemHeroicSta(bool augments) const +{ + int total = 0; + const auto item = GetItem(); + if (item) { + total = item->HeroicSta; + if (augments) + for (int i = AUG_BEGIN; i < EmuConstants::ITEM_COMMON_SIZE; ++i) + if (GetAugment(i)) + total += GetAugment(i)->GetItemHeroicSta(); + } + return total; +} + +int ItemInst::GetItemHeroicDex(bool augments) const +{ + int total = 0; + const auto item = GetItem(); + if (item) { + total = item->HeroicDex; + if (augments) + for (int i = AUG_BEGIN; i < EmuConstants::ITEM_COMMON_SIZE; ++i) + if (GetAugment(i)) + total += GetAugment(i)->GetItemHeroicDex(); + } + return total; +} + +int ItemInst::GetItemHeroicAgi(bool augments) const +{ + int total = 0; + const auto item = GetItem(); + if (item) { + total = item->HeroicAgi; + if (augments) + for (int i = AUG_BEGIN; i < EmuConstants::ITEM_COMMON_SIZE; ++i) + if (GetAugment(i)) + total += GetAugment(i)->GetItemHeroicAgi(); + } + return total; +} + +int ItemInst::GetItemHeroicInt(bool augments) const +{ + int total = 0; + const auto item = GetItem(); + if (item) { + total = item->HeroicInt; + if (augments) + for (int i = AUG_BEGIN; i < EmuConstants::ITEM_COMMON_SIZE; ++i) + if (GetAugment(i)) + total += GetAugment(i)->GetItemHeroicInt(); + } + return total; +} + +int ItemInst::GetItemHeroicWis(bool augments) const +{ + int total = 0; + const auto item = GetItem(); + if (item) { + total = item->HeroicWis; + if (augments) + for (int i = AUG_BEGIN; i < EmuConstants::ITEM_COMMON_SIZE; ++i) + if (GetAugment(i)) + total += GetAugment(i)->GetItemHeroicWis(); + } + return total; +} + +int ItemInst::GetItemHeroicCha(bool augments) const +{ + int total = 0; + const auto item = GetItem(); + if (item) { + total = item->HeroicCha; + if (augments) + for (int i = AUG_BEGIN; i < EmuConstants::ITEM_COMMON_SIZE; ++i) + if (GetAugment(i)) + total += GetAugment(i)->GetItemHeroicCha(); + } + return total; +} + +int ItemInst::GetItemHeroicMR(bool augments) const +{ + int total = 0; + const auto item = GetItem(); + if (item) { + total = item->HeroicMR; + if (augments) + for (int i = AUG_BEGIN; i < EmuConstants::ITEM_COMMON_SIZE; ++i) + if (GetAugment(i)) + total += GetAugment(i)->GetItemHeroicMR(); + } + return total; +} + +int ItemInst::GetItemHeroicFR(bool augments) const +{ + int total = 0; + const auto item = GetItem(); + if (item) { + total = item->HeroicFR; + if (augments) + for (int i = AUG_BEGIN; i < EmuConstants::ITEM_COMMON_SIZE; ++i) + if (GetAugment(i)) + total += GetAugment(i)->GetItemHeroicFR(); + } + return total; +} + +int ItemInst::GetItemHeroicCR(bool augments) const +{ + int total = 0; + const auto item = GetItem(); + if (item) { + total = item->HeroicCR; + if (augments) + for (int i = AUG_BEGIN; i < EmuConstants::ITEM_COMMON_SIZE; ++i) + if (GetAugment(i)) + total += GetAugment(i)->GetItemHeroicCR(); + } + return total; +} + +int ItemInst::GetItemHeroicPR(bool augments) const +{ + int total = 0; + const auto item = GetItem(); + if (item) { + total = item->HeroicPR; + if (augments) + for (int i = AUG_BEGIN; i < EmuConstants::ITEM_COMMON_SIZE; ++i) + if (GetAugment(i)) + total += GetAugment(i)->GetItemHeroicPR(); + } + return total; +} + +int ItemInst::GetItemHeroicDR(bool augments) const +{ + int total = 0; + const auto item = GetItem(); + if (item) { + total = item->HeroicDR; + if (augments) + for (int i = AUG_BEGIN; i < EmuConstants::ITEM_COMMON_SIZE; ++i) + if (GetAugment(i)) + total += GetAugment(i)->GetItemHeroicDR(); + } + return total; +} + +int ItemInst::GetItemHeroicCorrup(bool augments) const +{ + int total = 0; + const auto item = GetItem(); + if (item) { + total = item->HeroicSVCorrup; + if (augments) + for (int i = AUG_BEGIN; i < EmuConstants::ITEM_COMMON_SIZE; ++i) + if (GetAugment(i)) + total += GetAugment(i)->GetItemHeroicCorrup(); + } + return total; +} + +int ItemInst::GetItemHaste(bool augments) const +{ + int total = 0; + const auto item = GetItem(); + if (item) { + total = item->Haste; + if (augments) + for (int i = AUG_BEGIN; i < EmuConstants::ITEM_COMMON_SIZE; ++i) + if (GetAugment(i)) { + int temp = GetAugment(i)->GetItemHaste(); + if (temp > total) + total = temp; + } + } + return total; +} // // class EvolveInfo diff --git a/common/item.h b/common/item.h index a5dd01f95..b6babde9f 100644 --- a/common/item.h +++ b/common/item.h @@ -29,6 +29,7 @@ class EvolveInfo; // Stores information about an evolving item family #include "../common/eq_constants.h" #include "../common/item_struct.h" #include "../common/timer.h" +#include "../common/bodytypes.h" #include #include @@ -418,6 +419,58 @@ public: void StopTimer(std::string name); void ClearTimers(); + // Get a total of a stat, including augs + // These functions should be used in place of other code manually totaling + // to centralize where it is done to make future changes easier (ex. whenever powersources come around) + // and to minimize errors. CalcItemBonuses however doesn't use these in interest of performance + // by default these do not recurse into augs + int GetItemArmorClass(bool augments = false) const; + int GetItemElementalDamage(int &magic, int &fire, int &cold, int &poison, int &disease, int &chromatic, int &prismatic, int &physical, int &corruption, bool augments = false) const; + // These two differ in the fact that they're quick checks (they are checked BEFORE the one above + int GetItemElementalFlag(bool augments = false) const; + int GetItemElementalDamage(bool augments = false) const; + int GetItemRecommendedLevel(bool augments = false) const; + int GetItemRequiredLevel(bool augments = false) const; + int GetItemWeaponDamage(bool augments = false) const; + int GetItemBackstabDamage(bool augments = false) const; + // these two are just quick checks + int GetItemBaneDamageBody(bool augments = false) const; + int GetItemBaneDamageRace(bool augments = false) const; + int GetItemBaneDamageBody(bodyType against, bool augments = false) const; + int GetItemBaneDamageRace(uint16 against, bool augments = false) const; + int GetItemMagical(bool augments = false) const; + int GetItemHP(bool augments = false) const; + int GetItemMana(bool augments = false) const; + int GetItemEndur(bool augments = false) const; + int GetItemAttack(bool augments = false) const; + int GetItemStr(bool augments = false) const; + int GetItemSta(bool augments = false) const; + int GetItemDex(bool augments = false) const; + int GetItemAgi(bool augments = false) const; + int GetItemInt(bool augments = false) const; + int GetItemWis(bool augments = false) const; + int GetItemCha(bool augments = false) const; + int GetItemMR(bool augments = false) const; + int GetItemFR(bool augments = false) const; + int GetItemCR(bool augments = false) const; + int GetItemPR(bool augments = false) const; + int GetItemDR(bool augments = false) const; + int GetItemCorrup(bool augments = false) const; + int GetItemHeroicStr(bool augments = false) const; + int GetItemHeroicSta(bool augments = false) const; + int GetItemHeroicDex(bool augments = false) const; + int GetItemHeroicAgi(bool augments = false) const; + int GetItemHeroicInt(bool augments = false) const; + int GetItemHeroicWis(bool augments = false) const; + int GetItemHeroicCha(bool augments = false) const; + int GetItemHeroicMR(bool augments = false) const; + int GetItemHeroicFR(bool augments = false) const; + int GetItemHeroicCR(bool augments = false) const; + int GetItemHeroicPR(bool augments = false) const; + int GetItemHeroicDR(bool augments = false) const; + int GetItemHeroicCorrup(bool augments = false) const; + int GetItemHaste(bool augments = false) const; + protected: ////////////////////////// // Protected Members From 8f0d9015be6fe15854479859ce9d68afc10e9b24 Mon Sep 17 00:00:00 2001 From: "Michael Cook (mackal)" Date: Sat, 16 Jan 2016 17:17:09 -0500 Subject: [PATCH 18/56] Fix rec/req level issues --- zone/bonuses.cpp | 320 ++++++++++++++++++++++------------------------- zone/bot.cpp | 102 ++++++++------- zone/bot.h | 2 +- zone/client.h | 2 +- 4 files changed, 200 insertions(+), 226 deletions(-) diff --git a/zone/bonuses.cpp b/zone/bonuses.cpp index 9e2461bd6..e709bdef4 100644 --- a/zone/bonuses.cpp +++ b/zone/bonuses.cpp @@ -207,32 +207,31 @@ void Client::ProcessItemCaps() itembonuses.ATK = std::min(itembonuses.ATK, CalcItemATKCap()); } -void Client::AddItemBonuses(const ItemInst *inst, StatBonuses* newbon, bool isAug, bool isTribute) { - if(!inst || !inst->IsType(ItemClassCommon)) - { +void Client::AddItemBonuses(const ItemInst *inst, StatBonuses *newbon, bool isAug, bool isTribute, int rec_override) +{ + if (!inst || !inst->IsType(ItemClassCommon)) { return; } - if(inst->GetAugmentType()==0 && isAug == true) - { + if (inst->GetAugmentType() == 0 && isAug == true) { return; } const Item_Struct *item = inst->GetItem(); - if(!isTribute && !inst->IsEquipable(GetBaseRace(),GetClass())) - { - if(item->ItemType != ItemTypeFood && item->ItemType != ItemTypeDrink) + if (!isTribute && !inst->IsEquipable(GetBaseRace(), GetClass())) { + if (item->ItemType != ItemTypeFood && item->ItemType != ItemTypeDrink) return; } - if(GetLevel() < item->ReqLevel) - { + if (GetLevel() < inst->GetItemRequiredLevel(true)) { return; } - if(GetLevel() >= item->RecLevel) - { + // So there isn't a very nice way to get the real rec level from the aug's inst, so we just pass it in, only + // used for augs + auto rec_level = isAug ? rec_override : inst->GetItemRecommendedLevel(true); + if (GetLevel() >= rec_level) { newbon->AC += item->AC; newbon->HP += item->HP; newbon->Mana += item->Mana; @@ -281,280 +280,257 @@ void Client::AddItemBonuses(const ItemInst *inst, StatBonuses* newbon, bool isAu newbon->HeroicDR += item->HeroicDR; newbon->HeroicCorrup += item->HeroicSVCorrup; - } - else - { + } else { int lvl = GetLevel(); - int reclvl = item->RecLevel; - newbon->AC += CalcRecommendedLevelBonus( lvl, reclvl, item->AC ); - newbon->HP += CalcRecommendedLevelBonus( lvl, reclvl, item->HP ); - newbon->Mana += CalcRecommendedLevelBonus( lvl, reclvl, item->Mana ); - newbon->Endurance += CalcRecommendedLevelBonus( lvl, reclvl, item->Endur ); - newbon->ATK += CalcRecommendedLevelBonus( lvl, reclvl, item->Attack ); - newbon->STR += CalcRecommendedLevelBonus( lvl, reclvl, (item->AStr + item->HeroicStr) ); - newbon->STA += CalcRecommendedLevelBonus( lvl, reclvl, (item->ASta + item->HeroicSta) ); - newbon->DEX += CalcRecommendedLevelBonus( lvl, reclvl, (item->ADex + item->HeroicDex) ); - newbon->AGI += CalcRecommendedLevelBonus( lvl, reclvl, (item->AAgi + item->HeroicAgi) ); - newbon->INT += CalcRecommendedLevelBonus( lvl, reclvl, (item->AInt + item->HeroicInt) ); - newbon->WIS += CalcRecommendedLevelBonus( lvl, reclvl, (item->AWis + item->HeroicWis) ); - newbon->CHA += CalcRecommendedLevelBonus( lvl, reclvl, (item->ACha + item->HeroicCha) ); + newbon->AC += CalcRecommendedLevelBonus(lvl, rec_level, item->AC); + newbon->HP += CalcRecommendedLevelBonus(lvl, rec_level, item->HP); + newbon->Mana += CalcRecommendedLevelBonus(lvl, rec_level, item->Mana); + newbon->Endurance += CalcRecommendedLevelBonus(lvl, rec_level, item->Endur); + newbon->ATK += CalcRecommendedLevelBonus(lvl, rec_level, item->Attack); + newbon->STR += CalcRecommendedLevelBonus(lvl, rec_level, (item->AStr + item->HeroicStr)); + newbon->STA += CalcRecommendedLevelBonus(lvl, rec_level, (item->ASta + item->HeroicSta)); + newbon->DEX += CalcRecommendedLevelBonus(lvl, rec_level, (item->ADex + item->HeroicDex)); + newbon->AGI += CalcRecommendedLevelBonus(lvl, rec_level, (item->AAgi + item->HeroicAgi)); + newbon->INT += CalcRecommendedLevelBonus(lvl, rec_level, (item->AInt + item->HeroicInt)); + newbon->WIS += CalcRecommendedLevelBonus(lvl, rec_level, (item->AWis + item->HeroicWis)); + newbon->CHA += CalcRecommendedLevelBonus(lvl, rec_level, (item->ACha + item->HeroicCha)); - newbon->MR += CalcRecommendedLevelBonus( lvl, reclvl, (item->MR + item->HeroicMR) ); - newbon->FR += CalcRecommendedLevelBonus( lvl, reclvl, (item->FR + item->HeroicFR) ); - newbon->CR += CalcRecommendedLevelBonus( lvl, reclvl, (item->CR + item->HeroicCR) ); - newbon->PR += CalcRecommendedLevelBonus( lvl, reclvl, (item->PR + item->HeroicPR) ); - newbon->DR += CalcRecommendedLevelBonus( lvl, reclvl, (item->DR + item->HeroicDR) ); - newbon->Corrup += CalcRecommendedLevelBonus( lvl, reclvl, (item->SVCorruption + item->HeroicSVCorrup) ); + newbon->MR += CalcRecommendedLevelBonus(lvl, rec_level, (item->MR + item->HeroicMR)); + newbon->FR += CalcRecommendedLevelBonus(lvl, rec_level, (item->FR + item->HeroicFR)); + newbon->CR += CalcRecommendedLevelBonus(lvl, rec_level, (item->CR + item->HeroicCR)); + newbon->PR += CalcRecommendedLevelBonus(lvl, rec_level, (item->PR + item->HeroicPR)); + newbon->DR += CalcRecommendedLevelBonus(lvl, rec_level, (item->DR + item->HeroicDR)); + newbon->Corrup += + CalcRecommendedLevelBonus(lvl, rec_level, (item->SVCorruption + item->HeroicSVCorrup)); - newbon->STRCapMod += CalcRecommendedLevelBonus( lvl, reclvl, item->HeroicStr ); - newbon->STACapMod += CalcRecommendedLevelBonus( lvl, reclvl, item->HeroicSta ); - newbon->DEXCapMod += CalcRecommendedLevelBonus( lvl, reclvl, item->HeroicDex ); - newbon->AGICapMod += CalcRecommendedLevelBonus( lvl, reclvl, item->HeroicAgi ); - newbon->INTCapMod += CalcRecommendedLevelBonus( lvl, reclvl, item->HeroicInt ); - newbon->WISCapMod += CalcRecommendedLevelBonus( lvl, reclvl, item->HeroicWis ); - newbon->CHACapMod += CalcRecommendedLevelBonus( lvl, reclvl, item->HeroicCha ); - newbon->MRCapMod += CalcRecommendedLevelBonus( lvl, reclvl, item->HeroicMR ); - newbon->CRCapMod += CalcRecommendedLevelBonus( lvl, reclvl, item->HeroicFR ); - newbon->FRCapMod += CalcRecommendedLevelBonus( lvl, reclvl, item->HeroicCR ); - newbon->PRCapMod += CalcRecommendedLevelBonus( lvl, reclvl, item->HeroicPR ); - newbon->DRCapMod += CalcRecommendedLevelBonus( lvl, reclvl, item->HeroicDR ); - newbon->CorrupCapMod += CalcRecommendedLevelBonus( lvl, reclvl, item->HeroicSVCorrup ); + newbon->STRCapMod += CalcRecommendedLevelBonus(lvl, rec_level, item->HeroicStr); + newbon->STACapMod += CalcRecommendedLevelBonus(lvl, rec_level, item->HeroicSta); + newbon->DEXCapMod += CalcRecommendedLevelBonus(lvl, rec_level, item->HeroicDex); + newbon->AGICapMod += CalcRecommendedLevelBonus(lvl, rec_level, item->HeroicAgi); + newbon->INTCapMod += CalcRecommendedLevelBonus(lvl, rec_level, item->HeroicInt); + newbon->WISCapMod += CalcRecommendedLevelBonus(lvl, rec_level, item->HeroicWis); + newbon->CHACapMod += CalcRecommendedLevelBonus(lvl, rec_level, item->HeroicCha); + newbon->MRCapMod += CalcRecommendedLevelBonus(lvl, rec_level, item->HeroicMR); + newbon->CRCapMod += CalcRecommendedLevelBonus(lvl, rec_level, item->HeroicFR); + newbon->FRCapMod += CalcRecommendedLevelBonus(lvl, rec_level, item->HeroicCR); + newbon->PRCapMod += CalcRecommendedLevelBonus(lvl, rec_level, item->HeroicPR); + newbon->DRCapMod += CalcRecommendedLevelBonus(lvl, rec_level, item->HeroicDR); + newbon->CorrupCapMod += CalcRecommendedLevelBonus(lvl, rec_level, item->HeroicSVCorrup); - newbon->HeroicSTR += CalcRecommendedLevelBonus( lvl, reclvl, item->HeroicStr ); - newbon->HeroicSTA += CalcRecommendedLevelBonus( lvl, reclvl, item->HeroicSta ); - newbon->HeroicDEX += CalcRecommendedLevelBonus( lvl, reclvl, item->HeroicDex ); - newbon->HeroicAGI += CalcRecommendedLevelBonus( lvl, reclvl, item->HeroicAgi ); - newbon->HeroicINT += CalcRecommendedLevelBonus( lvl, reclvl, item->HeroicInt ); - newbon->HeroicWIS += CalcRecommendedLevelBonus( lvl, reclvl, item->HeroicWis ); - newbon->HeroicCHA += CalcRecommendedLevelBonus( lvl, reclvl, item->HeroicCha ); - newbon->HeroicMR += CalcRecommendedLevelBonus( lvl, reclvl, item->HeroicMR ); - newbon->HeroicFR += CalcRecommendedLevelBonus( lvl, reclvl, item->HeroicFR ); - newbon->HeroicCR += CalcRecommendedLevelBonus( lvl, reclvl, item->HeroicCR ); - newbon->HeroicPR += CalcRecommendedLevelBonus( lvl, reclvl, item->HeroicPR ); - newbon->HeroicDR += CalcRecommendedLevelBonus( lvl, reclvl, item->HeroicDR ); - newbon->HeroicCorrup += CalcRecommendedLevelBonus( lvl, reclvl, item->HeroicSVCorrup ); + newbon->HeroicSTR += CalcRecommendedLevelBonus(lvl, rec_level, item->HeroicStr); + newbon->HeroicSTA += CalcRecommendedLevelBonus(lvl, rec_level, item->HeroicSta); + newbon->HeroicDEX += CalcRecommendedLevelBonus(lvl, rec_level, item->HeroicDex); + newbon->HeroicAGI += CalcRecommendedLevelBonus(lvl, rec_level, item->HeroicAgi); + newbon->HeroicINT += CalcRecommendedLevelBonus(lvl, rec_level, item->HeroicInt); + newbon->HeroicWIS += CalcRecommendedLevelBonus(lvl, rec_level, item->HeroicWis); + newbon->HeroicCHA += CalcRecommendedLevelBonus(lvl, rec_level, item->HeroicCha); + newbon->HeroicMR += CalcRecommendedLevelBonus(lvl, rec_level, item->HeroicMR); + newbon->HeroicFR += CalcRecommendedLevelBonus(lvl, rec_level, item->HeroicFR); + newbon->HeroicCR += CalcRecommendedLevelBonus(lvl, rec_level, item->HeroicCR); + newbon->HeroicPR += CalcRecommendedLevelBonus(lvl, rec_level, item->HeroicPR); + newbon->HeroicDR += CalcRecommendedLevelBonus(lvl, rec_level, item->HeroicDR); + newbon->HeroicCorrup += CalcRecommendedLevelBonus(lvl, rec_level, item->HeroicSVCorrup); } - //FatherNitwit: New style haste, shields, and regens - if(newbon->haste < (int32)item->Haste) { + // FatherNitwit: New style haste, shields, and regens + if (newbon->haste < (int32)item->Haste) { newbon->haste = item->Haste; } - if(item->Regen > 0) + if (item->Regen > 0) newbon->HPRegen += item->Regen; - if(item->ManaRegen > 0) + if (item->ManaRegen > 0) newbon->ManaRegen += item->ManaRegen; - if(item->EnduranceRegen > 0) + if (item->EnduranceRegen > 0) newbon->EnduranceRegen += item->EnduranceRegen; - if(item->DamageShield > 0) { - if((newbon->DamageShield + item->DamageShield) > RuleI(Character, ItemDamageShieldCap)) + if (item->DamageShield > 0) { + if ((newbon->DamageShield + item->DamageShield) > RuleI(Character, ItemDamageShieldCap)) newbon->DamageShield = RuleI(Character, ItemDamageShieldCap); else newbon->DamageShield += item->DamageShield; } - if(item->SpellShield > 0) { - if((newbon->SpellShield + item->SpellShield) > RuleI(Character, ItemSpellShieldingCap)) + if (item->SpellShield > 0) { + if ((newbon->SpellShield + item->SpellShield) > RuleI(Character, ItemSpellShieldingCap)) newbon->SpellShield = RuleI(Character, ItemSpellShieldingCap); else newbon->SpellShield += item->SpellShield; } - if(item->Shielding > 0) { - if((newbon->MeleeMitigation + item->Shielding) > RuleI(Character, ItemShieldingCap)) + if (item->Shielding > 0) { + if ((newbon->MeleeMitigation + item->Shielding) > RuleI(Character, ItemShieldingCap)) newbon->MeleeMitigation = RuleI(Character, ItemShieldingCap); else newbon->MeleeMitigation += item->Shielding; } - if(item->StunResist > 0) { - if((newbon->StunResist + item->StunResist) > RuleI(Character, ItemStunResistCap)) + if (item->StunResist > 0) { + if ((newbon->StunResist + item->StunResist) > RuleI(Character, ItemStunResistCap)) newbon->StunResist = RuleI(Character, ItemStunResistCap); else newbon->StunResist += item->StunResist; } - if(item->StrikeThrough > 0) { - if((newbon->StrikeThrough + item->StrikeThrough) > RuleI(Character, ItemStrikethroughCap)) + if (item->StrikeThrough > 0) { + if ((newbon->StrikeThrough + item->StrikeThrough) > RuleI(Character, ItemStrikethroughCap)) newbon->StrikeThrough = RuleI(Character, ItemStrikethroughCap); else newbon->StrikeThrough += item->StrikeThrough; } - if(item->Avoidance > 0) { - if((newbon->AvoidMeleeChance + item->Avoidance) > RuleI(Character, ItemAvoidanceCap)) + if (item->Avoidance > 0) { + if ((newbon->AvoidMeleeChance + item->Avoidance) > RuleI(Character, ItemAvoidanceCap)) newbon->AvoidMeleeChance = RuleI(Character, ItemAvoidanceCap); else newbon->AvoidMeleeChance += item->Avoidance; } - if(item->Accuracy > 0) { - if((newbon->HitChance + item->Accuracy) > RuleI(Character, ItemAccuracyCap)) + if (item->Accuracy > 0) { + if ((newbon->HitChance + item->Accuracy) > RuleI(Character, ItemAccuracyCap)) newbon->HitChance = RuleI(Character, ItemAccuracyCap); else newbon->HitChance += item->Accuracy; } - if(item->CombatEffects > 0) { - if((newbon->ProcChance + item->CombatEffects) > RuleI(Character, ItemCombatEffectsCap)) + if (item->CombatEffects > 0) { + if ((newbon->ProcChance + item->CombatEffects) > RuleI(Character, ItemCombatEffectsCap)) newbon->ProcChance = RuleI(Character, ItemCombatEffectsCap); else newbon->ProcChance += item->CombatEffects; } - if(item->DotShielding > 0) { - if((newbon->DoTShielding + item->DotShielding) > RuleI(Character, ItemDoTShieldingCap)) + if (item->DotShielding > 0) { + if ((newbon->DoTShielding + item->DotShielding) > RuleI(Character, ItemDoTShieldingCap)) newbon->DoTShielding = RuleI(Character, ItemDoTShieldingCap); else newbon->DoTShielding += item->DotShielding; } - if(item->HealAmt > 0) { - if((newbon->HealAmt + item->HealAmt) > RuleI(Character, ItemHealAmtCap)) + if (item->HealAmt > 0) { + if ((newbon->HealAmt + item->HealAmt) > RuleI(Character, ItemHealAmtCap)) newbon->HealAmt = RuleI(Character, ItemHealAmtCap); else newbon->HealAmt += item->HealAmt; } - if(item->SpellDmg > 0) { - if((newbon->SpellDmg + item->SpellDmg) > RuleI(Character, ItemSpellDmgCap)) + if (item->SpellDmg > 0) { + if ((newbon->SpellDmg + item->SpellDmg) > RuleI(Character, ItemSpellDmgCap)) newbon->SpellDmg = RuleI(Character, ItemSpellDmgCap); else newbon->SpellDmg += item->SpellDmg; } - if(item->Clairvoyance > 0) { - if((newbon->Clairvoyance + item->Clairvoyance) > RuleI(Character, ItemClairvoyanceCap)) + if (item->Clairvoyance > 0) { + if ((newbon->Clairvoyance + item->Clairvoyance) > RuleI(Character, ItemClairvoyanceCap)) newbon->Clairvoyance = RuleI(Character, ItemClairvoyanceCap); else newbon->Clairvoyance += item->Clairvoyance; } - if(item->DSMitigation > 0) { - if((newbon->DSMitigation + item->DSMitigation) > RuleI(Character, ItemDSMitigationCap)) + if (item->DSMitigation > 0) { + if ((newbon->DSMitigation + item->DSMitigation) > RuleI(Character, ItemDSMitigationCap)) newbon->DSMitigation = RuleI(Character, ItemDSMitigationCap); else newbon->DSMitigation += item->DSMitigation; } - if (item->Worn.Effect > 0 && item->Worn.Type == ET_WornEffect) {// latent effects + if (item->Worn.Effect > 0 && item->Worn.Type == ET_WornEffect) { // latent effects ApplySpellsBonuses(item->Worn.Effect, item->Worn.Level, newbon, 0, item->Worn.Type); } - if (item->Focus.Effect>0 && (item->Focus.Type == ET_Focus)) { // focus effects + if (item->Focus.Effect > 0 && (item->Focus.Type == ET_Focus)) { // focus effects ApplySpellsBonuses(item->Focus.Effect, item->Focus.Level, newbon, 0); } - switch(item->BardType) - { + switch (item->BardType) { case 51: /* All (e.g. Singing Short Sword) */ - { - if(item->BardValue > newbon->singingMod) - newbon->singingMod = item->BardValue; - if(item->BardValue > newbon->brassMod) - newbon->brassMod = item->BardValue; - if(item->BardValue > newbon->stringedMod) - newbon->stringedMod = item->BardValue; - if(item->BardValue > newbon->percussionMod) - newbon->percussionMod = item->BardValue; - if(item->BardValue > newbon->windMod) - newbon->windMod = item->BardValue; - break; - } + { + if (item->BardValue > newbon->singingMod) + newbon->singingMod = item->BardValue; + if (item->BardValue > newbon->brassMod) + newbon->brassMod = item->BardValue; + if (item->BardValue > newbon->stringedMod) + newbon->stringedMod = item->BardValue; + if (item->BardValue > newbon->percussionMod) + newbon->percussionMod = item->BardValue; + if (item->BardValue > newbon->windMod) + newbon->windMod = item->BardValue; + break; + } case 50: /* Singing */ - { - if(item->BardValue > newbon->singingMod) - newbon->singingMod = item->BardValue; - break; - } + { + if (item->BardValue > newbon->singingMod) + newbon->singingMod = item->BardValue; + break; + } case 23: /* Wind */ - { - if(item->BardValue > newbon->windMod) - newbon->windMod = item->BardValue; - break; - } + { + if (item->BardValue > newbon->windMod) + newbon->windMod = item->BardValue; + break; + } case 24: /* stringed */ - { - if(item->BardValue > newbon->stringedMod) - newbon->stringedMod = item->BardValue; - break; - } + { + if (item->BardValue > newbon->stringedMod) + newbon->stringedMod = item->BardValue; + break; + } case 25: /* brass */ - { - if(item->BardValue > newbon->brassMod) - newbon->brassMod = item->BardValue; - break; - } + { + if (item->BardValue > newbon->brassMod) + newbon->brassMod = item->BardValue; + break; + } case 26: /* Percussion */ - { - if(item->BardValue > newbon->percussionMod) - newbon->percussionMod = item->BardValue; - break; - } + { + if (item->BardValue > newbon->percussionMod) + newbon->percussionMod = item->BardValue; + break; + } } - if (item->SkillModValue != 0 && item->SkillModType <= HIGHEST_SKILL){ + if (item->SkillModValue != 0 && item->SkillModType <= HIGHEST_SKILL) { if ((item->SkillModValue > 0 && newbon->skillmod[item->SkillModType] < item->SkillModValue) || - (item->SkillModValue < 0 && newbon->skillmod[item->SkillModType] > item->SkillModValue)) - { + (item->SkillModValue < 0 && newbon->skillmod[item->SkillModType] > item->SkillModValue)) { newbon->skillmod[item->SkillModType] = item->SkillModValue; newbon->skillmodmax[item->SkillModType] = item->SkillModMax; } } // Add Item Faction Mods - if (item->FactionMod1) - { - if (item->FactionAmt1 > 0 && item->FactionAmt1 > GetItemFactionBonus(item->FactionMod1)) - { + if (item->FactionMod1) { + if (item->FactionAmt1 > 0 && item->FactionAmt1 > GetItemFactionBonus(item->FactionMod1)) { AddItemFactionBonus(item->FactionMod1, item->FactionAmt1); - } - else if (item->FactionAmt1 < 0 && item->FactionAmt1 < GetItemFactionBonus(item->FactionMod1)) - { + } else if (item->FactionAmt1 < 0 && item->FactionAmt1 < GetItemFactionBonus(item->FactionMod1)) { AddItemFactionBonus(item->FactionMod1, item->FactionAmt1); } } - if (item->FactionMod2) - { - if (item->FactionAmt2 > 0 && item->FactionAmt2 > GetItemFactionBonus(item->FactionMod2)) - { + if (item->FactionMod2) { + if (item->FactionAmt2 > 0 && item->FactionAmt2 > GetItemFactionBonus(item->FactionMod2)) { AddItemFactionBonus(item->FactionMod2, item->FactionAmt2); - } - else if (item->FactionAmt2 < 0 && item->FactionAmt2 < GetItemFactionBonus(item->FactionMod2)) - { + } else if (item->FactionAmt2 < 0 && item->FactionAmt2 < GetItemFactionBonus(item->FactionMod2)) { AddItemFactionBonus(item->FactionMod2, item->FactionAmt2); } } - if (item->FactionMod3) - { - if (item->FactionAmt3 > 0 && item->FactionAmt3 > GetItemFactionBonus(item->FactionMod3)) - { + if (item->FactionMod3) { + if (item->FactionAmt3 > 0 && item->FactionAmt3 > GetItemFactionBonus(item->FactionMod3)) { AddItemFactionBonus(item->FactionMod3, item->FactionAmt3); - } - else if (item->FactionAmt3 < 0 && item->FactionAmt3 < GetItemFactionBonus(item->FactionMod3)) - { + } else if (item->FactionAmt3 < 0 && item->FactionAmt3 < GetItemFactionBonus(item->FactionMod3)) { AddItemFactionBonus(item->FactionMod3, item->FactionAmt3); } } - if (item->FactionMod4) - { - if (item->FactionAmt4 > 0 && item->FactionAmt4 > GetItemFactionBonus(item->FactionMod4)) - { + if (item->FactionMod4) { + if (item->FactionAmt4 > 0 && item->FactionAmt4 > GetItemFactionBonus(item->FactionMod4)) { AddItemFactionBonus(item->FactionMod4, item->FactionAmt4); - } - else if (item->FactionAmt4 < 0 && item->FactionAmt4 < GetItemFactionBonus(item->FactionMod4)) - { + } else if (item->FactionAmt4 < 0 && item->FactionAmt4 < GetItemFactionBonus(item->FactionMod4)) { AddItemFactionBonus(item->FactionMod4, item->FactionAmt4); } } if (item->ExtraDmgSkill != 0 && item->ExtraDmgSkill <= HIGHEST_SKILL) { - if((newbon->SkillDamageAmount[item->ExtraDmgSkill] + item->ExtraDmgAmt) > RuleI(Character, ItemExtraDmgCap)) + if ((newbon->SkillDamageAmount[item->ExtraDmgSkill] + item->ExtraDmgAmt) > + RuleI(Character, ItemExtraDmgCap)) newbon->SkillDamageAmount[item->ExtraDmgSkill] = RuleI(Character, ItemExtraDmgCap); else newbon->SkillDamageAmount[item->ExtraDmgSkill] += item->ExtraDmgAmt; } - if (!isAug) - { - int i; - for (i = 0; i < EmuConstants::ITEM_COMMON_SIZE; i++) { - AddItemBonuses(inst->GetAugment(i),newbon,true); - } + if (!isAug) { + for (int i = 0; i < EmuConstants::ITEM_COMMON_SIZE; i++) + AddItemBonuses(inst->GetAugment(i), newbon, true, false, rec_level); } - } void Client::AdditiveWornBonuses(const ItemInst *inst, StatBonuses* newbon, bool isAug) { diff --git a/zone/bot.cpp b/zone/bot.cpp index 01f2da41d..9207b5139 100644 --- a/zone/bot.cpp +++ b/zone/bot.cpp @@ -8829,7 +8829,7 @@ void Bot::CalcItemBonuses(StatBonuses* newbon) newbon->EnduranceRegen = CalcEnduranceRegenCap(); } -void Bot::AddItemBonuses(const ItemInst *inst, StatBonuses* newbon, bool isAug, bool isTribute) { +void Bot::AddItemBonuses(const ItemInst *inst, StatBonuses* newbon, bool isAug, bool isTribute, in rec_override) { if(!inst || !inst->IsType(ItemClassCommon)) { return; @@ -8848,12 +8848,13 @@ void Bot::AddItemBonuses(const ItemInst *inst, StatBonuses* newbon, bool isAug, return; } - if(GetLevel() < item->ReqLevel) + if(GetLevel() < inst->GetItemRequiredLevel(true)) { return; } - if(GetLevel() >= item->RecLevel) + auto rec_level = isAug ? rec_override : inst->GetItemRecommendedLevel(true); + if(GetLevel() >= rec_level) { newbon->AC += item->AC; newbon->HP += item->HP; @@ -8907,55 +8908,54 @@ void Bot::AddItemBonuses(const ItemInst *inst, StatBonuses* newbon, bool isAug, else { int lvl = GetLevel(); - int reclvl = item->RecLevel; - newbon->AC += CalcRecommendedLevelBonus( lvl, reclvl, item->AC ); - newbon->HP += CalcRecommendedLevelBonus( lvl, reclvl, item->HP ); - newbon->Mana += CalcRecommendedLevelBonus( lvl, reclvl, item->Mana ); - newbon->Endurance += CalcRecommendedLevelBonus( lvl, reclvl, item->Endur ); - newbon->ATK += CalcRecommendedLevelBonus( lvl, reclvl, item->Attack ); - newbon->STR += CalcRecommendedLevelBonus( lvl, reclvl, (item->AStr + item->HeroicStr) ); - newbon->STA += CalcRecommendedLevelBonus( lvl, reclvl, (item->ASta + item->HeroicSta) ); - newbon->DEX += CalcRecommendedLevelBonus( lvl, reclvl, (item->ADex + item->HeroicDex) ); - newbon->AGI += CalcRecommendedLevelBonus( lvl, reclvl, (item->AAgi + item->HeroicAgi) ); - newbon->INT += CalcRecommendedLevelBonus( lvl, reclvl, (item->AInt + item->HeroicInt) ); - newbon->WIS += CalcRecommendedLevelBonus( lvl, reclvl, (item->AWis + item->HeroicWis) ); - newbon->CHA += CalcRecommendedLevelBonus( lvl, reclvl, (item->ACha + item->HeroicCha) ); + newbon->AC += CalcRecommendedLevelBonus( lvl, rec_level, item->AC ); + newbon->HP += CalcRecommendedLevelBonus( lvl, rec_level, item->HP ); + newbon->Mana += CalcRecommendedLevelBonus( lvl, rec_level, item->Mana ); + newbon->Endurance += CalcRecommendedLevelBonus( lvl, rec_level, item->Endur ); + newbon->ATK += CalcRecommendedLevelBonus( lvl, rec_level, item->Attack ); + newbon->STR += CalcRecommendedLevelBonus( lvl, rec_level, (item->AStr + item->HeroicStr) ); + newbon->STA += CalcRecommendedLevelBonus( lvl, rec_level, (item->ASta + item->HeroicSta) ); + newbon->DEX += CalcRecommendedLevelBonus( lvl, rec_level, (item->ADex + item->HeroicDex) ); + newbon->AGI += CalcRecommendedLevelBonus( lvl, rec_level, (item->AAgi + item->HeroicAgi) ); + newbon->INT += CalcRecommendedLevelBonus( lvl, rec_level, (item->AInt + item->HeroicInt) ); + newbon->WIS += CalcRecommendedLevelBonus( lvl, rec_level, (item->AWis + item->HeroicWis) ); + newbon->CHA += CalcRecommendedLevelBonus( lvl, rec_level, (item->ACha + item->HeroicCha) ); - newbon->MR += CalcRecommendedLevelBonus( lvl, reclvl, (item->MR + item->HeroicMR) ); - newbon->FR += CalcRecommendedLevelBonus( lvl, reclvl, (item->FR + item->HeroicFR) ); - newbon->CR += CalcRecommendedLevelBonus( lvl, reclvl, (item->CR + item->HeroicCR) ); - newbon->PR += CalcRecommendedLevelBonus( lvl, reclvl, (item->PR + item->HeroicPR) ); - newbon->DR += CalcRecommendedLevelBonus( lvl, reclvl, (item->DR + item->HeroicDR) ); - newbon->Corrup += CalcRecommendedLevelBonus( lvl, reclvl, (item->SVCorruption + item->HeroicSVCorrup) ); + newbon->MR += CalcRecommendedLevelBonus( lvl, rec_level, (item->MR + item->HeroicMR) ); + newbon->FR += CalcRecommendedLevelBonus( lvl, rec_level, (item->FR + item->HeroicFR) ); + newbon->CR += CalcRecommendedLevelBonus( lvl, rec_level, (item->CR + item->HeroicCR) ); + newbon->PR += CalcRecommendedLevelBonus( lvl, rec_level, (item->PR + item->HeroicPR) ); + newbon->DR += CalcRecommendedLevelBonus( lvl, rec_level, (item->DR + item->HeroicDR) ); + newbon->Corrup += CalcRecommendedLevelBonus( lvl, rec_level, (item->SVCorruption + item->HeroicSVCorrup) ); - newbon->STRCapMod += CalcRecommendedLevelBonus( lvl, reclvl, item->HeroicStr ); - newbon->STACapMod += CalcRecommendedLevelBonus( lvl, reclvl, item->HeroicSta ); - newbon->DEXCapMod += CalcRecommendedLevelBonus( lvl, reclvl, item->HeroicDex ); - newbon->AGICapMod += CalcRecommendedLevelBonus( lvl, reclvl, item->HeroicAgi ); - newbon->INTCapMod += CalcRecommendedLevelBonus( lvl, reclvl, item->HeroicInt ); - newbon->WISCapMod += CalcRecommendedLevelBonus( lvl, reclvl, item->HeroicWis ); - newbon->CHACapMod += CalcRecommendedLevelBonus( lvl, reclvl, item->HeroicCha ); - newbon->MRCapMod += CalcRecommendedLevelBonus( lvl, reclvl, item->HeroicMR ); - newbon->CRCapMod += CalcRecommendedLevelBonus( lvl, reclvl, item->HeroicFR ); - newbon->FRCapMod += CalcRecommendedLevelBonus( lvl, reclvl, item->HeroicCR ); - newbon->PRCapMod += CalcRecommendedLevelBonus( lvl, reclvl, item->HeroicPR ); - newbon->DRCapMod += CalcRecommendedLevelBonus( lvl, reclvl, item->HeroicDR ); - newbon->CorrupCapMod += CalcRecommendedLevelBonus( lvl, reclvl, item->HeroicSVCorrup ); + newbon->STRCapMod += CalcRecommendedLevelBonus( lvl, rec_level, item->HeroicStr ); + newbon->STACapMod += CalcRecommendedLevelBonus( lvl, rec_level, item->HeroicSta ); + newbon->DEXCapMod += CalcRecommendedLevelBonus( lvl, rec_level, item->HeroicDex ); + newbon->AGICapMod += CalcRecommendedLevelBonus( lvl, rec_level, item->HeroicAgi ); + newbon->INTCapMod += CalcRecommendedLevelBonus( lvl, rec_level, item->HeroicInt ); + newbon->WISCapMod += CalcRecommendedLevelBonus( lvl, rec_level, item->HeroicWis ); + newbon->CHACapMod += CalcRecommendedLevelBonus( lvl, rec_level, item->HeroicCha ); + newbon->MRCapMod += CalcRecommendedLevelBonus( lvl, rec_level, item->HeroicMR ); + newbon->CRCapMod += CalcRecommendedLevelBonus( lvl, rec_level, item->HeroicFR ); + newbon->FRCapMod += CalcRecommendedLevelBonus( lvl, rec_level, item->HeroicCR ); + newbon->PRCapMod += CalcRecommendedLevelBonus( lvl, rec_level, item->HeroicPR ); + newbon->DRCapMod += CalcRecommendedLevelBonus( lvl, rec_level, item->HeroicDR ); + newbon->CorrupCapMod += CalcRecommendedLevelBonus( lvl, rec_level, item->HeroicSVCorrup ); - newbon->HeroicSTR += CalcRecommendedLevelBonus( lvl, reclvl, item->HeroicStr ); - newbon->HeroicSTA += CalcRecommendedLevelBonus( lvl, reclvl, item->HeroicSta ); - newbon->HeroicDEX += CalcRecommendedLevelBonus( lvl, reclvl, item->HeroicDex ); - newbon->HeroicAGI += CalcRecommendedLevelBonus( lvl, reclvl, item->HeroicAgi ); - newbon->HeroicINT += CalcRecommendedLevelBonus( lvl, reclvl, item->HeroicInt ); - newbon->HeroicWIS += CalcRecommendedLevelBonus( lvl, reclvl, item->HeroicWis ); - newbon->HeroicCHA += CalcRecommendedLevelBonus( lvl, reclvl, item->HeroicCha ); - newbon->HeroicMR += CalcRecommendedLevelBonus( lvl, reclvl, item->HeroicMR ); - newbon->HeroicFR += CalcRecommendedLevelBonus( lvl, reclvl, item->HeroicFR ); - newbon->HeroicCR += CalcRecommendedLevelBonus( lvl, reclvl, item->HeroicCR ); - newbon->HeroicPR += CalcRecommendedLevelBonus( lvl, reclvl, item->HeroicPR ); - newbon->HeroicDR += CalcRecommendedLevelBonus( lvl, reclvl, item->HeroicDR ); - newbon->HeroicCorrup += CalcRecommendedLevelBonus( lvl, reclvl, item->HeroicSVCorrup ); + newbon->HeroicSTR += CalcRecommendedLevelBonus( lvl, rec_level, item->HeroicStr ); + newbon->HeroicSTA += CalcRecommendedLevelBonus( lvl, rec_level, item->HeroicSta ); + newbon->HeroicDEX += CalcRecommendedLevelBonus( lvl, rec_level, item->HeroicDex ); + newbon->HeroicAGI += CalcRecommendedLevelBonus( lvl, rec_level, item->HeroicAgi ); + newbon->HeroicINT += CalcRecommendedLevelBonus( lvl, rec_level, item->HeroicInt ); + newbon->HeroicWIS += CalcRecommendedLevelBonus( lvl, rec_level, item->HeroicWis ); + newbon->HeroicCHA += CalcRecommendedLevelBonus( lvl, rec_level, item->HeroicCha ); + newbon->HeroicMR += CalcRecommendedLevelBonus( lvl, rec_level, item->HeroicMR ); + newbon->HeroicFR += CalcRecommendedLevelBonus( lvl, rec_level, item->HeroicFR ); + newbon->HeroicCR += CalcRecommendedLevelBonus( lvl, rec_level, item->HeroicCR ); + newbon->HeroicPR += CalcRecommendedLevelBonus( lvl, rec_level, item->HeroicPR ); + newbon->HeroicDR += CalcRecommendedLevelBonus( lvl, rec_level, item->HeroicDR ); + newbon->HeroicCorrup += CalcRecommendedLevelBonus( lvl, rec_level, item->HeroicSVCorrup ); } //FatherNitwit: New style haste, shields, and regens @@ -9124,10 +9124,8 @@ void Bot::AddItemBonuses(const ItemInst *inst, StatBonuses* newbon, bool isAug, if (!isAug) { - int i; - for (i = 0; i < EmuConstants::ITEM_COMMON_SIZE; i++) { - AddItemBonuses(inst->GetAugment(i),newbon,true); - } + for (int i = 0; i < EmuConstants::ITEM_COMMON_SIZE; i++) + AddItemBonuses(inst->GetAugment(i),newbon,true, false, rec_level); } } diff --git a/zone/bot.h b/zone/bot.h index a280a2a58..c35fd1f7b 100644 --- a/zone/bot.h +++ b/zone/bot.h @@ -193,7 +193,7 @@ public: virtual int32 CheckAggroAmount(uint16 spellid); virtual void CalcBonuses(); void CalcItemBonuses(StatBonuses* newbon); - void AddItemBonuses(const ItemInst *inst, StatBonuses* newbon, bool isAug = false, bool isTribute = false); + void AddItemBonuses(const ItemInst *inst, StatBonuses* newbon, bool isAug = false, bool isTribute = false, int rec_override = 0); int CalcRecommendedLevelBonus(uint8 level, uint8 reclevel, int basestat); virtual void MakePet(uint16 spell_id, const char* pettype, const char *petname = nullptr); virtual FACTION_VALUE GetReverseFactionCon(Mob* iOther); diff --git a/zone/client.h b/zone/client.h index bc2f89b87..24522f63d 100644 --- a/zone/client.h +++ b/zone/client.h @@ -1275,7 +1275,7 @@ public: protected: friend class Mob; void CalcItemBonuses(StatBonuses* newbon); - void AddItemBonuses(const ItemInst *inst, StatBonuses* newbon, bool isAug = false, bool isTribute = false); + void AddItemBonuses(const ItemInst *inst, StatBonuses* newbon, bool isAug = false, bool isTribute = false, int rec_override = 0); void AdditiveWornBonuses(const ItemInst *inst, StatBonuses* newbon, bool isAug = false); int CalcRecommendedLevelBonus(uint8 level, uint8 reclevel, int basestat); void CalcEdibleBonuses(StatBonuses* newbon); From ad1c91f204c2e05139a02260d5f9dde969eafb8c Mon Sep 17 00:00:00 2001 From: "Michael Cook (mackal)" Date: Sat, 16 Jan 2016 17:52:21 -0500 Subject: [PATCH 19/56] Fix bots --- zone/bot.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/zone/bot.cpp b/zone/bot.cpp index 9207b5139..5ce63714c 100644 --- a/zone/bot.cpp +++ b/zone/bot.cpp @@ -8829,7 +8829,7 @@ void Bot::CalcItemBonuses(StatBonuses* newbon) newbon->EnduranceRegen = CalcEnduranceRegenCap(); } -void Bot::AddItemBonuses(const ItemInst *inst, StatBonuses* newbon, bool isAug, bool isTribute, in rec_override) { +void Bot::AddItemBonuses(const ItemInst *inst, StatBonuses* newbon, bool isAug, bool isTribute, int rec_override) { if(!inst || !inst->IsType(ItemClassCommon)) { return; From 600866f5730f2b01803ddb37306fd39e553b668d Mon Sep 17 00:00:00 2001 From: "Michael Cook (mackal)" Date: Sat, 16 Jan 2016 18:29:17 -0500 Subject: [PATCH 20/56] Rewrite Bane and Elemental Dmg stuff and GetWeaponDamage (client version) --- zone/attack.cpp | 253 +++++++++++++----------------------------------- zone/mob.cpp | 168 +++++++++++++++++++++++++++++++- zone/mob.h | 2 + 3 files changed, 234 insertions(+), 189 deletions(-) diff --git a/zone/attack.cpp b/zone/attack.cpp index 532a53686..85ee29e9d 100644 --- a/zone/attack.cpp +++ b/zone/attack.cpp @@ -928,231 +928,108 @@ int Mob::GetWeaponDamage(Mob *against, const ItemInst *weapon_item, uint32 *hate int banedmg = 0; int x = 0; - if(!against || against->GetInvul() || against->GetSpecialAbility(IMMUNE_MELEE)){ + if (!against || against->GetInvul() || against->GetSpecialAbility(IMMUNE_MELEE)) return 0; - } - //check for items being illegally attained - if(weapon_item){ - const Item_Struct *mWeaponItem = weapon_item->GetItem(); - if(mWeaponItem){ - if(mWeaponItem->ReqLevel > GetLevel()){ - return 0; - } - - if(!weapon_item->IsEquipable(GetBaseRace(), GetClass())){ - return 0; - } - } - else{ + // check for items being illegally attained + if (weapon_item) { + if (!weapon_item->GetItem()) + return 0; + + if (weapon_item->GetItemRequiredLevel(true) > GetLevel()) + return 0; + + if (!weapon_item->IsEquipable(GetBaseRace(), GetClass())) return 0; - } } - if(against->GetSpecialAbility(IMMUNE_MELEE_NONMAGICAL)){ - if(weapon_item){ + if (against->GetSpecialAbility(IMMUNE_MELEE_NONMAGICAL)) { + if (weapon_item) { // check to see if the weapon is magic - bool MagicWeapon = false; - if(weapon_item->GetItem() && weapon_item->GetItem()->Magic) - MagicWeapon = true; - else - if(spellbonuses.MagicWeapon || itembonuses.MagicWeapon) - MagicWeapon = true; + bool MagicWeapon = weapon_item->GetItemMagical(true) || spellbonuses.MagicWeapon || itembonuses.MagicWeapon; + if (MagicWeapon) { + auto rec_level = weapon_item->GetItemRecommendedLevel(true); + if (IsClient() && GetLevel() < rec_level) + dmg = CastToClient()->CalcRecommendedLevelBonus( + GetLevel(), rec_level, weapon_item->GetItemWeaponDamage(true)); else - // An augment on the weapon that is marked magic makes - // the item magical. - for(x = 0; MagicWeapon == false && x < EmuConstants::ITEM_COMMON_SIZE; x++) - { - if(weapon_item->GetAugment(x) && weapon_item->GetAugment(x)->GetItem()) - { - if (weapon_item->GetAugment(x)->GetItem()->Magic) - MagicWeapon = true; - } - } - - if(MagicWeapon) { - - if(IsClient() && GetLevel() < weapon_item->GetItem()->RecLevel){ - dmg = CastToClient()->CalcRecommendedLevelBonus(GetLevel(), weapon_item->GetItem()->RecLevel, weapon_item->GetItem()->Damage); - } - else{ - dmg = weapon_item->GetItem()->Damage; - } - - for(int x = 0; x < EmuConstants::ITEM_COMMON_SIZE; x++){ - if(weapon_item->GetAugment(x) && weapon_item->GetAugment(x)->GetItem()){ - dmg += weapon_item->GetAugment(x)->GetItem()->Damage; - if (hate) *hate += weapon_item->GetAugment(x)->GetItem()->Damage + weapon_item->GetAugment(x)->GetItem()->ElemDmgAmt; - } - } + dmg = weapon_item->GetItemWeaponDamage(true); dmg = dmg <= 0 ? 1 : dmg; - } - else + } else { return 0; - } - else{ - bool MagicGloves=false; + } + } else { + bool MagicGloves = false; if (IsClient()) { - ItemInst *gloves=CastToClient()->GetInv().GetItem(MainHands); - if (gloves != nullptr) { - MagicGloves = gloves->GetItem()->Magic; - } + const ItemInst *gloves = CastToClient()->GetInv().GetItem(MainHands); + if (gloves) + MagicGloves = gloves->GetItemMagical(true); } - if((GetClass() == MONK || GetClass() == BEASTLORD)) { - if(MagicGloves || GetLevel() >= 30){ + if (GetClass() == MONK || GetClass() == BEASTLORD) { + if (MagicGloves || GetLevel() >= 30) { dmg = GetHandToHandDamage(); - if (hate) *hate += dmg; + if (hate) + *hate += dmg; } - } - else if(GetOwner() && GetLevel() >= RuleI(Combat, PetAttackMagicLevel)){ //pets wouldn't actually use this but... - dmg = 1; //it gives us an idea if we can hit - } - else if(MagicGloves || GetSpecialAbility(SPECATK_MAGICAL)){ + } else if (GetOwner() && + GetLevel() >= + RuleI(Combat, PetAttackMagicLevel)) { // pets wouldn't actually use this but... + dmg = 1; // it gives us an idea if we can hit + } else if (MagicGloves || GetSpecialAbility(SPECATK_MAGICAL)) { dmg = 1; - } - else + } else return 0; } - } - else{ - if(weapon_item){ - if(weapon_item->GetItem()){ - - if(IsClient() && GetLevel() < weapon_item->GetItem()->RecLevel){ - dmg = CastToClient()->CalcRecommendedLevelBonus(GetLevel(), weapon_item->GetItem()->RecLevel, weapon_item->GetItem()->Damage); - } - else{ - dmg = weapon_item->GetItem()->Damage; + } else { + if (weapon_item) { + if (weapon_item->GetItem()) { + auto rec_level = weapon_item->GetItemRecommendedLevel(true); + if (IsClient() && GetLevel() < rec_level) { + dmg = CastToClient()->CalcRecommendedLevelBonus( + GetLevel(), rec_level, weapon_item->GetItemWeaponDamage(true)); + } else { + dmg = weapon_item->GetItemWeaponDamage(true); } - for (int x = 0; x < EmuConstants::ITEM_COMMON_SIZE; x++){ - if(weapon_item->GetAugment(x) && weapon_item->GetAugment(x)->GetItem()){ - dmg += weapon_item->GetAugment(x)->GetItem()->Damage; - if (hate) *hate += weapon_item->GetAugment(x)->GetItem()->Damage + weapon_item->GetAugment(x)->GetItem()->ElemDmgAmt; - } - } dmg = dmg <= 0 ? 1 : dmg; } - } - else{ + } else { dmg = GetHandToHandDamage(); - if (hate) *hate += dmg; + if (hate) + *hate += dmg; } } int eledmg = 0; - if(!against->GetSpecialAbility(IMMUNE_MAGIC)){ - if(weapon_item && weapon_item->GetItem() && weapon_item->GetItem()->ElemDmgAmt){ - if(IsClient() && GetLevel() < weapon_item->GetItem()->RecLevel){ - eledmg = CastToClient()->CalcRecommendedLevelBonus(GetLevel(), weapon_item->GetItem()->RecLevel, weapon_item->GetItem()->ElemDmgAmt); - } - else{ - eledmg = weapon_item->GetItem()->ElemDmgAmt; - } - - if(eledmg) - { - eledmg = (eledmg * against->ResistSpell(weapon_item->GetItem()->ElemDmgType, 0, this) / 100); - } - } - - if(weapon_item){ - for (int x = 0; x < EmuConstants::ITEM_COMMON_SIZE; x++){ - if(weapon_item->GetAugment(x) && weapon_item->GetAugment(x)->GetItem()){ - if(weapon_item->GetAugment(x)->GetItem()->ElemDmgAmt) - eledmg += (weapon_item->GetAugment(x)->GetItem()->ElemDmgAmt * against->ResistSpell(weapon_item->GetAugment(x)->GetItem()->ElemDmgType, 0, this) / 100); - } - } - } + if (!against->GetSpecialAbility(IMMUNE_MAGIC)) { + if (weapon_item && weapon_item->GetItem() && weapon_item->GetItemElementalFlag(true)) + // the client actually has the way this is done, it does not appear to check req! + eledmg = against->ResistElementalWeaponDmg(weapon_item); } - if(against->GetSpecialAbility(IMMUNE_MELEE_EXCEPT_BANE)){ - if(weapon_item && weapon_item->GetItem()){ - if(weapon_item->GetItem()->BaneDmgBody == against->GetBodyType()){ - if(IsClient() && GetLevel() < weapon_item->GetItem()->RecLevel){ - banedmg += CastToClient()->CalcRecommendedLevelBonus(GetLevel(), weapon_item->GetItem()->RecLevel, weapon_item->GetItem()->BaneDmgAmt); - } - else{ - banedmg += weapon_item->GetItem()->BaneDmgAmt; - } - } + if (weapon_item && weapon_item->GetItem() && + (weapon_item->GetItemBaneDamageBody(true) || weapon_item->GetItemBaneDamageRace(true))) + banedmg = against->CheckBaneDamage(weapon_item); - if(weapon_item->GetItem()->BaneDmgRace == against->GetRace()){ - if(IsClient() && GetLevel() < weapon_item->GetItem()->RecLevel){ - banedmg += CastToClient()->CalcRecommendedLevelBonus(GetLevel(), weapon_item->GetItem()->RecLevel, weapon_item->GetItem()->BaneDmgRaceAmt); - } - else{ - banedmg += weapon_item->GetItem()->BaneDmgRaceAmt; - } - } - - for (int x = 0; x < EmuConstants::ITEM_COMMON_SIZE; x++){ - if(weapon_item->GetAugment(x) && weapon_item->GetAugment(x)->GetItem()){ - if(weapon_item->GetAugment(x)->GetItem()->BaneDmgBody == against->GetBodyType()){ - banedmg += weapon_item->GetAugment(x)->GetItem()->BaneDmgAmt; - } - - if(weapon_item->GetAugment(x)->GetItem()->BaneDmgRace == against->GetRace()){ - banedmg += weapon_item->GetAugment(x)->GetItem()->BaneDmgRaceAmt; - } - } - } - } - - if(!eledmg && !banedmg) - { - if(!GetSpecialAbility(SPECATK_BANE)) + if (against->GetSpecialAbility(IMMUNE_MELEE_EXCEPT_BANE)) { + if (!eledmg && !banedmg) { + if (!GetSpecialAbility(SPECATK_BANE)) return 0; else return 1; - } - else { + } else { dmg += (banedmg + eledmg); - if (hate) *hate += banedmg; - } - } - else{ - if(weapon_item && weapon_item->GetItem()){ - if(weapon_item->GetItem()->BaneDmgBody == against->GetBodyType()){ - if(IsClient() && GetLevel() < weapon_item->GetItem()->RecLevel){ - banedmg += CastToClient()->CalcRecommendedLevelBonus(GetLevel(), weapon_item->GetItem()->RecLevel, weapon_item->GetItem()->BaneDmgAmt); - } - else{ - banedmg += weapon_item->GetItem()->BaneDmgAmt; - } - } - - if(weapon_item->GetItem()->BaneDmgRace == against->GetRace()){ - if(IsClient() && GetLevel() < weapon_item->GetItem()->RecLevel){ - banedmg += CastToClient()->CalcRecommendedLevelBonus(GetLevel(), weapon_item->GetItem()->RecLevel, weapon_item->GetItem()->BaneDmgRaceAmt); - } - else{ - banedmg += weapon_item->GetItem()->BaneDmgRaceAmt; - } - } - - for (int x = 0; x < EmuConstants::ITEM_COMMON_SIZE; x++){ - if(weapon_item->GetAugment(x) && weapon_item->GetAugment(x)->GetItem()){ - if(weapon_item->GetAugment(x)->GetItem()->BaneDmgBody == against->GetBodyType()){ - banedmg += weapon_item->GetAugment(x)->GetItem()->BaneDmgAmt; - } - - if(weapon_item->GetAugment(x)->GetItem()->BaneDmgRace == against->GetRace()){ - banedmg += weapon_item->GetAugment(x)->GetItem()->BaneDmgRaceAmt; - } - } - } + if (hate) + *hate += banedmg; } + } else { dmg += (banedmg + eledmg); - if (hate) *hate += banedmg; + if (hate) + *hate += banedmg; } - if(dmg <= 0){ - return 0; - } - else - return dmg; + return std::max(0, dmg); } //note: throughout this method, setting `damage` to a negative is a way to diff --git a/zone/mob.cpp b/zone/mob.cpp index e28ccefcc..2ac1c7f5e 100644 --- a/zone/mob.cpp +++ b/zone/mob.cpp @@ -5689,4 +5689,170 @@ int32 Mob::GetMeleeMitigation() { mitigation += itembonuses.MeleeMitigationEffect; mitigation += aabonuses.MeleeMitigationEffect; return mitigation; -} \ No newline at end of file +} + +/* this is the mob being attacked. + * Pass in the weapon's ItemInst + */ +int Mob::ResistElementalWeaponDmg(const ItemInst *item) +{ + if (!item) + return 0; + int magic = 0, fire = 0, cold = 0, poison = 0, disease = 0, chromatic = 0, prismatic = 0, physical = 0, + corruption = 0; + int resist = 0; + int roll = 0; + /* this is how the client does the resist rolls for these. + * Given the difficulty of parsing out these resists, I'll trust the client + */ + if (item->GetItemElementalDamage(magic, fire, cold, poison, disease, chromatic, prismatic, physical, corruption, true)) { + if (magic) { + resist = GetMR(); + if (resist >= 201) { + magic = 0; + } else { + roll = zone->random.Int(0, 200) - resist; + if (roll < 1) + magic = 0; + else if (roll < 100) + magic = magic * roll / 100; + } + } + + if (fire) { + resist = GetFR(); + if (resist >= 201) { + fire = 0; + } else { + roll = zone->random.Int(0, 200) - resist; + if (roll < 1) + fire = 0; + else if (roll < 100) + fire = fire * roll / 100; + } + } + + if (cold) { + resist = GetCR(); + if (resist >= 201) { + cold = 0; + } else { + roll = zone->random.Int(0, 200) - resist; + if (roll < 1) + cold = 0; + else if (roll < 100) + cold = cold * roll / 100; + } + } + + if (poison) { + resist = GetPR(); + if (resist >= 201) { + poison = 0; + } else { + roll = zone->random.Int(0, 200) - resist; + if (roll < 1) + poison = 0; + else if (roll < 100) + poison = poison * roll / 100; + } + } + + if (disease) { + resist = GetDR(); + if (resist >= 201) { + disease = 0; + } else { + roll = zone->random.Int(0, 200) - resist; + if (roll < 1) + disease = 0; + else if (roll < 100) + disease = disease * roll / 100; + } + } + + if (corruption) { + resist = GetCorrup(); + if (resist >= 201) { + corruption = 0; + } else { + roll = zone->random.Int(0, 200) - resist; + if (roll < 1) + corruption = 0; + else if (roll < 100) + corruption = corruption * roll / 100; + } + } + + if (chromatic) { + resist = GetFR(); + int temp = GetCR(); + if (temp < resist) + resist = temp; + + temp = GetMR(); + if (temp < resist) + resist = temp; + + temp = GetDR(); + if (temp < resist) + resist = temp; + + temp = GetPR(); + if (temp < resist) + resist = temp; + + if (resist >= 201) { + chromatic = 0; + } else { + roll = zone->random.Int(0, 200) - resist; + if (roll < 1) + chromatic = 0; + else if (roll < 100) + chromatic = chromatic * roll / 100; + } + } + + if (prismatic) { + resist = (GetFR() + GetCR() + GetMR() + GetDR() + GetPR()) / 5; + if (resist >= 201) { + prismatic = 0; + } else { + roll = zone->random.Int(0, 200) - resist; + if (roll < 1) + prismatic = 0; + else if (roll < 100) + prismatic = prismatic * roll / 100; + } + } + + if (physical) { + resist = GetPhR(); + if (resist >= 201) { + physical = 0; + } else { + roll = zone->random.Int(0, 200) - resist; + if (roll < 1) + physical = 0; + else if (roll < 100) + physical = physical * roll / 100; + } + } + } + + return magic + fire + cold + poison + disease + chromatic + prismatic + physical + corruption; +} + +/* this is the mob being attacked. + * Pass in the weapon's ItemInst + */ +int Mob::CheckBaneDamage(const ItemInst *item) +{ + if (!item) + return 0; + + int damage = item->GetItemBaneDamageBody(GetBodyType(), true); + damage += item->GetItemBaneDamageRace(GetRace(), true); + + return damage; +} diff --git a/zone/mob.h b/zone/mob.h index 334c81e51..516bdfe8b 100644 --- a/zone/mob.h +++ b/zone/mob.h @@ -231,6 +231,8 @@ public: int resist_override = 0, bool CharismaCheck = false, bool CharmTick = false, bool IsRoot = false, int level_override = -1); int ResistPhysical(int level_diff, uint8 caster_level); + int ResistElementalWeaponDmg(const ItemInst *item); + int CheckBaneDamage(const ItemInst *item); uint16 GetSpecializeSkillValue(uint16 spell_id) const; void SendSpellBarDisable(); void SendSpellBarEnable(uint16 spellid); From 1ddbfdf4e9ee03b9a6ce0d599ad8f581930f59e0 Mon Sep 17 00:00:00 2001 From: "Michael Cook (mackal)" Date: Sat, 16 Jan 2016 18:46:32 -0500 Subject: [PATCH 21/56] Fix ItemInst::GetItemElementalDamage --- common/item.cpp | 18 +++++++++--------- 1 file changed, 9 insertions(+), 9 deletions(-) diff --git a/common/item.cpp b/common/item.cpp index a7b6987de..26ec154c3 100644 --- a/common/item.cpp +++ b/common/item.cpp @@ -2342,31 +2342,31 @@ int ItemInst::GetItemElementalDamage(int &magic, int &fire, int &cold, int &pois if (item) { switch (item->ElemDmgType) { case RESIST_MAGIC: - magic = item->ElemDmgAmt; + magic += item->ElemDmgAmt; break; case RESIST_FIRE: - fire = item->ElemDmgAmt; + fire += item->ElemDmgAmt; break; case RESIST_COLD: - cold = item->ElemDmgAmt; + cold += item->ElemDmgAmt; break; case RESIST_POISON: - poison = item->ElemDmgAmt; + poison += item->ElemDmgAmt; break; case RESIST_DISEASE: - disease = item->ElemDmgAmt; + disease += item->ElemDmgAmt; break; case RESIST_CHROMATIC: - chromatic = item->ElemDmgAmt; + chromatic += item->ElemDmgAmt; break; case RESIST_PRISMATIC: - prismatic = item->ElemDmgAmt; + prismatic += item->ElemDmgAmt; break; case RESIST_PHYSICAL: - physical = item->ElemDmgAmt; + physical += item->ElemDmgAmt; break; case RESIST_CORRUPTION: - corruption = item->ElemDmgAmt; + corruption += item->ElemDmgAmt; break; } From 04b7ba7a1d0ff983e0de2d2e6800e3ec7e334015 Mon Sep 17 00:00:00 2001 From: Uleat Date: Wed, 20 Jan 2016 21:54:18 -0500 Subject: [PATCH 22/56] Added proxy accessors for all TextLink fields --- zone/client.cpp | 49 ++++++++++++++++++++++++++++++++++++++++++------- zone/client.h | 30 +++++++++++++++++++++++++++++- 2 files changed, 71 insertions(+), 8 deletions(-) diff --git a/zone/client.cpp b/zone/client.cpp index ceedf19d7..3fab7671e 100644 --- a/zone/client.cpp +++ b/zone/client.cpp @@ -8423,7 +8423,19 @@ void Client::TextLink::Reset() m_ItemData = nullptr; m_LootData = nullptr; m_ItemInst = nullptr; + m_Proxy_unknown_1 = NOT_USED; m_ProxyItemID = NOT_USED; + m_ProxyAugment1ID = NOT_USED; + m_ProxyAugment2ID = NOT_USED; + m_ProxyAugment3ID = NOT_USED; + m_ProxyAugment4ID = NOT_USED; + m_ProxyAugment5ID = NOT_USED; + m_ProxyAugment6ID = NOT_USED; + m_ProxyIsEvolving = NOT_USED; + m_ProxyEvolveGroup = NOT_USED; + m_ProxyEvolveLevel = NOT_USED; + m_ProxyOrnamentIcon = NOT_USED; + m_ProxyHash = NOT_USED; m_ProxyText = nullptr; m_TaskUse = false; m_Link.clear(); @@ -8439,8 +8451,8 @@ void Client::TextLink::generate_body() RoF2: "%1X" "%05X" "%05X" "%05X" "%05X" "%05X" "%05X" "%05X" "%1X" "%04X" "%02X" "%05X" "%08X" (56) RoF: "%1X" "%05X" "%05X" "%05X" "%05X" "%05X" "%05X" "%05X" "%1X" "%04X" "%1X" "%05X" "%08X" (55) - SoF: "%1X" "%05X" "%05X" "%05X" "%05X" "%05X" "%05X" "%1X" "%04X" "%1X" "%05X" "%08X" (50) - 6.2: "%1X" "%05X" "%05X" "%05X" "%05X" "%05X" "%05X" "%1X" "%04X" "%1X" "%08X" (45) + SoF: "%1X" "%05X" "%05X" "%05X" "%05X" "%05X" "%05X" "%1X" "%04X" "%1X" "%05X" "%08X" (50) + 6.2: "%1X" "%05X" "%05X" "%05X" "%05X" "%05X" "%05X" "%1X" "%04X" "%1X" "%08X" (45) */ memset(&m_LinkBodyStruct, 0, sizeof(TextLinkBody_Struct)); @@ -8492,13 +8504,36 @@ void Client::TextLink::generate_body() break; } - if (m_ProxyItemID != NOT_USED) { + if (m_Proxy_unknown_1) + m_LinkBodyStruct.unknown_1 = m_Proxy_unknown_1; + if (m_ProxyItemID) m_LinkBodyStruct.item_id = m_ProxyItemID; - } + if (m_ProxyAugment1ID) + m_LinkBodyStruct.augment_1 = m_ProxyAugment1ID; + if (m_ProxyAugment2ID) + m_LinkBodyStruct.augment_2 = m_ProxyAugment2ID; + if (m_ProxyAugment3ID) + m_LinkBodyStruct.augment_3 = m_ProxyAugment3ID; + if (m_ProxyAugment4ID) + m_LinkBodyStruct.augment_4 = m_ProxyAugment4ID; + if (m_ProxyAugment5ID) + m_LinkBodyStruct.augment_5 = m_ProxyAugment5ID; + if (m_ProxyAugment6ID) + m_LinkBodyStruct.augment_6 = m_ProxyAugment6ID; + if (m_ProxyIsEvolving) + m_LinkBodyStruct.is_evolving = m_ProxyIsEvolving; + if (m_ProxyEvolveGroup) + m_LinkBodyStruct.evolve_group = m_ProxyEvolveGroup; + if (m_ProxyEvolveLevel) + m_LinkBodyStruct.evolve_level = m_ProxyEvolveLevel; + if (m_ProxyOrnamentIcon) + m_LinkBodyStruct.ornament_icon = m_ProxyOrnamentIcon; + if (m_ProxyHash) + m_LinkBodyStruct.hash = m_ProxyHash; - if (m_TaskUse) { + + if (m_TaskUse) m_LinkBodyStruct.hash = 0x14505DC2; - } m_LinkBody = StringFormat( "%1X" "%05X" "%05X" "%05X" "%05X" "%05X" "%05X" "%05X" "%1X" "%04X" "%02X" "%05X" "%08X", @@ -8515,7 +8550,7 @@ void Client::TextLink::generate_body() (0xFF & m_LinkBodyStruct.evolve_level), (0x000FFFFF & m_LinkBodyStruct.ornament_icon), (0xFFFFFFFF & m_LinkBodyStruct.hash) - ); + ); } void Client::TextLink::generate_text() diff --git a/zone/client.h b/zone/client.h index 24522f63d..d9f2f0dfc 100644 --- a/zone/client.h +++ b/zone/client.h @@ -831,7 +831,22 @@ public: void SetItemData(const Item_Struct* itemData) { m_ItemData = itemData; } void SetLootData(const ServerLootItem_Struct* lootData) { m_LootData = lootData; } void SetItemInst(const ItemInst* itemInst) { m_ItemInst = itemInst; } - void SetProxyItemID(uint32 proxyItemID) { m_ProxyItemID = proxyItemID; } // mainly for saylinks..but, not limited to + + // mainly for saylinks..but, not limited to + void SetProxyUnknown1(uint8 proxyUnknown1) { m_Proxy_unknown_1 = proxyUnknown1; } + void SetProxyItemID(uint32 proxyItemID) { m_ProxyItemID = proxyItemID; } + void SetProxyAugment1ID(uint32 proxyAugmentID) { m_ProxyAugment1ID = proxyAugmentID; } + void SetProxyAugment2ID(uint32 proxyAugmentID) { m_ProxyAugment2ID = proxyAugmentID; } + void SetProxyAugment3ID(uint32 proxyAugmentID) { m_ProxyAugment3ID = proxyAugmentID; } + void SetProxyAugment4ID(uint32 proxyAugmentID) { m_ProxyAugment4ID = proxyAugmentID; } + void SetProxyAugment5ID(uint32 proxyAugmentID) { m_ProxyAugment5ID = proxyAugmentID; } + void SetProxyAugment6ID(uint32 proxyAugmentID) { m_ProxyAugment6ID = proxyAugmentID; } + void SetProxyIsEvolving(uint8 proxyIsEvolving) { m_ProxyIsEvolving = proxyIsEvolving; } + void SetProxyEvolveGroup(uint32 proxyEvolveGroup) { m_ProxyEvolveGroup = proxyEvolveGroup; } + void SetProxyEvolveLevel(uint8 proxyEvolveLevel) { m_ProxyEvolveLevel = proxyEvolveLevel; } + void SetProxyOrnamentIcon(uint32 proxyOrnamentIcon) { m_ProxyOrnamentIcon = proxyOrnamentIcon; } + void SetProxyHash(int proxyHash) { m_ProxyHash = proxyHash; } + void SetProxyText(const char* proxyText) { m_ProxyText = proxyText; } // overrides standard text use void SetTaskUse() { m_TaskUse = true; } @@ -855,7 +870,20 @@ public: const Item_Struct* m_ItemData; const ServerLootItem_Struct* m_LootData; const ItemInst* m_ItemInst; + + uint8 m_Proxy_unknown_1; uint32 m_ProxyItemID; + uint32 m_ProxyAugment1ID; + uint32 m_ProxyAugment2ID; + uint32 m_ProxyAugment3ID; + uint32 m_ProxyAugment4ID; + uint32 m_ProxyAugment5ID; + uint32 m_ProxyAugment6ID; + uint8 m_ProxyIsEvolving; + uint32 m_ProxyEvolveGroup; + uint8 m_ProxyEvolveLevel; + uint32 m_ProxyOrnamentIcon; + int m_ProxyHash; const char* m_ProxyText; bool m_TaskUse; TextLinkBody_Struct m_LinkBodyStruct; From d86307c7203eb55e2d341c960c823f91109f804f Mon Sep 17 00:00:00 2001 From: "Michael Cook (mackal)" Date: Wed, 20 Jan 2016 22:31:35 -0500 Subject: [PATCH 23/56] Rework say links We now consume 1 item ID for say links, this means you will be able to create more items! We used ID 0xFFFFF for this, which is the max ID an item can be in the item links. You have the rest to play with! Normal say links pass the ID in the first aug slot and silent say links in the second aug slot. This means we can have MANY more say links as well! --- common/features.h | 3 + zone/bot.cpp | 5 +- zone/client_packet.cpp | 137 ++++++++++++++++++----------------------- zone/questmgr.cpp | 13 ++-- zone/zone.cpp | 2 +- 5 files changed, 72 insertions(+), 88 deletions(-) diff --git a/common/features.h b/common/features.h index 8115efd82..9ceddb31b 100644 --- a/common/features.h +++ b/common/features.h @@ -273,6 +273,9 @@ enum { #define NPC_DEFAULT_LOGGING_ENABLED false +// This is the item ID we use for say links, we use the max that fits in 5 ASCII chars +#define SAYLINK_ITEM_ID 0xFFFFF + /* diff --git a/zone/bot.cpp b/zone/bot.cpp index 5ce63714c..01aafa4aa 100644 --- a/zone/bot.cpp +++ b/zone/bot.cpp @@ -13774,11 +13774,10 @@ std::string Bot::CreateSayLink(Client* c, const char* message, const char* name) } safe_delete_array(escaped_string); - sayid += 500000; - Client::TextLink linker; linker.SetLinkType(linker.linkItemData); - linker.SetProxyItemID(sayid); + linker.SetProxyItemID(SAYLINK_ITEM_ID); + linker.SetProxyAugment1ID(sayid); linker.SetProxyText(name); auto say_link = linker.GenerateLink(); diff --git a/zone/client_packet.cpp b/zone/client_packet.cpp index 58381db62..1475b6c74 100644 --- a/zone/client_packet.cpp +++ b/zone/client_packet.cpp @@ -8090,97 +8090,80 @@ void Client::Handle_OP_InstillDoubt(const EQApplicationPacket *app) void Client::Handle_OP_ItemLinkClick(const EQApplicationPacket *app) { - if (app->size != sizeof(ItemViewRequest_Struct)){ - Log.Out(Logs::General, Logs::Error, "Wrong size on OP_ItemLinkClick. Got: %i, Expected: %i", app->size, sizeof(ItemViewRequest_Struct)); + if (app->size != sizeof(ItemViewRequest_Struct)) { + Log.Out(Logs::General, Logs::Error, "Wrong size on OP_ItemLinkClick. Got: %i, Expected: %i", app->size, + sizeof(ItemViewRequest_Struct)); DumpPacket(app); return; } DumpPacket(app); - ItemViewRequest_Struct* ivrs = (ItemViewRequest_Struct*)app->pBuffer; + ItemViewRequest_Struct *ivrs = (ItemViewRequest_Struct *)app->pBuffer; - //todo: verify ivrs->link_hash based on a rule, in case we don't care about people being able to sniff data from the item DB + // todo: verify ivrs->link_hash based on a rule, in case we don't care about people being able to sniff data + // from the item DB - const Item_Struct* item = database.GetItem(ivrs->item_id); + const Item_Struct *item = database.GetItem(ivrs->item_id); if (!item) { - if (ivrs->item_id > 500000) - { - std::string response = ""; - int sayid = ivrs->item_id - 500000; - bool silentsaylink = false; - - if (sayid > 250000) //Silent Saylink - { - sayid = sayid - 250000; - silentsaylink = true; - } - - if (sayid > 0) - { - - std::string query = StringFormat("SELECT `phrase` FROM saylink WHERE `id` = '%i'", sayid); - auto results = database.QueryDatabase(query); - if (!results.Success()) { - Message(13, "Error: The saylink (%s) was not found in the database.", response.c_str()); - return; - } - - if (results.RowCount() != 1) { - Message(13, "Error: The saylink (%s) was not found in the database.", response.c_str()); - return; - } - - auto row = results.begin(); - response = row[0]; - - } - - if ((response).size() > 0) - { - if (!mod_saylink(response, silentsaylink)) { return; } - - if (GetTarget() && GetTarget()->IsNPC()) - { - if (silentsaylink) - { - parse->EventNPC(EVENT_SAY, GetTarget()->CastToNPC(), this, response.c_str(), 0); - parse->EventPlayer(EVENT_SAY, this, response.c_str(), 0); - } - else - { - Message(7, "You say, '%s'", response.c_str()); - ChannelMessageReceived(8, 0, 100, response.c_str()); - } - return; - } - else - { - if (silentsaylink) - { - parse->EventPlayer(EVENT_SAY, this, response.c_str(), 0); - } - else - { - Message(7, "You say, '%s'", response.c_str()); - ChannelMessageReceived(8, 0, 100, response.c_str()); - } - return; - } - } - else - { - Message(13, "Error: Say Link not found or is too long."); - return; - } - } - else { + if (ivrs->item_id != SAYLINK_ITEM_ID) { Message(13, "Error: The item for the link you have clicked on does not exist!"); return; } + // This new scheme will shuttle the ID in the first augment for non-silent links + // and the second augment for silent. + std::string response = ""; + bool silentsaylink = ivrs->augments[1] > 0 ? true : false; + int sayid = silentsaylink ? ivrs->augments[1] : ivrs->augments[0]; + if (sayid > 0) { + std::string query = StringFormat("SELECT `phrase` FROM saylink WHERE `id` = '%i'", sayid); + auto results = database.QueryDatabase(query); + if (!results.Success()) { + Message(13, "Error: The saylink (%s) was not found in the database.", response.c_str()); + return; + } + + if (results.RowCount() != 1) { + Message(13, "Error: The saylink (%s) was not found in the database.", response.c_str()); + return; + } + + auto row = results.begin(); + response = row[0]; + } + + if ((response).size() > 0) { + if (!mod_saylink(response, silentsaylink)) { + return; + } + + if (GetTarget() && GetTarget()->IsNPC()) { + if (silentsaylink) { + parse->EventNPC(EVENT_SAY, GetTarget()->CastToNPC(), this, response.c_str(), 0); + parse->EventPlayer(EVENT_SAY, this, response.c_str(), 0); + } else { + Message(7, "You say, '%s'", response.c_str()); + ChannelMessageReceived(8, 0, 100, response.c_str()); + } + return; + } else { + if (silentsaylink) { + parse->EventPlayer(EVENT_SAY, this, response.c_str(), 0); + } else { + Message(7, "You say, '%s'", response.c_str()); + ChannelMessageReceived(8, 0, 100, response.c_str()); + } + return; + } + } else { + Message(13, "Error: Say Link not found or is too long."); + return; + } } - ItemInst* inst = database.CreateItem(item, item->MaxCharges, ivrs->augments[0], ivrs->augments[1], ivrs->augments[2], ivrs->augments[3], ivrs->augments[4], ivrs->augments[5]); + ItemInst *inst = + database.CreateItem(item, item->MaxCharges, ivrs->augments[0], ivrs->augments[1], ivrs->augments[2], + ivrs->augments[3], ivrs->augments[4], ivrs->augments[5]); if (inst) { SendItemPacket(0, inst, ItemPacketViewLink); safe_delete(inst); diff --git a/zone/questmgr.cpp b/zone/questmgr.cpp index 86b8cb7d9..fa8788bbf 100644 --- a/zone/questmgr.cpp +++ b/zone/questmgr.cpp @@ -2766,14 +2766,13 @@ const char* QuestManager::saylink(char* Phrase, bool silent, const char* LinkNam } safe_delete_array(escaped_string); - if (silent) - sayid = sayid + 750000; - else - sayid = sayid + 500000; - //Create the say link as an item link hash Client::TextLink linker; - linker.SetProxyItemID(sayid); + linker.SetProxyItemID(SAYLINK_ITEM_ID); + if (silent) + linker.SetProxyAugment2ID(sayid); + else + linker.SetProxyAugment1ID(sayid); linker.SetProxyText(LinkName); auto say_link = linker.GenerateLink(); @@ -3164,4 +3163,4 @@ void QuestManager::UpdateZoneHeader(std::string type, std::string value) { memcpy(outapp->pBuffer, &zone->newzone_data, outapp->size); entity_list.QueueClients(0, outapp); safe_delete(outapp); -} \ No newline at end of file +} diff --git a/zone/zone.cpp b/zone/zone.cpp index b3a6fc1ca..08a98fb10 100644 --- a/zone/zone.cpp +++ b/zone/zone.cpp @@ -292,7 +292,7 @@ bool Zone::LoadGroundSpawns() { char* name=0; uint32 gsnumber=0; for(gsindex=0;gsindex<50;gsindex++){ - if(groundspawn.spawn[gsindex].item>0 && groundspawn.spawn[gsindex].item<500000){ + if(groundspawn.spawn[gsindex].item>0 && groundspawn.spawn[gsindex].item Date: Thu, 21 Jan 2016 11:53:14 -0500 Subject: [PATCH 24/56] If an error occurs (!results.Success()) in loadlootdrops the method continues processing instead of exiting. --- common/shareddb.cpp | 1 + 1 file changed, 1 insertion(+) diff --git a/common/shareddb.cpp b/common/shareddb.cpp index f82d54fad..97f2f69ee 100644 --- a/common/shareddb.cpp +++ b/common/shareddb.cpp @@ -1920,6 +1920,7 @@ void SharedDatabase::LoadLootDrops(void *data, uint32 size) { "ON lootdrop.id = lootdrop_entries.lootdrop_id ORDER BY lootdrop_id"; auto results = QueryDatabase(query); if (!results.Success()) { + return; } uint32 current_id = 0; From c4cdf811e3cbbf009d4d3b2ad6af7505e52f9def Mon Sep 17 00:00:00 2001 From: Akkadius Date: Fri, 22 Jan 2016 13:42:14 -0600 Subject: [PATCH 25/56] Fix for zone controller spawn events where npc isn't inserted into entity list yet --- zone/entity.cpp | 19 ++++++++++--------- 1 file changed, 10 insertions(+), 9 deletions(-) diff --git a/zone/entity.cpp b/zone/entity.cpp index 92fefb2ec..a79d01609 100644 --- a/zone/entity.cpp +++ b/zone/entity.cpp @@ -644,15 +644,6 @@ void EntityList::AddNPC(NPC *npc, bool SendSpawnPacket, bool dontqueue) parse->EventNPC(EVENT_SPAWN, npc, nullptr, "", 0); - /* Zone controller process EVENT_SPAWN_ZONE */ - if (RuleB(Zone, UseZoneController)) { - if (entity_list.GetNPCByNPCTypeID(ZONE_CONTROLLER_NPC_ID) && npc->GetNPCTypeID() != ZONE_CONTROLLER_NPC_ID){ - char data_pass[100] = { 0 }; - snprintf(data_pass, 99, "%d %d", npc->GetID(), npc->GetNPCTypeID()); - parse->EventNPC(EVENT_SPAWN_ZONE, entity_list.GetNPCByNPCTypeID(ZONE_CONTROLLER_NPC_ID)->CastToNPC(), nullptr, data_pass, 0); - } - } - uint16 emoteid = npc->GetEmoteID(); if (emoteid != 0) npc->DoNPCEmote(ONSPAWN, emoteid); @@ -678,6 +669,16 @@ void EntityList::AddNPC(NPC *npc, bool SendSpawnPacket, bool dontqueue) npc_list.insert(std::pair(npc->GetID(), npc)); mob_list.insert(std::pair(npc->GetID(), npc)); + + /* Zone controller process EVENT_SPAWN_ZONE */ + if (RuleB(Zone, UseZoneController)) { + if (entity_list.GetNPCByNPCTypeID(ZONE_CONTROLLER_NPC_ID) && npc->GetNPCTypeID() != ZONE_CONTROLLER_NPC_ID){ + char data_pass[100] = { 0 }; + snprintf(data_pass, 99, "%d %d", npc->GetID(), npc->GetNPCTypeID()); + parse->EventNPC(EVENT_SPAWN_ZONE, entity_list.GetNPCByNPCTypeID(ZONE_CONTROLLER_NPC_ID)->CastToNPC(), nullptr, data_pass, 0); + } + } + } void EntityList::AddMerc(Merc *merc, bool SendSpawnPacket, bool dontqueue) From 15c92f019a92c3840b82bebbdb8c76b140c1fa1d Mon Sep 17 00:00:00 2001 From: "Michael Cook (mackal)" Date: Mon, 25 Jan 2016 14:00:22 -0500 Subject: [PATCH 26/56] Mob::Charmed() should be useful now We should really clean this up, but this is quicker --- zone/mob.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/zone/mob.h b/zone/mob.h index 516bdfe8b..554634006 100644 --- a/zone/mob.h +++ b/zone/mob.h @@ -887,7 +887,7 @@ public: Mob* GetShieldTarget() const { return shield_target; } void SetShieldTarget(Mob* mob) { shield_target = mob; } bool HasActiveSong() const { return(bardsong != 0); } - bool Charmed() const { return charmed; } + bool Charmed() const { return typeofpet == petCharmed; } static uint32 GetLevelHP(uint8 tlevel); uint32 GetZoneID() const; //for perl virtual int32 CheckAggroAmount(uint16 spell_id, Mob *target, bool isproc = false); From 1b7841f683c58a0c816cc6d4bfe9214d29f0b0e2 Mon Sep 17 00:00:00 2001 From: Uleat Date: Tue, 26 Jan 2016 15:08:41 -0500 Subject: [PATCH 27/56] Fix for Berserker 'Piercing' skill issues --- changelog.txt | 3 +++ common/eq_constants.h | 8 ++++---- common/patches/rof2_constants.h | 2 ++ common/patches/rof_constants.h | 2 ++ common/patches/sod_constants.h | 2 ++ common/patches/sof_constants.h | 2 ++ common/patches/titanium_constants.h | 2 ++ common/patches/uf_constants.h | 2 ++ common/skills.cpp | 2 +- common/skills.h | 4 ++-- world/client.cpp | 5 +++++ zone/attack.cpp | 22 ++++++++++------------ zone/bot.cpp | 6 +++--- zone/client.cpp | 15 ++++++++++++--- zone/client_process.cpp | 5 +++++ zone/common.h | 2 +- zone/mob.cpp | 7 ++++++- zone/special_attacks.cpp | 4 ++-- 18 files changed, 66 insertions(+), 29 deletions(-) diff --git a/changelog.txt b/changelog.txt index 6bc29becc..c758d165c 100644 --- a/changelog.txt +++ b/changelog.txt @@ -1,5 +1,8 @@ EQEMu Changelog (Started on Sept 24, 2003 15:50) ------------------------------------------------------- +== 01/26/2016 == +Uleat: Fix for Berserker 'Piercing' skill issues. Server Admins: If you run custom skill sets, this patch touches the code segments that you will need to modify if you have changed the default berserker 1H-/2H-piercing skill values. + == 01/13/2016 == Kinglykrab: Modified #flag so you can refresh your target's account status (GM status level) without them having to relog. - Just target the person whose flag you want to refresh and type #flag. diff --git a/common/eq_constants.h b/common/eq_constants.h index 0fec1f223..add66c2f4 100644 --- a/common/eq_constants.h +++ b/common/eq_constants.h @@ -799,10 +799,10 @@ static const uint8 SkillDamageTypes[HIGHEST_SKILL + 1] = // change to _SkillServ /*Intimidation*/ DamageTypeUnknown, /*Berserking*/ DamageTypeUnknown, /*Taunt*/ DamageTypeUnknown, -/*Frenzy*/ 74 //, -// /*RemoveTrap*/ DamageTypeUnknown, // Needs research (set for SenseTrap value) -// /*TripleAttack*/ DamageTypeUnknown, // Needs research (set for DoubleAttack value) -// /*2HPiercing*/ 36 // Needs research (set for 1HPiercing value - similar to slash/blunt) +/*Frenzy*/ 74, +/*RemoveTrap*/ DamageTypeUnknown, // Needs research (set for SenseTrap value) +/*TripleAttack*/ DamageTypeUnknown, // Needs research (set for DoubleAttack value) +/*2HPiercing*/ 36 // Needs research (set for 1HPiercing value - similar to slash/blunt) }; /* diff --git a/common/patches/rof2_constants.h b/common/patches/rof2_constants.h index 4c8245737..0732044ca 100644 --- a/common/patches/rof2_constants.h +++ b/common/patches/rof2_constants.h @@ -186,6 +186,8 @@ namespace RoF2 { static const size_t POTION_BELT_ITEM_COUNT = 5; static const size_t TEXT_LINK_BODY_LENGTH = 56; + + static const size_t PLAYER_PROFILE_SKILL_MAX = Skill2HPiercing; } namespace limits { diff --git a/common/patches/rof_constants.h b/common/patches/rof_constants.h index 8b5fadbf2..b348f5fd5 100644 --- a/common/patches/rof_constants.h +++ b/common/patches/rof_constants.h @@ -185,6 +185,8 @@ namespace RoF { static const size_t POTION_BELT_ITEM_COUNT = 5; static const size_t TEXT_LINK_BODY_LENGTH = 55; + + static const size_t PLAYER_PROFILE_SKILL_MAX = SkillTripleAttack; } namespace limits { diff --git a/common/patches/sod_constants.h b/common/patches/sod_constants.h index 5dad9bb09..ebd1d7d48 100644 --- a/common/patches/sod_constants.h +++ b/common/patches/sod_constants.h @@ -182,6 +182,8 @@ namespace SoD { static const size_t POTION_BELT_ITEM_COUNT = 5; static const size_t TEXT_LINK_BODY_LENGTH = 50; + + static const size_t PLAYER_PROFILE_SKILL_MAX = SkillTripleAttack; } namespace limits { diff --git a/common/patches/sof_constants.h b/common/patches/sof_constants.h index 260722f00..4ffcdd525 100644 --- a/common/patches/sof_constants.h +++ b/common/patches/sof_constants.h @@ -182,6 +182,8 @@ namespace SoF { static const size_t POTION_BELT_ITEM_COUNT = 5; static const size_t TEXT_LINK_BODY_LENGTH = 50; + + static const size_t PLAYER_PROFILE_SKILL_MAX = SkillTripleAttack; } namespace limits { diff --git a/common/patches/titanium_constants.h b/common/patches/titanium_constants.h index d7e2a4964..4915c829c 100644 --- a/common/patches/titanium_constants.h +++ b/common/patches/titanium_constants.h @@ -181,6 +181,8 @@ namespace Titanium { static const size_t POTION_BELT_ITEM_COUNT = 4; static const size_t TEXT_LINK_BODY_LENGTH = 45; + + static const size_t PLAYER_PROFILE_SKILL_MAX = SkillFrenzy; } namespace limits { diff --git a/common/patches/uf_constants.h b/common/patches/uf_constants.h index 1a5a4cc44..b8096fd58 100644 --- a/common/patches/uf_constants.h +++ b/common/patches/uf_constants.h @@ -182,6 +182,8 @@ namespace UF { static const size_t POTION_BELT_ITEM_COUNT = 5; static const size_t TEXT_LINK_BODY_LENGTH = 50; + + static const size_t PLAYER_PROFILE_SKILL_MAX = SkillTripleAttack; } namespace limits { diff --git a/common/skills.cpp b/common/skills.cpp index 5edca778b..85c660f6c 100644 --- a/common/skills.cpp +++ b/common/skills.cpp @@ -71,7 +71,7 @@ float EQEmu::GetSkillMeleePushForce(SkillUseTypes skill) case SkillEagleStrike: case SkillKick: case SkillTigerClaw: - //case Skill2HPiercing: + case Skill2HPiercing: return 0.2f; case SkillArchery: return 0.15f; diff --git a/common/skills.h b/common/skills.h index c79a522ee..4e1e9eb83 100644 --- a/common/skills.h +++ b/common/skills.h @@ -114,7 +114,7 @@ enum SkillUseTypes /*13049*/ SkillTripleAttack, // RoF2+ specific skills -// /*00789*/ Skill2HPiercing, +/*00789*/ Skill2HPiercing, // /*01216*/ SkillNone, // This needs to move down as new skills are added /*00000*/ _EmuSkillCount // move to last position of active enumeration labels @@ -171,7 +171,7 @@ enum SkillUseTypes }; // temporary until it can be sorted out... -#define HIGHEST_SKILL SkillTripleAttack +#define HIGHEST_SKILL Skill2HPiercing // Spell Effects use this value to determine if an effect applies to all skills. #define ALL_SKILLS -1 diff --git a/world/client.cpp b/world/client.cpp index 9a194e5ec..dc17d7b4d 100644 --- a/world/client.cpp +++ b/world/client.cpp @@ -1814,6 +1814,11 @@ void Client::SetClassStartingSkills(PlayerProfile_Struct *pp) pp->skills[i] = database.GetSkillCap(pp->class_, (SkillUseTypes)i, 1); } } + + if (cle->GetClientVersion() < static_cast(ClientVersion::RoF2) && pp->class_ == BERSERKER) { + pp->skills[Skill1HPiercing] = pp->skills[Skill2HPiercing]; + pp->skills[Skill2HPiercing] = 0; + } } void Client::SetRaceStartingSkills( PlayerProfile_Struct *pp ) diff --git a/zone/attack.cpp b/zone/attack.cpp index 85ee29e9d..2fdf5f115 100644 --- a/zone/attack.cpp +++ b/zone/attack.cpp @@ -76,7 +76,7 @@ bool Mob::AttackAnimation(SkillUseTypes &skillinuse, int Hand, const ItemInst* w case ItemType1HPiercing: // Piercing { skillinuse = Skill1HPiercing; - type = animPiercing; + type = anim1HPiercing; break; } case ItemType1HBlunt: // 1H Blunt @@ -93,7 +93,10 @@ bool Mob::AttackAnimation(SkillUseTypes &skillinuse, int Hand, const ItemInst* w } case ItemType2HPiercing: // 2H Piercing { - skillinuse = Skill1HPiercing; // change to Skill2HPiercing once activated + if (IsClient() && CastToClient()->GetClientVersion() < ClientVersion::RoF2) + skillinuse = Skill1HPiercing; + else + skillinuse = Skill2HPiercing; type = anim2HWeapon; break; } @@ -127,7 +130,7 @@ bool Mob::AttackAnimation(SkillUseTypes &skillinuse, int Hand, const ItemInst* w } case Skill1HPiercing: // Piercing { - type = animPiercing; + type = anim1HPiercing; break; } case Skill1HBlunt: // 1H Blunt @@ -140,7 +143,7 @@ bool Mob::AttackAnimation(SkillUseTypes &skillinuse, int Hand, const ItemInst* w type = anim2HSlashing; //anim2HWeapon break; } - case 99: // 2H Piercing // change to Skill2HPiercing once activated + case Skill2HPiercing: // 2H Piercing { type = anim2HWeapon; break; @@ -1652,10 +1655,10 @@ bool NPC::Attack(Mob* other, int Hand, bool bRiposte, bool IsStrikethrough, bool skillinuse = Skill2HSlashing; break; case ItemType1HPiercing: - //skillinuse = Skill1HPiercing; - //break; + skillinuse = Skill1HPiercing; + break; case ItemType2HPiercing: - skillinuse = Skill1HPiercing; // change to Skill2HPiercing once activated + skillinuse = Skill2HPiercing; break; case ItemType1HBlunt: skillinuse = Skill1HBlunt; @@ -1683,11 +1686,6 @@ bool NPC::Attack(Mob* other, int Hand, bool bRiposte, bool IsStrikethrough, bool ItemInst weapon_inst(weapon, charges); AttackAnimation(skillinuse, Hand, &weapon_inst); - // Remove this once Skill2HPiercing is activated - //Work-around for there being no 2HP skill - We use 99 for the 2HB animation and 36 for pierce messages - if(skillinuse == 99) - skillinuse = static_cast(36); - //basically "if not immune" then do the attack if((weapon_damage) > 0) { diff --git a/zone/bot.cpp b/zone/bot.cpp index 01aafa4aa..926df4fb0 100644 --- a/zone/bot.cpp +++ b/zone/bot.cpp @@ -1179,7 +1179,7 @@ uint16 Bot::GetPrimarySkillValue() { break; } case ItemType2HPiercing: { - skill = Skill1HPiercing; // change to Skill2HPiercing once activated + skill = Skill2HPiercing; break; } case ItemTypeMartial: { @@ -6493,7 +6493,7 @@ void Bot::RogueBackstab(Mob* other, bool min_damage, int ReuseTime) { ndamage = -5; DoSpecialAttackDamage(other, SkillBackstab, ndamage, min_hit, hate, ReuseTime); - DoAnim(animPiercing); + DoAnim(anim1HPiercing); } void Bot::RogueAssassinate(Mob* other) { @@ -6505,7 +6505,7 @@ void Bot::RogueAssassinate(Mob* other) { other->Damage(this, -5, SPELL_UNKNOWN, SkillBackstab); } - DoAnim(animPiercing); + DoAnim(anim1HPiercing); } void Bot::DoClassAttacks(Mob *target, bool IsRiposte) { diff --git a/zone/client.cpp b/zone/client.cpp index 3fab7671e..c8c1494e5 100644 --- a/zone/client.cpp +++ b/zone/client.cpp @@ -2343,11 +2343,17 @@ bool Client::HasSkill(SkillUseTypes skill_id) const { } bool Client::CanHaveSkill(SkillUseTypes skill_id) const { + if (GetClientVersion() < ClientVersion::RoF2 && class_ == BERSERKER && skill_id == Skill1HPiercing) + skill_id = Skill2HPiercing; + return(database.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(SkillUseTypes skillid, uint16 class_, uint16 level) const { + if (GetClientVersion() < ClientVersion::RoF2 && class_ == BERSERKER && skillid == Skill1HPiercing) + skillid = Skill2HPiercing; + return(database.GetSkillCap(class_, skillid, level)); } @@ -4211,7 +4217,10 @@ uint16 Client::GetPrimarySkillValue() } case ItemType2HPiercing: // 2H Piercing { - skill = Skill1HPiercing; // change to Skill2HPiercing once activated + if (IsClient() && CastToClient()->GetClientVersion() < ClientVersion::RoF2) + skill = Skill1HPiercing; + else + skill = Skill2HPiercing; break; } case ItemTypeMartial: // Hand to Hand @@ -4950,11 +4959,11 @@ void Client::ShowSkillsWindow() const char* SkillName[] = {"1H Blunt","1H Slashing","2H Blunt","2H Slashing","Abjuration","Alteration","Apply Poison","Archery", "Backstab","Bind Wound","Bash","Block","Brass Instruments","Channeling","Conjuration","Defense","Disarm","Disarm Traps","Divination", "Dodge","Double Attack","Dragon Punch","Dual Wield","Eagle Strike","Evocation","Feign Death","Flying Kick","Forage","Hand to Hand", - "Hide","Kick","Meditate","Mend","Offense","Parry","Pick Lock","Piercing","Ripost","Round Kick","Safe Fall","Sense Heading", + "Hide","Kick","Meditate","Mend","Offense","Parry","Pick Lock","1H Piercing","Ripost","Round Kick","Safe Fall","Sense Heading", "Singing","Sneak","Specialize Abjuration","Specialize Alteration","Specialize Conjuration","Specialize Divination","Specialize Evocation","Pick Pockets", "Stringed Instruments","Swimming","Throwing","Tiger Claw","Tracking","Wind Instruments","Fishing","Make Poison","Tinkering","Research", "Alchemy","Baking","Tailoring","Sense Traps","Blacksmithing","Fletching","Brewing","Alcohol Tolerance","Begging","Jewelry Making", - "Pottery","Percussion Instruments","Intimidation","Berserking","Taunt","Frenzy","Remove Traps","Triple Attack"}; + "Pottery","Percussion Instruments","Intimidation","Berserking","Taunt","Frenzy","Remove Traps","Triple Attack","2H Piercing"}; for(int i = 0; i <= (int)HIGHEST_SKILL; i++) Skills[SkillName[i]] = (SkillUseTypes)i; diff --git a/zone/client_process.cpp b/zone/client_process.cpp index 3b973e7b7..3154a9ca9 100644 --- a/zone/client_process.cpp +++ b/zone/client_process.cpp @@ -1553,6 +1553,11 @@ void Client::OPGMTraining(const EQApplicationPacket *app) //Set it to 1 with CanHaveSkill or you wont be able to train past 1. } } + + if (GetClientVersion() < ClientVersion::RoF2 && GetClass() == BERSERKER) { + gmtrain->skills[Skill1HPiercing] = gmtrain->skills[Skill2HPiercing]; + gmtrain->skills[Skill2HPiercing] = 0; + } //#pragma GCC pop_options uchar ending[]={0x34,0x87,0x8a,0x3F,0x01 diff --git a/zone/common.h b/zone/common.h index 48749dbc3..bcae779a9 100644 --- a/zone/common.h +++ b/zone/common.h @@ -511,7 +511,7 @@ typedef struct //make DoAnim take it instead of int, to enforce its use. enum { //type arguments to DoAnim animKick = 1, - animPiercing = 2, //might be piercing? + anim1HPiercing = 2, //might be piercing? anim2HSlashing = 3, anim2HWeapon = 4, anim1HWeapon = 5, diff --git a/zone/mob.cpp b/zone/mob.cpp index 2ac1c7f5e..3dad9b247 100644 --- a/zone/mob.cpp +++ b/zone/mob.cpp @@ -5029,7 +5029,10 @@ uint16 Mob::GetSkillByItemType(int ItemType) case ItemType2HBlunt: return Skill2HBlunt; case ItemType2HPiercing: - return Skill1HPiercing; // change to 2HPiercing once activated + if (IsClient() && CastToClient()->GetClientVersion() < ClientVersion::RoF2) + return Skill1HPiercing; + else + return Skill2HPiercing; case ItemTypeBow: return SkillArchery; case ItemTypeLargeThrowing: @@ -5057,6 +5060,8 @@ uint8 Mob::GetItemTypeBySkill(SkillUseTypes skill) return ItemType2HSlash; case Skill1HPiercing: return ItemType1HPiercing; + case Skill2HPiercing: // watch for undesired client behavior + return ItemType2HPiercing; case Skill1HBlunt: return ItemType1HBlunt; case Skill2HBlunt: diff --git a/zone/special_attacks.cpp b/zone/special_attacks.cpp index c43c8f432..2c763df13 100644 --- a/zone/special_attacks.cpp +++ b/zone/special_attacks.cpp @@ -660,7 +660,7 @@ void Mob::RogueBackstab(Mob* other, bool min_damage, int ReuseTime) } DoSpecialAttackDamage(other, SkillBackstab, ndamage, min_hit, hate, ReuseTime, false, false); - DoAnim(animPiercing); + DoAnim(anim1HPiercing); } // assassinate [No longer used for regular assassinate 6-29-14] @@ -673,7 +673,7 @@ void Mob::RogueAssassinate(Mob* other) }else{ other->Damage(this, -5, SPELL_UNKNOWN, SkillBackstab); } - DoAnim(animPiercing); //piercing animation + DoAnim(anim1HPiercing); //piercing animation } void Client::RangedAttack(Mob* other, bool CanDoubleAttack) { From 52541c6532bfce47754df3d7cdabaa8b2a78af91 Mon Sep 17 00:00:00 2001 From: Tim DeLong Date: Tue, 26 Jan 2016 16:44:11 -0500 Subject: [PATCH 28/56] Item weight was being downcast to uint8 which impacted any item with weight over 255. For SoD, SoF, and UF, prior to sending item info to the client we now cap weight at 255 to ensure the item remains heavy instead of being made (in most cases), super light. --- common/item_struct.h | 2 +- common/patches/sod.cpp | 3 ++- common/patches/sof.cpp | 3 ++- common/patches/uf.cpp | 3 ++- common/shareddb.cpp | 2 +- 5 files changed, 8 insertions(+), 5 deletions(-) diff --git a/common/item_struct.h b/common/item_struct.h index ba8afcd14..937c9e47c 100644 --- a/common/item_struct.h +++ b/common/item_struct.h @@ -83,7 +83,7 @@ struct Item_Struct { char Lore[80]; // Lore Name: *=lore, &=summoned, #=artifact, ~=pending lore char IDFile[30]; // Visible model uint32 ID; // Unique ID (also PK for DB) - uint8 Weight; // Item weight * 10 + int32 Weight; // Item weight * 10 uint8 NoRent; // No Rent: 0=norent, 255=not norent uint8 NoDrop; // No Drop: 0=nodrop, 255=not nodrop uint8 Size; // Size: 0=tiny, 1=small, 2=medium, 3=large, 4=giant diff --git a/common/patches/sod.cpp b/common/patches/sod.cpp index bbd5acd45..d5a6035f4 100644 --- a/common/patches/sod.cpp +++ b/common/patches/sod.cpp @@ -3623,7 +3623,8 @@ namespace SoD memset(&ibs, 0, sizeof(SoD::structs::ItemBodyStruct)); ibs.id = item->ID; - ibs.weight = item->Weight; + // weight is uint8 in the struct, and some weights exceed that, so capping at 255. + ibs.weight = (item->Weight > 255) ? 255 : item->Weight; ibs.norent = item->NoRent; ibs.nodrop = item->NoDrop; ibs.attune = item->Attuneable; diff --git a/common/patches/sof.cpp b/common/patches/sof.cpp index d8b7db541..f407ffdc0 100644 --- a/common/patches/sof.cpp +++ b/common/patches/sof.cpp @@ -2945,7 +2945,8 @@ namespace SoF memset(&ibs, 0, sizeof(SoF::structs::ItemBodyStruct)); ibs.id = item->ID; - ibs.weight = item->Weight; + // weight is uint8 in the struct, and some weights exceed that, so capping at 255. + ibs.weight = (item->Weight > 255) ? 255 : item->Weight; ibs.norent = item->NoRent; ibs.nodrop = item->NoDrop; ibs.attune = item->Attuneable; diff --git a/common/patches/uf.cpp b/common/patches/uf.cpp index 0efa502c0..c42de5145 100644 --- a/common/patches/uf.cpp +++ b/common/patches/uf.cpp @@ -3924,7 +3924,8 @@ namespace UF memset(&ibs, 0, sizeof(UF::structs::ItemBodyStruct)); ibs.id = item->ID; - ibs.weight = item->Weight; + // weight is uint8 in the struct, and some weights exceed that, so capping at 255. + ibs.weight = (item->Weight > 255) ? 255 : item->Weight; ibs.norent = item->NoRent; ibs.nodrop = item->NoDrop; ibs.attune = item->Attuneable; diff --git a/common/shareddb.cpp b/common/shareddb.cpp index 97f2f69ee..79bac527e 100644 --- a/common/shareddb.cpp +++ b/common/shareddb.cpp @@ -857,7 +857,7 @@ void SharedDatabase::LoadItems(void *data, uint32 size, int32 items, uint32 max_ strcpy(item.IDFile, row[ItemField::idfile]); item.ID = (uint32)atoul(row[ItemField::id]); - item.Weight = (uint8)atoi(row[ItemField::weight]); + item.Weight = (int32)atoi(row[ItemField::weight]); item.NoRent = disableNoRent ? (uint8)atoi("255") : (uint8)atoi(row[ItemField::norent]); item.NoDrop = disableNoDrop ? (uint8)atoi("255") : (uint8)atoi(row[ItemField::nodrop]); item.Size = (uint8)atoi(row[ItemField::size]); From 430be0f2b7b91184339f3f6cf44ec037da0eb9cc Mon Sep 17 00:00:00 2001 From: Uleat Date: Tue, 26 Jan 2016 19:02:07 -0500 Subject: [PATCH 29/56] Follow-up for Titanium client - item weight fix (WARNING: re-run shared_memory; Note: re-run cmake; see changelog.txt) --- changelog.txt | 3 +++ common/CMakeLists.txt | 6 ++++-- common/patches/titanium.cpp | 8 ++++++-- common/patches/titanium_itemfields_a.h | 19 +++++++++++++++++++ ...m_itemfields.h => titanium_itemfields_b.h} | 10 ++++------ 5 files changed, 36 insertions(+), 10 deletions(-) create mode 100644 common/patches/titanium_itemfields_a.h rename common/patches/{titanium_itemfields.h => titanium_itemfields_b.h} (96%) diff --git a/changelog.txt b/changelog.txt index c758d165c..ee77f075d 100644 --- a/changelog.txt +++ b/changelog.txt @@ -2,6 +2,9 @@ EQEMu Changelog (Started on Sept 24, 2003 15:50) ------------------------------------------------------- == 01/26/2016 == Uleat: Fix for Berserker 'Piercing' skill issues. Server Admins: If you run custom skill sets, this patch touches the code segments that you will need to modify if you have changed the default berserker 1H-/2H-piercing skill values. +Uleat (Daerath): Fix for precision-loss item weight conversions in older clients. + - WARNING: YOU MUST RE-RUN SHARED_MEMORY.EXE BEFORE STARTING SERVER OR ITEM LOSS WILL OCCUR! + - Note: Cmake must be re-run to include/exclude the required files == 01/13/2016 == Kinglykrab: Modified #flag so you can refresh your target's account status (GM status level) without them having to relog. diff --git a/common/CMakeLists.txt b/common/CMakeLists.txt index f847957db..09ed7e02c 100644 --- a/common/CMakeLists.txt +++ b/common/CMakeLists.txt @@ -213,7 +213,8 @@ SET(common_headers patches/rof2_structs.h patches/titanium.h patches/titanium_constants.h - patches/titanium_itemfields.h + patches/titanium_itemfields_a.h + patches/titanium_itemfields_b.h patches/titanium_ops.h patches/titanium_structs.h patches/uf.h @@ -265,7 +266,8 @@ SOURCE_GROUP(Patches FILES patches/rof2_constants.h patches/rof2_structs.h patches/titanium.h - patches/titanium_itemfields.h + patches/titanium_itemfields_a.h + patches/titanium_itemfields_b.h patches/titanium_ops.h patches/titanium_constants.h patches/titanium_structs.h diff --git a/common/patches/titanium.cpp b/common/patches/titanium.cpp index 42544f3b9..d3873dd97 100644 --- a/common/patches/titanium.cpp +++ b/common/patches/titanium.cpp @@ -2126,7 +2126,9 @@ namespace Titanium #define C(field) "|%s" #define S(field) "|%s" #define F(field) "|%f" -#include "titanium_itemfields.h" +#include "titanium_itemfields_a.h" + "|%i" // mask for item->Weight +#include "titanium_itemfields_b.h" "%.*s\"" // Quotes (and protection, if needed) around static data "|%s|%s|%s|%s|%s|%s|%s|%s|%s|%s" // Sub items "%.*s%s" // For trailing quotes (and protection) if a subitem; @@ -2138,7 +2140,9 @@ namespace Titanium #define C(field) ,field #define S(field) ,item->field #define F(field) ,item->field -#include "titanium_itemfields.h" +#include "titanium_itemfields_a.h" + , ((item->Weight > 255) ? (255) : (item->Weight)) +#include "titanium_itemfields_b.h" , depth, protection , sub_items[0] ? sub_items[0] : "" , sub_items[1] ? sub_items[1] : "" diff --git a/common/patches/titanium_itemfields_a.h b/common/patches/titanium_itemfields_a.h new file mode 100644 index 000000000..ba8d7b1c6 --- /dev/null +++ b/common/patches/titanium_itemfields_a.h @@ -0,0 +1,19 @@ +/* + + +These fields must be in the order of how they are serialized! + + + +*/ + + +/* 000 */ //I(ItemClass) Leave this one off on purpose +/* 001 */ S(Name) +/* 002 */ S(Lore) +/* 003 */ S(IDFile) +/* 004 */ I(ID) + +/* 005 */ //I(Weight) handled manually + +// titanium_itemfields_b.h diff --git a/common/patches/titanium_itemfields.h b/common/patches/titanium_itemfields_b.h similarity index 96% rename from common/patches/titanium_itemfields.h rename to common/patches/titanium_itemfields_b.h index dc87a714e..194a31f1c 100644 --- a/common/patches/titanium_itemfields.h +++ b/common/patches/titanium_itemfields_b.h @@ -8,12 +8,10 @@ These fields must be in the order of how they are serialized! */ -/* 000 */ //I(ItemClass) Leave this one off on purpose -/* 001 */ S(Name) -/* 002 */ S(Lore) -/* 003 */ S(IDFile) -/* 004 */ I(ID) -/* 005 */ I(Weight) +// titanium_itemfields_a.h + +/* 005 */ //I(Weight) handled manually + /* 006 */ I(NoRent) /* 007 */ I(NoDrop) /* 008 */ I(Size) From f98c04ca7afd5fcc52431863f1d11ed828916670 Mon Sep 17 00:00:00 2001 From: Uleat Date: Wed, 27 Jan 2016 17:39:36 -0500 Subject: [PATCH 30/56] Fix for false triggering of warning message for command alias processing --- zone/command.cpp | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/zone/command.cpp b/zone/command.cpp index 4c25b25d2..b5d060f87 100644 --- a/zone/command.cpp +++ b/zone/command.cpp @@ -424,7 +424,9 @@ int command_init(void) std::map>> command_settings; database.GetCommandSettings(command_settings); - for (std::map::iterator iter_cl = commandlist.begin(); iter_cl != commandlist.end(); ++iter_cl) { + + std::map working_cl = commandlist; + for (std::map::iterator iter_cl = working_cl.begin(); iter_cl != working_cl.end(); ++iter_cl) { std::map>>::iterator iter_cs = command_settings.find(iter_cl->first); if (iter_cs == command_settings.end()) { if (iter_cl->second->access == 0) From c19a5d7c756fa3fb633b1832b3d6c1a8ec4d5e4b Mon Sep 17 00:00:00 2001 From: Tim DeLong Date: Thu, 28 Jan 2016 08:15:38 -0500 Subject: [PATCH 31/56] Casttime was too small for the possible data values. The Potion of Serious Healing has a cast time of 90.0 sec (90000), but this was downcast to a lower value. Updated Casttime from uint16 to uint32. This change also makes CastTime have the same data type as Fulfilment which is notable as they are in a struct union and should have the same type. --- common/item_struct.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/common/item_struct.h b/common/item_struct.h index 937c9e47c..0d7505a2c 100644 --- a/common/item_struct.h +++ b/common/item_struct.h @@ -160,7 +160,7 @@ struct Item_Struct { //uint32 Unk059; union { uint32 Fulfilment; // Food fulfilment (How long it lasts) - int16 CastTime; // Cast Time for clicky effects, in milliseconds + uint32 CastTime; // Cast Time for clicky effects, in milliseconds }; uint32 EliteMaterial; int32 ProcRate; From 3ce3f591a83edb4d5f51746af8697c7a868f5182 Mon Sep 17 00:00:00 2001 From: Natedog2012 Date: Thu, 28 Jan 2016 13:23:58 -0800 Subject: [PATCH 32/56] UF and ROF2 spawn packet packet for chests now working properly. --- common/patches/rof2.cpp | 81 ++++++++++++++++++++++++++++++++--- common/patches/uf.cpp | 11 +++-- utils/patches/patch_RoF2.conf | 3 ++ utils/patches/patch_UF.conf | 3 ++ zone/client.cpp | 2 +- 5 files changed, 90 insertions(+), 10 deletions(-) diff --git a/common/patches/rof2.cpp b/common/patches/rof2.cpp index e0e8f307f..1b2da5cda 100644 --- a/common/patches/rof2.cpp +++ b/common/patches/rof2.cpp @@ -4076,6 +4076,17 @@ namespace RoF2 if (strlen(emu->suffix)) PacketSize += strlen(emu->suffix) + 1; + if (emu->DestructibleObject || emu->class_ == 62) + { + if (emu->DestructibleObject) + PacketSize = PacketSize - 4; // No bodytype + + PacketSize += 53; // Fixed portion + PacketSize += strlen(emu->DestructibleModel) + 1; + PacketSize += strlen(emu->DestructibleName2) + 1; + PacketSize += strlen(emu->DestructibleString) + 1; + } + bool ShowName = 1; if (emu->bodytype >= 66) { @@ -4110,7 +4121,14 @@ namespace RoF2 VARSTRUCT_ENCODE_STRING(Buffer, emu->name); VARSTRUCT_ENCODE_TYPE(uint32, Buffer, emu->spawnId); VARSTRUCT_ENCODE_TYPE(uint8, Buffer, emu->level); - VARSTRUCT_ENCODE_TYPE(float, Buffer, SpawnSize - 0.7); // Eye Height? + if (emu->DestructibleObject) + { + VARSTRUCT_ENCODE_TYPE(float, Buffer, 10); // was int and 0x41200000 + } + else + { + VARSTRUCT_ENCODE_TYPE(float, Buffer, SpawnSize - 0.7); // Eye Height? + } VARSTRUCT_ENCODE_TYPE(uint8, Buffer, emu->NPC); structs::Spawn_Struct_Bitfields *Bitfields = (structs::Spawn_Struct_Bitfields*)Buffer; @@ -4130,6 +4148,12 @@ namespace RoF2 Bitfields->targetable_with_hotkey = emu->targetable_with_hotkey ? 1 : 0; Bitfields->showname = ShowName; + if (emu->DestructibleObject) + { + VARSTRUCT_ENCODE_TYPE(uint32, Buffer, 0x1d600000); + Buffer = Buffer - 4; + } + // Not currently found // Bitfields->statue = 0; // Bitfields->buyer = 0; @@ -4138,21 +4162,66 @@ namespace RoF2 uint8 OtherData = 0; + if (emu->class_ == 62) //LDoN Chest + OtherData = OtherData | 0x04; + if (strlen(emu->title)) OtherData = OtherData | 16; if (strlen(emu->suffix)) OtherData = OtherData | 32; + if (emu->DestructibleObject) + OtherData = OtherData | 0xe1; // Live has 0xe1 for OtherData + VARSTRUCT_ENCODE_TYPE(uint8, Buffer, OtherData); - VARSTRUCT_ENCODE_TYPE(float, Buffer, -1); // unknown3 + if (emu->DestructibleObject) + { + VARSTRUCT_ENCODE_TYPE(uint32, Buffer, 0x00000000); + } + else + { + VARSTRUCT_ENCODE_TYPE(float, Buffer, -1); // unknown3 + } VARSTRUCT_ENCODE_TYPE(float, Buffer, 0); // unknown4 - // Setting this next field to zero will cause a crash. Looking at ShowEQ, if it is zero, the bodytype field is not - // present. Will sort that out later. - VARSTRUCT_ENCODE_TYPE(uint8, Buffer, 1); // This is a properties count field - VARSTRUCT_ENCODE_TYPE(uint32, Buffer, emu->bodytype); + if (emu->DestructibleObject || emu->class_ == 62) + { + VARSTRUCT_ENCODE_STRING(Buffer, emu->DestructibleModel); + VARSTRUCT_ENCODE_STRING(Buffer, emu->DestructibleName2); + VARSTRUCT_ENCODE_STRING(Buffer, emu->DestructibleString); + + VARSTRUCT_ENCODE_TYPE(uint32, Buffer, emu->DestructibleAppearance); + VARSTRUCT_ENCODE_TYPE(uint32, Buffer, emu->DestructibleUnk1); + + VARSTRUCT_ENCODE_TYPE(uint32, Buffer, emu->DestructibleID1); + VARSTRUCT_ENCODE_TYPE(uint32, Buffer, emu->DestructibleID2); + VARSTRUCT_ENCODE_TYPE(uint32, Buffer, emu->DestructibleID3); + VARSTRUCT_ENCODE_TYPE(uint32, Buffer, emu->DestructibleID4); + + VARSTRUCT_ENCODE_TYPE(uint32, Buffer, emu->DestructibleUnk2); + VARSTRUCT_ENCODE_TYPE(uint32, Buffer, emu->DestructibleUnk3); + VARSTRUCT_ENCODE_TYPE(uint32, Buffer, emu->DestructibleUnk4); + VARSTRUCT_ENCODE_TYPE(uint32, Buffer, emu->DestructibleUnk5); + VARSTRUCT_ENCODE_TYPE(uint32, Buffer, emu->DestructibleUnk6); + VARSTRUCT_ENCODE_TYPE(uint32, Buffer, emu->DestructibleUnk7); + VARSTRUCT_ENCODE_TYPE(uint8, Buffer, emu->DestructibleUnk8); + VARSTRUCT_ENCODE_TYPE(uint32, Buffer, emu->DestructibleUnk9); + } + + + if (!emu->DestructibleObject) + { + // Setting this next field to zero will cause a crash. Looking at ShowEQ, if it is zero, the bodytype field is not + // present. Will sort that out later. + VARSTRUCT_ENCODE_TYPE(uint8, Buffer, 1); // This is a properties count field + VARSTRUCT_ENCODE_TYPE(uint32, Buffer, emu->bodytype); + } + else + { + VARSTRUCT_ENCODE_TYPE(uint8, Buffer, 0); + } VARSTRUCT_ENCODE_TYPE(uint8, Buffer, emu->curHp); VARSTRUCT_ENCODE_TYPE(uint8, Buffer, emu->haircolor); diff --git a/common/patches/uf.cpp b/common/patches/uf.cpp index c42de5145..adcd8f241 100644 --- a/common/patches/uf.cpp +++ b/common/patches/uf.cpp @@ -2818,9 +2818,11 @@ namespace UF if (strlen(emu->suffix)) PacketSize += strlen(emu->suffix) + 1; - if (emu->DestructibleObject) + if (emu->DestructibleObject || emu->class_ == 62) { - PacketSize = PacketSize - 4; // No bodytype + if (emu->DestructibleObject) + PacketSize = PacketSize - 4; // No bodytype + PacketSize += 53; // Fixed portion PacketSize += strlen(emu->DestructibleModel) + 1; PacketSize += strlen(emu->DestructibleName2) + 1; @@ -2903,6 +2905,9 @@ namespace UF uint8 OtherData = 0; + if (emu->class_ == 62) //Ldon chest + OtherData = OtherData | 0x01; + if (strlen(emu->title)) OtherData = OtherData | 0x04; @@ -2924,7 +2929,7 @@ namespace UF } VARSTRUCT_ENCODE_TYPE(float, Buffer, 0); // unknown4 - if (emu->DestructibleObject) + if (emu->DestructibleObject || emu->class_ == 62) { VARSTRUCT_ENCODE_STRING(Buffer, emu->DestructibleModel); VARSTRUCT_ENCODE_STRING(Buffer, emu->DestructibleName2); diff --git a/utils/patches/patch_RoF2.conf b/utils/patches/patch_RoF2.conf index 6afb7209e..8ae8a1a69 100644 --- a/utils/patches/patch_RoF2.conf +++ b/utils/patches/patch_RoF2.conf @@ -540,6 +540,9 @@ OP_FeignDeath=0x52fa OP_Mend=0x0ecf OP_Bind_Wound=0x0386 OP_LDoNOpen=0x3d5c +#OP_LDoNDisarmTraps= #Same as OP_DisarmTraps in RoF +OP_LDoNPickLock=0x9be3 +OP_LDoNInspect=0x0438 # Task packets OP_TaskDescription=0x3714 diff --git a/utils/patches/patch_UF.conf b/utils/patches/patch_UF.conf index e3af9aa7d..1e57a202d 100644 --- a/utils/patches/patch_UF.conf +++ b/utils/patches/patch_UF.conf @@ -535,6 +535,9 @@ OP_InstillDoubt=0x221a # C OP_FeignDeath=0x002b # C OP_Mend=0x10a6 # C OP_LDoNOpen=0x032b # C +OP_LDoNDisarmTraps=0x1a84 +OP_LDoNPickLock=0x0370 +OP_LDoNInspect=0x0aaa # Task packets OP_TaskActivityComplete=0x5832 # C diff --git a/zone/client.cpp b/zone/client.cpp index c8c1494e5..e24c24627 100644 --- a/zone/client.cpp +++ b/zone/client.cpp @@ -4638,7 +4638,7 @@ void Client::HandleLDoNOpen(NPC *target) AddEXP(target->GetLevel()*target->GetLevel()*2625/10, GetLevelCon(target->GetLevel())); } } - target->Death(this, 1, SPELL_UNKNOWN, SkillHandtoHand); + target->Death(this, 0, SPELL_UNKNOWN, SkillHandtoHand); } } } From 65b44248fb59752b1889c48852368989832393dc Mon Sep 17 00:00:00 2001 From: Xackery Date: Sat, 30 Jan 2016 00:01:06 -0800 Subject: [PATCH 33/56] table schema for character_corpses is zone_id, not zoneid. --- zone/client_packet.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/zone/client_packet.cpp b/zone/client_packet.cpp index f20ffb5f4..ec7c8e323 100644 --- a/zone/client_packet.cpp +++ b/zone/client_packet.cpp @@ -6131,7 +6131,7 @@ void Client::Handle_OP_GMSearchCorpse(const EQApplicationPacket *app) char *escSearchString = new char[129]; database.DoEscapeString(escSearchString, gmscs->Name, strlen(gmscs->Name)); - std::string query = StringFormat("SELECT charname, zoneid, x, y, z, time_of_death, is_rezzed, is_buried " + std::string query = StringFormat("SELECT charname, zone_id, x, y, z, time_of_death, is_rezzed, is_buried " "FROM character_corpses WheRE charname LIKE '%%%s%%' ORDER BY charname LIMIT %i", escSearchString, maxResults); safe_delete_array(escSearchString); From 7efccad13e0a5f3c5f9ffe5450ddf4bd53f5f93d Mon Sep 17 00:00:00 2001 From: Natedog2012 Date: Tue, 2 Feb 2016 01:53:22 -0800 Subject: [PATCH 34/56] GetFreeGrid should no longer crash when trying to #wpadd in a zone that has no grids --- zone/waypoints.cpp | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/zone/waypoints.cpp b/zone/waypoints.cpp index 5ab46dc1f..51a7af4fb 100644 --- a/zone/waypoints.cpp +++ b/zone/waypoints.cpp @@ -1186,8 +1186,7 @@ uint32 ZoneDatabase::GetFreeGrid(uint16 zoneid) { return 0; auto row = results.begin(); - uint32 freeGridID = 1; - freeGridID = atoi(row[0]) + 1; + uint32 freeGridID = row[0] ? atoi(row[0]) + 1 : 1; return freeGridID; } From 33c7016a0e94f895088ef50c850babcea55c426d Mon Sep 17 00:00:00 2001 From: JJ Date: Thu, 4 Feb 2016 19:17:17 -0500 Subject: [PATCH 35/56] Simple spelling fix. [skip ci] --- zone/tasks.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/zone/tasks.cpp b/zone/tasks.cpp index d52ae842b..0e7de67cb 100644 --- a/zone/tasks.cpp +++ b/zone/tasks.cpp @@ -3043,7 +3043,7 @@ void ClientTaskState::AcceptNewTask(Client *c, int TaskID, int NPCID, bool enfor NPC *npc = entity_list.GetID(NPCID)->CastToNPC(); if(!npc) { c->Message(clientMessageYellow, "Task Giver ID is %i", NPCID); - c->Message(clientMessageError, "Unable to find NPC to send EVENT_TASKACCEPTD to. Report this bug."); + c->Message(clientMessageError, "Unable to find NPC to send EVENT_TASKACCEPTED to. Report this bug."); safe_delete_array(buf); return; } From 306586fa7eaaa7dc8e2cc50ed5e8b2fe7fd34e24 Mon Sep 17 00:00:00 2001 From: "Michael Cook (mackal)" Date: Sat, 6 Feb 2016 19:33:44 -0500 Subject: [PATCH 36/56] Exclude discs from buff slot stealing logic --- zone/spells.cpp | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/zone/spells.cpp b/zone/spells.cpp index b8c3023b8..45c52a48b 100644 --- a/zone/spells.cpp +++ b/zone/spells.cpp @@ -3140,7 +3140,7 @@ int Mob::AddBuff(Mob *caster, uint16 spell_id, int duration, int32 level_overrid Log.Out(Logs::Detail, Logs::Spells, "Adding buff %d will overwrite spell %d in slot %d with caster level %d", spell_id, curbuf.spellid, buffslot, curbuf.casterlevel); // If this is the first buff it would override, use its slot - if (!will_overwrite) + if (!will_overwrite && !IsDisciplineBuff(spell_id)) emptyslot = buffslot; will_overwrite = true; overwrite_slots.push_back(buffslot); @@ -3190,7 +3190,7 @@ int Mob::AddBuff(Mob *caster, uint16 spell_id, int duration, int32 level_overrid // if we hadn't found a free slot before, or if this is earlier // we use it - if (emptyslot == -1 || *cur < emptyslot) + if (emptyslot == -1 || (*cur < emptyslot && !IsDisciplineBuff(spell_id))) emptyslot = *cur; } } From cdd56ec0e13e9d70361d21dccd94b57709d6ef87 Mon Sep 17 00:00:00 2001 From: hateborne Date: Wed, 10 Feb 2016 16:51:58 -0500 Subject: [PATCH 37/56] FlatItemExtraSpellAmt Custom Rule Addition Added FlatItemExtraSpellAmt rule (boolean) to allow SpellDmg on items to be added as raw damage versus scaled. --- changelog.txt | 3 +++ common/ruletypes.h | 1 + zone/effects.cpp | 3 +++ 3 files changed, 7 insertions(+) diff --git a/changelog.txt b/changelog.txt index ee77f075d..ec4fec5d9 100644 --- a/changelog.txt +++ b/changelog.txt @@ -1,5 +1,8 @@ EQEMu Changelog (Started on Sept 24, 2003 15:50) ------------------------------------------------------- +== 02/10/2016 == +Hateborne: Added FlatItemExtraSpellAmt rule (boolean) to allow SpellDmg on items to be added as raw damage versus scaled. + == 01/26/2016 == Uleat: Fix for Berserker 'Piercing' skill issues. Server Admins: If you run custom skill sets, this patch touches the code segments that you will need to modify if you have changed the default berserker 1H-/2H-piercing skill values. Uleat (Daerath): Fix for precision-loss item weight conversions in older clients. diff --git a/common/ruletypes.h b/common/ruletypes.h index f83ea0266..143c62c17 100644 --- a/common/ruletypes.h +++ b/common/ruletypes.h @@ -361,6 +361,7 @@ RULE_BOOL(Spells, NPC_UseFocusFromSpells, true) // Allow npcs to use most spell RULE_BOOL(Spells, NPC_UseFocusFromItems, false) // Allow npcs 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, AlwaysSendTargetsBuffs, false) // ignore LAA level if true +RULE_BOOL(Spells, FlatItemExtraSpellAmt, false) // allow SpellDmg stat to affect all spells, regardless of cast time/cooldown/etc RULE_CATEGORY_END() RULE_CATEGORY(Combat) diff --git a/zone/effects.cpp b/zone/effects.cpp index dc3392403..1fafb1426 100644 --- a/zone/effects.cpp +++ b/zone/effects.cpp @@ -225,6 +225,9 @@ int32 Mob::GetActDoTDamage(uint16 spell_id, int32 value, Mob* target) { int32 Mob::GetExtraSpellAmt(uint16 spell_id, int32 extra_spell_amt, int32 base_spell_dmg) { + if (RuleB(Spells, FlatItemExtraSpellAmt)) + return extra_spell_amt; + int total_cast_time = 0; if (spells[spell_id].recast_time >= spells[spell_id].recovery_time) From 31b6346f038d1b697569fdbf313257b33e323cb2 Mon Sep 17 00:00:00 2001 From: Natedog2012 Date: Thu, 11 Feb 2016 13:07:42 -0800 Subject: [PATCH 38/56] Fix the math so berserkers aren't left out in spell related checks. --- zone/bot.cpp | 16 ++++++++-------- zone/effects.cpp | 8 ++++---- zone/merc.cpp | 2 +- zone/mob.cpp | 2 +- zone/oldcode.cpp | 4 ++-- zone/spell_effects.cpp | 8 ++++---- 6 files changed, 20 insertions(+), 20 deletions(-) diff --git a/zone/bot.cpp b/zone/bot.cpp index 926df4fb0..dee437849 100644 --- a/zone/bot.cpp +++ b/zone/bot.cpp @@ -5463,7 +5463,7 @@ int32 Bot::CalcBotAAFocus(BotfocusType type, uint32 aa_ID, uint32 points, uint16 LimitFound = true; break; case SE_LimitMaxLevel: - spell_level = spell.classes[(GetClass() % 16) - 1]; + spell_level = spell.classes[(GetClass() % 17) - 1]; lvldiff = spell_level - base1; //every level over cap reduces the effect by base2 percent unless from a clicky when ItemCastsUseFocus is true if(lvldiff > 0 && (spell_level <= RuleI(Character, MaxLevel) || RuleB(Character, ItemCastsUseFocus) == false)) { @@ -5477,7 +5477,7 @@ int32 Bot::CalcBotAAFocus(BotfocusType type, uint32 aa_ID, uint32 points, uint16 } break; case SE_LimitMinLevel: - if((spell.classes[(GetClass() % 16) - 1]) < base1) + if((spell.classes[(GetClass() % 17) - 1]) < base1) LimitFound = true; break; case SE_LimitCastTimeMin: @@ -5915,7 +5915,7 @@ int32 Bot::CalcBotFocusEffect(BotfocusType bottype, uint16 focus_id, uint16 spel case SE_LimitMaxLevel:{ if (IsNPC()) break; - spell_level = spell.classes[(GetClass() % 16) - 1]; + spell_level = spell.classes[(GetClass() % 17) - 1]; lvldiff = (spell_level - focus_spell.base[i]); if(lvldiff > 0 && (spell_level <= RuleI(Character, MaxLevel) || RuleB(Character, ItemCastsUseFocus) == false)) { if(focus_spell.base2[i] > 0) { @@ -5931,7 +5931,7 @@ int32 Bot::CalcBotFocusEffect(BotfocusType bottype, uint16 focus_id, uint16 spel case SE_LimitMinLevel: if (IsNPC()) break; - if (spell.classes[(GetClass() % 16) - 1] < focus_spell.base[i]) + if (spell.classes[(GetClass() % 17) - 1] < focus_spell.base[i]) return 0; break; @@ -7083,7 +7083,7 @@ int32 Bot::GetActSpellDamage(uint16 spell_id, int32 value, Mob* target) { value -= GetBotFocusEffect(BotfocusFcDamageAmt, spell_id); - if(itembonuses.SpellDmg && spells[spell_id].classes[(GetClass() % 16) - 1] >= GetLevel() - 5) + if(itembonuses.SpellDmg && spells[spell_id].classes[(GetClass() % 17) - 1] >= GetLevel() - 5) value += (GetExtraSpellAmt(spell_id, itembonuses.SpellDmg, value) * ratio / 100); entity_list.MessageClose(this, false, 100, MT_SpellCrits, "%s delivers a critical blast! (%d)", GetName(), -value); @@ -7102,7 +7102,7 @@ int32 Bot::GetActSpellDamage(uint16 spell_id, int32 value, Mob* target) { value -= GetBotFocusEffect(BotfocusFcDamageAmtCrit, spell_id); value -= GetBotFocusEffect(BotfocusFcDamageAmt, spell_id); - if(itembonuses.SpellDmg && spells[spell_id].classes[(GetClass() % 16) - 1] >= GetLevel() - 5) + if(itembonuses.SpellDmg && spells[spell_id].classes[(GetClass() % 17) - 1] >= GetLevel() - 5) value += GetExtraSpellAmt(spell_id, itembonuses.SpellDmg, value); return value; @@ -7135,7 +7135,7 @@ int32 Bot::GetActSpellHealing(uint16 spell_id, int32 value, Mob* target) { value += GetBotFocusEffect(BotfocusFcHealAmt, spell_id); value += target->GetFocusIncoming(focusFcHealAmtIncoming, SE_FcHealAmtIncoming, this, spell_id); - if(itembonuses.HealAmt && spells[spell_id].classes[(GetClass() % 16) - 1] >= GetLevel() - 5) + if(itembonuses.HealAmt && spells[spell_id].classes[(GetClass() % 17) - 1] >= GetLevel() - 5) value += (GetExtraSpellAmt(spell_id, itembonuses.HealAmt, value) * modifier); value += (value * target->GetHealRate(spell_id, this) / 100); @@ -7239,7 +7239,7 @@ int32 Bot::GetActSpellCasttime(uint16 spell_id, int32 casttime) { } int32 Bot::GetActSpellCost(uint16 spell_id, int32 cost) { - if(this->itembonuses.Clairvoyance && spells[spell_id].classes[(GetClass()%16) - 1] >= GetLevel() - 5) { + if(this->itembonuses.Clairvoyance && spells[spell_id].classes[(GetClass()%17) - 1] >= GetLevel() - 5) { int32 mana_back = (this->itembonuses.Clairvoyance * zone->random.Int(1, 100) / 100); if(mana_back > cost) mana_back = cost; diff --git a/zone/effects.cpp b/zone/effects.cpp index 1fafb1426..fb444c372 100644 --- a/zone/effects.cpp +++ b/zone/effects.cpp @@ -112,7 +112,7 @@ int32 Mob::GetActSpellDamage(uint16 spell_id, int32 value, Mob* target) { value -= GetFocusEffect(focusFcDamageAmt, spell_id); value -= GetFocusEffect(focusFcDamageAmt2, spell_id); - if(!spells[spell_id].no_heal_damage_item_mod && itembonuses.SpellDmg && spells[spell_id].classes[(GetClass()%16) - 1] >= GetLevel() - 5) + if(!spells[spell_id].no_heal_damage_item_mod && itembonuses.SpellDmg && spells[spell_id].classes[(GetClass()%17) - 1] >= GetLevel() - 5) value -= GetExtraSpellAmt(spell_id, itembonuses.SpellDmg, value)*ratio/100; else if (IsNPC() && CastToNPC()->GetSpellScale()) @@ -145,7 +145,7 @@ int32 Mob::GetActSpellDamage(uint16 spell_id, int32 value, Mob* target) { value -= GetFocusEffect(focusFcDamageAmt, spell_id); value -= GetFocusEffect(focusFcDamageAmt2, spell_id); - if(!spells[spell_id].no_heal_damage_item_mod && itembonuses.SpellDmg && spells[spell_id].classes[(GetClass()%16) - 1] >= GetLevel() - 5) + if(!spells[spell_id].no_heal_damage_item_mod && itembonuses.SpellDmg && spells[spell_id].classes[(GetClass()%17) - 1] >= GetLevel() - 5) value -= GetExtraSpellAmt(spell_id, itembonuses.SpellDmg, value); if (IsNPC() && CastToNPC()->GetSpellScale()) @@ -290,7 +290,7 @@ int32 Mob::GetActSpellHealing(uint16 spell_id, int32 value, Mob* target) { value += GetFocusEffect(focusFcHealAmt, spell_id); value += target->GetFocusIncoming(focusFcHealAmtIncoming, SE_FcHealAmtIncoming, this, spell_id); - if(!spells[spell_id].no_heal_damage_item_mod && itembonuses.HealAmt && spells[spell_id].classes[(GetClass()%16) - 1] >= GetLevel() - 5) + if(!spells[spell_id].no_heal_damage_item_mod && itembonuses.HealAmt && spells[spell_id].classes[(GetClass()%17) - 1] >= GetLevel() - 5) value += GetExtraSpellAmt(spell_id, itembonuses.HealAmt, value) * modifier; value += value*target->GetHealRate(spell_id, this)/100; @@ -339,7 +339,7 @@ int32 Client::GetActSpellCost(uint16 spell_id, int32 cost) cost *= 2; // Formula = Unknown exact, based off a random percent chance up to mana cost(after focuses) of the cast spell - if(itembonuses.Clairvoyance && spells[spell_id].classes[(GetClass()%16) - 1] >= GetLevel() - 5) + if(itembonuses.Clairvoyance && spells[spell_id].classes[(GetClass()%17) - 1] >= GetLevel() - 5) { int16 mana_back = itembonuses.Clairvoyance * zone->random.Int(1, 100) / 100; // Doesnt generate mana, so best case is a free spell diff --git a/zone/merc.cpp b/zone/merc.cpp index b4125735e..91a69f374 100644 --- a/zone/merc.cpp +++ b/zone/merc.cpp @@ -2678,7 +2678,7 @@ int16 Merc::GetFocusEffect(focusType type, uint16 spell_id) { int32 Merc::GetActSpellCost(uint16 spell_id, int32 cost) { // Formula = Unknown exact, based off a random percent chance up to mana cost(after focuses) of the cast spell - if(this->itembonuses.Clairvoyance && spells[spell_id].classes[(GetClass()%16) - 1] >= GetLevel() - 5) + if(this->itembonuses.Clairvoyance && spells[spell_id].classes[(GetClass()%17) - 1] >= GetLevel() - 5) { int16 mana_back = this->itembonuses.Clairvoyance * zone->random.Int(1, 100) / 100; // Doesnt generate mana, so best case is a free spell diff --git a/zone/mob.cpp b/zone/mob.cpp index 3dad9b247..0e2cd7d88 100644 --- a/zone/mob.cpp +++ b/zone/mob.cpp @@ -5117,7 +5117,7 @@ int8 Mob::GetDecayEffectValue(uint16 spell_id, uint16 spelleffect) { if (!IsValidSpell(spell_id)) return false; - int spell_level = spells[spell_id].classes[(GetClass()%16) - 1]; + int spell_level = spells[spell_id].classes[(GetClass()%17) - 1]; int effect_value = 0; int lvlModifier = 100; diff --git a/zone/oldcode.cpp b/zone/oldcode.cpp index 075923360..600e8ad5c 100644 --- a/zone/oldcode.cpp +++ b/zone/oldcode.cpp @@ -1082,11 +1082,11 @@ int32 Client::GenericFocus(uint16 spell_id, uint16 modspellid) switch( spells[modspellid].effectid[i] ) { case SE_LimitMaxLevel: - if (spell.classes[(GetClass()%16) - 1] > modspell.base[i]) + if (spell.classes[(GetClass()%17) - 1] > modspell.base[i]) return 100; break; case SE_LimitMinLevel: - if (spell.classes[(GetClass()%16) - 1] < modspell.base[i]) + if (spell.classes[(GetClass()%17) - 1] < modspell.base[i]) return 100; break; case SE_IncreaseRange: diff --git a/zone/spell_effects.cpp b/zone/spell_effects.cpp index e866d1e0f..d5006a52b 100644 --- a/zone/spell_effects.cpp +++ b/zone/spell_effects.cpp @@ -4227,7 +4227,7 @@ int16 Client::CalcAAFocus(focusType type, const AA::Rank &rank, uint16 spell_id) break; case SE_LimitMaxLevel: - spell_level = spell.classes[(GetClass() % 16) - 1]; + spell_level = spell.classes[(GetClass() % 17) - 1]; lvldiff = spell_level - base1; // every level over cap reduces the effect by base2 percent unless from a clicky when // ItemCastsUseFocus is true @@ -4243,7 +4243,7 @@ int16 Client::CalcAAFocus(focusType type, const AA::Rank &rank, uint16 spell_id) break; case SE_LimitMinLevel: - if ((spell.classes[(GetClass() % 16) - 1]) < base1) + if ((spell.classes[(GetClass() % 17) - 1]) < base1) LimitFailure = true; break; @@ -4661,7 +4661,7 @@ int16 Mob::CalcFocusEffect(focusType type, uint16 focus_id, uint16 spell_id, boo case SE_LimitMaxLevel: if (IsNPC()) break; - spell_level = spell.classes[(GetClass() % 16) - 1]; + spell_level = spell.classes[(GetClass() % 17) - 1]; lvldiff = spell_level - focus_spell.base[i]; // every level over cap reduces the effect by focus_spell.base2[i] percent unless from a clicky // when ItemCastsUseFocus is true @@ -4679,7 +4679,7 @@ int16 Mob::CalcFocusEffect(focusType type, uint16 focus_id, uint16 spell_id, boo case SE_LimitMinLevel: if (IsNPC()) break; - if (spell.classes[(GetClass() % 16) - 1] < focus_spell.base[i]) + if (spell.classes[(GetClass() % 17) - 1] < focus_spell.base[i]) return (0); break; From b432830dfcf36989b4e6d3143c2ed26dcf48b0e9 Mon Sep 17 00:00:00 2001 From: hateborne Date: Thu, 11 Feb 2016 17:37:32 -0500 Subject: [PATCH 39/56] IgnoreSpellDmgLvlRestriction Rule Added (re-resubmitted) Added IgnoreSpellDmgLvlRestriction rule (boolean) to ignore the 5 level spread when checking to add SpellDmg. Resubmitting due to the change Natedog made ::shakefist:: --- changelog.txt | 3 +++ common/ruletypes.h | 1 + zone/effects.cpp | 10 ++++++++-- 3 files changed, 12 insertions(+), 2 deletions(-) diff --git a/changelog.txt b/changelog.txt index ec4fec5d9..ce52c7384 100644 --- a/changelog.txt +++ b/changelog.txt @@ -1,5 +1,8 @@ EQEMu Changelog (Started on Sept 24, 2003 15:50) ------------------------------------------------------- +== 02/11/2016 == +Hateborne: Added IgnoreSpellDmgLvlRestriction rule (boolean) to ignore the 5 level spread when checking to add SpellDmg + == 02/10/2016 == Hateborne: Added FlatItemExtraSpellAmt rule (boolean) to allow SpellDmg on items to be added as raw damage versus scaled. diff --git a/common/ruletypes.h b/common/ruletypes.h index 143c62c17..cc5316406 100644 --- a/common/ruletypes.h +++ b/common/ruletypes.h @@ -362,6 +362,7 @@ RULE_BOOL(Spells, NPC_UseFocusFromItems, false) // Allow npcs to use most item d RULE_BOOL(Spells, UseAdditiveFocusFromWornSlot, false) // Allows an additive focus effect to be calculated from worn slot. RULE_BOOL(Spells, AlwaysSendTargetsBuffs, false) // ignore LAA 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 RULE_CATEGORY_END() RULE_CATEGORY(Combat) diff --git a/zone/effects.cpp b/zone/effects.cpp index fb444c372..05f6cd927 100644 --- a/zone/effects.cpp +++ b/zone/effects.cpp @@ -112,7 +112,10 @@ int32 Mob::GetActSpellDamage(uint16 spell_id, int32 value, Mob* target) { value -= GetFocusEffect(focusFcDamageAmt, spell_id); value -= GetFocusEffect(focusFcDamageAmt2, spell_id); - if(!spells[spell_id].no_heal_damage_item_mod && itembonuses.SpellDmg && spells[spell_id].classes[(GetClass()%17) - 1] >= GetLevel() - 5) + if (RuleB(Spells, IgnoreSpellDmgLvlRestriction) && !spells[spell_id].no_heal_damage_item_mod && itembonuses.SpellDmg) + value -= GetExtraSpellAmt(spell_id, itembonuses.SpellDmg, value)*ratio / 100; + + else if(!spells[spell_id].no_heal_damage_item_mod && itembonuses.SpellDmg && spells[spell_id].classes[(GetClass() % 17) - 1] >= GetLevel() - 5) value -= GetExtraSpellAmt(spell_id, itembonuses.SpellDmg, value)*ratio/100; else if (IsNPC() && CastToNPC()->GetSpellScale()) @@ -145,7 +148,10 @@ int32 Mob::GetActSpellDamage(uint16 spell_id, int32 value, Mob* target) { value -= GetFocusEffect(focusFcDamageAmt, spell_id); value -= GetFocusEffect(focusFcDamageAmt2, spell_id); - if(!spells[spell_id].no_heal_damage_item_mod && itembonuses.SpellDmg && spells[spell_id].classes[(GetClass()%17) - 1] >= GetLevel() - 5) + if (RuleB(Spells, IgnoreSpellDmgLvlRestriction) && !spells[spell_id].no_heal_damage_item_mod && itembonuses.SpellDmg) + value -= GetExtraSpellAmt(spell_id, itembonuses.SpellDmg, value); + + else if (!spells[spell_id].no_heal_damage_item_mod && itembonuses.SpellDmg && spells[spell_id].classes[(GetClass() % 17) - 1] >= GetLevel() - 5) value -= GetExtraSpellAmt(spell_id, itembonuses.SpellDmg, value); if (IsNPC() && CastToNPC()->GetSpellScale()) From a8f353518e324024fec382aa00b1d8a98378c761 Mon Sep 17 00:00:00 2001 From: KayenEQ Date: Fri, 12 Feb 2016 18:19:03 -0500 Subject: [PATCH 40/56] Allow backstabs done with bane weapons to hit targets immune to all melee except bane. Skill attacks will now give appropriate immune messages. --- zone/special_attacks.cpp | 9 ++++++--- 1 file changed, 6 insertions(+), 3 deletions(-) diff --git a/zone/special_attacks.cpp b/zone/special_attacks.cpp index 2c763df13..3758d2e1b 100644 --- a/zone/special_attacks.cpp +++ b/zone/special_attacks.cpp @@ -100,11 +100,14 @@ void Mob::DoSpecialAttackDamage(Mob *who, SkillUseTypes skill, int32 max_damage, //this really should go through the same code as normal melee damage to //pick up all the special behavior there - if (!who) + if ((who == nullptr || ((IsClient() && CastToClient()->dead) || (who->IsClient() && who->CastToClient()->dead)) || HasDied() || (!IsAttackAllowed(who)))) return; + + if(who->GetInvul() || who->GetSpecialAbility(IMMUNE_MELEE)) + max_damage = -5; - if(who->GetInvul() || who->GetSpecialAbility(IMMUNE_MELEE) || who->GetSpecialAbility(IMMUNE_MELEE_EXCEPT_BANE)) - return; //-5? + if (who->GetSpecialAbility(IMMUNE_MELEE_EXCEPT_BANE) && skill != SkillBackstab) + max_damage = -5; uint32 hate = max_damage; if(hate_override > -1) From 2268e6ed34805da15dc5ec47bd5e06eb93516ad7 Mon Sep 17 00:00:00 2001 From: Natedog2012 Date: Sat, 27 Feb 2016 01:37:35 -0800 Subject: [PATCH 41/56] Fix up Object packet for UF / RoF / RoF2. SolidType was incorrect as those fields are the XY tilt for the object. Need database values for these fields so they will actually be useful. --- common/patches/rof.cpp | 4 ++-- common/patches/rof2.cpp | 4 ++-- common/patches/rof2_structs.h | 3 ++- common/patches/rof_structs.h | 3 ++- common/patches/uf.cpp | 4 ++-- common/patches/uf_structs.h | 3 ++- 6 files changed, 12 insertions(+), 9 deletions(-) diff --git a/common/patches/rof.cpp b/common/patches/rof.cpp index 988eba916..b5349b617 100644 --- a/common/patches/rof.cpp +++ b/common/patches/rof.cpp @@ -975,8 +975,8 @@ namespace RoF VARSTRUCT_ENCODE_TYPE(uint32, OutBuffer, emu->drop_id); // Some unique id VARSTRUCT_ENCODE_TYPE(uint32, OutBuffer, 0); // Same for all objects in the zone VARSTRUCT_ENCODE_TYPE(float, OutBuffer, emu->heading); - VARSTRUCT_ENCODE_TYPE(float, OutBuffer, 0); // Normally 0, but seen (float)255.0 as well - VARSTRUCT_ENCODE_TYPE(uint32, OutBuffer, emu->solidtype); // Unknown + VARSTRUCT_ENCODE_TYPE(float, OutBuffer, 0); // X tilt + VARSTRUCT_ENCODE_TYPE(float, OutBuffer, 0); // Y tilt VARSTRUCT_ENCODE_TYPE(float, OutBuffer, emu->size != 0 && (float)emu->size < 5000.f ? (float)((float)emu->size / 100.0f) : 1.f ); // This appears to be the size field. Hackish logic because some PEQ DB items were corrupt. VARSTRUCT_ENCODE_TYPE(float, OutBuffer, emu->y); VARSTRUCT_ENCODE_TYPE(float, OutBuffer, emu->x); diff --git a/common/patches/rof2.cpp b/common/patches/rof2.cpp index 1b2da5cda..1724b8167 100644 --- a/common/patches/rof2.cpp +++ b/common/patches/rof2.cpp @@ -1046,8 +1046,8 @@ namespace RoF2 VARSTRUCT_ENCODE_TYPE(uint32, OutBuffer, emu->drop_id); // Some unique id VARSTRUCT_ENCODE_TYPE(uint32, OutBuffer, 0); // Same for all objects in the zone VARSTRUCT_ENCODE_TYPE(float, OutBuffer, emu->heading); - VARSTRUCT_ENCODE_TYPE(float, OutBuffer, 0); // Normally 0, but seen (float)255.0 as well - VARSTRUCT_ENCODE_TYPE(uint32, OutBuffer, emu->solidtype); // Unknown + VARSTRUCT_ENCODE_TYPE(float, OutBuffer, 0); // X tilt + VARSTRUCT_ENCODE_TYPE(float, OutBuffer, 0); // Y tilt VARSTRUCT_ENCODE_TYPE(float, OutBuffer, emu->size != 0 && (float)emu->size < 5000.f ? (float)((float)emu->size / 100.0f) : 1.f ); // This appears to be the size field. Hackish logic because some PEQ DB items were corrupt. VARSTRUCT_ENCODE_TYPE(float, OutBuffer, emu->y); VARSTRUCT_ENCODE_TYPE(float, OutBuffer, emu->x); diff --git a/common/patches/rof2_structs.h b/common/patches/rof2_structs.h index 1e93b7434..20d3b47f2 100644 --- a/common/patches/rof2_structs.h +++ b/common/patches/rof2_structs.h @@ -2845,7 +2845,8 @@ struct Object_Struct { /*00*/ uint32 drop_id; // Unique object id for zone /*00*/ uint32 unknown024; // 53 9e f9 7e - same for all objects in the zone? /*00*/ float heading; // heading -/*00*/ float unknown032[2]; // 00 00 00 00 00 00 00 00 +/*00*/ float x_tilt; //Tilt entire object on X axis +/*00*/ float y_tilt; //Tilt entire object on Y axis /*00*/ float size; // Size - default 1 /*00*/ float z; // z coord /*00*/ float x; // x coord diff --git a/common/patches/rof_structs.h b/common/patches/rof_structs.h index e24935d35..86f8b0872 100644 --- a/common/patches/rof_structs.h +++ b/common/patches/rof_structs.h @@ -2873,7 +2873,8 @@ struct Object_Struct { /*00*/ uint32 drop_id; // Unique object id for zone /*00*/ uint32 unknown024; // 53 9e f9 7e - same for all objects in the zone? /*00*/ float heading; // heading -/*00*/ float unknown032[2]; // 00 00 00 00 00 00 00 00 +/*00*/ float x_tilt; //Tilt entire object on X axis +/*00*/ float y_tilt; //Tilt entire object on Y axis /*00*/ float size; // Size - default 1 /*00*/ float z; // z coord /*00*/ float x; // x coord diff --git a/common/patches/uf.cpp b/common/patches/uf.cpp index adcd8f241..bc7d2906c 100644 --- a/common/patches/uf.cpp +++ b/common/patches/uf.cpp @@ -857,8 +857,8 @@ namespace UF // This next field is actually a float. There is a groundspawn in freeportwest (sack of money sitting on some barrels) which requires this // field to be set to (float)255.0 to appear at all, and also the size field below to be 5, to be the correct size. I think SoD has the same // issue. - VARSTRUCT_ENCODE_TYPE(uint32, OutBuffer, 0); - VARSTRUCT_ENCODE_TYPE(uint32, OutBuffer, emu->solidtype); // Unknown, observed 0 + VARSTRUCT_ENCODE_TYPE(float, OutBuffer, 0); //X tilt + VARSTRUCT_ENCODE_TYPE(float, OutBuffer, 0); //Y tilt VARSTRUCT_ENCODE_TYPE(float, OutBuffer, emu->size != 0 && (float)emu->size < 5000.f ? (float)((float)emu->size / 100.0f) : 1.f ); // This appears to be the size field. Hackish logic because some PEQ DB items were corrupt. VARSTRUCT_ENCODE_TYPE(float, OutBuffer, emu->y); VARSTRUCT_ENCODE_TYPE(float, OutBuffer, emu->x); diff --git a/common/patches/uf_structs.h b/common/patches/uf_structs.h index 7f3a7dcc0..75e590abd 100644 --- a/common/patches/uf_structs.h +++ b/common/patches/uf_structs.h @@ -2450,7 +2450,8 @@ struct Object_Struct { /*20*/ uint32 unknown020; // 00 00 00 00 /*24*/ uint32 unknown024; // 53 9e f9 7e - same for all objects in the zone? /*40*/ float heading; // heading -/*32*/ uint8 unknown032[8]; // 00 00 00 00 00 00 00 00 +/*00*/ float x_tilt; //Tilt entire object on X axis +/*00*/ float y_tilt; //Tilt entire object on Y axis /*28*/ float size; // Size - default 1 /*44*/ float z; // z coord /*48*/ float x; // x coord From 63cce6875f05c299a3e3883201defa224d1bdc63 Mon Sep 17 00:00:00 2001 From: Uleat Date: Sat, 27 Feb 2016 20:27:11 -0500 Subject: [PATCH 42/56] Rework of NPC::PickPocket() - added stacking ability --- common/ruletypes.h | 1 + zone/npc.cpp | 239 +++++++++++++++++++-------------------------- 2 files changed, 100 insertions(+), 140 deletions(-) diff --git a/common/ruletypes.h b/common/ruletypes.h index cc5316406..641266b2f 100644 --- a/common/ruletypes.h +++ b/common/ruletypes.h @@ -126,6 +126,7 @@ RULE_INT(Character, InvSnapshotMinIntervalM, 180) // Minimum time (in minutes) b RULE_INT(Character, InvSnapshotMinRetryM, 30) // Time (in minutes) to re-attempt an inventory snapshot after a failure RULE_INT(Character, InvSnapshotHistoryD, 30) // Time (in days) to keep snapshot entries RULE_BOOL(Character, RestrictSpellScribing, false) // Restricts spell scribing to allowable races/classes of spell scroll, if true +RULE_BOOL(Character, UseStackablePickPocketing, true) // Allows stackable pickpocketed items to stack instead of only being allowed in empty inventory slots RULE_CATEGORY_END() RULE_CATEGORY(Mercs) diff --git a/zone/npc.cpp b/zone/npc.cpp index 22e4b4b0d..103b5548e 100644 --- a/zone/npc.cpp +++ b/zone/npc.cpp @@ -1425,13 +1425,13 @@ uint32 NPC::GetMaxDamage(uint8 tlevel) return dmg; } -void NPC::PickPocket(Client* thief) { - +void NPC::PickPocket(Client* thief) +{ thief->CheckIncreaseSkill(SkillPickPockets, nullptr, 5); - //make sure were allowed to targte them: - int olevel = GetLevel(); - if(olevel > (thief->GetLevel() + THIEF_PICKPOCKET_OVER)) { + //make sure were allowed to target them: + int over_level = GetLevel(); + if(over_level > (thief->GetLevel() + THIEF_PICKPOCKET_OVER)) { thief->Message(13, "You are too inexperienced to pick pocket this target"); thief->SendPickPocketResponse(this, 0, PickPocketFailed); //should we check aggro @@ -1447,150 +1447,109 @@ void NPC::PickPocket(Client* thief) { } int steal_skill = thief->GetSkill(SkillPickPockets); - int stealchance = steal_skill*100/(5*olevel+5); - ItemInst* inst = 0; - int x = 0; - int slot[50]; - int steal_items[50]; - int charges[50]; - int money[4]; - money[0] = GetPlatinum(); - money[1] = GetGold(); - money[2] = GetSilver(); - money[3] = GetCopper(); - if (steal_skill < 125) - money[0] = 0; - if (steal_skill < 60) - money[1] = 0; - memset(slot,0,50); - memset(steal_items,0,50); - memset(charges,0,50); + int steal_chance = steal_skill * 100 / (5 * over_level + 5); + //Determine wheter to steal money or an item. - bool no_coin = ((money[0] + money[1] + money[2] + money[3]) == 0); - bool steal_item = (zone->random.Roll(50) || no_coin); - if (steal_item) - { - ItemList::iterator cur,end; - cur = itemlist.begin(); - end = itemlist.end(); - for(; cur != end && x < 49; ++cur) { - ServerLootItem_Struct* citem = *cur; - const Item_Struct* item = database.GetItem(citem->item_id); - if (item) - { - inst = database.CreateItem(item, citem->charges); - bool is_arrow = (item->ItemType == ItemTypeArrow) ? true : false; - int slot_id = thief->GetInv().FindFreeSlot(false, true, inst->GetItem()->Size, is_arrow); - if (/*!Equipped(item->ID) &&*/ - !item->Magic && item->NoDrop != 0 && !inst->IsType(ItemClassContainer) && slot_id != INVALID_INDEX - /*&& steal_skill > item->StealSkill*/ ) - { - slot[x] = slot_id; - steal_items[x] = item->ID; - if (inst->IsStackable()) - charges[x] = 1; - else - charges[x] = citem->charges; - x++; - } - } + int money[6] = { 0, ((steal_skill >= 125) ? (GetPlatinum()) : (0)), ((steal_skill >= 60) ? (GetGold()) : (0)), GetSilver(), GetCopper(), 0 }; + bool has_coin = ((money[PickPocketPlatinum] | money[PickPocketGold] | money[PickPocketSilver] | money[PickPocketCopper]) != 0); + bool steal_item = (steal_skill >= steal_chance && (zone->random.Roll(50) || !has_coin)); + + // still needs to have FindFreeSlot vs PutItemInInventory issue worked out + while (steal_item) { + std::vector> loot_selection; // + for (auto item_iter : itemlist) { + if (!item_iter || !item_iter->item_id) + continue; + + auto item_test = database.GetItem(item_iter->item_id); + if (item_test->Magic || !item_test->NoDrop || item_test->ItemType == ItemClassContainer || thief->CheckLoreConflict(item_test)) + continue; + + loot_selection.push_back(std::make_pair(item_test, ((item_test->Stackable) ? (1) : (item_iter->charges)))); } - if (x > 0) - { - int random = zone->random.Int(0, x-1); - inst = database.CreateItem(steal_items[random], charges[random]); - if (inst) - { - const Item_Struct* item = inst->GetItem(); - if (item) - { - if (/*item->StealSkill || */steal_skill >= stealchance) - { - thief->PutItemInInventory(slot[random], *inst); - thief->SendItemPacket(slot[random], inst, ItemPacketTrade); - RemoveItem(item->ID); - thief->SendPickPocketResponse(this, 0, PickPocketItem, item); - } - else - steal_item = false; - } - else - steal_item = false; - } - else - steal_item = false; - } - else if (!no_coin) - { + if (loot_selection.empty()) { steal_item = false; - } - else - { - thief->Message(0, "This target's pockets are empty"); - thief->SendPickPocketResponse(this, 0, PickPocketFailed); - } - } - if (!steal_item) //Steal money - { - uint32 amt = zone->random.Int(1, (steal_skill/25)+1); - int steal_type = 0; - if (!money[0]) - { - steal_type = 1; - if (!money[1]) - { - steal_type = 2; - if (!money[2]) - { - steal_type = 3; - } - } + break; } - if (zone->random.Roll(stealchance)) - { - switch (steal_type) - { - case 0:{ - if (amt > GetPlatinum()) - amt = GetPlatinum(); - SetPlatinum(GetPlatinum()-amt); - thief->AddMoneyToPP(0,0,0,amt,false); - thief->SendPickPocketResponse(this, amt, PickPocketPlatinum); - break; - } - case 1:{ - if (amt > GetGold()) - amt = GetGold(); - SetGold(GetGold()-amt); - thief->AddMoneyToPP(0,0,amt,0,false); - thief->SendPickPocketResponse(this, amt, PickPocketGold); - break; - } - case 2:{ - if (amt > GetSilver()) - amt = GetSilver(); - SetSilver(GetSilver()-amt); - thief->AddMoneyToPP(0,amt,0,0,false); - thief->SendPickPocketResponse(this, amt, PickPocketSilver); - break; - } - case 3:{ - if (amt > GetCopper()) - amt = GetCopper(); - SetCopper(GetCopper()-amt); - thief->AddMoneyToPP(amt,0,0,0,false); - thief->SendPickPocketResponse(this, amt, PickPocketCopper); - break; - } + int random = zone->random.Int(0, (loot_selection.size() - 1)); + uint16 slot_id = thief->GetInv().FindFreeSlot(false, true, (loot_selection[random].first->Size), (loot_selection[random].first->ItemType == ItemTypeArrow)); + if (slot_id == INVALID_INDEX) { + steal_item = false; + break; + } + + auto item_inst = database.CreateItem(loot_selection[random].first, loot_selection[random].second); + if (item_inst == nullptr) { + steal_item = false; + break; + } + + // Successful item pickpocket + if (item_inst->IsStackable() && RuleB(Character, UseStackablePickPocketing)) { + if (!thief->TryStacking(item_inst, ItemPacketTrade, false, false)) { + thief->PutItemInInventory(slot_id, *item_inst); + thief->SendItemPacket(slot_id, item_inst, ItemPacketTrade); } } - else - { - thief->SendPickPocketResponse(this, 0, PickPocketFailed); + else { + thief->PutItemInInventory(slot_id, *item_inst); + thief->SendItemPacket(slot_id, item_inst, ItemPacketTrade); } + RemoveItem(item_inst->GetID()); + thief->SendPickPocketResponse(this, 0, PickPocketItem, item_inst->GetItem()); + + return; } - safe_delete(inst); + + while (!steal_item && has_coin) { + uint32 coin_amount = zone->random.Int(1, (steal_skill / 25) + 1); + + int coin_type = PickPocketPlatinum; + while (coin_type <= PickPocketCopper) { + if (money[coin_type]) { + if (coin_amount > money[coin_type]) + coin_amount = money[coin_type]; + break; + } + ++coin_type; + } + if (coin_type > PickPocketCopper) + break; + + memset(money, 0, (sizeof(int) * 6)); + money[coin_type] = coin_amount; + + if (zone->random.Roll(steal_chance)) { // Successful coin pickpocket + switch (coin_type) { + case PickPocketPlatinum: + SetPlatinum(GetPlatinum() - coin_amount); + break; + case PickPocketGold: + SetGold(GetGold() - coin_amount); + break; + case PickPocketSilver: + SetSilver(GetSilver() - coin_amount); + break; + case PickPocketCopper: + SetCopper(GetCopper() - coin_amount); + break; + default: // has_coin..but, doesn't have coin? + thief->SendPickPocketResponse(this, 0, PickPocketFailed); + return; + } + + thief->AddMoneyToPP(money[3], money[2], money[1], money[0], false); + thief->SendPickPocketResponse(this, coin_amount, coin_type); + return; + } + + thief->SendPickPocketResponse(this, 0, PickPocketFailed); + return; + } + + thief->Message(0, "This target's pockets are empty"); + thief->SendPickPocketResponse(this, 0, PickPocketFailed); } void Mob::NPCSpecialAttacks(const char* parse, int permtag, bool reset, bool remove) { From 02e0431a7924c4bc9693648393767c9cead149bf Mon Sep 17 00:00:00 2001 From: KayenEQ Date: Mon, 29 Feb 2016 02:29:41 -0500 Subject: [PATCH 43/56] Fix for ammo weapon damage not calculating when launching projectiles with rule enabled. --- zone/special_attacks.cpp | 7 +++++-- 1 file changed, 5 insertions(+), 2 deletions(-) diff --git a/zone/special_attacks.cpp b/zone/special_attacks.cpp index 3758d2e1b..6c6177d29 100644 --- a/zone/special_attacks.cpp +++ b/zone/special_attacks.cpp @@ -904,7 +904,7 @@ void Mob::DoArcheryAttackDmg(Mob* other, const ItemInst* RangeWeapon, const Ite WDmg = weapon_damage; if (LaunchProjectile){//1: Shoot the Projectile once we calculate weapon damage. - TryProjectileAttack(other, AmmoItem, SkillArchery, WDmg, RangeWeapon, Ammo, AmmoSlot, speed); + TryProjectileAttack(other, AmmoItem, SkillArchery, (WDmg + ADmg), RangeWeapon, Ammo, AmmoSlot, speed); return; } @@ -926,7 +926,10 @@ void Mob::DoArcheryAttackDmg(Mob* other, const ItemInst* RangeWeapon, const Ite MaxDmg += MaxDmg*bonusArcheryDamageModifier / 100; - Log.Out(Logs::Detail, Logs::Combat, "Bow DMG %d, Arrow DMG %d, Max Damage %d.", WDmg, ADmg, MaxDmg); + if (RuleB(Combat, ProjectileDmgOnImpact)) + Log.Out(Logs::Detail, Logs::Combat, "Bow and Arrow DMG %d, Max Damage %d.", WDmg, MaxDmg); + else + Log.Out(Logs::Detail, Logs::Combat, "Bow DMG %d, Arrow DMG %d, Max Damage %d.", WDmg, ADmg, MaxDmg); bool dobonus = false; if(GetClass() == RANGER && GetLevel() > 50){ From abedfd3918542ffb8e9f9a972cc3738a073abbf0 Mon Sep 17 00:00:00 2001 From: Uleat Date: Mon, 29 Feb 2016 21:46:53 -0500 Subject: [PATCH 44/56] Add MainAmmo slot check for AddItemBonuses - only includes skill mods --- changelog.txt | 3 + common/item.cpp | 11 +- common/patches/sod.cpp | 2 +- common/patches/sod_structs.h | 2 +- common/patches/sof.cpp | 2 +- common/patches/sof_structs.h | 2 +- common/patches/titanium_itemfields_b.h | 2 +- zone/bonuses.cpp | 568 ++++++++++++------------- zone/client.h | 2 +- 9 files changed, 298 insertions(+), 296 deletions(-) diff --git a/changelog.txt b/changelog.txt index ce52c7384..a9239d1fe 100644 --- a/changelog.txt +++ b/changelog.txt @@ -1,5 +1,8 @@ EQEMu Changelog (Started on Sept 24, 2003 15:50) ------------------------------------------------------- +== 02/29/2016 == +Uleat: Change in AddItemBonuses - now includes ammo slot for skill mods only. Defined SoD- client SkillModMax packet property (client does not show..but, does enforce.) + == 02/11/2016 == Hateborne: Added IgnoreSpellDmgLvlRestriction rule (boolean) to ignore the 5 level spread when checking to add SpellDmg diff --git a/common/item.cpp b/common/item.cpp index 26ec154c3..5d1142d2c 100644 --- a/common/item.cpp +++ b/common/item.cpp @@ -2230,11 +2230,12 @@ void ItemInst::ScaleItem() { m_scaledItem->Mana = (int32)((float)m_item->Mana*Mult); m_scaledItem->AC = (int32)((float)m_item->AC*Mult); - m_scaledItem->SkillModValue = (int32)((float)m_item->SkillModValue*Mult); - m_scaledItem->BaneDmgAmt = (int8)((float)m_item->BaneDmgAmt*Mult); - m_scaledItem->BardValue = (int32)((float)m_item->BardValue*Mult); - m_scaledItem->ElemDmgAmt = (uint8)((float)m_item->ElemDmgAmt*Mult); - m_scaledItem->Damage = (uint32)((float)m_item->Damage*Mult); + // check these..some may not need to be modified (really need to check all stats/bonuses) + //m_scaledItem->SkillModValue = (int32)((float)m_item->SkillModValue*Mult); + //m_scaledItem->BaneDmgAmt = (int8)((float)m_item->BaneDmgAmt*Mult); // watch (10 entries with charmfileid) + m_scaledItem->BardValue = (int32)((float)m_item->BardValue*Mult); // watch (no entries with charmfileid) + m_scaledItem->ElemDmgAmt = (uint8)((float)m_item->ElemDmgAmt*Mult); // watch (no entries with charmfileid) + m_scaledItem->Damage = (uint32)((float)m_item->Damage*Mult); // watch m_scaledItem->CombatEffects = (int8)((float)m_item->CombatEffects*Mult); m_scaledItem->Shielding = (int8)((float)m_item->Shielding*Mult); diff --git a/common/patches/sod.cpp b/common/patches/sod.cpp index d5a6035f4..424ad5a22 100644 --- a/common/patches/sod.cpp +++ b/common/patches/sod.cpp @@ -3661,7 +3661,7 @@ namespace SoD ibs.Races = item->Races; ibs.Deity = item->Deity; ibs.SkillModValue = item->SkillModValue; - ibs.unknown6 = 0; + ibs.SkillModMax = item->SkillModMax; ibs.SkillModType = item->SkillModType; ibs.BaneDmgRace = item->BaneDmgRace; ibs.BaneDmgBody = item->BaneDmgBody; diff --git a/common/patches/sod_structs.h b/common/patches/sod_structs.h index d9abef4c6..20e2a56b4 100644 --- a/common/patches/sod_structs.h +++ b/common/patches/sod_structs.h @@ -4006,7 +4006,7 @@ struct ItemBodyStruct uint32 Races; uint32 Deity; int32 SkillModValue; - uint32 unknown6; + uint32 SkillModMax; uint32 SkillModType; uint32 BaneDmgRace; uint32 BaneDmgBody; diff --git a/common/patches/sof.cpp b/common/patches/sof.cpp index f407ffdc0..11e365a71 100644 --- a/common/patches/sof.cpp +++ b/common/patches/sof.cpp @@ -2983,7 +2983,7 @@ namespace SoF ibs.Races = item->Races; ibs.Deity = item->Deity; ibs.SkillModValue = item->SkillModValue; - ibs.unknown6 = 0; + ibs.SkillModMax = item->SkillModMax; ibs.SkillModType = item->SkillModType; ibs.BaneDmgRace = item->BaneDmgRace; ibs.BaneDmgBody = item->BaneDmgBody; diff --git a/common/patches/sof_structs.h b/common/patches/sof_structs.h index db7cfe028..d78277721 100644 --- a/common/patches/sof_structs.h +++ b/common/patches/sof_structs.h @@ -3861,7 +3861,7 @@ struct ItemBodyStruct uint32 Races; uint32 Deity; int32 SkillModValue; - uint32 unknown6; + uint32 SkillModMax; uint32 SkillModType; uint32 BaneDmgRace; uint32 BaneDmgBody; diff --git a/common/patches/titanium_itemfields_b.h b/common/patches/titanium_itemfields_b.h index 194a31f1c..30dc73bff 100644 --- a/common/patches/titanium_itemfields_b.h +++ b/common/patches/titanium_itemfields_b.h @@ -39,7 +39,7 @@ These fields must be in the order of how they are serialized! /* 030 */ I(AC) /* 031 */ I(Deity) /* 032 */ I(SkillModValue) -/* 033 */ C("0") +/* 033 */ I(SkillModMax) /* 034 */ I(SkillModType) /* 035 */ I(BaneDmgRace) /* 036 */ I(BaneDmgAmt) diff --git a/zone/bonuses.cpp b/zone/bonuses.cpp index e709bdef4..413b8d6c6 100644 --- a/zone/bonuses.cpp +++ b/zone/bonuses.cpp @@ -144,12 +144,12 @@ void Client::CalcItemBonuses(StatBonuses* newbon) { SetTwoHanderEquipped(false); unsigned int i; - //should not include 21 (SLOT_AMMO) - for (i = MainCharm; i < MainAmmo; i++) { + // Update: MainAmmo should only calc skill mods (TODO: Check for other cases) + for (i = MainCharm; i <= MainAmmo; i++) { const ItemInst* inst = m_inv[i]; if(inst == 0) continue; - AddItemBonuses(inst, newbon); + AddItemBonuses(inst, newbon, false, false, 0, (i == MainAmmo)); //These are given special flags due to how often they are checked for various spell effects. const Item_Struct *item = inst->GetItem(); @@ -207,7 +207,7 @@ void Client::ProcessItemCaps() itembonuses.ATK = std::min(itembonuses.ATK, CalcItemATKCap()); } -void Client::AddItemBonuses(const ItemInst *inst, StatBonuses *newbon, bool isAug, bool isTribute, int rec_override) +void Client::AddItemBonuses(const ItemInst *inst, StatBonuses *newbon, bool isAug, bool isTribute, int rec_override, bool ammo_slot_item) { if (!inst || !inst->IsType(ItemClassCommon)) { return; @@ -227,309 +227,307 @@ void Client::AddItemBonuses(const ItemInst *inst, StatBonuses *newbon, bool isAu if (GetLevel() < inst->GetItemRequiredLevel(true)) { return; } - + // So there isn't a very nice way to get the real rec level from the aug's inst, so we just pass it in, only // used for augs auto rec_level = isAug ? rec_override : inst->GetItemRecommendedLevel(true); - if (GetLevel() >= rec_level) { - newbon->AC += item->AC; - newbon->HP += item->HP; - newbon->Mana += item->Mana; - newbon->Endurance += item->Endur; - newbon->ATK += item->Attack; - newbon->STR += (item->AStr + item->HeroicStr); - newbon->STA += (item->ASta + item->HeroicSta); - newbon->DEX += (item->ADex + item->HeroicDex); - newbon->AGI += (item->AAgi + item->HeroicAgi); - newbon->INT += (item->AInt + item->HeroicInt); - newbon->WIS += (item->AWis + item->HeroicWis); - newbon->CHA += (item->ACha + item->HeroicCha); - newbon->MR += (item->MR + item->HeroicMR); - newbon->FR += (item->FR + item->HeroicFR); - newbon->CR += (item->CR + item->HeroicCR); - newbon->PR += (item->PR + item->HeroicPR); - newbon->DR += (item->DR + item->HeroicDR); - newbon->Corrup += (item->SVCorruption + item->HeroicSVCorrup); + if (!ammo_slot_item) { + if (GetLevel() >= rec_level) { + newbon->AC += item->AC; + newbon->HP += item->HP; + newbon->Mana += item->Mana; + newbon->Endurance += item->Endur; + newbon->ATK += item->Attack; + newbon->STR += (item->AStr + item->HeroicStr); + newbon->STA += (item->ASta + item->HeroicSta); + newbon->DEX += (item->ADex + item->HeroicDex); + newbon->AGI += (item->AAgi + item->HeroicAgi); + newbon->INT += (item->AInt + item->HeroicInt); + newbon->WIS += (item->AWis + item->HeroicWis); + newbon->CHA += (item->ACha + item->HeroicCha); - newbon->STRCapMod += item->HeroicStr; - newbon->STACapMod += item->HeroicSta; - newbon->DEXCapMod += item->HeroicDex; - newbon->AGICapMod += item->HeroicAgi; - newbon->INTCapMod += item->HeroicInt; - newbon->WISCapMod += item->HeroicWis; - newbon->CHACapMod += item->HeroicCha; - newbon->MRCapMod += item->HeroicMR; - newbon->CRCapMod += item->HeroicFR; - newbon->FRCapMod += item->HeroicCR; - newbon->PRCapMod += item->HeroicPR; - newbon->DRCapMod += item->HeroicDR; - newbon->CorrupCapMod += item->HeroicSVCorrup; + newbon->MR += (item->MR + item->HeroicMR); + newbon->FR += (item->FR + item->HeroicFR); + newbon->CR += (item->CR + item->HeroicCR); + newbon->PR += (item->PR + item->HeroicPR); + newbon->DR += (item->DR + item->HeroicDR); + newbon->Corrup += (item->SVCorruption + item->HeroicSVCorrup); - newbon->HeroicSTR += item->HeroicStr; - newbon->HeroicSTA += item->HeroicSta; - newbon->HeroicDEX += item->HeroicDex; - newbon->HeroicAGI += item->HeroicAgi; - newbon->HeroicINT += item->HeroicInt; - newbon->HeroicWIS += item->HeroicWis; - newbon->HeroicCHA += item->HeroicCha; - newbon->HeroicMR += item->HeroicMR; - newbon->HeroicFR += item->HeroicFR; - newbon->HeroicCR += item->HeroicCR; - newbon->HeroicPR += item->HeroicPR; - newbon->HeroicDR += item->HeroicDR; - newbon->HeroicCorrup += item->HeroicSVCorrup; + newbon->STRCapMod += item->HeroicStr; + newbon->STACapMod += item->HeroicSta; + newbon->DEXCapMod += item->HeroicDex; + newbon->AGICapMod += item->HeroicAgi; + newbon->INTCapMod += item->HeroicInt; + newbon->WISCapMod += item->HeroicWis; + newbon->CHACapMod += item->HeroicCha; + newbon->MRCapMod += item->HeroicMR; + newbon->CRCapMod += item->HeroicFR; + newbon->FRCapMod += item->HeroicCR; + newbon->PRCapMod += item->HeroicPR; + newbon->DRCapMod += item->HeroicDR; + newbon->CorrupCapMod += item->HeroicSVCorrup; - } else { - int lvl = GetLevel(); + newbon->HeroicSTR += item->HeroicStr; + newbon->HeroicSTA += item->HeroicSta; + newbon->HeroicDEX += item->HeroicDex; + newbon->HeroicAGI += item->HeroicAgi; + newbon->HeroicINT += item->HeroicInt; + newbon->HeroicWIS += item->HeroicWis; + newbon->HeroicCHA += item->HeroicCha; + newbon->HeroicMR += item->HeroicMR; + newbon->HeroicFR += item->HeroicFR; + newbon->HeroicCR += item->HeroicCR; + newbon->HeroicPR += item->HeroicPR; + newbon->HeroicDR += item->HeroicDR; + newbon->HeroicCorrup += item->HeroicSVCorrup; - newbon->AC += CalcRecommendedLevelBonus(lvl, rec_level, item->AC); - newbon->HP += CalcRecommendedLevelBonus(lvl, rec_level, item->HP); - newbon->Mana += CalcRecommendedLevelBonus(lvl, rec_level, item->Mana); - newbon->Endurance += CalcRecommendedLevelBonus(lvl, rec_level, item->Endur); - newbon->ATK += CalcRecommendedLevelBonus(lvl, rec_level, item->Attack); - newbon->STR += CalcRecommendedLevelBonus(lvl, rec_level, (item->AStr + item->HeroicStr)); - newbon->STA += CalcRecommendedLevelBonus(lvl, rec_level, (item->ASta + item->HeroicSta)); - newbon->DEX += CalcRecommendedLevelBonus(lvl, rec_level, (item->ADex + item->HeroicDex)); - newbon->AGI += CalcRecommendedLevelBonus(lvl, rec_level, (item->AAgi + item->HeroicAgi)); - newbon->INT += CalcRecommendedLevelBonus(lvl, rec_level, (item->AInt + item->HeroicInt)); - newbon->WIS += CalcRecommendedLevelBonus(lvl, rec_level, (item->AWis + item->HeroicWis)); - newbon->CHA += CalcRecommendedLevelBonus(lvl, rec_level, (item->ACha + item->HeroicCha)); + } + else { + int lvl = GetLevel(); - newbon->MR += CalcRecommendedLevelBonus(lvl, rec_level, (item->MR + item->HeroicMR)); - newbon->FR += CalcRecommendedLevelBonus(lvl, rec_level, (item->FR + item->HeroicFR)); - newbon->CR += CalcRecommendedLevelBonus(lvl, rec_level, (item->CR + item->HeroicCR)); - newbon->PR += CalcRecommendedLevelBonus(lvl, rec_level, (item->PR + item->HeroicPR)); - newbon->DR += CalcRecommendedLevelBonus(lvl, rec_level, (item->DR + item->HeroicDR)); - newbon->Corrup += - CalcRecommendedLevelBonus(lvl, rec_level, (item->SVCorruption + item->HeroicSVCorrup)); + newbon->AC += CalcRecommendedLevelBonus(lvl, rec_level, item->AC); + newbon->HP += CalcRecommendedLevelBonus(lvl, rec_level, item->HP); + newbon->Mana += CalcRecommendedLevelBonus(lvl, rec_level, item->Mana); + newbon->Endurance += CalcRecommendedLevelBonus(lvl, rec_level, item->Endur); + newbon->ATK += CalcRecommendedLevelBonus(lvl, rec_level, item->Attack); + newbon->STR += CalcRecommendedLevelBonus(lvl, rec_level, (item->AStr + item->HeroicStr)); + newbon->STA += CalcRecommendedLevelBonus(lvl, rec_level, (item->ASta + item->HeroicSta)); + newbon->DEX += CalcRecommendedLevelBonus(lvl, rec_level, (item->ADex + item->HeroicDex)); + newbon->AGI += CalcRecommendedLevelBonus(lvl, rec_level, (item->AAgi + item->HeroicAgi)); + newbon->INT += CalcRecommendedLevelBonus(lvl, rec_level, (item->AInt + item->HeroicInt)); + newbon->WIS += CalcRecommendedLevelBonus(lvl, rec_level, (item->AWis + item->HeroicWis)); + newbon->CHA += CalcRecommendedLevelBonus(lvl, rec_level, (item->ACha + item->HeroicCha)); - newbon->STRCapMod += CalcRecommendedLevelBonus(lvl, rec_level, item->HeroicStr); - newbon->STACapMod += CalcRecommendedLevelBonus(lvl, rec_level, item->HeroicSta); - newbon->DEXCapMod += CalcRecommendedLevelBonus(lvl, rec_level, item->HeroicDex); - newbon->AGICapMod += CalcRecommendedLevelBonus(lvl, rec_level, item->HeroicAgi); - newbon->INTCapMod += CalcRecommendedLevelBonus(lvl, rec_level, item->HeroicInt); - newbon->WISCapMod += CalcRecommendedLevelBonus(lvl, rec_level, item->HeroicWis); - newbon->CHACapMod += CalcRecommendedLevelBonus(lvl, rec_level, item->HeroicCha); - newbon->MRCapMod += CalcRecommendedLevelBonus(lvl, rec_level, item->HeroicMR); - newbon->CRCapMod += CalcRecommendedLevelBonus(lvl, rec_level, item->HeroicFR); - newbon->FRCapMod += CalcRecommendedLevelBonus(lvl, rec_level, item->HeroicCR); - newbon->PRCapMod += CalcRecommendedLevelBonus(lvl, rec_level, item->HeroicPR); - newbon->DRCapMod += CalcRecommendedLevelBonus(lvl, rec_level, item->HeroicDR); - newbon->CorrupCapMod += CalcRecommendedLevelBonus(lvl, rec_level, item->HeroicSVCorrup); + newbon->MR += CalcRecommendedLevelBonus(lvl, rec_level, (item->MR + item->HeroicMR)); + newbon->FR += CalcRecommendedLevelBonus(lvl, rec_level, (item->FR + item->HeroicFR)); + newbon->CR += CalcRecommendedLevelBonus(lvl, rec_level, (item->CR + item->HeroicCR)); + newbon->PR += CalcRecommendedLevelBonus(lvl, rec_level, (item->PR + item->HeroicPR)); + newbon->DR += CalcRecommendedLevelBonus(lvl, rec_level, (item->DR + item->HeroicDR)); + newbon->Corrup += + CalcRecommendedLevelBonus(lvl, rec_level, (item->SVCorruption + item->HeroicSVCorrup)); - newbon->HeroicSTR += CalcRecommendedLevelBonus(lvl, rec_level, item->HeroicStr); - newbon->HeroicSTA += CalcRecommendedLevelBonus(lvl, rec_level, item->HeroicSta); - newbon->HeroicDEX += CalcRecommendedLevelBonus(lvl, rec_level, item->HeroicDex); - newbon->HeroicAGI += CalcRecommendedLevelBonus(lvl, rec_level, item->HeroicAgi); - newbon->HeroicINT += CalcRecommendedLevelBonus(lvl, rec_level, item->HeroicInt); - newbon->HeroicWIS += CalcRecommendedLevelBonus(lvl, rec_level, item->HeroicWis); - newbon->HeroicCHA += CalcRecommendedLevelBonus(lvl, rec_level, item->HeroicCha); - newbon->HeroicMR += CalcRecommendedLevelBonus(lvl, rec_level, item->HeroicMR); - newbon->HeroicFR += CalcRecommendedLevelBonus(lvl, rec_level, item->HeroicFR); - newbon->HeroicCR += CalcRecommendedLevelBonus(lvl, rec_level, item->HeroicCR); - newbon->HeroicPR += CalcRecommendedLevelBonus(lvl, rec_level, item->HeroicPR); - newbon->HeroicDR += CalcRecommendedLevelBonus(lvl, rec_level, item->HeroicDR); - newbon->HeroicCorrup += CalcRecommendedLevelBonus(lvl, rec_level, item->HeroicSVCorrup); - } - - // FatherNitwit: New style haste, shields, and regens - if (newbon->haste < (int32)item->Haste) { - newbon->haste = item->Haste; - } - if (item->Regen > 0) - newbon->HPRegen += item->Regen; - - if (item->ManaRegen > 0) - newbon->ManaRegen += item->ManaRegen; - - if (item->EnduranceRegen > 0) - newbon->EnduranceRegen += item->EnduranceRegen; - - if (item->DamageShield > 0) { - if ((newbon->DamageShield + item->DamageShield) > RuleI(Character, ItemDamageShieldCap)) - newbon->DamageShield = RuleI(Character, ItemDamageShieldCap); - else - newbon->DamageShield += item->DamageShield; - } - if (item->SpellShield > 0) { - if ((newbon->SpellShield + item->SpellShield) > RuleI(Character, ItemSpellShieldingCap)) - newbon->SpellShield = RuleI(Character, ItemSpellShieldingCap); - else - newbon->SpellShield += item->SpellShield; - } - if (item->Shielding > 0) { - if ((newbon->MeleeMitigation + item->Shielding) > RuleI(Character, ItemShieldingCap)) - newbon->MeleeMitigation = RuleI(Character, ItemShieldingCap); - else - newbon->MeleeMitigation += item->Shielding; - } - if (item->StunResist > 0) { - if ((newbon->StunResist + item->StunResist) > RuleI(Character, ItemStunResistCap)) - newbon->StunResist = RuleI(Character, ItemStunResistCap); - else - newbon->StunResist += item->StunResist; - } - if (item->StrikeThrough > 0) { - if ((newbon->StrikeThrough + item->StrikeThrough) > RuleI(Character, ItemStrikethroughCap)) - newbon->StrikeThrough = RuleI(Character, ItemStrikethroughCap); - else - newbon->StrikeThrough += item->StrikeThrough; - } - if (item->Avoidance > 0) { - if ((newbon->AvoidMeleeChance + item->Avoidance) > RuleI(Character, ItemAvoidanceCap)) - newbon->AvoidMeleeChance = RuleI(Character, ItemAvoidanceCap); - else - newbon->AvoidMeleeChance += item->Avoidance; - } - if (item->Accuracy > 0) { - if ((newbon->HitChance + item->Accuracy) > RuleI(Character, ItemAccuracyCap)) - newbon->HitChance = RuleI(Character, ItemAccuracyCap); - else - newbon->HitChance += item->Accuracy; - } - if (item->CombatEffects > 0) { - if ((newbon->ProcChance + item->CombatEffects) > RuleI(Character, ItemCombatEffectsCap)) - newbon->ProcChance = RuleI(Character, ItemCombatEffectsCap); - else - newbon->ProcChance += item->CombatEffects; - } - if (item->DotShielding > 0) { - if ((newbon->DoTShielding + item->DotShielding) > RuleI(Character, ItemDoTShieldingCap)) - newbon->DoTShielding = RuleI(Character, ItemDoTShieldingCap); - else - newbon->DoTShielding += item->DotShielding; - } - - if (item->HealAmt > 0) { - if ((newbon->HealAmt + item->HealAmt) > RuleI(Character, ItemHealAmtCap)) - newbon->HealAmt = RuleI(Character, ItemHealAmtCap); - else - newbon->HealAmt += item->HealAmt; - } - if (item->SpellDmg > 0) { - if ((newbon->SpellDmg + item->SpellDmg) > RuleI(Character, ItemSpellDmgCap)) - newbon->SpellDmg = RuleI(Character, ItemSpellDmgCap); - else - newbon->SpellDmg += item->SpellDmg; - } - if (item->Clairvoyance > 0) { - if ((newbon->Clairvoyance + item->Clairvoyance) > RuleI(Character, ItemClairvoyanceCap)) - newbon->Clairvoyance = RuleI(Character, ItemClairvoyanceCap); - else - newbon->Clairvoyance += item->Clairvoyance; - } - - if (item->DSMitigation > 0) { - if ((newbon->DSMitigation + item->DSMitigation) > RuleI(Character, ItemDSMitigationCap)) - newbon->DSMitigation = RuleI(Character, ItemDSMitigationCap); - else - newbon->DSMitigation += item->DSMitigation; - } - if (item->Worn.Effect > 0 && item->Worn.Type == ET_WornEffect) { // latent effects - ApplySpellsBonuses(item->Worn.Effect, item->Worn.Level, newbon, 0, item->Worn.Type); - } - - if (item->Focus.Effect > 0 && (item->Focus.Type == ET_Focus)) { // focus effects - ApplySpellsBonuses(item->Focus.Effect, item->Focus.Level, newbon, 0); - } - - switch (item->BardType) { - case 51: /* All (e.g. Singing Short Sword) */ - { - if (item->BardValue > newbon->singingMod) - newbon->singingMod = item->BardValue; - if (item->BardValue > newbon->brassMod) - newbon->brassMod = item->BardValue; - if (item->BardValue > newbon->stringedMod) - newbon->stringedMod = item->BardValue; - if (item->BardValue > newbon->percussionMod) - newbon->percussionMod = item->BardValue; - if (item->BardValue > newbon->windMod) - newbon->windMod = item->BardValue; - break; - } - case 50: /* Singing */ - { - if (item->BardValue > newbon->singingMod) - newbon->singingMod = item->BardValue; - break; - } - case 23: /* Wind */ - { - if (item->BardValue > newbon->windMod) - newbon->windMod = item->BardValue; - break; - } - case 24: /* stringed */ - { - if (item->BardValue > newbon->stringedMod) - newbon->stringedMod = item->BardValue; - break; - } - case 25: /* brass */ - { - if (item->BardValue > newbon->brassMod) - newbon->brassMod = item->BardValue; - break; - } - case 26: /* Percussion */ - { - if (item->BardValue > newbon->percussionMod) - newbon->percussionMod = item->BardValue; - break; - } + newbon->STRCapMod += CalcRecommendedLevelBonus(lvl, rec_level, item->HeroicStr); + newbon->STACapMod += CalcRecommendedLevelBonus(lvl, rec_level, item->HeroicSta); + newbon->DEXCapMod += CalcRecommendedLevelBonus(lvl, rec_level, item->HeroicDex); + newbon->AGICapMod += CalcRecommendedLevelBonus(lvl, rec_level, item->HeroicAgi); + newbon->INTCapMod += CalcRecommendedLevelBonus(lvl, rec_level, item->HeroicInt); + newbon->WISCapMod += CalcRecommendedLevelBonus(lvl, rec_level, item->HeroicWis); + newbon->CHACapMod += CalcRecommendedLevelBonus(lvl, rec_level, item->HeroicCha); + newbon->MRCapMod += CalcRecommendedLevelBonus(lvl, rec_level, item->HeroicMR); + newbon->CRCapMod += CalcRecommendedLevelBonus(lvl, rec_level, item->HeroicFR); + newbon->FRCapMod += CalcRecommendedLevelBonus(lvl, rec_level, item->HeroicCR); + newbon->PRCapMod += CalcRecommendedLevelBonus(lvl, rec_level, item->HeroicPR); + newbon->DRCapMod += CalcRecommendedLevelBonus(lvl, rec_level, item->HeroicDR); + newbon->CorrupCapMod += CalcRecommendedLevelBonus(lvl, rec_level, item->HeroicSVCorrup); + + newbon->HeroicSTR += CalcRecommendedLevelBonus(lvl, rec_level, item->HeroicStr); + newbon->HeroicSTA += CalcRecommendedLevelBonus(lvl, rec_level, item->HeroicSta); + newbon->HeroicDEX += CalcRecommendedLevelBonus(lvl, rec_level, item->HeroicDex); + newbon->HeroicAGI += CalcRecommendedLevelBonus(lvl, rec_level, item->HeroicAgi); + newbon->HeroicINT += CalcRecommendedLevelBonus(lvl, rec_level, item->HeroicInt); + newbon->HeroicWIS += CalcRecommendedLevelBonus(lvl, rec_level, item->HeroicWis); + newbon->HeroicCHA += CalcRecommendedLevelBonus(lvl, rec_level, item->HeroicCha); + newbon->HeroicMR += CalcRecommendedLevelBonus(lvl, rec_level, item->HeroicMR); + newbon->HeroicFR += CalcRecommendedLevelBonus(lvl, rec_level, item->HeroicFR); + newbon->HeroicCR += CalcRecommendedLevelBonus(lvl, rec_level, item->HeroicCR); + newbon->HeroicPR += CalcRecommendedLevelBonus(lvl, rec_level, item->HeroicPR); + newbon->HeroicDR += CalcRecommendedLevelBonus(lvl, rec_level, item->HeroicDR); + newbon->HeroicCorrup += CalcRecommendedLevelBonus(lvl, rec_level, item->HeroicSVCorrup); + } + + // FatherNitwit: New style haste, shields, and regens + if (newbon->haste < (int32)item->Haste) { + newbon->haste = item->Haste; + } + if (item->Regen > 0) + newbon->HPRegen += item->Regen; + + if (item->ManaRegen > 0) + newbon->ManaRegen += item->ManaRegen; + + if (item->EnduranceRegen > 0) + newbon->EnduranceRegen += item->EnduranceRegen; + + if (item->DamageShield > 0) { + if ((newbon->DamageShield + item->DamageShield) > RuleI(Character, ItemDamageShieldCap)) + newbon->DamageShield = RuleI(Character, ItemDamageShieldCap); + else + newbon->DamageShield += item->DamageShield; + } + if (item->SpellShield > 0) { + if ((newbon->SpellShield + item->SpellShield) > RuleI(Character, ItemSpellShieldingCap)) + newbon->SpellShield = RuleI(Character, ItemSpellShieldingCap); + else + newbon->SpellShield += item->SpellShield; + } + if (item->Shielding > 0) { + if ((newbon->MeleeMitigation + item->Shielding) > RuleI(Character, ItemShieldingCap)) + newbon->MeleeMitigation = RuleI(Character, ItemShieldingCap); + else + newbon->MeleeMitigation += item->Shielding; + } + if (item->StunResist > 0) { + if ((newbon->StunResist + item->StunResist) > RuleI(Character, ItemStunResistCap)) + newbon->StunResist = RuleI(Character, ItemStunResistCap); + else + newbon->StunResist += item->StunResist; + } + if (item->StrikeThrough > 0) { + if ((newbon->StrikeThrough + item->StrikeThrough) > RuleI(Character, ItemStrikethroughCap)) + newbon->StrikeThrough = RuleI(Character, ItemStrikethroughCap); + else + newbon->StrikeThrough += item->StrikeThrough; + } + if (item->Avoidance > 0) { + if ((newbon->AvoidMeleeChance + item->Avoidance) > RuleI(Character, ItemAvoidanceCap)) + newbon->AvoidMeleeChance = RuleI(Character, ItemAvoidanceCap); + else + newbon->AvoidMeleeChance += item->Avoidance; + } + if (item->Accuracy > 0) { + if ((newbon->HitChance + item->Accuracy) > RuleI(Character, ItemAccuracyCap)) + newbon->HitChance = RuleI(Character, ItemAccuracyCap); + else + newbon->HitChance += item->Accuracy; + } + if (item->CombatEffects > 0) { + if ((newbon->ProcChance + item->CombatEffects) > RuleI(Character, ItemCombatEffectsCap)) + newbon->ProcChance = RuleI(Character, ItemCombatEffectsCap); + else + newbon->ProcChance += item->CombatEffects; + } + if (item->DotShielding > 0) { + if ((newbon->DoTShielding + item->DotShielding) > RuleI(Character, ItemDoTShieldingCap)) + newbon->DoTShielding = RuleI(Character, ItemDoTShieldingCap); + else + newbon->DoTShielding += item->DotShielding; + } + + if (item->HealAmt > 0) { + if ((newbon->HealAmt + item->HealAmt) > RuleI(Character, ItemHealAmtCap)) + newbon->HealAmt = RuleI(Character, ItemHealAmtCap); + else + newbon->HealAmt += item->HealAmt; + } + if (item->SpellDmg > 0) { + if ((newbon->SpellDmg + item->SpellDmg) > RuleI(Character, ItemSpellDmgCap)) + newbon->SpellDmg = RuleI(Character, ItemSpellDmgCap); + else + newbon->SpellDmg += item->SpellDmg; + } + if (item->Clairvoyance > 0) { + if ((newbon->Clairvoyance + item->Clairvoyance) > RuleI(Character, ItemClairvoyanceCap)) + newbon->Clairvoyance = RuleI(Character, ItemClairvoyanceCap); + else + newbon->Clairvoyance += item->Clairvoyance; + } + + if (item->DSMitigation > 0) { + if ((newbon->DSMitigation + item->DSMitigation) > RuleI(Character, ItemDSMitigationCap)) + newbon->DSMitigation = RuleI(Character, ItemDSMitigationCap); + else + newbon->DSMitigation += item->DSMitigation; + } + if (item->Worn.Effect > 0 && item->Worn.Type == ET_WornEffect) { // latent effects + ApplySpellsBonuses(item->Worn.Effect, item->Worn.Level, newbon, 0, item->Worn.Type); + } + + if (item->Focus.Effect > 0 && (item->Focus.Type == ET_Focus)) { // focus effects + ApplySpellsBonuses(item->Focus.Effect, item->Focus.Level, newbon, 0); + } + + switch (item->BardType) { + case 51: /* All (e.g. Singing Short Sword) */ + if (item->BardValue > newbon->singingMod) + newbon->singingMod = item->BardValue; + if (item->BardValue > newbon->brassMod) + newbon->brassMod = item->BardValue; + if (item->BardValue > newbon->stringedMod) + newbon->stringedMod = item->BardValue; + if (item->BardValue > newbon->percussionMod) + newbon->percussionMod = item->BardValue; + if (item->BardValue > newbon->windMod) + newbon->windMod = item->BardValue; + break; + case 50: /* Singing */ + if (item->BardValue > newbon->singingMod) + newbon->singingMod = item->BardValue; + break; + case 23: /* Wind */ + if (item->BardValue > newbon->windMod) + newbon->windMod = item->BardValue; + break; + case 24: /* stringed */ + if (item->BardValue > newbon->stringedMod) + newbon->stringedMod = item->BardValue; + break; + case 25: /* brass */ + if (item->BardValue > newbon->brassMod) + newbon->brassMod = item->BardValue; + break; + case 26: /* Percussion */ + if (item->BardValue > newbon->percussionMod) + newbon->percussionMod = item->BardValue; + break; + } + + // Add Item Faction Mods + if (item->FactionMod1) { + if (item->FactionAmt1 > 0 && item->FactionAmt1 > GetItemFactionBonus(item->FactionMod1)) { + AddItemFactionBonus(item->FactionMod1, item->FactionAmt1); + } + else if (item->FactionAmt1 < 0 && item->FactionAmt1 < GetItemFactionBonus(item->FactionMod1)) { + AddItemFactionBonus(item->FactionMod1, item->FactionAmt1); + } + } + if (item->FactionMod2) { + if (item->FactionAmt2 > 0 && item->FactionAmt2 > GetItemFactionBonus(item->FactionMod2)) { + AddItemFactionBonus(item->FactionMod2, item->FactionAmt2); + } + else if (item->FactionAmt2 < 0 && item->FactionAmt2 < GetItemFactionBonus(item->FactionMod2)) { + AddItemFactionBonus(item->FactionMod2, item->FactionAmt2); + } + } + if (item->FactionMod3) { + if (item->FactionAmt3 > 0 && item->FactionAmt3 > GetItemFactionBonus(item->FactionMod3)) { + AddItemFactionBonus(item->FactionMod3, item->FactionAmt3); + } + else if (item->FactionAmt3 < 0 && item->FactionAmt3 < GetItemFactionBonus(item->FactionMod3)) { + AddItemFactionBonus(item->FactionMod3, item->FactionAmt3); + } + } + if (item->FactionMod4) { + if (item->FactionAmt4 > 0 && item->FactionAmt4 > GetItemFactionBonus(item->FactionMod4)) { + AddItemFactionBonus(item->FactionMod4, item->FactionAmt4); + } + else if (item->FactionAmt4 < 0 && item->FactionAmt4 < GetItemFactionBonus(item->FactionMod4)) { + AddItemFactionBonus(item->FactionMod4, item->FactionAmt4); + } + } + + if (item->ExtraDmgSkill != 0 && item->ExtraDmgSkill <= HIGHEST_SKILL) { + if ((newbon->SkillDamageAmount[item->ExtraDmgSkill] + item->ExtraDmgAmt) > + RuleI(Character, ItemExtraDmgCap)) + newbon->SkillDamageAmount[item->ExtraDmgSkill] = RuleI(Character, ItemExtraDmgCap); + else + newbon->SkillDamageAmount[item->ExtraDmgSkill] += item->ExtraDmgAmt; + } } + // Process when ammo_slot_item = true or false if (item->SkillModValue != 0 && item->SkillModType <= HIGHEST_SKILL) { if ((item->SkillModValue > 0 && newbon->skillmod[item->SkillModType] < item->SkillModValue) || - (item->SkillModValue < 0 && newbon->skillmod[item->SkillModType] > item->SkillModValue)) { + (item->SkillModValue < 0 && newbon->skillmod[item->SkillModType] > item->SkillModValue)) { + newbon->skillmod[item->SkillModType] = item->SkillModValue; newbon->skillmodmax[item->SkillModType] = item->SkillModMax; } } - // Add Item Faction Mods - if (item->FactionMod1) { - if (item->FactionAmt1 > 0 && item->FactionAmt1 > GetItemFactionBonus(item->FactionMod1)) { - AddItemFactionBonus(item->FactionMod1, item->FactionAmt1); - } else if (item->FactionAmt1 < 0 && item->FactionAmt1 < GetItemFactionBonus(item->FactionMod1)) { - AddItemFactionBonus(item->FactionMod1, item->FactionAmt1); - } - } - if (item->FactionMod2) { - if (item->FactionAmt2 > 0 && item->FactionAmt2 > GetItemFactionBonus(item->FactionMod2)) { - AddItemFactionBonus(item->FactionMod2, item->FactionAmt2); - } else if (item->FactionAmt2 < 0 && item->FactionAmt2 < GetItemFactionBonus(item->FactionMod2)) { - AddItemFactionBonus(item->FactionMod2, item->FactionAmt2); - } - } - if (item->FactionMod3) { - if (item->FactionAmt3 > 0 && item->FactionAmt3 > GetItemFactionBonus(item->FactionMod3)) { - AddItemFactionBonus(item->FactionMod3, item->FactionAmt3); - } else if (item->FactionAmt3 < 0 && item->FactionAmt3 < GetItemFactionBonus(item->FactionMod3)) { - AddItemFactionBonus(item->FactionMod3, item->FactionAmt3); - } - } - if (item->FactionMod4) { - if (item->FactionAmt4 > 0 && item->FactionAmt4 > GetItemFactionBonus(item->FactionMod4)) { - AddItemFactionBonus(item->FactionMod4, item->FactionAmt4); - } else if (item->FactionAmt4 < 0 && item->FactionAmt4 < GetItemFactionBonus(item->FactionMod4)) { - AddItemFactionBonus(item->FactionMod4, item->FactionAmt4); - } - } - - if (item->ExtraDmgSkill != 0 && item->ExtraDmgSkill <= HIGHEST_SKILL) { - if ((newbon->SkillDamageAmount[item->ExtraDmgSkill] + item->ExtraDmgAmt) > - RuleI(Character, ItemExtraDmgCap)) - newbon->SkillDamageAmount[item->ExtraDmgSkill] = RuleI(Character, ItemExtraDmgCap); - else - newbon->SkillDamageAmount[item->ExtraDmgSkill] += item->ExtraDmgAmt; - } - if (!isAug) { for (int i = 0; i < EmuConstants::ITEM_COMMON_SIZE; i++) - AddItemBonuses(inst->GetAugment(i), newbon, true, false, rec_level); + AddItemBonuses(inst->GetAugment(i), newbon, true, false, rec_level, ammo_slot_item); } } diff --git a/zone/client.h b/zone/client.h index d9f2f0dfc..b1d43c49c 100644 --- a/zone/client.h +++ b/zone/client.h @@ -1303,7 +1303,7 @@ public: protected: friend class Mob; void CalcItemBonuses(StatBonuses* newbon); - void AddItemBonuses(const ItemInst *inst, StatBonuses* newbon, bool isAug = false, bool isTribute = false, int rec_override = 0); + void AddItemBonuses(const ItemInst *inst, StatBonuses* newbon, bool isAug = false, bool isTribute = false, int rec_override = 0, bool ammo_slot_item = false); void AdditiveWornBonuses(const ItemInst *inst, StatBonuses* newbon, bool isAug = false); int CalcRecommendedLevelBonus(uint8 level, uint8 reclevel, int basestat); void CalcEdibleBonuses(StatBonuses* newbon); From 66b62303e42f7f3125c8c6f1921ca89d83683c1b Mon Sep 17 00:00:00 2001 From: Akkadius Date: Mon, 29 Feb 2016 22:01:33 -0600 Subject: [PATCH 45/56] Fix for shared_memory and clearing out hotfix_ when ran --- shared_memory/main.cpp | 12 ++++++++++++ 1 file changed, 12 insertions(+) diff --git a/shared_memory/main.cpp b/shared_memory/main.cpp index 3d47f217f..11d21153b 100644 --- a/shared_memory/main.cpp +++ b/shared_memory/main.cpp @@ -62,6 +62,18 @@ int main(int argc, char **argv) { database.LoadLogSettings(Log.log_settings); Log.StartFileLogs(); + database.LoadVariables(); + + /* If we're running shared memory and hotfix has no custom name, we probably want to start from scratch... */ + char db_hotfix_name[256] = { 0 }; + if (database.GetVariable("hotfix_name", db_hotfix_name, 256)) { + if (strlen(db_hotfix_name) > 0 && strcasecmp("hotfix_", db_hotfix_name) == 0) { + Log.Out(Logs::General, Logs::Status, "Current hotfix in variables is the default %s, clearing out variable", db_hotfix_name); + std::string query = StringFormat("UPDATE `variables` SET `value`='' WHERE (`varname`='hotfix_name')"); + database.QueryDatabase(query); + } + } + std::string hotfix_name = ""; bool load_all = true; bool load_items = false; From 141d6e3e8b5777a2b5053b336d885ebd7b0422ca Mon Sep 17 00:00:00 2001 From: Uleat Date: Tue, 1 Mar 2016 16:55:31 -0500 Subject: [PATCH 46/56] Fix for two possible crash points in NPC::Death() --- zone/attack.cpp | 222 +++++++++++++++++++++++------------------------- 1 file changed, 105 insertions(+), 117 deletions(-) diff --git a/zone/attack.cpp b/zone/attack.cpp index 2fdf5f115..247e31058 100644 --- a/zone/attack.cpp +++ b/zone/attack.cpp @@ -1874,50 +1874,52 @@ void NPC::Damage(Mob* other, int32 damage, uint16 spell_id, SkillUseTypes attack } } -bool NPC::Death(Mob* killer_mob, int32 damage, uint16 spell, SkillUseTypes attack_skill) { - Log.Out(Logs::Detail, Logs::Combat, "Fatal blow dealt by %s with %d damage, spell %d, skill %d", killer_mob->GetName(), damage, spell, attack_skill); +bool NPC::Death(Mob* killer_mob, int32 damage, uint16 spell, SkillUseTypes attack_skill) +{ + Log.Out(Logs::Detail, Logs::Combat, "Fatal blow dealt by %s with %d damage, spell %d, skill %d", + ((killer_mob) ? (killer_mob->GetName()) : ("[nullptr]")), damage, spell, attack_skill); Mob *oos = nullptr; - if(killer_mob) { + if (killer_mob) { oos = killer_mob->GetOwnerOrSelf(); char buffer[48] = { 0 }; - snprintf(buffer, 47, "%d %d %d %d", killer_mob ? killer_mob->GetID() : 0, damage, spell, static_cast(attack_skill)); - if(parse->EventNPC(EVENT_DEATH, this, oos, buffer, 0) != 0) - { - if(GetHP() < 0) { + snprintf(buffer, 47, "%d %d %d %d", killer_mob->GetID(), damage, spell, static_cast(attack_skill)); + + if (parse->EventNPC(EVENT_DEATH, this, oos, buffer, 0) != 0) { + if (GetHP() < 0) { SetHP(0); } return false; } - if(killer_mob && killer_mob->IsClient() && (spell != SPELL_UNKNOWN) && damage > 0) { - char val1[20]={0}; + if (killer_mob->IsClient() && (spell != SPELL_UNKNOWN) && damage > 0) { + char val1[20] = { 0 }; entity_list.MessageClose_StringID(this, false, 100, MT_NonMelee, HIT_NON_MELEE, killer_mob->GetCleanName(), GetCleanName(), ConvertArray(damage, val1)); } - } else { - + } + else { char buffer[48] = { 0 }; - snprintf(buffer, 47, "%d %d %d %d", killer_mob ? killer_mob->GetID() : 0, damage, spell, static_cast(attack_skill)); - if(parse->EventNPC(EVENT_DEATH, this, nullptr, buffer, 0) != 0) - { - if(GetHP() < 0) { + snprintf(buffer, 47, "%d %d %d %d", 0, damage, spell, static_cast(attack_skill)); + + if (parse->EventNPC(EVENT_DEATH, this, nullptr, buffer, 0) != 0) { + if (GetHP() < 0) { SetHP(0); } return false; } } - if (IsEngaged()) - { + if (IsEngaged()) { zone->DelAggroMob(); Log.Out(Logs::Detail, Logs::Attack, "%s Mobs currently Aggro %i", __FUNCTION__, zone->MobsAggroCount()); } + SetHP(0); SetPet(0); - if (GetSwarmOwner()){ + if (GetSwarmOwner()) { Mob* owner = entity_list.GetMobID(GetSwarmOwner()); if (owner) owner->SetTempPetCount(owner->GetTempPetCount() - 1); @@ -1927,14 +1929,14 @@ bool NPC::Death(Mob* killer_mob, int32 damage, uint16 spell, SkillUseTypes attac entity_list.RemoveFromTargets(this, p_depop); - if(p_depop == true) + if (p_depop == true) return false; HasAISpellEffects = false; BuffFadeAll(); uint8 killed_level = GetLevel(); - EQApplicationPacket* app= new EQApplicationPacket(OP_Death,sizeof(Death_Struct)); + EQApplicationPacket* app = new EQApplicationPacket(OP_Death, sizeof(Death_Struct)); Death_Struct* d = (Death_Struct*)app->pBuffer; d->spawn_id = GetID(); d->killer_id = killer_mob ? killer_mob->GetID() : 0; @@ -1945,55 +1947,49 @@ bool NPC::Death(Mob* killer_mob, int32 damage, uint16 spell, SkillUseTypes attac app->priority = 6; entity_list.QueueClients(killer_mob, app, false); - if(respawn2) { + safe_delete(app); + + if (respawn2) { respawn2->DeathReset(1); } - if (killer_mob) { - if(GetClass() != LDON_TREASURE) - hate_list.AddEntToHateList(killer_mob, damage); - } - - safe_delete(app); + if (killer_mob && GetClass() != LDON_TREASURE) + hate_list.AddEntToHateList(killer_mob, damage); Mob *give_exp = hate_list.GetDamageTopOnHateList(this); - if(give_exp == nullptr) + if (give_exp == nullptr) give_exp = killer; - if(give_exp && give_exp->HasOwner()) { + if (give_exp && give_exp->HasOwner()) { bool ownerInGroup = false; - if((give_exp->HasGroup() && give_exp->GetGroup()->IsGroupMember(give_exp->GetUltimateOwner())) + if ((give_exp->HasGroup() && give_exp->GetGroup()->IsGroupMember(give_exp->GetUltimateOwner())) || (give_exp->IsPet() && (give_exp->GetOwner()->IsClient() - || ( give_exp->GetOwner()->HasGroup() && give_exp->GetOwner()->GetGroup()->IsGroupMember(give_exp->GetOwner()->GetUltimateOwner()))))) + || (give_exp->GetOwner()->HasGroup() && give_exp->GetOwner()->GetGroup()->IsGroupMember(give_exp->GetOwner()->GetUltimateOwner()))))) ownerInGroup = true; give_exp = give_exp->GetUltimateOwner(); #ifdef BOTS - if(!RuleB(Bots, BotGroupXP) && !ownerInGroup) { + if (!RuleB(Bots, BotGroupXP) && !ownerInGroup) { give_exp = nullptr; } #endif //BOTS } - if(give_exp && give_exp->IsTempPet() && give_exp->IsPetOwnerClient()) { - - if (give_exp->IsNPC() && give_exp->CastToNPC()->GetSwarmOwner()){ - Mob* temp_owner = nullptr; - temp_owner = entity_list.GetMobID(give_exp->CastToNPC()->GetSwarmOwner()); - + if (give_exp && give_exp->IsTempPet() && give_exp->IsPetOwnerClient()) { + if (give_exp->IsNPC() && give_exp->CastToNPC()->GetSwarmOwner()) { + Mob* temp_owner = entity_list.GetMobID(give_exp->CastToNPC()->GetSwarmOwner()); if (temp_owner) give_exp = temp_owner; } } - int PlayerCount = 0; // QueryServ Player Counting Client *give_exp_client = nullptr; - if(give_exp && give_exp->IsClient()) + if (give_exp && give_exp->IsClient()) give_exp_client = give_exp->CastToClient(); //do faction hits even if we are a merchant, so long as a player killed us @@ -2001,43 +1997,43 @@ bool NPC::Death(Mob* killer_mob, int32 damage, uint16 spell, SkillUseTypes attac hate_list.DoFactionHits(GetNPCFactionID()); bool IsLdonTreasure = (this->GetClass() == LDON_TREASURE); - if (give_exp_client && !IsCorpse()) - { + + if (give_exp_client && !IsCorpse()) { Group *kg = entity_list.GetGroupByClient(give_exp_client); Raid *kr = entity_list.GetRaidByClient(give_exp_client); int32 finalxp = EXP_FORMULA; finalxp = give_exp_client->mod_client_xp(finalxp, this); - if(kr) - { - if(!IsLdonTreasure && MerchantType == 0) { + if (kr) { + if (!IsLdonTreasure && MerchantType == 0) { kr->SplitExp((finalxp), this); - if(killer_mob && (kr->IsRaidMember(killer_mob->GetName()) || kr->IsRaidMember(killer_mob->GetUltimateOwner()->GetName()))) - killer_mob->TrySpellOnKill(killed_level,spell); + if (killer_mob && (kr->IsRaidMember(killer_mob->GetName()) || kr->IsRaidMember(killer_mob->GetUltimateOwner()->GetName()))) + killer_mob->TrySpellOnKill(killed_level, spell); } + /* Send the EVENT_KILLED_MERIT event for all raid members */ for (int i = 0; i < MAX_RAID_MEMBERS; i++) { if (kr->members[i].member != nullptr && kr->members[i].member->IsClient()) { // If Group Member is Client Client *c = kr->members[i].member; parse->EventNPC(EVENT_KILLED_MERIT, this, c, "killed", 0); - if(RuleB(NPC, EnableMeritBasedFaction)) + if (RuleB(NPC, EnableMeritBasedFaction)) c->SetFactionLevel(c->CharacterID(), GetNPCFactionID(), c->GetBaseClass(), c->GetBaseRace(), c->GetDeity()); mod_npc_killed_merit(kr->members[i].member); - if(RuleB(TaskSystem, EnableTaskSystem)) + if (RuleB(TaskSystem, EnableTaskSystem)) kr->members[i].member->UpdateTasksOnKill(GetNPCTypeID()); PlayerCount++; } } // QueryServ Logging - Raid Kills - if(RuleB(QueryServ, PlayerLogNPCKills)){ + if (RuleB(QueryServ, PlayerLogNPCKills)) { ServerPacket* pack = new ServerPacket(ServerOP_QSPlayerLogNPCKills, sizeof(QSPlayerLogNPCKill_Struct) + (sizeof(QSPlayerLogNPCKillsPlayers_Struct) * PlayerCount)); PlayerCount = 0; - QSPlayerLogNPCKill_Struct* QS = (QSPlayerLogNPCKill_Struct*) pack->pBuffer; + QSPlayerLogNPCKill_Struct* QS = (QSPlayerLogNPCKill_Struct*)pack->pBuffer; QS->s1.NPCID = this->GetNPCTypeID(); QS->s1.ZoneID = this->GetZoneID(); QS->s1.Type = 2; // Raid Fight @@ -2054,13 +2050,13 @@ bool NPC::Death(Mob* killer_mob, int32 damage, uint16 spell, SkillUseTypes attac // End QueryServ Logging } - else if (give_exp_client->IsGrouped() && kg != nullptr) - { - if(!IsLdonTreasure && MerchantType == 0) { + else if (give_exp_client->IsGrouped() && kg != nullptr) { + if (!IsLdonTreasure && MerchantType == 0) { kg->SplitExp((finalxp), this); - if(killer_mob && (kg->IsGroupMember(killer_mob->GetName()) || kg->IsGroupMember(killer_mob->GetUltimateOwner()->GetName()))) - killer_mob->TrySpellOnKill(killed_level,spell); + if (killer_mob && (kg->IsGroupMember(killer_mob->GetName()) || kg->IsGroupMember(killer_mob->GetUltimateOwner()->GetName()))) + killer_mob->TrySpellOnKill(killed_level, spell); } + /* Send the EVENT_KILLED_MERIT event and update kill tasks * for all group members */ for (int i = 0; i < MAX_GROUP_MEMBERS; i++) { @@ -2068,12 +2064,12 @@ bool NPC::Death(Mob* killer_mob, int32 damage, uint16 spell, SkillUseTypes attac Client *c = kg->members[i]->CastToClient(); parse->EventNPC(EVENT_KILLED_MERIT, this, c, "killed", 0); - if(RuleB(NPC, EnableMeritBasedFaction)) + if (RuleB(NPC, EnableMeritBasedFaction)) c->SetFactionLevel(c->CharacterID(), GetNPCFactionID(), c->GetBaseClass(), c->GetBaseRace(), c->GetDeity()); mod_npc_killed_merit(c); - if(RuleB(TaskSystem, EnableTaskSystem)) + if (RuleB(TaskSystem, EnableTaskSystem)) c->UpdateTasksOnKill(GetNPCTypeID()); PlayerCount++; @@ -2081,10 +2077,10 @@ bool NPC::Death(Mob* killer_mob, int32 damage, uint16 spell, SkillUseTypes attac } // QueryServ Logging - Group Kills - if(RuleB(QueryServ, PlayerLogNPCKills)){ + if (RuleB(QueryServ, PlayerLogNPCKills)) { ServerPacket* pack = new ServerPacket(ServerOP_QSPlayerLogNPCKills, sizeof(QSPlayerLogNPCKill_Struct) + (sizeof(QSPlayerLogNPCKillsPlayers_Struct) * PlayerCount)); PlayerCount = 0; - QSPlayerLogNPCKill_Struct* QS = (QSPlayerLogNPCKill_Struct*) pack->pBuffer; + QSPlayerLogNPCKill_Struct* QS = (QSPlayerLogNPCKill_Struct*)pack->pBuffer; QS->s1.NPCID = this->GetNPCTypeID(); QS->s1.ZoneID = this->GetZoneID(); QS->s1.Type = 1; // Group Fight @@ -2100,36 +2096,34 @@ bool NPC::Death(Mob* killer_mob, int32 damage, uint16 spell, SkillUseTypes attac } // End QueryServ Logging } - else - { - if(!IsLdonTreasure && MerchantType == 0) { + else { + if (!IsLdonTreasure && MerchantType == 0) { int conlevel = give_exp->GetLevelCon(GetLevel()); - if (conlevel != CON_GREEN) - { - if(!GetOwner() || (GetOwner() && !GetOwner()->IsClient())) - { + if (conlevel != CON_GREEN) { + if (!GetOwner() || (GetOwner() && !GetOwner()->IsClient())) { give_exp_client->AddEXP((finalxp), conlevel); - if(killer_mob && (killer_mob->GetID() == give_exp_client->GetID() || killer_mob->GetUltimateOwner()->GetID() == give_exp_client->GetID())) - killer_mob->TrySpellOnKill(killed_level,spell); + if (killer_mob && (killer_mob->GetID() == give_exp_client->GetID() || killer_mob->GetUltimateOwner()->GetID() == give_exp_client->GetID())) + killer_mob->TrySpellOnKill(killed_level, spell); } } } - /* Send the EVENT_KILLED_MERIT event */ + + /* Send the EVENT_KILLED_MERIT event */ parse->EventNPC(EVENT_KILLED_MERIT, this, give_exp_client, "killed", 0); - if(RuleB(NPC, EnableMeritBasedFaction)) + if (RuleB(NPC, EnableMeritBasedFaction)) give_exp_client->SetFactionLevel(give_exp_client->CharacterID(), GetNPCFactionID(), give_exp_client->GetBaseClass(), - give_exp_client->GetBaseRace(), give_exp_client->GetDeity()); + give_exp_client->GetBaseRace(), give_exp_client->GetDeity()); mod_npc_killed_merit(give_exp_client); - if(RuleB(TaskSystem, EnableTaskSystem)) + if (RuleB(TaskSystem, EnableTaskSystem)) give_exp_client->UpdateTasksOnKill(GetNPCTypeID()); // QueryServ Logging - Solo - if(RuleB(QueryServ, PlayerLogNPCKills)){ + if (RuleB(QueryServ, PlayerLogNPCKills)) { ServerPacket* pack = new ServerPacket(ServerOP_QSPlayerLogNPCKills, sizeof(QSPlayerLogNPCKill_Struct) + (sizeof(QSPlayerLogNPCKillsPlayers_Struct) * 1)); - QSPlayerLogNPCKill_Struct* QS = (QSPlayerLogNPCKill_Struct*) pack->pBuffer; + QSPlayerLogNPCKill_Struct* QS = (QSPlayerLogNPCKill_Struct*)pack->pBuffer; QS->s1.NPCID = this->GetNPCTypeID(); QS->s1.ZoneID = this->GetZoneID(); QS->s1.Type = 0; // Solo Fight @@ -2147,71 +2141,69 @@ bool NPC::Death(Mob* killer_mob, int32 damage, uint16 spell, SkillUseTypes attac && MerchantType == 0 && killer && (killer->IsClient() || (killer->HasOwner() && killer->GetUltimateOwner()->IsClient()) || (killer->IsNPC() && killer->CastToNPC()->GetSwarmInfo() && killer->CastToNPC()->GetSwarmInfo()->GetOwner() && killer->CastToNPC()->GetSwarmInfo()->GetOwner()->IsClient()))) { - if(killer != 0) - { - if(killer->GetOwner() != 0 && killer->GetOwner()->IsClient()) + if (killer != 0) { + if (killer->GetOwner() != 0 && killer->GetOwner()->IsClient()) killer = killer->GetOwner(); - if(!killer->CastToClient()->GetGM() && killer->IsClient()) + if (killer->IsClient() && !killer->CastToClient()->GetGM()) this->CheckMinMaxLevel(killer); } + entity_list.RemoveFromAutoXTargets(this); uint16 emoteid = this->GetEmoteID(); - Corpse* corpse = new Corpse(this, &itemlist, GetNPCTypeID(), &NPCTypedata,level>54?RuleI(NPC,MajorNPCCorpseDecayTimeMS):RuleI(NPC,MinorNPCCorpseDecayTimeMS)); + Corpse* corpse = new Corpse(this, &itemlist, GetNPCTypeID(), &NPCTypedata, level>54 ? RuleI(NPC, MajorNPCCorpseDecayTimeMS) : RuleI(NPC, MinorNPCCorpseDecayTimeMS)); entity_list.LimitRemoveNPC(this); entity_list.AddCorpse(corpse, GetID()); entity_list.UnMarkNPC(GetID()); entity_list.RemoveNPC(GetID()); this->SetID(0); - if(killer != 0 && emoteid != 0) + + if (killer != 0 && emoteid != 0) corpse->CastToNPC()->DoNPCEmote(AFTERDEATH, emoteid); - if(killer != 0 && killer->IsClient()) { + if (killer != 0 && killer->IsClient()) { corpse->AllowPlayerLoot(killer, 0); - if(killer->IsGrouped()) { + if (killer->IsGrouped()) { Group* group = entity_list.GetGroupByClient(killer->CastToClient()); - if(group != 0) { - for(int i=0;i<6;i++) { // Doesnt work right, needs work - if(group->members[i] != nullptr) { - corpse->AllowPlayerLoot(group->members[i],i); + if (group != 0) { + for (int i = 0; i<6; i++) { // Doesnt work right, needs work + if (group->members[i] != nullptr) { + corpse->AllowPlayerLoot(group->members[i], i); } } } } - else if(killer->IsRaidGrouped()){ + else if (killer->IsRaidGrouped()) { Raid* r = entity_list.GetRaidByClient(killer->CastToClient()); - if(r){ + if (r) { int i = 0; - for(int x = 0; x < MAX_RAID_MEMBERS; x++) - { - switch(r->GetLootType()) - { + for (int x = 0; x < MAX_RAID_MEMBERS; x++) { + switch (r->GetLootType()) { case 0: case 1: - if(r->members[x].member && r->members[x].IsRaidLeader){ + if (r->members[x].member && r->members[x].IsRaidLeader) { corpse->AllowPlayerLoot(r->members[x].member, i); i++; } break; case 2: - if(r->members[x].member && r->members[x].IsRaidLeader){ + if (r->members[x].member && r->members[x].IsRaidLeader) { corpse->AllowPlayerLoot(r->members[x].member, i); i++; } - else if(r->members[x].member && r->members[x].IsGroupLeader){ + else if (r->members[x].member && r->members[x].IsGroupLeader) { corpse->AllowPlayerLoot(r->members[x].member, i); i++; } break; case 3: - if(r->members[x].member && r->members[x].IsLooter){ + if (r->members[x].member && r->members[x].IsLooter) { corpse->AllowPlayerLoot(r->members[x].member, i); i++; } break; case 4: - if(r->members[x].member) - { + if (r->members[x].member) { corpse->AllowPlayerLoot(r->members[x].member, i); i++; } @@ -2222,41 +2214,36 @@ bool NPC::Death(Mob* killer_mob, int32 damage, uint16 spell, SkillUseTypes attac } } - if(zone && zone->adv_data) - { + if (zone && zone->adv_data) { ServerZoneAdventureDataReply_Struct *sr = (ServerZoneAdventureDataReply_Struct*)zone->adv_data; - if(sr->type == Adventure_Kill) - { + if (sr->type == Adventure_Kill) { zone->DoAdventureCountIncrease(); } - else if(sr->type == Adventure_Assassinate) - { - if(sr->data_id == GetNPCTypeID()) - { + else if (sr->type == Adventure_Assassinate) { + if (sr->data_id == GetNPCTypeID()) { zone->DoAdventureCountIncrease(); } - else - { + else { zone->DoAdventureAssassinationCountIncrease(); } } } } - else + else { entity_list.RemoveFromXTargets(this); + } // Parse quests even if we're killed by an NPC - if(oos) { + if (oos) { mod_npc_killed(oos); uint16 emoteid = this->GetEmoteID(); - if(emoteid != 0) + if (emoteid != 0) this->DoNPCEmote(ONDEATH, emoteid); - if(oos->IsNPC()) - { + if (oos->IsNPC()) { parse->EventNPC(EVENT_NPC_SLAY, oos->CastToNPC(), this, "", 0); uint16 emoteid = oos->GetEmoteID(); - if(emoteid != 0) + if (emoteid != 0) oos->CastToNPC()->DoNPCEmote(KILLEDNPC, emoteid); killer_mob->TrySpellOnKill(killed_level, spell); } @@ -2264,7 +2251,8 @@ bool NPC::Death(Mob* killer_mob, int32 damage, uint16 spell, SkillUseTypes attac WipeHateList(); p_depop = true; - if(killer_mob && killer_mob->GetTarget() == this) //we can kill things without having them targeted + + if (killer_mob && killer_mob->GetTarget() == this) //we can kill things without having them targeted killer_mob->SetTarget(nullptr); //via AE effects and such.. entity_list.UpdateFindableNPCState(this, true); @@ -2275,7 +2263,7 @@ bool NPC::Death(Mob* killer_mob, int32 damage, uint16 spell, SkillUseTypes attac /* Zone controller process EVENT_DEATH_ZONE (Death events) */ if (RuleB(Zone, UseZoneController)) { - if (entity_list.GetNPCByNPCTypeID(ZONE_CONTROLLER_NPC_ID) && this->GetNPCTypeID() != ZONE_CONTROLLER_NPC_ID){ + if (entity_list.GetNPCByNPCTypeID(ZONE_CONTROLLER_NPC_ID) && this->GetNPCTypeID() != ZONE_CONTROLLER_NPC_ID) { char data_pass[100] = { 0 }; snprintf(data_pass, 99, "%d %d %d %d %d", killer_mob ? killer_mob->GetID() : 0, damage, spell, static_cast(attack_skill), this->GetNPCTypeID()); parse->EventNPC(EVENT_DEATH_ZONE, entity_list.GetNPCByNPCTypeID(ZONE_CONTROLLER_NPC_ID)->CastToNPC(), nullptr, data_pass, 0); From 09589edcdddd240288006506cf72d9e7f6bf8037 Mon Sep 17 00:00:00 2001 From: Uleat Date: Tue, 1 Mar 2016 18:23:36 -0500 Subject: [PATCH 47/56] Fix for LDoN treasure npcs poofing - please report any issues --- changelog.txt | 3 +++ zone/attack.cpp | 8 +++++++- 2 files changed, 10 insertions(+), 1 deletion(-) diff --git a/changelog.txt b/changelog.txt index a9239d1fe..3964d37b5 100644 --- a/changelog.txt +++ b/changelog.txt @@ -1,5 +1,8 @@ EQEMu Changelog (Started on Sept 24, 2003 15:50) ------------------------------------------------------- +== 03/01/2016 == +Uleat: Fix for LDoN treasure 'npcs' not leaving a corpse (please report any issues..) + == 02/29/2016 == Uleat: Change in AddItemBonuses - now includes ammo slot for skill mods only. Defined SoD- client SkillModMax packet property (client does not show..but, does enforce.) diff --git a/zone/attack.cpp b/zone/attack.cpp index 247e31058..c14a74059 100644 --- a/zone/attack.cpp +++ b/zone/attack.cpp @@ -2138,8 +2138,9 @@ bool NPC::Death(Mob* killer_mob, int32 damage, uint16 spell, SkillUseTypes attac } if (!HasOwner() && !IsMerc() && class_ != MERCHANT && class_ != ADVENTUREMERCHANT && !GetSwarmInfo() - && MerchantType == 0 && killer && (killer->IsClient() || (killer->HasOwner() && killer->GetUltimateOwner()->IsClient()) || + && MerchantType == 0 && ((killer && (killer->IsClient() || (killer->HasOwner() && killer->GetUltimateOwner()->IsClient()) || (killer->IsNPC() && killer->CastToNPC()->GetSwarmInfo() && killer->CastToNPC()->GetSwarmInfo()->GetOwner() && killer->CastToNPC()->GetSwarmInfo()->GetOwner()->IsClient()))) + || (killer_mob && IsLdonTreasure))) { if (killer != 0) { if (killer->GetOwner() != 0 && killer->GetOwner()->IsClient()) @@ -2213,6 +2214,11 @@ bool NPC::Death(Mob* killer_mob, int32 damage, uint16 spell, SkillUseTypes attac } } } + else if (killer_mob && IsLdonTreasure) { + auto u_owner = killer_mob->GetUltimateOwner(); + if (u_owner->IsClient()) + corpse->AllowPlayerLoot(u_owner, 0); + } if (zone && zone->adv_data) { ServerZoneAdventureDataReply_Struct *sr = (ServerZoneAdventureDataReply_Struct*)zone->adv_data; From 655d2d47baf7633e01edabcccd342844996a391d Mon Sep 17 00:00:00 2001 From: Natedog2012 Date: Tue, 1 Mar 2016 22:30:54 -0800 Subject: [PATCH 48/56] Fix the typo in this change. Pets size should scale up properly until 3x normal size. --- zone/pets.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/zone/pets.cpp b/zone/pets.cpp index f5f741f44..fd777fab4 100644 --- a/zone/pets.cpp +++ b/zone/pets.cpp @@ -283,7 +283,7 @@ void Mob::MakePoweredPet(uint16 spell_id, const char* pettype, int16 petpower, npc_type->level += 1 + ((int)act_power / 25) > npc_type->level + RuleR(Pets, PetPowerLevelCap) ? RuleR(Pets, PetPowerLevelCap) : 1 + ((int)act_power / 25); // gains an additional level for every 25 pet power npc_type->min_dmg = (npc_type->min_dmg * (1 + (scale_power / 2))); npc_type->max_dmg = (npc_type->max_dmg * (1 + (scale_power / 2))); - npc_type->size = npc_type->size * (1 + (scale_power / 2)) > npc_type->size * 3 ? npc_type->size * 3 : (1 + (scale_power / 2)); + npc_type->size = npc_type->size * (1 + (scale_power / 2)) > npc_type->size * 3 ? npc_type->size * 3 : npc_type-> size * (1 + (scale_power / 2)); } record.petpower = act_power; } From 9599501acec61a282a7855a56a1edb04d11771b8 Mon Sep 17 00:00:00 2001 From: "Michael Cook (mackal)" Date: Sat, 5 Mar 2016 16:28:53 -0500 Subject: [PATCH 49/56] Implement extra bind points (secondary recall) For SE_Gate, base2 is which bind to use (starting at 1) For SE_BindAffinity, base1 is which bind to set (starting at 1) For SE_GateCastersBindpoint, base1 is which bind to use (starting at 1) here was actually no spells that don't send to the main bind, but it uses a base1 of 1 which matches with SE_Gate This also doesn't break anything The quest stuff for now hasn't been updated to be able to make use of the extra binds There are a total of 5 bind points, with the 5th being your starting city --- changelog.txt | 8 +++ common/database.cpp | 4 +- common/version.h | 2 +- utils/sql/db_update_manifest.txt | 1 + .../required/2016_03_05_secondary_recall.sql | 6 ++ world/worlddb.cpp | 12 ++-- zone/client.cpp | 7 +-- zone/client.h | 4 +- zone/lua_client.cpp | 10 +-- zone/mob.h | 2 +- zone/npc.h | 2 +- zone/perl_client.cpp | 2 +- zone/questmgr.cpp | 2 +- zone/spell_effects.cpp | 27 ++++---- zone/zonedb.cpp | 61 ++++++++++--------- zone/zonedb.h | 2 +- zone/zoning.cpp | 45 +++++++------- 17 files changed, 109 insertions(+), 88 deletions(-) create mode 100644 utils/sql/git/required/2016_03_05_secondary_recall.sql diff --git a/changelog.txt b/changelog.txt index 3964d37b5..e3762b3dd 100644 --- a/changelog.txt +++ b/changelog.txt @@ -1,5 +1,13 @@ EQEMu Changelog (Started on Sept 24, 2003 15:50) ------------------------------------------------------- +== 03/05/2016 == +mackal: Implement extra bind points (secondary recall) + For SE_Gate, base2 is which bind to use (starting at 1) + For SE_BindAffinity, base1 is which bind to set (starting at 1) + For SE_GateCastersBindpoint, base1 is which bind to use (starting at 1) + There was actually no spells that don't send to the main bind, but it uses a base1 of 1 which matches with SE_Gate + This also doesn't break anything + == 03/01/2016 == Uleat: Fix for LDoN treasure 'npcs' not leaving a corpse (please report any issues..) diff --git a/common/database.cpp b/common/database.cpp index b8889fa06..cdafaa165 100644 --- a/common/database.cpp +++ b/common/database.cpp @@ -636,11 +636,11 @@ bool Database::SaveCharacterCreate(uint32 character_id, uint32 account_id, Playe ); auto results = QueryDatabase(query); /* Save Bind Points */ - query = StringFormat("REPLACE INTO `character_bind` (id, zone_id, instance_id, x, y, z, heading, is_home)" + query = StringFormat("REPLACE INTO `character_bind` (id, zone_id, instance_id, x, y, z, heading, slot)" " VALUES (%u, %u, %u, %f, %f, %f, %f, %i), " "(%u, %u, %u, %f, %f, %f, %f, %i)", character_id, pp->binds[0].zoneId, 0, pp->binds[0].x, pp->binds[0].y, pp->binds[0].z, pp->binds[0].heading, 0, - character_id, pp->binds[4].zoneId, 0, pp->binds[4].x, pp->binds[4].y, pp->binds[4].z, pp->binds[4].heading, 1 + character_id, pp->binds[4].zoneId, 0, pp->binds[4].x, pp->binds[4].y, pp->binds[4].z, pp->binds[4].heading, 4 ); results = QueryDatabase(query); /* Save Skills */ diff --git a/common/version.h b/common/version.h index b1be73905..04bf9189c 100644 --- a/common/version.h +++ b/common/version.h @@ -30,7 +30,7 @@ Manifest: https://github.com/EQEmu/Server/blob/master/utils/sql/db_update_manifest.txt */ -#define CURRENT_BINARY_DATABASE_VERSION 9095 +#define CURRENT_BINARY_DATABASE_VERSION 9096 #ifdef BOTS #define CURRENT_BINARY_BOTS_DATABASE_VERSION 9000 #else diff --git a/utils/sql/db_update_manifest.txt b/utils/sql/db_update_manifest.txt index 31f3d2ccf..6f48f983e 100644 --- a/utils/sql/db_update_manifest.txt +++ b/utils/sql/db_update_manifest.txt @@ -349,6 +349,7 @@ 9093|2015_12_21_items_updates_evoitem.sql|SHOW COLUMNS FROM `items` LIKE 'evoitem'|empty| 9094|2015_12_29_quest_zone_events.sql|SELECT * FROM perl_event_export_settings WHERE event_description = 'EVENT_SPAWN_ZONE'|empty| 9095|2016_01_08_command_find_aliases.sql|SELECT * FROM `command_settings` WHERE `command` LIKE 'findaliases'|empty| +9096|2016_03_05_secondary_recall.sql|SHOW COLUMNS FROM `character_bind` LIKE 'slot'|empty| # Upgrade conditions: # This won't be needed after this system is implemented, but it is used database that are not diff --git a/utils/sql/git/required/2016_03_05_secondary_recall.sql b/utils/sql/git/required/2016_03_05_secondary_recall.sql new file mode 100644 index 000000000..7b0f02754 --- /dev/null +++ b/utils/sql/git/required/2016_03_05_secondary_recall.sql @@ -0,0 +1,6 @@ +ALTER TABLE `character_bind` ADD `slot` int(4) AFTER `id`; +UPDATE `character_bind` SET `slot`='0' WHERE `is_home`=0; +UPDATE `character_bind` SET `slot`='4' WHERE `is_home`=1; +ALTER TABLE `character_bind` DROP PRIMARY KEY, ADD PRIMARY KEY(`id`, `slot`); +ALTER TABLE `character_bind` DROP COLUMN `is_home`; + diff --git a/world/worlddb.cpp b/world/worlddb.cpp index b09758888..357ab3c33 100644 --- a/world/worlddb.cpp +++ b/world/worlddb.cpp @@ -159,10 +159,10 @@ void WorldDatabase::GetCharSelectInfo(uint32 accountID, EQApplicationPacket **ou } /* Set Bind Point Data for any character that may possibly be missing it for any reason */ - cquery = StringFormat("SELECT `zone_id`, `instance_id`, `x`, `y`, `z`, `heading`, `is_home` FROM `character_bind` WHERE `id` = %i LIMIT 2", character_id); + cquery = StringFormat("SELECT `zone_id`, `instance_id`, `x`, `y`, `z`, `heading`, `slot` FROM `character_bind` WHERE `id` = %i LIMIT 5", character_id); auto results_bind = database.QueryDatabase(cquery); for (auto row_b = results_bind.begin(); row_b != results_bind.end(); ++row_b) { - if (row_b[6] && atoi(row_b[6]) == 1){ has_home = 1; } + if (row_b[6] && atoi(row_b[6]) == 4){ has_home = 1; } if (row_b[6] && atoi(row_b[6]) == 0){ has_bind = 1; } } @@ -189,14 +189,14 @@ void WorldDatabase::GetCharSelectInfo(uint32 accountID, EQApplicationPacket **ou pp.binds[0] = pp.binds[4]; /* If no home bind set, set it */ if (has_home == 0) { - std::string query = StringFormat("REPLACE INTO `character_bind` (id, zone_id, instance_id, x, y, z, heading, is_home)" + std::string query = StringFormat("REPLACE INTO `character_bind` (id, zone_id, instance_id, x, y, z, heading, slot)" " VALUES (%u, %u, %u, %f, %f, %f, %f, %i)", - character_id, pp.binds[4].zoneId, 0, pp.binds[4].x, pp.binds[4].y, pp.binds[4].z, pp.binds[4].heading, 1); + character_id, pp.binds[4].zoneId, 0, pp.binds[4].x, pp.binds[4].y, pp.binds[4].z, pp.binds[4].heading, 4); auto results_bset = QueryDatabase(query); } /* If no regular bind set, set it */ if (has_bind == 0) { - std::string query = StringFormat("REPLACE INTO `character_bind` (id, zone_id, instance_id, x, y, z, heading, is_home)" + std::string query = StringFormat("REPLACE INTO `character_bind` (id, zone_id, instance_id, x, y, z, heading, slot)" " VALUES (%u, %u, %u, %f, %f, %f, %f, %i)", character_id, pp.binds[0].zoneId, 0, pp.binds[0].x, pp.binds[0].y, pp.binds[0].z, pp.binds[0].heading, 0); auto results_bset = QueryDatabase(query); @@ -285,7 +285,7 @@ int WorldDatabase::MoveCharacterToBind(int CharID, uint8 bindnum) bindnum = 0; } - std::string query = StringFormat("SELECT zone_id, instance_id, x, y, z FROM character_bind WHERE id = %u AND is_home = %u LIMIT 1", CharID, bindnum == 4 ? 1 : 0); + std::string query = StringFormat("SELECT zone_id, instance_id, x, y, z FROM character_bind WHERE id = %u AND slot = %u LIMIT 1", CharID, bindnum); auto results = database.QueryDatabase(query); if(!results.Success() || results.RowCount() == 0) { return 0; diff --git a/zone/client.cpp b/zone/client.cpp index e24c24627..5a9724fa8 100644 --- a/zone/client.cpp +++ b/zone/client.cpp @@ -587,10 +587,9 @@ bool Client::Save(uint8 iCommitNow) { database.SaveCharacterCurrency(CharacterID(), &m_pp); /* Save Current Bind Points */ - auto regularBindPosition = glm::vec4(m_pp.binds[0].x, m_pp.binds[0].y, m_pp.binds[0].z, 0.0f); - auto homeBindPosition = glm::vec4(m_pp.binds[4].x, m_pp.binds[4].y, m_pp.binds[4].z, 0.0f); - database.SaveCharacterBindPoint(CharacterID(), m_pp.binds[0].zoneId, m_pp.binds[0].instance_id, regularBindPosition, 0); /* Regular bind */ - database.SaveCharacterBindPoint(CharacterID(), m_pp.binds[4].zoneId, m_pp.binds[4].instance_id, homeBindPosition, 1); /* Home Bind */ + for (int i = 0; i < 5; i++) + if (m_pp.binds[i].zoneId) + database.SaveCharacterBindPoint(CharacterID(), m_pp.binds[i], i); /* Save Character Buffs */ database.SaveBuffs(this); diff --git a/zone/client.h b/zone/client.h index b1d43c49c..f36422d3a 100644 --- a/zone/client.h +++ b/zone/client.h @@ -582,8 +582,8 @@ public: void GoToBind(uint8 bindnum = 0); void GoToSafeCoords(uint16 zone_id, uint16 instance_id); - void Gate(); - void SetBindPoint(int to_zone = -1, int to_instance = 0, const glm::vec3& location = glm::vec3()); + void Gate(uint8 bindnum = 0); + void SetBindPoint(int bind_num = 0, int to_zone = -1, int to_instance = 0, const glm::vec3& location = glm::vec3()); void SetStartZone(uint32 zoneid, float x = 0.0f, float y =0.0f, float z = 0.0f); uint32 GetStartZone(void); void MovePC(const char* zonename, float x, float y, float z, float heading, uint8 ignorerestrictions = 0, ZoneMode zm = ZoneSolicited); diff --git a/zone/lua_client.cpp b/zone/lua_client.cpp index d77b83c9f..3db1eabea 100644 --- a/zone/lua_client.cpp +++ b/zone/lua_client.cpp @@ -232,27 +232,27 @@ void Lua_Client::SetBindPoint() { void Lua_Client::SetBindPoint(int to_zone) { Lua_Safe_Call_Void(); - self->SetBindPoint(to_zone); + self->SetBindPoint(0, to_zone); } void Lua_Client::SetBindPoint(int to_zone, int to_instance) { Lua_Safe_Call_Void(); - self->SetBindPoint(to_zone, to_instance); + self->SetBindPoint(0, to_zone, to_instance); } void Lua_Client::SetBindPoint(int to_zone, int to_instance, float new_x) { Lua_Safe_Call_Void(); - self->SetBindPoint(to_zone, to_instance, glm::vec3(new_x,0.0f,0.0f)); + self->SetBindPoint(0, to_zone, to_instance, glm::vec3(new_x,0.0f,0.0f)); } void Lua_Client::SetBindPoint(int to_zone, int to_instance, float new_x, float new_y) { Lua_Safe_Call_Void(); - self->SetBindPoint(to_zone, to_instance, glm::vec3(new_x, new_y, 0.0f)); + self->SetBindPoint(0, to_zone, to_instance, glm::vec3(new_x, new_y, 0.0f)); } void Lua_Client::SetBindPoint(int to_zone, int to_instance, float new_x, float new_y, float new_z) { Lua_Safe_Call_Void(); - self->SetBindPoint(to_zone, to_instance, glm::vec3(new_x, new_y, new_z)); + self->SetBindPoint(0, to_zone, to_instance, glm::vec3(new_x, new_y, new_z)); } float Lua_Client::GetBindX() { diff --git a/zone/mob.h b/zone/mob.h index 554634006..11c11573f 100644 --- a/zone/mob.h +++ b/zone/mob.h @@ -468,7 +468,7 @@ public: inline bool IsMoving() const { return moving; } virtual void SetMoving(bool move) { moving = move; m_Delta = glm::vec4(); } virtual void GoToBind(uint8 bindnum = 0) { } - virtual void Gate(); + virtual void Gate(uint8 bindnum = 0); int GetWalkspeed() const { return(_GetWalkSpeed()); } int GetRunspeed() const { return(_GetRunSpeed()); } void SetCurrentSpeed(int in); diff --git a/zone/npc.h b/zone/npc.h index 327918c19..fe658aab2 100644 --- a/zone/npc.h +++ b/zone/npc.h @@ -165,7 +165,7 @@ public: virtual FACTION_VALUE GetReverseFactionCon(Mob* iOther); void GoToBind(uint8 bindnum = 0) { GMMove(m_SpawnPoint.x, m_SpawnPoint.y, m_SpawnPoint.z, m_SpawnPoint.w); } - void Gate(); + void Gate(uint8 bindnum = 0); void GetPetState(SpellBuff_Struct *buffs, uint32 *items, char *name); void SetPetState(SpellBuff_Struct *buffs, uint32 *items); diff --git a/zone/perl_client.cpp b/zone/perl_client.cpp index d4c5f34d0..9c51b8a92 100644 --- a/zone/perl_client.cpp +++ b/zone/perl_client.cpp @@ -1072,7 +1072,7 @@ XS(XS_Client_SetBindPoint) new_z = (float)SvNV(ST(5)); } - THIS->SetBindPoint(to_zone, to_instance, glm::vec3(new_x, new_y, new_z)); + THIS->SetBindPoint(0, to_zone, to_instance, glm::vec3(new_x, new_y, new_z)); } XSRETURN_EMPTY; } diff --git a/zone/questmgr.cpp b/zone/questmgr.cpp index fa8788bbf..b16613e75 100644 --- a/zone/questmgr.cpp +++ b/zone/questmgr.cpp @@ -1565,7 +1565,7 @@ void QuestManager::ding() { void QuestManager::rebind(int zoneid, const glm::vec3& location) { QuestManagerCurrentQuestVars(); if(initiator && initiator->IsClient()) { - initiator->SetBindPoint(zoneid, 0, location); + initiator->SetBindPoint(0, zoneid, 0, location); } } diff --git a/zone/spell_effects.cpp b/zone/spell_effects.cpp index d5006a52b..ca10259a1 100644 --- a/zone/spell_effects.cpp +++ b/zone/spell_effects.cpp @@ -499,7 +499,7 @@ bool Mob::SpellEffect(Mob* caster, uint16 spell_id, float partial, int level_ove break; } - case SE_GateCastersBindpoint: //Shin: Used on Teleport Bind. + case SE_GateCastersBindpoint: // Used on Teleport Bind. case SE_Teleport: // gates, rings, circles, etc case SE_Teleport2: { @@ -532,13 +532,16 @@ bool Mob::SpellEffect(Mob* caster, uint16 spell_id, float partial, int level_ove } if (effect == SE_GateCastersBindpoint && caster->IsClient()) - { //Shin: Teleport Bind uses caster's bind point - x = caster->CastToClient()->GetBindX(); - y = caster->CastToClient()->GetBindY(); - z = caster->CastToClient()->GetBindZ(); - heading = caster->CastToClient()->GetBindHeading(); + { // Teleport Bind uses caster's bind point + int index = spells[spell_id].base[i] - 1; + if (index < 0 || index > 4) + index = 0; + x = caster->CastToClient()->GetBindX(index); + y = caster->CastToClient()->GetBindY(index); + z = caster->CastToClient()->GetBindZ(index); + heading = caster->CastToClient()->GetBindHeading(index); //target_zone = caster->CastToClient()->GetBindZoneId(); target_zone doesn't work due to const char - CastToClient()->MovePC(caster->CastToClient()->GetBindZoneID(), 0, x, y, z, heading); + CastToClient()->MovePC(caster->CastToClient()->GetBindZoneID(index), 0, x, y, z, heading); break; } @@ -917,7 +920,7 @@ bool Mob::SpellEffect(Mob* caster, uint16 spell_id, float partial, int level_ove if(caster->IsClient() && caster != this) caster->CastToClient()->QueuePacket(message_packet); - CastToClient()->SetBindPoint(); + CastToClient()->SetBindPoint(spells[spell_id].base[i] - 1); Save(); safe_delete(action_packet); safe_delete(message_packet); @@ -966,7 +969,7 @@ bool Mob::SpellEffect(Mob* caster, uint16 spell_id, float partial, int level_ove if(caster->IsClient() && caster != this) caster->CastToClient()->QueuePacket(message_packet); - CastToClient()->SetBindPoint(); + CastToClient()->SetBindPoint(spells[spell_id].base[i] - 1); Save(); safe_delete(action_packet); safe_delete(message_packet); @@ -1002,7 +1005,7 @@ bool Mob::SpellEffect(Mob* caster, uint16 spell_id, float partial, int level_ove if(caster->IsClient() && caster != this) caster->CastToClient()->QueuePacket(message_packet); - CastToClient()->SetBindPoint(); + CastToClient()->SetBindPoint(spells[spell_id].base[i] - 1); Save(); safe_delete(action_packet); safe_delete(message_packet); @@ -1012,7 +1015,7 @@ bool Mob::SpellEffect(Mob* caster, uint16 spell_id, float partial, int level_ove break; } - case SE_Gate: //TO DO: Add support for secondary and tertiary gate abilities (base2) + case SE_Gate: { #ifdef SPELL_EFFECT_SPAM snprintf(effect_desc, _EDLEN, "Gate"); @@ -1020,7 +1023,7 @@ bool Mob::SpellEffect(Mob* caster, uint16 spell_id, float partial, int level_ove if(!spellbonuses.AntiGate){ if(zone->random.Roll(effect_value)) - Gate(); + Gate(spells[spell_id].base2[i] - 1); else caster->Message_StringID(MT_SpellFailure,GATE_FAIL); } diff --git a/zone/zonedb.cpp b/zone/zonedb.cpp index 591f8c3d3..e90e64af5 100644 --- a/zone/zonedb.cpp +++ b/zone/zonedb.cpp @@ -1260,30 +1260,27 @@ bool ZoneDatabase::LoadCharacterPotions(uint32 character_id, PlayerProfile_Struc return true; } -bool ZoneDatabase::LoadCharacterBindPoint(uint32 character_id, PlayerProfile_Struct* pp){ - std::string query = StringFormat("SELECT `zone_id`, `instance_id`, `x`, `y`, `z`, `heading`, `is_home` FROM `character_bind` WHERE `id` = %u LIMIT 2", character_id); +bool ZoneDatabase::LoadCharacterBindPoint(uint32 character_id, PlayerProfile_Struct *pp) +{ + std::string query = StringFormat("SELECT `slot`, `zone_id`, `instance_id`, `x`, `y`, `z`, `heading` FROM " + "`character_bind` WHERE `id` = %u LIMIT 5", + character_id); auto results = database.QueryDatabase(query); + if (!results.RowCount()) // SHIT -- this actually isn't good + return true; + for (auto row = results.begin(); row != results.end(); ++row) { - - /* Is home bind */ - if (atoi(row[6]) == 1){ - pp->binds[4].zoneId = atoi(row[0]); - pp->binds[4].instance_id = atoi(row[1]); - pp->binds[4].x = atoi(row[2]); - pp->binds[4].y = atoi(row[3]); - pp->binds[4].z = atoi(row[4]); - pp->binds[4].heading = atoi(row[5]); + int index = atoi(row[0]); + if (index < 0 || index > 4) continue; - } - /* Is regular bind point */ - pp->binds[0].zoneId = atoi(row[0]); - pp->binds[0].instance_id = atoi(row[1]); - pp->binds[0].x = atoi(row[2]); - pp->binds[0].y = atoi(row[3]); - pp->binds[0].z = atoi(row[4]); - pp->binds[0].heading = atoi(row[5]); + pp->binds[index].zoneId = atoi(row[1]); + pp->binds[index].instance_id = atoi(row[2]); + pp->binds[index].x = atoi(row[3]); + pp->binds[index].y = atoi(row[4]); + pp->binds[index].z = atoi(row[5]); + pp->binds[index].heading = atoi(row[6]); } return true; @@ -1295,19 +1292,23 @@ bool ZoneDatabase::SaveCharacterLanguage(uint32 character_id, uint32 lang_id, ui return true; } -bool ZoneDatabase::SaveCharacterBindPoint(uint32 character_id, uint32 zone_id, uint32 instance_id, const glm::vec4& position, uint8 is_home){ - if (zone_id <= 0) { - return false; - } - +bool ZoneDatabase::SaveCharacterBindPoint(uint32 character_id, const BindStruct &bind, uint32 bind_num) +{ /* Save Home Bind Point */ - std::string query = StringFormat("REPLACE INTO `character_bind` (id, zone_id, instance_id, x, y, z, heading, is_home)" - " VALUES (%u, %u, %u, %f, %f, %f, %f, %i)", character_id, zone_id, instance_id, position.x, position.y, position.z, position.w, is_home); - Log.Out(Logs::General, Logs::None, "ZoneDatabase::SaveCharacterBindPoint for character ID: %i zone_id: %u instance_id: %u position: %s ishome: %u", character_id, zone_id, instance_id, to_string(position).c_str(), is_home); + std::string query = + StringFormat("REPLACE INTO `character_bind` (id, zone_id, instance_id, x, y, z, heading, slot) VALUES (%u, " + "%u, %u, %f, %f, %f, %f, %i)", + character_id, bind.zoneId, bind.instance_id, bind.x, bind.y, bind.z, bind.heading, bind_num); + + Log.Out(Logs::General, Logs::None, "ZoneDatabase::SaveCharacterBindPoint for character ID: %i zone_id: %u " + "instance_id: %u position: %f %f %f %f bind_num: %u", + character_id, bind.zoneId, bind.instance_id, bind.x, bind.y, bind.z, bind.heading, bind_num); + auto results = QueryDatabase(query); - if (!results.RowsAffected()) { - Log.Out(Logs::General, Logs::None, "ERROR Bind Home Save: %s. %s", results.ErrorMessage().c_str(), query.c_str()); - } + if (!results.RowsAffected()) + Log.Out(Logs::General, Logs::None, "ERROR Bind Home Save: %s. %s", results.ErrorMessage().c_str(), + query.c_str()); + return true; } diff --git a/zone/zonedb.h b/zone/zonedb.h index c4d26792d..b5e1d3509 100644 --- a/zone/zonedb.h +++ b/zone/zonedb.h @@ -277,7 +277,7 @@ public: bool LoadCharacterLeadershipAA(uint32 character_id, PlayerProfile_Struct* pp); /* Character Data Saves */ - bool SaveCharacterBindPoint(uint32 character_id, uint32 zone_id, uint32 instance_id, const glm::vec4& position, uint8 is_home); + bool SaveCharacterBindPoint(uint32 character_id, const BindStruct &bind, uint32 bind_num); bool SaveCharacterCurrency(uint32 character_id, PlayerProfile_Struct* pp); bool SaveCharacterData(uint32 character_id, uint32 account_id, PlayerProfile_Struct* pp, ExtendedProfile_Struct* m_epp); bool SaveCharacterAA(uint32 character_id, uint32 aa_id, uint32 current_level, uint32 charges); diff --git a/zone/zoning.cpp b/zone/zoning.cpp index 5b60448ec..9c7ae87a4 100644 --- a/zone/zoning.cpp +++ b/zone/zoning.cpp @@ -707,37 +707,40 @@ void Client::GoToSafeCoords(uint16 zone_id, uint16 instance_id) { } -void Mob::Gate() { - GoToBind(); +void Mob::Gate(uint8 bindnum) { + GoToBind(bindnum); } -void Client::Gate() { - Mob::Gate(); +void Client::Gate(uint8 bindnum) { + Mob::Gate(bindnum); } -void NPC::Gate() { +void NPC::Gate(uint8 bindnum) { entity_list.MessageClose_StringID(this, true, 200, MT_Spells, GATES, GetCleanName()); - Mob::Gate(); + Mob::Gate(bindnum); } -void Client::SetBindPoint(int to_zone, int to_instance, const glm::vec3& location) { +void Client::SetBindPoint(int bind_num, int to_zone, int to_instance, const glm::vec3 &location) +{ + if (bind_num < 0 || bind_num >= 4) + bind_num = 0; + if (to_zone == -1) { - m_pp.binds[0].zoneId = zone->GetZoneID(); - m_pp.binds[0].instance_id = (zone->GetInstanceID() != 0 && zone->IsInstancePersistent()) ? zone->GetInstanceID() : 0; - m_pp.binds[0].x = m_Position.x; - m_pp.binds[0].y = m_Position.y; - m_pp.binds[0].z = m_Position.z; + m_pp.binds[bind_num].zoneId = zone->GetZoneID(); + m_pp.binds[bind_num].instance_id = + (zone->GetInstanceID() != 0 && zone->IsInstancePersistent()) ? zone->GetInstanceID() : 0; + m_pp.binds[bind_num].x = m_Position.x; + m_pp.binds[bind_num].y = m_Position.y; + m_pp.binds[bind_num].z = m_Position.z; + } else { + m_pp.binds[bind_num].zoneId = to_zone; + m_pp.binds[bind_num].instance_id = to_instance; + m_pp.binds[bind_num].x = location.x; + m_pp.binds[bind_num].y = location.y; + m_pp.binds[bind_num].z = location.z; } - else { - m_pp.binds[0].zoneId = to_zone; - m_pp.binds[0].instance_id = to_instance; - m_pp.binds[0].x = location.x; - m_pp.binds[0].y = location.y; - m_pp.binds[0].z = location.z; - } - auto regularBindPoint = glm::vec4(m_pp.binds[0].x, m_pp.binds[0].y, m_pp.binds[0].z, 0.0f); - database.SaveCharacterBindPoint(this->CharacterID(), m_pp.binds[0].zoneId, m_pp.binds[0].instance_id, regularBindPoint, 0); + database.SaveCharacterBindPoint(this->CharacterID(), m_pp.binds[bind_num], bind_num); } void Client::GoToBind(uint8 bindnum) { From 6382ec2cb883c19fa83c82ec63089b9d3afea2f2 Mon Sep 17 00:00:00 2001 From: Russell Kinasz Date: Sun, 6 Mar 2016 18:36:57 -0800 Subject: [PATCH 50/56] Prevent crash in spell casting when raid doesn't exist --- zone/spells.cpp | 20 ++++++++++++++++---- 1 file changed, 16 insertions(+), 4 deletions(-) diff --git a/zone/spells.cpp b/zone/spells.cpp index 45c52a48b..061b2fd38 100644 --- a/zone/spells.cpp +++ b/zone/spells.cpp @@ -1732,7 +1732,10 @@ bool Mob::DetermineSpellTargets(uint16 spell_id, Mob *&spell_target, Mob *&ae_ce } else if(IsRaidGrouped()) { - group_id_caster = (GetRaid()->GetGroup(CastToClient()) == 0xFFFF) ? 0 : (GetRaid()->GetGroup(CastToClient()) + 1); + if (Raid* raid = GetRaid()) { + uint32 group_id = raid->GetGroup(CastToClient()); + group_id_caster = (group_id == 0xFFFFFFFF) ? 0 : (group_id + 1); + } } } else if(IsPet()) @@ -1744,7 +1747,10 @@ bool Mob::DetermineSpellTargets(uint16 spell_id, Mob *&spell_target, Mob *&ae_ce } else if(owner->IsRaidGrouped()) { - group_id_caster = (owner->GetRaid()->GetGroup(CastToClient()) == 0xFFFF) ? 0 : (owner->GetRaid()->GetGroup(CastToClient()) + 1); + if (Raid* raid = owner->GetRaid()) { + uint32 group_id = raid->GetGroup(owner->CastToClient()); + group_id_caster = (group_id == 0xFFFFFFFF) ? 0 : (group_id + 1); + } } } #ifdef BOTS @@ -1770,7 +1776,10 @@ bool Mob::DetermineSpellTargets(uint16 spell_id, Mob *&spell_target, Mob *&ae_ce } else if(spell_target->IsRaidGrouped()) { - group_id_target = (spell_target->GetRaid()->GetGroup(CastToClient()) == 0xFFFF) ? 0 : (spell_target->GetRaid()->GetGroup(CastToClient()) + 1); + if (Raid* raid = spell_target->GetRaid()) { + uint32 group_id = raid->GetGroup(spell_target->CastToClient()); + group_id_target = (group_id == 0xFFFFFFFF) ? 0 : (group_id + 1); + } } } else if(spell_target->IsPet()) @@ -1782,7 +1791,10 @@ bool Mob::DetermineSpellTargets(uint16 spell_id, Mob *&spell_target, Mob *&ae_ce } else if(owner->IsRaidGrouped()) { - group_id_target = (owner->GetRaid()->GetGroup(CastToClient()) == 0xFFFF) ? 0 : (owner->GetRaid()->GetGroup(CastToClient()) + 1); + if (Raid* raid = owner->GetRaid()) { + uint32 group_id = raid->GetGroup(owner->CastToClient()); + group_id_target = (group_id == 0xFFFFFFFF) ? 0 : (group_id + 1); + } } } #ifdef BOTS From 9291318a854e8be3a314a8233e69c90d0d3ee5e7 Mon Sep 17 00:00:00 2001 From: Russell Kinasz Date: Sun, 6 Mar 2016 19:35:21 -0800 Subject: [PATCH 51/56] Fix formatting in last commit --- zone/spells.cpp | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/zone/spells.cpp b/zone/spells.cpp index 061b2fd38..90efd791f 100644 --- a/zone/spells.cpp +++ b/zone/spells.cpp @@ -1734,7 +1734,7 @@ bool Mob::DetermineSpellTargets(uint16 spell_id, Mob *&spell_target, Mob *&ae_ce { if (Raid* raid = GetRaid()) { uint32 group_id = raid->GetGroup(CastToClient()); - group_id_caster = (group_id == 0xFFFFFFFF) ? 0 : (group_id + 1); + group_id_caster = (group_id == 0xFFFFFFFF) ? 0 : (group_id + 1); } } } @@ -1749,7 +1749,7 @@ bool Mob::DetermineSpellTargets(uint16 spell_id, Mob *&spell_target, Mob *&ae_ce { if (Raid* raid = owner->GetRaid()) { uint32 group_id = raid->GetGroup(owner->CastToClient()); - group_id_caster = (group_id == 0xFFFFFFFF) ? 0 : (group_id + 1); + group_id_caster = (group_id == 0xFFFFFFFF) ? 0 : (group_id + 1); } } } @@ -1778,7 +1778,7 @@ bool Mob::DetermineSpellTargets(uint16 spell_id, Mob *&spell_target, Mob *&ae_ce { if (Raid* raid = spell_target->GetRaid()) { uint32 group_id = raid->GetGroup(spell_target->CastToClient()); - group_id_target = (group_id == 0xFFFFFFFF) ? 0 : (group_id + 1); + group_id_target = (group_id == 0xFFFFFFFF) ? 0 : (group_id + 1); } } } @@ -1793,7 +1793,7 @@ bool Mob::DetermineSpellTargets(uint16 spell_id, Mob *&spell_target, Mob *&ae_ce { if (Raid* raid = owner->GetRaid()) { uint32 group_id = raid->GetGroup(owner->CastToClient()); - group_id_target = (group_id == 0xFFFFFFFF) ? 0 : (group_id + 1); + group_id_target = (group_id == 0xFFFFFFFF) ? 0 : (group_id + 1); } } } From e2e1298523034f9231e869f0a04b416281ce584e Mon Sep 17 00:00:00 2001 From: Uleat Date: Tue, 8 Mar 2016 16:25:05 -0500 Subject: [PATCH 52/56] Removed all bot command spell scripts but 'template' query --- .../bind_affinity_spells.sql | 78 ------- .../charm_spells.sql | 73 ------ .../bot_command_spell_scripts/cure_spells.sql | 193 --------------- .../depart_spells.sql | 61 ----- .../escape_spells.sql | 45 ---- .../bot_command_spell_scripts/grow_spells.sql | 39 ---- .../invisibility_spells.sql | 151 ------------ .../levitation_spells.sql | 94 -------- .../bot_command_spell_scripts/lull_spells.sql | 86 ------- .../mesmerize_spells.sql | 76 ------ .../movement_speed_spells.sql | 74 ------ .../resistance_spells.sql | 221 ------------------ .../resurrect_spells.sql | 71 ------ .../bot_command_spell_scripts/rune_spells.sql | 40 ---- .../shrink_spells.sql | 49 ---- .../water_breathing_spells.sql | 84 ------- 16 files changed, 1435 deletions(-) delete mode 100644 utils/scripts/bot_command_spell_scripts/bind_affinity_spells.sql delete mode 100644 utils/scripts/bot_command_spell_scripts/charm_spells.sql delete mode 100644 utils/scripts/bot_command_spell_scripts/cure_spells.sql delete mode 100644 utils/scripts/bot_command_spell_scripts/depart_spells.sql delete mode 100644 utils/scripts/bot_command_spell_scripts/escape_spells.sql delete mode 100644 utils/scripts/bot_command_spell_scripts/grow_spells.sql delete mode 100644 utils/scripts/bot_command_spell_scripts/invisibility_spells.sql delete mode 100644 utils/scripts/bot_command_spell_scripts/levitation_spells.sql delete mode 100644 utils/scripts/bot_command_spell_scripts/lull_spells.sql delete mode 100644 utils/scripts/bot_command_spell_scripts/mesmerize_spells.sql delete mode 100644 utils/scripts/bot_command_spell_scripts/movement_speed_spells.sql delete mode 100644 utils/scripts/bot_command_spell_scripts/resistance_spells.sql delete mode 100644 utils/scripts/bot_command_spell_scripts/resurrect_spells.sql delete mode 100644 utils/scripts/bot_command_spell_scripts/rune_spells.sql delete mode 100644 utils/scripts/bot_command_spell_scripts/shrink_spells.sql delete mode 100644 utils/scripts/bot_command_spell_scripts/water_breathing_spells.sql diff --git a/utils/scripts/bot_command_spell_scripts/bind_affinity_spells.sql b/utils/scripts/bot_command_spell_scripts/bind_affinity_spells.sql deleted file mode 100644 index a48b3318b..000000000 --- a/utils/scripts/bot_command_spell_scripts/bind_affinity_spells.sql +++ /dev/null @@ -1,78 +0,0 @@ -SELECT --- base - CASE - WHEN `targettype` = '5' AND `CastRestriction` = '0' THEN 'Single' - ELSE CONCAT(`targettype`, ', ', `CastRestriction`) -- 'UNDEFINED' - END target_type, - CASE - WHEN `zonetype` NOT IN ('-1', '0') THEN `zonetype` - ELSE '0' - END zone_type, - caster_class, - spell_level, - `id` spell_id, - CONCAT('"', `name`, '"') spell_name, - `mana` mana_cost --- base - -FROM ( - SELECT 'CLERIC' caster_class, `classes2` spell_level, - `targettype`, `CastRestriction`, `zonetype`, `id`, `name`, `mana` - FROM `spells_new` - WHERE `classes2` NOT IN ('254', '255') - AND `SpellAffectIndex` = '14' - AND '25' IN (`effectid1`, `effectid2`, `effectid3`, `effectid4`, `effectid5`, `effectid6`, `effectid7`, `effectid8`, `effectid9`, `effectid10`, `effectid11`, `effectid12`) -UNION ALL - SELECT 'DRUID' caster_class, `classes6` spell_level, - `targettype`, `CastRestriction`, `zonetype`, `id`, `name`, `mana` - FROM `spells_new` - WHERE `classes6` NOT IN ('254', '255') - AND `SpellAffectIndex` = '14' - AND '25' IN (`effectid1`, `effectid2`, `effectid3`, `effectid4`, `effectid5`, `effectid6`, `effectid7`, `effectid8`, `effectid9`, `effectid10`, `effectid11`, `effectid12`) -UNION ALL - SELECT 'SHAMAN' caster_class, `classes10` spell_level, - `targettype`, `CastRestriction`, `zonetype`, `id`, `name`, `mana` - FROM `spells_new` - WHERE `classes10` NOT IN ('254', '255') - AND `SpellAffectIndex` = '14' - AND '25' IN (`effectid1`, `effectid2`, `effectid3`, `effectid4`, `effectid5`, `effectid6`, `effectid7`, `effectid8`, `effectid9`, `effectid10`, `effectid11`, `effectid12`) -UNION ALL - SELECT 'NECROMANCER' caster_class, `classes11` spell_level, - `targettype`, `CastRestriction`, `zonetype`, `id`, `name`, `mana` - FROM `spells_new` - WHERE `classes11` NOT IN ('254', '255') - AND `SpellAffectIndex` = '14' - AND '25' IN (`effectid1`, `effectid2`, `effectid3`, `effectid4`, `effectid5`, `effectid6`, `effectid7`, `effectid8`, `effectid9`, `effectid10`, `effectid11`, `effectid12`) -UNION ALL - SELECT 'WIZARD' caster_class, `classes12` spell_level, - `targettype`, `CastRestriction`, `zonetype`, `id`, `name`, `mana` - FROM `spells_new` - WHERE `classes12` NOT IN ('254', '255') - AND `SpellAffectIndex` = '14' - AND '25' IN (`effectid1`, `effectid2`, `effectid3`, `effectid4`, `effectid5`, `effectid6`, `effectid7`, `effectid8`, `effectid9`, `effectid10`, `effectid11`, `effectid12`) -UNION ALL - SELECT 'MAGICIAN' caster_class, `classes13` spell_level, - `targettype`, `CastRestriction`, `zonetype`, `id`, `name`, `mana` - FROM `spells_new` - WHERE `classes13` NOT IN ('254', '255') - AND `SpellAffectIndex` = '14' - AND '25' IN (`effectid1`, `effectid2`, `effectid3`, `effectid4`, `effectid5`, `effectid6`, `effectid7`, `effectid8`, `effectid9`, `effectid10`, `effectid11`, `effectid12`) -UNION ALL - SELECT 'ENCHANTER' caster_class, `classes14` spell_level, - `targettype`, `CastRestriction`, `zonetype`, `id`, `name`, `mana` - FROM `spells_new` - WHERE `classes14` NOT IN ('254', '255') - AND `SpellAffectIndex` = '14' - AND '25' IN (`effectid1`, `effectid2`, `effectid3`, `effectid4`, `effectid5`, `effectid6`, `effectid7`, `effectid8`, `effectid9`, `effectid10`, `effectid11`, `effectid12`) -) spells - --- WHERE `name` NOT LIKE '%II' --- --- --- WHERE `name` NOT LIKE '%Rk. II%' --- AND `name` NOT LIKE '%Rk.II%' --- AND `name` NOT LIKE '%Rk. III%' --- AND `name` NOT LIKE '%Rk.III%' -ORDER BY mana_cost DESC, - FIELD(target_type, 'Single'), - spell_level, - FIELD(caster_class, 'CLERIC', 'DRUID', 'SHAMAN', 'NECROMANCER', 'WIZARD', 'MAGICIAN', 'ENCHANTER') diff --git a/utils/scripts/bot_command_spell_scripts/charm_spells.sql b/utils/scripts/bot_command_spell_scripts/charm_spells.sql deleted file mode 100644 index f2c5e82b8..000000000 --- a/utils/scripts/bot_command_spell_scripts/charm_spells.sql +++ /dev/null @@ -1,73 +0,0 @@ -SELECT --- base - CASE - WHEN `targettype` = '5' AND `CastRestriction` = '0' THEN 'Single' - WHEN `targettype` = '9' AND `CastRestriction` = '0' THEN 'Animal' - WHEN `targettype` = '10' AND `CastRestriction` = '0' THEN 'Undead' - WHEN `targettype` = '11' AND `CastRestriction` = '0' THEN 'Summoned' - WHEN `targettype` = '16' AND `CastRestriction` = '0' THEN 'Plant' - ELSE CONCAT(`targettype`, ', ', `CastRestriction`) -- 'UNDEFINED' - END target_type, - CASE - WHEN `zonetype` NOT IN ('-1', '0') THEN `zonetype` - ELSE '0' - END zone_type, - caster_class, - spell_level, - `id` spell_id, - CONCAT('"', `name`, '"') spell_name, - `mana` mana_cost, --- base --- extra - `ResistDiff` resist_diff, - `max1` max_target_level --- extra - -FROM ( - SELECT 'DRUID' caster_class, `classes6` spell_level, - `targettype`, `CastRestriction`, `zonetype`, `id`, `name`, `mana`, `ResistDiff`, `max1` - FROM `spells_new` - WHERE `classes6` NOT IN ('254', '255') - AND `SpellAffectIndex` = '12' - AND '22' IN (`effectid1`, `effectid2`, `effectid3`, `effectid4`, `effectid5`, `effectid6`, `effectid7`, `effectid8`, `effectid9`, `effectid10`, `effectid11`, `effectid12`) -UNION ALL - SELECT 'SHAMAN' caster_class, `classes10` spell_level, - `targettype`, `CastRestriction`, `zonetype`, `id`, `name`, `mana`, `ResistDiff`, `max1` - FROM `spells_new` - WHERE `classes10` NOT IN ('254', '255') - AND `SpellAffectIndex` = '12' - AND '22' IN (`effectid1`, `effectid2`, `effectid3`, `effectid4`, `effectid5`, `effectid6`, `effectid7`, `effectid8`, `effectid9`, `effectid10`, `effectid11`, `effectid12`) -UNION ALL - SELECT 'NECROMANCER' caster_class, `classes11` spell_level, - `targettype`, `CastRestriction`, `zonetype`, `id`, `name`, `mana`, `ResistDiff`, `max1` - FROM `spells_new` - WHERE `classes11` NOT IN ('254', '255') - AND `SpellAffectIndex` = '12' - AND '22' IN (`effectid1`, `effectid2`, `effectid3`, `effectid4`, `effectid5`, `effectid6`, `effectid7`, `effectid8`, `effectid9`, `effectid10`, `effectid11`, `effectid12`) -UNION ALL - SELECT 'MAGICIAN' caster_class, `classes13` spell_level, - `targettype`, `CastRestriction`, `zonetype`, `id`, `name`, `mana`, `ResistDiff`, `max1` - FROM `spells_new` - WHERE `classes13` NOT IN ('254', '255') - AND `SpellAffectIndex` = '12' - AND '22' IN (`effectid1`, `effectid2`, `effectid3`, `effectid4`, `effectid5`, `effectid6`, `effectid7`, `effectid8`, `effectid9`, `effectid10`, `effectid11`, `effectid12`) -UNION ALL - SELECT 'ENCHANTER' caster_class, `classes14` spell_level, - `targettype`, `CastRestriction`, `zonetype`, `id`, `name`, `mana`, `ResistDiff`, `max1` - FROM `spells_new` - WHERE `classes14` NOT IN ('254', '255') - AND `SpellAffectIndex` = '12' - AND '22' IN (`effectid1`, `effectid2`, `effectid3`, `effectid4`, `effectid5`, `effectid6`, `effectid7`, `effectid8`, `effectid9`, `effectid10`, `effectid11`, `effectid12`) -) spells - --- WHERE `name` NOT LIKE '%II' --- --- --- WHERE `name` NOT LIKE '%Rk. II%' --- AND `name` NOT LIKE '%Rk.II%' --- AND `name` NOT LIKE '%Rk. III%' --- AND `name` NOT LIKE '%Rk.III%' -ORDER BY resist_diff, - FIELD(target_type, 'Animal', 'Undead', 'Summoned', 'Plant', 'Single'), - max_target_level DESC, - spell_level, - FIELD(caster_class, 'DRUID', 'SHAMAN', 'NECROMANCER', 'MAGICIAN', 'ENCHANTER') diff --git a/utils/scripts/bot_command_spell_scripts/cure_spells.sql b/utils/scripts/bot_command_spell_scripts/cure_spells.sql deleted file mode 100644 index 75ef1d25c..000000000 --- a/utils/scripts/bot_command_spell_scripts/cure_spells.sql +++ /dev/null @@ -1,193 +0,0 @@ -SELECT --- base - CASE - WHEN `targettype` = '3' AND `CastRestriction` = '0' THEN 'GroupV1' - WHEN `targettype` = '5' AND `CastRestriction` = '0' THEN 'Single' - WHEN `targettype` = '41' AND `CastRestriction` = '0' THEN 'GroupV2' - ELSE CONCAT(`targettype`, ', ', `CastRestriction`) -- 'UNDEFINED' - END target_type, - CASE - WHEN `zonetype` NOT IN ('-1', '0') THEN `zonetype` - ELSE '0' - END zone_type, - caster_class, - spell_level, - `id` spell_id, - CONCAT('"', `name`, '"') spell_name, - `mana` mana_cost, --- base --- extra - ( - (IF(('20' IN (`effectid1`, `effectid2`, `effectid3`, `effectid4`, `effectid5`, `effectid6`, `effectid7`, `effectid8`, `effectid9`, `effectid10`, `effectid11`, `effectid12`)), '1', '0')) | - (IF(('35' IN (`effectid1`, `effectid2`, `effectid3`, `effectid4`, `effectid5`, `effectid6`, `effectid7`, `effectid8`, `effectid9`, `effectid10`, `effectid11`, `effectid12`)), '2', '0')) | - (IF(('36' IN (`effectid1`, `effectid2`, `effectid3`, `effectid4`, `effectid5`, `effectid6`, `effectid7`, `effectid8`, `effectid9`, `effectid10`, `effectid11`, `effectid12`)), '4', '0')) | - (IF(('116' IN (`effectid1`, `effectid2`, `effectid3`, `effectid4`, `effectid5`, `effectid6`, `effectid7`, `effectid8`, `effectid9`, `effectid10`, `effectid11`, `effectid12`)), '8', '0')) | - (IF(('369' IN (`effectid1`, `effectid2`, `effectid3`, `effectid4`, `effectid5`, `effectid6`, `effectid7`, `effectid8`, `effectid9`, `effectid10`, `effectid11`, `effectid12`)), '16', '0')) - ) cure_mask --- extra - -FROM ( - SELECT 'CLERIC' caster_class, `classes2` spell_level, - `targettype`, `CastRestriction`, `zonetype`, `id`, `name`, `mana`, - `effectid1`, `effectid2`, `effectid3`, `effectid4`, `effectid5`, `effectid6`, `effectid7`, `effectid8`, `effectid9`, `effectid10`, `effectid11`, `effectid12` - FROM `spells_new` - WHERE `classes2` NOT IN ('254', '255') - AND `SpellAffectIndex` = '1' --- 6-self, 10-undead, 14-pet, 45-ring - AND `targettype` NOT IN ('6', '10', '14', '45') - AND ( --- 20-blindness, 35-disease, 36-poison, 116-curse, 369-corruption - '20' IN (`effectid1`, `effectid2`, `effectid3`, `effectid4`, `effectid5`, `effectid6`, `effectid7`, `effectid8`, `effectid9`, `effectid10`, `effectid11`, `effectid12`) - OR '35' IN (`effectid1`, `effectid2`, `effectid3`, `effectid4`, `effectid5`, `effectid6`, `effectid7`, `effectid8`, `effectid9`, `effectid10`, `effectid11`, `effectid12`) - OR '36' IN (`effectid1`, `effectid2`, `effectid3`, `effectid4`, `effectid5`, `effectid6`, `effectid7`, `effectid8`, `effectid9`, `effectid10`, `effectid11`, `effectid12`) - OR '116' IN (`effectid1`, `effectid2`, `effectid3`, `effectid4`, `effectid5`, `effectid6`, `effectid7`, `effectid8`, `effectid9`, `effectid10`, `effectid11`, `effectid12`) - OR '369' IN (`effectid1`, `effectid2`, `effectid3`, `effectid4`, `effectid5`, `effectid6`, `effectid7`, `effectid8`, `effectid9`, `effectid10`, `effectid11`, `effectid12`) - ) -UNION ALL - SELECT 'PALADIN' caster_class, `classes3` spell_level, - `targettype`, `CastRestriction`, `zonetype`, `id`, `name`, `mana`, - `effectid1`, `effectid2`, `effectid3`, `effectid4`, `effectid5`, `effectid6`, `effectid7`, `effectid8`, `effectid9`, `effectid10`, `effectid11`, `effectid12` - FROM `spells_new` - WHERE `classes3` NOT IN ('254', '255') - AND `SpellAffectIndex` = '1' --- 6-self, 10-undead, 14-pet, 45-ring - AND `targettype` NOT IN ('6', '10', '14', '45') - AND ( --- 20-blindness, 35-disease, 36-poison, 116-curse, 369-corruption - '20' IN (`effectid1`, `effectid2`, `effectid3`, `effectid4`, `effectid5`, `effectid6`, `effectid7`, `effectid8`, `effectid9`, `effectid10`, `effectid11`, `effectid12`) - OR '35' IN (`effectid1`, `effectid2`, `effectid3`, `effectid4`, `effectid5`, `effectid6`, `effectid7`, `effectid8`, `effectid9`, `effectid10`, `effectid11`, `effectid12`) - OR '36' IN (`effectid1`, `effectid2`, `effectid3`, `effectid4`, `effectid5`, `effectid6`, `effectid7`, `effectid8`, `effectid9`, `effectid10`, `effectid11`, `effectid12`) - OR '116' IN (`effectid1`, `effectid2`, `effectid3`, `effectid4`, `effectid5`, `effectid6`, `effectid7`, `effectid8`, `effectid9`, `effectid10`, `effectid11`, `effectid12`) - OR '369' IN (`effectid1`, `effectid2`, `effectid3`, `effectid4`, `effectid5`, `effectid6`, `effectid7`, `effectid8`, `effectid9`, `effectid10`, `effectid11`, `effectid12`) - ) -UNION ALL - SELECT 'RANGER' caster_class, `classes4` spell_level, - `targettype`, `CastRestriction`, `zonetype`, `id`, `name`, `mana`, - `effectid1`, `effectid2`, `effectid3`, `effectid4`, `effectid5`, `effectid6`, `effectid7`, `effectid8`, `effectid9`, `effectid10`, `effectid11`, `effectid12` - FROM `spells_new` - WHERE `classes4` NOT IN ('254', '255') - AND `SpellAffectIndex` = '1' --- 6-self, 10-undead, 14-pet, 45-ring - AND `targettype` NOT IN ('6', '10', '14', '45') - AND ( --- 20-blindness, 35-disease, 36-poison, 116-curse, 369-corruption - '20' IN (`effectid1`, `effectid2`, `effectid3`, `effectid4`, `effectid5`, `effectid6`, `effectid7`, `effectid8`, `effectid9`, `effectid10`, `effectid11`, `effectid12`) - OR '35' IN (`effectid1`, `effectid2`, `effectid3`, `effectid4`, `effectid5`, `effectid6`, `effectid7`, `effectid8`, `effectid9`, `effectid10`, `effectid11`, `effectid12`) - OR '36' IN (`effectid1`, `effectid2`, `effectid3`, `effectid4`, `effectid5`, `effectid6`, `effectid7`, `effectid8`, `effectid9`, `effectid10`, `effectid11`, `effectid12`) - OR '116' IN (`effectid1`, `effectid2`, `effectid3`, `effectid4`, `effectid5`, `effectid6`, `effectid7`, `effectid8`, `effectid9`, `effectid10`, `effectid11`, `effectid12`) - OR '369' IN (`effectid1`, `effectid2`, `effectid3`, `effectid4`, `effectid5`, `effectid6`, `effectid7`, `effectid8`, `effectid9`, `effectid10`, `effectid11`, `effectid12`) - ) -UNION ALL - SELECT 'SHADOWKNIGHT' caster_class, `classes5` spell_level, - `targettype`, `CastRestriction`, `zonetype`, `id`, `name`, `mana`, - `effectid1`, `effectid2`, `effectid3`, `effectid4`, `effectid5`, `effectid6`, `effectid7`, `effectid8`, `effectid9`, `effectid10`, `effectid11`, `effectid12` - FROM `spells_new` - WHERE `classes5` NOT IN ('254', '255') - AND `SpellAffectIndex` = '1' --- 6-self, 10-undead, 14-pet, 45-ring - AND `targettype` NOT IN ('6', '10', '14', '45') - AND ( --- 20-blindness, 35-disease, 36-poison, 116-curse, 369-corruption - '20' IN (`effectid1`, `effectid2`, `effectid3`, `effectid4`, `effectid5`, `effectid6`, `effectid7`, `effectid8`, `effectid9`, `effectid10`, `effectid11`, `effectid12`) - OR '35' IN (`effectid1`, `effectid2`, `effectid3`, `effectid4`, `effectid5`, `effectid6`, `effectid7`, `effectid8`, `effectid9`, `effectid10`, `effectid11`, `effectid12`) - OR '36' IN (`effectid1`, `effectid2`, `effectid3`, `effectid4`, `effectid5`, `effectid6`, `effectid7`, `effectid8`, `effectid9`, `effectid10`, `effectid11`, `effectid12`) - OR '116' IN (`effectid1`, `effectid2`, `effectid3`, `effectid4`, `effectid5`, `effectid6`, `effectid7`, `effectid8`, `effectid9`, `effectid10`, `effectid11`, `effectid12`) - OR '369' IN (`effectid1`, `effectid2`, `effectid3`, `effectid4`, `effectid5`, `effectid6`, `effectid7`, `effectid8`, `effectid9`, `effectid10`, `effectid11`, `effectid12`) - ) -UNION ALL - SELECT 'DRUID' caster_class, `classes6` spell_level, - `targettype`, `CastRestriction`, `zonetype`, `id`, `name`, `mana`, - `effectid1`, `effectid2`, `effectid3`, `effectid4`, `effectid5`, `effectid6`, `effectid7`, `effectid8`, `effectid9`, `effectid10`, `effectid11`, `effectid12` - FROM `spells_new` - WHERE `classes6` NOT IN ('254', '255') - AND `SpellAffectIndex` = '1' --- 6-self, 10-undead, 14-pet, 45-ring - AND `targettype` NOT IN ('6', '10', '14', '45') - AND ( --- 20-blindness, 35-disease, 36-poison, 116-curse, 369-corruption - '20' IN (`effectid1`, `effectid2`, `effectid3`, `effectid4`, `effectid5`, `effectid6`, `effectid7`, `effectid8`, `effectid9`, `effectid10`, `effectid11`, `effectid12`) - OR '35' IN (`effectid1`, `effectid2`, `effectid3`, `effectid4`, `effectid5`, `effectid6`, `effectid7`, `effectid8`, `effectid9`, `effectid10`, `effectid11`, `effectid12`) - OR '36' IN (`effectid1`, `effectid2`, `effectid3`, `effectid4`, `effectid5`, `effectid6`, `effectid7`, `effectid8`, `effectid9`, `effectid10`, `effectid11`, `effectid12`) - OR '116' IN (`effectid1`, `effectid2`, `effectid3`, `effectid4`, `effectid5`, `effectid6`, `effectid7`, `effectid8`, `effectid9`, `effectid10`, `effectid11`, `effectid12`) - OR '369' IN (`effectid1`, `effectid2`, `effectid3`, `effectid4`, `effectid5`, `effectid6`, `effectid7`, `effectid8`, `effectid9`, `effectid10`, `effectid11`, `effectid12`) - ) -UNION ALL - SELECT 'BARD' caster_class, `classes8` spell_level, - `targettype`, `CastRestriction`, `zonetype`, `id`, `name`, `mana`, - `effectid1`, `effectid2`, `effectid3`, `effectid4`, `effectid5`, `effectid6`, `effectid7`, `effectid8`, `effectid9`, `effectid10`, `effectid11`, `effectid12` - FROM `spells_new` - WHERE `classes8` NOT IN ('254', '255') - AND `SpellAffectIndex` = '1' --- 6-self, 10-undead, 14-pet, 45-ring - AND `targettype` NOT IN ('6', '10', '14', '45') - AND ( --- 20-blindness, 35-disease, 36-poison, 116-curse, 369-corruption - '20' IN (`effectid1`, `effectid2`, `effectid3`, `effectid4`, `effectid5`, `effectid6`, `effectid7`, `effectid8`, `effectid9`, `effectid10`, `effectid11`, `effectid12`) - OR '35' IN (`effectid1`, `effectid2`, `effectid3`, `effectid4`, `effectid5`, `effectid6`, `effectid7`, `effectid8`, `effectid9`, `effectid10`, `effectid11`, `effectid12`) - OR '36' IN (`effectid1`, `effectid2`, `effectid3`, `effectid4`, `effectid5`, `effectid6`, `effectid7`, `effectid8`, `effectid9`, `effectid10`, `effectid11`, `effectid12`) - OR '116' IN (`effectid1`, `effectid2`, `effectid3`, `effectid4`, `effectid5`, `effectid6`, `effectid7`, `effectid8`, `effectid9`, `effectid10`, `effectid11`, `effectid12`) - OR '369' IN (`effectid1`, `effectid2`, `effectid3`, `effectid4`, `effectid5`, `effectid6`, `effectid7`, `effectid8`, `effectid9`, `effectid10`, `effectid11`, `effectid12`) - ) -UNION ALL - SELECT 'SHAMAN' caster_class, `classes10` spell_level, - `targettype`, `CastRestriction`, `zonetype`, `id`, `name`, `mana`, - `effectid1`, `effectid2`, `effectid3`, `effectid4`, `effectid5`, `effectid6`, `effectid7`, `effectid8`, `effectid9`, `effectid10`, `effectid11`, `effectid12` - FROM `spells_new` - WHERE `classes10` NOT IN ('254', '255') - AND `SpellAffectIndex` = '1' --- 6-self, 10-undead, 14-pet, 45-ring - AND `targettype` NOT IN ('6', '10', '14', '45') - AND ( --- 20-blindness, 35-disease, 36-poison, 116-curse, 369-corruption - '20' IN (`effectid1`, `effectid2`, `effectid3`, `effectid4`, `effectid5`, `effectid6`, `effectid7`, `effectid8`, `effectid9`, `effectid10`, `effectid11`, `effectid12`) - OR '35' IN (`effectid1`, `effectid2`, `effectid3`, `effectid4`, `effectid5`, `effectid6`, `effectid7`, `effectid8`, `effectid9`, `effectid10`, `effectid11`, `effectid12`) - OR '36' IN (`effectid1`, `effectid2`, `effectid3`, `effectid4`, `effectid5`, `effectid6`, `effectid7`, `effectid8`, `effectid9`, `effectid10`, `effectid11`, `effectid12`) - OR '116' IN (`effectid1`, `effectid2`, `effectid3`, `effectid4`, `effectid5`, `effectid6`, `effectid7`, `effectid8`, `effectid9`, `effectid10`, `effectid11`, `effectid12`) - OR '369' IN (`effectid1`, `effectid2`, `effectid3`, `effectid4`, `effectid5`, `effectid6`, `effectid7`, `effectid8`, `effectid9`, `effectid10`, `effectid11`, `effectid12`) - ) -UNION ALL - SELECT 'NECROMANCER' caster_class, `classes11` spell_level, - `targettype`, `CastRestriction`, `zonetype`, `id`, `name`, `mana`, - `effectid1`, `effectid2`, `effectid3`, `effectid4`, `effectid5`, `effectid6`, `effectid7`, `effectid8`, `effectid9`, `effectid10`, `effectid11`, `effectid12` - FROM `spells_new` - WHERE `classes11` NOT IN ('254', '255') - AND `SpellAffectIndex` = '1' --- 6-self, 10-undead, 14-pet, 45-ring - AND `targettype` NOT IN ('6', '10', '14', '45') - AND ( --- 20-blindness, 35-disease, 36-poison, 116-curse, 369-corruption - '20' IN (`effectid1`, `effectid2`, `effectid3`, `effectid4`, `effectid5`, `effectid6`, `effectid7`, `effectid8`, `effectid9`, `effectid10`, `effectid11`, `effectid12`) - OR '35' IN (`effectid1`, `effectid2`, `effectid3`, `effectid4`, `effectid5`, `effectid6`, `effectid7`, `effectid8`, `effectid9`, `effectid10`, `effectid11`, `effectid12`) - OR '36' IN (`effectid1`, `effectid2`, `effectid3`, `effectid4`, `effectid5`, `effectid6`, `effectid7`, `effectid8`, `effectid9`, `effectid10`, `effectid11`, `effectid12`) - OR '116' IN (`effectid1`, `effectid2`, `effectid3`, `effectid4`, `effectid5`, `effectid6`, `effectid7`, `effectid8`, `effectid9`, `effectid10`, `effectid11`, `effectid12`) - OR '369' IN (`effectid1`, `effectid2`, `effectid3`, `effectid4`, `effectid5`, `effectid6`, `effectid7`, `effectid8`, `effectid9`, `effectid10`, `effectid11`, `effectid12`) - ) -UNION ALL - SELECT 'BEASTLORD' caster_class, `classes15` spell_level, - `targettype`, `CastRestriction`, `zonetype`, `id`, `name`, `mana`, - `effectid1`, `effectid2`, `effectid3`, `effectid4`, `effectid5`, `effectid6`, `effectid7`, `effectid8`, `effectid9`, `effectid10`, `effectid11`, `effectid12` - FROM `spells_new` - WHERE `classes15` NOT IN ('254', '255') - AND `SpellAffectIndex` = '1' --- 6-self, 10-undead, 14-pet, 45-ring - AND `targettype` NOT IN ('6', '10', '14', '45') - AND ( --- 20-blindness, 35-disease, 36-poison, 116-curse, 369-corruption - '20' IN (`effectid1`, `effectid2`, `effectid3`, `effectid4`, `effectid5`, `effectid6`, `effectid7`, `effectid8`, `effectid9`, `effectid10`, `effectid11`, `effectid12`) - OR '35' IN (`effectid1`, `effectid2`, `effectid3`, `effectid4`, `effectid5`, `effectid6`, `effectid7`, `effectid8`, `effectid9`, `effectid10`, `effectid11`, `effectid12`) - OR '36' IN (`effectid1`, `effectid2`, `effectid3`, `effectid4`, `effectid5`, `effectid6`, `effectid7`, `effectid8`, `effectid9`, `effectid10`, `effectid11`, `effectid12`) - OR '116' IN (`effectid1`, `effectid2`, `effectid3`, `effectid4`, `effectid5`, `effectid6`, `effectid7`, `effectid8`, `effectid9`, `effectid10`, `effectid11`, `effectid12`) - OR '369' IN (`effectid1`, `effectid2`, `effectid3`, `effectid4`, `effectid5`, `effectid6`, `effectid7`, `effectid8`, `effectid9`, `effectid10`, `effectid11`, `effectid12`) - ) -) spells - --- WHERE `name` NOT LIKE '%II' --- --- --- WHERE `name` NOT LIKE '%Rk. II%' --- AND `name` NOT LIKE '%Rk.II%' --- AND `name` NOT LIKE '%Rk. III%' --- AND `name` NOT LIKE '%Rk.III%' -ORDER BY FIELD(target_type, 'Single', 'GroupV1', 'GroupV2'), - spell_level DESC, - cure_mask DESC, - FIELD(caster_class, 'CLERIC', 'PALADIN', 'RANGER', 'SHADOWKNIGHT', 'DRUID', 'BARD', 'SHAMAN', 'NECROMANCER', 'BEASTLORD') diff --git a/utils/scripts/bot_command_spell_scripts/depart_spells.sql b/utils/scripts/bot_command_spell_scripts/depart_spells.sql deleted file mode 100644 index 205ba27f1..000000000 --- a/utils/scripts/bot_command_spell_scripts/depart_spells.sql +++ /dev/null @@ -1,61 +0,0 @@ -SELECT --- base - CASE - WHEN `targettype` = '3' AND `CastRestriction` = '0' THEN 'GroupV1' - ELSE CONCAT(`targettype`, ', ', `CastRestriction`) -- 'UNDEFINED' - END target_type, - CASE - WHEN `zonetype` NOT IN ('-1', '0') THEN `zonetype` - ELSE '0' - END zone_type, - caster_class, - spell_level, - `id` spell_id, - CONCAT('"', `name`, '"') spell_name, - `mana` mana_cost, --- base --- extra - CONCAT('"', `teleport_zone`, '"') short_name, - CONCAT('"', IFNULL((SELECT `long_name` FROM `zone` WHERE `short_name` = `teleport_zone` LIMIT 1), 'Unreachable Destination'), '"') long_name --- extra - -FROM ( - SELECT 'DRUID' caster_class, `classes6` spell_level, - `targettype`, `CastRestriction`, `zonetype`, `id`, `name`, `mana`, `teleport_zone` - FROM `spells_new` - WHERE `classes6` NOT IN ('254', '255') - AND `SpellAffectIndex` = '40' - AND ( - '83' IN (`effectid1`, `effectid2`, `effectid3`, `effectid4`, `effectid5`, `effectid6`, `effectid7`, `effectid8`, `effectid9`, `effectid10`, `effectid11`, `effectid12`) - OR '86' IN (`effectid1`, `effectid2`, `effectid3`, `effectid4`, `effectid5`, `effectid6`, `effectid7`, `effectid8`, `effectid9`, `effectid10`, `effectid11`, `effectid12`) - OR ( - '88' IN (`effectid1`, `effectid2`, `effectid3`, `effectid4`, `effectid5`, `effectid6`, `effectid7`, `effectid8`, `effectid9`, `effectid10`, `effectid11`, `effectid12`) - AND `teleport_zone` NOT LIKE 'same' - ) - ) -UNION ALL - SELECT 'WIZARD' caster_class, `classes12` spell_level, - `targettype`, `CastRestriction`, `zonetype`, `id`, `name`, `mana`, `teleport_zone` - FROM `spells_new` - WHERE `classes12` NOT IN ('254', '255') - AND `SpellAffectIndex` = '40' - AND ( - '83' IN (`effectid1`, `effectid2`, `effectid3`, `effectid4`, `effectid5`, `effectid6`, `effectid7`, `effectid8`, `effectid9`, `effectid10`, `effectid11`, `effectid12`) - OR '86' IN (`effectid1`, `effectid2`, `effectid3`, `effectid4`, `effectid5`, `effectid6`, `effectid7`, `effectid8`, `effectid9`, `effectid10`, `effectid11`, `effectid12`) - OR ( - '88' IN (`effectid1`, `effectid2`, `effectid3`, `effectid4`, `effectid5`, `effectid6`, `effectid7`, `effectid8`, `effectid9`, `effectid10`, `effectid11`, `effectid12`) - AND `teleport_zone` NOT LIKE 'same' - ) - ) -) spells - --- WHERE `name` NOT LIKE '%II' --- --- --- WHERE `name` NOT LIKE '%Rk. II%' --- AND `name` NOT LIKE '%Rk.II%' --- AND `name` NOT LIKE '%Rk. III%' --- AND `name` NOT LIKE '%Rk.III%' -ORDER BY FIELD(target_type, 'GroupV1'), - FIELD(caster_class, 'DRUID', 'WIZARD'), - spell_level, - spell_name diff --git a/utils/scripts/bot_command_spell_scripts/escape_spells.sql b/utils/scripts/bot_command_spell_scripts/escape_spells.sql deleted file mode 100644 index 4e08ddeb0..000000000 --- a/utils/scripts/bot_command_spell_scripts/escape_spells.sql +++ /dev/null @@ -1,45 +0,0 @@ -SELECT --- base - CASE - WHEN `targettype` = '41' AND `CastRestriction` = '0' THEN 'GroupV2' - ELSE CONCAT(`targettype`, ', ', `CastRestriction`) -- 'UNDEFINED' - END target_type, - CASE - WHEN `zonetype` NOT IN ('-1', '0') THEN `zonetype` - ELSE '0' - END zone_type, - caster_class, - spell_level, - `id` spell_id, - CONCAT('"', `name`, '"') spell_name, - `mana` mana_cost --- base - -FROM ( - SELECT 'DRUID' caster_class, `classes6` spell_level, - `targettype`, `CastRestriction`, `zonetype`, `id`, `name`, `mana` - FROM `spells_new` - WHERE `classes6` NOT IN ('254', '255') - AND `SpellAffectIndex` = '40' - AND '88' IN (`effectid1`, `effectid2`, `effectid3`, `effectid4`, `effectid5`, `effectid6`, `effectid7`, `effectid8`, `effectid9`, `effectid10`, `effectid11`, `effectid12`) - AND `teleport_zone` LIKE 'same' -UNION ALL - SELECT 'WIZARD' caster_class, `classes12` spell_level, - `targettype`, `CastRestriction`, `zonetype`, `id`, `name`, `mana` - FROM `spells_new` - WHERE `classes12` NOT IN ('254', '255') - AND `SpellAffectIndex` = '40' - AND '88' IN (`effectid1`, `effectid2`, `effectid3`, `effectid4`, `effectid5`, `effectid6`, `effectid7`, `effectid8`, `effectid9`, `effectid10`, `effectid11`, `effectid12`) - AND `teleport_zone` LIKE 'same' -) spells - --- WHERE `name` NOT LIKE '%II' --- --- --- WHERE `name` NOT LIKE '%Rk. II%' --- AND `name` NOT LIKE '%Rk.II%' --- AND `name` NOT LIKE '%Rk. III%' --- AND `name` NOT LIKE '%Rk.III%' -ORDER BY FIELD(target_type, 'GroupV2'), - FIELD(caster_class, 'DRUID', 'WIZARD'), - spell_level, - spell_name diff --git a/utils/scripts/bot_command_spell_scripts/grow_spells.sql b/utils/scripts/bot_command_spell_scripts/grow_spells.sql deleted file mode 100644 index 4dbca1a06..000000000 --- a/utils/scripts/bot_command_spell_scripts/grow_spells.sql +++ /dev/null @@ -1,39 +0,0 @@ -SELECT --- base - CASE - WHEN `targettype` = '5' AND `CastRestriction` = '0' THEN 'Single' - ELSE CONCAT(`targettype`, ', ', `CastRestriction`) -- 'UNDEFINED' - END target_type, - CASE - WHEN `zonetype` NOT IN ('-1', '0') THEN `zonetype` - ELSE '0' - END zone_type, - caster_class, - spell_level, - `id` spell_id, - CONCAT('"', `name`, '"') spell_name, - `mana` mana_cost --- base - -FROM ( - SELECT 'SHAMAN' caster_class, `classes10` spell_level, - `targettype`, `CastRestriction`, `zonetype`, `id`, `name`, `mana` - FROM `spells_new` - WHERE `classes10` NOT IN ('254', '255') - AND `SpellAffectIndex` = '10' --- 6-self - AND `targettype` NOT IN ('6') - AND `effectid1` = '89' -- implementation restricted to `effectid1` - AND `effect_base_value1` > 100 -- implementation restricted to `effect_base_value1` -) spells - --- WHERE `name` NOT LIKE '%II' --- --- --- WHERE `name` NOT LIKE '%Rk. II%' --- AND `name` NOT LIKE '%Rk.II%' --- AND `name` NOT LIKE '%Rk. III%' --- AND `name` NOT LIKE '%Rk.III%' -ORDER BY FIELD(target_type, 'Single'), - FIELD(caster_class, 'SHAMAN'), - spell_level, - spell_name diff --git a/utils/scripts/bot_command_spell_scripts/invisibility_spells.sql b/utils/scripts/bot_command_spell_scripts/invisibility_spells.sql deleted file mode 100644 index 8545cab30..000000000 --- a/utils/scripts/bot_command_spell_scripts/invisibility_spells.sql +++ /dev/null @@ -1,151 +0,0 @@ -SELECT --- base - CASE - WHEN `targettype` = '5' AND `CastRestriction` = '0' THEN 'Single' - WHEN `targettype` = '41' AND `CastRestriction` = '0' THEN 'GroupV2' - ELSE CONCAT(`targettype`, ', ', `CastRestriction`) -- 'UNDEFINED' - END target_type, - CASE - WHEN `zonetype` NOT IN ('-1', '0') THEN `zonetype` - ELSE '0' - END zone_type, - caster_class, - spell_level, - `id` spell_id, - CONCAT('"', `name`, '"') spell_name, - `mana` mana_cost, --- base --- extra - CASE - WHEN `effectid1` = '12' THEN 'Living' - WHEN `effectid1` = '13' THEN 'See' - WHEN `effectid1` = '28' THEN 'Undead' - WHEN `effectid1` = '29' THEN 'Animal' - ELSE `effectid1` -- 'UNDEFINED' - END invis_type --- extra - -FROM ( - SELECT 'CLERIC' caster_class, `classes2` spell_level, - `targettype`, `CastRestriction`, `zonetype`, `id`, `name`, `mana`, `effectid1` - FROM `spells_new` - WHERE `classes2` NOT IN ('254', '255') - AND `SpellAffectIndex` IN ('5', '9') --- 6-self - AND `targettype` NOT IN ('6') --- 12-living, 13-see, 28-undead, 29-animal - AND `effectid1` IN ('12', '13', '28', '29') -- implementation restricted to `effectid1` -UNION ALL - SELECT 'PALADIN' caster_class, `classes3` spell_level, - `targettype`, `CastRestriction`, `zonetype`, `id`, `name`, `mana`, `effectid1` - FROM `spells_new` - WHERE `classes3` NOT IN ('254', '255') - AND `SpellAffectIndex` IN ('5', '9') --- 6-self - AND `targettype` NOT IN ('6') --- 12-living, 13-see, 28-undead, 29-animal - AND `effectid1` IN ('12', '13', '28', '29') -- implementation restricted to `effectid1` -UNION ALL - SELECT 'RANGER' caster_class, `classes4` spell_level, - `targettype`, `CastRestriction`, `zonetype`, `id`, `name`, `mana`, `effectid1` - FROM `spells_new` - WHERE `classes4` NOT IN ('254', '255') - AND `SpellAffectIndex` IN ('5', '9') --- 6-self - AND `targettype` NOT IN ('6') --- 12-living, 13-see, 28-undead, 29-animal - AND `effectid1` IN ('12', '13', '28', '29') -- implementation restricted to `effectid1` -UNION ALL - SELECT 'SHADOWKNIGHT' caster_class, `classes5` spell_level, - `targettype`, `CastRestriction`, `zonetype`, `id`, `name`, `mana`, `effectid1` - FROM `spells_new` - WHERE `classes5` NOT IN ('254', '255') - AND `SpellAffectIndex` IN ('5', '9') --- 6-self - AND `targettype` NOT IN ('6') --- 12-living, 13-see, 28-undead, 29-animal - AND `effectid1` IN ('12', '13', '28', '29') -- implementation restricted to `effectid1` -UNION ALL - SELECT 'DRUID' caster_class, `classes6` spell_level, - `targettype`, `CastRestriction`, `zonetype`, `id`, `name`, `mana`, `effectid1` - FROM `spells_new` - WHERE `classes6` NOT IN ('254', '255') - AND `SpellAffectIndex` IN ('5', '9') --- 6-self - AND `targettype` NOT IN ('6') --- 12-living, 13-see, 28-undead, 29-animal - AND `effectid1` IN ('12', '13', '28', '29') -- implementation restricted to `effectid1` -UNION ALL - SELECT 'SHAMAN' caster_class, `classes10` spell_level, - `targettype`, `CastRestriction`, `zonetype`, `id`, `name`, `mana`, `effectid1` - FROM `spells_new` - WHERE `classes10` NOT IN ('254', '255') - AND `SpellAffectIndex` IN ('5', '9') --- 6-self - AND `targettype` NOT IN ('6') --- 12-living, 13-see, 28-undead, 29-animal - AND `effectid1` IN ('12', '13', '28', '29') -- implementation restricted to `effectid1` -UNION ALL - SELECT 'NECROMANCER' caster_class, `classes11` spell_level, - `targettype`, `CastRestriction`, `zonetype`, `id`, `name`, `mana`, `effectid1` - FROM `spells_new` - WHERE `classes11` NOT IN ('254', '255') - AND `SpellAffectIndex` IN ('5', '9') --- 6-self - AND `targettype` NOT IN ('6') --- 12-living, 13-see, 28-undead, 29-animal - AND `effectid1` IN ('12', '13', '28', '29') -- implementation restricted to `effectid1` -UNION ALL - SELECT 'WIZARD' caster_class, `classes12` spell_level, - `targettype`, `CastRestriction`, `zonetype`, `id`, `name`, `mana`, `effectid1` - FROM `spells_new` - WHERE `classes12` NOT IN ('254', '255') - AND `SpellAffectIndex` IN ('5', '9') --- 6-self - AND `targettype` NOT IN ('6') --- 12-living, 13-see, 28-undead, 29-animal - AND `effectid1` IN ('12', '13', '28', '29') -- implementation restricted to `effectid1` -UNION ALL - SELECT 'MAGICIAN' caster_class, `classes13` spell_level, - `targettype`, `CastRestriction`, `zonetype`, `id`, `name`, `mana`, `effectid1` - FROM `spells_new` - WHERE `classes13` NOT IN ('254', '255') - AND `SpellAffectIndex` IN ('5', '9') --- 6-self - AND `targettype` NOT IN ('6') --- 12-living, 13-see, 28-undead, 29-animal - AND `effectid1` IN ('12', '13', '28', '29') -- implementation restricted to `effectid1` -UNION ALL - SELECT 'ENCHANTER' caster_class, `classes14` spell_level, - `targettype`, `CastRestriction`, `zonetype`, `id`, `name`, `mana`, `effectid1` - FROM `spells_new` - WHERE `classes14` NOT IN ('254', '255') - AND `SpellAffectIndex` IN ('5', '9') --- 6-self - AND `targettype` NOT IN ('6') --- 12-living, 13-see, 28-undead, 29-animal - AND `effectid1` IN ('12', '13', '28', '29') -- implementation restricted to `effectid1` -UNION ALL - SELECT 'BEASTLORD' caster_class, `classes15` spell_level, - `targettype`, `CastRestriction`, `zonetype`, `id`, `name`, `mana`, `effectid1` - FROM `spells_new` - WHERE `classes15` NOT IN ('254', '255') - AND `SpellAffectIndex` IN ('5', '9') --- 6-self - AND `targettype` NOT IN ('6') --- 12-living, 13-see, 28-undead, 29-animal - AND `effectid1` IN ('12', '13', '28', '29') -- implementation restricted to `effectid1` -) spells - --- WHERE `name` NOT LIKE '%II' --- --- --- WHERE `name` NOT LIKE '%Rk. II%' --- AND `name` NOT LIKE '%Rk.II%' --- AND `name` NOT LIKE '%Rk. III%' --- AND `name` NOT LIKE '%Rk.III%' -ORDER BY FIELD(invis_type, 'Animal', 'Undead', 'Living', 'See'), - FIELD(target_type, 'Single', 'GroupV2'), - zone_type, - spell_level DESC, - spell_name, - FIELD(caster_class, 'CLERIC', 'PALADIN', 'RANGER', 'SHADOWKNIGHT', 'DRUID', 'SHAMAN', 'NECROMANCER', 'WIZARD', 'MAGICIAN', 'ENCHANTER', 'BEASTLORD') diff --git a/utils/scripts/bot_command_spell_scripts/levitation_spells.sql b/utils/scripts/bot_command_spell_scripts/levitation_spells.sql deleted file mode 100644 index 2193c75b7..000000000 --- a/utils/scripts/bot_command_spell_scripts/levitation_spells.sql +++ /dev/null @@ -1,94 +0,0 @@ -SELECT --- base - CASE - WHEN `targettype` = '5' AND `CastRestriction` = '0' THEN 'Single' - WHEN `targettype` = '41' AND `CastRestriction` = '0' THEN 'GroupV2' - ELSE CONCAT(`targettype`, ', ', `CastRestriction`) -- 'UNDEFINED' - END target_type, - CASE - WHEN `zonetype` NOT IN ('-1', '0') THEN `zonetype` - ELSE '0' - END zone_type, - caster_class, - spell_level, - `id` spell_id, - CONCAT('"', `name`, '"') spell_name, - `mana` mana_cost --- base - -FROM ( - SELECT 'RANGER' caster_class, `classes4` spell_level, - `targettype`, `CastRestriction`, `zonetype`, `id`, `name`, `mana` - FROM `spells_new` - WHERE `classes4` NOT IN ('254', '255') - AND `SpellAffectIndex` IN ('2', '28') --- 6-self, 43-groupclientandpet - AND `targettype` NOT IN ('6', '43') - AND '57' IN (`effectid1`, `effectid2`, `effectid3`, `effectid4`, `effectid5`, `effectid6`, `effectid7`, `effectid8`, `effectid9`, `effectid10`, `effectid11`, `effectid12`) -UNION ALL - SELECT 'DRUID' caster_class, `classes6` spell_level, - `targettype`, `CastRestriction`, `zonetype`, `id`, `name`, `mana` - FROM `spells_new` - WHERE `classes6` NOT IN ('254', '255') - AND `SpellAffectIndex` IN ('2', '28') --- 6-self, 43-groupclientandpet - AND `targettype` NOT IN ('6', '43') - AND '57' IN (`effectid1`, `effectid2`, `effectid3`, `effectid4`, `effectid5`, `effectid6`, `effectid7`, `effectid8`, `effectid9`, `effectid10`, `effectid11`, `effectid12`) -UNION ALL - SELECT 'SHAMAN' caster_class, `classes10` spell_level, - `targettype`, `CastRestriction`, `zonetype`, `id`, `name`, `mana` - FROM `spells_new` - WHERE `classes10` NOT IN ('254', '255') - AND `SpellAffectIndex` IN ('2', '28') --- 6-self, 43-groupclientandpet - AND `targettype` NOT IN ('6', '43') - AND '57' IN (`effectid1`, `effectid2`, `effectid3`, `effectid4`, `effectid5`, `effectid6`, `effectid7`, `effectid8`, `effectid9`, `effectid10`, `effectid11`, `effectid12`) -UNION ALL - SELECT 'NECROMANCER' caster_class, `classes11` spell_level, - `targettype`, `CastRestriction`, `zonetype`, `id`, `name`, `mana` - FROM `spells_new` - WHERE `classes11` NOT IN ('254', '255') - AND `SpellAffectIndex` IN ('2', '28') --- 6-self, 43-groupclientandpet - AND `targettype` NOT IN ('6', '43') - AND '57' IN (`effectid1`, `effectid2`, `effectid3`, `effectid4`, `effectid5`, `effectid6`, `effectid7`, `effectid8`, `effectid9`, `effectid10`, `effectid11`, `effectid12`) -UNION ALL - SELECT 'WIZARD' caster_class, `classes12` spell_level, - `targettype`, `CastRestriction`, `zonetype`, `id`, `name`, `mana` - FROM `spells_new` - WHERE `classes12` NOT IN ('254', '255') - AND `SpellAffectIndex` IN ('2', '28') --- 6-self, 43-groupclientandpet - AND `targettype` NOT IN ('6', '43') - AND '57' IN (`effectid1`, `effectid2`, `effectid3`, `effectid4`, `effectid5`, `effectid6`, `effectid7`, `effectid8`, `effectid9`, `effectid10`, `effectid11`, `effectid12`) -UNION ALL - SELECT 'ENCHANTER' caster_class, `classes14` spell_level, - `targettype`, `CastRestriction`, `zonetype`, `id`, `name`, `mana` - FROM `spells_new` - WHERE `classes14` NOT IN ('254', '255') - AND `SpellAffectIndex` IN ('2', '28') --- 6-self, 43-groupclientandpet - AND `targettype` NOT IN ('6', '43') - AND '57' IN (`effectid1`, `effectid2`, `effectid3`, `effectid4`, `effectid5`, `effectid6`, `effectid7`, `effectid8`, `effectid9`, `effectid10`, `effectid11`, `effectid12`) -UNION ALL - SELECT 'BEASTLORD' caster_class, `classes15` spell_level, - `targettype`, `CastRestriction`, `zonetype`, `id`, `name`, `mana` - FROM `spells_new` - WHERE `classes15` NOT IN ('254', '255') - AND `SpellAffectIndex` IN ('2', '28') --- 6-self, 43-groupclientandpet - AND `targettype` NOT IN ('6', '43') - AND '57' IN (`effectid1`, `effectid2`, `effectid3`, `effectid4`, `effectid5`, `effectid6`, `effectid7`, `effectid8`, `effectid9`, `effectid10`, `effectid11`, `effectid12`) -) spells - --- WHERE `name` NOT LIKE '%II' --- --- --- WHERE `name` NOT LIKE '%Rk. II%' --- AND `name` NOT LIKE '%Rk.II%' --- AND `name` NOT LIKE '%Rk. III%' --- AND `name` NOT LIKE '%Rk.III%' -ORDER BY FIELD(target_type, 'Single', 'GroupV2'), - zone_type, - spell_level DESC, - spell_name, - FIELD(caster_class, 'RANGER', 'DRUID', 'SHAMAN', 'NECROMANCER', 'WIZARD', 'ENCHANTER', 'BEASTLORD') diff --git a/utils/scripts/bot_command_spell_scripts/lull_spells.sql b/utils/scripts/bot_command_spell_scripts/lull_spells.sql deleted file mode 100644 index 2d0989b85..000000000 --- a/utils/scripts/bot_command_spell_scripts/lull_spells.sql +++ /dev/null @@ -1,86 +0,0 @@ --- needs criteria refinement - -SELECT --- base - CASE - WHEN `targettype` = '5' AND `CastRestriction` = '0' THEN 'Single' - WHEN `targettype` = '8' AND `CastRestriction` = '0' THEN 'AETarget' - WHEN `targettype` = '9' AND `CastRestriction` = '0' THEN 'Animal' - WHEN `targettype` = '10' AND `CastRestriction` = '0' THEN 'Undead' - ELSE CONCAT(`targettype`, ', ', `CastRestriction`) -- 'UNDEFINED' - END target_type, - CASE - WHEN `zonetype` NOT IN ('-1', '0') THEN `zonetype` - ELSE '0' - END zone_type, - caster_class, - spell_level, - `id` spell_id, - CONCAT('"', `name`, '"') spell_name, - `mana` mana_cost --- base - -FROM ( - SELECT 'CLERIC' caster_class, `classes2` spell_level, - `targettype`, `CastRestriction`, `zonetype`, `id`, `name`, `mana` - FROM `spells_new` - WHERE `classes2` NOT IN ('254', '255') - AND `SpellAffectIndex` = '12' - AND '18' IN (`effectid1`, `effectid2`, `effectid3`, `effectid4`, `effectid5`, `effectid6`, `effectid7`, `effectid8`, `effectid9`, `effectid10`, `effectid11`, `effectid12`) -UNION ALL - SELECT 'PALADIN' caster_class, `classes3` spell_level, - `targettype`, `CastRestriction`, `zonetype`, `id`, `name`, `mana` - FROM `spells_new` - WHERE `classes3` NOT IN ('254', '255') - AND `SpellAffectIndex` = '12' - AND '18' IN (`effectid1`, `effectid2`, `effectid3`, `effectid4`, `effectid5`, `effectid6`, `effectid7`, `effectid8`, `effectid9`, `effectid10`, `effectid11`, `effectid12`) -UNION ALL - SELECT 'RANGER' caster_class, `classes4` spell_level, - `targettype`, `CastRestriction`, `zonetype`, `id`, `name`, `mana` - FROM `spells_new` - WHERE `classes4` NOT IN ('254', '255') - AND `SpellAffectIndex` = '12' - AND '18' IN (`effectid1`, `effectid2`, `effectid3`, `effectid4`, `effectid5`, `effectid6`, `effectid7`, `effectid8`, `effectid9`, `effectid10`, `effectid11`, `effectid12`) -UNION ALL - SELECT 'SHADOWKNIGHT' caster_class, `classes5` spell_level, - `targettype`, `CastRestriction`, `zonetype`, `id`, `name`, `mana` - FROM `spells_new` - WHERE `classes5` NOT IN ('254', '255') - AND `SpellAffectIndex` = '12' - AND '18' IN (`effectid1`, `effectid2`, `effectid3`, `effectid4`, `effectid5`, `effectid6`, `effectid7`, `effectid8`, `effectid9`, `effectid10`, `effectid11`, `effectid12`) -UNION ALL - SELECT 'DRUID' caster_class, `classes6` spell_level, - `targettype`, `CastRestriction`, `zonetype`, `id`, `name`, `mana` - FROM `spells_new` - WHERE `classes6` NOT IN ('254', '255') - AND `SpellAffectIndex` = '12' - AND '18' IN (`effectid1`, `effectid2`, `effectid3`, `effectid4`, `effectid5`, `effectid6`, `effectid7`, `effectid8`, `effectid9`, `effectid10`, `effectid11`, `effectid12`) -UNION ALL - SELECT 'NECROMANCER' caster_class, `classes11` spell_level, - `targettype`, `CastRestriction`, `zonetype`, `id`, `name`, `mana` - FROM `spells_new` - WHERE `classes11` NOT IN ('254', '255') - AND `SpellAffectIndex` = '12' - AND '18' IN (`effectid1`, `effectid2`, `effectid3`, `effectid4`, `effectid5`, `effectid6`, `effectid7`, `effectid8`, `effectid9`, `effectid10`, `effectid11`, `effectid12`) -UNION ALL - SELECT 'ENCHANTER' caster_class, `classes14` spell_level, - `targettype`, `CastRestriction`, `zonetype`, `id`, `name`, `mana` - FROM `spells_new` - WHERE `classes14` NOT IN ('254', '255') - AND `SpellAffectIndex` = '12' - AND '18' IN (`effectid1`, `effectid2`, `effectid3`, `effectid4`, `effectid5`, `effectid6`, `effectid7`, `effectid8`, `effectid9`, `effectid10`, `effectid11`, `effectid12`) -) spells - --- WHERE `name` NOT LIKE '%II' --- --- --- WHERE `name` NOT LIKE '%Rk. II%' --- AND `name` NOT LIKE '%Rk.II%' --- AND `name` NOT LIKE '%Rk. III%' --- AND `name` NOT LIKE '%Rk.III%' -ORDER BY FIELD(target_type, 'Animal', 'Undead', 'Single', 'AETarget'), - target_type, - zone_type, - FIELD(caster_class, 'CLERIC', 'PALADIN', 'RANGER', 'SHADOWKNIGHT', 'DRUID', 'NECROMANCER', 'ENCHANTER'), - spell_level, - spell_id, - spell_name diff --git a/utils/scripts/bot_command_spell_scripts/mesmerize_spells.sql b/utils/scripts/bot_command_spell_scripts/mesmerize_spells.sql deleted file mode 100644 index a23d62af6..000000000 --- a/utils/scripts/bot_command_spell_scripts/mesmerize_spells.sql +++ /dev/null @@ -1,76 +0,0 @@ --- needs criteria refinement - -SELECT --- base - CASE - WHEN `targettype` = '4' AND `CastRestriction` = '0' THEN 'AECaster' - WHEN `targettype` = '5' AND `CastRestriction` = '0' THEN 'Single' - WHEN `targettype` = '8' AND `CastRestriction` = '0' THEN 'AETarget' - WHEN `targettype` = '10' AND `CastRestriction` = '0' THEN 'Undead' - WHEN `targettype` = '11' AND `CastRestriction` = '0' THEN 'Summoned' - ELSE CONCAT(`targettype`, ', ', `CastRestriction`) -- 'UNDEFINED' - END target_type, - CASE - WHEN `zonetype` NOT IN ('-1', '0') THEN `zonetype` - ELSE '0' - END zone_type, - caster_class, - spell_level, - `id` spell_id, - CONCAT('"', `name`, '"') spell_name, - `mana` mana_cost, --- base --- extra - `ResistDiff` resist_diff, - `max1` max_target_level --- extra - -FROM ( - SELECT 'BARD' caster_class, `classes8` spell_level, - `targettype`, `CastRestriction`, `zonetype`, `id`, `name`, `mana`, `ResistDiff`, `max1` - FROM `spells_new` - WHERE `classes8` NOT IN ('254', '255') - AND `SpellAffectIndex` IN ('12', '13', '25', '27', '41', '43') --- 45-ring - AND `targettype` NOT IN ('45') - AND `effectid1` = '31' -UNION ALL - SELECT 'NECROMANCER' caster_class, `classes11` spell_level, - `targettype`, `CastRestriction`, `zonetype`, `id`, `name`, `mana`, `ResistDiff`, `max1` - FROM `spells_new` - WHERE `classes11` NOT IN ('254', '255') - AND `SpellAffectIndex` IN ('12', '13', '25', '27', '41', '43') --- 45-ring - AND `targettype` NOT IN ('45') - AND `effectid1` = '31' -UNION ALL - SELECT 'MAGICIAN' caster_class, `classes13` spell_level, - `targettype`, `CastRestriction`, `zonetype`, `id`, `name`, `mana`, `ResistDiff`, `max1` - FROM `spells_new` - WHERE `classes13` NOT IN ('254', '255') - AND `SpellAffectIndex` IN ('12', '13', '25', '27', '41', '43') --- 45-ring - AND `targettype` NOT IN ('45') - AND `effectid1` = '31' -UNION ALL - SELECT 'ENCHANTER' caster_class, `classes14` spell_level, - `targettype`, `CastRestriction`, `zonetype`, `id`, `name`, `mana`, `ResistDiff`, `max1` - FROM `spells_new` - WHERE `classes14` NOT IN ('254', '255') - AND `SpellAffectIndex` IN ('12', '13', '25', '27', '41', '43') --- 45-ring - AND `targettype` NOT IN ('45') - AND `effectid1` = '31' -) spells - --- WHERE `name` NOT LIKE '%II' --- --- --- WHERE `name` NOT LIKE '%Rk. II%' --- AND `name` NOT LIKE '%Rk.II%' --- AND `name` NOT LIKE '%Rk. III%' --- AND `name` NOT LIKE '%Rk.III%' -ORDER BY resist_diff, - FIELD(target_type, 'Undead', 'Summoned', 'Single', 'AECaster', 'AETarget'), - max_target_level DESC, - spell_level DESC, - FIELD(caster_class, 'BARD', 'NECROMANCER', 'MAGICIAN', 'ENCHANTER') diff --git a/utils/scripts/bot_command_spell_scripts/movement_speed_spells.sql b/utils/scripts/bot_command_spell_scripts/movement_speed_spells.sql deleted file mode 100644 index aaabf2fa2..000000000 --- a/utils/scripts/bot_command_spell_scripts/movement_speed_spells.sql +++ /dev/null @@ -1,74 +0,0 @@ -SELECT --- base - CASE - WHEN `targettype` = '3' AND `CastRestriction` = '0' THEN 'GroupV1' - WHEN `targettype` = '5' AND `CastRestriction` = '0' THEN 'Single' - WHEN `targettype` = '41' AND `CastRestriction` = '0' THEN 'GroupV2' - ELSE CONCAT(`targettype`, ', ', `CastRestriction`) -- 'UNDEFINED' - END target_type, - CASE - WHEN `zonetype` NOT IN ('-1', '0') THEN `zonetype` - ELSE '0' - END zone_type, - caster_class, - spell_level, - `id` spell_id, - CONCAT('"', `name`, '"') spell_name, - `mana` mana_cost, --- base --- extra - `effect_base_value2` base_speed --- extra - -FROM ( - SELECT 'RANGER' caster_class, `classes4` spell_level, - `targettype`, `CastRestriction`, `zonetype`, `id`, `name`, `mana`, `effect_base_value2` - FROM `spells_new` - WHERE `classes4` NOT IN ('254', '255') - AND `SpellAffectIndex` IN ('7', '10') --- 6-self - AND `targettype` NOT IN ('6') - AND `CastRestriction` = '0' - AND `effectdescnum` = '65' -UNION ALL - SELECT 'DRUID' caster_class, `classes6` spell_level, - `targettype`, `CastRestriction`, `zonetype`, `id`, `name`, `mana`, `effect_base_value2` - FROM `spells_new` - WHERE `classes6` NOT IN ('254', '255') - AND `SpellAffectIndex` IN ('7', '10') --- 6-self - AND `targettype` NOT IN ('6') - AND `CastRestriction` = '0' - AND `effectdescnum` = '65' -UNION ALL - SELECT 'SHAMAN' caster_class, `classes10` spell_level, - `targettype`, `CastRestriction`, `zonetype`, `id`, `name`, `mana`, `effect_base_value2` - FROM `spells_new` - WHERE `classes10` NOT IN ('254', '255') - AND `SpellAffectIndex` IN ('7', '10') --- 6-self - AND `targettype` NOT IN ('6') - AND `CastRestriction` = '0' - AND `effectdescnum` = '65' -UNION ALL - SELECT 'BEASTLORD' caster_class, `classes15` spell_level, - `targettype`, `CastRestriction`, `zonetype`, `id`, `name`, `mana`, `effect_base_value2` - FROM `spells_new` - WHERE `classes15` NOT IN ('254', '255') - AND `SpellAffectIndex` IN ('7', '10') --- 6-self - AND `targettype` NOT IN ('6') - AND `CastRestriction` = '0' - AND `effectdescnum` = '65' -) spells - --- WHERE `name` NOT LIKE '%II' --- --- --- WHERE `name` NOT LIKE '%Rk. II%' --- AND `name` NOT LIKE '%Rk.II%' --- AND `name` NOT LIKE '%Rk. III%' --- AND `name` NOT LIKE '%Rk.III%' -ORDER BY FIELD(target_type, 'Single', 'GroupV1', 'GroupV2'), - effect_base_value2 DESC, - spell_level, - FIELD(caster_class, 'RANGER', 'DRUID', 'SHAMAN', 'BEASTLORD') diff --git a/utils/scripts/bot_command_spell_scripts/resistance_spells.sql b/utils/scripts/bot_command_spell_scripts/resistance_spells.sql deleted file mode 100644 index 0cda671e7..000000000 --- a/utils/scripts/bot_command_spell_scripts/resistance_spells.sql +++ /dev/null @@ -1,221 +0,0 @@ -SELECT --- base - CASE - WHEN `targettype` = '3' AND `CastRestriction` = '0' THEN 'GroupV1' - WHEN `targettype` = '5' AND `CastRestriction` = '0' THEN 'Single' - WHEN `targettype` = '41' AND `CastRestriction` = '0' THEN 'GroupV2' - ELSE CONCAT(`targettype`, ', ', `CastRestriction`) -- 'UNDEFINED' - END target_type, - CASE - WHEN `zonetype` NOT IN ('-1', '0') THEN `zonetype` - ELSE '0' - END zone_type, - caster_class, - spell_level, - `id` spell_id, - CONCAT('"', `name`, '"') spell_name, - `mana` mana_cost, --- base --- extra - ( - (IF(('46' IN (`effectid1`, `effectid2`, `effectid3`, `effectid4`, `effectid5`, `effectid6`, `effectid7`, `effectid8`, `effectid9`, `effectid10`, `effectid11`, `effectid12`)), '1', '0')) | - (IF(('47' IN (`effectid1`, `effectid2`, `effectid3`, `effectid4`, `effectid5`, `effectid6`, `effectid7`, `effectid8`, `effectid9`, `effectid10`, `effectid11`, `effectid12`)), '2', '0')) | - (IF(('48' IN (`effectid1`, `effectid2`, `effectid3`, `effectid4`, `effectid5`, `effectid6`, `effectid7`, `effectid8`, `effectid9`, `effectid10`, `effectid11`, `effectid12`)), '4', '0')) | - (IF(('49' IN (`effectid1`, `effectid2`, `effectid3`, `effectid4`, `effectid5`, `effectid6`, `effectid7`, `effectid8`, `effectid9`, `effectid10`, `effectid11`, `effectid12`)), '8', '0')) | - (IF(('50' IN (`effectid1`, `effectid2`, `effectid3`, `effectid4`, `effectid5`, `effectid6`, `effectid7`, `effectid8`, `effectid9`, `effectid10`, `effectid11`, `effectid12`)), '16', '0')) | - (IF(('370' IN (`effectid1`, `effectid2`, `effectid3`, `effectid4`, `effectid5`, `effectid6`, `effectid7`, `effectid8`, `effectid9`, `effectid10`, `effectid11`, `effectid12`)), '32', '0')) - ) resist_type --- extra - -FROM ( - SELECT 'CLERIC' caster_class, `classes2` spell_level, - `targettype`, `CastRestriction`, `zonetype`, `id`, `name`, `mana`, - `effectid1`, `effectid2`, `effectid3`, `effectid4`, `effectid5`, `effectid6`, `effectid7`, `effectid8`, `effectid9`, `effectid10`, `effectid11`, `effectid12` - FROM `spells_new` - WHERE `classes2` NOT IN ('254', '255') - AND `SpellAffectIndex` = '2' --- 6-self, 14-pet, 39-groupnopets, 46-targetstarget - AND `targettype` NOT IN ('6', '14', '39', '46') - AND ( - - '46' IN (`effectid1`, `effectid2`, `effectid3`, `effectid4`, `effectid5`, `effectid6`, `effectid7`, `effectid8`, `effectid9`, `effectid10`, `effectid11`, `effectid12`) - OR '47' IN (`effectid1`, `effectid2`, `effectid3`, `effectid4`, `effectid5`, `effectid6`, `effectid7`, `effectid8`, `effectid9`, `effectid10`, `effectid11`, `effectid12`) - OR '48' IN (`effectid1`, `effectid2`, `effectid3`, `effectid4`, `effectid5`, `effectid6`, `effectid7`, `effectid8`, `effectid9`, `effectid10`, `effectid11`, `effectid12`) - OR '49' IN (`effectid1`, `effectid2`, `effectid3`, `effectid4`, `effectid5`, `effectid6`, `effectid7`, `effectid8`, `effectid9`, `effectid10`, `effectid11`, `effectid12`) - OR '50' IN (`effectid1`, `effectid2`, `effectid3`, `effectid4`, `effectid5`, `effectid6`, `effectid7`, `effectid8`, `effectid9`, `effectid10`, `effectid11`, `effectid12`) - OR '370' IN (`effectid1`, `effectid2`, `effectid3`, `effectid4`, `effectid5`, `effectid6`, `effectid7`, `effectid8`, `effectid9`, `effectid10`, `effectid11`, `effectid12`) - ) -UNION ALL - SELECT 'PALADIN' caster_class, `classes3` spell_level, - `targettype`, `CastRestriction`, `zonetype`, `id`, `name`, `mana`, - `effectid1`, `effectid2`, `effectid3`, `effectid4`, `effectid5`, `effectid6`, `effectid7`, `effectid8`, `effectid9`, `effectid10`, `effectid11`, `effectid12` - FROM `spells_new` - WHERE `classes3` NOT IN ('254', '255') - AND `SpellAffectIndex` = '2' --- 6-self, 14-pet, 39-groupnopets, 46-targetstarget - AND `targettype` NOT IN ('6', '14', '39', '46') - AND ( - - '46' IN (`effectid1`, `effectid2`, `effectid3`, `effectid4`, `effectid5`, `effectid6`, `effectid7`, `effectid8`, `effectid9`, `effectid10`, `effectid11`, `effectid12`) - OR '47' IN (`effectid1`, `effectid2`, `effectid3`, `effectid4`, `effectid5`, `effectid6`, `effectid7`, `effectid8`, `effectid9`, `effectid10`, `effectid11`, `effectid12`) - OR '48' IN (`effectid1`, `effectid2`, `effectid3`, `effectid4`, `effectid5`, `effectid6`, `effectid7`, `effectid8`, `effectid9`, `effectid10`, `effectid11`, `effectid12`) - OR '49' IN (`effectid1`, `effectid2`, `effectid3`, `effectid4`, `effectid5`, `effectid6`, `effectid7`, `effectid8`, `effectid9`, `effectid10`, `effectid11`, `effectid12`) - OR '50' IN (`effectid1`, `effectid2`, `effectid3`, `effectid4`, `effectid5`, `effectid6`, `effectid7`, `effectid8`, `effectid9`, `effectid10`, `effectid11`, `effectid12`) - OR '370' IN (`effectid1`, `effectid2`, `effectid3`, `effectid4`, `effectid5`, `effectid6`, `effectid7`, `effectid8`, `effectid9`, `effectid10`, `effectid11`, `effectid12`) - ) -UNION ALL - SELECT 'RANGER' caster_class, `classes4` spell_level, - `targettype`, `CastRestriction`, `zonetype`, `id`, `name`, `mana`, - `effectid1`, `effectid2`, `effectid3`, `effectid4`, `effectid5`, `effectid6`, `effectid7`, `effectid8`, `effectid9`, `effectid10`, `effectid11`, `effectid12` - FROM `spells_new` - WHERE `classes4` NOT IN ('254', '255') - AND `SpellAffectIndex` = '2' --- 6-self, 14-pet, 39-groupnopets, 46-targetstarget - AND `targettype` NOT IN ('6', '14', '39', '46') - AND ( - - '46' IN (`effectid1`, `effectid2`, `effectid3`, `effectid4`, `effectid5`, `effectid6`, `effectid7`, `effectid8`, `effectid9`, `effectid10`, `effectid11`, `effectid12`) - OR '47' IN (`effectid1`, `effectid2`, `effectid3`, `effectid4`, `effectid5`, `effectid6`, `effectid7`, `effectid8`, `effectid9`, `effectid10`, `effectid11`, `effectid12`) - OR '48' IN (`effectid1`, `effectid2`, `effectid3`, `effectid4`, `effectid5`, `effectid6`, `effectid7`, `effectid8`, `effectid9`, `effectid10`, `effectid11`, `effectid12`) - OR '49' IN (`effectid1`, `effectid2`, `effectid3`, `effectid4`, `effectid5`, `effectid6`, `effectid7`, `effectid8`, `effectid9`, `effectid10`, `effectid11`, `effectid12`) - OR '50' IN (`effectid1`, `effectid2`, `effectid3`, `effectid4`, `effectid5`, `effectid6`, `effectid7`, `effectid8`, `effectid9`, `effectid10`, `effectid11`, `effectid12`) - OR '370' IN (`effectid1`, `effectid2`, `effectid3`, `effectid4`, `effectid5`, `effectid6`, `effectid7`, `effectid8`, `effectid9`, `effectid10`, `effectid11`, `effectid12`) - ) -UNION ALL - SELECT 'SHADOWKNIGHT' caster_class, `classes5` spell_level, - `targettype`, `CastRestriction`, `zonetype`, `id`, `name`, `mana`, - `effectid1`, `effectid2`, `effectid3`, `effectid4`, `effectid5`, `effectid6`, `effectid7`, `effectid8`, `effectid9`, `effectid10`, `effectid11`, `effectid12` - FROM `spells_new` - WHERE `classes5` NOT IN ('254', '255') - AND `SpellAffectIndex` = '2' --- 6-self, 14-pet, 39-groupnopets, 46-targetstarget - AND `targettype` NOT IN ('6', '14', '39', '46') - AND ( - - '46' IN (`effectid1`, `effectid2`, `effectid3`, `effectid4`, `effectid5`, `effectid6`, `effectid7`, `effectid8`, `effectid9`, `effectid10`, `effectid11`, `effectid12`) - OR '47' IN (`effectid1`, `effectid2`, `effectid3`, `effectid4`, `effectid5`, `effectid6`, `effectid7`, `effectid8`, `effectid9`, `effectid10`, `effectid11`, `effectid12`) - OR '48' IN (`effectid1`, `effectid2`, `effectid3`, `effectid4`, `effectid5`, `effectid6`, `effectid7`, `effectid8`, `effectid9`, `effectid10`, `effectid11`, `effectid12`) - OR '49' IN (`effectid1`, `effectid2`, `effectid3`, `effectid4`, `effectid5`, `effectid6`, `effectid7`, `effectid8`, `effectid9`, `effectid10`, `effectid11`, `effectid12`) - OR '50' IN (`effectid1`, `effectid2`, `effectid3`, `effectid4`, `effectid5`, `effectid6`, `effectid7`, `effectid8`, `effectid9`, `effectid10`, `effectid11`, `effectid12`) - OR '370' IN (`effectid1`, `effectid2`, `effectid3`, `effectid4`, `effectid5`, `effectid6`, `effectid7`, `effectid8`, `effectid9`, `effectid10`, `effectid11`, `effectid12`) - ) -UNION ALL - SELECT 'DRUID' caster_class, `classes6` spell_level, - `targettype`, `CastRestriction`, `zonetype`, `id`, `name`, `mana`, - `effectid1`, `effectid2`, `effectid3`, `effectid4`, `effectid5`, `effectid6`, `effectid7`, `effectid8`, `effectid9`, `effectid10`, `effectid11`, `effectid12` - FROM `spells_new` - WHERE `classes6` NOT IN ('254', '255') - AND `SpellAffectIndex` = '2' --- 6-self, 14-pet, 39-groupnopets, 46-targetstarget - AND `targettype` NOT IN ('6', '14', '39', '46') - AND ( - - '46' IN (`effectid1`, `effectid2`, `effectid3`, `effectid4`, `effectid5`, `effectid6`, `effectid7`, `effectid8`, `effectid9`, `effectid10`, `effectid11`, `effectid12`) - OR '47' IN (`effectid1`, `effectid2`, `effectid3`, `effectid4`, `effectid5`, `effectid6`, `effectid7`, `effectid8`, `effectid9`, `effectid10`, `effectid11`, `effectid12`) - OR '48' IN (`effectid1`, `effectid2`, `effectid3`, `effectid4`, `effectid5`, `effectid6`, `effectid7`, `effectid8`, `effectid9`, `effectid10`, `effectid11`, `effectid12`) - OR '49' IN (`effectid1`, `effectid2`, `effectid3`, `effectid4`, `effectid5`, `effectid6`, `effectid7`, `effectid8`, `effectid9`, `effectid10`, `effectid11`, `effectid12`) - OR '50' IN (`effectid1`, `effectid2`, `effectid3`, `effectid4`, `effectid5`, `effectid6`, `effectid7`, `effectid8`, `effectid9`, `effectid10`, `effectid11`, `effectid12`) - OR '370' IN (`effectid1`, `effectid2`, `effectid3`, `effectid4`, `effectid5`, `effectid6`, `effectid7`, `effectid8`, `effectid9`, `effectid10`, `effectid11`, `effectid12`) - ) -UNION ALL - SELECT 'SHAMAN' caster_class, `classes10` spell_level, - `targettype`, `CastRestriction`, `zonetype`, `id`, `name`, `mana`, - `effectid1`, `effectid2`, `effectid3`, `effectid4`, `effectid5`, `effectid6`, `effectid7`, `effectid8`, `effectid9`, `effectid10`, `effectid11`, `effectid12` - FROM `spells_new` - WHERE `classes10` NOT IN ('254', '255') - AND `SpellAffectIndex` = '2' --- 6-self, 14-pet, 39-groupnopets, 46-targetstarget - AND `targettype` NOT IN ('6', '14', '39', '46') - AND ( - - '46' IN (`effectid1`, `effectid2`, `effectid3`, `effectid4`, `effectid5`, `effectid6`, `effectid7`, `effectid8`, `effectid9`, `effectid10`, `effectid11`, `effectid12`) - OR '47' IN (`effectid1`, `effectid2`, `effectid3`, `effectid4`, `effectid5`, `effectid6`, `effectid7`, `effectid8`, `effectid9`, `effectid10`, `effectid11`, `effectid12`) - OR '48' IN (`effectid1`, `effectid2`, `effectid3`, `effectid4`, `effectid5`, `effectid6`, `effectid7`, `effectid8`, `effectid9`, `effectid10`, `effectid11`, `effectid12`) - OR '49' IN (`effectid1`, `effectid2`, `effectid3`, `effectid4`, `effectid5`, `effectid6`, `effectid7`, `effectid8`, `effectid9`, `effectid10`, `effectid11`, `effectid12`) - OR '50' IN (`effectid1`, `effectid2`, `effectid3`, `effectid4`, `effectid5`, `effectid6`, `effectid7`, `effectid8`, `effectid9`, `effectid10`, `effectid11`, `effectid12`) - OR '370' IN (`effectid1`, `effectid2`, `effectid3`, `effectid4`, `effectid5`, `effectid6`, `effectid7`, `effectid8`, `effectid9`, `effectid10`, `effectid11`, `effectid12`) - ) -UNION ALL - SELECT 'NECROMANCER' caster_class, `classes11` spell_level, - `targettype`, `CastRestriction`, `zonetype`, `id`, `name`, `mana`, - `effectid1`, `effectid2`, `effectid3`, `effectid4`, `effectid5`, `effectid6`, `effectid7`, `effectid8`, `effectid9`, `effectid10`, `effectid11`, `effectid12` - FROM `spells_new` - WHERE `classes11` NOT IN ('254', '255') - AND `SpellAffectIndex` = '2' --- 6-self, 14-pet, 39-groupnopets, 46-targetstarget - AND `targettype` NOT IN ('6', '14', '39', '46') - AND ( - - '46' IN (`effectid1`, `effectid2`, `effectid3`, `effectid4`, `effectid5`, `effectid6`, `effectid7`, `effectid8`, `effectid9`, `effectid10`, `effectid11`, `effectid12`) - OR '47' IN (`effectid1`, `effectid2`, `effectid3`, `effectid4`, `effectid5`, `effectid6`, `effectid7`, `effectid8`, `effectid9`, `effectid10`, `effectid11`, `effectid12`) - OR '48' IN (`effectid1`, `effectid2`, `effectid3`, `effectid4`, `effectid5`, `effectid6`, `effectid7`, `effectid8`, `effectid9`, `effectid10`, `effectid11`, `effectid12`) - OR '49' IN (`effectid1`, `effectid2`, `effectid3`, `effectid4`, `effectid5`, `effectid6`, `effectid7`, `effectid8`, `effectid9`, `effectid10`, `effectid11`, `effectid12`) - OR '50' IN (`effectid1`, `effectid2`, `effectid3`, `effectid4`, `effectid5`, `effectid6`, `effectid7`, `effectid8`, `effectid9`, `effectid10`, `effectid11`, `effectid12`) - OR '370' IN (`effectid1`, `effectid2`, `effectid3`, `effectid4`, `effectid5`, `effectid6`, `effectid7`, `effectid8`, `effectid9`, `effectid10`, `effectid11`, `effectid12`) - ) -UNION ALL - SELECT 'MAGICIAN' caster_class, `classes13` spell_level, - `targettype`, `CastRestriction`, `zonetype`, `id`, `name`, `mana`, - `effectid1`, `effectid2`, `effectid3`, `effectid4`, `effectid5`, `effectid6`, `effectid7`, `effectid8`, `effectid9`, `effectid10`, `effectid11`, `effectid12` - FROM `spells_new` - WHERE `classes13` NOT IN ('254', '255') - AND `SpellAffectIndex` = '2' --- 6-self, 14-pet, 39-groupnopets, 46-targetstarget - AND `targettype` NOT IN ('6', '14', '39', '46') - AND ( - - '46' IN (`effectid1`, `effectid2`, `effectid3`, `effectid4`, `effectid5`, `effectid6`, `effectid7`, `effectid8`, `effectid9`, `effectid10`, `effectid11`, `effectid12`) - OR '47' IN (`effectid1`, `effectid2`, `effectid3`, `effectid4`, `effectid5`, `effectid6`, `effectid7`, `effectid8`, `effectid9`, `effectid10`, `effectid11`, `effectid12`) - OR '48' IN (`effectid1`, `effectid2`, `effectid3`, `effectid4`, `effectid5`, `effectid6`, `effectid7`, `effectid8`, `effectid9`, `effectid10`, `effectid11`, `effectid12`) - OR '49' IN (`effectid1`, `effectid2`, `effectid3`, `effectid4`, `effectid5`, `effectid6`, `effectid7`, `effectid8`, `effectid9`, `effectid10`, `effectid11`, `effectid12`) - OR '50' IN (`effectid1`, `effectid2`, `effectid3`, `effectid4`, `effectid5`, `effectid6`, `effectid7`, `effectid8`, `effectid9`, `effectid10`, `effectid11`, `effectid12`) - OR '370' IN (`effectid1`, `effectid2`, `effectid3`, `effectid4`, `effectid5`, `effectid6`, `effectid7`, `effectid8`, `effectid9`, `effectid10`, `effectid11`, `effectid12`) - ) -UNION ALL - SELECT 'ENCHANTER' caster_class, `classes14` spell_level, - `targettype`, `CastRestriction`, `zonetype`, `id`, `name`, `mana`, - `effectid1`, `effectid2`, `effectid3`, `effectid4`, `effectid5`, `effectid6`, `effectid7`, `effectid8`, `effectid9`, `effectid10`, `effectid11`, `effectid12` - FROM `spells_new` - WHERE `classes14` NOT IN ('254', '255') - AND `SpellAffectIndex` = '2' --- 6-self, 14-pet, 39-groupnopets, 46-targetstarget - AND `targettype` NOT IN ('6', '14', '39', '46') - AND ( - - '46' IN (`effectid1`, `effectid2`, `effectid3`, `effectid4`, `effectid5`, `effectid6`, `effectid7`, `effectid8`, `effectid9`, `effectid10`, `effectid11`, `effectid12`) - OR '47' IN (`effectid1`, `effectid2`, `effectid3`, `effectid4`, `effectid5`, `effectid6`, `effectid7`, `effectid8`, `effectid9`, `effectid10`, `effectid11`, `effectid12`) - OR '48' IN (`effectid1`, `effectid2`, `effectid3`, `effectid4`, `effectid5`, `effectid6`, `effectid7`, `effectid8`, `effectid9`, `effectid10`, `effectid11`, `effectid12`) - OR '49' IN (`effectid1`, `effectid2`, `effectid3`, `effectid4`, `effectid5`, `effectid6`, `effectid7`, `effectid8`, `effectid9`, `effectid10`, `effectid11`, `effectid12`) - OR '50' IN (`effectid1`, `effectid2`, `effectid3`, `effectid4`, `effectid5`, `effectid6`, `effectid7`, `effectid8`, `effectid9`, `effectid10`, `effectid11`, `effectid12`) - OR '370' IN (`effectid1`, `effectid2`, `effectid3`, `effectid4`, `effectid5`, `effectid6`, `effectid7`, `effectid8`, `effectid9`, `effectid10`, `effectid11`, `effectid12`) - ) -UNION ALL - SELECT 'BEASTLORD' caster_class, `classes15` spell_level, - `targettype`, `CastRestriction`, `zonetype`, `id`, `name`, `mana`, - `effectid1`, `effectid2`, `effectid3`, `effectid4`, `effectid5`, `effectid6`, `effectid7`, `effectid8`, `effectid9`, `effectid10`, `effectid11`, `effectid12` - FROM `spells_new` - WHERE `classes15` NOT IN ('254', '255') - AND `SpellAffectIndex` = '2' --- 6-self, 14-pet, 39-groupnopets, 46-targetstarget - AND `targettype` NOT IN ('6', '14', '39', '46') - AND ( - - '46' IN (`effectid1`, `effectid2`, `effectid3`, `effectid4`, `effectid5`, `effectid6`, `effectid7`, `effectid8`, `effectid9`, `effectid10`, `effectid11`, `effectid12`) - OR '47' IN (`effectid1`, `effectid2`, `effectid3`, `effectid4`, `effectid5`, `effectid6`, `effectid7`, `effectid8`, `effectid9`, `effectid10`, `effectid11`, `effectid12`) - OR '48' IN (`effectid1`, `effectid2`, `effectid3`, `effectid4`, `effectid5`, `effectid6`, `effectid7`, `effectid8`, `effectid9`, `effectid10`, `effectid11`, `effectid12`) - OR '49' IN (`effectid1`, `effectid2`, `effectid3`, `effectid4`, `effectid5`, `effectid6`, `effectid7`, `effectid8`, `effectid9`, `effectid10`, `effectid11`, `effectid12`) - OR '50' IN (`effectid1`, `effectid2`, `effectid3`, `effectid4`, `effectid5`, `effectid6`, `effectid7`, `effectid8`, `effectid9`, `effectid10`, `effectid11`, `effectid12`) - OR '370' IN (`effectid1`, `effectid2`, `effectid3`, `effectid4`, `effectid5`, `effectid6`, `effectid7`, `effectid8`, `effectid9`, `effectid10`, `effectid11`, `effectid12`) - ) -) spells - --- WHERE `name` NOT LIKE '%II' --- --- --- WHERE `name` NOT LIKE '%Rk. II%' --- AND `name` NOT LIKE '%Rk.II%' --- AND `name` NOT LIKE '%Rk. III%' --- AND `name` NOT LIKE '%Rk.III%' -ORDER BY FIELD(target_type, 'Single', 'GroupV1', 'GroupV2'), - spell_level DESC, - resist_type DESC, - FIELD(caster_class, 'CLERIC', 'PALADIN', 'RANGER', 'SHADOWKNIGHT', 'DRUID', 'SHAMAN', 'NECROMANCER', 'MAGICIAN', 'ENCHANTER', 'BEASTLORD') diff --git a/utils/scripts/bot_command_spell_scripts/resurrect_spells.sql b/utils/scripts/bot_command_spell_scripts/resurrect_spells.sql deleted file mode 100644 index ac5903727..000000000 --- a/utils/scripts/bot_command_spell_scripts/resurrect_spells.sql +++ /dev/null @@ -1,71 +0,0 @@ -SELECT --- base - CASE - WHEN `targettype` = '4' AND `CastRestriction` = '0' THEN 'AECaster' - WHEN `targettype` = '15' AND `CastRestriction` = '0' THEN 'Corpse' - ELSE CONCAT(`targettype`, ', ', `CastRestriction`) -- 'UNDEFINED' - END target_type, - CASE - WHEN `zonetype` NOT IN ('-1', '0') THEN `zonetype` - ELSE '0' - END zone_type, - caster_class, - spell_level, - `id` spell_id, - CONCAT('"', `name`, '"') spell_name, - `mana` mana_cost, --- base --- extra - `effect_base_value1` percent --- extra - -FROM ( - SELECT 'CLERIC' caster_class, `classes2` spell_level, - `targettype`, `CastRestriction`, `zonetype`, `id`, `name`, `mana`, `effect_base_value1` - FROM `spells_new` - WHERE `classes2` NOT IN ('254', '255') - AND `SpellAffectIndex` IN ('1', '13') - AND `effectid1` = '81' -UNION ALL - SELECT 'PALADIN' caster_class, `classes3` spell_level, - `targettype`, `CastRestriction`, `zonetype`, `id`, `name`, `mana`, `effect_base_value1` - FROM `spells_new` - WHERE `classes3` NOT IN ('254', '255') - AND `SpellAffectIndex` IN ('1', '13') - AND `effectid1` = '81' -UNION ALL - SELECT 'DRUID' caster_class, `classes6` spell_level, - `targettype`, `CastRestriction`, `zonetype`, `id`, `name`, `mana`, `effect_base_value1` - FROM `spells_new` - WHERE `classes6` NOT IN ('254', '255') - AND `SpellAffectIndex` IN ('1', '13') - AND `effectid1` = '81' -UNION ALL - SELECT 'SHAMAN' caster_class, `classes10` spell_level, - `targettype`, `CastRestriction`, `zonetype`, `id`, `name`, `mana`, `effect_base_value1` - FROM `spells_new` - WHERE `classes10` NOT IN ('254', '255') - AND `SpellAffectIndex` IN ('1', '13') - AND `effectid1` = '81' -UNION ALL - SELECT 'NECROMANCER' caster_class, `classes11` spell_level, - `targettype`, `CastRestriction`, `zonetype`, `id`, `name`, `mana`, `effect_base_value1` - FROM `spells_new` - WHERE `classes11` NOT IN ('254', '255') - AND `SpellAffectIndex` IN ('1', '13') - AND `effectid1` = '81' -) spells - --- WHERE `name` NOT LIKE '%II' --- --- --- WHERE `name` NOT LIKE '%Rk. II%' --- AND `name` NOT LIKE '%Rk.II%' --- AND `name` NOT LIKE '%Rk. III%' --- AND `name` NOT LIKE '%Rk.III%' -ORDER BY percent DESC, - FIELD(target_type, 'Corpse', 'AETarget'), - zone_type, - FIELD(caster_class, 'CLERIC', 'PALADIN', 'DRUID', 'SHAMAN', 'NECROMANCER'), - spell_level, - spell_id, - spell_name diff --git a/utils/scripts/bot_command_spell_scripts/rune_spells.sql b/utils/scripts/bot_command_spell_scripts/rune_spells.sql deleted file mode 100644 index 30ebee130..000000000 --- a/utils/scripts/bot_command_spell_scripts/rune_spells.sql +++ /dev/null @@ -1,40 +0,0 @@ -SELECT --- base - CASE - WHEN `targettype` = '3' AND `CastRestriction` = '0' THEN 'GroupV1' - WHEN `targettype` = '5' AND `CastRestriction` = '0' THEN 'Single' - WHEN `targettype` = '41' AND `CastRestriction` = '0' THEN 'GroupV2' - ELSE CONCAT(`targettype`, ', ', `CastRestriction`) -- 'UNDEFINED' - END target_type, - CASE - WHEN `zonetype` NOT IN ('-1', '0') THEN `zonetype` - ELSE '0' - END zone_type, - caster_class, - spell_level, - `id` spell_id, - CONCAT('"', `name`, '"') spell_name, - `mana` mana_cost, --- base --- extra - `max1` max_absorbtion --- extra - -FROM ( - SELECT 'ENCHANTER' caster_class, `classes14` spell_level, - `targettype`, `CastRestriction`, `zonetype`, `id`, `name`, `mana`, `max1` - FROM `spells_new` - WHERE `classes14` NOT IN ('254', '255') - AND `SpellAffectIndex` = '2' - AND `effectid1` = '55' -) spells - --- WHERE `name` NOT LIKE '%II' --- --- --- WHERE `name` NOT LIKE '%Rk. II%' --- AND `name` NOT LIKE '%Rk.II%' --- AND `name` NOT LIKE '%Rk. III%' --- AND `name` NOT LIKE '%Rk.III%' -ORDER BY FIELD(target_type, 'Single', 'GroupV1', 'GroupV2'), - spell_level DESC, - max1 DESC diff --git a/utils/scripts/bot_command_spell_scripts/shrink_spells.sql b/utils/scripts/bot_command_spell_scripts/shrink_spells.sql deleted file mode 100644 index 26ee84883..000000000 --- a/utils/scripts/bot_command_spell_scripts/shrink_spells.sql +++ /dev/null @@ -1,49 +0,0 @@ -SELECT --- base - CASE - WHEN `targettype` = '5' AND `CastRestriction` = '0' THEN 'Single' - ELSE CONCAT(`targettype`, ', ', `CastRestriction`) -- 'UNDEFINED' - END target_type, - CASE - WHEN `zonetype` NOT IN ('-1', '0') THEN `zonetype` - ELSE '0' - END zone_type, - caster_class, - spell_level, - `id` spell_id, - CONCAT('"', `name`, '"') spell_name, - `mana` mana_cost --- base - -FROM ( - SELECT 'SHAMAN' caster_class, `classes10` spell_level, - `targettype`, `CastRestriction`, `zonetype`, `id`, `name`, `mana` - FROM `spells_new` - WHERE `classes10` NOT IN ('254', '255') - AND `SpellAffectIndex` = '10' --- 6-self - AND `targettype` NOT IN ('6') - AND `effectid1` = '89' -- implementation restricted to `effectid1` - AND `effect_base_value1` < 100 -- implementation restricted to `effect_base_value1` -UNION ALL - SELECT 'BEASTLORD' caster_class, `classes15` spell_level, - `targettype`, `CastRestriction`, `zonetype`, `id`, `name`, `mana` - FROM `spells_new` - WHERE `classes15` NOT IN ('254', '255') - AND `SpellAffectIndex` = '10' --- 6-self - AND `targettype` NOT IN ('6') - AND `effectid1` = '89' -- implementation restricted to `effectid1` - AND `effect_base_value1` < 100 -- implementation restricted to `effect_base_value1` -) spells - --- WHERE `name` NOT LIKE '%II' --- --- --- WHERE `name` NOT LIKE '%Rk. II%' --- AND `name` NOT LIKE '%Rk.II%' --- AND `name` NOT LIKE '%Rk. III%' --- AND `name` NOT LIKE '%Rk.III%' -ORDER BY FIELD(target_type, 'Single'), - FIELD(caster_class, 'SHAMAN', 'BEASTLORD'), - spell_level, - spell_name diff --git a/utils/scripts/bot_command_spell_scripts/water_breathing_spells.sql b/utils/scripts/bot_command_spell_scripts/water_breathing_spells.sql deleted file mode 100644 index b6f815429..000000000 --- a/utils/scripts/bot_command_spell_scripts/water_breathing_spells.sql +++ /dev/null @@ -1,84 +0,0 @@ -SELECT --- base - CASE - WHEN `targettype` = '5' AND `CastRestriction` = '0' THEN 'Single' - WHEN `targettype` = '41' AND `CastRestriction` = '0' THEN 'GroupV2' - ELSE CONCAT(`targettype`, ', ', `CastRestriction`) -- 'UNDEFINED' - END target_type, - CASE - WHEN `zonetype` NOT IN ('-1', '0') THEN `zonetype` - ELSE '0' - END zone_type, - caster_class, - spell_level, - `id` spell_id, - CONCAT('"', `name`, '"') spell_name, - `mana` mana_cost --- base - -FROM ( - SELECT 'RANGER' caster_class, `classes4` spell_level, - `targettype`, `CastRestriction`, `zonetype`, `id`, `name`, `mana` - FROM `spells_new` - WHERE `classes4` NOT IN ('254', '255') - AND `SpellAffectIndex` IN ('2', '14') --- 6-self - AND `targettype` NOT IN ('6') - AND `effectid1` = '14' -UNION ALL - SELECT 'DRUID' caster_class, `classes6` spell_level, - `targettype`, `CastRestriction`, `zonetype`, `id`, `name`, `mana` - FROM `spells_new` - WHERE `classes6` NOT IN ('254', '255') - AND `SpellAffectIndex` IN ('2', '14') --- 6-self - AND `targettype` NOT IN ('6') - AND `effectid1` = '14' -UNION ALL - SELECT 'SHAMAN' caster_class, `classes10` spell_level, - `targettype`, `CastRestriction`, `zonetype`, `id`, `name`, `mana` - FROM `spells_new` - WHERE `classes10` NOT IN ('254', '255') - AND `SpellAffectIndex` IN ('2', '14') --- 6-self - AND `targettype` NOT IN ('6') - AND `effectid1` = '14' -UNION ALL - SELECT 'NECROMANCER' caster_class, `classes11` spell_level, - `targettype`, `CastRestriction`, `zonetype`, `id`, `name`, `mana` - FROM `spells_new` - WHERE `classes11` NOT IN ('254', '255') - AND `SpellAffectIndex` IN ('2', '14') --- 6-self - AND `targettype` NOT IN ('6') - AND `effectid1` = '14' -UNION ALL - SELECT 'ENCHANTER' caster_class, `classes14` spell_level, - `targettype`, `CastRestriction`, `zonetype`, `id`, `name`, `mana` - FROM `spells_new` - WHERE `classes14` NOT IN ('254', '255') - AND `SpellAffectIndex` IN ('2', '14') --- 6-self - AND `targettype` NOT IN ('6') - AND `effectid1` = '14' -UNION ALL - SELECT 'BEASTLORD' caster_class, `classes15` spell_level, - `targettype`, `CastRestriction`, `zonetype`, `id`, `name`, `mana` - FROM `spells_new` - WHERE `classes15` NOT IN ('254', '255') - AND `SpellAffectIndex` IN ('2', '14') --- 6-self - AND `targettype` NOT IN ('6') - AND `effectid1` = '14' -) spells - --- WHERE `name` NOT LIKE '%II' --- --- --- WHERE `name` NOT LIKE '%Rk. II%' --- AND `name` NOT LIKE '%Rk.II%' --- AND `name` NOT LIKE '%Rk. III%' --- AND `name` NOT LIKE '%Rk.III%' -ORDER BY FIELD(target_type, 'Single', 'GroupV2'), - spell_level, - spell_name, - FIELD(caster_class, 'RANGER', 'DRUID', 'SHAMAN', 'NECROMANCER', 'ENCHANTER', 'BEASTLORD') From 87d92fe809478a1214ec55027e8b2de602d62b0c Mon Sep 17 00:00:00 2001 From: Uleat Date: Sun, 20 Mar 2016 17:27:08 -0400 Subject: [PATCH 53/56] Update to #myskills to show proper 'Piercing' skill - 1HPiercing will still show if there is a value..but, will not be available for use if your class doesn't support it. --- common/skills.cpp | 86 +++++++++++++++++++++++++++++++++++++++++++++++ common/skills.h | 4 +++ zone/client.cpp | 43 ++++++++++-------------- 3 files changed, 107 insertions(+), 26 deletions(-) diff --git a/common/skills.cpp b/common/skills.cpp index 85c660f6c..987004a2a 100644 --- a/common/skills.cpp +++ b/common/skills.cpp @@ -106,3 +106,89 @@ bool EQEmu::IsBardInstrumentSkill(SkillUseTypes skill) return false; } } + +const std::map& EQEmu::GetSkillUseTypesMap() +{ + static const std::map skill_use_types_map = { + { Skill1HBlunt, "1H Blunt" }, + { Skill1HSlashing, "1H Slashing" }, + { Skill2HBlunt, "2H Blunt" }, + { Skill2HSlashing, "2H Slashing" }, + { SkillAbjuration, "Abjuration" }, + { SkillAlteration, "Alteration" }, + { SkillApplyPoison, "Apply Poison" }, + { SkillArchery, "Archery" }, + { SkillBackstab, "Backstab" }, + { SkillBindWound, "Bind Wound" }, + { SkillBash, "Bash" }, + { SkillBlock, "Block" }, + { SkillBrassInstruments, "Brass Instruments" }, + { SkillChanneling, "Channeling" }, + { SkillConjuration, "Conjuration" }, + { SkillDefense, "Defense" }, + { SkillDisarm, "Disarm" }, + { SkillDisarmTraps, "Disarm Traps" }, + { SkillDivination, "Divination" }, + { SkillDodge, "Dodge" }, + { SkillDoubleAttack, "Double Attack" }, + { SkillDragonPunch, "Dragon Punch" }, + { SkillDualWield, "Dual Wield" }, + { SkillEagleStrike, "Eagle Strike" }, + { SkillEvocation, "Evocation" }, + { SkillFeignDeath, "Feign Death" }, + { SkillFlyingKick, "Flying Kick" }, + { SkillForage, "Forage" }, + { SkillHandtoHand, "Hand to Hand" }, + { SkillHide, "Hide" }, + { SkillKick, "Kick" }, + { SkillMeditate, "Meditate" }, + { SkillMend, "Mend" }, + { SkillOffense, "Offense" }, + { SkillParry, "Parry" }, + { SkillPickLock, "Pick Lock" }, + { Skill1HPiercing, "1H Piercing" }, + { SkillRiposte, "Riposte" }, + { SkillRoundKick, "Round Kick" }, + { SkillSafeFall, "Safe Fall" }, + { SkillSenseHeading, "Sense Heading" }, + { SkillSinging, "Singing" }, + { SkillSneak, "Sneak" }, + { SkillSpecializeAbjure, "Specialize Abjuration" }, + { SkillSpecializeAlteration, "Specialize Alteration" }, + { SkillSpecializeConjuration, "Specialize Conjuration" }, + { SkillSpecializeDivination, "Specialize Divination" }, + { SkillSpecializeEvocation, "Specialize Evocation" }, + { SkillPickPockets, "Pick Pockets" }, + { SkillStringedInstruments, "Stringed Instruments" }, + { SkillSwimming, "Swimming" }, + { SkillThrowing, "Throwing" }, + { SkillTigerClaw, "Tiger Claw" }, + { SkillTracking, "Tracking" }, + { SkillWindInstruments, "Wind Instruments" }, + { SkillFishing, "Fishing" }, + { SkillMakePoison, "Make Poison" }, + { SkillTinkering, "Tinkering" }, + { SkillResearch, "Research" }, + { SkillAlchemy, "Alchemy" }, + { SkillBaking, "Baking" }, + { SkillTailoring, "Tailoring" }, + { SkillSenseTraps, "Sense Traps" }, + { SkillBlacksmithing, "Blacksmithing" }, + { SkillFletching, "Fletching" }, + { SkillBrewing, "Brewing" }, + { SkillAlcoholTolerance, "Alcohol Tolerance" }, + { SkillBegging, "Begging" }, + { SkillJewelryMaking, "Jewelry Making" }, + { SkillPottery, "Pottery" }, + { SkillPercussionInstruments, "Percussion Instruments" }, + { SkillIntimidation, "Intimidation" }, + { SkillBerserking, "Berserking" }, + { SkillTaunt, "Taunt" }, + { SkillFrenzy, "Frenzy" }, + { SkillRemoveTraps, "Remove Traps" }, + { SkillTripleAttack, "Triple Attack" }, + { Skill2HPiercing, "2H Piercing" } + }; + + return skill_use_types_map; +} diff --git a/common/skills.h b/common/skills.h index 4e1e9eb83..a9c5c6095 100644 --- a/common/skills.h +++ b/common/skills.h @@ -18,6 +18,8 @@ #ifndef SKILLS_H #define SKILLS_H +#include + /* ** This is really messed up... Are we using SkillTypes as a pseudo repository? The 76th skill really throws ** things for standardization... @@ -273,6 +275,8 @@ namespace EQEmu { bool IsSpecializedSkill(SkillUseTypes skill); float GetSkillMeleePushForce(SkillUseTypes skill); bool IsBardInstrumentSkill(SkillUseTypes skill); + + const std::map& GetSkillUseTypesMap(); } #endif diff --git a/zone/client.cpp b/zone/client.cpp index 5a9724fa8..f41e35bd2 100644 --- a/zone/client.cpp +++ b/zone/client.cpp @@ -4950,36 +4950,27 @@ void Client::ShowSkillsWindow() { const char *WindowTitle = "Skills"; std::string WindowText; - // using a map for easy alphabetizing of the skills list - std::map Skills; - std::map::iterator it; + std::map Skills = EQEmu::GetSkillUseTypesMap(); - // this list of names must keep the same order as that in common/skills.h - const char* SkillName[] = {"1H Blunt","1H Slashing","2H Blunt","2H Slashing","Abjuration","Alteration","Apply Poison","Archery", - "Backstab","Bind Wound","Bash","Block","Brass Instruments","Channeling","Conjuration","Defense","Disarm","Disarm Traps","Divination", - "Dodge","Double Attack","Dragon Punch","Dual Wield","Eagle Strike","Evocation","Feign Death","Flying Kick","Forage","Hand to Hand", - "Hide","Kick","Meditate","Mend","Offense","Parry","Pick Lock","1H Piercing","Ripost","Round Kick","Safe Fall","Sense Heading", - "Singing","Sneak","Specialize Abjuration","Specialize Alteration","Specialize Conjuration","Specialize Divination","Specialize Evocation","Pick Pockets", - "Stringed Instruments","Swimming","Throwing","Tiger Claw","Tracking","Wind Instruments","Fishing","Make Poison","Tinkering","Research", - "Alchemy","Baking","Tailoring","Sense Traps","Blacksmithing","Fletching","Brewing","Alcohol Tolerance","Begging","Jewelry Making", - "Pottery","Percussion Instruments","Intimidation","Berserking","Taunt","Frenzy","Remove Traps","Triple Attack","2H Piercing"}; - for(int i = 0; i <= (int)HIGHEST_SKILL; i++) - Skills[SkillName[i]] = (SkillUseTypes)i; + if (GetClientVersion() < ClientVersion::RoF2) + Skills[Skill1HPiercing] = "Piercing"; // print out all available skills - for(it = Skills.begin(); it != Skills.end(); ++it) { - if(GetSkill(it->second) > 0 || MaxSkill(it->second) > 0) { - WindowText += it->first; - // line up the values - for (int j = 0; j < EmuConstants::ITEM_COMMON_SIZE; j++) - WindowText += " "; - WindowText += itoa(this->GetSkill(it->second)); - if (MaxSkill(it->second) > 0) { - WindowText += "/"; - WindowText += itoa(this->GetMaxSkillAfterSpecializationRules(it->second,this->MaxSkill(it->second))); - } - WindowText += "
"; + for (auto skills_iter : Skills) { + if (skills_iter.first == Skill2HPiercing && GetClientVersion() < ClientVersion::RoF2) + continue; + if (!GetSkill(skills_iter.first) && !MaxSkill(skills_iter.first)) + continue; + + WindowText += skills_iter.second; + // line up the values + WindowText += "      "; + WindowText += itoa(this->GetSkill(skills_iter.first)); + if (MaxSkill(skills_iter.first) > 0) { + WindowText += "/"; + WindowText += itoa(this->GetMaxSkillAfterSpecializationRules(skills_iter.first, this->MaxSkill(skills_iter.first))); } + WindowText += "
"; } this->SendPopupToClient(WindowTitle, WindowText.c_str()); } From 5c812fb824c3a3314847df5508fec97e606c99ed Mon Sep 17 00:00:00 2001 From: Uleat Date: Sun, 20 Mar 2016 17:51:09 -0400 Subject: [PATCH 54/56] Fix for gcc fail --- common/skills.h | 96 +------------------------------------------------ 1 file changed, 1 insertion(+), 95 deletions(-) diff --git a/common/skills.h b/common/skills.h index a9c5c6095..5ffba33b9 100644 --- a/common/skills.h +++ b/common/skills.h @@ -18,15 +18,9 @@ #ifndef SKILLS_H #define SKILLS_H +#include #include -/* -** This is really messed up... Are we using SkillTypes as a pseudo repository? The 76th skill really throws -** things for standardization... -** -** Below is an attempt to clean this up a little... -*/ - /* ** Skill use types ** @@ -180,94 +174,6 @@ enum SkillUseTypes // server profile does not reflect this yet..so, prefixed with 'PACKET_' #define PACKET_SKILL_ARRAY_SIZE 100 -// TODO: add string return for skill names - -/* -** Old typedef enumeration -** -*/ -/* Correct Skill Numbers as of 4-14-2002 -typedef enum { - _1H_BLUNT = 0, - _1H_SLASHING = 1, - _2H_BLUNT = 2, - _2H_SLASHING = 3, - ABJURE = 4, - ALTERATION = 5, - APPLY_POISON = 6, - ARCHERY = 7, - BACKSTAB = 8, - BIND_WOUND = 9, - BASH = 10, - BLOCKSKILL = 11, - BRASS_INSTRUMENTS = 12, - CHANNELING = 13, - CONJURATION = 14, - DEFENSE = 15, - DISARM = 16, - DISARM_TRAPS = 17, - DIVINATION = 18, - DODGE = 19, - DOUBLE_ATTACK = 20, - DRAGON_PUNCH = 21, //aka Tail Rake - DUAL_WIELD = 22, - EAGLE_STRIKE = 23, - EVOCATION = 24, - FEIGN_DEATH = 25, - FLYING_KICK = 26, - FORAGE = 27, - HAND_TO_HAND = 28, - HIDE = 29, - KICK = 30, - MEDITATE = 31, - MEND = 32, - OFFENSE = 33, - PARRY = 34, - PICK_LOCK = 35, - PIERCING = 36, - RIPOSTE = 37, - ROUND_KICK = 38, - SAFE_FALL = 39, - SENSE_HEADING = 40, - SINGING = 41, - SNEAK = 42, - SPECIALIZE_ABJURE = 43, - SPECIALIZE_ALTERATION = 44, - SPECIALIZE_CONJURATION = 45, - SPECIALIZE_DIVINATION = 46, - SPECIALIZE_EVOCATION = 47, - PICK_POCKETS = 48, - STRINGED_INSTRUMENTS = 49, - SWIMMING = 50, - THROWING = 51, - TIGER_CLAW = 52, - TRACKING = 53, - WIND_INSTRUMENTS = 54, - FISHING = 55, - MAKE_POISON = 56, - TINKERING = 57, - RESEARCH = 58, - ALCHEMY = 59, - BAKING = 60, - TAILORING = 61, - SENSE_TRAPS = 62, - BLACKSMITHING = 63, - FLETCHING = 64, - BREWING = 65, - ALCOHOL_TOLERANCE = 66, - BEGGING = 67, - JEWELRY_MAKING = 68, - POTTERY = 69, - PERCUSSION_INSTRUMENTS = 70, - INTIMIDATION = 71, - BERSERKING = 72, - TAUNT = 73, - FRENZY = 74, - GENERIC_TRADESKILL = 75 -} SkillType; - -#define HIGHEST_SKILL FRENZY -*/ // for skill related helper functions namespace EQEmu { From 48425834268bf6d5cfff115983cf2f7444f30513 Mon Sep 17 00:00:00 2001 From: Uleat Date: Sun, 20 Mar 2016 20:09:14 -0400 Subject: [PATCH 55/56] Added some markers for skills.h and eq_constants.h enumerations --- common/eq_constants.h | 96 +++++++++++++++++++++---------------------- common/skills.h | 34 +++++++-------- 2 files changed, 65 insertions(+), 65 deletions(-) diff --git a/common/eq_constants.h b/common/eq_constants.h index add66c2f4..728013eba 100644 --- a/common/eq_constants.h +++ b/common/eq_constants.h @@ -32,17 +32,17 @@ enum LightTypes lightTypeTorch, lightTypeTinyGlowingSkull, lightTypeSmallLantern, - lightTypeSteinOfMoggok, + lightTypeSteinOfMoggok, // 5 lightTypeLargeLantern, lightTypeFlamelessLantern, lightTypeGlobeOfStars, lightTypeLightGlobe, - lightTypeLightstone, + lightTypeLightstone, // 10 lightTypeGreaterLightstone, lightTypeFireBeetleEye, lightTypeColdlight, lightTypeUnknown1, - lightTypeUnknown2 + lightTypeUnknown2 // 15 }; #define LIGHT_TYPES_COUNT 16 @@ -58,12 +58,12 @@ enum LightLevels lightLevelTorch, lightLevelSmallMagic, lightLevelRedLight, - lightLevelBlueLight, + lightLevelBlueLight, // 5 lightLevelSmallLantern, lightLevelMagicLantern, lightLevelLargeLantern, lightLevelLargeMagic, - lightLevelBrilliant + lightLevelBrilliant // 10 }; #define LIGHT_LEVELS_COUNT 11 @@ -111,62 +111,62 @@ enum ItemUseTypes : uint8 /*9140*/ ItemType1HPiercing, /*9139*/ ItemType1HBlunt, /*9142*/ ItemType2HBlunt, -/*5504*/ ItemTypeBow, +/*5504*/ ItemTypeBow, // 5 /*----*/ ItemTypeUnknown1, /*----*/ ItemTypeLargeThrowing, /*5505*/ ItemTypeShield, /*5506*/ ItemTypeScroll, -/*5507*/ ItemTypeArmor, +/*5507*/ ItemTypeArmor, // 10 /*5508*/ ItemTypeMisc, // a lot of random crap has this item use. /*7564*/ ItemTypeLockPick, /*----*/ ItemTypeUnknown2, /*5509*/ ItemTypeFood, -/*5510*/ ItemTypeDrink, +/*5510*/ ItemTypeDrink, // 15 /*5511*/ ItemTypeLight, /*5512*/ ItemTypeCombinable, // not all stackable items are this use... /*5513*/ ItemTypeBandage, /*----*/ ItemTypeSmallThrowing, -/*----*/ ItemTypeSpell, // spells and tomes +/*----*/ ItemTypeSpell, // 20 // spells and tomes /*5514*/ ItemTypePotion, /*----*/ ItemTypeUnknown3, /*0406*/ ItemTypeWindInstrument, /*0407*/ ItemTypeStringedInstrument, -/*0408*/ ItemTypeBrassInstrument, +/*0408*/ ItemTypeBrassInstrument, // 25 /*0405*/ ItemTypePercussionInstrument, /*5515*/ ItemTypeArrow, /*----*/ ItemTypeUnknown4, /*5521*/ ItemTypeJewelry, -/*----*/ ItemTypeSkull, +/*----*/ ItemTypeSkull, // 30 /*5516*/ ItemTypeBook, // skill-up tomes/books? (would probably need a pp flag if true...) /*5517*/ ItemTypeNote, /*5518*/ ItemTypeKey, /*----*/ ItemTypeCoin, -/*5520*/ ItemType2HPiercing, +/*5520*/ ItemType2HPiercing, // 35 /*----*/ ItemTypeFishingPole, /*----*/ ItemTypeFishingBait, /*5519*/ ItemTypeAlcohol, /*----*/ ItemTypeKey2, // keys and satchels?? (questable keys?) -/*----*/ ItemTypeCompass, +/*----*/ ItemTypeCompass, // 40 /*----*/ ItemTypeUnknown5, /*----*/ ItemTypePoison, // might be wrong, but includes poisons /*----*/ ItemTypeUnknown6, /*----*/ ItemTypeUnknown7, -/*5522*/ ItemTypeMartial, +/*5522*/ ItemTypeMartial, // 45 /*----*/ ItemTypeUnknown8, /*----*/ ItemTypeUnknown9, /*----*/ ItemTypeUnknown10, /*----*/ ItemTypeUnknown11, -/*----*/ ItemTypeSinging, +/*----*/ ItemTypeSinging, // 50 /*5750*/ ItemTypeAllInstrumentTypes, /*5776*/ ItemTypeCharm, /*----*/ ItemTypeDye, /*----*/ ItemTypeAugmentation, -/*----*/ ItemTypeAugmentationSolvent, +/*----*/ ItemTypeAugmentationSolvent, // 55 /*----*/ ItemTypeAugmentationDistiller, /*----*/ ItemTypeUnknown12, /*----*/ ItemTypeFellowshipKit, /*----*/ ItemTypeUnknown13, -/*----*/ ItemTypeRecipe, +/*----*/ ItemTypeRecipe, // 60 /*----*/ ItemTypeAdvancedRecipe, /*----*/ ItemTypeJournal, // only one(1) database entry /*----*/ ItemTypeAltCurrency, // alt-currency (as opposed to coinage) @@ -237,32 +237,32 @@ enum AugmentationUseTypes : uint8 { AugTypeGeneralMultipleStat, AugTypeGeneralSpellEffect, AugTypeWeaponGeneral, - AugTypeWeaponElemDamage, + AugTypeWeaponElemDamage, // 5 AugTypeWeaponBaseDamage, AugTypeGeneralGroup, AugTypeGeneralRaid, AugTypeGeneralDragonsPoints, - AugTypeCraftedCommon, + AugTypeCraftedCommon, // 10 AugTypeCraftedGroup1, AugTypeCraftedRaid1, AugTypeEnergeiacGroup, AugTypeEnergeiacRaid, - AugTypeEmblem, + AugTypeEmblem, // 15 AugTypeCraftedGroup2, AugTypeCraftedRaid2, AugTypeUnknown1, AugTypeUnknown2, - AugTypeOrnamentation, + AugTypeOrnamentation, // 20 AugTypeSpecialOrnamentation, AugTypeUnknown3, AugTypeUnknown4, AugTypeUnknown5, - AugTypeUnknown6, + AugTypeUnknown6, // 25 AugTypeUnknown7, AugTypeUnknown8, AugTypeUnknown9, AugTypeUnknown10, - AugTypeEpic25, + AugTypeEpic25, // 30 AugTypeTest, _AugTypeCount, AugTypeAll = 255 @@ -280,17 +280,17 @@ enum AugmentationRestrictionTypes : uint8 { /*9135*/ AugRestrWeapons, /*9136*/ AugRestr1HWeapons, /*9137*/ AugRestr2HWeapons, -/*9138*/ AugRestr1HSlash, +/*9138*/ AugRestr1HSlash, // 5 /*9139*/ AugRestr1HBlunt, /*9140*/ AugRestrPiercing, /*9148*/ AugRestrHandToHand, /*9141*/ AugRestr2HSlash, -/*9142*/ AugRestr2HBlunt, +/*9142*/ AugRestr2HBlunt, // 10 /*9143*/ AugRestr2HPierce, /*9144*/ AugRestrBows, /*9145*/ AugRestrShields, /*8052*/ AugRestr1HSlash1HBluntOrHandToHand, -/*9200*/ AugRestr1HBluntOrHandToHand, // no listed peq entries +/*9200*/ AugRestr1HBluntOrHandToHand, // 15 // no listed peq entries // these three appear to be post-RoF (12-10-2012) and can not be verified until RoF (05-10-2013) is supported /*????*/ AugRestrUnknown1, @@ -317,57 +317,57 @@ enum ContainerUseTypes : uint8 /*3402*/ BagTypeQuiver, /*3403*/ BagTypeBeltPouch, /*3404*/ BagTypeWristPouch, -/*3405*/ BagTypeBackPack, +/*3405*/ BagTypeBackPack, // 5 /*3406*/ BagTypeSmallChest, /*3407*/ BagTypeLargeChest, /*----*/ BagTypeBandolier, // <*Database Reference Only> /*3408*/ BagTypeMedicineBag, -/*3409*/ BagTypeToolBox, +/*3409*/ BagTypeToolBox, // 10 /*3410*/ BagTypeLexicon, /*3411*/ BagTypeMortar, /*3412*/ BagTypeSelfDusting, // Quest container (Auto-clear contents?) /*3413*/ BagTypeMixingBowl, -/*3414*/ BagTypeOven, +/*3414*/ BagTypeOven, // 15 /*3415*/ BagTypeSewingKit, /*3416*/ BagTypeForge, /*3417*/ BagTypeFletchingKit, /*3418*/ BagTypeBrewBarrel, -/*3419*/ BagTypeJewelersKit, +/*3419*/ BagTypeJewelersKit, // 20 /*3420*/ BagTypePotteryWheel, /*3421*/ BagTypeKiln, /*3422*/ BagTypeKeymaker, // (no database entries as of peq rev 69) /*3423*/ BagTypeWizardsLexicon, -/*3424*/ BagTypeMagesLexicon, +/*3424*/ BagTypeMagesLexicon, // 25 /*3425*/ BagTypeNecromancersLexicon, /*3426*/ BagTypeEnchantersLexicon, /*----*/ BagTypeUnknown1, // (a coin pouch/purse?) (no database entries as of peq rev 69) /*----*/ BagTypeConcordanceofResearch, // <*Database Reference Only> -/*3427*/ BagTypeAlwaysWorks, // Quest container (Never-fail combines?) +/*3427*/ BagTypeAlwaysWorks, // 30 // Quest container (Never-fail combines?) /*3428*/ BagTypeKoadaDalForge, // High Elf /*3429*/ BagTypeTeirDalForge, // Dark Elf /*3430*/ BagTypeOggokForge, // Ogre /*3431*/ BagTypeStormguardForge, // Dwarf -/*3432*/ BagTypeAkanonForge, // Gnome +/*3432*/ BagTypeAkanonForge, // 35 // Gnome /*3433*/ BagTypeNorthmanForge, // Barbarian /*----*/ BagTypeUnknown2, // (no database entries as of peq rev 69) /*3434*/ BagTypeCabilisForge, // Iksar /*3435*/ BagTypeFreeportForge, // Human 1 -/*3436*/ BagTypeRoyalQeynosForge, // Human 2 +/*3436*/ BagTypeRoyalQeynosForge, // 40 // Human 2 /*3439*/ BagTypeHalflingTailoringKit, /*3438*/ BagTypeErudTailoringKit, /*3440*/ BagTypeFierDalTailoringKit, // Wood Elf /*3441*/ BagTypeFierDalFletchingKit, // Wood Elf -/*3437*/ BagTypeIksarPotteryWheel, +/*3437*/ BagTypeIksarPotteryWheel, // 45 /*3442*/ BagTypeTackleBox, /*3443*/ BagTypeTrollForge, /*3445*/ BagTypeFierDalForge, // Wood Elf /*3444*/ BagTypeValeForge, // Halfling -/*3446*/ BagTypeErudForge, +/*3446*/ BagTypeErudForge, // 50 /*----*/ BagTypeTradersSatchel, // <*Database Reference Only> (db: Yellow Trader's Satchel Token?) /*5785*/ BagTypeGuktaForge, // Froglok (no database entries as of peq rev 69) /*3359*/ BagTypeAugmentationSealer, /*----*/ BagTypeIceCreamChurn, // <*Database Reference Only> -/*6325*/ BagTypeTransformationmold, // Ornamentation +/*6325*/ BagTypeTransformationmold, // 55 // Ornamentation /*6340*/ BagTypeDetransformationmold, // Ornamentation Stripper /*5400*/ BagTypeUnattuner, /*7684*/ BagTypeTradeskillBag, @@ -816,7 +816,7 @@ enum MaterialUseSlots : uint8 MaterialArms, MaterialWrist, MaterialHands, - MaterialLegs, + MaterialLegs, // 5 MaterialFeet, MaterialPrimary, MaterialSecondary, @@ -864,22 +864,22 @@ enum InventoryMapTypes : int16 { MapSharedBank, MapTrade, MapWorld, - MapLimbo, + MapLimbo, // 5 MapTribute, MapTrophyTribute, MapGuildTribute, MapMerchant, - MapDeleted, + MapDeleted, // 10 MapCorpse, MapBazaar, MapInspect, MapRealEstate, - MapViewMODPC, + MapViewMODPC, // 15 MapViewMODBank, MapViewMODSharedBank, MapViewMODLimbo, MapAltStorage, - MapArchived, + MapArchived, // 20 MapMail, MapGuildTrophyTribute, MapKrono, @@ -893,35 +893,35 @@ enum InventoryMainTypes : int16 { MainHead, MainFace, MainEar2, - MainNeck, + MainNeck, // 5 MainShoulders, MainArms, MainBack, MainWrist1, - MainWrist2, + MainWrist2, // 10 MainRange, MainHands, MainPrimary, MainSecondary, - MainFinger1, + MainFinger1, // 15 MainFinger2, MainChest, MainLegs, MainFeet, - MainWaist, + MainWaist, // 20 MainPowerSource = 9999, // temp MainAmmo = 21, // temp MainGeneral1, MainGeneral2, MainGeneral3, - MainGeneral4, + MainGeneral4, // 25 MainGeneral5, MainGeneral6, MainGeneral7, MainGeneral8, //MainGeneral9, //MainGeneral10, - MainCursor, + MainCursor, // 30 _MainCount }; diff --git a/common/skills.h b/common/skills.h index 5ffba33b9..0868c3329 100644 --- a/common/skills.h +++ b/common/skills.h @@ -33,84 +33,84 @@ enum SkillUseTypes /*13857*/ Skill2HBlunt, /*13858*/ Skill2HSlashing, /*13859*/ SkillAbjuration, -/*13861*/ SkillAlteration, +/*13861*/ SkillAlteration, // 5 /*13862*/ SkillApplyPoison, /*13863*/ SkillArchery, /*13864*/ SkillBackstab, /*13866*/ SkillBindWound, -/*13867*/ SkillBash, +/*13867*/ SkillBash, // 10 /*13871*/ SkillBlock, /*13872*/ SkillBrassInstruments, /*13874*/ SkillChanneling, /*13875*/ SkillConjuration, -/*13876*/ SkillDefense, +/*13876*/ SkillDefense, // 15 /*13877*/ SkillDisarm, /*13878*/ SkillDisarmTraps, /*13879*/ SkillDivination, /*13880*/ SkillDodge, -/*13881*/ SkillDoubleAttack, +/*13881*/ SkillDoubleAttack, // 20 /*13882*/ SkillDragonPunch, /*13924*/ SkillTailRake = SkillDragonPunch, // Iksar Monk equivilent /*13883*/ SkillDualWield, /*13884*/ SkillEagleStrike, /*13885*/ SkillEvocation, -/*13886*/ SkillFeignDeath, +/*13886*/ SkillFeignDeath, // 25 /*13888*/ SkillFlyingKick, /*13889*/ SkillForage, /*13890*/ SkillHandtoHand, /*13891*/ SkillHide, -/*13893*/ SkillKick, +/*13893*/ SkillKick, // 30 /*13894*/ SkillMeditate, /*13895*/ SkillMend, /*13896*/ SkillOffense, /*13897*/ SkillParry, -/*13899*/ SkillPickLock, +/*13899*/ SkillPickLock, // 35 /*13900*/ Skill1HPiercing, // Changed in RoF2(05-10-2013) /*13903*/ SkillRiposte, /*13904*/ SkillRoundKick, /*13905*/ SkillSafeFall, -/*13906*/ SkillSenseHeading, +/*13906*/ SkillSenseHeading, // 40 /*13908*/ SkillSinging, /*13909*/ SkillSneak, /*13910*/ SkillSpecializeAbjure, // No idea why they truncated this one..especially when there are longer ones... /*13911*/ SkillSpecializeAlteration, -/*13912*/ SkillSpecializeConjuration, +/*13912*/ SkillSpecializeConjuration, // 45 /*13913*/ SkillSpecializeDivination, /*13914*/ SkillSpecializeEvocation, /*13915*/ SkillPickPockets, /*13916*/ SkillStringedInstruments, -/*13917*/ SkillSwimming, +/*13917*/ SkillSwimming, // 50 /*13919*/ SkillThrowing, /*13920*/ SkillTigerClaw, /*13921*/ SkillTracking, /*13923*/ SkillWindInstruments, -/*13854*/ SkillFishing, +/*13854*/ SkillFishing, // 55 /*13853*/ SkillMakePoison, /*13852*/ SkillTinkering, /*13851*/ SkillResearch, /*13850*/ SkillAlchemy, -/*13865*/ SkillBaking, +/*13865*/ SkillBaking, // 60 /*13918*/ SkillTailoring, /*13907*/ SkillSenseTraps, /*13870*/ SkillBlacksmithing, /*13887*/ SkillFletching, -/*13873*/ SkillBrewing, +/*13873*/ SkillBrewing, // 65 /*13860*/ SkillAlcoholTolerance, /*13868*/ SkillBegging, /*13892*/ SkillJewelryMaking, /*13901*/ SkillPottery, -/*13898*/ SkillPercussionInstruments, +/*13898*/ SkillPercussionInstruments, // 70 /*13922*/ SkillIntimidation, /*13869*/ SkillBerserking, /*13902*/ SkillTaunt, -/*05837*/ SkillFrenzy, // This appears to be the only listed one not grouped with the others +/*05837*/ SkillFrenzy, // 74 // This appears to be the only listed one not grouped with the others // SoF+ specific skills -/*03670*/ SkillRemoveTraps, +/*03670*/ SkillRemoveTraps, // 75 /*13049*/ SkillTripleAttack, // RoF2+ specific skills -/*00789*/ Skill2HPiercing, +/*00789*/ Skill2HPiercing, // 77 // /*01216*/ SkillNone, // This needs to move down as new skills are added /*00000*/ _EmuSkillCount // move to last position of active enumeration labels From 1e344f2ad28a0e04122349ac719f89b064797759 Mon Sep 17 00:00:00 2001 From: Uleat Date: Mon, 21 Mar 2016 18:35:11 -0400 Subject: [PATCH 56/56] Added 'Open Chest' animation for LDoN chest death (thanks Natedog!) --- zone/attack.cpp | 10 ++++++++++ 1 file changed, 10 insertions(+) diff --git a/zone/attack.cpp b/zone/attack.cpp index c14a74059..858e6aee9 100644 --- a/zone/attack.cpp +++ b/zone/attack.cpp @@ -1936,6 +1936,16 @@ bool NPC::Death(Mob* killer_mob, int32 damage, uint16 spell, SkillUseTypes attac BuffFadeAll(); uint8 killed_level = GetLevel(); + if (GetClass() == LDON_TREASURE) { // open chest + EQApplicationPacket* outapp = new EQApplicationPacket(OP_Animation, sizeof(Animation_Struct)); + Animation_Struct* anim = (Animation_Struct*)outapp->pBuffer; + anim->spawnid = GetID(); + anim->action = 0x0F; + anim->speed = 10; + entity_list.QueueCloseClients(this, outapp); + safe_delete(outapp); + } + EQApplicationPacket* app = new EQApplicationPacket(OP_Death, sizeof(Death_Struct)); Death_Struct* d = (Death_Struct*)app->pBuffer; d->spawn_id = GetID();