forked from Simnation/Main
204 lines
6.9 KiB
Lua
204 lines
6.9 KiB
Lua
-- https://learn.microsoft.com/en-us/windows/win32/inputdev/virtual-key-codes
|
|
local sequenceKeys = {
|
|
{ code = 0x56, label = "V" },
|
|
{ code = 0x43, label = "C" },
|
|
{ code = 0x52, label = "R" },
|
|
{ code = 0x51, label = "Q" },
|
|
{ code = 0x47, label = "G" },
|
|
{ code = 0x45, label = "E" },
|
|
{ code = 0x58, label = "X" },
|
|
{ code = 0x59, label = "Y" },
|
|
{ code = 0x48, label = "H" },
|
|
{ code = 0x5A, label = "Z" },
|
|
}
|
|
|
|
local function DrawSecRect(x, y, w, h, r, g, b, a)
|
|
DrawRect(x + w * 0.5, y + h * 0.5, w, h, r, g, b, math.floor(a))
|
|
end
|
|
|
|
local function DrawSeqText(x, y, text, scale, r, g, b, a, outline)
|
|
SetTextFont(0)
|
|
SetTextScale(scale, scale)
|
|
SetTextColour(r, g, b, math.floor(a))
|
|
SetTextCentre(true)
|
|
if outline then
|
|
SetTextDropshadow(1, 0, 0, 0, 50)
|
|
SetTextOutline()
|
|
end
|
|
SetTextEntry("STRING")
|
|
AddTextComponentSubstringPlayerName(text)
|
|
DrawText(x, y)
|
|
end
|
|
|
|
local function DisablePlayerInput()
|
|
for group = 0, 2 do
|
|
DisableAllControlActions(group)
|
|
end
|
|
EnableControlAction(0, 1, true)
|
|
EnableControlAction(0, 2, true)
|
|
EnableControlAction(0, 241, true)
|
|
EnableControlAction(0, 242, true)
|
|
end
|
|
|
|
local function DrawMultiMinigameBoxes(multiSequences, currentStep, progress, pressedFlags, coords, label, infoText, alpha, boostPos)
|
|
alpha = alpha or 1
|
|
local onScreen, sx, sy = GetScreenCoordFromWorldCoord(coords.x, coords.y, coords.z)
|
|
if not onScreen then return end
|
|
|
|
local seqCount = #multiSequences
|
|
local boxW, boxH = 0.02, 0.03
|
|
local stepSpace = 0.002
|
|
local rowSpace = 0.003
|
|
|
|
local totalHeight = seqCount * boxH + (seqCount - 1) * rowSpace
|
|
local startY = sy - (totalHeight * 0.5)
|
|
|
|
local labelY = startY - 0.04
|
|
if label and label ~= "" then
|
|
DrawSeqText(sx, labelY, label, 0.18, 255, 255, 255, 255 * alpha, true)
|
|
end
|
|
local infoY = startY + totalHeight
|
|
if infoText and infoText ~= "" then
|
|
DrawSeqText(sx, infoY, infoText, 0.15, 255, 255, 255, 255 * alpha, true)
|
|
end
|
|
|
|
for s = 1, seqCount do
|
|
local sequence = multiSequences[s]
|
|
local seqSteps = #sequence
|
|
local rowY = startY + (s - 1) * (boxH + rowSpace)
|
|
local totalW = seqSteps * boxW + (seqSteps - 1) * stepSpace
|
|
local rowStartX = sx - (totalW * 0.5)
|
|
local cStep = currentStep[s]
|
|
local cProgress = progress[s]
|
|
local rowPressed = pressedFlags[s]
|
|
|
|
for i = 1, seqSteps do
|
|
local bx = rowStartX + (i - 1) * (boxW + stepSpace)
|
|
if rowPressed[i] then
|
|
DrawSecRect(bx, rowY - boxH * 0.5, boxW, boxH, 108, 240, 156, 180 * alpha)
|
|
elseif i == cStep then
|
|
DrawSecRect(bx, rowY - boxH * 0.5, boxW, boxH, 0, 0, 0, 180 * alpha)
|
|
|
|
local fillW = boxW * cProgress
|
|
if boostPos and boostPos + 0.1 > cProgress then
|
|
DrawSecRect(bx + boxW * boostPos, rowY - boxH * 0.5, boxW * 0.1, boxH, 108, 255, 156, 75 * alpha)
|
|
end
|
|
|
|
DrawSecRect(bx, rowY - boxH * 0.5, fillW, boxH, 108, 240, 156, 180 * alpha)
|
|
else
|
|
DrawSecRect(bx, rowY - boxH * 0.5, boxW, boxH, 0, 0, 0, 180 * alpha)
|
|
end
|
|
|
|
local stepData = sequence[i]
|
|
local textX = bx + boxW * 0.5
|
|
local textY = rowY - boxH * 0.5 + 0.005
|
|
local labelText = stepData.label or "??"
|
|
local tScale = 0.3 - (0.022 * #labelText)
|
|
if tScale < 0.18 then tScale = 0.18 end
|
|
DrawSeqText(textX, textY, labelText, tScale, 255, 255, 255, 255 * alpha, false)
|
|
end
|
|
end
|
|
end
|
|
|
|
function HoldSequenceMinigame(coords, sequenceCount, length, timePerInput, allowSkips, label, infoText)
|
|
sequenceCount = math.max(1, sequenceCount)
|
|
|
|
local seed = GetGameTimer()
|
|
local multiSequences = {}
|
|
for s = 1, sequenceCount do
|
|
local seq = {}
|
|
for i = 1, length do
|
|
seq[i] = sequenceKeys[math.random(#sequenceKeys)]
|
|
end
|
|
multiSequences[s] = seq
|
|
end
|
|
|
|
local currentStep = {}
|
|
local progress = {}
|
|
local pressedFlags = {}
|
|
for s = 1, sequenceCount do
|
|
currentStep[s] = 1
|
|
progress[s] = 0.0
|
|
pressedFlags[s] = {}
|
|
for i = 1, length do
|
|
pressedFlags[s][i] = false
|
|
end
|
|
end
|
|
|
|
local finished = false
|
|
local prevTime = nil
|
|
|
|
while not finished do
|
|
Citizen.Wait(0)
|
|
|
|
if IsRawKeyDown(0x1B) or IsRawKeyDown(0x08) then
|
|
return false
|
|
end
|
|
|
|
DisablePlayerInput()
|
|
|
|
local boostPos
|
|
if sequenceCount == 1 and allowSkips then
|
|
math.randomseed(seed .. currentStep[1])
|
|
boostPos = math.random(5, 8) / 10
|
|
end
|
|
|
|
DrawMultiMinigameBoxes(multiSequences, currentStep, progress, pressedFlags, coords, label, infoText, 1, boostPos)
|
|
|
|
local allDone = true
|
|
for s = 1, sequenceCount do
|
|
if currentStep[s] <= length then
|
|
allDone = false
|
|
break
|
|
end
|
|
end
|
|
if allDone then
|
|
finished = true
|
|
else
|
|
local now = GetGameTimer()
|
|
if not prevTime then
|
|
prevTime = now
|
|
end
|
|
local deltaMS = now - prevTime
|
|
prevTime = now
|
|
|
|
for s = 1, sequenceCount do
|
|
if currentStep[s] <= length then
|
|
local stepData = multiSequences[s][currentStep[s]]
|
|
local correctKey = stepData.code
|
|
if IsRawKeyDown(correctKey) then
|
|
local fillSpeed = deltaMS / timePerInput
|
|
progress[s] = progress[s] + fillSpeed
|
|
if progress[s] >= 1.0 then
|
|
progress[s] = 1.0
|
|
pressedFlags[s][currentStep[s]] = true
|
|
currentStep[s] = currentStep[s] + 1
|
|
progress[s] = 0.0
|
|
end
|
|
else
|
|
if boostPos and progress[s] >= boostPos + 0.02 and progress[s] <= boostPos + 0.12 then
|
|
progress[s] = 1.0
|
|
pressedFlags[s][currentStep[s]] = true
|
|
currentStep[s] = currentStep[s] + 1
|
|
progress[s] = 0.0
|
|
else
|
|
progress[s] = 0
|
|
end
|
|
end
|
|
end
|
|
end
|
|
end
|
|
end
|
|
|
|
local endDuration = 300
|
|
local endTime = GetGameTimer() + endDuration
|
|
while GetGameTimer() < endTime do
|
|
Citizen.Wait(0)
|
|
DisablePlayerInput()
|
|
local alpha = math.max(0, (endTime - GetGameTimer()) / endDuration)
|
|
|
|
DrawMultiMinigameBoxes(multiSequences, currentStep, progress, pressedFlags, coords, label, infoText, alpha)
|
|
end
|
|
|
|
return true
|
|
end
|