Проблема с таймером и проверкой.
Sunday
Дата: Воскресенье, 13.01.2013, 14:58:54 | Сообщение # 1
Сообщений: 186
Репутация: 24 [ +/- ]
Вопрос такой, бывает что когда игрок покупает невидимость то по истечнию времени она не вырубается и он так и бегает до конца карты с ней, так же и с бессмертием... Подскажите как обезопасить код от подобного? В основном лог ругается на CreateTimer. // ------------------------------------------------------------- * // *** Невидимость *** * // ------------------------------------------------------------- * Код
else if ( strcmp(info,"option11") == 0 ) { { ActionMenu(client); if (g_iCredits[client] >= 10) { if (IsPlayerAlive(client)) { SetEntityRenderMode(client, RENDER_TRANSCOLOR); SetEntityRenderColor(client, 255, 255, 255, 0); CreateTimer(30.0, invisibility_A, client); g_iCredits[client] -= 10; PrintToChat(client, "[SM] \x01Вы купили Невидимость на 30 секунд! \x04[10 кр]. \x01Осталось \x04%i кр.", g_iCredits[client]); } else { PrintToChat(client, "[SM] \x01Вы должны быть живым, что бы воспользоваться магазином."); } } else { PrintToChat(client, "[SM] \x01Кредитов: \x04%i. \x04(Не хватает кредитов. Нужно 10)", g_iCredits[client]); } } }
Код
public Action:invisibility_A(Handle:timer, any:client) { if (!IsPlayerAlive(client) || IsFakeClient(client)) { return; } SetEntityRenderColor(client, 255, 255, 255, 255); PrintToChat(client, "[SM] \x04Невидимость закончилось!"); }
// ------------------------------------------------------------- * // *** Бессмертие *** * // ------------------------------------------------------------- * Код
else if ( strcmp(info,"option12") == 0 ) { { ActionMenu(client); if (g_iCredits[client] >= 30) { if (IsPlayerAlive(client)) { SetEntProp(client, Prop_Data, "m_takedamage", 0); CreateTimer(10.0, Command_GodOff, client); g_iCredits[client] -= 30; PrintToChat(client, "[SM] \x01Вы купили Бессмертие на 10 секунд! \x04[30 кр]. \x01Осталось \x04%i кр.", g_iCredits[client]); } else { PrintToChat(client, "[SM] \x01Вы должны быть живым, что бы воспользоваться магазином."); } } else { PrintToChat(client, "[SM] \x01кредита(ов): \x04%i. \x04(Не хватает кредитов. Нужно 30)", g_iCredits[client]); } } } } }
Код
public Action: Command_GodOff(Handle:timer, any:client) { if (!IsPlayerAlive(client) || IsFakeClient(client)) { return; } SetEntProp(client, Prop_Data, "m_takedamage", 2); PrintToChat(client, "Бессмертие закончилось!"); }
Scarface_slv
Дата: Воскресенье, 13.01.2013, 15:12:19 | Сообщение # 2
Сообщений: 737
Репутация: 61 [ +/- ]
Нужно сохранять Handle таймера в индексе игрока, есть же урок:
Код
#include <sourcemod> new Handle:wS_Timer[MAXPLAYERS+1]; public OnClientPutInServer(client) { // Сохраняем Handle таймера wS_Timer[client] = CreateTimer(15.0, wS_Hello, client); } // Если игрок покидает сервер, не увидев приветствие, то убиваем таймер. public OnClientDisconnect(client) { if (wS_Timer[client] != INVALID_HANDLE) { KillTimer(wS_Timer[client]); wS_Timer[client] = INVALID_HANDLE; } } public Action:wS_Hello(Handle:timer, any:client) { // Приветствуем через чат PrintToChat(client, "Hello, %N!", client); // Сбрасываем Handle таймера на INVALID_HANDLE, чтобы знать, что активного таймера НЕТ. wS_Timer[client] = INVALID_HANDLE; }
Сообщение отредактировал Scarface_slv - Воскресенье, 13.01.2013, 15:12:57
Sunday
Дата: Воскресенье, 13.01.2013, 15:23:41 | Сообщение # 3
Сообщений: 186
Репутация: 24 [ +/- ]
Я читал эту тему и понял иначе, что если ты создаешь хандл то надо убивать таймер а если исползуешь в массиве то не надо... СпасибоScarface_slv , сейчас попоробую сделать так и потестирую на валидность.
Scarface_slv
Дата: Воскресенье, 13.01.2013, 17:17:48 | Сообщение # 4
Сообщений: 737
Репутация: 61 [ +/- ]
Можно и без этого наверно, просто если игрок купит и выйдет то в логах сервера будут ошибки)
Sunday
Дата: Воскресенье, 13.01.2013, 19:08:53 | Сообщение # 5
Сообщений: 186
Репутация: 24 [ +/- ]
Цитата (Scarface_slv )
Можно и без этого наверно, просто если игрок купит и выйдет то в логах сервера будут ошибки)
Спасибо, сделал по твоему совету, на сервере уже работает и пока что ни одной ошибки в логах. Я там еще проверку поставил, а то если умирал игрок при выполнении функции отключения, то невидимость оставалась до конца раунда: Код
public Action:invisibility_A(Handle:timer, any:client) { if (!IsPlayerAlive(client)) { SetEntityRenderColor(client, 255, 255, 255, 255); } SetEntityRenderColor(client, 255, 255, 255, 255); PrintToChat(client, "[SM] \x04Невидимость закончилось!"); Timer_invis[client] = INVALID_HANDLE; }
По идеи вроде случаи все предусмотрены, если игрок выйдет например или дисконнект то таймер просто убьет себя. Код
public OnClientDisconnect(client) { if (Timer_invis[client] != INVALID_HANDLE) { KillTimer(Timer_invis[client]); Timer_invis[client] = INVALID_HANDLE; } }
Сообщение отредактировал Sunday - Воскресенье, 13.01.2013, 19:18:38