[Spells] Implement PVP resist and duration overrides (#1513)

* Make use of PVP resist field

* Implement PVP duration formulas
This commit is contained in:
Michael Cook (mackal) 2021-09-03 21:19:39 -04:00 committed by GitHub
parent af6d344e12
commit 41352f77ae
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
9 changed files with 60 additions and 24 deletions

View File

@ -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]);

View File

@ -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]);

View File

@ -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

View File

@ -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

View File

@ -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

View File

@ -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';

View File

@ -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)

View File

@ -83,6 +83,8 @@ public:
int GetPVPResistCalc();
int GetPVPResistCap();
int GetSpellCategory();
int GetPVPDuration();
int GetPVPDurationCap();
int GetCanMGB();
int GetDispelFlag();
int GetMinResist();

View File

@ -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);