script_name("Dynamic AntiHGF") script_author("Maku Kenesu") script_version("1.0") require "lib.moonloader" require "lib.sampfuncs" local inicfg = require "inicfg" local LABEL_PREFIX = "[AntiHGF] " local FULL_LABEL_PREFIX = "[AntiHGF by Maku Kenesu] " local CONFIG_DIR_FALLBACK = getWorkingDirectory() .. "\\config\\" local CONFIG_FILE_PATH = CONFIG_DIR_FALLBACK .. "AntiHGF.ini" if not doesDirectoryExist(CONFIG_DIR_FALLBACK) then createDirectory(CONFIG_DIR_FALLBACK) end if not doesFileExist(CONFIG_FILE_PATH) then local file = io.open(CONFIG_FILE_PATH, "w") file:write(" ") file:close() local defaultIni = inicfg.load({ Options = { isScriptEnabled = true, safeSecondsFromNow = 11, posX = 640, posY = 540, fontSize = 14, fontName = "Arial Bold", safeText = "SAFE TO HEAL", unsafeText = "NOT SAFE TO HEAL", safeColor = "008000", unsafeColor = "800000" } }, CONFIG_FILE_PATH) inicfg.save(defaultIni, CONFIG_FILE_PATH) end local configIni = inicfg.load(nil, CONFIG_FILE_PATH) inicfg.save(configIni, CONFIG_FILE_PATH) local COLOR_PRIMARY = "{FF8400}" local COLOR_ACCENT = "{FFC100}" local COLOR_WHITE = "{FFFFFF}" local COLOR_ALERT = "{FF2222}" local COLOR_SAFE = "{22FF22}" local wasPlayerHit = false local lastHitTimestamp = 0 local healSafeTimestamp = configIni.Options.safeSecondsFromNow local isFirstHitDetected = true local renderFontHandle = nil local textPosX = configIni.Options.posX or 640 local textPosY = configIni.Options.posY or 540 local fontSize = configIni.Options.fontSize or 14 local fontName = configIni.Options.fontName or "Arial Bold" local selectingPosition = false local cursorVisible = false configIni.Options.safeText = configIni.Options.safeText or "SAFE TO HEAL" configIni.Options.unsafeText = configIni.Options.unsafeText or "NOT SAFE TO HEAL" configIni.Options.safeColor = configIni.Options.safeColor or "008000" configIni.Options.unsafeColor = configIni.Options.unsafeColor or "800000" function main() while not isSampAvailable() do wait(100) end sampAddChatMessage(COLOR_PRIMARY .. FULL_LABEL_PREFIX .. COLOR_WHITE .. "Loaded successfully. " .. COLOR_ACCENT .. "Timer: " .. COLOR_WHITE .. configIni.Options.safeSecondsFromNow .. "s", -1) sampAddChatMessage(COLOR_PRIMARY .. FULL_LABEL_PREFIX .. COLOR_WHITE .. "Use " .. COLOR_ACCENT .. "/hgf.help" .. COLOR_WHITE .. " for commands.", -1) sampRegisterChatCommand("hgf", cmdToggleScript) sampRegisterChatCommand("hgf.help", cmdHelp) sampRegisterChatCommand("hgf.h", cmdMiniHelp) sampRegisterChatCommand("hgf.pos", cmdEnablePositionMode) sampRegisterChatCommand("hgf.size", cmdChangeFontSize) sampRegisterChatCommand("hgf.text", cmdChangeText) sampRegisterChatCommand("hgf.color", cmdChangeColor) sampRegisterChatCommand("hgf.font", cmdChangeFont) renderFontHandle = renderCreateFont(fontName, fontSize, 8) while true do wait(0) if configIni.Options.isScriptEnabled then detectGunfightHit() updateHealSafeTimer() end drawHealStatusText() if selectingPosition then handleMouseClickPlacement() end end end function renderfont(x, y, text, color) local black = 0xFF000000 renderFontDrawText(renderFontHandle, text, x + 1, y + 1, black) renderFontDrawText(renderFontHandle, text, x - 1, y + 1, black) renderFontDrawText(renderFontHandle, text, x + 1, y - 1, black) renderFontDrawText(renderFontHandle, text, x - 1, y - 1, black) renderFontDrawText(renderFontHandle, text, x, y, color) end function detectGunfightHit() local WEAPON_IDS = {22, 23, 24, 25, 27, 28, 29, 30, 31, 32, 33, 34} for _, weaponId in ipairs(WEAPON_IDS) do if hasCharBeenDamagedByWeapon(PLAYER_PED, weaponId) or isCharShooting(PLAYER_PED) then if isFirstHitDetected then sampAddChatMessage(COLOR_PRIMARY .. LABEL_PREFIX .. COLOR_ALERT .. configIni.Options.unsafeText, -1) addOneOffSound(0.0, 0.0, 0.0, 1053) isFirstHitDetected = false end lastHitTimestamp = os.time() healSafeTimestamp = lastHitTimestamp + configIni.Options.safeSecondsFromNow wasPlayerHit = true clearCharLastWeaponDamage(PLAYER_PED) break end end end function updateHealSafeTimer() local currentTime = os.time() if wasPlayerHit and currentTime >= healSafeTimestamp then wasPlayerHit = false isFirstHitDetected = true sampAddChatMessage(COLOR_PRIMARY .. LABEL_PREFIX .. COLOR_SAFE .. configIni.Options.safeText, -1) addOneOffSound(0.0, 0.0, 0.0, 1052) end end function drawHealStatusText() if not renderFontHandle then return end local displayText, displayColor if configIni.Options.isScriptEnabled then if wasPlayerHit then displayText = configIni.Options.unsafeText displayColor = tonumber("0xFF" .. configIni.Options.unsafeColor) else displayText = configIni.Options.safeText displayColor = tonumber("0xFF" .. configIni.Options.safeColor) end renderfont(textPosX, textPosY, displayText, displayColor) else renderfont(textPosX, textPosY, LABEL_PREFIX .. "Disabled", 0xFFAAAAAA) end if selectingPosition then renderfont(20, 20, LABEL_PREFIX .. "Click anywhere to set text position", 0xFFFFFF00) end end function showCursorState(show) if show then if not cursorVisible then showCursor(true) lockPlayerControl(true) cursorVisible = true end else if cursorVisible then showCursor(false) lockPlayerControl(false) cursorVisible = false end end end function handleMouseClickPlacement() showCursorState(true) if wasKeyPressed(VK_LBUTTON) then local mx, my = getCursorPos() if mx and my then textPosX, textPosY = mx, my configIni.Options.posX, configIni.Options.posY = mx, my inicfg.save(configIni, CONFIG_FILE_PATH) selectingPosition = false showCursorState(false) sampAddChatMessage(COLOR_PRIMARY .. LABEL_PREFIX .. COLOR_WHITE .. "Position saved at X: " .. COLOR_ACCENT .. mx .. COLOR_WHITE .. " Y: " .. COLOR_ACCENT .. my, -1) end end end function cmdEnablePositionMode() selectingPosition = not selectingPosition local stateText = selectingPosition and (COLOR_SAFE .. "Enabled") or (COLOR_ALERT .. "Disabled") sampAddChatMessage(COLOR_PRIMARY .. LABEL_PREFIX .. COLOR_WHITE .. "Position selection mode: " .. stateText, -1) if not selectingPosition then showCursorState(false) end end function cmdToggleScript() configIni.Options.isScriptEnabled = not configIni.Options.isScriptEnabled local statusText = configIni.Options.isScriptEnabled and (COLOR_SAFE .. "Enabled") or (COLOR_ALERT .. "Disabled") sampAddChatMessage(COLOR_PRIMARY .. LABEL_PREFIX .. COLOR_WHITE .. statusText, -1) inicfg.save(configIni, CONFIG_FILE_PATH) end function cmdChangeFontSize(arg) local size = tonumber(arg) if size and size > 5 and size <= 40 then configIni.Options.fontSize = size inicfg.save(configIni, CONFIG_FILE_PATH) renderFontHandle = renderCreateFont(configIni.Options.fontName, size, 8) sampAddChatMessage(COLOR_PRIMARY .. LABEL_PREFIX .. COLOR_WHITE .. "Font size set to " .. COLOR_ACCENT .. size, -1) else sampAddChatMessage(COLOR_PRIMARY .. LABEL_PREFIX .. COLOR_ALERT .. "Usage: " .. COLOR_ACCENT .. "/hgf.size [6-40]", -1) end end function cmdChangeFont(arg) if not arg or arg == "" then sampAddChatMessage(COLOR_PRIMARY .. LABEL_PREFIX .. COLOR_ALERT .. "Usage: " .. COLOR_ACCENT .. "/hgf.font [font name]", -1) return end configIni.Options.fontName = arg inicfg.save(configIni, CONFIG_FILE_PATH) renderFontHandle = renderCreateFont(arg, configIni.Options.fontSize, 8) sampAddChatMessage(COLOR_PRIMARY .. LABEL_PREFIX .. COLOR_WHITE .. "Font changed to " .. COLOR_ACCENT .. arg, -1) end function cmdChangeText(arg) if not arg or arg == "" then sampAddChatMessage(COLOR_PRIMARY .. LABEL_PREFIX .. COLOR_ALERT .. "Usage: " .. COLOR_ACCENT .. "/hgf.text [safe | unsafe] [your text]", -1) return end local t, text = arg:match("^(%S+)%s+(.+)$") if t and text then if t == "safe" then configIni.Options.safeText = text sampAddChatMessage(COLOR_PRIMARY .. LABEL_PREFIX .. COLOR_SAFE .. "Safe text updated: " .. COLOR_WHITE .. text, -1) elseif t == "unsafe" then configIni.Options.unsafeText = text sampAddChatMessage(COLOR_PRIMARY .. LABEL_PREFIX .. COLOR_ALERT .. "Unsafe text updated: " .. COLOR_WHITE .. text, -1) else sampAddChatMessage(COLOR_PRIMARY .. LABEL_PREFIX .. COLOR_ALERT .. "Use: " .. COLOR_ACCENT .. "/hgf.text safe [text]" .. COLOR_WHITE .. " or " .. COLOR_ACCENT .. "/hgf.text unsafe [text]", -1) return end inicfg.save(configIni, CONFIG_FILE_PATH) else sampAddChatMessage(COLOR_PRIMARY .. LABEL_PREFIX .. COLOR_ALERT .. "Usage: " .. COLOR_ACCENT .. "/hgf.text [safe | unsafe] [your text]", -1) end end function cmdChangeColor(arg) if not arg or arg == "" then sampAddChatMessage(COLOR_PRIMARY .. LABEL_PREFIX .. COLOR_ALERT .. "Usage: " .. COLOR_ACCENT .. "/hgf.color [safe | unsafe] [RRGGBB]", -1) return end local t, hex = arg:match("^(%S+)%s+([A-Fa-f0-9]+)$") if t and hex then if #hex ~= 6 then sampAddChatMessage(COLOR_PRIMARY .. LABEL_PREFIX .. COLOR_ALERT .. "Color must be 6-digit hex like " .. COLOR_ACCENT .. "FF2222", -1) return end if t == "safe" then configIni.Options.safeColor = hex sampAddChatMessage(COLOR_PRIMARY .. LABEL_PREFIX .. COLOR_SAFE .. "Safe color set to " .. COLOR_ACCENT .. hex, -1) elseif t == "unsafe" then configIni.Options.unsafeColor = hex sampAddChatMessage(COLOR_PRIMARY .. LABEL_PREFIX .. COLOR_ALERT .. "Unsafe color set to " .. COLOR_ACCENT .. hex, -1) else sampAddChatMessage(COLOR_PRIMARY .. LABEL_PREFIX .. COLOR_ALERT .. "Use: " .. COLOR_ACCENT .. "/hgf.color safe [RRGGBB]" .. COLOR_WHITE .. " or " .. COLOR_ACCENT .. "/hgf.color unsafe [RRGGBB]", -1) return end inicfg.save(configIni, CONFIG_FILE_PATH) else sampAddChatMessage(COLOR_PRIMARY .. LABEL_PREFIX .. COLOR_ALERT .. "Usage: " .. COLOR_ACCENT .. "/hgf.color [safe | unsafe] [RRGGBB]", -1) end end function cmdHelp() sampAddChatMessage(COLOR_WHITE .. "-------------- " .. COLOR_PRIMARY .. FULL_LABEL_PREFIX .. COLOR_WHITE .. "--------------", -1) sampAddChatMessage(COLOR_ACCENT .. "/hgf" .. COLOR_WHITE .. " - Enable/Disable script", -1) sampAddChatMessage(COLOR_ACCENT .. "/hgf.pos" .. COLOR_WHITE .. " - Click to choose text position", -1) sampAddChatMessage(COLOR_ACCENT .. "/hgf.size [6-40]" .. COLOR_WHITE .. " - Change font size", -1) sampAddChatMessage(COLOR_ACCENT .. "/hgf.font [font]" .. COLOR_WHITE .. " - Change font name", -1) sampAddChatMessage(COLOR_ACCENT .. "/hgf.text [safe | unsafe] [text]" .. COLOR_WHITE .. " - Change displayed text", -1) sampAddChatMessage(COLOR_ACCENT .. "/hgf.color [safe | unsafe] [RRGGBB]" .. COLOR_WHITE .. " - Change colors", -1) sampAddChatMessage(COLOR_ACCENT .. "/hgf.help" .. COLOR_WHITE .. " or " .. COLOR_ACCENT .. "/hgf.h" .. COLOR_WHITE .. " - Show help", -1) sampAddChatMessage(COLOR_WHITE .. "-----------------------------------------------------------------", -1) end function cmdMiniHelp() sampAddChatMessage(COLOR_ACCENT .. "/hgf" .. COLOR_WHITE .. ", /hgf.pos, /hgf.size, /hgf.font, /hgf.text, /hgf.color, /hgf.help", -1) end