Помощ с функция

Ако имате затруднения при изработката/преработката на даден плъгин - пишете тук, ще се опитаме да ви помогнем!
Аватар
arunbg
Извън линия
Потребител
Потребител
Мнения: 30
Регистриран на: 16 Окт 2016, 16:04

Помощ с функция

Мнение от arunbg » 18 Окт 2016, 12:12

Опитвам се сам да редактирам един плъгин та ако нещо се препъна да пиша тук. За сега ми е нужна функция,която да брои в момента колко играчи има в сървъра. Тоест ако има 6 играча в сървъра ,променливата p_server = на функцията и да изкара 6. Има ли такава вградена като get_maxplayers() или... ?

Аватар
WaLkZ
Извън линия
Администратор
Администратор
Мнения: 799
Регистриран на: 05 Окт 2016, 21:13
Местоположение: Варна
Се отблагодари: 75 пъти
Получена благодарност: 227 пъти
Обратна връзка:

Re: Помощ с функция

Мнение от WaLkZ » 18 Окт 2016, 12:49

Просто си създай една глобална променлива g_counter и при client_putinserver увеличаваш с 1, а при client_disconnect намаляш с 1.

Аватар
OciXCrom
Извън линия
Администратор
Администратор
Мнения: 7206
Регистриран на: 06 Окт 2016, 19:20
Местоположение: /resetscore
Се отблагодари: 117 пъти
Получена благодарност: 1295 пъти
Обратна връзка:

Re: Помощ с функция

Мнение от OciXCrom » 18 Окт 2016, 14:35

Има и вградена функция - get_playersnum().

Аватар
TheRedShoko
Извън линия
Модератор
Модератор
Мнения: 1016
Регистриран на: 06 Окт 2016, 07:42
Местоположение: Бургас
Се отблагодари: 5 пъти
Получена благодарност: 84 пъти

Re: Помощ с функция

Мнение от TheRedShoko » 18 Окт 2016, 14:37

Пробвай с:

I вариант

Код за потвърждение: Избери целия код

get_playersnum()
Не съм пробвал дали работи коректно, но предполагам, че не би трябвало да създава проблеми.

II вариант

Код за потвърждение: Избери целия код

new players[32], pnum
get_players(players, pnum)
където

Код за потвърждение: Избери целия код

players[32] - масив с индексите на играчите

Код за потвърждение: Избери целия код

pnum - брой на играчите
III вариант

Код за потвърждение: Избери целия код

new maxPlayers
public plugin_init()
{
    maxPlayers = get_maxplayers()
}

GetOnlinePlayers()
{
    new onlinePlayers = 0
    
    for (new i = 1; i <= maxPlayers; i++)
    {
        if (!is_user_connected(i))
        {
            continue
        }
        
        onlinePlayers++
    }
    
    return onlinePlayers
} 

Аватар
WaLkZ
Извън линия
Администратор
Администратор
Мнения: 799
Регистриран на: 05 Окт 2016, 21:13
Местоположение: Варна
Се отблагодари: 75 пъти
Получена благодарност: 227 пъти
Обратна връзка:

Re: Помощ с функция

Мнение от WaLkZ » 18 Окт 2016, 14:57

Имайте в предвид, че всяка функция отдолу е имплементирана. В случая get_playersnum() отдолу всеки път върти цикъл за да даде текущите играчи.

Код за потвърждение: Избери целия код

static cell AMX_NATIVE_CALL get_playersnum(AMX *amx, cell *params)
{
	if (!params[1])
		return g_players_num;

	int a = 0;
	
	for (int i = 1; i <= gpGlobals->maxClients; ++i)
	{
		CPlayer* pPlayer = GET_PLAYER_POINTER_I(i);
		
		if (pPlayer->initialized && (GETPLAYERUSERID(pPlayer->pEdict) > 0))
			++a;
	}

	return a;
}
Ето и имплементацията на get_players()

Код за потвърждение: Избери целия код

static cell AMX_NATIVE_CALL get_players(AMX *amx, cell *params) /* 4 param */
{
	int iNum = 0;
	int ilen;
	char* sptemp = get_amxstring(amx, params[3], 0, ilen);
	int flags = UTIL_ReadFlags(sptemp);

	cell *aPlayers = get_amxaddr(amx, params[1]);
	cell *iMax = get_amxaddr(amx, params[2]);

	int team = 0;

	if (flags & 48)
	{
		sptemp = get_amxstring(amx, params[4], 0, ilen);

		if (flags & 16)
		{
			if (flags & 64)
				team = g_teamsIds.findTeamId(sptemp);
			else
				team = g_teamsIds.findTeamIdCase(sptemp);
		}
	}

	for (int i = 1; i <= gpGlobals->maxClients; ++i)
	{
		CPlayer* pPlayer = GET_PLAYER_POINTER_I(i);
		if (pPlayer->ingame || ((flags & 256) && pPlayer->initialized))
		{
			if (pPlayer->IsAlive() ? (flags & 2) : (flags & 1))
				continue;
			if (pPlayer->IsBot() ? (flags & 4) : (flags & 8))
				continue;
			if ((flags & 16) && (pPlayer->teamId != team))
				continue;
			if ((flags & 128) && (pPlayer->pEdict->v.flags & FL_PROXY))
				continue;
			if (flags & 32)
			{
				if (flags & 64)
				{
					if (stristr(pPlayer->name.chars(), sptemp) == NULL)
						continue;
				}
				else if (strstr(pPlayer->name.chars(), sptemp) == NULL)
					continue;
			}
			aPlayers[iNum++] = i;
		}
	}

	*iMax = iNum;
	
	return 1;
}

Аватар
arunbg
Извън линия
Потребител
Потребител
Мнения: 30
Регистриран на: 16 Окт 2016, 16:04

Re: Помощ с функция

Мнение от arunbg » 19 Окт 2016, 11:24

Благодаря. Та... общо взето направих две променливи и сложих едно условие. Въпросът е дали съм сложил условието(if) на правилното място... Плъгинът,който редактирам е team semiclip. Искам да го направя така,че след като даден сървър има 18 човека той да се включи,а ако има под 18 да се изключи. Код :

Код за потвърждение: Избери целия код

#include <amxmodx>
#include <fakemeta>
#include <chatcolor>

#pragma semicolon 1

#define DISTANCE 120

new g_iTeam[33];
new bool:g_bSolid[33];
new bool:g_bHasSemiclip[33];
new Float:g_fOrigin[33][3];

new bool:g_bSemiclipEnabled;

new g_iForwardId[3];
new g_iMaxPlayers;
new g_iCvar[4];
new g_players;

public plugin_init( )
{
	register_plugin( "(Team-)Semiclip", "1.2", "SchlumPF*" );
	
	g_iCvar[0] = register_cvar( "semiclip_enabled", "1" );
	g_iCvar[1] = register_cvar( "semiclip_teamclip", "0" );
	g_iCvar[2] = register_cvar( "semiclip_transparancy", "1" );
	g_iCvar[3] = register_cvar( "semiclip_players_min", "18" );
	
	register_forward( FM_ClientCommand, "fwdClientCommand" );
	
	if( get_pcvar_num( g_iCvar[0] ) )
	{
		g_iForwardId[0] = register_forward( FM_PlayerPreThink, "fwdPlayerPreThink" );
		g_iForwardId[1] = register_forward( FM_PlayerPostThink, "fwdPlayerPostThink" );
		g_iForwardId[2] = register_forward( FM_AddToFullPack, "fwdAddToFullPack_Post", 1 );
		
		g_bSemiclipEnabled = true;
	}
	else
		g_bSemiclipEnabled = false;
	
	g_iMaxPlayers = get_maxplayers( );
	g_players = get_playersnum();
}

public fwdPlayerPreThink( plr )
{
	static id, last_think;

	if( last_think > plr )
	{
	    if(g_players >= get_pcvar_num(g_iCvar[3]))
		{
		for( id = 1 ; id <= g_iMaxPlayers ; id++ )
		{
			if( is_user_alive( id ) )
			{
				if( get_pcvar_num( g_iCvar[1] ) )
					g_iTeam[id] = get_user_team( id );
				
				g_bSolid[id] = pev( id, pev_solid ) == SOLID_SLIDEBOX ? true : false;
				pev( id, pev_origin, g_fOrigin[id] );
			}
			else
				g_bSolid[id] = false;
		}
		    ColorChat(0,BLUE,"^4 [CG]^1 SemiClip^3 activated^1.");
		}
		else
		    ColorChat(0,RED,"^4 [CG]^1 SemiClip^3 activated^1.");
	}

	last_think = plr;

	if( g_bSolid[plr] )
	{
		for( id = 1 ; id <= g_iMaxPlayers ; id++ )
		{
			if( g_bSolid[id] && get_distance_f( g_fOrigin[plr], g_fOrigin[id] ) <= DISTANCE && id != plr )
			{
				if( get_pcvar_num( g_iCvar[1] ) && g_iTeam[plr] != g_iTeam[id] )
					return FMRES_IGNORED;
	
				set_pev( id, pev_solid, SOLID_NOT );
				g_bHasSemiclip[id] = true;
			}
		}
	}

	return FMRES_IGNORED;
}

public fwdPlayerPostThink( plr )
{
	static id;

	for( id = 1 ; id <= g_iMaxPlayers ; id++ )
	{
		if( g_bHasSemiclip[id] )
		{
			set_pev( id, pev_solid, SOLID_SLIDEBOX );
			g_bHasSemiclip[id] = false;
		}
	}
}

public fwdAddToFullPack_Post( es_handle, e, ent, host, hostflags, player, pset )
{
	if( player )
	{
		if( g_bSolid[host] && g_bSolid[ent] && get_distance_f( g_fOrigin[host], g_fOrigin[ent] ) <= DISTANCE )
		{
			if( get_pcvar_num( g_iCvar[1] ) && g_iTeam[host] != g_iTeam[ent] )
				return FMRES_IGNORED;
				
			set_es( es_handle, ES_Solid, SOLID_NOT ); // makes semiclip flawless
			
			if( get_pcvar_num( g_iCvar[2] ) == 1 )
			{
				set_es( es_handle, ES_RenderMode, kRenderTransAlpha );
				set_es( es_handle, ES_RenderAmt, 85 );
			}
			else if( get_pcvar_num( g_iCvar[2] ) == 2 )
			{
				set_es( es_handle, ES_Effects, EF_NODRAW );
				set_es( es_handle, ES_Solid, SOLID_NOT );
			}
		}
	}
	
	return FMRES_IGNORED;
}

// is there a better way to detect changings of g_iCvar[0]?
public fwdClientCommand( plr )
{
	// use the forwards just when needed, for good performance
	if( !get_pcvar_num( g_iCvar[0] ) && g_bSemiclipEnabled )
	{
		unregister_forward( FM_PlayerPreThink, g_iForwardId[0] );
		unregister_forward( FM_PlayerPostThink, g_iForwardId[1] );
		unregister_forward( FM_AddToFullPack, g_iForwardId[2], 1 );
		
		g_bSemiclipEnabled = false;
	}
	else if( get_pcvar_num( g_iCvar[0] ) && !g_bSemiclipEnabled )
	{
		g_iForwardId[0] = register_forward( FM_PlayerPreThink, "fwdPlayerPreThink" );
		g_iForwardId[1] = register_forward( FM_PlayerPostThink, "fwdPlayerPostThink" );
		g_iForwardId[2] = register_forward( FM_AddToFullPack, "fwdAddToFullPack_Post", 1 );
		
		g_bSemiclipEnabled = true;
	}
}
Редактираните редове са от 53 ред до 72. На 53-ти ред е условието,което аз съм добавил.

Аватар
TheRedShoko
Извън линия
Модератор
Модератор
Мнения: 1016
Регистриран на: 06 Окт 2016, 07:42
Местоположение: Бургас
Се отблагодари: 5 пъти
Получена благодарност: 84 пъти

Re: Помощ с функция

Мнение от TheRedShoko » 19 Окт 2016, 15:25

g_players получава стойността си в plugin_init и повече не се променя. В plugin_init get_playersnum ще върне 0, т.е. никога няма да се изпълни условието, за да се включи semiclip-a. PlayerPreThink се извиква на всеки кадър на играч, т.е. ако игач има 60 fps PreThink-a ще се извика 60 пъти в секундата, което може да причини допълнителен лаг в сървъра, ако извикваш get_playersnum на всеки prethink. Съобщенията ще се принтват по 60 пъти в секунда, което най-вероятно ще претовари сървъра. По-добре използвай метамод плъгина за semiclip, а не amxx плъгина.

Аватар
arunbg
Извън линия
Потребител
Потребител
Мнения: 30
Регистриран на: 16 Окт 2016, 16:04

Re: Помощ с функция

Мнение от arunbg » 19 Окт 2016, 20:11

Код за потвърждение: Избери целия код

#include <amxmodx>
#include <fakemeta>
#include <chatcolor>

#pragma semicolon 1

#define DISTANCE 120

new g_iTeam[33];
new bool:g_bSolid[33];
new bool:g_bHasSemiclip[33];
new Float:g_fOrigin[33][3];

new bool:g_bSemiclipEnabled;
new bool:g_players;

new g_iForwardId[3];
new g_iMaxPlayers;
new g_iCvar[4];

new g_NewNum;
new g_OldNum;

public plugin_init( )
{
	register_plugin( "(Team-)Semiclip", "1.2", "SchlumPF*" );
	
	g_iCvar[0] = register_cvar( "semiclip_enabled", "1" );
	g_iCvar[1] = register_cvar( "semiclip_teamclip", "0" );
	g_iCvar[2] = register_cvar( "semiclip_transparancy", "1" );
	g_iCvar[3] = register_cvar( "semiclip_players_min", "18" );
	
	register_forward( FM_ClientCommand, "fwdClientCommand" );
	
	if( get_pcvar_num( g_iCvar[0] ) )
	{
		g_iForwardId[0] = register_forward( FM_PlayerPreThink, "fwdPlayerPreThink" );
		g_iForwardId[1] = register_forward( FM_PlayerPostThink, "fwdPlayerPostThink" );
		g_iForwardId[2] = register_forward( FM_AddToFullPack, "fwdAddToFullPack_Post", 1 );
		
		g_bSemiclipEnabled = true;
	}
	else
		g_bSemiclipEnabled = false;
	
	g_iMaxPlayers = get_maxplayers();
	g_players = false;
}

public fwdPlayerPreThink( plr )
{
	static id, last_think;

	if( last_think > plr )
	{
	    if(get_playersnum() >= get_pcvar_num(g_iCvar[3]))
		{
		for( id = 1 ; id <= g_iMaxPlayers ; id++ )
		{
			if( is_user_alive( id ) )
			{
				if( get_pcvar_num( g_iCvar[1] ) )
					g_iTeam[id] = get_user_team( id );
				
				g_bSolid[id] = pev( id, pev_solid ) == SOLID_SLIDEBOX ? true : false;
				pev( id, pev_origin, g_fOrigin[id] );
			}
			else
				g_bSolid[id] = false;
		}
		    g_players = true;
			g_NewNum = 1;
		}
		else
		{
		    g_players = false;
			g_NewNum = 0;
	    }
	}
	
	if(g_players == true && g_OldNum != g_NewNum)
	{
	    ColorChat(0,BLUE,"^4 [CG]^1 SemiClip^3 activated^1.");
	}
	
	else if(g_players == false && g_OldNum != g_NewNum)
	{
	    ColorChat(0,RED,"^4 [CG]^1 SemiClip^3 activated^1.");
	}

	last_think = plr;

	if( g_bSolid[plr] )
	{
		for( id = 1 ; id <= g_iMaxPlayers ; id++ )
		{
			if( g_bSolid[id] && get_distance_f( g_fOrigin[plr], g_fOrigin[id] ) <= DISTANCE && id != plr )
			{
				if( get_pcvar_num( g_iCvar[1] ) && g_iTeam[plr] != g_iTeam[id] )
					return FMRES_IGNORED;
	
				set_pev( id, pev_solid, SOLID_NOT );
				g_bHasSemiclip[id] = true;
			}
		}
	}

	return FMRES_IGNORED;
}

public fwdPlayerPostThink( plr )
{
	static id;

	for( id = 1 ; id <= g_iMaxPlayers ; id++ )
	{
		if( g_bHasSemiclip[id] )
		{
			set_pev( id, pev_solid, SOLID_SLIDEBOX );
			g_bHasSemiclip[id] = false;
		}
	}
}

public fwdAddToFullPack_Post( es_handle, e, ent, host, hostflags, player, pset )
{
	if( player )
	{
		if( g_bSolid[host] && g_bSolid[ent] && get_distance_f( g_fOrigin[host], g_fOrigin[ent] ) <= DISTANCE )
		{
			if( get_pcvar_num( g_iCvar[1] ) && g_iTeam[host] != g_iTeam[ent] )
				return FMRES_IGNORED;
				
			set_es( es_handle, ES_Solid, SOLID_NOT ); // makes semiclip flawless
			
			if( get_pcvar_num( g_iCvar[2] ) == 1 )
			{
				set_es( es_handle, ES_RenderMode, kRenderTransAlpha );
				set_es( es_handle, ES_RenderAmt, 85 );
			}
			else if( get_pcvar_num( g_iCvar[2] ) == 2 )
			{
				set_es( es_handle, ES_Effects, EF_NODRAW );
				set_es( es_handle, ES_Solid, SOLID_NOT );
			}
		}
	}
	
	return FMRES_IGNORED;
}

// is there a better way to detect changings of g_iCvar[0]?
public fwdClientCommand( plr )
{
	// use the forwards just when needed, for good performance
	if( !get_pcvar_num( g_iCvar[0] ) && g_bSemiclipEnabled )
	{
		unregister_forward( FM_PlayerPreThink, g_iForwardId[0] );
		unregister_forward( FM_PlayerPostThink, g_iForwardId[1] );
		unregister_forward( FM_AddToFullPack, g_iForwardId[2], 1 );
		
		g_bSemiclipEnabled = false;
	}
	else if( get_pcvar_num( g_iCvar[0] ) && !g_bSemiclipEnabled )
	{
		g_iForwardId[0] = register_forward( FM_PlayerPreThink, "fwdPlayerPreThink" );
		g_iForwardId[1] = register_forward( FM_PlayerPostThink, "fwdPlayerPostThink" );
		g_iForwardId[2] = register_forward( FM_AddToFullPack, "fwdAddToFullPack_Post", 1 );
		
		g_bSemiclipEnabled = true;
	}
}

g_players променливата я направих от тип bool.
Функцията get_playersnum() я добавих директно към условието на цикъла for. Така предполагам,че на всяко въртене на цикъла отново ще се опроверява.
Добавих 2 нови условия.

Аватар
OciXCrom
Извън линия
Администратор
Администратор
Мнения: 7206
Регистриран на: 06 Окт 2016, 19:20
Местоположение: /resetscore
Се отблагодари: 117 пъти
Получена благодарност: 1295 пъти
Обратна връзка:

Re: Помощ с функция

Мнение от OciXCrom » 19 Окт 2016, 20:14

Можеш да добавиш глобална променлива, като през определено време да проверяваш броя на играчи (примерно 5 секунди), съответно променливата да се променя в зависимост от броя. Ако променливата е false, просто блокирай функциите на плъгина.

Код за потвърждение: Избери целия код

#define TASK_CHECK 555777
#define NEEDED_PLAYERS 18

new bool:g_blEnabled

public plugin_init()
    set_task(5.0, "CheckPlayers", TASK_CHECK, .flags = "b")
    
public CheckPlayers()
{
    if(get_playersnum() >= NEEDED_PLAYERS)
    {
        g_blEnabled = true
        ColorChat(0, BLUE, "^4[CG] ^1SemiClip ^3activated^1.")
    }
    else
    {
        g_blEnabled = false
        ColorChat(0, RED, "^4[CG] ^1SemiClip ^3deactivated^1.")
    }
} 

Аватар
arunbg
Извън линия
Потребител
Потребител
Мнения: 30
Регистриран на: 16 Окт 2016, 16:04

Re: Помощ с функция

Мнение от arunbg » 19 Окт 2016, 21:05

OciXCrom™ написа:Ако променливата е false, просто блокирай функциите на плъгина.
Тоест в fwdPlayerPreThink да сложа едно общо условие? + Това .flag = "b" какво 'казва' ?

Заключено
  • Подобни теми
    Отговори
    Преглеждания
     Последно мнение

Обратно към “Помощ в скриптирането”

Кой е на линия

Потребители разглеждащи този форум: 0 регистрирани и 16 госта