Added tentative support for medals - need to check if gun/armour/talent are involved. Haven't tested it yet - at least non-medal use still works correctly.

This commit is contained in:
Zergling_man 2023-05-14 15:12:17 +10:00
parent 532a6b24e7
commit 98d86c829e
3 changed files with 31 additions and 10 deletions

4
README
View File

@ -3,6 +3,7 @@ Rank Code Personal Database.
How to use: How to use:
Currently there is no real UI, so start by running python in this dir and `import codegen`. Currently there is no real UI, so start by running python in this dir and `import codegen`.
Config file is in ~/.config/swat.cfg. If you want it somewhere else, open codegen.py and edit line 6. Do this BEFORE `import codegen`. If you've already imported it, quit python and reopen it. Config file is in ~/.config/swat.cfg. If you want it somewhere else, open codegen.py and edit line 6. Do this BEFORE `import codegen`. If you've already imported it, quit python and reopen it.
If you are using Windows, you HAVE to edit that line or setup will fail.
Setup: Setup:
Execute `codegen.add_user('{YOUR IGN}')`. This will create the config file if it doesn't exist. You can add as many users as you like if you want to have multiple profiles for whatever reason (I cannot think of a reason, I just added it for fun). Execute `codegen.add_user('{YOUR IGN}')`. This will create the config file if it doesn't exist. You can add as many users as you like if you want to have multiple profiles for whatever reason (I cannot think of a reason, I just added it for fun).
@ -12,7 +13,8 @@ General use:
To load a code, use `codegen.read_code('0000-0000-0000-0000')`. You can put it in without the hyphens, also you can use anything in there, doesn't have to be hyphens. I recommend having something in between because it's helpful for checking the code is right. To load a code, use `codegen.read_code('0000-0000-0000-0000')`. You can put it in without the hyphens, also you can use anything in there, doesn't have to be hyphens. I recommend having something in between because it's helpful for checking the code is right.
To load a bunch of codes at once, do `codegen.mass_add()`, it just calls `read_code` in a loop. It stops if you give it a blank line. To load a bunch of codes at once, do `codegen.mass_add()`, it just calls `read_code` in a loop. It stops if you give it a blank line.
To generate codes, use `codegen.generate('class/line')`, where you give it class/gun/armour/trait/spec/talent. Look in tables.py for the names you should be using; it is not case sensitive, at least. Also gun is optional unless it's mav/wm. (Note if you try to gen the wrong gun on a class, my gen will not stop you. The code will probably be invalid 🤷.) To generate codes, use `codegen.generate('class/line')`, where you give it class/armour/trait/spec/talent. Look in tables.py for the names you should be using; it is not case sensitive, at least.
If generating mav/wm, you must specify the gun BEFORE the class, with no slash, like so: "glwm", "rmav". For WM use two letters, for mav use one. Actually WM *might* work with one. Not sure.
To check your progress, use `codegen.ranks()`. It's not very pretty yet, it's a work in progress. To check your progress, use `codegen.ranks()`. It's not very pretty yet, it's a work in progress.

View File

@ -1,4 +1,4 @@
import encode, decode import encode, decode, shared
import tables import tables
import os import os
@ -6,7 +6,7 @@ conf={}
confp=os.path.expanduser('~/.config/swat.cfg') # This won't work on Windows. You'll need to tweak this to run it on Windows. Not my problem. confp=os.path.expanduser('~/.config/swat.cfg') # This won't work on Windows. You'll need to tweak this to run it on Windows. Not my problem.
defaults={'classes':[(1,3),(1,3),(1,3),(1,3),(1,3),(1,3),(1,3),(0,0),(0,0),(1,3),(1,3),(1,3)],'guns':[(1,3),(1,3),(1,3),(1,3),(1,3),(0,0),(0,0),(0,0)],'armour':[(1,3),(1,3),(1,3),(1,3)],'traits':[(1,3),(1,3),(1,3),(1,3),(1,3),(1,3),(1,3),(1,3),(1,3),(1,3),(1,3),(1,3),(1,3),(1,3),(1,3),(1,3)],'specs':[(1,3),(1,3),(1,3),(1,3),(1,3),(1,3),(1,3),(1,3),(1,3)],'talents':[(12,12),(1,3),(1,3),(1,3),(1,3),(1,3),(1,3)]} defaults={'classes':[(1,3),(1,3),(1,3),(1,3),(1,3),(1,3),(1,3),(0,0),(0,0),(1,3),(1,3),(1,3)],'guns':[(1,3),(1,3),(1,3),(1,3),(1,3),(0,0),(0,0),(0,0)],'armour':[(1,3),(1,3),(1,3),(1,3)],'traits':[(1,3),(1,3),(1,3),(1,3),(1,3),(1,3),(1,3),(1,3),(1,3),(1,3),(1,3),(1,3),(1,3),(1,3),(1,3),(1,3)],'specs':[(1,3),(1,3),(1,3),(1,3),(1,3),(1,3),(1,3),(1,3),(1,3)],'talents':[(12,12),(1,3),(1,3),(1,3),(1,3),(1,3),(1,3)],'medals':{}}
def add_user(name): def add_user(name):
namehash=encode.hash_name(name) # Store the hash so that if they request a different name that happens to have the same hash, it can just be stored together. namehash=encode.hash_name(name) # Store the hash so that if they request a different name that happens to have the same hash, it can just be stored together.
if namehash in conf : conf[namehash]['names'].add(name) if namehash in conf : conf[namehash]['names'].add(name)
@ -30,8 +30,11 @@ def load_conf():
lines=n.split('\n') lines=n.split('\n')
header=lines[0].split(' ') header=lines[0].split(' ')
nhash=int(header[0]); names=set(header[1:]) # Makes deduping way easier nhash=int(header[0]); names=set(header[1:]) # Makes deduping way easier
medals={}
if ':' in lines[-1]: # Since this isn't used in any other line, it's safe
medals={n.split(':')[0]:n.split(':')[1] for n in lines.pop(-1).split(' ')}
stuff={k:parse_conf_line(v) for k,v in zip(tables.displays_str[:-1],lines[1:])} stuff={k:parse_conf_line(v) for k,v in zip(tables.displays_str[:-1],lines[1:])}
conf[nhash]={'names':names}|stuff conf[nhash]={'names':names}|stuff|{'medals':medals}
update_all_talents() update_all_talents()
global active_profile global active_profile
active_profile=nhash active_profile=nhash
@ -45,6 +48,7 @@ def save_conf():
write+=' '.join([str(k)]+list(v['names']))+'\n' write+=' '.join([str(k)]+list(v['names']))+'\n'
for n in map(lambda x:unparse_conf_line(v[x]),tables.displays_str[:-1]): for n in map(lambda x:unparse_conf_line(v[x]),tables.displays_str[:-1]):
write+=n+'\n' write+=n+'\n'
write+=' '.join(f'{h}:{m}' for h,m in v['medals'].items())+'\n'
write+='\n' write+='\n'
write=write[:-2] write=write[:-2]
open(confp,'w').write(write) open(confp,'w').write(write)
@ -84,25 +88,28 @@ def read_code(code,save=True):
if rank<9: show[-1]='Hidden' # Don't spoil the talent if rank<9: show[-1]='Hidden' # Don't spoil the talent
print(show) print(show)
print(str(rank)+'/'+str(cap)) print(str(rank)+'/'+str(cap))
print(data) print(data) # Extract medals and save them
medals=data[1:-1]
if any(medals): conf[active_profile]['medals'][shared.muxhero(hero[0],hero[3],hero[4])]=shared.muxmedals(medals)
if not check: print('No name given, code validation not performed') if not check: print('No name given, code validation not performed')
else: else:
if check!=validator: print('code did not validate:',validator,check); return if check!=validator: print('code did not validate:',validator,check); return
else: print('code validated') else: print('code validated')
if not save: return
for thing in zip(tables.displays_str[:-1],hero): for thing in zip(tables.displays_str[:-1],hero):
saved=conf[active_profile][thing[0]][thing[1]] saved=conf[active_profile][thing[0]][thing[1]]
saved=(max(saved[0],rank),max(saved[1],cap)) saved=(max(saved[0],rank),max(saved[1],cap))
conf[active_profile][thing[0]][thing[1]]=saved conf[active_profile][thing[0]][thing[1]]=saved
update_talents(hero[0]) update_talents(hero[0])
if not save: return
save_conf() save_conf()
def mass_add(): def mass_add():
a=input('>') a=input('>')
while a: while a:
try: read_code(a) try: read_code(a,false)
except: pass except: pass
a=input('>') a=input('>')
save_conf()
def generate(officer=None): def generate(officer=None):
pro=conf[active_profile] pro=conf[active_profile]
@ -126,7 +133,10 @@ def generate(officer=None):
if gun: out.insert(1,lookup_piece(gun,tables.guns,True)) if gun: out.insert(1,lookup_piece(gun,tables.guns,True))
else: out.insert(1,tables.gunmaps_wrapped[out[0]]) else: out.insert(1,tables.gunmaps_wrapped[out[0]])
out[-1]=tables.clas[out[0]].index(out[-1]) out[-1]=tables.clas[out[0]].index(out[-1])
return encode.encode(active_profile,*out,rank,cap) muxed=shared.muxhero(out[0],out[3],out[4])
meds=[]
if muxed in pro['medals']: meds=shared.muxmedals(pro['medals'][muxed])
return encode.encode(active_profile,*out,rank,cap,0,*meds)
def lookup_piece(piece,table,partial=False): def lookup_piece(piece,table,partial=False):
if len(piece)<3: p=piece.upper() if len(piece)<3: p=piece.upper()
@ -145,4 +155,6 @@ def ranks():
print(f'{o[0]}: {o[1][0]}/{o[1][1]}',end=', ') print(f'{o[0]}: {o[1][0]}/{o[1][1]}',end=', ')
print() print()
load_conf() load_conf()
if __name__=="__main__": print("Please open an interpreter and use 'import codegen', this script doesn't serve as an entrypoint on its own yet.")

View File

@ -26,4 +26,11 @@ def combine(code,namehash=''):
def fill0s(num,zeroes=0): def fill0s(num,zeroes=0):
if not zeroes: return str(int(num)) if not zeroes: return str(int(num))
n=str(num) n=str(num)
return '0'*(zeroes-len(n))+n return '0'*(zeroes-len(n))+n
def muxhero(clas,trait,spec):
return clas+trait*12+spec*12*16 # It's actually stored backwards like this, spec is in the most significant bits. Whatever, it doesn't need to be reversable.
def muxmedals(key,moh=-1,pcc=-1,cob=-1,lsa=-1,rem=-1):
if moh!=-1: return key+moh*2+pcc*4+cob*8+lsa*16+rem*32
return bool(key&1),bool(key&2),bool(key&4),bool(key&8),bool(key&16),key//32