diff options
Diffstat (limited to 'src/game/LootHandler.cpp')
-rw-r--r-- | src/game/LootHandler.cpp | 58 |
1 files changed, 37 insertions, 21 deletions
diff --git a/src/game/LootHandler.cpp b/src/game/LootHandler.cpp index 6ca7ae1c535..172a6ef46c2 100644 --- a/src/game/LootHandler.cpp +++ b/src/game/LootHandler.cpp @@ -1,7 +1,7 @@ /* - * Copyright (C) 2005-2008 MaNGOS <http://www.mangosproject.org/> + * Copyright (C) 2005-2009 MaNGOS <http://getmangos.com/> * - * Copyright (C) 2008 Trinity <http://www.trinitycore.org/> + * Copyright (C) 2008-2009 Trinity <http://www.trinitycore.org/> * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by @@ -46,8 +46,7 @@ void WorldSession::HandleAutostoreLootItemOpcode( WorldPacket & recv_data ) if (IS_GAMEOBJECT_GUID(lguid)) { - GameObject *go = - ObjectAccessor::GetGameObject(*player, lguid); + GameObject *go = player->GetMap()->GetGameObject(lguid); // not check distance for GO in case owned GO (fishing bobber case, for example) or Fishing hole GO if (!go || (go->GetOwnerGUID() != _player->GetGUID() && go->GetGoType() != GAMEOBJECT_TYPE_FISHINGHOLE) && !go->IsWithinDistInMap(_player,INTERACTION_DISTANCE)) @@ -82,8 +81,7 @@ void WorldSession::HandleAutostoreLootItemOpcode( WorldPacket & recv_data ) } else { - Creature* pCreature = - ObjectAccessor::GetCreature(*player, lguid); + Creature* pCreature = GetPlayer()->GetMap()->GetCreature(lguid); bool ok_loot = pCreature && pCreature->isAlive() == (player->getClass()==CLASS_ROGUE && pCreature->lootForPickPocketed); @@ -154,6 +152,8 @@ void WorldSession::HandleAutostoreLootItemOpcode( WorldPacket & recv_data ) --loot->unlootedCount; player->SendNewItem(newitem, uint32(item->count), false, false, true); + player->GetAchievementMgr().UpdateAchievementCriteria(ACHIEVEMENT_CRITERIA_TYPE_LOOT_ITEM, item->itemid, item->count); + player->GetAchievementMgr().UpdateAchievementCriteria(ACHIEVEMENT_CRITERIA_TYPE_LOOT_TYPE, loot->loot_type, item->count); } else player->SendEquipError( msg, NULL, NULL ); @@ -174,7 +174,7 @@ void WorldSession::HandleLootMoneyOpcode( WorldPacket & /*recv_data*/ ) { case HIGHGUID_GAMEOBJECT: { - GameObject *pGameObject = ObjectAccessor::GetGameObject(*GetPlayer(), guid); + GameObject *pGameObject = GetPlayer()->GetMap()->GetGameObject(guid); // not check distance for GO in case owned GO (fishing bobber case, for example) if( pGameObject && (pGameObject->GetOwnerGUID()==_player->GetGUID() || pGameObject->IsWithinDistInMap(_player,INTERACTION_DISTANCE)) ) @@ -199,7 +199,7 @@ void WorldSession::HandleLootMoneyOpcode( WorldPacket & /*recv_data*/ ) } case HIGHGUID_UNIT: { - Creature* pCreature = ObjectAccessor::GetCreature(*GetPlayer(), guid); + Creature* pCreature = GetPlayer()->GetMap()->GetCreature(guid); bool ok_loot = pCreature && pCreature->isAlive() == (player->getClass()==CLASS_ROGUE && pCreature->lootForPickPocketed); @@ -224,15 +224,16 @@ void WorldSession::HandleLootMoneyOpcode( WorldPacket & /*recv_data*/ ) Player* playerGroup = itr->getSource(); if(!playerGroup) continue; - if (player->GetDistance2d(playerGroup) < sWorld.getConfig(CONFIG_GROUP_XP_DISTANCE)) + if (player->IsWithinDist(playerGroup,sWorld.getConfig(CONFIG_GROUP_XP_DISTANCE),false)) playersNear.push_back(playerGroup); } uint32 money_per_player = uint32((pLoot->gold)/(playersNear.size())); - for (std::vector<Player*>::iterator i = playersNear.begin(); i != playersNear.end(); ++i) + for (std::vector<Player*>::const_iterator i = playersNear.begin(); i != playersNear.end(); ++i) { (*i)->ModifyMoney( money_per_player ); + (*i)->GetAchievementMgr().UpdateAchievementCriteria(ACHIEVEMENT_CRITERIA_TYPE_LOOT_MONEY, money_per_player); //Offset surely incorrect, but works WorldPacket data( SMSG_LOOT_MONEY_NOTIFY, 4 ); data << uint32(money_per_player); @@ -240,7 +241,10 @@ void WorldSession::HandleLootMoneyOpcode( WorldPacket & /*recv_data*/ ) } } else + { player->ModifyMoney( pLoot->gold ); + player->GetAchievementMgr().UpdateAchievementCriteria(ACHIEVEMENT_CRITERIA_TYPE_LOOT_MONEY, pLoot->gold); + } pLoot->gold = 0; pLoot->NotifyMoneyRemoved(); } @@ -283,10 +287,12 @@ void WorldSession::DoLootRelease( uint64 lguid ) player->RemoveFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_LOOTING); + if(!player->IsInWorld()) + return; + if (IS_GAMEOBJECT_GUID(lguid)) { - GameObject *go = - ObjectAccessor::GetGameObject(*player, lguid); + GameObject *go = GetPlayer()->GetMap()->GetGameObject(lguid); // not check distance for GO in case owned GO (fishing bobber case, for example) or Fishing hole GO if (!go || (go->GetOwnerGUID() != _player->GetGUID() && go->GetGoType() != GAMEOBJECT_TYPE_FISHINGHOLE) && !go->IsWithinDistInMap(_player,INTERACTION_DISTANCE)) @@ -326,7 +332,7 @@ void WorldSession::DoLootRelease( uint64 lguid ) int32 ReqValue = 175; LockEntry const *lockInfo = sLockStore.LookupEntry(go->GetGOInfo()->chest.lockId); if(lockInfo) - ReqValue = lockInfo->requiredminingskill; + ReqValue = lockInfo->Skill[0]; float skill = float(player->GetSkillValue(SKILL_MINING))/(ReqValue+25); double chance = pow(0.8*chance_rate,4*(1/double(max_amount))*double(uses)); if(roll_chance_f(100*chance+skill)) @@ -383,14 +389,22 @@ void WorldSession::DoLootRelease( uint64 lguid ) Item *pItem = player->GetItemByGuid(lguid ); if(!pItem) return; - if( (pItem->GetProto()->BagFamily & BAG_FAMILY_MASK_MINING_SUPP) && - pItem->GetProto()->Class == ITEM_CLASS_TRADE_GOODS && - pItem->GetCount() >= 5) + + ItemPrototype const* proto = pItem->GetProto(); + + // destroy only 5 items from stack in case prospecting and milling + if( (proto->BagFamily & (BAG_FAMILY_MASK_MINING_SUPP|BAG_FAMILY_MASK_HERBS)) && + proto->Class == ITEM_CLASS_TRADE_GOODS) { pItem->m_lootGenerated = false; pItem->loot.clear(); - uint32 count = 5; + uint32 count = pItem->GetCount(); + + // >=5 checked in spell code, but will work for cheating cases also with removing from another stacks. + if(count > 5) + count = 5; + player->DestroyItemCount(pItem, count, true); } else @@ -400,7 +414,7 @@ void WorldSession::DoLootRelease( uint64 lguid ) } else { - Creature* pCreature = ObjectAccessor::GetCreature(*player, lguid); + Creature* pCreature = GetPlayer()->GetMap()->GetCreature(lguid); bool ok_loot = pCreature && pCreature->isAlive() == (player->getClass()==CLASS_ROGUE && pCreature->lootForPickPocketed); if ( !ok_loot || !pCreature->IsWithinDistInMap(_player,INTERACTION_DISTANCE) ) @@ -457,7 +471,7 @@ void WorldSession::HandleLootMasterGiveOpcode( WorldPacket & recv_data ) if(IS_CREATURE_GUID(GetPlayer()->GetLootGUID())) { - Creature *pCreature = ObjectAccessor::GetCreature(*GetPlayer(), lootguid); + Creature *pCreature = GetPlayer()->GetMap()->GetCreature(lootguid); if(!pCreature) return; @@ -465,7 +479,7 @@ void WorldSession::HandleLootMasterGiveOpcode( WorldPacket & recv_data ) } else if(IS_GAMEOBJECT_GUID(GetPlayer()->GetLootGUID())) { - GameObject *pGO = ObjectAccessor::GetGameObject(*GetPlayer(), lootguid); + GameObject *pGO = GetPlayer()->GetMap()->GetGameObject(lootguid); if(!pGO) return; @@ -477,7 +491,7 @@ void WorldSession::HandleLootMasterGiveOpcode( WorldPacket & recv_data ) if (slotid > pLoot->items.size()) { - sLog.outDebug("AutoLootItem: Player %s might be using a hack! (slot %d, size %d)",GetPlayer()->GetName(), slotid, pLoot->items.size()); + sLog.outDebug("AutoLootItem: Player %s might be using a hack! (slot %d, size %lu)",GetPlayer()->GetName(), slotid, (unsigned long)pLoot->items.size()); return; } @@ -495,6 +509,8 @@ void WorldSession::HandleLootMasterGiveOpcode( WorldPacket & recv_data ) // not move item from loot to target inventory Item * newitem = target->StoreNewItem( dest, item.itemid, true, item.randomPropertyId ); target->SendNewItem(newitem, uint32(item.count), false, false, true ); + target->GetAchievementMgr().UpdateAchievementCriteria(ACHIEVEMENT_CRITERIA_TYPE_LOOT_ITEM, item.itemid, item.count); + target->GetAchievementMgr().UpdateAchievementCriteria(ACHIEVEMENT_CRITERIA_TYPE_LOOT_TYPE, pLoot->loot_type, item.count); // mark as looted item.count=0; |