aboutsummaryrefslogtreecommitdiff
path: root/srb.py
blob: e762b724008cf2519903374590d3fb9851fb4fe7 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
#!/usr/bin/env python3
# Startdate: 2024-03-08-6 15:28
# File: srb_lib.py
# Purpose: frontend for srb_lib
# History:
# Usage:
# Reference:
#    blog posts 2024-03
#    delsum from github
#    bgconf.py

# WORKHERE: right now, this only just corrects any file. in the future, offer options like --profile 1 --set-money 3045 --give-plane all or --give-plane marcie
# or --take-plan marcie or --set-rank-level 1,general --set-rank-level 1,none --set-rank-level all,general
# or --give-weapon pumpkin --take-weapon bees
# or --give-balloons-level 10 --take-balloons-level 11
# make chart of level numbers, which ones have balloons
# or --reset-level 5 (which zeros out all info about completion of that level)
# --set-plane-health 1 (through 4)
# --set-plane-weapon 1 (through 5)
# --set-plane-stunt 1 (through 4)
# --set-profile-name "asdbdf"

import srb_lib, argparse, sys
from srb_lib import ferror, debuglev

HELP_WEAPONS = ""

for w in srb_lib.WEAPONS:
   HELP_WEAPONS += str(w["id"]) + "," + w["name"] + ','
HELP_WEAPONS = HELP_WEAPONS.rstrip(",")

parser = argparse.ArgumentParser(description="Cli tool for manipulating savegame files for srb.exe",
   formatter_class=argparse.RawDescriptionHelpFormatter,
   epilog=f"""LEVELS include {[i['name'] for i in srb_lib.LEVELS]+list(range(0,len(srb_lib.LEVELS)))}
WEAPONS include {HELP_WEAPONS}
NAME_CHARS include "{srb_lib.NAME_CHARS}"
""")
parser.add_argument("-V","--version",action="version",version="%(prog)s " + srb_lib.srb_lib_version)
parser.add_argument("-d","--debug",nargs='?',default=0,type=int,choices=range(0,11),help="Set debug level")
parser.add_argument("--profile",type=int,choices=range(1,4),help="Profile in user menu.")
parser.add_argument("--get-money",action="store_true",help="Print current money for profile.")
parser.add_argument("--set-money",type=int,help="Set money for profile.")
parser.add_argument("--get-weapon",action="store_true",help="Print currently equipped weapon for profile.")
# choices seems to be too strict here for the numbers. We can live with just the
#choices=[i for i in srb_lib.WEAPONS if i != "undefined"]+list(range(0,16))
#parser.add_argument("--set-weapon",choices=[i for i in srb_lib.WEAPONS if i != "undefined"],help="Print currently equipped weapon for profile.")
parser.add_argument("--set-weapon",help="Set currently equipped weapon for profile.")
parser.add_argument("--get-purchased-weapons",action="store_true",help="Print currently purchased weapon for profile.")
parser.add_argument("--add-purchased-weapons",action="append",help="For profile, add these purchased weapons. Can be used multiple times.")
parser.add_argument("--remove-purchased-weapons",action="append",help="For profile, add these purchased weapons. Can be used multiple times.")
parser.add_argument("--get-level",help="Print status for this level for profile.")
parser.add_argument("--get-levelset",help="Print status for this levelset for profile.")
parser.add_argument("--get-name",action="store_true",help="Print name for profile.")
parser.add_argument("--set-name",help="Set name for profile.")
parser.add_argument("--get-profile-in-use",action="store_true",help="Print if profile is in use.")
parser.add_argument("--get-tutorial-completed",action="store_true",help="Print if profile has completed the tutorial.")
parser.add_argument("--set-tutorial-completed",choices=["True","False"],help="Set tutorial-completed for profile.")
parser.add_argument("--get-health",action="store_true",help="Print stat health for profile.")
parser.add_argument("--set-health",type=int,choices=range(1,5),help="Set stat health for profile.")
parser.add_argument("--get-stunt",action="store_true",help="Print stat stunt for profile.")
parser.add_argument("--set-stunt",type=int,choices=range(1,5),help="Set stat stunt for profile.")
parser.add_argument("--get-gun",action="store_true",help="Print stat gun for profile.")
parser.add_argument("--set-gun",type=int,choices=range(1,6),help="Set stat gun for profile.")
parser.add_argument("--checksum",action=argparse.BooleanOptionalAction,default=True,help="Correct checksum. Default is to do this. It happens at the end of everything else.")
parser.add_argument("file",default="Profile 1.sav")
args = parser.parse_args()
debuglevel = 0
if args.debug:
   debuglevel = args.debug

if debuglev(1,debuglevel):
   ferror("debug level", debuglevel)
if debuglev(8,debuglevel):
   ferror(args)

# common parameters
profile_id = args.profile

#print(f"profile_id={profile_id}")

# WORKHERE: new actions that need --profile must be added here.
if not profile_id and (args.get_money or args.set_money or args.get_weapon or args.set_weapon or args.get_level or args.get_name or args.set_name or args.get_profile_in_use or args.get_purchased_weapons or args.get_tutorial_completed or args.add_purchased_weapons or args.remove_purchased_weapons or args.get_health or args.get_stunt or args.get_gun or args.set_health or args.set_stunt or args.set_gun or args.get_levelset):
   ferror("Warning: Cannot perform most actions without --profile. Not all tasks may run.")
else:
   if args.get_money:
      money = srb_lib.get_money(args.file, profile_id)
      print(f"Profile {profile_id} has {money} money.")
   if args.set_money:
      if args.set_money > 0xFFFF:
         ferror(f"Warning: Do not set money higher than 65535. While it can technically work, there's no need for that in-game anyways. Continuing...")
      else:
         data = srb_lib.set_money(args.file, profile_id, args.set_money)
         srb_lib.write_file(args.file,0,data)
   if args.get_weapon:
      print(f"Profile {profile_id} has weapon {srb_lib.get_weapon(args.file, profile_id)}")
   if args.set_weapon:
      try:
         args.set_weapon = int(args.set_weapon)
      except:
         pass
      data = srb_lib.set_weapon(args.file, profile_id, args.set_weapon)
      if type(data) == int and data == -1:
         # error is printed in the function
         pass
      else:
         srb_lib.write_file(args.file,0,data)
   if args.get_level:
      print(f"Profile {profile_id} has level {args.get_level} status {srb_lib.get_level_status(args.file,profile_id,args.get_level)}")
   if args.get_levelset:
      print(f"Profile {profile_id} has levelset {args.get_levelset} status {srb_lib.get_levelset_status(args.file,profile_id,args.get_levelset)}")
   if args.get_name:
      print(f"Profile {profile_id} has name {srb_lib.get_name(args.file,profile_id)}")
   if args.set_name:
      data, message = srb_lib.set_name(args.file, profile_id, args.set_name)
      if (type(data) == int and data == -1) or message != "":
         ferror(f"Failed to set profile {profile_id} name to {args.set_name} because {message}")
      else:
         srb_lib.write_file(args.file,0,data)
   if args.get_profile_in_use:
      print(f"Profile {profile_id} in use is {srb_lib.get_profile_in_use(args.file,profile_id)}")
   if args.get_purchased_weapons:
      print(f"Profile {profile_id} has weapons {srb_lib.get_purchased_weapons(args.file,profile_id)}")
   if args.add_purchased_weapons:
      data, message = srb_lib.set_purchased_weapons(args.file,profile_id,"add",args.add_purchased_weapons)
      if (type(data) == int and data == -1) or message != "":
         ferror(f"Failed to add purchased weapons {args.add_purchased_weapons} because {message}")
      else:
         srb_lib.write_file(args.file,0,data)
   if args.remove_purchased_weapons:
      data, message = srb_lib.set_purchased_weapons(args.file,profile_id,"remove",args.remove_purchased_weapons)
      if (type(data) == int and data == -1) or message != "":
         ferror(f"Failed to add purchased weapons {args.remove_purchased_weapons} because {message}")
      else:
         srb_lib.write_file(args.file,0,data)
   if args.get_tutorial_completed:
      print(f"Profile {profile_id} completed-tutorial is {srb_lib.get_tutorial_completed(args.file,profile_id)}")
   if args.set_tutorial_completed:
      thisbool = False if args.set_tutorial_completed == "False" else True
      data, newstatus = srb_lib.set_tutorial_completed(args.file,profile_id,thisbool)
      srb_lib.write_file(args.file,0,data)
   if args.get_health:
      stat, message = srb_lib.get_plane_stat(args.file,profile_id,"health")
      # error is printed in the function, so if not any error, run
      if not (stat == -1 or message != ""):
         print(f"Profile {profile_id} has health level {stat}")
   if args.set_health:
      data, message = srb_lib.set_plane_stat(args.file,profile_id,"health",args.set_health)
      if data == -1 or message != "":
         print(f"Failed to set health to {args.set_health} because {message}")
      else:
         srb_lib.write_file(args.file,0,data)
   if args.get_stunt:
      stat, message = srb_lib.get_plane_stat(args.file,profile_id,"stunt")
      # error is printed in the function, so if not any error, run
      if not (stat == -1 or message != ""):
         print(f"Profile {profile_id} has stunt level {stat}")
   if args.set_stunt:
      data, message = srb_lib.set_plane_stat(args.file,profile_id,"stunt",args.set_stunt)
      if data == -1 or message != "":
         print(f"Failed to set stunt to {args.set_stunt} because {message}")
      else:
         srb_lib.write_file(args.file,0,data)
   if args.get_gun:
      stat, message = srb_lib.get_plane_stat(args.file,profile_id,"gun")
      # error is printed in the function, so if not any error, run
      if not (stat == -1 or message != ""):
         print(f"Profile {profile_id} has gun level {stat}")
   if args.set_gun:
      data, message = srb_lib.set_plane_stat(args.file,profile_id,"gun",args.set_gun)
      if data == -1 or message != "":
         print(f"Failed to set gun to {args.set_gun} because {message}")
      else:
         srb_lib.write_file(args.file,0,data)

if args.checksum:
   f = args.file
   #for f in args.file:
   if debuglev(1,debuglevel):
      ferror(f"Fixing checksum for file {f}")
   srb_lib.correct_file(f,debuglevel)
bgstack15