diff --git a/resources/plugins/plugins.json b/resources/plugins/plugins.json index 9b415eea..f93888d5 100644 --- a/resources/plugins/plugins.json +++ b/resources/plugins/plugins.json @@ -1,7 +1,8 @@ -[ - "base", - "jtacautolase", - "skynetiads", - "ewrs", - "herculescargo" -] +[ + "base", + "jtacautolase", + "skynetiads", + "ewrs", + "herculescargo", + "splashdamage" +] diff --git a/resources/plugins/splashdamage/LICENSE.md b/resources/plugins/splashdamage/LICENSE.md new file mode 100644 index 00000000..29f81d81 --- /dev/null +++ b/resources/plugins/splashdamage/LICENSE.md @@ -0,0 +1,201 @@ + Apache License + Version 2.0, January 2004 + http://www.apache.org/licenses/ + + TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION + + 1. Definitions. + + "License" shall mean the terms and conditions for use, reproduction, + and distribution as defined by Sections 1 through 9 of this document. + + "Licensor" shall mean the copyright owner or entity authorized by + the copyright owner that is granting the License. + + "Legal Entity" shall mean the union of the acting entity and all + other entities that control, are controlled by, or are under common + control with that entity. For the purposes of this definition, + "control" means (i) the power, direct or indirect, to cause the + direction or management of such entity, whether by contract or + otherwise, or (ii) ownership of fifty percent (50%) or more of the + outstanding shares, or (iii) beneficial ownership of such entity. + + "You" (or "Your") shall mean an individual or Legal Entity + exercising permissions granted by this License. + + "Source" form shall mean the preferred form for making modifications, + including but not limited to software source code, documentation + source, and configuration files. + + "Object" form shall mean any form resulting from mechanical + transformation or translation of a Source form, including but + not limited to compiled object code, generated documentation, + and conversions to other media types. + + "Work" shall mean the work of authorship, whether in Source or + Object form, made available under the License, as indicated by a + copyright notice that is included in or attached to the work + (an example is provided in the Appendix below). + + "Derivative Works" shall mean any work, whether in Source or Object + form, that is based on (or derived from) the Work and for which the + editorial revisions, annotations, elaborations, or other modifications + represent, as a whole, an original work of authorship. For the purposes + of this License, Derivative Works shall not include works that remain + separable from, or merely link (or bind by name) to the interfaces of, + the Work and Derivative Works thereof. + + "Contribution" shall mean any work of authorship, including + the original version of the Work and any modifications or additions + to that Work or Derivative Works thereof, that is intentionally + submitted to Licensor for inclusion in the Work by the copyright owner + or by an individual or Legal Entity authorized to submit on behalf of + the copyright owner. For the purposes of this definition, "submitted" + means any form of electronic, verbal, or written communication sent + to the Licensor or its representatives, including but not limited to + communication on electronic mailing lists, source code control systems, + and issue tracking systems that are managed by, or on behalf of, the + Licensor for the purpose of discussing and improving the Work, but + excluding communication that is conspicuously marked or otherwise + designated in writing by the copyright owner as "Not a Contribution." + + "Contributor" shall mean Licensor and any individual or Legal Entity + on behalf of whom a Contribution has been received by Licensor and + subsequently incorporated within the Work. + + 2. Grant of Copyright License. Subject to the terms and conditions of + this License, each Contributor hereby grants to You a perpetual, + worldwide, non-exclusive, no-charge, royalty-free, irrevocable + copyright license to reproduce, prepare Derivative Works of, + publicly display, publicly perform, sublicense, and distribute the + Work and such Derivative Works in Source or Object form. + + 3. Grant of Patent License. Subject to the terms and conditions of + this License, each Contributor hereby grants to You a perpetual, + worldwide, non-exclusive, no-charge, royalty-free, irrevocable + (except as stated in this section) patent license to make, have made, + use, offer to sell, sell, import, and otherwise transfer the Work, + where such license applies only to those patent claims licensable + by such Contributor that are necessarily infringed by their + Contribution(s) alone or by combination of their Contribution(s) + with the Work to which such Contribution(s) was submitted. If You + institute patent litigation against any entity (including a + cross-claim or counterclaim in a lawsuit) alleging that the Work + or a Contribution incorporated within the Work constitutes direct + or contributory patent infringement, then any patent licenses + granted to You under this License for that Work shall terminate + as of the date such litigation is filed. + + 4. Redistribution. You may reproduce and distribute copies of the + Work or Derivative Works thereof in any medium, with or without + modifications, and in Source or Object form, provided that You + meet the following conditions: + + (a) You must give any other recipients of the Work or + Derivative Works a copy of this License; and + + (b) You must cause any modified files to carry prominent notices + stating that You changed the files; and + + (c) You must retain, in the Source form of any Derivative Works + that You distribute, all copyright, patent, trademark, and + attribution notices from the Source form of the Work, + excluding those notices that do not pertain to any part of + the Derivative Works; and + + (d) If the Work includes a "NOTICE" text file as part of its + distribution, then any Derivative Works that You distribute must + include a readable copy of the attribution notices contained + within such NOTICE file, excluding those notices that do not + pertain to any part of the Derivative Works, in at least one + of the following places: within a NOTICE text file distributed + as part of the Derivative Works; within the Source form or + documentation, if provided along with the Derivative Works; or, + within a display generated by the Derivative Works, if and + wherever such third-party notices normally appear. The contents + of the NOTICE file are for informational purposes only and + do not modify the License. You may add Your own attribution + notices within Derivative Works that You distribute, alongside + or as an addendum to the NOTICE text from the Work, provided + that such additional attribution notices cannot be construed + as modifying the License. + + You may add Your own copyright statement to Your modifications and + may provide additional or different license terms and conditions + for use, reproduction, or distribution of Your modifications, or + for any such Derivative Works as a whole, provided Your use, + reproduction, and distribution of the Work otherwise complies with + the conditions stated in this License. + + 5. Submission of Contributions. Unless You explicitly state otherwise, + any Contribution intentionally submitted for inclusion in the Work + by You to the Licensor shall be under the terms and conditions of + this License, without any additional terms or conditions. + Notwithstanding the above, nothing herein shall supersede or modify + the terms of any separate license agreement you may have executed + with Licensor regarding such Contributions. + + 6. Trademarks. This License does not grant permission to use the trade + names, trademarks, service marks, or product names of the Licensor, + except as required for reasonable and customary use in describing the + origin of the Work and reproducing the content of the NOTICE file. + + 7. Disclaimer of Warranty. Unless required by applicable law or + agreed to in writing, Licensor provides the Work (and each + Contributor provides its Contributions) on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or + implied, including, without limitation, any warranties or conditions + of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A + PARTICULAR PURPOSE. You are solely responsible for determining the + appropriateness of using or redistributing the Work and assume any + risks associated with Your exercise of permissions under this License. + + 8. Limitation of Liability. In no event and under no legal theory, + whether in tort (including negligence), contract, or otherwise, + unless required by applicable law (such as deliberate and grossly + negligent acts) or agreed to in writing, shall any Contributor be + liable to You for damages, including any direct, indirect, special, + incidental, or consequential damages of any character arising as a + result of this License or out of the use or inability to use the + Work (including but not limited to damages for loss of goodwill, + work stoppage, computer failure or malfunction, or any and all + other commercial damages or losses), even if such Contributor + has been advised of the possibility of such damages. + + 9. Accepting Warranty or Additional Liability. While redistributing + the Work or Derivative Works thereof, You may choose to offer, + and charge a fee for, acceptance of support, warranty, indemnity, + or other liability obligations and/or rights consistent with this + License. However, in accepting such obligations, You may act only + on Your own behalf and on Your sole responsibility, not on behalf + of any other Contributor, and only if You agree to indemnify, + defend, and hold each Contributor harmless for any liability + incurred by, or claims asserted against, such Contributor by reason + of your accepting any such warranty or additional liability. + + END OF TERMS AND CONDITIONS + + APPENDIX: How to apply the Apache License to your work. + + To apply the Apache License to your work, attach the following + boilerplate notice, with the fields enclosed by brackets "[]" + replaced with your own identifying information. (Don't include + the brackets!) The text should be enclosed in the appropriate + comment syntax for the file format. We also recommend that a + file or class name and description of purpose be included on the + same "printed page" as the copyright notice for easier + identification within third-party archives. + + Copyright [yyyy] [name of copyright owner] + + Licensed under the Apache License, Version 2.0 (the "License"); + you may not use this file except in compliance with the License. + You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + + Unless required by applicable law or agreed to in writing, software + distributed under the License is distributed on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + See the License for the specific language governing permissions and + limitations under the License. diff --git a/resources/plugins/splashdamage/SplashDamage.lua b/resources/plugins/splashdamage/SplashDamage.lua new file mode 100644 index 00000000..442cf004 --- /dev/null +++ b/resources/plugins/splashdamage/SplashDamage.lua @@ -0,0 +1,228 @@ +--[[ + +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 diff --git a/resources/plugins/splashdamage/plugin.json b/resources/plugins/splashdamage/plugin.json new file mode 100644 index 00000000..b0953d62 --- /dev/null +++ b/resources/plugins/splashdamage/plugin.json @@ -0,0 +1,12 @@ +{ + "nameInUI": "Splash Damage", + "defaultValue": false, + "specificOptions": [], + "scriptsWorkOrders": [ + { + "file": "SplashDamage.lua", + "mnemonic": "Splash Damage" + } + ], + "configurationWorkOrders": [] +} \ No newline at end of file