76 lines
3.4 KiB
Python
76 lines
3.4 KiB
Python
|
import shared
|
||
|
import random
|
||
|
import tables
|
||
|
|
||
|
def encode(name,clas,gun,armour,trait,spec,talent,rank=-1,cap=-1,xp=0, key=False,moh=False,pcc=False,cob=False,lsa=False,rem=False,seed=-1):
|
||
|
if rank==-1: # actually means gun wasn't given, so shift them
|
||
|
gun,armour,trait,spec,talent,rank=-1,gun,armour,trait,spec,talent
|
||
|
gtalent=tables.clas[clas][talent]
|
||
|
if clas>9: clas+=5 # Shift tech/Alice up to their positions - always
|
||
|
# ... And do it before modifying clas below.
|
||
|
if gun!=-1:
|
||
|
#encode gun into class
|
||
|
if clas==9: clas+=gun+1 # Because 9 outside is Mav, and 9 inside is GLWM
|
||
|
if clas==8: clas+=gun-5
|
||
|
rank-=1 # This actually DOES affect part 2 for some fucking reason
|
||
|
cap=max(cap,(rank)//3+(rank>9)) #Sanity-check
|
||
|
code1=encode_data(clas,armour,trait,spec,talent,rank,cap,xp, key,moh,pcc,cob,lsa,rem,seed)
|
||
|
code2=validate_data(name,clas,armour,trait,spec,gtalent,rank,cap,xp, key,moh,pcc,cob,lsa,rem)
|
||
|
shared.trace(code1,code2)
|
||
|
code=shared.combine(code1,code2)
|
||
|
shared.trace(code)
|
||
|
return shared.delimit(shared.scramble(code),'-')
|
||
|
|
||
|
def encode_data(clas,armour,trait,spec,talent,rank,cap=-1,xp=0, key=False,moh=False,pcc=False,cob=False,lsa=False,rem=False,seed=-1):
|
||
|
if clas==6: armour=2 # Borg is heavy borg
|
||
|
if clas==8: clas=6; armour=0 # LR WM is light borg
|
||
|
if clas==9: clas=6; armour=1 # GL WM is med borg
|
||
|
seed,clas=rand(seed,clas)
|
||
|
rank,cap=adjust_rank(rank,cap,key,moh,pcc)
|
||
|
code1=0
|
||
|
weight=1
|
||
|
for n in list(zip(tables.weights,[xp//10,rank,cap,cob,lsa,rem,clas,armour,trait,spec,talent])):
|
||
|
shared.trace(code1,weight,n[0],n[1])
|
||
|
weight*=n[0]
|
||
|
code1+=n[1]*weight
|
||
|
return str(seed)+shared.fill0s(code1,9)+str(xp%10)
|
||
|
|
||
|
def validate_data(name,clas,armour,trait,spec,talent,rank,cap=0,xp=0, key=False,moh=False,pcc=False,cob=False,lsa=False,rem=False):
|
||
|
# gtalent is now looked up outside, before class modification - because I've adjusted that table to be more useful in general.
|
||
|
if isinstance(name,str): name=hash_name(name)
|
||
|
fac1=[171,142,175,157,167,150,149,151,153,165]
|
||
|
fac2=[169,170,166,173,158,177,161,180,186,159] # I don't understand these, but I hope they work.
|
||
|
code2=name*(spec+1) +(trait+4)*(trait+6) +(rank+1)*(xp+1) +(talent+1)*43*fac1[name%10] -(clas+1)*(241+fac2[name%10]) -(rem+1)*50 +(key+1)*4 +(moh+1)*9 +(pcc+1)*19 +(cob+1)*39 +(lsa+1)*79 +(armour+1)*159
|
||
|
code2+=100*(cap+1)*(code2%1000) # To be honest I don't understand any of this. It's just random nonsense.
|
||
|
while code2>99999:
|
||
|
code2=code2%100000+code2//100000
|
||
|
return shared.fill0s(code2,5)
|
||
|
|
||
|
############################
|
||
|
# SUPPORTING FUNCTIONS BELOW
|
||
|
############################
|
||
|
|
||
|
def getval(char):
|
||
|
vals='_9483726150rstlmeaiuonycdpjkhgxwfvqzb(-[.!' # szszss'
|
||
|
#vals='_5698472031aeioyusptndchbrxvzjmlkwgfq-!.([' # meebs'
|
||
|
if char in vals: return vals.index(char)+1
|
||
|
return 43*len(char.encode('utf-8')) # Apparently multibyte chars do this
|
||
|
|
||
|
def hash_name(name):
|
||
|
parsed=name.lower().replace(')','(').replace(']','[')
|
||
|
checksum=0
|
||
|
for i in range(len(parsed)):
|
||
|
checksum+=getval(parsed[i])*((i+1)%3+1)
|
||
|
return checksum
|
||
|
|
||
|
def adjust_rank(rank,cap=-1, key=False,moh=False,pcc=False):
|
||
|
rank+=key*2+moh # Invalid if rank <11, but whatever
|
||
|
if rank>8: #Can't have PCC below r10, and there are only two possible cap states after that
|
||
|
cap=(cap==4)*2+pcc+1 # I don't know why pcc is encoded like this, I would have thought cap would behave normally if not pcc, but nope.
|
||
|
return rank,cap
|
||
|
|
||
|
def rand(seed,clas):
|
||
|
if seed>-1: n=seed
|
||
|
else: n=int(random.random()*4)*2
|
||
|
if clas>9: return n+1,clas-10
|
||
|
return n,clas
|