123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889890891 |
- import random as r
- import argparse
- import sys
- import adversaries
- import gear
-
- beg = ["a","e","i","o","u","ba","be","bi","bo","bu","by","y","da","de","di","do","du","dy","fa","fi","fo","fe","fu","ga","ge","gi","go","gu","ka","ke","ki","ko","ku","ky","ma","me","mi","mo","mu","na","ne","ni","no","nu","pa","pe","pi","po","pu","ra","re","ri","ro","ru","ry","sa","se","si","so","su","ta","te","ti","to","tu","ty","wa","we","wi","wo","wy","za","ze","zi","zo","zu","zy"]
- mid = beg + ["l","x","n","r", "k"]
-
- def binarize(num, l=None):
- r = bin(num)[2:]
- try:
- l = int(l)
- except:
- l = None
- if l != None:
- while len(r) < l:
- r = "0" + r
- return r
-
- def gen_name(length=None, minimum=3):
- maximum = 8
- if length == None:
- lgt = r.randint(minimum,maximum)
- else:
- if length > maximum:
- length = maximum
- print("Maximum name length is 8.")
- lgt = length
- morae = []
- while len("".join(morae)) < lgt:
- if len(morae) == 0:
- mora = r.choice(beg)
- morae.append(mora[0].upper() + mora[1:])
- else:
- mora = r.choice(mid)
- if morae[-1] == mora:
- mora = r.choice(mid)
- morae.append(mora)
- fname = "".join(morae)[:lgt]
- return fname
-
- class Plot:
- loc1 = ["friendly","hostile","derelict","airless","poison-filled/covered","overgrown","looted","burning","frozen","haunted","infested"]
- loc2 = ["asteroid","moon","space station","spaceship","ringworld","Dyson sphere","planet","Space Whale","pocket of folded space","time vortex","Reroll"]
- miss = ["explore","loot everything not bolted down too securely","find the last group of kobolds who came here","find a rumored secret weapon","find a way to break someone else's secret weapon","claim this place in the name of the Kobold Empire","make friends","rediscover lost technology","find lost magical items","find and defeat a powerful enemy"]
- prob = adversaries.prob
-
- def __init__(self, loc_desc=None, locIndex=None, battlefield=None, location=None, missIndex=None, oops=None, mission=None, probIndex=None, problem=None, probName=None, secProblem=None, thirdProblem=None):
- self.loc_desc = loc_desc if loc_desc != None else Plot.loc1[r.randint(0, len(Plot.loc1)-1)]
- self.locIndex = int(locIndex) if locIndex != None else r.randint(0, len(Plot.loc2)-1)
- self.battlefield = int(battlefield) if battlefield != None else 0
- self.location = location if location != None else Plot.loc2[self.locIndex]
- if locIndex == None and self.locIndex == len(Plot.loc2) - 2:
- if self.battlefield == 0:
- self.battlefield = 1
- self.locIndex = r.randint(0, len(Plot.loc2)-3)
- elif locIndex == None and self.locIndex != len(Plot.loc2) - 1:
- if self.location == "":
- self.location = Plot.loc2[self.locIndex]
- if self.location[0].lower() in ["a","e","i","o","u"]:
- self.locart = 1
- else:
- self.locart = 0
- self.missIndex = missIndex if missIndex != None else r.randint(0, len(Plot.miss)-1)
- self.oops = int(oops) if oops != None else r.randint(1,12)
- if self.oops != 1:
- self.oops = 0
- self.mission = Plot.miss[self.missIndex]
- self.probIndex = probIndex if probIndex != None else r.randint(0, len(Plot.prob)-1)
- self.problem = Plot.prob[self.probIndex]
- if type(self.problem["name"]) != str:
- self.problem["name"] = self.problem["name"]()
- if type(self.problem["note"]) != str:
- self.problem["note"] = self.problem["note"]()
- if self.problem["hasMinion"]:
- if secProblem != None:
- try:
- self.secProblem = Plot.prob[secProblem]
- except:
- self.secProblem = Plot.prob[r.choice(self.problem["potentialMinions"])]
- else:
- self.secProblem = Plot.prob[r.choice(self.problem["potentialMinions"])]
- if type(self.secProblem["name"]) != str:
- self.secProblem["name"] = self.secProblem["name"]()
- if type(self.secProblem["note"]) != str:
- self.secProblem["note"] = self.secProblem["note"]()
- self.fullProblem = ""
- if self.problem["needsName"]:
- self.problem["givenname"] = probName if probName != None else gen_name()
- self.fullProblem += self.problem["givenname"] + ", "
- if not self.problem["isPlural"] and self.problem["name"].split(" ")[0] not in ["Old", "Pev"]:
- if self.problem["name"][0].lower() in ["a","e","i","o","u"]:
- self.fullProblem += "an "
- else:
- self.fullProblem += "a "
- self.fullProblem += self.problem["name"]
- if self.problem["hasMinion"]:
- self.fullProblem += " and their minion, "
- # if self.secProblem["name"][0].lower() in ["a","e","i","o","u"]:
- # self.fullProblem += "an "
- # else:
- # self.fullProblem += "a "
- self.fullProblem += self.secProblem["name"]
-
-
- class Character:
- # Remember to update gen_gadget() when you add gadgets
- GADGETS = gear.gadgets
- # Remember to update gen_career() when you add careers
- CAREERS = [ {"id": 0, "name": "Soldier/Guard"},
- {"id": 1, "name": "Pilot"},
- {"id": 2, "name": "Medic"},
- {"id": 3, "name": "Mechanic"},
- {"id": 4, "name": "Politician"},
- {"id": 5, "name": "Spellcaster"},
- {"id": 6, "name": "Performer"},
- {"id": 7, "name": "Historian"},
- {"id": 8, "name": "Spy"},
- {"id": 9, "name": "Cook"},
- {"id": 10, "name": "Cartographer"},
- {"id": 11, "name": "Inventor"},
- {"id": 12, "name": "Merchant"},
- {"id": 13, "name": "Bard"},
- {"id": 14, "name": "Sorcerer"},
- {"id": 15, "name": "Cleric"},
- {"id": 16, "name": "Rogue"},
- {"id": 17, "name": "Ranger"},
- {"id": 18, "name": "Barbarian"},
- {"id": 19, "name": "Artificer"},
- {"id": 20, "name": "Druid"},
- {"id": 21, "name": "Wizard"},
- {"id": 22, "name": "Fighter"},
- {"id": 23, "name": "Monk"},
- {"id": 24, "name": "Paladin"},
- {"id": 25, "name": "Warlock"},
- {"id": 26, "name": "Blood Hunter"}
- ]
-
- def __init__(self, name=None, career=None, stats=None, gadget=None):
- self.name = name if name != None else ""
- if career == None:
- self.career = ""
- elif isinstance(career, str):
- self.career = career
- elif isinstance(career, int) and career in range(27):
- self.career = [x for x in Character.CAREERS if x["id"] == career][0]
- else:
- self.career = ""
- self.stats = stats if stats != None else []
- if gadget == None:
- self.gadget = ""
- elif isinstance(gadget, str) or isinstance(gadget, dict):
- self.gadget = gadget
- if type(self.gadget["description"]) != str:
- self.gadget["description"] = self.gadget["description"]()
- else:
- self.gadget = next((x for x in Character.GADGETS if x["id"] == gadget), "")
- if type(self.gadget["description"]) != str:
- self.gadget["description"] = self.gadget["description"]()
- self.generate()
-
- def generate(self):
- if self.name == "" or self.name == None:
- self.gen_name()
- if self.stats == [] or self.stats == None:
- self.gen_stats()
- if self.career == "" or self.career == None:
- self.gen_career()
- if self.gadget == "" or self.gadget == None:
- self.gen_gadget()
-
- def gen_name(self):
- self.name = gen_name()
-
- def gen_stats(self, n=12):
- if n < 0:
- print("Too few stat points!")
- return [0,0,0,0]
- stats = [0,0,0,0]
- points = n
- slots = [0,1,2,3]
- for _ in range(points):
- tgl = False
- while tgl == False:
- slt = r.choice(slots)
- if slt <= 1:
- if stats[slt] == 6: continue
- if stats[slt] == 5 and r.randint(0,1) != 1: continue
- else:
- if stats[slt] == 6: continue
- if stats[slt] > 2 and r.randint(0,stats[slt]-2) != 1: continue
- stats[slt] += 1
- tgl = True
- stats[3] = stats[3] + 1
- if stats[3] > 6:
- stats[3] = 6
- stats[2] = stats[2] + 1
- if stats[2] > 6:
- stats[2] = 6
- self.stats = stats
-
- def gen_career(self):
- cid = r.randint(0,26)
- self.career = next((x for x in Character.CAREERS if x["id"] == cid), "")
-
- def gen_gadget(self):
- gid = r.randint(0,36)
- self.gadget = [x for x in Character.GADGETS if x["id"] == gid][0]
- if type(self.gadget["description"]) != str:
- self.gadget["description"] = self.gadget["description"]()
-
- def print_name(self, html=False):
- if isinstance(self.career, str):
- cname = self.career
- cid = next((x for x in Character.CAREERS if x["name"] == cname), "")
- else:
- cname = self.career["name"]
- c = dict(next((x for x in Character.CAREERS if x["name"] == cname), ""))
- cid = c["id"]
-
- if html:
- charText = f"<h4>Name: {self.name} (Kobold {cname})</h4>"
- else:
- charText = f"\nName: {self.name} (Kobold {cname} {cid})"
- print(charText)
-
- def print(self, html=False):
- if html:
- if isinstance(self.career, str):
- cname = self.career
- else:
- cname = self.career["name"]
- if isinstance(self.gadget, str):
- gdg = {"id": 127, "name": self.gadget, "description": "", "reusable": True}
- else:
- gdg = self.gadget
- out = (
- f"<div class='kobold'>\n"
- f" <span class='koboldid'>\n"
- f" <span class='koboldname'>{self.name}</span><br>\n"
- f" <span class='koboldcareer'>Kobold {cname}</span>\n"
- f" </span>\n"
- f" <br>\n"
- f" <span class='koboldstats'>\n"
- f" <ul>\n"
- f" <li>Order: {self.stats[0]}</li>\n"
- f" <li>Chaos: {self.stats[1]}</li>\n"
- f" <li>Brain: {self.stats[2]}</li>\n"
- f" <li>Body: {self.stats[3]}</li>\n"
- f" </ul>\n"
- f" </span>\n"
- f" <br>\n"
- f" <span class='koboldgadget'>\n"
- f" <span class='koboldgadgetname'>{gdg['name']}</span><br>\n"
- f" <span class='koboldgadgetdescription'>{gdg['description']}</span>\n"
- f" <span class='koboldgadgetreuse'>{'<br>Reusable' if gdg['reusable'] else ''}</span>\n"
- f" </span>"
- f"</div>\n"
- )
- print(out)
- else:
- self.print_name()
- print(f"Order: {self.stats[0]}")
- print(f"Chaos: {self.stats[1]}")
- print(f"Brain: {self.stats[2]}")
- print(f"Body: {self.stats[3]}")
- if isinstance(self.gadget, str):
- print(f"Gadget: {self.gadget}")
- else:
- print(f"Gadget: {self.gadget['name']} ({self.gadget['description']}{'- Reusable' if self.gadget['reusable'] else ''})")
-
- class Ship:
- NAME1 = ["Red","Orange","Yellow","Green","Blue","Violet","Dark","Light","Frenzied","Maniacal","Ancient"]
- NAME2 = ["Moon","Comet","Star","Saber","World-Eater","Dancer","Looter","Phlogiston","Fireball","Mecha","Raptor"]
- GQUAL = ["is stealthy & unarmored","is speedy & unarmored","is maneuverable & unarmored","is always repairable","is self-repairing","is flamboyant & speedy","is slow & armored","is flamboyant & armored","is hard to maneuver & armored","has Too Many Weapons!","has a prototype hyperdrive"]
- BQUAL = ["has an annoying AI","has inconveniently crossed circuits","has an unpredictable power source","drifts to the right","is haunted","was recently 'found' so the kobolds are unused to it","is too cold","has a constant odd smell","its interior design... changes","its water pressure shifts between slow drip and power wash","it leaves a visible smoke trail"]
- def __init__(self, name1=None, name2=None, gqual = None, bqual = None):
- self.name1 = name1 if name1 != None else r.choice(Ship.NAME1)
- self.name2 = name2 if name2 != None else r.choice(Ship.NAME2)
- self.gqual = gqual if gqual != None else r.choice(Ship.GQUAL)
- self.bqual = bqual if bqual != None else r.choice(Ship.BQUAL)
- self.fullname = f"{self.name1} {self.name2}"
-
- def print(self, html=False):
- if (html):
- shipText = f"<p>The <strong>{self.fullname}</strong> <span style='color: blue;'>{self.gqual}</span>, but <span style='color: red;'>{self.bqual}</span>.</p>\n"
- else:
- shipText = f"The {self.fullname} {self.gqual}, but {self.bqual}.\n"
- print(shipText)
-
- class Campaign:
- ALPHABET = "0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz?- "
- NAMELETS = ['a', 'e', 'i', 'o', 'u', 'b', 'y', 'd', 'f', 'g', 'k', 'm', 'n', 'p', 'r', 's', 't', 'w', 'z', 'l', 'x']
-
- def __init__(self, n=None, makeChars=True, fromPW=False, pw=None):
- if fromPW == True:
- self.ship = None
- self.params = None
- self.characters = None
- self.art = None
- self.masterpassword = pw
- self.decode_key(pw)
- else:
- self.masterpassword = None
- self.create_campaign(n, makeChars)
-
- def create_campaign(self, n=None, makeChars=True):
- n = 6 if n == None else n
- self.ship = Ship()
- self.params = Plot()
- self.params.problem["fullname"] = ""
- # if self.params.problem["id"] in [1,2]:
- # self.params.problem["fullname"] += " led by " + self.params.problem["name"]
- # if self.params.problem["id"] in [4,7,8,10]:
- # self.params.problem["fullname"] += " named " + self.params.problem["name"]
- if makeChars:
- self.characters = []
- for _ in range(n):
- c = Character()
- c.generate()
- self.characters.append(c)
- self.art = "an" if self.params.loc_desc[0] in ["a","e","i","o","u"] else "a"
-
- def generate_key(self):
- """
- "PACKTA CTICS! ------- ------- ------- ------- ------- ------- ------- ------- ------- ------- ------- -------" should generate the Season 3 Pack Tactics crew.
- "JUSTIN BAILEY" and "NARPAS SWORD" should do something too.
- Key is analphanumeric string generated from a bitfield
- Bitfield is:
- Location 1: 7 bits
- Location 2: 7 bits
- Location Battlefield: 1 bit
- Mission: 7 bits
- Oops: 1 bit
- Problem 1: 7 bits
- Problem 1 name: 40 bits
- Problem 2: 7 bits
- Ship name 1: 7 bits
- Ship name 2: 7 bits
- Ship gqual: 7 bits
- Ship bqual: 7 bits
- Character 1 name: 40 bits
- Character 1 career: 7 bits
- Character 1 order: 3 bits
- Character 1 chaos: 3 bits
- Character 1 body: 3 bits
- Character 1 brain: 3 bits
- Character 1 gadget: 7 bits
- Character 2 name: 40 bits
- Character 2 career: 7 bits
- Character 2 order: 3 bits
- Character 2 chaos: 3 bits
- Character 2 body: 3 bits
- Character 2 brain: 3 bits
- Character 2 gadget: 7 bits
- Character 3 name: 40 bits
- Character 3 career: 7 bits
- Character 3 order: 3 bits
- Character 3 chaos: 3 bits
- Character 3 body: 3 bits
- Character 3 brain: 3 bits
- Character 3 gadget: 7 bits
- Character 4 name: 40 bits
- Character 4 career: 7 bits
- Character 4 order: 3 bits
- Character 4 chaos: 3 bits
- Character 4 body: 3 bits
- Character 4 brain: 3 bits
- Character 4 gadget: 7 bits
- Character 5 name: 40 bits
- Character 5 career: 7 bits
- Character 5 order: 3 bits
- Character 5 chaos: 3 bits
- Character 5 body: 3 bits
- Character 5 brain: 3 bits
- Character 5 gadget: 7 bits
- Character 6 name: 40 bits
- Character 6 career: 7 bits
- Character 6 order: 3 bits
- Character 6 chaos: 3 bits
- Character 6 body: 3 bits
- Character 6 brain: 3 bits
- Character 6 gadget: 7 bits
- 104 for campaign
- 396 for characters
- total 501
- 11 remaining
- """
- self.key = ""
- l1 = bin(Plot.loc1.index(self.params.loc_desc))[2:]
- l2 = bin(Plot.loc2.index(self.params.location))[2:]
- lb = bin(self.params.battlefield)[2:]
- op = bin(self.params.oops)[2:]
- ms = bin(self.params.missIndex)[2:]
- pb1 = bin(self.params.probIndex)[2:]
- if self.params.problem["hasMinion"]:
- pb2 = bin(self.params.secProblem["id"])[2:]
- else:
- pb2 = bin(127)[2:]
- if self.params.problem["needsName"]:
- pbname = self.encode_name(self.params.problem["givenname"])
- else:
- pbname = self.encode_name("yyyyyyyy")
- n1 = bin(Ship.NAME1.index(self.ship.name1))[2:]
- n2 = bin(Ship.NAME2.index(self.ship.name2))[2:]
- gq = bin(Ship.GQUAL.index(self.ship.gqual))[2:]
- bq = bin(Ship.BQUAL.index(self.ship.bqual))[2:]
- chars = {}
- i = 0
- for chct in self.characters:
- chars[i] = {
- "name": self.encode_name(chct.name),
- "career": bin(chct.career["id"])[2:],
- "order": bin(chct.stats[0])[2:],
- "chaos": bin(chct.stats[1])[2:],
- "body": bin(chct.stats[2])[2:],
- "brains": bin(chct.stats[3])[2:],
- "gadget": bin(chct.gadget["id"])[2:]
- }
- i += 1
- l1 = lpad(l1, 7)
- l2 = lpad(l2, 7)
- ms = lpad(ms, 7)
- pb1 = lpad(pb1, 7)
- pb2 = lpad(pb2, 7)
- pbname = lpad(pbname, 40, "1")
- n1 = lpad(n1, 7)
- n2 = lpad(n2, 7)
- gq = lpad(gq, 7)
- bq = lpad(bq, 7)
- self.key += l1 + l2 + lb + ms + op + pb1 + pbname + pb2 + n1 + n2 + gq + bq
- for k,chct in chars.items():
- chct["name"] = lpad(chct["name"], 40, "1")
- chct["career"] = lpad(chct["career"], 7)
- chct["order"] = lpad(chct["order"],3)
- chct["chaos"] = lpad(chct["chaos"], 3)
- chct["body"] = lpad(chct["body"], 3)
- chct["brains"] = lpad(chct["brains"], 3)
- chct["gadget"] = lpad(chct["gadget"], 7)
- self.key += chct["name"] + chct["career"] + chct["order"] + chct["chaos"] + chct["body"] + chct["brains"] + chct["gadget"]
- while len(self.key) < 509:
- self.key = self.key + "0"
- letters = []
- letter = []
- for bit in self.key:
- letter.append(bit)
- if len(letter) == 6:
- letters.append(Campaign.ALPHABET[int("".join(letter),2)])
- letter = []
- words = []
- word = []
- for lt in letters:
- word.append(lt)
- if len(word) == 6:
- words.append("".join(word))
- word = []
- words.append("".join(word))
- self.password = " ".join(words)
- return self.password
-
- def decode_key(self, pw):
- densePwd = pw.replace(" ", "")
- aBuiltin = densePwd[:12].upper()
- builtins = ["PACKTACTICS!", "JUSTINBAILEY", "NARPASSWORD", "PACKTACTICS1", "PACKTACTICS2", "PACKTACTICS3", "OHNOITSPEV!!"]
- if len(densePwd) != 84 and (aBuiltin not in builtins):
- print("This password is not valid. If this is a password that this generator created, please email noelle@noelle.codes and let me know.")
- sys.exit(0)
- if aBuiltin in builtins:
- if aBuiltin == "PACKTACTICS!" or aBuiltin == "PACKTACTICS3":
- # Create a campaign featuring the Season 3 Pack Tactics crew.
- self.ship = Ship("Red", "Star", "is maneuverable & unarmored", "has a politician who thinks they're in charge of it")
- self.params = Plot()
- self.art = "an" if self.params.loc_desc[0] in ["a","e","i","o","u"] else "a"
- self.characters = []
- self.characters.append(Character("Niwri", 17, [3, 4, 4, 3], 123))
- self.characters.append(Character("Zax", 18, [1, 6, 2, 5], 124))
- self.characters.append(Character("Chroma", 19, [4, 2, 5, 3], 125))
- self.characters.append(Character("Zenosha", 20, [3, 4, 5, 2], 126))
- self.characters.append(Character("Snax", 21, [3, 4, 6, 1], 127))
- # self.print_params()
- # self.print_chars()
- return
- elif aBuiltin == "PACKTACTICS1":
- # Create a campaign featuring the Season 1 Pack Tactics crew.
- self.ship = Ship()
- self.params = Plot()
- self.art = "an" if self.params.loc_desc[0] in ["a","e","i","o","u"] else "a"
- self.characters = []
- self.characters.append(Character("Daldain", 13, [3, 4, 5, 2], 114))
- self.characters.append(Character("Gox", 18, [2, 5, 2, 5], 115))
- self.characters.append(Character("Zeeli", 14, [4, 2, 5, 3], 116))
- self.characters.append(Character("Sox", 16, [3, 3, 3, 3], 117))
- # self.print_params()
- # self.print_chars()
- return
- elif aBuiltin == "PACKTACTICS2":
- # Create a campaign featuring the Season 2 Pack Tactics crew.
- self.ship = Ship("Red", "Star", "is maneuverable & unarmored", "has a politician who thinks they're in charge of it")
- self.params = Plot()
- self.art = "an" if self.params.loc_desc[0] in ["a","e","i","o","u"] else "a"
- self.characters = []
- self.characters.append(Character("Daldain", 13, [4, 5, 5, 3], 118))
- self.characters.append(Character("Gox", 18, [2, 6, 4, 5], 119))
- self.characters.append(Character("Zeeli", 14, [3, 4, 6, 5], 120))
- self.characters.append(Character("Marwyse", 15, [4, 4, 6, 3], 121))
- self.characters.append(Character("Sox", 16, [5, 4, 4, 4], 122))
- # self.print_params()
- # self.print_chars()
- return
- elif aBuiltin == "JUSTINBAILEY":
- # Create a random campaign, but everyone's Gadget is a leotard that somehow is also an environment suit
- self.create_campaign(n=6, makeChars=True)
- for c in self.characters:
- c.gadget = {"id":127, "name": "The Bailey", "description": "A form-fitting leotard that somehow protects the wearer from all environmental effects except extreme heat - including vacuum and poison.", "reusable": True}
- # self.print_params()
- # self.print_chars()
- return
- elif aBuiltin == "NARPASSWORD":
- # Create a random campaign, but all the kobolds' stats are set to 6
- self.create_campaign(n=6, makeChars=True)
- for c in self.characters:
- c.stats = [6,6,6,6]
- # self.print_params()
- # self.print_chars()
- return
- elif aBuiltin == "OHNOITSPEV!!":
- # Create a random campaign, but the adversary is Pev
- self.create_campaign(n=6, makeChars=True)
- self.params = Plot(probIndex=121)
- return
- numPwd = []
- for c in densePwd:
- numPwd.append(Campaign.ALPHABET.index(c))
- bitPwd = [lpad(bin(x).replace("0b",""), 6) for x in numPwd]
- longBitPwd = []
- for word in bitPwd:
- longword = lpad(word,6)
- longBitPwd.append(longword)
- self.newBitfield = "".join(longBitPwd)
- while len(self.newBitfield) < 509:
- self.newBitfield += "0"
- outkey = {}
- # Location 1: 7 bits
- i,j = 0,7
- outkey["loc1"] = int(self.newBitfield[i:j], 2)
- # Location 2: 7 bits
- i,j = j,j+7
- outkey["loc2"] = int(self.newBitfield[i:j], 2)
- # Location Battlefield: 1 bit
- i,j = j,j+1
- outkey["battlefield"] = int(self.newBitfield[i:j], 2)
- # Mission: 7 bits
- i,j = j,j+7
- outkey["miss"] = int(self.newBitfield[i:j], 2)
- # Oops: 1 bit
- i,j = j,j+1
- outkey["oops"] = int(self.newBitfield[i:j], 2)
- # Problem 1: 7 bits
- i,j = j,j+7
- outkey["prob1"] = int(self.newBitfield[i:j], 2)
- # Problem 1 name: 40 bits
- i,j = j,j+40
- outkey["prob1name"] = self.newBitfield[i:j]
- # Problem 2: 7 bits
- i,j = j,j+7
- outkey["prob2"] = int(self.newBitfield[i:j], 2)
- # Ship name 1: 7 bits
- i,j = j,j+7
- outkey["sname1"] = int(self.newBitfield[i:j], 2)
- # Ship name 2: 7 bits
- i,j = j,j+7
- outkey["sname2"] = int(self.newBitfield[i:j], 2)
- # Ship gqual: 7 bits
- i,j = j,j+7
- outkey["gqual"] = int(self.newBitfield[i:j], 2)
- # Ship bqual: 7 bits
- i,j = j,j+7
- outkey["bqual"] = int(self.newBitfield[i:j], 2)
- # Character 1 name: 40 bits
- i,j = j,j+40
- outkey["char1name"] = self.newBitfield[i:j]
- # Character 1 career: 7 bits
- i,j = j,j+7
- outkey["char1career"] = int(self.newBitfield[i:j], 2)
- # Character 1 order: 3 bits
- i,j = j,j+3
- outkey["char1ord"] = int(self.newBitfield[i:j], 2)
- # Character 1 chaos: 3 bits
- i,j = j,j+3
- outkey["char1cha"] = int(self.newBitfield[i:j], 2)
- # Character 1 body: 3 bits
- i,j = j,j+3
- outkey["char1bod"] = int(self.newBitfield[i:j], 2)
- # Character 1 brain: 3 bits
- i,j = j,j+3
- outkey["char1bra"] = int(self.newBitfield[i:j], 2)
- # Character 1 gadget: 7 bits
- i,j = j,j+7
- outkey["char1gad"] = int(self.newBitfield[i:j], 2)
- # Character 2 name: 40 bits
- i,j = j,j+40
- outkey["char2name"] = self.newBitfield[i:j]
- # Character 2 career: 7 bits
- i,j = j,j+7
- outkey["char2career"] = int(self.newBitfield[i:j], 2)
- # Character 2 order: 3 bits
- i,j = j,j+3
- outkey["char2ord"] = int(self.newBitfield[i:j], 2)
- # Character 2 chaos: 3 bits
- i,j = j,j+3
- outkey["char2cha"] = int(self.newBitfield[i:j], 2)
- # Character 2 body: 3 bits
- i,j = j,j+3
- outkey["char2bod"] = int(self.newBitfield[i:j], 2)
- # Character 2 brain: 3 bits
- i,j = j,j+3
- outkey["char2bra"] = int(self.newBitfield[i:j], 2)
- # Character 2 gadget: 7 bits
- i,j = j,j+7
- outkey["char2gad"] = int(self.newBitfield[i:j], 2)
- # Character 3 name: 40 bits
- i,j = j,j+40
- outkey["char3name"] = self.newBitfield[i:j]
- # Character 3 career: 7 bits
- i,j = j,j+7
- outkey["char3career"] = int(self.newBitfield[i:j], 2)
- # Character 3 order: 3 bits
- i,j = j,j+3
- outkey["char3ord"] = int(self.newBitfield[i:j], 2)
- # Character 3 chaos: 3 bits
- i,j = j,j+3
- outkey["char3cha"] = int(self.newBitfield[i:j], 2)
- # Character 3 body: 3 bits
- i,j = j,j+3
- outkey["char3bod"] = int(self.newBitfield[i:j], 2)
- # Character 3 brain: 3 bits
- i,j = j,j+3
- outkey["char3bra"] = int(self.newBitfield[i:j], 2)
- # Character 3 gadget: 7 bits
- i,j = j,j+7
- outkey["char3gad"] = int(self.newBitfield[i:j], 2)
- # Character 4 name: 40 bits
- i,j = j,j+40
- outkey["char4name"] = self.newBitfield[i:j]
- # Character 4 career: 7 bits
- i,j = j,j+7
- outkey["char4career"] = int(self.newBitfield[i:j], 2)
- # Character 4 order: 3 bits
- i,j = j,j+3
- outkey["char4ord"] = int(self.newBitfield[i:j], 2)
- # Character 4 chaos: 3 bits
- i,j = j,j+3
- outkey["char4cha"] = int(self.newBitfield[i:j], 2)
- # Character 4 body: 3 bits
- i,j = j,j+3
- outkey["char4bod"] = int(self.newBitfield[i:j], 2)
- # Character 4 brain: 3 bits
- i,j = j,j+3
- outkey["char4bra"] = int(self.newBitfield[i:j], 2)
- # Character 4 gadget: 7 bits
- i,j = j,j+7
- outkey["char4gad"] = int(self.newBitfield[i:j], 2)
- # Character 5 name: 40 bits
- i,j = j,j+40
- outkey["char5name"] = self.newBitfield[i:j]
- # Character 5 career: 7 bits
- i,j = j,j+7
- outkey["char5career"] = int(self.newBitfield[i:j], 2)
- # Character 5 order: 3 bits
- i,j = j,j+3
- outkey["char5ord"] = int(self.newBitfield[i:j], 2)
- # Character 5 chaos: 3 bits
- i,j = j,j+3
- outkey["char5cha"] = int(self.newBitfield[i:j], 2)
- # Character 5 body: 3 bits
- i,j = j,j+3
- outkey["char5bod"] = int(self.newBitfield[i:j], 2)
- # Character 5 brain: 3 bits
- i,j = j,j+3
- outkey["char5bra"] = int(self.newBitfield[i:j], 2)
- # Character 5 gadget: 7 bits
- i,j = j,j+7
- outkey["char5gad"] = int(self.newBitfield[i:j], 2)
- # Character 6 name: 40 bits
- i,j = j,j+40
- outkey["char6name"] = self.newBitfield[i:j]
- # Character 6 career: 7 bits
- i,j = j,j+7
- outkey["char6career"] = int(self.newBitfield[i:j], 2)
- # Character 6 order: 3 bits
- i,j = j,j+3
- outkey["char6ord"] = int(self.newBitfield[i:j], 2)
- # Character 6 chaos: 3 bits
- i,j = j,j+3
- outkey["char6cha"] = int(self.newBitfield[i:j], 2)
- # Character 6 body: 3 bits
- i,j = j,j+3
- outkey["char6bod"] = int(self.newBitfield[i:j], 2)
- # Character 6 brain: 3 bits
- i,j = j,j+3
- outkey["char6bra"] = int(self.newBitfield[i:j], 2)
- # Character 6 gadget: 7 bits
- i,j = j,j+7
- outkey["char6gad"] = int(self.newBitfield[i:j], 2)
- self.ship = Ship(Ship.NAME1[outkey["sname1"]], Ship.NAME2[outkey["sname2"]], Ship.GQUAL[outkey["gqual"]], Ship.BQUAL[outkey["bqual"]])
- self.params = Plot(loc_desc=Plot.loc1[outkey["loc1"]], locIndex=outkey["loc2"], battlefield=outkey["battlefield"], location=None, missIndex=outkey["miss"], oops=outkey["oops"], mission=None, probIndex=outkey["prob1"], problem=None, probName=self.decode_name(outkey["prob1name"]), secProblem=outkey["prob2"], thirdProblem=None)
- self.art = "an" if self.params.loc_desc[0] in ["a","e","i","o","u"] else "a"
- self.characters = []
- for q in range(1,7):
- keys = [f"char{q}name", f"char{q}career", f"char{q}ord", f"char{q}cha", f"char{q}bod", f"char{q}bra", f"char{q}gad"]
- c = Character(name=self.decode_name(outkey[keys[0]]), career=outkey[keys[1]], stats=[outkey[keys[2]], outkey[keys[3]], outkey[keys[4]], outkey[keys[5]]], gadget=outkey[keys[6]])
- self.characters.append(c)
- #return self.newBitfield
-
- def encode_name(self, name):
- field = "".join([lpad(bin(Campaign.NAMELETS.index(c.lower()))[2:], 5) for c in name])
- return field
-
- def decode_name(self, field):
- i,j = 35,40
- name = ""
- for _ in range(8):
- k = int(field[i:j], 2)
- if k != 31:
- name = Campaign.NAMELETS[k] + name
- i,j = i-5, i
- name = name[0].upper() + name[1:]
- return name
-
- def print_params(self, endc=" ", html=False):
- st = ["Order:", "Chaos:", "Brains:", "Body:"]
- cst = ", ".join([" ".join(y) for y in list(zip(st, [str(x) for x in self.params.problem["stats"]]))])
- if self.params.oops == 1:
- oops = "...well, they weren't paying attention, so don't tell them, but they're supposed to "
- else:
- oops = ""
- mission = oops + self.params.mission
- # pl = "s" if self.params.problem["isPlural"] else ""
- note = self.params.problem["note"]
- secnote = ""
- if self.params.problem["hasMinion"]:
- secnote = "Their minion: " + self.params.secProblem["note"]
- lines = [
- f"The Kobolds of the {self.ship.fullname}",
- f"have been sent out to {self.art} {self.params.loc_desc} {self.params.location}!",
- f"in order to {mission}",
- f"but they're challenged by {self.params.fullProblem}!",
- f"{note} {secnote}",
- f"The stats of the {self.params.problem['shortname']}",
- f"{cst}"
- ]
- if self.params.problem["hasMinion"]:
- mst = ", ".join([" ".join(y) for y in list(zip(st, [str(x) for x in self.params.secProblem["stats"]]))])
- # spl = "s" if self.params.secProblem["isPlural"] else ""
- lines.append(f"The stats of the {self.params.secProblem['shortname']}")
- lines.append(f"{mst}")
- if html:
- secnote = ""
- if self.params.problem["hasMinion"]:
- secnote = "Their minion: " + self.params.secProblem["note"] + "<br>\n"
- out = (
- f"<div id='theship' class='firstrow'>\n"
- f" <span class='head'>The Ship</span>\n"
- f" <span id='shipname'>\n"
- f" The {self.ship.fullname}!\n"
- f" </span>\n"
- f" <br>\n"
- f" <span id='shipquality1'>\n"
- f" It {self.ship.gqual}...\n"
- f" </span><br>\n"
- f" <span id='shipquality2'>\n"
- f" But {self.ship.bqual}!\n"
- f" </span>\n"
- f"</div>\n"
- f"<div id='themission' class='firstrow'>\n"
- f" <span class='head'>The Mission</span>\n"
- f" <span id='missionloc'>\n"
- f" The kobolds have been sent to {self.art} {self.params.loc_desc} {self.params.location}\n"
- f" </span><br>\n"
- f" <span id='missiontarget'>\n"
- f" in order to {mission}!\n"
- f" </span>\n"
- f"</div>\n<br clear='all'>\n"
- f"<div id='theadversary' class='firstrow'>\n"
- f" <span class='head'>The Adversary</span>\n"
- f" They're challenged by <span id='advname'>{self.params.fullProblem}</span>!\n"
- f" <br>\n"
- f" <span id='problemnote'>\n"
- f" {self.params.problem['note']}<br>\n"
- f" {secnote}"
- f" </span>\n"
- f" <span id='problemstats'>\n"
- f" The stats of the {self.params.problem['shortname']}:<br>\n"
- f" {cst}\n"
- f" </span>\n"
- )
- if self.params.problem["hasMinion"]:
- out += (
- f" <br><span id='secprobstats'>\n"
- f" The stats of the {self.params.secProblem['shortname']}:<br>\n"
- f" {mst}\n"
- f" </span>\n"
- )
- out += f"</div>\n"
- print(out)
- print(f"<br clear='all'>\n")
- else:
- print(f"{lines[0]} {lines[1]} {lines[2]} -- {lines[3]}")
- print(f"{lines[4]}")
- print(f"{lines[5]}: {lines[6]}")
- if self.params.problem["hasMinion"]:
- print(f"- {lines[7]}: {lines[8]}")
- print()
- self.ship.print(html=html)
-
- def print_chars(self, html=False):
- if html:
- print(f"<div id='thekobolds'>\n")
- print(f"<span class='head'>The Kobolds</span>\n")
- else:
- print("The kobolds:")
- for k in self.characters:
- k.print(html=html)
- if html:
- print(f"</div>\n<br clear='all'>\n")
-
- def print_password(self, html=False):
- if self.masterpassword:
- pw = self.masterpassword
- else:
- pw = self.generate_key()
- if html:
- out = (
- f"<div id='passwordbox'>"
- f"<span class='passwordhead'>Permalink to this campaign:</span><br>"
- f"<span><a href='http://node.noelle.codes/kobold?pw={pw.replace(' ', '')}'>{pw.replace(' ', '')}</a></span><br><br>"
- f"<span class='passwordhead'><a href='http://node.noelle.codes/kobold'>Generate a new random campaign</a></span><br>"
- f"</div>"
- )
- print(out)
- print(f"<br clear='all'>\n")
- else:
- print(f"Password: {pw}")
-
- def decode(self, pwd):
- pass
-
- def lpad(s, n, c="0"):
- while len(s) < n:
- s = c + s
- return s
-
- if __name__ == "__main__":
- parser = argparse.ArgumentParser()
- group = parser.add_mutually_exclusive_group()
- group.add_argument("-c", "--campaign", help="print a full campaign block with N kobolds (default 6)", nargs="?", const=6, type=int, metavar="N")
- group.add_argument("-k", "--kobolds", help="print N kobolds", type=int, nargs="?", const=1, default=1, metavar="N")
- group.add_argument("-n", "--names", help="print N kobolds without stat blocks", nargs="?", const=1, type=int, metavar="N")
- group.add_argument("-p", "--params", help="print only the parameters of a campaign", action="store_true")
- group.add_argument("-s", "--ship", help="print only the ship name and description", action="store_true")
- group.add_argument("-pw", "--password", help="print the campaign defined by the submitted password", type=str, nargs="?", const=1, metavar="PW")
- parser.add_argument("--html", help="print in HTML instead of plain text", action="store_true")
- args = parser.parse_args()
- html = True if args.html else False
- if args.password:
- cmp = Campaign(fromPW = True, pw=args.password)
- cmp.print_params(html=html)
- cmp.print_chars(html=html)
- cmp.print_password(html=html)
- elif args.campaign:
- cmp = Campaign(args.campaign)
- cmp.print_params(html=html)
- cmp.print_chars(html=html)
- cmp.print_password(html=html)
- elif args.params:
- cmp = Campaign(makeChars=False)
- cmp.print_params(html=html)
- elif args.ship:
- ship = Ship()
- ship.print(html=html)
- elif args.names:
- for _ in range(args.names):
- c = Character()
- c.generate()
- c.print_name(html=html)
- else:
- for _ in range(args.kobolds):
- c = Character()
- c.generate()
- c.print(html=html)
|