Скриптер
Участник
Пользователь
- Сообщения
- 460
- Реакции
- 273
- Помог
- 9 раз(а)
- Ошибка
-
Ошибок нет, логи чисты
- ОС
- Linux
- Amx Mod X
-
AMX Mod X 1.9.0.5241 (http://www.amxmodx.org) Authors: David "BAILOPAN" Anderson, Pavol "PM OnoTo" Marko Felix "SniperBeamer" Geyer, Jonny "Got His Gun" Bergstrom Lukasz "SidLuke" Wlasinski, Christian "Basic-Master" Hammacher Borja "faluco" Ferrer, Scott "DS" Ehlert Compiled: Jan 30 2019 07:09:07 Built from: https://github.com/alliedmodders/amxmodx/commit/2110037 Build ID: 5241:2110037 Core mode: JIT+ASM32
C++
- Билд
-
Exe version 1.1.2.7/Stdio (cstrike) ReHLDS version: 3.4.0-dev+m Build date: 15:08:41 Oct 22 2018 (1654) Build from:
C++
- ReGamedll
-
ReGameDLL version: 5.7.0.322-dev Build date: 11:41:14 Jan 13 2019 Build from: https://github.com/s1lentq/ReGameDLL_CS/commit/7398bb7
C++
- Версия Metamod
-
Metamod-r v1.3.0.128, API (5:13) Metamod-r build: 17:47:54 Aug 24 2018 Metamod-r from: https://github.com/theAsmodai/metamod-r/commit/0cf2f70
C++
- Список метамодулей
-
description stat pend file vers src load unload [ 1] Reunion RUN - reunion_mm_i386.so v0.1.0.92 ini Start Never [ 2] ReAuthCheck RUN - reauthcheck_mm_i386.so v0.1.6 ini Start Never [ 3] AMX Mod X RUN - amxmodx_mm_i386.so v1.9.0.5241 ini ANY [ 4] Rechecker RUN - rechecker_mm_i386.so v2.5 ini ANY [ 5] VoiceTranscoder RUN - VoiceTranscoder.so v2017RC3 ini ANY [ 6] WHBlocker RUN - whblocker_mm_i386.so v1.5.696 ini ANY [ 7] ReSemiclip RUN - resemiclip_mm_i386.so v2.3.9 ini ANY [ 8] CStrike RUN - cstrike_amxx_i386.so v1.9.0.5241 pl3 ANY [ 9] CSX RUN - csx_amxx_i386.so v1.9.0.5241 pl3 ANY [10] MySQL RUN - mysql_amxx_i386.so v1.9.0.5241 pl3 ANY [11] FakeMeta RUN - fakemeta_amxx_i386.so v1.9.0.5241 pl3 ANY [12] ReAPI RUN - reapi_amxx_i386.so v5.8.0.165-dev pl3 ANY Never [13] Engine RUN - engine_amxx_i386.so v1.9.0.5241 pl3 ANY [14] Fun RUN - fun_amxx_i386.so v1.9.0.5241 pl3 ANY [15] Ham Sandwich RUN - hamsandwich_amxx_i386.so v1.9.0.5241 pl3 ANY 15 plugins, 15 running
C++
- Список плагинов
-
Currently loaded plugins: name version author file status [ 1] Admin Load 3.10.0 F@nt0M adminloader.amx running [ 2] FreshBans 1.4.0b kanagava fresh_bans.amxx running [ 3] Ping Checker 26.0.1 RC1 h1k3 ping_checker.am running [ 4] AFK Control ReNew 1.2(a) neygomon afk_control.amx running [ 5] Admin Chat 0.1 ./. hud_adminchat.a running [ 6] Spec Money Save 0.2 F@nt0M spec_money_save running [ 7] Deathrun: Core 1.1.4 Mistrick deathrun_core.a running [ 8] Checkpoints 0.8 Psycrow checkpoints.amx debug [ 9] Deathrun: Teleport Spo 1.0.2 Mistrick deathrun_telepo running [ 10] Deathrun: Buttons Cont 1.0.1 Mistrick deathrun_button running [ 11] Deathrun: Informer 1.0 Mistrick deathrun_inform running [ 12] Deathrun: Lifes 1.0 Mistrick deathrun_lifes. running [ 13] Deathrun: Modes 1.0.5 Mistrick deathrun_modes. running [ 14] Deathrun Mode: Buttons 1.0.0 Mistrick deathrun_mode_b running [ 15] Deathrun Mode: Duel 1.0.3 Mistrick deathrun_mode_d running [ 16] Deathrun Mode: Free 1.0.1 Mistrick deathrun_mode_f running [ 17] Deathrun Mode: Invis 1.0.1 Mistrick deathrun_mode_i running [ 18] Deathrun Mode: Skill M 1.0.1 Mistrick deathrun_mode_s running [ 19] Deathrun: Shop 0.1.2 Mistrick deathrun_shop.a running [ 20] unknown unknown unknown shop_item_lookt running [ 21] GameName Wins 0.7.1 w0w gamename_wins.a running [ 22] ReChecker Logging 1.0 custom rc_logging.amxx running [ 23] Music manager 1.0.3 .cpCTRL music.amxx running [ 24] WebTime 0.1 GoZombi Server timeleft_web.am running [ 25] Map Manager: Core 3.0.0 Mistrick map_manager_cor running [ 26] Map Manager: Scheduler 0.1.0 Mistrick map_manager_sch running [ 27] Map Manager: Rtv 0.0.4 Mistrick map_manager_rtv running [ 28] Map Manager: Nominatio 0.0.8 Mistrick map_manager_nom running [ 29] Map Manager: BlockList 0.0.3 Mistrick map_manager_blo running [ 30] Map Manager: Online so 0.0.2 Mistrick map_manager_onl running [ 31] Map Manager: Effects 0.0.8 Mistrick map_manager_eff running [ 32] Map Manager: Informer 0.0.5 Mistrick map_manager_inf running [ 33] Map Manager: Advanced 0.0.4 Mistrick map_manager_adv running [ 34] Chat Manager 1.1.1-11 Mistrick chatmanager.amx running [ 35] Chat Manager: Addon 0.0.4-70 Mistrick chatmanager_add running 35 plugins, 35 running
C++
- Автор плагина
- Psycrow
- Версия плагина
- 0.8
- Исходный код
-
/* https://next21.ru/2013/06/deathrun-чекпоинты/ */ #include <amxmodx> #include <reapi> #include <fakemeta_util> #include <deathrun_duel> #if AMXX_VERSION_NUM < 183 #include <colorchat> #include <dhudmessage> #endif #define PLUGIN "Checkpoints" #define VERSION "0.8" #define AUTHOR "Psycrow" #define MODEL_CHECKPOINT "models/agr/other/checkpoint.mdl" #define SOUND_CHECKPOINT "agr/other/checkpoint.wav" #define CLASSNAME_CHECKPOINT "checkpoint" #define MAX_CHECKPOINTS 32 #define TASK_SECONDS 40401 #define CHECKPOINT_RADIUS 45.0 #define CHECKPOINT_KEY 450893 #define CHAT_PREFIX "^4***" enum _:CvarList { CVAR_CHECKPOINT_REWARD, // common reward, 0 - none CVAR_CHECKPOINT_KOEF, // common reward multiplier CVAR_CHECKPOINT_FINISH_REWARD[3], // rewards for finish, 0 - none } new g_iCheckpointsNum, g_iCheckpoint[MAX_CHECKPOINTS], g_iWasChanged, g_iRoundEnd, g_iFinishedNum, g_iDuelStart, g_pCvars[CvarList] new g_fwdFinish; new g_iSecond[MAX_PLAYERS + 1]; new g_iPlrCompleted[MAX_PLAYERS + 1]; public plugin_precache() { precache_model(MODEL_CHECKPOINT) precache_sound(SOUND_CHECKPOINT) } public plugin_init() { register_plugin(PLUGIN, VERSION, AUTHOR) register_menucmd(register_menuid("Checkpoint Menu"), 1023, "handler_checkpoint_menu"); register_concmd("cp_origins", "show_checkpoint_menu", ADMIN_MAP, "-Open Checkpoint Spawn Menu") register_dictionary("deathrun_checkpoints.txt") g_pCvars[CVAR_CHECKPOINT_REWARD] = register_cvar("cv_checkpoint_reward", "300") g_pCvars[CVAR_CHECKPOINT_KOEF] = register_cvar("cv_checkpoint_money_koef", "1") g_pCvars[CVAR_CHECKPOINT_FINISH_REWARD][0] = register_cvar("cv_checkpoint_money_last_first", "2000") g_pCvars[CVAR_CHECKPOINT_FINISH_REWARD][1] = register_cvar("cv_checkpoint_money_last_second", "1000") g_pCvars[CVAR_CHECKPOINT_FINISH_REWARD][2] = register_cvar("cv_checkpoint_money_last_third", "500") g_fwdFinish = CreateMultiForward("cv_touch_last_checkpoint", ET_IGNORE, FP_CELL); load_checkpoints() } /*** Checkpoints functions ***/ load_checkpoints() { new szMap[48] get_mapname(szMap, 47) add(szMap, 47, ".ini") new szDirCfg[128], iDir, szFile[128] get_localinfo("amxx_configsdir", szDirCfg, 127) add(szDirCfg, 127, "/settings/checkpoints") iDir = open_dir(szDirCfg, szFile, 126) if (!iDir) { server_print("[%s] Checkpoints were not loaded", PLUGIN) return } while (next_file(iDir, szFile, 126)) { if (szFile[0] == '.') continue if (equali(szMap, szFile)) { format(szFile, 126, "%s/%s", szDirCfg, szFile) load_spawn(szFile) break } } close_dir(iDir) } load_spawn(const szFile[]) { new iFile = fopen(szFile, "rt") if (!iFile) { server_print("[%s] Unable to open %s.", PLUGIN, szFile) return } new szLineData[512], szOrigin[3][24], Float: fOrigin[3], szAngle[24], Float: fAngle while (iFile && !feof(iFile)) { fgets(iFile, szLineData, 511) if (!szLineData[0] || szLineData[0] == ';') continue parse(szLineData, szOrigin[0], 23, szOrigin[1], 23, szOrigin[2], 23, szAngle, 23) fOrigin[0] = str_to_float(szOrigin[0]) fOrigin[1] = str_to_float(szOrigin[1]) fOrigin[2] = str_to_float(szOrigin[2]) fAngle = str_to_float(szAngle) create_checkpoint(fOrigin, fAngle) } fclose(iFile) switch (g_iCheckpointsNum) { case 0: server_print("[%s] Checkpoints were not loaded", PLUGIN) case 1: server_print("[%s] Loaded one checkpoint", PLUGIN) default: server_print("[%s] Loaded %d checkpoints", PLUGIN, g_iCheckpointsNum) } set_finish_bodypart() } create_checkpoint(const Float: fOrigin[3], const Float: fAngle) { static iEventsRegistration if (g_iCheckpointsNum == MAX_CHECKPOINTS) return 1 new iEnt = rg_create_entity("info_target"); if (is_nullent(iEnt)) return 1 set_entvar(iEnt, var_origin, fOrigin) engfunc(EngFunc_SetModel, iEnt, MODEL_CHECKPOINT) set_entvar(iEnt, var_mins, Float: {-CHECKPOINT_RADIUS, -CHECKPOINT_RADIUS, -CHECKPOINT_RADIUS}) set_entvar(iEnt, var_maxs, Float: {CHECKPOINT_RADIUS, CHECKPOINT_RADIUS, CHECKPOINT_RADIUS}) new Float: fAngles[3] fAngles[1] = fAngle set_entvar(iEnt, var_angles, fAngles) set_entvar(iEnt, var_solid, SOLID_TRIGGER) set_entvar(iEnt, var_movetype, MOVETYPE_NOCLIP) set_entvar(iEnt, var_classname, CLASSNAME_CHECKPOINT) set_entvar(iEnt, var_impulse, CHECKPOINT_KEY) set_entvar(iEnt, var_framerate, 1.0) set_entvar(iEnt, var_colormap, random(256)) new Float: fGlow = 1.0 if (fGlow > 0.0) { new Float: fColors[3] fColors[0] = random(256) + 0.0 fColors[1] = random(256) + 0.0 fColors[2] = random(256) + 0.0 set_entvar(iEnt, var_renderfx, kRenderFxGlowShell) set_entvar(iEnt, var_renderamt, fGlow) set_entvar(iEnt, var_rendercolor, fColors) } g_iCheckpoint[g_iCheckpointsNum++] = iEnt if (!iEventsRegistration) { register_event("HLTV", "Event_HLTV", "a", "1=0", "2=0") RegisterHookChain(RG_RoundEnd, "RoundEnd", true); RegisterHookChain(RG_CBasePlayer_Spawn, "CBasePlayer_Spawn", true); SetTouch(iEnt, "Touch_Checkpoint"); if (g_iWasChanged) SetTouch(iEnt, ""); Event_HLTV() iEventsRegistration = 1 } return 0 } set_finish_bodypart() { if (!g_iCheckpointsNum) return for (new i = 0; i < g_iCheckpointsNum - 1; i++) { set_entvar(g_iCheckpoint[i], var_body, 0) set_entvar(g_iCheckpoint[i], var_skin, 0) } set_entvar(g_iCheckpoint[g_iCheckpointsNum - 1], var_body, 1) set_entvar(g_iCheckpoint[g_iCheckpointsNum - 1], var_skin, 1) } save_checkpoints() { new szDirCfg[128], szFile[128] get_localinfo("amxx_configsdir", szDirCfg, 127) add(szDirCfg, 127, "/settings/checkpoints") get_mapname(szFile, 127) format(szFile, 127, "%s/%s.ini", szDirCfg, szFile) if (!dir_exists(szDirCfg)) mkdir(szDirCfg) delete_file(szFile) if (!g_iCheckpointsNum) return 0 for (new i = 0; i < g_iCheckpointsNum; i++) { new szText[128], Float: fOrigin[3], Float: fAngles[3] get_entvar(g_iCheckpoint[i], var_origin, fOrigin) get_entvar(g_iCheckpoint[i], var_angles, fAngles) format(szText, 127, "^"%f^" ^"%f^" ^"%f^" ^"%f^"", fOrigin[0], fOrigin[1], fOrigin[2], fAngles[2]) write_file(szFile, szText, -1) } return 0 } /*** Menu handlers ***/ public show_checkpoint_menu(id) { if (get_user_flags(id) & ADMIN_MAP) display_checkpoint_menu(id) return PLUGIN_HANDLED } display_checkpoint_menu(const id) { new szMenu[512], iLen, iKeys = (1 << 9); iLen = formatex(szMenu, 511, "%L \d[%i|%i]^n^n", LANG_PLAYER, "MENU_HEADER", g_iCheckpointsNum, MAX_CHECKPOINTS) if (g_iCheckpointsNum != MAX_CHECKPOINTS) { iLen += formatex(szMenu[iLen], 511 - iLen, "\d[1] \w%L^n", id, "MENU_SPAWN") iKeys |= (1 << 0); } if (g_iCheckpointsNum) { iLen += formatex(szMenu[iLen], 511 - iLen, "\d[2] \w%L^n", id, "MENU_REMOVE") iLen += formatex(szMenu[iLen], 511 - iLen, "\d[3] \w%L^n", id, "MENU_REMOVE_ALL") iKeys |= (1 << 1|1 << 2); } if (g_iWasChanged) { iLen += formatex(szMenu[iLen], 511 - iLen, "^n\d[4] \w%L^n", id, "MENU_SAVE") iKeys |= (1 << 3); } iLen += formatex(szMenu[iLen], 511 - iLen, "^n\d[0] \w%L", id, "MENU_EXIT") show_menu(id, iKeys, szMenu, -1, "Checkpoint Menu") } public handler_checkpoint_menu(id, key) { if (key == 9) return PLUGIN_CONTINUE switch (key) { case 0: { new Float: fOrigin[3], Float: fAngles[3]; new iEnt = _fm_get_aim_origin(id, fOrigin); fOrigin[2] += CHECKPOINT_RADIUS; get_entvar(id, var_v_angle, fAngles) if (!create_checkpoint(fOrigin, fAngles[1])) { set_finish_bodypart() g_iWasChanged = 1 SetTouch(iEnt, ""); if (check_stuck(fOrigin, id)) client_print_color(id, print_team_red, "%s ^1%L", CHAT_PREFIX, LANG_PLAYER, "CP_CAN_STUCK") } } case 1: { SetTouch(g_iCheckpoint[--g_iCheckpointsNum], ""); rg_remove_entity(g_iCheckpoint[g_iCheckpointsNum]) if (g_iCheckpointsNum) set_finish_bodypart() g_iWasChanged = 1 } case 2: { for (new i = 0; i < g_iCheckpointsNum; i++) { SetTouch(g_iCheckpoint[i], ""); rg_remove_entity(g_iCheckpoint[i]) } g_iCheckpointsNum = 0 g_iWasChanged = 1 } case 3: { if (!save_checkpoints()) { client_print_color(id, print_team_red, "%s ^1%L", CHAT_PREFIX, LANG_PLAYER, "CP_SAVED") g_iWasChanged = 0 if (g_iCheckpointsNum) { for (new i = 0; i < g_iCheckpointsNum; i++) SetTouch(g_iCheckpoint[i], "Touch_Checkpoint"); } arrayset(g_iPlrCompleted, -1, 33) g_iFinishedNum = 0 } } } display_checkpoint_menu(id) return PLUGIN_CONTINUE } /*** Global events ***/ public client_disconnected(id) { g_iSecond[id] = 0; remove_task(id + TASK_SECONDS); g_iPlrCompleted[id] = -1; } public Event_HLTV() { g_iRoundEnd = 0 g_iFinishedNum = 0 arrayset(g_iPlrCompleted, -1, 33) for (new i = 1; i <= MaxClients; i++) { if (!is_user_connected(i)) continue; g_iSecond[i] = 0; remove_task(i + TASK_SECONDS); } } public RoundEnd(WinStatus: winStatus, ScenarioEventEndRound: scenarioEvent, Float: fDelay) { if (winStatus == WINSTATUS_CTS || winStatus == WINSTATUS_TERRORISTS || winStatus == WINSTATUS_DRAW) g_iRoundEnd = 1; } public CBasePlayer_Spawn(id) { g_iSecond[id] = 0; remove_task(id + TASK_SECONDS); if (get_member(id, m_iTeam) == TEAM_CT) set_task(1.0, "Task_Seconds", id + TASK_SECONDS, _, _, "b"); } public Task_Seconds(id) { id -= TASK_SECONDS; if (!is_user_connected(id) || !is_user_alive(id) || get_member(id, m_iTeam) != TEAM_CT) { remove_task(id + TASK_SECONDS); return; } g_iSecond[id]++; } public Touch_Checkpoint(const iEnt, const iPlayer) { static i, iPos if (g_iRoundEnd || get_entvar(iEnt, var_impulse) != CHECKPOINT_KEY) return HC_CONTINUE; if (g_iDuelStart) return HC_CONTINUE; for (i = 0; i < g_iCheckpointsNum; i++) { if (g_iCheckpoint[i] == iEnt) { iPos = i break } } if (g_iPlrCompleted[iPlayer] >= iPos || !is_user_alive(iPlayer)) return HC_CONTINUE; client_cmd(iPlayer, "spk %s", SOUND_CHECKPOINT) new iReward if (iPos == g_iCheckpointsNum - 1) { new playerName[32]; get_user_name(iPlayer, playerName, charsmax(playerName)); client_print_color(0, print_team_default, "^4*** ^1%L", iPlayer, "CP_FINISH_CHAT", playerName, ++g_iFinishedNum, g_iSecond[iPlayer]); new fmt[450]; formatex(fmt, charsmax(fmt), "%L", LANG_PLAYER, "CP_FINISH_HUD", g_iFinishedNum, g_iSecond[iPlayer]); replace_all(fmt, charsmax(fmt), "\n", "^n"); say_dhudmessage(0, 155, 155, 155, -1.0, 0.14, 4, fmt); if (g_iFinishedNum > 3) iReward = get_pcvar_num(g_pCvars[CVAR_CHECKPOINT_REWARD]) else iReward = get_pcvar_num(g_pCvars[CVAR_CHECKPOINT_FINISH_REWARD][g_iFinishedNum - 1]) new returnvalue; ExecuteForward(g_fwdFinish, returnvalue, iPlayer); } else { iReward = get_pcvar_num(g_pCvars[CVAR_CHECKPOINT_REWARD]) say_hudmessage(iPlayer, 155, 155, 155, -1.0, 0.78, 2, "%L", LANG_PLAYER, "CP_COMPLETE", iPos + 1, iReward); } if (iReward) rg_add_account(iPlayer, iReward) g_iPlrCompleted[iPlayer] = iPos return HC_CONTINUE; } public dr_duel_start(iPlayerCT, iPlayerTE) g_iDuelStart = 1 public dr_duel_finish() g_iDuelStart = 0 public dr_duel_canceled() g_iDuelStart = 0 stock _fm_get_aim_origin(index, Float:origin[3]) { new Float:start[3], Float:view_ofs[3]; pev(index, pev_origin, start); pev(index, pev_view_ofs, view_ofs); xs_vec_add(start, view_ofs, start); new Float:dest[3]; pev(index, pev_v_angle, dest); engfunc(EngFunc_MakeVectors, dest); global_get(glb_v_forward, dest); xs_vec_mul_scalar(dest, 9999.0, dest); xs_vec_add(start, dest, dest); engfunc(EngFunc_TraceLine, start, dest, 0, index, 0); get_tr2(0, TR_vecEndPos, origin); return get_tr2(0, TR_pHit); } stock say_hudmessage(const iIndex, const iRed, const iGreen, const iBlue, Float: fX = -1.0, Float: fY = -1.0, iHoldTime = 10, szMessage[], any:...) { new szMsg[512]; vformat(szMsg, charsmax(szMsg), szMessage, 9); new iMsgSync; if (!iMsgSync) iMsgSync = CreateHudSyncObj(); set_hudmessage(iRed, iGreen, iBlue, fX, fY, 0, 6.0, float(iHoldTime), 0.1, 0.2, -1); ShowSyncHudMsg(iIndex, iMsgSync, szMsg); } stock say_dhudmessage(const iIndex, const iRed, const iGreen, const iBlue, Float: fX = -1.0, Float: fY = -1.0, iHoldTime = 10, szMessage[], any:...) { new szMsg[512]; vformat(szMsg, charsmax(szMsg), szMessage, 9); set_dhudmessage(iRed, iGreen, iBlue, fX, fY, 0, 6.0, float(iHoldTime), 0.1, 0.2); show_dhudmessage(iIndex, szMsg); } stock rg_remove_entity(iEnt) { if (is_entity(iEnt)) { set_entvar(iEnt, var_flags, get_entvar(iEnt, var_flags) | FL_KILLME); set_entvar(iEnt, var_nextthink, get_gametime()); } } stock bool: check_stuck(const Float: fOrigin[3], const iPlayer) { static tr engfunc(EngFunc_TraceHull, fOrigin, fOrigin, 0, HULL_HUMAN, iPlayer, tr) if (!get_tr2(tr, TR_StartSolid) || !get_tr2(tr, TR_AllSolid)) return false return true }
C++
Немного подогнал под свои нужды, но от сюда сразу проблема (на скрине)
Проблема именно с финишем, с другими чекпоинтами все в порядке, соприкосновение - срабатывание кода, блок повторного срабатывания, если уже касался. С финишем же не так, блока повторного срабатывания будто нет, а он вроде как, есть.
Немного помудрив, решил проблему следующим способом:
Это (в функции create_checkpoint)
Заменив на это
До меня дошло что функция вызывалась всего 1 раз, на первую создаваемую ентити.
Стоит ли использовать
SetTouch
(reapi) вместо дефолтного Ham_Touch
который предлагает автор? (С реапи пока тоже непонятно, то работает, то нет.31 Мар 2019
Это (в функции create_checkpoint)
Код:
if (!iEventsRegistration)
{
register_event("HLTV", "Event_HLTV", "a", "1=0", "2=0")
RegisterHookChain(RG_RoundEnd, "RoundEnd", true);
RegisterHookChain(RG_CBasePlayer_Spawn, "CBasePlayer_Spawn", true);
- SetTouch(iEnt, "Touch_Checkpoint");
if (g_iWasChanged)
SetTouch(iEnt, "");
Event_HLTV()
iEventsRegistration = 1
}
C++
Код:
+ SetTouch(iEnt, "Touch_Checkpoint");
if (!iEventsRegistration)
{
register_event("HLTV", "Event_HLTV", "a", "1=0", "2=0")
RegisterHookChain(RG_RoundEnd, "RoundEnd", true);
RegisterHookChain(RG_CBasePlayer_Spawn, "CBasePlayer_Spawn", true);
if (g_iWasChanged)
SetTouch(iEnt, "");
Event_HLTV()
iEventsRegistration = 1
}
C++
Как это работало у Psycrow я так и не допер
(не смотрел старый код после своих правок, но у него функция регистрации тача была на том же месте
)


В этой теме было размещено решение! Перейти к решению.
Последнее редактирование: