From e7ef4b5484fe3df0fa0e78eff5ac415aa7ddf7ea Mon Sep 17 00:00:00 2001 From: Arthur Ice Date: Sun, 24 Aug 2014 12:37:44 -0700 Subject: [PATCH] SpellGlobalCheck converted to QueryDatabase --- zone/spells.cpp | 160 ++++++++++++++++++++++-------------------------- 1 file changed, 74 insertions(+), 86 deletions(-) diff --git a/zone/spells.cpp b/zone/spells.cpp index 4eddf5883..357fafbd4 100644 --- a/zone/spells.cpp +++ b/zone/spells.cpp @@ -1252,7 +1252,7 @@ void Mob::CastedSpellFinished(uint16 spell_id, uint32 target_id, uint16 slot, } } - if(IsClient()) { + if(IsClient()) { CheckNumHitsRemaining(NUMHIT_MatchingSpells); TrySympatheticProc(target, spell_id); } @@ -1378,7 +1378,7 @@ bool Mob::DetermineSpellTargets(uint16 spell_id, Mob *&spell_target, Mob *&ae_ce mlog(AA__MESSAGE, "Project Illusion overwrote target caster: %s spell id: %d was ON", GetName(), spell_id); targetType = ST_GroupClientAndPet; } - + if (spell_target && !spell_target->PassCastRestriction(true, spells[spell_id].CastRestriction)){ Message_StringID(13,SPELL_NEED_TAR); return false; @@ -1386,16 +1386,16 @@ bool Mob::DetermineSpellTargets(uint16 spell_id, Mob *&spell_target, Mob *&ae_ce //Must be out of combat. (If Beneficial checks casters combat state, Deterimental checks targets) if (!spells[spell_id].InCombat && spells[spell_id].OutofCombat){ - if (IsDetrimentalSpell(spell_id)) { - if ( (spell_target->IsNPC() && spell_target->IsEngaged()) || + if (IsDetrimentalSpell(spell_id)) { + if ( (spell_target->IsNPC() && spell_target->IsEngaged()) || (spell_target->IsClient() && spell_target->CastToClient()->GetAggroCount())){ Message_StringID(13,SPELL_NO_EFFECT); //Unsure correct string return false; } } - else if (IsBeneficialSpell(spell_id)) { - if ( (IsNPC() && IsEngaged()) || + else if (IsBeneficialSpell(spell_id)) { + if ( (IsNPC() && IsEngaged()) || (IsClient() && CastToClient()->GetAggroCount())){ if (IsDiscipline(spell_id)) Message_StringID(13,NO_ABILITY_IN_COMBAT); @@ -1409,16 +1409,16 @@ bool Mob::DetermineSpellTargets(uint16 spell_id, Mob *&spell_target, Mob *&ae_ce //Must be in combat. (If Beneficial checks casters combat state, Deterimental checks targets) else if (spells[spell_id].InCombat && !spells[spell_id].OutofCombat){ - if (IsDetrimentalSpell(spell_id)) { - if ( (spell_target->IsNPC() && !spell_target->IsEngaged()) || + if (IsDetrimentalSpell(spell_id)) { + if ( (spell_target->IsNPC() && !spell_target->IsEngaged()) || (spell_target->IsClient() && !spell_target->CastToClient()->GetAggroCount())){ Message_StringID(13,SPELL_NO_EFFECT); //Unsure correct string return false; } } - else if (IsBeneficialSpell(spell_id)) { - if ( (IsNPC() && !IsEngaged()) || + else if (IsBeneficialSpell(spell_id)) { + if ( (IsNPC() && !IsEngaged()) || (IsClient() && !CastToClient()->GetAggroCount())){ if (IsDiscipline(spell_id)) Message_StringID(13,NO_ABILITY_OUT_OF_COMBAT); @@ -1782,10 +1782,10 @@ bool Mob::DetermineSpellTargets(uint16 spell_id, Mob *&spell_target, Mob *&ae_ce case ST_PetMaster: { - + Mob *owner = nullptr; - - if (IsPet()) + + if (IsPet()) owner = GetOwner(); else if ((IsNPC() && CastToNPC()->GetSwarmOwner())) owner = entity_list.GetMobID(CastToNPC()->GetSwarmOwner()); @@ -1975,7 +1975,7 @@ bool Mob::SpellFinished(uint16 spell_id, Mob *spell_target, uint16 slot, uint16 if (!TrySpellProjectile(spell_target, spell_id)) return false; } - + else if(!SpellOnTarget(spell_id, spell_target, false, true, resist_adjust, false)) { if(IsBuffSpell(spell_id) && IsBeneficialSpell(spell_id)) { // Prevent mana usage/timers being set for beneficial buffs @@ -2723,7 +2723,7 @@ int Mob::CheckStackConflict(uint16 spellid1, int caster_level1, uint16 spellid2, if ((effect2 == SE_BStacker) && (!IsCastonFadeDurationSpell(spellid1) && buffs[buffslot].ticsremaining != 1 && IsEffectInSpell(spellid1, SE_CStacker))) return -1; } - + if (spellbonuses.DStacker[0]) { if ((effect2 == SE_DStacker) && (sp2.effectid[i] <= spellbonuses.DStacker[1])) return -1; @@ -2775,7 +2775,7 @@ int Mob::CheckStackConflict(uint16 spellid1, int caster_level1, uint16 spellid2, mlog(SPELLS__STACKING, "%s (%d) blocks effect %d on slot %d below %d, but we do not have that effect on that slot. Ignored.", sp1.name, spellid1, blocked_effect, blocked_slot, blocked_below_value); } - } + } } } else { mlog(SPELLS__STACKING, "%s (%d) and %s (%d) appear to be in the same line, skipping Stacking Overwrite/Blocking checks", @@ -3564,7 +3564,7 @@ bool Mob::SpellOnTarget(uint16 spell_id, Mob* spelltar, bool reflect, bool use_r if(spell_effectiveness == 0 || !IsPartialCapableSpell(spell_id) ) { mlog(SPELLS__RESISTS, "Spell %d was completely resisted by %s", spell_id, spelltar->GetName()); - + if (spells[spell_id].resisttype == RESIST_PHYSICAL){ Message_StringID(MT_SpellFailure, PHYSICAL_RESIST_FAIL,spells[spell_id].name); spelltar->Message_StringID(MT_SpellFailure, YOU_RESIST, spells[spell_id].name); @@ -3707,7 +3707,7 @@ bool Mob::SpellOnTarget(uint16 spell_id, Mob* spelltar, bool reflect, bool use_r TrySpellTrigger(spelltar, spell_id); TryApplyEffect(spelltar, spell_id); - + if (spelltar->IsAIControlled() && IsDetrimentalSpell(spell_id) && !IsHarmonySpell(spell_id)) { int32 aggro_amount = CheckAggroAmount(spell_id, isproc); mlog(SPELLS__CASTING, "Spell %d cast on %s generated %d hate", spell_id, spelltar->GetName(), aggro_amount); @@ -3733,7 +3733,7 @@ bool Mob::SpellOnTarget(uint16 spell_id, Mob* spelltar, bool reflect, bool use_r safe_delete(action_packet); return false; } - + // cause the effects to the target if(!spelltar->SpellEffect(this, spell_id, spell_effectiveness)) { @@ -3746,11 +3746,11 @@ bool Mob::SpellOnTarget(uint16 spell_id, Mob* spelltar, bool reflect, bool use_r return false; } - + if (IsDetrimentalSpell(spell_id)) { - + CheckNumHitsRemaining(NUMHIT_OutgoingSpells); - + if (spelltar) spelltar->CheckNumHitsRemaining(NUMHIT_IncomingSpells); } @@ -4408,7 +4408,7 @@ float Mob::ResistSpell(uint8 resist_type, uint16 spell_id, Mob *caster, bool use if (CharismaCheck) { - /* + /* Charisma ONLY effects the initial resist check when charm is cast with 10 CHA = -1 Resist mod up to 255 CHA (min ~ 75 cha) Charisma less than ~ 75 gives a postive modifier to resist checks at approximate ratio of -10 CHA = +6 Resist. Mez spells do same initial resist check as a above. @@ -4470,7 +4470,7 @@ float Mob::ResistSpell(uint8 resist_type, uint16 spell_id, Mob *caster, bool use if (CharmTick) { int min_charmbreakchance = ((100/RuleI(Spells, CharmBreakCheckChance))/66 * 100)*2; - + if (resist_chance < min_charmbreakchance) resist_chance = min_charmbreakchance; } @@ -4965,68 +4965,56 @@ int Client::FindSpellBookSlotBySpellID(uint16 spellid) { return -1; //default } -bool Client::SpellGlobalCheck(uint16 Spell_ID, uint16 Char_ID) { +bool Client::SpellGlobalCheck(uint16 spell_ID, uint16 char_ID) { - std::string Spell_Global_Name; - int Spell_Global_Value; - int Global_Value; + std::string spell_Global_Name; + int spell_Global_Value; + int global_Value; - char errbuf[MYSQL_ERRMSG_SIZE]; - char *query = 0; - MYSQL_RES *result; - MYSQL_ROW row; - - if (database.RunQuery(query,MakeAnyLenString(&query, "SELECT qglobal, value FROM spell_globals WHERE spellid=%i", Spell_ID), errbuf, &result)) { - safe_delete_array(query); - - if (mysql_num_rows(result) == 1) { - row = mysql_fetch_row(result); - Spell_Global_Name = row[0]; - Spell_Global_Value = atoi(row[1]); - - mysql_free_result(result); - - if (Spell_Global_Name.empty()) { // If the entry in the spell_globals table has nothing set for the qglobal name - return true; - } - else if (database.RunQuery(query,MakeAnyLenString(&query, "SELECT value FROM quest_globals WHERE charid=%i AND name='%s'", Char_ID, Spell_Global_Name.c_str()), errbuf, &result)) { - safe_delete_array(query); - - if (mysql_num_rows(result) == 1) { - row = mysql_fetch_row(result); - - Global_Value = atoi(row[0]); - mysql_free_result(result); - if (Global_Value == Spell_Global_Value) { // If the values match from both tables, allow the spell to be scribed - return true; - } - else if (Global_Value > Spell_Global_Value) { // Check if the qglobal value is greater than the require spellglobal value - return true; - } - else // If no matching result found in qglobals, don't scribe this spell - { - LogFile->write(EQEMuLog::Error, "Char ID: %i Spell_globals Name: '%s' Value: '%i' did not match QGlobal Value: '%i' for Spell ID %i", Char_ID, Spell_Global_Name.c_str(), Spell_Global_Value, Global_Value, Spell_ID); - return false; - } - } - else - LogFile->write(EQEMuLog::Error, "Char ID: %i does not have the Qglobal Name: '%s' for Spell ID %i", Char_ID, Spell_Global_Name.c_str(), Spell_ID); - safe_delete_array(query); - } - else - LogFile->write(EQEMuLog::Error, "Spell ID %i query of spell_globals with Name: '%s' Value: '%i' failed", Spell_ID, Spell_Global_Name.c_str(), Spell_Global_Value); - } - else { - return true; // Spell ID isn't listed in the spells_global table, so it is not restricted from scribing - } - mysql_free_result(result); - } - else { - LogFile->write(EQEMuLog::Error, "Error while querying Spell ID %i spell_globals table query '%s': %s", Spell_ID, query, errbuf); - safe_delete_array(query); + std::string query = StringFormat("SELECT qglobal, value FROM spell_globals " + "WHERE spellid = %i", spell_ID); + auto results = database.QueryDatabase(query); + if (!results.Success()) { + LogFile->write(EQEMuLog::Error, "Error while querying Spell ID %i spell_globals table query '%s': %s", spell_ID, query.c_str(), results.ErrorMessage().c_str()); return false; // Query failed, so prevent spell from scribing just in case - } - return false; // Default is false + } + + if (results.RowCount() != 1) + return true; // Spell ID isn't listed in the spells_global table, so it is not restricted from scribing + + auto row = results.begin(); + spell_Global_Name = row[0]; + spell_Global_Value = atoi(row[1]); + + if (spell_Global_Name.empty()) + return true; // If the entry in the spell_globals table has nothing set for the qglobal name + + query = StringFormat("SELECT value FROM quest_globals " + "WHERE charid = %i AND name = '%s'", + char_ID, spell_Global_Name.c_str()); + results = database.QueryDatabase(query); + if (!results.Success()) { + LogFile->write(EQEMuLog::Error, "Spell ID %i query of spell_globals with Name: '%s' Value: '%i' failed", spell_ID, spell_Global_Name.c_str(), spell_Global_Value); + return false; + } + + if (results.RowCount() != 1) { + LogFile->write(EQEMuLog::Error, "Char ID: %i does not have the Qglobal Name: '%s' for Spell ID %i", char_ID, spell_Global_Name.c_str(), spell_ID); + return false; + } + + row = results.begin(); + + global_Value = atoi(row[0]); + + if (global_Value == spell_Global_Value) + return true; // If the values match from both tables, allow the spell to be scribed + else if (global_Value > spell_Global_Value) + return true; // Check if the qglobal value is greater than the require spellglobal value + + // If no matching result found in qglobals, don't scribe this spell + LogFile->write(EQEMuLog::Error, "Char ID: %i Spell_globals Name: '%s' Value: '%i' did not match QGlobal Value: '%i' for Spell ID %i", char_ID, spell_Global_Name.c_str(), spell_Global_Value, global_Value, spell_ID); + return false; } // TODO get rid of this @@ -5081,7 +5069,7 @@ bool Mob::FindType(uint16 type, bool bOffensive, uint16 threshold) { } bool Mob::IsCombatProc(uint16 spell_id) { - + if (RuleB(Spells, FocusCombatProcs)) return false; @@ -5092,7 +5080,7 @@ bool Mob::IsCombatProc(uint16 spell_id) { { for (int i = 0; i < MAX_PROCS; i++){ - if (PermaProcs[i].spellID == spell_id || SpellProcs[i].spellID == spell_id + if (PermaProcs[i].spellID == spell_id || SpellProcs[i].spellID == spell_id || RangedProcs[i].spellID == spell_id){ return true; } @@ -5150,7 +5138,7 @@ bool Mob::AddDefensiveProc(uint16 spell_id, uint16 iChance, uint16 base_spell_id { if(spell_id == SPELL_UNKNOWN) return(false); - + int i; for (i = 0; i < MAX_PROCS; i++) { if (DefensiveProcs[i].spellID == SPELL_UNKNOWN) {