init python: class quest_class(object): def __init__(self, **kwargs): self.title = "" self.hint = "" self.__dict__.update(kwargs) def status(self): return list(self.__dict__) class counter_class(object): def __init__(self, **kwargs): self.title = "" self.bool = False # Can me switched to 'True' and 'False' for events self.trigger = False # Can only be switched to 'True' self.counter = 0 self.hg_counter = 0 # Hermione self.gw_counter = 0 # Ginny self.cc_counter = 0 # Cho self.ll_counter = 0 # Luna self.sb_counter = 0 # Susan self.ag_counter = 0 # Astoria self.dg_counter = 0 # Daphne self.pp_counter = 0 # Pansy self.ss_counter = 0 # Snape self.nt_counter = 0 # Tonks self.__dict__.update(kwargs) def status(self): return list(self.__dict__) def triggered(self): self.trigger = True self.counter += 1 return class event_class(object): """ Handles and tracks event progression. Event labels ending with "_intro" are treated as one-time events. Otherwise the event can be repeated. `tier` (int): The current tier number, which determines the set of events to run. `counter` (int): The number of successfully completed events. `points` (int): The number of successfully completed events in the current tier. """ def __init__(self, **kwargs): self.title = "" self.hint = "" self.counter = 0 self.start_label = "" self.start_tier = 1 self.inProgress = False self.events = [] self.icons = [] self.iconset = [] self.__dict__.update(kwargs) # _tier is relative to start_tier self._tier = 0 self._points = 0 if not self.events: raise Exception('Events: "events" list was not defined for "{}".'.format(self.title)) self._max_tiers = len(self.events) if not self.iconset: raise Exception('Events: "iconset" list was not defined for "{}". You need to add at least one set of icons.'.format(self.title)) elif len(self.iconset) < self._max_tiers: for i in xrange(self._max_tiers-len(self.iconset)): self.iconset.append([self.iconset[0][0], self.iconset[0][1]]) if self.icons and len(self.icons) < self._max_tiers: raise Exception('Events: "icons" list does not match the number of events for "{}".'.format(self.title)) for i in xrange(self._max_tiers): for j in xrange(len(self.events[i])): self.events[i][j] += [False] def start(self): self.counter += 1 for i in xrange(len(self.events[self._tier])): if self.events[self._tier][i][1] == False: self.events[self._tier][i][1] = True self.points += 1 return renpy.jump(self.events[self._tier][i][0]) self.start_random() def start_advance(self): self.counter += 1 for i in xrange(self._max_tiers): for j in xrange(len(self.events[i])): if self.events[i][j][1] == False: self.events[i][j][1] = True self._tier = i self.points += 1 return renpy.jump(self.events[i][j][0]) self.start_random() def start_random(self): events_filtered = filter(lambda x: '_intro' not in x[0], self.events[self._tier]) random_event = events_filtered[random.randint(0, len(events_filtered)-1)][0] return renpy.jump(random_event) def change_icon(self, a="heart_half", b="heart_red"): for icon in self.iconset: if icon[1] == a: icon[1] = b def get_menu_item(self, disabled=False): menu_text = "" if self.hint: menu_text += "{{image={}_check_True}}".format(gui.theme()) if self.title: menu_text += "\"{}\"".format(self.title) imagepath = "interface/icons/small/" icon = None if len(self.icons) > 0 and self.icons[self._tier]: icon = imagepath + self.icons[self._tier] + ".webp" progress = [] for i, ev in enumerate(self.events[self._tier]): is_complete = ev[1] if is_complete: if self.iconset[self._tier][1] == "heart_half": if i == len(self.events[self._tier])-1: progress.append(imagepath + self.iconset[self._tier][1] + ".webp") else: progress.append(imagepath + "heart_red.webp") else: progress.append(imagepath + self.iconset[self._tier][1] + ".webp") else: progress.append(imagepath + self.iconset[self._tier][0] + ".webp") if disabled: return gui.menu_item(menu_text, "block", icon=icon, progress=progress, style="disabled") else: return gui.menu_item(menu_text, self.start_label, icon=icon, progress=progress) def fail(self): self.counter = max(0, self.counter-1) self.points -= 1 self.events[self._tier][self._points][1] = False return def fail_intentional(self): self.counter = max(0, self.counter-1) self.points -= 1 return # Reset the event completely def reset(self): for i in xrange(self._max_tiers): for j in xrange(len(self.events[i])): self.events[i][j][1] = False self._tier = 0 self._points = 0 self.counter = 0 self.inProgress = False def status(self, value): status_list = [] for item in self.events[value-1]: status_list += [item[1]] return status_list def is_complete(self, ignore_in_progress=False): is_last_tier = (self._tier == self._max_tiers - 1) return is_last_tier and self.is_tier_complete(ignore_in_progress=ignore_in_progress) def is_tier_complete(self, ignore_in_progress=False): event_count = len(self.events[self._tier]) return self.points == event_count and (not self.inProgress or ignore_in_progress) def is_event_complete(self, tier, event): relative_tier = tier - self.start_tier try: return bool(self.events[relative_tier][event-1][1]) except IndexError: return False @property def points(self): return self._points @points.setter def points(self, value): self._points = max(0, min(value, len(self.events[self._tier]))) @property def tier(self): return self._tier + self.start_tier @tier.setter def tier(self, value): relative_tier = max(0, min(value - self.start_tier, self._max_tiers - 1)) if relative_tier != self._tier: # Change tier and reset progress self._points = 0 self._tier = relative_tier class stats_class(dict): def __delitem__(self, key): """Override delitem method to delete inner dictionary key.""" del self[key] def __missing__(self, key): """Return zero if key does not exist in the inner dictionary.""" return 0 def __setattr__(self, name, value): """Override setattr method to add attributes as keys and values in the inner dictionary.""" self[name] = value def __getattr__(self, name): """Override getattr method to return a value of the key from the inner dictionary.""" # Skip protected attributes and/or injected Ren'py methods if not name.startswith("_"): return self[name] raise AttributeError("'"+self.__class__.__name__+"' has no attribute '"+name+"'") def status(self): """Print currently defined keys and values in the console.""" for key, value in self.iteritems(): print key + " == " + str(value) return def reset(self): """Reset all key values back to default values depending on the value type.""" for key in self.iterkeys(): if isinstance(self[key], (float, int)): self[key] = 0 elif isinstance(self[key], bool): self[key] = False else: pass return