diff options
author | Michael <michaelneubert1988@gmail.com> | 2014-06-05 19:42:48 +0200 |
---|---|---|
committer | Michael <michaelneubert1988@gmail.com> | 2014-06-05 19:42:48 +0200 |
commit | 83c2e79d52a57ec670b439ed6f822dd18e0ac55e (patch) | |
tree | 774cb4f6a175e60ca979772559efa60411e9eff4 | |
parent | 289a5c4318c5509eafeb36389a81bddc2ed349ca (diff) | |
parent | 36102bea64d536b6ac04ac728c64321cfc5e55f2 (diff) |
Merge branch 'master' of github.com:TrinityCore/TrinityCore into 4.3.4
Conflicts:
src/server/game/Entities/Player/Player.cpp
src/server/game/Entities/Unit/Unit.cpp
src/server/game/Handlers/CharacterHandler.cpp
src/server/game/Spells/Auras/SpellAuraEffects.cpp
src/server/scripts/Spells/spell_paladin.cpp
19 files changed, 216 insertions, 199 deletions
diff --git a/sql/updates/world/2014_06_03_world_creature.sql b/sql/updates/world/2014_06_03_world_creature.sql new file mode 100644 index 00000000000..81953785fd5 --- /dev/null +++ b/sql/updates/world/2014_06_03_world_creature.sql @@ -0,0 +1 @@ +UPDATE `creature` SET `phaseMask`=1 WHERE `id`=21347; diff --git a/src/server/game/AI/CreatureAI.cpp b/src/server/game/AI/CreatureAI.cpp index dd8b42deb9f..ac9de00cd10 100644 --- a/src/server/game/AI/CreatureAI.cpp +++ b/src/server/game/AI/CreatureAI.cpp @@ -43,6 +43,11 @@ void CreatureAI::Talk(uint8 id, WorldObject const* whisperTarget /*= NULL*/) sCreatureTextMgr->SendChat(me, id, whisperTarget); } +void CreatureAI::TalkToMap(uint8 id, WorldObject const* whisperTarget /*= NULL*/) +{ + sCreatureTextMgr->SendChat(me, id, whisperTarget, CHAT_MSG_ADDON, LANG_ADDON, TEXT_RANGE_MAP); +} + void CreatureAI::DoZoneInCombat(Creature* creature /*= NULL*/, float maxRangeToNearestTarget /* = 50.0f*/) { if (!creature) diff --git a/src/server/game/AI/CreatureAI.h b/src/server/game/AI/CreatureAI.h index 6357ac33f1e..209995d359d 100644 --- a/src/server/game/AI/CreatureAI.h +++ b/src/server/game/AI/CreatureAI.h @@ -79,6 +79,7 @@ class CreatureAI : public UnitAI public: void Talk(uint8 id, WorldObject const* whisperTarget = NULL); + void TalkToMap(uint8 id, WorldObject const* whisperTarget = NULL); explicit CreatureAI(Creature* creature) : UnitAI(creature), me(creature), m_MoveInLineOfSight_locked(false) { } virtual ~CreatureAI() { } diff --git a/src/server/game/AI/CreatureAIImpl.h b/src/server/game/AI/CreatureAIImpl.h index 7447e290ba9..378d3ca18ab 100644 --- a/src/server/game/AI/CreatureAIImpl.h +++ b/src/server/game/AI/CreatureAIImpl.h @@ -327,7 +327,7 @@ class EventMap typedef std::multimap<uint32, uint32> EventStore; public: - EventMap() : _time(0), _phase(0) { } + EventMap() : _time(0), _phase(0), _lastEvent(0) { } /** * @name Reset @@ -447,27 +447,22 @@ class EventMap /** * @name RepeatEvent - * @brief Cancels the closest event and reschedules it. + * @brief Repeats the mostly recently executed event. * @param time Time until the event occurs. */ - void RepeatEvent(uint32 time) + void Repeat(uint32 time) { - if (Empty()) - return; - - uint32 eventId = _eventMap.begin()->second; - _eventMap.erase(_eventMap.begin()); - ScheduleEvent(eventId, time); + _eventMap.insert(EventStore::value_type(_time + time, _lastEvent)); } /** - * @name PopEvent - * @brief Remove the first event in the map. + * @name RepeatEvent + * @brief Repeats the mostly recently executed event. + * @param time Time until the event occurs. Equivalent to Repeat(urand(minTime, maxTime). */ - void PopEvent() + void Repeat(uint32 minTime, uint32 maxTime) { - if (!Empty()) - _eventMap.erase(_eventMap.begin()); + Repeat(urand(minTime, maxTime)); } /** @@ -488,6 +483,7 @@ class EventMap else { uint32 eventId = (itr->second & 0x0000FFFF); + _lastEvent = itr->second; // include phase/group _eventMap.erase(itr); return eventId; } @@ -497,28 +493,6 @@ class EventMap } /** - * @name GetEvent - * @brief Returns the next event to execute. - * @return Id of the event to execute. - */ - uint32 GetEvent() - { - while (!Empty()) - { - EventStore::iterator itr = _eventMap.begin(); - - if (itr->first > _time) - return 0; - else if (_phase && (itr->second & 0xFF000000) && !(itr->second & (_phase << 24))) - _eventMap.erase(itr); - else - return (itr->second & 0x0000FFFF); - } - - return 0; - } - - /** * @name DelayEvents * @brief Delays all events in the map. If delay is greater than or equal internal timer, delay will be 0. * @param delay Amount of delay. @@ -631,6 +605,21 @@ class EventMap return phase <= 8 && (!phase || _phase & (1 << (phase - 1))); } + /** + * @name GetTimeUntilEvent + * @brief Returns time in milliseconds until next event. + * @param Id of the event. + * @return Time of next event. + */ + uint32 GetTimeUntilEvent(uint32 eventId) const + { + for (EventStore::const_iterator itr = _eventMap.begin(); itr != _eventMap.end(); ++itr) + if (eventId == (itr->second & 0x0000FFFF)) + return itr->first - _time; + + return std::numeric_limits<uint32>::max(); + } + private: /** * @name _time @@ -662,6 +651,13 @@ class EventMap * details. */ EventStore _eventMap; + + + /** + * @name _lastEvent + * @brief Stores information on the most recently executed event + */ + uint32 _lastEvent; }; enum AITarget diff --git a/src/server/game/Accounts/AccountMgr.cpp b/src/server/game/Accounts/AccountMgr.cpp index d8f61a22314..773e169e5c2 100644 --- a/src/server/game/Accounts/AccountMgr.cpp +++ b/src/server/game/Accounts/AccountMgr.cpp @@ -517,7 +517,7 @@ bool AccountMgr::HasPermission(uint32 accountId, uint32 permissionId, uint32 rea return false; } - rbac::RBACData rbac(accountId, "", realmId); + rbac::RBACData rbac(accountId, "", realmId, GetSecurity(accountId)); rbac.LoadFromDB(); bool hasPermission = rbac.HasPermission(permissionId); diff --git a/src/server/game/Entities/Player/Player.cpp b/src/server/game/Entities/Player/Player.cpp index 5ab77a6bb34..ac6b6a97fbb 100644 --- a/src/server/game/Entities/Player/Player.cpp +++ b/src/server/game/Entities/Player/Player.cpp @@ -708,7 +708,7 @@ Player::Player(WorldSession* session): Unit(true), phaseMgr(this) m_areaUpdateId = 0; m_team = 0; - + m_needsZoneUpdate = false; m_nextSave = sWorld->getIntConfig(CONFIG_INTERVAL_SAVE); @@ -5930,31 +5930,30 @@ float Player::OCTRegenMPPerSpirit() void Player::ApplyRatingMod(CombatRating cr, int32 value, bool apply) { - m_baseRatingValue[cr] +=(apply ? value : -value); + m_baseRatingValue[cr] += (apply ? value : -value); // explicit affected values + float const mult = GetRatingMultiplier(cr); + float const oldVal = m_baseRatingValue[cr] * mult; + float const newVal = m_baseRatingValue[cr] * mult; + switch (cr) { case CR_HASTE_MELEE: - { - float RatingChange = value * GetRatingMultiplier(cr); - ApplyAttackTimePercentMod(BASE_ATTACK, RatingChange, apply); - ApplyAttackTimePercentMod(OFF_ATTACK, RatingChange, apply); - if (getClass() == CLASS_DEATH_KNIGHT) - UpdateAllRunesRegen(); + ApplyAttackTimePercentMod(BASE_ATTACK, oldVal, false); + ApplyAttackTimePercentMod(OFF_ATTACK, oldVal, false); + ApplyAttackTimePercentMod(BASE_ATTACK, newVal, true); + ApplyAttackTimePercentMod(OFF_ATTACK, newVal, true); break; - } case CR_HASTE_RANGED: - { - ApplyAttackTimePercentMod(RANGED_ATTACK, value * GetRatingMultiplier(cr), apply); + ApplyAttackTimePercentMod(RANGED_ATTACK, oldVal, false); + ApplyAttackTimePercentMod(RANGED_ATTACK, newVal, true); break; - } case CR_HASTE_SPELL: - { - ApplyCastTimePercentMod(value * GetRatingMultiplier(cr), apply); + ApplyCastTimePercentMod(oldVal, false); + ApplyCastTimePercentMod(newVal, true); break; - } - default: + default: // shut up compiler warnings break; } diff --git a/src/server/game/Entities/Unit/Unit.cpp b/src/server/game/Entities/Unit/Unit.cpp index 038db352edd..30c20b08cac 100644 --- a/src/server/game/Entities/Unit/Unit.cpp +++ b/src/server/game/Entities/Unit/Unit.cpp @@ -957,79 +957,85 @@ void Unit::CalculateSpellDamageTaken(SpellNonMeleeDamage* damageInfo, int32 dama SpellSchoolMask damageSchoolMask = SpellSchoolMask(damageInfo->schoolMask); - if (IsDamageReducedByArmor(damageSchoolMask, spellInfo)) - damage = CalcArmorReducedDamage(victim, damage, spellInfo, attackType); - - bool blocked = false; - // Per-school calc - switch (spellInfo->DmgClass) + // Spells with SPELL_ATTR4_FIXED_DAMAGE ignore resilience because their damage is based off another spell's damage. + if (!(spellInfo->AttributesEx4 & SPELL_ATTR4_FIXED_DAMAGE)) { - // Melee and Ranged Spells - case SPELL_DAMAGE_CLASS_RANGED: - case SPELL_DAMAGE_CLASS_MELEE: + if (IsDamageReducedByArmor(damageSchoolMask, spellInfo)) + damage = CalcArmorReducedDamage(victim, damage, spellInfo, attackType); + + bool blocked = false; + // Per-school calc + switch (spellInfo->DmgClass) { - // Physical Damage - if (damageSchoolMask & SPELL_SCHOOL_MASK_NORMAL) + // Melee and Ranged Spells + case SPELL_DAMAGE_CLASS_RANGED: + case SPELL_DAMAGE_CLASS_MELEE: { - // Get blocked status - blocked = isSpellBlocked(victim, spellInfo, attackType); - } + // Physical Damage + if (damageSchoolMask & SPELL_SCHOOL_MASK_NORMAL) + { + // Get blocked status + blocked = isSpellBlocked(victim, spellInfo, attackType); + } - if (crit) - { - damageInfo->HitInfo |= SPELL_HIT_TYPE_CRIT; - - // Calculate crit bonus - uint32 crit_bonus = damage; - // Apply crit_damage bonus for melee spells - if (Player* modOwner = GetSpellModOwner()) - modOwner->ApplySpellMod(spellInfo->Id, SPELLMOD_CRIT_DAMAGE_BONUS, crit_bonus); - damage += crit_bonus; - - // Apply SPELL_AURA_MOD_ATTACKER_RANGED_CRIT_DAMAGE or SPELL_AURA_MOD_ATTACKER_MELEE_CRIT_DAMAGE - float critPctDamageMod = 0.0f; - if (attackType == RANGED_ATTACK) - critPctDamageMod += victim->GetTotalAuraModifier(SPELL_AURA_MOD_ATTACKER_RANGED_CRIT_DAMAGE); - else - critPctDamageMod += victim->GetTotalAuraModifier(SPELL_AURA_MOD_ATTACKER_MELEE_CRIT_DAMAGE); + if (crit) + { + damageInfo->HitInfo |= SPELL_HIT_TYPE_CRIT; + + // Calculate crit bonus + uint32 crit_bonus = damage; + // Apply crit_damage bonus for melee spells + if (Player* modOwner = GetSpellModOwner()) + modOwner->ApplySpellMod(spellInfo->Id, SPELLMOD_CRIT_DAMAGE_BONUS, crit_bonus); + damage += crit_bonus; + + // Apply SPELL_AURA_MOD_ATTACKER_RANGED_CRIT_DAMAGE or SPELL_AURA_MOD_ATTACKER_MELEE_CRIT_DAMAGE + float critPctDamageMod = 0.0f; + if (attackType == RANGED_ATTACK) + critPctDamageMod += victim->GetTotalAuraModifier(SPELL_AURA_MOD_ATTACKER_RANGED_CRIT_DAMAGE); + else + critPctDamageMod += victim->GetTotalAuraModifier(SPELL_AURA_MOD_ATTACKER_MELEE_CRIT_DAMAGE); - // Increase crit damage from SPELL_AURA_MOD_CRIT_DAMAGE_BONUS - critPctDamageMod += (GetTotalAuraMultiplierByMiscMask(SPELL_AURA_MOD_CRIT_DAMAGE_BONUS, spellInfo->GetSchoolMask()) - 1.0f) * 100; + // Increase crit damage from SPELL_AURA_MOD_CRIT_DAMAGE_BONUS + critPctDamageMod += (GetTotalAuraMultiplierByMiscMask(SPELL_AURA_MOD_CRIT_DAMAGE_BONUS, spellInfo->GetSchoolMask()) - 1.0f) * 100; - if (critPctDamageMod != 0) - AddPct(damage, critPctDamageMod); - } + if (critPctDamageMod != 0) + AddPct(damage, critPctDamageMod); + } - // Spell weapon based damage CAN BE crit & blocked at same time - if (blocked) - { - // double blocked amount if block is critical - uint32 value = victim->GetBlockPercent(); - if (victim->isBlockCritical()) - value *= 2; // double blocked percent - damageInfo->blocked = CalculatePct(damage, value); - damage -= damageInfo->blocked; - } + // Spell weapon based damage CAN BE crit & blocked at same time + if (blocked) + { + // double blocked amount if block is critical + uint32 value = victim->GetBlockPercent(); + if (victim->isBlockCritical()) + value *= 2; // double blocked percent + damageInfo->blocked = CalculatePct(damage, value); + damage -= damageInfo->blocked; + } - ApplyResilience(victim, &damage); - break; - } - // Magical Attacks - case SPELL_DAMAGE_CLASS_NONE: - case SPELL_DAMAGE_CLASS_MAGIC: - { - // If crit add critical bonus - if (crit) - { - damageInfo->HitInfo |= SPELL_HIT_TYPE_CRIT; - damage = SpellCriticalDamageBonus(spellInfo, damage, victim); + ApplyResilience(victim, &damage); + break; } + // Magical Attacks + case SPELL_DAMAGE_CLASS_NONE: + case SPELL_DAMAGE_CLASS_MAGIC: + { + // If crit add critical bonus + if (crit) + { + damageInfo->HitInfo |= SPELL_HIT_TYPE_CRIT; + damage = SpellCriticalDamageBonus(spellInfo, damage, victim); - ApplyResilience(victim, &damage); - break; + } + + ApplyResilience(victim, &damage); + break; + + } + default: + break; } - default: - break; } // Script Hook For CalculateSpellDamageTaken -- Allow scripts to change the Damage post class mitigation calculations @@ -8409,11 +8415,6 @@ uint32 Unit::SpellDamageBonusDone(Unit* victim, SpellInfo const* spellProto, uin if (spellProto->AttributesEx3 & SPELL_ATTR3_NO_DONE_BONUS) return pdamage; - // small exception for Deep Wounds, can't find any general rule - // should ignore ALL damage mods, they already calculated in trigger spell - if (spellProto->Id == 12721) // Deep Wounds - return pdamage; - // For totems get damage bonus from owner if (GetTypeId() == TYPEID_UNIT && ToCreature()->IsTotem()) if (Unit* owner = GetOwner()) @@ -8429,7 +8430,7 @@ uint32 Unit::SpellDamageBonusDone(Unit* victim, SpellInfo const* spellProto, uin DoneTotalMod *= ToCreature()->GetSpellDamageMod(ToCreature()->GetCreatureTemplate()->rank); // Some spells don't benefit from pct done mods - if (!(spellProto->AttributesEx6 & SPELL_ATTR6_NO_DONE_PCT_DAMAGE_MODS) && !spellProto->IsRankOf(sSpellMgr->GetSpellInfo(12162))) + if (!(spellProto->AttributesEx6 & SPELL_ATTR6_NO_DONE_PCT_DAMAGE_MODS)) { AuraEffectList const& mModDamagePercentDone = GetAuraEffectsByType(SPELL_AURA_MOD_DAMAGE_PERCENT_DONE); for (AuraEffectList::const_iterator i = mModDamagePercentDone.begin(); i != mModDamagePercentDone.end(); ++i) @@ -8680,18 +8681,15 @@ uint32 Unit::SpellDamageBonusTaken(Unit* caster, SpellInfo const* spellProto, ui float TakenTotalMod = 1.0f; float TakenTotalCasterMod = 0.0f; - // get all auras from caster that allow the spell to ignore resistance (sanctified wrath) - AuraEffectList const& IgnoreResistAuras = caster->GetAuraEffectsByType(SPELL_AURA_MOD_IGNORE_TARGET_RESIST); - for (AuraEffectList::const_iterator i = IgnoreResistAuras.begin(); i != IgnoreResistAuras.end(); ++i) + // Mod damage from spell mechanic + if (uint32 mechanicMask = spellProto->GetAllEffectsMechanicMask()) { - if ((*i)->GetMiscValue() & spellProto->GetSchoolMask()) - TakenTotalCasterMod += (float((*i)->GetAmount())); + AuraEffectList const& mDamageDoneMechanic = GetAuraEffectsByType(SPELL_AURA_MOD_MECHANIC_DAMAGE_TAKEN_PERCENT); + for (AuraEffectList::const_iterator i = mDamageDoneMechanic.begin(); i != mDamageDoneMechanic.end(); ++i) + if (mechanicMask & uint32(1 << ((*i)->GetMiscValue()))) + AddPct(TakenTotalMod, (*i)->GetAmount()); } - // from positive and negative SPELL_AURA_MOD_DAMAGE_PERCENT_TAKEN - // multiplicative bonus, for example Dispersion + Shadowform (0.10*0.85=0.085) - TakenTotalMod *= GetTotalAuraMultiplierByMiscMask(SPELL_AURA_MOD_DAMAGE_PERCENT_TAKEN, spellProto->GetSchoolMask()); - //.. taken pct: dummy auras AuraEffectList const& mDummyAuras = GetAuraEffectsByType(SPELL_AURA_DUMMY); for (AuraEffectList::const_iterator i = mDummyAuras.begin(); i != mDummyAuras.end(); ++i) @@ -8709,45 +8707,47 @@ uint32 Unit::SpellDamageBonusTaken(Unit* caster, SpellInfo const* spellProto, ui break; } } - - // From caster spells - AuraEffectList const& mOwnerTaken = GetAuraEffectsByType(SPELL_AURA_MOD_DAMAGE_FROM_CASTER); - for (AuraEffectList::const_iterator i = mOwnerTaken.begin(); i != mOwnerTaken.end(); ++i) - if ((*i)->GetCasterGUID() == caster->GetGUID() && (*i)->IsAffectingSpell(spellProto)) - AddPct(TakenTotalMod, (*i)->GetAmount()); - - // Mod damage from spell mechanic - if (uint32 mechanicMask = spellProto->GetAllEffectsMechanicMask()) + // Spells with SPELL_ATTR4_FIXED_DAMAGE should only benefit from mechanic damage mod auras. + if (!(spellProto->AttributesEx4 & SPELL_ATTR4_FIXED_DAMAGE)) { - AuraEffectList const& mDamageDoneMechanic = GetAuraEffectsByType(SPELL_AURA_MOD_MECHANIC_DAMAGE_TAKEN_PERCENT); - for (AuraEffectList::const_iterator i = mDamageDoneMechanic.begin(); i != mDamageDoneMechanic.end(); ++i) - if (mechanicMask & uint32(1<<((*i)->GetMiscValue()))) - AddPct(TakenTotalMod, (*i)->GetAmount()); - } + // get all auras from caster that allow the spell to ignore resistance (sanctified wrath) + AuraEffectList const& IgnoreResistAuras = caster->GetAuraEffectsByType(SPELL_AURA_MOD_IGNORE_TARGET_RESIST); + for (AuraEffectList::const_iterator i = IgnoreResistAuras.begin(); i != IgnoreResistAuras.end(); ++i) + { + if ((*i)->GetMiscValue() & spellProto->GetSchoolMask()) + TakenTotalCasterMod += (float((*i)->GetAmount())); + } - int32 TakenAdvertisedBenefit = SpellBaseDamageBonusTaken(spellProto->GetSchoolMask()); + // From caster spells + AuraEffectList const& mOwnerTaken = GetAuraEffectsByType(SPELL_AURA_MOD_DAMAGE_FROM_CASTER); + for (AuraEffectList::const_iterator i = mOwnerTaken.begin(); i != mOwnerTaken.end(); ++i) + if ((*i)->GetCasterGUID() == caster->GetGUID() && (*i)->IsAffectingSpell(spellProto)) + AddPct(TakenTotalMod, (*i)->GetAmount()); - // Check for table values - float coeff = 0; - SpellBonusEntry const* bonus = sSpellMgr->GetSpellBonusData(spellProto->Id); - if (bonus) - coeff = (damagetype == DOT) ? bonus->dot_damage : bonus->direct_damage; + int32 TakenAdvertisedBenefit = SpellBaseDamageBonusTaken(spellProto->GetSchoolMask()); - // Default calculation - if (TakenAdvertisedBenefit) - { - if (!bonus || coeff < 0) - coeff = CalculateDefaultCoefficient(spellProto, damagetype) * int32(stack); + // Check for table values + float coeff = 0; + SpellBonusEntry const* bonus = sSpellMgr->GetSpellBonusData(spellProto->Id); + if (bonus) + coeff = (damagetype == DOT) ? bonus->dot_damage : bonus->direct_damage; - float factorMod = CalculateLevelPenalty(spellProto) * stack; - // level penalty still applied on Taken bonus - is it blizzlike? - if (Player* modOwner = GetSpellModOwner()) + // Default calculation + if (TakenAdvertisedBenefit) { - coeff *= 100.0f; - modOwner->ApplySpellMod(spellProto->Id, SPELLMOD_BONUS_MULTIPLIER, coeff); - coeff /= 100.0f; + if (!bonus || coeff < 0) + coeff = CalculateDefaultCoefficient(spellProto, damagetype) * int32(stack); + + float factorMod = CalculateLevelPenalty(spellProto) * stack; + // level penalty still applied on Taken bonus - is it blizzlike? + if (Player* modOwner = GetSpellModOwner()) + { + coeff *= 100.0f; + modOwner->ApplySpellMod(spellProto->Id, SPELLMOD_BONUS_MULTIPLIER, coeff); + coeff /= 100.0f; + } + TakenTotal += int32(TakenAdvertisedBenefit * coeff * factorMod); } - TakenTotal+= int32(TakenAdvertisedBenefit * coeff * factorMod); } float tmpDamage = 0.0f; diff --git a/src/server/game/Handlers/CharacterHandler.cpp b/src/server/game/Handlers/CharacterHandler.cpp index 737197878fb..5345113d106 100644 --- a/src/server/game/Handlers/CharacterHandler.cpp +++ b/src/server/game/Handlers/CharacterHandler.cpp @@ -788,6 +788,7 @@ void WorldSession::HandlePlayerLoginOpcode(WorldPacket& recvData) if (PlayerLoading() || GetPlayer() != NULL) { TC_LOG_ERROR("network", "Player tries to login again, AccountId = %d", GetAccountId()); + KickPlayer(); return; } diff --git a/src/server/game/Handlers/TicketHandler.cpp b/src/server/game/Handlers/TicketHandler.cpp index 4ea4d835ae9..53cde5e8e5a 100644 --- a/src/server/game/Handlers/TicketHandler.cpp +++ b/src/server/game/Handlers/TicketHandler.cpp @@ -187,6 +187,8 @@ void WorldSession::HandleGMSurveySubmit(WorldPacket& recvData) uint32 mainSurvey; // GMSurveyCurrentSurvey.dbc, column 1 (all 9) ref to GMSurveySurveys.dbc recvData >> mainSurvey; + std::unordered_set<uint32> surveyIds; + SQLTransaction trans = CharacterDatabase.BeginTransaction(); // sub_survey1, r1, comment1, sub_survey2, r2, comment2, sub_survey3, r3, comment3, sub_survey4, r4, comment4, sub_survey5, r5, comment5, sub_survey6, r6, comment6, sub_survey7, r7, comment7, sub_survey8, r8, comment8, sub_survey9, r9, comment9, sub_survey10, r10, comment10, for (uint8 i = 0; i < 15; i++) { @@ -200,12 +202,16 @@ void WorldSession::HandleGMSurveySubmit(WorldPacket& recvData) std::string comment; // comment ("Usage: GMSurveyAnswerSubmit(question, rank, comment)") recvData >> comment; + // make sure the same sub survey is not added to DB twice + if (!surveyIds.insert(subSurveyId).second) + continue; + PreparedStatement* stmt = CharacterDatabase.GetPreparedStatement(CHAR_INS_GM_SUBSURVEY); stmt->setUInt32(0, nextSurveyID); stmt->setUInt32(1, subSurveyId); stmt->setUInt32(2, rank); stmt->setString(3, comment); - CharacterDatabase.Execute(stmt); + trans->Append(stmt); } std::string comment; // just a guess @@ -217,7 +223,9 @@ void WorldSession::HandleGMSurveySubmit(WorldPacket& recvData) stmt->setUInt32(2, mainSurvey); stmt->setString(3, comment); - CharacterDatabase.Execute(stmt); + trans->Append(stmt); + + CharacterDatabase.CommitTransaction(trans); } void WorldSession::HandleReportLag(WorldPacket& recvData) diff --git a/src/server/game/Miscellaneous/SharedDefines.h b/src/server/game/Miscellaneous/SharedDefines.h index 8a17536c9cc..cbcf509747b 100644 --- a/src/server/game/Miscellaneous/SharedDefines.h +++ b/src/server/game/Miscellaneous/SharedDefines.h @@ -436,7 +436,7 @@ enum SpellAttr4 SPELL_ATTR4_UNK5 = 0x00000020, // 5 SPELL_ATTR4_NOT_STEALABLE = 0x00000040, // 6 although such auras might be dispellable, they cannot be stolen SPELL_ATTR4_TRIGGERED = 0x00000080, // 7 spells forced to be triggered - SPELL_ATTR4_FIXED_DAMAGE = 0x00000100, // 8 ignores taken percent damage mods? + SPELL_ATTR4_FIXED_DAMAGE = 0x00000100, // 8 Ignores resilience and any (except mechanic related) damage or % damage taken auras on target. SPELL_ATTR4_TRIGGER_ACTIVATE = 0x00000200, // 9 initially disabled / trigger activate from event (Execute, Riposte, Deep Freeze end other) SPELL_ATTR4_SPELL_VS_EXTEND_COST = 0x00000400, // 10 Rogue Shiv have this flag SPELL_ATTR4_UNK11 = 0x00000800, // 11 diff --git a/src/server/game/Server/WorldSession.cpp b/src/server/game/Server/WorldSession.cpp index 7c7c2613592..e40470c5cdb 100644 --- a/src/server/game/Server/WorldSession.cpp +++ b/src/server/game/Server/WorldSession.cpp @@ -124,7 +124,9 @@ WorldSession::WorldSession(uint32 id, WorldSocket* sock, AccountTypes sec, uint8 _filterAddonMessages(false), recruiterId(recruiter), isRecruiter(isARecruiter), - _RBACData(NULL) + _RBACData(NULL), + expireTime(60000), // 1 min after socket loss, session is deleted + forceExit(false) { memset(m_Tutorials, 0, sizeof(m_Tutorials)); @@ -449,8 +451,12 @@ bool WorldSession::Update(uint32 diff, PacketFilter& updater) ///- Cleanup socket pointer if need if (m_Socket && m_Socket->IsClosed()) { - m_Socket->RemoveReference(); - m_Socket = NULL; + expireTime -= expireTime > diff ? diff : expireTime; + if (expireTime < diff || forceExit) + { + m_Socket->RemoveReference(); + m_Socket = NULL; + } } if (!m_Socket) @@ -476,7 +482,6 @@ void WorldSession::LogoutPlayer(bool save) DoLootRelease(lguid); ///- If the player just died before logging out, make him appear as a ghost - //FIXME: logout must be delayed in case lost connection with client in time of combat if (_player->GetDeathTimer()) { _player->getHostileRefManager().deleteReferences(); @@ -606,7 +611,10 @@ void WorldSession::LogoutPlayer(bool save) void WorldSession::KickPlayer() { if (m_Socket) + { m_Socket->CloseSocket(); + forceExit = true; + } } void WorldSession::SendNotification(const char *format, ...) diff --git a/src/server/game/Server/WorldSession.h b/src/server/game/Server/WorldSession.h index a34c614f7e1..ae32f48f622 100644 --- a/src/server/game/Server/WorldSession.h +++ b/src/server/game/Server/WorldSession.h @@ -1081,6 +1081,8 @@ class WorldSession ACE_Based::LockedQueue<WorldPacket*, ACE_Thread_Mutex> _recvQueue; z_stream_s* _compressionStream; rbac::RBACData* _RBACData; + uint32 expireTime; + bool forceExit; WorldSession(WorldSession const& right) = delete; WorldSession& operator=(WorldSession const& right) = delete; diff --git a/src/server/game/Spells/Auras/SpellAuraEffects.cpp b/src/server/game/Spells/Auras/SpellAuraEffects.cpp index 61a1ea40120..efc24792a7c 100644 --- a/src/server/game/Spells/Auras/SpellAuraEffects.cpp +++ b/src/server/game/Spells/Auras/SpellAuraEffects.cpp @@ -5833,7 +5833,9 @@ void AuraEffect::HandlePeriodicDamageAurasTick(Unit* target, Unit* caster) const damage = caster->SpellCriticalDamageBonus(m_spellInfo, damage, target); int32 dmg = damage; - caster->ApplyResilience(target, &dmg); + + if (!(GetSpellInfo()->AttributesEx4 & SPELL_ATTR4_FIXED_DAMAGE)) + caster->ApplyResilience(target, &dmg); damage = dmg; caster->CalcAbsorbResist(target, GetSpellInfo()->GetSchoolMask(), DOT, damage, &absorb, &resist, GetSpellInfo()); @@ -5900,7 +5902,8 @@ void AuraEffect::HandlePeriodicHealthLeechAuraTick(Unit* target, Unit* caster) c } int32 dmg = damage; - caster->ApplyResilience(target, &dmg); + if (!(GetSpellInfo()->AttributesEx4 & SPELL_ATTR4_FIXED_DAMAGE)) + caster->ApplyResilience(target, &dmg); damage = dmg; caster->CalcAbsorbResist(target, GetSpellInfo()->GetSchoolMask(), DOT, damage, &absorb, &resist, m_spellInfo); diff --git a/src/server/game/Spells/Spell.cpp b/src/server/game/Spells/Spell.cpp index 661c1ec340a..b64ee454e2e 100644 --- a/src/server/game/Spells/Spell.cpp +++ b/src/server/game/Spells/Spell.cpp @@ -569,7 +569,7 @@ m_caster((info->AttributesEx6 & SPELL_ATTR6_CAST_BY_CHARMER && caster->GetCharme m_spellState = SPELL_STATE_NULL; _triggeredCastFlags = triggerFlags; if (info->AttributesEx4 & SPELL_ATTR4_TRIGGERED) - _triggeredCastFlags = TRIGGERED_FULL_MASK; + _triggeredCastFlags = TriggerCastFlags(TRIGGERED_FULL_MASK & ~TRIGGERED_IGNORE_EQUIPPED_ITEM_REQUIREMENT); m_CastItem = NULL; m_castItemGUID = 0; diff --git a/src/server/game/Spells/SpellMgr.cpp b/src/server/game/Spells/SpellMgr.cpp index 33a2bd2d41a..218f7b5a37d 100644 --- a/src/server/game/Spells/SpellMgr.cpp +++ b/src/server/game/Spells/SpellMgr.cpp @@ -3244,6 +3244,9 @@ void SpellMgr::LoadSpellInfoCorrections() case 63675: // Improved Devouring Plague spellInfo->AttributesEx3 |= SPELL_ATTR3_NO_DONE_BONUS; break; + case 12721: // Deep Wounds shouldnt ignore resillience or damage taken auras because its damage is not based off a spell. + spellInfo->AttributesEx4 = 0; + break; case 8145: // Tremor Totem (instant pulse) case 6474: // Earthbind Totem (instant pulse) spellInfo->AttributesEx5 |= SPELL_ATTR5_START_PERIODIC_AT_APPLY; diff --git a/src/server/scripts/Kalimdor/CavernsOfTime/CullingOfStratholme/instance_culling_of_stratholme.cpp b/src/server/scripts/Kalimdor/CavernsOfTime/CullingOfStratholme/instance_culling_of_stratholme.cpp index dbd844aa34c..503166e0b12 100644 --- a/src/server/scripts/Kalimdor/CavernsOfTime/CullingOfStratholme/instance_culling_of_stratholme.cpp +++ b/src/server/scripts/Kalimdor/CavernsOfTime/CullingOfStratholme/instance_culling_of_stratholme.cpp @@ -187,7 +187,7 @@ class instance_culling_of_stratholme : public InstanceMapScript // Summon Chromie and global whisper if (Creature* chromie = instance->SummonCreature(NPC_CHROMIE_2, ChromieSummonPos)) if (!instance->GetPlayers().isEmpty()) - sCreatureTextMgr->SendChat(chromie, SAY_CRATES_COMPLETED, NULL, CHAT_MSG_ADDON, LANG_ADDON, TEXT_RANGE_MAP); + chromie->AI()->TalkToMap(SAY_CRATES_COMPLETED); } DoUpdateWorldState(WORLDSTATE_CRATES_REVEALED, _crateCount); break; diff --git a/src/server/scripts/Northrend/CrusadersColiseum/TrialOfTheCrusader/trial_of_the_crusader.h b/src/server/scripts/Northrend/CrusadersColiseum/TrialOfTheCrusader/trial_of_the_crusader.h index 562105c0866..8a62453d7c1 100644 --- a/src/server/scripts/Northrend/CrusadersColiseum/TrialOfTheCrusader/trial_of_the_crusader.h +++ b/src/server/scripts/Northrend/CrusadersColiseum/TrialOfTheCrusader/trial_of_the_crusader.h @@ -40,7 +40,7 @@ enum SpellIds enum MiscData { - DESPAWN_TIME = 300000, + DESPAWN_TIME = 1200000, DISPLAYID_DESTROYED_FLOOR = 9060 }; diff --git a/src/server/scripts/Northrend/Naxxramas/boss_kelthuzad.cpp b/src/server/scripts/Northrend/Naxxramas/boss_kelthuzad.cpp index 8b3ac64fb89..c5c70cf3957 100644 --- a/src/server/scripts/Northrend/Naxxramas/boss_kelthuzad.cpp +++ b/src/server/scripts/Northrend/Naxxramas/boss_kelthuzad.cpp @@ -368,38 +368,33 @@ public: if (Phase == 1) { - while (uint32 eventId = events.GetEvent()) + while (uint32 eventId = events.ExecuteEvent()) { switch (eventId) { case EVENT_WASTE: DoSummon(NPC_WASTE, Pos[RAND(0, 3, 6, 9)]); - events.RepeatEvent(urand(2000, 5000)); + events.Repeat(2000, 5000); break; case EVENT_ABOMIN: if (nAbomination < 8) { DoSummon(NPC_ABOMINATION, Pos[RAND(1, 4, 7, 10)]); nAbomination++; - events.RepeatEvent(20000); + events.Repeat(20000); } - else - events.PopEvent(); break; case EVENT_WEAVER: if (nWeaver < 8) { DoSummon(NPC_WEAVER, Pos[RAND(0, 3, 6, 9)]); nWeaver++; - events.RepeatEvent(25000); + events.Repeat(25000); } - else - events.PopEvent(); break; case EVENT_TRIGGER: if (GameObject* trigger = ObjectAccessor::GetGameObject(*me, instance->GetData64(DATA_KELTHUZAD_TRIGGER))) trigger->SetPhaseMask(2, true); - events.PopEvent(); break; case EVENT_PHASE: events.Reset(); @@ -419,7 +414,6 @@ public: Phase = 2; break; default: - events.PopEvent(); break; } } @@ -461,17 +455,17 @@ public: if (me->HasUnitState(UNIT_STATE_CASTING)) return; - if (uint32 eventId = events.GetEvent()) + if (uint32 eventId = events.ExecuteEvent()) { switch (eventId) { case EVENT_BOLT: DoCastVictim(SPELL_FROST_BOLT); - events.RepeatEvent(urand(5000, 10000)); + events.Repeat(5000, 10000); break; case EVENT_NOVA: DoCastAOE(SPELL_FROST_BOLT_AOE); - events.RepeatEvent(urand(15000, 30000)); + events.Repeat(15000, 30000); break; case EVENT_CHAIN: { @@ -490,7 +484,7 @@ public: } if (!chained.empty()) Talk(SAY_CHAIN); - events.RepeatEvent(urand(100000, 180000)); + events.Repeat(100000, 180000); break; } case EVENT_CHAINED_SPELL: @@ -565,10 +559,8 @@ public: ++itr; } - if (chained.empty()) - events.PopEvent(); - else - events.RepeatEvent(5000); + if (!chained.empty()) + events.Repeat(5000); break; } @@ -596,23 +588,22 @@ public: Talk(SAY_SPECIAL); } - events.RepeatEvent(urand(20000, 50000)); + events.Repeat(20000, 50000); break; } case EVENT_FISSURE: if (Unit* target = SelectTarget(SELECT_TARGET_RANDOM, 0)) DoCast(target, SPELL_SHADOW_FISURE); - events.RepeatEvent(urand(10000, 45000)); + events.Repeat(10000, 45000); break; case EVENT_BLAST: if (Unit* target = SelectTarget(SELECT_TARGET_RANDOM, RAID_MODE(1, 0), 0, true)) DoCast(target, SPELL_FROST_BLAST); if (rand()%2) Talk(SAY_FROST_BLAST); - events.RepeatEvent(urand(30000, 90000)); + events.Repeat(30000, 90000); break; default: - events.PopEvent(); break; } } diff --git a/src/server/scripts/Northrend/Nexus/EyeOfEternity/boss_malygos.cpp b/src/server/scripts/Northrend/Nexus/EyeOfEternity/boss_malygos.cpp index 169d942e536..5291e4baed3 100644 --- a/src/server/scripts/Northrend/Nexus/EyeOfEternity/boss_malygos.cpp +++ b/src/server/scripts/Northrend/Nexus/EyeOfEternity/boss_malygos.cpp @@ -664,7 +664,7 @@ public: Talk(SAY_BUFF_SPARK); } else if (spell->Id == SPELL_MALYGOS_BERSERK) - sCreatureTextMgr->SendChat(me, EMOTE_HIT_BERSERKER_TIMER, NULL, CHAT_MSG_ADDON, LANG_ADDON, TEXT_RANGE_MAP); + TalkToMap(EMOTE_HIT_BERSERKER_TIMER); } void MoveInLineOfSight(Unit* who) override @@ -1113,8 +1113,7 @@ public: npc_power_sparkAI(Creature* creature) : ScriptedAI(creature) { _instance = creature->GetInstanceScript(); - // Talk range was not enough for this encounter - sCreatureTextMgr->SendChat(me, EMOTE_POWER_SPARK_SUMMONED, NULL, CHAT_MSG_ADDON, LANG_ADDON, TEXT_RANGE_MAP); + TalkToMap(EMOTE_POWER_SPARK_SUMMONED); MoveToMalygos(); } |