Core/LFG:

Fix priority of the player when its added to the lfg group
        Better implementation of the Dungeon Deserter debuff
        Rewrite the NeedBeforeGreed loot
        Fixed players being shown as Unknown Entity when entering the lfg group
        Some incremental optimizations after original patch
Thanks to Retriman and Paecman for base implementation

Signed-off-by: Machiavelli <machiavelli.trinity@gmail.com>
This commit is contained in:
Subv2112
2012-01-14 17:37:28 +01:00
committed by Machiavelli
parent dbbac0bdaa
commit f4075f0f94
14 changed files with 346 additions and 52 deletions
@@ -0,0 +1,8 @@
DROP TABLE IF EXISTS `lfg_data`;
CREATE TABLE `lfg_data` (
`guid` INT(10) UNSIGNED NOT NULL DEFAULT '0' COMMENT 'Global Unique Identifier',
`dungeon` INT(10) UNSIGNED NOT NULL DEFAULT '0',
`state` TINYINT(3) UNSIGNED NOT NULL DEFAULT '0',
PRIMARY KEY (`guid`)
) ENGINE=INNODB DEFAULT CHARSET=utf8 COMMENT='LFG Data';
+111 -4
View File
@@ -72,6 +72,54 @@ LFGMgr::~LFGMgr()
delete it->second;
}
void LFGMgr::_LoadFromDB(Field* fields, uint64 guid)
{
if (!fields)
return;
if (!IS_GROUP(guid))
return;
uint32 dungeon = fields[16].GetUInt32();
uint8 state = fields[17].GetUInt8();
if (!dungeon || !state)
return;
SetDungeon(guid, dungeon);
switch (state)
{
case LFG_STATE_DUNGEON:
case LFG_STATE_FINISHED_DUNGEON:
SetState(guid, (LfgState)state);
break;
default:
break;
}
}
void LFGMgr::_SaveToDB(uint64 guid, uint32 db_guid)
{
if (!IS_GROUP(guid))
return;
PreparedStatement* stmt = CharacterDatabase.GetPreparedStatement(CHAR_DEL_LFG_DATA);
stmt->setUInt32(0, db_guid);
CharacterDatabase.Execute(stmt);
stmt = CharacterDatabase.GetPreparedStatement(CHAR_INS_LFG_DATA);
stmt->setUInt32(0, db_guid);
stmt->setUInt32(1, GetDungeon(guid));
stmt->setUInt32(2, GetState(guid));
CharacterDatabase.Execute(stmt);
}
/// Load rewards for completing dungeons
void LFGMgr::LoadRewards()
{
@@ -245,7 +293,8 @@ void LFGMgr::Update(uint32 diff)
UpdateProposal(m_lfgProposalId, guid, true);
}
else
currentQueue.push_back(frontguid); // Lfg group not found, add this group to the queue.
if (std::find(currentQueue.begin(), currentQueue.end(), frontguid) == currentQueue.end()) //already in queue?
currentQueue.push_back(frontguid); // Lfg group not found, add this group to the queue.
firstNew.clear();
}
}
@@ -382,7 +431,10 @@ void LFGMgr::InitializeLockedDungeons(Player* player)
else if (DisableMgr::IsDisabledFor(DISABLE_TYPE_MAP, dungeon->map, player))
locktype = LFG_LOCKSTATUS_RAID_LOCKED;
else if (dungeon->difficulty > DUNGEON_DIFFICULTY_NORMAL && player->GetBoundInstance(dungeon->map, Difficulty(dungeon->difficulty)))
locktype = LFG_LOCKSTATUS_RAID_LOCKED;
{
if (!player->GetGroup() || !player->GetGroup()->isLFGGroup() || GetDungeon(player->GetGroup()->GetGUID(), true) != dungeon->ID || GetState(player->GetGroup()->GetGUID()) != LFG_STATE_DUNGEON)
locktype = LFG_LOCKSTATUS_RAID_LOCKED;
}
else if (dungeon->minlevel > level)
locktype = LFG_LOCKSTATUS_TOO_LOW_LEVEL;
else if (dungeon->maxlevel < level)
@@ -808,7 +860,7 @@ bool LFGMgr::CheckCompatibility(LfgGuidList check, LfgProposal*& pProposal)
{
uint64 guid = (*it);
LfgQueueInfoMap::iterator itQueue = m_QueueInfoMap.find(guid);
if (itQueue == m_QueueInfoMap.end())
if (itQueue == m_QueueInfoMap.end() || GetState(guid) != LFG_STATE_QUEUED)
{
sLog->outError("LFGMgr::CheckCompatibility: [" UI64FMTD "] is not queued but listed as queued!", (*it));
RemoveFromQueue(guid);
@@ -923,6 +975,42 @@ bool LFGMgr::CheckCompatibility(LfgGuidList check, LfgProposal*& pProposal)
if (numPlayers != MAXGROUPSIZE)
{
sLog->outDebug(LOG_FILTER_LFG, "LFGMgr::CheckCompatibility: (%s) Compatibles but not match. Players(%u)", strGuids.c_str(), numPlayers);
uint8 Tanks_Needed = LFG_TANKS_NEEDED;
uint8 Healers_Needed = LFG_HEALERS_NEEDED;
uint8 Dps_Needed = LFG_DPS_NEEDED;
for (LfgQueueInfoMap::const_iterator itQueue = pqInfoMap.begin(); itQueue != pqInfoMap.end(); ++itQueue)
{
LfgQueueInfo* queue = itQueue->second;
for (LfgRolesMap::const_iterator itPlayer = queue->roles.begin(); itPlayer != queue->roles.end(); ++itPlayer)
{
uint8 roles = itPlayer->second;
if ((roles & ROLE_TANK) && Tanks_Needed > 0)
--Tanks_Needed;
else if ((roles & ROLE_HEALER) && Healers_Needed > 0)
--Healers_Needed;
else if ((roles & ROLE_DAMAGE) && Dps_Needed > 0)
--Dps_Needed;
}
}
for (PlayerSet::const_iterator itPlayers = players.begin(); itPlayers != players.end(); ++itPlayers)
{
for (LfgQueueInfoMap::const_iterator itQueue = pqInfoMap.begin(); itQueue != pqInfoMap.end(); ++itQueue)
{
LfgQueueInfo* queue = itQueue->second;
if (!queue)
continue;
for (LfgRolesMap::const_iterator itPlayer = queue->roles.begin(); itPlayer != queue->roles.end(); ++itPlayer)
{
if (*itPlayers == ObjectAccessor::FindPlayer(itPlayer->first))
{
queue->tanks = Tanks_Needed;
queue->healers = Healers_Needed;
queue->dps = Dps_Needed;
}
}
}
}
return true;
}
sLog->outDebug(LOG_FILTER_LFG, "LFGMgr::CheckCompatibility: (%s) MATCH! Group formed", strGuids.c_str());
@@ -1078,6 +1166,11 @@ void LFGMgr::UpdateRoleCheck(uint64 gguid, uint64 guid /* = 0 */, uint8 roles /*
}
m_QueueInfoMap[gguid] = pqInfo;
if(GetState(gguid) != LFG_STATE_NONE)
{
LfgGuidList& currentQueue = m_currentQueue[team];
currentQueue.push_front(gguid);
}
AddToQueue(gguid, team);
}
@@ -1384,6 +1477,7 @@ void LFGMgr::UpdateProposal(uint32 proposalId, uint64 guid, bool accept)
break;
}
}
m_teleport.push_back(pguid);
grp->SetLfgRoles(pguid, pProposal->players[pguid]->role);
SetState(pguid, LFG_STATE_DUNGEON);
}
@@ -1395,6 +1489,7 @@ void LFGMgr::UpdateProposal(uint32 proposalId, uint64 guid, bool accept)
uint64 gguid = grp->GetGUID();
SetDungeon(gguid, dungeon->Entry());
SetState(gguid, LFG_STATE_DUNGEON);
_SaveToDB(gguid, grp->GetDbStoreId());
// Remove players/groups from Queue
for (LfgGuidList::const_iterator it = pProposal->queues.begin(); it != pProposal->queues.end(); ++it)
@@ -1509,7 +1604,9 @@ void LFGMgr::RemoveProposal(LfgProposalMap::iterator itProposal, LfgUpdateType t
for (LfgGuidList::const_iterator it = pProposal->queues.begin(); it != pProposal->queues.end(); ++it)
{
uint64 guid = *it;
AddToQueue(guid, team);
LfgGuidList& currentQueue = m_currentQueue[team];
currentQueue.push_front(guid); //Add GUID for high priority
AddToQueue(guid, team); //We have to add each GUID in newQueue to check for a new groups
}
delete pProposal;
@@ -1921,6 +2018,16 @@ const std::string& LFGMgr::GetComment(uint64 guid)
return m_Players[guid].GetComment();
}
bool LFGMgr::IsTeleported(uint64 pguid)
{
if (std::find(m_teleport.begin(), m_teleport.end(), pguid) != m_teleport.end())
{
m_teleport.remove(pguid);
return true;
}
return false;
}
const LfgDungeonSet& LFGMgr::GetSelectedDungeons(uint64 guid)
{
sLog->outDebug(LOG_FILTER_LFG, "LFGMgr::GetSelectedDungeons: [" UI64FMTD "]", guid);
+6 -2
View File
@@ -287,6 +287,9 @@ class LFGMgr
void InitializeLockedDungeons(Player* player);
void _LoadFromDB(Field* fields, uint64 guid);
void _SaveToDB(uint64 guid, uint32 db_guid);
void SetComment(uint64 guid, const std::string& comment);
const LfgLockMap& GetLockedDungeons(uint64 guid);
LfgState GetState(uint64 guid);
@@ -298,7 +301,9 @@ class LFGMgr
void RemoveGroupData(uint64 guid);
uint8 GetKicksLeft(uint64 gguid);
uint8 GetVotesNeeded(uint64 gguid);
bool IsTeleported(uint64 pguid);
void SetRoles(uint64 guid, uint8 roles);
void SetSelectedDungeons(uint64 guid, const LfgDungeonSet& dungeons);
private:
@@ -306,10 +311,8 @@ class LFGMgr
const std::string& GetComment(uint64 gguid);
void RestoreState(uint64 guid);
void SetDungeon(uint64 guid, uint32 dungeon);
void SetSelectedDungeons(uint64 guid, const LfgDungeonSet& dungeons);
void SetLockedDungeons(uint64 guid, const LfgLockMap& lock);
void DecreaseKicksLeft(uint64 guid);
void NoExiste(uint8 lala);
// Queue
void AddToQueue(uint64 guid, uint8 queueId);
@@ -352,6 +355,7 @@ class LFGMgr
LfgGuidListMap m_currentQueue; ///< Ordered list. Used to find groups
LfgGuidListMap m_newToQueue; ///< New groups to add to queue
LfgCompatibleMap m_CompatibleMap; ///< Compatible dungeons
LfgGuidList m_teleport; ///< Players being teleported
// Rolecheck - Proposal - Vote Kicks
LfgRoleCheckMap m_RoleChecks; ///< Current Role checks
LfgProposalMap m_Proposals; ///< Current Proposals
+91 -5
View File
@@ -2305,9 +2305,14 @@ bool Player::TeleportToBGEntryPoint()
if (m_bgData.joinPos.m_mapId == MAPID_INVALID)
return false;
Group* group = GetGroup();
if (group && group->isLFGGroup() && group->GetMembersCount() == 1)
group->Disband();
else
ScheduleDelayedOperation(DELAYED_BG_GROUP_RESTORE);
ScheduleDelayedOperation(DELAYED_BG_MOUNT_RESTORE);
ScheduleDelayedOperation(DELAYED_BG_TAXI_RESTORE);
ScheduleDelayedOperation(DELAYED_BG_GROUP_RESTORE);
return TeleportTo(m_bgData.joinPos);
}
@@ -7371,6 +7376,22 @@ void Player::UpdateZone(uint32 newZone, uint32 newArea)
SendInitWorldStates(newZone, newArea); // only if really enters to new zone, not just area change, works strange...
}
// group update
if (GetGroup())
{
SetGroupUpdateFlag(GROUP_UPDATE_FULL);
Group* grp = GetGroup();
if (GetSession() && grp->isLFGGroup() && sLFGMgr->IsTeleported(GetGUID()))
{
for (GroupReference* itr = grp->GetFirstMember(); itr != NULL; itr = itr->next())
{
Player* tempplr = itr->getSource();
if (tempplr)
GetSession()->SendNameQueryOpcode(tempplr->GetGUID());
}
}
}
m_zoneUpdateId = newZone;
m_zoneUpdateTimer = ZONE_UPDATE_INTERVAL;
@@ -7458,10 +7479,6 @@ void Player::UpdateZone(uint32 newZone, uint32 newArea)
// recent client version not send leave/join channel packets for built-in local channels
UpdateLocalChannels(newZone);
// group update
if (GetGroup())
SetGroupUpdateFlag(GROUP_UPDATE_FULL);
UpdateZoneDependentAuras(newZone);
}
@@ -11794,6 +11811,75 @@ InventoryResult Player::CanUseItem(ItemTemplate const* proto) const
return EQUIP_ERR_ITEM_NOT_FOUND;
}
InventoryResult Player::CanRollForItem(ItemTemplate const* proto) const
{
if (!proto)
return EQUIP_ERR_ITEM_NOT_FOUND;
// Used by group, function NeedBeforeGreed, to know if a prototype can be used by a player
const static uint32 item_weapon_skills[MAX_ITEM_SUBCLASS_WEAPON] =
{
SKILL_AXES, SKILL_2H_AXES, SKILL_BOWS, SKILL_GUNS, SKILL_MACES,
SKILL_2H_MACES, SKILL_POLEARMS, SKILL_SWORDS, SKILL_2H_SWORDS, 0,
SKILL_STAVES, 0, 0, SKILL_FIST_WEAPONS, 0,
SKILL_DAGGERS, SKILL_THROWN, SKILL_ASSASSINATION, SKILL_CROSSBOWS, SKILL_WANDS,
SKILL_FISHING
}; //Copy from function Item::GetSkill()
if ((proto->AllowableClass & getClassMask()) == 0 || (proto->AllowableRace & getRaceMask()) == 0)
return EQUIP_ERR_YOU_CAN_NEVER_USE_THAT_ITEM;
if (proto->RequiredSpell != 0 && !HasSpell(proto->RequiredSpell))
return EQUIP_ERR_NO_REQUIRED_PROFICIENCY;
if (proto->RequiredSkill != 0)
{
if (!GetSkillValue(proto->RequiredSkill))
return EQUIP_ERR_NO_REQUIRED_PROFICIENCY;
else if (GetSkillValue(proto->RequiredSkill) < proto->RequiredSkillRank)
return EQUIP_ERR_CANT_EQUIP_SKILL;
}
uint8 _class = getClass();
if (proto->Class == ITEM_CLASS_WEAPON && GetSkillValue(item_weapon_skills[proto->SubClass]) == 0)
return EQUIP_ERR_NO_REQUIRED_PROFICIENCY;
if (proto->Class == ITEM_CLASS_ARMOR && proto->SubClass > ITEM_SUBCLASS_ARMOR_MISC && proto->SubClass < ITEM_SUBCLASS_ARMOR_BUCKLER && proto->InventoryType != INVTYPE_CLOAK)
{
if (_class == CLASS_WARRIOR || _class == CLASS_PALADIN || _class == CLASS_DEATH_KNIGHT)
{
if (getLevel() < 40)
{
if (proto->SubClass != ITEM_SUBCLASS_ARMOR_MAIL)
return EQUIP_ERR_CANT_DO_RIGHT_NOW;
}
else if (proto->SubClass != ITEM_SUBCLASS_ARMOR_PLATE)
return EQUIP_ERR_CANT_DO_RIGHT_NOW;
}
else if (_class == CLASS_HUNTER || _class == CLASS_SHAMAN)
{
if (getLevel() < 40)
{
if (proto->SubClass != ITEM_SUBCLASS_ARMOR_LEATHER)
return EQUIP_ERR_CANT_DO_RIGHT_NOW;
}
else if (proto->SubClass != ITEM_SUBCLASS_ARMOR_MAIL)
return EQUIP_ERR_CANT_DO_RIGHT_NOW;
}
if (_class == CLASS_ROGUE || _class == CLASS_DRUID)
if (proto->SubClass != ITEM_SUBCLASS_ARMOR_LEATHER)
return EQUIP_ERR_CANT_DO_RIGHT_NOW;
if (_class == CLASS_MAGE || _class == CLASS_PRIEST || _class == CLASS_WARLOCK)
if (proto->SubClass != ITEM_SUBCLASS_ARMOR_CLOTH)
return EQUIP_ERR_CANT_DO_RIGHT_NOW;
}
return EQUIP_ERR_OK;
}
InventoryResult Player::CanUseAmmo(uint32 item) const
{
sLog->outDebug(LOG_FILTER_PLAYER_ITEMS, "STORAGE: CanUseAmmo item = %u", item);
+1
View File
@@ -1277,6 +1277,7 @@ class Player : public Unit, public GridObject<Player>
bool HasItemTotemCategory(uint32 TotemCategory) const;
InventoryResult CanUseItem(ItemTemplate const* pItem) const;
InventoryResult CanUseAmmo(uint32 item) const;
InventoryResult CanRollForItem(ItemTemplate const* item) const;
Item* StoreNewItem(ItemPosCountVec const& pos, uint32 item, bool update, int32 randomPropertyId = 0);
Item* StoreNewItem(ItemPosCountVec const& pos, uint32 item, bool update, int32 randomPropertyId, AllowedLooterSet &allowedLooters);
Item* StoreItem(ItemPosCountVec const& pos, Item* pItem, bool update);
+88 -31
View File
@@ -190,6 +190,9 @@ void Group::LoadGroupFromDB(Field* fields)
m_raidDifficulty = RAID_DIFFICULTY_10MAN_NORMAL;
else
m_raidDifficulty = Difficulty(r_diff);
if (m_groupType & GROUPTYPE_LFG)
sLFGMgr->_LoadFromDB(fields, GetGUID());
}
void Group::LoadMemberFromDB(uint32 guidLow, uint8 memberFlags, uint8 subgroup, uint8 roles)
@@ -211,6 +214,14 @@ void Group::LoadMemberFromDB(uint32 guidLow, uint8 memberFlags, uint8 subgroup,
m_memberSlots.push_back(member);
SubGroupCounterIncrease(subgroup);
if (isLFGGroup())
{
LfgDungeonSet Dungeons;
Dungeons.insert(sLFGMgr->GetDungeon(GetGUID()));
sLFGMgr->SetSelectedDungeons(member.guid, Dungeons);
sLFGMgr->SetState(member.guid, sLFGMgr->GetState(GetGUID()));
}
}
void Group::ConvertToLFG()
@@ -441,7 +452,7 @@ bool Group::RemoveMember(uint64 guid, const RemoveMethod &method /*= GROUP_REMOV
return m_memberSlots.size();
// remove member and change leader (if need) only if strong more 2 members _before_ member remove (BG allow 1 member group)
if (GetMembersCount() > (isBGGroup() ? 1u : 2u))
if (GetMembersCount() > ((isBGGroup() || isLFGGroup()) ? 1u : 2u))
{
Player* player = ObjectAccessor::FindPlayer(guid);
if (player)
@@ -485,6 +496,8 @@ bool Group::RemoveMember(uint64 guid, const RemoveMethod &method /*= GROUP_REMOV
CharacterDatabase.Execute(stmt);
DelinkMember(guid);
// Reevaluate group enchanter if the leaving player had enchanting skill or the player is offline
if ((player && player->GetSkillValue(SKILL_ENCHANTING)) || !player)
ResetMaxEnchantingLevel();
@@ -534,6 +547,20 @@ bool Group::RemoveMember(uint64 guid, const RemoveMethod &method /*= GROUP_REMOV
}
SendUpdate();
if (isLFGGroup() && GetMembersCount() == 1)
{
Player* Leader = ObjectAccessor::FindPlayer(GetLeaderGUID());
LFGDungeonEntry const* dungeon = sLFGDungeonStore.LookupEntry(sLFGMgr->GetDungeon(GetGUID()));
if ((Leader && dungeon && Leader->isAlive() && Leader->GetMapId() != dungeon->map) || !dungeon)
{
Disband();
return false;
}
}
if (m_memberMgr.getSize() < ((isLFGGroup() || isBGGroup()) ? 1u : 2u))
Disband();
return true;
}
@@ -673,6 +700,10 @@ void Group::Disband(bool hideDestroy /* = false */)
CharacterDatabase.CommitTransaction(trans);
ResetInstances(INSTANCE_RESET_GROUP_DISBAND, false, NULL);
ResetInstances(INSTANCE_RESET_GROUP_DISBAND, true, NULL);
PreparedStatement* stmt = CharacterDatabase.GetPreparedStatement(CHAR_DEL_LFG_DATA);
stmt->setUInt32(0, m_dbStoreId);
CharacterDatabase.Execute(stmt);
sGroupMgr->FreeGroupDbStoreId(this);
}
@@ -709,6 +740,28 @@ void Group::SendLootStartRoll(uint32 CountDown, uint32 mapid, const Roll &r)
}
}
void Group::SendLootStartRollToPlayer(uint32 CountDown, uint32 mapid, Player* p, bool NeedBlocked, const Roll &r)
{
if (!p || !p->GetSession())
return;
WorldPacket data(SMSG_LOOT_START_ROLL, (8 + 4 + 4 + 4 + 4 + 4 + 4 + 1 ));
data << uint64(r.itemGUID); // guid of rolled item
data << uint32(mapid); // 3.3.3 mapid
data << uint32(r.totalPlayersRolling); // maybe the number of players rolling for it???
data << uint32(r.itemid); // the itemEntryId for the item that shall be rolled for
data << uint32(r.itemRandomSuffix); // randomSuffix
data << uint32(r.itemRandomPropId); // item random property ID
data << uint32(r.itemCount); // items in stack
data << uint32(CountDown); // the countdown time to choose "need" or "greed"
uint8 VoteMask = r.rollVoteMask;
if (NeedBlocked)
VoteMask &= ~ROLL_FLAG_TYPE_NEED;
data << uint8(VoteMask); // roll type mask
p->GetSession()->SendPacket(&data);
}
void Group::SendLootRoll(uint64 SourceGuid, uint64 TargetGuid, uint8 RollNumber, uint8 RollType, const Roll &r)
{
WorldPacket data(SMSG_LOOT_ROLL, (8+4+8+4+4+4+1+1+1));
@@ -887,7 +940,7 @@ void Group::GroupLoot(Loot* loot, WorldObject* pLootedObject)
}
}
void Group::NeedBeforeGreed(Loot* loot, WorldObject* pLootedObject)
void Group::NeedBeforeGreed(Loot* loot, WorldObject* lootedObject)
{
ItemTemplate const* item;
uint8 itemSlot = 0;
@@ -902,7 +955,7 @@ void Group::NeedBeforeGreed(Loot* loot, WorldObject* pLootedObject)
if (item->Quality >= uint32(m_lootThreshold))
{
uint64 newitemGUID = MAKE_NEW_GUID(sObjectMgr->GenerateLowGuid(HIGHGUID_ITEM), 0, HIGHGUID_ITEM);
Roll* r=new Roll(newitemGUID, *i);
Roll* r = new Roll(newitemGUID, *i);
for (GroupReference* itr = GetFirstMember(); itr != NULL; itr = itr->next())
{
@@ -911,21 +964,17 @@ void Group::NeedBeforeGreed(Loot* loot, WorldObject* pLootedObject)
continue;
bool allowedForPlayer = i->AllowedForPlayer(playerToRoll);
if (playerToRoll->CanUseItem(item) == EQUIP_ERR_OK && allowedForPlayer)
if (allowedForPlayer && playerToRoll->IsWithinDistInMap(lootedObject, sWorld->getFloatConfig(CONFIG_GROUP_XP_DISTANCE), false))
{
if (playerToRoll->IsWithinDistInMap(pLootedObject, sWorld->getFloatConfig(CONFIG_GROUP_XP_DISTANCE), false))
r->totalPlayersRolling++;
if (playerToRoll->GetPassOnGroupLoot())
{
r->totalPlayersRolling++;
if (playerToRoll->GetPassOnGroupLoot())
{
r->playerVote[playerToRoll->GetGUID()] = PASS;
r->totalPass++;
// can't broadcast the pass now. need to wait until all rolling players are known.
}
else
r->playerVote[playerToRoll->GetGUID()] = NOT_EMITED_YET;
r->playerVote[playerToRoll->GetGUID()] = PASS;
r->totalPass++;
// can't broadcast the pass now. need to wait until all rolling players are known.
}
else
r->playerVote[playerToRoll->GetGUID()] = NOT_EMITED_YET;
}
}
@@ -941,25 +990,24 @@ void Group::NeedBeforeGreed(Loot* loot, WorldObject* pLootedObject)
loot->items[itemSlot].is_blocked = true;
// If there is any "auto pass", broadcast the pass now.
if (r->totalPass)
//Broadcast Pass and Send Rollstart
for (Roll::PlayerVote::const_iterator itr=r->playerVote.begin(); itr != r->playerVote.end(); ++itr)
{
for (Roll::PlayerVote::const_iterator itr=r->playerVote.begin(); itr != r->playerVote.end(); ++itr)
{
Player* p = ObjectAccessor::FindPlayer(itr->first);
if (!p || !p->GetSession())
continue;
Player* p = ObjectAccessor::FindPlayer(itr->first);
if (!p || !p->GetSession())
continue;
if (itr->second == PASS)
SendLootRoll(newitemGUID, p->GetGUID(), 128, ROLL_PASS, *r);
}
if (itr->second == PASS)
SendLootRoll(newitemGUID, p->GetGUID(), 128, ROLL_PASS, *r);
if (p->CanRollForItem(item) == EQUIP_ERR_OK)
SendLootStartRollToPlayer(60000, lootedObject->GetMapId(), p, false, *r);
else
SendLootStartRollToPlayer(60000, lootedObject->GetMapId(), p, true, *r);
}
SendLootStartRoll(60000, pLootedObject->GetMapId(), *r);
RollId.push_back(r);
if (Creature* creature = pLootedObject->ToCreature())
if (Creature* creature = lootedObject->ToCreature())
{
creature->m_groupLootTimer = 60000;
creature->lootingGroupLowGUID = GetLowGUID();
@@ -1242,9 +1290,7 @@ void Group::SendTargetIconList(WorldSession* session)
void Group::SendUpdate()
{
for (member_witerator witr = m_memberSlots.begin(); witr != m_memberSlots.end(); ++witr)
{
SendUpdateToPlayer(witr->guid, &(*witr));
}
}
void Group::SendUpdateToPlayer(uint64 playerGUID, MemberSlot* slot)
@@ -2118,8 +2164,19 @@ void Group::LinkMember(GroupReference* pRef)
m_memberMgr.insertFirst(pRef);
}
void Group::DelinkMember(GroupReference* /*pRef*/) const
void Group::DelinkMember(uint64 guid)
{
GroupReference* ref = m_memberMgr.getFirst();
while (ref)
{
GroupReference* nextRef = ref->next();
if (ref->getSource()->GetGUID() == guid)
{
ref->unlink();
break;
}
ref = nextRef;
}
}
Group::BoundInstancesMap& Group::GetBoundInstances(Difficulty difficulty)
+2 -1
View File
@@ -273,6 +273,7 @@ class Group
bool isRollLootActive() const;
void SendLootStartRoll(uint32 CountDown, uint32 mapid, const Roll &r);
void SendLootStartRollToPlayer(uint32 CountDown, uint32 mapid, Player* p, bool NeedBlocked, const Roll &r);
void SendLootRoll(uint64 SourceGuid, uint64 TargetGuid, uint8 RollNumber, uint8 RollType, const Roll &r);
void SendLootRollWon(uint64 SourceGuid, uint64 TargetGuid, uint8 RollNumber, uint8 RollType, const Roll &r);
void SendLootAllPassed(uint32 NumberOfPlayers, const Roll &r);
@@ -289,7 +290,7 @@ class Group
void ResetMaxEnchantingLevel();
void LinkMember(GroupReference* pRef);
void DelinkMember(GroupReference* /*pRef*/) const;
void DelinkMember(uint64 guid);
InstanceGroupBind* BindToInstance(InstanceSave* save, bool permanent, bool load = false);
void UnbindInstance(uint32 mapid, uint8 difficulty, bool unload = false);
+4 -4
View File
@@ -119,10 +119,10 @@ void GroupMgr::LoadGroups()
// Delete all groups with less than 2 members
CharacterDatabase.DirectExecute("DELETE FROM groups WHERE guid NOT IN (SELECT guid FROM group_member GROUP BY guid HAVING COUNT(guid) > 1)");
// 0 1 2 3 4 5 6 7 8 9
QueryResult result = CharacterDatabase.PQuery("SELECT leaderGuid, lootMethod, looterGuid, lootThreshold, icon1, icon2, icon3, icon4, icon5, icon6"
// 10 11 12 13 14 15
", icon7, icon8, groupType, difficulty, raiddifficulty, guid FROM groups ORDER BY guid ASC");
// 0 1 2 3 4 5 6 7 8 9
QueryResult result = CharacterDatabase.PQuery("SELECT g.leaderGuid, g.lootMethod, g.looterGuid, g.lootThreshold, g.icon1, g.icon2, g.icon3, g.icon4, g.icon5, g.icon6"
// 10 11 12 13 14 15 16 17
", g.icon7, g.icon8, g.groupType, g.difficulty, g.raiddifficulty, g.guid, lfg.dungeon, lfg.state FROM groups g LEFT JOIN lfg_data lfg ON lfg.guid = g.guid ORDER BY g.guid ASC");
if (!result)
{
sLog->outString(">> Loaded 0 group definitions. DB table `groups` is empty!");
+2 -2
View File
@@ -28,12 +28,12 @@ void GroupReference::targetObjectBuildLink()
void GroupReference::targetObjectDestroyLink()
{
// called from unlink()
getTarget()->DelinkMember(this);
//getTarget()->DelinkMember(this);
}
void GroupReference::sourceObjectDestroyLink()
{
// called from invalidate()
getTarget()->DelinkMember(this);
//getTarget()->DelinkMember(this);
}
@@ -43,6 +43,7 @@
#include "ScriptMgr.h"
#include "Battleground.h"
#include "AccountMgr.h"
#include "LFGMgr.h"
class LoginQueryHolder : public SQLQueryHolder
{
@@ -196,7 +197,7 @@ bool LoginQueryHolder::Initialize()
stmt = CharacterDatabase.GetPreparedStatement(CHAR_SEL_ACCOUNT_INSTANCELOCKTIMES);
stmt->setUInt32(0, m_accountId);
res &= SetPreparedQuery(PLAYER_LOGIN_QUERY_LOADINSTANCELOCKTIMES, stmt);
return res;
}
@@ -892,6 +893,17 @@ void WorldSession::HandlePlayerLogin(LoginQueryHolder* holder)
}
}
if (Group* group = pCurrChar->GetGroup())
{
if (group->isLFGGroup())
{
LfgDungeonSet Dungeons;
Dungeons.insert(sLFGMgr->GetDungeon(group->GetGUID()));
sLFGMgr->SetSelectedDungeons(pCurrChar->GetGUID(), Dungeons);
sLFGMgr->SetState(pCurrChar->GetGUID(), sLFGMgr->GetState(group->GetGUID()));
}
}
if (!pCurrChar->GetMap()->AddPlayerToMap(pCurrChar) || !pCurrChar->CheckInstanceLoginValid())
{
AreaTrigger const* at = sObjectMgr->GetGoBackTrigger(pCurrChar->GetMapId());
@@ -48,7 +48,8 @@ void BuildPartyLockDungeonBlock(WorldPacket& data, const LfgLockPartyMap& lockMa
void WorldSession::HandleLfgJoinOpcode(WorldPacket& recv_data)
{
if (!sWorld->getBoolConfig(CONFIG_DUNGEON_FINDER_ENABLE) ||
(GetPlayer()->GetGroup() && GetPlayer()->GetGroup()->GetLeaderGUID() != GetPlayer()->GetGUID()))
(GetPlayer()->GetGroup() && GetPlayer()->GetGroup()->GetLeaderGUID() != GetPlayer()->GetGUID() &&
(GetPlayer()->GetGroup()->GetMembersCount() == MAXGROUPSIZE || !GetPlayer()->GetGroup()->isLFGGroup())))
{
recv_data.rfinish();
return;
+11 -1
View File
@@ -1445,7 +1445,17 @@ class spell_gen_luck_of_the_draw : public SpellScriptLoader
if (GetUnitOwner()->GetTypeId() != TYPEID_PLAYER)
return;
LFGDungeonEntry const* randomDungeon = sLFGDungeonStore.LookupEntry(*(sLFGMgr->GetSelectedDungeons(GetUnitOwner()->GetGUID()).begin()));
const LfgDungeonSet dungeons = sLFGMgr->GetSelectedDungeons(GetUnitOwner()->GetGUID());
LfgDungeonSet::const_iterator itr = dungeons.begin();
if (itr == dungeons.end())
{
Remove(AURA_REMOVE_BY_DEFAULT);
return;
}
LFGDungeonEntry const* randomDungeon = sLFGDungeonStore.LookupEntry(*itr);
Group* group = GetUnitOwner()->ToPlayer()->GetGroup();
Map const* map = GetUnitOwner()->GetMap();
if (group && group->isLFGGroup())
@@ -325,6 +325,10 @@ void CharacterDatabaseConnection::DoPrepareStatements()
// For loading and deleting expired auctions at startup
PREPARE_STATEMENT(CHAR_SEL_EXPIRED_AUCTIONS, "SELECT id, auctioneerguid, itemguid, itemEntry, itemowner, buyoutprice, time, buyguid, lastbid, startbid, deposit FROM auctionhouse ah INNER JOIN item_instance ii ON ii.guid = ah.itemguid WHERE ah.time <= ?", CONNECTION_SYNCH)
// LFG Data
PREPARE_STATEMENT(CHAR_INS_LFG_DATA, "INSERT INTO lfg_data (guid, dungeon, state) VALUES (?, ?, ?)", CONNECTION_ASYNC)
PREPARE_STATEMENT(CHAR_DEL_LFG_DATA, "DELETE FROM lfg_data WHERE guid = ?", CONNECTION_ASYNC)
// Player saving
PREPARE_STATEMENT(CHAR_INS_CHARACTER, "INSERT INTO characters (guid, account, name, race, class, gender, level, xp, money, playerBytes, playerBytes2, playerFlags, "
@@ -351,6 +351,9 @@ enum CharacterDatabaseStatements
CHAR_DEL_CHARACTER_SOCIAL,
CHAR_UPD_CHARACTER_SOCIAL_NOTE,
CHAR_UPD_CHARACTER_POSITION,
CHAR_INS_LFG_DATA,
CHAR_DEL_LFG_DATA,
MAX_CHARACTERDATABASE_STATEMENTS,
};