diff --git a/common/shareddb.cpp b/common/shareddb.cpp index 2a52ebe0e..18a2bed3d 100644 --- a/common/shareddb.cpp +++ b/common/shareddb.cpp @@ -1840,6 +1840,7 @@ void SharedDatabase::LoadSpells(void *data, int max_spells) { sp[tempid].effectdescnum = atoi(row[157]); sp[tempid].npc_no_los = atoi(row[159]) != 0; + sp[tempid].feedbackable = atoi(row[160]) != 0; sp[tempid].reflectable = atoi(row[161]) != 0; sp[tempid].bonushate=atoi(row[162]); @@ -2287,4 +2288,4 @@ void SharedDatabase::LoadCharacterInspectMessage(uint32 character_id, InspectMes void SharedDatabase::SaveCharacterInspectMessage(uint32 character_id, const InspectMessage_Struct* message) { std::string query = StringFormat("REPLACE INTO `character_inspect_messages` (id, inspect_message) VALUES (%u, '%s')", character_id, EscapeString(message->text).c_str()); auto results = QueryDatabase(query); -} \ No newline at end of file +} diff --git a/common/spdat.cpp b/common/spdat.cpp index 581575aa4..8721078d7 100644 --- a/common/spdat.cpp +++ b/common/spdat.cpp @@ -1427,6 +1427,7 @@ int GetSpellStatValue(uint32 spell_id, const char* stat_identifier, uint8 slot) else if (id == "descnum") { return spells[spell_id].descnum; } else if (id == "effectdescnum") { return spells[spell_id].effectdescnum; } else if (id == "npc_no_los") { return spells[spell_id].npc_no_los; } + else if (id == "feedbackable") { return spells[spell_id].feedbackable; } else if (id == "reflectable") { return spells[spell_id].reflectable; } else if (id == "bonushate") { return spells[spell_id].bonushate; } else if (id == "endurcost") { return spells[spell_id].EndurCost; } @@ -1469,4 +1470,4 @@ int GetSpellStatValue(uint32 spell_id, const char* stat_identifier, uint8 slot) else if (id == "damageshieldtype") { return spells[spell_id].DamageShieldType; } return 0; -} \ No newline at end of file +} diff --git a/common/spdat.h b/common/spdat.h index 0e9c8c027..509170000 100644 --- a/common/spdat.h +++ b/common/spdat.h @@ -842,7 +842,7 @@ typedef enum { #define SE_DispelDetrimental 154 // implemented, @Dispel, removes only detrimental effects on a target, base: pct chance (950=95%), limit: none, max: none #define SE_SpellCritDmgIncrease 155 // implemented - no known live spells use this currently #define SE_IllusionCopy 156 // implemented - Deception -#define SE_SpellDamageShield 157 // implemented - Petrad's Protection +#define SE_SpellDamageShield 157 // implemented, @DS, causes non-melee damage on caster of a spell, base: Amt DS (negative), limit: none, max: unknown (same as base but +) #define SE_Reflect 158 // implemented #define SE_AllStats 159 // implemented //#define SE_MakeDrunk 160 // *not implemented - Effect works entirely client side (Should check against tolerance) @@ -1302,7 +1302,7 @@ struct SPDat_Spell_Struct /* 157 */ int effectdescnum; // eqstr of effect description -- SECONDARY_CATEGORY_1 /* 158 */ //int secondary_category_2; //Category Desc ID 3 -- SECONDARY_CATEGORY_2 /* 159 */ bool npc_no_los; // -- NO_NPC_LOS -/* 160 */ //bool feedbackable; // -- FEEDBACKABLE +/* 160 */ bool feedbackable; // -- FEEDBACKABLE /* 161 */ bool reflectable; // -- REFLECTABLE /* 162 */ int bonushate; // -- HATE_MOD /* 163 */ //int resist_per_level; // -- RESIST_PER_LEVEL diff --git a/zone/attack.cpp b/zone/attack.cpp index d5cd9005c..dbfee1e3a 100644 --- a/zone/attack.cpp +++ b/zone/attack.cpp @@ -2875,10 +2875,15 @@ void Mob::DamageShield(Mob* attacker, bool spell_ds) { spellid = spellbonuses.DamageShieldSpellID; } else { - DS = spellbonuses.SpellDamageShield; + DS = spellbonuses.SpellDamageShield + itembonuses.SpellDamageShield + aabonuses.SpellDamageShield; rev_ds = 0; // This ID returns "you are burned", seemed most appropriate for spell DS spellid = 2166; + /* + Live Message - not yet used on emu + Feedback onto you "YOUR mind burns from TARGETS NAME's feedback for %i points of non-melee damage." + Feedback onto other "TARGETS NAME's mind burns from YOUR feedback for %i points of non-melee damage." + */ } if (DS == 0 && rev_ds == 0) @@ -2912,6 +2917,7 @@ void Mob::DamageShield(Mob* attacker, bool spell_ds) { DS -= DS * ds_mitigation / 100; } + attacker->Damage(this, -DS, spellid, EQ::skills::SkillAbjuration/*hackish*/, false); //we can assume there is a spell now auto outapp = new EQApplicationPacket(OP_Damage, sizeof(CombatDamage_Struct)); diff --git a/zone/bonuses.cpp b/zone/bonuses.cpp index 390917ff7..9a640196a 100644 --- a/zone/bonuses.cpp +++ b/zone/bonuses.cpp @@ -1672,6 +1672,10 @@ void Mob::ApplyAABonuses(const AA::Rank &rank, StatBonuses *newbon) newbon->ZoneSuspendMinion = base1; break; + case SE_SpellDamageShield: + newbon->SpellDamageShield += base1; + break; + // to do case SE_PetDiscipline: break; @@ -3727,7 +3731,7 @@ void NPC::CalcItemBonuses(StatBonuses *newbon) newbon->DamageShield += cur->DamageShield; } if(cur->SpellShield > 0) { - newbon->SpellDamageShield += cur->SpellShield; + newbon->SpellShield += cur->SpellShield; } if(cur->Shielding > 0) { newbon->MeleeMitigation += cur->Shielding; diff --git a/zone/mob.h b/zone/mob.h index ac222a3dd..b9e3bfd85 100644 --- a/zone/mob.h +++ b/zone/mob.h @@ -848,7 +848,6 @@ public: int GetHealRate() const { return itembonuses.HealRate + spellbonuses.HealRate + aabonuses.HealRate; } int GetMemoryBlurChance(int base_chance); - bool TryDoubleMeleeRoundEffect(); bool GetUseDoubleMeleeRoundDmgBonus() const { return use_double_melee_round_dmg_bonus; } inline void SetUseDoubleMeleeRoundDmgBonus(bool val) { use_double_melee_round_dmg_bonus = val; } diff --git a/zone/spells.cpp b/zone/spells.cpp index 2553b5e10..97caa49c7 100644 --- a/zone/spells.cpp +++ b/zone/spells.cpp @@ -3989,8 +3989,9 @@ bool Mob::SpellOnTarget(uint16 spell_id, Mob *spelltar, bool reflect, bool use_r spell_effectiveness = 100; } - if(spelltar->spellbonuses.SpellDamageShield && IsDetrimentalSpell(spell_id)) + if (spells[spell_id].feedbackable && (spelltar->spellbonuses.SpellDamageShield || spelltar->itembonuses.SpellDamageShield || spelltar->aabonuses.SpellDamageShield)) { spelltar->DamageShield(this, true); + } if (spelltar->IsAIControlled() && IsDetrimentalSpell(spell_id) && !IsHarmonySpell(spell_id)) { int32 aggro_amount = CheckAggroAmount(spell_id, spelltar, isproc);