mirror of
https://github.com/dcs-retribution/dcs-retribution.git
synced 2025-11-10 15:41:24 +00:00
Update campaigns and the splash damage plugin.
This commit is contained in:
parent
17751e52fd
commit
bc54e57fd4
@ -1,8 +1,9 @@
|
||||
{
|
||||
"name": "Nevada - Exercise Vegas Nerve",
|
||||
"theater": "Nevada",
|
||||
"authors": "Starfire",
|
||||
"description": "<p>A Red Flag Exercise scenario for the NTTR comprising 4 control points.</p>",
|
||||
"miz": "exercise_vegas_nerve.miz",
|
||||
"performance": 0
|
||||
{
|
||||
"name": "Nevada - Exercise Vegas Nerve",
|
||||
"theater": "Nevada",
|
||||
"authors": "Starfire",
|
||||
"description": "<p>A Red Flag Exercise scenario for the NTTR comprising 4 control points.</p>",
|
||||
"version": 2,
|
||||
"miz": "exercise_vegas_nerve.miz",
|
||||
"performance": 0
|
||||
}
|
||||
Binary file not shown.
11
resources/campaigns/operation_peace_spring.json
Normal file
11
resources/campaigns/operation_peace_spring.json
Normal file
@ -0,0 +1,11 @@
|
||||
{
|
||||
"name": "Syria - Operation Peace Spring",
|
||||
"theater": "Syria",
|
||||
"authors": "Starfire",
|
||||
"recommended_player_faction": "Bluefor Modern",
|
||||
"recommended_enemy_faction": "Turkey 2005",
|
||||
"description": "<p>This is a semi-fictional what-if scenario for Operation Peace Spring, during which Turkish forces that crossed into Syria on an offensive against Kurdish militias were emboldened by early successes to continue pushing further southward. Attempts to broker a ceasefire have failed. Members of Operation Inherent Resolve have gathered at Ramat David Airbase in Israel to launch a counter-offensive. Campaign inversion is available if you wish to play as Turkey.</p>",
|
||||
"version": 2,
|
||||
"miz": "operation_peace_spring.miz",
|
||||
"performance": 1
|
||||
}
|
||||
BIN
resources/campaigns/operation_peace_spring.miz
Normal file
BIN
resources/campaigns/operation_peace_spring.miz
Normal file
Binary file not shown.
@ -1,228 +0,0 @@
|
||||
--[[
|
||||
|
||||
2 October 2020
|
||||
FrozenDroid:
|
||||
- Added error handling to all event handler and scheduled functions. Lua script errors can no longer bring the server down.
|
||||
- Added some extra checks to which weapons to handle, make sure they actually have a warhead (how come S-8KOM's don't have a warhead field...?)
|
||||
28 October 2020
|
||||
FrozenDroid:
|
||||
- Uncommented error logging, actually made it an error log which shows a message box on error.
|
||||
- Fixed the too restrictive weapon filter (took out the HE warhead requirement)
|
||||
--]]
|
||||
|
||||
|
||||
local weaponDamageEnable = 1
|
||||
local killRangeMultiplier = 0.3
|
||||
local staticDamageRangeMultiplier = 0.1
|
||||
local stunRangeMultiplier = 1.0
|
||||
|
||||
local suppressedGroups = {}
|
||||
local tracked_weapons = {}
|
||||
local USearchArray = {}
|
||||
WpnHandler = {}
|
||||
|
||||
local function getDistance(point1, point2)
|
||||
|
||||
local x1 = point1.x
|
||||
local y1 = point1.y
|
||||
local z1 = point1.z
|
||||
local x2 = point2.x
|
||||
local y2 = point2.y
|
||||
local z2 = point2.z
|
||||
local dX = math.abs(x1-x2)
|
||||
local dZ = math.abs(z1-z2)
|
||||
local distance = math.sqrt(dX*dX + dZ*dZ)
|
||||
|
||||
return distance
|
||||
|
||||
end
|
||||
|
||||
local function getDistance3D(point1, point2)
|
||||
|
||||
local x1 = point1.x
|
||||
local y1 = point1.y
|
||||
local z1 = point1.z
|
||||
local x2 = point2.x
|
||||
local y2 = point2.y
|
||||
local z2 = point2.z
|
||||
|
||||
local dX = math.abs(x1-x2)
|
||||
local dY = math.abs(y1-y2)
|
||||
local dZ = math.abs(z1-z2)
|
||||
local distance = math.sqrt(dX*dX + dZ*dZ + dY*dY)
|
||||
|
||||
return distance
|
||||
|
||||
end
|
||||
|
||||
local function suppress(suppArray)
|
||||
|
||||
suppressedGroups[suppArray[1]:getName()] = {["SuppGroup"] = suppArray[1], ["SuppTime"] = suppArray[2]}
|
||||
if suppArray[1]:getController() then
|
||||
suppArray[1]:getController():setOnOff(false)
|
||||
-- env.info("Group: "..suppArray[1]:getName().." suppressed")
|
||||
end
|
||||
|
||||
end
|
||||
|
||||
local function unSuppress(unSuppGroup)
|
||||
-- env.info("In unSuppress")
|
||||
if unSuppGroup:isExist() and unSuppGroup:getController() then
|
||||
unSuppGroup:getController():setOnOff(true)
|
||||
-- env.info("Got controller")
|
||||
-- env.info("Suppressed group removed from table")
|
||||
suppressedGroups[unSuppGroup:getName()] = nil
|
||||
end
|
||||
end
|
||||
|
||||
local function ifFoundS(foundItem, impactPoint)
|
||||
-- trigger.action.outText("Found Static", 10)
|
||||
-- env.info("Found static in kill range")
|
||||
local point1 = foundItem:getPoint()
|
||||
point1.y = point1.y + 2
|
||||
local point2 = impactPoint
|
||||
point2.y = point2.y + 2
|
||||
if land.isVisible(point1, point2) == true then
|
||||
-- env.info("Static"..foundItem:getID().. "Destroyed by script")
|
||||
trigger.action.explosion(point1, 5)
|
||||
end
|
||||
end
|
||||
|
||||
local function ifFoundU(foundItem, USearchArray)
|
||||
|
||||
-- env.info("Found Unit")
|
||||
local point1 = foundItem:getPoint()
|
||||
-- env.info("Got point")
|
||||
point1.y = point1.y + 5
|
||||
local point2 = USearchArray.point
|
||||
point2.y = point2.y + 5
|
||||
if land.isVisible(point1, point2) == true then
|
||||
-- env.info("is visible LOS")
|
||||
local distanceFrom = getDistance(point1, point2)
|
||||
-- env.info("got distance: "..distanceFrom)
|
||||
if distanceFrom < USearchArray.exMass*killRangeMultiplier then
|
||||
trigger.action.explosion(foundItem:getPoint(), 1)
|
||||
-- env.info("Unit: "..foundItem:getName().." was destroyed by script")
|
||||
-- else
|
||||
-- local suppTimer = math.random(30,100)
|
||||
-- local suppArray = {foundItem:getGroup(), suppTimer}
|
||||
-- suppress(suppArray)
|
||||
end
|
||||
end
|
||||
|
||||
end
|
||||
|
||||
local function track_wpns()
|
||||
-- env.info("Weapon Track Start")
|
||||
for wpn_id_, wpnData in pairs(tracked_weapons) do
|
||||
|
||||
if wpnData.wpn:isExist() then -- just update position and direction.
|
||||
wpnData.pos = wpnData.wpn:getPosition().p
|
||||
wpnData.dir = wpnData.wpn:getPosition().x
|
||||
wpnData.exMass = wpnData.wpn:getDesc().warhead.explosiveMass
|
||||
--wpnData.lastIP = land.getIP(wpnData.pos, wpnData.dir, 50)
|
||||
else -- wpn no longer exists, must be dead.
|
||||
-- trigger.action.outText("Weapon impacted, mass of weapon warhead is " .. wpnData.exMass, 2)
|
||||
local ip = land.getIP(wpnData.pos, wpnData.dir, 20) -- terrain intersection point with weapon's nose. Only search out 20 meters though.
|
||||
local impactPoint
|
||||
if not ip then -- use last calculated IP
|
||||
impactPoint = wpnData.pos
|
||||
-- trigger.action.outText("Impact Point:\nPos X: " .. impactPoint.x .. "\nPos Z: " .. impactPoint.z, 2)
|
||||
else -- use intersection point
|
||||
impactPoint = ip
|
||||
-- trigger.action.outText("Impact Point:\nPos X: " .. impactPoint.x .. "\nPos Z: " .. impactPoint.z, 2)
|
||||
end
|
||||
local staticRadius = wpnData.exMass*staticDamageRangeMultiplier
|
||||
-- trigger.action.outText("Static Radius :"..staticRadius, 10)
|
||||
local VolS =
|
||||
{
|
||||
id = world.VolumeType.SPHERE,
|
||||
params =
|
||||
{
|
||||
point = impactPoint,
|
||||
radius = staticRadius
|
||||
}
|
||||
}
|
||||
local VolU =
|
||||
{
|
||||
id = world.VolumeType.SPHERE,
|
||||
params =
|
||||
{
|
||||
point = impactPoint,
|
||||
radius = wpnData.exMass*stunRangeMultiplier
|
||||
}
|
||||
}
|
||||
-- env.info("Static search radius: " ..wpnData.exMass*staticDamageRangeMultiplier)
|
||||
-- env.warning("Begin Search")
|
||||
-- trigger.action.outText("Beginning Searches", 10)
|
||||
world.searchObjects(Object.Category.STATIC, VolS, ifFoundS,impactPoint)
|
||||
USearchArray = {["point"] = impactPoint, ["exMass"] = wpnData.exMass}
|
||||
world.searchObjects(Object.Category.UNIT, VolU, ifFoundU, USearchArray)
|
||||
-- env.warning("Finished Search")
|
||||
tracked_weapons[wpn_id_] = nil -- remove from tracked weapons first.
|
||||
end
|
||||
end
|
||||
-- env.info("Weapon Track End")
|
||||
end
|
||||
|
||||
local function checkSuppression()
|
||||
-- env.info("Checking suppression")
|
||||
for i, group in pairs(suppressedGroups) do
|
||||
-- env.info("Check group exists, #".. i)
|
||||
if group.SuppGroup:isExist() then
|
||||
-- env.info("It does")
|
||||
group.SuppTime = group.SuppTime - 10
|
||||
if group.SuppTime < 1 then
|
||||
-- env.info("SuppTime < 1")
|
||||
unSuppress(group.SuppGroup)
|
||||
end
|
||||
else
|
||||
suppressedGroups[group.SuppGroup:getName()] = nil
|
||||
end
|
||||
end
|
||||
-- env.info("Ending suppression check")
|
||||
end
|
||||
|
||||
function onWpnEvent(event)
|
||||
if event.id == world.event.S_EVENT_SHOT then
|
||||
if event.weapon then
|
||||
local ordnance = event.weapon
|
||||
local weapon_desc = ordnance:getDesc()
|
||||
if (weapon_desc.category == 3 or weapon_desc.category == 2 or weapon_desc.category == 1) and not (weapon_desc.missileCategory == 1 or weapon_desc.missileCategory == 2 or weapon_desc.missileCategory == 3) and weapon_desc.warhead and weapon_desc.warhead.explosiveMass and event.initiator then
|
||||
tracked_weapons[event.weapon.id_] = { wpn = ordnance, init = event.initiator:getName(), pos = ordnance:getPoint(), dir = ordnance:getPosition().x, exMass = weapon_desc.warhead.explosiveMass }
|
||||
-- env.info("Tracking " .. event.initiator:getName())
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
function WpnHandler:onEvent(event)
|
||||
protectedCall(onWpnEvent, event)
|
||||
end
|
||||
|
||||
function protectedCall(...)
|
||||
local status, retval = pcall(...)
|
||||
if not status then
|
||||
env.error("Splash damage script error... gracefully caught! " .. retval, true)
|
||||
end
|
||||
end
|
||||
|
||||
if (weaponDamageEnable == 1) then
|
||||
timer.scheduleFunction(function()
|
||||
protectedCall(track_wpns)
|
||||
return timer.getTime() + 1
|
||||
end,
|
||||
{},
|
||||
timer.getTime() + 0.5
|
||||
)
|
||||
|
||||
timer.scheduleFunction(function()
|
||||
protectedCall(checkSuppression)
|
||||
return timer.getTime() + 1
|
||||
end,
|
||||
{},
|
||||
timer.getTime() + 10
|
||||
)
|
||||
|
||||
world.addEventHandler(WpnHandler)
|
||||
end
|
||||
209
resources/plugins/splashdamage/Weapons_Damage_Updated.lua
Normal file
209
resources/plugins/splashdamage/Weapons_Damage_Updated.lua
Normal file
@ -0,0 +1,209 @@
|
||||
|
||||
|
||||
--[[
|
||||
2 October 2020
|
||||
FrozenDroid:
|
||||
- Added error handling to all event handler and scheduled functions. Lua script errors can no longer bring the server down.
|
||||
- Added some extra checks to which weapons to handle, make sure they actually have a warhead (how come S-8KOM's don't have a warhead field...?)
|
||||
28 October 2020
|
||||
FrozenDroid:
|
||||
- Uncommented error logging, actually made it an error log which shows a message box on error.
|
||||
- Fixed the too restrictive weapon filter (took out the HE warhead requirement)
|
||||
--]]
|
||||
|
||||
explTable = {
|
||||
["FAB_100"] = 45,
|
||||
["FAB_250"] = 100,
|
||||
["FAB_250M54TU"]= 100,
|
||||
["FAB_500"] = 213,
|
||||
["FAB_1500"] = 675,
|
||||
["BetAB_500"] = 98,
|
||||
["BetAB_500ShP"]= 107,
|
||||
["KH-66_Grom"] = 108,
|
||||
["M_117"] = 201,
|
||||
["Mk_81"] = 60,
|
||||
["Mk_82"] = 118,
|
||||
["AN_M64"] = 121,
|
||||
["Mk_83"] = 274,
|
||||
["Mk_84"] = 582,
|
||||
["MK_82AIR"] = 118,
|
||||
["MK_82SNAKEYE"]= 118,
|
||||
["GBU_10"] = 582,
|
||||
["GBU_12"] = 118,
|
||||
["GBU_16"] = 274,
|
||||
["KAB_1500Kr"] = 675,
|
||||
["KAB_500Kr"] = 213,
|
||||
["KAB_500"] = 213,
|
||||
["GBU_31"] = 582,
|
||||
["GBU_31_V_3B"] = 582,
|
||||
["GBU_31_V_2B"] = 582,
|
||||
["GBU_31_V_4B"] = 582,
|
||||
["GBU_32_V_2B"] = 202,
|
||||
["GBU_38"] = 118,
|
||||
["AGM_62"] = 400,
|
||||
["GBU_24"] = 582,
|
||||
["X_23"] = 111,
|
||||
["X_23L"] = 111,
|
||||
["X_28"] = 160,
|
||||
["X_25ML"] = 89,
|
||||
["X_25MP"] = 89,
|
||||
["X_25MR"] = 140,
|
||||
["X_58"] = 140,
|
||||
["X_29L"] = 320,
|
||||
["X_29T"] = 320,
|
||||
["X_29TE"] = 320,
|
||||
["AGM_84E"] = 488,
|
||||
["AGM_88C"] = 89,
|
||||
["AGM_122"] = 15,
|
||||
["AGM_123"] = 274,
|
||||
["AGM_130"] = 582,
|
||||
["AGM_119"] = 176,
|
||||
["AGM_154C"] = 305,
|
||||
["S-24A"] = 24,
|
||||
--["S-24B"] = 123,
|
||||
["S-25OF"] = 194,
|
||||
["S-25OFM"] = 150,
|
||||
["S-25O"] = 150,
|
||||
["S_25L"] = 190,
|
||||
["S-5M"] = 1,
|
||||
["C_8"] = 4,
|
||||
["C_8OFP2"] = 3,
|
||||
["C_13"] = 21,
|
||||
["C_24"] = 123,
|
||||
["C_25"] = 151,
|
||||
["HYDRA_70M15"] = 2,
|
||||
["Zuni_127"] = 5,
|
||||
["ARAKM70BHE"] = 4,
|
||||
["BR_500"] = 118,
|
||||
["Rb 05A"] = 217,
|
||||
["HEBOMB"] = 40,
|
||||
["HEBOMBD"] = 40,
|
||||
["MK-81SE"] = 60,
|
||||
["AN-M57"] = 56,
|
||||
["AN-M64"] = 180,
|
||||
["AN-M65"] = 295,
|
||||
["AN-M66A2"] = 536,
|
||||
}
|
||||
|
||||
local weaponDamageEnable = 1
|
||||
WpnHandler = {}
|
||||
tracked_weapons = {}
|
||||
refreshRate = 0.1
|
||||
|
||||
local function getDistance(point1, point2)
|
||||
local x1 = point1.x
|
||||
local y1 = point1.y
|
||||
local z1 = point1.z
|
||||
local x2 = point2.x
|
||||
local y2 = point2.y
|
||||
local z2 = point2.z
|
||||
local dX = math.abs(x1-x2)
|
||||
local dZ = math.abs(z1-z2)
|
||||
local distance = math.sqrt(dX*dX + dZ*dZ)
|
||||
return distance
|
||||
end
|
||||
|
||||
local function getDistance3D(point1, point2)
|
||||
local x1 = point1.x
|
||||
local y1 = point1.y
|
||||
local z1 = point1.z
|
||||
local x2 = point2.x
|
||||
local y2 = point2.y
|
||||
local z2 = point2.z
|
||||
local dX = math.abs(x1-x2)
|
||||
local dY = math.abs(y1-y2)
|
||||
local dZ = math.abs(z1-z2)
|
||||
local distance = math.sqrt(dX*dX + dZ*dZ + dY*dY)
|
||||
return distance
|
||||
end
|
||||
|
||||
local function vec3Mag(speedVec)
|
||||
|
||||
mag = speedVec.x*speedVec.x + speedVec.y*speedVec.y+speedVec.z*speedVec.z
|
||||
mag = math.sqrt(mag)
|
||||
--trigger.action.outText("X = " .. speedVec.x ..", y = " .. speedVec.y .. ", z = "..speedVec.z, 10)
|
||||
--trigger.action.outText("Speed = " .. mag, 1)
|
||||
return mag
|
||||
|
||||
end
|
||||
|
||||
local function lookahead(speedVec)
|
||||
|
||||
speed = vec3Mag(speedVec)
|
||||
dist = speed * refreshRate * 1.5
|
||||
return dist
|
||||
|
||||
end
|
||||
|
||||
local function track_wpns()
|
||||
-- env.info("Weapon Track Start")
|
||||
for wpn_id_, wpnData in pairs(tracked_weapons) do
|
||||
if wpnData.wpn:isExist() then -- just update speed, position and direction.
|
||||
wpnData.pos = wpnData.wpn:getPosition().p
|
||||
wpnData.dir = wpnData.wpn:getPosition().x
|
||||
wpnData.speed = wpnData.wpn:getVelocity()
|
||||
--wpnData.lastIP = land.getIP(wpnData.pos, wpnData.dir, 50)
|
||||
else -- wpn no longer exists, must be dead.
|
||||
-- trigger.action.outText("Weapon impacted, mass of weapon warhead is " .. wpnData.exMass, 2)
|
||||
local ip = land.getIP(wpnData.pos, wpnData.dir, lookahead(wpnData.speed)) -- terrain intersection point with weapon's nose. Only search out 20 meters though.
|
||||
local impactPoint
|
||||
if not ip then -- use last calculated IP
|
||||
impactPoint = wpnData.pos
|
||||
-- trigger.action.outText("Impact Point:\nPos X: " .. impactPoint.x .. "\nPos Z: " .. impactPoint.z, 2)
|
||||
else -- use intersection point
|
||||
impactPoint = ip
|
||||
-- trigger.action.outText("Impact Point:\nPos X: " .. impactPoint.x .. "\nPos Z: " .. impactPoint.z, 2)
|
||||
end
|
||||
--env.info("Weapon is gone") -- Got to here --
|
||||
--trigger.action.outText("Weapon Type was: ".. wpnData.name, 20)
|
||||
if explTable[wpnData.name] then
|
||||
--env.info("triggered explosion size: "..explTable[wpnData.name])
|
||||
trigger.action.explosion(impactPoint, explTable[wpnData.name])
|
||||
--trigger.action.smoke(impactPoint, 0)
|
||||
end
|
||||
tracked_weapons[wpn_id_] = nil -- remove from tracked weapons first.
|
||||
end
|
||||
end
|
||||
-- env.info("Weapon Track End")
|
||||
end
|
||||
|
||||
function onWpnEvent(event)
|
||||
if event.id == world.event.S_EVENT_SHOT then
|
||||
if event.weapon then
|
||||
local ordnance = event.weapon
|
||||
local weapon_desc = ordnance:getDesc()
|
||||
if (weapon_desc.category ~= 0) and event.initiator then
|
||||
if (weapon_desc.category == 1) then
|
||||
if (weapon_desc.MissileCategory ~= 1 and weapon_desc.MissileCategory ~= 2) then
|
||||
tracked_weapons[event.weapon.id_] = { wpn = ordnance, init = event.initiator:getName(), pos = ordnance:getPoint(), dir = ordnance:getPosition().x, name = ordnance:getTypeName(), speed = ordnance:getVelocity() }
|
||||
end
|
||||
else
|
||||
tracked_weapons[event.weapon.id_] = { wpn = ordnance, init = event.initiator:getName(), pos = ordnance:getPoint(), dir = ordnance:getPosition().x, name = ordnance:getTypeName(), speed = ordnance:getVelocity() }
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
local function protectedCall(...)
|
||||
local status, retval = pcall(...)
|
||||
if not status then
|
||||
env.warning("Splash damage script error... gracefully caught! " .. retval, true)
|
||||
end
|
||||
end
|
||||
|
||||
|
||||
function WpnHandler:onEvent(event)
|
||||
protectedCall(onWpnEvent, event)
|
||||
end
|
||||
|
||||
if (weaponDamageEnable == 1) then
|
||||
timer.scheduleFunction(function()
|
||||
protectedCall(track_wpns)
|
||||
return timer.getTime() + refreshRate
|
||||
end,
|
||||
{},
|
||||
timer.getTime() + refreshRate
|
||||
)
|
||||
world.addEventHandler(WpnHandler)
|
||||
end
|
||||
@ -4,9 +4,9 @@
|
||||
"specificOptions": [],
|
||||
"scriptsWorkOrders": [
|
||||
{
|
||||
"file": "SplashDamage.lua",
|
||||
"file": "Weapons_Damage_Updated.lua",
|
||||
"mnemonic": "Splash Damage"
|
||||
}
|
||||
],
|
||||
"configurationWorkOrders": []
|
||||
}
|
||||
}
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user