@@ -4282,10 +4282,8 @@ void tracker_apply_coop_mods(Tracker *t, const AppSettings *settings,
42824282
42834283 if (mod->action == COOP_MOD_TOGGLE) {
42844284 cat->is_manually_completed = !cat->is_manually_completed;
4285- bool all_children_done = (cat->criteria_count > 0 &&
4286- cat->completed_criteria_count >= cat->criteria_count);
4287- cat->done = cat->is_manually_completed || all_children_done;
42884285
4286+ // Recalculate children FIRST so completed_criteria_count is correct
42894287 for (int j = 0; j < cat->criteria_count; j++) {
42904288 TrackableItem *crit = cat->criteria[j];
42914289 bool crit_naturally_done = (crit->goal > 0 && crit->progress >= crit->goal);
@@ -4295,6 +4293,11 @@ void tracker_apply_coop_mods(Tracker *t, const AppSettings *settings,
42954293 for (int k = 0; k < cat->criteria_count; k++) {
42964294 if (cat->criteria[k]->done) cat->completed_criteria_count++;
42974295 }
4296+
4297+ // Now calculate parent done based on updated children
4298+ bool all_children_done = (cat->criteria_count > 0 &&
4299+ cat->completed_criteria_count >= cat->criteria_count);
4300+ cat->done = cat->is_manually_completed || all_children_done;
42984301 any_applied = true;
42994302 }
43004303 break;
@@ -4331,6 +4334,7 @@ void tracker_apply_coop_mods(Tracker *t, const AppSettings *settings,
43314334 }
43324335
43334336 if (any_applied) {
4337+ SDL_SetAtomicInt(&g_suppress_settings_watch, 1);
43344338 settings_save(settings, td, SAVE_CONTEXT_ALL);
43354339 }
43364340}
@@ -5958,12 +5962,13 @@ static void render_trackable_category_section(Tracker *t, const AppSettings *set
59585962 // Co-op: Receivers respect stat checkbox permission
59595963 if (is_hovered && ImGui::IsMouseClicked(ImGuiMouseButton_Left) && !t->
59605964 is_visual_layout_editing) {
5961- if (settings->network_mode == NETWORK_RECEIVER &&
5965+ bool rcv_in_lobby = (settings->network_mode == NETWORK_RECEIVER &&
5966+ g_coop_ctx && coop_net_get_state(g_coop_ctx) == COOP_NET_CONNECTED);
5967+ if (rcv_in_lobby &&
59625968 settings->coop_stat_checkbox == COOP_STAT_CHECKBOX_HOST_ONLY) {
59635969 // Host-only mode: clicking disabled for receivers
5964- } else if (settings->network_mode == NETWORK_RECEIVER &&
5965- settings->coop_stat_checkbox == COOP_STAT_CHECKBOX_ANY_PLAYER &&
5966- g_coop_ctx) {
5970+ } else if (rcv_in_lobby &&
5971+ settings->coop_stat_checkbox == COOP_STAT_CHECKBOX_ANY_PLAYER) {
59675972 // Any-player mode: send toggle request to host
59685973 CoopCustomGoalModMsg mod = {};
59695974 snprintf(mod.goal_root_name, sizeof(mod.goal_root_name), "%s", crit->root_name);
@@ -5985,6 +5990,7 @@ static void render_trackable_category_section(Tracker *t, const AppSettings *set
59855990 criteria_count);
59865991 cat->done = cat->is_manually_completed || all_children_done;
59875992
5993+ SDL_SetAtomicInt(&g_suppress_settings_watch, 1);
59885994 settings_save(settings, t->template_data, SAVE_CONTEXT_ALL);
59895995 SDL_SetAtomicInt(&g_coop_broadcast_needed, 1);
59905996 SDL_SetAtomicInt(&g_game_data_changed, 1);
@@ -6214,12 +6220,13 @@ static void render_trackable_category_section(Tracker *t, const AppSettings *set
62146220 // Co-op: Receivers respect stat checkbox permission
62156221 if (is_hovered_parent && ImGui::IsMouseClicked(ImGuiMouseButton_Left) && !t->
62166222 is_visual_layout_editing) {
6217- if (settings->network_mode == NETWORK_RECEIVER &&
6223+ bool rcv_in_lobby = (settings->network_mode == NETWORK_RECEIVER &&
6224+ g_coop_ctx && coop_net_get_state(g_coop_ctx) == COOP_NET_CONNECTED);
6225+ if (rcv_in_lobby &&
62186226 settings->coop_stat_checkbox == COOP_STAT_CHECKBOX_HOST_ONLY) {
62196227 // Host-only mode: clicking disabled for receivers
6220- } else if (settings->network_mode == NETWORK_RECEIVER &&
6221- settings->coop_stat_checkbox == COOP_STAT_CHECKBOX_ANY_PLAYER &&
6222- g_coop_ctx) {
6228+ } else if (rcv_in_lobby &&
6229+ settings->coop_stat_checkbox == COOP_STAT_CHECKBOX_ANY_PLAYER) {
62236230 // Any-player mode: send toggle request to host (parent stat)
62246231 CoopCustomGoalModMsg mod = {};
62256232 snprintf(mod.goal_root_name, sizeof(mod.goal_root_name), "%s", cat->root_name);
@@ -6229,10 +6236,8 @@ static void render_trackable_category_section(Tracker *t, const AppSettings *set
62296236 } else {
62306237 // Host or singleplayer: toggle locally
62316238 cat->is_manually_completed = !cat->is_manually_completed;
6232- bool all_children_naturally_done = (
6233- cat->criteria_count > 0 && cat->completed_criteria_count >= cat->criteria_count);
6234- cat->done = cat->is_manually_completed || all_children_naturally_done;
62356239
6240+ // Recalculate children FIRST so completed_criteria_count is correct
62366241 for (int j = 0; j < cat->criteria_count; ++j) {
62376242 TrackableItem *crit = cat->criteria[j];
62386243 bool crit_naturally_done = (crit->goal > 0 && crit->progress >= crit->goal);
@@ -6244,6 +6249,12 @@ static void render_trackable_category_section(Tracker *t, const AppSettings *set
62446249 if (cat->criteria[k]->done) cat->completed_criteria_count++;
62456250 }
62466251
6252+ // Now calculate parent done based on updated children
6253+ bool all_children_done = (
6254+ cat->criteria_count > 0 && cat->completed_criteria_count >= cat->criteria_count);
6255+ cat->done = cat->is_manually_completed || all_children_done;
6256+
6257+ SDL_SetAtomicInt(&g_suppress_settings_watch, 1);
62476258 settings_save(settings, t->template_data, SAVE_CONTEXT_ALL);
62486259 SDL_SetAtomicInt(&g_coop_broadcast_needed, 1);
62496260 SDL_SetAtomicInt(&g_game_data_changed, 1);
@@ -7206,7 +7217,9 @@ static void render_custom_goals_section(Tracker *t, const AppSettings *settings,
72067217 // Deactivating when in visual layout editor mode
72077218 // Co-op: Receivers respect custom goal permission
72087219 // Co-op: Show tooltip for host-only custom goals
7209- if (is_hovered && settings->network_mode == NETWORK_RECEIVER &&
7220+ bool rcv_in_lobby = (settings->network_mode == NETWORK_RECEIVER &&
7221+ g_coop_ctx && coop_net_get_state(g_coop_ctx) == COOP_NET_CONNECTED);
7222+ if (is_hovered && rcv_in_lobby &&
72107223 settings->coop_custom_goal_mode == COOP_CUSTOM_HOST_ONLY) {
72117224 char tooltip_buf[128];
72127225 snprintf(tooltip_buf, sizeof(tooltip_buf),
@@ -7215,12 +7228,11 @@ static void render_custom_goals_section(Tracker *t, const AppSettings *settings,
72157228 }
72167229
72177230 if (is_hovered && ImGui::IsMouseClicked(ImGuiMouseButton_Left) && !t->is_visual_layout_editing) {
7218- if (settings->network_mode == NETWORK_RECEIVER &&
7231+ if (rcv_in_lobby &&
72197232 settings->coop_custom_goal_mode == COOP_CUSTOM_HOST_ONLY) {
72207233 // Host-only mode: clicking disabled for receivers
7221- } else if (settings->network_mode == NETWORK_RECEIVER &&
7222- settings->coop_custom_goal_mode == COOP_CUSTOM_ANY_PLAYER &&
7223- g_coop_ctx) {
7234+ } else if (rcv_in_lobby &&
7235+ settings->coop_custom_goal_mode == COOP_CUSTOM_ANY_PLAYER) {
72247236 // Any-player mode: send toggle request to host
72257237 CoopCustomGoalModMsg mod = {};
72267238 snprintf(mod.goal_root_name, sizeof(mod.goal_root_name), "%s", item->root_name);
@@ -7239,6 +7251,7 @@ static void render_custom_goals_section(Tracker *t, const AppSettings *settings,
72397251 item->linked_goal_mode));
72407252 }
72417253 item->progress = item->done ? 1 : 0;
7254+ SDL_SetAtomicInt(&g_suppress_settings_watch, 1);
72427255 settings_save(settings, t->template_data, SAVE_CONTEXT_ALL);
72437256 // Lightweight broadcast path: no full file re-merge needed for custom goals
72447257 SDL_SetAtomicInt(&g_coop_broadcast_needed, 1);
0 commit comments