//----------------------------------------------------------------------------
void CGuildMemberModule::quitGuild()
{
	MODULE_AST( _GuildMemberCore );
	CGuild * guild = EGS_PD_CAST<CGuild*>( _GuildMemberCore->getGuild() );
	EGS_PD_AST( guild );
	SM_STATIC_PARAMS_1( params,STRING_MANAGER::player );
	params[0].setEIdAIAlias( _GuildMemberCore->getIngameEId(), CAIAliasTranslator::getInstance()->getAIAlias(_GuildMemberCore->getIngameEId()) );
	
	CFameManager::getInstance().clearPlayerGuild( _GuildMemberCore->getIngameEId() );

	CGuildCharProxy proxy;
	getProxy(proxy);
	proxy.cancelAFK();
	clearOnlineGuildProperties();
	guild->deleteMember( _GuildMemberCore );
	if ( guild->getMembersBegin() == guild->getMembersEnd() )
	{
		CGuildManager::getInstance()->deleteGuild(guild->getId());
		proxy.sendSystemMessage("GUILD_DESTROYED");
	}
	else
	{
		guild->sendMessageToGuildMembers("GUILD_QUIT", params);
		SM_STATIC_PARAMS_1(params, STRING_MANAGER::string_id);
		params[0].StringId = guild->getNameId();
		proxy.sendSystemMessage("GUILD_YOU_QUIT", params);
	}
}
//----------------------------------------------------------------------------
void CBuildingPhysicalGuild::getClientDescription(uint16 roomIdx, uint16 ownerIndex, CCharacter * user, uint64 & icon, uint32 & textId )const
{
#ifdef NL_DEBUG
	nlassert(user);
#endif
	CMirrorPropValueRO<TYPE_CELL> mirrorValue( TheDataset, user->getEntityRowId(), DSPropertyCELL );
	const sint32 cell = mirrorValue;
	// if user is inside a building, icons and texts are found the same way as standard building
	if ( CBuildingManager::getInstance()->isRoomCell(cell) )
	{
		icon = UINT64_CONSTANT(0x8000000000000000) + _Template->Rooms[roomIdx].Icon;
		textId = CZoneManager::getInstance().sendPlaceName( user->getEntityRowId(), _Template->Rooms[roomIdx].PhraseId );
	}
	// otherwise, display the guild icon and guild name
	else
	{
		if ( ownerIndex >= _Guilds.size() )
		{
			nlwarning("<BUILDING>%s ask for guild room %u count is %u, in building '%s'",ownerIndex, _Guilds.size(), user->getId().toString().c_str(),_Name.c_str());
			textId = 0;
			icon = 0;
			return;
		}
		CGuild * guild = CGuildManager::getInstance()->getGuildFromId( _Guilds[ownerIndex] );
		if ( !guild )
		{
			nlwarning("<BUILDING>%s ask for guild %u. This guild is invalid",user->getId().toString().c_str(), _Guilds[ownerIndex] );
			textId = 0;
			icon = 0;
			return;
		}
		icon = guild->getIcon();
		static TVectorParamCheck params(1);
		params[0].Type = STRING_MANAGER::string_id;
		params[0].StringId = guild->getNameId();
		textId = STRING_MANAGER::sendStringToClient( user->getEntityRowId(),"GUILD_ROOM",params );
	}
}
//----------------------------------------------------------------------------
void CGuildMemberModule::_inviteCharacterInGuild(CGuildCharProxy& invitor, CGuildCharProxy& target)const
{
	CGuild * guild = EGS_PD_CAST<CGuild*>( _GuildMemberCore->getGuild() );
	EGS_PD_AST( guild );

	SM_STATIC_PARAMS_1( params1, STRING_MANAGER::player );
	params1[0].setEIdAIAlias( target.getId(), CAIAliasTranslator::getInstance()->getAIAlias( target.getId()) );

	/// check invitor grade
	if ( !canInvite() )
	{
		CCharacter::sendDynamicSystemMessage( invitor.getRowId(), "GUILD_INSUFFICIENT_GRADE",params1 );
		return;
	}

	/// target must not have a guild
	CGuildMemberModule * guildModule;
	if ( target.getModule( guildModule ) )
	{
		invitor.sendSystemMessage("GUILD_ALREADY_MEMBER",params1);
		return;
	}

	/// target must not be invited
	CGuildInvitationModule * inviteModule;
	if ( target.getModule(inviteModule) )
	{
		CCharacter::sendDynamicSystemMessage( invitor.getRowId(), "GUILD_ALREADY_HAS_JOIN_PROPOSAL",params1 );
		return;		
	}

	/// the invitor must not be in the ignore list of the target
	{
		CCharacter * invitedChar = PlayerManager.getChar(target.getId());
		if( invitedChar == 0 ) return;
		if(invitedChar->hasInIgnoreList(invitor.getId()))
		{
			// Use the standard "player declines your offer". Don't use specific message because
			// maybe not a good idea to inform a player that someone ignores him
			CCharacter::sendDynamicSystemMessage( invitor.getRowId(), "GUILD_REFUSE_JOIN",params1 );
			return;
		}
	}

	/// target must not be an outpost pvp enemy of the invitor's guild
	CCharacter * invitorPlayer = PlayerManager.getChar( invitor.getEntityRowId() );
	if( invitorPlayer )
	{
		CEntityBase * targetEntity = CEntityBaseManager::getEntityBasePtr( target.getEntityRowId() );
		if(targetEntity)
		{
			if( targetEntity->getOutpostAlias() !=0 )
			{
				CSmartPtr<COutpost> outpost = COutpostManager::getInstance().getOutpostFromAlias( targetEntity->getOutpostAlias() );
				if( outpost )
				{
					if( (outpost->getOwnerGuild()==invitorPlayer->getGuildId() &&  targetEntity->getOutpostSide()==OUTPOSTENUMS::OutpostAttacker) ||
						(outpost->getAttackerGuild()==invitorPlayer->getGuildId() &&  targetEntity->getOutpostSide()==OUTPOSTENUMS::OutpostOwner) )
					{
						CCharacter::sendDynamicSystemMessage( invitor.getRowId(), "GUILD_CANT_INVITE_OUTPOST_ENEMY" );
						return;
					}
				}
				else
				{
					nlwarning("<CGuildMemberModule::inviteTargetInGuild> can't get outpost %d of target",targetEntity->getOutpostAlias() );
				}
			}
		}
		else
		{
			nlwarning("<CGuildMemberModule::inviteTargetInGuild> can't get target %s",target.getId().toString().c_str() );
		}
	}
	else
	{
		nlwarning("<CGuildMemberModule::inviteTargetInGuild> can't get char from invitor %s",invitor.getId().toString().c_str() );
	}

	/// check if there is room in the guild
	if (  guild->getMemberCount() >= GuildMaxMemberCount )
	{
		SM_STATIC_PARAMS_1(params,STRING_MANAGER::integer);
		params[0].Int = GuildMaxMemberCount;
		CCharacter::sendDynamicSystemMessage( invitor.getRowId(), "GUILD_MAX_MEMBER_COUNT", params);
		return;		
	}

	/// check guild and invited member allegiances compatibilities
	CGuild::TAllegiances guildAllegiance, invitedAllegiance;
	guildAllegiance = guild->getAllegiance();
	CCharacter * invitedChar = PlayerManager.getChar(target.getId());
	if( invitedChar == 0 ) return;
	invitedAllegiance = invitedChar->getAllegiance();
	if( invitedAllegiance.first != guildAllegiance.first && invitedAllegiance.first != PVP_CLAN::Neutral )
	{
		SM_STATIC_PARAMS_2( params, STRING_MANAGER::player, STRING_MANAGER::faction );
		params[0].setEIdAIAlias( target.getId(), CAIAliasTranslator::getInstance()->getAIAlias( target.getId()) );
		params[1].Enum = PVP_CLAN::getFactionIndex(invitedAllegiance.first);
		invitor.sendSystemMessage("GUILD_ICOMPATIBLE_ALLEGIANCE",params);
		return;
	}
	if( invitedAllegiance.second != guildAllegiance.second && invitedAllegiance.second != PVP_CLAN::Neutral )
	{
		SM_STATIC_PARAMS_2( params, STRING_MANAGER::player, STRING_MANAGER::faction );
		params[0].setEIdAIAlias( target.getId(), CAIAliasTranslator::getInstance()->getAIAlias( target.getId()) );
		params[1].Enum = PVP_CLAN::getFactionIndex(invitedAllegiance.second);
		invitor.sendSystemMessage("GUILD_ICOMPATIBLE_ALLEGIANCE",params);
		return;
	}

	// build a new invitation
	MODULE_AST(guild);
	CGuildInvitation *invitation = new CGuildInvitation( guild, invitor.getRowId() );
	CGuildManager::getInstance()->addInvitation( invitation );

	// build a module on it
	inviteModule = new CGuildInvitationModule(target,invitation);

	// tell client
	SM_STATIC_PARAMS_2(params2,STRING_MANAGER::player,STRING_MANAGER::string_id);
	params2[0].setEIdAIAlias( invitor.getId(), CAIAliasTranslator::getInstance()->getAIAlias( invitor.getId()) );
	params2[1].StringId = guild->getNameId();
	uint32 txt = STRING_MANAGER::sendStringToClient( target.getRowId(),"GUILD_JOIN_PROPOSAL",params2 );
	PlayerManager.sendImpulseToClient(target.getId(), "GUILD:JOIN_PROPOSAL", txt );
}
//----------------------------------------------------------------------------
void CGuildMemberModule::setGrade( uint16 index,uint8 session, EGSPD::CGuildGrade::TGuildGrade grade)const
{
	MODULE_AST( _GuildMemberCore );
	CGuild * guild = EGS_PD_CAST<CGuild*>(_GuildMemberCore->getGuild());
	EGS_PD_AST( guild );
	CGuildCharProxy proxy;
	getProxy(proxy);
	proxy.cancelAFK();
		
	if ( guild->getMembersSession() != session )
	{
		proxy.sendSystemMessage( "GUILD_BAD_SESSION" );
		return;
	}
	if ( _GuildMemberCore->getMemberIndex() == index )
	{
		nlwarning("<GUILD>%s tries to change its grade",proxy.getId().toString().c_str());
		return;
	}
	CGuildMember * member = guild->getMemberByIndex( index );
	if ( member == NULL )
	{
		nlwarning("<GUILD>%s set invalid member idx %u as leader",proxy.getId().toString().c_str(),index );
		return;
	}
	EGSPD::CGuildGrade::TGuildGrade oldGrade = member->getGrade();
	if ( !canAffectGrade( oldGrade ) )
	{
		proxy.sendSystemMessage("GUILD_INSUFFICIENT_GRADE");
		return;
	}

	if ( !CGuildManager::getInstance()->isGMGuild( guild->getId() ) && guild->getGradeCount(grade) >= guild->getMaxGradeCount(grade) )
	{
		SM_STATIC_PARAMS_1( paramFull, STRING_MANAGER::string_id );
		paramFull[0].StringId = CEntityIdTranslator::getInstance()->getEntityNameStringId(member->getIngameEId());
		proxy.sendSystemMessage("GUILD_GRADE_FULL",paramFull);
		return;
	}
	
	member->setMemberGrade(grade);
	guild->incGradeCount( grade );
	guild->decGradeCount( oldGrade );
	
	// send system message
	SM_STATIC_PARAMS_3(params,STRING_MANAGER::player,STRING_MANAGER::player,STRING_MANAGER::string_id);
	params[0].setEIdAIAlias( proxy.getId(), CAIAliasTranslator::getInstance()->getAIAlias(proxy.getId()) );
	params[1].setEIdAIAlias( member->getIngameEId(), CAIAliasTranslator::getInstance()->getAIAlias(member->getIngameEId()) );
	params[2].StringId = guild->getNameId();
	
	// If the player is online, the module must be recreated. Do as the reference was destroyed
	CGuildMemberModule * module = NULL;
	if ( member->getReferencingModule(module) )
	{
		CGuildCharProxy targetProxy;
		module->getProxy(targetProxy);
		member->removeReferencingModule(module);
		module->onReferencedDestruction();
		IModule * moduleTarget = createModule(targetProxy,member);
		guild->setMemberClientDB( member );
		MODULE_AST(moduleTarget);
	}
}