Помогите с оптимизацией

Тема в разделе "Программирование / Скриптинг", создана пользователем (admiral), 2 сен 2013.

  1. (admiral)

    (admiral)

    Сообщения:
    69
    Симпатии:
    8
    Есть массив, где для каждого игрока есть булево значение.Нужно создавать повторяющийся таймер с интервалом в 0.1 секунды, вызывающий временные энтити на месте игроков со значением true. Какой способ лучше?
    1)
    Код:
    new Handle:NemesisAura;
    new bool:g_IsNemesis[MAXPLAYERS + 1];
    public ZR_OnClientInfected(client, attacker, bool:motherInfect, bool:respawnOverride, bool:respawn)
    {
    	if (!g_IsNemesis[client])
    		return;
    	if (NemesisAura == INVALID_HANDLE)
    		NemesisAura = CreateTimer(0.1, TimerAura, _, TIMER_REPEAT | TIMER_FLAG_NO_MAPCHANGE);
    }
    public Action:TimerAura(Handle:timer)
    {
    	for (new client = 1; client < MaxClients; client++)
    	{
    		if (g_IsNemesis[client] && IsPlayerAlive(client))
    		{
    			static Float:origin[3];
    			GetEntPropVector(client, Prop_Data, "m_vecOrigin", origin);
    			TE_Start("Dynamic Light");
    			TE_WriteVector("m_vecOrigin", origin);
    			TE_WriteNum("r", цвет);
    			TE_WriteNum("g", цвет);
    			TE_WriteNum("b", цвет);
    			TE_WriteNum("exponent", 50);
    			TE_WriteFloat("m_fRadius", 50.0);
    			TE_WriteFloat("m_fTime", 2.0);
    			TE_WriteFloat("m_fDecay", 0.0);
    			TE_SendToAll();
    		}
    	}
    }
    public OnClientDisconnect(client) // такая же проверка при спауне игрока и при превращении его в человека
    {
    	if (g_IsNemesis[client])
    	{
    		g_IsNemesis[client] = false;
    		if (NemesisAura != INVALID_HANDLE)
    		{
    			for (new i = 1; i < MaxClients; i++)
    			{
    				new x;
    				if (g_IsNemesis[i])
    					x++;
    				if (!x)
    				{
    					KillTimer(NemesisAura);
    					NemesisAura = INVALID_HANDLE;
    				}
    			}
    		}
    	}
    }
    2)
    Код:
    new Handle:NemesisAura[MAXPLAYERS + 1];
    new bool:g_IsNemesis[MAXPLAYERS + 1];
    public ZR_OnClientInfected(client, attacker, bool:motherInfect, bool:respawnOverride, bool:respawn)
    {
    	if (!g_IsNemesis[client])
    		return;
    	if (NemesisAura[client] == INVALID_HANDLE)
    		NemesisAura[client] = CreateTimer(0.1, TimerAura, client, TIMER_REPEAT | TIMER_FLAG_NO_MAPCHANGE);
    }
    public Action:TimerAura(Handle:timer, any:data)
    {
    	static Float:origin[3];
    	GetEntPropVector(data, Prop_Data, "m_vecOrigin", origin);
    	TE_Start("Dynamic Light");
    	TE_WriteVector("m_vecOrigin", origin);
    	TE_WriteNum("r", цвет);
    	TE_WriteNum("g", цвет);
    	TE_WriteNum("b", цвет);
    	TE_WriteNum("exponent", 50);
    	TE_WriteFloat("m_fRadius", 50.0);
    	TE_WriteFloat("m_fTime", 2.0);
    	TE_WriteFloat("m_fDecay", 0.0);
    	TE_SendToAll();
    }
    public OnClientDisconnect(client) // такая же проверка при спауне игрока и при превращении его в человека, при убийстве таймер игрока удаляется
    {
    	if (g_IsNemesis[client])
    	{
    		g_IsNemesis[client] = false;
    		if (NemesisAura[client] != INVALID_HANDLE)
    		{
    			KillTimer(NemesisAura[client]);
    			NemesisAura[client] = INVALID_HANDLE;
    		}
    	}
    }
    3)У меня еще была идея создать динамический массив, и при инфецировании игрока, если g_IsNemesis[client] = true, заносить его индекс в этот массив, а при таймере (он был бы один) получать клиентов из массива и создавать на их месте временные энтити. А при убийстве или спауне, если g_IsNemesis[client] = true, находить индекс игрока в массиве с помощью FindValueInArray и удалять его, и проверять, если размер массива равен 0, то удалить таймер.
    Если вы знаете способ лучше, то, пожалуйста, опишите его.
     
  2. Reiko1231

    Reiko1231 AlexTheRegent

    Сообщения:
    237
    Симпатии:
    569
    В первом способе недочет в цикле фор:
    Код:
    for (new client = 1; client <= MaxClients; client++)
    Пропущено или равно, иначе для последнего клиента данный цикл не будет выполняться.

    По поводу задания - есть вариант с прикреплением свечения к игроку, там не нужны будут никакие таймеры, и не будет бликов\мерцаний. Вот пример с аптечкой - создается аптечка, потом к ней прикрепляется свечение, которое везде следует за ней:
    Код:
    	new iEntity = CreateEntityByName("prop_physics_override");
    	DispatchKeyValue(iEntity, "model", "models/items/healthkit.mdl");
    	DispatchKeyValueVector(iEntity, "origin", fOrigin);
    	DispatchKeyValue(iEntity, "solid", "6");
    	DispatchSpawn(iEntity);
    		
    	new iEnt = CreateEntityByName("light_dynamic");  
    	DispatchKeyValue(iEnt, "_light", "255 0 0");  
    	DispatchKeyValue(iEnt, "brightness", "10");  
    	DispatchKeyValueFloat(iEnt, "spotlight_radius", 360.0);  
    	DispatchKeyValueFloat(iEnt, "distance", 50.0);  
    	DispatchKeyValue(iEnt, "style", "0");
    	DispatchSpawn(iEnt);
    	TeleportEntity(iEnt, fOrigin, NULL_VECTOR, NULL_VECTOR);
    		
    	new String:szTarget[32];
    	Format(szTarget, sizeof(szTarget), "lighthealthkit_%d", iEntity);
    	DispatchKeyValue(iEntity, "targetname", szTarget);
    	SetVariantString(szTarget);
    	AcceptEntityInput(iEnt, "SetParent");
    	AcceptEntityInput(iEnt, "TurnOn");
     
    (admiral) нравится это.