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);
}
float GroupObjectImplementation::getGroupHarvestModifier(CreatureObject* player) {

	String skillNovice = "outdoors_ranger_novice";
	String skillMaster = "outdoors_ranger_master";

	float modifier = 1.2f;

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

		if(scno->isPlayerCreature()) {
			CreatureObject* groupMember = cast<CreatureObject*>( scno.get());

			if(groupMember == player)
				continue;

			if(groupMember->hasSkill(skillNovice)) {

				if(groupMember->isInRange(player, 64.0f)) {

					if(groupMember->hasSkill(skillMaster)) {
						modifier = 1.4f;
						break;
					}
					modifier = 1.3f;
				}
			}
		}
	}

	return modifier;
}
void GroupObjectImplementation::removeGroupModifiers() {
	for (int i = 0; i < groupMembers.size(); i++) {
		CreatureObject* player = getGroupMember(i);

		if (!player->isPlayerCreature())
			continue;

		removeGroupModifiers(player);
	}
}
int GroupObjectImplementation::getNumberOfPlayerMembers() {
	int playerCount = 0;

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

		if (member->isPlayerCreature()) {
			playerCount++;
		}
	}

	return playerCount;
}
bool GroupObjectImplementation::isOtherMemberPlayingMusic(CreatureObject* player) {
	for (int i = 0; i < getGroupSize(); ++i) {
		Reference<CreatureObject*> groupMember = (getGroupMember(i)).castTo<CreatureObject*>();

		if (groupMember == NULL || groupMember == player || !groupMember->isPlayerCreature())
			continue;

		if (groupMember->isPlayingMusic()) {
			return true;
		}
	}

	return false;
}
void GroupObjectImplementation::removeGroupModifiers() {
	for (int i = 0; i < groupMembers.size(); i++) {
		CreatureObject* crea = getGroupMember(i).castTo<CreatureObject*>().get();

		if (crea == NULL)
			continue;

		if (!crea->isPlayerCreature())
			continue;

		ManagedReference<CreatureObject*> player = cast<CreatureObject*>( crea);
		removeGroupModifiers(player);
	}
}
void GroupObjectImplementation::disband() {
	// this locked
	ManagedReference<ChatRoom* > chat = chatRoom;

	for (int i = 0; i < groupMembers.size(); i++) {
		if (groupMembers.get(i) == NULL) {
			continue;
		}

		Reference<CreatureObject*> groupMember = getGroupMember(i).castTo<CreatureObject*>();

		try {
			Locker clocker(groupMember, _this.get());

			if (groupMember->isPlayerCreature()) {
				if (chat != NULL) {
					chat->removePlayer(groupMember, false);
					chat->sendDestroyTo(groupMember);

					ChatRoom* room = chat->getParent();
					room->sendDestroyTo(groupMember);
				}

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

			groupMember->updateGroup(NULL);
			//play->updateGroupId(0);

			//sendClosestWaypointDestroyTo(play);

			//removeSquadLeaderBonuses(play);
		} catch (Exception& e) {
			System::out << "Exception in GroupObject::disband(Player* player)\n";
		}
	}

	destroyChatRoom();

	if (hasSquadLeader())
		removeGroupModifiers();

	groupMembers.removeAll();

	//The mission waypoints should not be destroyed. They belong to the players.
	//missionWaypoints.removeAll();
}
void GroupObjectImplementation::addGroupModifiers() {
	ManagedReference<GroupObject*> thisGroup = _this.getReferenceUnsafeStaticCast();

	Locker glocker(thisGroup);

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

		if (!player->isPlayerCreature())
			continue;

		Locker clocker(player, thisGroup);

		addGroupModifiers(player);
	}
}
void GroupObjectImplementation::addGroupModifiers() {
	ManagedReference<GroupObject*> thisGroup = _this.get();

	Locker glocker(thisGroup);

	for (int i = 0; i < groupMembers.size(); i++) {
		CreatureObject* crea = getGroupMember(i).castTo<CreatureObject*>().get();

		if (crea == NULL)
			continue;

		if (!crea->isPlayerCreature())
			continue;

		ManagedReference<CreatureObject*> player = cast<CreatureObject*>( crea);

		Locker clocker(player, thisGroup);

		addGroupModifiers(player);
	}
}
void GroupObjectImplementation::disband() {
	//Group is locked

	for (int i = 0; i < groupMembers.size(); i++) {
		if (groupMembers.get(i) == NULL)
			continue;

		Reference<CreatureObject*> groupMember = getGroupMember(i);

		try {
			Locker clocker(groupMember, _this.getReferenceUnsafeStaticCast());

			if (groupMember->isPlayerCreature()) {
				PlayerObject* ghost = groupMember->getPlayerObject();

				if (ghost != NULL) {
					ghost->removeWaypointBySpecialType(WaypointObject::SPECIALTYPE_NEARESTMISSIONFORGROUP);
				}
			}

			groupMember->updateGroup(NULL);

		} catch (Exception& e) {
			System::out << "Exception in GroupObject::disband(Player* player)\n";
		}
	}

	if (hasSquadLeader())
		removeGroupModifiers();

	while (groupMembers.size() > 0) {
		CreatureObject* member = groupMembers.get(0).get().get();

		updatePvPStatusNearCreature(member);

		groupMembers.remove(0);
	}

	destroyChatRoom();
}
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);
}