Intial Commit
|
After Width: | Height: | Size: 118 KiB |
@@ -0,0 +1,108 @@
|
||||
require "KFT_Ferret"
|
||||
require "Vehicles/Papa_Chad_Tank_Cannon"
|
||||
|
||||
local F = KFTFerret
|
||||
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.M1919A4_Coax
|
||||
or not chooseWeaponPC or not tankAimSystemPC then
|
||||
print("[KI5FerretTurret] MTK turret API unavailable; controls not installed.")
|
||||
return
|
||||
end
|
||||
local profile = {}
|
||||
for key, value in pairs(weaponConfig.M1919A4_Coax) 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 = nil
|
||||
profile.coax = false
|
||||
profile.sound = "HRSys_Ferret_Browning_Fire"
|
||||
profile.soundEnd = "HRSys_Ferret_Browning_End"
|
||||
profile.rotationTime = 12
|
||||
profile.soundTurret = "Turret_Manual"
|
||||
profile.soundTurretCooldown = 0.25
|
||||
weaponConfig[F.weaponPart] = profile
|
||||
F.profile = profile
|
||||
|
||||
local originalChoose = chooseWeaponPC
|
||||
chooseWeaponPC = function(vehicle)
|
||||
if F.isFerret(vehicle) then
|
||||
if not F.inputBlocked and F.weaponReady(vehicle) then 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.isFerret(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.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("[KI5FerretTurret] Gunner controls registered with Military Tool Kit.")
|
||||
end
|
||||
|
||||
Events.OnGameBoot.Add(F.installClient)
|
||||
Events.OnGameStart.Add(F.installClient)
|
||||
@@ -0,0 +1,27 @@
|
||||
require "KFT_Ferret"
|
||||
|
||||
local F = KFTFerret
|
||||
local function persistTurret(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 F.isGunner(vehicle, player) then F.savePose(vehicle, string.format("%03d", value)) end
|
||||
end
|
||||
Events.OnClientCommand.Add(persistTurret)
|
||||
|
||||
-- MTK supplies the ammunition items and unpacking recipes. Give them a modest
|
||||
-- source in military ammunition stores even when the M41 is not enabled.
|
||||
require "Items/ProceduralDistributions"
|
||||
local supplies = ProceduralDistributions.list.ArmyStorageAmmunition
|
||||
if supplies and supplies.items then
|
||||
local alreadyPresent = false
|
||||
for index = 1, #supplies.items, 2 do
|
||||
if supplies.items[index] == "Base.762x63mmCarton" then alreadyPresent = true end
|
||||
end
|
||||
if not alreadyPresent then
|
||||
table.insert(supplies.items, "Base.762x63mmCarton")
|
||||
table.insert(supplies.items, 3)
|
||||
end
|
||||
end
|
||||
@@ -0,0 +1,92 @@
|
||||
-- Local compatibility adapter. Original Workshop files remain dependencies.
|
||||
KFTFerret = KFTFerret or {}
|
||||
local F = KFTFerret
|
||||
F.scriptName = "Base.62daimlerFerretMk2"
|
||||
F.weaponPart = "KFT_FerretMG"
|
||||
F.ammoType = "Base.762x63mm"
|
||||
F.version = 1
|
||||
|
||||
function F.isFerret(vehicle)
|
||||
return vehicle ~= nil and vehicle:getScriptName() == F.scriptName
|
||||
end
|
||||
|
||||
function F.isGunner(vehicle, character)
|
||||
return F.isFerret(vehicle) and character ~= nil
|
||||
and character:getVehicle() == vehicle and vehicle:getSeat(character) == 1
|
||||
end
|
||||
|
||||
function F.AmmoAccess(vehicle, part, character)
|
||||
return F.isGunner(vehicle, character)
|
||||
end
|
||||
|
||||
function F.InitTurret(vehicle, part)
|
||||
local data = part:getModData()
|
||||
local vehicleData = vehicle:getModData()
|
||||
local pose = data.kftPose or vehicleData.turretAnimID or "002"
|
||||
vehicleData.turretAnimID = pose
|
||||
part:setModelVisible("Default", true)
|
||||
vehicle:playPartAnim(part, pose)
|
||||
local gloveBox = vehicle:getPartById("GloveBox")
|
||||
if gloveBox then gloveBox:setModelVisible("interiorTop", false) end
|
||||
end
|
||||
|
||||
function F.InitGloveBox(vehicle, part)
|
||||
part:setModelVisible("interiorTop", false)
|
||||
end
|
||||
|
||||
function F.InitWeapon(vehicle, part)
|
||||
local data = part:getModData()
|
||||
if not data.kftInitialized then
|
||||
-- Called once for a newly added part, including an existing-save migration.
|
||||
-- A removed or destroyed gun is never recreated on subsequent loads.
|
||||
if not part:getInventoryItem() then
|
||||
VehicleUtils.createPartInventoryItem(part)
|
||||
part:setCondition(100)
|
||||
end
|
||||
data.kftInitialized = F.version
|
||||
end
|
||||
end
|
||||
|
||||
function F.weaponReady(vehicle)
|
||||
if not F.isFerret(vehicle) then return false end
|
||||
local part = vehicle:getPartById(F.weaponPart)
|
||||
return part ~= nil and part:getInventoryItem() ~= nil and part:getCondition() > 0
|
||||
end
|
||||
|
||||
function F.poseForAngle(relativeAngle)
|
||||
local pose = math.floor(math.floor((relativeAngle % 360) + 0.5) / 2) * 2 + 2
|
||||
if pose > 360 then pose = 2 end
|
||||
return string.format("%03d", pose)
|
||||
end
|
||||
|
||||
function F.savePose(vehicle, pose)
|
||||
local turret = vehicle:getPartById("Turrent")
|
||||
if not turret then return end
|
||||
vehicle:getModData().turretAnimID = pose
|
||||
local data = turret:getModData()
|
||||
if data.kftPose ~= pose then
|
||||
data.kftPose = pose
|
||||
if isServer() then vehicle:transmitPartModData(turret) end
|
||||
end
|
||||
end
|
||||
|
||||
function F.patchScript()
|
||||
local script = getScriptManager():getVehicle(F.scriptName)
|
||||
if not script then
|
||||
print("[KI5FerretTurret] Ferret Mk2 script unavailable; adapter not applied.")
|
||||
return false
|
||||
end
|
||||
if script:getPartById(F.weaponPart) then return true end
|
||||
if not script:getPartById("GloveBox") or not script:getPartById("FER62HatchTurret") then
|
||||
print("[KI5FerretTurret] Unexpected Ferret layout; adapter not applied.")
|
||||
return false
|
||||
end
|
||||
-- Load merges only the named parts. Do NOT call Loaded(): in B42.21 it
|
||||
-- multiplies chassis dimensions and suspension by modelScale a second time.
|
||||
script:Load("62daimlerFerretMk2", require "KFT_FerretPatch")
|
||||
print("[KI5FerretTurret] Ferret Mk2 turret parts applied (v0.1.1).")
|
||||
return true
|
||||
end
|
||||
|
||||
Events.OnGameBoot.Add(F.patchScript)
|
||||
Events.OnInitGlobalModData.Add(F.patchScript)
|
||||
@@ -0,0 +1,214 @@
|
||||
return [=[
|
||||
{
|
||||
part GloveBox
|
||||
{
|
||||
lua { create = Vehicles.Create.Default, init = KFTFerret.InitGloveBox, }
|
||||
}
|
||||
part Turrent
|
||||
{
|
||||
category = nodisplay,
|
||||
area = SeatFrontRight,
|
||||
model Default { file = KFT_FerretTurret, scale = 1.0, offset = 0 0 0, rotate = 0 0 0, }
|
||||
lua { create = KFTFerret.InitTurret, init = KFTFerret.InitTurret, }
|
||||
anim 002 { anim = KFT_FerretYaw_002, animate = FALSE, }
|
||||
anim 004 { anim = KFT_FerretYaw_004, animate = FALSE, }
|
||||
anim 006 { anim = KFT_FerretYaw_006, animate = FALSE, }
|
||||
anim 008 { anim = KFT_FerretYaw_008, animate = FALSE, }
|
||||
anim 010 { anim = KFT_FerretYaw_010, animate = FALSE, }
|
||||
anim 012 { anim = KFT_FerretYaw_012, animate = FALSE, }
|
||||
anim 014 { anim = KFT_FerretYaw_014, animate = FALSE, }
|
||||
anim 016 { anim = KFT_FerretYaw_016, animate = FALSE, }
|
||||
anim 018 { anim = KFT_FerretYaw_018, animate = FALSE, }
|
||||
anim 020 { anim = KFT_FerretYaw_020, animate = FALSE, }
|
||||
anim 022 { anim = KFT_FerretYaw_022, animate = FALSE, }
|
||||
anim 024 { anim = KFT_FerretYaw_024, animate = FALSE, }
|
||||
anim 026 { anim = KFT_FerretYaw_026, animate = FALSE, }
|
||||
anim 028 { anim = KFT_FerretYaw_028, animate = FALSE, }
|
||||
anim 030 { anim = KFT_FerretYaw_030, animate = FALSE, }
|
||||
anim 032 { anim = KFT_FerretYaw_032, animate = FALSE, }
|
||||
anim 034 { anim = KFT_FerretYaw_034, animate = FALSE, }
|
||||
anim 036 { anim = KFT_FerretYaw_036, animate = FALSE, }
|
||||
anim 038 { anim = KFT_FerretYaw_038, animate = FALSE, }
|
||||
anim 040 { anim = KFT_FerretYaw_040, animate = FALSE, }
|
||||
anim 042 { anim = KFT_FerretYaw_042, animate = FALSE, }
|
||||
anim 044 { anim = KFT_FerretYaw_044, animate = FALSE, }
|
||||
anim 046 { anim = KFT_FerretYaw_046, animate = FALSE, }
|
||||
anim 048 { anim = KFT_FerretYaw_048, animate = FALSE, }
|
||||
anim 050 { anim = KFT_FerretYaw_050, animate = FALSE, }
|
||||
anim 052 { anim = KFT_FerretYaw_052, animate = FALSE, }
|
||||
anim 054 { anim = KFT_FerretYaw_054, animate = FALSE, }
|
||||
anim 056 { anim = KFT_FerretYaw_056, animate = FALSE, }
|
||||
anim 058 { anim = KFT_FerretYaw_058, animate = FALSE, }
|
||||
anim 060 { anim = KFT_FerretYaw_060, animate = FALSE, }
|
||||
anim 062 { anim = KFT_FerretYaw_062, animate = FALSE, }
|
||||
anim 064 { anim = KFT_FerretYaw_064, animate = FALSE, }
|
||||
anim 066 { anim = KFT_FerretYaw_066, animate = FALSE, }
|
||||
anim 068 { anim = KFT_FerretYaw_068, animate = FALSE, }
|
||||
anim 070 { anim = KFT_FerretYaw_070, animate = FALSE, }
|
||||
anim 072 { anim = KFT_FerretYaw_072, animate = FALSE, }
|
||||
anim 074 { anim = KFT_FerretYaw_074, animate = FALSE, }
|
||||
anim 076 { anim = KFT_FerretYaw_076, animate = FALSE, }
|
||||
anim 078 { anim = KFT_FerretYaw_078, animate = FALSE, }
|
||||
anim 080 { anim = KFT_FerretYaw_080, animate = FALSE, }
|
||||
anim 082 { anim = KFT_FerretYaw_082, animate = FALSE, }
|
||||
anim 084 { anim = KFT_FerretYaw_084, animate = FALSE, }
|
||||
anim 086 { anim = KFT_FerretYaw_086, animate = FALSE, }
|
||||
anim 088 { anim = KFT_FerretYaw_088, animate = FALSE, }
|
||||
anim 090 { anim = KFT_FerretYaw_090, animate = FALSE, }
|
||||
anim 092 { anim = KFT_FerretYaw_092, animate = FALSE, }
|
||||
anim 094 { anim = KFT_FerretYaw_094, animate = FALSE, }
|
||||
anim 096 { anim = KFT_FerretYaw_096, animate = FALSE, }
|
||||
anim 098 { anim = KFT_FerretYaw_098, animate = FALSE, }
|
||||
anim 100 { anim = KFT_FerretYaw_100, animate = FALSE, }
|
||||
anim 102 { anim = KFT_FerretYaw_102, animate = FALSE, }
|
||||
anim 104 { anim = KFT_FerretYaw_104, animate = FALSE, }
|
||||
anim 106 { anim = KFT_FerretYaw_106, animate = FALSE, }
|
||||
anim 108 { anim = KFT_FerretYaw_108, animate = FALSE, }
|
||||
anim 110 { anim = KFT_FerretYaw_110, animate = FALSE, }
|
||||
anim 112 { anim = KFT_FerretYaw_112, animate = FALSE, }
|
||||
anim 114 { anim = KFT_FerretYaw_114, animate = FALSE, }
|
||||
anim 116 { anim = KFT_FerretYaw_116, animate = FALSE, }
|
||||
anim 118 { anim = KFT_FerretYaw_118, animate = FALSE, }
|
||||
anim 120 { anim = KFT_FerretYaw_120, animate = FALSE, }
|
||||
anim 122 { anim = KFT_FerretYaw_122, animate = FALSE, }
|
||||
anim 124 { anim = KFT_FerretYaw_124, animate = FALSE, }
|
||||
anim 126 { anim = KFT_FerretYaw_126, animate = FALSE, }
|
||||
anim 128 { anim = KFT_FerretYaw_128, animate = FALSE, }
|
||||
anim 130 { anim = KFT_FerretYaw_130, animate = FALSE, }
|
||||
anim 132 { anim = KFT_FerretYaw_132, animate = FALSE, }
|
||||
anim 134 { anim = KFT_FerretYaw_134, animate = FALSE, }
|
||||
anim 136 { anim = KFT_FerretYaw_136, animate = FALSE, }
|
||||
anim 138 { anim = KFT_FerretYaw_138, animate = FALSE, }
|
||||
anim 140 { anim = KFT_FerretYaw_140, animate = FALSE, }
|
||||
anim 142 { anim = KFT_FerretYaw_142, animate = FALSE, }
|
||||
anim 144 { anim = KFT_FerretYaw_144, animate = FALSE, }
|
||||
anim 146 { anim = KFT_FerretYaw_146, animate = FALSE, }
|
||||
anim 148 { anim = KFT_FerretYaw_148, animate = FALSE, }
|
||||
anim 150 { anim = KFT_FerretYaw_150, animate = FALSE, }
|
||||
anim 152 { anim = KFT_FerretYaw_152, animate = FALSE, }
|
||||
anim 154 { anim = KFT_FerretYaw_154, animate = FALSE, }
|
||||
anim 156 { anim = KFT_FerretYaw_156, animate = FALSE, }
|
||||
anim 158 { anim = KFT_FerretYaw_158, animate = FALSE, }
|
||||
anim 160 { anim = KFT_FerretYaw_160, animate = FALSE, }
|
||||
anim 162 { anim = KFT_FerretYaw_162, animate = FALSE, }
|
||||
anim 164 { anim = KFT_FerretYaw_164, animate = FALSE, }
|
||||
anim 166 { anim = KFT_FerretYaw_166, animate = FALSE, }
|
||||
anim 168 { anim = KFT_FerretYaw_168, animate = FALSE, }
|
||||
anim 170 { anim = KFT_FerretYaw_170, animate = FALSE, }
|
||||
anim 172 { anim = KFT_FerretYaw_172, animate = FALSE, }
|
||||
anim 174 { anim = KFT_FerretYaw_174, animate = FALSE, }
|
||||
anim 176 { anim = KFT_FerretYaw_176, animate = FALSE, }
|
||||
anim 178 { anim = KFT_FerretYaw_178, animate = FALSE, }
|
||||
anim 180 { anim = KFT_FerretYaw_180, animate = FALSE, }
|
||||
anim 182 { anim = KFT_FerretYaw_182, animate = FALSE, }
|
||||
anim 184 { anim = KFT_FerretYaw_184, animate = FALSE, }
|
||||
anim 186 { anim = KFT_FerretYaw_186, animate = FALSE, }
|
||||
anim 188 { anim = KFT_FerretYaw_188, animate = FALSE, }
|
||||
anim 190 { anim = KFT_FerretYaw_190, animate = FALSE, }
|
||||
anim 192 { anim = KFT_FerretYaw_192, animate = FALSE, }
|
||||
anim 194 { anim = KFT_FerretYaw_194, animate = FALSE, }
|
||||
anim 196 { anim = KFT_FerretYaw_196, animate = FALSE, }
|
||||
anim 198 { anim = KFT_FerretYaw_198, animate = FALSE, }
|
||||
anim 200 { anim = KFT_FerretYaw_200, animate = FALSE, }
|
||||
anim 202 { anim = KFT_FerretYaw_202, animate = FALSE, }
|
||||
anim 204 { anim = KFT_FerretYaw_204, animate = FALSE, }
|
||||
anim 206 { anim = KFT_FerretYaw_206, animate = FALSE, }
|
||||
anim 208 { anim = KFT_FerretYaw_208, animate = FALSE, }
|
||||
anim 210 { anim = KFT_FerretYaw_210, animate = FALSE, }
|
||||
anim 212 { anim = KFT_FerretYaw_212, animate = FALSE, }
|
||||
anim 214 { anim = KFT_FerretYaw_214, animate = FALSE, }
|
||||
anim 216 { anim = KFT_FerretYaw_216, animate = FALSE, }
|
||||
anim 218 { anim = KFT_FerretYaw_218, animate = FALSE, }
|
||||
anim 220 { anim = KFT_FerretYaw_220, animate = FALSE, }
|
||||
anim 222 { anim = KFT_FerretYaw_222, animate = FALSE, }
|
||||
anim 224 { anim = KFT_FerretYaw_224, animate = FALSE, }
|
||||
anim 226 { anim = KFT_FerretYaw_226, animate = FALSE, }
|
||||
anim 228 { anim = KFT_FerretYaw_228, animate = FALSE, }
|
||||
anim 230 { anim = KFT_FerretYaw_230, animate = FALSE, }
|
||||
anim 232 { anim = KFT_FerretYaw_232, animate = FALSE, }
|
||||
anim 234 { anim = KFT_FerretYaw_234, animate = FALSE, }
|
||||
anim 236 { anim = KFT_FerretYaw_236, animate = FALSE, }
|
||||
anim 238 { anim = KFT_FerretYaw_238, animate = FALSE, }
|
||||
anim 240 { anim = KFT_FerretYaw_240, animate = FALSE, }
|
||||
anim 242 { anim = KFT_FerretYaw_242, animate = FALSE, }
|
||||
anim 244 { anim = KFT_FerretYaw_244, animate = FALSE, }
|
||||
anim 246 { anim = KFT_FerretYaw_246, animate = FALSE, }
|
||||
anim 248 { anim = KFT_FerretYaw_248, animate = FALSE, }
|
||||
anim 250 { anim = KFT_FerretYaw_250, animate = FALSE, }
|
||||
anim 252 { anim = KFT_FerretYaw_252, animate = FALSE, }
|
||||
anim 254 { anim = KFT_FerretYaw_254, animate = FALSE, }
|
||||
anim 256 { anim = KFT_FerretYaw_256, animate = FALSE, }
|
||||
anim 258 { anim = KFT_FerretYaw_258, animate = FALSE, }
|
||||
anim 260 { anim = KFT_FerretYaw_260, animate = FALSE, }
|
||||
anim 262 { anim = KFT_FerretYaw_262, animate = FALSE, }
|
||||
anim 264 { anim = KFT_FerretYaw_264, animate = FALSE, }
|
||||
anim 266 { anim = KFT_FerretYaw_266, animate = FALSE, }
|
||||
anim 268 { anim = KFT_FerretYaw_268, animate = FALSE, }
|
||||
anim 270 { anim = KFT_FerretYaw_270, animate = FALSE, }
|
||||
anim 272 { anim = KFT_FerretYaw_272, animate = FALSE, }
|
||||
anim 274 { anim = KFT_FerretYaw_274, animate = FALSE, }
|
||||
anim 276 { anim = KFT_FerretYaw_276, animate = FALSE, }
|
||||
anim 278 { anim = KFT_FerretYaw_278, animate = FALSE, }
|
||||
anim 280 { anim = KFT_FerretYaw_280, animate = FALSE, }
|
||||
anim 282 { anim = KFT_FerretYaw_282, animate = FALSE, }
|
||||
anim 284 { anim = KFT_FerretYaw_284, animate = FALSE, }
|
||||
anim 286 { anim = KFT_FerretYaw_286, animate = FALSE, }
|
||||
anim 288 { anim = KFT_FerretYaw_288, animate = FALSE, }
|
||||
anim 290 { anim = KFT_FerretYaw_290, animate = FALSE, }
|
||||
anim 292 { anim = KFT_FerretYaw_292, animate = FALSE, }
|
||||
anim 294 { anim = KFT_FerretYaw_294, animate = FALSE, }
|
||||
anim 296 { anim = KFT_FerretYaw_296, animate = FALSE, }
|
||||
anim 298 { anim = KFT_FerretYaw_298, animate = FALSE, }
|
||||
anim 300 { anim = KFT_FerretYaw_300, animate = FALSE, }
|
||||
anim 302 { anim = KFT_FerretYaw_302, animate = FALSE, }
|
||||
anim 304 { anim = KFT_FerretYaw_304, animate = FALSE, }
|
||||
anim 306 { anim = KFT_FerretYaw_306, animate = FALSE, }
|
||||
anim 308 { anim = KFT_FerretYaw_308, animate = FALSE, }
|
||||
anim 310 { anim = KFT_FerretYaw_310, animate = FALSE, }
|
||||
anim 312 { anim = KFT_FerretYaw_312, animate = FALSE, }
|
||||
anim 314 { anim = KFT_FerretYaw_314, animate = FALSE, }
|
||||
anim 316 { anim = KFT_FerretYaw_316, animate = FALSE, }
|
||||
anim 318 { anim = KFT_FerretYaw_318, animate = FALSE, }
|
||||
anim 320 { anim = KFT_FerretYaw_320, animate = FALSE, }
|
||||
anim 322 { anim = KFT_FerretYaw_322, animate = FALSE, }
|
||||
anim 324 { anim = KFT_FerretYaw_324, animate = FALSE, }
|
||||
anim 326 { anim = KFT_FerretYaw_326, animate = FALSE, }
|
||||
anim 328 { anim = KFT_FerretYaw_328, animate = FALSE, }
|
||||
anim 330 { anim = KFT_FerretYaw_330, animate = FALSE, }
|
||||
anim 332 { anim = KFT_FerretYaw_332, animate = FALSE, }
|
||||
anim 334 { anim = KFT_FerretYaw_334, animate = FALSE, }
|
||||
anim 336 { anim = KFT_FerretYaw_336, animate = FALSE, }
|
||||
anim 338 { anim = KFT_FerretYaw_338, animate = FALSE, }
|
||||
anim 340 { anim = KFT_FerretYaw_340, animate = FALSE, }
|
||||
anim 342 { anim = KFT_FerretYaw_342, animate = FALSE, }
|
||||
anim 344 { anim = KFT_FerretYaw_344, animate = FALSE, }
|
||||
anim 346 { anim = KFT_FerretYaw_346, animate = FALSE, }
|
||||
anim 348 { anim = KFT_FerretYaw_348, animate = FALSE, }
|
||||
anim 350 { anim = KFT_FerretYaw_350, animate = FALSE, }
|
||||
anim 352 { anim = KFT_FerretYaw_352, animate = FALSE, }
|
||||
anim 354 { anim = KFT_FerretYaw_354, animate = FALSE, }
|
||||
anim 356 { anim = KFT_FerretYaw_356, animate = FALSE, }
|
||||
anim 358 { anim = KFT_FerretYaw_358, animate = FALSE, }
|
||||
anim 360 { anim = KFT_FerretYaw_360, animate = FALSE, }
|
||||
}
|
||||
part FER62HatchTurret
|
||||
{
|
||||
parent = Turrent,
|
||||
model HATCHtop { file = KFT_FerretHatch, scale = 1.0, offset = 0 0 0, rotate = 0 0 0, }
|
||||
anim Open { anim = KFT_FerretHatch, reverse = FALSE, animate = TRUE, rate = 1.0, }
|
||||
anim Close { anim = KFT_FerretHatch, reverse = TRUE, animate = TRUE, rate = 1.5, }
|
||||
anim Closed { anim = KFT_FerretHatch, reverse = FALSE, animate = FALSE, }
|
||||
anim Opened { anim = KFT_FerretHatch, reverse = TRUE, animate = FALSE, }
|
||||
}
|
||||
part KFT_FerretMG
|
||||
{
|
||||
itemType = Base.M1919A4_Coax2,
|
||||
category = Turrent,
|
||||
area = SeatFrontRight,
|
||||
mechanicArea = SeatFrontRight,
|
||||
parent = Turrent,
|
||||
container { capacity = 10, conditionAffectsCapacity = false, test = KFTFerret.AmmoAccess, }
|
||||
lua { create = KFTFerret.InitWeapon, init = KFTFerret.InitWeapon, }
|
||||
}
|
||||
}
|
||||
]=]
|
||||
@@ -0,0 +1,33 @@
|
||||
module Base
|
||||
{
|
||||
sound HRSys_Ferret_Browning_Fire
|
||||
{
|
||||
category = Vehicle,
|
||||
master = Primary,
|
||||
is3D = true,
|
||||
loop = false,
|
||||
maxInstancesPerEmitter = 8,
|
||||
clip
|
||||
{
|
||||
file = media/sound/HRSys_Ferret_Browning_Fire.wav,
|
||||
volume = 1.0,
|
||||
distanceMin = 3,
|
||||
distanceMax = 60,
|
||||
}
|
||||
}
|
||||
sound HRSys_Ferret_Browning_End
|
||||
{
|
||||
category = Vehicle,
|
||||
master = Primary,
|
||||
is3D = true,
|
||||
loop = false,
|
||||
maxInstancesPerEmitter = 8,
|
||||
clip
|
||||
{
|
||||
file = media/sound/HRSys_Ferret_Browning_End.wav,
|
||||
volume = 1.0,
|
||||
distanceMin = 3,
|
||||
distanceMax = 60,
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,20 @@
|
||||
module Base
|
||||
{
|
||||
model KFT_FerretTurret
|
||||
{
|
||||
mesh = vehicles/KFT_FerretTurret|KFT_FerretTurret,
|
||||
shader = damn_vehicle_noreflect_shader,
|
||||
scale = 0.1,
|
||||
static = FALSE,
|
||||
boneWeight = body_bone 1.0,
|
||||
boneWeight = KFT_FerretYaw 1.0,
|
||||
}
|
||||
model KFT_FerretHatch
|
||||
{
|
||||
mesh = vehicles/KFT_FerretTurret|KFT_FerretHatch,
|
||||
shader = damn_vehicle_noreflect_shader,
|
||||
scale = 0.1,
|
||||
static = FALSE,
|
||||
boneWeight = door_turret_bone 1.0,
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,10 @@
|
||||
name=HRSys Functional Turrets - Ferret
|
||||
id=hrsys_functionalturrets_ferret
|
||||
description=Adds a functioning turret and gunner-operated .30-calibre Browning machine gun to KI5's '62 Daimler Ferret Mk2.
|
||||
author=Riggs0
|
||||
category=vehicle
|
||||
require=\damnlib,\62daimlerFerret,\Military_Tool_Kit
|
||||
versionMin=42.20.0
|
||||
modversion=0.1.4
|
||||
icon=icon.png
|
||||
poster=preview.png
|
||||
|
After Width: | Height: | Size: 1.1 MiB |
@@ -0,0 +1,4 @@
|
||||
{
|
||||
"IGUI_VehiclePartKFT_FerretMG": "Ferret Browning (.30-06)",
|
||||
"IGUI_VehiclePartTurrent": "Turret"
|
||||
}
|
||||
|
After Width: | Height: | Size: 118 KiB |
@@ -0,0 +1,10 @@
|
||||
name=HRSys Functional Turrets - Ferret
|
||||
id=hrsys_functionalturrets_ferret
|
||||
description=Adds a functioning turret and gunner-operated .30-calibre Browning machine gun to KI5's '62 Daimler Ferret Mk2.
|
||||
author=Riggs0
|
||||
category=vehicle
|
||||
require=\damnlib,\62daimlerFerret,\Military_Tool_Kit
|
||||
versionMin=42.20.0
|
||||
modversion=0.1.4
|
||||
icon=icon.png
|
||||
poster=preview.png
|
||||
|
After Width: | Height: | Size: 1.1 MiB |
|
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
|
||||
|
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"
|
||||
}
|
||||
|
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
|
||||
|
After Width: | Height: | Size: 1.1 MiB |