Difference between revisions of "Script - Flashy Deaths (new)"
(update) |
(update) |
||
Line 9: | Line 9: | ||
We'll call this '''deto-sct.tbm''' - it needs to be placed into '''''../data/tables/''''' directory. | We'll call this '''deto-sct.tbm''' - it needs to be placed into '''''../data/tables/''''' directory. | ||
<pre>#Conditional Hooks | <pre>#Conditional Hooks | ||
− | + | ||
$Application: FS2_Open | $Application: FS2_Open | ||
$On Mission Start: | $On Mission Start: | ||
− | + | ||
[ | [ | ||
− | + | ||
---------------------- | ---------------------- | ||
-- parser functions -- | -- parser functions -- | ||
---------------------- | ---------------------- | ||
− | + | ||
--- get newline and make sure its lowercase | --- get newline and make sure its lowercase | ||
function get_next_line(nfile) | function get_next_line(nfile) | ||
Line 29: | Line 29: | ||
return nline | return nline | ||
end | end | ||
− | + | ||
--- find keyword and return the place where it ends | --- find keyword and return the place where it ends | ||
function find_keyword(line_to_parse, keyword) | function find_keyword(line_to_parse, keyword) | ||
Line 35: | Line 35: | ||
keyword = keyword:lower() | keyword = keyword:lower() | ||
local key_s, key_e = line_to_parse:find(keyword) | local key_s, key_e = line_to_parse:find(keyword) | ||
− | + | ||
-- if we cant find a thing | -- if we cant find a thing | ||
if key_s == nil then | if key_s == nil then | ||
return nil | return nil | ||
end | end | ||
− | + | ||
-- check if the line has been commented away | -- check if the line has been commented away | ||
local comment_s, comment_e = line_to_parse:find("--") | local comment_s, comment_e = line_to_parse:find("--") | ||
− | + | ||
if comment_s == nil then | if comment_s == nil then | ||
return key_e | return key_e | ||
Line 49: | Line 49: | ||
return nil | return nil | ||
end | end | ||
− | + | ||
return key_e | return key_e | ||
end | end | ||
− | + | ||
--- function to initialize the vars | --- function to initialize the vars | ||
function init_entry(name) | function init_entry(name) | ||
− | + | arr_SD_rad[name] = 1 | |
− | |||
− | |||
− | arr_SD_rad[name] = | ||
arr_SD_eff[name] = { } | arr_SD_eff[name] = { } | ||
arr_SD_m[name] = 1 | arr_SD_m[name] = 1 | ||
− | arr_SF_rad[name] = | + | arr_SF_rad[name] = 1 |
arr_SF_eff[name] = 0 | arr_SF_eff[name] = 0 | ||
arr_SB_int[name] = 0 | arr_SB_int[name] = 0 | ||
arr_SB_dur[name] = 0 | arr_SB_dur[name] = 0 | ||
arr_SB_time[name] = 0 | arr_SB_time[name] = 0 | ||
+ | arr_SB_dist[name] = 1 | ||
end | end | ||
− | + | ||
--- specific parsing funcs to make things easier to read --- | --- specific parsing funcs to make things easier to read --- | ||
--- string or rather substring parser | --- string or rather substring parser | ||
Line 77: | Line 75: | ||
return substring | return substring | ||
end | end | ||
− | + | ||
--- function to parse numbers | --- function to parse numbers | ||
function parse_number(start_key, line_to_parse) | function parse_number(start_key, line_to_parse) | ||
− | local result = line_to_parse:match( | + | local result = line_to_parse:sub(start_key) |
− | + | local r_value = result:match('[0-9%.]+') | |
+ | r_value = tonumber(r_value) | ||
+ | return r_value | ||
end | end | ||
− | + | ||
--- function to parse arrays of numbers | --- function to parse arrays of numbers | ||
function parse_number_array(start_key, line_to_parse) | function parse_number_array(start_key, line_to_parse) | ||
-- stuff the array | -- stuff the array | ||
local r = { } | local r = { } | ||
− | for p in line_to_parse:gmatch( | + | local p |
+ | for p in line_to_parse:gmatch('[0-9%.]+') do | ||
p = tonumber(p) | p = tonumber(p) | ||
p = math.floor(p) | p = math.floor(p) | ||
Line 95: | Line 96: | ||
return r | return r | ||
end | end | ||
− | + | ||
--- function to parse things | --- function to parse things | ||
function parse_entry(keyword, flashfile, type, use_same_line) | function parse_entry(keyword, flashfile, type, use_same_line) | ||
Line 116: | Line 117: | ||
end | end | ||
new_entry = find_keyword(c_line, "Name:") | new_entry = find_keyword(c_line, "Name:") | ||
+ | current_start_line = c_line | ||
else | else | ||
c_line = use_same_line | c_line = use_same_line | ||
end | end | ||
− | + | ||
-- check if we found a new entry | -- check if we found a new entry | ||
if new_entry == nil then | if new_entry == nil then | ||
− | c_key = find_keyword(c_line, keyword) | + | local c_key = find_keyword(c_line, keyword) |
if c_key == nil then | if c_key == nil then | ||
-- we didn't find the thing... | -- we didn't find the thing... | ||
Line 142: | Line 144: | ||
end | end | ||
end | end | ||
− | + | ||
----------------------------------------------- | ----------------------------------------------- | ||
-- loading the flash animations | -- loading the flash animations | ||
Line 149: | Line 151: | ||
while something_to_parse == true do | while something_to_parse == true do | ||
local c_line = get_next_line(n_file) | local c_line = get_next_line(n_file) | ||
− | + | ||
-- if we are at end of file, stop the loop | -- if we are at end of file, stop the loop | ||
if c_line == nil then | if c_line == nil then | ||
Line 155: | Line 157: | ||
break | break | ||
end | end | ||
− | + | ||
local entry_start = find_keyword(c_line, "Filename:") | local entry_start = find_keyword(c_line, "Filename:") | ||
− | + | ||
-- if we found something else, try next line | -- if we found something else, try next line | ||
if entry_start ~= nil then | if entry_start ~= nil then | ||
-- ok... so we should have a good entry candidate and all that | -- ok... so we should have a good entry candidate and all that | ||
local current_entry = parse_string(entry_start, c_line) | local current_entry = parse_string(entry_start, c_line) | ||
− | animation = gr.loadTexture(current_entry, true) | + | local animation = gr.loadTexture(current_entry, true) |
table.insert(arr_D_eff, animation) | table.insert(arr_D_eff, animation) | ||
if animation:isValid() == false then | if animation:isValid() == false then | ||
Line 170: | Line 172: | ||
end | end | ||
end | end | ||
− | + | ||
-- actual flash effect parsing function | -- actual flash effect parsing function | ||
function parse_flash_file(flashfile) | function parse_flash_file(flashfile) | ||
Line 190: | Line 192: | ||
else | else | ||
entry_start = find_keyword(use_same_line, "Name:") | entry_start = find_keyword(use_same_line, "Name:") | ||
+ | current_start_line = use_same_line | ||
if entry_start ~= nil then | if entry_start ~= nil then | ||
+ | local not_new_entry = false | ||
-- insert while loop here to enable breaks as next statements | -- insert while loop here to enable breaks as next statements | ||
while entry_start ~= nil do | while entry_start ~= nil do | ||
− | current_entry = parse_string(entry_start, use_same_line) | + | if not_new_entry == false then |
− | + | current_entry = parse_string(entry_start, use_same_line) | |
− | + | -- init the entry | |
− | + | init_entry(current_entry) | |
+ | use_same_line = false | ||
+ | ba.print("\nClass: " .. current_entry .. "\n") | ||
+ | end | ||
+ | |||
local temp_val = nil | local temp_val = nil | ||
local temp_arr = nil | local temp_arr = nil | ||
entry_start = nil | entry_start = nil | ||
− | + | ||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
-- detonation radius | -- detonation radius | ||
− | temp_val, use_same_line = parse_entry("Detonation Radius:", flashfile, "n", use_same_line) | + | temp_val, use_same_line = parse_entry("Detonation Radius Multiplier:", flashfile, "n", use_same_line) |
if temp_val == -2 then | if temp_val == -2 then | ||
break | break | ||
− | + | elseif temp_val ~= -1 then | |
+ | ba.print("DRM: " .. temp_val .. "\n") | ||
arr_SD_rad[current_entry] = temp_val | arr_SD_rad[current_entry] = temp_val | ||
end | end | ||
+ | |||
-- random detonation effects | -- random detonation effects | ||
local temp_arr = {} | local temp_arr = {} | ||
Line 237: | Line 223: | ||
if temp_val == -2 then | if temp_val == -2 then | ||
break | break | ||
− | + | elseif temp_val ~= -1 then | |
+ | ba.print("DE: " .. temp_val .. "\n") | ||
arr_SD_eff[current_entry] = temp_arr | arr_SD_eff[current_entry] = temp_arr | ||
end | end | ||
− | + | ||
-- multiplier for the detonation occurrance | -- multiplier for the detonation occurrance | ||
temp_val, use_same_line = parse_entry("Detonation Multiplier:", flashfile, "n", use_same_line) | temp_val, use_same_line = parse_entry("Detonation Multiplier:", flashfile, "n", use_same_line) | ||
Line 246: | Line 233: | ||
break | break | ||
elseif temp_val ~= -1 then | elseif temp_val ~= -1 then | ||
+ | ba.print("DM: " .. temp_val .. "\n") | ||
arr_SD_m[current_entry] = temp_val | arr_SD_m[current_entry] = temp_val | ||
end | end | ||
− | + | ||
-- final flash radius | -- final flash radius | ||
− | temp_val, use_same_line = parse_entry("Flash Radius:", flashfile, "n", use_same_line) | + | temp_val, use_same_line = parse_entry("Flash Radius Multiplier:", flashfile, "n", use_same_line) |
if temp_val == -2 then | if temp_val == -2 then | ||
break | break | ||
− | + | elseif temp_val ~= -1 then | |
+ | ba.print("FRM: " .. temp_val .. "\n") | ||
arr_SF_rad[current_entry] = temp_val | arr_SF_rad[current_entry] = temp_val | ||
end | end | ||
− | + | ||
-- flash effect | -- flash effect | ||
temp_val, use_same_line = parse_entry("Flash Effect:", flashfile, "n", use_same_line) | temp_val, use_same_line = parse_entry("Flash Effect:", flashfile, "n", use_same_line) | ||
if temp_val == -2 then | if temp_val == -2 then | ||
break | break | ||
− | + | elseif temp_val ~= -1 then | |
+ | ba.print("FE: " .. temp_val .. "\n") | ||
math.floor(temp_val) | math.floor(temp_val) | ||
arr_SF_eff[current_entry] = temp_val | arr_SF_eff[current_entry] = temp_val | ||
end | end | ||
− | + | ||
-- blinding effect | -- blinding effect | ||
temp_val, use_same_line = parse_entry("Blinding Effect Intensity:", flashfile, "n", use_same_line) | temp_val, use_same_line = parse_entry("Blinding Effect Intensity:", flashfile, "n", use_same_line) | ||
if temp_val == -2 then | if temp_val == -2 then | ||
break | break | ||
− | + | elseif temp_val ~= -1 then | |
+ | ba.print("BE: " .. temp_val .. "\n") | ||
+ | temp_val = temp_val + "0" | ||
if temp_val < 0 then | if temp_val < 0 then | ||
temp_val = 0 | temp_val = 0 | ||
Line 278: | Line 270: | ||
arr_SB_int[current_entry] = temp_val | arr_SB_int[current_entry] = temp_val | ||
end | end | ||
− | + | ||
-- blinding duration | -- blinding duration | ||
temp_val, use_same_line = parse_entry("Blinding Effect Duration:", flashfile, "n", use_same_line) | temp_val, use_same_line = parse_entry("Blinding Effect Duration:", flashfile, "n", use_same_line) | ||
if temp_val == -2 then | if temp_val == -2 then | ||
break | break | ||
− | + | elseif temp_val ~= -1 then | |
+ | ba.print("BEDu: " .. temp_val .. "\n") | ||
arr_SB_dur[current_entry] = temp_val | arr_SB_dur[current_entry] = temp_val | ||
end | end | ||
− | + | ||
-- blast effect delay | -- blast effect delay | ||
temp_val, use_same_line = parse_entry("Blast Effect Delay:", flashfile, "n", use_same_line) | temp_val, use_same_line = parse_entry("Blast Effect Delay:", flashfile, "n", use_same_line) | ||
if temp_val == -2 then | if temp_val == -2 then | ||
break | break | ||
− | + | elseif temp_val ~= -1 then | |
+ | ba.print("BEDe: " .. temp_val .. "\n") | ||
arr_SB_time[current_entry] = temp_val | arr_SB_time[current_entry] = temp_val | ||
+ | end | ||
+ | |||
+ | -- blast effect delay | ||
+ | temp_val, use_same_line = parse_entry("Blinding Effect Distance Multiplier:", flashfile, "n", use_same_line) | ||
+ | if temp_val == -2 then | ||
+ | break | ||
+ | elseif temp_val ~= -1 then | ||
+ | ba.print("BEDM: " .. temp_val .. "\n") | ||
+ | arr_SB_dist[current_entry] = temp_val | ||
+ | end | ||
+ | |||
+ | if current_start_line == use_same_line then | ||
+ | use_same_line = get_next_line(flashfile) | ||
+ | local temp_string = find_keyword(use_same_line, "Name:") | ||
+ | if temp_string == nil then | ||
+ | current_start_line = use_same_line | ||
+ | entry_start = use_same_line | ||
+ | else | ||
+ | entry_start = nil | ||
+ | end | ||
+ | |||
+ | not_new_entry = true | ||
end | end | ||
end | end | ||
Line 301: | Line 317: | ||
end | end | ||
end | end | ||
− | + | ||
---------- | ---------- | ||
-- main -- | -- main -- | ||
---------- | ---------- | ||
− | + | ||
-- init arrays | -- init arrays | ||
arrayShipName = {} | arrayShipName = {} | ||
− | |||
− | |||
− | |||
arr_SD_rad = {} | arr_SD_rad = {} | ||
arr_SD_eff = {} | arr_SD_eff = {} | ||
Line 319: | Line 332: | ||
arr_SB_dur = {} | arr_SB_dur = {} | ||
arr_SB_time = {} | arr_SB_time = {} | ||
+ | arr_SB_dist = {} | ||
arr_D_eff = {} | arr_D_eff = {} | ||
− | + | ||
-- open reference file, if any | -- open reference file, if any | ||
-- if failed... pass the script | -- if failed... pass the script | ||
− | filename_flash = " | + | filename_flash = "exp_flashes.cfg" |
filename_flashani = "exp_ani_flashes.cfg" | filename_flashani = "exp_ani_flashes.cfg" | ||
if ((cf.fileExists(filename_flash, "data/config/", true) == true) and (cf.fileExists(filename_flashani, "data/config/", true) == true)) then | if ((cf.fileExists(filename_flash, "data/config/", true) == true) and (cf.fileExists(filename_flashani, "data/config/", true) == true)) then | ||
boolflashfileOK = true | boolflashfileOK = true | ||
end | end | ||
− | + | ||
if boolflashfileOK then | if boolflashfileOK then | ||
-- open to read the contents | -- open to read the contents | ||
Line 336: | Line 350: | ||
-- close the file | -- close the file | ||
flashanifile:close() | flashanifile:close() | ||
− | + | ||
-- continue with the rest in similar manner | -- continue with the rest in similar manner | ||
flashfile = cf.openFile(filename_flash, "r") | flashfile = cf.openFile(filename_flash, "r") | ||
parse_flash_file(flashfile) | parse_flash_file(flashfile) | ||
flashfile:close() | flashfile:close() | ||
− | + | ||
-- setup rest of the required stuff | -- setup rest of the required stuff | ||
math.randomseed( os.time() ) | math.randomseed( os.time() ) | ||
f_counter = {} | f_counter = {} | ||
v_null = ba.createVector(0,0,0) | v_null = ba.createVector(0,0,0) | ||
+ | v_temp = ba.createVector(0,0,0) | ||
+ | v_rnd_sphere = ba.createVector(0,0,0) | ||
arr_FS_List = {} | arr_FS_List = {} | ||
arr_FS = {} | arr_FS = {} | ||
Line 360: | Line 376: | ||
ba.warning("Failed to initialize flashy deaths script") | ba.warning("Failed to initialize flashy deaths script") | ||
end | end | ||
− | + | ||
---------------------------------- | ---------------------------------- | ||
-- functions for later sections -- | -- functions for later sections -- | ||
---------------------------------- | ---------------------------------- | ||
− | + | ||
function blinding_effect(intensity, duration, time) | function blinding_effect(intensity, duration, time) | ||
bl_int_init = bl_int | bl_int_init = bl_int | ||
− | + | ||
if (intensity < bl_max) then | if (intensity < bl_max) then | ||
if intensity > bl_int then | if intensity > bl_int then | ||
local effect_time = bl_end - bl_start | local effect_time = bl_end - bl_start | ||
local delta_time = time - bl_start | local delta_time = time - bl_start | ||
− | + | ||
if effect_time == 0 then | if effect_time == 0 then | ||
bl_max = intensity | bl_max = intensity | ||
Line 392: | Line 408: | ||
end | end | ||
end | end | ||
− | + | ||
function process_blinding_effect_frame(time) | function process_blinding_effect_frame(time) | ||
if bl_max == 0 then | if bl_max == 0 then | ||
return | return | ||
end | end | ||
− | + | ||
local effect_time = bl_end - bl_start | local effect_time = bl_end - bl_start | ||
local delta_time = time - bl_start | local delta_time = time - bl_start | ||
local pct_time = (effect_time - delta_time) / effect_time | local pct_time = (effect_time - delta_time) / effect_time | ||
local case_time | local case_time | ||
− | + | ||
-- lets go case by case | -- lets go case by case | ||
if pct_time < 0.0 then | if pct_time < 0.0 then | ||
Line 412: | Line 428: | ||
-- effect is still fading away | -- effect is still fading away | ||
case_time = 1 - (pct_time / 0.85) | case_time = 1 - (pct_time / 0.85) | ||
− | bl_int = math.pow(((1 + math.cos(case_time * math.pi))/2),3) | + | bl_int = bl_max * math.pow(((1 + math.cos(case_time * math.pi))/2),3) |
elseif pct_time > 0.90 then | elseif pct_time > 0.90 then | ||
-- effect is still getting stronger | -- effect is still getting stronger | ||
Line 424: | Line 440: | ||
bl_int = bl_max | bl_int = bl_max | ||
end | end | ||
− | + | ||
if bl_int ~= 0 then | if bl_int ~= 0 then | ||
a = bl_int * 255 | a = bl_int * 255 | ||
− | |||
gr.flashScreen(a,a,a) | gr.flashScreen(a,a,a) | ||
end | end | ||
end | end | ||
− | + | ||
function do_death_flash(name, number) | function do_death_flash(name, number) | ||
− | + | ||
-- death flash explosion | -- death flash explosion | ||
arr_FS_List[name] = 2 | arr_FS_List[name] = 2 | ||
Line 440: | Line 455: | ||
local str_F_class = arr_FS_Class[name] | local str_F_class = arr_FS_Class[name] | ||
arr_FS_Class[name] = nil | arr_FS_Class[name] = nil | ||
− | local n_F_rad = (math.random() + 0.5) * arr_SF_rad[str_F_class] | + | local l_f_model_r = tb.ShipClasses[str_F_class].Model.Radius |
+ | local n_F_rad = 1.5 * (math.random() + 0.5) * l_f_model_r * arr_SF_rad[str_F_class] | ||
local l_anim_flash = arr_D_eff[arr_SF_eff[str_F_class]] | local l_anim_flash = arr_D_eff[arr_SF_eff[str_F_class]] | ||
if l_anim_flash:isValid() then | if l_anim_flash:isValid() then | ||
ts.createParticle(v_F_pos,v_null,f_F_time,n_F_rad,PARTICLE_BITMAP,-1,false,l_anim_flash) | ts.createParticle(v_F_pos,v_null,f_F_time,n_F_rad,PARTICLE_BITMAP,-1,false,l_anim_flash) | ||
end | end | ||
− | + | ||
-- death flash blinding effect | -- death flash blinding effect | ||
if arr_SB_int[str_F_class] > 0 then | if arr_SB_int[str_F_class] > 0 then | ||
Line 451: | Line 467: | ||
local coord_y | local coord_y | ||
coord_x, coord_y = v_F_pos:getScreenCoords() | coord_x, coord_y = v_F_pos:getScreenCoords() | ||
− | + | ||
if coord_x ~= false then | if coord_x ~= false then | ||
− | blinding_effect(arr_SB_int[str_F_class], arr_SB_dur[str_F_class], f_M_time) | + | local l_f_dist_mult = 1 |
+ | local l_player = hv.Player | ||
+ | if l_player:isValid() then | ||
+ | local l_v_plr_pos = l_player.Position | ||
+ | local l_n_distace_fls_plr = v_F_pos:getDistance(l_v_plr_pos) | ||
+ | local l_n_max_fls_distance = 2 * l_f_model_r * arr_SB_dist[str_F_class] | ||
+ | if l_n_distace_fls_plr > l_n_max_fls_distance then | ||
+ | local l_n_exp_dist_mult = l_n_distace_fls_plr / l_n_max_fls_distance | ||
+ | l_f_dist_mult = 1 / math.pow(l_n_exp_dist_mult, 2) | ||
+ | end | ||
+ | blinding_effect(arr_SB_int[str_F_class] * l_f_dist_mult, arr_SB_dur[str_F_class], f_M_time) | ||
+ | end | ||
end | end | ||
end | end | ||
− | + | ||
-- purge from the list | -- purge from the list | ||
table.insert(arr_FS_done, number) | table.insert(arr_FS_done, number) | ||
end | end | ||
− | + | ||
function check_flash(name) | function check_flash(name) | ||
local class = arr_FS_Class[name] | local class = arr_FS_Class[name] | ||
Line 468: | Line 495: | ||
end | end | ||
end | end | ||
− | + | ||
return false; | return false; | ||
end | end | ||
− | + | ||
function add_to_flash_list(name, class) | function add_to_flash_list(name, class) | ||
arr_FS_List[name] = 1 | arr_FS_List[name] = 1 | ||
Line 481: | Line 508: | ||
table.insert(arr_FS,name) | table.insert(arr_FS,name) | ||
end | end | ||
− | + | ||
+ | function get_rnd_vector_sphere() | ||
+ | local l_bool_ok_to_pass = false | ||
+ | local l_get_rnd = math.random | ||
+ | |||
+ | while (l_bool_ok_to_pass == false) do | ||
+ | |||
+ | -- get random vector (cube, -1 to 1) | ||
+ | v_rnd_sphere[1] = (2* (l_get_rnd() - 0.5)) | ||
+ | v_rnd_sphere[2] = (2* (l_get_rnd() - 0.5)) | ||
+ | v_rnd_sphere[3] = (2* (l_get_rnd() - 0.5)) | ||
+ | local l_n_mag = v_rnd_sphere:getMagnitude() | ||
+ | |||
+ | -- accept only values within a sphere (uniform) | ||
+ | if l_n_mag <= 1 then | ||
+ | v_rnd_sphere = v_rnd_sphere / l_n_mag | ||
+ | l_bool_ok_to_pass = true | ||
+ | end | ||
+ | end | ||
+ | return v_rnd_sphere; | ||
+ | end | ||
+ | |||
+ | function get_ray_collision_pos(ship, v_ray, num_tries) | ||
+ | local l_or_ship = ship.Orientation | ||
+ | local l_m_model = ship.Class.Model | ||
+ | local l_f_radius = 30000 | ||
+ | local l_v_pos_mod = v_null | ||
+ | local l_n_has_tried = 0 | ||
+ | local l_c_ray_pos | ||
+ | local l_get_rnd = math.random | ||
+ | |||
+ | while (l_n_has_tried < num_tries) do | ||
+ | if l_m_model:isValid() then | ||
+ | l_f_radius = l_m_model.Radius | ||
+ | for i=1,3 do | ||
+ | local l_rnd = (2* (l_get_rnd() - 0.5)) | ||
+ | if l_rnd >= 0 then | ||
+ | v_temp[i] = l_m_model.BoundingBoxMax[i] * l_rnd | ||
+ | else | ||
+ | v_temp[i] = l_m_model.BoundingBoxMin[i] * l_rnd * (-1) | ||
+ | end | ||
+ | end | ||
+ | l_v_pos_mod = l_or_ship:unrotateVector(v_temp) | ||
+ | else | ||
+ | l_v_pos_mod = v_null | ||
+ | end | ||
+ | |||
+ | local v_ray = v_ray * l_f_radius | ||
+ | local l_v_end_pos = ship.Position - v_ray + l_v_pos_mod | ||
+ | local l_v_start_pos = ship.Position + v_ray + l_v_pos_mod | ||
+ | |||
+ | l_c_ray_pos = ship:checkRayCollision(l_v_start_pos, l_v_end_pos) | ||
+ | |||
+ | if l_c_ray_pos ~= nil then | ||
+ | l_n_has_tried = 3 | ||
+ | else | ||
+ | l_n_has_tried = 1 + l_n_has_tried | ||
+ | end | ||
+ | end | ||
+ | |||
+ | return l_c_ray_pos | ||
+ | end | ||
+ | |||
+ | function get_number_of_explosions(attempts) | ||
+ | local l_n_partials | ||
+ | local l_n_full | ||
+ | l_n_full, l_n_partials = math.modf(attempts) | ||
+ | |||
+ | if l_n_partials ~= 0 then | ||
+ | if math.random() > l_n_partials then | ||
+ | l_n_full = l_n_full + 1 | ||
+ | end | ||
+ | end | ||
+ | |||
+ | return l_n_full | ||
+ | end | ||
] | ] | ||
− | + | ||
$State: GS_STATE_GAME_PLAY | $State: GS_STATE_GAME_PLAY | ||
$On Frame: | $On Frame: | ||
− | + | ||
[ | [ | ||
− | + | ||
f_M_time = mn.getMissionTime() | f_M_time = mn.getMissionTime() | ||
− | + | ||
if ((f_M_time ~= nil) and boolflashfileOK) then | if ((f_M_time ~= nil) and boolflashfileOK) then | ||
− | + | ||
f_F_time = ba.getFrametime(true) | f_F_time = ba.getFrametime(true) | ||
− | + | ||
f_rnd = math.random() | f_rnd = math.random() | ||
n_ships = #mn.Ships | n_ships = #mn.Ships | ||
− | + | ||
for h = 1, n_ships do | for h = 1, n_ships do | ||
o_ship = mn.Ships[h] | o_ship = mn.Ships[h] | ||
str_S_class = o_ship.Class.Name:lower() | str_S_class = o_ship.Class.Name:lower() | ||
− | + | ||
--ONLY SHIPS WITH EFFECTS-- | --ONLY SHIPS WITH EFFECTS-- | ||
− | + | ||
if ((arr_SF_rad[str_S_class] ~= nil) and (arr_SD_rad[str_S_class] ~= nil)) then | if ((arr_SF_rad[str_S_class] ~= nil) and (arr_SD_rad[str_S_class] ~= nil)) then | ||
str_S_name = o_ship.Name | str_S_name = o_ship.Name | ||
floatHP = o_ship.HitpointsLeft | floatHP = o_ship.HitpointsLeft | ||
− | + | ||
if floatHP <= 0 then | if floatHP <= 0 then | ||
− | + | ||
v_S_pos = o_ship.Position | v_S_pos = o_ship.Position | ||
− | + | ||
if arr_SF_rad[str_S_class] > 0 then | if arr_SF_rad[str_S_class] > 0 then | ||
if arr_FS_List[str_S_name] == nil then | if arr_FS_List[str_S_name] == nil then | ||
Line 517: | Line 619: | ||
end | end | ||
end | end | ||
− | + | ||
if arr_SD_rad[str_S_class] > 0 then | if arr_SD_rad[str_S_class] > 0 then | ||
arr_FS_Pos[str_S_name] = v_S_pos | arr_FS_Pos[str_S_name] = v_S_pos | ||
− | + | ||
if f_counter[str_S_name] == nil then | if f_counter[str_S_name] == nil then | ||
f_counter[str_S_name] = 0 | f_counter[str_S_name] = 0 | ||
− | + | ||
end | end | ||
− | + | ||
f_rnd = math.random() | f_rnd = math.random() | ||
local l_n_SD_eff = #arr_SD_eff[str_S_class] | local l_n_SD_eff = #arr_SD_eff[str_S_class] | ||
− | + | ||
while f_counter[str_S_name] > f_rnd do | while f_counter[str_S_name] > f_rnd do | ||
f_counter[str_S_name] = f_counter[str_S_name] - f_rnd | f_counter[str_S_name] = f_counter[str_S_name] - f_rnd | ||
− | + | local n_attempts = get_number_of_explosions(arr_SD_m[str_S_class]) | |
− | local n_attempts = arr_SD_m[str_S_class] | + | |
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
for n = 1,n_attempts do | for n = 1,n_attempts do | ||
− | local | + | local l_bool_ok_to_pass = false |
− | local | + | |
− | local | + | local l_v_rnd = get_rnd_vector_sphere() |
− | local | + | |
− | + | local l_c_pos = get_ray_collision_pos(o_ship, l_v_rnd, 3) | |
− | + | ||
− | + | -- check if the ray actually hit anything even after three tries | |
− | + | if l_c_pos ~= nil then | |
− | + | local l_m_model = o_ship.Class.Model | |
− | + | local l_f_det_r = (2* math.random() + 0.5) * l_m_model.Radius * arr_SD_rad[str_S_class] * 0.1 | |
− | + | local l_arr_SD_eff = arr_SD_eff[str_S_class] | |
− | + | if l_n_SD_eff == 1 then | |
− | + | local l_anim_det = arr_D_eff[l_arr_SD_eff[1]] | |
− | + | if l_anim_det:isValid() then | |
− | + | ts.createParticle(l_c_pos,v_null,f_F_time,l_f_det_r,PARTICLE_BITMAP,-1,false,l_anim_det) | |
− | + | end | |
− | + | elseif l_n_SD_eff > 1 then | |
− | + | local l_n_rnd_id = math.random(l_n_SD_eff) | |
+ | local l_anim_det = arr_D_eff[l_arr_SD_eff[l_n_rnd_id]] | ||
+ | if l_anim_det:isValid() then | ||
+ | ts.createParticle(l_c_pos,v_null,f_F_time,l_f_det_r,PARTICLE_BITMAP,-1,false,l_anim_det) | ||
+ | end | ||
end | end | ||
end | end | ||
end | end | ||
− | + | ||
if f_counter[str_S_name] <= 0 then | if f_counter[str_S_name] <= 0 then | ||
f_counter[str_S_name] = 0 | f_counter[str_S_name] = 0 | ||
Line 568: | Line 667: | ||
f_rnd = math.random() | f_rnd = math.random() | ||
end | end | ||
− | + | ||
end | end | ||
− | + | ||
f_counter[str_S_name] = f_counter[str_S_name] + f_F_time | f_counter[str_S_name] = f_counter[str_S_name] + f_F_time | ||
end | end | ||
− | + | ||
end | end | ||
− | + | ||
end | end | ||
− | + | ||
n_FS = #arr_FS | n_FS = #arr_FS | ||
− | + | ||
for x=1,n_FS do | for x=1,n_FS do | ||
name = arr_FS[x] | name = arr_FS[x] | ||
− | + | ||
if arr_FS_List[name] == 1 then | if arr_FS_List[name] == 1 then | ||
− | + | ||
− | if mn.Ships[name]:isValid() | + | if mn.Ships[name]:isValid() then |
− | + | if mn.Ships[name]:hasShipExploded() == 2 then | |
− | |||
− | |||
− | |||
do_death_flash(name, x) | do_death_flash(name, x) | ||
+ | else | ||
+ | -- randomized flash explosion | ||
+ | if check_flash(name) == true then | ||
+ | do_death_flash(name, x) | ||
+ | end | ||
end | end | ||
end | end | ||
− | + | ||
end | end | ||
− | + | ||
end | end | ||
− | + | ||
n_FS_done = #arr_FS_done | n_FS_done = #arr_FS_done | ||
if n_FS_done > 0 then | if n_FS_done > 0 then | ||
− | + | ||
for o=n_FS_done,1,-1 do | for o=n_FS_done,1,-1 do | ||
table.remove(arr_FS,arr_FS_done[o]) | table.remove(arr_FS,arr_FS_done[o]) | ||
− | + | ||
end | end | ||
− | + | ||
arr_FS_done = nil | arr_FS_done = nil | ||
arr_FS_done = {} | arr_FS_done = {} | ||
− | + | ||
end | end | ||
− | + | ||
end | end | ||
− | + | ||
process_blinding_effect_frame(f_M_time) | process_blinding_effect_frame(f_M_time) | ||
− | + | ||
end | end | ||
− | + | ||
] | ] | ||
− | + | ||
$Application: FS2_Open | $Application: FS2_Open | ||
$On Mission End: | $On Mission End: | ||
− | + | ||
[ | [ | ||
− | + | ||
-- kill the arrays... | -- kill the arrays... | ||
if boolflashfileOK then | if boolflashfileOK then | ||
arrayShipName = nil | arrayShipName = nil | ||
− | |||
− | |||
− | |||
arr_SD_rad = nil | arr_SD_rad = nil | ||
arr_SD_eff = nil | arr_SD_eff = nil | ||
Line 642: | Line 740: | ||
end | end | ||
arr_D_eff = nil | arr_D_eff = nil | ||
− | + | ||
f_counter = nil | f_counter = nil | ||
arr_FS_List = nil | arr_FS_List = nil | ||
Line 650: | Line 748: | ||
arr_FS_done = nil | arr_FS_done = nil | ||
arr_FS_time = nil | arr_FS_time = nil | ||
− | + | ||
boolflashfileOK = nil | boolflashfileOK = nil | ||
end | end | ||
− | + | ||
] | ] | ||
− | + | ||
#End</pre> | #End</pre> | ||
Line 673: | Line 771: | ||
*'''Blinding Effect Duration:''' sets the duration of the blinding effect in milliseconds | *'''Blinding Effect Duration:''' sets the duration of the blinding effect in milliseconds | ||
*'''Blast Effect Delay:''' sets the base time for flash & blinding effect to appear in milliseconds | *'''Blast Effect Delay:''' sets the base time for flash & blinding effect to appear in milliseconds | ||
+ | *'''Blinding Effect Distance Multiplier:''' defines the multiplier applied to the blinding effect attenuation distances | ||
Table allows for lines to be commented using '--' as comment marker | Table allows for lines to be commented using '--' as comment marker |
Revision as of 21:25, 7 March 2010
Function
New version of the flashy deaths effect by Wanderer. You may wish to check out the script's thread on HLP.
Please note that this script requires two additional files in .cfg format whose specs can be found below.
NOTE THAT .CFG FILES GO TO DATA/CONFIG DIRECTORY
Table Entry
We'll call this deto-sct.tbm - it needs to be placed into ../data/tables/ directory.
#Conditional Hooks $Application: FS2_Open $On Mission Start: [ ---------------------- -- parser functions -- ---------------------- --- get newline and make sure its lowercase function get_next_line(nfile) -- read the line nline = nfile:read("*l") -- change to lowercase if nline ~= nil then nline = nline:lower() end return nline end --- find keyword and return the place where it ends function find_keyword(line_to_parse, keyword) -- find any instances of the keyword keyword = keyword:lower() local key_s, key_e = line_to_parse:find(keyword) -- if we cant find a thing if key_s == nil then return nil end -- check if the line has been commented away local comment_s, comment_e = line_to_parse:find("--") if comment_s == nil then return key_e elseif comment_s < key_s then return nil end return key_e end --- function to initialize the vars function init_entry(name) arr_SD_rad[name] = 1 arr_SD_eff[name] = { } arr_SD_m[name] = 1 arr_SF_rad[name] = 1 arr_SF_eff[name] = 0 arr_SB_int[name] = 0 arr_SB_dur[name] = 0 arr_SB_time[name] = 0 arr_SB_dist[name] = 1 end --- specific parsing funcs to make things easier to read --- --- string or rather substring parser function parse_string(start_key, line_to_parse) local substring = line_to_parse:sub(start_key) -- remove empty spaces local substring_start = substring:find("%a") substring = substring:sub(substring_start) return substring end --- function to parse numbers function parse_number(start_key, line_to_parse) local result = line_to_parse:sub(start_key) local r_value = result:match('[0-9%.]+') r_value = tonumber(r_value) return r_value end --- function to parse arrays of numbers function parse_number_array(start_key, line_to_parse) -- stuff the array local r = { } local p for p in line_to_parse:gmatch('[0-9%.]+') do p = tonumber(p) p = math.floor(p) table.insert(r, p) end return r end --- function to parse things function parse_entry(keyword, flashfile, type, use_same_line) local new_entry = nil local return_val local return_array = {} local c_line if use_same_line == false then c_line = get_next_line(flashfile) if c_line == nil then -- end of file return -2, false, return_array end while c_line:len() == 0 do c_line = get_next_line(flashfile) if c_line == nil then -- end of file return -2, false, return_array end end new_entry = find_keyword(c_line, "Name:") current_start_line = c_line else c_line = use_same_line end -- check if we found a new entry if new_entry == nil then local c_key = find_keyword(c_line, keyword) if c_key == nil then -- we didn't find the thing... return -1, c_line, return_array end if type == "n" then -- soo... parse a number return_val = parse_number(c_key, c_line) return return_val, false, return_array elseif type == "array_n" then -- soo... parse an array of numbers return_array = parse_number_array(c_key, c_line) return_val = #return_array return return_val, false, return_array end else -- found new entry instead... return -2, c_line, return_array end end ----------------------------------------------- -- loading the flash animations function parse_flash_ani_file(n_file) local something_to_parse = true while something_to_parse == true do local c_line = get_next_line(n_file) -- if we are at end of file, stop the loop if c_line == nil then something_to_parse = false break end local entry_start = find_keyword(c_line, "Filename:") -- if we found something else, try next line if entry_start ~= nil then -- ok... so we should have a good entry candidate and all that local current_entry = parse_string(entry_start, c_line) local animation = gr.loadTexture(current_entry, true) table.insert(arr_D_eff, animation) if animation:isValid() == false then ba.warning("Animation defined in " .. filename_flashani .. " " .. current_entry .. " is invalid") end end end end -- actual flash effect parsing function function parse_flash_file(flashfile) -- pick first line entries_left = true use_same_line = false while entries_left == true do -- find ship name if use_same_line == false then use_same_line = get_next_line(flashfile) end if use_same_line == nil then -- end of file entries_left = false break end if use_same_line:len() == 0 then use_same_line = false else entry_start = find_keyword(use_same_line, "Name:") current_start_line = use_same_line if entry_start ~= nil then local not_new_entry = false -- insert while loop here to enable breaks as next statements while entry_start ~= nil do if not_new_entry == false then current_entry = parse_string(entry_start, use_same_line) -- init the entry init_entry(current_entry) use_same_line = false ba.print("\nClass: " .. current_entry .. "\n") end local temp_val = nil local temp_arr = nil entry_start = nil -- detonation radius temp_val, use_same_line = parse_entry("Detonation Radius Multiplier:", flashfile, "n", use_same_line) if temp_val == -2 then break elseif temp_val ~= -1 then ba.print("DRM: " .. temp_val .. "\n") arr_SD_rad[current_entry] = temp_val end -- random detonation effects local temp_arr = {} temp_val, use_same_line, temp_arr = parse_entry("Detonation Effects:", flashfile, "array_n", use_same_line) if temp_val == -2 then break elseif temp_val ~= -1 then ba.print("DE: " .. temp_val .. "\n") arr_SD_eff[current_entry] = temp_arr end -- multiplier for the detonation occurrance temp_val, use_same_line = parse_entry("Detonation Multiplier:", flashfile, "n", use_same_line) if temp_val == -2 then break elseif temp_val ~= -1 then ba.print("DM: " .. temp_val .. "\n") arr_SD_m[current_entry] = temp_val end -- final flash radius temp_val, use_same_line = parse_entry("Flash Radius Multiplier:", flashfile, "n", use_same_line) if temp_val == -2 then break elseif temp_val ~= -1 then ba.print("FRM: " .. temp_val .. "\n") arr_SF_rad[current_entry] = temp_val end -- flash effect temp_val, use_same_line = parse_entry("Flash Effect:", flashfile, "n", use_same_line) if temp_val == -2 then break elseif temp_val ~= -1 then ba.print("FE: " .. temp_val .. "\n") math.floor(temp_val) arr_SF_eff[current_entry] = temp_val end -- blinding effect temp_val, use_same_line = parse_entry("Blinding Effect Intensity:", flashfile, "n", use_same_line) if temp_val == -2 then break elseif temp_val ~= -1 then ba.print("BE: " .. temp_val .. "\n") temp_val = temp_val + "0" if temp_val < 0 then temp_val = 0 elseif temp_val > 100 then temp_val = 100 end arr_SB_int[current_entry] = temp_val end -- blinding duration temp_val, use_same_line = parse_entry("Blinding Effect Duration:", flashfile, "n", use_same_line) if temp_val == -2 then break elseif temp_val ~= -1 then ba.print("BEDu: " .. temp_val .. "\n") arr_SB_dur[current_entry] = temp_val end -- blast effect delay temp_val, use_same_line = parse_entry("Blast Effect Delay:", flashfile, "n", use_same_line) if temp_val == -2 then break elseif temp_val ~= -1 then ba.print("BEDe: " .. temp_val .. "\n") arr_SB_time[current_entry] = temp_val end -- blast effect delay temp_val, use_same_line = parse_entry("Blinding Effect Distance Multiplier:", flashfile, "n", use_same_line) if temp_val == -2 then break elseif temp_val ~= -1 then ba.print("BEDM: " .. temp_val .. "\n") arr_SB_dist[current_entry] = temp_val end if current_start_line == use_same_line then use_same_line = get_next_line(flashfile) local temp_string = find_keyword(use_same_line, "Name:") if temp_string == nil then current_start_line = use_same_line entry_start = use_same_line else entry_start = nil end not_new_entry = true end end else use_same_line = get_next_line(flashfile) end end end end ---------- -- main -- ---------- -- init arrays arrayShipName = {} arr_SD_rad = {} arr_SD_eff = {} arr_SD_m = {} arr_SF_rad = {} arr_SF_eff = {} arr_SB_int = {} arr_SB_dur = {} arr_SB_time = {} arr_SB_dist = {} arr_D_eff = {} -- open reference file, if any -- if failed... pass the script filename_flash = "exp_flashes.cfg" filename_flashani = "exp_ani_flashes.cfg" if ((cf.fileExists(filename_flash, "data/config/", true) == true) and (cf.fileExists(filename_flashani, "data/config/", true) == true)) then boolflashfileOK = true end if boolflashfileOK then -- open to read the contents flashanifile = cf.openFile(filename_flashani, "r") -- parse contents parse_flash_ani_file(flashanifile) -- close the file flashanifile:close() -- continue with the rest in similar manner flashfile = cf.openFile(filename_flash, "r") parse_flash_file(flashfile) flashfile:close() -- setup rest of the required stuff math.randomseed( os.time() ) f_counter = {} v_null = ba.createVector(0,0,0) v_temp = ba.createVector(0,0,0) v_rnd_sphere = ba.createVector(0,0,0) arr_FS_List = {} arr_FS = {} arr_FS_Class = {} arr_FS_Pos = {} arr_FS_done = {} arr_FS_time = {} bl_int = 0 bl_end = 0 bl_max = 0 bl_start = 0 bl_int_init = 0 else ba.warning("Failed to initialize flashy deaths script") end ---------------------------------- -- functions for later sections -- ---------------------------------- function blinding_effect(intensity, duration, time) bl_int_init = bl_int if (intensity < bl_max) then if intensity > bl_int then local effect_time = bl_end - bl_start local delta_time = time - bl_start if effect_time == 0 then bl_max = intensity bl_start = time bl_end = time + (duration / 1000) else local pct_time = (effect_time - delta_time) / effect_time if pct_time < 0.85 then bl_max = intensity bl_start = time bl_end = time + (duration / 1000) end end end else bl_max = intensity bl_start = time bl_end = time + (duration / 1000) end end function process_blinding_effect_frame(time) if bl_max == 0 then return end local effect_time = bl_end - bl_start local delta_time = time - bl_start local pct_time = (effect_time - delta_time) / effect_time local case_time -- lets go case by case if pct_time < 0.0 then -- effect has faded away bl_int = 0 bl_max = 0 blindint_intensity_start = 0 elseif pct_time < 0.85 then -- effect is still fading away case_time = 1 - (pct_time / 0.85) bl_int = bl_max * math.pow(((1 + math.cos(case_time * math.pi))/2),3) elseif pct_time > 0.90 then -- effect is still getting stronger if pct_time == 0 then case_time = -1 else case_time = -1 * ((pct_time - 0.9) / 0.1) end bl_int = math.pow(((1 + math.cos(case_time * math.pi))/2),2) * (bl_max - bl_int_init) + bl_int_init else bl_int = bl_max end if bl_int ~= 0 then a = bl_int * 255 gr.flashScreen(a,a,a) end end function do_death_flash(name, number) -- death flash explosion arr_FS_List[name] = 2 local v_F_pos = arr_FS_Pos[name] arr_FS_Pos[name] = nil local str_F_class = arr_FS_Class[name] arr_FS_Class[name] = nil local l_f_model_r = tb.ShipClasses[str_F_class].Model.Radius local n_F_rad = 1.5 * (math.random() + 0.5) * l_f_model_r * arr_SF_rad[str_F_class] local l_anim_flash = arr_D_eff[arr_SF_eff[str_F_class]] if l_anim_flash:isValid() then ts.createParticle(v_F_pos,v_null,f_F_time,n_F_rad,PARTICLE_BITMAP,-1,false,l_anim_flash) end -- death flash blinding effect if arr_SB_int[str_F_class] > 0 then local coord_x local coord_y coord_x, coord_y = v_F_pos:getScreenCoords() if coord_x ~= false then local l_f_dist_mult = 1 local l_player = hv.Player if l_player:isValid() then local l_v_plr_pos = l_player.Position local l_n_distace_fls_plr = v_F_pos:getDistance(l_v_plr_pos) local l_n_max_fls_distance = 2 * l_f_model_r * arr_SB_dist[str_F_class] if l_n_distace_fls_plr > l_n_max_fls_distance then local l_n_exp_dist_mult = l_n_distace_fls_plr / l_n_max_fls_distance l_f_dist_mult = 1 / math.pow(l_n_exp_dist_mult, 2) end blinding_effect(arr_SB_int[str_F_class] * l_f_dist_mult, arr_SB_dur[str_F_class], f_M_time) end end end -- purge from the list table.insert(arr_FS_done, number) end function check_flash(name) local class = arr_FS_Class[name] if arr_SB_time[class] > 0 then if arr_FS_time[name] <= f_M_time then return true; end end return false; end function add_to_flash_list(name, class) arr_FS_List[name] = 1 arr_FS_Class[name] = class if arr_SB_time[class] > 0 then local temp_time = math.random() + 1 arr_FS_time[name] = arr_SB_time[class] * temp_time / 1000 + f_M_time end table.insert(arr_FS,name) end function get_rnd_vector_sphere() local l_bool_ok_to_pass = false local l_get_rnd = math.random while (l_bool_ok_to_pass == false) do -- get random vector (cube, -1 to 1) v_rnd_sphere[1] = (2* (l_get_rnd() - 0.5)) v_rnd_sphere[2] = (2* (l_get_rnd() - 0.5)) v_rnd_sphere[3] = (2* (l_get_rnd() - 0.5)) local l_n_mag = v_rnd_sphere:getMagnitude() -- accept only values within a sphere (uniform) if l_n_mag <= 1 then v_rnd_sphere = v_rnd_sphere / l_n_mag l_bool_ok_to_pass = true end end return v_rnd_sphere; end function get_ray_collision_pos(ship, v_ray, num_tries) local l_or_ship = ship.Orientation local l_m_model = ship.Class.Model local l_f_radius = 30000 local l_v_pos_mod = v_null local l_n_has_tried = 0 local l_c_ray_pos local l_get_rnd = math.random while (l_n_has_tried < num_tries) do if l_m_model:isValid() then l_f_radius = l_m_model.Radius for i=1,3 do local l_rnd = (2* (l_get_rnd() - 0.5)) if l_rnd >= 0 then v_temp[i] = l_m_model.BoundingBoxMax[i] * l_rnd else v_temp[i] = l_m_model.BoundingBoxMin[i] * l_rnd * (-1) end end l_v_pos_mod = l_or_ship:unrotateVector(v_temp) else l_v_pos_mod = v_null end local v_ray = v_ray * l_f_radius local l_v_end_pos = ship.Position - v_ray + l_v_pos_mod local l_v_start_pos = ship.Position + v_ray + l_v_pos_mod l_c_ray_pos = ship:checkRayCollision(l_v_start_pos, l_v_end_pos) if l_c_ray_pos ~= nil then l_n_has_tried = 3 else l_n_has_tried = 1 + l_n_has_tried end end return l_c_ray_pos end function get_number_of_explosions(attempts) local l_n_partials local l_n_full l_n_full, l_n_partials = math.modf(attempts) if l_n_partials ~= 0 then if math.random() > l_n_partials then l_n_full = l_n_full + 1 end end return l_n_full end ] $State: GS_STATE_GAME_PLAY $On Frame: [ f_M_time = mn.getMissionTime() if ((f_M_time ~= nil) and boolflashfileOK) then f_F_time = ba.getFrametime(true) f_rnd = math.random() n_ships = #mn.Ships for h = 1, n_ships do o_ship = mn.Ships[h] str_S_class = o_ship.Class.Name:lower() --ONLY SHIPS WITH EFFECTS-- if ((arr_SF_rad[str_S_class] ~= nil) and (arr_SD_rad[str_S_class] ~= nil)) then str_S_name = o_ship.Name floatHP = o_ship.HitpointsLeft if floatHP <= 0 then v_S_pos = o_ship.Position if arr_SF_rad[str_S_class] > 0 then if arr_FS_List[str_S_name] == nil then add_to_flash_list(str_S_name, str_S_class) end end if arr_SD_rad[str_S_class] > 0 then arr_FS_Pos[str_S_name] = v_S_pos if f_counter[str_S_name] == nil then f_counter[str_S_name] = 0 end f_rnd = math.random() local l_n_SD_eff = #arr_SD_eff[str_S_class] while f_counter[str_S_name] > f_rnd do f_counter[str_S_name] = f_counter[str_S_name] - f_rnd local n_attempts = get_number_of_explosions(arr_SD_m[str_S_class]) for n = 1,n_attempts do local l_bool_ok_to_pass = false local l_v_rnd = get_rnd_vector_sphere() local l_c_pos = get_ray_collision_pos(o_ship, l_v_rnd, 3) -- check if the ray actually hit anything even after three tries if l_c_pos ~= nil then local l_m_model = o_ship.Class.Model local l_f_det_r = (2* math.random() + 0.5) * l_m_model.Radius * arr_SD_rad[str_S_class] * 0.1 local l_arr_SD_eff = arr_SD_eff[str_S_class] if l_n_SD_eff == 1 then local l_anim_det = arr_D_eff[l_arr_SD_eff[1]] if l_anim_det:isValid() then ts.createParticle(l_c_pos,v_null,f_F_time,l_f_det_r,PARTICLE_BITMAP,-1,false,l_anim_det) end elseif l_n_SD_eff > 1 then local l_n_rnd_id = math.random(l_n_SD_eff) local l_anim_det = arr_D_eff[l_arr_SD_eff[l_n_rnd_id]] if l_anim_det:isValid() then ts.createParticle(l_c_pos,v_null,f_F_time,l_f_det_r,PARTICLE_BITMAP,-1,false,l_anim_det) end end end end if f_counter[str_S_name] <= 0 then f_counter[str_S_name] = 0 else f_rnd = math.random() end end f_counter[str_S_name] = f_counter[str_S_name] + f_F_time end end end n_FS = #arr_FS for x=1,n_FS do name = arr_FS[x] if arr_FS_List[name] == 1 then if mn.Ships[name]:isValid() then if mn.Ships[name]:hasShipExploded() == 2 then do_death_flash(name, x) else -- randomized flash explosion if check_flash(name) == true then do_death_flash(name, x) end end end end end n_FS_done = #arr_FS_done if n_FS_done > 0 then for o=n_FS_done,1,-1 do table.remove(arr_FS,arr_FS_done[o]) end arr_FS_done = nil arr_FS_done = {} end end process_blinding_effect_frame(f_M_time) end ] $Application: FS2_Open $On Mission End: [ -- kill the arrays... if boolflashfileOK then arrayShipName = nil arr_SD_rad = nil arr_SD_eff = nil arr_SF_rad = nil arr_SF_eff = nil arr_SB_int = nil arr_SB_dur = nil arr_SB_time = nil local n_effects = #arr_D_eff for j=1,n_effects do arr_D_eff[j]:unload() end arr_D_eff = nil f_counter = nil arr_FS_List = nil arr_FS = nil arr_FS_Class = nil arr_FS_Pos = nil arr_FS_done = nil arr_FS_time = nil boolflashfileOK = nil end ] #End
expl_flashes.cfg
This file needs to be placed into ../data/config/ directory.
Please note that the following list isn't complete yet.
- Name: defines the ship for which this entry is made for
- Width: & Height: & Length: define the dimensions inside which the detonations occur
- Detonation Radius: defines the radius (base radius) of the detonation effects
- Detonation Effects: list of ID values of the effects (defined in the other cfg file), may have multiple ones
- Detonation Multiplier: multiplier which controls the amount of explosions triggered. 0.2 is 80% decrease, 1.2 is 20% increase
- Flash Radius: defines the radius of the flash when ship actually goes away
- Flash Effect: ID values of the flash effect, as listed in line order entry in additional cfg
- Blinding Effect Intensity: value from 0 to 100, sets the intensity of the blinding effect - requires flash effect to be defined
- Blinding Effect Duration: sets the duration of the blinding effect in milliseconds
- Blast Effect Delay: sets the base time for flash & blinding effect to appear in milliseconds
- Blinding Effect Distance Multiplier: defines the multiplier applied to the blinding effect attenuation distances
Table allows for lines to be commented using '--' as comment marker
==Terran== Name: GTDr Amazon Advanced Width: 80 Height: 100 Length: 200 Detonation Radius: 100 Detonation Effects: 2, 3 Flash Radius: 750 Flash Effect: 1 Name: GTFr Triton Width: 110 Height: 130 Length: 250 Detonation Radius: 100 Detonation Effects: 2, 3 Flash Radius: 750 Flash Effect: 1 Name: TC-Tri Width: 110 Height: 130 Length: 250 Detonation Radius: 100 Detonation Effects: 2, 3 Flash Radius: 750 Flash Effect: 1 Name: GTFr Poseidon Width: 35 Height: 30 Length: 60 Detonation Radius: 25 Detonation Effects: 2, 3 Flash Radius: 700 Flash Effect: 1 Name: @GTC Fenris Width: 150 Height: 200 Length: 250 Detonation Radius: 100 Detonation Effects: 2, 3 Flash Radius: 1000 Flash Effect: 1 Name: GTM Hippocrates Width: 80 Height: 275 Length: 375 Detonation Radius: 200 Detonation Effects: 2, 3 Flash Radius: 1700 Flash Effect: 1 Name: GTC Leviathan Width: 150 Height: 200 Length: 250 Detonation Radius: 100 Detonation Effects: 2, 3 Flash Radius: 1000 Flash Effect: 1 Name: GTSc Faustus Width: 95 Height: 85 Length: 160 Detonation Radius: 50 Detonation Effects: 2, 3 Flash Radius: 800 Flash Effect: 1 Name: GTG Zephyrus Width: 80 Height: 70 Length: 255 Detonation Radius: 80 Detonation Effects: 2, 3 Flash Radius: 800 Flash Effect: 1 Name: GTA Charbydis Width: 60 Height: 90 Length: 110 Detonation Radius: 75 Detonation Effects: 2, 3 Flash Radius: 600 Flash Effect: 1 Name: GTD Orion Width: 500 Height: 500 Length: 1900 Detonation Radius: 500 Detonation Effects: 2, 3 Flash Radius: 2500 Flash Effect: 1 Name: GTD Hecate Width: 700 Height: 500 Length: 1900 Detonation Radius: 500 Detonation Effects: 2, 3 Flash Radius: 2500 Flash Effect: 1 Name: GTD Hades Width: 700 Height: 500 Length: 3200 Detonation Radius: 800 Detonation Effects: 2, 3 Flash Radius: 4000 Flash Effect: 1 Name: GTI Arcadia Width: 1000 Height: 1200 Length: 800 Detonation Radius: 1000 Detonation Effects: 2, 3 Flash Radius: 5000 Flash Effect: 1 Name: GTVA Colossus Width: 10000 Height: 12000 Length: 8000 Detonation Radius: 10000 Detonation Effects: 2, 3 Flash Radius: 50000 Flash Effect: 1 Name: GTCv Deimos Width: 350 Height: 400 Length: 750 Detonation Radius: 200 Detonation Effects: 2, 3 Flash Radius: 1500 Flash Effect: 1 Name: GTC Aeolus Width: 80 Height: 90 Length: 275 Detonation Radius: 100 Detonation Effects: 2, 3 Flash Radius: 1000 Flash Effect: 1 Name: NTF Iceni Width: 400 Height: 450 Length: 1000 Detonation Radius: 300 Detonation Effects: 2, 3 Flash Radius: 1500 Flash Effect: 1 Name: NTF Boadicea Width: 10000 Height: 12000 Length: 8000 Detonation Radius: 10000 Detonation Effects: 2, 3 Flash Radius: 50000 Flash Effect: 1 Name: @GTT Elysium Width: 35 Height: 45 Length: 35 Detonation Radius: 25 Detonation Effects: 2, 3 Flash Radius: 500 Flash Effect: 1 Name: @GTT Argo Width: 95 Height: 70 Length: 160 Detonation Radius: 75 Detonation Effects: 2, 3 Flash Radius: 600 Flash Effect: 1 Name: GTI Ganymede Width: 10000 Height: 12000 Length: 8000 Detonation Radius: 10000 Detonation Effects: 2, 3 Flash Radius: 50000 Flash Effect: 1 Name: Knossos Width: 10000 Height: 12000 Length: 8000 Detonation Radius: 10000 Detonation Effects: 2, 3 Flash Radius: 50000 Flash Effect: 1 Name: TC-Meson Bomb Width: 10000 Height: 12000 Length: 8000 Detonation Radius: 10000 Detonation Effects: 2, 3 Flash Radius: 50000 Flash Effect: 1 ==Vasudan== Name: PVFr Ma'at Width: 20 Height: 20 Length: 55 Detonation Radius: 25 Detonation Effects: 2, 3 Flash Radius: 600 Flash Effect: 1 Name: GVFr Bes Width: 25 Height: 15 Length: 60 Detonation Radius: 25 Detonation Effects: 2, 3 Flash Radius: 600 Flash Effect: 1 Name: GVFr Satis Width: 45 Height: 50 Length: 110 Detonation Radius: 50 Detonation Effects: 2, 3 Flash Radius: 800 Flash Effect: 1 Name: GVG Anuket Width: 85 Height: 80 Length: 350 Detonation Radius: 100 Detonation Effects: 2, 3 Flash Radius: 900 Flash Effect: 1 Name: GVC Aten Width: 150 Height: 50 Length: 240 Detonation Radius: 100 Detonation Effects: 2, 3 Flash Radius: 1000 Flash Effect: 1 Name: GVC Mentu Width: 180 Height: 140 Length: 325 Detonation Radius: 100 Detonation Effects: 2, 3 Flash Radius: 800 Flash Effect: 1 Name: GVCv Sobek Width: 275 Height: 275 Length: 620 Detonation Radius: 200 Detonation Effects: 2, 3 Flash Radius: 1500 Flash Effect: 1 Name: GVD Typhon Width: 700 Height: 300 Length: 2200 Detonation Radius: 500 Detonation Effects: 2, 3 Flash Radius: 2500 Flash Effect: 1 Name: GVA Setekh Width: 100 Height: 100 Length: 200 Detonation Radius: 75 Detonation Effects: 2, 3 Flash Radius: 600 Flash Effect: 1 Name: GVD Hatshepsut Width: 700 Height: 600 Length: 2200 Detonation Radius: 500 Detonation Effects: 2, 3 Flash Radius: 2500 Flash Effect: 1 Name: GTSG Mjolnir Width: 100 Height: 110 Length: 90 Detonation Radius: 40 Detonation Effects: 2, 3 Flash Radius: 500 Flash Effect: 1
exp_ani_flashes.cfg
This file needs to be placed into ../data/config/ directory.
Contains an ordered list of animations. First defined effect gets ID number 1, second gets ID number 2 and so on. These ID numbers are used in Detonation Effects: and Flash Effect: entries to define the desired animations.
Filename: EXP_flash Filename: exp04 Filename: exp05
Notes
As stated above the shiplist isn't complete yet, meaning that the destruction of any ships other than the ones specified in the current expl_flashes.cfg will not trigger any effect.