aboutsummaryrefslogtreecommitdiff
path: root/srb_lib.py
diff options
context:
space:
mode:
Diffstat (limited to 'srb_lib.py')
-rw-r--r--srb_lib.py41
1 files changed, 23 insertions, 18 deletions
diff --git a/srb_lib.py b/srb_lib.py
index c916c6b..d388385 100644
--- a/srb_lib.py
+++ b/srb_lib.py
@@ -412,14 +412,14 @@ def get_collected_breakables(data_object,profile_id, level, silent=False):
print(f"Debug: abs 0x{CHECKSUM_LENGTH+pos_level_which_breakables:04x} which breakables: b{profile_level_which_breakables:05b}")
return ','.join(breakables_list), breakables_mask
-def set_level_status(data_object,profile_id,level,status):
+def set_level_status(data_object,profile_id,level,status,fix_levelset_available_levels=True):
""" Set completion rank for a level, e.g., general """
data = _get_data_from_data_object(data_object)
level_obj, message = get_level_info(level)
if message != "" or level_obj == -1:
ferror(f"Unable to get level status for {level}.")
current_status, _, _ = get_level_status(data, profile_id, level, silent=True)
- print(f"Before changing, level {level} has status {current_status}")
+ #print(f"Before changing, level {level} has status {current_status}")
bits = 0x0
try:
bits = [i for i in LEVEL_STATUSES if i["name"]==status][0]["b"]
@@ -429,17 +429,18 @@ def set_level_status(data_object,profile_id,level,status):
data = srb_pack('<1I',data,PROFILE_START_POSITION[profile_id]+POS_LEVEL_START+(INT_SIZE*level_obj["pos_r"]),bits)
current_status, _, _ = get_level_status(data, profile_id, level, silent=True)
levelset_available_levels = get_levelset_available_levels(data,profile_id,level_obj["setid"])
- print(f"debug: levelset {level_obj['setid']} currently has {levelset_available_levels} available levels.")
+ #print(f"debug: levelset {level_obj['setid']} currently has {levelset_available_levels} available levels.")
# if setting to any completed status, if the levelset available levels is less than this level, then make it this.
- if levelset_available_levels < (level_obj["set_pos"] + 1) and status not in ["none"]:
- data, message = set_levelset_available_levels(data,profile_id,level_obj["setid"],level_obj["set_pos"] + 1)
- if message != "":
- return -1, -1, f"Unable to set levelset available levels to minimum of this level set_pos {level_obj['set_pos']}"
- # decrement the available levels in the levelset if clearing out this level and the available levels is exactly this one.
- if levelset_available_levels == (level_obj["set_pos"] + 1) and status in ["none"]:
- data, message = set_levelset_available_levels(data,profile_id,level_obj["setid"],level_obj["set_pos"])
- if message != "":
- return -1, -1, f"Unable to decrement levelset available levels."
+ if fix_levelset_available_levels:
+ if levelset_available_levels < (level_obj["set_pos"] + 1) and status not in ["none"]:
+ data, message = set_levelset_available_levels(data,profile_id,level_obj["setid"],level_obj["set_pos"] + 1)
+ if message != "":
+ return -1, -1, f"Unable to set levelset available levels to minimum of this level set_pos {level_obj['set_pos']}"
+ # decrement the available levels in the levelset if clearing out this level and the available levels is exactly this one.
+ if levelset_available_levels == (level_obj["set_pos"] + 1) and status in ["none"]:
+ data, message = set_levelset_available_levels(data,profile_id,level_obj["setid"],level_obj["set_pos"])
+ if message != "":
+ return -1, -1, f"Unable to decrement levelset available levels."
return data, current_status, ""
def set_level_balloons(data_object,profile_id,level,count):
@@ -504,7 +505,7 @@ def get_levelset_status(data_object,profile_id,levelset,silent=False):
# it comes back as an int, but does it look better as a hex?
return profile_levelset_status, completed_letters
-def set_level_letters(data_object,profile_id,level,letters):
+def set_level_letters(data_object,profile_id,level,letters, silent = False):
""" Set collected letters for given level to all or none. """
data = _get_data_from_data_object(data_object)
level_obj, message = get_level_info(level)
@@ -532,7 +533,8 @@ def set_level_letters(data_object,profile_id,level,letters):
profile_levelset_completed_letters_mask = struct.unpack_from('<1I',data,pos_levelset_completed_letters_mask)[0] >> 1
# python trick to reverse a custom-formatted string and convert back to int while reading the string as base 2
profile_levelset_completed_letters_mask = int(f"{profile_levelset_completed_letters_mask:0{len(levelset_obj['le'])}b}"[::-1],2)
- print(f"debug: levelset {levelset_obj['id']} before changes has letters mask {profile_levelset_completed_letters_mask:0{len(levelset_obj['le'])}b}")
+ if not silent:
+ print(f"debug: levelset {levelset_obj['id']} before changes has letters mask {profile_levelset_completed_letters_mask:0{len(levelset_obj['le'])}b}")
levels_to_check = [i for i in LEVELS if i["setid"] == levelset_obj["id"]]
#print(f"need to check levels {levels_to_check}")
levelset_letters_count = 0
@@ -561,12 +563,13 @@ def set_level_letters(data_object,profile_id,level,letters):
#print(f"debug: intermediate, new_letter_mask={new_letter_mask}")
new_letter_mask = "".join(new_letter_mask)
new_letter_mask_int = int(new_letter_mask,2)
- #print(f"debug: new_letter_mask updated list is str {new_letter_mask}, int {new_letter_mask_int}")
- #print(f"debug: total letters collected for levelset {levelset_obj['id']}: {levelset_letters_count}")
- print(f"debug: new letters bitmask for levelset {levelset_obj['id']}: {new_letter_mask_int:0{len(new_letter_mask)}b}")
+ if not silent:
+ #print(f"debug: new_letter_mask updated list is str {new_letter_mask}, int {new_letter_mask_int}")
+ #print(f"debug: total letters collected for levelset {levelset_obj['id']}: {levelset_letters_count}")
+ print(f"debug: new letters bitmask for levelset {levelset_obj['id']}: {new_letter_mask_int:0{len(new_letter_mask)}b}")
# bitmask needs to be reversed and left-1-bitshifted
new_letter_mask_final = int(f"{new_letter_mask_int:0{len(levelset_obj['le'])}b}"[::-1],2) << 1
- print(f"debug: so that final bitmask should be {new_letter_mask_final:016b}")
+ #print(f"debug: so that final bitmask should be {new_letter_mask_final:016b}")
# set levelset letter count
data = srb_pack('<1I',data,pos_levelset_completed_letters_count,levelset_letters_count)
# set levelset letter mask
@@ -625,6 +628,8 @@ def get_collected_balloons_for_levelset(data_object,profile_id,levelset,silent=F
def get_level_info(level):
""" Returns dictionary of level from LEVELS, searching by id or name. """
+ if level in LEVELS:
+ return level, ""
try:
# if it is an integer, make sure it shows up as one in the next check
level = int(level)
bgstack15