InstanceGroupBind* Group::BindToInstance(DungeonPersistentState* state, bool permanent, bool load) { if (state && !isBGGroup()) { InstanceGroupBind& bind = m_boundInstances[state->GetMapId()]; if (bind.state) { // when a boss is killed or when copying the players's binds to the group if (permanent != bind.perm || state != bind.state) if (!load) CharacterDatabase.PExecute("UPDATE group_instance SET instance = '%u', permanent = '%u' WHERE leaderGuid = '%u' AND instance = '%u'", state->GetInstanceId(), permanent, GetLeaderGuid().GetCounter(), bind.state->GetInstanceId()); } else if (!load) CharacterDatabase.PExecute("INSERT INTO group_instance (leaderGuid, instance, permanent) VALUES ('%u', '%u', '%u')", GetLeaderGuid().GetCounter(), state->GetInstanceId(), permanent); if (bind.state != state) { if (bind.state) bind.state->RemoveGroup(this); state->AddGroup(this); } bind.state = state; bind.perm = permanent; if (!load) DEBUG_LOG("Group::BindToInstance: Group (Id: %d) is now bound to map %d, instance %d", GetId(), state->GetMapId(), state->GetInstanceId()); return &bind; } else return NULL; }
void CreatureGroup::RespawnAll(Creature* except) { for (std::map<ObjectGuid, CreatureGroupMember*>::iterator itr = _members.begin(); itr != _members.end(); ++itr) if (itr->first != except->GetObjectGuid()) if (Creature* otherMember = except->GetMap()->GetCreature(itr->first)) Respawn(otherMember, itr->second); if (except->GetObjectGuid() != GetLeaderGuid()) if (Creature* otherMember = except->GetMap()->GetCreature(GetLeaderGuid())) Respawn(otherMember, NULL); }
void CreatureGroup::OnMemberAttackStart(Creature* member, Unit *target) { if (!(_options & OPTION_AGGRO_TOGETHER)) return; for (std::map<ObjectGuid, CreatureGroupMember*>::iterator itr = _members.begin(); itr != _members.end(); ++itr) if (itr->first != member->GetObjectGuid()) MemberAssist(member->GetMap()->GetCreature(itr->first), target); if (member->GetObjectGuid() != GetLeaderGuid()) MemberAssist(member->GetMap()->GetCreature(GetLeaderGuid()), target); }
void CreatureGroup::Respawn(Creature* member, CreatureGroupMember const* memberEntry /* = NULL for leader */) { // Prevent stack overflow (member->Respawn() can call CreatureGroup::Respawn, etc ...) if (_respawnGuard) return; _respawnGuard = true; if (member->IsInWorld() && member->GetRespawnTime() > time(NULL)) { if (memberEntry && memberEntry->memberFlags & OPTION_FORMATION_MOVE) { if (Unit* leader = member->GetMap()->GetUnit(GetLeaderGuid())) { float x, y, z; if (leader->isAlive() || leader->GetTypeId() != TYPEID_UNIT) leader->GetPosition(x, y, z); else leader->ToCreature()->GetRespawnCoord(x, y, z); memberEntry->ComputeRelativePosition(leader->GetOrientation(), x, y); member->UpdateGroundPositionZ(x, y, z); member->NearTeleportTo(x, y, z, leader->GetAngle(x, y) + M_PI); } } member->Respawn(); } _respawnGuard = false; }
void Group::UnbindInstance(uint32 mapid, bool unload) { BoundInstancesMap::iterator itr = m_boundInstances.find(mapid); if (itr != m_boundInstances.end()) { if (!unload) CharacterDatabase.PExecute("DELETE FROM group_instance WHERE leaderGuid = '%u' AND instance = '%u'", GetLeaderGuid().GetCounter(), itr->second.state->GetInstanceId()); itr->second.state->RemoveGroup(this); // save can become invalid m_boundInstances.erase(itr); } }
void CreatureGroup::OnLeaveCombat(Creature* member) { bool masterEvade = member->GetObjectGuid() == GetLeaderGuid(); if (_options & OPTION_EVADE_TOGETHER) { for (std::map<ObjectGuid, CreatureGroupMember*>::iterator itr = _members.begin(); itr != _members.end(); ++itr) if (itr->first != member->GetObjectGuid()) if (Creature* otherMember = member->GetMap()->GetCreature(itr->first)) if (otherMember->IsInWorld() && otherMember->isAlive() && otherMember->AI()) otherMember->AI()->EnterEvadeMode(); if (member->GetObjectGuid() != GetLeaderGuid()) if (Creature* otherMember = member->GetMap()->GetCreature(GetLeaderGuid())) if (otherMember->IsInWorld() && otherMember->isAlive() && otherMember->AI()) { masterEvade = true; otherMember->AI()->EnterEvadeMode(); } } if (_options & OPTION_RESPAWN_ALL_ON_ANY_EVADE || (_options & OPTION_RESPAWN_ALL_ON_MASTER_EVADE && masterEvade)) RespawnAll(member); }
void Group::ChangeLeader(ObjectGuid guid) { member_citerator slot = _getMemberCSlot(guid); if (slot == m_memberSlots.end()) return; // used by eluna GlobalEluna(OnChangeLeader(this, guid, GetLeaderGuid())); _setLeader(guid); WorldPacket data(SMSG_GROUP_SET_LEADER, slot->name.size() + 1); data << slot->name; BroadcastPacket(&data, true); SendUpdate(); }