Указать на ошибки

Hejter

xor ebx, ebx
Сообщения
1,759
Реакции
393
Делаю голод для паблика. Оффтоп
Хотелось бы узнать чего не хватает в моем коде или сделано не так. Вообщем оптимизировать его.
PHP:
#pragma semicolon 1

#include <sdktools>

/* Спасибо Zipcore - макросы */
#define LoopIngameClients(%1) for(int %1=1;%1<=MaxClients;++%1)\
if(IsClientInGame(%1))

#define start_hunger 100 // Сколько давать ед. голода при спавне?
#define minus_hunger 2 // Кол-во ед. снятия голода

new p_hunger[MAXPLAYERS + 1]; // Голод -+
new bool:b_hunger[MAXPLAYERS + 1]; // Голод true/false

Handle g_hHunger = null;
ConVar g_cvCheckHunger;
new Float:g_fCheckHunger;

public OnPluginStart(){
	HookEvent("player_spawn", PlayerSpawn);
	HookEvent("player_death", PlayerDeath);
	
	g_cvCheckHunger = CreateConVar("sm_check_hunger", "5.0", "Отрезок времени через которое игроку будет отнимать голод.");
	HookConVarChange(g_cvCheckHunger, ConVar_Callback);
	g_fCheckHunger = GetConVarFloat(g_cvCheckHunger);
	
	HookEvent("round_start", RoundStart);
	HookEvent("round_end", RoundEnd);
}

public ConVar_Callback(Handle:cvar, const String:oldVal[], const String:newVal[])
{
	if (cvar == g_cvCheckHunger)
	{
		g_fCheckHunger = GetConVarFloat(g_cvCheckHunger);
		
		if(g_hHunger != null)
			CloseHandle(g_hHunger);
		
		g_hHunger = CreateTimer(g_fCheckHunger, Timer_CheckHunger, 0, TIMER_REPEAT);
	}
}

public RoundStart(Handle:event, const String:name[], bool:dontBroadcast){
	g_hHunger = CreateTimer(g_fCheckHunger, Timer_CheckHunger, 0, TIMER_REPEAT);
}

public RoundEnd(Handle:event, const String:name[], bool:dontBroadcast){
	if(g_hHunger != null)
	{
		KillTimer(g_hHunger);
		g_hHunger = null;
	}
}

public Action:Timer_CheckHunger(Handle:timer)
{
	CheckHunger();
	
	return Plugin_Continue;
}

CheckHunger()
{
	LoopIngameClients(client)
	{		
		Hunger(client);
	}
}

Hunger(client)
{
	if (IsClientInGame(client) && IsPlayerAlive(client) && b_hunger[client])
	{
		if (b_hunger[client] == true)
		{
			if (p_hunger[client] > 0)
			{
				p_hunger[client] -= minus_hunger;
				PrintHintText(client, "Голод %d", p_hunger[client]);
			}
			else if (p_hunger[client] <= 0)
			{
				ForcePlayerSuicide(client);
				b_hunger[client] = false;
			}
		}	
	}
}

public OnClientDisconnect(client){
	Info(client);
}

/* Спасибо AlmazON - убиваем глобальный таймер, если все игроки вышли с сервера */
public OnClientDisconnect_Post(client)
{
	for (new i = 1; i <= MaxClients; ++i)
	{
		if (IsClientInGame(i)) return;
	}
	if(g_hHunger != null)
	{
		KillTimer(g_hHunger);
		g_hHunger = null;
	}
}

public Info(client){
	p_hunger[client] = 0;
	b_hunger[client] = false;
}

public PlayerDeath(Handle:event, const String:name[], bool:dontBroadcast){
	new client = GetClientOfUserId(GetEventInt(event, "userid"));
	
	if(IsClientInGame(client) && !IsFakeClient(client))
	{
		p_hunger[client] = 0;
		b_hunger[client] = false;
	}
}

public PlayerSpawn(Handle:event, const String:name[], bool:dontBroadcast){
	new client = GetClientOfUserId(GetEventInt(event, "userid")); 
	
	if(IsClientInGame(client) && IsPlayerAlive(client))
	{
		p_hunger[client] = start_hunger;
		b_hunger[client] = true;
		/* if (p_hunger[client] == start_hunger)
		{
			HungerTimer[client] = CreateTimer(minus_hunger_timer, hunger_timer, GetClientUserId(client), TIMER_REPEAT);
			b_hunger[client] = true;
		} */
	}
}
 
Последнее редактирование:

Черная вдова

Участник
Сообщения
2,795
Реакции
670
У тебя фугкция Info используется 1 раз ? Или я не заметил, вобщем если 1 раз тогда незачем делать ее
На спавне и смерти игрока надо использовать ид игрока который соспавнился/умер а не цикл по всем игрокам
В конце 2 раза чекаешь hunger причем в 2 оформлениях

Добавлено через 1 минуту
О ты код обновил

Добавлено через 3 минуты
Ну вот ты исправил про цикл, а вот таймер как всегда на 1 игрока :D
 
Последнее редактирование:

Hejter

xor ebx, ebx
Сообщения
1,759
Реакции
393
У тебя фугкция Info используется 1 раз ? Или я не заметил, вобщем если 1 раз тогда незачем делать ее
На спавне и смерти игрока надо использовать ид игрока который соспавнился/умер а не цикл по всем игрокам
В конце 2 раза чекаешь hunger причем в 2 оформлениях

Добавлено через 1 минуту
О ты код обновил

Добавлено через 3 минуты
Ну вот ты исправил про цикл, а вот таймер как всегда на 1 игрока :D
Запостил старую версию, которая более менее работала.


Уже поправил эту ошибку. Сейчас таймер под циклом.
 
Последнее редактирование:

AlmazON

Не путать с самим yand3xmail
Сообщения
5,099
Реакции
2,755
Вообщем оптимизировать его
PHP:
#pragma semicolon 1

#include <sdktools>

#define start_hunger 100 // Сколько давать ед. голода при спавне?
#define minus_hunger 2 // Кол-во ед. снятия голода
#define minus_hunger_timer 5.0 // Промежуток снятие голода

new p_hunger[MAXPLAYERS + 1];
new bool:b_hunger[MAXPLAYERS + 1];

new Handle:HungerTimer[MAXPLAYERS + 1];

public OnPluginStart(){
    HookEvent("player_spawn", PlayerSpawn);
    HookEvent("player_death", PlayerDeath);
}

public OnClientDisconnect(client){
    p_hunger[client] = 0;
    b_hunger[client] = false;
    func_killtimer(client);
}

public PlayerDeath(Handle:event, const String:name[], bool:dontBroadcast){
    OnClientDisconnect(GetClientOfUserId(GetEventInt(event, "userid")));
}

public PlayerSpawn(Handle:event, const String:name[], bool:dontBroadcast){
    new client = GetClientOfUserId(GetEventInt(event, "userid"));
    func_killtimer(client);
	p_hunger[client] = start_hunger;
	HungerTimer[client] = CreateTimer(minus_hunger_timer, hunger_timer, client, TIMER_REPEAT);
	b_hunger[client] = true;
}

public Action:hunger_timer(Handle:timer, any:client){
   if (b_hunger[client])
    {
        if (b_hunger[client] == true)
        {
            if (p_hunger[client] > 0)
            {
                p_hunger[client] -= minus_hunger;
                PrintHintText(client, "Голод %d", p_hunger[client]);
            }
            else if (p_hunger[client] <= 0)
            {
                ForcePlayerSuicide(client);
                b_hunger[client] = false;
            }
            return Plugin_Continue;
        }
		
		HungerTimer[client] = INVALID_HANDLE;
    } 
    return Plugin_Stop;
}

func_killtimer(client){
    if(HungerTimer[client]) 
    { 
        KillTimer(HungerTimer[client]); 
        HungerTimer[client] = INVALID_HANDLE; 
    }
}
Глобальные переменные вообще не нужны в данный момент... Короче, как будет "голодоутоляющее", тогда и стоит думать о них.
В целом, код ни о чём... Не успел возродиться - уже голод через несколько секунд. Глупо.
 

Hejter

xor ebx, ebx
Сообщения
1,759
Реакции
393
Короче, как будет "голодоутоляющее", тогда и стоит думать о них.
Уже есть. Просто пока что они не используются здесь, они пишутся в другом плагине, потом перенесу в этот. Оффтоп
Пост обновил первый.
 

Черная вдова

Участник
Сообщения
2,795
Реакции
670
PHP:
#pragma semicolon 1

#include <sdktools>

#define start_hunger 100 // Сколько давать ед. голода при спавне?
#define minus_hunger 2 // Кол-во ед. снятия голода
#define minus_hunger_timer 5.0 // Промежуток снятие голода

new p_hunger[MAXPLAYERS + 1];
new bool:b_hunger[MAXPLAYERS + 1];

new Handle:HungerTimer[MAXPLAYERS + 1];

public OnPluginStart(){
    HookEvent("player_spawn", PlayerSpawn);
    HookEvent("player_death", PlayerDeath);
}

public OnClientDisconnect(client){
    p_hunger[client] = 0;
    b_hunger[client] = false;
    func_killtimer(client);
}

public PlayerDeath(Handle:event, const String:name[], bool:dontBroadcast){
    OnClientDisconnect(GetClientOfUserId(GetEventInt(event, "userid")));
}

public PlayerSpawn(Handle:event, const String:name[], bool:dontBroadcast){
    new client = GetClientOfUserId(GetEventInt(event, "userid"));
	p_hunger[client] = start_hunger;
	HungerTimer[client] = CreateTimer(minus_hunger_timer, hunger_timer, client, TIMER_REPEAT);
	b_hunger[client] = true;
}

public Action:hunger_timer(Handle:timer, any:client){
   if (b_hunger[client])
    {
        if (b_hunger[client] == true)
        {
            if (p_hunger[client] > 0)
            {
                p_hunger[client] -= minus_hunger;
                PrintHintText(client, "Голод %d", p_hunger[client]);
            }
            else if (p_hunger[client] <= 0)
            {
                ForcePlayerSuicide(client);
                b_hunger[client] = false;
            }
            return Plugin_Continue;
        }
		
		HungerTimer[client] = INVALID_HANDLE;
    } 
    return Plugin_Stop;
}

func_killtimer(client){
    if(HungerTimer[client]) 
    { 
        KillTimer(HungerTimer[client]); 
        HungerTimer[client] = INVALID_HANDLE; 
    }
}
Глобальные переменные вообще не нужны в данный момент... Короче, как будет "голодоутоляющее", тогда и стоит думать о них.
В целом, код ни о чём... Не успел возродиться - уже голод через несколько секунд. Глупо.

Ну ты пади хочешь раунды по 3 часа что бы голод не сразу был
 

The End Is Near...

Russian Roulette
Сообщения
874
Реакции
691
глянул мельком.. может игрок умереть не на севере? а быть мертвым при спавне?

3. p_hunger[client] = start_hunger;
if (p_hunger[client] == start_hunger) О_О

4. таймер можно не глобально заюзать, наверное, если игрок мертв, не пройдет проверку, стопнится в конце - хотя хз, см п. 6

5. else if (p_hunger[client] <= 0) лишнее, else достаточно

6. а если игрок выжил в раунде? таймер не остановится, так? причем запустится новый

ну это лишь поверхностно, надо смотреть логику, лень, хотя какая там логика, банально запускаешь таймер и отнимаешь значение

алмазон, тута все ок?)
PHP:
public Action:hunger_timer(Handle:timer, any:client){
   if (b_hunger[client])
    {
        if (b_hunger[client] == true)
        {
            if (p_hunger[client] > 0)
            {
                p_hunger[client] -= minus_hunger;
                PrintHintText(client, "Голод %d", p_hunger[client]);
            }
            else if (p_hunger[client] <= 0)
            {
                ForcePlayerSuicide(client);
                b_hunger[client] = false;
            }
            return Plugin_Continue;
        }
        
        HungerTimer[client] = INVALID_HANDLE;
    } 
    return Plugin_Stop;
}

upd. зачем вообще переменная b_hunger??
 

AlmazON

Не путать с самим yand3xmail
Сообщения
5,099
Реакции
2,755
хочешь раунды по 3 часа что бы голод не сразу был
Попробуй поиграть с таким голодом. Да с ним и взрыва бомбы не дождёшься, все перемрут!
Я потом забил, так как:
Глобальные переменные вообще не нужны в данный момент
 

Hejter

xor ebx, ebx
Сообщения
1,759
Реакции
393
Попробуй поиграть с таким голодом. Да с ним и взрыва бомбы не дождёшься, все перемрут!

Конкретно голод будет отнимать опр. кол-во ед. в X секунд.
Это лишь сейчас минимум времени стоит.
И плагин не конкретно для паблик серверов, а для всех, вообще расчитывал на Hunger Games мод.

И можно ведь добавить Если игрок убил кого-то то +X ед. к голоду.

Я в оффтопе писал, что код мусорка и возможно кому то нужен будет.

Добавлено через 2 минуты
6. а если игрок выжил в раунде? таймер не остановится, так? причем запустится новый
И как мне тогда его убивать? Если таймер глобальный.

Добавлено через 3 минуты
Я забил, так как:
Они уже нужны. Т.к после голода я начну писать инвентарь или условие получение голода.
Кроме голода будет и жажда.
 
Последнее редактирование:

The End Is Near...

Russian Roulette
Сообщения
874
Реакции
691
И как мне тогда его убивать? Если таймер глобальный.
как, как, также, как и обычный

upd. знаешь самую главную свою ошибку? ты стараешься сделать все сразу, с использованием всяких переменных, типа вот, плагин получился большой, осталось за малым, но тебе это мешает, мешает в каком плане, первое, это отвлекает, второе, ты просто путаешься, не можешь уследить, где, что изменилось, ну это на мой взгляд
 

Hejter

xor ebx, ebx
Сообщения
1,759
Реакции
393
если ты таймер оставишь глобальный, то получается, когда он работает - "голод" отнимается, или другая логика нужна?

Ну да такая логика.

Добавлено через 46 секунд
upd. знаешь самую главную свою ошибку? ты стараешься сделать все сразу, с использованием всяких переменных, типа вот, плагин получился большой, осталось за малым, но тебе это мешает, мешает в каком плане, первое, это отвлекает, второе, ты просто путаешься, не можешь уследить, где, что изменилось, ну это на мой взгляд
В точку.
 
Последнее редактирование:

The End Is Near...

Russian Roulette
Сообщения
874
Реакции
691
если работает, значит Таймер != INVALID_HANDLE, ведь после окончания таймер делаем = INVALID_HANDLE, останется проверить, везде ли все ок, везде ли переменные на своих местах, ну и тому подобное
 

Hejter

xor ebx, ebx
Сообщения
1,759
Реакции
393
если работает, значит Таймер != INVALID_HANDLE, ведь после окончания таймер делаем = INVALID_HANDLE, останется проверить, везде ли все ок, везде ли переменные на своих местах, ну и тому подобное

Чем отличается != null от != INVALID_HANDLE?
Глянь первый пост темы (код). Там таймер вроде как убивается
PHP:
if(g_hTimer != null)
			CloseHandle(g_hTimer);

Добавлено через 12 минут
если работает, значит Таймер != INVALID_HANDLE, ведь после окончания таймер делаем = INVALID_HANDLE, останется проверить, везде ли все ок, везде ли переменные на своих местах, ну и тому подобное

Не вижу смысла это делать. А если игрок умирает, мне что таймер придется убивать? Проще уж тогда булем.
 
Последнее редактирование:

AlmazON

Не путать с самим yand3xmail
Сообщения
5,099
Реакции
2,755

R1KO

fuck society
Сообщения
9,457
Реакции
7,786
  • Команда форума
  • #20
Hejter, с чего бы им взяться ?
 
Сверху Снизу