diff --git a/src/game/BattleGround.cpp b/src/game/BattleGround.cpp index b19d53474..761e970fe 100644 --- a/src/game/BattleGround.cpp +++ b/src/game/BattleGround.cpp @@ -705,12 +705,10 @@ void BattleGround::EndBattleGround(uint32 winner) if (team == winner) { RewardMark(plr,ITEM_WINNER_COUNT); - RewardQuest(plr); + RewardQuestComplete(plr); } else - { RewardMark(plr,ITEM_LOSER_COUNT); - } plr->CombatStopWithPets(true); @@ -764,10 +762,6 @@ uint32 BattleGround::GetBattlemasterEntry() const void BattleGround::RewardMark(Player *plr,uint32 count) { - // 'Inactive' this aura prevents the player from gaining honor points and battleground tokens - if (plr->GetDummyAura(SPELL_AURA_PLAYER_INACTIVE)) - return; - BattleGroundMarks mark; bool IsSpell; switch(GetTypeID()) @@ -802,22 +796,52 @@ void BattleGround::RewardMark(Player *plr,uint32 count) } if (IsSpell) - plr->CastSpell(plr, mark, true); - else if (objmgr.GetItemPrototype( mark ) ) + RewardSpellCast(plr,mark); + else + RewardItem(plr,mark,count); +} + +void BattleGround::RewardSpellCast(Player *plr, uint32 spell_id) +{ + // 'Inactive' this aura prevents the player from gaining honor points and battleground tokens + if (plr->GetDummyAura(SPELL_AURA_PLAYER_INACTIVE)) + return; + + SpellEntry const *spellInfo = sSpellStore.LookupEntry(spell_id); + if(!spellInfo) { - ItemPosCountVec dest; - uint32 no_space_count = 0; - uint8 msg = plr->CanStoreNewItem( NULL_BAG, NULL_SLOT, dest, mark, count, &no_space_count ); - if( msg != EQUIP_ERR_OK ) // convert to possible store amount - count -= no_space_count; - - if( count != 0 && !dest.empty()) // can add some - if (Item* item = plr->StoreNewItem( dest, mark, true, 0)) - plr->SendNewItem(item,count,false,true); - - if (no_space_count > 0) - SendRewardMarkByMail(plr,mark,no_space_count); + sLog.outError("Battleground reward casting spell %u not exist.",spell_id); + return; } + + plr->CastSpell(plr, spellInfo, true); +} + +void BattleGround::RewardItem(Player *plr, uint32 item_id, uint32 count) +{ + // 'Inactive' this aura prevents the player from gaining honor points and battleground tokens + if (plr->GetDummyAura(SPELL_AURA_PLAYER_INACTIVE)) + return; + + ItemPosCountVec dest; + uint32 no_space_count = 0; + uint8 msg = plr->CanStoreNewItem( NULL_BAG, NULL_SLOT, dest, item_id, count, &no_space_count ); + + if( msg == EQUIP_ERR_ITEM_NOT_FOUND) + { + sLog.outErrorDb("Battleground reward item (Entry %u) not exist in `item_template`.",item_id); + return; + } + + if( msg != EQUIP_ERR_OK ) // convert to possible store amount + count -= no_space_count; + + if( count != 0 && !dest.empty()) // can add some + if (Item* item = plr->StoreNewItem( dest, item_id, true, 0)) + plr->SendNewItem(item,count,false,true); + + if (no_space_count > 0) + SendRewardMarkByMail(plr,item_id,no_space_count); } void BattleGround::SendRewardMarkByMail(Player *plr,uint32 mark, uint32 count) @@ -857,12 +881,8 @@ void BattleGround::SendRewardMarkByMail(Player *plr,uint32 mark, uint32 count) } } -void BattleGround::RewardQuest(Player *plr) +void BattleGround::RewardQuestComplete(Player *plr) { - // 'Inactive' this aura prevents the player from gaining honor points and battleground tokens - if (plr->GetDummyAura(SPELL_AURA_PLAYER_INACTIVE)) - return; - uint32 quest; switch(GetTypeID()) { @@ -882,7 +902,7 @@ void BattleGround::RewardQuest(Player *plr) return; } - plr->CastSpell(plr, quest, true); + RewardSpellCast(plr, quest); } void BattleGround::BlockMovement(Player *plr) diff --git a/src/game/BattleGround.h b/src/game/BattleGround.h index 187708544..91eb32382 100644 --- a/src/game/BattleGround.h +++ b/src/game/BattleGround.h @@ -411,7 +411,9 @@ class BattleGround void RewardReputationToTeam(uint32 faction_id, uint32 Reputation, uint32 TeamID); void RewardMark(Player *plr,uint32 count); void SendRewardMarkByMail(Player *plr,uint32 mark, uint32 count); - void RewardQuest(Player *plr); + void RewardItem(Player *plr, uint32 item_id, uint32 count); + void RewardQuestComplete(Player *plr); + void RewardSpellCast(Player *plr, uint32 spell_id); void UpdateWorldState(uint32 Field, uint32 Value); void UpdateWorldStateForPlayer(uint32 Field, uint32 Value, Player *Source); void EndBattleGround(uint32 winner); diff --git a/src/game/Creature.h b/src/game/Creature.h index 9953a31be..c71106a8d 100644 --- a/src/game/Creature.h +++ b/src/game/Creature.h @@ -104,6 +104,21 @@ enum Gossip_Guard_Skill GOSSIP_GUARD_SKILL_ENGINERING = 91 }; +enum GossipOptionIcon +{ + GOSSIP_ICON_CHAT = 0, //white chat bubble + GOSSIP_ICON_VENDOR = 1, //brown bag + GOSSIP_ICON_TAXI = 2, //flight + GOSSIP_ICON_TRAINER = 3, //book + GOSSIP_ICON_INTERACT_1 = 4, //interaction wheel + GOSSIP_ICON_INTERACT_2 = 5, //interaction wheel + GOSSIP_ICON_MONEY_BAG = 6, //brown bag with yellow dot + GOSSIP_ICON_TALK = 7, //white chat bubble with black dots + GOSSIP_ICON_TABARD = 8, //tabard + GOSSIP_ICON_BATTLE = 9, //two swords + GOSSIP_ICON_DOT = 10 //yellow dot +}; + struct GossipOption { uint32 Id; @@ -600,6 +615,7 @@ class MANGOS_DLL_SPEC Creature : public Unit bool IsVisibleInGridForPlayer(Player* pl) const; void RemoveCorpse(); + bool isDeadByDefault() const { return m_isDeadByDefault; }; time_t const& GetRespawnTime() const { return m_respawnTime; } time_t GetRespawnTimeEx() const; diff --git a/src/game/GridNotifiers.h b/src/game/GridNotifiers.h index c4eddee21..daf393eff 100644 --- a/src/game/GridNotifiers.h +++ b/src/game/GridNotifiers.h @@ -504,6 +504,53 @@ namespace MaNGOS // CHECKS && DO classes // WorldObject check classes + class RaiseDeadObjectCheck + { + public: + RaiseDeadObjectCheck(Unit* funit, float range) : i_funit(funit), i_range(range) {} + bool operator()(Creature* u) + { + if (i_funit->GetTypeId()!=TYPEID_PLAYER || !((Player*)i_funit)->isHonorOrXPTarget(u) || + u->getDeathState() != CORPSE || u->isDeadByDefault() || u->isInFlight() || + ( u->GetCreatureTypeMask() & (1 << (CREATURE_TYPE_HUMANOID-1)) )==0 || + (u->GetDisplayId() != u->GetNativeDisplayId())) + return false; + + return i_funit->IsWithinDistInMap(u, i_range); + } + template bool operator()(NOT_INTERESTED*) { return false; } + private: + Unit* const i_funit; + float i_range; + }; + + class ExplodeCorpseObjectCheck + { + public: + ExplodeCorpseObjectCheck(Unit* funit, float range) : i_funit(funit), i_range(range) {} + bool operator()(Player* u) + { + if (u->getDeathState()!=CORPSE || u->isInFlight() || + u->HasAuraType(SPELL_AURA_GHOST) || (u->GetDisplayId() != u->GetNativeDisplayId())) + return false; + + return i_funit->IsWithinDistInMap(u, i_range); + } + bool operator()(Creature* u) + { + if (u->getDeathState()!=CORPSE || u->isInFlight() || u->isDeadByDefault() || + (u->GetDisplayId() != u->GetNativeDisplayId()) || + (u->GetCreatureTypeMask() & CREATURE_TYPEMASK_MECHANICAL_OR_ELEMENTAL)!=0) + return false; + + return i_funit->IsWithinDistInMap(u, i_range); + } + template bool operator()(NOT_INTERESTED*) { return false; } + private: + Unit* const i_funit; + float i_range; + }; + class CannibalizeObjectCheck { public: @@ -513,22 +560,16 @@ namespace MaNGOS if( i_funit->IsFriendlyTo(u) || u->isAlive() || u->isInFlight() ) return false; - if(i_funit->IsWithinDistInMap(u, i_range) ) - return true; - - return false; + return i_funit->IsWithinDistInMap(u, i_range); } bool operator()(Corpse* u); bool operator()(Creature* u) { - if( i_funit->IsFriendlyTo(u) || u->isAlive() || u->isInFlight() || + if (i_funit->IsFriendlyTo(u) || u->isAlive() || u->isInFlight() || (u->GetCreatureTypeMask() & CREATURE_TYPEMASK_HUMANOID_OR_UNDEAD)==0) return false; - if(i_funit->IsWithinDistInMap(u, i_range) ) - return true; - - return false; + return i_funit->IsWithinDistInMap(u, i_range); } template bool operator()(NOT_INTERESTED*) { return false; } private: diff --git a/src/game/Level3.cpp b/src/game/Level3.cpp index e71727a1d..2da83263e 100644 --- a/src/game/Level3.cpp +++ b/src/game/Level3.cpp @@ -1064,11 +1064,7 @@ bool ChatHandler::HandleCooldownCommand(const char* args) return false; } - WorldPacket data( SMSG_CLEAR_COOLDOWN, (4+8) ); - data << uint32(spell_id); - data << uint64(target->GetGUID()); - target->GetSession()->SendPacket(&data); - target->RemoveSpellCooldown(spell_id); + target->RemoveSpellCooldown(spell_id,true); PSendSysMessage(LANG_REMOVE_COOLDOWN, spell_id, target==m_session->GetPlayer() ? GetMangosString(LANG_YOU) : tNameLink.c_str()); } return true; diff --git a/src/game/Player.cpp b/src/game/Player.cpp index 75ac13adf..15e5387df 100644 --- a/src/game/Player.cpp +++ b/src/game/Player.cpp @@ -3213,6 +3213,20 @@ void Player::removeSpell(uint32 spell_id, bool disabled, bool update_action_bar_ } } + +void Player::RemoveSpellCooldown( uint32 spell_id, bool update /* = false */ ) +{ + m_spellCooldowns.erase(spell_id); + + if(update) + { + WorldPacket data(SMSG_CLEAR_COOLDOWN, (4+8)); + data << uint32(spell_id); + data << uint64(GetGUID()); + SendDirectMessage(&data); + } +} + void Player::RemoveArenaSpellCooldowns() { // remove cooldowns on spells that has < 15 min CD diff --git a/src/game/Player.h b/src/game/Player.h index abfede30d..64de57d91 100644 --- a/src/game/Player.h +++ b/src/game/Player.h @@ -1416,7 +1416,7 @@ class MANGOS_DLL_SPEC Player : public Unit void AddSpellCooldown(uint32 spell_id, uint32 itemid, time_t end_time); void SendCooldownEvent(SpellEntry const *spellInfo, uint32 itemId = 0, Spell* spell = NULL); void ProhibitSpellScholl(SpellSchoolMask idSchoolMask, uint32 unTimeMs ); - void RemoveSpellCooldown(uint32 spell_id) { m_spellCooldowns.erase(spell_id); } + void RemoveSpellCooldown(uint32 spell_id, bool update = false); void RemoveArenaSpellCooldowns(); void RemoveAllSpellCooldown(); void _LoadSpellCooldowns(QueryResult *result); diff --git a/src/game/SharedDefines.h b/src/game/SharedDefines.h index eaf50a2cb..3c2e12d32 100644 --- a/src/game/SharedDefines.h +++ b/src/game/SharedDefines.h @@ -1769,6 +1769,7 @@ enum CreatureType }; uint32 const CREATURE_TYPEMASK_HUMANOID_OR_UNDEAD = (1 << (CREATURE_TYPE_HUMANOID-1)) | (1 << (CREATURE_TYPE_UNDEAD-1)); +uint32 const CREATURE_TYPEMASK_MECHANICAL_OR_ELEMENTAL = (1 << (CREATURE_TYPE_MECHANICAL-1)) | (1 << (CREATURE_TYPE_ELEMENTAL-1)); // CreatureFamily.dbc enum CreatureFamily diff --git a/src/game/Spell.cpp b/src/game/Spell.cpp index 10f339780..817797fc1 100644 --- a/src/game/Spell.cpp +++ b/src/game/Spell.cpp @@ -423,6 +423,36 @@ Spell::~Spell() { } +template +WorldObject* Spell::FindCorpseUsing() +{ + // non-standard target selection + SpellRangeEntry const* srange = sSpellRangeStore.LookupEntry(m_spellInfo->rangeIndex); + float max_range = GetSpellMaxRange(srange); + + CellPair p(MaNGOS::ComputeCellPair(m_caster->GetPositionX(), m_caster->GetPositionY())); + Cell cell(p); + cell.data.Part.reserved = ALL_DISTRICT; + cell.SetNoCreate(); + + WorldObject* result = NULL; + + T u_check(m_caster, max_range); + MaNGOS::WorldObjectSearcher searcher(m_caster, result, u_check); + + TypeContainerVisitor, GridTypeMapContainer > grid_searcher(searcher); + CellLock cell_lock(cell, p); + cell_lock->Visit(cell_lock, grid_searcher, *m_caster->GetMap()); + + if (!result) + { + TypeContainerVisitor, WorldTypeMapContainer > world_searcher(searcher); + cell_lock->Visit(cell_lock, world_searcher, *m_caster->GetMap()); + } + + return result; +} + void Spell::FillTargetMap() { // TODO: ADD the correct target FILLS!!!!!! @@ -537,29 +567,7 @@ void Spell::FillTargetMap() { case 20577: // Cannibalize { - // non-standard target selection - SpellRangeEntry const* srange = sSpellRangeStore.LookupEntry(m_spellInfo->rangeIndex); - float max_range = GetSpellMaxRange(srange); - - CellPair p(MaNGOS::ComputeCellPair(m_caster->GetPositionX(), m_caster->GetPositionY())); - Cell cell(p); - cell.data.Part.reserved = ALL_DISTRICT; - cell.SetNoCreate(); - - WorldObject* result = NULL; - - MaNGOS::CannibalizeObjectCheck u_check(m_caster, max_range); - MaNGOS::WorldObjectSearcher searcher(m_caster, result, u_check); - - TypeContainerVisitor, GridTypeMapContainer > grid_searcher(searcher); - CellLock cell_lock(cell, p); - cell_lock->Visit(cell_lock, grid_searcher, *m_caster->GetMap()); - - if(!result) - { - TypeContainerVisitor, WorldTypeMapContainer > world_searcher(searcher); - cell_lock->Visit(cell_lock, world_searcher, *m_caster->GetMap()); - } + WorldObject* result = FindCorpseUsing (); if(result) { @@ -580,15 +588,7 @@ void Spell::FillTargetMap() { // clear cooldown at fail if(m_caster->GetTypeId()==TYPEID_PLAYER) - { - ((Player*)m_caster)->RemoveSpellCooldown(m_spellInfo->Id); - - WorldPacket data(SMSG_CLEAR_COOLDOWN, (4+8)); - data << uint32(m_spellInfo->Id); - data << uint64(m_caster->GetGUID()); - ((Player*)m_caster)->GetSession()->SendPacket(&data); - } - + ((Player*)m_caster)->RemoveSpellCooldown(m_spellInfo->Id,true); SendCastResult(SPELL_FAILED_NO_EDIBLE_CORPSES); finish(false); } diff --git a/src/game/Spell.h b/src/game/Spell.h index fc2eb2314..ac2544b59 100644 --- a/src/game/Spell.h +++ b/src/game/Spell.h @@ -381,6 +381,8 @@ class Spell void SetTargetMap(uint32 i,uint32 cur,UnitList& TagUnitMap); void FillAreaTargets( UnitList& TagUnitMap, float x, float y, float radius, SpellNotifyPushType pushType, SpellTargets spellTargets ); + template WorldObject* FindCorpseUsing(); + bool CheckTarget( Unit* target, uint32 eff ); bool CanAutoCast(Unit* target); diff --git a/src/game/SpellAuras.cpp b/src/game/SpellAuras.cpp index eda33f012..aac327cd4 100644 --- a/src/game/SpellAuras.cpp +++ b/src/game/SpellAuras.cpp @@ -2386,29 +2386,7 @@ void Aura::HandleAuraDummy(bool apply, bool Real) break; } case SPELLFAMILY_HUNTER: - { - // Improved Aspect of the Viper - if( GetId()==38390 && m_target->GetTypeId()==TYPEID_PLAYER ) - { - if(apply) - { - // + effect value for Aspect of the Viper - SpellModifier *mod = new SpellModifier; - mod->op = SPELLMOD_EFFECT1; - mod->value = m_modifier.m_amount; - mod->type = SPELLMOD_FLAT; - mod->spellId = GetId(); - mod->mask = 0x4000000000000LL; - mod->mask2= 0LL; - - m_spellmod = mod; - } - - ((Player*)m_target)->AddSpellMod(m_spellmod, apply); - return; - } break; - } case SPELLFAMILY_SHAMAN: { // Improved Weapon Totems diff --git a/src/game/SpellEffects.cpp b/src/game/SpellEffects.cpp index 5aeb6752b..3e3693a4b 100644 --- a/src/game/SpellEffects.cpp +++ b/src/game/SpellEffects.cpp @@ -1199,12 +1199,7 @@ void Spell::EffectDummy(uint32 i) (GetSpellSchoolMask(spellInfo) & SPELL_SCHOOL_MASK_FROST) && spellInfo->Id != 11958 && GetSpellRecoveryTime(spellInfo) > 0 ) { - ((Player*)m_caster)->RemoveSpellCooldown(classspell); - - WorldPacket data(SMSG_CLEAR_COOLDOWN, (4+8)); - data << uint32(classspell); - data << uint64(m_caster->GetGUID()); - ((Player*)m_caster)->GetSession()->SendPacket(&data); + ((Player*)m_caster)->RemoveSpellCooldown(classspell,true); } } return; @@ -1447,14 +1442,7 @@ void Spell::EffectDummy(uint32 i) SpellEntry const *spellInfo = sSpellStore.LookupEntry(classspell); if (spellInfo->SpellFamilyName == SPELLFAMILY_ROGUE && (spellInfo->SpellFamilyFlags & 0x0000024000000860LL)) - { - ((Player*)m_caster)->RemoveSpellCooldown(classspell); - - WorldPacket data(SMSG_CLEAR_COOLDOWN, (4+8)); - data << uint32(classspell); - data << uint64(m_caster->GetGUID()); - ((Player*)m_caster)->GetSession()->SendPacket(&data); - } + ((Player*)m_caster)->RemoveSpellCooldown(classspell,true); } return; } @@ -1505,14 +1493,7 @@ void Spell::EffectDummy(uint32 i) SpellEntry const *spellInfo = sSpellStore.LookupEntry(classspell); if (spellInfo->SpellFamilyName == SPELLFAMILY_HUNTER && spellInfo->Id != 23989 && GetSpellRecoveryTime(spellInfo) > 0 ) - { - ((Player*)m_caster)->RemoveSpellCooldown(classspell); - - WorldPacket data(SMSG_CLEAR_COOLDOWN, (4+8)); - data << uint32(classspell); - data << uint64(m_caster->GetGUID()); - ((Player*)m_caster)->GetSession()->SendPacket(&data); - } + ((Player*)m_caster)->RemoveSpellCooldown(classspell,true); } return; } @@ -1611,17 +1592,8 @@ void Spell::EffectDummy(uint32 i) // non-standard cast requirement check if (!unitTarget || unitTarget->getAttackers().empty()) { - // clear cooldown at fail if(m_caster->GetTypeId()==TYPEID_PLAYER) - { - ((Player*)m_caster)->RemoveSpellCooldown(m_spellInfo->Id); - - WorldPacket data(SMSG_CLEAR_COOLDOWN, (4+8)); - data << uint32(m_spellInfo->Id); - data << uint64(m_caster->GetGUID()); - ((Player*)m_caster)->GetSession()->SendPacket(&data); - } - + ((Player*)m_caster)->RemoveSpellCooldown(m_spellInfo->Id,true); SendCastResult(SPELL_FAILED_TARGET_AFFECTING_COMBAT); return; } diff --git a/src/game/StatSystem.cpp b/src/game/StatSystem.cpp index 1d49de04e..849f90575 100644 --- a/src/game/StatSystem.cpp +++ b/src/game/StatSystem.cpp @@ -671,16 +671,6 @@ void Player::UpdateManaRegen() power_regen_mp5 += GetStat(Stats(mod->m_miscvalue)) * mod->m_amount / 500.0f; } - // Bonus from some dummy auras - AuraList const& mDummyAuras = GetAurasByType(SPELL_AURA_PERIODIC_DUMMY); - for(AuraList::const_iterator i = mDummyAuras.begin();i != mDummyAuras.end(); ++i) - if((*i)->GetId() == 34074) // Aspect of the Viper - { - power_regen_mp5 += (*i)->GetModifier()->m_amount * Intellect / 500.0f; - // Add regen bonus from level in this dummy - power_regen_mp5 += getLevel() * 35 / 100; - } - // Set regen rate in cast state apply only on spirit based regen int32 modManaRegenInterrupt = GetTotalAuraModifier(SPELL_AURA_MOD_MANA_REGEN_INTERRUPT); if (modManaRegenInterrupt > 100) diff --git a/src/shared/revision_nr.h b/src/shared/revision_nr.h index cdecaf091..db8717e63 100644 --- a/src/shared/revision_nr.h +++ b/src/shared/revision_nr.h @@ -1,4 +1,4 @@ #ifndef __REVISION_NR_H__ #define __REVISION_NR_H__ - #define REVISION_NR "7804" + #define REVISION_NR "7809" #endif // __REVISION_NR_H__