From 41352f77ae2fe9d0e782022d55104a643ea87d2e Mon Sep 17 00:00:00 2001 From: "Michael Cook (mackal)" Date: Fri, 3 Sep 2021 21:19:39 -0400 Subject: [PATCH] [Spells] Implement PVP resist and duration overrides (#1513) * Make use of PVP resist field * Implement PVP duration formulas --- .../base/base_spells_new_repository.h | 36 +++++++++---------- common/shareddb.cpp | 2 ++ common/spdat.h | 4 +-- common/version.h | 2 +- utils/sql/db_update_manifest.txt | 1 + .../git/required/2021_08_31_pvp_duration.sql | 2 ++ zone/lua_spell.cpp | 12 +++++++ zone/lua_spell.h | 2 ++ zone/spells.cpp | 23 ++++++++++-- 9 files changed, 60 insertions(+), 24 deletions(-) create mode 100644 utils/sql/git/required/2021_08_31_pvp_duration.sql diff --git a/common/repositories/base/base_spells_new_repository.h b/common/repositories/base/base_spells_new_repository.h index e273667ad..111140f27 100644 --- a/common/repositories/base/base_spells_new_repository.h +++ b/common/repositories/base/base_spells_new_repository.h @@ -199,8 +199,8 @@ public: int pvpresistcalc; int pvpresistcap; int spell_category; - int field181; - int field182; + int pvp_duration; + int pvp_duration_cap; int pcnpc_only_flag; int cast_not_standing; int can_mgb; @@ -446,8 +446,8 @@ public: "pvpresistcalc", "pvpresistcap", "spell_category", - "field181", - "field182", + "pvp_duration", + "pvp_duration_cap", "pcnpc_only_flag", "cast_not_standing", "can_mgb", @@ -718,8 +718,8 @@ public: entry.pvpresistcalc = 100; entry.pvpresistcap = -150; entry.spell_category = -99; - entry.field181 = 7; - entry.field182 = 65; + entry.pvp_duration = 0; + entry.pvp_duration_cap = 0; entry.pcnpc_only_flag = 0; entry.cast_not_standing = 0; entry.can_mgb = 0; @@ -990,8 +990,8 @@ public: entry.pvpresistcalc = atoi(row[178]); entry.pvpresistcap = atoi(row[179]); entry.spell_category = atoi(row[180]); - entry.field181 = atoi(row[181]); - entry.field182 = atoi(row[182]); + entry.pvp_duration = atoi(row[181]); + entry.pvp_duration_cap = atoi(row[182]); entry.pcnpc_only_flag = atoi(row[183]); entry.cast_not_standing = atoi(row[184]); entry.can_mgb = atoi(row[185]); @@ -1260,8 +1260,8 @@ public: update_values.push_back(columns[178] + " = " + std::to_string(spells_new_entry.pvpresistcalc)); update_values.push_back(columns[179] + " = " + std::to_string(spells_new_entry.pvpresistcap)); update_values.push_back(columns[180] + " = " + std::to_string(spells_new_entry.spell_category)); - update_values.push_back(columns[181] + " = " + std::to_string(spells_new_entry.field181)); - update_values.push_back(columns[182] + " = " + std::to_string(spells_new_entry.field182)); + update_values.push_back(columns[181] + " = " + std::to_string(spells_new_entry.pvp_duration)); + update_values.push_back(columns[182] + " = " + std::to_string(spells_new_entry.pvp_duration_cap)); update_values.push_back(columns[183] + " = " + std::to_string(spells_new_entry.pcnpc_only_flag)); update_values.push_back(columns[184] + " = " + std::to_string(spells_new_entry.cast_not_standing)); update_values.push_back(columns[185] + " = " + std::to_string(spells_new_entry.can_mgb)); @@ -1518,8 +1518,8 @@ public: insert_values.push_back(std::to_string(spells_new_entry.pvpresistcalc)); insert_values.push_back(std::to_string(spells_new_entry.pvpresistcap)); insert_values.push_back(std::to_string(spells_new_entry.spell_category)); - insert_values.push_back(std::to_string(spells_new_entry.field181)); - insert_values.push_back(std::to_string(spells_new_entry.field182)); + insert_values.push_back(std::to_string(spells_new_entry.pvp_duration)); + insert_values.push_back(std::to_string(spells_new_entry.pvp_duration_cap)); insert_values.push_back(std::to_string(spells_new_entry.pcnpc_only_flag)); insert_values.push_back(std::to_string(spells_new_entry.cast_not_standing)); insert_values.push_back(std::to_string(spells_new_entry.can_mgb)); @@ -1784,8 +1784,8 @@ public: insert_values.push_back(std::to_string(spells_new_entry.pvpresistcalc)); insert_values.push_back(std::to_string(spells_new_entry.pvpresistcap)); insert_values.push_back(std::to_string(spells_new_entry.spell_category)); - insert_values.push_back(std::to_string(spells_new_entry.field181)); - insert_values.push_back(std::to_string(spells_new_entry.field182)); + insert_values.push_back(std::to_string(spells_new_entry.pvp_duration)); + insert_values.push_back(std::to_string(spells_new_entry.pvp_duration_cap)); insert_values.push_back(std::to_string(spells_new_entry.pcnpc_only_flag)); insert_values.push_back(std::to_string(spells_new_entry.cast_not_standing)); insert_values.push_back(std::to_string(spells_new_entry.can_mgb)); @@ -2054,8 +2054,8 @@ public: entry.pvpresistcalc = atoi(row[178]); entry.pvpresistcap = atoi(row[179]); entry.spell_category = atoi(row[180]); - entry.field181 = atoi(row[181]); - entry.field182 = atoi(row[182]); + entry.pvp_duration = atoi(row[181]); + entry.pvp_duration_cap = atoi(row[182]); entry.pcnpc_only_flag = atoi(row[183]); entry.cast_not_standing = atoi(row[184]); entry.can_mgb = atoi(row[185]); @@ -2315,8 +2315,8 @@ public: entry.pvpresistcalc = atoi(row[178]); entry.pvpresistcap = atoi(row[179]); entry.spell_category = atoi(row[180]); - entry.field181 = atoi(row[181]); - entry.field182 = atoi(row[182]); + entry.pvp_duration = atoi(row[181]); + entry.pvp_duration_cap = atoi(row[182]); entry.pcnpc_only_flag = atoi(row[183]); entry.cast_not_standing = atoi(row[184]); entry.can_mgb = atoi(row[185]); diff --git a/common/shareddb.cpp b/common/shareddb.cpp index 7e638d6e0..7c86067bc 100644 --- a/common/shareddb.cpp +++ b/common/shareddb.cpp @@ -1855,6 +1855,8 @@ void SharedDatabase::LoadSpells(void *data, int max_spells) { sp[tempid].pvpresistcalc=atoi(row[178]); sp[tempid].pvpresistcap=atoi(row[179]); sp[tempid].spell_category=atoi(row[180]); + sp[tempid].pvp_duration = atoi(row[181]); + sp[tempid].pvp_duration_cap = atoi(row[182]); sp[tempid].pcnpc_only_flag=atoi(row[183]); sp[tempid].cast_not_standing = atoi(row[184]) != 0; sp[tempid].can_mgb=atoi(row[185]); diff --git a/common/spdat.h b/common/spdat.h index 1834b4a29..81cb122eb 100644 --- a/common/spdat.h +++ b/common/spdat.h @@ -1318,8 +1318,8 @@ struct SPDat_Spell_Struct /* 178 */ int pvpresistcalc; // -- PVP_RESIST_PER_LEVEL /* 179 */ int pvpresistcap; // -- PVP_RESIST_CAP /* 180 */ int spell_category; // -- GLOBAL_GROUP -/* 181 */ //int pvp_duration; // buffdurationformula for PvP -- PVP_DURATION -/* 182 */ //int pvp_duration_cap; // buffduration for PvP -- PVP_DURATION_CAP +/* 181 */ int pvp_duration; // buffdurationformula for PvP -- PVP_DURATION +/* 182 */ int pvp_duration_cap; // buffduration for PvP -- PVP_DURATION_CAP /* 183 */ int pcnpc_only_flag; // valid values are 0, 1 = PCs (and mercs), and 2 = NPCs (and not mercs) -- PCNPC_ONLY_FLAG /* 184 */ bool cast_not_standing; // this is checked in the client's EQ_Spell::IsCastWhileInvisSpell, this also blocks SE_InterruptCasting from affecting this spell -- CAST_NOT_STANDING /* 185 */ bool can_mgb; // 0=no, -1 or 1 = yes -- CAN_MGB diff --git a/common/version.h b/common/version.h index 514bed8c7..18a11b1b1 100644 --- a/common/version.h +++ b/common/version.h @@ -34,7 +34,7 @@ * Manifest: https://github.com/EQEmu/Server/blob/master/utils/sql/db_update_manifest.txt */ -#define CURRENT_BINARY_DATABASE_VERSION 9167 +#define CURRENT_BINARY_DATABASE_VERSION 9168 #ifdef BOTS #define CURRENT_BINARY_BOTS_DATABASE_VERSION 9028 diff --git a/utils/sql/db_update_manifest.txt b/utils/sql/db_update_manifest.txt index 8fd174822..8e6a7a40e 100644 --- a/utils/sql/db_update_manifest.txt +++ b/utils/sql/db_update_manifest.txt @@ -421,6 +421,7 @@ 9165|2021_04_28_idle_pathing.sql|SHOW COLUMNS FROM `spawn2` LIKE 'path_when_zone_idle'|empty| 9166|2021_02_12_dynamic_zone_members.sql|SHOW TABLES LIKE 'dynamic_zone_members'|empty| 9167|2021_06_06_beastlord_pets.sql|SHOW TABLES LIKE 'pets_beastlord_data'|empty| +9168|2021_08_31_pvp_duration.sql|SHOW COLUMNS FROM `spells_new` LIKE 'pvp_duration'|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/2021_08_31_pvp_duration.sql b/utils/sql/git/required/2021_08_31_pvp_duration.sql new file mode 100644 index 000000000..e0fe00bfc --- /dev/null +++ b/utils/sql/git/required/2021_08_31_pvp_duration.sql @@ -0,0 +1,2 @@ +ALTER TABLE `spells_new` CHANGE `field181` `pvp_duration` int(11) NOT NULL DEFAULT '0'; +ALTER TABLE `spells_new` CHANGE `field182` `pvp_duration_cap` int(11) NOT NULL DEFAULT '0'; diff --git a/zone/lua_spell.cpp b/zone/lua_spell.cpp index c7730efff..5e7dcff73 100644 --- a/zone/lua_spell.cpp +++ b/zone/lua_spell.cpp @@ -354,6 +354,16 @@ int Lua_Spell::GetSpellCategory() { return self->spell_category; } +int Lua_Spell::GetPVPDuration() { + Lua_Safe_Call_Int(); + return self->pvp_duration; +} + +int Lua_Spell::GetPVPDurationCap() { + Lua_Safe_Call_Int(); + return self->pvp_duration_cap; +} + int Lua_Spell::GetCanMGB() { Lua_Safe_Call_Int(); return self->can_mgb; @@ -543,6 +553,8 @@ luabind::scope lua_register_spell() { .def("PVPResistCalc", &Lua_Spell::GetPVPResistCalc) .def("PVPResistCap", &Lua_Spell::GetPVPResistCap) .def("SpellCategory", &Lua_Spell::GetSpellCategory) + .def("PVPDuration", &Lua_Spell::GetPVPDuration) + .def("PVPDurationCap", &Lua_Spell::GetPVPDurationCap) .def("CanMGB", &Lua_Spell::GetCanMGB) .def("DispelFlag", &Lua_Spell::GetDispelFlag) .def("MinResist", &Lua_Spell::GetMinResist) diff --git a/zone/lua_spell.h b/zone/lua_spell.h index e2def8a6a..b9af8a564 100644 --- a/zone/lua_spell.h +++ b/zone/lua_spell.h @@ -83,6 +83,8 @@ public: int GetPVPResistCalc(); int GetPVPResistCap(); int GetSpellCategory(); + int GetPVPDuration(); + int GetPVPDurationCap(); int GetCanMGB(); int GetDispelFlag(); int GetMinResist(); diff --git a/zone/spells.cpp b/zone/spells.cpp index 567d239c6..c098060a0 100644 --- a/zone/spells.cpp +++ b/zone/spells.cpp @@ -2816,8 +2816,14 @@ int Mob::CalcBuffDuration(Mob *caster, Mob *target, uint16 spell_id, int32 caste if(!target) target = caster; - formula = spells[spell_id].buffdurationformula; - duration = spells[spell_id].buffduration; + // PVP duration + if (IsDetrimentalSpell(spell_id) && target->IsClient() && caster->IsClient()) { + formula = spells[spell_id].pvp_duration; + duration = spells[spell_id].pvp_duration_cap; + } else { + formula = spells[spell_id].buffdurationformula; + duration = spells[spell_id].buffduration; + } int castlevel = caster->GetCasterLevel(spell_id); if(caster_level_override > 0) @@ -4591,7 +4597,18 @@ float Mob::ResistSpell(uint8 resist_type, uint16 spell_id, Mob *caster, bool use } //Get resist modifier and adjust it based on focus 2 resist about eq to 1% resist chance - int resist_modifier = (use_resist_override) ? resist_override : spells[spell_id].ResistDiff; + int resist_modifier = 0; + if (use_resist_override) { + resist_modifier = resist_override; + } else { + // PVP, we don't have the normal per_level or cap stuff implemented ... so ahh do that + // and make sure the PVP versions are also handled. + if (IsClient() && caster->IsClient()) { + resist_modifier = spells[spell_id].pvpresistbase; + } else { + resist_modifier = spells[spell_id].ResistDiff; + } + } if(caster->GetSpecialAbility(CASTING_RESIST_DIFF)) resist_modifier += caster->GetSpecialAbilityParam(CASTING_RESIST_DIFF, 0);