Intial Commit

This commit is contained in:
2026-10-27 17:27:44 -04:00
parent 1fa6e14bde
commit 5743c34a21
49 changed files with 1454 additions and 0 deletions
Binary file not shown.

After

Width:  |  Height:  |  Size: 118 KiB

@@ -0,0 +1,123 @@
require "KLT_LAV"
require "TimedActions/KLT_ReloadLAV"
require "Vehicles/Papa_Chad_Tank_Cannon"
local F = KLTLAV
local characterVariables = {
"M2_idle", "M2_360Anim", "M2_045Anim", "M2_090Anim", "M2_135Anim",
"M2_180Anim", "M2_225Anim", "M2_270Anim", "M2_315Anim",
}
function F.installClient()
if F.clientInstalled then return end
if not weaponConfig or not weaponConfig.M41_76mm
or not chooseWeaponPC or not tankAimSystemPC then
print("[KI5LAVTurret] MTK turret API unavailable; controls not installed.")
return
end
local profile = {}
for key, value in pairs(weaponConfig.M41_76mm) do profile[key] = value end
profile.requiredPart = F.weaponPart
profile.requiredSeat = "SeatGunner" -- MTK's label for index 1, not a renamed seat.
profile.requiredItem = F.ammoType
profile.requiredItemHE = F.heAmmoType
profile.coax = false
profile.sound = "HRSys_LAV300_90mm_Fire"
profile.soundEnd = "HRSys_LAV300_90mm_End"
profile.rotationTime = 10
profile.shotsPerMinute = 12
profile.startHeight = 0.7
profile.penetrationMM = 150
profile.soundTurret = "Turret_Electre"
profile.soundTurretCooldown = 0.25
weaponConfig[F.weaponPart] = profile
F.profile = profile
-- Keep AP damage unchanged. HE uses precisely the tank profile's explosion
-- radius, flash radius and damage, with MTK's existing explosion code.
local heProfile = {}
for key, value in pairs(profile) do heProfile[key] = value end
heProfile.penetrationMM = weaponConfig.M41_76mm.penetrationMM
F.heProfile = heProfile
local originalChoose = chooseWeaponPC
chooseWeaponPC = function(vehicle)
if F.isLAV(vehicle) then
if not F.inputBlocked and F.weaponReady(vehicle) and not F.pendingReload[getPlayer()] then
local part = vehicle:getPartById(F.weaponPart)
local container = part and part:getItemContainer()
if container and container:containsType(F.heAmmoType) then return heProfile end
return profile
end
return nil
end
return originalChoose(vehicle)
end
local originalAim = tankAimSystemPC
Events.OnPlayerUpdate.Remove(originalAim)
tankAimSystemPC = function(player)
local vehicle = player and player:getVehicle()
if not F.isLAV(vehicle) then return originalAim(player) end
local gunner = F.isGunner(vehicle, player) and player == getPlayer() and not player:isDead()
local overInventory = UIManager and UIManager.isMouseOverInventory
and UIManager.isMouseOverInventory()
-- Still call MTK so its existing projectiles continue to advance. A nil
-- weapon prevents input/state changes from driver or non-local updates.
F.inputBlocked = not gunner or overInventory or getGameSpeed() == 0
if F.inputBlocked then
originalAim(player)
F.inputBlocked = false
return
end
local oldDirection = player:getDirectionAngle()
local oldSneaking = player:isSneaking()
local oldVariables = {}
for _, name in ipairs(characterVariables) do oldVariables[name] = player:getVariableString(name) end
local aiming = isMouseButtonDown(1) and player:getCharacterActions():isEmpty()
if aiming then
-- ToWorld also uses the installed Viewpoint mouse bridge when active.
-- Scaled mouse coordinates are required by the base-game conversion.
local x, y = ISCoordConversion.ToWorld(getMouseXScaled(), getMouseYScaled(), player:getZ() + profile.startHeight)
if x and y then
local dx, dy = x - player:getX(), y - player:getY()
if dx * dx + dy * dy > 0.0001 then
player:setDirectionAngle(math.deg(math.atan2(dy, dx)))
end
end
end
local weapon = vehicle:getPartById(F.weaponPart)
local container = weapon and weapon:getItemContainer()
local round = aiming and isMouseButtonDown(0) and container and (container:FindAndReturn(F.heAmmoType) or container:FindAndReturn(F.ammoType))
originalAim(player)
if round and isClient() and not container:contains(round) then
sendRemoveItemFromContainer(container, round)
end
-- Keep DAMN's existing seated pose instead of MTK's exposed M2 gunner pose.
player:setDirectionAngle(oldDirection)
player:setSneaking(oldSneaking)
for _, name in ipairs(characterVariables) do
if oldVariables[name] and oldVariables[name] ~= "" then
player:setVariable(name, oldVariables[name])
else
player:clearVariable(name)
end
end
if aiming and turretAngles[vehicle:getId()] and not isClient() then
local hull = calculateVehicleRotation(vehicle:getAngleX(), vehicle:getAngleY(), vehicle:getAngleZ())
local relative = (hull - turretAngles[vehicle:getId()] + 360) % 360
F.savePose(vehicle, F.poseForAngle(relative))
end
end
Events.OnPlayerUpdate.Add(tankAimSystemPC)
F.clientInstalled = true
print("[KI5LAVTurret] Gunner controls registered with Military Tool Kit.")
end
Events.OnGameBoot.Add(F.installClient)
Events.OnGameStart.Add(F.installClient)
@@ -0,0 +1,85 @@
require "TimedActions/ISBaseTimedAction"
require "KLT_LAV"
KLT_ReloadLAV = ISBaseTimedAction:derive("KLT_ReloadLAV")
local L = KLTLAV
function KLT_ReloadLAV:isValid()
if isClient() or not L.isGunner(self.vehicle, self.character) or not L.weaponReady(self.vehicle) then return false end
local gun = self.vehicle:getPartById(L.weaponPart)
local storage = self.vehicle:getPartById(L.storagePart)
return gun == self.gun and storage == self.storage and storage:getInventoryItem() ~= nil
and storage:getCondition() > 0 and gun:getItemContainer() == self.breech
and storage:getItemContainer() == self.source and self.breech:isEmpty()
and self.source:contains(self.round) and L.isAmmoType(self.round:getFullType())
end
function KLT_ReloadLAV:start()
self.character:getEmitter():playSound("Turret_Reload_Open")
end
function KLT_ReloadLAV:clearPending()
if L.pendingReload[self.character] == self then L.pendingReload[self.character] = nil end
end
function KLT_ReloadLAV:stop()
self:clearPending()
ISBaseTimedAction.stop(self)
end
function KLT_ReloadLAV:forceCancel()
self:clearPending()
end
function KLT_ReloadLAV:perform()
-- Validate again: leaving the seat, losing the round or loading another
-- shell during the action must never create or move ammunition.
if self:isValid() then
self.source:Remove(self.round)
self.breech:AddItem(self.round)
self.character:getEmitter():playSound("Turret_Reload_Close")
end
self:clearPending()
ISBaseTimedAction.perform(self)
end
function KLT_ReloadLAV:new(character, vehicle, gun, storage, round)
local o = ISBaseTimedAction.new(self, character)
o.vehicle = vehicle
o.gun = gun
o.storage = storage
o.source = storage:getItemContainer()
o.breech = gun:getItemContainer()
o.round = round
o.maxTime = 300 -- about five seconds before character modifiers
o.stopOnWalk = true
o.stopOnRun = true
o.stopOnAim = false -- pendingReload blocks firing while the player holds aim
return o
end
function L.queueReload(character)
local vehicle = character and character:getVehicle()
if not L.isGunner(vehicle, character) or not L.weaponReady(vehicle) or L.pendingReload[character] then return false end
if isClient() then character:Say("LAV reload prototype currently supports single-player."); return false end
local gun = vehicle:getPartById(L.weaponPart)
local storage = vehicle:getPartById(L.storagePart)
local source = storage and storage:getItemContainer()
local breech = gun and gun:getItemContainer()
if not source or not breech or not breech:isEmpty() then return false end
-- Match MTK tank reload priority: HE first when both types are stored.
local round = source:FindAndReturn(L.heAmmoType) or source:FindAndReturn(L.ammoType)
if not round then character:Say("No 90 mm AP or HE shells in LAV ammunition storage."); return false end
local action = KLT_ReloadLAV:new(character, vehicle, gun, storage, round)
if not action:isValid() then return false end
L.pendingReload[character] = action
ISTimedActionQueue.add(action)
return true
end
Events.OnKeyPressed.Add(function(key)
if key == Keyboard.KEY_R and getGameSpeed() > 0
and not (UIManager and UIManager.isMouseOverInventory and UIManager.isMouseOverInventory()) then
L.queueReload(getSpecificPlayer(0))
end
end)
@@ -0,0 +1,19 @@
require "KLT_LAV"
local L = KLTLAV
Events.OnClientCommand.Add(function(module, command, player, args)
if module ~= "turret_sync" or command ~= "syncAnim" or not args then return end
if type(args.vehicleID) ~= "number" or type(args.animID) ~= "string" then return end
local value = tonumber(args.animID)
if not value or value % 2 ~= 0 or value < 2 or value > 360 then return end
local vehicle = getVehicleById(args.vehicleID)
if L.isGunner(vehicle, player) then L.savePose(vehicle, string.format("%03d", value)) end
end)
require "Items/ProceduralDistributions"
local supplies = ProceduralDistributions.list.ArmyStorageAmmunition
if supplies and supplies.items then
for _, ammoType in ipairs({L.ammoType, L.heAmmoType}) do
local present = false
for i = 1, #supplies.items, 2 do if supplies.items[i] == ammoType then present = true end end
if not present then table.insert(supplies.items, ammoType); table.insert(supplies.items, 3) end
end
end
@@ -0,0 +1,113 @@
KLTLAV = KLTLAV or {}
local L = KLTLAV
L.scriptName = "Base.84gageV300fsv"
L.weaponPart = "KLT_LAV90"
L.storagePart = "KLT_LAVAmmo"
L.ammoType = "KLT.Shell90AP"
L.heAmmoType = "KLT.Shell90HE"
L.pendingReload = L.pendingReload or {}
function L.isAmmoType(fullType)
return fullType == L.ammoType or fullType == L.heAmmoType
end
function L.isLAV(vehicle)
return vehicle ~= nil and vehicle:getScriptName() == L.scriptName
end
function L.isGunner(vehicle, character)
return L.isLAV(vehicle) and character ~= nil and not character:isDead()
and character:getVehicle() == vehicle and vehicle:getSeat(character) == 1
end
function L.AmmoAccess(vehicle, part, character)
return L.isGunner(vehicle, character)
end
function L.BreechAccess(vehicle, part, character)
-- The reload action alone inserts one round. Storage remains accessible.
return false
end
function L.InitGloveBox(vehicle, part)
part:setModelVisible("BaseV300FSV", false)
part:setModelVisible("InteriorV3002", false)
end
function L.InitTurret(vehicle, part)
local pose = part:getModData().kltPose or vehicle:getModData().turretAnimID or "002"
vehicle:getModData().turretAnimID = pose
part:setModelVisible("Default", true)
vehicle:playPartAnim(part, pose)
local glove = vehicle:getPartById("GloveBox")
if glove then L.InitGloveBox(vehicle, glove) end
end
function L.InitInterior(vehicle, part)
-- One animated model per part. B42 updates each ModelInfo against the
-- first ModelInfo for its part; two independent players on Turrent would
-- clear the owner's track pointer and leak its frozen pose tracks.
part:setModelVisible("Default", true)
end
function L.CreateGunnerDoor(vehicle, part)
Vehicles.Create.Door(vehicle, part)
part:setModelVisible("KLT_RigLink", true)
end
function L.InitGunnerDoor(vehicle, part)
Vehicles.Init.Door(vehicle, part)
part:setModelVisible("KLT_RigLink", true)
end
local function initializePart(vehicle, part)
local data = part:getModData()
if not data.kltInitialized then
if not part:getInventoryItem() then
VehicleUtils.createPartInventoryItem(part)
part:setCondition(100)
end
data.kltInitialized = 1
end
end
L.InitWeapon = initializePart
L.InitStorage = initializePart
function L.weaponReady(vehicle)
if not L.isLAV(vehicle) then return false end
local part = vehicle:getPartById(L.weaponPart)
return part ~= nil and part:getInventoryItem() ~= nil and part:getCondition() > 0
end
function L.poseForAngle(angle)
local pose = math.floor(math.floor((angle % 360) + 0.5) / 2) * 2 + 2
if pose > 360 then pose = 2 end
return string.format("%03d", pose)
end
function L.savePose(vehicle, pose)
local part = vehicle:getPartById("Turrent")
if not part then return end
vehicle:getModData().turretAnimID = pose
if part:getModData().kltPose ~= pose then
part:getModData().kltPose = pose
if isServer() then vehicle:transmitPartModData(part) end
end
end
function L.patchScript()
local script = getScriptManager():getVehicle(L.scriptName)
if not script then print("[KI5LAVTurret] LAV FSV script unavailable."); return false end
if script:getPartById(L.weaponPart) then return true end
if not script:getPartById("WindowGunnerHatch") or not script:getPartById("GloveBox")
or not script:getPartById("DoorRearLeft") or not script:getPartById("V300fsvViewports") then
print("[KI5LAVTurret] Unexpected LAV FSV layout; adapter not applied.")
return false
end
-- Merge only the named parts. Loaded() would rescale finalized physics.
script:Load("84gageV300fsv", require "KLT_LAVPatch")
print("[KI5LAVTurret] LAV FSV parts applied (v0.1.2).")
return true
end
Events.OnGameBoot.Add(L.patchScript)
Events.OnInitGlobalModData.Add(L.patchScript)
@@ -0,0 +1,240 @@
return [=[
{
part GloveBox { lua { create = Vehicles.Create.Default, init = KLTLAV.InitGloveBox, } }
part Turrent
{
category = nodisplay,
area = SeatRearLeft,
model Default { file = KLT_LAVTurret, scale = 1.0, offset = 0 0 0, rotate = 0 0 0, }
lua { create = KLTLAV.InitTurret, init = KLTLAV.InitTurret, }
anim 002 { anim = KLT_LAVYaw_002, animate = FALSE, }
anim 004 { anim = KLT_LAVYaw_004, animate = FALSE, }
anim 006 { anim = KLT_LAVYaw_006, animate = FALSE, }
anim 008 { anim = KLT_LAVYaw_008, animate = FALSE, }
anim 010 { anim = KLT_LAVYaw_010, animate = FALSE, }
anim 012 { anim = KLT_LAVYaw_012, animate = FALSE, }
anim 014 { anim = KLT_LAVYaw_014, animate = FALSE, }
anim 016 { anim = KLT_LAVYaw_016, animate = FALSE, }
anim 018 { anim = KLT_LAVYaw_018, animate = FALSE, }
anim 020 { anim = KLT_LAVYaw_020, animate = FALSE, }
anim 022 { anim = KLT_LAVYaw_022, animate = FALSE, }
anim 024 { anim = KLT_LAVYaw_024, animate = FALSE, }
anim 026 { anim = KLT_LAVYaw_026, animate = FALSE, }
anim 028 { anim = KLT_LAVYaw_028, animate = FALSE, }
anim 030 { anim = KLT_LAVYaw_030, animate = FALSE, }
anim 032 { anim = KLT_LAVYaw_032, animate = FALSE, }
anim 034 { anim = KLT_LAVYaw_034, animate = FALSE, }
anim 036 { anim = KLT_LAVYaw_036, animate = FALSE, }
anim 038 { anim = KLT_LAVYaw_038, animate = FALSE, }
anim 040 { anim = KLT_LAVYaw_040, animate = FALSE, }
anim 042 { anim = KLT_LAVYaw_042, animate = FALSE, }
anim 044 { anim = KLT_LAVYaw_044, animate = FALSE, }
anim 046 { anim = KLT_LAVYaw_046, animate = FALSE, }
anim 048 { anim = KLT_LAVYaw_048, animate = FALSE, }
anim 050 { anim = KLT_LAVYaw_050, animate = FALSE, }
anim 052 { anim = KLT_LAVYaw_052, animate = FALSE, }
anim 054 { anim = KLT_LAVYaw_054, animate = FALSE, }
anim 056 { anim = KLT_LAVYaw_056, animate = FALSE, }
anim 058 { anim = KLT_LAVYaw_058, animate = FALSE, }
anim 060 { anim = KLT_LAVYaw_060, animate = FALSE, }
anim 062 { anim = KLT_LAVYaw_062, animate = FALSE, }
anim 064 { anim = KLT_LAVYaw_064, animate = FALSE, }
anim 066 { anim = KLT_LAVYaw_066, animate = FALSE, }
anim 068 { anim = KLT_LAVYaw_068, animate = FALSE, }
anim 070 { anim = KLT_LAVYaw_070, animate = FALSE, }
anim 072 { anim = KLT_LAVYaw_072, animate = FALSE, }
anim 074 { anim = KLT_LAVYaw_074, animate = FALSE, }
anim 076 { anim = KLT_LAVYaw_076, animate = FALSE, }
anim 078 { anim = KLT_LAVYaw_078, animate = FALSE, }
anim 080 { anim = KLT_LAVYaw_080, animate = FALSE, }
anim 082 { anim = KLT_LAVYaw_082, animate = FALSE, }
anim 084 { anim = KLT_LAVYaw_084, animate = FALSE, }
anim 086 { anim = KLT_LAVYaw_086, animate = FALSE, }
anim 088 { anim = KLT_LAVYaw_088, animate = FALSE, }
anim 090 { anim = KLT_LAVYaw_090, animate = FALSE, }
anim 092 { anim = KLT_LAVYaw_092, animate = FALSE, }
anim 094 { anim = KLT_LAVYaw_094, animate = FALSE, }
anim 096 { anim = KLT_LAVYaw_096, animate = FALSE, }
anim 098 { anim = KLT_LAVYaw_098, animate = FALSE, }
anim 100 { anim = KLT_LAVYaw_100, animate = FALSE, }
anim 102 { anim = KLT_LAVYaw_102, animate = FALSE, }
anim 104 { anim = KLT_LAVYaw_104, animate = FALSE, }
anim 106 { anim = KLT_LAVYaw_106, animate = FALSE, }
anim 108 { anim = KLT_LAVYaw_108, animate = FALSE, }
anim 110 { anim = KLT_LAVYaw_110, animate = FALSE, }
anim 112 { anim = KLT_LAVYaw_112, animate = FALSE, }
anim 114 { anim = KLT_LAVYaw_114, animate = FALSE, }
anim 116 { anim = KLT_LAVYaw_116, animate = FALSE, }
anim 118 { anim = KLT_LAVYaw_118, animate = FALSE, }
anim 120 { anim = KLT_LAVYaw_120, animate = FALSE, }
anim 122 { anim = KLT_LAVYaw_122, animate = FALSE, }
anim 124 { anim = KLT_LAVYaw_124, animate = FALSE, }
anim 126 { anim = KLT_LAVYaw_126, animate = FALSE, }
anim 128 { anim = KLT_LAVYaw_128, animate = FALSE, }
anim 130 { anim = KLT_LAVYaw_130, animate = FALSE, }
anim 132 { anim = KLT_LAVYaw_132, animate = FALSE, }
anim 134 { anim = KLT_LAVYaw_134, animate = FALSE, }
anim 136 { anim = KLT_LAVYaw_136, animate = FALSE, }
anim 138 { anim = KLT_LAVYaw_138, animate = FALSE, }
anim 140 { anim = KLT_LAVYaw_140, animate = FALSE, }
anim 142 { anim = KLT_LAVYaw_142, animate = FALSE, }
anim 144 { anim = KLT_LAVYaw_144, animate = FALSE, }
anim 146 { anim = KLT_LAVYaw_146, animate = FALSE, }
anim 148 { anim = KLT_LAVYaw_148, animate = FALSE, }
anim 150 { anim = KLT_LAVYaw_150, animate = FALSE, }
anim 152 { anim = KLT_LAVYaw_152, animate = FALSE, }
anim 154 { anim = KLT_LAVYaw_154, animate = FALSE, }
anim 156 { anim = KLT_LAVYaw_156, animate = FALSE, }
anim 158 { anim = KLT_LAVYaw_158, animate = FALSE, }
anim 160 { anim = KLT_LAVYaw_160, animate = FALSE, }
anim 162 { anim = KLT_LAVYaw_162, animate = FALSE, }
anim 164 { anim = KLT_LAVYaw_164, animate = FALSE, }
anim 166 { anim = KLT_LAVYaw_166, animate = FALSE, }
anim 168 { anim = KLT_LAVYaw_168, animate = FALSE, }
anim 170 { anim = KLT_LAVYaw_170, animate = FALSE, }
anim 172 { anim = KLT_LAVYaw_172, animate = FALSE, }
anim 174 { anim = KLT_LAVYaw_174, animate = FALSE, }
anim 176 { anim = KLT_LAVYaw_176, animate = FALSE, }
anim 178 { anim = KLT_LAVYaw_178, animate = FALSE, }
anim 180 { anim = KLT_LAVYaw_180, animate = FALSE, }
anim 182 { anim = KLT_LAVYaw_182, animate = FALSE, }
anim 184 { anim = KLT_LAVYaw_184, animate = FALSE, }
anim 186 { anim = KLT_LAVYaw_186, animate = FALSE, }
anim 188 { anim = KLT_LAVYaw_188, animate = FALSE, }
anim 190 { anim = KLT_LAVYaw_190, animate = FALSE, }
anim 192 { anim = KLT_LAVYaw_192, animate = FALSE, }
anim 194 { anim = KLT_LAVYaw_194, animate = FALSE, }
anim 196 { anim = KLT_LAVYaw_196, animate = FALSE, }
anim 198 { anim = KLT_LAVYaw_198, animate = FALSE, }
anim 200 { anim = KLT_LAVYaw_200, animate = FALSE, }
anim 202 { anim = KLT_LAVYaw_202, animate = FALSE, }
anim 204 { anim = KLT_LAVYaw_204, animate = FALSE, }
anim 206 { anim = KLT_LAVYaw_206, animate = FALSE, }
anim 208 { anim = KLT_LAVYaw_208, animate = FALSE, }
anim 210 { anim = KLT_LAVYaw_210, animate = FALSE, }
anim 212 { anim = KLT_LAVYaw_212, animate = FALSE, }
anim 214 { anim = KLT_LAVYaw_214, animate = FALSE, }
anim 216 { anim = KLT_LAVYaw_216, animate = FALSE, }
anim 218 { anim = KLT_LAVYaw_218, animate = FALSE, }
anim 220 { anim = KLT_LAVYaw_220, animate = FALSE, }
anim 222 { anim = KLT_LAVYaw_222, animate = FALSE, }
anim 224 { anim = KLT_LAVYaw_224, animate = FALSE, }
anim 226 { anim = KLT_LAVYaw_226, animate = FALSE, }
anim 228 { anim = KLT_LAVYaw_228, animate = FALSE, }
anim 230 { anim = KLT_LAVYaw_230, animate = FALSE, }
anim 232 { anim = KLT_LAVYaw_232, animate = FALSE, }
anim 234 { anim = KLT_LAVYaw_234, animate = FALSE, }
anim 236 { anim = KLT_LAVYaw_236, animate = FALSE, }
anim 238 { anim = KLT_LAVYaw_238, animate = FALSE, }
anim 240 { anim = KLT_LAVYaw_240, animate = FALSE, }
anim 242 { anim = KLT_LAVYaw_242, animate = FALSE, }
anim 244 { anim = KLT_LAVYaw_244, animate = FALSE, }
anim 246 { anim = KLT_LAVYaw_246, animate = FALSE, }
anim 248 { anim = KLT_LAVYaw_248, animate = FALSE, }
anim 250 { anim = KLT_LAVYaw_250, animate = FALSE, }
anim 252 { anim = KLT_LAVYaw_252, animate = FALSE, }
anim 254 { anim = KLT_LAVYaw_254, animate = FALSE, }
anim 256 { anim = KLT_LAVYaw_256, animate = FALSE, }
anim 258 { anim = KLT_LAVYaw_258, animate = FALSE, }
anim 260 { anim = KLT_LAVYaw_260, animate = FALSE, }
anim 262 { anim = KLT_LAVYaw_262, animate = FALSE, }
anim 264 { anim = KLT_LAVYaw_264, animate = FALSE, }
anim 266 { anim = KLT_LAVYaw_266, animate = FALSE, }
anim 268 { anim = KLT_LAVYaw_268, animate = FALSE, }
anim 270 { anim = KLT_LAVYaw_270, animate = FALSE, }
anim 272 { anim = KLT_LAVYaw_272, animate = FALSE, }
anim 274 { anim = KLT_LAVYaw_274, animate = FALSE, }
anim 276 { anim = KLT_LAVYaw_276, animate = FALSE, }
anim 278 { anim = KLT_LAVYaw_278, animate = FALSE, }
anim 280 { anim = KLT_LAVYaw_280, animate = FALSE, }
anim 282 { anim = KLT_LAVYaw_282, animate = FALSE, }
anim 284 { anim = KLT_LAVYaw_284, animate = FALSE, }
anim 286 { anim = KLT_LAVYaw_286, animate = FALSE, }
anim 288 { anim = KLT_LAVYaw_288, animate = FALSE, }
anim 290 { anim = KLT_LAVYaw_290, animate = FALSE, }
anim 292 { anim = KLT_LAVYaw_292, animate = FALSE, }
anim 294 { anim = KLT_LAVYaw_294, animate = FALSE, }
anim 296 { anim = KLT_LAVYaw_296, animate = FALSE, }
anim 298 { anim = KLT_LAVYaw_298, animate = FALSE, }
anim 300 { anim = KLT_LAVYaw_300, animate = FALSE, }
anim 302 { anim = KLT_LAVYaw_302, animate = FALSE, }
anim 304 { anim = KLT_LAVYaw_304, animate = FALSE, }
anim 306 { anim = KLT_LAVYaw_306, animate = FALSE, }
anim 308 { anim = KLT_LAVYaw_308, animate = FALSE, }
anim 310 { anim = KLT_LAVYaw_310, animate = FALSE, }
anim 312 { anim = KLT_LAVYaw_312, animate = FALSE, }
anim 314 { anim = KLT_LAVYaw_314, animate = FALSE, }
anim 316 { anim = KLT_LAVYaw_316, animate = FALSE, }
anim 318 { anim = KLT_LAVYaw_318, animate = FALSE, }
anim 320 { anim = KLT_LAVYaw_320, animate = FALSE, }
anim 322 { anim = KLT_LAVYaw_322, animate = FALSE, }
anim 324 { anim = KLT_LAVYaw_324, animate = FALSE, }
anim 326 { anim = KLT_LAVYaw_326, animate = FALSE, }
anim 328 { anim = KLT_LAVYaw_328, animate = FALSE, }
anim 330 { anim = KLT_LAVYaw_330, animate = FALSE, }
anim 332 { anim = KLT_LAVYaw_332, animate = FALSE, }
anim 334 { anim = KLT_LAVYaw_334, animate = FALSE, }
anim 336 { anim = KLT_LAVYaw_336, animate = FALSE, }
anim 338 { anim = KLT_LAVYaw_338, animate = FALSE, }
anim 340 { anim = KLT_LAVYaw_340, animate = FALSE, }
anim 342 { anim = KLT_LAVYaw_342, animate = FALSE, }
anim 344 { anim = KLT_LAVYaw_344, animate = FALSE, }
anim 346 { anim = KLT_LAVYaw_346, animate = FALSE, }
anim 348 { anim = KLT_LAVYaw_348, animate = FALSE, }
anim 350 { anim = KLT_LAVYaw_350, animate = FALSE, }
anim 352 { anim = KLT_LAVYaw_352, animate = FALSE, }
anim 354 { anim = KLT_LAVYaw_354, animate = FALSE, }
anim 356 { anim = KLT_LAVYaw_356, animate = FALSE, }
anim 358 { anim = KLT_LAVYaw_358, animate = FALSE, }
anim 360 { anim = KLT_LAVYaw_360, animate = FALSE, }
}
part KLT_LAVInterior
{
category = nodisplay,
parent = Turrent,
model Default { file = KLT_LAVInterior, scale = 1.0, offset = 0 0 0, rotate = 0 0 0, }
lua { create = KLTLAV.InitInterior, init = KLTLAV.InitInterior, }
}
part DoorRearLeft
{
parent = Turrent,
model KLT_RigLink { file = KLT_LAVRigLink, scale = 1.0, offset = 0 0 0, rotate = 0 0 0, }
lua { create = KLTLAV.CreateGunnerDoor, init = KLTLAV.InitGunnerDoor, }
}
part WindowGunnerHatch
{
model windowRL668 { file = KLT_LAVHatch, scale = 1.0, offset = 0 0 0, rotate = 0 0 0, }
anim ClosedToOpen { anim = KLT_LAVHatch, animate = FALSE, }
}
part V300fsvViewports
{
parent = Turrent,
model fsvViewports { file = KLT_LAVViewports, scale = 1.0, offset = 0 0 0, rotate = 0 0 0, }
}
part Radio
{
parent = Turrent,
model sfvadio { file = KLT_LAVRadio, scale = 1.0, offset = 0 0 0, rotate = 0 0 0, }
}
part KLT_LAV90
{
itemType = KLT.LAV90Gun,
specificItem = false,
category = Turrent,
area = SeatRearLeft,
mechanicArea = SeatRearLeft,
parent = Turrent,
container { capacity = 8, conditionAffectsCapacity = false, test = KLTLAV.BreechAccess, }
lua { create = KLTLAV.InitWeapon, init = KLTLAV.InitWeapon, }
}
part KLT_LAVAmmo
{
itemType = KLT.LAV90Rack,
specificItem = false,
category = Turrent,
area = SeatRearLeft,
container { capacity = 160, conditionAffectsCapacity = false, test = KLTLAV.AmmoAccess, }
lua { create = KLTLAV.InitStorage, init = KLTLAV.InitStorage, }
}
}
]=]
@@ -0,0 +1,33 @@
module Base
{
sound HRSys_LAV300_90mm_Fire
{
category = Vehicle,
master = Primary,
is3D = true,
loop = false,
maxInstancesPerEmitter = 8,
clip
{
file = media/sound/HRSys_LAV300_90mm_Fire.wav,
volume = 1.0,
distanceMin = 5,
distanceMax = 100,
}
}
sound HRSys_LAV300_90mm_End
{
category = Vehicle,
master = Primary,
is3D = true,
loop = false,
maxInstancesPerEmitter = 8,
clip
{
file = media/sound/HRSys_LAV300_90mm_End.wav,
volume = 1.0,
distanceMin = 5,
distanceMax = 100,
}
}
}
@@ -0,0 +1,51 @@
module KLT
{
item LAV90Gun
{
DisplayCategory = VehicleMaintenance,
DisplayName = LAV 90 mm cannon,
ItemType = base:normal,
Weight = 30.0,
Icon = M41_76mm,
VehicleType = 2,
ConditionMax = 100,
MechanicsItem = TRUE,
MaxCapacity = 8,
ConditionAffectsCapacity = false,
}
item LAV90Rack
{
DisplayCategory = VehicleMaintenance,
DisplayName = LAV 90 mm ammunition rack,
ItemType = base:normal,
Weight = 15.0,
Icon = CarTrunk,
VehicleType = 2,
ConditionMax = 100,
MechanicsItem = TRUE,
MaxCapacity = 160,
ConditionAffectsCapacity = false,
}
item Shell90AP
{
DisplayCategory = Ammo,
DisplayName = LAV 90 mm AP shell,
ItemType = base:normal,
Weight = 8.0,
Icon = 76mmAmmoAP,
Count = 1,
WorldStaticModel = 76mm_Item,
Tags = base:ammo,
}
item Shell90HE
{
DisplayCategory = Ammo,
DisplayName = LAV 90 mm HE shell,
ItemType = base:normal,
Weight = 8.0,
Icon = 76mmAmmoHE,
Count = 1,
WorldStaticModel = 76mmHE_Item,
Tags = base:ammo,
}
}
@@ -0,0 +1,54 @@
module Base
{
model KLT_LAVTurret
{
mesh = vehicles/KLT_LAVTurret|KLT_LAVTurret,
shader = damn_vehicle_noreflect_shader,
scale = 0.1,
static = FALSE,
boneWeight = body_bone 1.0,
boneWeight = KLT_LAVYaw 1.0,
}
model KLT_LAVInterior
{
mesh = vehicles/KLT_LAVTurret|KLT_LAVInterior,
shader = damn_wheel_shader,
scale = 0.1,
static = FALSE,
texture = Vehicles/Vehicles_84gageV300_Interior,
boneWeight = KLT_LAVYaw 1.0,
}
model KLT_LAVHatch
{
mesh = vehicles/KLT_LAVTurret|KLT_LAVHatch,
shader = damn_vehicle_noreflect_shader,
scale = 0.1,
static = FALSE,
boneWeight = hatch_gunner_bone 1.0,
}
model KLT_LAVViewports
{
mesh = vehicles/KLT_LAVTurret|KLT_LAVViewports,
shader = damn_vehicle_shader,
scale = 0.1,
static = FALSE,
boneWeight = KLT_LAVYaw 1.0,
}
model KLT_LAVRadio
{
mesh = vehicles/KLT_LAVTurret|KLT_LAVRadio,
shader = damn_wheel_shader,
scale = 0.1,
static = FALSE,
texture = Vehicles/Vehicles_84gageV300_Interior,
boneWeight = KLT_LAVYaw 1.0,
}
model KLT_LAVRigLink
{
mesh = vehicles/KLT_LAVTurret|KLT_LAVRigLink,
shader = damn_vehicle_noreflect_shader,
scale = 0.1,
static = FALSE,
boneWeight = body_bone 1.0,
}
}
@@ -0,0 +1,10 @@
name=HRSys Functional Turrets - LAV-300
id=hrsys_functionalturrets_lav300
description=Adds a functioning turret and gunner-operated 90 mm cannon with AP and HE ammunition to KI5's '84 Cadillac Gage LAV-300 FSV.
author=Riggs0
category=vehicle
require=\damnlib,\84gageV300,\Military_Tool_Kit
versionMin=42.20.0
modversion=0.1.4
icon=icon.png
poster=preview.png
Binary file not shown.

After

Width:  |  Height:  |  Size: 1.1 MiB

@@ -0,0 +1,5 @@
{
"IGUI_VehiclePartKLT_LAV90": "LAV 90 mm cannon (breech)",
"IGUI_VehiclePartKLT_LAVAmmo": "LAV 90 mm ammunition storage",
"IGUI_VehiclePartTurrent": "Turret"
}
@@ -0,0 +1,6 @@
{
"ItemName_KLT.LAV90Gun": "LAV 90 mm cannon",
"ItemName_KLT.LAV90Rack": "LAV 90 mm ammunition rack",
"ItemName_KLT.Shell90AP": "LAV 90 mm AP shell",
"ItemName_KLT.Shell90HE": "LAV 90 mm HE shell"
}
Binary file not shown.

After

Width:  |  Height:  |  Size: 118 KiB

@@ -0,0 +1,10 @@
name=HRSys Functional Turrets - LAV-300
id=hrsys_functionalturrets_lav300
description=Adds a functioning turret and gunner-operated 90 mm cannon with AP and HE ammunition to KI5's '84 Cadillac Gage LAV-300 FSV.
author=Riggs0
category=vehicle
require=\damnlib,\84gageV300,\Military_Tool_Kit
versionMin=42.20.0
modversion=0.1.4
icon=icon.png
poster=preview.png
Binary file not shown.

After

Width:  |  Height:  |  Size: 1.1 MiB