diff options
author | B. Stack <bgstack15@gmail.com> | 2024-03-19 13:12:15 -0400 |
---|---|---|
committer | B. Stack <bgstack15@gmail.com> | 2024-03-19 13:12:15 -0400 |
commit | 5d403bec9273db6b5b5afdd1730f6bcd96766243 (patch) | |
tree | 1fda5a12b7ffb2bb2955e70a01172eeca6f5d300 /srb_lib.py | |
parent | add get/add/remove purchased planes (diff) | |
download | srb_lib-5d403bec9273db6b5b5afdd1730f6bcd96766243.tar.gz srb_lib-5d403bec9273db6b5b5afdd1730f6bcd96766243.tar.bz2 srb_lib-5d403bec9273db6b5b5afdd1730f6bcd96766243.zip |
add set-level, set-level-balloons
Diffstat (limited to 'srb_lib.py')
-rw-r--r-- | srb_lib.py | 91 |
1 files changed, 71 insertions, 20 deletions
@@ -130,20 +130,28 @@ LEVELS = [ # hex values # WORKHERE: I think balloons and letters merely count as one of the types of requirements. there can up to 5 secondary objectives in a level (maybe the levels without balloons though?). This is probably a bitmask for secondary objectives (including all-balloons,all-letters),health,time. # Definitely 0x64 means the whole level is 100% complete, rank General. -LEVEL_STATUSES = { - "4A": "3-balloons,no-letters,under-time,good-health,corporal", - "47": "2-balloons,no-letters,under-time,good-health,corporal", - "59": "all-balloons,all-letters,under-time,good-health,sergeant", - "5B": "all-balloons,all-letters,under-time,good-health,colonel", - "5B": "9-balloons,no-letter,under-time,good-health,colonel", - "5D": "all-balloons,all-letters,under-time,good-health,colonel", - "5E": "all-balloons,no-letter,under-time,good-health,colonel", - "60": "all-balloons,all-letters,under-time,good-health,colonel", - "61": "all-balloons,all-letters,under-time,2/3obj,good-health,colonel", - "62": "all-balloons,all-letters,under-time,good-health,colonel", - "63": "all-balloons,all-letters,under-time,good-health,colonel", - "64": "all-balloons,all-letters,under-time,good-health,general" -} +#LEVEL_STATUSES = { +# "4A": "3-balloons,no-letters,under-time,good-health,corporal", +# "47": "2-balloons,no-letters,under-time,good-health,corporal", +# "59": "all-balloons,all-letters,under-time,good-health,sergeant", +# "5B": "all-balloons,all-letters,under-time,good-health,colonel", +# "5B": "9-balloons,no-letter,under-time,good-health,colonel", +# "5D": "all-balloons,all-letters,under-time,good-health,colonel", +# "5E": "all-balloons,no-letter,under-time,good-health,colonel", +# "60": "all-balloons,all-letters,under-time,good-health,colonel", +# "61": "all-balloons,all-letters,under-time,2/3obj,good-health,colonel", +# "62": "all-balloons,all-letters,under-time,good-health,colonel", +# "63": "all-balloons,all-letters,under-time,good-health,colonel", +# "64": "all-balloons,all-letters,under-time,good-health,general" +#} + +# While there are other bitmasks for most ranks, general is only ever 0x64. +LEVEL_STATUSES = [ + {"b":0x47,"name":"corporal"}, + {"b":0x59,"name":"sergeant"}, + {"b":0x5B,"name":"colonel"}, + {"b":0x64,"name":"general"}, # depends on all secondary objectives, all letters, all balloons, under time, at least 50/100 health, not lost any lives. +] POS_TUTORIAL_COMPLETED = 0x2D0 # bool @@ -342,7 +350,7 @@ def get_purchased_weapons(data_object,profile_id,silent=False): print(f"debug: currently have 0x{weapons_mask:04x} b{weapons_mask:016b}, {weapons_list}") return ','.join(weapons_list), weapons_mask -def get_level_status(data_object,profile_id,level): +def get_level_status(data_object,profile_id,level,silent=False): """ WORKHERE: need to write set methods for this. """ data = _get_data_from_data_object(data_object) level_obj, message = get_level_info(level) @@ -351,7 +359,8 @@ def get_level_status(data_object,profile_id,level): levelset_obj, message = get_levelset_info(level_obj["setid"]) if message != "" or levelset_obj == -1: ferror(f"Unable to get levelset status for {level_obj['setid']}.") - print(f"Debug: for input {level} found level_obj {level_obj} and message {message}") + if not silent: + print(f"Debug: for input {level} found level_obj {level_obj} and message {message}") pos_level_status = PROFILE_START_POSITION[profile_id]+POS_LEVEL_START+(INT_SIZE*level_obj["pos_r"]) pos_level_balloons = PROFILE_START_POSITION[profile_id]+POS_LEVEL_BALLOONS+(level_obj["setid"]*POS_LEVEL_BALLOONS_MULTIPLIER_LEVELSET)+(POS_LEVEL_BALLOONS_MULTIPLIER_LEVEL*level_obj["set_pos"]) pos_level_which_balloons = pos_level_balloons + INT_SIZE @@ -360,14 +369,56 @@ def get_level_status(data_object,profile_id,level): profile_level_balloons = data[pos_level_balloons] profile_level_which_balloons = struct.unpack_from('<1i',data,pos_level_which_balloons)[0] profile_level_letters = data[pos_level_letters] - print(f"Debug: abs 0x{CHECKSUM_LENGTH+pos_level_status:04x} level status 0x{profile_level_status:x}") - print(f"Debug: abs 0x{CHECKSUM_LENGTH+pos_level_balloons:04x} collected balloon count: {profile_level_balloons}/{level_obj['b']}") - print(f"Debug: abs 0x{CHECKSUM_LENGTH+pos_level_which_balloons:04x} which balloons: b{profile_level_which_balloons:010b}") - print(f"Debug: abs 0x{CHECKSUM_LENGTH+pos_level_letters:04x} letter count: {profile_level_letters}/{len(level_obj['l'])}") + if not silent: + print(f"Debug: abs 0x{CHECKSUM_LENGTH+pos_level_status:04x} level status 0x{profile_level_status:x}") + print(f"Debug: abs 0x{CHECKSUM_LENGTH+pos_level_balloons:04x} collected balloon count: {profile_level_balloons}/{level_obj['b']}") + print(f"Debug: abs 0x{CHECKSUM_LENGTH+pos_level_which_balloons:04x} which balloons: b{profile_level_which_balloons:010b}") + print(f"Debug: abs 0x{CHECKSUM_LENGTH+pos_level_letters:04x} letter count: {profile_level_letters}/{len(level_obj['l'])}") # WORKHERE: show which balloons are collected already for this level? # it comes back as an int, but does it look better as a hex? return hex(profile_level_status) +def set_level_status(data_object,profile_id,level,status): + data = _get_data_from_data_object(data_object) + level_obj, message = get_level_info(level) + if message != "" or level == -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}") + bits = 0x0 + try: + bits = [i for i in LEVEL_STATUSES if i["name"]==status][0]["b"] + except: + return data, "", f"unable-to-set-level-completion-status-{status}" + print(f"debug: will try to set bits {bits:02x}") + 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) + return data, current_status, "" + +def set_level_balloons(data_object,profile_id,level,count): + data = _get_data_from_data_object(data_object) + level_obj, message = get_level_info(level) + if message != "" or level == -1: + ferror(f"Unable to get level status for {level}.") + # simplify the task; does a user really need to set individual balloons?! + if count not in ["all","none"]: + return -1, f"Can only set balloons to all or none for a level." + pos_level_balloons = PROFILE_START_POSITION[profile_id]+POS_LEVEL_BALLOONS+(level_obj["setid"]*POS_LEVEL_BALLOONS_MULTIPLIER_LEVELSET)+(POS_LEVEL_BALLOONS_MULTIPLIER_LEVEL*level_obj["set_pos"]) + pos_level_which_balloons = pos_level_balloons + INT_SIZE + #profile_level_balloons = data[pos_level_balloons] + #profile_level_which_balloons = struct.unpack_from('<1i',data,pos_level_which_balloons)[0] + #print(f"Debug: abs 0x{CHECKSUM_LENGTH+pos_level_balloons:04x} collected balloon count: {profile_level_balloons}/{level_obj['b']}") + #print(f"Debug: abs 0x{CHECKSUM_LENGTH+pos_level_which_balloons:04x} which balloons: b{profile_level_which_balloons:010b}") + if count == "all": + target_count = 10 + target_which = 0x3FF # b1111111111, or bitmask that is 10 bits long + else: + target_count = 0 + target_which = 0x0 + data = srb_pack('<1i',data,pos_level_balloons,target_count) + data = srb_pack('<1i',data,pos_level_which_balloons,target_which) + return data, "" + def get_levelset_status(data_object,profile_id,levelset): """ WORKHERE: need to make set methods. """ data = _get_data_from_data_object(data_object) |