Clan System

Categoria cu cereri de pluginuri si nu numai.

Moderators: Moderatori ajutatori, Moderatori, Echipa eXtreamCS.com

Forum rules
Accesează link-ul pentru a putea vedea regulile forumului

Daca doriti sa vi se modifice un plugin, va rugam postati aici .
Post Reply
User avatar
limbaa
Membru, skill 0
Membru, skill 0
Posts: 33
Joined: 26 Oct 2015, 11:25
Detinator Steam: Da
Detinator server CS: GOX.BLACKGAMES.RO
SteamID: tenlimba96
Fond eXtream: 0
Discord: GaBy#1976
Has thanked: 4 times
Contact:

10 Oct 2020, 14:49

Plugin Cerut: Clan system in engleza
Descriere (adica ce face el mai exact): Poate cineva sa il traduca?

Code: Select all

/*================================================================================
	
		*****************************************************
		************* [AMXX Clan/Group System] **************
		*****************************************************
	
	----------------------
	-*- Licensing Info -*-
	----------------------
	
	Clan/Group System (v1.3 bugfixed)
	Copyright (C) 2016-2017 by Chamo.
	
	This program is free software: you can redistribute it and/or modify
	it under the terms of the GNU General Public License as published by
	the Free Software Foundation, either version 3 of the License, or
	(at your option) any later version.
	
	This program is distributed in the hope that it will be useful,
	but WITHOUT ANY WARRANTY; without even the implied warranty of
	MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
	GNU General Public License for more details.
	
	You should have received a copy of the GNU General Public License
	along with this program.  If not, see <http://www.gnu.org/licenses/>.
	
	In addition, as a special exception, the author gives permission to
	link the code of this program with the Half-Life Game Engine ("HL
	Engine") and Modified Game Libraries ("MODs") developed by Valve,
	L.L.C ("Valve"). You must obey the GNU General Public License in all
	respects for all of the code used other than the HL Engine and MODs
	from Valve. If you modify this file, you may extend this exception
	to your version of the file, but you are not obligated to do so. If
	you do not wish to do so, delete this exception statement from your
	version.
	
	---- CHANGELOG ----
	
	v1.3
	
		v1.3 (bugfixed)
		
		- Corregido error que no permitia invitar jugadores al Clan.
		- Corregidos ciertos errores/bugs menores.
		- Optimizados ciertas partes del codigo.
		- Corregidos errores ortograficos/de tipeo en algunos mensajes.
		- Aumentado limite de caracteres MINIMOS para:
			-- NOMBRE DEL CLAN: 7 caracteres (anterior) -> 10 caracteres (actual).
			-- TAG DEL CLAN: 4 caracteres (anterior) -> 6 caracteres (actual).
		- Aumentado limite de caracteres MAXIMOS para:
			-- NOMBRE DEL CLAN: 25 caracteres (anterior) -> 32 caracteres (actual).
			-- TAG DEL CLAN: 15 caracteres (anterior) -> 24 caracteres (actual).
		- Expandida lista de CARACTERES ESPECIALES permitidos para: NOMBRE/TAG/MENSAJE DE BIENVENIDA DEL CLAN.
	
		v1.3
		
		- Re-estructuración del 85%+ del código original.
		- Mejoradas ciertas partes del código anterior.
		- Ahora si no tienes clan, el chat sera igual el default del juego.
		- Re-estructurado el chat, quedando de la siguiente manera:
			-- El chat GLOBAL (say) -> (TAG/[NOMBRE DEL CLAN]) --- NOMBRE: TEXTO
			-- El chat DE EQUIPOS (say_team/say /cc) -> RANGO NOMBRE: TEXTO (el color del chat depende del rango)
		- Cambiados y reordenados algunas opciones del menú principal del clan.
		- Ahora, los menúes "LISTA DE MIEMBROS", "EXPULSAR MIEMBROS" y "EDITAR RANGO", muestran la lista de miembros, ordenándolos en forma DESCENDENTE según el rango:
			-- LÍDER ([ON/OFF]-LINE)
			-- CO-LÍDER ([ON/OFF]-LINE)
			-- SUB-LÍDER ([ON/OFF]-LINE)
			-- MIEMBRO ([ON/OFF]-LINE)
		- Cambiado la estructura del menú "INFORMACIÓN DEL CLAN".
		- Añadido "TOP DE CLANES" (2) los cuales son de:
			- LA MAYOR CANTIDAD DE TIEMPO DE ACTIVIDAD
			- EL MENOR NUMERO DE MIEMBROS, los cuales están ordenados, respectivamente:
				--- Forma DESCENDENTE
				--- Forma ASCENDENTE.
			
	v1.2
	- Fixeadas algunas cosas pequeñas.
	- Arreglado error de incompatibilidad entre versiones:
	-- (Si se usaba una versión vieja, y luego una actual, los Clanes guardados no eran cargados)
	- Ahora el Chat global (say), muestra el TAG del Clan del jugador que escribe (de no tener Clan,
	  mostrará 'SIN CLAN').
	- Ahora el Chat del Clan no muestra TAG, solamente: 'Rango', 'Nombre' y 'Texto', su estructura
	es casi igual a la anterior.
	- Agregado 'Tiempo de actividad del Clan', que sirve para poder invitar miembros:
	+Tiempo de actividad = +cantidad de miembros para poder invitar (idea de totopizza).
	- Agregado al menú del Clan la opción 'VER INFORMACIÓN DEL CLAN.' que muestra diferentes cosas del Clan,
	como: 'Lider', 'Nombre', 'Nº de Miembros', y 'Tiempo de Actividad' (de no tener 'TAG' o 'Tiempo de Actividad',
	mostrará "Sin TAG"/"No hay registros aun", respectivamente).
	- Agregado bloqueo de cambio de nick durante el juego, para evitar bugs con el Guardado/Cargado de datos.
	
	v1.1
	- Fixeados algunos errores que se pasaron por alto
	- Agregado chat para team (puede ser por say_team, o custom, escribiendo /cc)
	-- La estructura del Chat es igual en ambos casos, y depende de quien escriba:
	--- Member = TAG - Name (Team color) - Text (yelow)
	--- Sub-Leader = TAG - Name (green) - Text (yelow)
	--- Co-Leader = TAG - Name (green) - Text (team color)
	--- Leader = TAG - Name (white) - Text (green)
	-- De no tener TAG el Clan, se motrara "[SIN TAG]...."
	- Agregado mensaje de bienvenida custom (editable por el/los Co-Líderes/Líder)
	- Agregado TAG o prefijo custom (editable por el/los Co-Líderes/Líder)
	
	v1.0
	- Lanzamiento oficial
	
	------- END -------
=================================================================================*/

/*=====================
	LIBRERIAS
=====================*/

#include <amxmodx>
#include <amxmisc>
#include <fvault>
#include <engine>
#include <hamsandwich>
#include <cstrike>
#include <fakemeta>

#if AMXX_VERSION_NUM <= 182
	#include <dhudmessage>
#endif

/*==================
	MACROS
==================*/

#define M_HookTeamSay
#define M_TimerThinkTime			(get_gametime()+1.0)
#define M_HaveClan(%1)			(!bool:(A_PlayerVars[%1][PI_CLAN_ID] == -1))
#define M_ActivityTimeNeed(%1)			((CI_SecondsInOneMinute * CI_MinutesNeed) + (%1 > 4 ? ((%1 + %1) * CI_ExtraSecondsNeed) : 0))

/*=========================
	ENUMERACIONES
=========================*/

enum _:E_ExtraVars
{
	PLUGIN_NAME, PLUGIN_VERSION, PLUGIN_AUTHOR,
	
	DONT_HAVE_CLAN = 0, CONFIRM_CLAN_NAME, HAVE_CLAN, INVITE_PLAYERS_TO_CLAN, CONFIRM_INVITATION_TO_CLAN,
	SHOW_CLAN_MEMBERS, SHOW_KICK_MEMBERS, SHOW_EDIT_CLAN_MEMBERS_STATUS, CHOOSE_STATUS_TO_CLAN_MEMBER,
	CONFIRM_CLAN_MEMBER_STATUS, SHOW_CLAN_INFO, SHOW_CLANES_TOP_ONE, SHOW_CLANES_TOP_TWO,
	
	MIN_CLAN_NAME_LEN = 10, MAX_CLAN_NAME_LEN = 32,
	MIN_CLAN_TAG_LEN = 6, MAX_CLAN_TAG_LEN = 24,
	MIN_CLAN_WELCOME_LEN = 10, MAX_CLAN_WELCOME_LEN = 35,
	
	STATUS_MEMBER = 0, STATUS_SUBLEADER, STATUS_COLEADER, STATUS_LEADER,
	
	CREATE_NEW_CLAN = 0, CHANGE_CLAN_TAG, CHANGE_CLAN_WELCOME_MESSAGE,
	
	CHAT_COLOR_GREY = 40, CHAT_COLOR_RED, CHAT_COLOR_BLUE,
	
	VALIDATE_SAY = 0, VALIDATE_CLAN_NAME, VALIDATE_CLAN_TAG, VALIDATE_CLAN_WELCOME_MESSAGE,
	
	LOAD_CLANES_DATA = 0, SAVE_CLANES_DATA, LOAD_PLAYERS_DATA, SAVE_PLAYERS_DATA,
	
	SEARCH_ALL_STATUS = -1,
	
	SEARCH_ALL_MEMBERS = 0, SEARCH_ONLINE_MEMBERS, SEARCH_OFFLINE_MEMBERS,
	
	SORT_BY_ACTIVITY_TIME = 0, SORT_BY_CLAN_MEMBERS,
	
	SORT_DOWNWARDS = 0, SORT_UPWARDS
};

enum _:E_GlobalVarsStruct
{
	GI_MAX_PLAYERS,
	
	Array:GDA_CLANES,
	
	Trie:GT_CLANES_NAMES,
	Trie:GT_CLANES_MEMBERS_NAMES,
	Trie:GT_CLANES_TAGS,
	Trie:GT_CLANES_VALUES,
	
	GSZ_TEXT[300]
};

enum _:E_PlayerVarsStruct
{
	bool:PBO_IS_CONNECTED,
	bool:PBO_IS_ALIVE,
	bool:PBO_IS_BOT,
	
	PI_CLAN_ID,
	PI_CLAN_STATUS,
	PI_CURRENT_TIMER,
	PI_STATUS,
	PI_CHOOSE_STATUS_FOR_MEMBER,
	
	PSZ_CLIENT_NAME[32],
	PSZ_CLAN_NAME[MAX_CLAN_NAME_LEN]
};

enum _:E_ClanesData
{
	I_CLAN_ID,
	I_CLAN_MEMBERS,
	I_CLAN_ACTIVITY_TIME,
	
	SZ_CLAN_NAME[MAX_CLAN_NAME_LEN],
	SZ_CLAN_LEADER[32],
	SZ_CLAN_TAG[MAX_CLAN_TAG_LEN],
	SZ_CLAN_WELCOME_MESSAGE[MAX_CLAN_WELCOME_LEN]
};

enum _:E_ClanesValues
{
	I_VALUE_CLAN_ID,
	I_VALUE_CLAN_MEMBERS,
	I_VALUE_CLAN_ACTIVITY_TIME,
	I_VALUE_CLAN_NAME,
	I_VALUE_CLAN_LEADER,
	I_VALUE_CLAN_TAG,
	I_VALUE_CLAN_WELCOME_MESSAGE
};

/*======================
	CONSTANTES
======================*/

new const CSZ_PluginInfo[(PLUGIN_AUTHOR + 1)][] =
{
	"AMXX CLAN/GROUP SYSTEM",
	"1.3 (bugfixed)",
	"Chamo."
};

new const CSZ_CsTeamNamesTable[][] =
{
	"UNASSIGNED",
	"TERRORIST",
	"CT",
	"SPECTATOR"
};

new const CSZ_ClanMemberStatus[STATUS_LEADER+1][] =
{
	"Membru",
	"SUB-Leader",
	"CO-Leader",
	"Leader"
};

new const CSZ_ClanesValuesNames[E_ClanesValues][] =
{
	"ID",
	"MEMBERS",
	"ACTIVITY TIME",
	"NAME",
	"LEADER",
	"TAG",
	"WELCOME MESSAGE"
};

new const CSZ_TimerClassName[] = "Timer";
new const CSZ_Prefix[] = "!g[AMXX-CLANES]!y";
new const CSZ_AvailableSpecialCharacters[] = "#$&()*+-:<=>@[]{|}~";
new const CSZ_ClanesVault[] = "ClanesList.INI";
new const CSZ_PlayersVault[] = "ClanesData";

const CI_SecondsInOneMinute = 60;
const CI_MinutesNeed = 50;
const CI_ExtraSecondsNeed = 20;
const CI_MaxClanesOnTop = 15;

/*=====================
	VARIABLES
=====================*/

new A_GlobalVars[E_GlobalVarsStruct], A_PlayerVars[33][E_PlayerVarsStruct], A_ClanData[E_ClanesData];

/*======================================================================
			FORWARDS DEL PLUGIN (AMXX)
======================================================================*/

public plugin_init()
{
	register_plugin(CSZ_PluginInfo[PLUGIN_NAME], CSZ_PluginInfo[PLUGIN_VERSION], CSZ_PluginInfo[PLUGIN_AUTHOR]);
	
	RegisterHam(Ham_Spawn, "player", "HAM_PLAYER_Spawn_Post", true);
	RegisterHam(Ham_Killed, "player", "HAM_PLAYER_Killed_Post", true);
	
	register_think(CSZ_TimerClassName, "THINK_Timer");
	
	register_forward(FM_ClientUserInfoChanged, "FM_ClientUserInfoChanged_Pre");
	
	register_clcmd("say", "CLCOMMAND_Say");
	register_clcmd("say /clan", "CLCOMMAND_Clan");
	register_clcmd("say clan", "CLCOMMAND_Clan");
	register_clcmd("say_team /clan", "CLCOMMAND_Clan");
	register_clcmd("say_team clan", "CLCOMMAND_Clan");
	register_clcmd("MESSAGEMODE_Clanes", "CLCOMMAND_Clanes");
	
	#if defined M_HookTeamSay
		register_clcmd("say_team", "CLCOMMAND_Say");
	#else
	{
		register_clcmd("say /cc", "CLCOMMAND_ClanChat");
		register_clcmd("say_team /cc", "CLCOMMAND_ClanChat");
		register_clcmd("MESSAGEMODE_ClanChat", "CLCOMMAND_Say");
	}
	#endif
	
	A_GlobalVars[GI_MAX_PLAYERS] = get_maxplayers();
	A_GlobalVars[GDA_CLANES] = _:ArrayCreate(E_ClanesData);
	A_GlobalVars[GT_CLANES_NAMES] = _:TrieCreate();
	A_GlobalVars[GT_CLANES_MEMBERS_NAMES] = _:TrieCreate();
	A_GlobalVars[GT_CLANES_TAGS] = _:TrieCreate();
	A_GlobalVars[GT_CLANES_VALUES] = _:TrieCreate();
	
	for (new I; I < sizeof CSZ_ClanesValuesNames; I++)
		TrieSetCell(A_GlobalVars[GT_CLANES_VALUES], CSZ_ClanesValuesNames[I], I);
	
	ClanesData(LOAD_CLANES_DATA);
	
	new I_Entity;
	
	do
		I_Entity = create_entity("info_target");
	while (!is_valid_ent(I_Entity))
	
	entity_set_float(I_Entity, EV_FL_nextthink, M_TimerThinkTime);
	entity_set_string(I_Entity, EV_SZ_classname, CSZ_TimerClassName);
}

public plugin_end()
{
	ClanesData(SAVE_CLANES_DATA);
	
	ArrayDestroy(A_GlobalVars[GDA_CLANES]);
}

/*=======================================================================
			FORWARDS DEL CLIENTE (AMXX)
=======================================================================*/

public client_putinserver(I_Client)
{
	A_PlayerVars[I_Client][PBO_IS_CONNECTED] = true;
	
	if (is_user_bot(I_Client))
		A_PlayerVars[I_Client][PBO_IS_BOT] = true;
	
	get_user_name(I_Client, A_PlayerVars[I_Client][PSZ_CLIENT_NAME], charsmax(A_PlayerVars[][PSZ_CLIENT_NAME]));
	
	A_PlayerVars[I_Client][PI_CLAN_ID] = -1;
	
	PlayersData(I_Client, LOAD_PLAYERS_DATA);
	
	set_task(0.1, "SendTeamInfoChatColor", I_Client);
}

public client_disconnected(I_Client)
{
	if (A_PlayerVars[I_Client][PBO_IS_CONNECTED])
		PlayersData(I_Client, SAVE_PLAYERS_DATA);
	
	A_PlayerVars[I_Client][PBO_IS_CONNECTED] = A_PlayerVars[I_Client][PBO_IS_BOT] = false;
}

/*===============================================================================
			CALLBACKS DE LOS COMANDOS HOOKEADOS
===============================================================================*/

/*=============================================
	COMANDOS DE CLIENTE (CLCOMMAND_*)
=============================================*/

public CLCOMMAND_Say(const I_Client)
{
	static SZ_SayType[8];
	
	read_argv(0, SZ_SayType, charsmax(SZ_SayType));
	
	new bool:BO_IsSay = bool:equal(SZ_SayType, "say");
	
	if (!BO_IsSay && !M_HaveClan(I_Client))
	{
		UTIL_SendPrint(I_Client, I_Client, "%s The !ColorCHAT!y And team color is exclusive to !gCLANES!.", CSZ_Prefix);
			
		return PLUGIN_HANDLED_MAIN;
	}
	
	static SZ_Text[190];
	
	read_argv(1, SZ_Text, charsmax(SZ_Text));
	replace_all(SZ_Text, charsmax(SZ_Text), "%", " ");
	
	if (!IsValidText(_, SZ_Text, VALIDATE_SAY))
		return PLUGIN_HANDLED_MAIN;
	
	static I;
	
	if (BO_IsSay)
	{
		if (M_HaveClan(I_Client))
		{
			GetClanData(A_PlayerVars[I_Client][PI_CLAN_ID]);
			
			format(SZ_Text, charsmax(SZ_Text), "!color%s!y: %s", A_PlayerVars[I_Client][PSZ_CLIENT_NAME], SZ_Text);
			
			if (A_ClanData[SZ_CLAN_TAG][0])
				format(SZ_Text, charsmax(SZ_Text), "!color%s!y --- %s", A_ClanData[SZ_CLAN_TAG], SZ_Text);
			else
				format(SZ_Text, charsmax(SZ_Text), "!g[%s]!y --- %s", A_ClanData[SZ_CLAN_NAME], SZ_Text);
		}
		else
			format(SZ_Text, charsmax(SZ_Text), "!color%s!y: %s", A_PlayerVars[I_Client][PSZ_CLIENT_NAME], SZ_Text);
	}
	else
	{
		switch (A_PlayerVars[I_Client][PI_CLAN_STATUS])
		{
			case STATUS_LEADER: format(SZ_Text, charsmax(SZ_Text), "!color[!g%s!color] %s!y: !g%s", CSZ_ClanMemberStatus[A_PlayerVars[I_Client][PI_CLAN_STATUS]], A_PlayerVars[I_Client][PSZ_CLIENT_NAME], SZ_Text);
			
			case STATUS_COLEADER: format(SZ_Text, charsmax(SZ_Text), "!color[%s] !g%s!y: !color%s", CSZ_ClanMemberStatus[A_PlayerVars[I_Client][PI_CLAN_STATUS]], A_PlayerVars[I_Client][PSZ_CLIENT_NAME], SZ_Text);
			
			case STATUS_SUBLEADER: format(SZ_Text, charsmax(SZ_Text), "!color[!y%s!color] !g%s!y: %s", CSZ_ClanMemberStatus[A_PlayerVars[I_Client][PI_CLAN_STATUS]], A_PlayerVars[I_Client][PSZ_CLIENT_NAME], SZ_Text);
			
			default: format(SZ_Text, charsmax(SZ_Text), "!color[!y%s!color] %s!y: %s", CSZ_ClanMemberStatus[A_PlayerVars[I_Client][PI_CLAN_STATUS]], A_PlayerVars[I_Client][PSZ_CLIENT_NAME], SZ_Text);
		}
	}
	
	for (I = 1; I <= A_GlobalVars[GI_MAX_PLAYERS]; I++)
	{
		if (!A_PlayerVars[I][PBO_IS_CONNECTED])
			continue;
		
		if (!BO_IsSay && A_PlayerVars[I][PI_CLAN_ID] != A_PlayerVars[I_Client][PI_CLAN_ID])
			continue;
	
		UTIL_SendPrint(I, ((!BO_IsSay && A_PlayerVars[I_Client][PI_CLAN_STATUS] == STATUS_LEADER) ? CHAT_COLOR_GREY : I_Client), SZ_Text);
	}
	
	return PLUGIN_HANDLED_MAIN;
}

public CLCOMMAND_Clan(const I_Client)
{
	SM_Clan(I_Client, _, (M_HaveClan(I_Client) ? HAVE_CLAN : DONT_HAVE_CLAN));
	
	return PLUGIN_HANDLED_MAIN;
}

public CLCOMMAND_Clanes(const I_Client)
{
	static SZ_Text[100];
	
	read_argv(1, SZ_Text, charsmax(SZ_Text));
	
	switch (A_PlayerVars[I_Client][PI_STATUS])
	{
		case CREATE_NEW_CLAN:
		{
			if (!IsValidText(I_Client, SZ_Text, VALIDATE_CLAN_NAME))
			{
				SM_Clan(I_Client, _, (M_HaveClan(I_Client) ? HAVE_CLAN : DONT_HAVE_CLAN));
				
				return PLUGIN_HANDLED_MAIN;
			}
			
			copy(A_PlayerVars[I_Client][PSZ_CLAN_NAME], charsmax(A_PlayerVars[][PSZ_CLAN_NAME]), SZ_Text);
			
			SM_Clan(I_Client, _, CONFIRM_CLAN_NAME);
		}
		
		case CHANGE_CLAN_TAG:
		{
			if (!IsValidText(I_Client, SZ_Text, VALIDATE_CLAN_TAG))
			{
				SM_Clan(I_Client, _, (M_HaveClan(I_Client) ? HAVE_CLAN : DONT_HAVE_CLAN));
				
				return PLUGIN_HANDLED_MAIN;
			}
			
			GetClanData(A_PlayerVars[I_Client][PI_CLAN_ID]);
			
			copy(A_ClanData[SZ_CLAN_TAG], charsmax(A_ClanData[SZ_CLAN_TAG]), SZ_Text);
			
			UpdateClanData(A_PlayerVars[I_Client][PI_CLAN_ID]);
			
			if (A_ClanData[SZ_CLAN_TAG][0])
			{
				formatex(A_GlobalVars[GSZ_TEXT], charsmax(A_GlobalVars[GSZ_TEXT]), "%s The !g%s !yColor %s!y And edit the!y ColorTAG!y And the !gCLAN: !Color %s!g!.", CSZ_Prefix, CSZ_ClanMemberStatus[A_PlayerVars[I_Client][PI_CLAN_STATUS]], A_PlayerVars[I_Client][PSZ_CLIENT_NAME], SZ_Text);
				
				UTIL_SendPrint(I_Client, I_Client, "%s You changed the !ColorTAG !yfrom %s !gCLAN !yto !Color: %s!g!.", CSZ_Prefix, (A_PlayerVars[I_Client][PI_STATUS] >= STATUS_LEADER ? " tu" : "l"), SZ_Text);
			}
			else
			{
				formatex(A_GlobalVars[GSZ_TEXT], charsmax(A_GlobalVars[GSZ_TEXT]), "%s The !g%s !Color %s !yAnd I create a !ColorTAG !y And for the !gCLAN:!Color %s!g!.", CSZ_Prefix, CSZ_ClanMemberStatus[A_PlayerVars[I_Client][PI_CLAN_STATUS]], A_PlayerVars[I_Client][PSZ_CLIENT_NAME], SZ_Text);
				
				UTIL_SendPrint(I_Client, I_Client, "%s You created the following !ColorTAG !yAnd for %s !gCLAN! Color: %s!g!.", CSZ_Prefix, (A_PlayerVars[I_Client][PI_STATUS] >= STATUS_LEADER ? " tu" : "el"), SZ_Text);
			}
			
			SendMessageToMembers(I_Client, A_GlobalVars[GSZ_TEXT]);
		}
		
		case CHANGE_CLAN_WELCOME_MESSAGE:
		{
			if (!IsValidText(I_Client, SZ_Text, VALIDATE_CLAN_WELCOME_MESSAGE))
			{
				SM_Clan(I_Client, _, (M_HaveClan(I_Client) ? HAVE_CLAN : DONT_HAVE_CLAN));
				
				return PLUGIN_HANDLED_MAIN;
			}
			
			GetClanData(A_PlayerVars[I_Client][PI_CLAN_ID]);
			
			UTIL_SendPrint(I_Client, I_Client, "%s The new !Color WELCOME MESSAGE !yAnd from %s !gCLAN !yis !Color:!g%s!.", CSZ_Prefix, (A_PlayerVars[I_Client][PI_CLAN_STATUS] >= STATUS_LEADER ? " tu" : "l"), SZ_Text);
			
			copy(A_ClanData[SZ_CLAN_WELCOME_MESSAGE], charsmax(A_ClanData[SZ_CLAN_WELCOME_MESSAGE]), SZ_Text);
			
			UpdateClanData(A_PlayerVars[I_Client][PI_CLAN_ID]);
		}
	}
	
	return PLUGIN_HANDLED_MAIN;
}

#if !defined M_HookTeamSay
public CLCOMMAND_ClanChat(const I_Client)
{
	if (!M_HaveClan(I_Client))
	{
		UTIL_SendPrint(I_Client, I_Client, "%s The !ColorCHAT !yAnd team color is exclusive to !gCLANES!.", CSZ_Prefix);
		
		return PLUGIN_HANDLED_MAIN;
	}
	
	UTIL_SendCMDWithHUD(I_Client, "messagemode MESSAGEMODE_ClanChat", "Write your message for the Clan", _, 0.0, 0.03, 3.0);
	
	return PLUGIN_HANDLED_MAIN;
}
#endif

/*============================================================================
			CALLBACKS DEL MÓDULO HAMSANDWICH
============================================================================*/

public HAM_PLAYER_Spawn_Post(const I_Player)
{
	if (!is_user_alive(I_Player))
		return;
	
	A_PlayerVars[I_Player][PBO_IS_ALIVE] = true;
}

public HAM_PLAYER_Killed_Post(const I_Player)
	A_PlayerVars[I_Player][PBO_IS_ALIVE] = false;

/*=========================================================================
			CALLBACKS DEL MÓDULO FAKEMETA
=========================================================================*/

public FM_ClientUserInfoChanged_Pre(const I_Client, const SZ_InfoBuffer[])
{
	if (!A_PlayerVars[I_Client][PBO_IS_CONNECTED])
		return FMRES_IGNORED;
	
	static SZ_NewName[32];
	
	get_user_info(I_Client, "name", SZ_NewName, charsmax(SZ_NewName));
	
	if (equal(SZ_NewName, A_PlayerVars[I_Client][PSZ_CLIENT_NAME]))
		return FMRES_IGNORED;
	
	UTIL_SendPrint(I_Client, I_Client, "%s Name change is not allowed", CSZ_Prefix);
	
	set_user_info(I_Client, "name", A_PlayerVars[I_Client][PSZ_CLIENT_NAME]);
	
	return FMRES_SUPERCEDE;
}

/*=======================================================================
			CALLBACKS DEL MÓDULO ENGINE
=======================================================================*/

public THINK_Timer(const I_Entity)
{
	static I_Player;
	
	for (I_Player = 1; I_Player <= A_GlobalVars[GI_MAX_PLAYERS]; I_Player++)
	{
		if (!A_PlayerVars[I_Player][PBO_IS_ALIVE] || !M_HaveClan(I_Player))
			continue;
		
		A_PlayerVars[I_Player][PI_CURRENT_TIMER]++;
	}
	
	entity_set_float(I_Entity, EV_FL_nextthink, M_TimerThinkTime);
}

/*=============================================================================
			MENUS Y SUS RESPECTIVOS CALLBACKS
=============================================================================*/

/*=====================================
		FUNCIONES
=====================================*/

SM_Clan(const I_Player, const I_Value = 0, const I_ShowType, const SZ_Text[] = EOS)
{
	new bool:BO_IsOnline, I_Menu, I_TotalMembers, I_OnLineMembers, I_OffLineMembers, I_FindMembers;
	static I, SZ_ChoosePlayerID[2], SZ_MemberName[32], SZ_MemberStatus[11];
	
	switch (I_ShowType)
	{
		case DONT_HAVE_CLAN:
		{
			formatex(A_GlobalVars[GSZ_TEXT], charsmax(A_GlobalVars[GSZ_TEXT]), "\r***********************************\y^n\y%s^n\yVERSION\w: \r%s \w| \yBY\w: \r%s^n***********************************^n\yYOU DO NOT BELONG TO ANY CLAN",
			CSZ_PluginInfo[PLUGIN_NAME], CSZ_PluginInfo[PLUGIN_VERSION], CSZ_PluginInfo[PLUGIN_AUTHOR]);
			
			I_Menu = menu_create(A_GlobalVars[GSZ_TEXT], "HM_Clan");
			
			menu_additem(I_Menu, "\yCREATE A CLAN\r.");
			
			menu_setprop(I_Menu, MPROP_EXITNAME, "\rGET OUT\y.");
		}
		
		case CONFIRM_CLAN_NAME:
		{
			formatex(A_GlobalVars[GSZ_TEXT], charsmax(A_GlobalVars[GSZ_TEXT]), "\w¿\yYOU WANT TO CREATE THE CALLED CLAN\w: \r%s\w?", A_PlayerVars[I_Player][PSZ_CLAN_NAME]);
			
			I_Menu = menu_create(A_GlobalVars[GSZ_TEXT], "HM_ConfirmClanName");
			
			menu_additem(I_Menu, "\ySI, CREATE CLAN\r.");
			
			menu_setprop(I_Menu, MPROP_EXITNAME, "\rDO NOT COME BACK\y.");
		}
		
		case HAVE_CLAN:
		{
			formatex(A_GlobalVars[GSZ_TEXT], charsmax(A_GlobalVars[GSZ_TEXT]), "\r***********************************\y^n\y%s^n\yVERSION\w: \r%s \w| \yBY\w: \r%s^n***********************************^n\r\R\w",
			CSZ_PluginInfo[PLUGIN_NAME], CSZ_PluginInfo[PLUGIN_VERSION], CSZ_PluginInfo[PLUGIN_AUTHOR]);
			
			I_Menu = menu_create(A_GlobalVars[GSZ_TEXT], "HM_Clan");
			
			menu_additem(I_Menu, "\yINVITE PLAYERS\r.");
			menu_additem(I_Menu, "\yLIST OF MEMBERS\r.");
			
			if (A_PlayerVars[I_Player][PI_CLAN_STATUS] >= STATUS_SUBLEADER)
				menu_additem(I_Menu, "\yEXPELL MEMBER\r.");
			else
				menu_additem(I_Menu, "\dEXPELL MEMBER\r.");
			
			if (A_PlayerVars[I_Player][PI_CLAN_STATUS] >= STATUS_COLEADER)
				menu_additem(I_Menu, "\yEDIT RANG\r.");
			else
				menu_additem(I_Menu, "\dEDIT RANG\r.");
			
			menu_additem(I_Menu, "\yCLAN INFORMATION\r.");
			
			if (A_PlayerVars[I_Player][PI_CLAN_STATUS] >= STATUS_COLEADER)
			{
				menu_additem(I_Menu, (A_ClanData[SZ_CLAN_TAG][0] ? "\yEDIT TAG" : "\yREGISTER A TAG"));
				menu_additem(I_Menu, (A_ClanData[SZ_CLAN_WELCOME_MESSAGE][0] ? "\yEDIT WELCOME MESSAGE" : "\yCREATE WELCOME MESSAGE"));
			}
			else
			{
				menu_additem(I_Menu, (A_ClanData[SZ_CLAN_TAG][0] ? "\dEDIT TAG" : "\dREGISTER A TAG"));
				menu_additem(I_Menu, (A_ClanData[SZ_CLAN_WELCOME_MESSAGE][0] ? "\dEDIT WELCOME MESSAGE" : "\dCREATE WELCOME MESSAGE"));
			}
			
			menu_additem(I_Menu, "\ySEE TOP OF CLANS \w- \rACTIVITY TIME.");
			menu_additem(I_Menu, "\ySEE TOP OF CLANS \w- \rNUMBER OF MEMBERS.");
			
			if (A_PlayerVars[I_Player][PI_CLAN_STATUS] >= STATUS_LEADER)
				menu_additem(I_Menu, "\yDESTROY CLAN\r.");
			else
				menu_additem(I_Menu, "\dDESTROY CLAN\r.");
			
			menu_setprop(I_Menu, MPROP_BACKNAME, "\y<<<\r.");
			menu_setprop(I_Menu, MPROP_NEXTNAME, "\y>>>\r.");
			menu_setprop(I_Menu, MPROP_EXITNAME, "\rGET OUT\y.");
		}
		
		case INVITE_PLAYERS_TO_CLAN:
		{
			I_Menu = menu_create("\yINVITE PLAYERS TO THE CLAN\w\R", "HM_InviteToClan");
			
			for (I = 1; I <= A_GlobalVars[GI_MAX_PLAYERS]; I++)
			{
				if (!IsAvailableToInvite(I_Player, I))
					continue;
				
				SZ_ChoosePlayerID[0] = I;
				
				menu_additem(I_Menu, A_PlayerVars[I][PSZ_CLIENT_NAME], SZ_ChoosePlayerID);
			}
			
			menu_setprop(I_Menu, MPROP_BACKNAME, "\y<<<\r.");
			menu_setprop(I_Menu, MPROP_NEXTNAME, "\y>>>\r.");
			menu_setprop(I_Menu, MPROP_EXITNAME, "\rGET OUT\y.");
		}
		
		case CONFIRM_INVITATION_TO_CLAN:
		{			
			GetClanData(A_PlayerVars[I_Value][PI_CLAN_ID]);
			
			formatex(A_GlobalVars[GSZ_TEXT], charsmax(A_GlobalVars[GSZ_TEXT]), "\yTHE PLAYER \r%s \yHE IS INVITING YOU TO JOIN HIS CLAN^n^n\yNAME\w: \r%s^n\yLEADER\w: \r%s^n\yNUMBER OF MEMBERS\w: \r%d^n^n\
			\w¿\rDO YOU WANT TO ACCEPT THE INVITATION\w?", A_PlayerVars[I_Value][PSZ_CLIENT_NAME], A_ClanData[SZ_CLAN_NAME], A_ClanData[SZ_CLAN_LEADER], A_ClanData[I_CLAN_MEMBERS]);
			
			I_Menu = menu_create(A_GlobalVars[GSZ_TEXT], "HM_ConfirmInvitation");
			
			SZ_ChoosePlayerID[0] = I_Value;
			
			menu_additem(I_Menu, "\ySI, ACCEPT INVITATION\r.", SZ_ChoosePlayerID[0]);
			
			menu_setprop(I_Menu, MPROP_EXITNAME, "\rNO, REFUSE INVITATION\y.");
		}
		
		case SHOW_CLAN_MEMBERS:
		{
			I_Menu = menu_create("\yCLAN MEMBERS\w\R", "HM_ClanMembers");
			
			GetClanData(A_PlayerVars[I_Player][PI_CLAN_ID]);
			
			for (I = STATUS_LEADER; I >= STATUS_MEMBER; I--)
			{
				I_TotalMembers = GetTotalClanMembersOfSameStatus(A_PlayerVars[I_Player][PI_CLAN_ID], I, I_OffLineMembers, I_OffLineMembers, A_ClanData[I_CLAN_MEMBERS]);
				I_FindMembers = 0;
				
				while (I_FindMembers++ < I_TotalMembers)
				{
					GetClanMembers(A_PlayerVars[I_Player][PI_CLAN_ID], I, SZ_MemberName, charsmax(SZ_MemberName), SZ_MemberStatus, charsmax(SZ_MemberStatus), BO_IsOnline, bool:(I_FindMembers == I_TotalMembers));
										
					formatex(A_GlobalVars[GSZ_TEXT], charsmax(A_GlobalVars[GSZ_TEXT]), "%s \y[\r%s\y] \w---> %s", SZ_MemberName, SZ_MemberStatus, (BO_IsOnline ? "\r[\yONLINE\r]" : "\y[\dOFFLINE\y]"));
				
					menu_additem(I_Menu, A_GlobalVars[GSZ_TEXT]);
				}
			}
			
			menu_setprop(I_Menu, MPROP_BACKNAME, "\y<<<\r.");
			menu_setprop(I_Menu, MPROP_NEXTNAME, "\y>>>\r.");
			menu_setprop(I_Menu, MPROP_EXITNAME, "\rGET OUT\y.");
		}
		
		case SHOW_KICK_MEMBERS:
		{
			I_Menu = menu_create("\yEXPELL CLAN MEMBER\w\R", "HM_KickMembers");
			
			GetClanData(A_PlayerVars[I_Player][PI_CLAN_ID]);
			
			for (I = STATUS_LEADER; I >= STATUS_MEMBER; I--)
			{
				I_TotalMembers = GetTotalClanMembersOfSameStatus(A_PlayerVars[I_Player][PI_CLAN_ID], I, I_OffLineMembers, I_OffLineMembers, A_ClanData[I_CLAN_MEMBERS]);
				I_FindMembers = 0;
				
				while (I_FindMembers++ < I_TotalMembers)
				{
					GetClanMembers(A_PlayerVars[I_Player][PI_CLAN_ID], I, SZ_MemberName, charsmax(SZ_MemberName), SZ_MemberStatus, charsmax(SZ_MemberStatus), BO_IsOnline, bool:(I_FindMembers == I_TotalMembers));
					
					formatex(A_GlobalVars[GSZ_TEXT], charsmax(A_GlobalVars[GSZ_TEXT]), "%s \y[\r%s\y] \w---> %s", SZ_MemberName, SZ_MemberStatus, (BO_IsOnline ? "\r[\yONLINE\r]" : "\y[\dOFFLINE\y]"));
				
					menu_additem(I_Menu, A_GlobalVars[GSZ_TEXT], SZ_MemberName);
				}
			}
			
			menu_setprop(I_Menu, MPROP_BACKNAME, "\y<<<\r.");
			menu_setprop(I_Menu, MPROP_NEXTNAME, "\y>>>\r.");
			menu_setprop(I_Menu, MPROP_EXITNAME, "\rGET OUT\y.");
		}
		
		case SHOW_EDIT_CLAN_MEMBERS_STATUS:
		{
			I_Menu = menu_create("\yEDIT CLAN MEMBER RANK\w\R", "HM_EditMemberStatus");
			
			GetClanData(A_PlayerVars[I_Player][PI_CLAN_ID]);
			
			for (I = STATUS_LEADER; I >= STATUS_MEMBER; I--)
			{
				I_TotalMembers = GetTotalClanMembersOfSameStatus(A_PlayerVars[I_Player][PI_CLAN_ID], I, I_OffLineMembers, I_OffLineMembers, A_ClanData[I_CLAN_MEMBERS]);
				I_FindMembers = 0;
				
				while (I_FindMembers++ < I_TotalMembers)
				{
					GetClanMembers(A_PlayerVars[I_Player][PI_CLAN_ID], I, SZ_MemberName, charsmax(SZ_MemberName), SZ_MemberStatus, charsmax(SZ_MemberStatus), BO_IsOnline, bool:(I_FindMembers == I_TotalMembers));
					
					formatex(A_GlobalVars[GSZ_TEXT], charsmax(A_GlobalVars[GSZ_TEXT]), "%s \y[\r%s\y] \w---> %s", SZ_MemberName, SZ_MemberStatus, (BO_IsOnline ? "\r[\yONLINE\r]" : "\y[\dOFFLINE\y]"));
				
					menu_additem(I_Menu, A_GlobalVars[GSZ_TEXT], SZ_MemberName);
				}
			}
			
			menu_setprop(I_Menu, MPROP_BACKNAME, "\y<<<\r.");
			menu_setprop(I_Menu, MPROP_NEXTNAME, "\y>>>\r.");
			menu_setprop(I_Menu, MPROP_EXITNAME, "\rGET OUT\y.");
		}
		
		case SHOW_CLAN_INFO:
		{
			new I_Hours, I_Minutes, I_Seconds;
			
			static SZ_ActivityTime[100];
			
			GetClanActivityTime((I_Value < 0 ? A_PlayerVars[I_Player][PI_CLAN_ID] : I_Value), I_Hours, I_Minutes, I_Seconds);
						
			I_TotalMembers = GetTotalClanMembersOfSameStatus((I_Value < 0 ? A_PlayerVars[I_Player][PI_CLAN_ID] : I_Value), SEARCH_ALL_STATUS, I_OnLineMembers, I_OffLineMembers, A_ClanData[I_CLAN_MEMBERS]);
			
			if (!I_OnLineMembers)
				formatex(A_GlobalVars[GSZ_TEXT], charsmax(A_GlobalVars[GSZ_TEXT]), "^t^t^t^t^t\r•  \y%d (\rOFF-LINE\y)", I_OffLineMembers);
			else
			{
				if (!I_OffLineMembers)
					formatex(A_GlobalVars[GSZ_TEXT], charsmax(A_GlobalVars[GSZ_TEXT]), "^t^t^t^t^t\r•  \y%d (\rON-LINE\y)", I_OnLineMembers);
				else
					formatex(A_GlobalVars[GSZ_TEXT], charsmax(A_GlobalVars[GSZ_TEXT]), "^t^t^t^t^t\r•  \y%d (\rON-LINE\y)^n^t^t^t^t^t\r•  \y%d (\rOFF-LINE\y)", I_OnLineMembers, I_OffLineMembers);
			}
			
			SZ_ActivityTime[0] = EOS;
			
			if (I_Hours <= 0 && I_Minutes <= 0 && I_Seconds <= 0)
				formatex(SZ_ActivityTime, charsmax(SZ_ActivityTime), "\rNO RECORDS YET");
			else
			{
				if (I_Hours)
					formatex(SZ_ActivityTime, charsmax(SZ_ActivityTime), "\r%d \yH%s", I_Hours, (I_Minutes || I_Seconds ? " \w| " : ""));
				
				if (I_Minutes)
					format(SZ_ActivityTime, charsmax(SZ_ActivityTime), "%s\r%d \yM%s", SZ_ActivityTime, I_Minutes, (I_Seconds ? " \w| " : ""));
				
				if (I_Seconds)
					format(SZ_ActivityTime, charsmax(SZ_ActivityTime), "%s\r%d \yS", SZ_ActivityTime, I_Seconds);
				
				add(SZ_ActivityTime, charsmax(SZ_ActivityTime), " OF GAME");
			}
				
			
			if (!A_ClanData[SZ_CLAN_TAG][0])
			{
				format(A_GlobalVars[GSZ_TEXT], charsmax(A_GlobalVars[GSZ_TEXT]), "\yINFORMACIÓN DEL CLAN^n^n\yNOMBRE\w: \r%s^n\yNº DE MIEMBROS\w: \r%d ^n%s^n\yLÍDER\w: \r%s^n\yTAG\w: \rSIN TAG^n\yTIEMPO DE ACTIVIDAD\w: %s^n",
				A_ClanData[SZ_CLAN_NAME], A_ClanData[I_CLAN_MEMBERS], A_GlobalVars[GSZ_TEXT], A_ClanData[SZ_CLAN_LEADER], SZ_ActivityTime);
			}
			else
			{
				format(A_GlobalVars[GSZ_TEXT], charsmax(A_GlobalVars[GSZ_TEXT]), "\yINFORMACIÓN DEL CLAN^n^n\yNOMBRE\w: \r%s^n\yNº DE MIEMBROS\w: \r%d^n%s^n\yLÍDER\w: \r%s^n\yTAG\w: \r%s^n\yTIEMPO DE ACTIVIDAD\w: %s^n",
				A_ClanData[SZ_CLAN_NAME], A_ClanData[I_CLAN_MEMBERS], A_GlobalVars[GSZ_TEXT], A_ClanData[SZ_CLAN_LEADER], A_ClanData[SZ_CLAN_TAG], SZ_ActivityTime);
			}
			
			I_Menu = menu_create(A_GlobalVars[GSZ_TEXT], "HM_ClanInfo");
			
			menu_additem(I_Menu, "\rVOLVER\y.", "1");
			
			menu_setprop(I_Menu, MPROP_EXIT, MEXIT_NEVER);
		}
		
		case CHOOSE_STATUS_TO_CLAN_MEMBER:
		{
			I_Menu = menu_create("\yELIGE UN NUEVO RANGO PARA ESTE MIEMBRO", "HM_ChooseStatusToMember");
			
			for (I = 0; I < charsmax(CSZ_ClanMemberStatus); I++)
			{
				formatex(A_GlobalVars[GSZ_TEXT], charsmax(A_GlobalVars[GSZ_TEXT]), "\r%s", CSZ_ClanMemberStatus[I]);
				
				menu_additem(I_Menu, A_GlobalVars[GSZ_TEXT], SZ_Text);
			}
			
			menu_setprop(I_Menu, MPROP_EXITNAME, "\rVOLVER\y.");
		}
		
		case CONFIRM_CLAN_MEMBER_STATUS:
		{
			I_OnLineMembers = GetMemberRealID(SZ_Text);
			
			if (I_OnLineMembers)
			{
				formatex(A_GlobalVars[GSZ_TEXT], charsmax(A_GlobalVars[GSZ_TEXT]), "\w¿\yESTAS SEGURO DE QUERER EDITAR EL RALGO DE\w: \r%s\w?^n^n\
				\yRANGO ACTUAL\w: \r%s^n\yRANGO ELEGIDO\w: \r%s", A_PlayerVars[I_OnLineMembers][PSZ_CLIENT_NAME], CSZ_ClanMemberStatus[A_PlayerVars[I_OnLineMembers][PI_CLAN_STATUS]],
				CSZ_ClanMemberStatus[A_PlayerVars[I_Player][PI_CHOOSE_STATUS_FOR_MEMBER]]);
			}
			else
			{
				static SZ_Data[10], SZ_Status[2];
				
				fvault_get_data(CSZ_PlayersVault, SZ_Text, SZ_Data, charsmax(SZ_Data));
				
				parse(SZ_Data, 0, 0, SZ_Status, charsmax(SZ_Status));
				
				I_OnLineMembers = str_to_num(SZ_Status);
				
				formatex(A_GlobalVars[GSZ_TEXT], charsmax(A_GlobalVars[GSZ_TEXT]), "\w¿\yESTAS SEGURO DE QUERER EDITAR EL RALGO DE\w: \r%s\w?^n^n\
				\yRANGO ACTUAL\w: \r%s^n\yRANGO ELEGIDO\w: \r%s", SZ_Text, CSZ_ClanMemberStatus[I_OnLineMembers],
				CSZ_ClanMemberStatus[A_PlayerVars[I_Player][PI_CHOOSE_STATUS_FOR_MEMBER]]);
			}
			
			I_Menu = menu_create(A_GlobalVars[GSZ_TEXT], "HM_ConfirmMemberStatus");
			
			menu_additem(I_Menu, "\ySI, EDITAR RANGO\r.", SZ_Text);
			
			menu_setprop(I_Menu, MPROP_EXITNAME, "\rNO, VOLVER\y.");
		}
		
		case SHOW_CLANES_TOP_ONE:
		{
			I_Menu = menu_create("\yTOP DE CLANES (\rDESC\y) \w- \rTIEMPO DE ACTIVIDAD\w\R", "HM_ClanesTop");
			
			new I_BestClan;
			static I_MaxClanes;
			
			I_MaxClanes = ArraySize(A_GlobalVars[GDA_CLANES]);
			
			if (I_MaxClanes > CI_MaxClanesOnTop)
				I_MaxClanes = CI_MaxClanesOnTop;
			
			for (I = 0; I < I_MaxClanes; I++)
			{
				I_BestClan = GetBestClan(SORT_BY_ACTIVITY_TIME, SORT_DOWNWARDS, bool:(I == (I_MaxClanes - 1)));
								
				formatex(A_GlobalVars[GSZ_TEXT], charsmax(A_GlobalVars[GSZ_TEXT]), "\r%s", A_ClanData[SZ_CLAN_NAME]);
				
				SZ_ChoosePlayerID[0] = I_BestClan;
				
				menu_additem(I_Menu, A_GlobalVars[GSZ_TEXT], SZ_ChoosePlayerID);
			}
			
			menu_setprop(I_Menu, MPROP_BACKNAME, "\y<<<\r.");
			menu_setprop(I_Menu, MPROP_NEXTNAME, "\y>>>\r.");
			menu_setprop(I_Menu, MPROP_EXITNAME, "\rSALIR\y.");
		}
		
		case SHOW_CLANES_TOP_TWO:
		{
			I_Menu = menu_create("\yTOP DE CLANES (\rASC\y) \w- \rCANTIDAD DE MIEMBROS\w\R", "HM_ClanesTop");
			
			new I_BestClan;
			static I_MaxClanes;
			
			I_MaxClanes = ArraySize(A_GlobalVars[GDA_CLANES]);
			
			if (I_MaxClanes > CI_MaxClanesOnTop)
				I_MaxClanes = CI_MaxClanesOnTop;
			
			for (I = 0; I < I_MaxClanes; I++)
			{				
				I_BestClan = GetBestClan(SORT_BY_CLAN_MEMBERS, SORT_UPWARDS, bool:(I == (I_MaxClanes - 1)));
								
				formatex(A_GlobalVars[GSZ_TEXT], charsmax(A_GlobalVars[GSZ_TEXT]), "\r%s", A_ClanData[SZ_CLAN_NAME]);
				
				SZ_ChoosePlayerID[0] = I_BestClan;
				
				menu_additem(I_Menu, A_GlobalVars[GSZ_TEXT], SZ_ChoosePlayerID);
			}
			
			menu_setprop(I_Menu, MPROP_BACKNAME, "\y<<<\r.");
			menu_setprop(I_Menu, MPROP_NEXTNAME, "\y>>>\r.");
			menu_setprop(I_Menu, MPROP_EXITNAME, "\rSALIR\y.");
		}
	}
	
	menu_display(I_Player, I_Menu);
}

/*=====================================
		CALLBACKS
=====================================*/

public HM_Clan(const I_Player, const I_Menu, const I_Item)
{
	if (I_Item == MENU_EXIT)
	{
		menu_destroy(I_Menu);
		
		return;
	}
	
	switch (I_Item)
	{
		case 0:
		{
			if (M_HaveClan(I_Player))
			{
				new I_Hours, I_Minutes, I_Seconds;
				
				if (GetClanActivityTime(A_PlayerVars[I_Player][PI_CLAN_ID], I_Hours, I_Minutes, I_Seconds, true) > A_ClanData[I_CLAN_ACTIVITY_TIME])
				{
					A_GlobalVars[GSZ_TEXT][0] = EOS;
					
					if (I_Hours)
						formatex(A_GlobalVars[GSZ_TEXT], charsmax(A_GlobalVars[GSZ_TEXT]), "!color%d !yhora%s%s", I_Hours, (I_Hours > 1 ? "s" : ""), (I_Minutes || I_Seconds ? " !g| " : ""));
					
					if (I_Minutes)
						format(A_GlobalVars[GSZ_TEXT], charsmax(A_GlobalVars[GSZ_TEXT]), "%s!color%d !yminuto%s%s", A_GlobalVars[GSZ_TEXT], I_Minutes, (I_Minutes > 1 ? "s" : ""), (I_Seconds ? " !g| " : ""));
					
					if (I_Seconds)
						format(A_GlobalVars[GSZ_TEXT], charsmax(A_GlobalVars[GSZ_TEXT]), "%s!color%d !ysegundo%s", A_GlobalVars[GSZ_TEXT], I_Seconds, (I_Seconds > 1 ? "s" : ""));
					
					add(A_GlobalVars[GSZ_TEXT], charsmax(A_GlobalVars[GSZ_TEXT]), " de juego");
					
					UTIL_SendPrint(I_Player, I_Player, "%s Para invitar a otro jugador, %s !gCLAN!y necesita acumular!color:!g!.", CSZ_Prefix, (A_PlayerVars[I_Player][PI_CLAN_STATUS] >= STATUS_LEADER ? "tu" : "el"));
					UTIL_SendPrint(I_Player, I_Player, "%s %s!g!.", CSZ_Prefix, A_GlobalVars[GSZ_TEXT]);
				}
				else
					SM_Clan(I_Player, _, INVITE_PLAYERS_TO_CLAN);
			}
			else
			{
				A_PlayerVars[I_Player][PI_STATUS] = CREATE_NEW_CLAN;
				
				UTIL_SendCMDWithHUD(I_Player, "messagemode MESSAGEMODE_Clanes", "Ingresa un nombre para tu clan!", _, 0.0, 0.03, 3.0);
			}
		}
		
		case 1:
		{
			if (M_HaveClan(I_Player))
				SM_Clan(I_Player, _, SHOW_CLAN_MEMBERS);
		}
		
		case 2:
		{
			if (M_HaveClan(I_Player))
			{
				if (A_PlayerVars[I_Player][PI_CLAN_STATUS] >= STATUS_SUBLEADER)
					SM_Clan(I_Player, _, SHOW_KICK_MEMBERS);
				else
				{
					UTIL_SendPrint(I_Player, I_Player, "%s No tienes acceso suficiente, necesitas ser al menos un!color: %s!g!.", CSZ_Prefix, CSZ_ClanMemberStatus[STATUS_SUBLEADER]);
					
					SM_Clan(I_Player, _, (M_HaveClan(I_Player) ? HAVE_CLAN : DONT_HAVE_CLAN));
				}
			}
		}
		
		case 3:
		{
			if (M_HaveClan(I_Player))
			{
				if (A_PlayerVars[I_Player][PI_CLAN_STATUS] >= STATUS_COLEADER)
					SM_Clan(I_Player, _, SHOW_EDIT_CLAN_MEMBERS_STATUS);
				else
				{
					UTIL_SendPrint(I_Player, I_Player, "%s No tienes acceso suficiente, necesitasr ser al menos un!color: %s!g!.", CSZ_Prefix, CSZ_ClanMemberStatus[STATUS_COLEADER]);
					
					SM_Clan(I_Player, _, (M_HaveClan(I_Player) ? HAVE_CLAN : DONT_HAVE_CLAN));
				}
			}
		}
		
		case 4:
		{
			if (M_HaveClan(I_Player))
				SM_Clan(I_Player, -1, SHOW_CLAN_INFO);
		}
		
		case 5:
		{
			if (M_HaveClan(I_Player))
			{
				if (A_PlayerVars[I_Player][PI_CLAN_STATUS] >= STATUS_COLEADER)
				{
					if (A_PlayerVars[I_Player][PI_CLAN_STATUS] >= STATUS_LEADER)
						UTIL_SendCMDWithHUD(I_Player, "messagemode MESSAGEMODE_Clanes", "Crea y/o edita un TAG para identificar a tu clan!", { 255, 255, 0}, 0.0, 0.03, 3.0);
					else
						UTIL_SendCMDWithHUD(I_Player, "messagemode MESSAGEMODE_Clanes", "Crea y/o edita un TAG para identificar a el clan!", { 255, 255, 0}, 0.0, 0.03, 3.0);
					
					A_PlayerVars[I_Player][PI_STATUS] = CHANGE_CLAN_TAG;
				}
				else
				{
					UTIL_SendPrint(I_Player, I_Player, "%s No tienes acceso suficiente, necesitas ser al menos un!color: %s!g!.", CSZ_Prefix, CSZ_ClanMemberStatus[STATUS_COLEADER]);
					
					SM_Clan(I_Player, _, (M_HaveClan(I_Player) ? HAVE_CLAN : DONT_HAVE_CLAN));
				}
			}
		}
		
		case 6:
		{
			if (M_HaveClan(I_Player))
			{
				if (A_PlayerVars[I_Player][PI_CLAN_STATUS] >= STATUS_COLEADER)
				{
					UTIL_SendCMDWithHUD(I_Player, "messagemode MESSAGEMODE_Clanes", "Crea y/o edita un mensaje de bienvenida^npara los futuros miembros del clan!", { 0, 255, 0}, 0.0, 0.03, 3.0);
					
					A_PlayerVars[I_Player][PI_STATUS] = CHANGE_CLAN_WELCOME_MESSAGE;
				}
				else
				{
					UTIL_SendPrint(I_Player, I_Player, "%s No tienes acceso suficiente, necesitasr ser al menos un!color: %s!g!.", CSZ_Prefix, CSZ_ClanMemberStatus[STATUS_COLEADER]);
					
					SM_Clan(I_Player, _, (M_HaveClan(I_Player) ? HAVE_CLAN : DONT_HAVE_CLAN));
				}
			}
		}
		case 7:
		{
			if (M_HaveClan(I_Player))
				SM_Clan(I_Player, _, SHOW_CLANES_TOP_ONE);
		}
		case 8:
		{
			if (M_HaveClan(I_Player))
				SM_Clan(I_Player, _, SHOW_CLANES_TOP_TWO);
		}
		case 9:
		{
			if (M_HaveClan(I_Player))
			{
				if (A_PlayerVars[I_Player][PI_CLAN_STATUS] >= STATUS_LEADER)
				{
					GetClanData(A_PlayerVars[I_Player][PI_CLAN_ID]);
						
					TrieDeleteKey(A_GlobalVars[GT_CLANES_NAMES], A_ClanData[SZ_CLAN_NAME]);
					TrieDeleteKey(A_GlobalVars[GT_CLANES_TAGS], A_ClanData[SZ_CLAN_TAG]);
						
					DestroyClan(I_Player, A_PlayerVars[I_Player][PI_CLAN_ID]);
						
					ArrayDeleteItem(A_GlobalVars[GDA_CLANES], A_PlayerVars[I_Player][PI_CLAN_ID]);
						
					ChangeAllClanIDs(A_PlayerVars[I_Player][PI_CLAN_ID]);
						
					A_PlayerVars[I_Player][PI_CLAN_ID] = -1;
					A_PlayerVars[I_Player][PI_CLAN_STATUS] = A_PlayerVars[I_Player][PI_CURRENT_TIMER] = STATUS_MEMBER;
						
					UTIL_SendPrint(I_Player, I_Player, "%s Acabas de !colorDESTRUIR!y tu !gCLAN!.", CSZ_Prefix);
				}
			}
		}	
	}
}

public HM_ConfirmClanName(const I_Player, const I_Menu, const I_Item)
{
	if (I_Item == MENU_EXIT)
	{
		SM_Clan(I_Player, _, (M_HaveClan(I_Player) ? HAVE_CLAN : DONT_HAVE_CLAN));
		
		menu_destroy(I_Menu);
		
		return;
	}
	
	copy(A_ClanData[SZ_CLAN_NAME], charsmax(A_ClanData[SZ_CLAN_NAME]), A_PlayerVars[I_Player][PSZ_CLAN_NAME]);
	copy(A_ClanData[SZ_CLAN_LEADER], charsmax(A_ClanData[SZ_CLAN_LEADER]), A_PlayerVars[I_Player][PSZ_CLIENT_NAME]);
	
	A_ClanData[SZ_CLAN_TAG][0] = A_ClanData[SZ_CLAN_WELCOME_MESSAGE][0] = EOS;
	A_ClanData[I_CLAN_MEMBERS] = 1;
	A_ClanData[I_CLAN_ID] = A_PlayerVars[I_Player][PI_CLAN_ID] = ArraySize(A_GlobalVars[GDA_CLANES]);
	A_PlayerVars[I_Player][PI_CLAN_STATUS] = STATUS_LEADER;
	
	ArrayPushArray(A_GlobalVars[GDA_CLANES], A_ClanData);
	
	UTIL_SendPrint(I_Player, I_Player, "%s Creaste el !gCLAN!color: %s!y con éxito!g!.", CSZ_Prefix, A_ClanData[SZ_CLAN_NAME]);
	UTIL_SendPrint(0, random_num(CHAT_COLOR_RED, CHAT_COLOR_BLUE), "%s Un nuevo !gCLAN!y ha surgido, su nombre es!color: %s!g!.", CSZ_Prefix, A_ClanData[SZ_CLAN_NAME]);
}

public HM_InviteToClan(const I_Player, const I_Menu, const I_Item)
{
	if (I_Item == MENU_EXIT)
	{
		SM_Clan(I_Player, _, (M_HaveClan(I_Player) ? HAVE_CLAN : DONT_HAVE_CLAN));
		
		menu_destroy(I_Menu);
		
		return;
	}
	
	static I_Temporal, SZ_ChoosePlayerID[2];
	
	menu_item_getinfo(I_Menu, I_Item, I_Temporal, SZ_ChoosePlayerID, charsmax(SZ_ChoosePlayerID), _, _, I_Temporal);
	
	SM_Clan(SZ_ChoosePlayerID[0], I_Player, CONFIRM_INVITATION_TO_CLAN);
}

public HM_ConfirmInvitation(const I_Player, const I_Menu, const I_Item)
{
	if (I_Item == MENU_EXIT)
	{
		menu_destroy(I_Menu);
		
		return;
	}
	
	static I_Temporal, SZ_InviterPlayerID[2];
	
	menu_item_getinfo(I_Menu, I_Item, I_Temporal, SZ_InviterPlayerID, charsmax(SZ_InviterPlayerID), _, _, I_Temporal);
	
	GetClanData(A_PlayerVars[SZ_InviterPlayerID[0]][PI_CLAN_ID]);
	
	A_ClanData[I_CLAN_MEMBERS]++;
	
	A_PlayerVars[I_Player][PI_CLAN_ID] = A_ClanData[I_CLAN_ID];
	A_PlayerVars[I_Player][PI_CLAN_STATUS] = STATUS_MEMBER;
	
	UpdateClanData(A_ClanData[I_CLAN_ID]);
	
	if (A_ClanData[SZ_CLAN_WELCOME_MESSAGE][0])
		UTIL_SendPrint(I_Player, I_Player, "%s !color%s!y %s", CSZ_Prefix, A_ClanData[SZ_CLAN_WELCOME_MESSAGE], A_PlayerVars[I_Player][PSZ_CLIENT_NAME]);
	else
		UTIL_SendPrint(I_Player, I_Player, "%s Ahora formas parte del !gCLAN!color: %s!y, bienvenido!g!.", CSZ_Prefix, A_ClanData[SZ_CLAN_NAME]);
	
	UTIL_SendPrint(SZ_InviterPlayerID[0], SZ_InviterPlayerID[0], "%s !color%s!y acepto tu invitación al !gCLAN!.", CSZ_Prefix, A_PlayerVars[I_Player][PSZ_CLIENT_NAME]);
	
	formatex(A_GlobalVars[GSZ_TEXT], charsmax(A_GlobalVars[GSZ_TEXT]), "%s %!color%s!y se ha unido al !gCLAN!g.", CSZ_Prefix, A_PlayerVars[I_Player][PSZ_CLIENT_NAME]);
	
	SendMessageToMembers(I_Player, A_GlobalVars[GSZ_TEXT]);
}

public HM_ClanMembers(const I_Player, const I_Menu, const I_Item)
{
	if (I_Item == MENU_EXIT)
	{
		menu_destroy(I_Menu);
		
		SM_Clan(I_Player, _, (M_HaveClan(I_Player) ? HAVE_CLAN : DONT_HAVE_CLAN));
		
		return;
	}
	
	SM_Clan(I_Player, _, SHOW_CLAN_MEMBERS);
}

public HM_ClanInfo(const I_Player, const I_Menu, const I_Item)
{
	if (!I_Item)
	{
		menu_destroy(I_Menu);
		
		SM_Clan(I_Player, _, (M_HaveClan(I_Player) ? HAVE_CLAN : DONT_HAVE_CLAN));
	}
}

public HM_KickMembers(const I_Player, const I_Menu, const I_Item)
{
	if (I_Item == MENU_EXIT)
	{
		SM_Clan(I_Player, _, (M_HaveClan(I_Player) ? HAVE_CLAN : DONT_HAVE_CLAN));
		
		menu_destroy(I_Menu);
		
		return;
	}
	
	new I_MemberPlayerID;
	static SZ_MemberName[32];
	
	menu_item_getinfo(I_Menu, I_Item, I_MemberPlayerID, SZ_MemberName, charsmax(SZ_MemberName), _, _, I_MemberPlayerID);
	
	I_MemberPlayerID = GetMemberRealID(SZ_MemberName);
	
	if (I_MemberPlayerID)
	{
		if (I_Player != I_MemberPlayerID && A_PlayerVars[I_MemberPlayerID][PI_CLAN_STATUS] >= A_PlayerVars[I_Player][PI_CLAN_STATUS])
		{
			UTIL_SendPrint(I_Player, I_Player, "%s No puedes kickear a !color%s!y del !gCLAN!y por que es %s!color%s!y%s!g!.", CSZ_Prefix,
			A_PlayerVars[I_MemberPlayerID][PSZ_CLIENT_NAME], (A_PlayerVars[I_MemberPlayerID][PI_CLAN_STATUS] >= STATUS_LEADER ? "el " : ""),
			CSZ_ClanMemberStatus[A_PlayerVars[I_MemberPlayerID][PI_CLAN_STATUS]],
			(A_PlayerVars[I_Player][PI_CLAN_STATUS] == A_PlayerVars[I_MemberPlayerID][PI_CLAN_STATUS] ? " al igual que tú" : ""));
			
			SM_Clan(I_Player, _, (M_HaveClan(I_Player) ? SHOW_KICK_MEMBERS : DONT_HAVE_CLAN));
			
			return;
		}
		else if (I_Player == I_MemberPlayerID)
		{
			UTIL_SendPrint(I_Player, I_Player, "%s No puedes kickearte a ti mismo del !gCLAN!.", CSZ_Prefix);
			
			SM_Clan(I_Player, _, (M_HaveClan(I_Player) ? SHOW_KICK_MEMBERS : DONT_HAVE_CLAN));
			
			return;
		}
		
		A_PlayerVars[I_MemberPlayerID][PI_CLAN_ID] = -1;
		A_PlayerVars[I_MemberPlayerID][PI_CLAN_STATUS] = STATUS_MEMBER;
		
		if (A_PlayerVars[I_Player][PI_CLAN_STATUS] >= STATUS_LEADER)
		{
			UTIL_SendPrint(I_MemberPlayerID, I_MemberPlayerID, "%s El !g%s!color %s!y te acaba de kickear de su !gCLAN!.", CSZ_Prefix,
			CSZ_ClanMemberStatus[A_PlayerVars[I_Player][PI_CLAN_STATUS]], A_PlayerVars[I_Player][PSZ_CLIENT_NAME]);
			
			UTIL_SendPrint(I_Player, I_Player, "%s Acabas de kickear a !color%s!y de tu !gCLAN!.", CSZ_Prefix, A_PlayerVars[I_MemberPlayerID][PSZ_CLIENT_NAME])
		}
		else
		{
			UTIL_SendPrint(I_MemberPlayerID, I_MemberPlayerID, "%s El !g%s!color %s!y te acaba de kickear del su !gCLAN!.", CSZ_Prefix,
			CSZ_ClanMemberStatus[A_PlayerVars[I_Player][PI_CLAN_STATUS]], A_PlayerVars[I_Player][PSZ_CLIENT_NAME]);
			
			UTIL_SendPrint(I_Player, I_Player, "%s Acabas de kickear a !color%s!y del !gCLAN!.", CSZ_Prefix, A_PlayerVars[I_MemberPlayerID][PSZ_CLIENT_NAME]);
		}
	}
	else
	{
		new I_Status;
		static SZ_Data[10], SZ_Status[2];
		
		fvault_get_data(CSZ_PlayersVault, SZ_MemberName, SZ_Data, charsmax(SZ_Data));

		parse(SZ_Data, 0, 0, SZ_Status, charsmax(SZ_Status));
		
		I_Status = str_to_num(SZ_Status);
		
		if (I_Status >= A_PlayerVars[I_Player][PI_CLAN_STATUS])
		{
			UTIL_SendPrint(I_Player, I_Player, "%s No puedes kickear a !color%s!y por que es %s!color%s!y%s!g!.", CSZ_Prefix, SZ_MemberName,
			(I_Status >= STATUS_LEADER ? "el " : ""), CSZ_ClanMemberStatus[I_Status], (I_Status == A_PlayerVars[I_Player][PI_CLAN_STATUS] ? " al igual que tú" : ""));
			
			SM_Clan(I_Player, _, (M_HaveClan(I_Player) ? SHOW_KICK_MEMBERS : DONT_HAVE_CLAN));
			
			return;
		}
		
		formatex(SZ_Data, charsmax(SZ_Data), "-1 0");
		
		fvault_set_data(CSZ_PlayersVault, SZ_MemberName, SZ_Data);
		
		UTIL_SendPrint(I_Player, I_Player, "%s Acabas de kickear a !color%s!y de%s !gCLAN!.", CSZ_Prefix, SZ_MemberName, (A_PlayerVars[I_Player][PI_CLAN_STATUS] >= STATUS_LEADER ? " tu" : "l"));
	}	
	
	GetClanData(A_PlayerVars[I_Player][PI_CLAN_ID]);
	
	A_ClanData[I_CLAN_MEMBERS]--;
	
	UpdateClanData(A_PlayerVars[I_Player][PI_CLAN_ID]);
	
	SM_Clan(I_Player, _, (M_HaveClan(I_Player) ? SHOW_KICK_MEMBERS : DONT_HAVE_CLAN));
}

public HM_EditMemberStatus(const I_Player, const I_Menu, const I_Item)
{
	if (I_Item == MENU_EXIT)
	{
		SM_Clan(I_Player, _, (M_HaveClan(I_Player) ? HAVE_CLAN : DONT_HAVE_CLAN));
		
		menu_destroy(I_Menu);
		
		return;
	}
	
	new I_MemberPlayerID;
	static SZ_MemberName[32];
	
	menu_item_getinfo(I_Menu, I_Item, I_MemberPlayerID, SZ_MemberName, charsmax(SZ_MemberName), _, _, I_MemberPlayerID);
	
	I_MemberPlayerID = GetMemberRealID(SZ_MemberName);
	
	if (I_MemberPlayerID)
	{
		if (I_MemberPlayerID != I_Player && A_PlayerVars[I_MemberPlayerID][PI_CLAN_STATUS] >= A_PlayerVars[I_Player][PI_CLAN_STATUS])
		{
			UTIL_SendPrint(I_Player, I_Player, "%s No puedes editar el rango de !color%s!y por que es %s!color%s!y%s!g!.", CSZ_Prefix,
			A_PlayerVars[I_MemberPlayerID][PSZ_CLIENT_NAME], (A_PlayerVars[I_MemberPlayerID][PI_CLAN_STATUS] >= STATUS_LEADER ? "el " : ""),
			CSZ_ClanMemberStatus[A_PlayerVars[I_MemberPlayerID][PI_CLAN_STATUS]],
			(A_PlayerVars[I_MemberPlayerID][PI_CLAN_STATUS] == A_PlayerVars[I_Player][PI_CLAN_STATUS] ? " al igual que tú" : ""));
				
			SM_Clan(I_Player, _, (M_HaveClan(I_Player) ? SHOW_EDIT_CLAN_MEMBERS_STATUS : DONT_HAVE_CLAN));
			
			return;
		}
		else if (I_MemberPlayerID == I_Player)
		{
			UTIL_SendPrint(I_Player, I_Player, "%s No puedes cambiarte tu propio rango!g!.", CSZ_Prefix);
			
			SM_Clan(I_Player, _, (M_HaveClan(I_Player) ? SHOW_EDIT_CLAN_MEMBERS_STATUS : DONT_HAVE_CLAN));
			
			return;
		}
		else
			SM_Clan(I_Player, _, CHOOSE_STATUS_TO_CLAN_MEMBER, A_PlayerVars[I_MemberPlayerID][PSZ_CLIENT_NAME]);
	}
	else
	{
		new I_Status;
		static SZ_Data[10], SZ_Status[2];
		
		fvault_get_data(CSZ_PlayersVault, SZ_MemberName, SZ_Data, charsmax(SZ_Data));
		
		parse(SZ_Data, 0, 0, SZ_Status, charsmax(SZ_Status));
		
		I_Status = str_to_num(SZ_Status);
		
		if (I_Status >= A_PlayerVars[I_Player][PI_CLAN_STATUS])
		{
			UTIL_SendPrint(I_Player, I_Player, "%s No puedes editar el rango de !color%s!y por que es %s!color%s!y%s!g!.", CSZ_Prefix, SZ_MemberName,
			(I_Status >= STATUS_LEADER ? "el " : ""), CSZ_ClanMemberStatus[I_Status], (I_Status == A_PlayerVars[I_Player][PI_CLAN_STATUS] ? " al igual que tú" : ""));
			
			SM_Clan(I_Player, _, (M_HaveClan(I_Player) ? SHOW_EDIT_CLAN_MEMBERS_STATUS : DONT_HAVE_CLAN));
			
			return;
		}
		
		SM_Clan(I_Player, _, CHOOSE_STATUS_TO_CLAN_MEMBER, SZ_MemberName);
	}
}

public HM_ChooseStatusToMember(const I_Player, const I_Menu, const I_Item)
{
	if (I_Item == MENU_EXIT)
	{
		SM_Clan(I_Player, _, (M_HaveClan(I_Player) ? SHOW_EDIT_CLAN_MEMBERS_STATUS : DONT_HAVE_CLAN));
		
		menu_destroy(I_Menu);
		
		return;
	}
	
	new I_Temporal;
	static SZ_MemberName[32];
	
	menu_item_getinfo(I_Menu, I_Item, I_Temporal, SZ_MemberName, charsmax(SZ_MemberName), _, _, I_Temporal);
	
	if (A_PlayerVars[I_Player][PI_CLAN_STATUS] < STATUS_LEADER && I_Item == STATUS_COLEADER)
	{
		UTIL_SendPrint(I_Player, I_Player, "%s No puedes elegir un rango igual al tuyo!g!.", CSZ_Prefix);
		
		SM_Clan(I_Player, _, (M_HaveClan(I_Player) ? CHOOSE_STATUS_TO_CLAN_MEMBER : DONT_HAVE_CLAN), SZ_MemberName);
		
		return;
	}
	
	A_PlayerVars[I_Player][PI_CHOOSE_STATUS_FOR_MEMBER] = I_Item;
	
	SM_Clan(I_Player, _, CONFIRM_CLAN_MEMBER_STATUS, SZ_MemberName);
}

public HM_ConfirmMemberStatus(const I_Player, const I_Menu, const I_Item)
{
	if (I_Item == MENU_EXIT)
	{
		SM_Clan(I_Player, _, (M_HaveClan(I_Player) ? SHOW_EDIT_CLAN_MEMBERS_STATUS : DONT_HAVE_CLAN));
		
		menu_destroy(I_Menu);
		
		return;
	}
	
	new I_MemberPlayerID;
	static SZ_MemberName[32];
	
	menu_item_getinfo(I_Menu, I_Item, I_MemberPlayerID, SZ_MemberName, charsmax(SZ_MemberName), _, _, I_MemberPlayerID);
	
	I_MemberPlayerID = GetMemberRealID(SZ_MemberName);
	
	if (I_MemberPlayerID)
	{
		if (A_PlayerVars[I_MemberPlayerID][PI_CLAN_STATUS] == A_PlayerVars[I_Player][PI_CHOOSE_STATUS_FOR_MEMBER])
		{
			UTIL_SendPrint(I_Player, I_Player, "%s No puedes elegir el mismo rango que posee actualmente este miembro!g!.", CSZ_Prefix);
			
			if (M_HaveClan(I_Player))
				SM_Clan(I_Player, _, CHOOSE_STATUS_TO_CLAN_MEMBER, A_PlayerVars[I_MemberPlayerID][PSZ_CLIENT_NAME]);
			else
				SM_Clan(I_Player, _, DONT_HAVE_CLAN);
			
			return;
		}
		
		new I_LastStatus = A_PlayerVars[I_MemberPlayerID][PI_CLAN_STATUS];
		
		A_PlayerVars[I_MemberPlayerID][PI_CLAN_STATUS] = A_PlayerVars[I_Player][PI_CHOOSE_STATUS_FOR_MEMBER];
		
		UTIL_SendPrint(I_MemberPlayerID, I_MemberPlayerID, "%s Has sido %s al rango!color: %s!y por cortesia del !g%s!color %s!g!.", CSZ_Prefix,
		(A_PlayerVars[I_MemberPlayerID][PI_CLAN_STATUS] > I_LastStatus ? "ascendido" : "degradado"),
		CSZ_ClanMemberStatus[A_PlayerVars[I_MemberPlayerID][PI_CLAN_STATUS]], CSZ_ClanMemberStatus[A_PlayerVars[I_Player][PI_CLAN_STATUS]],
		A_PlayerVars[I_Player][PSZ_CLIENT_NAME]);
		
		UTIL_SendPrint(I_Player, I_Player, "%s Cambiaste el rango de !color%s!y al de!color: !g%s!.", CSZ_Prefix, A_PlayerVars[I_MemberPlayerID][PSZ_CLIENT_NAME],
		CSZ_ClanMemberStatus[A_PlayerVars[I_MemberPlayerID][PI_CLAN_STATUS]]);
	}
	else
	{
		static SZ_Data[10], SZ_ClanID[4], SZ_Status[2];
		
		fvault_get_data(CSZ_PlayersVault, SZ_MemberName, SZ_Data, charsmax(SZ_Data));
		
		parse(SZ_Data, SZ_ClanID, charsmax(SZ_ClanID), SZ_Status, charsmax(SZ_Status));
		
		if (str_to_num(SZ_Status) == A_PlayerVars[I_Player][PI_CHOOSE_STATUS_FOR_MEMBER])
		{
			UTIL_SendPrint(I_Player, I_Player, "%s No puedes elegir el mismo rango que posee actualmente este miembro!g!.", CSZ_Prefix);
			
			if (M_HaveClan(I_Player))
				SM_Clan(I_Player, _, CHOOSE_STATUS_TO_CLAN_MEMBER, SZ_MemberName);
			else
				SM_Clan(I_Player, _, DONT_HAVE_CLAN);
			
			return;
		}
		
		formatex(SZ_Data, charsmax(SZ_Data), "%s %d", SZ_ClanID, A_PlayerVars[I_Player][PI_CHOOSE_STATUS_FOR_MEMBER]);
			
		fvault_set_data(CSZ_PlayersVault, SZ_MemberName, SZ_Data);
			
		UTIL_SendPrint(I_Player, I_Player, "%s Cambiaste el rango de !color%s!y al de!color: !g%s!.", CSZ_Prefix, SZ_MemberName,
		CSZ_ClanMemberStatus[A_PlayerVars[I_Player][PI_CHOOSE_STATUS_FOR_MEMBER]]);
	}
}

public HM_ClanesTop(const I_Player, const I_Menu, const I_Item)
{
	if (I_Item == MENU_EXIT)
	{
		SM_Clan(I_Player, _, (M_HaveClan(I_Player) ? HAVE_CLAN : DONT_HAVE_CLAN));
		
		menu_destroy(I_Menu);
		
		return;
	}
	
	static I_Temporal, SZ_ClanID[2];
	
	menu_item_getinfo(I_Menu, I_Item, I_Temporal, SZ_ClanID, charsmax(SZ_ClanID), _, _, I_Temporal);
	
	SM_Clan(I_Player, SZ_ClanID[0], SHOW_CLAN_INFO);
}

/*==============================================================
			FUNCIONES PUBLICAS
==============================================================*/

public SendTeamInfoChatColor(const I_Player)
{
	if (!A_PlayerVars[I_Player][PBO_IS_CONNECTED])
		return;
		
	static I, I_TeamInfoID;
	
	if (!I_TeamInfoID)
		I_TeamInfoID = get_user_msgid("TeamInfo");
	
	for (I = CHAT_COLOR_GREY; I <= CHAT_COLOR_BLUE; I++)
	{
		message_begin(MSG_ONE, I_TeamInfoID, _, I_Player);
		{
			write_byte(I);
			write_string(CSZ_CsTeamNamesTable[I-CHAT_COLOR_GREY]);
		}
		message_end();
	}
}

/*==============================================================
			FUNCIONES PRIVADAS
==============================================================*/

bool:IsValidText(const I_Player = 0, const SZ_Text[], const I_ValidateType)
{
	new I, I_Characters, I_Len = strlen(SZ_Text);
	new SZ_InvalidCharacter[2];
	
	switch (I_ValidateType)
	{
		case VALIDATE_SAY:
		{
			if (!I_Len)
				return false;
			
			for (I = 0; I < I_Len; I++)
			{
				if (!isspace(SZ_Text[I]))
					I_Characters++;
			}
			
			if (I_Characters < 1)
				return false;
		}
		
		case VALIDATE_CLAN_NAME:
		{
			if (I_Len < MIN_CLAN_NAME_LEN)
			{
				client_print(I_Player, print_center, "[ERROR]: El nombre del clan debe tener un minimo de %d caracteres!.", MIN_CLAN_NAME_LEN);
				
				UTIL_SendPrint(I_Player, I_Player, "%s !colorERROR!g:!y El !colorNOMBRE!y del !gCLAN!y debe tener un minimo de %d caracteres!g!.", CSZ_Prefix, MIN_CLAN_NAME_LEN);
								
				return false;
			}
			
			for (I = 0; I < I_Len; I++)
			{
				if (isalnum(SZ_Text[I]))
				{
					I_Characters++;
					
					continue;
				}
				else if (isspace(SZ_Text[I]))
					continue;
				
				SZ_InvalidCharacter[0] = SZ_Text[I];
				
				if (contain(CSZ_AvailableSpecialCharacters, SZ_InvalidCharacter[0]) == -1)
				{
					client_print(I_Player, print_center, "[ERROR]: El nombre del clan no puede contener caracteres especiales (%s)!.", SZ_InvalidCharacter);
						
					UTIL_SendPrint(I_Player, I_Player, "%s !colorERROR!g:!y El !colorNOMBRE!y del !gCLAN!y no puede contener caracteres especiales (!color%s!y)!g!.", CSZ_Prefix, SZ_InvalidCharacter);
						
					return false;
				}
				else
					I_Characters++;
			}
			
			if (!I_Characters)
			{
				client_print(I_Player, print_center, "[ERROR]: El nombre del clan no puede contener solo espacios!.");
						
				UTIL_SendPrint(I_Player, I_Player, "%s !colorERROR!g:!y El !colorNOMBRE!y del !gCLAN!y no puede contener solo espacios!g!.", CSZ_Prefix);
					
				return false;
			}
			
			if (TrieKeyExists(A_GlobalVars[GT_CLANES_NAMES], SZ_Text))
			{
				client_print(I_Player, print_center, "[ERROR]: Ya existe un clan con este nombre!.");
				
				UTIL_SendPrint(I_Player, I_Player, "%s !colorERROR!g:!y Ya existe un !gCLAN!y con este nombre!g!.", CSZ_Prefix);
				
				return false;
			}
		}
		
		case VALIDATE_CLAN_TAG:
		{
			if (I_Len < MIN_CLAN_TAG_LEN)
			{
				client_print(I_Player, print_center, "[ERROR]: El TAG del clan debe tener un minimo de %d caracteres!.", MIN_CLAN_TAG_LEN);
				
				UTIL_SendPrint(I_Player, I_Player, "%s !colorERROR!g:!y El !colorTAG!y del !gCLAN!y debe tener un minimo de %d caracteres!g!.", CSZ_Prefix, MIN_CLAN_TAG_LEN);
								
				return false;
			}
			
			for (I = 0; I < I_Len; I++)
			{
				if (isalnum(SZ_Text[I]))
				{
					I_Characters++;
					
					continue;
				}
				else if (isspace(SZ_Text[I]))
					continue;
				
				SZ_InvalidCharacter[0] = SZ_Text[I];
				
				if (contain(CSZ_AvailableSpecialCharacters, SZ_InvalidCharacter[0]) == -1)
				{
					client_print(I_Player, print_center, "[ERROR]: El TAG del clan no puede contener caracteres especiales (%s)!.", SZ_InvalidCharacter);
						
					UTIL_SendPrint(I_Player, I_Player, "%s !colorERROR!g:!y El !colorTAG!y del !gCLAN!y no puede contener caracteres especiales (!color%s!y)!g!.", CSZ_Prefix, SZ_InvalidCharacter);
						
					return false;
				}
				else
					I_Characters++;
			}
			
			if (!I_Characters)
			{
				client_print(I_Player, print_center, "[ERROR]: El TAG del clan no puede contener solo espacios!.");
						
				UTIL_SendPrint(I_Player, I_Player, "%s !colorERROR!g:!y El !colorTAG!y del !gCLAN!y no puede contener solo espacios!g!.", CSZ_Prefix);
					
				return false;
			}
			
			if (TrieKeyExists(A_GlobalVars[GT_CLANES_TAGS], SZ_Text))
			{
				client_print(I_Player, print_center, "[ERROR]: Ya existe un clan con ese TAG!.");
				
				UTIL_SendPrint(I_Player, I_Player, "%s !colorERROR!g:!y Ya existe un !gCLAN!y con ese TAG!g!.", CSZ_Prefix);
				
				return false;
			}
		}
		
		case VALIDATE_CLAN_WELCOME_MESSAGE:
		{
			if (I_Len < MIN_CLAN_WELCOME_LEN)
			{
				client_print(I_Player, print_center, "[ERROR]: El mensaje de bienvenida clan debe tener un minimo de %d caracteres!.", MIN_CLAN_WELCOME_LEN);
				
				UTIL_SendPrint(I_Player, I_Player, "%s !colorERROR!g:!y El !colorMENSAJE DE BIENVENIDA!y del !gCLAN!y debe tener un minimo de %d caracteres!g!.", CSZ_Prefix, MIN_CLAN_WELCOME_LEN);
								
				return false;
			}
			
			for (I = 0; I < I_Len; I++)
			{
				if (isalnum(SZ_Text[I]))
				{
					I_Characters++;
					
					continue;
				}
				else if (isspace(SZ_Text[I]))
					continue;
				
				SZ_InvalidCharacter[0] = SZ_Text[I];
				
				if (contain(CSZ_AvailableSpecialCharacters, SZ_InvalidCharacter[0]) == -1)
				{
					client_print(I_Player, print_center, "[ERROR]: El mensaje de bienvenida del clan no puede contener caracteres especiales (%s)!.", SZ_InvalidCharacter);
						
					UTIL_SendPrint(I_Player, I_Player, "%s !colorERROR!g:!y El !colorMENSAJE DE BIENVENIDA!y del !gCLAN!y no puede contener caracteres especiales (!color%s!y)!g!.", CSZ_Prefix, SZ_InvalidCharacter);
						
					return false;
				}
				else
					I_Characters++;
			}
			
			if (!I_Characters)
			{
				client_print(I_Player, print_center, "[ERROR]: El TAG del clan no puede contener solo espacios!.");
						
				UTIL_SendPrint(I_Player, I_Player, "%s !colorERROR!g:!y El !colorTAG!y del !gCLAN!y no puede contener solo espacios!g!.", CSZ_Prefix);
					
				return false;
			}
		}
	}
	
	return true;
}

bool:IsAvailableToInvite(const I_InviterID, const I_Player)
{
	if (I_InviterID == I_Player || !A_PlayerVars[I_Player][PBO_IS_CONNECTED] || M_HaveClan(I_Player))
		return false;
	
	return true;
}

bool:IsAvailableClanMember(const I_Player, const I_ClanID)
{
	if (!A_PlayerVars[I_Player][PBO_IS_CONNECTED] || A_PlayerVars[I_Player][PI_CLAN_ID] != I_ClanID)
		return false;
	
	return true;
}

SendMessageToMembers(const I_Player, const SZ_Message[])
{
	static I;
	
	for (I = 1; I <= A_GlobalVars[GI_MAX_PLAYERS]; I++)
	{
		if (!IsAvailableClanMember(I, A_PlayerVars[I_Player][PI_CLAN_ID]) || I == I_Player)
			continue;
		
		UTIL_SendPrint(I, I, SZ_Message);
	}
}

GetBestClan(const I_SortByValue, const I_SortType, const bool:BO_StopSort)
{
	static I_MaxClanes, SZ_ClanName[MAX_CLAN_NAME_LEN], Trie:T_LastClanes;
	
	if (!T_LastClanes)
		T_LastClanes = TrieCreate();
	
	I_MaxClanes = ArraySize(A_GlobalVars[GDA_CLANES]);
	
	new I_ValueToSort = (I_SortByValue == SORT_BY_ACTIVITY_TIME ? I_CLAN_ACTIVITY_TIME : I_CLAN_MEMBERS);
	new I_BestClanValue = (I_SortType == SORT_DOWNWARDS ? 0 : 2147483647);
	new I_BestClanID = -1;
	
	for (new I; I < I_MaxClanes; I++)
	{
		GetClanData(I);
				
		if (TrieKeyExists(T_LastClanes, A_ClanData[SZ_CLAN_NAME]))
			continue;
		
		if (I_SortType == SORT_DOWNWARDS)
		{
			if (A_ClanData[I_ValueToSort] > I_BestClanValue)
			{
				I_BestClanID = I;
				I_BestClanValue = A_ClanData[I_ValueToSort];
			}
		}
		else
		{
			if (A_ClanData[I_ValueToSort] < I_BestClanValue)
			{
				I_BestClanID = I;
				I_BestClanValue = A_ClanData[I_ValueToSort];
			}
		}
	}
	
	GetClanData(I_BestClanID);
	
	copy(SZ_ClanName, charsmax(SZ_ClanName), A_ClanData[SZ_CLAN_NAME]);
	
	TrieSetCell(T_LastClanes, SZ_ClanName, true);
	
	if (BO_StopSort)
		TrieClear(T_LastClanes);
	
	return I_BestClanID;
}

GetMemberRealID(const SZ_MemberName[])
{
	static I;
	
	for (I = 1; I <= A_GlobalVars[GI_MAX_PLAYERS]; I++)
	{
		if (!A_PlayerVars[I][PBO_IS_CONNECTED])
			continue;
		
		if (equal(SZ_MemberName, A_PlayerVars[I][PSZ_CLIENT_NAME]))
			return I;
	}
	
	return 0;
}

GetClanActivityTime(const I_ClanID, &I_Hours, &I_Minutes, &I_Seconds, const bool:BO_AcvitityNeed = false)
{
	new I_ActivityTime;
	
	if (BO_AcvitityNeed)
	{
		I_ActivityTime = GetClanActivityTimeNeed(I_ClanID);
		
		I_Hours = (I_ActivityTime / 3600);
		I_Minutes = ((I_ActivityTime - (I_Hours * 3600)) / 60);
		I_Seconds = (I_ActivityTime - ((I_Hours * 3600) + (I_Minutes * 60)));
	}
	else
	{
		GetClanData(I_ClanID);
		
		I_ActivityTime = A_ClanData[I_CLAN_ACTIVITY_TIME];
		
		I_Hours = (I_ActivityTime / 3600);
		I_Minutes = ((I_ActivityTime - (I_Hours * 3600)) / 60);
		I_Seconds = (I_ActivityTime - ((I_Hours * 3600) + (I_Minutes * 60)));
	}
	
	return I_ActivityTime;
}

GetTotalClanMembersOfSameStatus(const I_ClanID, const I_StatusToSearch = SEARCH_ALL_STATUS, &I_OnLineMembers, &I_OffLineMembers, I_MaxClanMembers)
{
	static I, Trie:T_LastMembers;
	new I_TotalMembers;
	
	if (!T_LastMembers)
		T_LastMembers = TrieCreate();

	for (I = 1; I <= A_GlobalVars[GI_MAX_PLAYERS]; I++)
	{
		if (!IsAvailableClanMember(I, I_ClanID) || TrieKeyExists(T_LastMembers, A_PlayerVars[I][PSZ_CLIENT_NAME]) || (I_StatusToSearch > SEARCH_ALL_STATUS && A_PlayerVars[I][PI_CLAN_STATUS] != I_StatusToSearch))
				continue;
			
		TrieSetCell(T_LastMembers, A_PlayerVars[I][PSZ_CLIENT_NAME], true);
			
		I_TotalMembers++;
		I_OnLineMembers++;
	}
	
	if (I_TotalMembers >= I_MaxClanMembers)
	{
		TrieClear(T_LastMembers);
		
		return I_TotalMembers;
	}
	
	new I_MemberClanID, I_MemberStatus;
	static I_VaultSize, SZ_KeyName[32], SZ_Data[10], SZ_ClanID[4], SZ_Status[2];
		
	I_VaultSize = fvault_size(CSZ_PlayersVault);
		
	for (I = 0; I < I_VaultSize; I++)
	{
		fvault_get_keyname(CSZ_PlayersVault, I, SZ_KeyName, charsmax(SZ_KeyName));
		
		if (TrieKeyExists(T_LastMembers, SZ_KeyName))
			continue;
		
		fvault_get_data(CSZ_PlayersVault, SZ_KeyName, SZ_Data, charsmax(SZ_Data));
			
		parse(SZ_Data, SZ_ClanID, charsmax(SZ_ClanID), SZ_Status, charsmax(SZ_Status));
			
		I_MemberClanID = str_to_num(SZ_ClanID);
		I_MemberStatus = str_to_num(SZ_Status);
			
		if (I_MemberClanID != I_ClanID || (I_StatusToSearch > SEARCH_ALL_STATUS && I_MemberStatus != I_StatusToSearch))
				continue;
			
		TrieSetCell(T_LastMembers, SZ_KeyName, true);
			
		I_TotalMembers++;
		I_OffLineMembers++;
		
		if (I_TotalMembers >= I_MaxClanMembers)
		{
			TrieClear(T_LastMembers);
			
			return I_TotalMembers;
		}
	}
	
	TrieClear(T_LastMembers);
	
	return I_TotalMembers;
}

GetClanMembers(const I_ClanID, const I_StatusToSearch = SEARCH_ALL_STATUS, SZ_MemberName[] = EOS, const I_MemberNameLen = 0, SZ_MemberStatus[] = EOS, const I_MemberStatusLen = 0, &bool:BO_IsOnline, bool:BO_StopSearch)
{
	static I, Trie:T_LastMembers;
	
	if (!T_LastMembers)
		T_LastMembers = TrieCreate();
		
	for (I = 1; I <= A_GlobalVars[GI_MAX_PLAYERS]; I++)
	{
		if (!IsAvailableClanMember(I, I_ClanID) || TrieKeyExists(T_LastMembers, A_PlayerVars[I][PSZ_CLIENT_NAME]) || (I_StatusToSearch > SEARCH_ALL_STATUS && A_PlayerVars[I][PI_CLAN_STATUS] != I_StatusToSearch))
			continue;
		
		TrieSetCell(T_LastMembers, A_PlayerVars[I][PSZ_CLIENT_NAME], true);
		
		copy(SZ_MemberName, I_MemberNameLen, A_PlayerVars[I][PSZ_CLIENT_NAME]);
		copy(SZ_MemberStatus, I_MemberStatusLen, CSZ_ClanMemberStatus[A_PlayerVars[I][PI_CLAN_STATUS]]);
		
		BO_IsOnline = true;
		
		goto CheckSearch;
	}
	
	new I_MemberClanID, I_MemberStatus;
	static I_VaultSize, SZ_KeyName[32], SZ_Data[10], SZ_ClanID[4], SZ_Status[2];
	
	I_VaultSize = fvault_size(CSZ_PlayersVault);
	
	for (I = 0; I < I_VaultSize; I++)
	{
		fvault_get_keyname(CSZ_PlayersVault, I, SZ_KeyName, charsmax(SZ_KeyName));
		
		if (TrieKeyExists(T_LastMembers, SZ_KeyName))
			continue;
		
		fvault_get_data(CSZ_PlayersVault, SZ_KeyName, SZ_Data, charsmax(SZ_Data));
		
		parse(SZ_Data, SZ_ClanID, charsmax(SZ_ClanID), SZ_Status, charsmax(SZ_Status));
		
		I_MemberClanID = str_to_num(SZ_ClanID);
		I_MemberStatus = str_to_num(SZ_Status);
				
		if (I_MemberClanID != I_ClanID || (I_StatusToSearch > SEARCH_ALL_STATUS && I_MemberStatus != I_StatusToSearch))
			continue;
		
		TrieSetCell(T_LastMembers, SZ_KeyName, true);
		
		copy(SZ_MemberName, I_MemberNameLen, SZ_KeyName);
		copy(SZ_MemberStatus, I_MemberStatusLen, CSZ_ClanMemberStatus[I_MemberStatus]);
		
		BO_IsOnline = false;
		
		break;
	}
	
	CheckSearch:
	{
		if (BO_StopSearch)
			TrieClear(T_LastMembers);
	}
}

GetClanActivityTimeNeed(const I_ClanID)
{
	GetClanData(I_ClanID);
	
	return (A_ClanData[I_CLAN_MEMBERS] < 3 ? 0 : M_ActivityTimeNeed(A_ClanData[I_CLAN_MEMBERS]));
}

GetClanData(const I_ClanID)
	ArrayGetArray(A_GlobalVars[GDA_CLANES], I_ClanID, A_ClanData);
	
ChangeAllClanIDs(const I_ClanID)
{
	new I_MemberClanID;
	static I, I_Size, I_MaxClanes, SZ_KeyName[32], SZ_Data[10], SZ_ClanID[4], SZ_Status[2];
	
	for (I = 1; I <= A_GlobalVars[GI_MAX_PLAYERS]; I++)
	{
		if (!M_HaveClan(I) || A_PlayerVars[I][PI_CLAN_ID] <= I_ClanID)
			continue;
		
		A_PlayerVars[I][PI_CLAN_ID]--;
	}
	
	I_Size = fvault_size(CSZ_PlayersVault)
	
	for (I = 0; I < I_Size; I++)
	{
		fvault_get_keyname(CSZ_PlayersVault, I, SZ_KeyName, charsmax(SZ_KeyName));
		fvault_get_data(CSZ_PlayersVault, SZ_KeyName, SZ_Data, charsmax(SZ_Data));
		
		parse(SZ_Data, SZ_ClanID, charsmax(SZ_ClanID), SZ_Status, charsmax(SZ_Status));
		
		I_MemberClanID = str_to_num(SZ_Data);
		
		if (I_MemberClanID <= I_ClanID)
			continue;
		
		formatex(SZ_Data, charsmax(SZ_Data), "%d %s", (I_MemberClanID - 1), SZ_Status);
		
		fvault_set_data(CSZ_PlayersVault, SZ_KeyName, SZ_Data);
	}
	
	I_MaxClanes = ArraySize(A_GlobalVars[GDA_CLANES]);
	
	for (I = 0; I < I_MaxClanes; I++)
	{
		GetClanData(I);
		
		if (A_ClanData[I_CLAN_ID] > I_ClanID)
			A_ClanData[I_CLAN_ID]--;
		
		UpdateClanData(I);
	}
}
	
DestroyClan(const I_ClanLeader, const I_ClanID)
{
	new I_CurrentMembers;
	
	static I;
	
	for (I = 1; I <= A_GlobalVars[GI_MAX_PLAYERS]; I++)
	{
		if (!IsAvailableClanMember(I, I_ClanID) || I == I_ClanLeader)
			continue;
		
		I_CurrentMembers++;
		
		A_PlayerVars[I][PI_CLAN_STATUS] = A_PlayerVars[I][PI_CURRENT_TIMER] = STATUS_MEMBER;
		A_PlayerVars[I][PI_CLAN_ID] = -1;
		
		UTIL_SendPrint(I, I, "%s El !g%s !color%s!y acaba de destruir el !gCLAN!y donde estabas!g!.", CSZ_Prefix, CSZ_ClanMemberStatus[A_PlayerVars[I_ClanLeader][PI_CLAN_STATUS]], A_PlayerVars[I_ClanLeader][PSZ_CLIENT_NAME]);
	}
	
	if (I_CurrentMembers < A_ClanData[I_CLAN_MEMBERS])
	{
		static I_Size, SZ_KeyName[32], SZ_Data[10], SZ_ClanID[4];
		
		I_Size = fvault_size(CSZ_PlayersVault);
		
		for (I = 0; I < I_Size; I++)
		{
			if (I_CurrentMembers >= A_ClanData[I_CLAN_MEMBERS])
				break;
			
			fvault_get_keyname(CSZ_PlayersVault, I, SZ_KeyName, charsmax(SZ_KeyName));
			fvault_get_data(CSZ_PlayersVault, SZ_KeyName, SZ_Data, charsmax(SZ_Data));
			
			parse(SZ_Data, SZ_ClanID, charsmax(SZ_ClanID));
			
			if (str_to_num(SZ_ClanID) != I_ClanID)
				continue;
			
			formatex(SZ_Data, charsmax(SZ_Data), "-1 0");
			
			fvault_set_data(CSZ_PlayersVault, SZ_KeyName, SZ_Data);
			
			I_CurrentMembers++;
		}
	}
}
	
UpdateClanData(const I_ClanID, const bool:BO_IsLoadingClanes = false)
	BO_IsLoadingClanes ? ArrayPushArray(A_GlobalVars[GDA_CLANES], A_ClanData) : ArraySetArray(A_GlobalVars[GDA_CLANES], I_ClanID, A_ClanData);
	
ClanesData(const I_Mode)
{
	new I_File;
	
	get_configsdir(A_GlobalVars[GSZ_TEXT], charsmax(A_GlobalVars[GSZ_TEXT]));
	format(A_GlobalVars[GSZ_TEXT], charsmax(A_GlobalVars[GSZ_TEXT]), "%s/%s", A_GlobalVars[GSZ_TEXT], CSZ_ClanesVault);
	
	switch (I_Mode)
	{
		case LOAD_CLANES_DATA:
		{
			if (!file_exists(A_GlobalVars[GSZ_TEXT]))
			{
				I_File = fopen(A_GlobalVars[GSZ_TEXT], "wt");
				
				return;
			}
			
			I_File = fopen(A_GlobalVars[GSZ_TEXT], "rt");
	
			new I_Value, SZ_Key[50], SZ_Data[50];
	
			while (!feof(I_File))
			{
				fgets(I_File, A_GlobalVars[GSZ_TEXT], charsmax(A_GlobalVars[GSZ_TEXT]));
				replace(A_GlobalVars[GSZ_TEXT], charsmax(A_GlobalVars[GSZ_TEXT]), "^n", "");
				
				if (!A_GlobalVars[GSZ_TEXT][0])
					continue;
		
				strtok(A_GlobalVars[GSZ_TEXT], SZ_Key, charsmax(SZ_Key), SZ_Data, charsmax(SZ_Data), '=');
		
				trim(SZ_Key);
				trim(SZ_Data);
		
				if (TrieGetCell(A_GlobalVars[GT_CLANES_VALUES], SZ_Key, I_Value))
				{
					switch (I_Value)
					{
						case I_VALUE_CLAN_ID: A_ClanData[I_CLAN_ID] = str_to_num(SZ_Data);
						
						case I_VALUE_CLAN_MEMBERS: A_ClanData[I_CLAN_MEMBERS] = str_to_num(SZ_Data);
						
						case I_VALUE_CLAN_ACTIVITY_TIME: A_ClanData[I_CLAN_ACTIVITY_TIME] = str_to_num(SZ_Data);
						
						case I_VALUE_CLAN_NAME:
						{
							copy(A_ClanData[SZ_CLAN_NAME], charsmax(A_ClanData[SZ_CLAN_NAME]), SZ_Data);
							
							TrieSetCell(A_GlobalVars[GT_CLANES_NAMES], A_ClanData[SZ_CLAN_NAME], true);
						}
				
						case I_VALUE_CLAN_LEADER: copy(A_ClanData[SZ_CLAN_LEADER], charsmax(A_ClanData[SZ_CLAN_LEADER]), SZ_Data);
						
						case I_VALUE_CLAN_TAG:
						{
							copy(A_ClanData[SZ_CLAN_TAG], charsmax(A_ClanData[SZ_CLAN_TAG]), SZ_Data);
							
							TrieSetCell(A_GlobalVars[GT_CLANES_TAGS], SZ_Data, true);
						}
						
						case I_VALUE_CLAN_WELCOME_MESSAGE: copy(A_ClanData[SZ_CLAN_WELCOME_MESSAGE], charsmax(A_ClanData[SZ_CLAN_WELCOME_MESSAGE]), SZ_Data);
					}
				}
		
				if (I_Value >= charsmax(CSZ_ClanesValuesNames))
					UpdateClanData(A_ClanData[I_CLAN_ID], true);
			}
	
			fclose(I_File);
		}
		
		case SAVE_CLANES_DATA:
		{
			if (file_exists(A_GlobalVars[GSZ_TEXT]))
				delete_file(A_GlobalVars[GSZ_TEXT]);
			
			I_File = fopen(A_GlobalVars[GSZ_TEXT], "wt");
			
			for (new I; I < ArraySize(A_GlobalVars[GDA_CLANES]); I++)
			{
				GetClanData(I);
				
				formatex(A_GlobalVars[GSZ_TEXT], charsmax(A_GlobalVars[GSZ_TEXT]), "ID = %d^nMEMBERS = %d^nACTIVITY TIME = %d^nNAME = %s^nLEADER = %s^nTAG = %s^nWELCOME MESSAGE = %s^n^n",
				A_ClanData[I_CLAN_ID], A_ClanData[I_CLAN_MEMBERS], A_ClanData[I_CLAN_ACTIVITY_TIME], A_ClanData[SZ_CLAN_NAME], A_ClanData[SZ_CLAN_LEADER], A_ClanData[SZ_CLAN_TAG],
				A_ClanData[SZ_CLAN_WELCOME_MESSAGE]);
				
				fputs(I_File, A_GlobalVars[GSZ_TEXT]);
			}
	
			fclose(I_File);
		}
			
	}
}

PlayersData(const I_Player, const I_Mode)
{
	if (!A_PlayerVars[I_Player][PBO_IS_CONNECTED] || A_PlayerVars[I_Player][PBO_IS_BOT] || I_Mode == SAVE_PLAYERS_DATA && !M_HaveClan(I_Player))
		return;
	
	static SZ_Data[10];
	
	switch (I_Mode)
	{
		case LOAD_PLAYERS_DATA:
		{
			if (fvault_get_data(CSZ_PlayersVault, A_PlayerVars[I_Player][PSZ_CLIENT_NAME], SZ_Data, charsmax(SZ_Data)))
			{
				static SZ_ClanID[4], SZ_Status[2];
				
				parse(SZ_Data, SZ_ClanID, charsmax(SZ_ClanID), SZ_Status, charsmax(SZ_Status));
				
				A_PlayerVars[I_Player][PI_CLAN_ID] = str_to_num(SZ_ClanID);
				A_PlayerVars[I_Player][PI_CLAN_STATUS] = str_to_num(SZ_Status);
			}
		}
		
		case SAVE_PLAYERS_DATA:
		{
			formatex(SZ_Data, charsmax(SZ_Data), "%d %d", A_PlayerVars[I_Player][PI_CLAN_ID], A_PlayerVars[I_Player][PI_CLAN_STATUS]);
			
			fvault_set_data(CSZ_PlayersVault, A_PlayerVars[I_Player][PSZ_CLIENT_NAME], SZ_Data);
			
			if (!M_HaveClan(I_Player))
				return;
			
			GetClanData(A_PlayerVars[I_Player][PI_CLAN_ID]);
			
			A_ClanData[I_CLAN_ACTIVITY_TIME] += A_PlayerVars[I_Player][PI_CURRENT_TIMER];
			
			UpdateClanData(A_PlayerVars[I_Player][PI_CLAN_ID]);
		}
	}
}

/*========================================
		(UTILIDADES)
========================================*/

UTIL_SendPrint(const I_Player = 0, const I_ColorChat, const SZ_Text[], any:...)
{
	static I_SayTextID, SZ_Message[190];
	
	if (!I_SayTextID)
		I_SayTextID = get_user_msgid("SayText");
	
	vformat(SZ_Message, charsmax(SZ_Message), SZ_Text, 4);
	
	replace_all(SZ_Message, charsmax(SZ_Message), "!y", "^1");
	replace_all(SZ_Message, charsmax(SZ_Message), "!color", "^3");
	replace_all(SZ_Message, charsmax(SZ_Message), "!g", "^4");
	
	message_begin((I_Player ? MSG_ONE : MSG_BROADCAST), I_SayTextID, _, I_Player);
	{
		write_byte(I_ColorChat);
		write_string(SZ_Message);
	}
	message_end();
}

UTIL_SendCMDWithHUD(const I_Player, const SZ_CMD[], const SZ_Text[], A_Color[3] = { 255, 255, 255 }, const Float:F_XPosition = -1.0, const Float:F_YPosition = 0.65, const Float:F_HoldTime)
{
	if (!A_PlayerVars[I_Player][PBO_IS_CONNECTED])
			return;
		
	for (new I; I < sizeof (A_Color); I++)
	{
		if (A_Color[I] > 255)
			A_Color[I] = 255;
	}
	
	client_cmd(I_Player, "%s", SZ_CMD);
	
	set_dhudmessage(A_Color[0], A_Color[1], A_Color[2], F_XPosition, F_YPosition, 0, 0.0, F_HoldTime, 0.1, 0.1);
	show_dhudmessage(I_Player, SZ_Text);
}
Serverul impune conditii strict HLDS/REHLDS?: ReHlds
Ai cautat pluginul?(daca da, precizeaza cum): Da dar nu il gasesc in engleza
Necesita mod special?: Nup
RoyalServer
User avatar
kidd0x
Utilizator neserios (tepar)
Utilizator neserios (tepar)
Posts: 1054
Joined: 06 Oct 2018, 14:41
Detinator Steam: Da
SteamID: /id/kidd0x/
Reputatie: Utilizator neserios (tepar!)
Fond eXtream: 0
Location: Constangeles
Discord: kidd0x
Has thanked: 172 times
Been thanked: 81 times

12 Oct 2020, 01:44

Google translate : Im a joke to you ?
lexz
Scripter eXtreamCS
Scripter eXtreamCS
Posts: 918
Joined: 02 Nov 2020, 01:57
Detinator Steam: Da
Fond eXtream: 0
Discord: lexzor#0630
Has thanked: 71 times
Been thanked: 136 times

18 Nov 2020, 08:44

Bro aici se fac cereri de scripting, lucruri pe care nu stii tu sa le faci, nu ca ti-e greu sa folosesti google translate :))))
Post Reply

Return to “Cereri”

  • Information
  • Who is online

    Users browsing this forum: No registered users and 37 guests