diff options
Diffstat (limited to 'srb_lib.py')
-rw-r--r-- | srb_lib.py | 41 |
1 files changed, 23 insertions, 18 deletions
@@ -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) |