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