class Inventor(TarotCard): # Someone who might be able to make an invention. TAGS = (MT_PERSON, ) active = True SOCKETS = ( TarotSocket("MT_SOCKET_Ingredients", TarotSignal(SIG_INGREDIENTS, [ME_PROBLEM]), consequences={ CONSEQUENCE_WIN: TarotTransformer("Invention", (ME_PROBLEM, )) }), TarotSocket("MT_SOCKET_ScienceBoost", TarotSignal(SIG_SCIENCEBOOST, []), consequences={ CONSEQUENCE_WIN: TarotTransformer("Invention", (ME_PROBLEM, )) }), ) AUTO_MEMO = "{ME_PERSON} in {ME_PERSON.scene} may be able to build a {ME_PROBLEM.solution} for {ME_PROBLEM}, given the right supplies." def custom_init(self, nart): if ME_PROBLEM not in self.elements: self.elements[ME_PROBLEM] = TechnoProblem( plotutility.random_disease_name(), plotutility.random_medicine_name()) if not self.elements.get(ME_AUTOREVEAL): sp = self.add_sub_plot(nart, "MT_REVEAL_Inventor", ident="REVEAL") self.elements[ME_PERSON] = sp.elements[ME_PERSON] return True
class SocketTester(TarotCard): LABEL = "TEST_TAROT_SOCKET" active = True def custom_init(self, nart): sp = self.add_sub_plot(nart, "ADD_BORING_NPC", elements={"LOCALE": None}) npc = sp.elements["NPC"] self.elements[ME_PERSON] = npc self.elements[ME_FACTION] = plotutility.RandomBanditCircle(nart.camp) self.elements[ME_CRIME] = CrimeObject("the llama burning", "burned the llama") self.visible = True return True def METROSCENE_ENTER(self, camp): npc = self.elements[ME_PERSON] print("{} is at {}".format(npc, npc.get_scene())) def _test_win(self, camp, alpha, beta=None): print("Win signal received") SOCKETS = (TarotSocket("MT_SOCKET_TEST", TarotSignal("TEST_SIGNAL", []), consequences={CONSEQUENCE_WIN: _test_win}), ) SIGNALS = (TarotSignal("TEST_SIGNAL", []), )
class FactionInvestigator(TarotCard): TAGS = (MT_PERSON, ) active = True ONE_USE = True AUTO_MEMO = "{ME_PERSON} at {MEP_LOC} is investigating {ME_FACTION}." SOCKETS = (TarotSocket("MT_SOCKET_Investigate", TarotSignal(SIG_INCRIMINATE, [ME_FACTION]), consequences={ CONSEQUENCE_WIN: TarotTransformer("FactionCrimesProof", [ME_FACTION], [ME_CRIME]) }), ) def custom_init(self, nart): if ME_FACTION not in self.elements: self.elements[ME_FACTION] = plotutility.RandomBanditCircle( nart.camp) if not self.elements.get(ME_AUTOREVEAL): sp = self.add_sub_plot(nart, "MT_REVEAL_Investigator", ident="REVEAL", elements={ "INVESTIGATION_SUBJECT": str(self.elements[ME_FACTION]) }) self.elements[ME_PERSON] = sp.elements[ME_PERSON] self.elements["MEP_LOC"] = self.elements[ME_PERSON].get_scene() return True
class Epidemic(TarotCard): # An illness strikes the area. TAGS = (MT_THREAT, ) QOL = gears.QualityOfLife(health=-4, prosperity=-1) active = True NEGATIONS = ("Recovery", ) UNIQUE = True SOCKETS = (TarotSocket("MT_SOCKET_Cure", TarotSignal(SIG_CURE, [ME_PROBLEM]), consequences={ CONSEQUENCE_WIN: TarotTransformer("Recovery", (ME_PROBLEM, )) }), ) AUTO_MEMO = "{METROSCENE} has been afflicted with {ME_PROBLEM}." def custom_init(self, nart): if ME_PROBLEM not in self.elements: self.elements[ME_PROBLEM] = TechnoProblem( plotutility.random_disease_name(), plotutility.random_medicine_name(), ("DISEASE", )) if not self.elements.get(ME_AUTOREVEAL): sp = self.add_sub_plot(nart, "MT_REVEAL_Epidemic", ident="REVEAL") return True
class WannabeChemist(TarotCard): # An aspiring techno-alchemist TAGS = (MT_PERSON, ) active = True SOCKETS = (TarotSocket("MT_SOCKET_HireMe", TarotSignal(SIG_HIRE, (ME_POSITION, )), consequences={ CONSEQUENCE_WIN: TarotTransformer("Chemist", (ME_PERSON, ME_PROBLEM), ()) }), ) AUTO_MEMO = "{ME_PERSON} at {ME_PERSON.scene} wants to set up a chemistry lab in order to combat {ME_PROBLEM}." def custom_init(self, nart): if ME_POSITION not in self.elements: self.elements[ME_POSITION] = PositionObject("Chemist") else: self.elements[ME_POSITION].job_title = "Chemist" if not self.elements.get(ME_AUTOREVEAL): sp = self.add_sub_plot(nart, "MT_REVEAL_WannabeChemist", ident="REVEAL") if ME_PERSON not in self.elements: self.elements[ME_PERSON] = sp.elements[ME_PERSON] return True
class HateClub(TarotCard): # A group of people who love to hate. TAGS = (MT_THREAT, ME_FACTION) QOL = gears.QualityOfLife(stability=-2, community=-2) active = True NEGATIONS = ("TheDisbanded", ) UNIQUE = True SOCKETS = (TarotSocket("MT_SOCKET_Accuse", TarotSignal(SIG_ACCUSE, [ME_FACTION]), consequences={ CONSEQUENCE_WIN: TarotTransformer("TheDisbanded", (ME_FACTION, ), (ME_CRIME, )) }), ) def custom_init(self, nart): # Add the subplot which will decide the splinter faction and provide a discovery route. if not self.elements.get(ME_AUTOREVEAL): sp = self.add_sub_plot(nart, "MT_REVEAL_HateClub", ident="REVEAL") if ME_FACTION not in self.elements: self.elements[ME_FACTION] = sp.elements[ME_FACTION] else: if "METROSCENE" in self.elements: location = self.elements["METROSCENE"] else: location = None self.memo = Memo( "You learned that {} has been taken over by extremists.". format(self.elements[ME_FACTION]), location) return True
class DinosaurAttack(TarotCard): # Genetically engineered dinosaurs causing problems. TAGS = (MT_THREAT, ) QOL = gears.QualityOfLife(defense=-4, health=-1) active = True NEGATIONS = ("EcologicalBalance", ) UNIQUE = True SOCKETS = (TarotSocket("MT_SOCKET_DinosaurSolution", TarotSignal(SIG_APPLY, [ME_PROBLEM]), consequences={ CONSEQUENCE_WIN: TarotTransformer("EcologicalBalance", (ME_PROBLEM, )) }), ) AUTO_MEMO = "{METROSCENE} is under constant threat from mutant dinosaurs." def custom_init(self, nart): if ME_PROBLEM not in self.elements: self.elements[ME_PROBLEM] = TechnoProblem('mutant dinosaurs', "sonic fence", ("MONSTERS", )) if not self.elements.get(ME_AUTOREVEAL): sp = self.add_sub_plot(nart, "MT_REVEAL_Dinosaurs", ident="REVEAL") return True
class WannabeReporter(TarotCard): # A journalist seeking a platform TAGS = (MT_PERSON, ) active = True SOCKETS = (TarotSocket("MT_SOCKET_HireMe", TarotSignal(SIG_HIRE, (ME_POSITION, )), consequences={ CONSEQUENCE_WIN: TarotTransformer("TheMedia", (ME_PERSON, ), ()) }), ) AUTO_MEMO = "{ME_PERSON} at {ME_PERSON.scene} is a reporter looking for a job." def custom_init(self, nart): if ME_POSITION not in self.elements: self.elements[ME_POSITION] = PositionObject("Reporter") else: self.elements[ME_POSITION].job_title = "Reporter" if not self.elements.get(ME_AUTOREVEAL): sp = self.add_sub_plot(nart, "MT_REVEAL_WannabeReporter", ident="REVEAL") if ME_PERSON not in self.elements: self.elements[ME_PERSON] = sp.elements[ME_PERSON] return True
class TheQuitter(TarotCard): TAGS = ( MT_PERSON, MT_FACTION, ) active = True ONE_USE = True AUTO_MEMO = "{ME_PERSON} used to work for {ME_FACTION}." SOCKETS = (TarotSocket("MT_SOCKET_InformantF", TarotSignal(SIG_CRIME, [ME_CRIME]), consequences={ CONSEQUENCE_WIN: TarotTransformer("Atrocity", [ME_FACTION, ME_CRIME], []) }), ) def custom_init(self, nart): if ME_FACTION not in self.elements: self.elements[ME_FACTION] = plotutility.RandomBanditCircle( nart.camp) if ME_CRIME not in self.elements: self.elements[ME_CRIME] = CrimeObject("the atrocity", "committed an atrocity") if not self.elements.get(ME_AUTOREVEAL): sp = self.add_sub_plot(nart, "MT_REVEAL_Quitter", ident="REVEAL") if ME_PERSON not in self.elements: self.elements[ME_PERSON] = sp.elements[ME_PERSON] return True
class Henchman(TarotCard): TAGS = (MT_PERSON, ) active = True ONE_USE = True AUTO_MEMO = "{ME_PERSON} has been doing dirty work for {ME_ACTOR}." SOCKETS = (TarotSocket( "MT_SOCKET_HenchmanLiability", TarotSignal(SIG_CRIME, [ME_CRIME]), consequences={ CONSEQUENCE_WIN: TarotTransformer("FeetOfClay", [(ME_PERSON, ME_ACTOR), ME_LIABILITY], [ ME_CRIME, ]) }), ) def custom_init(self, nart): if ME_CRIME not in self.elements: self.elements[ME_CRIME] = CrimeObject("the atrocity", "committed an atrocity") if not self.elements.get(ME_AUTOREVEAL): sp = self.add_sub_plot(nart, "MT_REVEAL_Henchman", ident="REVEAL") self.elements[ME_PERSON] = sp.elements[ME_PERSON] return True
class Kleptocrat(TarotCard): # A politician with their hand in the treasury TAGS = (MT_THREAT, ME_PERSON) UNIQUE = True QOL = gears.QualityOfLife(prosperity=-2, stability=-2) active = True NEGATIONS = ("HasBeen", "TheExiled") SOCKETS = ( TarotSocket("MT_SOCKET_Accuse", TarotSignal(SIG_ACCUSE, [ ME_PERSON, ]), consequences={ CONSEQUENCE_WIN: TarotTransformer("TheExiled", (ME_PERSON, )) }), TarotSocket("MT_SOCKET_Cancel", TarotSignal(SIG_CANCEL, [ME_PERSON]), consequences={ CONSEQUENCE_WIN: TarotTransformer("HasBeen", (ME_PERSON, )) }), TarotSocket("MT_SOCKET_Extort", TarotSignal(SIG_EXTORT, [ME_PERSON]), consequences={ CONSEQUENCE_WIN: TarotTransformer("CultHierophant", (ME_PERSON, )), "CONSEQUENCE_GOAWAY": TarotTransformer("TheExiled", (ME_PERSON, )), }), ) AUTO_MEMO = "{ME_PERSON} at {ME_PERSON.scene} is a corrupt {ME_PERSON.job}." def custom_init(self, nart): if not self.elements.get(ME_AUTOREVEAL): sp = self.add_sub_plot(nart, "MT_REVEAL_Kleptocrat", ident="REVEAL") if ME_PERSON not in self.elements: self.elements[ME_PERSON] = sp.elements[ME_PERSON] return True
class RobberBaron(TarotCard): # Exploitation leading to widespread poverty. TAGS = (MT_THREAT, MT_PERSON, MT_FACTION) QOL = gears.QualityOfLife(prosperity=-4, community=-1) active = True NEGATIONS = ("TheExiled", ) UNIQUE = True SOCKETS = ( TarotSocket("MT_SOCKET_Accuse", TarotSignal(SIG_ACCUSE, [ ME_PERSON, ]), consequences={ CONSEQUENCE_WIN: TarotTransformer("TheExiled", (ME_PERSON, )) }), TarotSocket("MT_SOCKET_Accuse", TarotSignal(SIG_ACCUSE, [ ME_FACTION, ]), consequences={ CONSEQUENCE_WIN: TarotTransformer("TheExiled", (ME_PERSON, )) }), ) AUTO_MEMO = "{ME_PERSON} practically owns {METROSCENE}." def custom_init(self, nart): if not self.elements.get(ME_AUTOREVEAL): sp = self.add_sub_plot(nart, "MT_REVEAL_RobberBaron", ident="REVEAL") if ME_PERSON not in self.elements: self.elements[ME_PERSON] = sp.elements[ME_PERSON] if ME_FACTION in sp.elements: self.elements[ME_FACTION] = sp.elements[ME_FACTION] if ME_FACTION not in self.elements: mynpc = self.elements[ME_PERSON] self.elements[ME_FACTION] = gears.factions.Circle( nart.camp, name="{} Industries".format(mynpc)) mynpc.faction = self.elements[ME_FACTION] return True
class Demagogue(TarotCard): # A character exploiting local divisions for personal gain TAGS = (MT_THREAT, ME_PERSON) UNIQUE = True QOL = gears.QualityOfLife(community=-3) active = True NEGATIONS = ("HasBeen", ) SOCKETS = ( TarotSocket("MT_SOCKET_Cancel", TarotSignal(SIG_CANCEL, [ME_PERSON]), consequences={ CONSEQUENCE_WIN: TarotTransformer("HasBeen", (ME_PERSON, )) }), TarotSocket("MT_SOCKET_Extort", TarotSignal(SIG_EXTORT, [ME_PERSON]), consequences={ CONSEQUENCE_WIN: TarotTransformer("CultHierophant", (ME_PERSON, )), "CONSEQUENCE_GOAWAY": TarotTransformer("TheExiled", (ME_PERSON, )), }), ) def custom_init(self, nart): if not self.elements.get(ME_AUTOREVEAL): sp = self.add_sub_plot(nart, "MT_REVEAL_Demagogue", ident="REVEAL") if ME_PERSON not in self.elements: self.elements[ME_PERSON] = sp.elements[ME_PERSON] else: self.memo = Memo( "You learned that {} is a demagogue.".format( self.elements[ME_PERSON]), self.elements[ME_PERSON].get_scene()) return True
class Shortages(TarotCard): TAGS = (MT_THREAT, ) QOL = gears.QualityOfLife(prosperity=-3, health=-2) active = True NEGATIONS = ("Recovery", ) UNIQUE = True SOCKETS = (TarotSocket( "MT_SOCKET_FamineRelief", TarotSignal(SIG_FOODBOOST, []), consequences={CONSEQUENCE_WIN: TarotTransformer("Recovery", [])}), ) AUTO_MEMO = "{METROSCENE} is suffering from a shortage of basic necessities." def custom_init(self, nart): if not self.elements.get(ME_AUTOREVEAL): sp = self.add_sub_plot(nart, "MT_REVEAL_Shortages", ident="REVEAL") return True
class FactionClue(TarotCard): # A clue linking a faction to a crime. TAGS = () active = True ONE_USE = True SOCKETS = (TarotSocket("MT_SOCKET_SearchClue", TarotSignal(SIG_INCRIMINATE, [ME_FACTION]), consequences={ CONSEQUENCE_WIN: TarotTransformer("FactionCrimesProof", (ME_FACTION, ), (ME_CRIME, )) }), ) def custom_init(self, nart): if not self.elements.get(ME_AUTOREVEAL): sp = self.add_sub_plot(nart, "MT_REVEAL_ClueItem", ident="REVEAL") self.elements[ME_PUZZLEITEM] = sp.elements[ME_PUZZLEITEM] return True
class FactionComputer(TarotCard): TAGS = () active = True ONE_USE = True SOCKETS = (TarotSocket("MT_SOCKET_Decrypt", TarotSignal(SIG_DECRYPT, [ ME_FACTION, ]), consequences={ CONSEQUENCE_WIN: TarotTransformer("FactionClue", (ME_FACTION, ME_PUZZLEITEM), []) }), ) def custom_init(self, nart): if not self.elements.get(ME_AUTOREVEAL): sp = self.add_sub_plot(nart, "MT_REVEAL_FactionComputer", ident="REVEAL") self.elements[ME_PUZZLEITEM] = sp.elements[ME_PUZZLEITEM] return True
class CursedEarth(TarotCard): active = True SOCKETS = (TarotSocket("MT_SOCKET_CursedEarthSolution", TarotSignal(SIG_APPLY, [ME_PROBLEM]), consequences={ CONSEQUENCE_WIN: TarotTransformer("TheFarm", (ME_PROBLEM, ME_BOOSTSOURCE)) }), ) AUTO_MEMO = "The land around {METROSCENE} is too damaged to grow anything." SOLUTIONS = ("terraforming kit", "soil purifier", "isotope filter") def custom_init(self, nart): if ME_PROBLEM not in self.elements: self.elements[ME_PROBLEM] = TechnoProblem( 'polluted land', random.choice(self.SOLUTIONS)) if not self.elements.get(ME_AUTOREVEAL): sp = self.add_sub_plot(nart, "MT_REVEAL_CursedEarth", ident="REVEAL") return True
class TheMedia(TarotCard): # A person that has the power to amplify a message TAGS = (MT_PERSON, ) active = True SOCKETS = (TarotSocket("MT_SOCKET_Amplify", TarotSignal(SIG_AMPLIFY, ), consequences={ CONSEQUENCE_WIN: TarotTransformer("BadPress", ((ME_ACTOR, ME_PERSON), ), (ME_PERSON, ME_LIABILITY)) }), ) AUTO_MEMO = "{ME_PERSON} is a {ME_PERSON.job} with a large audience in {METROSCENE}." def custom_init(self, nart): # Add the subplot which will decide the splinter faction and provide a discovery route. if not self.elements.get(ME_AUTOREVEAL): sp = self.add_sub_plot(nart, "MT_REVEAL_TheMedia", ident="REVEAL") if ME_PERSON not in self.elements: self.elements[ME_PERSON] = sp.elements[ME_PERSON] return True