While experimenting with capital ships explosion damage, I found that the normal procedure was to create a separate function for every ship you want to implement explosion damage for, which was mostly a duplicate of the other ones, except for a section where you have several DoDamageProximitySobGroup(), that have the various damage radii, and how much is done at each.
This is quite inefficient (in terms of writing code, if not speed), and also hard to implement, especially if you don't have much experience.
I have written a function that, I hope, defeats this problem. It works as a single rule, that looks up a table (provided) for the name, and damage radii, of every ship that needs to be checked. It allows you to have a variable number of radii, each with a different amount of damage (to simulate ships further away taking less damage), and a variable number of ships. It takes up a lot less space than older functions, and is very easy to implement. To add a new ship, or change an existing one, you just have to modify or add a few values to the table.
Updates:
v1.0 - The original code
v1.2 - Added better SobGroup splitting, and auto calculation of numbers of ships and radii
v1.3 - Changed damage from once per death to once per second, added more names to table, lots of general improvements
v2.0 - Having had a look at the Complex Mod's scripts, I have altered about a third of the code. It is now capable of causing the damage at a specific time, determined by fDeathTime.
I have also decided, as of version 2.0, to preserve version 1, as the last one, which did damage per second, was very stable and efficient. The code will be left in the spoiler below:
Explosion Damage, v1.3
Code:ExplosionsTable = { { -- The start of a ship entry in the table name = "Hgn_Mothership", -- The name of the ship numRadii = 0, -- How many radii entries there are - leave this, it is set later radii = -- The radii table { {fRange = 1000, fDamage = 1500}, -- An entry, containing the radius, and amount of damage dealt {fRange = 2000, fDamage = 400}, -- Set the fDamage, which can be a decimal, to your ( desired damage / the ship's sobDieTime ), }, -- as the damage is dealt every second, not once during the explosion }, { name = "Vgr_Mothership", -- Another ship entry numRadii = 0, radii = { {fRange = 1000, fDamage = 1000}, -- This will deal 7000 damage within 1 km, as the Vgr_Mothership's sobDieTime is 7 {fRange = 2000, fDamage = 200 }, -- This will deal an additional 1400 within 2 km {fRange = 4000, fDamage = 100 }, -- This will deal an additional 700 within 4 km }, -- So ships within 1 km will lose a total of 9100 health }, } iTotalShips = 0 -- Initiating a global variable, to count ships into. Don't set this manually function initExplDamage() print("In initExplDamage()\n") --START OF SHIP NUMBER CHECKING SECTION local iTempEntryCount = 0 -- This is used to count the actual number of ships repeat iTempEntryCount = iTempEntryCount + 1 until (not ExplosionsTable[iTempEntryCount + 1]) -- Loop through all. When the next one is nil (false), you have the exact number of entries print(" Counting ships: "..iTempEntryCount.." in total\n") iTotalShips = iTempEntryCount -- Set the global variable --END OF SHIP NUMBER CHECKING SECTION --START OF RADII CHECKING SECTION for iShipEntry = 1, iTotalShips do -- This is used to count the actual numbers of radii iTempEntryCount = 0 -- Resetting the previously used local variable repeat iTempEntryCount = iTempEntryCount + 1 -- Loop through all. When the next one is nil (false), you have the exact number of entries until (not ExplosionsTable[iShipEntry].radii[iTempEntryCount + 1]) print(" "..ExplosionsTable[iShipEntry].name.." has "..iTempEntryCount.." damage radii\n") ExplosionsTable[iShipEntry].numRadii = iTempEntryCount -- Set the global variable end --END OF RADII CHECKING SECTION print("Initiating Tabular Explosion Damage, with "..iTotalShips.." ships\n") Rule_AddInterval("LoopThroughExplosionTable", 1) end function implementExplDamage(sSobGroup, tDamageTable) -- This function takes the table that lists damage and radii for that ship if (SobGroup_HealthPercentage(sSobGroup) <= 0) then -- If the ship's dying, do some damage print (" A ship \""..tDamageTable.name.."\"is exploding!!\n") for iPlayerIndex = 0, Universe_PlayerCount() - 1 do -- Go through every player to do damage to if (Player_IsAlive(iPlayerIndex) == 1) then -- If that player is still alive, for iDamageEntry = 1, tDamageTable.numRadii do -- Go through every level of damage, as listed in the table -- And do damage to all player's ships in proximity SobGroup_DoDamageProximitySobGroup(sSobGroup, iPlayerIndex, tDamageTable.radii[iDamageEntry].fDamage, tDamageTable.radii[iDamageEntry].fRange) --print (" Doing "..tDamageTable.radii[iDamageEntry].fDamage.." damage to all player "..iPlayerIndex.." ships, at "..tDamageTable.radii[iDamageEntry].fRange.." metres\n") end end end end end function LoopThroughExplosionTable() --print ("In LoopThroughExplosionTable()\n") Update_AllShips() SobGroup_Create("TempRuntimeSobGroup") SobGroup_Clear("TempRuntimeSobGroup") for iPlayerIndex = 0, Universe_PlayerCount() - 1 do -- Go through every player if (Player_IsAlive(iPlayerIndex) == 1) then -- Don't bother for dead players for iTableEntry = 1, iTotalShips do -- Go through all the ship entries local shipName = ExplosionsTable[iTableEntry].name -- Inititate the ship's name to the appropriate entry in the table Player_FillShipsByType("TempRuntimeSobGroup", iPlayerIndex, shipName) -- Get all ships of that ype local numShips = SobGroup_Count("TempRuntimeSobGroup") -- Count them if (numShips > 0) then --print (" Player "..iPlayerIndex.." has "..numShips.." ships of type "..shipName.."\n") end if (numShips == 0) then -- Do nothing elseif (numShips == 1) then -- If 1 ship, don't need to split SobGroups implementExplDamage("TempRuntimeSobGroup", ExplosionsTable[iTableEntry]) elseif (numShips == 2) then -- If 2 ships, SplitGroup won't work, only SplitGroupReference --print(" 2 ships, so using SplitGroupReference") local numGroups = SobGroup_SplitGroupReference("sRuntimeGroup2", "TempRuntimeSobGroup", "AllShips", numShips) for iShipIndex = 0, numGroups - 1 do if (SobGroup_Count("sRuntimeGroup2"..iShipIndex) == 1) then implementExplDamage("sRuntimeGroup2"..iShipIndex, ExplosionsTable[iTableEntry]) else print(" [SobGroup Splitting of "..SobGroup_Count("sRuntimeGroup2"..iShipIndex).." of Player "..iPlayerIndex.."'s "..numShips.." "..shipName.."'s failed. Skipping]") end end elseif (numShips ~= 0) then -- Split groups, if not 0 ships (in which case, skip) local numGroups = SobGroup_SplitGroup("sRuntimeGroup2", "TempRuntimeSobGroup", numShips) for iShipIndex = 0, numGroups - 1 do if (SobGroup_Count("sRuntimeGroup2"..iShipIndex) ~= 1) then -- If it hasn't split completely, try again with SplitGroupReference print(" [Basic Splitting of "..SobGroup_Count("sRuntimeGroup2"..iShipIndex).." of Player "..iPlayerIndex.."'s "..numShips.." "..shipName.."'s failed. Using SplitGroupReference]") local numGroups2 = SobGroup_SplitGroupReference("sRuntimeGroup3", "sRuntimeGroup2"..iShipIndex, "AllShips", numShips) for iShipIndex2 = 0, numGroups2 - 1 do if (SobGroup_Count("sRuntimeGroup3"..iShipIndex2) == 1) then implementExplDamage("sRuntimeGroup3"..iShipIndex2, ExplosionsTable[iTableEntry]) else print(" [Advanced Splitting failed. Skipping]") end end else implementExplDamage("sRuntimeGroup2"..iShipIndex, ExplosionsTable[iTableEntry]) end end end end end end end
This code up there is only the main part. It doesn't contain SobGroup_SplitGroup, or any documentation. Documentation isn't really needed, as the table is still very similar to the current version, and any important info is in the comments.
The code for the latest version, however, is below:
The above already has a table that does some damage for the vaygr and hiigaran motherships. Note that it is only an example, and should be replaced with your preferred values.Code:ExplosionsTable = { { -- The start of a ship entry in the table name = "Hgn_Mothership", -- The name of the ship numRadii = 0, -- How many radii entries there are - leave this, it is set later fDeathTime = 6.5, -- How long after the ship runs out of health, and starts exploding, should the damage be applied radii = -- The radii table { {fRange = 1000, fDamage = 10000}, -- An entry, containing the radius (fRange), and amount of damage dealt (fDamage) {fRange = 2000, fDamage = 4000 }, }, }, { name = "Vgr_Mothership", -- Another ship entry numRadii = 0, fDeathTime = 6.5, -- Note that this value must be smaller than the ship's sobDieTime, and also, radii = -- The difference should be MORE than the sum of fDeathCheckRate and fTimerCheckRate (below) { {fRange = 1000, fDamage = 8000}, {fRange = 2000, fDamage = 2000}, {fRange = 4000, fDamage = 1000}, }, }, } fDeathCheckRate = 0.1 -- This affects how often the script checks for dying ships, and starts timing them fTimerCheckRate = 0.2 -- This is how often the script checks if the timers are done, and implement explosion damage -- For both of these values, setting them lower will give greater accuracy -- In addition, any ship's (sobDieTime - fDeathTime) MUST be greater than the sum of these two iTotalShips = 0 -- Initiating a global variable, to count ships into. Don't set this manually function initExplDamage() print("In initExplDamage()") iTotalShips = LengthOf(ExplosionsTable) -- Count the number of entries in the table print(" Counting ships: "..iTotalShips.." in total")-- And therefore the number of ships with Explosion Damage for iShipEntry = 1, iTotalShips do -- For each ship, count the number of damage radii ExplosionsTable[iShipEntry].numRadii = LengthOf(ExplosionsTable[iShipEntry].radii) print(" "..ExplosionsTable[iShipEntry].name.." has "..ExplosionsTable[iShipEntry].numRadii.." damage radii, and an fDeathTime of "..ExplosionsTable[iShipEntry].fDeathTime) end print("Initiating Tabular Explosion Damage, with "..iTotalShips.." ships") ExplWaitTimers = {} -- Create a table - this will later contain the timers for iTempCounter = 1, iTotalShips do ExplWaitTimers[iTempCounter] = {} -- Create sub-tables, one for each ship type end -- Each one will later contain a counter for every ship of that type that is exploding Rule_AddInterval("LoopThroughExplosionTable", fDeathCheckRate) -- Add the rule that adds ships to the "Exploding" list, and the timer Rule_AddInterval("CheckTimers", fTimerCheckRate) -- Add the rule that checks the "Exploding" list for ships whose timer has finished end function implementExplDamage(sSobGroup, tDamageTable) -- This function takes the table that lists damage and radii for that ship --print (" A ship/s of type \""..tDamageTable.name.."\" is/are exploding!!") for iPlayerIndex = 0, Universe_PlayerCount() - 1 do -- Go through every player to do damage to if (Player_IsAlive(iPlayerIndex) == 1) then -- If that player is still alive, for iDamageEntry = 1, tDamageTable.numRadii do -- Go through every level of damage, as listed in the table -- And do damage to all player's ships in proximity SobGroup_DoDamageProximitySobGroup(sSobGroup, iPlayerIndex, tDamageTable.radii[iDamageEntry].fDamage, tDamageTable.radii[iDamageEntry].fRange) end end end end function LoopThroughExplosionTable() --print ("In LoopThroughExplosionTable()") Update_AllShips() SobGroup_Create("TempRuntimeSobGroup") SobGroup_Clear("TempRuntimeSobGroup") for iTableEntry = 1, iTotalShips do -- Go through all the ship entries local shipName = ExplosionsTable[iTableEntry].name -- Inititate the ship's name to the appropriate entry in the table local iWaitTimer = FindOrCreateNextEmptySobGroup(shipName) -- Generate a temporary timer index - this will be used if any ships are dying for iPlayerIndex = 0, Universe_PlayerCount() - 1 do -- Go through every player if (Player_IsAlive(iPlayerIndex) == 1) then -- Don't bother for dead players Player_FillShipsByType("TempRuntimeSobGroup", iPlayerIndex, shipName) -- Get all ships of that ype local numShips = SobGroup_Count("TempRuntimeSobGroup") -- Count them --if (numShips > 0) then --print (" Player "..iPlayerIndex.." has "..numShips.." ships of type "..shipName) --end if (numShips == 1) then -- If 1 ship, don't need to split SobGroups CheckShipForDeath("TempRuntimeSobGroup", iWaitTimer, iTableEntry) elseif (numShips == 2) then -- If 2 ships, SplitGroup won't work, only SplitGroupReference local numGroups = SobGroup_SplitGroupReference("sRuntimeGroup2", "TempRuntimeSobGroup", "AllShips", numShips) for iShipIndex = 0, numGroups - 1 do if (SobGroup_Count("sRuntimeGroup2"..iShipIndex) == 1) then CheckShipForDeath("sRuntimeGroup2"..iShipIndex, iWaitTimer, iTableEntry) else print(" [SobGroup Splitting of "..SobGroup_Count("sRuntimeGroup2"..iShipIndex).." of Player "..iPlayerIndex.."'s "..numShips.." "..shipName.."'s failed. Skipping]") end end elseif (numShips > 2) then -- Split groups, if not 0 ships (in which case, skip) local numGroups = SobGroup_SplitGroup("sRuntimeGroup2", "TempRuntimeSobGroup", numShips) for iShipIndex = 0, numGroups - 1 do if (SobGroup_Count("sRuntimeGroup2"..iShipIndex) ~= 1) then -- If it hasn't split completely, try again with SplitGroupReference print(" [Basic Splitting of "..SobGroup_Count("sRuntimeGroup2"..iShipIndex).." of Player "..iPlayerIndex.."'s "..numShips.." "..shipName.."'s failed. Using SplitGroupReference]") local numGroups2 = SobGroup_SplitGroupReference("sRuntimeGroup3", "sRuntimeGroup2"..iShipIndex, "AllShips", numShips) for iShipIndex2 = 0, numGroups2 - 1 do if (SobGroup_Count("sRuntimeGroup3"..iShipIndex2) == 1) then CheckShipForDeath("sRuntimeGroup3"..iShipIndex2, iWaitTimer, iTableEntry) else print(" [Advanced Splitting failed. Skipping]") -- Aaargh! This didn't work either! Oh, well, skip them for now end end else CheckShipForDeath("sRuntimeGroup2"..iShipIndex, iWaitTimer, iTableEntry) -- It split properly the first time end end end end end if (SobGroup_Empty(shipName..iWaitTimer) == 0) then -- This group would have been generated with the temporary timer index and filled with any dying ships ExplWaitTimers[iTableEntry][iWaitTimer] = Wait_Start(ExplosionsTable[iTableEntry].fDeathTime) -- If it's empty, it will be used again next time print ("Initiating wait timer \"ExplWaitTimers["..iTableEntry.."]["..iWaitTimer.."]\"") end -- If it's not empty, a ship has started exploding, and the actual timer for it is initiated, using the temporary index end end function CheckShipForDeath(sSobGroup, iWaitTimer, iShipEntry) -- This is the function that will add dying ships to a the shipName..iWaitTimer group if (SobGroup_HealthPercentage(sSobGroup) <= 0) then -- If the ship is dying, we should add it to the SobGroup, but for iSobIndex = 1, iWaitTimer do -- We should only add the ship if it hasn't been added before if (SobGroup_GroupInGroup(ExplosionsTable[iShipEntry].name..iSobIndex, sSobGroup) == 1) then return -- Otherwise, we will be wasting memory, AND, it will override other ships that start dying later end -- As the function runs several times a second, and the ship has <= 0 health each time end SobGroup_SobGroupAdd(ExplosionsTable[iShipEntry].name..iWaitTimer, sSobGroup) -- If the function has't returned yet, the ship is a new one - add it --print("A ship, "..ExplosionsTable[iShipEntry].name..", ("..sSobGroup..") is dying - adding to SobGroup "..ExplosionsTable[iShipEntry].name..iWaitTimer) end end function LengthOf(tTable) local iTableLength = 0 repeat iTableLength = iTableLength + 1 until (not tTable[iTableLength + 1]) -- Loop through all. When the next one is nil (false), you have the exact number of entries return iTableLength end function FindOrCreateNextEmptySobGroup(sSobGroupBaseName) -- This function goes through all the dying ships SobGroups, and finds the first empty one (or creates a new one) local bFunctionOver = 0 -- When this is true, we are done local iWaitTimer = 1 -- The iterator - the name is standard throughout my script while (bFunctionOver == 0) do SobGroup_Create(sSobGroupBaseName..iWaitTimer) -- This will create, if not existing already if ( SobGroup_Empty(sSobGroupBaseName..iWaitTimer) == 1 ) then bFunctionOver = 1 -- If it's empty, return the current iWaitTimer else iWaitTimer = iWaitTimer + 1 -- Othewise, try again with the next one end end return iWaitTimer -- This value will be used to reference the new SobGroup, and a potentially new Timer variable end function CheckTimers() -- This function goes through all the existing timer variables (in the ExplWaitTimers table) for iShipEntry = 1, iTotalShips do -- And the associated dying ships SobGroups - if the timer is done, cause damage local iWaitTimer = 0 while (ExplWaitTimers[iShipEntry][iWaitTimer + 1]) do -- Go through all timers, until the next one is nil (i.e. you're on the last one) iWaitTimer = iWaitTimer + 1 if ( SobGroup_Empty(ExplosionsTable[iShipEntry].name..iWaitTimer) == 0 ) then -- If this isn't an empty explosion group, if ( Wait_End(ExplWaitTimers[iShipEntry][iWaitTimer]) == 1 ) then -- If the time has passed --print ("Implementing damage for ship "..ExplosionsTable[iShipEntry].name.." ("..ExplosionsTable[iShipEntry].name..iWaitTimer.."), with Timer \"ExplWaitTimers["..iShipEntry.."]["..iWaitTimer.."]\"") implementExplDamage(ExplosionsTable[iShipEntry].name..iWaitTimer, ExplosionsTable[iShipEntry]) SobGroup_Clear(ExplosionsTable[iShipEntry].name..iWaitTimer) -- Cause proximity damage, and clear the dying ships group ExplWaitTimers[iShipEntry][iWaitTimer] = 0 end end end end end
To implement, paste the above code into deathmatch.lua, also paste the SobGroup_SplitGroup() and SobGroup_SplitGroupReference() functions:
SplitGroup and SplitGroupReference
Code:function SobGroup_SplitGroup(SobGroupOut, SobGroupToSplit, NumberToSplit) -- function created by Apollyon470 local index = 0 local distance = 0 local bool = 0 local SobNum = 0 SobGroup_Create("TempSobGroup") SobGroup_Clear ("TempSobGroup") SobGroup_Create("TempSobGroup1") SobGroup_Clear ("TempSobGroup1") SobGroup_SobGroupAdd ("TempSobGroup", SobGroupToSplit) if ( SobGroup_Empty (SobGroupToSplit) == 1 ) then return 0 end if ( NumberToSplit > SobGroup_Count(SobGroupToSplit) ) then NumberToSplit = SobGroup_Count(SobGroupToSplit) end while (index < NumberToSplit ) do bool = 0 -- in the interests of resource saving, we start with a search band of 625 interval = 625 while (bool == 0) do distance = distance + interval -- something went wrong. Please tell me, or have a go at fixing it yourself. if (interval > 3000000) then bool = 1 return SobNum end SobGroup_FillProximitySobGroup ("TempSobGroup1", "TempSobGroup", SobGroupToSplit, distance) if (SobGroup_Empty("TempSobGroup1") == 1)then -- get the next interval else if (SobGroup_Count("TempSobGroup1") > 1) then -- too many ships, reduce interval if (interval <= .2) then -- Screw it! chunk 'em all in the same sobgroup SobGroup_Create(SobGroupOut .. tostring(SobNum)) SobGroup_Clear (SobGroupOut .. tostring(SobNum)) SobGroup_SobGroupAdd (SobGroupOut .. tostring(SobNum), "TempSobGroup1") SobGroup_Create("tempsob") SobGroup_FillSubstract("tempsob", "TempSobGroup", SobGroupOut .. tostring(SobNum)) SobGroup_Clear ("TempSobGroup") SobGroup_SobGroupAdd ("TempSobGroup", "tempsob") bool = 1 else distance = distance - interval interval = interval / 5 end else -- we got one! add it to the list! SobGroup_Create(SobGroupOut .. tostring(SobNum)) SobGroup_Clear (SobGroupOut .. tostring(SobNum)) SobGroup_SobGroupAdd (SobGroupOut .. tostring(SobNum), "TempSobGroup1") SobGroup_Create("tempsob") SobGroup_FillSubstract("tempsob", "TempSobGroup", SobGroupOut .. tostring(SobNum)) SobGroup_Clear ("TempSobGroup") SobGroup_SobGroupAdd ("TempSobGroup", "tempsob") bool = 1 end end end index = index + SobGroup_Count(SobGroupOut .. tostring(SobNum)) SobNum = SobNum + 1 end return SobNum end function SobGroup_SplitGroupReference(SobGroupOut, SobGroupToSplit, ReferenceSobGroup, NumberToSplit) -- function created by Apollyon470 local index = 0 local distance = 0 local bool = 0 local SobNum = 0 SobGroup_Create("TempSobGroup") SobGroup_Clear ("TempSobGroup") SobGroup_Create("TempSobGroup1") SobGroup_Clear ("TempSobGroup1") SobGroup_SobGroupAdd ("TempSobGroup", SobGroupToSplit) if ( SobGroup_Empty (SobGroupToSplit) == 1 ) then return 0 end if ( NumberToSplit > SobGroup_Count(SobGroupToSplit) ) then NumberToSplit = SobGroup_Count(SobGroupToSplit) end while (index < NumberToSplit ) do bool = 0 -- in the interests of resource saving, we start with a search band of 625 interval = 625 while (bool == 0) do distance = distance + interval -- something went wrong. Please tell me, or have a go at fixing it yourself. if (interval > 3000000) then bool = 1 return SobNum end SobGroup_FillProximitySobGroup ("TempSobGroup1", "TempSobGroup", ReferenceSobGroup, distance) if (SobGroup_Empty("TempSobGroup1") == 1)then -- get the next interval else if (SobGroup_Count("TempSobGroup1") > 1) then -- too many ships, reduce interval if (interval <= .2) then -- Screw it! chunk 'em all in the same sobgroup SobGroup_Create(SobGroupOut .. tostring(SobNum)) SobGroup_Clear (SobGroupOut .. tostring(SobNum)) SobGroup_SobGroupAdd (SobGroupOut .. tostring(SobNum), "TempSobGroup1") SobGroup_Create("tempsob") SobGroup_FillSubstract("tempsob", "TempSobGroup", SobGroupOut .. tostring(SobNum)) SobGroup_Clear ("TempSobGroup") SobGroup_SobGroupAdd ("TempSobGroup", "tempsob") bool = 1 else distance = distance - interval interval = interval / 5 end else -- we got one! add it to the list! SobGroup_Create(SobGroupOut .. tostring(SobNum)) SobGroup_Clear (SobGroupOut .. tostring(SobNum)) SobGroup_SobGroupAdd (SobGroupOut .. tostring(SobNum), "TempSobGroup1") SobGroup_Create("tempsob") SobGroup_FillSubstract("tempsob", "TempSobGroup", SobGroupOut .. tostring(SobNum)) SobGroup_Clear ("TempSobGroup") SobGroup_SobGroupAdd ("TempSobGroup", "tempsob") bool = 1 end end end index = index + SobGroup_Count(SobGroupOut .. tostring(SobNum)) SobNum = SobNum + 1 end return SobNum end
Next, paste the Update_AllShips() function:
Update_AllShips()
Code:function Update_AllShips() SobGroup_Create("AllShips") SobGroup_Clear("AllShips") for iPlayerIndex = 0, Universe_PlayerCount() - 1 do if (Player_IsAlive(iPlayerIndex) == 1) then SobGroup_SobGroupAdd("AllShips", "Player_Ships"..iPlayerIndex) end end end
Finally, and add one line to OnInit(), a function in deathmatch.lua:
voila!Code:initExplDamage()
If you know what you are doing, you may want to paste the scripts into a different file, then add it to your main file using dofilepath().
Also, if you are already using Update_AllShips(), or the splitting functions (you need both SplitGroup and SplitGroupReference), then you, of course, don't need to copy them again.
As for the table, here is how it works:
Whenever you add something, you should make sure it matches the layout of all the others, such as commas, variable names and braces.
The table is split into sections, each one is a table dedicated to one ship. In that table, the first variable, name, is a string containing the ship's name. The second variable, numRadii, you don't need to set, as the script will automatically count them and set it for its own use.
Next, the third variable, fDeathTime, is how long after the ship's health runs out the damage is done. This should be set so it matches the time of the big, blinding explosion, as that is the time that it seems logical for nearby ships to get hurt. This should be tailored for individual ships. For example, the Vaygr and Hiigaran motherships both take 7 seconds to die, and the FX explosion occurs about half a second before. So the values are set to 6.5. Note that the time is not exact. Instead, it will be within a range, equal to the sum of fDeathCheckRate and fTimerCheckRate. This isn't too bad, as the blinding flash tends to last for a while, and, at the default range, 0.3 (0.1 + 0.2), the damage should be during this explosion anyway. You can reduce those two values for greater accuracy. Finally, fDeathTime must not only be less than how long the ship takes to die, but the difference must be greater than the sum of the two variables. If it is not, ships will not do damage consistently. To find out how long a ship takes to die, look at the sobDieTime, in the *.ship file.
After fDeathTime is a table, radii, that contains individual entries. This contains a list of all the radii of damage that a ship will cause upon exploding. You can have any number of radii, so that ships further away don't get damaged as much. Note that they stack, so the closest ships will take damage from every radius, not just the nearest one. fRange is the size of each radius, and fDamage is the damage it causes. They can both be decimals.
As an example, if you have a ship that has a sobDieTime of 5 seconds, and you want all ships in 500 metres to take 1500 Damage, and 1 km to take 500 damage, one second before death, you will need to create two radii. The inner one should have an fRange of 500, and an fDamage of 1000. This will give all inner ships 1000 damage. The outer radius should have an fRange of 1000, and an fDamage of 500. This will give inner ships an additional 500 damage (for a total of 1500), and outer ships 500. fDeathTime should be set to 4.
If the ship were named Hgn_NewShip, the table entry would look like this:
Finally, after the ExplosionsTable, there are two variables: fDeathCheckRate, and fTimerCheckRate. These control how often the script checks for newly dying ships, and ships due for explosion damage (after fDeathTime has passed), respectively. The time of the explosion damage will only be accurate to the sum of these two. The default values (0.1 and 0.2) add up to 0.3, i.e. three tenths of a second. This is good enough for most ships. If you find you need greater accuracy, you can reduce these values.Code:{ name = "Hgn_NewShip", numRadii = 0, fDeathTime = 4, radii = { {fRange = 500, fDamage = 1000}, {fRange = 1000, fDamage = 500}, }, },
Note once a ship's sobDieTime is over, it disappears completely from the game, and it is no longer possible to apply damage. If the difference between the explosion time and the death time is less than the range, your ships will not explode consistently, as every time the range falls above the sobDieTime, there will be no ship to do explosion damage from.



