148 lines
4.8 KiB
Python
148 lines
4.8 KiB
Python
import encode, decode
|
|
import tables
|
|
import os
|
|
|
|
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.
|
|
|
|
|
|
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)]}
|
|
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.
|
|
if namehash in conf : conf[namehash]['names'].add(name)
|
|
else: conf[namehash]=defaults.copy()|{'names':{name}}
|
|
save_conf()
|
|
global active_profile
|
|
active_profile=namehash
|
|
|
|
def parse_conf_line(line):
|
|
a=line.split(' ')
|
|
out=[]
|
|
for n in a:
|
|
b=n.split('/')
|
|
out.append((int(b[0]),int(b[1])))
|
|
return out
|
|
|
|
def load_conf():
|
|
if not os.path.exists(confp): return
|
|
a=open(confp).read()
|
|
for n in a.split('\n\n'):
|
|
lines=n.split('\n')
|
|
header=lines[0].split(' ')
|
|
nhash=int(header[0]); names=set(header[1:]) # Makes deduping way easier
|
|
stuff={k:parse_conf_line(v) for k,v in zip(tables.displays_str[:-1],lines[1:])}
|
|
conf[nhash]={'names':names}|stuff
|
|
update_all_talents()
|
|
global active_profile
|
|
active_profile=nhash
|
|
|
|
def unparse_conf_line(line):
|
|
return ' '.join([str(n[0])+'/'+str(n[1]) for n in line])
|
|
|
|
def save_conf():
|
|
write=''
|
|
for k,v in conf.items():
|
|
write+=' '.join([str(k)]+list(v['names']))+'\n'
|
|
for n in map(lambda x:unparse_conf_line(v[x]),tables.displays_str[:-1]):
|
|
write+=n+'\n'
|
|
write+='\n'
|
|
write=write[:-2]
|
|
open(confp,'w').write(write)
|
|
|
|
def update_all_talents():
|
|
for profile in conf:
|
|
cl=dict(enumerate(conf[profile]['classes']))
|
|
t=defaults['talents'].copy()
|
|
conf[profile]['talents']=t
|
|
for n in range(1,7):
|
|
t[n]=update_talent(n,cl)
|
|
|
|
def update_talents(clas,profile=None):
|
|
if profile is None: profile=active_profile
|
|
cl=dict(enumerate(conf[profile]['classes']))
|
|
for talent in tables.clas[clas][1:]: # Don't care about courage
|
|
conf[profile]['talents'][talent]=update_talent(talent,cl)
|
|
|
|
def update_talent(talent,classes):
|
|
a=enumerate(tables.clas); b=filter(lambda x:talent in x[1],a); c=list(map(lambda x:x[0],b)); d=filter(lambda x:x[0] in c,classes.items()); rel_classes=list(map(lambda x:x[1],d))
|
|
ranks,caps=[],[]
|
|
for n in rel_classes: ranks.append(n[0]); caps.append(n[1])
|
|
ranks,caps=sorted(ranks),sorted(caps)
|
|
lon=len(ranks)//2+len(ranks)%2
|
|
return (ranks[-lon],caps[-lon])
|
|
|
|
def read_code(code,save=True):
|
|
data=list(decode.decode(code,active_profile))
|
|
check,validator=data.pop(-1),data.pop(-1)
|
|
talent=data.pop(5)
|
|
hero=data[0:6]
|
|
show=list(map(lambda x:x[0][x[1]],zip(tables.displays,hero)))
|
|
rank,cap=data[6:8]
|
|
cap=tables.cap[cap]
|
|
if rank==12: cap=12
|
|
data=data[8:]
|
|
if rank<9: show[-1]='Hidden' # Don't spoil the talent
|
|
print(show)
|
|
print(str(rank)+'/'+str(cap))
|
|
print(data)
|
|
if not check: print('No name given, code validation not performed')
|
|
else:
|
|
if check!=validator: print('code did not validate:',validator,check); return
|
|
else: print('code validated')
|
|
if not save: return
|
|
for thing in zip(tables.displays_str[:-1],hero):
|
|
saved=conf[active_profile][thing[0]][thing[1]]
|
|
saved=(max(saved[0],rank),max(saved[1],cap))
|
|
conf[active_profile][thing[0]][thing[1]]=saved
|
|
update_talents(hero[0])
|
|
save_conf()
|
|
|
|
def mass_add():
|
|
a=input('>')
|
|
while a:
|
|
try: read_code(a)
|
|
except: pass
|
|
a=input('>')
|
|
|
|
def generate(officer=None):
|
|
pro=conf[active_profile]
|
|
if officer is None: officer=input('> ')
|
|
pieces=officer.split('/')
|
|
c=pieces[0].lower()
|
|
if 'mav' in c:
|
|
gun=c[0]
|
|
pieces[0]='mav'
|
|
elif 'wm' in c:
|
|
gun=c[0:2]
|
|
pieces[0]='wm'
|
|
else: gun=''
|
|
out=[]
|
|
rank,cap=12,12
|
|
for n in zip(pieces,tables.displays_nogun,tables.displays_nogun_str):
|
|
ind=lookup_piece(n[0],n[1])
|
|
rank,cap=min(rank,pro[n[2]][ind][0]),min(cap,pro[n[2]][ind][1])
|
|
out.append(ind)
|
|
cap=(cap-(cap<10)+(cap>10))//3 # Derp
|
|
if gun: out.insert(1,lookup_piece(gun,tables.guns,True))
|
|
else: out.insert(1,tables.gunmaps_wrapped[out[0]])
|
|
out[-1]=tables.clas[out[0]].index(out[-1])
|
|
return encode.encode(active_profile,*out,rank,cap)
|
|
|
|
def lookup_piece(piece,table,partial=False):
|
|
if len(piece)<3: p=piece.upper()
|
|
else: p=piece.capitalize() # Bloody Americans
|
|
if not partial:
|
|
try: return table.index(p)
|
|
except ValueError: return None
|
|
res=list(filter(lambda x:x.startswith(p),table))
|
|
if len(res)!=1: return None # Ambiguous lookups not allowed
|
|
return table.index(res[0])
|
|
|
|
def ranks():
|
|
for n,m in zip(tables.displays_str,tables.displays):
|
|
a=zip(m,conf[active_profile][n])
|
|
for o in a:
|
|
print(f'{o[0]}: {o[1][0]}/{o[1][1]}',end=', ')
|
|
print()
|
|
|
|
load_conf() |