diff --git a/changelog.txt b/changelog.txt index 2fa5d5594..372c908c7 100644 --- a/changelog.txt +++ b/changelog.txt @@ -1,5 +1,11 @@ EQEMu Changelog (Started on Sept 24, 2003 15:50) ------------------------------------------------------- + +== 03/18/2013 == +Bad_Captain: Fixed zone crash due to merc focus effects & tribute. +Bad_Captain: Fixed merc aggro issues when client in melee range & spell recast timers. +Bad_Captain: Added melee DPS spells/disciplines & support. + == 03/17/2013 == Secrets: Fixed that pesky merc memleak. Secrets: Bit of code cleanup regarding mercs. diff --git a/common/patches/RoF.cpp b/common/patches/RoF.cpp index 1c56e27cd..b44cb8f37 100644 --- a/common/patches/RoF.cpp +++ b/common/patches/RoF.cpp @@ -3150,6 +3150,7 @@ ENCODE(OP_VetRewardsAvaliable) unsigned char * __emu_buffer = inapp->pBuffer; uint32 count = ((*p)->Size() / sizeof(InternalVeteranReward)); + *p = NULL; EQApplicationPacket *outapp_create = new EQApplicationPacket(OP_VetRewardsAvaliable, (sizeof(structs::VeteranReward)*count)); uchar *old_data = __emu_buffer; @@ -3174,7 +3175,7 @@ ENCODE(OP_VetRewardsAvaliable) } dest->FastQueuePacket(&outapp_create); - delete[] __emu_buffer; + delete inapp; } ENCODE(OP_WhoAllResponse) diff --git a/common/patches/SoD.cpp b/common/patches/SoD.cpp index 99e6cd8c0..9e272a14c 100644 --- a/common/patches/SoD.cpp +++ b/common/patches/SoD.cpp @@ -2097,6 +2097,7 @@ ENCODE(OP_VetRewardsAvaliable) unsigned char * __emu_buffer = inapp->pBuffer; uint32 count = ((*p)->Size() / sizeof(InternalVeteranReward)); + *p = NULL; EQApplicationPacket *outapp_create = new EQApplicationPacket(OP_VetRewardsAvaliable, (sizeof(structs::VeteranReward)*count)); uchar *old_data = __emu_buffer; @@ -2121,7 +2122,7 @@ ENCODE(OP_VetRewardsAvaliable) } dest->FastQueuePacket(&outapp_create); - delete[] __emu_buffer; + delete inapp; } ENCODE(OP_WhoAllResponse) diff --git a/common/patches/SoF.cpp b/common/patches/SoF.cpp index b2794d9af..873f3f19d 100644 --- a/common/patches/SoF.cpp +++ b/common/patches/SoF.cpp @@ -1735,6 +1735,7 @@ ENCODE(OP_VetRewardsAvaliable) unsigned char * __emu_buffer = inapp->pBuffer; uint32 count = ((*p)->Size() / sizeof(InternalVeteranReward)); + *p = NULL; EQApplicationPacket *outapp_create = new EQApplicationPacket(OP_VetRewardsAvaliable, (sizeof(structs::VeteranReward)*count)); uchar *old_data = __emu_buffer; @@ -1759,7 +1760,7 @@ ENCODE(OP_VetRewardsAvaliable) } dest->FastQueuePacket(&outapp_create); - delete[] __emu_buffer; + delete inapp; } ENCODE(OP_DeleteSpawn) { diff --git a/common/patches/Titanium.cpp b/common/patches/Titanium.cpp index 469ba9b57..8f4624bed 100644 --- a/common/patches/Titanium.cpp +++ b/common/patches/Titanium.cpp @@ -898,6 +898,7 @@ ENCODE(OP_VetRewardsAvaliable) unsigned char * __emu_buffer = inapp->pBuffer; uint32 count = ((*p)->Size() / sizeof(InternalVeteranReward)); + *p = NULL; EQApplicationPacket *outapp_create = new EQApplicationPacket(OP_VetRewardsAvaliable, (sizeof(structs::VeteranReward)*count)); uchar *old_data = __emu_buffer; @@ -916,7 +917,7 @@ ENCODE(OP_VetRewardsAvaliable) } dest->FastQueuePacket(&outapp_create); - delete[] __emu_buffer; + delete inapp; } ENCODE(OP_InspectAnswer) { diff --git a/common/patches/Underfoot.cpp b/common/patches/Underfoot.cpp index 0da4f60c9..d56a21d3b 100644 --- a/common/patches/Underfoot.cpp +++ b/common/patches/Underfoot.cpp @@ -2157,6 +2157,7 @@ ENCODE(OP_VetRewardsAvaliable) unsigned char * __emu_buffer = inapp->pBuffer; uint32 count = ((*p)->Size() / sizeof(InternalVeteranReward)); + *p = NULL; EQApplicationPacket *outapp_create = new EQApplicationPacket(OP_VetRewardsAvaliable, (sizeof(structs::VeteranReward)*count)); uchar *old_data = __emu_buffer; @@ -2181,7 +2182,7 @@ ENCODE(OP_VetRewardsAvaliable) } dest->FastQueuePacket(&outapp_create); - delete[] __emu_buffer; + delete inapp; } ENCODE(OP_WhoAllResponse) diff --git a/utils/sql/git/optional/2013_03_18_Merc_Spells.sql b/utils/sql/git/optional/2013_03_18_Merc_Spells.sql new file mode 100644 index 000000000..bf3b51076 --- /dev/null +++ b/utils/sql/git/optional/2013_03_18_Merc_Spells.sql @@ -0,0 +1,92 @@ +REPLACE INTO merc_spell_list_entries (merc_spell_list_id, spell_id, spell_type, stance_id, minlevel, maxlevel, slot, procChance) VALUES + ((SELECT merc_spell_list_id FROM merc_spell_lists WHERE class_id = 9 AND proficiency_id = 1), 23181, 16, 0, 1, 9, 1, 0 ), -- Strike of Impaired Vision + ((SELECT merc_spell_list_id FROM merc_spell_lists WHERE class_id = 9 AND proficiency_id = 1), 23182, 16, 0, 10, 19, 1, 0 ), -- Strike of Impaired Vision + ((SELECT merc_spell_list_id FROM merc_spell_lists WHERE class_id = 9 AND proficiency_id = 1), 23183, 16, 0, 20, 24, 1, 0 ), -- Strike of Impaired Vision + ((SELECT merc_spell_list_id FROM merc_spell_lists WHERE class_id = 9 AND proficiency_id = 1), 23184, 16, 0, 25, 29, 1, 0 ), -- Strike of Impaired Vision + ((SELECT merc_spell_list_id FROM merc_spell_lists WHERE class_id = 9 AND proficiency_id = 1), 23185, 16, 0, 30, 34, 1, 0 ), -- Strike of Impaired Vision + ((SELECT merc_spell_list_id FROM merc_spell_lists WHERE class_id = 9 AND proficiency_id = 1), 23186, 16, 0, 35, 39, 1, 0 ), -- Strike of Impaired Vision + ((SELECT merc_spell_list_id FROM merc_spell_lists WHERE class_id = 9 AND proficiency_id = 1), 23187, 16, 0, 40, 44, 1, 0 ), -- Strike of Impaired Vision + ((SELECT merc_spell_list_id FROM merc_spell_lists WHERE class_id = 9 AND proficiency_id = 1), 23188, 16, 0, 45, 49, 1, 0 ), -- Strike of Impaired Vision + ((SELECT merc_spell_list_id FROM merc_spell_lists WHERE class_id = 9 AND proficiency_id = 1), 23189, 16, 0, 50, 54, 1, 0 ), -- Strike of Impaired Vision + ((SELECT merc_spell_list_id FROM merc_spell_lists WHERE class_id = 9 AND proficiency_id = 1), 23190, 16, 0, 55, 59, 1, 0 ), -- Strike of Impaired Vision + ((SELECT merc_spell_list_id FROM merc_spell_lists WHERE class_id = 9 AND proficiency_id = 1), 23191, 16, 0, 60, 64, 1, 0 ), -- Strike of Impaired Vision + ((SELECT merc_spell_list_id FROM merc_spell_lists WHERE class_id = 9 AND proficiency_id = 1), 23192, 16, 0, 65, 69, 1, 0 ), -- Strike of Impaired Vision + ((SELECT merc_spell_list_id FROM merc_spell_lists WHERE class_id = 9 AND proficiency_id = 1), 23193, 16, 0, 70, 74, 1, 0 ), -- Strike of Impaired Vision + ((SELECT merc_spell_list_id FROM merc_spell_lists WHERE class_id = 9 AND proficiency_id = 1), 23194, 16, 0, 75, 79, 1, 0 ), -- Strike of Impaired Vision + ((SELECT merc_spell_list_id FROM merc_spell_lists WHERE class_id = 9 AND proficiency_id = 1), 23195, 16, 0, 80, 80, 1, 0 ), -- Strike of Impaired Vision + ((SELECT merc_spell_list_id FROM merc_spell_lists WHERE class_id = 9 AND proficiency_id = 1), 23196, 16, 0, 81, 81, 1, 0 ), -- Strike of Impaired Vision + ((SELECT merc_spell_list_id FROM merc_spell_lists WHERE class_id = 9 AND proficiency_id = 1), 23197, 16, 0, 82, 82, 1, 0 ), -- Strike of Impaired Vision + ((SELECT merc_spell_list_id FROM merc_spell_lists WHERE class_id = 9 AND proficiency_id = 1), 23198, 16, 0, 83, 83, 1, 0 ), -- Strike of Impaired Vision + ((SELECT merc_spell_list_id FROM merc_spell_lists WHERE class_id = 9 AND proficiency_id = 1), 23199, 16, 0, 84, 84, 1, 0 ), -- Strike of Impaired Vision + ((SELECT merc_spell_list_id FROM merc_spell_lists WHERE class_id = 9 AND proficiency_id = 1), 23200, 16, 0, 85, 95, 1, 0 ), -- Strike of Impaired Vision + ((SELECT merc_spell_list_id FROM merc_spell_lists WHERE class_id = 9 AND proficiency_id = 1), 37747, 16, 0, 96, 255, 1, 0 ), -- Strike of Impaired Vision + ((SELECT merc_spell_list_id FROM merc_spell_lists WHERE class_id = 9 AND proficiency_id = 1), (SELECT id FROM spells_new WHERE name = 'Hide' ORDER BY id DESC LIMIT 1), 8, 0, 1, 255, 1, 0 ), + ((SELECT merc_spell_list_id FROM merc_spell_lists WHERE class_id = 9 AND proficiency_id = 1), (SELECT id FROM spells_new WHERE name = 'Sneak Attack' ORDER BY id DESC LIMIT 1), 1024, 0, 20, 51, 1, 0 ), + ((SELECT merc_spell_list_id FROM merc_spell_lists WHERE class_id = 9 AND proficiency_id = 1), (SELECT id FROM spells_new WHERE name = 'Thief\'s Vengeance' ORDER BY id DESC LIMIT 1), 1024, 0, 52, 62, 1, 0 ), + ((SELECT merc_spell_list_id FROM merc_spell_lists WHERE class_id = 9 AND proficiency_id = 1), (SELECT id FROM spells_new WHERE name = 'Assassin\'s Strike' ORDER BY id DESC LIMIT 1), 1024, 0, 63, 64, 1, 0 ), + ((SELECT merc_spell_list_id FROM merc_spell_lists WHERE class_id = 9 AND proficiency_id = 1), (SELECT id FROM spells_new WHERE name = 'Kyv Strike' ORDER BY id DESC LIMIT 1), 1024, 0, 65, 68, 1, 0 ), + ((SELECT merc_spell_list_id FROM merc_spell_lists WHERE class_id = 9 AND proficiency_id = 1), (SELECT id FROM spells_new WHERE name = 'Thief\'s eyes' ORDER BY id DESC LIMIT 1), 1024, 0, 68, 255, 1, 0 ), + ((SELECT merc_spell_list_id FROM merc_spell_lists WHERE class_id = 9 AND proficiency_id = 1), (SELECT id FROM spells_new WHERE name = 'Daggerfall' ORDER BY id DESC LIMIT 1), 1024, 0, 69, 69, 1, 0 ), + ((SELECT merc_spell_list_id FROM merc_spell_lists WHERE class_id = 9 AND proficiency_id = 1), (SELECT id FROM spells_new WHERE name = 'Razorarc' ORDER BY id DESC LIMIT 1), 1024, 0, 70, 79, 1, 0 ), + ((SELECT merc_spell_list_id FROM merc_spell_lists WHERE class_id = 9 AND proficiency_id = 1), (SELECT id FROM spells_new WHERE name = 'Swiftblade' ORDER BY id DESC LIMIT 1), 1024, 0, 80, 84, 1, 0 ), + ((SELECT merc_spell_list_id FROM merc_spell_lists WHERE class_id = 9 AND proficiency_id = 1), (SELECT id FROM spells_new WHERE name = 'Swiftblade Rk. II' ORDER BY id DESC LIMIT 1), 1024, 0, 80, 84, 1, 0 ), + ((SELECT merc_spell_list_id FROM merc_spell_lists WHERE class_id = 9 AND proficiency_id = 1), (SELECT id FROM spells_new WHERE name = 'Swiftblade Rk. III' ORDER BY id DESC LIMIT 1), 1024, 0, 80, 84, 1, 0 ), + ((SELECT merc_spell_list_id FROM merc_spell_lists WHERE class_id = 9 AND proficiency_id = 1), (SELECT id FROM spells_new WHERE name = 'Daggerlunge' ORDER BY id DESC LIMIT 1), 1024, 0, 85, 89, 1, 0 ), + ((SELECT merc_spell_list_id FROM merc_spell_lists WHERE class_id = 9 AND proficiency_id = 1), (SELECT id FROM spells_new WHERE name = 'Daggerlunge Rk. II' ORDER BY id DESC LIMIT 1), 1024, 0, 85, 89, 1, 0 ), + ((SELECT merc_spell_list_id FROM merc_spell_lists WHERE class_id = 9 AND proficiency_id = 1), (SELECT id FROM spells_new WHERE name = 'Daggerlunge Rk. III' ORDER BY id DESC LIMIT 1), 1024, 0, 85, 89, 1, 0 ), + ((SELECT merc_spell_list_id FROM merc_spell_lists WHERE class_id = 9 AND proficiency_id = 1), (SELECT id FROM spells_new WHERE name = 'Daggerswipe' ORDER BY id DESC LIMIT 1), 1024, 0, 90, 94, 1, 0 ), + ((SELECT merc_spell_list_id FROM merc_spell_lists WHERE class_id = 9 AND proficiency_id = 1), (SELECT id FROM spells_new WHERE name = 'Daggerswipe Rk. II' ORDER BY id DESC LIMIT 1), 1024, 0, 90, 94, 1, 0 ), + ((SELECT merc_spell_list_id FROM merc_spell_lists WHERE class_id = 9 AND proficiency_id = 1), (SELECT id FROM spells_new WHERE name = 'Daggerswipe Rk. III' ORDER BY id DESC LIMIT 1), 1024, 0, 90, 94, 1, 0 ); + -- ((SELECT merc_spell_list_id FROM merc_spell_lists WHERE class_id = 9 AND proficiency_id = 1), (SELECT id FROM spells_new WHERE name = 'Daggerstrike' ORDER BY id DESC LIMIT 1), 1024, 0, 95, 99, 1, 0 ), + -- ((SELECT merc_spell_list_id FROM merc_spell_lists WHERE class_id = 9 AND proficiency_id = 1), (SELECT id FROM spells_new WHERE name = 'Daggerstrike Rk. II' ORDER BY id DESC LIMIT 1), 1024, 0, 95, 9, 1, 0 ), + -- ((SELECT merc_spell_list_id FROM merc_spell_lists WHERE class_id = 9 AND proficiency_id = 1), (SELECT id FROM spells_new WHERE name = 'Daggerstrike Rk. III' ORDER BY id DESC LIMIT 1), 1024, 0, 95, 9, 1, 0 ), + -- ((SELECT merc_spell_list_id FROM merc_spell_lists WHERE class_id = 9 AND proficiency_id = 1), (SELECT id FROM spells_new WHERE name = 'Daggerthrust' ORDER BY id DESC LIMIT 1), 1024, 0, 100, 255, 1, 0 ), + -- ((SELECT merc_spell_list_id FROM merc_spell_lists WHERE class_id = 9 AND proficiency_id = 1), (SELECT id FROM spells_new WHERE name = 'Daggerthrust Rk. II' ORDER BY id DESC LIMIT 1), 1024, 0, 100, 255, 1, 0 ), + -- ((SELECT merc_spell_list_id FROM merc_spell_lists WHERE class_id = 9 AND proficiency_id = 1), (SELECT id FROM spells_new WHERE name = 'Daggerthrust Rk. III' ORDER BY id DESC LIMIT 1), 1024, 0, 100, 255, 1, 0 ), + + +REPLACE INTO merc_spell_list_entries (merc_spell_list_id, spell_id, spell_type, stance_id, minlevel, maxlevel, slot, procChance) VALUES + ((SELECT merc_spell_list_id FROM merc_spell_lists WHERE class_id = 9 AND proficiency_id = 2), 23181, 16, 0, 1, 9, 1, 0 ), -- Strike of Impaired Vision + ((SELECT merc_spell_list_id FROM merc_spell_lists WHERE class_id = 9 AND proficiency_id = 2), 23182, 16, 0, 10, 19, 1, 0 ), -- Strike of Impaired Vision + ((SELECT merc_spell_list_id FROM merc_spell_lists WHERE class_id = 9 AND proficiency_id = 2), 23183, 16, 0, 20, 24, 1, 0 ), -- Strike of Impaired Vision + ((SELECT merc_spell_list_id FROM merc_spell_lists WHERE class_id = 9 AND proficiency_id = 2), 23184, 16, 0, 25, 29, 1, 0 ), -- Strike of Impaired Vision + ((SELECT merc_spell_list_id FROM merc_spell_lists WHERE class_id = 9 AND proficiency_id = 2), 23185, 16, 0, 30, 34, 1, 0 ), -- Strike of Impaired Vision + ((SELECT merc_spell_list_id FROM merc_spell_lists WHERE class_id = 9 AND proficiency_id = 2), 23186, 16, 0, 35, 39, 1, 0 ), -- Strike of Impaired Vision + ((SELECT merc_spell_list_id FROM merc_spell_lists WHERE class_id = 9 AND proficiency_id = 2), 23187, 16, 0, 40, 44, 1, 0 ), -- Strike of Impaired Vision + ((SELECT merc_spell_list_id FROM merc_spell_lists WHERE class_id = 9 AND proficiency_id = 2), 23188, 16, 0, 45, 49, 1, 0 ), -- Strike of Impaired Vision + ((SELECT merc_spell_list_id FROM merc_spell_lists WHERE class_id = 9 AND proficiency_id = 2), 23189, 16, 0, 50, 54, 1, 0 ), -- Strike of Impaired Vision + ((SELECT merc_spell_list_id FROM merc_spell_lists WHERE class_id = 9 AND proficiency_id = 2), 23190, 16, 0, 55, 59, 1, 0 ), -- Strike of Impaired Vision + ((SELECT merc_spell_list_id FROM merc_spell_lists WHERE class_id = 9 AND proficiency_id = 2), 23191, 16, 0, 60, 64, 1, 0 ), -- Strike of Impaired Vision + ((SELECT merc_spell_list_id FROM merc_spell_lists WHERE class_id = 9 AND proficiency_id = 2), 23192, 16, 0, 65, 69, 1, 0 ), -- Strike of Impaired Vision + ((SELECT merc_spell_list_id FROM merc_spell_lists WHERE class_id = 9 AND proficiency_id = 2), 23193, 16, 0, 70, 74, 1, 0 ), -- Strike of Impaired Vision + ((SELECT merc_spell_list_id FROM merc_spell_lists WHERE class_id = 9 AND proficiency_id = 2), 23194, 16, 0, 75, 79, 1, 0 ), -- Strike of Impaired Vision + ((SELECT merc_spell_list_id FROM merc_spell_lists WHERE class_id = 9 AND proficiency_id = 2), 23195, 16, 0, 80, 80, 1, 0 ), -- Strike of Impaired Vision + ((SELECT merc_spell_list_id FROM merc_spell_lists WHERE class_id = 9 AND proficiency_id = 2), 23196, 16, 0, 81, 81, 1, 0 ), -- Strike of Impaired Vision + ((SELECT merc_spell_list_id FROM merc_spell_lists WHERE class_id = 9 AND proficiency_id = 2), 23197, 16, 0, 82, 82, 1, 0 ), -- Strike of Impaired Vision + ((SELECT merc_spell_list_id FROM merc_spell_lists WHERE class_id = 9 AND proficiency_id = 2), 23198, 16, 0, 83, 83, 1, 0 ), -- Strike of Impaired Vision + ((SELECT merc_spell_list_id FROM merc_spell_lists WHERE class_id = 9 AND proficiency_id = 2), 23199, 16, 0, 84, 84, 1, 0 ), -- Strike of Impaired Vision + ((SELECT merc_spell_list_id FROM merc_spell_lists WHERE class_id = 9 AND proficiency_id = 2), 23200, 16, 0, 85, 95, 1, 0 ), -- Strike of Impaired Vision + ((SELECT merc_spell_list_id FROM merc_spell_lists WHERE class_id = 9 AND proficiency_id = 2), 37747, 16, 0, 96, 255, 1, 0 ), -- Strike of Impaired Vision + ((SELECT merc_spell_list_id FROM merc_spell_lists WHERE class_id = 9 AND proficiency_id = 2), (SELECT id FROM spells_new WHERE name = 'Hide' ORDER BY id DESC LIMIT 1), 8, 0, 1, 255, 1, 0 ), + ((SELECT merc_spell_list_id FROM merc_spell_lists WHERE class_id = 9 AND proficiency_id = 2), (SELECT id FROM spells_new WHERE name = 'Sneak Attack' ORDER BY id DESC LIMIT 1), 1024, 0, 20, 51, 1, 0 ), + ((SELECT merc_spell_list_id FROM merc_spell_lists WHERE class_id = 9 AND proficiency_id = 2), (SELECT id FROM spells_new WHERE name = 'Thief\'s Vengeance' ORDER BY id DESC LIMIT 1), 1024, 0, 52, 62, 1, 0 ), + ((SELECT merc_spell_list_id FROM merc_spell_lists WHERE class_id = 9 AND proficiency_id = 2), (SELECT id FROM spells_new WHERE name = 'Assassin\'s Strike' ORDER BY id DESC LIMIT 1), 1024, 0, 63, 64, 1, 0 ), + ((SELECT merc_spell_list_id FROM merc_spell_lists WHERE class_id = 9 AND proficiency_id = 2), (SELECT id FROM spells_new WHERE name = 'Ancient: Chaos Strike' ORDER BY id DESC LIMIT 1), 1024, 0, 65, 68, 1, 0 ), + ((SELECT merc_spell_list_id FROM merc_spell_lists WHERE class_id = 9 AND proficiency_id = 2), (SELECT id FROM spells_new WHERE name = 'Thief\'s eyes' ORDER BY id DESC LIMIT 1), 1024, 0, 68, 255, 1, 0 ), + ((SELECT merc_spell_list_id FROM merc_spell_lists WHERE class_id = 9 AND proficiency_id = 2), (SELECT id FROM spells_new WHERE name = 'Daggerfall' ORDER BY id DESC LIMIT 1), 1024, 0, 69, 69, 1, 0 ), + ((SELECT merc_spell_list_id FROM merc_spell_lists WHERE class_id = 9 AND proficiency_id = 2), (SELECT id FROM spells_new WHERE name = 'Razorarc' ORDER BY id DESC LIMIT 1), 1024, 0, 70, 79, 1, 0 ), + ((SELECT merc_spell_list_id FROM merc_spell_lists WHERE class_id = 9 AND proficiency_id = 2), (SELECT id FROM spells_new WHERE name = 'Swiftblade' ORDER BY id DESC LIMIT 1), 1024, 0, 80, 84, 1, 0 ), + ((SELECT merc_spell_list_id FROM merc_spell_lists WHERE class_id = 9 AND proficiency_id = 2), (SELECT id FROM spells_new WHERE name = 'Swiftblade Rk. II' ORDER BY id DESC LIMIT 1), 1024, 0, 80, 84, 1, 0 ), + ((SELECT merc_spell_list_id FROM merc_spell_lists WHERE class_id = 9 AND proficiency_id = 2), (SELECT id FROM spells_new WHERE name = 'Swiftblade Rk. III' ORDER BY id DESC LIMIT 1), 1024, 0, 80, 84, 1, 0 ), + ((SELECT merc_spell_list_id FROM merc_spell_lists WHERE class_id = 9 AND proficiency_id = 2), (SELECT id FROM spells_new WHERE name = 'Daggerlunge' ORDER BY id DESC LIMIT 1), 1024, 0, 85, 89, 1, 0 ), + ((SELECT merc_spell_list_id FROM merc_spell_lists WHERE class_id = 9 AND proficiency_id = 2), (SELECT id FROM spells_new WHERE name = 'Daggerlunge Rk. II' ORDER BY id DESC LIMIT 1), 1024, 0, 85, 89, 1, 0 ), + ((SELECT merc_spell_list_id FROM merc_spell_lists WHERE class_id = 9 AND proficiency_id = 2), (SELECT id FROM spells_new WHERE name = 'Daggerlunge Rk. III' ORDER BY id DESC LIMIT 1), 1024, 0, 85, 89, 1, 0 ), + ((SELECT merc_spell_list_id FROM merc_spell_lists WHERE class_id = 9 AND proficiency_id = 2), (SELECT id FROM spells_new WHERE name = 'Daggerswipe' ORDER BY id DESC LIMIT 1), 1024, 0, 90, 94, 1, 0 ), + ((SELECT merc_spell_list_id FROM merc_spell_lists WHERE class_id = 9 AND proficiency_id = 2), (SELECT id FROM spells_new WHERE name = 'Daggerswipe Rk. II' ORDER BY id DESC LIMIT 1), 1024, 0, 90, 94, 1, 0 ), + ((SELECT merc_spell_list_id FROM merc_spell_lists WHERE class_id = 9 AND proficiency_id = 2), (SELECT id FROM spells_new WHERE name = 'Daggerswipe Rk. III' ORDER BY id DESC LIMIT 1), 1024, 0, 90, 94, 1, 0 ); + -- ((SELECT merc_spell_list_id FROM merc_spell_lists WHERE class_id = 9 AND proficiency_id = 2), (SELECT id FROM spells_new WHERE name = 'Daggerstrike' ORDER BY id DESC LIMIT 1), 1024, 0, 95, 99, 1, 0 ), + -- ((SELECT merc_spell_list_id FROM merc_spell_lists WHERE class_id = 9 AND proficiency_id = 2), (SELECT id FROM spells_new WHERE name = 'Daggerstrike Rk. II' ORDER BY id DESC LIMIT 1), 1024, 0, 95, 99, 1, 0 ), + -- ((SELECT merc_spell_list_id FROM merc_spell_lists WHERE class_id = 9 AND proficiency_id = 2), (SELECT id FROM spells_new WHERE name = 'Daggerstrike Rk. III' ORDER BY id DESC LIMIT 1), 1024, 0, 95, 99, 1, 0 ), + -- ((SELECT merc_spell_list_id FROM merc_spell_lists WHERE class_id = 9 AND proficiency_id = 2), (SELECT id FROM spells_new WHERE name = 'Daggerthrust' ORDER BY id DESC LIMIT 1), 1024, 0, 100, 255, 1, 0 ), + -- ((SELECT merc_spell_list_id FROM merc_spell_lists WHERE class_id = 9 AND proficiency_id = 2), (SELECT id FROM spells_new WHERE name = 'Daggerthrust Rk. II' ORDER BY id DESC LIMIT 1), 1024, 0, 100, 255, 1, 0 ), + -- ((SELECT merc_spell_list_id FROM merc_spell_lists WHERE class_id = 9 AND proficiency_id = 2), (SELECT id FROM spells_new WHERE name = 'Daggerthrust Rk. III' ORDER BY id DESC LIMIT 1), 1024, 0, 100, 255, 1, 0 ); diff --git a/zone/hate_list.cpp b/zone/hate_list.cpp index 28ac0bccb..25a0bc197 100644 --- a/zone/hate_list.cpp +++ b/zone/hate_list.cpp @@ -258,8 +258,8 @@ Mob *HateList::GetTop(Mob *center) int32 hate = -1; if (RuleB(Aggro,SmartAggroList)){ - Mob* topClientInRange = NULL; - int32 hateClientInRange = -1; + Mob* topClientTypeInRange = NULL; + int32 hateClientTypeInRange = -1; int skipped_count = 0; LinkedListIterator iterator(list); @@ -313,9 +313,9 @@ Mob *HateList::GetTop(Mob *center) if(center->CombatRange(cur->ent)){ aggroMod += RuleI(Aggro, MeleeRangeAggroMod); - if(currentHate > hateClientInRange || cur->bFrenzy){ - hateClientInRange = currentHate; - topClientInRange = cur->ent; + if(currentHate > hateClientTypeInRange || cur->bFrenzy){ + hateClientTypeInRange = currentHate; + topClientTypeInRange = cur->ent; } } } @@ -351,18 +351,26 @@ Mob *HateList::GetTop(Mob *center) iterator.Advance(); } - if(topClientInRange != NULL && top != NULL) { + if(topClientTypeInRange != NULL && top != NULL) { bool isTopClientType = top->IsClient(); #ifdef BOTS if(!isTopClientType) { if(top->IsBot()) { isTopClientType = true; - topClientInRange = top; + topClientTypeInRange = top; } } #endif //BOTS + + if(!isTopClientType) { + if(top->IsMerc()) { + isTopClientType = true; + topClientTypeInRange = top; + } + } + if(!isTopClientType) - return topClientInRange; + return topClientTypeInRange; return top; } diff --git a/zone/merc.cpp b/zone/merc.cpp index eda622255..17fbcba66 100644 --- a/zone/merc.cpp +++ b/zone/merc.cpp @@ -37,9 +37,11 @@ Merc::Merc(const NPCType* d, float x, float y, float z, float heading) _baseFR = d->FR; _basePR = d->PR; _baseCorrup = d->Corrup; + _OwnerClientVersion = EQClientTitanium; RestRegenHP = 0; RestRegenMana = 0; RestRegenEndurance = 0; + cur_end = 0; _medding = false; _suspended = false; @@ -352,13 +354,6 @@ void Merc::CalcItemBonuses(StatBonuses* newbon) { AddItemBonuses(inst, newbon); }*/ - //tribute items - /*for (i = 0; i < MAX_PLAYER_TRIBUTES; i++) { - const ItemInst* inst = m_inv[TRIBUTE_SLOT_START + i]; - if(inst == 0) - continue; - AddItemBonuses(inst, newbon, false, true); - }*/ // Caps if(newbon->HPRegen > CalcHPRegenCap()) newbon->HPRegen = CalcHPRegenCap(); @@ -1867,10 +1862,6 @@ void Merc::AI_Process() { //TODO: Implement passive stances. //if(GetStance() != MercStancePassive) { if(!AI_IdleCastCheck() && !IsCasting()) { - if(GetClass() == MELEEDPS && !hidden) { - TryHide(); - } - if(GetArchetype() == ARCHETYPE_CASTER) { MercMeditate(true); } @@ -2030,7 +2021,9 @@ bool Merc::AI_IdleCastCheck() { result = true; break; case MELEEDPS: - failedToCast = true; + if(!entity_list.Merc_AICheckCloseBeneficialSpells(this, 100, MercAISpellRange, SpellType_Buff)) { + failedToCast = true; + } break; case CASTERDPS: failedToCast = true; @@ -2148,7 +2141,6 @@ bool Merc::AIDoSpellCast(uint16 spellid, Mob* tar, int32 mana_cost, uint32* oDon } else { //handle spell recast and recast timers SetSpellTimeCanCast(mercSpell.spellid, spells[spellid].recast_time); - //mercSpell.time_cancast = Timer::GetCurrentTime() + spells[spellid].recast_time; if(spells[spellid].EndurTimerIndex > 0) { SetSpellRecastTimer(spells[spellid].EndurTimerIndex, spellid, spells[spellid].recast_time); @@ -2312,7 +2304,10 @@ bool Merc::AICastSpell(int8 iChance, int32 iSpellTypes) { //we don't need spam of bots healing themselves MakeAnyLenString(&gmsg, "Casting %s on %s.", spells[selectedMercSpell.spellid].name, tar->GetCleanName()); if(gmsg) + { MercGroupSay(this, gmsg); + safe_delete_array(gmsg); + } } } @@ -2323,7 +2318,7 @@ bool Merc::AICastSpell(int8 iChance, int32 iSpellTypes) { } case SpellType_Buff: { - if(GetManaRatio() < 50) { + if(GetClass() == HEALER && GetManaRatio() < 50) { return false; //mercs buff when Mana > 50% } @@ -2333,52 +2328,87 @@ bool Merc::AICastSpell(int8 iChance, int32 iSpellTypes) { MercSpell selectedMercSpell = *itr; if(!((spells[selectedMercSpell.spellid].targettype == ST_Target || spells[selectedMercSpell.spellid].targettype == ST_Pet || - spells[selectedMercSpell.spellid].targettype == ST_Group || spells[selectedMercSpell.spellid].targettype == ST_GroupTeleport ))) { + spells[selectedMercSpell.spellid].targettype == ST_Group || spells[selectedMercSpell.spellid].targettype == ST_GroupTeleport || + spells[selectedMercSpell.spellid].targettype == ST_Self))) { continue; } - for( int i = 0; i < MAX_GROUP_MEMBERS; i++) { - if(g->members[i]) { - int32 oDontDoAgainBefore; - Mob* tar = g->members[i]; + if(spells[selectedMercSpell.spellid].targettype == ST_Self) { + if( !this->IsImmuneToSpell(selectedMercSpell.spellid, this) + && (this->CanBuffStack(selectedMercSpell.spellid, mercLevel, true) >= 0)) { - if( !tar->IsImmuneToSpell(selectedMercSpell.spellid, this) - && (tar->CanBuffStack(selectedMercSpell.spellid, mercLevel, true) >= 0)) { - - if( tar->GetArchetype() == ARCHETYPE_MELEE && IsEffectInSpell(selectedMercSpell.spellid, SE_IncreaseSpellHaste)) { - continue; - } - - uint32 TempDontBuffMeBeforeTime = tar->DontBuffMeBefore(); - - if(AIDoSpellCast(selectedMercSpell.spellid, tar, -1, &TempDontBuffMeBeforeTime)) { - if(TempDontBuffMeBeforeTime != tar->DontBuffMeBefore()) - tar->SetDontBuffMeBefore(TempDontBuffMeBeforeTime); - - castedSpell = true; - } + if( this->GetArchetype() == ARCHETYPE_MELEE && IsEffectInSpell(selectedMercSpell.spellid, SE_IncreaseSpellHaste)) { + continue; } - if(!castedSpell && tar->GetPet()) { + uint32 TempDontBuffMeBeforeTime = this->DontBuffMeBefore(); - //don't cast group spells on pets - if(IsGroupSpell(selectedMercSpell.spellid) - || spells[selectedMercSpell.spellid].targettype == ST_Group - || spells[selectedMercSpell.spellid].targettype == ST_GroupTeleport ) { - continue; + if(selectedMercSpell.spellid > 0) { + if(isDiscipline) { + castedSpell = UseDiscipline(selectedMercSpell.spellid, GetID()); } + else { + castedSpell = AIDoSpellCast(selectedMercSpell.spellid, this, -1, &TempDontBuffMeBeforeTime); - if(!tar->GetPet()->IsImmuneToSpell(selectedMercSpell.spellid, this) - && (tar->GetPet()->CanBuffStack(selectedMercSpell.spellid, mercLevel, true) >= 0)) { + if(TempDontBuffMeBeforeTime != this->DontBuffMeBefore()) + this->SetDontBuffMeBefore(TempDontBuffMeBeforeTime); + } + } + } + } + else { + for( int i = 0; i < MAX_GROUP_MEMBERS; i++) { + if(g->members[i]) { + int32 oDontDoAgainBefore; + Mob* tar = g->members[i]; + + if( !tar->IsImmuneToSpell(selectedMercSpell.spellid, this) + && (tar->CanBuffStack(selectedMercSpell.spellid, mercLevel, true) >= 0)) { + + if( tar->GetArchetype() == ARCHETYPE_MELEE && IsEffectInSpell(selectedMercSpell.spellid, SE_IncreaseSpellHaste)) { + continue; + } uint32 TempDontBuffMeBeforeTime = tar->DontBuffMeBefore(); - if(AIDoSpellCast(selectedMercSpell.spellid, tar->GetPet(), -1, &TempDontBuffMeBeforeTime)) { - if(TempDontBuffMeBeforeTime != tar->DontBuffMeBefore()) { - tar->SetDontBuffMeBefore(TempDontBuffMeBeforeTime); + if(selectedMercSpell.spellid > 0) { + if(isDiscipline) { + castedSpell = UseDiscipline(selectedMercSpell.spellid, GetID()); } + else { + castedSpell = AIDoSpellCast(selectedMercSpell.spellid, this, -1, &TempDontBuffMeBeforeTime); - castedSpell = true; + if(TempDontBuffMeBeforeTime != this->DontBuffMeBefore()) + this->SetDontBuffMeBefore(TempDontBuffMeBeforeTime); + } + } + } + + if(!castedSpell && tar->GetPet()) { + + //don't cast group spells on pets + if(IsGroupSpell(selectedMercSpell.spellid) + || spells[selectedMercSpell.spellid].targettype == ST_Group + || spells[selectedMercSpell.spellid].targettype == ST_GroupTeleport ) { + continue; + } + + if(!tar->GetPet()->IsImmuneToSpell(selectedMercSpell.spellid, this) + && (tar->GetPet()->CanBuffStack(selectedMercSpell.spellid, mercLevel, true) >= 0)) { + + uint32 TempDontBuffMeBeforeTime = tar->DontBuffMeBefore(); + + if(selectedMercSpell.spellid > 0) { + if(isDiscipline) { + castedSpell = UseDiscipline(selectedMercSpell.spellid, GetID()); + } + else { + castedSpell = AIDoSpellCast(selectedMercSpell.spellid, this, -1, &TempDontBuffMeBeforeTime); + + if(TempDontBuffMeBeforeTime != this->DontBuffMeBefore()) + this->SetDontBuffMeBefore(TempDontBuffMeBeforeTime); + } + } } } } @@ -2452,6 +2482,37 @@ bool Merc::AICastSpell(int8 iChance, int32 iSpellTypes) { break; } case SpellType_InCombatBuff: { + std::list buffSpellList = GetMercSpellsBySpellType(this, SpellType_InCombatBuff); + Mob* tar = this; + + for(std::list::iterator itr = buffSpellList.begin(); itr != buffSpellList.end(); itr++) { + MercSpell selectedMercSpell = *itr; + + if(!(spells[selectedMercSpell.spellid].targettype == ST_Self)) { + continue; + } + + if(spells[selectedMercSpell.spellid].skill == BACKSTAB && spells[selectedMercSpell.spellid].targettype == ST_Self) { + if(!hidden) { + continue; + } + } + + if( !tar->IsImmuneToSpell(selectedMercSpell.spellid, this) + && (tar->CanBuffStack(selectedMercSpell.spellid, mercLevel, true) >= 0)) { + + uint32 TempDontBuffMeBeforeTime = tar->DontBuffMeBefore(); + + if(selectedMercSpell.spellid > 0) { + if(isDiscipline) { + castedSpell = UseDiscipline(selectedMercSpell.spellid, GetID()); + } + else { + castedSpell = AIDoSpellCast(selectedMercSpell.spellid, this, -1); + } + } + } + } break; } case SpellType_Cure: { @@ -2692,7 +2753,7 @@ int16 Merc::GetFocusEffect(focusType type, uint16 spell_id) { int16 focus_max_real = 0; //item focus - for(int x=0; x<=MAX_WORN_INVENTORY; x++) + for(int x =0; x < MAX_WORN_INVENTORY; ++x) { TempItem = NULL; if (equipment[x] == 0) @@ -2726,42 +2787,6 @@ int16 Merc::GetFocusEffect(focusType type, uint16 spell_id) { } } - //Tribute Focus - for(int x = TRIBUTE_SLOT_START; x < (TRIBUTE_SLOT_START + MAX_PLAYER_TRIBUTES); ++x) - { - TempItem = NULL; - if (equipment[x] == 0) - continue; - TempItem = database.GetItem(equipment[x]); - if (TempItem && TempItem->Focus.Effect > 0 && TempItem->Focus.Effect != SPELL_UNKNOWN) { - if(rand_effectiveness) { - focus_max = CalcFocusEffect(type, TempItem->Focus.Effect, spell_id, true); - if (focus_max > 0 && focus_max_real >= 0 && focus_max > focus_max_real) { - focus_max_real = focus_max; - UsedItem = TempItem; - UsedFocusID = TempItem->Focus.Effect; - } else if (focus_max < 0 && focus_max < focus_max_real) { - focus_max_real = focus_max; - UsedItem = TempItem; - UsedFocusID = TempItem->Focus.Effect; - } - } - else { - Total = CalcFocusEffect(type, TempItem->Focus.Effect, spell_id); - if (Total > 0 && realTotal >= 0 && Total > realTotal) { - realTotal = Total; - UsedItem = TempItem; - UsedFocusID = TempItem->Focus.Effect; - } - else if (Total < 0 && Total < realTotal) { - realTotal = Total; - UsedItem = TempItem; - UsedFocusID = TempItem->Focus.Effect; - } - } - } - } - if(UsedItem && rand_effectiveness && focus_max_real != 0) realTotal = CalcFocusEffect(type, UsedFocusID, spell_id); @@ -3168,6 +3193,7 @@ int8 Merc::GetChanceToCastBySpellType(int16 spellType) { break; } case MELEEDPS:{ + chance = 50; break; } case CASTERDPS:{ @@ -3206,9 +3232,11 @@ int8 Merc::GetChanceToCastBySpellType(int16 spellType) { bool Merc::CheckStance(int16 stance) { + //checks of current stance matches stances listed as valid for spell in database + //stance = 0 for all stances, stance # for only that stance & -stance# for all but that stance if(stance == 0 || (stance > 0 && stance == GetStance()) - || (stance < 0 && abs(stance) == GetStance())) { + || (stance < 0 && abs(stance) != GetStance())) { return true; } @@ -3303,7 +3331,7 @@ MercSpell Merc::GetMercSpellBySpellID(Merc* caster, uint16 spellid) { continue; } - if((mercSpellList[i].spellid = spellid) + if((mercSpellList[i].spellid == spellid) && caster->CheckStance(mercSpellList[i].stance)) { result.spellid = mercSpellList[i].spellid; result.stance = mercSpellList[i].stance; @@ -4298,15 +4326,20 @@ bool Merc::UseDiscipline(int32 spell_id, int32 target) { return(false); } - //can we use the spell? const SPDat_Spell_Struct &spell = spells[spell_id]; - int8 level_to_use = spell.classes[GetClass() - 1]; - if(level_to_use == 255) { - return(false); - } - if(level_to_use > GetLevel()) { - return(false); + if(spell.recast_time > 0) + { + if(CheckDisciplineRecastTimers(this, spell_id, spells[spell_id].EndurTimerIndex)) { + if(spells[spell_id].EndurTimerIndex > 0) { + SetDisciplineRecastTimer(spells[spell_id].EndurTimerIndex, spell_id, spell.recast_time); + } + + SetSpellTimeCanCast(spell_id, spells[spell_id].recast_time); + } + else { + return(false); + } } if(GetEndurance() > spell.EndurCost) { @@ -4316,18 +4349,6 @@ bool Merc::UseDiscipline(int32 spell_id, int32 target) { return(false); } - if(spell.recast_time > 0) - { - if(CheckDisciplineRecastTimers(this, spells[spell_id].EndurTimerIndex)) { - if(spells[spell_id].EndurTimerIndex > 0) { - SetDisciplineRecastTimer(spells[spell_id].EndurTimerIndex, spell_id, spell.recast_time); - } - } - else { - return(false); - } - } - if(IsCasting()) InterruptSpell(); @@ -4400,13 +4421,14 @@ int32 Merc::GetDisciplineRemainingTime(Merc *caster, uint16 timer_id) { return result; } -bool Merc::CheckDisciplineRecastTimers(Merc *caster, uint16 spell_id) { +bool Merc::CheckDisciplineRecastTimers(Merc *caster, uint16 spell_id, uint16 timer_id) { if(caster) { MercSpell mercSpell = GetMercSpellBySpellID(caster, spell_id); if(mercSpell.spellid > 0 && mercSpell.time_cancast < Timer::GetCurrentTime()) { //checks spell recast - if(GetDisciplineRecastTimer(caster, spells[spell_id].EndurTimerIndex) < Timer::GetCurrentTime()) { //checks for spells on the same timer - return true; //can cast spell + if(timer_id > 0 && !(GetDisciplineRecastTimer(caster, timer_id) < Timer::GetCurrentTime())) { //checks for spells on the same timer + return false; //can't cast spell } + return true; } } return false; @@ -5378,7 +5400,7 @@ bool Client::CheckCanHireMerc(Mob* merchant, uint32 template_id) { //check for sufficient funds if(RuleB(Mercs, ChargeMercPurchaseCost)) { uint32 cost = Merc::CalcPurchaseCost(template_id, GetLevel()) * 100; // Cost is in gold - if(!HasMoney(cost)) { + if(cost > 0 && !HasMoney(cost)) { SendMercMerchantResponsePacket(1); result = false; } @@ -5416,7 +5438,7 @@ bool Client::CheckCanRetainMerc(uint32 upkeep) { //check for sufficient funds if(RuleB(Mercs, ChargeMercPurchaseCost)) { if(merc) { - if(!HasMoney(upkeep * 100)) { + if(upkeep > 0 && !HasMoney(upkeep * 100)) { SendMercMerchantResponsePacket(1); result = false; } diff --git a/zone/merc.h b/zone/merc.h index faf19eec3..b76bb566d 100644 --- a/zone/merc.h +++ b/zone/merc.h @@ -90,7 +90,7 @@ public: static int32 GetSpellRecastTimer(Merc *caster, uint16 timer_id); static bool CheckSpellRecastTimers(Merc *caster, uint16 spellid); static int32 GetDisciplineRecastTimer(Merc *caster, uint16 timer_id); - static bool CheckDisciplineRecastTimers(Merc *caster, uint16 spellid); + static bool CheckDisciplineRecastTimers(Merc *caster, uint16 spell_id, uint16 timer_id); static int32 GetDisciplineRemainingTime(Merc *caster, uint16 timer_id); static std::list GetMercSpellsForSpellEffect(Merc* caster, int spellEffect); static std::list GetMercSpellsForSpellEffectAndTargetType(Merc* caster, int spellEffect, SpellTargetType targetType); diff --git a/zone/mob.cpp b/zone/mob.cpp index 8bd2d362c..6c8bbc398 100644 --- a/zone/mob.cpp +++ b/zone/mob.cpp @@ -274,7 +274,7 @@ Mob::Mob(const char* in_name, memset(&itembonuses, 0, sizeof(StatBonuses)); memset(&spellbonuses, 0, sizeof(StatBonuses)); - //memset(&aabonuses, 0, sizeof(StatBonuses)); //don't need this until we start using Client::CalcAABonuses() + memset(&aabonuses, 0, sizeof(StatBonuses)); spellbonuses.AggroRange = -1; spellbonuses.AssistRange = -1; pLastChange = 0; diff --git a/zone/zonedb.cpp b/zone/zonedb.cpp index 79aee5662..6e2953534 100644 --- a/zone/zonedb.cpp +++ b/zone/zonedb.cpp @@ -1884,15 +1884,13 @@ void ZoneDatabase::LoadMercBuffs(Merc *merc) { BuffsLoaded = true; } - safe_delete(Query); - Query = 0; + safe_delete_array(Query); if(errorMessage.empty() && BuffsLoaded) { if(!database.RunQuery(Query, MakeAnyLenString(&Query, "DELETE FROM merc_buffs WHERE MercId = %u", merc->GetMercID()), TempErrorMessageBuffer)) { errorMessage = std::string(TempErrorMessageBuffer); - safe_delete(Query); - Query = 0; } + safe_delete_array(Query); } if(!errorMessage.empty()) { @@ -2206,7 +2204,7 @@ uint8 ZoneDatabase::GetZoneWeather(uint32 zoneid, uint32 version) { MYSQL_RES *result; MYSQL_ROW row; - if (RunQuery(query, MakeAnyLenString(&query, "SELECT weather FROM zone WHERE zoneidnumber=%i AND (version=%i OR version=0) ORDER BY version DESC", zoneid), errbuf, &result)) + if (RunQuery(query, MakeAnyLenString(&query, "SELECT weather FROM zone WHERE zoneidnumber=%i AND (version=%i OR version=0) ORDER BY version DESC", zoneid, version), errbuf, &result)) { safe_delete_array(query); if (mysql_num_rows(result) > 0) {