script_name("SignCheck Reminder")
script_author("Maku Kenesu")
script_version("1.0")
require "lib.moonloader"
require "lib.sampfuncs"
local sampev = require "lib.samp.events"
local inicfg = require "inicfg"
local CONFIG_DIR = getWorkingDirectory() .. "\\config\\"
local CONFIG_FILE = CONFIG_DIR .. "SignCheckReminder.ini"
local settings = inicfg.load({
settings = {
posX = 0.02,
posY = 0.5,
sound = true
}
}, CONFIG_FILE)
local FONT = renderCreateFont("Arial", 13, 5)
local SCREEN_X, SCREEN_Y = getScreenResolution()
local COLOR_WHITE = 0xFFFFFFFF
local COLOR_GREEN = 0xFF00FF00
local COLOR_RED = 0xFFFF0000
local COLOR_LABEL = 0xFFADFF2F
local COLOR_BG = 0x80000000
local PADDING_X, PADDING_Y = 10, 6
local LABEL = "[SignCheck Reminder] "
local AUTHOR = "by Maku Kenesu"
local isTextVisible = true
local isSignActive = false
local isRedAlert = false
local isPaycheckReceived = false
local isPaycheckExpired = false
local isEditing = false
local signEndTime, redEndTime, payEndTime, expireEndTime, nextSoundTime = 0, 0, 0, 0, 0
local blinkTimer, blinkState = 0, true -- for blinking /SIGNCHECK
local function getPixelPosition()
return settings.settings.posX * SCREEN_X, settings.settings.posY * SCREEN_Y
end
local function saveSettings()
inicfg.save(settings, CONFIG_FILE)
end
local function sendChat(msg, color)
sampAddChatMessage(string.format("{%06X}%s{FFFFFF}%s", bit.band(COLOR_LABEL, 0xFFFFFF), LABEL, msg), -1)
end
local function startSignTimer()
isSignActive = true
isRedAlert = false
isPaycheckReceived = false
isPaycheckExpired = false
signEndTime = os.clock() + 300
nextSoundTime = os.clock() + 30
blinkTimer = os.clock() + 1
blinkState = true
end
local function stopSignTimer()
isSignActive = false
end
local function startRedAlert()
isRedAlert = true
isSignActive = false
isPaycheckReceived = false
isPaycheckExpired = false
redEndTime = os.clock() + 60
end
local function startPaycheckReceived()
isPaycheckReceived = true
isSignActive = false
isRedAlert = false
isPaycheckExpired = false
payEndTime = os.clock() + 60
end
local function startPaycheckExpired()
isPaycheckExpired = true
isSignActive = false
isRedAlert = false
isPaycheckReceived = false
expireEndTime = os.clock() + 60
end
local function drawSignText(text, x, y, color)
local width = renderGetFontDrawTextLength(FONT, text)
local height = 20
local boxWidth = width + (PADDING_X * 2)
local boxHeight = height + (PADDING_Y * 2)
renderDrawBox(x, y, boxWidth, boxHeight, COLOR_BG)
renderFontDrawText(FONT, text, x + PADDING_X, y + PADDING_Y, color)
end
local function togglePositionEdit()
isEditing = not isEditing
showCursor(isEditing)
if isEditing then
sendChat("Move mode enabled. Click top-left corner to set new position.", COLOR_LABEL)
else
sendChat("Move mode disabled.", COLOR_LABEL)
end
end
local function handlePositionEdit()
if wasKeyPressed(VK_LBUTTON) then
local mouseX, mouseY = getCursorPos()
settings.settings.posX = mouseX / SCREEN_X
settings.settings.posY = mouseY / SCREEN_Y
saveSettings()
sendChat(string.format("New position saved (%.2f, %.2f).", settings.settings.posX, settings.settings.posY), COLOR_LABEL)
togglePositionEdit()
end
end
local function toggleSound()
settings.settings.sound = not settings.settings.sound
saveSettings()
local state = settings.settings.sound and "enabled" or "disabled"
sendChat("Sound alerts " .. state .. ".", COLOR_LABEL)
end
local function showHelp()
sendChat("Available commands:", COLOR_LABEL)
sampAddChatMessage("/sr.pos - Move the reminder text.", -1)
sampAddChatMessage("/sr.sound - Toggle sound alerts.", -1)
sampAddChatMessage("/sr.help - Show this help message.", -1)
end
function sampev.onServerMessage(_, text)
if text:find("Sign the check to receive your paycheck.", 1, true) then
startSignTimer()
if settings.settings.sound then
lua_thread.create(function()
addOneOffSound(0.0, 0.0, 0.0, 1097)
wait(3500)
addOneOffSound(0.0, 0.0, 0.0, 1098)
end)
end
elseif text:find("________ BANK STATEMENT ________", 1, true) then
if settings.settings.sound then addOneOffSound(0.0, 0.0, 0.0, 1133) end
stopSignTimer()
startPaycheckReceived()
elseif text:find("* You haven't played long enough to obtain a paycheck.", 1, true) then
if settings.settings.sound then addOneOffSound(0.0, 0.0, 0.0, 1056) end
startRedAlert()
elseif text:find("Your paycheck code expired. Please remember to /signcheck next time.", 1, true) then
if settings.settings.sound then addOneOffSound(0.0, 0.0, 0.0, 1056) end
startPaycheckExpired()
elseif text:find("You have one minute left before your paycheck code expires. Please type /signcheck to get your paycheck.", 1, true) then
if settings.settings.sound then
lua_thread.create(function()
addOneOffSound(0.0, 0.0, 0.0, 1068)
wait(3500)
addOneOffSound(0.0, 0.0, 0.0, 1069)
end)
end
end
end
function main()
while not isSampAvailable() do wait(100) end
sampAddChatMessage(string.format("{%06X}%s%s {FFFFFF}- Use /sr.help for commands.", bit.band(COLOR_LABEL, 0xFFFFFF), LABEL, AUTHOR), -1)
sampRegisterChatCommand("sr.pos", togglePositionEdit)
sampRegisterChatCommand("sr.sound", toggleSound)
sampRegisterChatCommand("sr.help", showHelp)
while true do
wait(0)
local now = os.clock()
if isRedAlert and now > redEndTime then isRedAlert = false end
if isSignActive and now > signEndTime then stopSignTimer() end
if isPaycheckReceived and now > payEndTime then isPaycheckReceived = false end
if isPaycheckExpired and now > expireEndTime then isPaycheckExpired = false end
-- Blink logic
if isSignActive and now >= blinkTimer then
blinkState = not blinkState
blinkTimer = now + 1
end
if isSignActive and now >= nextSoundTime then
if settings.settings.sound then addOneOffSound(0.0, 0.0, 0.0, 1057) end
nextSoundTime = now + 60
end
if isTextVisible then
local posX, posY = getPixelPosition()
local color, text = COLOR_WHITE, "No Check to Sign"
if isSignActive then
color = blinkState and COLOR_GREEN or COLOR_WHITE
text = "/SIGNCHECK"
elseif isRedAlert then
color, text = COLOR_RED, "Missed Paycheck"
elseif isPaycheckReceived then
color, text = COLOR_GREEN, "Paycheck Received"
elseif isPaycheckExpired then
color, text = COLOR_RED, "Paycheck Expired"
end
drawSignText(text, posX, posY, color)
end
if isEditing then handlePositionEdit() end
end
end