init 1 python: class RiamMar: colors = { # define some colors for used in formatting the additional info "negative" : "fc0", "neutral" : "aaa", "positive" : "0fc" } debug = False fontSize = int (0.5 * gui.label_text_size) # use x% (0.5 == 50%) of globally defined font size for additional info gameVersion = [ "Bad Hero", "Episode 2 - v2.8.1p (updated by CharonĂ¡)"] modCore = "3.1.3" guide = {} settings = {} imageLocation = "" lastLabel = "" loveInterests = ["angel", "bianca", "chelsey", "erin", "eva", "kate", "may"] modInfoTitle = "Riam's Mod" modMenuActiveTab = "UI" modMenuTabs = [ "UI", "Characters", "Walkthrough", "About" ] oldMCName = "" overlayBackground = Solid ("#0009") relationshipFiles = ["patch.renpy"] textSize = str (fontSize) def __init__ (self): self.collectibles = {} self.config = {} self.dialogChanges = {} # used for stuff in dialog_changes.rpy self.gameVersion = "\n".join (self.gameVersion) self.hardcodedItemsToRemove = [] # used for stuff in dialog_changes.rpy self.hardcodedItemsToRemoveIgnored = [] # used for stuff in dialog_changes.rpy self.hardcodedItemsToReplace = {} # used for stuff in dialog_changes.rpy self.replacements = {} # used for stuff in label overrides => labels/example.rpy self.preparePersistentData () self.imageLocation = self.getImageDirectory () def addGeneralInfo (self, files): for filename, menus in files.items (): for menuLineNumber, textsToFormat in menus.items (): for textKey, texts in textsToFormat.items (): newTextItem = "{size=" + self.textSize + "}{i}" for key, text in texts.items (): newTextItem += "\n{color=" + self.getColor (text ["color"]) + "}" + text ["value"] +"{/color}" newTextItem += "{/i}{/size}" self.updateReplacements (filename, menuLineNumber, textKey, self.getReplacementItem (filename, menuLineNumber, textKey) + newTextItem) return def debugInfo (self): return ("Current label: " + current_label + "\n\n") if self.debug else "" def activeModMenuTab (self): return "RiamMar_ModMenu_Tab_" + self.toScreenTitle (self.modMenuActiveTab) def addInfoAboutVariables (self, files): for filename, menus in files.items (): for menuLineNumber, choiceItems in menus.items (): for textKey, characterItems in choiceItems.items (): newTextItem = "{size=" + self.textSize + "}{i}" for characterName, infoItems in characterItems.items (): newTextItem += "\n" + characterName + ":" for infoVariable, infoValue in infoItems.items (): newTextItem += " {color=" + self.getColor (infoValue) + "}" + infoVariable + " " + ("+" if infoValue > 0 else "") + str (infoValue) + "{/color}," newTextItem = newTextItem[:-1] newTextItem = newTextItem + "{/i}{/size}" self.updateReplacements (filename, menuLineNumber, textKey, newTextItem + self.getReplacementItem (filename, menuLineNumber, textKey)) return def addStyles (self, styles): for styleType, styleItem in styles.items (): for styleName, itemStyles in styleItem.items (): styleName = self.getStyleName (styleType, styleName) setattr (style, styleName, Style (style.default)) for styleKey, styleValue in itemStyles.items (): setattr (getattr (style, styleName), styleKey, styleValue) def addToDialogChanges (self, dialogFrom, dialogTo): self.dialogChanges.update ({ dialogFrom : dialogTo }); return def addToIcons (self, freeroamChapter, labelName, itemName, iconType, itemPosition, tooltip, action = Null): if not freeroamChapter in self.collectibles: self.collectibles.update ({ freeroamChapter : {} }) if not labelName in self.collectibles [freeroamChapter]: self.collectibles [freeroamChapter].update ({ labelName : {} }) self.collectibles [freeroamChapter][labelName].update ( { itemName : (iconType, itemPosition, tooltip, action) }) def addToLabels (self, freeroamName, freeroamSection, labelName, labelPosition, labelBackground = True): if not freeroamName in self.labels: self.labels.update ({ freeroamName : {} }) if not freeroamSection in self.labels [freeroamName]: self.labels [freeroamName].update ({ freeroamSection : {} }) self.labels [freeroamName][freeroamSection].update ({ labelName : (labelPosition, labelBackground) }) def addToGuide (self, freeroamName, freeroamScreen, freeroamGuide): if isinstance (freeroamName, str) and isinstance (freeroamScreen, str) and isinstance (freeroamGuide, str): if freeroamName not in self.guide.keys (): self.guide [freeroamName] = {} if freeroamScreen not in self.guide [freeroamName].keys (): self.guide [freeroamName][freeroamScreen] = "" self.guide [freeroamName].update ({ freeroamScreen : freeroamGuide }) return True return False def addToHardcodedRemoveIgnoreList (self, itemsOrItem): if isinstance (itemsOrItem, list): for item in itemsOrItem: if item not in self.hardcodedItemsToRemoveIgnored: self.hardcodedItemsToRemoveIgnored.append (item) else: if itemsOrItem not in self.hardcodedItemsToRemoveIgnored: self.hardcodedItemsToRemoveIgnored.append (itemsOrItem) return def addToHardcodedRemoveList (self, itemsOrItem): if isinstance (itemsOrItem, list): for item in itemsOrItem: if item not in self.hardcodedItemsToRemove: self.hardcodedItemsToRemove.append (item) else: if itemsOrItem not in self.hardcodedItemsToRemove: self.hardcodedItemsToRemove.append (itemsOrItem) return def addToHardcodedReplaceDict (self, items): for key, item in items.items (): self.hardcodedItemsToReplace.update ({ key : item }) return def clearLines (self): self.replacements.clear () return def configure (self, values): for key, value in values.items (): self.config.update ({ key : value }) def getColor (self, value): if isinstance (value, int): return self.colors ["positive"] if value > 0 else self.colors ["negative"] if value < 0 else self.colors ["neutral"] elif value in self.colors.keys (): return self.colors [value] else: return self.colors ["neutral"] def getCompletion (self, frName): checklist = "{color=#fff}" checklist += "{b}Checklist:{/b}\n" checklist += "{/color}" return checklist def getIcons (self, freeroamName, freeroamSection): if freeroamName in self.collectibles: if freeroamSection in self.collectibles [freeroamName]: return self.collectibles [freeroamName][freeroamSection] def getLabels (self, freeroamName, freeroamSection): if freeroamName in self.labels: if freeroamSection in self.labels [freeroamName]: return self.labels [freeroamName][freeroamSection] def getImageDirectory (self): file_list = renpy.list_files () for file_name in file_list: if file_name.find ("RiamMar") >= 0 and file_name.find ("images") >= 0: self.imageLocation = (file_name[0:file_name.index ("images")]) + "images/" return self.imageLocation return "Couldn't fetch mod directory." def getGuide (self, freeroamName, freeroamSection): if freeroamName in self.guide: if freeroamSection in self.guide [freeroamName]: return "{color=#fff}{b}Location guide:{/b}\n" + self.guide [freeroamName][freeroamSection] + "{/color}" return "No guide for " + freeroamName + " - " + freeroamSection def getLocationGuideItems (self, guideType, freeroamName, freeroamSection): guide = getattr (self, guideType) if freeroamName in guide.keys (): if RiamMar_current_label in [ "after_load", "_return" ] and self.lastLabel != "": current_label = self.lastLabel else: current_label = RiamMar_current_label current_label = current_label.replace ("RiamMar_", "") if current_label in guide [freeroamName].keys (): return guide [freeroamName][current_label] return False def getMCName (self): return persistent.riamMar ["mcName"] def getModInfo (self): modInfo = "{size=" + self.textSize + "}" modInfo += "{color=#bfcab4}Riam's Mod for{/color}\n" ##### Game Info modInfo += "{i}" + self.gameVersion + "{/i}\n\n" ##### Walkthrough modInfo += "{color=#75ce6f}" if self.isActivated ("walkthrough") else "{color=#d1aca5}" modInfo += "Walkthrough mod is " modInfo += "activated" if self.isActivated ("walkthrough") else "deactivated" modInfo += "{/color}\n" #### Happy Family Mode modInfo += "{color=#75ce6f}" if self.isActivated ("family") else "{color=#d1aca5}" modInfo += "Special relationship is" modInfo += " not" if not self.isActivated ("family") else "" modInfo += " set" modInfo += "{/color}\n" #### Kinetic Novel mode modInfo += "{color=#75ce6f}" if self.isActivated ("kinetic") else "{color=#d1aca5}" modInfo += "Kinetic mode is " modInfo += "de" if not self.isActivated ("kinetic") else "" modInfo += "activated" modInfo += "{/color}" return modInfo def getModMenuTabs (self): return self.modMenuTabs def getRandomHookerName (self): return random.choice ([ "bitch", "hooker", "hussy", "slut", "wench", "whore" ]) def getReplacementItem (self, filename, menuLineNumber, key): if filename in self.replacements.keys (): if menuLineNumber in self.replacements [filename].keys (): if key in self.replacements [filename][menuLineNumber].keys (): return self.replacements [filename][menuLineNumber][key] return "" def getStyle (self, styleType, styleName): return getattr (style, self.getStyleName (styleType, styleName)) def getStyleName (self, type, name): styleName = "RiamMar_" + "Frame" if type == "frames" else "Button" return styleName + name def happyFamilyIsActivated (self): return persistent.RiamMar_happyFamily def hideModMenuTabs (self): for tabName in self.modMenuTabs: renpy.hide_screen ("RiamMar_ModMenu_Tab_" + self.toScreenTitle (tabName)) def isActive (self, modPart): return self.isActivated (modPart) def isActivated (self, modPart): modPartTranslation = { "allCumshot" : "kineticNovelAllCumshots", "auto-win" : "shufflePuzzleAutoWin", "autowin" : "shufflePuzzleAutoWin", "auto-win-minigames" : "shufflePuzzleAutoWin", "autowin-minigames" : "shufflePuzzleAutoWin", "canon" : "kineticNovelCanon", "collectibles" : "showCollectibles", "completion" : "showCompletion", "cumshot" : "kineticNovelAllCumshots", "cumshots" : "kineticNovelAllCumshots", "event" : "showEvents", "events" : "showEvents", "freeroamEnd" : "showFreeroamEnd", "freeroamFF" : "showFreeroamFF", "guide" : "showGuide", "guides" : "showGuide", "kinetic" : "kineticNovel", "kinetic-allCumshot" : "kineticNovelAllCumshots", "kinetic-canon" : "kineticNovelCanon", "kinetic-cumshot" : "kineticNovelAllCumshots", "kinetic-ntr" : "kineticNovelNTR", "kineticCanon" : "kineticNovelCanon", "kineticNTR" : "kineticNovelNTR", "labels" : "showLabels", "minigame" : "showShufflePuzzle", "minigames" : "showShufflePuzzle", "ntr" : "kineticNovelNTR", "puzzles" : "showShufflePuzzle", "quiz" : "showQuiz", "shufflePuzzle" : "showShufflePuzzle", "star" : "showCollectibles", "textboxMod" : "modTextbox", "timer": "minigameTimer", "tooltip" : "showTooltips", "tooltips" : "showTooltips", "tt" : "showTooltips", "walkthrough" : "showWalkthrough", "win-minigames" : "shufflePuzzleAutoWin" } if modPart in modPartTranslation.keys (): modPart = modPartTranslation [modPart] if modPart in persistent.riamMar.keys (): return persistent.riamMar [modPart] return False def overrideLabels (self, labels): kinetic_key = "kinetic" default_key = "default" label_keys = [ default_key, kinetic_key ] if any (item in label_keys for item in labels.keys ()): # if there are default or kinetic label overrides if kinetic_key in labels.keys (): # check if there are kinetic label overrides if self.isActive (kinetic_key): # if kinetic mode is activated self.updateLabelOverrides (labels [kinetic_key]) # set up all kinetic labels to override their targets # we want to keep default overrides for settings/mc renaming, end and warning labels etc. else: # but if kinetic mode is disabled for kineticLabelFrom in labels [kinetic_key].keys (): # go through all kinetic labels and if kineticLabelFrom in config.label_overrides.keys (): # if a kinetic label is overriding something self.overrideLabelsDel (kineticLabelFrom) # remove that label override if default_key in labels.keys (): # check if default labels are overridden (e.g. start has a settings/mc rename label added) self.updateLabelOverrides (labels [default_key]) # and add them to the override else: # if no kinetic labels are available, there are default labels self.updateLabelOverrides (labels [default_key]) # so, update label overrides elif isinstance (labels, "dict"): # if there are no default or kinetic labels and labels is a dict, simply add the dict to label overrides self.updateLabelOverrides (labels) # hopefully the person calling this function doesn't add stupid stuff as "labels"... def updateLabelOverrides (self, labels): global config config.label_overrides.update (labels) def overrideLabelsDel (self, label): global config config.label_overrides.pop (label) def preparePersistentData (self): global f, f2, mc_name renpy.save_persistent () settings = { "family" : True, "kineticNovel" : False, "kineticNovelAllCumshots" : True, "kineticNovelCanon" : False, "kineticNovelNTR" : False, "mcName" : "Frank", "minigameTimer" : False, "modQuicknav" : True, "modTextbox" : True, "opacityCompletion" : 0.6, "opacityGuide" : 0.6, "opacityLabels" : 0.6, "opacityQuicknav" : 0.6, "posQuicknavBottom" : False, "showCollectibles" : True, "showCompletion" : True, "showEvents" : True, "showFreeroamEnd" : True, "showFreeroamFF" : True, "showGuide" : True, "showLabels" : True, "showQuiz" : True, "showTooltips" : True, "showWalkthrough" : True, "showShufflePuzzle" : True, "shufflePuzzleAutoWin" : True } if persistent.riamMar is None: persistent.riamMar = {} for attribute, value in settings.items (): if attribute not in persistent.riamMar.keys (): persistent.riamMar.update ({ attribute : value }) if attribute == "mcName": f.name = f2.name = value return True def quitConfirmation (self): return self.config ["confirmQuit"] def quizCompleted (self, freeroam): return persistent.storyReward > 0 def resetLabels (self): self.labels = {} def setLabel (self): if not RiamMar_current_label in [ "after_load", "_return" ]: self.lastLabel = RiamMar_current_label def setMCName (self, newMCName): global f, f2, mc_name self.oldMCName = persistent.riamMar ["mcName"] self.hardcodedItemsToReplace.update ({ "Frank" : newMCName }) mc_name = f.name = f2.name = newMCName persistent.riamMar.update ({ "mcName" : newMCName }) renpy.save_persistent () def setPersistent (self, var, value): persistent.riamMar.update ({ var : value }) renpy.save_persistent () def setMoney (self, newMoneyValue): global money if newMoneyValue == "": newMoneyValue = 0 money = int (newMoneyValue) def showModMenuActiveTab (self): self.hideModMenuTabs () renpy.show_screen (self.activeModMenuTab ()) def shuffleCompleted (self, freeroam): return persistent.shuffleReward > 0 def setRelationshipScore (self, varName, varValue): varName = varValue def str (self, value): if not value: return type (value) return str (value) def toPercent (self, value, type = "str"): type = type.lower () types = { "floats" : ["f", "fl", "float"], "hexs" : ["a", "alpha", "h", "hex", "x"], "ints" : ["i", "int", "integer"], "strings" : ["s", "str", "string"] } if type in types ["floats"]: if isinstance (value, int): return float (value) / 100 return "Expected int, found " + type (value) if type in types ["hexs"]: if isinstance (value, int): value = float (value) / 100 if isinstance (value, float): return "{:02x}".format (int (value * 255)) return "Expected float or int, found " + type (value) if type in types ["ints"]: if isinstance (value, float): return int (value * 100) return "Expected float, found " + type (value) if type in types ["strings"]: if isinstance (value, int): return str (float (value) / 100) + "%" elif isinstance (value, float): return str (int (value * 100)) + "%" return "Expected float or int, found " + type (value) return "Unsupported type " + str (type) + ". Expected float, int or string." def toScreenTitle (self, screenName): return screenName.title ().replace (" ", "") def updateReplacements (self, filename, menuLineNumber, textKey, newTextItem): if not filename in self.replacements: self.replacements.update ({ filename : {} }) if not menuLineNumber in self.replacements [filename]: self.replacements [filename].update ({ menuLineNumber : {} }) self.replacements [filename][menuLineNumber].update ({ textKey : newTextItem }) return riamMar = RiamMar ()