diff options
Diffstat (limited to 'src/server/game')
| -rw-r--r-- | src/server/game/Entities/Item/Item.cpp | 20 | ||||
| -rw-r--r-- | src/server/game/Entities/Item/Item.h | 2 | ||||
| -rw-r--r-- | src/server/game/Entities/Player/Player.cpp | 9 | ||||
| -rw-r--r-- | src/server/game/Entities/Player/Player.h | 1 | ||||
| -rw-r--r-- | src/server/game/Entities/Unit/Unit.cpp | 60 | ||||
| -rw-r--r-- | src/server/game/Entities/Unit/Unit.h | 1 | ||||
| -rw-r--r-- | src/server/game/Handlers/LootHandler.cpp | 2 | ||||
| -rw-r--r-- | src/server/game/Loot/LootMgr.h | 2 | ||||
| -rw-r--r-- | src/server/game/Spells/SpellInfo.cpp | 18 | ||||
| -rw-r--r-- | src/server/game/Spells/SpellMgr.cpp | 3 | 
10 files changed, 63 insertions, 55 deletions
diff --git a/src/server/game/Entities/Item/Item.cpp b/src/server/game/Entities/Item/Item.cpp index 5303fb8dc38..5be1bbf5290 100644 --- a/src/server/game/Entities/Item/Item.cpp +++ b/src/server/game/Entities/Item/Item.cpp @@ -1210,7 +1210,6 @@ bool Item::CheckSoulboundTradeExpire()  void Item::ItemContainerSaveLootToDB()  {      // Saves the money and item loot associated with an openable item to the DB -      if (loot.isLooted()) // no money and no loot          return; @@ -1235,7 +1234,6 @@ void Item::ItemContainerSaveLootToDB()      // Save items      if (!loot.isLooted())      { -                  PreparedStatement* stmt_items = CharacterDatabase.GetPreparedStatement(CHAR_DEL_ITEMCONTAINER_ITEMS);          stmt_items->setUInt32(0, container_id);          trans->Append(stmt_items); @@ -1272,7 +1270,6 @@ void Item::ItemContainerSaveLootToDB()  bool Item::ItemContainerLoadLootFromDB()  {      // Loads the money and item loot associated with an openable item from the DB -      // Default. If there are no records for this item then it will be rolled for in Player::SendLoot()      m_lootGenerated = false; @@ -1302,7 +1299,6 @@ bool Item::ItemContainerLoadLootFromDB()          // Get a LootTemplate for the container item. This is where          //  the saved loot was originally rolled from, we will copy conditions from it          LootTemplate const* lt = LootTemplates_Item.GetLootFor(GetEntry()); -          if (lt)          {              do @@ -1335,24 +1331,24 @@ bool Item::ItemContainerLoadLootFromDB()                  // Finally add the LootItem to the container                  loot.items.push_back(loot_item); -                 +                  // Increment unlooted count                  loot.unlootedCount++; -            } while (item_result->NextRow()); +            } +            while (item_result->NextRow());          }      } -   // Mark the item if it has loot so it won't be generated again on open -   m_lootGenerated = !loot.isLooted(); +    // Mark the item if it has loot so it won't be generated again on open +    m_lootGenerated = !loot.isLooted(); -   return m_lootGenerated; +    return m_lootGenerated;  }  void Item::ItemContainerDeleteLootItemsFromDB()  {      // Deletes items associated with an openable item from the DB -      uint32 containerId = GetGUIDLow();      PreparedStatement* stmt = CharacterDatabase.GetPreparedStatement(CHAR_DEL_ITEMCONTAINER_ITEMS);      stmt->setUInt32(0, containerId); @@ -1364,7 +1360,6 @@ void Item::ItemContainerDeleteLootItemsFromDB()  void Item::ItemContainerDeleteLootItemFromDB(uint32 itemID)  {      // Deletes a single item associated with an openable item from the DB -      uint32 containerId = GetGUIDLow();      PreparedStatement* stmt = CharacterDatabase.GetPreparedStatement(CHAR_DEL_ITEMCONTAINER_ITEM);      stmt->setUInt32(0, containerId); @@ -1377,7 +1372,6 @@ void Item::ItemContainerDeleteLootItemFromDB(uint32 itemID)  void Item::ItemContainerDeleteLootMoneyFromDB()  {      // Deletes the money loot associated with an openable item from the DB -      uint32 containerId = GetGUIDLow();      PreparedStatement* stmt = CharacterDatabase.GetPreparedStatement(CHAR_DEL_ITEMCONTAINER_MONEY);      stmt->setUInt32(0, containerId); @@ -1389,8 +1383,6 @@ void Item::ItemContainerDeleteLootMoneyFromDB()  void Item::ItemContainerDeleteLootMoneyAndLootItemsFromDB()  {      // Deletes money and items associated with an openable item from the DB -      ItemContainerDeleteLootMoneyFromDB();      ItemContainerDeleteLootItemsFromDB();  } - diff --git a/src/server/game/Entities/Item/Item.h b/src/server/game/Entities/Item/Item.h index 2e1956250f3..ffe31ed765e 100644 --- a/src/server/game/Entities/Item/Item.h +++ b/src/server/game/Entities/Item/Item.h @@ -231,7 +231,7 @@ class Item : public Object          static void DeleteFromDB(SQLTransaction& trans, uint32 itemGuid);          virtual void DeleteFromDB(SQLTransaction& trans);          static void DeleteFromInventoryDB(SQLTransaction& trans, uint32 itemGuid); -         +          // Lootable items and their contents          void ItemContainerSaveLootToDB();          bool ItemContainerLoadLootFromDB(); diff --git a/src/server/game/Entities/Player/Player.cpp b/src/server/game/Entities/Player/Player.cpp index af7692b87c5..bca94517ef4 100644 --- a/src/server/game/Entities/Player/Player.cpp +++ b/src/server/game/Entities/Player/Player.cpp @@ -2067,15 +2067,6 @@ uint8 Player::GetChatTag() const      return tag;  } -void Player::SendTeleportPacket(Position &oldPos) -{ -    WorldPacket data2(MSG_MOVE_TELEPORT, 38); -    data2.append(GetPackGUID()); -    BuildMovementPacket(&data2); -    Relocate(&oldPos); -    SendMessageToSet(&data2, false); -} -  void Player::SendTeleportAckPacket()  {      WorldPacket data(MSG_MOVE_TELEPORT_ACK, 41); diff --git a/src/server/game/Entities/Player/Player.h b/src/server/game/Entities/Player/Player.h index cc08e9c2e18..1e8b6aedb3e 100644 --- a/src/server/game/Entities/Player/Player.h +++ b/src/server/game/Entities/Player/Player.h @@ -1947,7 +1947,6 @@ class Player : public Unit, public GridObject<Player>          void SendMessageToSetInRange(WorldPacket* data, float dist, bool self, bool own_team_only);          void SendMessageToSet(WorldPacket* data, Player const* skipped_rcvr); -        void SendTeleportPacket(Position &oldPos);          void SendTeleportAckPacket();          Corpse* GetCorpse() const; diff --git a/src/server/game/Entities/Unit/Unit.cpp b/src/server/game/Entities/Unit/Unit.cpp index 02a0ec7d5b9..dee977de054 100644 --- a/src/server/game/Entities/Unit/Unit.cpp +++ b/src/server/game/Entities/Unit/Unit.cpp @@ -5572,28 +5572,14 @@ bool Unit::HandleDummyAuraProc(Unit* victim, uint32 damage, AuraEffect* triggere                  // Shadow's Fate (Shadowmourne questline)                  case 71169:                  { -                    uint32 spellId = 0; - -                    switch (GetEntry()) +                    Unit* caster = triggeredByAura->GetCaster(); +                    if (caster && caster->GetTypeId() == TYPEID_PLAYER && caster->ToPlayer()->GetQuestStatus(24547) == QUEST_STATUS_INCOMPLETE)                      { -                        case 36678:                 // NPC:     Professor Putricide -                            spellId = 71518;        // Spell:   Unholy Infusion Credit -                            break; -                        case 37955:                 // NPC:     Blood-Queen Lana'thel -                            spellId = 72934;        // Spell:   Quest Credit -                            break; -                        case 36853:                 // NPC:     Sindragosa <Queen of the Frostbrood> -                            spellId = 72289;        // Spell:   Frost Infusion Quest Credit -                            break; -                        default: -                            break; +                        CastSpell(caster, 71203, true); +                        return true;                      } -                    if (spellId) -                        CastSpell((Unit*)NULL, spellId, true); - -                    CastSpell((Unit*)NULL, 71203, true); - -                    return true; +                    else +                        return false;                  }                  // Essence of the Blood Queen                  case 70871: @@ -9039,11 +9025,15 @@ bool Unit::HandleProcTriggerSpell(Unit* victim, uint32 damage, AuraEffect* trigg          case 71169:          {              // Victim needs more checks so bugs, rats or summons can not be affected by the proc. -            if (GetTypeId() != TYPEID_PLAYER || victim->GetTypeId() != TYPEID_UNIT || victim->GetCreatureType() == CREATURE_TYPE_CRITTER) +            if (GetTypeId() != TYPEID_PLAYER || !victim || victim->GetTypeId() != TYPEID_UNIT || victim->GetCreatureType() == CREATURE_TYPE_CRITTER)                  return false;              Player* player = ToPlayer(); -            if (player->GetQuestStatus(24547) != QUEST_STATUS_INCOMPLETE) +            if (player->GetQuestStatus(24547) == QUEST_STATUS_INCOMPLETE) +            { +                break; +            } +            else if (player->GetDifficulty(true) == RAID_DIFFICULTY_25MAN_NORMAL || player->GetDifficulty(true) == RAID_DIFFICULTY_25MAN_HEROIC)              {                  uint32 spellId = 0;                  uint32 questId = 0; @@ -9067,8 +9057,11 @@ bool Unit::HandleProcTriggerSpell(Unit* victim, uint32 damage, AuraEffect* trigg                  if (player->GetQuestStatus(questId) != QUEST_STATUS_INCOMPLETE || !player->HasAura(spellId))                      return false; + +                break;              } -            break; +            else +                return false;          }      } @@ -12113,7 +12106,10 @@ void Unit::CombatStart(Unit* target, bool initialAggro)          if (!target->isInCombat() && target->GetTypeId() != TYPEID_PLAYER              && !target->ToCreature()->HasReactState(REACT_PASSIVE) && target->ToCreature()->IsAIEnabled)          { -            target->ToCreature()->AI()->AttackStart(this); +            if (target->isPet()) +                target->ToCreature()->AI()->AttackedBy(this); // PetAI has special handler before AttackStart() +            else +                target->ToCreature()->AI()->AttackStart(this);          }          SetInCombatWith(target); @@ -17329,10 +17325,24 @@ void Unit::NearTeleportTo(float x, float y, float z, float orientation, bool cas      else      {          UpdatePosition(x, y, z, orientation, true); -        SendMovementFlagUpdate(); +        Position pos; // dummy, not used for creatures. +        SendTeleportPacket(pos); +        UpdateObjectVisibility();      }  } +void Unit::SendTeleportPacket(Position& oldPos) +{ +    WorldPacket data2(MSG_MOVE_TELEPORT, 38); +    data2.append(GetPackGUID()); +    BuildMovementPacket(&data2); +     +    if (GetTypeId() == TYPEID_PLAYER) +        Relocate(&oldPos); +         +    SendMessageToSet(&data2, false); +} +  bool Unit::UpdatePosition(float x, float y, float z, float orientation, bool teleport)  {      // prevent crash when a bad coord is sent by the client diff --git a/src/server/game/Entities/Unit/Unit.h b/src/server/game/Entities/Unit/Unit.h index bba58a2f5e9..5dbf800dc31 100644 --- a/src/server/game/Entities/Unit/Unit.h +++ b/src/server/game/Entities/Unit/Unit.h @@ -1593,6 +1593,7 @@ class Unit : public WorldObject          void SendSpellDamageImmune(Unit* target, uint32 spellId);          void NearTeleportTo(float x, float y, float z, float orientation, bool casting = false); +        void SendTeleportPacket(Position& oldPos);          virtual bool UpdatePosition(float x, float y, float z, float ang, bool teleport = false);          // returns true if unit's position really changed          bool UpdatePosition(const Position &pos, bool teleport = false) { return UpdatePosition(pos.GetPositionX(), pos.GetPositionY(), pos.GetPositionZ(), pos.GetOrientation(), teleport); } diff --git a/src/server/game/Handlers/LootHandler.cpp b/src/server/game/Handlers/LootHandler.cpp index b15636e75d2..92ba5237c68 100644 --- a/src/server/game/Handlers/LootHandler.cpp +++ b/src/server/game/Handlers/LootHandler.cpp @@ -393,8 +393,10 @@ void WorldSession::DoLootRelease(uint64 lguid)              player->DestroyItemCount(pItem, count, true);          }          else +        {              if (pItem->loot.isLooted()) // Only delete item if no loot or money (unlooted loot is saved to db)                  player->DestroyItem(pItem->GetBagSlot(), pItem->GetSlot(), true); +        }          return;                                             // item can be looted only single player      }      else diff --git a/src/server/game/Loot/LootMgr.h b/src/server/game/Loot/LootMgr.h index cfa5d370e3b..89425e1ee66 100644 --- a/src/server/game/Loot/LootMgr.h +++ b/src/server/game/Loot/LootMgr.h @@ -290,7 +290,7 @@ struct Loot      uint8 unlootedCount;      uint64 roundRobinPlayer;                                // GUID of the player having the Round-Robin ownership for the loot. If 0, round robin owner has released.      LootType loot_type;                                     // required for achievement system -     +      // GUIDLow of container that holds this loot (item_instance.entry)      //  Only set for inventory items that can be right-click looted      uint32 containerID; diff --git a/src/server/game/Spells/SpellInfo.cpp b/src/server/game/Spells/SpellInfo.cpp index fcfa441455e..61b92ce6f81 100644 --- a/src/server/game/Spells/SpellInfo.cpp +++ b/src/server/game/Spells/SpellInfo.cpp @@ -1546,11 +1546,21 @@ SpellCastResult SpellInfo::CheckTarget(Unit const* caster, WorldObject const* ta      if (unitTarget->HasUnitState(UNIT_STATE_IN_FLIGHT))          return SPELL_FAILED_BAD_TARGETS; -    if (TargetAuraState && !unitTarget->HasAuraState(AuraStateType(TargetAuraState), this, caster)) -        return SPELL_FAILED_TARGET_AURASTATE; +    /* TARGET_UNIT_MASTER gets blocked here for passengers, because the whole idea of this check is to  +    not allow passengers to be implicitly hit by spells, however this target type should be an exception, +    if this is left it kills spells that award kill credit from vehicle to master (few spells), +    the use of these 2 covers passenger target check, logically, if vehicle cast this to master it should always hit +    him, because it would be it's passenger, there's no such case where this gets to fail legitimacy, this problem +    cannot be solved from within the check in other way since target type cannot be called for the spell currently +    Spell examples: [ID - 52864 Devour Water, ID - 52862 Devour Wind, ID - 49370 Wyrmrest Defender: Destabilize Azure Dragonshrine Effect] */ +    if (!caster->IsVehicle() && !(caster->GetCharmerOrOwner() == target)) +    { +        if (TargetAuraState && !unitTarget->HasAuraState(AuraStateType(TargetAuraState), this, caster)) +            return SPELL_FAILED_TARGET_AURASTATE; -    if (TargetAuraStateNot && unitTarget->HasAuraState(AuraStateType(TargetAuraStateNot), this, caster)) -        return SPELL_FAILED_TARGET_AURASTATE; +        if (TargetAuraStateNot && unitTarget->HasAuraState(AuraStateType(TargetAuraStateNot), this, caster)) +            return SPELL_FAILED_TARGET_AURASTATE; +    }      if (TargetAuraSpell && !unitTarget->HasAura(sSpellMgr->GetSpellIdForDifficulty(TargetAuraSpell, caster)))          return SPELL_FAILED_TARGET_AURASTATE; diff --git a/src/server/game/Spells/SpellMgr.cpp b/src/server/game/Spells/SpellMgr.cpp index 3eefd969eed..d166c6f9ebf 100644 --- a/src/server/game/Spells/SpellMgr.cpp +++ b/src/server/game/Spells/SpellMgr.cpp @@ -3413,6 +3413,9 @@ void SpellMgr::LoadDbcDataCorrections()              case 71123: // Decimate (Stinky & Precious)                  spellInfo->EffectRadiusIndex[0] = EFFECT_RADIUS_100_YARDS; // 100yd                  break; +            case 71169: // Shadow's Fate +                spellInfo->AttributesEx3 |= SPELL_ATTR3_STACK_FOR_DIFF_CASTERS; +                break;              case 72378: // Blood Nova (Deathbringer Saurfang)              case 73058: // Blood Nova (Deathbringer Saurfang)                  spellInfo->EffectRadiusIndex[0] = EFFECT_RADIUS_200_YARDS;  | 
