From 5d39741be1bc2dac239166de41965dc10d2556f0 Mon Sep 17 00:00:00 2001
From: Blockyyy <88585273+Blockyyy@users.noreply.github.com>
Date: Sat, 11 Nov 2023 15:23:14 +0100
Subject: [PATCH] Delete star flags (#501)
* Expose save_file_remove_star_flags
* new packet
added a new packet type and two new functions
* oops
* create packet_save_remove_flag.c
move the new network functions to a new file
* Switch u32 to u8
Switched courseStarsToRemove from u32
to u8 for consistency
* fixed the function
-Fixed empty save file marked as existing
-Fixed SAVE_FILE_EXISTS flag being deleted
-Fixed removing ALL flags from the remote saves
---
autogen/convert_functions.py | 2 +-
autogen/lua_definitions/functions.lua | 8 +++
docs/lua/functions-4.md | 22 ++++++++
docs/lua/functions.md | 1 +
src/game/save_file.c | 16 ++++++
src/game/save_file.h | 1 +
src/pc/lua/smlua_functions_autogen.c | 22 ++++++++
src/pc/network/packets/packet.c | 1 +
src/pc/network/packets/packet.h | 5 ++
.../network/packets/packet_save_remove_flag.c | 55 +++++++++++++++++++
src/pc/network/packets/packet_save_set_flag.c | 2 +-
11 files changed, 133 insertions(+), 2 deletions(-)
create mode 100644 src/pc/network/packets/packet_save_remove_flag.c
diff --git a/autogen/convert_functions.py b/autogen/convert_functions.py
index 0b18b1513..eab7b3ddf 100644
--- a/autogen/convert_functions.py
+++ b/autogen/convert_functions.py
@@ -70,7 +70,7 @@ override_allowed_functions = {
"src/audio/external.h": [ " play_", "fade", "current_background", "stop_", "sound_banks", "drop_queued_background_music" ],
"src/game/rumble_init.c": [ "queue_rumble_", "reset_rumble_timers" ],
"src/pc/djui/djui_popup.h" : [ "create" ],
- "src/game/save_file.h": [ "save_file_get_", "save_file_set_flags", "save_file_clear_flags", "save_file_reload", "save_file_erase_current_backup_save", "save_file_set_star_flags", "save_file_is_cannon_unlocked", "touch_coin_score_age", "save_file_set_course_coin_score", "save_file_do_save" ],
+ "src/game/save_file.h": [ "save_file_get_", "save_file_set_flags", "save_file_clear_flags", "save_file_reload", "save_file_erase_current_backup_save", "save_file_set_star_flags", "save_file_is_cannon_unlocked", "touch_coin_score_age", "save_file_set_course_coin_score", "save_file_do_save", "save_file_remove_star_flags" ],
"src/pc/lua/utils/smlua_model_utils.h": [ "smlua_model_util_get_id" ],
"src/game/object_list_processor.h": [ "set_object_respawn_info_bits" ],
"src/game/mario_misc.h": [ "bhv_toad.*", "bhv_unlock_door.*" ],
diff --git a/autogen/lua_definitions/functions.lua b/autogen/lua_definitions/functions.lua
index 6d6e0ce71..20bc244fe 100644
--- a/autogen/lua_definitions/functions.lua
+++ b/autogen/lua_definitions/functions.lua
@@ -8065,6 +8065,14 @@ function save_file_reload(load_all)
-- ...
end
+--- @param fileIndex integer
+--- @param courseIndex integer
+--- @param starFlagsToRemove integer
+--- @return nil
+function save_file_remove_star_flags(fileIndex, courseIndex, starFlagsToRemove)
+ -- ...
+end
+
--- @param fileIndex integer
--- @param courseIndex integer
--- @param coinScore integer
diff --git a/docs/lua/functions-4.md b/docs/lua/functions-4.md
index 568147a09..277e72e5f 100644
--- a/docs/lua/functions-4.md
+++ b/docs/lua/functions-4.md
@@ -7007,6 +7007,28 @@
+## [save_file_remove_star_flags](#save_file_remove_star_flags)
+
+### Lua Example
+`save_file_remove_star_flags(fileIndex, courseIndex, starFlagsToRemove)`
+
+### Parameters
+| Field | Type |
+| ----- | ---- |
+| fileIndex | `integer` |
+| courseIndex | `integer` |
+| starFlagsToRemove | `integer` |
+
+### Returns
+- None
+
+### C Prototype
+`void save_file_remove_star_flags(s32 fileIndex, s32 courseIndex, u32 starFlagsToRemove);`
+
+[:arrow_up_small:](#)
+
+
+
## [save_file_set_course_coin_score](#save_file_set_course_coin_score)
### Lua Example
diff --git a/docs/lua/functions.md b/docs/lua/functions.md
index bb9f19d44..b94ebf35a 100644
--- a/docs/lua/functions.md
+++ b/docs/lua/functions.md
@@ -1507,6 +1507,7 @@
- [save_file_get_total_star_count](functions-4.md#save_file_get_total_star_count)
- [save_file_is_cannon_unlocked](functions-4.md#save_file_is_cannon_unlocked)
- [save_file_reload](functions-4.md#save_file_reload)
+ - [save_file_remove_star_flags](functions-4.md#save_file_remove_star_flags)
- [save_file_set_course_coin_score](functions-4.md#save_file_set_course_coin_score)
- [save_file_set_flags](functions-4.md#save_file_set_flags)
- [save_file_set_star_flags](functions-4.md#save_file_set_star_flags)
diff --git a/src/game/save_file.c b/src/game/save_file.c
index b9491472f..f1d5b48e0 100644
--- a/src/game/save_file.c
+++ b/src/game/save_file.c
@@ -703,6 +703,22 @@ void save_file_set_star_flags(s32 fileIndex, s32 courseIndex, u32 starFlags) {
gSaveFileModified = TRUE;
}
+void save_file_remove_star_flags(s32 fileIndex, s32 courseIndex, u32 starFlagsToRemove) {
+ if (INVALID_FILE_INDEX(fileIndex)) { return; }
+ if (INVALID_SRC_SLOT(gSaveFileUsingBackupSlot)) { return; }
+
+ if (courseIndex == -1) {
+ gSaveBuffer.files[fileIndex][gSaveFileUsingBackupSlot].flags &= ~STAR_FLAG_TO_SAVE_FLAG(starFlagsToRemove);
+ network_send_save_remove_flag(fileIndex, courseIndex, 0, STAR_FLAG_TO_SAVE_FLAG(starFlagsToRemove));
+ }
+ else if (!INVALID_COURSE_STAR_INDEX(courseIndex)) {
+ gSaveBuffer.files[fileIndex][gSaveFileUsingBackupSlot].courseStars[courseIndex] &= ~starFlagsToRemove;
+ network_send_save_remove_flag(fileIndex, courseIndex, starFlagsToRemove, 0);
+ }
+
+ gSaveFileModified = TRUE;
+}
+
s32 save_file_get_course_coin_score(s32 fileIndex, s32 courseIndex) {
if (INVALID_FILE_INDEX(fileIndex)) { return 0; }
if (INVALID_SRC_SLOT(gSaveFileUsingBackupSlot)) { return 0; }
diff --git a/src/game/save_file.h b/src/game/save_file.h
index f9c1f37d0..4d9b0b02d 100644
--- a/src/game/save_file.h
+++ b/src/game/save_file.h
@@ -148,6 +148,7 @@ void save_file_clear_flags(u32 flags);
u32 save_file_get_flags(void);
u32 save_file_get_star_flags(s32 fileIndex, s32 courseIndex);
void save_file_set_star_flags(s32 fileIndex, s32 courseIndex, u32 starFlags);
+void save_file_remove_star_flags(s32 fileIndex, s32 courseIndex, u32 starFlagsToRemove);
s32 save_file_get_course_coin_score(s32 fileIndex, s32 courseIndex);
void save_file_set_course_coin_score(s32 fileIndex, s32 courseIndex, u8 coinScore);
s32 save_file_is_cannon_unlocked(s32 fileIndex, s32 courseIndex);
diff --git a/src/pc/lua/smlua_functions_autogen.c b/src/pc/lua/smlua_functions_autogen.c
index 36423a576..5ac0cd4cf 100644
--- a/src/pc/lua/smlua_functions_autogen.c
+++ b/src/pc/lua/smlua_functions_autogen.c
@@ -26947,6 +26947,27 @@ int smlua_func_save_file_reload(lua_State* L) {
return 1;
}
+int smlua_func_save_file_remove_star_flags(lua_State* L) {
+ if (L == NULL) { return 0; }
+
+ int top = lua_gettop(L);
+ if (top != 3) {
+ LOG_LUA_LINE("Improper param count for '%s': Expected %u, Received %u", "save_file_remove_star_flags", 3, top);
+ return 0;
+ }
+
+ s32 fileIndex = smlua_to_integer(L, 1);
+ if (!gSmLuaConvertSuccess) { LOG_LUA("Failed to convert parameter %u for function '%s'", 1, "save_file_remove_star_flags"); return 0; }
+ s32 courseIndex = smlua_to_integer(L, 2);
+ if (!gSmLuaConvertSuccess) { LOG_LUA("Failed to convert parameter %u for function '%s'", 2, "save_file_remove_star_flags"); return 0; }
+ u32 starFlagsToRemove = smlua_to_integer(L, 3);
+ if (!gSmLuaConvertSuccess) { LOG_LUA("Failed to convert parameter %u for function '%s'", 3, "save_file_remove_star_flags"); return 0; }
+
+ save_file_remove_star_flags(fileIndex, courseIndex, starFlagsToRemove);
+
+ return 1;
+}
+
int smlua_func_save_file_set_course_coin_score(lua_State* L) {
if (L == NULL) { return 0; }
@@ -32684,6 +32705,7 @@ void smlua_bind_functions_autogen(void) {
smlua_bind_function(L, "save_file_get_total_star_count", smlua_func_save_file_get_total_star_count);
smlua_bind_function(L, "save_file_is_cannon_unlocked", smlua_func_save_file_is_cannon_unlocked);
smlua_bind_function(L, "save_file_reload", smlua_func_save_file_reload);
+ smlua_bind_function(L, "save_file_remove_star_flags", smlua_func_save_file_remove_star_flags);
smlua_bind_function(L, "save_file_set_course_coin_score", smlua_func_save_file_set_course_coin_score);
smlua_bind_function(L, "save_file_set_flags", smlua_func_save_file_set_flags);
smlua_bind_function(L, "save_file_set_star_flags", smlua_func_save_file_set_star_flags);
diff --git a/src/pc/network/packets/packet.c b/src/pc/network/packets/packet.c
index eb321820f..2284c6ea3 100644
--- a/src/pc/network/packets/packet.c
+++ b/src/pc/network/packets/packet.c
@@ -97,6 +97,7 @@ void packet_process(struct Packet* p) {
case PACKET_LEAVING: network_receive_leaving(p); break;
case PACKET_SAVE_FILE: network_receive_save_file(p); break;
case PACKET_SAVE_SET_FLAG: network_receive_save_set_flag(p); break;
+ case PACKET_SAVE_REMOVE_FLAG: network_receive_save_remove_flag(p); break;
case PACKET_NETWORK_PLAYERS: network_receive_network_players(p); break;
case PACKET_DEATH: network_receive_death(p); break;
diff --git a/src/pc/network/packets/packet.h b/src/pc/network/packets/packet.h
index d7b9cd91f..af7a0a39c 100644
--- a/src/pc/network/packets/packet.h
+++ b/src/pc/network/packets/packet.h
@@ -33,6 +33,7 @@ enum PacketType {
PACKET_LEAVING,
PACKET_SAVE_FILE,
PACKET_SAVE_SET_FLAG,
+ PACKET_SAVE_REMOVE_FLAG,
PACKET_NETWORK_PLAYERS,
PACKET_DEATH,
@@ -261,6 +262,10 @@ void network_receive_save_file(struct Packet* p);
void network_send_save_set_flag(s32 fileIndex, s32 courseIndex, u8 courseStars, u32 flags);
void network_receive_save_set_flag(struct Packet* p);
+// packet_save_remove_flag.c
+void network_send_save_remove_flag(s32 fileIndex, s32 courseIndex, u8 courseStarsToRemove, u32 flagsToRemove);
+void network_receive_save_remove_flag(struct Packet* p);
+
// packet_network_players.c
void network_send_network_players_request(void);
void network_receive_network_players_request(struct Packet* p);
diff --git a/src/pc/network/packets/packet_save_remove_flag.c b/src/pc/network/packets/packet_save_remove_flag.c
new file mode 100644
index 000000000..179d6e790
--- /dev/null
+++ b/src/pc/network/packets/packet_save_remove_flag.c
@@ -0,0 +1,55 @@
+#include
+#include "../network.h"
+#include "game/save_file.h"
+#include "buffers/buffers.h"
+#include "pc/debuglog.h"
+
+extern u8 gSaveFileUsingBackupSlot;
+
+void network_send_save_remove_flag(s32 fileIndex, s32 courseIndex, u8 courseStarsToRemove, u32 flagsToRemove) {
+ struct Packet p = { 0 };
+ packet_init(&p, PACKET_SAVE_REMOVE_FLAG, true, PLMT_NONE);
+ packet_write(&p, &fileIndex, sizeof(s32));
+ packet_write(&p, &courseIndex, sizeof(s32));
+ packet_write(&p, &courseStarsToRemove, sizeof(u8));
+ packet_write(&p, &flagsToRemove, sizeof(u32));
+ packet_write(&p, &gSaveFileUsingBackupSlot, sizeof(u8));
+ network_send(&p);
+}
+
+void network_receive_save_remove_flag(struct Packet* p) {
+ s32 fileIndex;
+ s32 courseIndex;
+ u8 courseStarsToRemove;
+ u32 flagsToRemove;
+ u8 backupSlot;
+ packet_read(p, &fileIndex, sizeof(s32));
+ packet_read(p, &courseIndex, sizeof(s32));
+ packet_read(p, &courseStarsToRemove, sizeof(u8));
+ packet_read(p, &flagsToRemove, sizeof(u32));
+ packet_read(p, &backupSlot, sizeof(u8));
+
+ if (fileIndex >= NUM_SAVE_FILES) {
+ LOG_ERROR("Invalid fileIndex: %d", fileIndex);
+ return;
+ }
+
+ if (courseIndex >= COURSE_COUNT) {
+ LOG_ERROR("Invalid courseIndex: %d", courseIndex);
+ return;
+ }
+
+ if (backupSlot > 1) {
+ LOG_ERROR("Invalid backupSlot: %d", backupSlot);
+ return;
+ }
+
+ // Remove the specified star flags and flags from the save data
+ if (courseIndex == -1) {
+ gSaveBuffer.files[fileIndex][backupSlot].flags &= ~flagsToRemove;
+ } else {
+ gSaveBuffer.files[fileIndex][backupSlot].courseStars[courseIndex] &= ~courseStarsToRemove;
+ }
+
+ gSaveFileModified = TRUE;
+}
\ No newline at end of file
diff --git a/src/pc/network/packets/packet_save_set_flag.c b/src/pc/network/packets/packet_save_set_flag.c
index a1a67d538..62e9f5403 100644
--- a/src/pc/network/packets/packet_save_set_flag.c
+++ b/src/pc/network/packets/packet_save_set_flag.c
@@ -47,4 +47,4 @@ void network_receive_save_set_flag(struct Packet* p) {
gSaveBuffer.files[fileIndex][backupSlot].courseStars[courseIndex] |= courseStars;
gSaveBuffer.files[fileIndex][backupSlot].flags |= flags;
gSaveFileModified = TRUE;
-}
+}
\ No newline at end of file