122 lines
5.5 KiB
Lua
122 lines
5.5 KiB
Lua
require "Vehicles/Papa_Chad_Tank_Cannon"
|
|
require "Vehicles/Papa_Chad_Tank_Aim"
|
|
|
|
MTKViewpointTurrets = MTKViewpointTurrets or {}
|
|
local M = MTKViewpointTurrets
|
|
local seats = { [0] = "SeatFrontLeft", [1] = "SeatGunner", [2] = "SeatFrontRight", [3] = "SeatRearRight" }
|
|
local scope = nil
|
|
|
|
local function enabled()
|
|
return MTKViewpointCamera and MTKViewpointCamera.enabled()
|
|
end
|
|
|
|
local function allowed(player, vehicle, weapon)
|
|
return player == getPlayer() and not player:isDead()
|
|
and MTKViewpointCamera.captured() and getGameSpeed() > 0
|
|
and not (UIManager and UIManager.isMouseOverInventory and UIManager.isMouseOverInventory())
|
|
and seats[vehicle:getSeat(player)] == weapon.requiredSeat
|
|
and player:getCharacterActions():isEmpty()
|
|
end
|
|
|
|
function M.install()
|
|
-- These local adapters register their own wrappers at boot/start. Install
|
|
-- them first, then wrap the completed chain, regardless of event order.
|
|
if KFTFerret and KFTFerret.installClient then KFTFerret.installClient() end
|
|
if KLTLAV and KLTLAV.installClient then KLTLAV.installClient() end
|
|
if not tankAimSystemPC or not chooseWeaponPC or not ISCoordConversion then return end
|
|
|
|
if ISCoordConversion.ToWorld ~= M.toWorld then
|
|
local previousToWorld = ISCoordConversion.ToWorld
|
|
M.toWorld = function(x, y, z)
|
|
-- Only override conversions inside this turret update. The Ferret
|
|
-- and LAV wrappers otherwise overwrite our camera heading with a
|
|
-- floor pick (or the screen-centre isometric fallback).
|
|
if scope and scope.x then return scope.x, scope.y end
|
|
return previousToWorld(x, y, z)
|
|
end
|
|
ISCoordConversion.ToWorld = M.toWorld
|
|
end
|
|
|
|
if chooseWeaponPC ~= M.choose then
|
|
local previousChoose = chooseWeaponPC
|
|
M.choose = function(vehicle)
|
|
-- MTK still advances existing projectiles when weapon input is
|
|
-- blocked; no simulation callback is removed or duplicated.
|
|
if scope and scope.blocked then return nil end
|
|
return previousChoose(vehicle)
|
|
end
|
|
chooseWeaponPC = M.choose
|
|
end
|
|
|
|
if tankAimSystemPC ~= M.aim then
|
|
local previousAim = tankAimSystemPC
|
|
Events.OnPlayerUpdate.Remove(previousAim)
|
|
M.aim = function(player)
|
|
local vehicle = player and player:getVehicle()
|
|
if not enabled() or not vehicle then return previousAim(player) end
|
|
local weapon = chooseWeaponPC(vehicle)
|
|
if not weapon then return previousAim(player) end
|
|
|
|
local oldScope = scope
|
|
scope = { blocked = not allowed(player, vehicle, weapon) }
|
|
local oldDirection = nil
|
|
if not scope.blocked and isMouseButtonDown(1) then
|
|
local heading = MTKViewpointCamera.heading()
|
|
if type(heading) == "number" and heading == heading and math.abs(heading) < math.huge then
|
|
oldDirection = player:getDirectionAngle()
|
|
local rad = math.rad(heading)
|
|
scope.x = player:getX() + math.cos(rad) * 100
|
|
scope.y = player:getY() + math.sin(rad) * 100
|
|
player:setDirectionAngle(heading)
|
|
else
|
|
scope.blocked = true
|
|
end
|
|
end
|
|
|
|
-- Restore temporary input even if a dependency raises an error.
|
|
local ok, err = pcall(previousAim, player)
|
|
scope = oldScope
|
|
if oldDirection ~= nil then player:setDirectionAngle(oldDirection) end
|
|
if not ok then error(err) end
|
|
end
|
|
tankAimSystemPC = M.aim
|
|
Events.OnPlayerUpdate.Add(M.aim)
|
|
print("[MTKViewpointTurrets] MTK camera aiming registered; Ferret/LAV wrappers retained.")
|
|
end
|
|
|
|
if TankCursor and TankCursor.prerender ~= M.cursor then
|
|
local previousCursor = TankCursor.prerender
|
|
M.cursor = function(self)
|
|
if not enabled() then return previousCursor(self) end
|
|
-- MTK's two iso-projected textures cannot represent the 3D view.
|
|
-- A centred cross marks camera bearing; green means the turret
|
|
-- has caught up in yaw, not that ammunition or a hit is guaranteed.
|
|
local player = getPlayer()
|
|
local vehicle = player and player:getVehicle()
|
|
local weapon = vehicle and chooseWeaponPC(vehicle)
|
|
if not weapon or not allowed(player, vehicle, weapon) or not isMouseButtonDown(1) then return end
|
|
local heading = MTKViewpointCamera.heading()
|
|
if not heading then return end
|
|
local turret = turretAngles and turretAngles[vehicle:getId()]
|
|
local aligned = turret and math.abs(((turret - heading + 540) % 360) - 180) <= 2
|
|
local r, g, b = 1, 0.75, 0.25
|
|
if aligned then r, g, b = 0.3, 1, 0.4 end
|
|
local x = getCore():getScreenWidth() / 2 - self.x
|
|
local y = getCore():getScreenHeight() / 2 - self.y
|
|
self:drawRect(x - 9, y, 5, 1, 0.9, r, g, b)
|
|
self:drawRect(x + 4, y, 5, 1, 0.9, r, g, b)
|
|
self:drawRect(x, y - 9, 1, 5, 0.9, r, g, b)
|
|
self:drawRect(x, y + 4, 1, 5, 0.9, r, g, b)
|
|
end
|
|
TankCursor.prerender = M.cursor
|
|
end
|
|
end
|
|
|
|
Events.OnGameBoot.Add(M.install)
|
|
Events.OnGameStart.Add(M.install)
|
|
Events.OnGameStart.Add(function()
|
|
if not MTKViewpointCamera then
|
|
print("[MTKViewpointTurrets] Camera bridge unavailable. Enable this mod and approve its local JAR in ZombieBuddy, then fully restart the game.")
|
|
end
|
|
end)
|