diff --git a/release/datapack_difficulty_dr-demo/_deltamodInfo.json b/release/datapack_difficulty_dr-demo/_deltamodInfo.json index aa077d9..1c9508c 100644 --- a/release/datapack_difficulty_dr-demo/_deltamodInfo.json +++ b/release/datapack_difficulty_dr-demo/_deltamodInfo.json @@ -16,4 +16,4 @@ "checksum": "4de4118ba4ad4243025e61337fe796532751032c0a04d0843d8b35f91ec2c220" } ] -} +} \ No newline at end of file diff --git a/release/datapack_difficulty_dr-fullgame/_deltamodInfo.json b/release/datapack_difficulty_dr-fullgame/_deltamodInfo.json index 05beaaf..f4e1a0c 100644 --- a/release/datapack_difficulty_dr-fullgame/_deltamodInfo.json +++ b/release/datapack_difficulty_dr-fullgame/_deltamodInfo.json @@ -36,4 +36,4 @@ "checksum": "370dfd141d2955d5a1960122919b16e4092b52ffbb85fda541bc4680c6b3b85c" } ] -} +} \ No newline at end of file diff --git a/src/customdifficulty_ch1to5.csx b/src/customdifficulty_ch1to5.csx index 3615ddb..e5d5c42 100644 --- a/src/customdifficulty_ch1to5.csx +++ b/src/customdifficulty_ch1to5.csx @@ -119,940 +119,700 @@ presets.Add( hitall = true }); -string loadsettingsblock(string chapter, string filechoice) -{ - string saveslot = @$" ""ch"" + string({chapter}) + ""_"" + string({filechoice})"; - return @$" - ossafe_ini_open(""difficulty.ini""); - - global.diff_damagemulti = ini_read_real({saveslot}, ""DAMAGE_MULTI"", {presets[preset_default].damagemulti.ToString("F10", CultureInfo.InvariantCulture)}); - global.diff_gameboarddmgx = ini_read_real({saveslot}, ""GAMEBOARD_DMG_X"", {presets[preset_default].gameboarddmgx.ToString("F10", CultureInfo.InvariantCulture)}); - global.diff_hitall = ini_read_real({saveslot}, ""HIT_ALL"", {presets[preset_default].hitall.ToString().ToLower()}); - global.diff_iframes = ini_read_real({saveslot}, ""I_FRAMES"", {presets[preset_default].iframes.ToString("F10", CultureInfo.InvariantCulture)}); - global.diff_enemycd = ini_read_real({saveslot}, ""ENEMY_COOLDOWNS"", {presets[preset_default].enemycd.ToString("F10", CultureInfo.InvariantCulture)}); - global.diff_gmbrdenemycd = ini_read_real({saveslot}, ""GMBRD_ENEMY_CDS"", {presets[preset_default].gmbrdenemycd.ToString("F10", CultureInfo.InvariantCulture)}); - global.diff_tpgain = ini_read_real({saveslot}, ""TP_GAIN"", {presets[preset_default].tpgain.ToString("F10", CultureInfo.InvariantCulture)}); - global.diff_extraenemies = ini_read_real({saveslot}, ""EXTRA_ENEMIES"", {presets[preset_default].extraenemies.ToString()}); - global.diff_battlerewards = ini_read_real({saveslot}, ""BATTLE_REWARDS"", {presets[preset_default].battlerewards.ToString("F10", CultureInfo.InvariantCulture)}); - global.diff_rewardranking = ini_read_real({saveslot}, ""REWARD_RANKING"", {presets[preset_default].rewardranking.ToString().ToLower()}); - global.diff_downdeficit = ini_read_real({saveslot}, ""DOWN_DEFICIT"", {presets[preset_default].downdeficit.ToString("F10", CultureInfo.InvariantCulture)}); - global.diff_downedregen = ini_read_real({saveslot}, ""DOWNED_REGEN"", {presets[preset_default].downedregen.ToString("F10", CultureInfo.InvariantCulture)}); - global.diff_victoryres = ini_read_real({saveslot}, ""VICTORY_RES"", {presets[preset_default].victoryres.ToString("F10", CultureInfo.InvariantCulture)}); - global.diff_plrdmg = ini_read_real({saveslot}, ""PLR_DMG"", {presets[preset_default].plrdmg.ToString("F10", CultureInfo.InvariantCulture)}); - global.diff_gmbrdplrdmg = ini_read_real({saveslot}, ""GMBRD_PLR_DMG"", {presets[preset_default].gmbrdplrdmg.ToString("F10", CultureInfo.InvariantCulture)}); - global.diff_plrheal = ini_read_real({saveslot}, ""PLR_HEAL"", {presets[preset_default].plrheal.ToString("F10", CultureInfo.InvariantCulture)}); - global.diff_gmbrdplrheal = ini_read_real({saveslot}, ""GMBRD_PLR_HEAL"", {presets[preset_default].gmbrdplrheal.ToString("F10", CultureInfo.InvariantCulture)}); - global.diff_mercy = ini_read_real({saveslot}, ""MERCY"", {presets[preset_default].mercy.ToString("F10", CultureInfo.InvariantCulture)}); - global.diff_saveheal = ini_read_real({saveslot}, ""SAVE_POINT_HEAL"", {presets[preset_default].saveheal.ToString().ToLower()}); - ossafe_ini_close(); - - // Determine preset - {string.Join(" else ", presets.Select(pair => @$" - if (global.diff_damagemulti == {pair.Value.damagemulti.ToString("F10", CultureInfo.InvariantCulture)} - && global.diff_gameboarddmgx == {pair.Value.gameboarddmgx.ToString("F10", CultureInfo.InvariantCulture)} - && global.diff_hitall == {pair.Value.hitall.ToString().ToLower()} - && global.diff_iframes == {pair.Value.iframes.ToString("F10", CultureInfo.InvariantCulture)} - && global.diff_enemycd == {pair.Value.enemycd.ToString("F10", CultureInfo.InvariantCulture)} - && global.diff_gmbrdenemycd == {pair.Value.gmbrdenemycd.ToString("F10", CultureInfo.InvariantCulture)} - && global.diff_tpgain == {pair.Value.tpgain.ToString("F10", CultureInfo.InvariantCulture)} - && global.diff_extraenemies == {pair.Value.extraenemies.ToString()} - && global.diff_battlerewards == {pair.Value.battlerewards.ToString("F10", CultureInfo.InvariantCulture)} - && global.diff_rewardranking == {pair.Value.rewardranking.ToString().ToLower()} - && global.diff_downdeficit == {pair.Value.downdeficit.ToString("F10", CultureInfo.InvariantCulture)} - && global.diff_downedregen == {pair.Value.downedregen.ToString("F10", CultureInfo.InvariantCulture)} - && global.diff_victoryres == {pair.Value.victoryres.ToString("F10", CultureInfo.InvariantCulture)} - && global.diff_plrdmg == {pair.Value.plrdmg.ToString("F10", CultureInfo.InvariantCulture)} - && global.diff_gmbrdplrdmg == {pair.Value.gmbrdplrdmg.ToString("F10", CultureInfo.InvariantCulture)} - && global.diff_plrheal == {pair.Value.plrheal.ToString("F10", CultureInfo.InvariantCulture)} - && global.diff_gmbrdplrheal == {pair.Value.gmbrdplrheal.ToString("F10", CultureInfo.InvariantCulture)} - && global.diff_mercy == {pair.Value.mercy.ToString("F10", CultureInfo.InvariantCulture)} - && global.diff_saveheal == {pair.Value.saveheal.ToString().ToLower()}) {{ - global.diff_preset = ""{pair.Key}""; - }} - "))} - else {{ - var userpresetnames = ds_map_keys_to_array(global.diff_userpresets); - var foundPreset = false; - for (var i = 0; i < array_length(userpresetnames); i++) {{ - var presetdata = ds_map_find_value(global.diff_userpresets, userpresetnames[i]); - if (global.diff_damagemulti == ds_map_find_value(presetdata, ""damagemulti"") - && global.diff_gameboarddmgx == ds_map_find_value(presetdata, ""gameboarddmgx"") - && global.diff_hitall == ds_map_find_value(presetdata, ""hitall"") - && global.diff_iframes == ds_map_find_value(presetdata, ""iframes"") - && global.diff_enemycd == ds_map_find_value(presetdata, ""enemycd"") - && global.diff_gmbrdenemycd == ds_map_find_value(presetdata, ""gmbrdenemycd"") - && global.diff_tpgain == ds_map_find_value(presetdata, ""tpgain"") - && global.diff_extraenemies == ds_map_find_value(presetdata, ""extraenemies"") - && global.diff_battlerewards == ds_map_find_value(presetdata, ""battlerewards"") - && global.diff_rewardranking == ds_map_find_value(presetdata, ""rewardranking"") - && global.diff_downdeficit == ds_map_find_value(presetdata, ""downdeficit"") - && global.diff_downedregen == ds_map_find_value(presetdata, ""downedregen"") - && global.diff_victoryres == ds_map_find_value(presetdata, ""victoryres"") - && global.diff_plrdmg == ds_map_find_value(presetdata, ""plrdmg"") - && global.diff_gmbrdplrdmg == ds_map_find_value(presetdata, ""gmbrdplrdmg"") - && global.diff_plrheal == ds_map_find_value(presetdata, ""plrheal"") - && global.diff_gmbrdplrheal == ds_map_find_value(presetdata, ""gmbrdplrheal"") - && global.diff_mercy == ds_map_find_value(presetdata, ""mercy"") - && global.diff_saveheal == ds_map_find_value(presetdata, ""saveheal"")) {{ - global.diff_preset = userpresetnames[i]; - foundPreset = true; - break; - }} - }} - if (!foundPreset) - global.diff_preset = ""Custom""; - }} - "; -} - -string savesettingsblock(string savename) -{ - return @$" - ossafe_ini_open(""difficulty.ini""); - ini_write_real({savename}, ""DAMAGE_MULTI"", global.diff_damagemulti); - ini_write_real({savename}, ""GAMEBOARD_DMG_X"", global.diff_gameboarddmgx); - ini_write_real({savename}, ""HIT_ALL"", global.diff_hitall); - ini_write_real({savename}, ""I_FRAMES"", global.diff_iframes); - ini_write_real({savename}, ""ENEMY_COOLDOWNS"", global.diff_enemycd); - ini_write_real({savename}, ""GMBRD_ENEMY_CDS"", global.diff_gmbrdenemycd); - ini_write_real({savename}, ""TP_GAIN"", global.diff_tpgain); - ini_write_real({savename}, ""EXTRA_ENEMIES"", global.diff_extraenemies); - ini_write_real({savename}, ""BATTLE_REWARDS"", global.diff_battlerewards); - ini_write_real({savename}, ""REWARD_RANKING"", global.diff_rewardranking); - ini_write_real({savename}, ""DOWN_DEFICIT"", global.diff_downdeficit); - ini_write_real({savename}, ""DOWNED_REGEN"", global.diff_downedregen); - ini_write_real({savename}, ""VICTORY_RES"", global.diff_victoryres); - ini_write_real({savename}, ""PLR_DMG"", global.diff_plrdmg); - ini_write_real({savename}, ""GMBRD_PLR_DMG"", global.diff_gmbrdplrdmg); - ini_write_real({savename}, ""PLR_HEAL"", global.diff_plrheal); - ini_write_real({savename}, ""GMBRD_PLR_HEAL"", global.diff_gmbrdplrheal); - ini_write_real({savename}, ""MERCY"", global.diff_mercy); - ini_write_real({savename}, ""SAVE_POINT_HEAL"", global.diff_saveheal); - ossafe_ini_close(); - "; -} - -// Add globals +// Add globals & menu string[] gamestartLikes = {"gml_GlobalScript_scr_gamestart"}; if (ch_no == 0) { string[] demoGamestartLikes = {"gml_GlobalScript_scr_gamestart_ch1"}; gamestartLikes = gamestartLikes.Concat(demoGamestartLikes).ToArray(); } - foreach (string scrName in gamestartLikes) { - importGroup.QueueRegexFindReplace(scrName, "function scr_gamestart(?:_ch1)?\\(\\)\\s*{", @$" - function scr_gamestart{(scrName.EndsWith("_ch1") ? "_ch1" : "")}() - {{ - var installed_customdifficulty = true; + importGroup.QueueFindReplace(scrName, "global.chapter = ", @$" + var installed_customdifficulty = true; - global.diff_array_contains = function(arg0, arg1) {{ - for (var i = 0; i < array_length(arg0); i++) {{ - if (arg0[i] == arg1) - return true; - }} - return false; + global.diff_array_contains = function(arg0, arg1) {{ + for (var i = 0; i < array_length(arg0); i++) {{ + if (arg0[i] == arg1) + return true; }} + return false; + }} - global.diff_array_sort = function(arg0, arg1) {{ - // TODO implement a proper sorting algo, cba atm - only runs once on load, save, or delete; so not too worried about it - var temparray = []; - for (var i = 0; i < array_length(arg0); i++) {{ - var insertat = array_length(temparray); - for (var j = 0; j < array_length(temparray); j++) {{ - if (arg0[i] < temparray[j]) {{ - insertat = j; - break; - }} + global.diff_array_sort = function(arg0, arg1) {{ + // TODO implement a proper sorting algo, cba atm - only runs once on load, save, or delete; so not too worried about it + var temparray = []; + for (var i = 0; i < array_length(arg0); i++) {{ + var insertat = array_length(temparray); + for (var j = 0; j < array_length(temparray); j++) {{ + if (arg0[i] < temparray[j]) {{ + insertat = j; + break; }} - array_insert(temparray, insertat, arg0[i]); }} - return temparray; + array_insert(temparray, insertat, arg0[i]); }} + return temparray; + }} - {((ch_no != 0) ? "" : @" - // WARNING: only works for delimiters 1 char long - // WARNING: does not have optional args from GM's impl - global.diff_string_split = function(arg0, arg1) + {((ch_no != 0) ? "" : @" + // WARNING: only works for delimiters 1 char long + // WARNING: does not have optional args from GM's impl + global.diff_string_split = function(arg0, arg1) + { + length = string_length(arg0); + var result = array_create(0); + array_push(result, """"); + + // string_char_at index starts at 1 for some reason + for (i = 1; i <= length; i++) { - length = string_length(arg0); - var result = array_create(0); - array_push(result, """"); + thischar = string_char_at(arg0, i); - // string_char_at index starts at 1 for some reason - for (i = 1; i <= length; i++) + if (thischar != arg1) { + result[array_length(result) - 1] = result[array_length(result) - 1] + thischar; + } + else { - thischar = string_char_at(arg0, i); - - if (thischar != arg1) { - result[array_length(result) - 1] = result[array_length(result) - 1] + thischar; - } - else - { - array_push(result, """"); - } + array_push(result, """"); } - - return result; } - ")} - global.diff_menupresetrow = -1; - global.diff_menucreateuserpresetrow = -1; - global.diff_menudeleteuserpresetrow = -1; + return result; + } + ")} - global.diff_saveuserpresetname = ""USER 1""; - global.diff_saveuserpreset = function(arg0) {{ - if (!arg0) - return; + global.diff_menupresetrow = undefined; + global.diff_menucreateuserpresetrow = undefined; + global.diff_menudeleteuserpresetrow = undefined; + + global.diff_saveuserpresetname = ""USER 1""; + global.diff_saveuserpreset = function() {{ + global.diff_preset = global.diff_saveuserpresetname; + + var presetdata = ds_map_create(); + ds_map_add(presetdata, ""damagemulti"", global.diff_damagemulti); + ds_map_add(presetdata, ""gameboarddmgx"", global.diff_gameboarddmgx); + ds_map_add(presetdata, ""hitall"", global.diff_hitall); + ds_map_add(presetdata, ""iframes"", global.diff_iframes); + ds_map_add(presetdata, ""enemycd"", global.diff_enemycd); + ds_map_add(presetdata, ""gmbrdenemycd"", global.diff_gmbrdenemycd); + ds_map_add(presetdata, ""tpgain"", global.diff_tpgain); + ds_map_add(presetdata, ""extraenemies"", global.diff_extraenemies); + ds_map_add(presetdata, ""battlerewards"", global.diff_battlerewards); + ds_map_add(presetdata, ""rewardranking"", global.diff_rewardranking); + ds_map_add(presetdata, ""downdeficit"", global.diff_downdeficit); + ds_map_add(presetdata, ""downedregen"", global.diff_downedregen); + ds_map_add(presetdata, ""victoryres"", global.diff_victoryres); + ds_map_add(presetdata, ""plrdmg"", global.diff_plrdmg); + ds_map_add(presetdata, ""gmbrdplrdmg"", global.diff_gmbrdplrdmg); + ds_map_add(presetdata, ""plrheal"", global.diff_plrheal); + ds_map_add(presetdata, ""gmbrdplrheal"", global.diff_gmbrdplrheal); + ds_map_add(presetdata, ""mercy"", global.diff_mercy); + ds_map_add(presetdata, ""saveheal"", global.diff_saveheal); + ds_map_set(global.diff_userpresets, global.diff_saveuserpresetname, presetdata); + + ossafe_ini_open(""difficulty.ini""); + var newuserpresetnames = ds_map_keys_to_array(global.diff_userpresets); + newuserpresetnames = global.diff_array_sort(newuserpresetnames, true); + var newmetapresetsvalue = """"; + for (var i = 0; i < array_length(newuserpresetnames); i++) {{ + if (i != 0) + newmetapresetsvalue += "";""; + newmetapresetsvalue += newuserpresetnames[i]; + }} + ini_write_string(""META"", ""PRESETS"", newmetapresetsvalue); + ossafe_ini_close(); - global.diff_preset = global.diff_saveuserpresetname; + var savedatarefs = global.diff_menu.save_data_refs(); + ossafe_ini_open(""difficulty.ini""); + for (var i = 0; i < array_length(savedatarefs); i++) {{ + ini_write_real(""preset_"" + global.diff_saveuserpresetname, savedatarefs[i].ini_key, savedatarefs[i].get()); + }} + ossafe_ini_close(); - var presetdata = ds_map_create(); - ds_map_add(presetdata, ""damagemulti"", global.diff_damagemulti); - ds_map_add(presetdata, ""gameboarddmgx"", global.diff_gameboarddmgx); - ds_map_add(presetdata, ""hitall"", global.diff_hitall); - ds_map_add(presetdata, ""iframes"", global.diff_iframes); - ds_map_add(presetdata, ""enemycd"", global.diff_enemycd); - ds_map_add(presetdata, ""gmbrdenemycd"", global.diff_gmbrdenemycd); - ds_map_add(presetdata, ""tpgain"", global.diff_tpgain); - ds_map_add(presetdata, ""extraenemies"", global.diff_extraenemies); - ds_map_add(presetdata, ""battlerewards"", global.diff_battlerewards); - ds_map_add(presetdata, ""rewardranking"", global.diff_rewardranking); - ds_map_add(presetdata, ""downdeficit"", global.diff_downdeficit); - ds_map_add(presetdata, ""downedregen"", global.diff_downedregen); - ds_map_add(presetdata, ""victoryres"", global.diff_victoryres); - ds_map_add(presetdata, ""plrdmg"", global.diff_plrdmg); - ds_map_add(presetdata, ""gmbrdplrdmg"", global.diff_gmbrdplrdmg); - ds_map_add(presetdata, ""plrheal"", global.diff_plrheal); - ds_map_add(presetdata, ""gmbrdplrheal"", global.diff_gmbrdplrheal); - ds_map_add(presetdata, ""mercy"", global.diff_mercy); - ds_map_add(presetdata, ""saveheal"", global.diff_saveheal); - ds_map_set(global.diff_userpresets, global.diff_saveuserpresetname, presetdata); - - ossafe_ini_open(""difficulty.ini""); - var newuserpresetnames = ds_map_keys_to_array(global.diff_userpresets); - newuserpresetnames = global.diff_array_sort(newuserpresetnames, true); - var newmetapresetsvalue = """"; + if (!is_undefined(global.diff_menupresetrow)) {{ + var userpresetvaluerange = """"; for (var i = 0; i < array_length(newuserpresetnames); i++) {{ - if (i != 0) - newmetapresetsvalue += "";""; - newmetapresetsvalue += newuserpresetnames[i]; - }} - ini_write_string(""META"", ""PRESETS"", newmetapresetsvalue); - ossafe_ini_close(); - - {savesettingsblock(@"""preset_"" + global.diff_saveuserpresetname")} - - if (global.diff_menupresetrow != -1) {{ - var userpresetvaluerange = """"; - for (var i = 0; i < array_length(newuserpresetnames); i++) {{ - userpresetvaluerange += "";"" + newuserpresetnames[i] + ""="" + newuserpresetnames[i] + ""`""; - }} - ds_map_replace(global.diff_menupresetrow, ""value_range_en"", ""{string.Join(";", presets.Select(pair => @$"{pair.Key.ToUpper()}={pair.Key}`"))};CUSTOM=Custom`"" + userpresetvaluerange); + userpresetvaluerange += "";"" + newuserpresetnames[i] + ""="" + newuserpresetnames[i] + ""`""; }} + global.diff_menupresetrow.value_range = ""{string.Join(";", presets.Select(pair => @$"{pair.Key.ToUpper()}={pair.Key}`"))};CUSTOM=Custom`"" + userpresetvaluerange; + }} - if (global.diff_menucreateuserpresetrow != -1) {{ - var createuserpresetsvaluerange = """"; - var hasaddednew = false; - for (var i = 1; i < 10; i++) {{ - var thispresetname = ""USER "" + string(i); - if (global.diff_array_contains(newuserpresetnames, thispresetname)) {{ - if (i != 1) - createuserpresetsvaluerange += "";""; - createuserpresetsvaluerange += thispresetname + ""="" + thispresetname + ""`""; - }} else if (!hasaddednew) {{ - if (i != 1) - createuserpresetsvaluerange += "";""; - createuserpresetsvaluerange += thispresetname + ""="" + thispresetname + ""`""; - hasaddednew = true; - }} - }} - var possibleuserpresetnames = [""USER 1"", ""USER 2"", ""USER 3"", ""USER 4"", ""USER 5"", ""USER 6"", ""USER 7"", ""USER 8"", ""USER 9""]; - for (var i = 0; i < array_length(newuserpresetnames); i++) {{ - if (!global.diff_array_contains(possibleuserpresetnames, newuserpresetnames[i])) {{ + if (!is_undefined(global.diff_menucreateuserpresetrow)) {{ + var createuserpresetsvaluerange = """"; + var hasaddednew = false; + for (var i = 1; i < 10; i++) {{ + var thispresetname = ""USER "" + string(i); + if (global.diff_array_contains(newuserpresetnames, thispresetname)) {{ + if (i != 1) createuserpresetsvaluerange += "";""; - createuserpresetsvaluerange += newuserpresetnames[i] + ""="" + newuserpresetnames[i] + ""`""; - }} + createuserpresetsvaluerange += thispresetname + ""="" + thispresetname + ""`""; + }} else if (!hasaddednew) {{ + if (i != 1) + createuserpresetsvaluerange += "";""; + createuserpresetsvaluerange += thispresetname + ""="" + thispresetname + ""`""; + hasaddednew = true; }} - ds_map_replace(global.diff_menucreateuserpresetrow, ""value_range_en"", createuserpresetsvaluerange); }} - - global.diff_deleteuserpresetname = """" - if (global.diff_menudeleteuserpresetrow != -1) {{ - var deleteuserpresetsvaluerange = """"; - for (var i = 0; i < array_length(newuserpresetnames); i++) {{ - if (i != 0) - deleteuserpresetsvaluerange += "";""; - else - global.diff_deleteuserpresetname = newuserpresetnames[i]; - deleteuserpresetsvaluerange += newuserpresetnames[i] + ""="" + newuserpresetnames[i] + ""`""; + var possibleuserpresetnames = [""USER 1"", ""USER 2"", ""USER 3"", ""USER 4"", ""USER 5"", ""USER 6"", ""USER 7"", ""USER 8"", ""USER 9""]; + for (var i = 0; i < array_length(newuserpresetnames); i++) {{ + if (!global.diff_array_contains(possibleuserpresetnames, newuserpresetnames[i])) {{ + createuserpresetsvaluerange += "";""; + createuserpresetsvaluerange += newuserpresetnames[i] + ""="" + newuserpresetnames[i] + ""`""; }} - ds_map_replace(global.diff_menudeleteuserpresetrow, ""value_range_en"", deleteuserpresetsvaluerange); - ds_map_replace(global.diff_menudeleteuserpresetrow, ""disabled"", deleteuserpresetsvaluerange == """"); }} - - global.diff_saveuserpresetname = ""USER 1""; + global.diff_menucreateuserpresetrow.value_range = createuserpresetsvaluerange; }} + global.diff_deleteuserpresetname = """"; - global.diff_deleteuserpreset = function(arg0) {{ - if (!arg0) - return; + if (!is_undefined(global.diff_menudeleteuserpresetrow)) {{ + var deleteuserpresetsvaluerange = """"; + for (var i = 0; i < array_length(newuserpresetnames); i++) {{ + if (i != 0) + deleteuserpresetsvaluerange += "";""; + else + global.diff_deleteuserpresetname = newuserpresetnames[i]; + deleteuserpresetsvaluerange += newuserpresetnames[i] + ""="" + newuserpresetnames[i] + ""`""; + }} + global.diff_menudeleteuserpresetrow.value_range = deleteuserpresetsvaluerange; + }} - if (!ds_map_exists(global.diff_userpresets, global.diff_deleteuserpresetname)) - return; + global.diff_saveuserpresetname = ""USER 1""; + }} + global.diff_deleteuserpresetname = """"; + global.diff_deleteuserpreset = function() {{ + if (!ds_map_exists(global.diff_userpresets, global.diff_deleteuserpresetname)) + return; - if (global.diff_deleteuserpresetname == global.diff_preset) - global.diff_preset = ""Custom""; + if (global.diff_deleteuserpresetname == global.diff_preset) + global.diff_preset = ""Custom""; - ds_map_delete(global.diff_userpresets, global.diff_deleteuserpresetname); + ds_map_delete(global.diff_userpresets, global.diff_deleteuserpresetname); - ossafe_ini_open(""difficulty.ini""); - var newuserpresetnames = ds_map_keys_to_array(global.diff_userpresets); - newuserpresetnames = global.diff_array_sort(newuserpresetnames, true); - var newmetapresetsvalue = """"; - for (var i = 0; i < array_length(newuserpresetnames); i++) {{ - if (i != 0) - newmetapresetsvalue += "";""; - newmetapresetsvalue += newuserpresetnames[i]; - }} - ini_write_string(""META"", ""PRESETS"", newmetapresetsvalue); - ossafe_ini_close(); + ossafe_ini_open(""difficulty.ini""); + var newuserpresetnames = ds_map_keys_to_array(global.diff_userpresets); + newuserpresetnames = global.diff_array_sort(newuserpresetnames, true); + var newmetapresetsvalue = """"; + for (var i = 0; i < array_length(newuserpresetnames); i++) {{ + if (i != 0) + newmetapresetsvalue += "";""; + newmetapresetsvalue += newuserpresetnames[i]; + }} + ini_write_string(""META"", ""PRESETS"", newmetapresetsvalue); + ossafe_ini_close(); - ossafe_ini_open(""difficulty.ini""); - if (ini_section_exists(""preset_"" + global.diff_deleteuserpresetname)) - ini_section_delete(""preset_"" + global.diff_deleteuserpresetname); - ossafe_ini_close(); + ossafe_ini_open(""difficulty.ini""); + if (ini_section_exists(""preset_"" + global.diff_deleteuserpresetname)) + ini_section_delete(""preset_"" + global.diff_deleteuserpresetname); + ossafe_ini_close(); - if (global.diff_menupresetrow != -1) {{ - var userpresetvaluerange = """"; - for (var i = 0; i < array_length(newuserpresetnames); i++) {{ - userpresetvaluerange += "";"" + newuserpresetnames[i] + ""="" + newuserpresetnames[i] + ""`""; - }} - ds_map_replace(global.diff_menupresetrow, ""value_range_en"", ""{string.Join(";", presets.Select(pair => @$"{pair.Key.ToUpper()}={pair.Key}`"))};CUSTOM=Custom`"" + userpresetvaluerange); + if (!is_undefined(global.diff_menupresetrow)) {{ + var userpresetvaluerange = """"; + for (var i = 0; i < array_length(newuserpresetnames); i++) {{ + userpresetvaluerange += "";"" + newuserpresetnames[i] + ""="" + newuserpresetnames[i] + ""`""; }} + global.diff_menupresetrow.value_range = ""{string.Join(";", presets.Select(pair => @$"{pair.Key.ToUpper()}={pair.Key}`"))};CUSTOM=Custom`"" + userpresetvaluerange; + }} - if (global.diff_menucreateuserpresetrow != -1) {{ - var createuserpresetsvaluerange = """"; - var hasaddednew = false; - for (var i = 1; i < 10; i++) {{ - var thispresetname = ""USER "" + string(i); - if (global.diff_array_contains(newuserpresetnames, thispresetname)) {{ - if (i != 1) - createuserpresetsvaluerange += "";""; - createuserpresetsvaluerange += thispresetname + ""="" + thispresetname + ""`""; - }} else if (!hasaddednew) {{ - if (i != 1) - createuserpresetsvaluerange += "";""; - createuserpresetsvaluerange += thispresetname + ""="" + thispresetname + ""`""; - hasaddednew = true; - }} - }} - var possibleuserpresetnames = [""USER 1"", ""USER 2"", ""USER 3"", ""USER 4"", ""USER 5"", ""USER 6"", ""USER 7"", ""USER 8"", ""USER 9""]; - for (var i = 0; i < array_length(newuserpresetnames); i++) {{ - if (!global.diff_array_contains(possibleuserpresetnames, newuserpresetnames[i])) {{ + if (!is_undefined(global.diff_menucreateuserpresetrow)) {{ + var createuserpresetsvaluerange = """"; + var hasaddednew = false; + for (var i = 1; i < 10; i++) {{ + var thispresetname = ""USER "" + string(i); + if (global.diff_array_contains(newuserpresetnames, thispresetname)) {{ + if (i != 1) createuserpresetsvaluerange += "";""; - createuserpresetsvaluerange += newuserpresetnames[i] + ""="" + newuserpresetnames[i] + ""`""; - }} + createuserpresetsvaluerange += thispresetname + ""="" + thispresetname + ""`""; + }} else if (!hasaddednew) {{ + if (i != 1) + createuserpresetsvaluerange += "";""; + createuserpresetsvaluerange += thispresetname + ""="" + thispresetname + ""`""; + hasaddednew = true; }} - ds_map_replace(global.diff_menucreateuserpresetrow, ""value_range_en"", createuserpresetsvaluerange); }} - - global.diff_deleteuserpresetname = """" - if (global.diff_menudeleteuserpresetrow != -1) {{ - var deleteuserpresetsvaluerange = """"; - for (var i = 0; i < array_length(newuserpresetnames); i++) {{ - if (i != 0) - deleteuserpresetsvaluerange += "";""; - else - global.diff_deleteuserpresetname = newuserpresetnames[i]; - deleteuserpresetsvaluerange += newuserpresetnames[i] + ""="" + newuserpresetnames[i] + ""`""; + var possibleuserpresetnames = [""USER 1"", ""USER 2"", ""USER 3"", ""USER 4"", ""USER 5"", ""USER 6"", ""USER 7"", ""USER 8"", ""USER 9""]; + for (var i = 0; i < array_length(newuserpresetnames); i++) {{ + if (!global.diff_array_contains(possibleuserpresetnames, newuserpresetnames[i])) {{ + createuserpresetsvaluerange += "";""; + createuserpresetsvaluerange += newuserpresetnames[i] + ""="" + newuserpresetnames[i] + ""`""; }} - ds_map_replace(global.diff_menudeleteuserpresetrow, ""value_range_en"", deleteuserpresetsvaluerange); - ds_map_replace(global.diff_menudeleteuserpresetrow, ""disabled"", deleteuserpresetsvaluerange == """"); }} - - global.diff_saveuserpresetname = ""USER 1""; + global.diff_menucreateuserpresetrow.value_range = createuserpresetsvaluerange; }} - global.diff_userpresets = ds_map_create(); - - // migrate old data as presets: difficulty_[0-2].ini -> USER [1-3] - for (var i = 0; i < 3; i++) {{ - if (ossafe_file_exists(""difficulty_"" + string(i) + "".ini"")) {{ - ossafe_ini_open(""difficulty_"" + string(i) + "".ini""); - global.diff_damagemulti = ini_read_real(""DIFFICULTY"", ""DAMAGE_MULTI"", {presets[preset_default].damagemulti.ToString("F10", CultureInfo.InvariantCulture)}); - global.diff_gameboarddmgx = ini_read_real(""DIFFICULTY"", ""GAMEBOARD_DMG_X"", {presets[preset_default].gameboarddmgx.ToString("F10", CultureInfo.InvariantCulture)}); - global.diff_hitall = ini_read_real(""DIFFICULTY"", ""HIT_ALL"", {presets[preset_default].hitall.ToString().ToLower()}); - global.diff_iframes = ini_read_real(""DIFFICULTY"", ""I_FRAMES"", {presets[preset_default].iframes.ToString("F10", CultureInfo.InvariantCulture)}); - global.diff_enemycd = ini_read_real(""DIFFICULTY"", ""ENEMY_COOLDOWNS"", {presets[preset_default].enemycd.ToString("F10", CultureInfo.InvariantCulture)}); - global.diff_gmbrdenemycd = ini_read_real(""DIFFICULTY"", ""GMBRD_ENEMY_CDS"", {presets[preset_default].gmbrdenemycd.ToString("F10", CultureInfo.InvariantCulture)}); - global.diff_tpgain = ini_read_real(""DIFFICULTY"", ""TP_GAIN"", {presets[preset_default].tpgain.ToString("F10", CultureInfo.InvariantCulture)}); - global.diff_extraenemies = ini_read_real(""DIFFICULTY"", ""EXTRA_ENEMIES"", {presets[preset_default].extraenemies.ToString()}); - global.diff_battlerewards = ini_read_real(""DIFFICULTY"", ""BATTLE_REWARDS"", {presets[preset_default].battlerewards.ToString("F10", CultureInfo.InvariantCulture)}); - global.diff_rewardranking = ini_read_real(""DIFFICULTY"", ""REWARD_RANKING"", {presets[preset_default].rewardranking.ToString().ToLower()}); - global.diff_downdeficit = ini_read_real(""DIFFICULTY"", ""DOWN_DEFICIT"", {presets[preset_default].downdeficit.ToString("F10", CultureInfo.InvariantCulture)}); - global.diff_downedregen = ini_read_real(""DIFFICULTY"", ""DOWNED_REGEN"", {presets[preset_default].downedregen.ToString("F10", CultureInfo.InvariantCulture)}); - global.diff_victoryres = ini_read_real(""DIFFICULTY"", ""VICTORY_RES"", {presets[preset_default].victoryres.ToString("F10", CultureInfo.InvariantCulture)}); - global.diff_plrdmg = ini_read_real(""DIFFICULTY"", ""PLR_DMG"", {presets[preset_default].plrdmg.ToString("F10", CultureInfo.InvariantCulture)}); - global.diff_gmbrdplrdmg = ini_read_real(""DIFFICULTY"", ""GMBRD_PLR_DMG"", {presets[preset_default].gmbrdplrdmg.ToString("F10", CultureInfo.InvariantCulture)}); - global.diff_plrheal = ini_read_real(""DIFFICULTY"", ""PLR_HEAL"", {presets[preset_default].plrheal.ToString("F10", CultureInfo.InvariantCulture)}); - global.diff_gmbrdplrheal = ini_read_real(""DIFFICULTY"", ""GMBRD_PLR_HEAL"", {presets[preset_default].gmbrdplrheal.ToString("F10", CultureInfo.InvariantCulture)}); - global.diff_mercy = ini_read_real(""DIFFICULTY"", ""MERCY"", {presets[preset_default].mercy.ToString("F10", CultureInfo.InvariantCulture)}); - global.diff_saveheal = ini_read_real(""DIFFICULTY"", ""SAVE_POINT_HEAL"", {presets[preset_default].saveheal.ToString().ToLower()}); - ossafe_ini_close(); - - global.diff_saveuserpresetname = ""USER "" + string(i+1); - global.diff_saveuserpreset(); - - ossafe_file_delete(""difficulty_"" + string(i) + "".ini""); + global.diff_deleteuserpresetname = """" + if (!is_undefined(global.diff_menudeleteuserpresetrow)) {{ + var deleteuserpresetsvaluerange = """"; + for (var i = 0; i < array_length(newuserpresetnames); i++) {{ + if (i != 0) + deleteuserpresetsvaluerange += "";""; + else + global.diff_deleteuserpresetname = newuserpresetnames[i]; + deleteuserpresetsvaluerange += newuserpresetnames[i] + ""="" + newuserpresetnames[i] + ""`""; }} + global.diff_menudeleteuserpresetrow.value_range = deleteuserpresetsvaluerange; }} + global.diff_saveuserpresetname = ""USER 1""; - // clean up some of the junk - for (var i = 3; i < 10; i++) {{ - if (ossafe_file_exists(""difficulty_"" + string(i) + "".ini"")) {{ - ossafe_file_delete(""difficulty_"" + string(i) + "".ini""); - }} - }} + }} - // load all user presets - if (ossafe_file_exists(""difficulty.ini"")) {{ - ossafe_ini_open(""difficulty.ini""); - var metapresetsiniraw = ini_read_string(""META"", ""PRESETS"", """"); - var userpresetnames = metapresetsiniraw == """" ? [] : {((ch_no != 0) ? "" : "global.diff_")}string_split(metapresetsiniraw, "";""); - for (var i = 0; i < array_length(userpresetnames); i++) {{ - var presetdata = ds_map_create(); - ds_map_add(presetdata, ""damagemulti"", ini_read_real(""preset_"" + userpresetnames[i], ""DAMAGE_MULTI"", {presets[preset_default].damagemulti.ToString("F10", CultureInfo.InvariantCulture)})); - ds_map_add(presetdata, ""gameboarddmgx"", ini_read_real(""preset_"" + userpresetnames[i], ""GAMEBOARD_DMG_X"", {presets[preset_default].gameboarddmgx.ToString("F10", CultureInfo.InvariantCulture)})); - ds_map_add(presetdata, ""hitall"", ini_read_real(""preset_"" + userpresetnames[i], ""HIT_ALL"", {presets[preset_default].hitall.ToString().ToLower()})); - ds_map_add(presetdata, ""iframes"", ini_read_real(""preset_"" + userpresetnames[i], ""I_FRAMES"", {presets[preset_default].iframes.ToString("F10", CultureInfo.InvariantCulture)})); - ds_map_add(presetdata, ""enemycd"", ini_read_real(""preset_"" + userpresetnames[i], ""ENEMY_COOLDOWNS"", {presets[preset_default].enemycd.ToString("F10", CultureInfo.InvariantCulture)})); - ds_map_add(presetdata, ""gmbrdenemycd"", ini_read_real(""preset_"" + userpresetnames[i], ""GMBRD_ENEMY_CDS"", {presets[preset_default].gmbrdenemycd.ToString("F10", CultureInfo.InvariantCulture)})); - ds_map_add(presetdata, ""tpgain"", ini_read_real(""preset_"" + userpresetnames[i], ""TP_GAIN"", {presets[preset_default].tpgain.ToString("F10", CultureInfo.InvariantCulture)})); - ds_map_add(presetdata, ""extraenemies"", ini_read_real(""preset_"" + userpresetnames[i], ""EXTRA_ENEMIES"", {presets[preset_default].extraenemies.ToString()})); - ds_map_add(presetdata, ""battlerewards"", ini_read_real(""preset_"" + userpresetnames[i], ""BATTLE_REWARDS"", {presets[preset_default].battlerewards.ToString("F10", CultureInfo.InvariantCulture)})); - ds_map_add(presetdata, ""rewardranking"", ini_read_real(""preset_"" + userpresetnames[i], ""REWARD_RANKING"", {presets[preset_default].rewardranking.ToString().ToLower()})); - ds_map_add(presetdata, ""downdeficit"", ini_read_real(""preset_"" + userpresetnames[i], ""DOWN_DEFICIT"", {presets[preset_default].downdeficit.ToString("F10", CultureInfo.InvariantCulture)})); - ds_map_add(presetdata, ""downedregen"", ini_read_real(""preset_"" + userpresetnames[i], ""DOWNED_REGEN"", {presets[preset_default].downedregen.ToString("F10", CultureInfo.InvariantCulture)})); - ds_map_add(presetdata, ""victoryres"", ini_read_real(""preset_"" + userpresetnames[i], ""VICTORY_RES"", {presets[preset_default].victoryres.ToString("F10", CultureInfo.InvariantCulture)})); - ds_map_add(presetdata, ""plrdmg"", ini_read_real(""preset_"" + userpresetnames[i], ""PLR_DMG"", {presets[preset_default].plrdmg.ToString("F10", CultureInfo.InvariantCulture)})); - ds_map_add(presetdata, ""gmbrdplrdmg"", ini_read_real(""preset_"" + userpresetnames[i], ""GMBRD_PLR_DMG"", {presets[preset_default].gmbrdplrdmg.ToString("F10", CultureInfo.InvariantCulture)})); - ds_map_add(presetdata, ""plrheal"", ini_read_real(""preset_"" + userpresetnames[i], ""PLR_HEAL"", {presets[preset_default].plrheal.ToString("F10", CultureInfo.InvariantCulture)})); - ds_map_add(presetdata, ""gmbrdplrheal"", ini_read_real(""preset_"" + userpresetnames[i], ""GMBRD_PLR_HEAL"", {presets[preset_default].gmbrdplrheal.ToString("F10", CultureInfo.InvariantCulture)})); - ds_map_add(presetdata, ""mercy"", ini_read_real(""preset_"" + userpresetnames[i], ""MERCY"", {presets[preset_default].mercy.ToString("F10", CultureInfo.InvariantCulture)})); - ds_map_add(presetdata, ""saveheal"", ini_read_real(""preset_"" + userpresetnames[i], ""SAVE_POINT_HEAL"", {presets[preset_default].saveheal.ToString().ToLower()})); - ds_map_add(global.diff_userpresets, userpresetnames[i], presetdata); - }} + global.diff_userpresets = ds_map_create(); + + // migrate old data as presets: difficulty_[0-2].ini -> USER [1-3] + for (var i = 0; i < 3; i++) {{ + if (ossafe_file_exists(""difficulty_"" + string(i) + "".ini"")) {{ + ossafe_ini_open(""difficulty_"" + string(i) + "".ini""); + global.diff_damagemulti = ini_read_real(""DIFFICULTY"", ""DAMAGE_MULTI"", {presets[preset_default].damagemulti.ToString("F10", CultureInfo.InvariantCulture)}); + global.diff_gameboarddmgx = ini_read_real(""DIFFICULTY"", ""GAMEBOARD_DMG_X"", {presets[preset_default].gameboarddmgx.ToString("F10", CultureInfo.InvariantCulture)}); + global.diff_hitall = ini_read_real(""DIFFICULTY"", ""HIT_ALL"", {presets[preset_default].hitall.ToString().ToLower()}); + global.diff_iframes = ini_read_real(""DIFFICULTY"", ""I_FRAMES"", {presets[preset_default].iframes.ToString("F10", CultureInfo.InvariantCulture)}); + global.diff_enemycd = ini_read_real(""DIFFICULTY"", ""ENEMY_COOLDOWNS"", {presets[preset_default].enemycd.ToString("F10", CultureInfo.InvariantCulture)}); + global.diff_gmbrdenemycd = ini_read_real(""DIFFICULTY"", ""GMBRD_ENEMY_CDS"", {presets[preset_default].gmbrdenemycd.ToString("F10", CultureInfo.InvariantCulture)}); + global.diff_tpgain = ini_read_real(""DIFFICULTY"", ""TP_GAIN"", {presets[preset_default].tpgain.ToString("F10", CultureInfo.InvariantCulture)}); + global.diff_extraenemies = ini_read_real(""DIFFICULTY"", ""EXTRA_ENEMIES"", {presets[preset_default].extraenemies.ToString()}); + global.diff_battlerewards = ini_read_real(""DIFFICULTY"", ""BATTLE_REWARDS"", {presets[preset_default].battlerewards.ToString("F10", CultureInfo.InvariantCulture)}); + global.diff_rewardranking = ini_read_real(""DIFFICULTY"", ""REWARD_RANKING"", {presets[preset_default].rewardranking.ToString().ToLower()}); + global.diff_downdeficit = ini_read_real(""DIFFICULTY"", ""DOWN_DEFICIT"", {presets[preset_default].downdeficit.ToString("F10", CultureInfo.InvariantCulture)}); + global.diff_downedregen = ini_read_real(""DIFFICULTY"", ""DOWNED_REGEN"", {presets[preset_default].downedregen.ToString("F10", CultureInfo.InvariantCulture)}); + global.diff_victoryres = ini_read_real(""DIFFICULTY"", ""VICTORY_RES"", {presets[preset_default].victoryres.ToString("F10", CultureInfo.InvariantCulture)}); + global.diff_plrdmg = ini_read_real(""DIFFICULTY"", ""PLR_DMG"", {presets[preset_default].plrdmg.ToString("F10", CultureInfo.InvariantCulture)}); + global.diff_gmbrdplrdmg = ini_read_real(""DIFFICULTY"", ""GMBRD_PLR_DMG"", {presets[preset_default].gmbrdplrdmg.ToString("F10", CultureInfo.InvariantCulture)}); + global.diff_plrheal = ini_read_real(""DIFFICULTY"", ""PLR_HEAL"", {presets[preset_default].plrheal.ToString("F10", CultureInfo.InvariantCulture)}); + global.diff_gmbrdplrheal = ini_read_real(""DIFFICULTY"", ""GMBRD_PLR_HEAL"", {presets[preset_default].gmbrdplrheal.ToString("F10", CultureInfo.InvariantCulture)}); + global.diff_mercy = ini_read_real(""DIFFICULTY"", ""MERCY"", {presets[preset_default].mercy.ToString("F10", CultureInfo.InvariantCulture)}); + global.diff_saveheal = ini_read_real(""DIFFICULTY"", ""SAVE_POINT_HEAL"", {presets[preset_default].saveheal.ToString().ToLower()}); ossafe_ini_close(); - }} - global.diff_usepreset = function() - {{ - switch (global.diff_preset) {{ - {string.Join("\n", presets.Select(pair => @$" - case ""{pair.Key}"": - global.diff_damagemulti = {pair.Value.damagemulti.ToString("F10", CultureInfo.InvariantCulture)}; - global.diff_gameboarddmgx = {pair.Value.gameboarddmgx.ToString("F10", CultureInfo.InvariantCulture)}; - global.diff_hitall = {pair.Value.hitall.ToString().ToLower()}; - global.diff_iframes = {pair.Value.iframes.ToString("F10", CultureInfo.InvariantCulture)}; - global.diff_enemycd = {pair.Value.enemycd.ToString("F10", CultureInfo.InvariantCulture)}; - global.diff_gmbrdenemycd = {pair.Value.gmbrdenemycd.ToString("F10", CultureInfo.InvariantCulture)}; - global.diff_tpgain = {pair.Value.tpgain.ToString("F10", CultureInfo.InvariantCulture)}; - global.diff_extraenemies = {pair.Value.extraenemies.ToString()}; - global.diff_battlerewards = {pair.Value.battlerewards.ToString("F10", CultureInfo.InvariantCulture)}; - global.diff_rewardranking = {pair.Value.rewardranking.ToString().ToLower()}; - global.diff_downdeficit = {pair.Value.downdeficit.ToString("F10", CultureInfo.InvariantCulture)}; - global.diff_downedregen = {pair.Value.downedregen.ToString("F10", CultureInfo.InvariantCulture)}; - global.diff_victoryres = {pair.Value.victoryres.ToString("F10", CultureInfo.InvariantCulture)}; - global.diff_plrdmg = {pair.Value.plrdmg.ToString("F10", CultureInfo.InvariantCulture)}; - global.diff_gmbrdplrdmg = {pair.Value.gmbrdplrdmg.ToString("F10", CultureInfo.InvariantCulture)}; - global.diff_plrheal = {pair.Value.plrheal.ToString("F10", CultureInfo.InvariantCulture)}; - global.diff_gmbrdplrheal = {pair.Value.gmbrdplrheal.ToString("F10", CultureInfo.InvariantCulture)}; - global.diff_mercy = {pair.Value.mercy.ToString("F10", CultureInfo.InvariantCulture)}; - global.diff_saveheal = {pair.Value.saveheal.ToString().ToLower()}; - break; - "))} - case ""Custom"": - // Nothing to do - break; - default: - if (ds_map_exists(global.diff_userpresets, global.diff_preset)) {{ - var presetdata = ds_map_find_value(global.diff_userpresets, global.diff_preset); - global.diff_damagemulti = ds_map_find_value(presetdata, ""damagemulti""); - global.diff_gameboarddmgx = ds_map_find_value(presetdata, ""gameboarddmgx""); - global.diff_hitall = ds_map_find_value(presetdata, ""hitall""); - global.diff_iframes = ds_map_find_value(presetdata, ""iframes""); - global.diff_enemycd = ds_map_find_value(presetdata, ""enemycd""); - global.diff_gmbrdenemycd = ds_map_find_value(presetdata, ""gmbrdenemycd""); - global.diff_tpgain = ds_map_find_value(presetdata, ""tpgain""); - global.diff_extraenemies = ds_map_find_value(presetdata, ""extraenemies""); - global.diff_battlerewards = ds_map_find_value(presetdata, ""battlerewards""); - global.diff_rewardranking = ds_map_find_value(presetdata, ""rewardranking""); - global.diff_downdeficit = ds_map_find_value(presetdata, ""downdeficit""); - global.diff_downedregen = ds_map_find_value(presetdata, ""downedregen""); - global.diff_victoryres = ds_map_find_value(presetdata, ""victoryres""); - global.diff_plrdmg = ds_map_find_value(presetdata, ""plrdmg""); - global.diff_gmbrdplrdmg = ds_map_find_value(presetdata, ""gmbrdplrdmg""); - global.diff_plrheal = ds_map_find_value(presetdata, ""plrheal""); - global.diff_gmbrdplrheal = ds_map_find_value(presetdata, ""gmbrdplrheal""); - global.diff_mercy = ds_map_find_value(presetdata, ""mercy""); - global.diff_saveheal = ds_map_find_value(presetdata, ""saveheal""); - }} - break; - }} - }} + global.diff_saveuserpresetname = ""USER "" + string(i+1); + global.diff_saveuserpreset(); - global.diff_usepreset_custom = function() - {{ - global.diff_preset = ""Custom""; - global.diff_usepreset(); + ossafe_file_delete(""difficulty_"" + string(i) + "".ini""); }} - - global.diff_usepreset_default = function() - {{ - global.diff_preset = ""{preset_default}""; - global.diff_usepreset(); + }} + global.diff_saveuserpresetname = ""USER 1""; + // clean up some of the junk + for (var i = 3; i < 10; i++) {{ + if (ossafe_file_exists(""difficulty_"" + string(i) + "".ini"")) {{ + ossafe_file_delete(""difficulty_"" + string(i) + "".ini""); }} + }} - global.diff_usepreset_default(); - - // Provide support for mod devs to add compatibility - global.diff_apply = function(arg0, arg1, arg2) {{ - switch (arg0) {{ - case ""DIFFOP_DAMAGE"": - return ceil(global.diff_damagemulti * arg1); - case ""DIFFOP_DAMAGE_GB"": - return (global.diff_gameboarddmgx < 0 ? global.diff_damagemulti : global.diff_gameboarddmgx) * arg1; - case ""DIFFOP_HITALL"": - return global.diff_hitall || arg1; - case ""DIFFOP_IFRAMES"": - return ceil(global.diff_iframes * arg1); - case ""DIFFOP_ENEMYCD"": - return round(global.diff_enemycd * arg1); - case ""DIFFOP_ENEMYCD_GB"": - return ceil((global.diff_gmbrdenemycd < 0 ? global.diff_enemycd : global.diff_gmbrdenemycd) * arg1); - case ""DIFFOP_TPGAIN"": - return ceil(global.diff_tpgain * arg1); - case ""DIFFOP_EXTRAENEMIES"": - return global.diff_extraenemies; - case ""DIFFOP_REWARDS"": - return ceil(global.diff_battlerewards * arg1); - case ""DIFFOP_REWARDRANK_GB"": - return global.diff_rewardranking || arg1; - case ""DIFFOP_DOWNDEF"": - return max(-999, floor(global.diff_downdeficit * arg1)); - case ""DIFFOP_DOWNREGEN"": - return ceil(global.diff_downedregen * arg1); - case ""DIFFOP_VICRES"": - return ceil(global.diff_victoryres >= 0 ? max(1, arg1 * global.diff_victoryres) : arg2); - case ""DIFFOP_PLRDMG"": - return ceil(global.diff_plrdmg * arg1); - case ""DIFFOP_PLRDMG_GB"": - return ceil(global.diff_gmbrdplrdmg * arg1); - case ""DIFFOP_PLRHEAL"": - return ceil(global.diff_plrheal * arg1); - case ""DIFFOP_PLRHEAL_GB"": - return ceil(global.diff_gmbrdplrheal * arg1); - case ""DIFFOP_MERCY"": - return ceil(global.diff_mercy * arg1); - case ""DIFFOP_SAVEHEAL"": - return global.diff_saveheal || arg1; - }} + // load all user presets + if (ossafe_file_exists(""difficulty.ini"")) {{ + ossafe_ini_open(""difficulty.ini""); + var metapresetsiniraw = ini_read_string(""META"", ""PRESETS"", """"); + var userpresetnames = metapresetsiniraw == """" ? [] : {((ch_no != 0) ? "" : "global.diff_")}string_split(metapresetsiniraw, "";""); + for (var i = 0; i < array_length(userpresetnames); i++) {{ + var presetdata = ds_map_create(); + ds_map_add(presetdata, ""damagemulti"", ini_read_real(""preset_"" + userpresetnames[i], ""DAMAGE_MULTI"", {presets[preset_default].damagemulti.ToString("F10", CultureInfo.InvariantCulture)})); + ds_map_add(presetdata, ""gameboarddmgx"", ini_read_real(""preset_"" + userpresetnames[i], ""GAMEBOARD_DMG_X"", {presets[preset_default].gameboarddmgx.ToString("F10", CultureInfo.InvariantCulture)})); + ds_map_add(presetdata, ""hitall"", ini_read_real(""preset_"" + userpresetnames[i], ""HIT_ALL"", {presets[preset_default].hitall.ToString().ToLower()})); + ds_map_add(presetdata, ""iframes"", ini_read_real(""preset_"" + userpresetnames[i], ""I_FRAMES"", {presets[preset_default].iframes.ToString("F10", CultureInfo.InvariantCulture)})); + ds_map_add(presetdata, ""enemycd"", ini_read_real(""preset_"" + userpresetnames[i], ""ENEMY_COOLDOWNS"", {presets[preset_default].enemycd.ToString("F10", CultureInfo.InvariantCulture)})); + ds_map_add(presetdata, ""gmbrdenemycd"", ini_read_real(""preset_"" + userpresetnames[i], ""GMBRD_ENEMY_CDS"", {presets[preset_default].gmbrdenemycd.ToString("F10", CultureInfo.InvariantCulture)})); + ds_map_add(presetdata, ""tpgain"", ini_read_real(""preset_"" + userpresetnames[i], ""TP_GAIN"", {presets[preset_default].tpgain.ToString("F10", CultureInfo.InvariantCulture)})); + ds_map_add(presetdata, ""extraenemies"", ini_read_real(""preset_"" + userpresetnames[i], ""EXTRA_ENEMIES"", {presets[preset_default].extraenemies.ToString()})); + ds_map_add(presetdata, ""battlerewards"", ini_read_real(""preset_"" + userpresetnames[i], ""BATTLE_REWARDS"", {presets[preset_default].battlerewards.ToString("F10", CultureInfo.InvariantCulture)})); + ds_map_add(presetdata, ""rewardranking"", ini_read_real(""preset_"" + userpresetnames[i], ""REWARD_RANKING"", {presets[preset_default].rewardranking.ToString().ToLower()})); + ds_map_add(presetdata, ""downdeficit"", ini_read_real(""preset_"" + userpresetnames[i], ""DOWN_DEFICIT"", {presets[preset_default].downdeficit.ToString("F10", CultureInfo.InvariantCulture)})); + ds_map_add(presetdata, ""downedregen"", ini_read_real(""preset_"" + userpresetnames[i], ""DOWNED_REGEN"", {presets[preset_default].downedregen.ToString("F10", CultureInfo.InvariantCulture)})); + ds_map_add(presetdata, ""victoryres"", ini_read_real(""preset_"" + userpresetnames[i], ""VICTORY_RES"", {presets[preset_default].victoryres.ToString("F10", CultureInfo.InvariantCulture)})); + ds_map_add(presetdata, ""plrdmg"", ini_read_real(""preset_"" + userpresetnames[i], ""PLR_DMG"", {presets[preset_default].plrdmg.ToString("F10", CultureInfo.InvariantCulture)})); + ds_map_add(presetdata, ""gmbrdplrdmg"", ini_read_real(""preset_"" + userpresetnames[i], ""GMBRD_PLR_DMG"", {presets[preset_default].gmbrdplrdmg.ToString("F10", CultureInfo.InvariantCulture)})); + ds_map_add(presetdata, ""plrheal"", ini_read_real(""preset_"" + userpresetnames[i], ""PLR_HEAL"", {presets[preset_default].plrheal.ToString("F10", CultureInfo.InvariantCulture)})); + ds_map_add(presetdata, ""gmbrdplrheal"", ini_read_real(""preset_"" + userpresetnames[i], ""GMBRD_PLR_HEAL"", {presets[preset_default].gmbrdplrheal.ToString("F10", CultureInfo.InvariantCulture)})); + ds_map_add(presetdata, ""mercy"", ini_read_real(""preset_"" + userpresetnames[i], ""MERCY"", {presets[preset_default].mercy.ToString("F10", CultureInfo.InvariantCulture)})); + ds_map_add(presetdata, ""saveheal"", ini_read_real(""preset_"" + userpresetnames[i], ""SAVE_POINT_HEAL"", {presets[preset_default].saveheal.ToString().ToLower()})); + ds_map_add(global.diff_userpresets, userpresetnames[i], presetdata); }} + ossafe_ini_close(); + }} - global.diff_savesettings = function() {{ - {savesettingsblock(@"""ch"" + string(global.chapter) + ""_"" + string(global.filechoice)")} + global.diff_usepreset = function() + {{ + switch (global.diff_preset) {{ + {string.Join("\n", presets.Select(pair => @$" + case ""{pair.Key}"": + global.diff_damagemulti = {pair.Value.damagemulti.ToString("F10", CultureInfo.InvariantCulture)}; + global.diff_gameboarddmgx = {pair.Value.gameboarddmgx.ToString("F10", CultureInfo.InvariantCulture)}; + global.diff_hitall = {pair.Value.hitall.ToString().ToLower()}; + global.diff_iframes = {pair.Value.iframes.ToString("F10", CultureInfo.InvariantCulture)}; + global.diff_enemycd = {pair.Value.enemycd.ToString("F10", CultureInfo.InvariantCulture)}; + global.diff_gmbrdenemycd = {pair.Value.gmbrdenemycd.ToString("F10", CultureInfo.InvariantCulture)}; + global.diff_tpgain = {pair.Value.tpgain.ToString("F10", CultureInfo.InvariantCulture)}; + global.diff_extraenemies = {pair.Value.extraenemies.ToString()}; + global.diff_battlerewards = {pair.Value.battlerewards.ToString("F10", CultureInfo.InvariantCulture)}; + global.diff_rewardranking = {pair.Value.rewardranking.ToString().ToLower()}; + global.diff_downdeficit = {pair.Value.downdeficit.ToString("F10", CultureInfo.InvariantCulture)}; + global.diff_downedregen = {pair.Value.downedregen.ToString("F10", CultureInfo.InvariantCulture)}; + global.diff_victoryres = {pair.Value.victoryres.ToString("F10", CultureInfo.InvariantCulture)}; + global.diff_plrdmg = {pair.Value.plrdmg.ToString("F10", CultureInfo.InvariantCulture)}; + global.diff_gmbrdplrdmg = {pair.Value.gmbrdplrdmg.ToString("F10", CultureInfo.InvariantCulture)}; + global.diff_plrheal = {pair.Value.plrheal.ToString("F10", CultureInfo.InvariantCulture)}; + global.diff_gmbrdplrheal = {pair.Value.gmbrdplrheal.ToString("F10", CultureInfo.InvariantCulture)}; + global.diff_mercy = {pair.Value.mercy.ToString("F10", CultureInfo.InvariantCulture)}; + global.diff_saveheal = {pair.Value.saveheal.ToString().ToLower()}; + break; + "))} + case ""Custom"": + // Nothing to do + break; + default: + if (ds_map_exists(global.diff_userpresets, global.diff_preset)) {{ + var presetdata = ds_map_find_value(global.diff_userpresets, global.diff_preset); + global.diff_damagemulti = ds_map_find_value(presetdata, ""damagemulti""); + global.diff_gameboarddmgx = ds_map_find_value(presetdata, ""gameboarddmgx""); + global.diff_hitall = ds_map_find_value(presetdata, ""hitall""); + global.diff_iframes = ds_map_find_value(presetdata, ""iframes""); + global.diff_enemycd = ds_map_find_value(presetdata, ""enemycd""); + global.diff_gmbrdenemycd = ds_map_find_value(presetdata, ""gmbrdenemycd""); + global.diff_tpgain = ds_map_find_value(presetdata, ""tpgain""); + global.diff_extraenemies = ds_map_find_value(presetdata, ""extraenemies""); + global.diff_battlerewards = ds_map_find_value(presetdata, ""battlerewards""); + global.diff_rewardranking = ds_map_find_value(presetdata, ""rewardranking""); + global.diff_downdeficit = ds_map_find_value(presetdata, ""downdeficit""); + global.diff_downedregen = ds_map_find_value(presetdata, ""downedregen""); + global.diff_victoryres = ds_map_find_value(presetdata, ""victoryres""); + global.diff_plrdmg = ds_map_find_value(presetdata, ""plrdmg""); + global.diff_gmbrdplrdmg = ds_map_find_value(presetdata, ""gmbrdplrdmg""); + global.diff_plrheal = ds_map_find_value(presetdata, ""plrheal""); + global.diff_gmbrdplrheal = ds_map_find_value(presetdata, ""gmbrdplrheal""); + global.diff_mercy = ds_map_find_value(presetdata, ""mercy""); + global.diff_saveheal = ds_map_find_value(presetdata, ""saveheal""); + }} + break; }} - - "); -} - -// Load globals from config -(string script, string chapter) [] loadLikes = {("gml_GlobalScript_scr_load", "global.chapter")}; -if (ch_no == 0) -{ - (string script, string chapter) [] loadCh1 = {("gml_GlobalScript_scr_load_ch1", "global.chapter")}; - loadLikes = loadLikes.Concat(loadCh1).ToArray(); -} -if (ch_no > 1 || ch_no == 0) -{ - (string script, string chapter) [] loadCh1 = {("gml_GlobalScript_scr_load_chapter1", "1")}; - loadLikes = loadLikes.Concat(loadCh1).ToArray(); -} -if (ch_no > 2) -{ - (string script, string chapter) [] loadCh2 = {("gml_GlobalScript_scr_load_chapter2", "2")}; - loadLikes = loadLikes.Concat(loadCh2).ToArray(); -} -if (ch_no > 3) -{ - (string script, string chapter) [] loadCh3 = {("gml_GlobalScript_scr_load_chapter3", "3")}; - loadLikes = loadLikes.Concat(loadCh3).ToArray(); -} -if (ch_no > 4) -{ - (string script, string chapter) [] loadCh4 = {("gml_GlobalScript_scr_load_chapter4", "4")}; - loadLikes = loadLikes.Concat(loadCh4).ToArray(); -} -// if (ch_no > 5) -// { -// (string script, string chapter) [] loadCh5 = {("gml_GlobalScript_scr_load_chapter5", "5")}; -// loadLikes = loadLikes.Concat(loadCh5).ToArray(); -// } -// if (ch_no > 6) -// { -// (string script, string chapter) [] loadCh6 = {("gml_GlobalScript_scr_load_chapter6", "6")}; -// loadLikes = loadLikes.Concat(loadCh6).ToArray(); -// } - -foreach ((string script, string chapter) loadLike in loadLikes) -{ - importGroup.QueueTrimmedLinesFindReplace(loadLike.script, $"ossafe_file_text_close{(loadLike.script.EndsWith("_ch1") ? "_ch1" : "")}(myfileid);", @$" - ossafe_file_text_close{(loadLike.script.EndsWith("_ch1") ? "_ch1" : "")}(myfileid); - - {loadsettingsblock(loadLike.chapter, "global.filechoice")} - - "); -} - -// Save globals to config -string[] saveLikes = {"gml_GlobalScript_scr_saveprocess"}; -if (ch_no == 0) -{ - string[] demoSaveLikes = {"gml_GlobalScript_scr_saveprocess_ch1"}; - saveLikes = saveLikes.Concat(demoSaveLikes).ToArray(); -} -foreach (string scrName in saveLikes) -{ - string saveslot = @" ""ch"" + string(global.chapter) + ""_"" + string(global.filechoice)"; - importGroup.QueueTrimmedLinesFindReplace(scrName, $"{(ch_no == 0 ? "var is_valid = " : "")}ossafe_file_text_close{(scrName.EndsWith("_ch1") ? "_ch1" : "")}(myfileid);", @$" - {(ch_no == 0 ? "var is_valid = " : "")}ossafe_file_text_close{(scrName.EndsWith("_ch1") ? "_ch1" : "")}(myfileid); - - {savesettingsblock(@"""ch"" + string(global.chapter) + ""_"" + string(global.filechoice)")} - "); -} - -// Delete config if file is deleted -{ - importGroup.QueueTrimmedLinesFindReplace("gml_Object_DEVICE_MENU_Step_0", @"TIME_STRING[MENUCOORD[5]] = ""--:--"";", @" - TIME_STRING[MENUCOORD[5]] = ""--:--""; - - ossafe_ini_open(""difficulty.ini""); - if (ini_section_exists(""ch"" + string(global.chapter) + ""_"" + string(MENUCOORD[5]))) - ini_section_delete(""ch"" + string(global.chapter) + ""_"" + string(MENUCOORD[5])); - ossafe_ini_close(); - "); -} -if (ch_no == 0) -{ - importGroup.QueueTrimmedLinesFindReplace("gml_Object_DEVICE_MENU_ch1_Step_0", @"TIME_STRING[MENUCOORD[5]] = ""--:--"";", @" - TIME_STRING[MENUCOORD[5]] = ""--:--""; - - ossafe_ini_open(""difficulty.ini""); - if (ini_section_exists(""ch"" + string(global.chapter) + ""_"" + string(MENUCOORD[5]))) - ini_section_delete(""ch"" + string(global.chapter) + ""_"" + string(MENUCOORD[5])); - ossafe_ini_close(); - "); -} - -// copy config if file is copied -string copysettingsblock = @$" - ossafe_ini_open(""difficulty.ini""); - if (ini_section_exists(""ch"" + string(global.chapter) + ""_"" + string(MENUCOORD[2]))){{ - ini_write_real(""ch"" + string(global.chapter) + ""_"" + string(MENUCOORD[3]), ""DAMAGE_MULTI"", ini_read_real(""ch"" + string(global.chapter) + ""_"" + string(MENUCOORD[2]), ""DAMAGE_MULTI"", {presets[preset_default].damagemulti.ToString("F10", CultureInfo.InvariantCulture)})); - ini_write_real(""ch"" + string(global.chapter) + ""_"" + string(MENUCOORD[3]), ""GAMEBOARD_DMG_X"", ini_read_real(""ch"" + string(global.chapter) + ""_"" + string(MENUCOORD[2]), ""GAMEBOARD_DMG_X"", {presets[preset_default].gameboarddmgx.ToString("F10", CultureInfo.InvariantCulture)})); - ini_write_real(""ch"" + string(global.chapter) + ""_"" + string(MENUCOORD[3]), ""HIT_ALL"", ini_read_real(""ch"" + string(global.chapter) + ""_"" + string(MENUCOORD[2]), ""HIT_ALL"", {presets[preset_default].hitall.ToString().ToLower()})); - ini_write_real(""ch"" + string(global.chapter) + ""_"" + string(MENUCOORD[3]), ""I_FRAMES"", ini_read_real(""ch"" + string(global.chapter) + ""_"" + string(MENUCOORD[2]), ""I_FRAMES"", {presets[preset_default].iframes.ToString("F10", CultureInfo.InvariantCulture)})); - ini_write_real(""ch"" + string(global.chapter) + ""_"" + string(MENUCOORD[3]), ""ENEMY_COOLDOWNS"", ini_read_real(""ch"" + string(global.chapter) + ""_"" + string(MENUCOORD[2]), ""ENEMY_COOLDOWNS"", {presets[preset_default].enemycd.ToString("F10", CultureInfo.InvariantCulture)})); - ini_write_real(""ch"" + string(global.chapter) + ""_"" + string(MENUCOORD[3]), ""GMBRD_ENEMY_CDS"", ini_read_real(""ch"" + string(global.chapter) + ""_"" + string(MENUCOORD[2]), ""GMBRD_ENEMY_CDS"", {presets[preset_default].gmbrdenemycd.ToString("F10", CultureInfo.InvariantCulture)})); - ini_write_real(""ch"" + string(global.chapter) + ""_"" + string(MENUCOORD[3]), ""TP_GAIN"", ini_read_real(""ch"" + string(global.chapter) + ""_"" + string(MENUCOORD[2]), ""TP_GAIN"", {presets[preset_default].tpgain.ToString("F10", CultureInfo.InvariantCulture)})); - ini_write_real(""ch"" + string(global.chapter) + ""_"" + string(MENUCOORD[3]), ""EXTRA_ENEMIES"", ini_read_real(""ch"" + string(global.chapter) + ""_"" + string(MENUCOORD[2]), ""EXTRA_ENEMIES"", {presets[preset_default].extraenemies.ToString()})); - ini_write_real(""ch"" + string(global.chapter) + ""_"" + string(MENUCOORD[3]), ""BATTLE_REWARDS"", ini_read_real(""ch"" + string(global.chapter) + ""_"" + string(MENUCOORD[2]), ""BATTLE_REWARDS"", {presets[preset_default].battlerewards.ToString("F10", CultureInfo.InvariantCulture)})); - ini_write_real(""ch"" + string(global.chapter) + ""_"" + string(MENUCOORD[3]), ""REWARD_RANKING"", ini_read_real(""ch"" + string(global.chapter) + ""_"" + string(MENUCOORD[2]), ""REWARD_RANKING"", {presets[preset_default].rewardranking.ToString().ToLower()})); - ini_write_real(""ch"" + string(global.chapter) + ""_"" + string(MENUCOORD[3]), ""DOWN_DEFICIT"", ini_read_real(""ch"" + string(global.chapter) + ""_"" + string(MENUCOORD[2]), ""DOWN_DEFICIT"", {presets[preset_default].downdeficit.ToString("F10", CultureInfo.InvariantCulture)})); - ini_write_real(""ch"" + string(global.chapter) + ""_"" + string(MENUCOORD[3]), ""DOWNED_REGEN"", ini_read_real(""ch"" + string(global.chapter) + ""_"" + string(MENUCOORD[2]), ""DOWNED_REGEN"", {presets[preset_default].downedregen.ToString("F10", CultureInfo.InvariantCulture)})); - ini_write_real(""ch"" + string(global.chapter) + ""_"" + string(MENUCOORD[3]), ""VICTORY_RES"", ini_read_real(""ch"" + string(global.chapter) + ""_"" + string(MENUCOORD[2]), ""VICTORY_RES"", {presets[preset_default].victoryres.ToString("F10", CultureInfo.InvariantCulture)})); - ini_write_real(""ch"" + string(global.chapter) + ""_"" + string(MENUCOORD[3]), ""PLR_DMG"", ini_read_real(""ch"" + string(global.chapter) + ""_"" + string(MENUCOORD[2]), ""PLR_DMG"", {presets[preset_default].plrdmg.ToString("F10", CultureInfo.InvariantCulture)})); - ini_write_real(""ch"" + string(global.chapter) + ""_"" + string(MENUCOORD[3]), ""GMBRD_PLR_DMG"", ini_read_real(""ch"" + string(global.chapter) + ""_"" + string(MENUCOORD[2]), ""GMBRD_PLR_DMG"", {presets[preset_default].gmbrdplrdmg.ToString("F10", CultureInfo.InvariantCulture)})); - ini_write_real(""ch"" + string(global.chapter) + ""_"" + string(MENUCOORD[3]), ""PLR_HEAL"", ini_read_real(""ch"" + string(global.chapter) + ""_"" + string(MENUCOORD[2]), ""PLR_HEAL"", {presets[preset_default].plrheal.ToString("F10", CultureInfo.InvariantCulture)})); - ini_write_real(""ch"" + string(global.chapter) + ""_"" + string(MENUCOORD[3]), ""GMBRD_PLR_HEAL"", ini_read_real(""ch"" + string(global.chapter) + ""_"" + string(MENUCOORD[2]), ""GMBRD_PLR_HEAL"", {presets[preset_default].gmbrdplrheal.ToString("F10", CultureInfo.InvariantCulture)})); - ini_write_real(""ch"" + string(global.chapter) + ""_"" + string(MENUCOORD[3]), ""MERCY"", ini_read_real(""ch"" + string(global.chapter) + ""_"" + string(MENUCOORD[2]), ""MERCY"", {presets[preset_default].mercy.ToString("F10", CultureInfo.InvariantCulture)})); - ini_write_real(""ch"" + string(global.chapter) + ""_"" + string(MENUCOORD[3]), ""SAVE_POINT_HEAL"", ini_read_real(""ch"" + string(global.chapter) + ""_"" + string(MENUCOORD[2]), ""SAVE_POINT_HEAL"", {presets[preset_default].saveheal.ToString().ToLower()})); - }} - ossafe_ini_close(); -"; -{ - importGroup.QueueTrimmedLinesFindReplace("gml_Object_DEVICE_MENU_Other_15", @"file_copy(""keyconfig_"" + string(MENUCOORD[2]) + "".ini"", ""keyconfig_"" + string(MENUCOORD[3]) + "".ini"");", @$" - file_copy(""keyconfig_"" + string(MENUCOORD[2]) + "".ini"", ""keyconfig_"" + string(MENUCOORD[3]) + "".ini""); - - {copysettingsblock} - "); -} -if (ch_no == 0) -{ - importGroup.QueueTrimmedLinesFindReplace("gml_Object_DEVICE_MENU_ch1_Other_15", @"file_copy(""keyconfig_"" + string(MENUCOORD[2]) + "".ini"", ""keyconfig_"" + string(MENUCOORD[3]) + "".ini"");", @$" - file_copy(""keyconfig_"" + string(MENUCOORD[2]) + "".ini"", ""keyconfig_"" + string(MENUCOORD[3]) + "".ini""); - - {copysettingsblock} - "); -} - -// Add mod menu -string[] darkcons = {"gml_Object_obj_darkcontroller"}; -if (ch_no == 0) -{ - string[] demoDarkcons = {"gml_Object_obj_darkcontroller_ch1"}; - darkcons = darkcons.Concat(demoDarkcons).ToArray(); -} -foreach (string darkcon in darkcons) -{ - importGroup.QueueAppend(darkcon + "_Create_0", @$" - - if (!variable_instance_exists(global, ""modmenu_data"")) - global.modmenu_data = array_create(0); - - var menudata = ds_map_create(); - ds_map_add(menudata, ""title_en"", ""Difficulty""); - ds_map_add(menudata, ""left_margin_en"", 0); - ds_map_add(menudata, ""left_value_pos_en"", 240); - ds_map_add(menudata, ""on_close"", ""diff_savesettings""); - - var formdata = array_create(0); - - var rowdata = ds_map_create(); - ds_map_add(rowdata, ""title_en"", ""Preset""); - var newuserpresetnames = ds_map_keys_to_array(global.diff_userpresets); - newuserpresetnames = global.diff_array_sort(newuserpresetnames, true); - var userpresetvaluerange = """"; - for (var i = 0; i < array_length(newuserpresetnames); i++) {{ - userpresetvaluerange += "";"" + newuserpresetnames[i] + ""="" + newuserpresetnames[i] + ""`""; }} - ds_map_add(rowdata, ""value_range_en"", ""{string.Join(";", presets.Select(pair => @$"{pair.Key.ToUpper()}={pair.Key}`"))};CUSTOM=Custom`"" + userpresetvaluerange); - ds_map_add(rowdata, ""value_name"", ""diff_preset""); - ds_map_add(rowdata, ""on_change"", ""diff_usepreset""); - ds_map_add(rowdata, ""force_scroll"", true); - array_push(formdata, rowdata); - global.diff_menupresetrow = rowdata; - - var rowdata = ds_map_create(); - ds_map_add(rowdata, ""title_en"", ""BATTLE""); - array_push(formdata, rowdata); - - var rowdata = ds_map_create(); - ds_map_add(rowdata, ""title_en"", ""Damage Multi""); - ds_map_add(rowdata, ""value_range_en"", ""0~1000%;INF=2147483647""); - ds_map_add(rowdata, ""value_name"", ""diff_damagemulti""); - ds_map_add(rowdata, ""on_change"", ""diff_usepreset_custom""); - array_push(formdata, rowdata); - - {(ch_no != 3 ? "" : @" - var rowdata = ds_map_create(); - ds_map_add(rowdata, ""title_en"", ""Gameboard Dmg X""); - ds_map_add(rowdata, ""value_range_en"", ""INHERIT=-1;0-1000%;INF=2147483647""); - ds_map_add(rowdata, ""value_name"", ""diff_gameboarddmgx""); - ds_map_add(rowdata, ""on_change"", ""diff_usepreset_custom""); - array_push(formdata, rowdata); - ")} - var rowdata = ds_map_create(); - ds_map_add(rowdata, ""title_en"", ""Hit.All""); - ds_map_add(rowdata, ""value_range_en"", ""OFF=false;ON=true""); - ds_map_add(rowdata, ""value_name"", ""diff_hitall""); - ds_map_add(rowdata, ""on_change"", ""diff_usepreset_custom""); - array_push(formdata, rowdata); - - var rowdata = ds_map_create(); - ds_map_add(rowdata, ""title_en"", ""I-Frames""); - ds_map_add(rowdata, ""value_range_en"", ""0~1000%""); - ds_map_add(rowdata, ""value_name"", ""diff_iframes""); - ds_map_add(rowdata, ""on_change"", ""diff_usepreset_custom""); - array_push(formdata, rowdata); - - var rowdata = ds_map_create(); - ds_map_add(rowdata, ""title_en"", ""Enemy Cooldowns""); - ds_map_add(rowdata, ""value_range_en"", ""0~200%""); - ds_map_add(rowdata, ""value_name"", ""diff_enemycd""); - ds_map_add(rowdata, ""on_change"", ""diff_usepreset_custom""); - array_push(formdata, rowdata); - - {(ch_no != 3 ? "" : @" - var rowdata = ds_map_create(); - ds_map_add(rowdata, ""title_en"", ""Gmbrd Enemy CDs""); - ds_map_add(rowdata, ""value_range_en"", ""INHERIT=-1;0~200%""); - ds_map_add(rowdata, ""value_name"", ""diff_gmbrdenemycd""); - ds_map_add(rowdata, ""on_change"", ""diff_usepreset_custom""); - array_push(formdata, rowdata); - ")} + global.diff_usepreset_custom = function() + {{ + global.diff_preset = ""Custom""; + global.diff_usepreset(); + }} - var rowdata = ds_map_create(); - ds_map_add(rowdata, ""title_en"", ""Extra Enemies""); - ds_map_add(rowdata, ""value_range_en"", ""NONE=0;+1=1;+2=2""); - ds_map_add(rowdata, ""value_name"", ""diff_extraenemies""); - ds_map_add(rowdata, ""on_change"", ""diff_usepreset_custom""); - array_push(formdata, rowdata); - - var rowdata = ds_map_create(); - ds_map_add(rowdata, ""title_en"", ""Battle Rewards""); - ds_map_add(rowdata, ""value_range_en"", ""0~1000%""); - ds_map_add(rowdata, ""value_name"", ""diff_battlerewards""); - ds_map_add(rowdata, ""on_change"", ""diff_usepreset_custom""); - array_push(formdata, rowdata); - - {((hide_rewardrank || ch_no != 3) ? "" : @" - var rowdata = ds_map_create(); - ds_map_add(rowdata, ""title_en"", ""Reward Ranking""); - ds_map_add(rowdata, ""value_range_en"", ""OFF=false;ON=true""); - ds_map_add(rowdata, ""value_name"", ""diff_rewardranking""); - ds_map_add(rowdata, ""on_change"", ""diff_usepreset_custom""); - array_push(formdata, rowdata); - ")} + global.diff_usepreset_default = function() + {{ + global.diff_preset = ""{preset_default}""; + global.diff_usepreset(); + }} - var rowdata = ds_map_create(); - ds_map_add(rowdata, ""title_en"", ""DOWN""); - array_push(formdata, rowdata); - - var rowdata = ds_map_create(); - ds_map_add(rowdata, ""title_en"", ""Down Deficit""); - ds_map_add(rowdata, ""value_range_en"", ""0~1000%;[-999]=2147483647""); - ds_map_add(rowdata, ""value_name"", ""diff_downdeficit""); - ds_map_add(rowdata, ""on_change"", ""diff_usepreset_custom""); - array_push(formdata, rowdata); - - var rowdata = ds_map_create(); - ds_map_add(rowdata, ""title_en"", ""Downed Regen""); - ds_map_add(rowdata, ""value_range_en"", ""0~1000%;INSTANT=2147483647""); - ds_map_add(rowdata, ""value_name"", ""diff_downedregen""); - ds_map_add(rowdata, ""on_change"", ""diff_usepreset_custom""); - array_push(formdata, rowdata); - - var rowdata = ds_map_create(); - ds_map_add(rowdata, ""title_en"", ""Victory Res""); - ds_map_add(rowdata, ""value_range_en"", ""OFF=-1;0~100%""); - ds_map_add(rowdata, ""value_name"", ""diff_victoryres""); - ds_map_add(rowdata, ""on_change"", ""diff_usepreset_custom""); - array_push(formdata, rowdata); - - var rowdata = ds_map_create(); - ds_map_add(rowdata, ""title_en"", ""PLAYER""); - array_push(formdata, rowdata); - - var rowdata = ds_map_create(); - ds_map_add(rowdata, ""title_en"", ""Damage""); - ds_map_add(rowdata, ""value_range_en"", ""0~1000%;INF=2147483647""); - ds_map_add(rowdata, ""value_name"", ""diff_plrdmg""); - ds_map_add(rowdata, ""on_change"", ""diff_usepreset_custom""); - array_push(formdata, rowdata); - - {(ch_no != 3 ? "" : @" - var rowdata = ds_map_create(); - ds_map_add(rowdata, ""title_en"", ""Gmbrd Damage""); - ds_map_add(rowdata, ""value_range_en"", ""INHERIT=-1;0-1000%;INF=2147483647""); - ds_map_add(rowdata, ""value_name"", ""diff_gmbrdplrdmg""); - ds_map_add(rowdata, ""on_change"", ""diff_usepreset_custom""); - array_push(formdata, rowdata); - ")} + global.diff_usepreset_default(); + + // Provide support for mod devs to add compatibility + global.diff_apply = function(arg0, arg1, arg2) {{ + switch (arg0) {{ + case ""DIFFOP_DAMAGE"": + return ceil(global.diff_damagemulti * arg1); + case ""DIFFOP_DAMAGE_GB"": + return (global.diff_gameboarddmgx < 0 ? global.diff_damagemulti : global.diff_gameboarddmgx) * arg1; + case ""DIFFOP_HITALL"": + return global.diff_hitall || arg1; + case ""DIFFOP_IFRAMES"": + return ceil(global.diff_iframes * arg1); + case ""DIFFOP_ENEMYCD"": + return round(global.diff_enemycd * arg1); + case ""DIFFOP_ENEMYCD_GB"": + return ceil((global.diff_gmbrdenemycd < 0 ? global.diff_enemycd : global.diff_gmbrdenemycd) * arg1); + case ""DIFFOP_TPGAIN"": + return ceil(global.diff_tpgain * arg1); + case ""DIFFOP_EXTRAENEMIES"": + return global.diff_extraenemies; + case ""DIFFOP_REWARDS"": + return ceil(global.diff_battlerewards * arg1); + case ""DIFFOP_REWARDRANK_GB"": + return global.diff_rewardranking || arg1; + case ""DIFFOP_DOWNDEF"": + return max(-999, floor(global.diff_downdeficit * arg1)); + case ""DIFFOP_DOWNREGEN"": + return ceil(global.diff_downedregen * arg1); + case ""DIFFOP_VICRES"": + return ceil(global.diff_victoryres >= 0 ? max(1, arg1 * global.diff_victoryres) : arg2); + case ""DIFFOP_PLRDMG"": + return ceil(global.diff_plrdmg * arg1); + case ""DIFFOP_PLRDMG_GB"": + return ceil(global.diff_gmbrdplrdmg * arg1); + case ""DIFFOP_PLRHEAL"": + return ceil(global.diff_plrheal * arg1); + case ""DIFFOP_PLRHEAL_GB"": + return ceil(global.diff_gmbrdplrheal * arg1); + case ""DIFFOP_MERCY"": + return ceil(global.diff_mercy * arg1); + case ""DIFFOP_SAVEHEAL"": + return global.diff_saveheal || arg1; + }} + }} - var rowdata = ds_map_create(); - ds_map_add(rowdata, ""title_en"", ""Healing""); - ds_map_add(rowdata, ""value_range_en"", ""0~1000%;INF=2147483647""); - ds_map_add(rowdata, ""value_name"", ""diff_plrheal""); - ds_map_add(rowdata, ""on_change"", ""diff_usepreset_custom""); - array_push(formdata, rowdata); - - {(ch_no != 3 ? "" : @" - var rowdata = ds_map_create(); - ds_map_add(rowdata, ""title_en"", ""Gmbrd Healing""); - ds_map_add(rowdata, ""value_range_en"", ""INHERIT=-1;0-1000%;INF=2147483647""); - ds_map_add(rowdata, ""value_name"", ""diff_gmbrdplrheal""); - ds_map_add(rowdata, ""on_change"", ""diff_usepreset_custom""); - array_push(formdata, rowdata); - ")} + if (variable_instance_exists(id, ""modmenu"")) {{ + var newuserpresetnames = ds_map_keys_to_array(global.diff_userpresets); + newuserpresetnames = global.diff_array_sort(newuserpresetnames, true); + var userpresetvaluerange = """"; + for (var i = 0; i < array_length(newuserpresetnames); i++) {{ + userpresetvaluerange += "";"" + newuserpresetnames[i] + ""="" + newuserpresetnames[i] + ""`""; + }} - var rowdata = ds_map_create(); - ds_map_add(rowdata, ""title_en"", ""TP Gain""); - ds_map_add(rowdata, ""value_range_en"", ""0~1000%;INF=2147483647""); - ds_map_add(rowdata, ""value_name"", ""diff_tpgain""); - ds_map_add(rowdata, ""on_change"", ""diff_usepreset_custom""); - array_push(formdata, rowdata); - - var rowdata = ds_map_create(); - ds_map_add(rowdata, ""title_en"", ""Mercy""); - ds_map_add(rowdata, ""value_range_en"", ""0~1000%;INF=2147483647""); - ds_map_add(rowdata, ""value_name"", ""diff_mercy""); - ds_map_add(rowdata, ""on_change"", ""diff_usepreset_custom""); - array_push(formdata, rowdata); - - var rowdata = ds_map_create(); - ds_map_add(rowdata, ""title_en"", ""SAVE Point Heal""); - ds_map_add(rowdata, ""value_range_en"", ""OFF=false;ON=true""); - ds_map_add(rowdata, ""value_name"", ""diff_saveheal""); - ds_map_add(rowdata, ""on_change"", ""diff_usepreset_custom""); - array_push(formdata, rowdata); - - var rowdata = ds_map_create(); - ds_map_add(rowdata, ""title_en"", """"); - array_push(formdata, rowdata); - - var rowdata = ds_map_create(); - ds_map_add(rowdata, ""title_en"", ""Save as preset""); - var createuserpresetsvaluerange = """"; - var hasaddednew = false; - for (var i = 1; i < 10; i++) {{ - var thispresetname = ""USER "" + string(i); - if (global.diff_array_contains(newuserpresetnames, thispresetname)) {{ - if (i != 1) - createuserpresetsvaluerange += "";""; - createuserpresetsvaluerange += thispresetname + ""="" + thispresetname + ""`""; - }} else if (!hasaddednew) {{ - if (i != 1) + var createuserpresetsvaluerange = """"; + var hasaddednew = false; + for (var i = 1; i < 10; i++) {{ + var thispresetname = ""USER "" + string(i); + if (global.diff_array_contains(newuserpresetnames, thispresetname)) {{ + if (i != 1) + createuserpresetsvaluerange += "";""; + createuserpresetsvaluerange += thispresetname + ""="" + thispresetname + ""`""; + }} else if (!hasaddednew) {{ + if (i != 1) + createuserpresetsvaluerange += "";""; + createuserpresetsvaluerange += thispresetname + ""="" + thispresetname + ""`""; + hasaddednew = true; + }} + }} + var possibleuserpresetnames = [""USER 1"", ""USER 2"", ""USER 3"", ""USER 4"", ""USER 5"", ""USER 6"", ""USER 7"", ""USER 8"", ""USER 9""]; + for (var i = 0; i < array_length(newuserpresetnames); i++) {{ + if (!global.diff_array_contains(possibleuserpresetnames, newuserpresetnames[i])) {{ createuserpresetsvaluerange += "";""; - createuserpresetsvaluerange += thispresetname + ""="" + thispresetname + ""`""; - hasaddednew = true; + createuserpresetsvaluerange += newuserpresetnames[i] + ""="" + newuserpresetnames[i] + ""`""; + }} }} - }} - var possibleuserpresetnames = [""USER 1"", ""USER 2"", ""USER 3"", ""USER 4"", ""USER 5"", ""USER 6"", ""USER 7"", ""USER 8"", ""USER 9""]; - for (var i = 0; i < array_length(newuserpresetnames); i++) {{ - if (!global.diff_array_contains(possibleuserpresetnames, newuserpresetnames[i])) {{ - createuserpresetsvaluerange += "";""; - createuserpresetsvaluerange += newuserpresetnames[i] + ""="" + newuserpresetnames[i] + ""`""; + + global.diff_deleteuserpresetname = """"; + var deleteuserpresetsvaluerange = """"; + for (var i = 0; i < array_length(newuserpresetnames); i++) {{ + if (i != 0) + deleteuserpresetsvaluerange += "";""; + else + global.diff_deleteuserpresetname = newuserpresetnames[i]; + deleteuserpresetsvaluerange += newuserpresetnames[i] + ""="" + newuserpresetnames[i] + ""`""; }} + + global.diff_menu = modmenu.create({{ + title: ""Difficulty"", + left_margin: 0, + left_value_pos: 240, + apply: {{type: ""OnClose"", func: function () {{ + // Determine preset + {string.Join(" else ", presets.Select(pair => @$" + if (global.diff_damagemulti == {pair.Value.damagemulti.ToString("F10", CultureInfo.InvariantCulture)} + && global.diff_gameboarddmgx == {pair.Value.gameboarddmgx.ToString("F10", CultureInfo.InvariantCulture)} + && global.diff_hitall == {pair.Value.hitall.ToString().ToLower()} + && global.diff_iframes == {pair.Value.iframes.ToString("F10", CultureInfo.InvariantCulture)} + && global.diff_enemycd == {pair.Value.enemycd.ToString("F10", CultureInfo.InvariantCulture)} + && global.diff_gmbrdenemycd == {pair.Value.gmbrdenemycd.ToString("F10", CultureInfo.InvariantCulture)} + && global.diff_tpgain == {pair.Value.tpgain.ToString("F10", CultureInfo.InvariantCulture)} + && global.diff_extraenemies == {pair.Value.extraenemies.ToString()} + && global.diff_battlerewards == {pair.Value.battlerewards.ToString("F10", CultureInfo.InvariantCulture)} + && global.diff_rewardranking == {pair.Value.rewardranking.ToString().ToLower()} + && global.diff_downdeficit == {pair.Value.downdeficit.ToString("F10", CultureInfo.InvariantCulture)} + && global.diff_downedregen == {pair.Value.downedregen.ToString("F10", CultureInfo.InvariantCulture)} + && global.diff_victoryres == {pair.Value.victoryres.ToString("F10", CultureInfo.InvariantCulture)} + && global.diff_plrdmg == {pair.Value.plrdmg.ToString("F10", CultureInfo.InvariantCulture)} + && global.diff_gmbrdplrdmg == {pair.Value.gmbrdplrdmg.ToString("F10", CultureInfo.InvariantCulture)} + && global.diff_plrheal == {pair.Value.plrheal.ToString("F10", CultureInfo.InvariantCulture)} + && global.diff_gmbrdplrheal == {pair.Value.gmbrdplrheal.ToString("F10", CultureInfo.InvariantCulture)} + && global.diff_mercy == {pair.Value.mercy.ToString("F10", CultureInfo.InvariantCulture)} + && global.diff_saveheal == {pair.Value.saveheal.ToString().ToLower()}) {{ + global.diff_preset = ""{pair.Key}""; + }} + "))} + else {{ + var userpresetnames = ds_map_keys_to_array(global.diff_userpresets); + var foundPreset = false; + for (var i = 0; i < array_length(userpresetnames); i++) {{ + var presetdata = ds_map_find_value(global.diff_userpresets, userpresetnames[i]); + if (global.diff_damagemulti == ds_map_find_value(presetdata, ""damagemulti"") + && global.diff_gameboarddmgx == ds_map_find_value(presetdata, ""gameboarddmgx"") + && global.diff_hitall == ds_map_find_value(presetdata, ""hitall"") + && global.diff_iframes == ds_map_find_value(presetdata, ""iframes"") + && global.diff_enemycd == ds_map_find_value(presetdata, ""enemycd"") + && global.diff_gmbrdenemycd == ds_map_find_value(presetdata, ""gmbrdenemycd"") + && global.diff_tpgain == ds_map_find_value(presetdata, ""tpgain"") + && global.diff_extraenemies == ds_map_find_value(presetdata, ""extraenemies"") + && global.diff_battlerewards == ds_map_find_value(presetdata, ""battlerewards"") + && global.diff_rewardranking == ds_map_find_value(presetdata, ""rewardranking"") + && global.diff_downdeficit == ds_map_find_value(presetdata, ""downdeficit"") + && global.diff_downedregen == ds_map_find_value(presetdata, ""downedregen"") + && global.diff_victoryres == ds_map_find_value(presetdata, ""victoryres"") + && global.diff_plrdmg == ds_map_find_value(presetdata, ""plrdmg"") + && global.diff_gmbrdplrdmg == ds_map_find_value(presetdata, ""gmbrdplrdmg"") + && global.diff_plrheal == ds_map_find_value(presetdata, ""plrheal"") + && global.diff_gmbrdplrheal == ds_map_find_value(presetdata, ""gmbrdplrheal"") + && global.diff_mercy == ds_map_find_value(presetdata, ""mercy"") + && global.diff_saveheal == ds_map_find_value(presetdata, ""saveheal"")) {{ + global.diff_preset = userpresetnames[i]; + foundPreset = true; + break; + }} + }} + if (!foundPreset) + global.diff_preset = ""Custom""; + }} + }}}}, + save: {{type: ""PerFile"", name: ""difficulty.ini""}}, + form: [{{ + type: ""Slider"", + title: ""Preset"", + data_ref: {{var: ""diff_preset"", default: ""Normal""}}, + value_range: ""{string.Join(";", presets.Select(pair => @$"{pair.Key.ToUpper()}={pair.Key}`"))};CUSTOM=Custom`"" + userpresetvaluerange, + no_save: true, + change_func: global.diff_usepreset, + ref: {{var: ""diff_menupresetrow""}} + }}, {{ + type: ""Header"", + title: ""BATTLE"" + }}, {{ + type: ""Slider"", + title: ""Damage Multi"", + data_ref: {{var: ""diff_damagemulti"", default: {presets[preset_default].damagemulti.ToString("F10", CultureInfo.InvariantCulture)}, ini_key: ""DAMAGE_MULTI""}}, + value_range: ""0~1000%;INF=2147483647"", + change_func: global.diff_usepreset_custom + }}, {{ + type: ""Slider"", + title: ""Gameboard Dmg X"", + data_ref: {{var: ""diff_gameboarddmgx"", default: {presets[preset_default].gameboarddmgx.ToString("F10", CultureInfo.InvariantCulture)}, ini_key: ""GAMEBOARD_DMG_X""}}, + value_range: ""INHERIT=-1;0-1000%;INF=2147483647"", + change_func: global.diff_usepreset_custom, + hidden: {(ch_no == 3 ? "false" : "true")} + }}, {{ + type: ""Toggle"", + title: ""Hit.All"", + data_ref: {{var: ""diff_hitall"", default: {presets[preset_default].hitall.ToString().ToLower()}, ini_key: ""HIT_ALL""}}, + value_range: ""OFF=false;ON=true"", + change_func: global.diff_usepreset_custom + }}, {{ + type: ""Slider"", + title: ""I-Frames"", + data_ref: {{var: ""diff_iframes"", default: {presets[preset_default].iframes.ToString("F10", CultureInfo.InvariantCulture)}, ini_key: ""I_FRAMES""}}, + value_range: ""0~1000%"", + change_func: global.diff_usepreset_custom + }}, {{ + type: ""Slider"", + title: ""Enemy Cooldowns"", + data_ref: {{var: ""diff_enemycd"", default: {presets[preset_default].enemycd.ToString("F10", CultureInfo.InvariantCulture)}, ini_key: ""ENEMY_COOLDOWNS""}}, + value_range: ""0~200%"", + change_func: global.diff_usepreset_custom + }}, {{ + type: ""Slider"", + title: ""Gmbrd Enemy CDs"", + data_ref: {{var: ""diff_gmbrdenemycd"", default: {presets[preset_default].gmbrdenemycd.ToString("F10", CultureInfo.InvariantCulture)}, ini_key: ""GMBRD_ENEMY_CDS""}}, + value_range: ""INHERIT=-1;0~200%"", + change_func: global.diff_usepreset_custom, + hidden: {(ch_no == 3 ? "false" : "true")} + }}, {{ + type: ""Toggle"", + title: ""Extra Enemies"", + data_ref: {{var: ""diff_extraenemies"", default: {presets[preset_default].extraenemies.ToString()}, ini_key: ""EXTRA_ENEMIES""}}, + value_range: ""NONE=0;+1=1;+2=2"", + change_func: global.diff_usepreset_custom + }}, {{ + type: ""Slider"", + title: ""Battle Rewards"", + data_ref: {{var: ""diff_battlerewards"", default: {presets[preset_default].battlerewards.ToString("F10", CultureInfo.InvariantCulture)}, ini_key: ""BATTLE_REWARDS""}}, + value_range: ""0~1000%"", + change_func: global.diff_usepreset_custom + }}, {{ + type: ""Toggle"", + title: ""Reward Ranking"", + data_ref: {{var: ""diff_rewardranking"", default: {presets[preset_default].rewardranking.ToString().ToLower()}, ini_key: ""REWARD_RANKING""}}, + value_range: ""OFF=false;ON=true"", + change_func: global.diff_usepreset_custom, + hidden: {(!hide_rewardrank && ch_no == 3 ? "false" : "true")} + }}, {{ + type: ""Header"", + title: ""DOWN"" + }}, {{ + type: ""Slider"", + title: ""Down Deficit"", + data_ref: {{var: ""diff_downdeficit"", default: {presets[preset_default].downdeficit.ToString("F10", CultureInfo.InvariantCulture)}, ini_key: ""DOWN_DEFICIT""}}, + value_range: ""0~1000%;[-999]=2147483647"", + change_func: global.diff_usepreset_custom + }}, {{ + type: ""Slider"", + title: ""Downed Regen"", + data_ref: {{var: ""diff_downedregen"", default: {presets[preset_default].downedregen.ToString("F10", CultureInfo.InvariantCulture)}, ini_key: ""DOWNED_REGEN""}}, + value_range: ""0~1000%;INSTANT=2147483647"", + change_func: global.diff_usepreset_custom + }}, {{ + type: ""Slider"", + title: ""Victory Res"", + data_ref: {{var: ""diff_victoryres"", default: {presets[preset_default].victoryres.ToString("F10", CultureInfo.InvariantCulture)}, ini_key: ""VICTORY_RES""}}, + value_range: ""OFF=-1;0~100%"", + change_func: global.diff_usepreset_custom + }}, {{ + type: ""Header"", + title: ""PLAYER"" + }}, {{ + type: ""Slider"", + title: ""Damage"", + data_ref: {{var: ""diff_plrdmg"", default: {presets[preset_default].plrdmg.ToString("F10", CultureInfo.InvariantCulture)}, ini_key: ""PLR_DMG""}}, + value_range: ""0~1000%;INF=2147483647"", + change_func: global.diff_usepreset_custom + }}, {{ + type: ""Slider"", + title: ""Gmbrd Damage"", + data_ref: {{var: ""diff_gmbrdplrdmg"", default: {presets[preset_default].gmbrdplrdmg.ToString("F10", CultureInfo.InvariantCulture)}, ini_key: ""GMBRD_PLR_DMG""}}, + value_range: ""INHERIT=-1;0-1000%;INF=2147483647"", + change_func: global.diff_usepreset_custom, + hidden: {(ch_no == 3 ? "false" : "true")} + }}, {{ + type: ""Slider"", + title: ""Healing"", + data_ref: {{var: ""diff_plrheal"", default: {presets[preset_default].plrheal.ToString("F10", CultureInfo.InvariantCulture)}, ini_key: ""PLR_HEAL""}}, + value_range: ""0~1000%;INF=2147483647"", + change_func: global.diff_usepreset_custom + }}, {{ + type: ""Slider"", + title: ""Gmbrd Healing"", + data_ref: {{var: ""diff_gmbrdplrheal"", default: {presets[preset_default].gmbrdplrheal.ToString("F10", CultureInfo.InvariantCulture)}, ini_key: ""GMBRD_PLR_HEAL""}}, + value_range: ""INHERIT=-1;0-1000%;INF=2147483647"", + change_func: global.diff_usepreset_custom, + hidden: {(ch_no == 3 ? "false" : "true")} + }}, {{ + type: ""Slider"", + title: ""TP Gain"", + data_ref: {{var: ""diff_tpgain"", default: {presets[preset_default].tpgain.ToString("F10", CultureInfo.InvariantCulture)}, ini_key: ""TP_GAIN""}}, + value_range: ""0~1000%;INF=2147483647"", + change_func: global.diff_usepreset_custom + }}, {{ + type: ""Slider"", + title: ""Mercy"", + data_ref: {{var: ""diff_mercy"", default: {presets[preset_default].mercy.ToString("F10", CultureInfo.InvariantCulture)}, ini_key: ""MERCY""}}, + value_range: ""0~1000%;INF=2147483647"", + change_func: global.diff_usepreset_custom + }}, {{ + type: ""Toggle"", + title: ""SAVE Point Heal"", + data_ref: {{var: ""diff_saveheal"", default: {presets[preset_default].saveheal.ToString().ToLower()}, ini_key: ""SAVE_POINT_HEAL""}}, + value_range: ""OFF=false;ON=true"", + change_func: global.diff_usepreset_custom + }}, {{ + type: ""Header"" + }}, {{ + type: ""Slider"", + title: ""Save as preset"", + data_ref: {{var: ""diff_saveuserpresetname"", default: ""USER 1""}}, + value_range: createuserpresetsvaluerange, + no_save: true, + revert_on_cancel: true, + accept_func: global.diff_saveuserpreset, + ref: {{var: ""diff_menucreateuserpresetrow""}} + }}, {{ + type: ""Slider"", + title: ""Delete a preset"", + data_ref: {{var: ""diff_deleteuserpresetname"", default: """"}}, + value_range: deleteuserpresetsvaluerange, + no_save: true, + revert_on_cancel: true, + accept_func: global.diff_deleteuserpreset, + disabled: function() {{ return is_undefined(global.diff_menudeleteuserpresetrow) || (global.diff_menudeleteuserpresetrow.value_range == """"); }}, + ref: {{var: ""diff_menudeleteuserpresetrow""}} + }}, {{ + type: ""Button"", + title: ""Reset to Defaults"", + trigger_func: global.diff_usepreset_default, + }}] + }}); }} - ds_map_add(rowdata, ""value_range_en"", createuserpresetsvaluerange); - ds_map_add(rowdata, ""value_name"", ""diff_saveuserpresetname""); - ds_map_add(rowdata, ""func_name"", ""diff_saveuserpreset""); - ds_map_add(rowdata, ""force_scroll"", true); - array_push(formdata, rowdata); - global.diff_menucreateuserpresetrow = rowdata; - - var rowdata = ds_map_create(); - ds_map_add(rowdata, ""title_en"", ""Delete a preset""); - global.diff_deleteuserpresetname = """"; - var deleteuserpresetsvaluerange = """"; - for (var i = 0; i < array_length(newuserpresetnames); i++) {{ - if (i != 0) - deleteuserpresetsvaluerange += "";""; - else - global.diff_deleteuserpresetname = newuserpresetnames[i]; - deleteuserpresetsvaluerange += newuserpresetnames[i] + ""="" + newuserpresetnames[i] + ""`""; - }} - ds_map_add(rowdata, ""value_range_en"", deleteuserpresetsvaluerange); - ds_map_add(rowdata, ""disabled"", deleteuserpresetsvaluerange == """"); - ds_map_add(rowdata, ""value_name"", ""diff_deleteuserpresetname""); - ds_map_add(rowdata, ""func_name"", ""diff_deleteuserpreset""); - ds_map_add(rowdata, ""force_scroll"", true); - array_push(formdata, rowdata); - global.diff_menudeleteuserpresetrow = rowdata; - - var rowdata = ds_map_create(); - ds_map_add(rowdata, ""title_en"", ""Reset to Defaults""); - ds_map_add(rowdata, ""func_name"", ""diff_usepreset_default""); - array_push(formdata, rowdata); - - ds_map_add(menudata, ""form"", formdata); - - array_push(global.modmenu_data, menudata); + + global.chapter = "); } diff --git a/src/modmenu.csx b/src/modmenu.csx index 6f9374c..14f903b 100644 --- a/src/modmenu.csx +++ b/src/modmenu.csx @@ -136,123 +136,665 @@ UndertaleModLib.Compiler.CodeImportGroup importGroup = new(Data){ ThrowOnNoOpFindReplace = true }; -// The demo is on an old version of game maker that doesn't have the string_split, string_ends_with, or string_trim functions so add (very) basic implementations +// Script lists +string[] gamestarts = {"gml_GlobalScript_scr_gamestart"}; +if (ch_no == 0) +{ + string[] demoGamestarts = {"gml_GlobalScript_scr_gamestart_ch1"}; + gamestarts = gamestarts.Concat(demoGamestarts).ToArray(); +} string[] darkcons = {"gml_Object_obj_darkcontroller"}; if (ch_no == 0) { string[] demoDarkcons = {"gml_Object_obj_darkcontroller_ch1"}; darkcons = darkcons.Concat(demoDarkcons).ToArray(); } + if (ch_no == 0) { - foreach (string darkcon in darkcons) - { - // WARNING: only works for delimiters 1 char long - // WARNING: does not have optional args from GM's impl - string string_split = @" - function string_split(arg0, arg1) + // WARNING: only works for delimiters 1 char long + // WARNING: does not have optional args from GM's impl + string string_split = @" + function string_split(arg0, arg1) + { + length = string_length(arg0); + var result = array_create(0); + array_push(result, """"); + + // string_char_at index starts at 1 for some reason + for (i = 1; i <= length; i++) { - length = string_length(arg0); - var result = array_create(0); - array_push(result, """"); + thischar = string_char_at(arg0, i); - // string_char_at index starts at 1 for some reason - for (i = 1; i <= length; i++) + if (thischar != arg1) { + result[array_length(result) - 1] = result[array_length(result) - 1] + thischar; + } + else { - thischar = string_char_at(arg0, i); - - if (thischar != arg1) { - result[array_length(result) - 1] = result[array_length(result) - 1] + thischar; - } - else - { - array_push(result, """"); - } + array_push(result, """"); } - - return result; } - "; + return result; + } + + "; + foreach (string darkcon in darkcons) + { importGroup.QueuePrepend(darkcon + "_Step_0", string_split); importGroup.QueuePrepend(darkcon + "_Draw_0", string_split); + } + foreach (string gamestart in gamestarts) + { + importGroup.QueuePrepend(gamestart, string_split); + } - // WARNING: only works for substr 1 char long - string string_ends_with = @" - function string_ends_with(arg0, arg1) - { - length = string_length(arg0); - // string_char_at index starts at 1 for some reason - lastchar = string_char_at(arg0, length); + // WARNING: only works for substr 1 char long + string string_ends_with = @" + function string_ends_with(arg0, arg1) + { + length = string_length(arg0); + // string_char_at index starts at 1 for some reason + lastchar = string_char_at(arg0, length); - return (lastchar == arg1); - } + return (lastchar == arg1); + } - "; + "; + foreach (string darkcon in darkcons) + { importGroup.QueuePrepend(darkcon + "_Step_0", string_ends_with); importGroup.QueuePrepend(darkcon + "_Draw_0", string_ends_with); + } + foreach (string gamestart in gamestarts) + { + importGroup.QueuePrepend(gamestart, string_ends_with); + } - // WARNING: only trims spaces, not other types of whitespace - // WARNING: only trims whitespace from the start of the string - string string_trim = @" - function string_trim(arg0) + // WARNING: only trims spaces, not other types of whitespace + // WARNING: only trims whitespace from the start of the string + string string_trim = @" + function string_trim(arg0) + { + length = string_length(arg0); + result = """"; + var foundNonWS = false; + + // string_char_at index starts at 1 for some reason + for (i = 1; i <= length; i++) { - length = string_length(arg0); - result = """"; - var foundNonWS = false; - - // string_char_at index starts at 1 for some reason - for (i = 1; i <= length; i++) - { - thischar = string_char_at(arg0, i); - - if (thischar != "" "") { - foundNonWS = true; - } + thischar = string_char_at(arg0, i); - if (foundNonWS) { - result += thischar; - } + if (thischar != "" "") { + foundNonWS = true; } - return result; + if (foundNonWS) { + result += thischar; + } } - "; + return result; + } + + "; + foreach (string darkcon in darkcons) + { importGroup.QueuePrepend(darkcon + "_Step_0", string_trim); importGroup.QueuePrepend(darkcon + "_Draw_0", string_trim); } + foreach (string gamestart in gamestarts) + { + importGroup.QueuePrepend(gamestart, string_trim); + } } -// Add menu create code -foreach (string darkcon in darkcons) +// Add modmenu gamestart code +foreach (string gamestart in gamestarts) { - importGroup.QueueAppend(darkcon + "_Create_0", @" + importGroup.QueueRegexFindReplace(gamestart, "function scr_gamestart(?:_ch1)?\\(\\)\\s*{", @$" + function scr_gamestart{(gamestart.EndsWith("_ch1") ? "_ch1" : "")}(){{ var installed_modmenu = true; - global.modmenuno = 0; - global.modsubmenuno = -1; - global.modsubmenuselected = false; - global.modsubmenuscroll = 0; - global.modmenu_data = array_create(0); - surf_modtitles = -1; - - // Apply acceleration to the scrollers so that they're not too fidly but not too slow - modscroller_step = 1; // reset to 1 as first interaction should be instantaneous - modscroller_speed_min = 0; - modscroller_speed_max = 3; - modscroller_speed = modscroller_speed_min; - modscroller_accel = 1 / 20; - - // some translation mods replace the english translation rather than using DR's built in localisation support, so can't always rely on global.lang and have to override for certain mods - global.modmenu_langoverride = """"; + modmenu = {{ + menu_no: 0, + row_no: -1, + row_selected: false, + row_scroll: 0, + menus: [], // array_create(0), + menus_light: [], // array_create(0), + menus_dark: [], // array_create(0), + menu_count: 0, + menu_light_count: 0, + menu_dark_count: 0, + world_menus: function () {{ + if (!global.darkzone) + return menus_light; + else + return menus_dark; + }}, + world_menu_count: function () {{ + if (!global.darkzone) + return menu_light_count; + else + return menu_dark_count; + }}, + active_menu: function () {{ + var arr = world_menus(); + return arr[menu_no]; + }}, + + surf_titles: -1, + get_surf_titles: function () {{ + if (!surface_exists(surf_titles)) + {{ + surf_titles = surface_create(410, 35); + }} + return surf_titles; + }}, + + // Apply acceleration to the scrollers so that they're not too fidly but not too slow + slider_step: 1, // reset to 1 as first interaction should be instantaneous + slider_speed_min: 0, + slider_speed_max: 3, + slider_speed: 0, + slider_accel: 1 / 20, + + // some translation mods replace the english translation rather than using DR's built in localisation support, so can't always rely on global.lang and have to override for certain mods + lang_override: """", + get_lang: function() {{ return (lang_override != """" ? lang_override : global.lang) }}, + find_loc: function(arg0, arg1) {{ + if (!is_array(arg0)) + return arg0; + var lang = is_undefined(arg1) ? get_lang() : arg1; + var first = """"; + for (var i = 0; i < array_length(arg0); i++) {{ + if (arg0[i].lang == lang) + return arg0[i].val; + if (i == 0) + first = arg0[i].val; + }} + return first; + }}, + + // save/load + string_savename: function(arg0) + {{ + var result = string_lower(arg0); + if (string_ends_with(result, "".ini"")) + result = string_delete(result, 0, -4); + result = string_lettersdigits(arg0); + return result + "".ini""; + }}, + string_savename_addini: function(arg0) + {{ + if (arg0 != string_lower(arg0)) + return arg0; + if (string_ends_with(arg0, "".ini"")) + return arg0; + if (arg0 != string_lettersdigits(arg0)) + return arg0; + return arg0 + "".ini""; + }}, + is_savenamestring: function(arg0) + {{ + if (arg0 != string_lower(arg0)) + return false; + if (!string_ends_with(arg0, "".ini"")) + return false; + if (string_delete(arg0, 0, -4) != string_lettersdigits(string_delete(arg0, 0, -4))) + return false; + return true; + }}, + load: function(arg0, arg1) {{ + for (var i = 0; i < menu_count; i++) {{ + menus[i].load(arg0, arg1); + }} + }}, + save: function(arg0) {{ + for (var i = 0; i < menu_count; i++) {{ + menus[i].save(arg0); + }} + }}, + copy: function(arg0, arg1) {{ + for (var i = 0; i < menu_count; i++) {{ + menus[i].copy(arg0, arg1); + }} + }}, + del: function(arg0) {{ + for (var i = 0; i < menu_count; i++) {{ + menus[i].del(arg0); + }} + }}, + + create: function (arg0) {{ + var menu = arg0; + // Menu - mandatory + try {{ var check = menu; if (is_undefined(check)) throw ""menu data is undefined""; }} catch (_e) {{ throw ""MODMENU VALIDATION ERROR: Tried to create a menu, but menu data was not supplied.""; }} + if (!is_struct(menu)) throw ""MODMENU VALIDATION ERROR: Tried to create a menu, but menu data is not a struct. ""; + try {{ var check = menu.title; if (!is_string(check)) check = check[0]; if (!is_string(check)) throw ""title[0] is not a string""; }} catch (_e) {{ throw ""MODMENU VALIDATION ERROR: Tried to create a menu without a title; or title is not a string.""; }} + try {{ var check = menu.form[0]; }} catch (_e) {{ throw ""MODMENU VALIDATION ERROR: Tried to create a menu without any form element.""; }} + + // Menu - optional + try {{ var check = menu.left_margin; if (!is_numeric(check)) check = check[0]; }} catch (_e) {{ menu.left_margin = 40; }} + try {{ var check = menu.left_margin; if (!is_numeric(check)) check = check[0]; if (!is_numeric(check)) throw ""left_margin is not numeric""; }} catch (_e) {{ throw ""MODMENU VALIDATION ERROR: Tried to create a menu, but left_margin is not numeric.""; }} + try {{ var check = menu.left_value_pos; if (!is_numeric(check)) check = check[0]; }} catch (_e) {{ menu.left_value_pos = 300; }} + try {{ var check = menu.left_value_pos; if (!is_numeric(check)) check = check[0]; if (!is_numeric(check)) throw ""left_value_pos is not numeric""; }} catch (_e) {{ throw ""MODMENU VALIDATION ERROR: Tried to create a menu, but left_value_pos is not numeric.""; }} + try {{ var check = menu.apply; }} catch (_e) {{ menu.apply = undefined; }} + try {{ var check = menu.apply; if (!is_undefined(check) && ((check.type != ""OnChange"" && check.type != ""OnClose""))) throw ""apply type failed validation""; }} catch (_e) {{ throw ""MODMENU VALIDATION ERROR: Tried to create a menu, but apply.type is not in set: OnChange, OnClose.""; }} + if (!is_undefined(menu.apply)) menu.apply = {{ + type: menu.apply.type, + func: menu.apply.func, + run_onchange: function() {{ if (type == ""OnChange"") func(); }}, + run_onclose: function() {{ if (type == ""OnClose"") func(); }}, + run_onload: function() {{ func(); }} + }}; + try {{ var check = menu.save_file; }} catch (_e) {{ menu.save_file = undefined; }} + try {{ var check = menu.save_file; if (!is_undefined(check) && ((check.type != ""Single"" && check.type != ""PerSlot"" && check.type != ""PerFile""))) throw ""save_file type failed validation""; }} catch (_e) {{ throw (""MODMENU VALIDATION ERROR: Tried to create a menu, but save_file.type is not in set: Single, PerSlot, PerFile.""); }} + // TODO auto generation for save_file.name doesn't seem to work; or it could be the validation that doesn't work + try {{ var check = menu.save_file; if (!is_undefined(check)) check = check.name; }} catch (_e) {{ menu.save_file.name = string_savename(find_loc(menu.title)); }} + {{ var check = menu.save_file; if (!is_undefined(check)) check = check.name; if (is_string(check) && !is_savenamestring(check)) menu.save_file.name = string_savename_addini(menu.save_file.name); }} + try {{ var check = menu.save_file; if (!is_undefined(check)) {{check = check.name; if (!is_string(check) || !is_savenamestring(check)) throw ""save_file name isn't a string or contains invalid characters or no .ini"";}} }} catch (_e) {{ throw (""MODMENU VALIDATION ERROR: Tried to create a menu, but save_file.name is missing; or is not a lower-case alphanumerical string. savefile.name = "" + menu.save_file.name); }} + if (!is_undefined(menu.save_file)) menu.save_file = {{ + type: menu.save_file.type, + name: menu.save_file.name, + category: function(arg0, arg1) {{ + switch (type) {{ + case ""Single"": + return ""SETTINGS""; + case ""PerSlot"": + return ""SLOT"" + string(is_undefined(arg1) ? global.filechoice : arg1); + case ""PerFile"": + return ""CH"" + string(is_undefined(arg0) ? global.chapter : arg0) + ""_"" + string(is_undefined(arg1) ? global.filechoice : arg1); + default: + throw (""Unsupported save_file type: "" + type); + }} + }} + }}; + try {{ var check = menu.world; }} catch (_e) {{ menu.world = ""Dark""; }} + try {{ var check = menu.world; if (!is_string(check) || (check != ""Dark"" && check != ""Light"" && check != ""Both"")) throw ""menu.world not a string in: Dark, Light, Both""; }} catch (_e) {{ throw ""MODMENU VALIDATION ERROR: Tried to create a menu, but world is not in set: Dark, Light, Both.""; }} + try {{ var check = menu.open_func; }} catch (_e) {{ menu.open_func = function () {{}}; }} + try {{ var check = menu.open_func; if (is_undefined(check)) throw ""open_func should not be undefined.""; }} catch (_e) {{ throw ""MODMENU VALIDATION ERROR: Tried to create a menu, but open_func is undefined.""; }} + try {{ var check = menu.close_func; }} catch (_e) {{ menu.close_func = function () {{}}; }} + try {{ var check = menu.close_func; if (is_undefined(check)) throw ""close_func should not be undefined.""; }} catch (_e) {{ throw ""MODMENU VALIDATION ERROR: Tried to create a menu, but close_func is undefined.""; }} + try {{ var check = menu.additional_save_data_refs; }} catch (_e) {{ menu.additional_save_data_refs = []; }} + try {{ var check = menu.additional_save_data_refs; if (!is_array(check)) throw ""additional_save_data_refs should be an array.""; }} catch (_e) {{ throw ""MODMENU VALIDATION ERROR: Tried to create a menu, but additional_save_data_refs is not an array.""; }} + + var init_data_ref = function(arg0) {{ + var data_ref = arg0; + // data ref - mandatory + try {{ var check = data_ref; if (is_undefined(check)) throw ""data ref is undefined""; }} catch (_e) {{ throw ""MODMENU VALIDATION ERROR: Tried to create a menu, but one or more data refs are undefined. ""; }} + if (!is_struct(data_ref)) throw ""MODMENU VALIDATION ERROR: Tried to create a menu, but one or more data refs are not a struct. ""; + try {{ var check = data_ref.var_name; if (!is_string(check)) throw ""data ref var_name should be a string.""; }} catch (_e) {{ throw ""MODMENU VALIDATION ERROR: Tried to create a menu, but data ref var_name is missing; or is not a string.""; }} + try {{ var check = data_ref.default_value; if (!is_string(check) && !is_numeric(check)) throw ""data ref default_value should be a string or numeric.""; }} catch (_e) {{ throw ""MODMENU VALIDATION ERROR: Tried to create a menu, but data ref default_value is missing; or is not a string/numeric.""; }} + // data ref - optional + try {{ var check = data_ref.handle; }} catch (_e) {{ data_ref.handle = global; }} + try {{ var check = data_ref.handle; if (is_undefined(check)) throw ""data ref handle should not be undefined.""; }} catch (_e) {{ throw ""MODMENU VALIDATION ERROR: Tried to create a menu, but data ref handle is not a handle.""; }} + // strip 'global.' from data_ref.var_name + {{ var check = data_ref.var_name; if (data_ref.handle == global && string_starts_with(check, ""global."")) data_ref.var_name = string_delete(data_ref.var_name, 0, 7); }} + try {{ var check = data_ref.ini_key; }} catch (_e) {{ data_ref.ini_key = data_ref.var_name; }} + try {{ var check = data_ref.ini_key; if (!is_string(check)) throw ""data ref ini_key should be a string.""; }} catch (_e) {{ throw ""MODMENU VALIDATION ERROR: Tried to create a menu, but data ref ini_key is not a string.""; }} + // helper methods + return {{ + var_name: data_ref.var_name, + default_value: data_ref.default_value, + handle: data_ref.handle, + ini_key: data_ref.ini_key, + get: function() {{ return variable_instance_exists(handle, var_name) ? variable_instance_get(handle, var_name) : default_value; }}, + set: function(arg0) {{ variable_instance_set(handle, var_name, (!is_undefined(arg0) ? arg0 : default_value)); }}, + read: function(arg0 /* section */) {{ + if (is_string(default_value)) return ini_read_string(arg0, ini_key, default_value); + if (is_numeric(default_value)) return ini_read_real(arg0, ini_key, default_value); + return default_value; + }}, + write: function(arg0 /* section */, arg1 /* value */) {{ + if (is_string(default_value)) ini_write_string(arg0, ini_key, arg1); + if (is_numeric(default_value)) ini_write_real(arg0, ini_key, arg1); + }}, + load: function(arg0 /* section */) {{ set(read(arg0)); }}, + save: function(arg0 /* section */) {{ write(arg0, get()); }}, + copy: function(arg0 /* from section */, arg1 /* to section */) {{ write(arg1, read(arg0)); }} + }}; + }}; + inited_form = []; + for (var i = 0; i < array_length(menu.form); i++) {{ + var row = menu.form[i]; + // Form - mandatory + try {{ var check = row; if (is_undefined(check)) throw ""row data is undefined""; }} catch (_e) {{ throw ""MODMENU VALIDATION ERROR: Tried to create a menu, but one or more form rows are undefined. ""; }} + if (!is_struct(row)) throw ""MODMENU VALIDATION ERROR: Tried to create a menu, but one or more form rows are not a struct. ""; + try {{ var check = row.type; if (!is_string(check) || (check != ""Slider"" && check != ""Toggle"" && check != ""Button"" && check != ""Header"")) throw ""row type should be a string in the set: Slider, Toggle, Button, Header""; }} catch (_e) {{ throw ""MODMENU VALIDATION ERROR: Tried to create a menu, but form row type is not a string in set: Slider, Toggle, Button, Header""; }} + + // Slider/Toggle/Button - mandatory | Header - optional + if (row.type == ""Slider"" || row.type == ""Toggle"" || row.type == ""Button"") {{ + try {{ var check = row.title; if (!is_string(check) && !is_array(check)) throw ""row title must be of type string or array""; if (is_array(check)) check = check[0]; }} catch (_e) {{ throw ""MODMENU VALIDATION ERROR: Tried to create a menu, but form Slider/Toggle/Button does not have a title.""; }} + }} else if (row.type == ""Header"") {{ + try {{ var check = row.title; if (is_array(check)) check = check[0]; }} catch (_e) {{ row.title = """"; }} + }} else throw (""Unsupported row type: "" + row.type); + + // Button - mandatory | Slider/Toggle - optional | Header - invalid + if (row.type == ""Button"") {{ + try {{ var check = row.trigger_func; if (is_undefined(check)) throw ""row trigger_func should not be undefined""; }} catch (_e) {{ throw ""MODMENU VALIDATION ERROR: Tried to create a menu, but Button does not have a trigger_func; or it is undefined.""; }} + }} else if (row.type == ""Slider"" || row.type == ""Toggle"") {{ + try {{ var check = row.trigger_func; }} catch (_e) {{ row.trigger_func = function() {{}}; }} + try {{ var check = row.trigger_func; if (is_undefined(check)) throw ""row trigger_func should not be undefined""; }} catch (_e) {{ throw ""MODMENU VALIDATION ERROR: Tried to create a menu, but Slider/Toggle trigger_func is undefined.""; }} + }} else if (row.type == ""Header"") {{}} else throw (""Unsupported row type: "" + row.type); + + // Slider/Toggle - mandatory | Button/Header - invalid + if (row.type == ""Slider"" || row.type == ""Toggle"") {{ + try {{ var check = row.data_ref; }} catch (_e) {{ throw ""MODMENU VALIDATION ERROR: Tried to create a menu, but form Slider/Toggle does not have a data_ref.""; }} + row.data_ref = init_data_ref(row.data_ref); + try {{ var check = row.value_range; if (!is_string(check) && !is_array(check)) throw ""row value_range must be of type string or array""; if (is_array(check)) check = check[0]; }} catch (_e) {{ throw ""MODMENU VALIDATION ERROR: Tried to create a menu, but form Slider/Toggle does not have a value_range.""; }} + }} else if (row.type == ""Button"" || row.type == ""Header"") {{}} else throw (""Unsupported row type: "" + row.type); + + // Slider/Toggle - optional | Button/Header - invalid + if (row.type == ""Slider"" || row.type == ""Toggle"") {{ + try {{ var check = row.no_save; }} catch (_e) {{ row.no_save = false; }} + try {{ var check = row.change_func; if (is_undefined(check)) throw ""row change_func should not be undefined""; }} catch (_e) {{ row.change_func = function() {{}}; }} + }} else if (row.type == ""Button"" || row.type == ""Header"") {{}} else throw (""Unsupported row type: "" + row.type); + + // Slider - optional | Toggle/Button/Header - invalid + if (row.type == ""Slider"") {{ + try {{ var check = row.revert_on_cancel; if (is_undefined(check)) throw ""row revert_on_cancel should be a bool or a callable""; }} catch (_e) {{ row.revert_on_cancel = false; }} + try {{ var check = row.cancel_func; if (is_undefined(check)) throw ""row cancel_func should not be a undefined""; }} catch (_e) {{ row.cancel_func = function() {{}}; }} + try {{ var check = row.accept_func; if (is_undefined(check)) throw ""row accept_func should not be a undefined""; }} catch (_e) {{ row.accept_func = function() {{}}; }} + }} else if (row.type == ""Toggle"" || row.type == ""Button"" || row.type == ""Header"") {{}} else throw (""Unsupported row type: "" + row.type); + + // Slider/Toggle/Button/Header - optional + if (row.type == ""Slider"" || row.type == ""Toggle"" || row.type == ""Button"" || row.type == ""Header"") {{ + try {{ var check = row.disabled; if (is_undefined(check)) throw ""row disabled should be a bool or a callable""; }} catch (_e) {{ row.disabled = false; }} + try {{ var check = row.hidden; if (is_undefined(check)) throw ""row hidden should be a bool or a callable""; }} catch (_e) {{ row.hidden = false; }} + try {{ var check = row.ref; }} catch (_e) {{ row.ref = undefined; }} + try {{ var check = row.ref; if (!is_undefined(check) && !is_string(check.var_name)) throw ""row ref var_name should be a string""; }} catch (_e) {{ throw ""MODMENU VALIDATION ERROR: Tried to create a menu, but form row ref does not have a valid value for 'var_name'.""; }} + try {{ var check = row.ref; if (!is_undefined(check)) check = check.handle; }} catch (_e) {{ row.ref.handle = global; }} + try {{ var check = row.ref; if (!is_undefined(check) && is_undefined(check.handle)) throw ""row ref handle should not be undefined""; }} catch (_e) {{ throw ""MODMENU VALIDATION ERROR: Tried to create a menu, but form row ref does not have a valid value for 'handle'.""; }} + }} else throw (""Unsupported row type: "" + row.type); + + if (row.type == ""Toggle"") + row = {{ + type: row.type, + title: row.title, + data_ref: row.data_ref, + value_range: row.value_range, + no_save: row.no_save, + trigger_func: row.trigger_func, + change_func: row.change_func, + disabled: row.disabled, + hidden: row.hidden, + ref: row.ref, + title_loc: function(arg0) {{ return global.modmenu.find_locfind_loc(title, arg0); }}, + value_range_loc: function(arg0) {{ return global.modmenu.find_locfind_loc(value_range, arg0); }}, + value_string: function() {{ + var value = data_ref.get(); + var value_range = value_range_loc(); + var ranges = string_split(value_range, "";""); + var valueString = """"; + + for (var j = 0; j < array_length(ranges); j++) {{ + var range = ranges[j]; + if (string_pos(""~"", range)) {{ + var minMax = string_split(string_replace(range, ""%"", """"), ""~""); + var isPercent = string_ends_with(range, ""%""); + var convVal = isPercent ? value * 100 : value; + if (convVal <= minMax[1] || j+1 == array_length(ranges)) {{ + valueString = string_trim(string_format(convVal, 3, (isPercent && convVal > -20 && convVal < 20) ? 1 : 0) + (isPercent ? ""%"" : """")); + break; + }} + }} else if (string_pos(""="", range)) {{ + var labelValue = string_split(string_replace(string_replace(range, ""%"", """"), ""`"", """"), ""=""); + var isString = string_ends_with(range, ""`""); + var isPercent = !isString && string_ends_with(range, ""%""); + var isBool = !isPercent && (labelValue[1] == ""false"" || labelValue[1] == ""true""); + + var isMatch = false; + if (isString) + isMatch = value == labelValue[1]; + else if (isBool) + isMatch = value == bool(labelValue[1]); + else {{ // number + var convBack = isPercent ? 1 / 100 : 1; + isMatch = value == real(labelValue[1]) * convBack; + }} + + if (isMatch || j+1 == array_length(ranges)) {{ + valueString = labelValue[0]; + break; + }} + }} else if (string_ends_with(range, ""%"")) {{ + var minMax = string_split(string_replace(range, ""%"", """"), ""-""); + if (value * 100 <= minMax[1] || j+1 == array_length(ranges)) {{ + valueString = string_trim(string_format(value * 100, 3, value < 0.2 ? 1 : 0) + ""%""); + break; + }} + }} + }} + + return valueString; + }}, + is_disabled: function() {{ return !is_bool(disabled) ? disabled() : disabled; }}, + is_hidden: function() {{ return !is_bool(hidden) ? hidden() : hidden; }} + }}; + else if (row.type == ""Slider"") + row = {{ + type: row.type, + title: row.title, + data_ref: row.data_ref, + value_range: row.value_range, + no_save: row.no_save, + revert_on_cancel: row.revert_on_cancel, + trigger_func: row.trigger_func, + change_func: row.change_func, + cancel_func: row.cancel_func, + accept_func: row.accept_func, + disabled: row.disabled, + hidden: row.hidden, + ref: row.ref, + title_loc: function(arg0) {{ return global.modmenu.find_locfind_loc(title, arg0); }}, + value_range_loc: function(arg0) {{ return global.modmenu.find_locfind_loc(value_range, arg0); }}, + value_string: function() {{ + var value = data_ref.get(); + var value_range = value_range_loc(); + var ranges = string_split(value_range, "";""); + var valueString = """"; + + for (var j = 0; j < array_length(ranges); j++) {{ + var range = ranges[j]; + if (string_pos(""~"", range)) {{ + var minMax = string_split(string_replace(range, ""%"", """"), ""~""); + var isPercent = string_ends_with(range, ""%""); + var convVal = isPercent ? value * 100 : value; + if (convVal <= minMax[1] || j+1 == array_length(ranges)) {{ + valueString = string_trim(string_format(convVal, 3, (isPercent && convVal > -20 && convVal < 20) ? 1 : 0) + (isPercent ? ""%"" : """")); + break; + }} + }} else if (string_pos(""="", range)) {{ + var labelValue = string_split(string_replace(string_replace(range, ""%"", """"), ""`"", """"), ""=""); + var isString = string_ends_with(range, ""`""); + var isPercent = !isString && string_ends_with(range, ""%""); + var isBool = !isPercent && (labelValue[1] == ""false"" || labelValue[1] == ""true""); + + var isMatch = false; + if (isString) + isMatch = value == labelValue[1]; + else if (isBool) + isMatch = value == bool(labelValue[1]); + else {{ // number + var convBack = isPercent ? 1 / 100 : 1; + isMatch = value == real(labelValue[1]) * convBack; + }} + + if (isMatch || j+1 == array_length(ranges)) {{ + valueString = labelValue[0]; + break; + }} + }} else if (string_ends_with(range, ""%"")) {{ + var minMax = string_split(string_replace(range, ""%"", """"), ""-""); + if (value * 100 <= minMax[1] || j+1 == array_length(ranges)) {{ + valueString = string_trim(string_format(value * 100, 3, value < 0.2 ? 1 : 0) + ""%""); + break; + }} + }} + }} + + return valueString; + }}, + is_disabled: function() {{ return !is_bool(disabled) ? disabled() : disabled; }}, + is_hidden: function() {{ return !is_bool(hidden) ? hidden() : hidden; }} + }}; + else if (row.type == ""Button"") + row = {{ + type: row.type, + title: row.title, + trigger_func: row.trigger_func, + disabled: row.disabled, + hidden: row.hidden, + ref: row.ref, + title_loc: function(arg0) {{ return global.modmenu.find_locfind_loc(title, arg0); }}, + is_disabled: function() {{ return !is_bool(disabled) ? disabled() : disabled; }}, + is_hidden: function() {{ return !is_bool(hidden) ? hidden() : hidden; }} + }}; + else if (row.type == ""Header"") + row = {{ + type: row.type, + title: row.title, + disabled: row.disabled, + hidden: row.hidden, + ref: row.ref, + title_loc: function(arg0) {{ return global.modmenu.find_locfind_loc(title, arg0); }}, + is_disabled: function() {{ return !is_bool(disabled) ? disabled() : disabled; }}, + is_hidden: function() {{ return !is_bool(hidden) ? hidden() : hidden; }} + }}; + else throw (""Unsupported row type: "" + row.type); + + if (!is_undefined(row.ref)) variable_instance_set(row.ref.handle, row.ref.var_name, row); + array_insert(inited_form, array_length(inited_form), row); + }} + menu.form = inited_form; + inited_add_data_refs = []; + for (var i = 0; i < array_length(menu.additional_save_data_refs); i++) {{ + array_insert(inited_add_data_refs, array_length(inited_add_data_refs), init_data_ref(menu.additional_save_data_refs[i])); + }} + menu.additional_save_data_refs = inited_add_data_refs; + + menu = {{ + title: menu.title, + left_margin: menu.left_margin, + left_value_pos: menu.left_value_pos, + apply: menu.apply, + save_file: menu.save_file, + world: menu.world, + open_func: menu.open_func, + close_func: menu.close_func, + form: menu.form, + additional_save_data_refs: menu.additional_save_data_refs, + title_loc: function(arg0) {{ return global.modmenu.find_loc(title, arg0); }}, + left_margin_loc: function(arg0) {{ return global.modmenu.find_loc(left_margin, arg0); }}, + left_value_pos_loc: function(arg0) {{ return global.modmenu.find_loc(left_value_pos, arg0); }}, + load: function(arg0, arg1) {{ + if (is_undefined(save_file)) + return; + + var section = save_file.category(arg0, arg1); + ossafe_ini_open(save_file.name); + for (var i = 0; i < array_length(form); i++) {{ + if (form[i].no_save) {{}} else if (form[i].type == ""Slider"" || form[i].type == ""Toggle"") {{ + form[i].data_ref.load(section); + }} else if (form[i].type == ""Button"" || form[i].type == ""Header"") {{}} else throw (""Unsupported row type: "" + form[i].type); + }} + for (var i = 0; i < array_length(additional_save_data_refs); i++) {{ + additional_save_data_refs[i].load(section); + }} + ossafe_ini_close(); + + if (!is_undefined(apply)) + apply.run_onload() + }}, + save: function(arg0) {{ + if (is_undefined(save_file)) + return; + + var section = save_file.category(undefined, arg0); + ossafe_ini_open(save_file.name); + for (var i = 0; i < array_length(form); i++) {{ + if (form[i].no_save) {{}} else if (form[i].type == ""Slider"" || form[i].type == ""Toggle"") {{ + form[i].data_ref.save(section); + }} else if (form[i].type == ""Button"" || form[i].type == ""Header"") {{}} else throw (""Unsupported row type: "" + form[i].type); + }} + for (var i = 0; i < array_length(additional_save_data_refs); i++) {{ + additional_save_data_refs[i].save(section); + }} + ossafe_ini_close(); + }}, + copy: function(arg0, arg1) {{ + if (is_undefined(save_file)) + return; + + var from = save_file.category(undefined, arg0); + var to = save_file.category(undefined, arg1); + ossafe_ini_open(save_file.name); + for (var i = 0; i < array_length(form); i++) {{ + if (form[i].no_save) {{}} else if (form[i].type == ""Slider"" || form[i].type == ""Toggle"") {{ + form[i].data_ref.copy(from, to); + }} else if (form[i].type == ""Button"" || form[i].type == ""Header"") {{}} else throw (""Unsupported row type: "" + form[i].type); + }} + for (var i = 0; i < array_length(additional_save_data_refs); i++) {{ + additional_save_data_refs[i].copy(from, to); + }} + ossafe_ini_close(); + }}, + del: function(arg0) {{ + if (is_undefined(save_file)) + return; + + var section = save_file.category(undefined, arg0); + ossafe_ini_open(save_file.name); + if (ini_section_exists(section)) + ini_section_delete(section); + ossafe_ini_close(); + }}, + all_data_refs: function() {{ + var data_refs = []; + array_copy(data_refs, 0, additional_save_data_refs, 0, array_length(additional_save_data_refs)); + for (var i = 0; i < array_length(form); i++) {{ + if (form[i].type == ""Slider"" || form[i].type == ""Toggle"") {{ + array_insert(data_refs, -1, form[i].data_ref); + }} else if (form[i].type == ""Button"" || form[i].type == ""Header"") {{}} else throw (""Unsupported row type: "" + form[i].type); + }} + return data_refs; + }}, + save_data_refs: function() {{ + var data_refs = []; + array_copy(data_refs, 0, additional_save_data_refs, 0, array_length(additional_save_data_refs)); + for (var i = 0; i < array_length(form); i++) {{ + if (form[i].no_save) {{}} else if (form[i].type == ""Slider"" || form[i].type == ""Toggle"") {{ + array_insert(data_refs, -1, form[i].data_ref); + }} else if (form[i].type == ""Button"" || form[i].type == ""Header"") {{}} else throw (""Unsupported row type: "" + form[i].type); + }} + return data_refs; + }} + }}; + + array_insert(menus, array_length(menus), menu); + menu_count++; + if (menu.world == ""Light"" || menu.world == ""Both"") {{ + array_insert(menus_light, array_length(menus_light), menu); + menu_light_count++; + }} + if (menu.world == ""Dark"" || menu.world == ""Both"") {{ + array_insert(menus_dark, array_length(menus_dark), menu); + menu_dark_count++; + }} + return menu; + }} + }}; + global.modmenu = modmenu; "); } -string global_lang = @"(global.modmenu_langoverride != """" ? global.modmenu_langoverride : global.lang)"; -Func ds_map_find_value_lang = - (id, key) => @$"(ds_map_exists({id}, {key} + ""_"" + {global_lang}) ? ds_map_find_value({id}, {key} + ""_"" + {global_lang}) : ds_map_find_value({id}, {key} + ""_en""))"; - +// Add dark menu create code +foreach (string darkcon in darkcons) +{ + importGroup.QueueAppend(darkcon + "_Create_0", "modmenu = global.modmenu;"); +} // Add menu draw code foreach (string darkcon in darkcons) @@ -273,7 +815,7 @@ foreach (string darkcon in darkcons) {{ draw_set_color(c_black); - if ({global_lang} == ""ja"") + if (global.lang == ""ja"") {{ draw_rectangle(xx + 60, yy + 85, xx + 580, yy + 412, false); scr_darkbox(xx + 50, yy + 75, xx + 590, yy + 422); @@ -286,24 +828,20 @@ foreach (string darkcon in darkcons) draw_set_color(c_white); - if (array_length(global.modmenu_data) > 0) + if (modmenu.menu_dark_count > 0) {{ // top row buttons - var isSubmenu = (global.modsubmenuno >= 0); - var isMenuLonely = array_length(global.modmenu_data) == 1; + var isSubmenu = (modmenu.row_no >= 0); + var isMenuLonely = modmenu.menu_dark_count == 1; var allmodmenus = """"; - for (var i = global.modmenuno; i < array_length(global.modmenu_data); i++) + for (var i = modmenu.menu_no; i < modmenu.menu_dark_count; i++) {{ - allmodmenus += string_upper({ds_map_find_value_lang("global.modmenu_data[i]", @"""title""")}) + (i + 1 < array_length(global.modmenu_data) ? "" "" : """"); + allmodmenus += string_upper(modmenu.menus_dark[i].title_loc()) + (i + 1 < modmenu.menu_dark_count ? "" "" : """"); }} - if (!surface_exists(surf_modtitles)) - {{ - surf_modtitles = surface_create(410, 35); - }} - surface_set_target(surf_modtitles); + surface_set_target(modmenu.get_surf_titles()); draw_clear_alpha(c_black, 0); if (isMenuLonely || !isSubmenu) @@ -325,42 +863,36 @@ foreach (string darkcon in darkcons) draw_set_color(c_gray); draw_text(0, 0, allmodmenus); draw_set_color(c_orange); - draw_text(0, 0, string_upper({ds_map_find_value_lang("global.modmenu_data[global.modmenuno]", @"""title""")})); + draw_text(0, 0, string_upper(modmenu.active_menu().title_loc())); }} draw_sprite(spr_darkmodsfade, 0, 410 - 35, 0); surface_reset_target(); - draw_surface(surf_modtitles, xx + 110, yy + 110); + draw_surface(modmenu.get_surf_titles(), xx + 110, yy + 110); if (!isSubmenu) {{ menusiner += 1; - draw_sprite_part(spr_heart_harrows, menusiner / 20, 8 - 8 * (global.modmenuno > 0), 0, 16 + 8 * (global.modmenuno > 0) + 8 * (global.modmenuno < (array_length(global.modmenu_data) - 1)), 16, xx + 85 - 8 * (global.modmenuno > 0), yy + 120); + draw_sprite_part(spr_heart_harrows, menusiner / 20, 8 - 8 * (modmenu.menu_no > 0), 0, 16 + 8 * (modmenu.menu_no > 0) + 8 * (modmenu.menu_no < (modmenu.menu_dark_count - 1)), 16, xx + 85 - 8 * (modmenu.menu_no > 0), yy + 120); }} // form buttons - var left_margin = {ds_map_find_value_lang("global.modmenu_data[global.modmenuno]", @"""left_margin""")}; - if (is_undefined(left_margin)) - left_margin = 40; + var left_margin = modmenu.active_menu().left_margin_loc(); var _xPos = xx + 130 + left_margin; var _heartXPos = xx + 105 + left_margin; - - var left_value_pos = {ds_map_find_value_lang("global.modmenu_data[global.modmenuno]", @"""left_value_pos""")}; - if (is_undefined(left_value_pos)) - left_value_pos = 300; - var _selectXPos = xx + 130 + left_value_pos; + var _selectXPos = xx + 130 + modmenu.active_menu().left_value_pos_loc(); draw_set_color(c_white); if (!isSubmenu) draw_set_color(c_gray); - var form_data = ds_map_find_value(global.modmenu_data[global.modmenuno], ""form""); + var form_data = modmenu.active_menu().form; var heartyprogress = 150; if (array_length(form_data) >= 0) {{ - var i = global.modsubmenuscroll; + var i = modmenu.row_scroll; var yprogress = 150; while ((yprogress <= 150 + 6 * 35) && (i < array_length(form_data) + 1)) {{ @@ -368,83 +900,35 @@ foreach (string darkcon in darkcons) {{ draw_set_color(c_white); draw_text(_xPos, yy + yprogress{(ch_no == 1 ? " + 1" : "")}, string_hash_to_newline({(darkcon.EndsWith("_ch1") ? ch1_back_text : back_text)})); // Back - if (global.modsubmenuno == i) + if (modmenu.row_no == i) heartyprogress = yprogress; yprogress += 35; break; }} var row_data = form_data[i]; - var row_hidden_data = ds_map_find_value(row_data, ""hidden""); - var row_hidden = !is_undefined(row_hidden_data) ? row_hidden_data : false; - if (row_hidden) {{ + if (row_data.is_hidden()) {{ i++; continue; }} - var row_disabled_data = ds_map_find_value(row_data, ""disabled""); - var row_disabled = !is_undefined(row_disabled_data) ? row_disabled_data : false; - if (row_disabled) + if (row_data.is_disabled()) draw_set_color(c_gray); - else if (global.modsubmenuselected && global.modsubmenuno == i) + else if (modmenu.row_selected && modmenu.row_no == i) draw_set_color(c_yellow); else draw_set_color(c_white); - var value_name = ds_map_find_value(row_data, ""value_name""); - var value = !is_undefined(value_name) ? variable_instance_get(global, value_name) : -1; - var value_range = {ds_map_find_value_lang("row_data", @"""value_range""")}; - var ranges = !is_undefined(value_range) ? string_split(value_range, "";"") : []; - var valueString = """"; - var isCategory = is_undefined(value_range) && is_undefined(ds_map_find_value(row_data, ""func_name"")); - - draw_text_transformed(_xPos - (isCategory * 28), yy + yprogress - (isCategory * 5){(ch_no == 1 ? " + 1" : "")}, string_hash_to_newline({ds_map_find_value_lang("row_data", @"""title""")}), (isCategory ? 0.5 : 1), (isCategory ? 0.5 : 1), 0); + var isCategory = (row_data.type == ""Header""); + draw_text_transformed(_xPos - (isCategory * 28), yy + yprogress - (isCategory * 5){(ch_no == 1 ? " + 1" : "")}, string_hash_to_newline(row_data.title_loc()), (isCategory ? 0.5 : 1), (isCategory ? 0.5 : 1), 0); if (isCategory){{ draw_line(_xPos - 28 - 3, yy + yprogress + 9, _xPos + 400, yy + yprogress + 9); }} - for (var j = 0; j < array_length(ranges); j++) {{ - var range = ranges[j]; - if (string_pos(""~"", range)) {{ - var minMax = string_split(string_replace(range, ""%"", """"), ""~""); - var isPercent = string_ends_with(range, ""%""); - var convVal = isPercent ? value * 100 : value; - if (convVal <= minMax[1] || j+1 == array_length(ranges)) {{ - valueString = string_trim(string_format(convVal, 3, (isPercent && convVal > -20 && convVal < 20) ? 1 : 0) + (isPercent ? ""%"" : """")); - break; - }} - }} else if (string_pos(""="", range)) {{ - var labelValue = string_split(string_replace(string_replace(range, ""%"", """"), ""`"", """"), ""=""); - var isString = string_ends_with(range, ""`""); - var isPercent = !isString && string_ends_with(range, ""%""); - var isBool = !isPercent && (labelValue[1] == ""false"" || labelValue[1] == ""true""); - - var isMatch = false; - if (isString) - isMatch = value == labelValue[1]; - else if (isBool) - isMatch = value == bool(labelValue[1]); - else {{ // number - var convBack = isPercent ? 1 / 100 : 1; - isMatch = value == real(labelValue[1]) * convBack; - }} - - if (isMatch || j+1 == array_length(ranges)) {{ - valueString = labelValue[0]; - break; - }} - }} else if (string_ends_with(range, ""%"")) {{ - var minMax = string_split(string_replace(range, ""%"", """"), ""-""); - if (value * 100 <= minMax[1] || j+1 == array_length(ranges)) {{ - valueString = string_trim(string_format(value * 100, 3, value < 0.2 ? 1 : 0) + ""%""); - break; - }} - }} - }} - - draw_text(_selectXPos, yy + yprogress{(ch_no == 1 ? " + 1" : "")}, string_hash_to_newline(valueString)); + if (row_data.type == ""Slider"" || row_data.type == ""Toggle"") + draw_text(_selectXPos, yy + yprogress{(ch_no == 1 ? " + 1" : "")}, string_hash_to_newline(row_data.value_string())); - if (global.modsubmenuno == i){{ + if (modmenu.row_no == i){{ heartyprogress = yprogress; }} yprogress += (isCategory ? 12 : 35); @@ -458,18 +942,17 @@ foreach (string darkcon in darkcons) for (var i = 0; i < array_length(form_data) + 1; i++) {{ if (i >= array_length(form_data)) {{ - if (global.modsubmenuscroll == i){{ + if (modmenu.row_scroll == i){{ scrollprogress = totalmenulength; }} totalmenulength += 35; continue; }} - if (global.modsubmenuscroll == i){{ + if (modmenu.row_scroll == i){{ scrollprogress = totalmenulength; }} - var isCategory = is_undefined({ds_map_find_value_lang("form_data[i]", @"""value_range""")}) && is_undefined(ds_map_find_value(form_data[i], ""func_name"")); - totalmenulength += (isCategory ? 12 : 35); + totalmenulength += ((form_data[i].type == ""Header"") ? 12 : 35); }} // also need to account for empty space at the bottom of the menu @@ -482,8 +965,7 @@ foreach (string darkcon in darkcons) }} else {{ - var isCategory = is_undefined({ds_map_find_value_lang("form_data[i]", @"""value_range""")}) && is_undefined(ds_map_find_value(form_data[i], ""func_name"")); - newlastscreenlength += (isCategory ? 12 : 35); + newlastscreenlength += ((form_data[i].type == ""Header"") ? 12 : 35); }} if (newlastscreenlength > menuscreenlength) @@ -506,10 +988,10 @@ foreach (string darkcon in darkcons) draw_set_color(c_white); draw_rectangle(xx + 85, yy + modscrollbary + modscrollery, xx + 90, yy + modscrollbary + modscrollerlength + modscrollery, false); - if (global.modsubmenuscroll > 0) + if (modmenu.row_scroll > 0) draw_sprite_ext(spr_morearrow, 0, xx + 81, (yy + modscrollbary) - 10 - (sin(cur_jewel / 12) * 3), 1, -1, 0, c_white, 1); - if ((global.modsubmenuscroll + 7) < (array_length(form_data) + 1)) + if ((modmenu.row_scroll + 7) < (array_length(form_data) + 1)) draw_sprite_ext(spr_morearrow, 0, xx + 81, yy + 10 + modscrollbary + modscrollbarlength + (sin(cur_jewel / 12) * 3), 1, 1, 0, c_white, 1); }} }} @@ -536,18 +1018,24 @@ foreach (string darkcon in darkcons) importGroup.QueueTrimmedLinesFindReplace(darkcon + "_Step_0", "if (global.menucoord[0] == 4)", "if (global.menucoord[0] == 5)"); importGroup.QueueAppend(darkcon + "_Step_0", @$" // override for deltaesp's spanish translation - if (global.modmenu_langoverride != ""es"" && global.lang == ""en"" && variable_instance_exists(global, ""esp_names"")) + if (modmenu.lang_override != ""es"" && global.lang == ""en"" && variable_instance_exists(global, ""esp_names"")) {{ - global.modmenu_langoverride = ""es""; + modmenu.lang_override = ""es""; + }} + // override for the Korean translation + // TODO this doesn't work for chapter 2 as the dubbing feature hasn't been added + if (modmenu.lang_override != ""ko"" && global.lang == ""ja"" && variable_instance_exists(global, ""krdub"")) + {{ + modmenu.lang_override = ""ko""; }} function scrolldownforcontent() {{ - var form_data = ds_map_find_value(global.modmenu_data[global.modmenuno], ""form""); - global.modsubmenuscroll = global.modsubmenuno + 1; + var form_data = modmenu.active_menu().form; + modmenu.row_scroll = modmenu.row_no + 1; var menuscreenlength = 7 * 35; var lastscreenlength = 0; - for (var i = global.modsubmenuno; i >= 0; i--) {{ + for (var i = modmenu.row_no; i >= 0; i--) {{ var newlastscreenlength = lastscreenlength; if (i >= array_length(form_data)) {{ @@ -555,8 +1043,7 @@ foreach (string darkcon in darkcons) }} else {{ - var isCategory = is_undefined({ds_map_find_value_lang("form_data[i]", @"""value_range""")}) && is_undefined(ds_map_find_value(form_data[i], ""func_name"")); - newlastscreenlength += (isCategory ? 12 : 35); + newlastscreenlength += ((form_data[i].type == ""Header"") ? 12 : 35); }} if (newlastscreenlength > menuscreenlength) @@ -564,17 +1051,17 @@ foreach (string darkcon in darkcons) break; }} lastscreenlength = newlastscreenlength; - global.modsubmenuscroll--; + modmenu.row_scroll--; }} }} function isneedscrolldown() {{ - var form_data = ds_map_find_value(global.modmenu_data[global.modmenuno], ""form""); + var form_data = modmenu.active_menu().form; var menuscreenlength = 7 * 35; var currentscreenlength = 0; var foundselected = false; - for (var i = global.modsubmenuscroll; i < array_length(form_data) + 1; i++) {{ + for (var i = modmenu.row_scroll; i < array_length(form_data) + 1; i++) {{ var newcurrentscreenlength = currentscreenlength; if (i >= array_length(form_data)) {{ @@ -582,8 +1069,7 @@ foreach (string darkcon in darkcons) }} else {{ - var isCategory = is_undefined({ds_map_find_value_lang("form_data[i]", @"""value_range""")}) && is_undefined(ds_map_find_value(form_data[i], ""func_name"")); - newcurrentscreenlength += (isCategory ? 12 : 35); + newcurrentscreenlength += ((form_data[i].type == ""Header"") ? 12 : 35); }} if (newcurrentscreenlength > menuscreenlength) @@ -591,7 +1077,7 @@ foreach (string darkcon in darkcons) break; }} currentscreenlength = newcurrentscreenlength; - if (i == global.modsubmenuno) + if (i == modmenu.row_no) {{ foundselected = true; }} @@ -601,29 +1087,29 @@ foreach (string darkcon in darkcons) function modsubmenu_up(arg0) {{ - global.modsubmenuno--; + modmenu.row_no--; - if (global.modsubmenuno < 0) + if (modmenu.row_no < 0) {{ - global.modsubmenuno = arg0 - 1; + modmenu.row_no = arg0 - 1; scrolldownforcontent(); }} else {{ - if (global.modsubmenuno < global.modsubmenuscroll) - global.modsubmenuscroll = global.modsubmenuno; + if (modmenu.row_no < modmenu.row_scroll) + modmenu.row_scroll = modmenu.row_no; }} }} function modsubmenu_down(arg0) {{ - global.modsubmenuno++; + modmenu.row_no++; - if (global.modsubmenuno >= arg0) + if (modmenu.row_no >= arg0) {{ - global.modsubmenuno = 0; - global.modsubmenuscroll = 0; + modmenu.row_no = 0; + modmenu.row_scroll = 0; }} else if (isneedscrolldown()) {{ @@ -633,37 +1119,26 @@ foreach (string darkcon in darkcons) function issubmenucategory(arg0, arg1) {{ - if (global.modsubmenuno >= (arg0 - 1)) + if (modmenu.row_no >= (arg0 - 1)) return false; - return - is_undefined({ds_map_find_value_lang("arg1[global.modsubmenuno]", @"""value_range""")}) && is_undefined(ds_map_find_value(arg1[global.modsubmenuno], ""func_name"")) + return (arg1[modmenu.row_no].type == ""Header""); }} function ishidden(arg0, arg1) {{ - if (global.modsubmenuno >= (arg0 - 1)) + if (modmenu.row_no >= (arg0 - 1)) return false; - var row_hidden_data = ds_map_find_value(arg1[global.modsubmenuno], ""hidden""); - var row_hidden = !is_undefined(row_hidden_data) ? row_hidden_data : false; - if (row_hidden) - return true; - - return false; + return arg1[modmenu.row_no].is_hidden(); }} function isdisabled(arg0, arg1) {{ - if (global.modsubmenuno >= (arg0 - 1)) + if (modmenu.row_no >= (arg0 - 1)) return false; - var row_disabled_data = ds_map_find_value(arg1[global.modsubmenuno], ""disabled""); - var row_disabled = !is_undefined(row_disabled_data) ? row_disabled_data : false; - if (row_disabled) - return true; - - return false; + return arg1[modmenu.row_no].is_disabled(); }} function shouldskiprow(arg0, arg1) @@ -673,40 +1148,43 @@ foreach (string darkcon in darkcons) if (global.menuno == 6) {{ - var isSubmenu = (global.modsubmenuno >= 0); + var isSubmenu = (modmenu.row_no >= 0); if (!isSubmenu) {{ // enter submenu right away if there is only one submenu - if (array_length(global.modmenu_data) == 1) - global.modsubmenuno = 0; + if (modmenu.menu_dark_count == 1) {{ + modmenu.row_no = 0; + + modmenu.active_menu().open_func(); + }} - if (array_length(global.modmenu_data) > 0) + if (modmenu.menu_dark_count > 0) {{ if (left_p()) {{ movenoise = 1; - global.modmenuno--; - if (global.modmenuno < 0) - global.modmenuno = array_length(global.modmenu_data) - 1; + modmenu.menu_no--; + if (modmenu.menu_no < 0) + modmenu.menu_no = modmenu.menu_dark_count - 1; }} if (right_p()) {{ movenoise = 1; - global.modmenuno++; - if (global.modmenuno >= array_length(global.modmenu_data)) - global.modmenuno = 0; + modmenu.menu_no++; + if (modmenu.menu_no >= modmenu.menu_dark_count) + modmenu.menu_no = 0; }} if (button1_p() && onebuffer < 0 && twobuffer < 0) {{ onebuffer = 2; selectnoise = 1; - global.modsubmenuno = 0; + modmenu.row_no = 0; // make sure category header or hidden/disabled row isn't selected - var form_data = ds_map_find_value(global.modmenu_data[global.modmenuno], ""form""); - var form_length = ds_map_exists(global.modmenu_data[global.modmenuno], ""form"") ? array_length(form_data) : 0; + var form_data = modmenu.active_menu().form; + var form_length = array_length(form_data); // back button form_length++; var movecount = 0; @@ -714,6 +1192,8 @@ foreach (string darkcon in darkcons) modsubmenu_down(form_length); movecount++; }} + + modmenu.active_menu().open_func(); }} }} if (button2_p() && onebuffer < 0 && twobuffer < 0) @@ -723,13 +1203,13 @@ foreach (string darkcon in darkcons) global.menuno = 0; global.submenu = 0; }} - }} else if (!global.modsubmenuselected) {{ - var form_data = ds_map_find_value(global.modmenu_data[global.modmenuno], ""form""); - var form_length = ds_map_exists(global.modmenu_data[global.modmenuno], ""form"") ? array_length(form_data) : 0; + }} else if (!modmenu.row_selected) {{ + var form_data = modmenu.active_menu().form; + var form_length = array_length(form_data); if (form_length <= 0) {{ - global.modsubmenuno = -1; - global.modsubmenuscroll = 0; + modmenu.row_no = -1; + modmenu.row_scroll = 0; }} // back button @@ -773,50 +1253,37 @@ foreach (string darkcon in darkcons) onebuffer = 2; selectnoise = 1; - if (global.modsubmenuno >= array_length(form_data)) {{ - global.modsubmenuno = -1; - global.modsubmenuscroll = 0; + if (modmenu.row_no >= array_length(form_data)) {{ + modmenu.row_no = -1; + modmenu.row_scroll = 0; - if (array_length(global.modmenu_data) == 1) + if (modmenu.menu_dark_count == 1) {{ global.menuno = 0; global.submenu = 0; }} - var on_close = ds_map_find_value(global.modmenu_data[global.modmenuno], ""on_close""); - if (!is_undefined(on_close)) - {{ - var functocall = variable_instance_get(global, on_close); - functocall(); - }} + modmenu.active_menu().close_func(); + if (!is_undefined(modmenu.active_menu().apply)) modmenu.active_menu().apply.run_onclose(); + if (!is_undefined(modmenu.active_menu().save_file)) modmenu.active_menu().save(); }} else {{ - global.modsubmenuselected = true; + modmenu.row_selected = true; // if range is only labels just cycle through them - var row_data = form_data[global.modsubmenuno]; - var value_range = {ds_map_find_value_lang("row_data", @"""value_range""")}; - var ranges = !is_undefined(value_range) ? string_split(value_range, "";"") : []; - var force_scroll = ds_map_exists(row_data, ""force_scroll"") ? ds_map_find_value(row_data, ""force_scroll"") : false; - var doToggle = !force_scroll; - - if (doToggle) {{ - for (var i = 0; i < array_length(ranges); i++) {{ - var range = ranges[i]; - if (!string_pos(""="", range)) {{ - doToggle = false; - break; - }} - }} - }} + var row_data = form_data[modmenu.row_no]; + var value_range = row_data.value_range_loc(); + var ranges = string_split(value_range, "";""); - if (doToggle || array_length(ranges) <= 0) {{ - global.modsubmenuselected = false; + if (row_data.type != ""Slider"") {{ + modmenu.row_selected = false; + modmenu.slider_orig_value = row_data.data_ref.get(); }} - if (doToggle && array_length(ranges) > 0) {{ - var value = variable_instance_get(global, ds_map_find_value(row_data, ""value_name"")); + if (row_data.type == ""Toggle"") {{ + // TODO does this handle spread ranges properly? + var value = row_data.data_ref.get(); var foundOption = false; for (var i = 0; i < array_length(ranges); i++) {{ @@ -862,56 +1329,40 @@ foreach (string darkcon in darkcons) }} }} - variable_instance_set(global, ds_map_find_value(row_data, ""value_name""), value); - - var on_change = ds_map_find_value(row_data, ""on_change""); - if (!is_undefined(on_change)) - {{ - var functocall = variable_instance_get(global, on_change); - functocall(); - }} + row_data.data_ref.set(value); + row_data.change_func(); + if (!is_undefined(modmenu.active_menu().apply)) modmenu.active_menu().apply.run_onchange(); }} - - if (doToggle || array_length(ranges) <= 0) {{ - var func_name = ds_map_find_value(row_data, ""func_name""); - if (!is_undefined(func_name)) - {{ - var functocall = variable_instance_get(global, func_name); - functocall(true); - }} - }} + if (row_data.type != ""Header"") + row_data.trigger_func(); }} }} if (button2_p() && onebuffer < 0 && twobuffer < 0) {{ cancelnoise = 1; twobuffer = 2; - global.modsubmenuno = -1; - global.modsubmenuscroll = 0; + modmenu.row_no = -1; + modmenu.row_scroll = 0; - if (array_length(global.modmenu_data) == 1) + if (modmenu.menu_dark_count == 1) {{ global.menuno = 0; global.submenu = 0; }} - var on_close = ds_map_find_value(global.modmenu_data[global.modmenuno], ""on_close""); - if (!is_undefined(on_close)) - {{ - var functocall = variable_instance_get(global, on_close); - functocall(); - }} + modmenu.active_menu().close_func(); + if (!is_undefined(modmenu.active_menu().apply)) modmenu.active_menu().apply.run_onclose(); + if (!is_undefined(modmenu.active_menu().save_file)) modmenu.active_menu().save(); }} }} else {{ - var form_data = ds_map_find_value(global.modmenu_data[global.modmenuno], ""form""); - var row_data = form_data[global.modsubmenuno]; - var value_range = {ds_map_find_value_lang("row_data", @"""value_range""")}; - var ranges = !is_undefined(value_range) ? string_split(value_range, "";"") : []; - var value_name = ds_map_find_value(row_data, ""value_name""); - var value = !is_undefined(value_name) ? variable_instance_get(global, value_name) : -1; + var form_data = modmenu.active_menu().form; + var row_data = form_data[modmenu.row_no]; + var value_range = row_data.value_range_loc(); + var ranges = string_split(value_range, "";""); + var value = row_data.data_ref.get(); - var scroll_todo = modscroller_step div 1; + var scroll_todo = modmenu.slider_step div 1; if (right_h() && scroll_todo > 0) {{ @@ -1025,16 +1476,12 @@ foreach (string darkcon in darkcons) }} }} - variable_instance_set(global, ds_map_find_value(row_data, ""value_name""), value); + row_data.data_ref.set(value); - var on_change = ds_map_find_value(row_data, ""on_change""); - if (!is_undefined(on_change)) - {{ - var functocall = variable_instance_get(global, on_change); - functocall(); - }} + row_data.change_func(); + if (!is_undefined(modmenu.active_menu().apply)) modmenu.active_menu().apply.run_onchange(); - modscroller_step = modscroller_step % 1; + modmenu.slider_step = modmenu.slider_step % 1; }} if (left_h() && scroll_todo > 0) @@ -1116,7 +1563,7 @@ foreach (string darkcon in darkcons) else value_adjust = -0.1; - var scroll_todo = modscroller_step div 1; + var scroll_todo = modmenu.slider_step div 1; value += value_adjust * scroll_todo; for (var i = array_length(ranges) - 1; i >= 0; i--) {{ @@ -1150,27 +1597,23 @@ foreach (string darkcon in darkcons) }} }} - variable_instance_set(global, ds_map_find_value(row_data, ""value_name""), value); + row_data.data_ref.set(value); - var on_change = ds_map_find_value(row_data, ""on_change""); - if (!is_undefined(on_change)) - {{ - var functocall = variable_instance_get(global, on_change); - functocall(); - }} + row_data.change_func(); + if (!is_undefined(modmenu.active_menu().apply)) modmenu.active_menu().apply.run_onchange(); - modscroller_step = modscroller_step % 1; + modmenu.slider_step = modmenu.slider_step % 1; }} if (right_h() || left_h()) {{ - modscroller_step += modscroller_speed; - modscroller_speed = clamp(modscroller_speed + modscroller_accel, modscroller_speed_min, modscroller_speed_max); + modmenu.slider_step += modmenu.slider_speed; + modmenu.slider_speed = clamp(modmenu.slider_speed + modmenu.slider_accel, modmenu.slider_speed_min, modmenu.slider_speed_max); }} else {{ - modscroller_step = 1; // reset to 1 as first interaction should be instantaneous - modscroller_speed = modscroller_speed_min; + modmenu.slider_step = 1; // reset to 1 as first interaction should be instantaneous + modmenu.slider_speed = modmenu.slider_speed_min; }} se_select = 0; @@ -1187,23 +1630,123 @@ foreach (string darkcon in darkcons) selectnoise = 1; onebuffer = 2; twobuffer = 2; - global.modsubmenuselected = false; - - var func_name = ds_map_find_value(row_data, ""func_name""); - if (!is_undefined(func_name)) - {{ - var functocall = variable_instance_get(global, func_name); - functocall(se_select); + modmenu.row_selected = false; + + if (se_select == 1) + row_data.accept_func(); + if (se_cancel == 1) {{ + if (row_data.revert_on_cancel && row_data.data_ref.get() != modmenu.slider_orig_value) {{ + row_data.data_ref.set(modmenu.slider_orig_value); + row_data.change_func(); + if (!is_undefined(modmenu.active_menu().apply)) modmenu.active_menu().apply.run_onchange(); + }} + row_data.cancel_func(); }} - modscroller_step = 1; // reset to 1 as first interaction should be instantaneous - modscroller_speed = modscroller_speed_min; + modmenu.slider_step = 1; // reset to 1 as first interaction should be instantaneous + modmenu.slider_speed = modmenu.slider_speed_min; + modmenu.slider_orig_value = undefined; }} }} }} "); } +// Save menu data +string[] saveLikes = {"gml_GlobalScript_scr_saveprocess"}; +if (ch_no == 0) +{ + string[] demoSaveLikes = {"gml_GlobalScript_scr_saveprocess_ch1"}; + saveLikes = saveLikes.Concat(demoSaveLikes).ToArray(); +} +foreach (string scrName in saveLikes) +{ + importGroup.QueueTrimmedLinesFindReplace(scrName, $"{(ch_no == 0 ? "var is_valid = " : "")}ossafe_file_text_close{(scrName.EndsWith("_ch1") ? "_ch1" : "")}(myfileid);", @$" + {(ch_no == 0 ? "var is_valid = " : "")}ossafe_file_text_close{(scrName.EndsWith("_ch1") ? "_ch1" : "")}(myfileid); + + global.modmenu.save(); + "); +} + +// Load menu data +(string script, string chapter) [] loadLikes = {("gml_GlobalScript_scr_load", "global.chapter")}; +if (ch_no == 0) +{ + (string script, string chapter) [] loadCh1 = {("gml_GlobalScript_scr_load_ch1", "global.chapter")}; + loadLikes = loadLikes.Concat(loadCh1).ToArray(); +} +if (ch_no > 1 || ch_no == 0) +{ + (string script, string chapter) [] loadCh1 = {("gml_GlobalScript_scr_load_chapter1", "1")}; + loadLikes = loadLikes.Concat(loadCh1).ToArray(); +} +if (ch_no > 2) +{ + (string script, string chapter) [] loadCh2 = {("gml_GlobalScript_scr_load_chapter2", "2")}; + loadLikes = loadLikes.Concat(loadCh2).ToArray(); +} +if (ch_no > 3) +{ + (string script, string chapter) [] loadCh3 = {("gml_GlobalScript_scr_load_chapter3", "3")}; + loadLikes = loadLikes.Concat(loadCh3).ToArray(); +} +if (ch_no > 4) +{ + (string script, string chapter) [] loadCh4 = {("gml_GlobalScript_scr_load_chapter4", "4")}; + loadLikes = loadLikes.Concat(loadCh4).ToArray(); +} +// if (ch_no > 5) +// { +// (string script, string chapter) [] loadCh5 = {("gml_GlobalScript_scr_load_chapter5", "5")}; +// loadLikes = loadLikes.Concat(loadCh5).ToArray(); +// } +// if (ch_no > 6) +// { +// (string script, string chapter) [] loadCh6 = {("gml_GlobalScript_scr_load_chapter6", "6")}; +// loadLikes = loadLikes.Concat(loadCh6).ToArray(); +// } + +foreach ((string script, string chapter) loadLike in loadLikes) +{ + importGroup.QueueTrimmedLinesFindReplace(loadLike.script, $"ossafe_file_text_close{(loadLike.script.EndsWith("_ch1") ? "_ch1" : "")}(myfileid);", @$" + ossafe_file_text_close{(loadLike.script.EndsWith("_ch1") ? "_ch1" : "")}(myfileid); + + global.modmenu.load({loadLike.chapter}); + "); +} + +// Copy menu data +string[] copyLikes = {"gml_Object_DEVICE_MENU_Other_15"}; +if (ch_no == 0) +{ + string[] demoCopyLikes = {"gml_Object_DEVICE_MENU_ch1_Other_15"}; + copyLikes = copyLikes.Concat(demoCopyLikes).ToArray(); +} +foreach (string scrName in copyLikes) +{ + importGroup.QueueTrimmedLinesFindReplace(scrName, @"file_copy(""keyconfig_"" + string(MENUCOORD[2]) + "".ini"", ""keyconfig_"" + string(MENUCOORD[3]) + "".ini"");", @$" + file_copy(""keyconfig_"" + string(MENUCOORD[2]) + "".ini"", ""keyconfig_"" + string(MENUCOORD[3]) + "".ini""); + + global.modmenu.copy(MENUCOORD[2], MENUCOORD[3]); + "); +} + +// Delete menu data +string[] deleteLikes = {"gml_Object_DEVICE_MENU_Step_0"}; +if (ch_no == 0) +{ + string[] demoDeleteLikes = {"gml_Object_DEVICE_MENU_ch1_Step_0"}; + copyLikes = deleteLikes.Concat(demoDeleteLikes).ToArray(); +} +foreach (string scrName in deleteLikes) +{ + importGroup.QueueTrimmedLinesFindReplace(scrName, @"TIME_STRING[MENUCOORD[5]] = ""--:--"";", @" + TIME_STRING[MENUCOORD[5]] = ""--:--""; + + global.modmenu.del(MENUCOORD[5]); + "); +} + // Finish edit importGroup.Import(); ScriptMessage($"Success: Mod menu added to '{displayName}'!");