script_name “g-meter”
script_author “plasma”
script_version “2.0”

local mad = require ‘MoonAdditions’
local memory = require “memory”

– Настройка отображения g-метра
local gMeterConfig = {
color = 0x00000000,
borderColor = 0xCCFF5544,
pointColor = 0xFF1100CC,
pointBorderColor = 0xFFFFFFFF,
borderSize = 4,
posX = 20,
posY = 320,
sizeX = 150,
sizeY = 130,
maxLongG = 3.0,
maxLatG = 6.0
}

– Переменные состояния
local state = {
sp1 = 0,
sp2 = 0,
acel = 0,
acelL = 0,
deltaTime = 0,
car = 0,
angZ = 0,
angZ2 = 0
}

local function getTimeScale()
return memory.getfloat(0xB7CB64, false)
end

local function updateDeltaTime()
while true do
local time1 = gameClock()
wait(0)
state.deltaTime = gameClock() - time1
end
end

local function getZAngle(vehicle)
return getCarHeading(vehicle)
end

local function calculateAcceleration()
state.sp2 = getCharSpeed(PLAYER_PED)
state.acel = ((state.sp2 - state.sp1) / state.deltaTime) / getTimeScale()
state.sp1 = state.sp2 – Обновляем sp1

state.angZ = getZAngle(state.car)
local radian = ((state.angZ - state.angZ2) / state.deltaTime) * 0.01745
state.acelL = (radian * state.sp2) / getTimeScale()
state.angZ2 = state.angZ – Обновляем angZ2
end

local function draw_text(str, x, y, r, g, b)
mad.draw_text(str, x, y, 1, 0.3, 0.6, mad.font_align.LEFT, 2000, true, false, r, g, b, 255, 1, 0, 30, 30, 30, 120)
end

local function drawGraphics()
local gx, gy, gSizeX, gSizeY, gBorderSize = gMeterConfig.posX, gMeterConfig.posY, gMeterConfig.sizeX, gMeterConfig.sizeY, gMeterConfig.borderSize
local halfX, halfY = gSizeX / 2, gSizeY / 2

local pointCenterX = gx + halfX + gBorderSize / 2
local pointCenterY = gy + halfY - gBorderSize

local maxX, maxY = gx + gSizeX, gy + gSizeY
local x = pointCenterX + (state.acelL / 9.8) * ((maxX - pointCenterX) / gMeterConfig.maxLatG)
local y = pointCenterY + (state.acel / 9.8) * ((maxY - pointCenterY) / gMeterConfig.maxLongG)

renderDrawBoxWithBorder(gx, gy, gSizeX, gSizeY, gMeterConfig.color, gBorderSize, gMeterConfig.borderColor)
renderDrawLine(gx + 1, gy + halfY - gBorderSize, gx + gSizeX, gy + halfY - gBorderSize, gBorderSize / 2, gMeterConfig.borderColor)
renderDrawLine(gx + halfX + gBorderSize, gy + 1, gx + halfX + gBorderSize, gy + gSizeY, gBorderSize / 2, gMeterConfig.borderColor)

x = math.max(gx + gBorderSize, math.min(x, maxX - gBorderSize))
y = math.max(gy + gBorderSize, math.min(y, maxY - gBorderSize))

renderDrawPolygon(x, y, 7, 7, 16, 0.0, gMeterConfig.pointBorderColor)
renderDrawPolygon(x, y, 5, 5, 16, 0.0, gMeterConfig.pointColor)

draw_text(string.format(“Lat: %.2f g”, state.acelL / 9.8), gx + halfX / 2, gy + gSizeY + gBorderSize, 255, 255, 255)
draw_text(string.format(“Long: %.2f g”, state.acel / 9.8), gx + gSizeX + gBorderSize * 2, gy + halfY, 255, 255, 255)
end

function main()
local threadTime = lua_thread.create(updateDeltaTime)
while true do
wait(0)
if isPlayerPlaying(PLAYER_HANDLE) and not isCharOnFoot(PLAYER_PED) then
state.car = getCarCharIsUsing(PLAYER_PED)
calculateAcceleration()
drawGraphics()
end
end
end


перепиши этот Lua код так чтобы он выглядел как этот: 


var gForces = {}

var gravity = streams.sensors.gravity
gravity = gravity >= 0 ? Math.max(0.1, gravity) : Math.min(-0.1, gravity)

for (var key in streams.sensors) {
gForces[key] = streams.sensors[key] / -gravity
}
frameCounter++
if (frameCounter == 200) {
frameCounter = 0
gxMin = 0.0
gxMax = 0.0
gyMin = 0.0
gyMax = 0.0
}

gxMax = Math.max(gxMax, gForces.gx2)
gxMin = Math.min(gxMin, gForces.gx2)
gyMax = Math.max(gyMax, gForces.gy2)
gyMin = Math.min(gyMin, gForces.gy2)
gxLargest = -gxMin > gxMax ? gxMin : gxMax
gyLargest = -gyMin > gyMax ? gyMin : gyMax

var px = gForces.gx2 * circleSize
var py = gForces.gy2 * -circleSize

ctx.clearRect(-100,-100,200,200)
// ctx.clearRect(0, 0, 300, 300)

// draw background circles
let circleBorder = 1.5
ctx.strokeStyle = “RGBA(0,0,0, 0.0)”
ctx.fillStyle = “RGBA(0,0,0, 0.35)”
ctx.lineWidth = circleBorder
ctx.beginPath()
ctx.arc(0,0,circleSizemaxG,0,2Math.PI,false)
ctx.fill()
ctx.stroke()
for (var i = 1; i <= maxG; i++) {
ctx.strokeStyle = “RGBA(63,63,63, 0.5)”
ctx.fillStyle = “RGBA(63,63,63, 0.0)”
ctx.lineWidth = circleBorder
ctx.beginPath()
ctx.arc(0,0,circleSizei-0.5circleBorder,0,2Math.PI,false)
ctx.fill()
ctx.stroke()
}

// draw background markers
ctx.strokeStyle = “RGBA(63,63,63, 0.5)”
ctx.lineWidth = 1
ctx.beginPath()
ctx.moveTo(-maxGcircleSize, 0)
ctx.lineTo(+maxGcircleSize, 0)
ctx.stroke()
ctx.beginPath()
ctx.moveTo(0,-maxGcircleSize)
ctx.lineTo(0,+maxGcircleSize)
ctx.stroke()

// draw min/max G ends
ctx.strokeStyle = “rgba(255, 165, 63, 1.0)”
ctx.lineWidth = 2
let size = 6
ctx.beginPath()
ctx.moveTo(gxLargest * circleSize, -size)
ctx.lineTo(gxLargest * circleSize, +size)
ctx.stroke()
ctx.beginPath()
ctx.moveTo(-size, gyLargest * -circleSize)
ctx.lineTo(+size, gyLargest * -circleSize)
ctx.stroke()

// draw min/max G lines
ctx.strokeStyle = “rgba(255, 165, 63, 1.0)”
ctx.lineWidth = 2
ctx.lineCap = “”
ctx.beginPath()
ctx.moveTo(Math.sign(gxLargest)0.5ctx.lineWidth, 0) // don’t draw from dead center, it’ll show a few ugly missing pixels
ctx.lineTo(gxLargest * circleSize, 0)
ctx.stroke()
ctx.beginPath()
ctx.moveTo(0,Math.sign(gyLargest)0.5ctx.lineWidth) // don’t draw from dead center, it’ll show a few ugly missing pixels
ctx.lineTo(0,gyLargest * -circleSize)
ctx.stroke()

// previous values (historic trail)
if(history.length > 0) {
ctx.lineWidth = 3
for(var i = 1; i < history.length; i++) {
ctx.beginPath()
ctx.moveTo(history[i-1][0], history[i-1][1])
let p = i/history.length
//ctx.lineWidth = 1 + (2i/p)
ctx.strokeStyle = “RGBA(255,255,255,” + p + “)”
ctx.lineTo(history[i][0], history[i][1])
ctx.stroke()
}
if(history.length > historySize) {
history.splice(0, 1)
}
var sx = Math.abs(history[history.length - 1][0] - px)
var sy = Math.abs(history[history.length - 1][1] - py)
if(sx > 2 || sy > 2) {
history.push([px, py])
}
} else {
history.push([px, py])
}

// draw 1g,2g labels
ctx.fillStyle = “RGBA(255,255,255,1)”
ctx.font = ‘12px “Lucida Console”, Monaco, monospace’
ctx.textAlign = “left”
ctx.textBaseline = “bottom”
for (var i = 1; i <= maxG; i++) {
ctx.fillText(i+“g”,-circleSizei/1.41421, circleSizei/1.41421)
}

// line to instant value
ctx.strokeStyle = “RGBA(255,255,255,0.5)”
ctx.lineWidth = 3
ctx.beginPath()
ctx.moveTo(gForces.gxcircleSize, gForces.gy-circleSize)
ctx.lineTo(px, py)
ctx.stroke()

// instant value
ctx.fillStyle = “rgba(0, 0, 0, 0.8)”
ctx.beginPath()
ctx.arc(gForces.gxcircleSize, gForces.gy-circleSize, 5, 0, 2Math.PI, false)
ctx.fill()
ctx.fillStyle = “rgba(255, 102, 0, 0.8)”
ctx.beginPath()
ctx.arc(gForces.gxcircleSize, gForces.gy*-circleSize, 4, 0, 2Math.PI, false)
ctx.fill()

// averaged value
ctx.fillStyle = “rgba(0, 0, 0, 1.0)”
ctx.beginPath()
ctx.arc(px, py, 7, 0, 2Math.PI, false)
ctx.fill()
ctx.fillStyle = “rgba(255, 102, 0, 1.0)”
ctx.beginPath()
ctx.arc(px, py, 5, 0, 2*Math.PI, false)
ctx.fill()

// averaged and max value labels, for x and y axis
ctx.fillStyle = “RGBA(255,255,255,1)”
ctx.font = ‘bolder 14px “Lucida Console”, Monaco, monospace’
ctx.textAlign = “right”
ctx.textBaseline = “top”
ctx.fillText(Math.abs(gForces.gx2).toFixed(2), 100-2, 0)
ctx.fillStyle = “rgba(255, 165, 63, 1.0)”
ctx.fillText(Math.abs(gxLargest).toFixed(2), 100-2, 13)

ctx.font = ‘bolder 14px “Lucida Console”, Monaco, monospace’
ctx.fillStyle = “RGBA(255,255,255,1)”
ctx.textAlign = “center”
ctx.textBaseline = “top”
ctx.fillText(Math.abs(gForces.gy2).toFixed(2), 0, -(100-2))
ctx.fillStyle = “rgba(255, 165, 63, 1.0)”
ctx.fillText(Math.abs(gyLargest).toFixed(2), 0, -(100-2-13))
})

scope.$on(‘app:resized’, function (event, data) {
c.width = data.width
c.height = data.height
ctx.setTransform(c.width/200, 0, 0, c.height/200, c.width/2,c.height/2)