void GroupObjectImplementation::addMember(SceneObject* newMember) {
	Locker locker(_this.get());

	GroupObjectDeltaMessage6* grp = new GroupObjectDeltaMessage6(_this.get());
	grp->startUpdate(1);
	groupMembers.add(newMember, grp);
	grp->close();

	broadcastMessage(grp);

	if (newMember->isPlayerCreature())
	{
		ManagedReference<CreatureObject*> playerCreature = cast<CreatureObject*>(newMember);

		sendTo(playerCreature, true);

		if (hasSquadLeader()) {
			addGroupModifiers(playerCreature);
		}

		scheduleUpdateNearestMissionForGroup(playerCreature->getPlanetCRC());
	}

	calcGroupLevel();
}
void GroupObjectImplementation::makeLeader(SceneObject* player) {
	if (groupMembers.size() < 2 || !player->isPlayerCreature())
		return;

	//SceneObject* obj = groupMembers.get();

	Reference<SceneObject*> temp = groupMembers.get(0).get();

	for (int i = 0; i < groupMembers.size(); ++i) {
		if (groupMembers.get(i) == player) {
			GroupObjectDeltaMessage6* grp = new GroupObjectDeltaMessage6(_this.get());
			grp->startUpdate(1);

			if (hasSquadLeader())
				removeGroupModifiers();

			groupMembers.set(0, player, grp, 2);
			groupMembers.set(i, temp.get(), grp, 0);

			grp->close();

			broadcastMessage(grp);

			if (hasSquadLeader())
				addGroupModifiers();

			return;
		}
	}
}
void GroupObjectImplementation::calcGroupLevel() {
	int highestPlayer = 0;
	groupLevel = 0;

	for (int i = 0; i < getGroupSize(); i++) {
		Reference<SceneObject*> member = getGroupMember(i);

		if (member->isPet()) {
			CreatureObject* creature = cast<CreatureObject*>(member.get());

			groupLevel += creature->getLevel() / 5;

		} else if (member->isPlayerCreature()) {
			CreatureObject* creature = cast<CreatureObject*>(member.get());

			int memberLevel = creature->getLevel();

			if (memberLevel > highestPlayer) {
				groupLevel += (memberLevel - highestPlayer + (highestPlayer / 5));
				highestPlayer = memberLevel;
			} else {
				groupLevel += memberLevel / 5;
			}
		}
	}

	GroupObjectDeltaMessage6* msg = new GroupObjectDeltaMessage6(_this.getReferenceUnsafeStaticCast());

	msg->updateLevel(this->groupLevel);
	msg->close();

	broadcastMessage(msg);
}
void GroupObjectImplementation::removeMember(CreatureObject* member) {
	bool wasLeader = getLeader() == member;

	if (hasSquadLeader()) {
		if (wasLeader)
			removeGroupModifiers();
		else
			removeGroupModifiers(member);
	}

	for (int i = 0; i < groupMembers.size(); i++) {
		CreatureObject* scno = groupMembers.get(i).get().get();

		if (scno == member) {
			GroupObjectDeltaMessage6* grp = new GroupObjectDeltaMessage6(_this.getReferenceUnsafeStaticCast());
			grp->startUpdate(1);
			groupMembers.remove(i, grp);
			grp->close();

			broadcastMessage(grp);
		}
	}

	if (member->isPlayerCreature()) {
		// Remove member's pets
		RemovePetsFromGroupTask* task = new RemovePetsFromGroupTask(member, _this.getReferenceUnsafeStaticCast());
		task->execute();

		//Close any open Group SUIs.
		ManagedReference<PlayerObject*> ghost = member->getPlayerObject();
		if (ghost != NULL) {
			ghost->closeSuiWindowType(SuiWindowType::GROUP_LOOT_RULE);
			ghost->closeSuiWindowType(SuiWindowType::GROUP_LOOT_CHANGED);
			ghost->closeSuiWindowType(SuiWindowType::GROUP_LOOT_PICK_LOOTER);

			ghost->removeWaypointBySpecialType(WaypointObject::SPECIALTYPE_NEARESTMISSIONFORGROUP);
		}

		//Reset Master Looter if needed.
		if (getMasterLooterID() == member->getObjectID()) {
			ManagedReference<CreatureObject*> groupLeader = getLeader();
			GroupManager::instance()->changeMasterLooter(_this.getReferenceUnsafeStaticCast(), groupLeader, false);
		}

		if (wasLeader && hasSquadLeader()) {
			addGroupModifiers();
		}

		Zone* zone = member->getZone();

		if (zone != NULL) {
			scheduleUpdateNearestMissionForGroup(zone->getPlanetCRC());
		}
	}

	updatePvPStatusNearCreature(member);

	calcGroupLevel();
}
void GroupObjectImplementation::removeMember(SceneObject* member) {
	ManagedReference<SceneObject*> obj = member;

	for (int i = 0; i < groupMembers.size(); i++) {
		SceneObject* scno = groupMembers.get(i).get().get();

		if (scno == member) {
			GroupObjectDeltaMessage6* grp = new GroupObjectDeltaMessage6(_this.get());
			grp->startUpdate(1);
			groupMembers.remove(i, grp);
			grp->close();

			broadcastMessage(grp);
		}
	}

	if (member->isPlayerCreature()) {
		// Remove member's pets
		CreatureObject* playerCreature = cast<CreatureObject*>(member);
		RemovePetsFromGroupTask* task = new RemovePetsFromGroupTask(playerCreature, _this.get());
		task->execute();

		//Close any open Group SUIs.
		ManagedReference<PlayerObject*> ghost = playerCreature->getPlayerObject();
		if (ghost != NULL) {
			ghost->closeSuiWindowType(SuiWindowType::GROUP_LOOT_RULE);
			ghost->closeSuiWindowType(SuiWindowType::GROUP_LOOT_CHANGED);
			ghost->closeSuiWindowType(SuiWindowType::GROUP_LOOT_PICK_LOOTER);
		}

		//Reset Master Looter if needed.
		if (getMasterLooterID() == playerCreature->getObjectID()) {
			ManagedReference<CreatureObject*> groupLeader = (getLeader()).castTo<CreatureObject*>();
			GroupManager::instance()->changeMasterLooter(_this.get(), groupLeader, false);
		}

		if (hasSquadLeader()) {
			removeGroupModifiers(playerCreature);
		}

		if (playerCreature->getPlayerObject() != NULL) {
			PlayerObject* ghost = playerCreature->getPlayerObject();
			ghost->removeWaypointBySpecialType(WaypointObject::SPECIALTYPE_NEARESTMISSIONFORGROUP);
		}
		scheduleUpdateNearestMissionForGroup(playerCreature->getPlanetCRC());
	}

	calcGroupLevel();
}
void GroupObjectImplementation::calcGroupLevel() {
	groupLevel = 0;

	for (int i = 0; i < getGroupSize(); i++) {
		SceneObject* member = getGroupMember(i);

		if (member->isCreatureObject()) {
			CreatureObject* creature = cast<CreatureObject*>(member);

			int currentlevel = groupLevel - getGroupSize();
			int memberlevel = creature->getLevel();

			if (memberlevel > currentlevel)
				groupLevel = memberlevel + getGroupSize();
		}
	}

	GroupObjectDeltaMessage6* msg = new GroupObjectDeltaMessage6(_this.get());

	msg->updateLevel(this->groupLevel);
	msg->close();

	broadcastMessage(msg);
}
void GroupObjectImplementation::addMember(CreatureObject* newMember) {
	Locker locker(_this.getReferenceUnsafeStaticCast());

	GroupObjectDeltaMessage6* grp = new GroupObjectDeltaMessage6(_this.getReferenceUnsafeStaticCast());
	grp->startUpdate(1);
	groupMembers.add(newMember, grp);
	grp->close();

	broadcastMessage(grp);

	if (newMember->isPlayerCreature()) {
		sendTo(newMember, true);

		if (hasSquadLeader()) {
			addGroupModifiers(newMember);
		}

		scheduleUpdateNearestMissionForGroup(newMember->getPlanetCRC());
	}

	updatePvPStatusNearCreature(newMember);

	calcGroupLevel();
}
void GroupObjectImplementation::updateLootRules() {
	GroupObjectDeltaMessage6* msg = new GroupObjectDeltaMessage6(_this.get());
	msg->updateLootRules(this->masterLooterID, this->lootRule);
	msg->close();
	broadcastMessage(msg);
}