diff --git a/ChapterMaster.yyp b/ChapterMaster.yyp index 714beea7ae..835b4a247e 100644 --- a/ChapterMaster.yyp +++ b/ChapterMaster.yyp @@ -495,7 +495,7 @@ "isEcma":false, "LibraryEmitters":[], "MetaData":{ - "IDEVersion":"2024.1300.0.781", + "IDEVersion":"2024.1300.0.785", }, "name":"ChapterMaster", "resources":[ @@ -736,6 +736,7 @@ {"id":{"name":"scr_fleet_functions","path":"scripts/scr_fleet_functions/scr_fleet_functions.yy",},}, {"id":{"name":"scr_forge_world_functions","path":"scripts/scr_forge_world_functions/scr_forge_world_functions.yy",},}, {"id":{"name":"scr_garrison","path":"scripts/scr_garrison/scr_garrison.yy",},}, + {"id":{"name":"scr_general_variable_functions","path":"scripts/scr_general_variable_functions/scr_general_variable_functions.yy",},}, {"id":{"name":"scr_get_diag_integer","path":"scripts/scr_get_diag_integer/scr_get_diag_integer.yy",},}, {"id":{"name":"scr_get_diag_string","path":"scripts/scr_get_diag_string/scr_get_diag_string.yy",},}, {"id":{"name":"scr_get_item_names","path":"scripts/scr_get_item_names/scr_get_item_names.yy",},}, @@ -814,6 +815,7 @@ {"id":{"name":"scr_save_controller","path":"scripts/scr_save_controller/scr_save_controller.yy",},}, {"id":{"name":"scr_save","path":"scripts/scr_save/scr_save.yy",},}, {"id":{"name":"scr_scrollbar","path":"scripts/scr_scrollbar/scr_scrollbar.yy",},}, + {"id":{"name":"scr_serialization_functions","path":"scripts/scr_serialization_functions/scr_serialization_functions.yy",},}, {"id":{"name":"scr_shader_initialize","path":"scripts/scr_shader_initialize/scr_shader_initialize.yy",},}, {"id":{"name":"scr_ship_battle","path":"scripts/scr_ship_battle/scr_ship_battle.yy",},}, {"id":{"name":"scr_ship_count","path":"scripts/scr_ship_count/scr_ship_count.yy",},}, diff --git a/objects/obj_controller/Create_0.gml b/objects/obj_controller/Create_0.gml index 9fc7d50265..a045313fbb 100644 --- a/objects/obj_controller/Create_0.gml +++ b/objects/obj_controller/Create_0.gml @@ -72,6 +72,8 @@ The Machine God watches over you. */ +show_debug_message("Creating Controller"); +log_message("Creating Controller"); marine_surface = surface_create(600, 600); scr_colors_initialize(); is_test_map=false; @@ -1344,6 +1346,41 @@ try{ catch(_exception){ global.star_name_colors[1] = make_color_rgb(col_r[1],col_g[1],col_b[1]); } + +#region save/load serialization + +/// Called from save function to take all object variables and convert them to a json savable format and return it +serialize = function(){ + var object_controller = self; + + var save_data = { + obj: object_get_name(object_index), + x, + y, + chaos_gods, + master_of_forge, + stc_research, + production_research, + player_forge_data, + end_turn_insights, + recruit_data, + marines, + loyalty, + spec_train_data + } + var excluded_from_save = ["temp", "serialize", "deserialize", "build_chaos_gods", "company_data","menu_buttons", + "location_viewer", "production_research_pathways", "specialist_point_handler", "spec_train_data"] + var excluded_from_save_start = ["restart_"]; + + copy_serializable_fields(object_controller, save_data, excluded_from_save, excluded_from_save_start); + + return save_data; +} + +// Deserialization is done within scr_load +#endregion + + // ** Loads the game ** if (global.load>0){ load_game=global.load; @@ -1361,6 +1398,18 @@ if (global.load>0){ exit; } +///! ************************************************************ */ +///! ************************************************************ */ +///! ************************************************************ */ +///! NOTHING BEYOND THIS POINT WILL BE SET AFTER A LOAD FROM SAVE */ +///! ************************************************************ */ +///! ************************************************************ */ +///! ************************************************************ */ +///! ************************************************************ */ + + + + var xx,yy,me,dist,go,planet; global.custom=1; @@ -1784,6 +1833,10 @@ if (welcome_pages>=5){ } } remov=string_length(string(temp[65])+string(temp[66])+string(temp[67])+string(temp[68])+string(temp[69]))+1; -action_set_alarm(2, 0); instance_create(0,0,obj_tooltip ); + +action_set_alarm(2, 0); + + +//**! DO NOT PUT THINGS AT THE BOTTOM OF THIS FILE IF YOU NEED THEM TO WORK AFTER LOADING FROM A SAVE, SEE LINE 1550 -ish */ \ No newline at end of file diff --git a/objects/obj_en_fleet/Create_0.gml b/objects/obj_en_fleet/Create_0.gml index 8a2abc8731..fa1dba0041 100644 --- a/objects/obj_en_fleet/Create_0.gml +++ b/objects/obj_en_fleet/Create_0.gml @@ -69,3 +69,49 @@ escort_health=100; alarm[8]=1; +#region save/load serialization + +/// Called from save function to take all object variables and convert them to a json savable format and return it +serialize = function(){ + var object_fleet = self; + + var save_data = { + obj: object_get_name(object_index), + x, + y, + } + + var excluded_from_save = ["temp", "serialize", "deserialize", "cargo_data"] + + copy_serializable_fields(object_fleet, save_data, excluded_from_save); + + return save_data; +} +deserialize = function(save_data){ + var exclusions = ["id"]; // skip automatic setting of certain vars, handle explicitly later + + // Automatic var setting + var all_names = struct_get_names(save_data); + var _len = array_length(all_names); + for(var i = 0; i < _len; i++){ + var var_name = all_names[i]; + if(array_contains(exclusions, var_name)){ + continue; + } + var loaded_value = struct_get(save_data, var_name); + // show_debug_message($"en_fleet {en_fleet_instance.id} - var: {var_name} - val: {loaded_value}"); + try { + variable_struct_set(self, var_name, loaded_value); + } catch (e){ + show_debug_message(e); + } + } + + if(save_data.orbiting != 0){ + var nearest_star = instance_nearest(x, y, obj_star); + orbiting = nearest_star; + // show_debug_message($"p_fleet id {id} deserialized: {self}"); + } +} + +#endregion \ No newline at end of file diff --git a/objects/obj_ini/Create_0.gml b/objects/obj_ini/Create_0.gml index 02b38e14d8..28f0479e82 100644 --- a/objects/obj_ini/Create_0.gml +++ b/objects/obj_ini/Create_0.gml @@ -31,6 +31,7 @@ penitent_current=0; penitent_end=0; man_size=0; home_planet = 2; +artifact_struct = array_create(200); // Equipment- maybe the bikes should go here or something? yes they should i=-1; @@ -103,15 +104,156 @@ gene_slaves = []; if (obj_creation.custom=0) then scr_initialize_standard(); }*/ +adv = []; +dis = []; + + if (instance_exists(obj_creation)) then custom=obj_creation.custom; if (global.load=0) then scr_initialize_custom(); +#region save/load serialization + +/// Called from save function to take all object variables and convert them to a json savable format and return it +serialize = function(){ + var object_ini = self; + + var marines = array_create(0); + for(var coy = 0; coy <=10; coy++){ + for(var mar = 0; mar <=500; mar++){ + var marine_json; + if(obj_ini.name[coy][mar] != ""){ + marine_json = jsonify_marine_struct(coy, mar, false); + array_push(marines, marine_json); + } else if(mar > 0){ + break; + } + } + } + var squads = []; + if (array_length(object_ini.squads)> 0){ + for (var i = 0;i < array_length(object_ini.squads);i++){ + array_push(squads, object_ini.squads[i].jsonify(false)); + } + } + + var artifact_struct_trimmed = []; + for(var i = 0; i < array_length(artifact_struct); i++){ + if(artifact_struct[i].name != ""){ + array_push(artifact_struct_trimmed, artifact_struct[i]); + } + } + + + var save_data = { + obj: object_get_name(object_index), + x, + y, + custom_advisors, + full_liveries: full_liveries, + complex_livery_data: complex_livery_data, + squad_types: squad_types, + artifact_struct: artifact_struct_trimmed, + marine_structs: marines, + squad_structs: squads, + // marines, + // squads + } + + if(struct_exists(object_ini, "last_ship")){ + save_data.last_ship = object_ini.last_ship; + } + + var excluded_from_save = ["temp", "serialize", "deserialize", "load_default_gear", "role_spawn_buffs", "TTRPG", "squads", "squad_types", "marines", "last_ship"]; + + copy_serializable_fields(object_ini, save_data, excluded_from_save); + + return save_data; +} +deserialize = function(save_data){ + var exclusions = ["complex_livery_data", "full_liveries", "squad_types", "marine_structs", "squad_structs"]; // skip automatic setting of certain vars, handle explicitly later + // Automatic var setting + var all_names = struct_get_names(save_data); + var _len = array_length(all_names); + for(var i = 0; i < _len; i++){ + var var_name = all_names[i]; + if(array_contains(exclusions, var_name)){ + continue; + } + + var loaded_value = struct_get(save_data, var_name); + // show_debug_message($"obj_ini var: {var_name} - val: {loaded_value}"); + try { + variable_struct_set(obj_ini, var_name, loaded_value); + } catch (e){ + show_debug_message(e); + } + } + + // Set explicit vars here + var livery_picker = new ColourItem(0,0); + livery_picker.scr_unit_draw_data(); + if(struct_exists(save_data, "full_liveries")){ + variable_struct_set(obj_ini, "full_liveries", save_data.full_liveries) + } else { + variable_struct_set(obj_ini, "full_liveries", array_create(21,DeepCloneStruct(livery_picker.map_colour))); + } + + if(struct_exists(save_data, "complex_livery_data")){ + variable_struct_set(obj_ini, "complex_livery_data", save_data.complex_livery_data); + } + if(struct_exists(save_data, "squad_types")){ + variable_struct_set(obj_ini, "squad_types", save_data.squad_types); + } + + if(struct_exists(save_data, "marine_structs")){ + obj_ini.TTRPG = array_create(11, []); + var marines_encoded_arr = save_data.marine_structs; + var _m_ar_len = array_length(marines_encoded_arr); + for(var m = 0; m < _m_ar_len; m++){ + var marine_json = marines_encoded_arr[m]; + var coy = marine_json.company; + var mar = marine_json.marine_number; + load_marine_struct(coy, mar, marine_json); + } + for(var coy = 0; coy < 11; coy++){ + var mar_start = array_length(obj_ini.TTRPG[coy]); + for(var mar = mar_start; mar < 501; mar++){ + obj_ini.TTRPG[coy][mar] = new TTRPG_stats("chapter",coy, mar, "blank"); + } + } + } + + if(struct_exists(save_data, "squad_structs")){ + obj_ini.squads = []; + var squad_fetch = save_data.squad_structs; + for (i=0;i 0)) { if (press == 1) { var del = obj_saveload.save[save]; - var _save_file = $"save{del}.ini"; + var _save_file = string(PATH_save_files, del); + var _save_preview = string(PATH_save_previews, del); if (file_exists(_save_file)) { file_delete(_save_file); if (file_exists($"save{del}log.ini")) { file_delete($"save{del}log.ini"); } - if (file_exists($"screen{del}.png")) { - file_delete($"screen{del}.png"); + if (file_exists(_save_preview)) { + file_delete(_save_preview); } with (obj_saveload) { instance_destroy(); diff --git a/objects/obj_saveload/Alarm_0.gml b/objects/obj_saveload/Alarm_0.gml index 8387bce3da..b5ea475873 100644 --- a/objects/obj_saveload/Alarm_0.gml +++ b/objects/obj_saveload/Alarm_0.gml @@ -4,7 +4,7 @@ if (save_part == 6) { with (obj_controller) { scr_save(5, obj_saveload.save_number); } - trickle = 50; + trickle = 2; } if (save_part == 5) { @@ -13,7 +13,7 @@ if (save_part == 5) { with (obj_controller) { scr_save(4, obj_saveload.save_number); } - trickle = 40; + trickle = 2; save_part = 6; } @@ -23,7 +23,7 @@ if (save_part == 4) { with (obj_controller) { scr_save(3, obj_saveload.save_number); } - trickle = 10; + trickle = 2; save_part = 5; } @@ -33,7 +33,7 @@ if (save_part == 3) { with (obj_controller) { scr_save(2, obj_saveload.save_number); } - trickle = 10; + trickle = 2; save_part = 4; } @@ -43,42 +43,32 @@ if (save_part == 2) { with (obj_controller) { scr_save(1, obj_saveload.save_number); } - trickle = 10; + trickle = 2; save_part = 3; } if (save_part == 1) { - if (file_exists("save" + string(save_number) + ".ini")) { - file_delete("save" + string(save_number) + ".ini"); + if (file_exists(string(PATH_save_files, save_number))) { + file_delete(string(PATH_save_files, save_number)); } - if (file_exists("screen" + string(save_number) + ".png")) { - file_delete("screen" + string(save_number) + ".png"); + if (file_exists(string(PATH_save_previews, save_number))) { + file_delete(string(PATH_save_previews, save_number)); } - ini_open("saves.ini"); - ini_section_delete(string(save_number)); - ini_close(); obj_saveload.save[save_number] = 0; save_part += 1; - trickle = 10; + trickle = 2; txt = "Preparing"; } + if (load_part==6){ txt="Praise to the Machine God"; if (global.restart>0) then txt="Praise be to the Emperor"; with(obj_controller){ + // show_debug_message($"load section 5"); scr_load(5,global.load); - // **sets up starting forge_points - location_viewer = new UnitQuickFindPanel(); - specialist_point_handler.calculate_research_points(); - - //** sets up marine_by_location view - with(obj_controller){ - global.star_name_colors[1] = make_color_rgb(body_colour_replace[0],body_colour_replace[1],body_colour_replace[2]); - sector_imperial_fleet_strength(); - } } - trickle=50; + trickle=2; if (instance_exists(obj_cuicons)){ obj_cuicons.alarm[1]=30; } @@ -91,9 +81,10 @@ if (load_part == 5) { } with (obj_controller) { + // show_debug_message($"load section 4"); scr_load(4, global.load); } - trickle = 10; + trickle = 2; load_part = 6; } @@ -103,9 +94,10 @@ if (load_part == 4) { txt = "Donning Power Armour"; } with (obj_controller) { + // show_debug_message($"load section 3"); scr_load(3, global.load); } - trickle = 40; + trickle = 2; load_part = 5; } @@ -115,9 +107,10 @@ if (load_part == 3) { txt = "Rousing the Machine Spirit"; } with (obj_controller) { + // show_debug_message($"load section 2"); scr_load(2, global.load); } - trickle = 10; + trickle = 2; load_part = 4; } @@ -127,16 +120,17 @@ if (load_part == 2) { txt = "Turtle Waxing Scalp"; } with (obj_controller) { + // show_debug_message($"load section 1"); scr_load(1, global.load); } - trickle = 10; + trickle = 2; load_part = 3; } if (load_part == 1) { - if (file_exists("save" + string(global.load) + ".ini")) { + if (file_exists(string(PATH_save_files, global.load))) { load_part += 1; - trickle = 10; + trickle = 2; txt = "Preparing"; } } diff --git a/objects/obj_saveload/Alarm_2.gml b/objects/obj_saveload/Alarm_2.gml index d89363e8ed..12761deac5 100644 --- a/objects/obj_saveload/Alarm_2.gml +++ b/objects/obj_saveload/Alarm_2.gml @@ -1,5 +1,5 @@ -screen_save("screen"+string(save_number)+".png"); +screen_save(string(PATH_save_previews, save_number)); alarm[3]=1; diff --git a/objects/obj_saveload/Alarm_4.gml b/objects/obj_saveload/Alarm_4.gml index 47ec398f89..96bf520e3a 100644 --- a/objects/obj_saveload/Alarm_4.gml +++ b/objects/obj_saveload/Alarm_4.gml @@ -1,12 +1,24 @@ - - -if (sprite_exists(img1)){sprite_delete(img1);} -if (sprite_exists(img2)){sprite_delete(img2);} -if (sprite_exists(img3)){sprite_delete(img3);} -if (sprite_exists(img4)){sprite_delete(img4);} -if (file_exists(working_directory + "\\screen"+string(save[top])+".png")) then img1=sprite_add(working_directory + "\\screen"+string(save[top])+".png",1,0,0,0,0); -if (file_exists(working_directory + "\\screen"+string(save[top+1])+".png")) then img2=sprite_add(working_directory + "\\screen"+string(save[top+1])+".png",1,0,0,0,0); -if (file_exists(working_directory + "\\screen"+string(save[top+2])+".png")) then img3=sprite_add(working_directory + "\\screen"+string(save[top+2])+".png",1,0,0,0,0); -if (file_exists(working_directory + "\\screen"+string(save[top+3])+".png")) then img4=sprite_add(working_directory + "\\screen"+string(save[top+3])+".png",1,0,0,0,0); - - +if (sprite_exists(img1)) { + sprite_delete(img1); +} +if (sprite_exists(img2)) { + sprite_delete(img2); +} +if (sprite_exists(img3)) { + sprite_delete(img3); +} +if (sprite_exists(img4)) { + sprite_delete(img4); +} +if (file_exists(string(PATH_save_previews, save[top]))) { + img1 = sprite_add(string(PATH_save_previews, save[top]), 1, 0, 0, 0, 0); +} +if (file_exists(string(PATH_save_previews, save[top + 1]) + ".png")) { + img2 = sprite_add(string(PATH_save_previews, save[top + 1]), 1, 0, 0, 0, 0); +} +if (file_exists(string(PATH_save_previews, save[top + 2]) + ".png")) { + img3 = sprite_add(string(PATH_save_previews, save[top + 2]), 1, 0, 0, 0, 0); +} +if (file_exists(string(PATH_save_previews, save[top + 3]))) { + img4 = sprite_add(string(PATH_save_previews, save[top + 3]), 1, 0, 0, 0, 0); +} diff --git a/objects/obj_saveload/Create_0.gml b/objects/obj_saveload/Create_0.gml index 55b6d46ea5..2dccd61d34 100644 --- a/objects/obj_saveload/Create_0.gml +++ b/objects/obj_saveload/Create_0.gml @@ -1,10 +1,18 @@ scr_image("loading",-50,0,0,0,0); +GameSave = {}; +GameSave.Stars = []; +GameSave.PlayerFleet = []; +GameSave.EnemyFleet = []; +GameSave.Ini = {}; +GameSave.Controller = {}; +GameSave.EventLog = []; menu=0;// 1 : save, 2: load save_part=0; load_part=0; save_number=0; +/// number of frames between load sections to draw the progress bar trickle=0; txt=""; hide=0; @@ -45,12 +53,11 @@ repeat(201){i+=1; } i=0; repeat(100){i+=1; - if (file_exists("save"+string(i)+".ini")){ + if (file_exists(string(PATH_save_files, i))){ saves+=1;save[saves]=i; } - if (!file_exists("save"+string(i)+".ini")) and (i>0) and (max_ini=0) then max_ini=i; - if (file_exists("save"+string(i+1)+".ini")) and (max_ini>0) then max_ini=0; -} + if (!file_exists(string(PATH_save_files, i))) and (i>0) and (max_ini=0) then max_ini=i; + if (file_exists(string(PATH_save_files, i + 1))) and (max_ini>0) then max_ini=0;} first_open=saves+1; @@ -96,10 +103,18 @@ if (file_exists("saves.ini")){ } - if (file_exists(working_directory + "\\screen"+string(save[1])+".png")) then img1=sprite_add(working_directory + "\\screen"+string(save[1])+".png",1,0,0,0,0); - if (file_exists(working_directory + "\\screen"+string(save[2])+".png")) then img2=sprite_add(working_directory + "\\screen"+string(save[2])+".png",1,0,0,0,0); - if (file_exists(working_directory + "\\screen"+string(save[3])+".png")) then img3=sprite_add(working_directory + "\\screen"+string(save[3])+".png",1,0,0,0,0); - if (file_exists(working_directory + "\\screen"+string(save[4])+".png")) then img4=sprite_add(working_directory + "\\screen"+string(save[4])+".png",1,0,0,0,0); + if (file_exists(string(PATH_save_previews, save[1]))) { + img1 = sprite_add(string(PATH_save_previews, save[1]), 1, 0, 0, 0, 0); + } + if (file_exists(string(PATH_save_previews, save[2]))) { + img2 = sprite_add(string(PATH_save_previews, save[2]), 1, 0, 0, 0, 0); + } + if (file_exists(string(PATH_save_previews, save[3]))) { + img3 = sprite_add(string(PATH_save_previews, save[3]), 1, 0, 0, 0, 0); + } + if (file_exists(string(PATH_save_previews, save[4]))) { + img4 = sprite_add(string(PATH_save_previews, save[4]), 1, 0, 0, 0, 0); + } ini_close(); diff --git a/objects/obj_saveload/Draw_0.gml b/objects/obj_saveload/Draw_0.gml index bed4329373..575a63a5e4 100644 --- a/objects/obj_saveload/Draw_0.gml +++ b/objects/obj_saveload/Draw_0.gml @@ -151,20 +151,31 @@ if (menu=1) or (menu=2){// This is the other one draw_set_font(fnt_40k_30b);draw_set_halign(fa_center); - if (save[o]>0){ + if (save[o] > 0) { // Delete Data draw_set_alpha(1); - draw_set_color(c_gray);draw_rectangle(x2+807,y2+113,x2+951,y2+146,0); - draw_set_color(c_black);draw_rectangle(x2+807,y2+113,x2+951,y2+146,1); - draw_text_transformed(x2+879,y2+117,string_hash_to_newline("Delete Game"),0.7,0.7,0); - if (scr_hit(x2+807,y2+113,x2+951,y2+146)=true){ - draw_set_alpha(0.1);draw_set_color(c_white);draw_rectangle(x2+807,y2+113,x2+951,y2+146,0);draw_set_alpha(1); - if (mouse_left>=1) and (!instance_exists(obj_popup)) and (cooldown<=0){// Clear - var com;com=instance_create(0,0,obj_popup); - com.image="fuklaw";com.title="Delete Save Game?"; - com.text="Are you sure you wish to delete Save "+string(save[o])+"- "+string(save_chapter[save[o]])+"?"; - com.option1="Yes";com.option2="No";com.save=o; - com.woopwoopwoop=menu;com.owner=top; + draw_set_color(c_gray); + draw_rectangle(x2 + 807, y2 + 113, x2 + 951, y2 + 146, 0); + draw_set_color(c_black); + draw_rectangle(x2 + 807, y2 + 113, x2 + 951, y2 + 146, 1); + draw_text_transformed(x2 + 879, y2 + 117, string_hash_to_newline("Delete Game"), 0.7, 0.7, 0); + if (scr_hit(x2 + 807, y2 + 113, x2 + 951, y2 + 146) == true) { + draw_set_alpha(0.1); + draw_set_color(c_white); + draw_rectangle(x2 + 807, y2 + 113, x2 + 951, y2 + 146, 0); + draw_set_alpha(1); + if ((mouse_left >= 1) && (!instance_exists(obj_popup)) && (cooldown <= 0)) { + // Clear + var com; + com = instance_create(0, 0, obj_popup); + com.image = "fuklaw"; + com.title = "Delete Save Game?"; + com.text = "Are you sure you wish to delete Save " + string(save[o]) + "- " + string(save_chapter[save[o]]) + "?"; + com.option1 = "Yes"; + com.option2 = "No"; + com.save = o; + com.woopwoopwoop = menu; + com.owner = top; } } } @@ -178,7 +189,7 @@ if (menu=1) or (menu=2){// This is the other one if (scr_hit(x2+977,y2+113,x2+1121,y2+146)=true){ draw_set_alpha(0.1);draw_set_color(c_white);draw_rectangle(x2+977,y2+113,x2+1121,y2+146,0);draw_set_alpha(1); if (mouse_left>=1) and (!instance_exists(obj_popup)) and (cooldown<=0){ - if (file_exists("save"+string(save[o])+".ini")){// Resets the data + if (file_exists(string(PATH_save_files, save[o]))) { // Resets the data global.restart=1;global.load=save[o]; menu=0;load_part=1;obj_cursor.image_alpha=0;splash=choose(0,1,2,3,4); @@ -212,7 +223,7 @@ if (menu=1) or (menu=2){// This is the other one if (mouse_left>=1) and (!instance_exists(obj_popup)) and (cooldown<=0){// Load global.load=save[o];menu=0;load_part=1;obj_cursor.image_alpha=0;splash=choose(0,1,2,3,4); - // show_message("loading 'save"+string(save[o])+".ini'"); + // show_message("loading 'save"+string(save[o])+".json'"); if (instance_exists(obj_main_menu)){ with(obj_main_menu){ @@ -245,7 +256,7 @@ if (menu=1) or (menu=2){// This is the other one if (instance_exists(obj_main_menu)){with(obj_main_menu){part_particles_clear(p_system);}} // If open slot then set the save.ini to the maximum - if (!file_exists("save"+string(save[o])+".ini")) or (save[o]=0) and (onceh=0){ + if (!file_exists(string(PATH_save_files, save[o])) || (save[o] == 0) && (onceh == 0)) { save_part=1;menu=0;save_number=max_ini;obj_cursor.image_alpha=0;splash=choose(0,1,2,3,4); with(obj_new_button){instance_destroy();} with(obj_ingame_menu){instance_destroy();} @@ -253,14 +264,27 @@ if (menu=1) or (menu=2){// This is the other one alarm[0]=1;onceh=1; } // If file exists then overright - if (file_exists("save"+string(save[o])+".ini")){file_delete("save"+string(save[o])+".ini"); - if (file_exists("screen"+string(save[o])+".png")) then file_delete("screen"+string(save[o])+".png"); - save_part=1;menu=0;save_number=o;obj_cursor.image_alpha=0;splash=choose(0,1,2,3,4); - with(obj_new_button){instance_destroy();} - with(obj_ingame_menu){instance_destroy();} + if (file_exists(string(PATH_save_files, save[o]))) { + file_delete(string(PATH_save_files, save[o])); + if (file_exists(string(PATH_save_previews, save[o]))) { + file_delete(string(PATH_save_previews, save[o])); + } + save_part = 1; + menu = 0; + save_number = o; + obj_cursor.image_alpha = 0; + splash = choose(0, 1, 2, 3, 4); + with (obj_new_button) { + instance_destroy(); + } + with (obj_ingame_menu) { + instance_destroy(); + } // Other here - alarm[0]=1;onceh=1; + alarm[0] = 1; + onceh = 1; } + } } } diff --git a/objects/obj_saveload/Mouse_60.gml b/objects/obj_saveload/Mouse_60.gml index 387b296751..2d793b8414 100644 --- a/objects/obj_saveload/Mouse_60.gml +++ b/objects/obj_saveload/Mouse_60.gml @@ -2,14 +2,29 @@ if (slow<0) then slow=0; slow+=1; -if (slow>=3){ - if (top>1){top-=1; - if (sprite_exists(img4)){sprite_delete(img4);} - img4=img3;img3=img2;img2=img1; - if (file_exists(working_directory + "\\screen"+string(save[top])+".png")) then img1=sprite_add(working_directory + "\\screen"+string(save[top])+".png",1,0,0,0,0); - if (!sprite_exists(img3)) and (file_exists(working_directory + "\\screen"+string(save[top+2])+".png")) then img3=sprite_add(working_directory + "\\screen"+string(save[top+3])+".png",1,0,0,0,0); - if (!sprite_exists(img2)) and (file_exists(working_directory + "\\screen"+string(save[top+1])+".png")) then img2=sprite_add(working_directory + "\\screen"+string(save[top+2])+".png",1,0,0,0,0); - if (!sprite_exists(img1)) and (file_exists(working_directory + "\\screen"+string(save[top])+".png")) then img1=sprite_add(working_directory + "\\screen"+string(save[top])+".png",1,0,0,0,0); - } +if (slow >= 3) { + if (top > 1) { + top -= 1; + if (sprite_exists(img4)) { + sprite_delete(img4); + } + img4 = img3; + img3 = img2; + img2 = img1; + if (file_exists(string(PATH_save_previews, save[top]))) { + img1 = sprite_add(string(PATH_save_previews, save[top]), 1, 0, 0, 0, 0); + } + + if ((!sprite_exists(img3)) && file_exists(string(PATH_save_previews, save[top + 2]))) { + img3 = sprite_add(string(PATH_save_previews, save[top + 3]), 1, 0, 0, 0, 0); + } + + if ((!sprite_exists(img2)) && file_exists(string(PATH_save_previews, save[top + 1]))) { + img2 = sprite_add(string(PATH_save_previews, save[top + 2]), 1, 0, 0, 0, 0); + } + + if ((!sprite_exists(img1)) && file_exists(string(PATH_save_previews, save[top]))) { + img1 = sprite_add(string(PATH_save_previews, save[top]), 1, 0, 0, 0, 0); + } + } } - diff --git a/objects/obj_saveload/Mouse_61.gml b/objects/obj_saveload/Mouse_61.gml index d9f929549a..cf9aba8af7 100644 --- a/objects/obj_saveload/Mouse_61.gml +++ b/objects/obj_saveload/Mouse_61.gml @@ -9,10 +9,18 @@ if (slow<=-3){ if (sprite_exists(img4)){sprite_delete(img4);} - if (file_exists(working_directory + "\\screen"+string(save[top+3])+".png")) then img4=sprite_add(working_directory + "\\screen"+string(save[top+3])+".png",1,0,0,0,0); - if (!sprite_exists(img3)) and (file_exists(working_directory + "\\screen"+string(save[top+2])+".png")) then img3=sprite_add(working_directory + "\\screen"+string(save[top+2])+".png",1,0,0,0,0); - if (!sprite_exists(img2)) and (file_exists(working_directory + "\\screen"+string(save[top+1])+".png")) then img2=sprite_add(working_directory + "\\screen"+string(save[top+1])+".png",1,0,0,0,0); - if (!sprite_exists(img1)) and (file_exists(working_directory + "\\screen"+string(save[top])+".png")) then img1=sprite_add(working_directory + "\\screen"+string(save[top])+".png",1,0,0,0,0); + if (file_exists(string(PATH_save_previews, save[top + 3]))) { + img4 = sprite_add(string(PATH_save_previews, save[top + 3]), 1, 0, 0, 0, 0); + } + if ((!sprite_exists(img3)) && file_exists(string(PATH_save_previews, save[top + 2]))) { + img3 = sprite_add(string(PATH_save_previews, save[top + 2]), 1, 0, 0, 0, 0); + } + if ((!sprite_exists(img2)) && file_exists(string(PATH_save_previews, save[top + 1]))) { + img2 = sprite_add(string(PATH_save_previews, save[top + 1]), 1, 0, 0, 0, 0); + } + if ((!sprite_exists(img1)) && file_exists(string(PATH_save_previews, save[top]))) { + img1 = sprite_add(string(PATH_save_previews, save[top]), 1, 0, 0, 0, 0); + } diff --git a/objects/obj_saveload/Step_0.gml b/objects/obj_saveload/Step_0.gml index cb0b22e0a1..7879a85777 100644 --- a/objects/obj_saveload/Step_0.gml +++ b/objects/obj_saveload/Step_0.gml @@ -6,11 +6,13 @@ if (reset>=50){ } if (trickle>-1){ - + var save_parts = 6; + + trickle-=1; - if (trickle>0) then bar+=1; + if (trickle>0) then bar+= min(100, round(100/save_parts)); if (trickle=0) then alarm[0]=1; - if (bar+1>=100) and (bar!=100){trickle=-1;bar=100;alarm[0]=-1;alarm[1]=20;} + if (bar>=100){trickle=-1;bar=100;alarm[0]=-1;alarm[1]=5;} } diff --git a/objects/obj_star/Create_0.gml b/objects/obj_star/Create_0.gml index af92514adc..fc9661bf67 100644 --- a/objects/obj_star/Create_0.gml +++ b/objects/obj_star/Create_0.gml @@ -109,3 +109,101 @@ global.star_name_colors = [ #AD5272, //why 12 is skipped in general, we will never know #80FF00 // Sleepy robots ] + + +#region save/load serialization + +/// Called from save function to take all object variables and convert them to a json savable format and return it +serialize = function(){ + var object_star = self; + + var planet_data = []; + + for(var p = 1; p <= object_star.planets; p++){ + planet_data[p] = { + dispo: object_star.dispo[p], + planet: object_star.planet[p], + }; + var var_names = variable_struct_get_names(object_star); + for(var n = 0; n < array_length(var_names); n++){ + var var_name = var_names[n]; + if(string_starts_with(var_name, "p_")){ + var val = object_star[$var_name][p]; + variable_struct_set(planet_data[p], var_name, val); + } + } + } + + + var save_data = { + obj: object_get_name(object_index), + x, + y, + present_fleet: object_star.present_fleet, + planet_data: planet_data, + } + if(struct_exists(object_star, "system_garrison")){ + save_data.system_garrison = object_star.system_garrison; + } + if(struct_exists(object_star, "system_sabatours")){ + save_data.system_sabatours = object_star.system_sabatours; + } + + + var excluded_from_save = ["temp", "serialize", "deserialize", "arraysum"]; + var excluded_from_save_start = ["p_"]; + + copy_serializable_fields(object_star, save_data, excluded_from_save, excluded_from_save_start); + + return save_data; +} + +function deserialize(save_data){ + var exclusions = ["id", "present_fleet", "planet_data"]; // skip automatic setting of certain vars, handle explicitly later + + // Automatic var setting + var all_names = struct_get_names(save_data); + var _len = array_length(all_names); + for(var i = 0; i < _len; i++){ + var var_name = all_names[i]; + if(array_contains(exclusions, var_name)){ + continue; + } + var loaded_value = struct_get(save_data, var_name); + variable_struct_set(self, var_name, loaded_value); + } + + // Set explicit vars here + if(struct_exists(save_data, "present_fleet")){ + variable_struct_set(self, "present_fleet", save_data.present_fleet); + } + + if(struct_exists(save_data, "planet_data")){ + var planet_arr = save_data.planet_data; + var _len = array_length(planet_arr); + for(var p = 1; p < _len; p++){ + var planet = planet_arr[p]; + var var_names = struct_get_names(planet); + for(var v = 0; v < array_length(var_names); v++){ + var var_name = var_names[v]; + var val = planet[$var_name]; + // var_name = "p_type" + // planet = {"p_type":"hive"}; + // val = planet[$var_name] = "hive" + + self[$var_name][p] = val; + // variable_struct_set(self, var_name, planet[$var_name]); + } + } + } + + if(struct_exists(save_data, "system_sabatours")){ + variable_struct_set(self, "system_sabatours", save_data.system_sabatours); + } + if(struct_exists(save_data, "system_garrison")){ + variable_struct_set(self, "system_garrison", save_data.system_garrison); + } + +} + +#endregion \ No newline at end of file diff --git a/scripts/__init_external/__init_external.gml b/scripts/__init_external/__init_external.gml index 72356b55f5..acba85bf39 100644 --- a/scripts/__init_external/__init_external.gml +++ b/scripts/__init_external/__init_external.gml @@ -21,7 +21,12 @@ function __init_external() { if (!directory_exists("Custom Files\\Custom Icons")) { directory_create("Custom Files\\Custom Icons"); } + if (!directory_exists("Save Files")) { + directory_create("Save Files"); + } + #macro PATH_save_files "Save Files\\save{0}.json" + #macro PATH_save_previews "Save Files\\screen{0}.png" #macro PATH_custom_icons $"Custom Files\\Custom Icons\\custom" #macro PATH_last_messages $"Logs/last_messages.log" diff --git a/scripts/scr_array_functions/scr_array_functions.gml b/scripts/scr_array_functions/scr_array_functions.gml index dda5d22fa6..6afd8656d8 100644 --- a/scripts/scr_array_functions/scr_array_functions.gml +++ b/scripts/scr_array_functions/scr_array_functions.gml @@ -189,3 +189,27 @@ function smart_delimeter_sign(_array_or_length, _loop_iteration, _dot_end = true return _delimeter; } + +/// @description Checks whether an array is "simple," meaning it does not exceed a specified depth and contains only simple variables. Recursively evaluates nested arrays. +/// @param {array} _array - The array to check. +/// @param {real} _max_depth - The maximum allowed depth for the array. +/// @param {real} _current_depth (DON'T PASS ANYTHING) The current recursion depth, used internally. +/// @returns {bool} +function is_basic_array(_array, _max_depth = 1, _current_depth = 1) { + if (_current_depth > _max_depth) { + return false; + } + + for (var i = 0, _len = array_length(_array); i < _len; i++) { + var _var = _array[i]; + if (is_array(_var)) { + if (!is_basic_array(_var, _max_depth, _current_depth + 1)) { + return false; + } + } else if (!is_basic_variable(_var)) { + return false; + } + } + + return true; +} diff --git a/scripts/scr_company_order/scr_company_order.gml b/scripts/scr_company_order/scr_company_order.gml index bd31adabaa..c2ea440780 100644 --- a/scripts/scr_company_order/scr_company_order.gml +++ b/scripts/scr_company_order/scr_company_order.gml @@ -47,7 +47,7 @@ function sort_all_companies(){ } } function scr_company_order(company) { - try_and_report_loop("company order", function(company){ + try_and_report_loop($"company order {company}", function(company){ // company : company number // This sorts and crunches the marine variables for the company diff --git a/scripts/scr_general_variable_functions/scr_general_variable_functions.gml b/scripts/scr_general_variable_functions/scr_general_variable_functions.gml new file mode 100644 index 0000000000..10d2c15fab --- /dev/null +++ b/scripts/scr_general_variable_functions/scr_general_variable_functions.gml @@ -0,0 +1,4 @@ +/// @description Checks if a variable is a simple data type (number, string, or boolean). +function is_basic_variable(_variable) { + return is_numeric(_variable) || is_string(_variable); +} diff --git a/scripts/scr_general_variable_functions/scr_general_variable_functions.yy b/scripts/scr_general_variable_functions/scr_general_variable_functions.yy new file mode 100644 index 0000000000..f968da3922 --- /dev/null +++ b/scripts/scr_general_variable_functions/scr_general_variable_functions.yy @@ -0,0 +1,13 @@ +{ + "$GMScript":"v1", + "%Name":"scr_general_variable_functions", + "isCompatibility":false, + "isDnD":false, + "name":"scr_general_variable_functions", + "parent":{ + "name":"Scripts", + "path":"folders/Scripts.yy", + }, + "resourceType":"GMScript", + "resourceVersion":"2.0", +} \ No newline at end of file diff --git a/scripts/scr_load/scr_load.gml b/scripts/scr_load/scr_load.gml index 9ad49b32bb..322d523f2e 100644 --- a/scripts/scr_load/scr_load.gml +++ b/scripts/scr_load/scr_load.gml @@ -1,616 +1,152 @@ -function return_json_from_ini(ini_area,ini_code, default_val=[]){ - var ini_fetch = ini_read_string(ini_area,ini_code,""); - if (ini_fetch!=""){ - return json_parse(base64_decode(ini_fetch)); - } else { - return default_val; - } -} +function load_marine_struct(company, marine, struct){ -function load_marine_struct(company, marine){ - var marStruct = ini_read_string("Mar","Struct"+string(company)+"."+string(marine),""); - if (marStruct != ""){ - marStruct = json_parse(base64_decode(marStruct)); - obj_ini.TTRPG[company, marine] = new TTRPG_stats("chapter", company, marine, "blank"); - obj_ini.TTRPG[company, marine].load_json_data(marStruct); - delete marStruct; - } else { - obj_ini.TTRPG[company, marine] = new TTRPG_stats("chapter", company, marine,"blank"); - } + obj_ini.TTRPG[company, marine] = new TTRPG_stats("chapter", company, marine, "blank"); + obj_ini.TTRPG[company, marine].load_json_data(struct); + }; function scr_load(save_part, save_id) { - var unit; - var rang=0,stars=0,pfleets=0,efleets=0; - - - - if (save_part=1) or (save_part=0){ - scr_load_controller(save_id); + var t1 = get_timer(); + var filename = string(PATH_save_files, save_id); + if(file_exists(filename)){ + var _gamesave_buffer = buffer_load(filename); + var _gamesave_string = buffer_read(_gamesave_buffer, buffer_string); + var json_game_save = json_parse(_gamesave_string); } - - if (save_part=2) or (save_part=0){ - log_message("Loading slot "+string(save_id)+" part 2"); - ini_open("tsave.ini"); - - stars=ini_read_real("Save","stars",0); - - // Stars - var i=-1; - repeat(stars){i+=1; - var new_star; - new_star=instance_create( - ini_read_real("Star",$"sr{i}x",0), - ini_read_real("Star",$"sr{i}y",0), - obj_star - ); - - new_star.name=ini_read_string("Star",$"sr{i}name",""); - new_star.star=ini_read_string("Star",$"sr{i}star",""); - new_star.planets=ini_read_real("Star",$"sr{i}planets",0); - new_star.owner=ini_read_real("Star",$"sr{i}owner",0); - new_star.x2=ini_read_real("Star",$"sr{i}x2",0); - new_star.y2=ini_read_real("Star",$"sr{i}y2",0); - new_star.old_x=ini_read_real("Star",$"sr{i}ox",0); - new_star.old_y=ini_read_real("Star",$"sr{i}oy",0); - new_star.warp_lanes = return_json_from_ini("Star",$"sr{i}warp_lanes",[]); - - new_star.vision=ini_read_real("Star",$"sr{i}vision",1); - new_star.storm=ini_read_real("Star",$"sr{i}storm",0); - new_star.trader=ini_read_real("Star",$"sr{i}trader",0); - new_star.craftworld=ini_read_real("Star",$"sr{i}craftworld",0); - new_star.space_hulk=ini_read_real("Star",$"sr{i}spacehulk",0); - if (new_star.space_hulk=1) then new_star.sprite_index=spr_star_hulk; - new_star.present_fleet=ini_read_string("Star",$"sr{i}present_fleets",""); - if (new_star.present_fleet!=""){ - new_star.present_fleet = json_parse(base64_decode(new_star.present_fleet)); - } else { - new_star.present_fleet = array_create(30, 0); - } - - var g=0; - repeat(4){g+=1; - if (new_star.planets>=g){ - new_star.planet[g]=ini_read_real("Star",$"sr{i}plan"+string(g),0); - new_star.dispo[g]=ini_read_real("Star",$"sr{i}dispo"+string(g),-10); - new_star.p_type[g]=ini_read_string("Star",$"sr{i}type"+string(g),""); - new_star.p_feature[g] = []; - var p_features = ini_read_string("Star",$"sr{i}feat"+string(g),""); - if (p_features != ""){ - var p_features = json_parse(base64_decode(p_features)); - for (var feat = 0;feat < array_length(p_features);feat++){ - var new_feat = new NewPlanetFeature(p_features[feat].f_type); - new_feat.load_json_data(p_features[feat]); - array_push(new_star.p_feature[g], new_feat); - } - } - new_star.p_owner[g]=ini_read_real("Star",$"sr{i}own"+string(g),0); - new_star.p_first[g]=ini_read_real("Star",$"sr{i}fir"+string(g),0); - new_star.p_population[g]=ini_read_real("Star",$"sr{i}popul"+string(g),0); - new_star.p_max_population[g]=ini_read_real("Star",$"sr{i}maxpop"+string(g),0); - new_star.p_large[g]=ini_read_real("Star",$"sr{i}large"+string(g),0); - new_star.p_pop[g]=ini_read_string("Star",$"sr{i}pop"+string(g),""); - new_star.p_guardsmen[g]=ini_read_real("Star",$"sr{i}guard"+string(g),0); - new_star.p_pdf[g]=ini_read_real("Star",$"sr{i}pdf"+string(g),0); - new_star.p_fortified[g]=ini_read_real("Star",$"sr{i}forti"+string(g),0); - new_star.p_station[g]=ini_read_real("Star",$"sr{i}stat"+string(g),0); - - new_star.p_player[g]=ini_read_real("Star",$"sr{i}play"+string(g),0); - new_star.p_lasers[g]=ini_read_real("Star",$"sr{i}p_lasers"+string(g),0); - new_star.p_silo[g]=ini_read_real("Star",$"sr{i}p_silo"+string(g),0); - new_star.p_defenses[g]=ini_read_real("Star",$"sr{i}p_defenses"+string(g),0); - new_star.p_operatives[g]=ini_read_string("Star",$"sr{i}operatives"+string(g),0); - if (new_star.p_operatives[g]!=0){ - new_star.p_operatives[g] = json_parse(base64_decode(new_star.p_operatives[g])) - } - new_star.p_upgrades[g] = []; - var p_upgrades = ini_read_string("Star",$"sr{i}upg"+string(g),""); - if (p_upgrades != ""){ - var p_upgrades = json_parse(base64_decode(p_upgrades)); - for (var feat = 0;feat < array_length(p_upgrades);feat++){ - var new_feat = new NewPlanetFeature(p_upgrades[feat].f_type); - new_feat.load_json_data(p_upgrades[feat]); - array_push(new_star.p_upgrades[g], new_feat); - } - } - - new_star.p_orks[g]=ini_read_real("Star",$"sr{i}or"+string(g),0); - new_star.p_tau[g]=ini_read_real("Star",$"sr{i}ta"+string(g),0); - new_star.p_eldar[g]=ini_read_real("Star",$"sr{i}el"+string(g),0); - new_star.p_traitors[g]=ini_read_real("Star",$"sr{i}tr"+string(g),0); - new_star.p_chaos[g]=ini_read_real("Star",$"sr{i}ch"+string(g),0); - new_star.p_demons[g]=ini_read_real("Star",$"sr{i}de"+string(g),0); - new_star.p_sisters[g]=ini_read_real("Star",$"sr{i}si"+string(g),0); - new_star.p_necrons[g]=ini_read_real("Star",$"sr{i}ne"+string(g),0); - new_star.p_tyranids[g]=ini_read_real("Star",$"sr{i}tyr"+string(g),0); - new_star.p_halp[g]=ini_read_real("Star",$"sr{i}halp"+string(g),0); - - new_star.p_heresy[g]=ini_read_real("Star",$"sr{i}heresy"+string(g),0); - new_star.p_hurssy[g]=ini_read_real("Star",$"sr{i}hurssy"+string(g),0); - new_star.p_hurssy_time[g]=ini_read_real("Star",$"sr{i}hurssy_time"+string(g),0); - new_star.p_heresy_secret[g]=ini_read_real("Star",$"sr{i}heresy_secret"+string(g),0); - new_star.p_influence[g]=ini_read_string("Star",$"sr{i}influence"+string(g),""); - if (new_star.p_influence[g] != ""){ - new_star.p_influence[g]=json_parse(base64_decode(new_star.p_influence[g])); - } else { - new_star.p_influence[g] = array_create(15, 0); - } - new_star.p_raided[g]=ini_read_real("Star",$"sr{i}raided"+string(g),0); - - - for (var p=0;p<8;p++){ - new_star.p_problem[g,p]=ini_read_string("Star",$"sr{i}prob{g}.{p}",""); - new_star.p_timer[g,p]=ini_read_real("Star",$"sr{i}time{g}.{p}",-1); - new_star.p_problem_other_data[g,p]=ini_read_string("Star",$"sr{i}prob_other{g}.{p}",""); - if (new_star.p_problem_other_data[g][p]!=""){ - new_star.p_problem_other_data[g][p] = json_parse(base64_decode(new_star.p_problem_other_data[g][p])); - } else { - new_star.p_problem_other_data[g][p]={}; - } - } - } - } - } - - - // obj_ini - //TODO allow methods to be passed as teh default to return_json_from_ini to optomise load speed - var livery_picker = new ColourItem(0,0); - livery_picker.scr_unit_draw_data(); - obj_ini.full_liveries = return_json_from_ini("Ini", "full_liveries",array_create(21,DeepCloneStruct(livery_picker.map_colour))); - obj_ini.culture_styles = return_json_from_ini("Ini", "styles", []); - obj_ini.custom_advisors = return_json_from_ini("Ini", "custom_advisors",{}); - obj_ini.home_name=ini_read_string("Ini","home_name","Error"); - obj_ini.home_type=ini_read_string("Ini","home_type","Error"); - obj_ini.recruiting_name=ini_read_string("Ini","recruiting_name","Error"); - obj_ini.recruiting_type=ini_read_string("Ini","recruiting_type","Error"); - obj_ini.chapter_name=ini_read_string("Ini","chapter_name","Error"); - obj_ini.fortress_name=ini_read_string("Ini","fortress_name","Error"); - obj_ini.flagship_name=ini_read_string("Ini","flagship_name","Error"); - obj_ini.icon=ini_read_real("Ini","icon",0); - obj_ini.icon_name=ini_read_string("Ini","icon_name","custom1"); - global.icon_name=obj_ini.icon_name; - obj_ini.man_size=ini_read_real("Ini","man_size",0); - // obj_ini.strin=ini_read_string("Ini","strin1",""); - // obj_ini.strin2=ini_read_string("Ini","strin2",""); - obj_ini.psy_powers=ini_read_string("Ini","psy_powers","librarius"); - - - global.chapter_icon_sprite = ini_read_real("Ini", "global_chapter_icon_sprite", spr_icon_chapters); - global.chapter_icon_frame = ini_read_real("Ini", "global_chapter_icon_frame", 0); - global.chapter_icon_path = ini_read_string("Ini", "global_chapter_icon_path", "Error"); - global.chapter_icon_filename = ini_read_real("Ini", "global_chapter_icon_filename", 0); + if(!struct_exists(obj_saveload.GameSave, "Save")){ + obj_saveload.GameSave = json_game_save; + } + if (save_part=1) or (save_part=0){ + log_message("Loading GLOBALS"); + // Globals + var globals = obj_saveload.GameSave.Save; + global.chapter_icon_sprite = spr_icon_chapters; + global.chapter_icon_frame = globals.chapter_icon_frame; + global.chapter_icon_path = globals.chapter_icon_path; + global.chapter_icon_filename = globals.chapter_icon_filename; + global.icon_name=globals.icon_name; + global.chapter_name = globals.chapter_name; + global.custom = globals.custom; if(global.chapter_icon_path != "Error" && global.chapter_icon_path != "") { global.chapter_icon_sprite = scr_image_cache(global.chapter_icon_path, global.chapter_icon_filename); } else { global.chapter_icon_sprite = spr_icon_chapters; } + // global.icon = globals.icon; + - obj_ini.companies=ini_read_real("Ini","companies",10); - obj_ini.company_title = return_json_from_ini("Ini","comp_title",array_create(21,"")); + } - obj_ini.gene_slaves = return_json_from_ini("Ini","gene_slaves",[]); - - obj_ini.complex_livery_data=ini_read_string("Ini","complex_livery",""); - if (obj_ini.complex_livery_data!=""){ - obj_ini.complex_livery_data=json_parse(base64_decode(obj_ini.complex_livery_data)); - } else{ - //TODO centralise and initialisation method for this other reference place is obj_creation create - obj_ini.complex_livery_data = complex_livery_default(); - } - var colour_temp = new ColourItem(0,0); - obj_ini.full_liveries = return_json_from_ini("Ini", "FullLivery",colour_temp.scr_unit_draw_data()); - // - obj_ini.preomnor=ini_read_real("Ini","preomnor",0); - obj_ini.voice=ini_read_real("Ini","voice",0); - obj_ini.doomed=ini_read_real("Ini","doomed",0); - obj_ini.lyman=ini_read_real("Ini","lyman",0); - obj_ini.omophagea=ini_read_real("Ini","omophagea",0); - obj_ini.ossmodula=ini_read_real("Ini","ossmodula",0); - obj_ini.membrane=ini_read_real("Ini","membrane",0); - obj_ini.zygote=ini_read_real("Ini","zygote",0); - obj_ini.betchers=ini_read_real("Ini","betchers",0); - obj_ini.catalepsean=ini_read_real("Ini","catalepsean",0); - obj_ini.secretions=ini_read_real("Ini","secretions",0); - obj_ini.occulobe=ini_read_real("Ini","occulobe",0); - obj_ini.mucranoid=ini_read_real("Ini","mucranoid",0); - // - obj_ini.master_name=ini_read_string("Ini","master_name","Error"); - obj_ini.chief_librarian_name=ini_read_string("Ini","chief_name","Error"); - obj_ini.high_chaplain_name=ini_read_string("Ini","high_name","Error"); - obj_ini.high_apothecary_name=ini_read_string("Ini","high2_name","Error"); - obj_ini.forge_master_name=ini_read_string("Ini","forgey_name","Error"); - obj_ini.lord_admiral_name=ini_read_string("Ini","lord_name","Error"); - obj_ini.previous_forge_masters=ini_read_string("Ini","previous_forge_masters",[]); - if (!is_array(obj_ini.previous_forge_masters)){ - obj_ini.previous_forge_masters=json_parse(base64_decode(obj_ini.previous_forge_masters)); - } - // - // - obj_ini.equipment=return_json_from_ini("Ini",$"equipment", array_create(200,"")) - obj_ini.equipment_type=return_json_from_ini("Ini",$"equipment_type", array_create(200,"")) - obj_ini.equipment_number=return_json_from_ini("Ini",$"equipment_number", array_create(200,"")) - obj_ini.equipment_condition=return_json_from_ini("Ini",$"equipment_condition",array_create(200,"")) - obj_ini.equipment_quality = return_json_from_ini("Ini", $"equipment_quality", array_create(200,"")) + if (save_part=2) or (save_part=0){ + log_message("Loading STARS"); - for (var g=0; g0) then obj_ini.race[coh,mah]=1; - } - - obj_ini.wep1[coh,mah]=ini_read_string("Mar","w1"+string(coh)+"."+string(mah),""); - obj_ini.wep2[coh,mah]=ini_read_string("Mar","w2"+string(coh)+"."+string(mah),""); - obj_ini.armour[coh,mah]=ini_read_string("Mar","ar"+string(coh)+"."+string(mah),""); - obj_ini.gear[coh,mah]=ini_read_string("Mar","ge"+string(coh)+"."+string(mah),""); - obj_ini.mobi[coh,mah]=ini_read_string("Mar","mb"+string(coh)+"."+string(mah),""); - - obj_ini.age[coh,mah]=ini_read_real("Mar","ag"+string(coh)+"."+string(mah),0); - obj_ini.spe[coh,mah]=ini_read_string("Mar","spe"+string(coh)+"."+string(mah),""); - obj_ini.god[coh,mah]=ini_read_real("Mar","god"+string(coh)+"."+string(mah),0); - load_marine_struct(coh,mah); - unit = obj_ini.TTRPG[coh,mah]; - if (string_length(unit.weapon_one()) != 0 && string_length(string_digits(unit.weapon_one())) == string_length(unit.weapon_one())) { - obj_ini.wep1[coh, mah] = real(obj_ini.wep1[coh, mah]); - } - if (string_length(unit.weapon_two()) != 0 && string_length(string_digits(unit.weapon_two())) == string_length(unit.weapon_two())) { - obj_ini.wep2[coh, mah] = real(obj_ini.wep2[coh, mah]); - } - if (string_length(unit.gear()) != 0 && string_length(string_digits(unit.gear())) == string_length(unit.gear())) { - obj_ini.gear[coh, mah] = real(obj_ini.gear[coh, mah]); - } - if (string_length(unit.mobility_item()) != 0 && string_length(string_digits(unit.mobility_item())) == string_length(unit.mobility_item())) { - obj_ini.mobi[coh, mah] = real(obj_ini.mobi[coh, mah]); - } - if (string_length(unit.armour()) != 0 && string_length(string_digits(unit.armour())) == string_length(unit.armour())) { - obj_ini.armour[coh, mah] = real(obj_ini.armour[coh, mah]); - } + if (save_part=3) or (save_part=0){ + log_message("Loading INI"); + // Ini + var ini_save_data = obj_saveload.GameSave.Ini; + obj_ini.deserialize(ini_save_data); + log_message("INI loaded"); + + // Controller + log_message("Loading CONTROLLER"); + var save_data = obj_saveload.GameSave.Controller; + /// for some reason, obj_controller having it's deserialize as part of + /// the object doesnt want to work + with(obj_controller){ + var exclusions = ["specialist_point_handler", "location_viewer", "id"]; // skip automatic setting of certain vars, handle explicitly later + + // Automatic var setting + var all_names = struct_get_names(save_data); + var _len = array_length(all_names); + for(var i = 0; i < _len; i++){ + var var_name = all_names[i]; + if(array_contains(exclusions, var_name)){ + continue; + } + var loaded_value = struct_get(save_data, var_name); + // show_debug_message($"obj_controller var: {var_name} - val: {loaded_value}"); + try { + variable_struct_set(obj_controller, var_name, loaded_value); + } catch (e){ + show_debug_message(e); } } + specialist_point_handler = new SpecialistPointHandler(); + specialist_point_handler.calculate_research_points(); + location_viewer = new UnitQuickFindPanel(); + scr_colors_initialize(); + scr_shader_initialize(); + + global.star_name_colors[1] = make_color_rgb(body_colour_replace[0],body_colour_replace[1],body_colour_replace[2]); + } + log_message("CONTROLLER loaded"); - if (string_count(obj_ini.spe[0,1],"$")>0) then obj_controller.born_leader=1; - - coh=100;mah=-1; - repeat(21){mah+=1; - obj_ini.race[coh,mah]=ini_read_real("Mar","co"+string(coh)+"."+string(mah),0); - obj_ini.role[coh,mah]=ini_read_string("Mar","rol"+string(coh)+"."+string(mah),""); - obj_ini.wep1[coh,mah]=ini_read_string("Mar","w1"+string(coh)+"."+string(mah),""); - obj_ini.wep2[coh,mah]=ini_read_string("Mar","w2"+string(coh)+"."+string(mah),""); - obj_ini.armour[coh,mah]=ini_read_string("Mar","ar"+string(coh)+"."+string(mah),""); - obj_ini.gear[coh,mah]=ini_read_string("Mar","ge"+string(coh)+"."+string(mah),""); - obj_ini.mobi[coh,mah]=ini_read_string("Mar","mb"+string(coh)+"."+string(mah),""); - } - coh=102; - mah=-1; - repeat(21){mah+=1; - obj_ini.race[coh,mah]=ini_read_string("Mar","co"+string(coh)+"."+string(mah),0); - obj_ini.role[coh,mah]=ini_read_string("Mar","rol"+string(coh)+"."+string(mah),""); - obj_ini.wep1[coh,mah]=ini_read_string("Mar","w1"+string(coh)+"."+string(mah),""); - obj_ini.wep2[coh,mah]=ini_read_string("Mar","w2"+string(coh)+"."+string(mah),""); - obj_ini.armour[coh,mah]=ini_read_string("Mar","ar"+string(coh)+"."+string(mah),""); - obj_ini.gear[coh,mah]=ini_read_string("Mar","ge"+string(coh)+"."+string(mah),""); - obj_ini.mobi[coh,mah]=ini_read_string("Mar","mb"+string(coh)+"."+string(mah),""); - } - - obj_ini.squads = []; - var squad_fetch = ini_read_string("Mar","squads",""); - if (squad_fetch != ""){ - squad_fetch = json_parse(base64_decode(squad_fetch)); - for (i=0;i} unit where unit[0] is company and unit[1] is the position diff --git a/scripts/scr_save/scr_save.gml b/scripts/scr_save/scr_save.gml index e6427bd8e9..0a3e62f089 100644 --- a/scripts/scr_save/scr_save.gml +++ b/scripts/scr_save/scr_save.gml @@ -15,612 +15,139 @@ function ini_encode_and_json_advanced(ini_area, ini_code, value){ } function scr_save(save_part,save_id) { + var t1 = get_timer(); try{ - var num=0,tot=0; - num=0;tot=0; - - num=instance_number(obj_star); - instance_array[tot]=0; - - // if (file_exists("save1.ini")) then file_delete("save1.ini"); - // argument 0 = the part of the save to do - //save_id = the save ID - - if (save_part=1) or (save_part=0){ - scr_save_controller(save_id); - - } - - - if (save_part=2) or (save_part=0){ - log_message("Saving to slot "+string(save_id)+" - Part 2"); - ini_open($"save{save_id}.ini"); - // Stars - - var num=instance_number(obj_star); - instance_array=0; - for (var i=0; i=g){ - ini_write_real("Star","sr"+string(i)+"plan"+string(g),instance_array[i].planet[g]); - ini_write_real("Star","sr"+string(i)+"dispo"+string(g),instance_array[i].dispo[g]); - ini_write_string("Star","sr"+string(i)+"type"+string(g),instance_array[i].p_type[g]); - var save_features = []; - if (array_length(instance_array[i].p_feature[g])> 0){ - for (var f = 0;f < array_length(instance_array[i].p_feature[g]);f++){ - save_features[f]=0; - var copy_feature = instance_array[i].p_feature[g][f]; - var new_feature = {}; - var names = variable_struct_get_names(copy_feature); - for (var name = 0; name < array_length(names); name++) { - if (!is_method(copy_feature[$ names[name]])){ - variable_struct_set(new_feature, names[name],copy_feature[$ names[name]]) - } - } - save_features[f] = new_feature; - } - } - ini_write_string("Star","sr"+string(i)+"feat"+string(g),base64_encode(json_stringify(save_features))); - ini_write_string("Star","sr"+string(i)+"operatives"+string(g),base64_encode(json_stringify(instance_array[i].p_operatives[g]))); - ini_write_real("Star","sr"+string(i)+"own"+string(g),instance_array[i].p_owner[g]); - ini_write_real("Star","sr"+string(i)+"fir"+string(g),instance_array[i].p_first[g]); - ini_write_real("Star","sr"+string(i)+"popul"+string(g),instance_array[i].p_population[g]); - ini_write_real("Star","sr"+string(i)+"maxpop"+string(g),instance_array[i].p_max_population[g]); - ini_write_real("Star","sr"+string(i)+"large"+string(g),instance_array[i].p_large[g]); - ini_write_string("Star","sr"+string(i)+"pop"+string(g),instance_array[i].p_pop[g]); - ini_write_real("Star","sr"+string(i)+"guard"+string(g),instance_array[i].p_guardsmen[g]); - ini_write_real("Star","sr"+string(i)+"pdf"+string(g),instance_array[i].p_pdf[g]); - ini_write_real("Star","sr"+string(i)+"forti"+string(g),instance_array[i].p_fortified[g]); - ini_write_real("Star","sr"+string(i)+"stat"+string(g),instance_array[i].p_station[g]); - - ini_write_real("Star","sr"+string(i)+"play"+string(g),instance_array[i].p_player[g]); - if (instance_array[i].p_first[g]=1) or (instance_array[i].p_owner[g]=1){ - ini_write_real("Star","sr"+string(i)+"p_lasers"+string(g),instance_array[i].p_lasers[g]); - ini_write_real("Star","sr"+string(i)+"p_silo"+string(g),instance_array[i].p_silo[g]); - ini_write_real("Star","sr"+string(i)+"p_defenses"+string(g),instance_array[i].p_defenses[g]); - } - save_features = []; - if (array_length(instance_array[i].p_upgrades[g])> 0){ - for (var f = 0;f < array_length(instance_array[i].p_upgrades[g]);f++){ - save_features[f]=0; - var copy_feature = instance_array[i].p_upgrades[g][f]; - var new_feature = {}; - var names = variable_struct_get_names(copy_feature); - for (var name = 0; name < array_length(names); name++) { - if (!is_method(copy_feature[$ names[name]])){ - variable_struct_set(new_feature, names[name],copy_feature[$ names[name]]) - } - } - save_features[f] = new_feature; - } - } - ini_write_string("Star","sr"+string(i)+"upg"+string(g),base64_encode(json_stringify(save_features))); - ini_write_real("Star","sr"+string(i)+"or"+string(g),instance_array[i].p_orks[g]); - ini_write_real("Star","sr"+string(i)+"ta"+string(g),instance_array[i].p_tau[g]); - ini_write_real("Star","sr"+string(i)+"el"+string(g),instance_array[i].p_eldar[g]); - ini_write_real("Star","sr"+string(i)+"tr"+string(g),instance_array[i].p_traitors[g]); - ini_write_real("Star","sr"+string(i)+"ch"+string(g),instance_array[i].p_chaos[g]); - ini_write_real("Star","sr"+string(i)+"de"+string(g),instance_array[i].p_demons[g]); - ini_write_real("Star","sr"+string(i)+"si"+string(g),instance_array[i].p_sisters[g]); - ini_write_real("Star","sr"+string(i)+"ne"+string(g),instance_array[i].p_necrons[g]); - ini_write_real("Star","sr"+string(i)+"tyr"+string(g),instance_array[i].p_tyranids[g]); - ini_write_real("Star","sr"+string(i)+"halp"+string(g),instance_array[i].p_halp[g]); - - ini_write_real("Star","sr"+string(i)+"hurssy"+string(g),instance_array[i].p_hurssy[g]); - ini_write_real("Star","sr"+string(i)+"hurssy_time"+string(g),instance_array[i].p_hurssy_time[g]); - ini_write_real("Star","sr"+string(i)+"heresy"+string(g),instance_array[i].p_heresy[g]); - ini_write_real("Star","sr"+string(i)+"heresy_secret"+string(g),instance_array[i].p_heresy_secret[g]); - ini_write_string("Star","sr"+string(i)+"influence"+string(g),base64_encode(json_stringify(instance_array[i].p_influence[g]))); - ini_write_real("Star","sr"+string(i)+"raided"+string(g),instance_array[i].p_raided[g]); - - for (var p=0;p<8;p++){ - ini_write_string("Star",$"sr{i}prob{g}.{p}",instance_array[i].p_problem[g,p]); - ini_write_real("Star",$"sr{i}time{g}.{p}",instance_array[i].p_timer[g,p]); - ini_write_string("Star",$"sr{i}prob_other{g}.{p}",base64_encode(json_stringify(instance_array[i].p_problem_other_data[g,p]))); - } - } - } - } - - - // Temporary artifact objects - ini_write_real("Controller","temp_arti",instance_number(obj_temp_arti)); - num=instance_number(obj_temp_arti);instance_array=0; - for (var i=0; i=12 && hour<24) ? "PM":"AM"; + if (hour=0) then hour=12; + var mahg=minute; + if (mahg<10) then minute=$"0{mahg}"; + log_message($"Saving to slot {save_id} - vars are assigned!"); + + obj_saveload.GameSave.Save = { + chapter_name: global.chapter_name, + sector_name: obj_ini.sector_name, + version: global.game_version, + play_time: play_time, + game_seed: global.game_seed, + use_custom_icon: obj_ini.use_custom_icon, + chapter_icon_sprite: global.chapter_icon_sprite, + chapter_icon_frame: global.chapter_icon_frame, + chapter_icon_path: global.chapter_icon_path, + icon_name: global.icon_name, + chapter_icon_filename: global.chapter_icon_filename, + date: string(month)+"/"+string(day)+"/"+string(year)+" ("+string(hour)+":"+string(minute)+" "+string(pm)+")", + founding: obj_ini.progenitor, + custom: global.custom, + stars: instance_number(obj_star), + p_fleets: instance_number(obj_p_fleet), + en_fleets: instance_number(obj_en_fleet), + sod: random_get_seed(), } - ini_write_string("Ini","artifact_struct"+string(g),base64_encode(json_stringify(new_artifact))); - } - - // - ini_encode_and_json("Ships","shi",obj_ini.ship); - ini_encode_and_json("Ships","shi_uid",obj_ini.ship_uid); - ini_encode_and_json("Ships","shi_class",obj_ini.ship_class); - ini_encode_and_json("Ships","shi_size",obj_ini.ship_size); - ini_encode_and_json("Ships","shi_leadership",obj_ini.ship_leadership); - ini_encode_and_json("Ships","shi_hp",obj_ini.ship_hp); - ini_encode_and_json("Ships","shi_maxhp",obj_ini.ship_maxhp); - ini_encode_and_json("Ships","shi_owner",obj_ini.ship_owner); - - - ini_encode_and_json("Ships","shi_location",obj_ini.ship_location); - ini_encode_and_json("Ships","shi_shields",obj_ini.ship_shields); - ini_encode_and_json("Ships","shi_conditions",obj_ini.ship_conditions); - ini_encode_and_json("Ships","shi_speed",obj_ini.ship_speed); - ini_encode_and_json("Ships","shi_turning",obj_ini.ship_turning); - - ini_encode_and_json("Ships","shi_front_ac",obj_ini.ship_front_armour); - ini_encode_and_json("Ships","shi_other_ac",obj_ini.ship_other_armour); - ini_encode_and_json("Ships","shi_weapons",obj_ini.ship_weapons); - - ini_encode_and_json("Ships","wep",obj_ini.ship_wep); - ini_encode_and_json("Ships","wep_facing",obj_ini.ship_wep_facing); - ini_encode_and_json("Ships","wep_condition",obj_ini.ship_wep_condition); - - ini_encode_and_json("Ships","shi_capacity",obj_ini.ship_capacity); - ini_encode_and_json("Ships","shi_carrying",obj_ini.ship_carrying); - ini_encode_and_json("Ships","shi_contents",obj_ini.ship_contents); - ini_encode_and_json("Ships","shi_turrets",obj_ini.ship_turrets); - - ini_close(); - } - - - if (save_part=3) or (save_part=0){log_message($"Saving to slot {save_id} - Part 3"); - ini_open($"save{save_id}.ini"); - var coh,mah,good; - for (coh=1;coh<=10;coh++){ - for (mah=1;mah<=100;mah++){ - if (obj_ini.veh_role[coh][mah]!=""){ - ini_write_real("Veh",$"co{coh}.{mah}",obj_ini.veh_race[coh,mah]); - ini_write_string("Veh",$"lo{coh}.{mah}",obj_ini.veh_loc[coh,mah]); - ini_write_string("Veh",$"rol{coh}.{mah}",obj_ini.veh_role[coh,mah]); - ini_write_real("Veh",$"lid{coh}.{mah}",obj_ini.veh_lid[coh,mah]); - ini_write_real("Veh",$"uid{coh}.{mah}",obj_ini.veh_uid[coh,mah]); - ini_write_real("Veh",$"wid{coh}.{mah}",obj_ini.veh_wid[coh,mah]); - - ini_write_string("Veh",$"w1{coh}.{mah}",obj_ini.veh_wep1[coh,mah]); - ini_write_string("Veh",$"w2{coh}.{mah}",obj_ini.veh_wep2[coh,mah]); - ini_write_string("Veh",$"w3{coh}.{mah}",obj_ini.veh_wep3[coh,mah]); - ini_write_string("Veh",$"up{coh}.{mah}",obj_ini.veh_upgrade[coh,mah]); - ini_write_string("Veh",$"ac{coh}.{mah}",obj_ini.veh_acc[coh,mah]); - - ini_write_real("Veh",$"hp{coh}.{mah}",obj_ini.veh_hp[coh,mah]); - ini_write_real("Veh",$"cha{coh}.{mah}",obj_ini.veh_chaos[coh,mah]); - ini_encode_and_json("Veh",$"last_ship{coh}.{mah}",obj_ini.last_ship[coh,mah]); - } - } - } - ini_close(); - } - - if (save_part=4) or (save_part=0){ - log_message("Saving to slot "+string(save_id)+" - Part 4"); - ini_open($"save{save_id}.ini"); - var coh,mah,good; - good=0;coh=100;mah=0; - log_message("Saving to slot "+string(save_id)+" - First Loop"); - repeat(30){mah+=1; - if (obj_ini.role[coh,mah]!=""){ - ini_write_real("Mar",$"co{coh}.{mah}",obj_ini.race[coh,mah]); - ini_write_string("Mar",$"num{coh}.{mah}",obj_ini.name[coh,mah]); - ini_write_string("Mar",$"rol{coh}.{mah}",obj_ini.role[coh,mah]); - ini_write_string("Mar",$"w1{coh}.{mah}",obj_ini.wep1[coh,mah]); - ini_write_string("Mar",$"w2{coh}.{mah}",obj_ini.wep2[coh,mah]); - ini_write_string("Mar",$"ar{coh}.{mah}",obj_ini.armour[coh,mah]); - ini_write_string("Mar",$"ge{coh}.{mah}",obj_ini.gear[coh,mah]); - ini_write_string("Mar",$"mb{coh}.{mah}",obj_ini.mobi[coh,mah]); - } - } - log_message("Saving to slot "+string(save_id)+" - Second Loop"); - for (coh=0;coh<=10;coh++){ - with (obj_ini){ - scr_company_order(coh); - } - for (mah=0;mah<=500;mah++){ - if (obj_ini.name[coh][mah] != ""){ - ini_write_real("Mar",$"co{coh}.{mah}",obj_ini.race[coh,mah]); - ini_write_string("Mar",$"lo{coh}.{mah}",obj_ini.loc[coh,mah]); - ini_write_string("Mar",$"num{coh}.{mah}",obj_ini.name[coh,mah]); - ini_write_string("Mar",$"rol{coh}.{mah}",obj_ini.role[coh,mah]); - - ini_write_string("Mar",$"w1{coh}.{mah}",obj_ini.wep1[coh,mah]); - ini_write_string("Mar",$"w2{coh}.{mah}",obj_ini.wep2[coh,mah]); - ini_write_string("Mar",$"ar{coh}.{mah}",obj_ini.armour[coh,mah]); - ini_write_string("Mar",$"ge{coh}.{mah}",obj_ini.gear[coh,mah]); - ini_write_string("Mar",$"mb{coh}.{mah}",obj_ini.mobi[coh,mah]); - ini_write_real("Mar",$"ag{coh}.{mah}",obj_ini.age[coh,mah]); - ini_write_string("Mar",$"spe{coh}.{mah}",obj_ini.spe[coh,mah]); - ini_write_real("Mar",$"god{coh}.{mah}",obj_ini.god[coh,mah]); - if (!is_struct(obj_ini.TTRPG[coh][mah])){ - TTRPG[coh][mah] = new TTRPG_stats("chapter", coh,mah, "blank"); - } else{ - ini_write_string("Mar",$"Struct{coh}.{mah}",base64_encode(jsonify_marine_struct(coh,mah))); - } - } else { - if (mah>0) then break; - } - } - } - log_message("Saving to slot "+string(save_id)+" - Squad Saving Start"); - var squad_copies = []; - if (array_length(obj_ini.squads)> 0){ - for (var i = 0;i < array_length(obj_ini.squads);i++){ - var _squad = obj_ini.squads[i].jsonify(); - array_push(squad_copies, _squad); + log_message($"Saving to slot {save_id} - GameSave struct created!"); + + /// STARS + var num=instance_number(obj_star); + for (var i=0; i=12 && hour<24) ? "PM":"AM"; - - if (hour=0) then hour=12; - - var mahg=minute; - if (mahg<10) then minute=$"0{mahg}"; - - // if (minute<10) then minute="0"+string(minute); - - ini_write_string("Save","date",string(month)+"/"+string(day)+"/"+string(year)+" ("+string(hour)+":"+string(minute)+" "+string(pm)+")"); - ini_write_real("Save","founding",obj_ini.progenitor); - // ini_write_string("Save","founding_secret",global.founding_secret); - ini_write_real("Save","custom",global.custom); - ini_write_real("Save","stars",instance_number(obj_star)); - ini_write_real("Save","p_fleets",instance_number(obj_p_fleet)); - ini_write_real("Save","en_fleets",instance_number(obj_en_fleet)); - ini_write_real("Save","sod",random_get_seed()); - ini_write_real("Save","corrupt",1); + // obj_controller variables here ini_write_real("boolean", "cheat_req", global.cheat_req); ini_write_real("boolean", "cheat_gene", global.cheat_gene); diff --git a/scripts/scr_serialization_functions/scr_serialization_functions.gml b/scripts/scr_serialization_functions/scr_serialization_functions.gml new file mode 100644 index 0000000000..cab00ec0ef --- /dev/null +++ b/scripts/scr_serialization_functions/scr_serialization_functions.gml @@ -0,0 +1,56 @@ +/// @desc Copies simple (serializable) variables from one struct to another, excluding specified names and prefixes. Useful for building save-data structs. +/// @param {struct} _source - The struct to copy variables from. +/// @param {struct} _destination - The struct to copy variables into. +/// @param {array} _exclude - List of variable names to exclude. +/// @param {array} _exclude_start - List of string prefixes; variables starting with any of these will be excluded. +function copy_serializable_fields(_source, _destination, _exclude = [], _exclude_start = []) { + /// Check all object variable values types and save the simple ones dynamically. + /// simple types are numbers, strings, bools. arrays of only simple types are also considered simple. + /// non-simple types are structs, functions, methods + /// functions and methods will be ignored completely, structs to be manually serialized/deserialised. + + var _all_names = struct_get_names(_source); + var _len = array_length(_all_names); + + for (var i = 0; i < _len; i++) { + var _field_name = _all_names[i]; + var _field_value = _source[$ _field_name]; + + if (is_method(_field_value)) { + continue; + } + + if (array_contains(_exclude, _field_name)) { + continue; // excluded by the full name + } + + if (string_starts_with_any(_field_name, _exclude_start)) { + continue; // excluded by the prefix + } + + if (struct_exists(_destination, _field_name)) { + continue; // already added + } + + if (is_basic_variable(_field_value)) { + variable_struct_set(_destination, _field_name, _field_value); + continue; + } + + if (is_array(_field_value)) { + if (!is_basic_array(_field_value, 2)) { + var _source_obj_name = struct_exists(_source, "object_index") ? object_get_name(_source.object_index) : ""; + log_warning($"Bad array save: '{_field_name}' internal type found was not a simple type and should probably have it's own serialize function - {_source_obj_name}!"); + } else { + variable_struct_set(_destination, _field_name, _field_value); + } + continue; + } + + if (is_struct(_field_value) && !struct_exists(_destination, _field_name)) { + var _source_obj_name = struct_exists(_source, "object_index") ? object_get_name(_source.object_index) : ""; + log_warning($"obj_ini.serialze() - {_source_obj_name} - object contains struct variable '{_field_name}' which has not been serialized. \n\tEnsure that serialization is written into the serialize and deserialization function if it is needed for this value, or that the variable is added to the ignore list to suppress this warning!"); + continue; + } + } +} diff --git a/scripts/scr_serialization_functions/scr_serialization_functions.yy b/scripts/scr_serialization_functions/scr_serialization_functions.yy new file mode 100644 index 0000000000..15357345d7 --- /dev/null +++ b/scripts/scr_serialization_functions/scr_serialization_functions.yy @@ -0,0 +1,13 @@ +{ + "$GMScript":"v1", + "%Name":"scr_serialization_functions", + "isCompatibility":false, + "isDnD":false, + "name":"scr_serialization_functions", + "parent":{ + "name":"Scripts", + "path":"folders/Scripts.yy", + }, + "resourceType":"GMScript", + "resourceVersion":"2.0", +} \ No newline at end of file diff --git a/scripts/scr_specialist_point_handler/scr_specialist_point_handler.gml b/scripts/scr_specialist_point_handler/scr_specialist_point_handler.gml index 6fb8667e58..2c4944f801 100644 --- a/scripts/scr_specialist_point_handler/scr_specialist_point_handler.gml +++ b/scripts/scr_specialist_point_handler/scr_specialist_point_handler.gml @@ -84,7 +84,7 @@ function SpecialistPointHandler() constructor{ forge_string += $"Techmarines: +{floor(forge_points)}#"; forge_points-=tech_points_used; forge_string += $"Vehicle Repairs:#"; - forge_string += $" Combat Repairs : {forge_veh_maintenance.repairs}\n"; + forge_string += $" Combat Repairs : {forge_veh_maintenance.repairs}#"; if (struct_exists(forge_veh_maintenance, "land_raider")){ forge_string += $" Land Raider Maintenance: -{forge_veh_maintenance.land_raider}#"; forge_points-=forge_veh_maintenance.land_raider; diff --git a/scripts/scr_squads/scr_squads.gml b/scripts/scr_squads/scr_squads.gml index 85a53e0807..7bf35df928 100644 --- a/scripts/scr_squads/scr_squads.gml +++ b/scripts/scr_squads/scr_squads.gml @@ -154,6 +154,8 @@ function UnitSquad(squad_type = undefined, company = undefined) constructor{ in future i'd like to tailer these to marine skill sets e.g the marines with the best ranged stats get given the best ranged equipment */ static sort_squad_loadout = function(from_armoury=true, to_armoury=true){ + var unit; + var required_load, unit_type, load_out_name, load_out_areas, load_out_slot,load_item, optional_load, item_to_add; squad_unit_types = find_squad_unit_types(); var full_squad_data = obj_ini.squad_types[$ type]; @@ -434,7 +436,7 @@ function UnitSquad(squad_type = undefined, company = undefined) constructor{ life_members++; } // for saving squads - static jsonify = function(){ + static jsonify = function(stringify = true){ var copy_struct = self; //grab marine structure var new_struct = {}; var copy_part; @@ -445,7 +447,11 @@ function UnitSquad(squad_type = undefined, company = undefined) constructor{ variable_struct_set(new_struct, names[name],copy_part); //if key value is not a method add to copy structure } } - return json_stringify(new_struct); + if(stringify){ + return json_stringify(new_struct, true); + } else { + return new_struct; + } } //function for loading in squad save data @@ -462,6 +468,7 @@ function UnitSquad(squad_type = undefined, company = undefined) constructor{ var locations = []; var system = "" var unit_loc; + var unit; var same_system = true; var same_loc_type = true; var loc_type = false; @@ -534,6 +541,7 @@ function UnitSquad(squad_type = undefined, company = undefined) constructor{ //this means the highest ranking dude in a squad will always be the squad leader //failing that the highest experience dude static determine_leader = function(){ + var unit; var member_length = array_length(members); var hierarchy = role_hierarchy(); var leader_hier_pos=array_length(hierarchy); @@ -607,6 +615,7 @@ function UnitSquad(squad_type = undefined, company = undefined) constructor{ } static member_loop = function(member_func, data_pack){ + var unit; member_length = array_length(members); for (var i=0;i} _prefixes - An array of string prefixes to match against. +/// @returns {boolean} +function string_starts_with_any(_str, _prefixes) { + for (var i = 0, _len = array_length(_prefixes); i < _len; ++i) { + if (string_starts_with(_str, _prefixes[i])) { + return true; + } + } + return false; +}