def on_pre_enter(self, *args): # Load saves to slots Refs.log(f'Check Saves - {self.is_new_game}') # On new game, set all but top empty slot to disabled # On load game, set only loaded to disabled found_empty = True for save_slot in range(1, 4): Refs.log(f'Check save slot {save_slot}') info = load_save_info(save_slot) if info is not None: self.saves[0] = True self.ids[f'save_slot_{save_slot}'].has_game = True self.ids[f'save_slot_{save_slot}'].put_save_info(info) self.ids[f'save_trash_{save_slot}'].disabled = False self.ids[f'save_trash_{save_slot}'].opacity = 1 self.set_save(save_slot, True) else: self.ids[f'save_trash_{save_slot}'].disabled = True self.ids[f'save_trash_{save_slot}'].opacity = 0 if self.is_new_game and found_empty: self.set_save(save_slot, True) found_empty = False else: self.set_save(save_slot, False)
def update_varenth(self, delta): Refs.log(f'Varenth {self._varenth} → {self._varenth + delta}') self._varenth += delta if self._varenth < 20000: self._tavern_locked = True elif self._renown > 'H': self._tavern_locked = False
def remove_item(self, item_id, count, hash=None): Refs.log(f'Remove {count} {item_id} to inventory.') if self._has_metadata[item_id]: if hash is None: raise Exception('Can\'t remove metadataed item with no hash') else: self._items[item_id]['count'] -= 1 self._items[item_id]['items'].pop(hash) else: self._items[item_id]['count'] -= count
def generate_respawn_time(self): self._boss_spawn_timer = uniform(self._respawn_time * 0.9, self._respawn_time * 1.1) calendar = Refs.gc.get_calendar() Refs.log( f'Floor {self._floor_id} boss will respawn in {calendar.get_int_time() + self._boss_spawn_timer} minutes (in-game)' ) calendar.schedule_event( calendar.get_int_time() + self._boss_spawn_timer, self.respawn_boss)
def add_item(self, item_id, count, metadata=None): Refs.log(f'Add {count} {item_id} to inventory.') if not self._has_metadata[item_id]: self._items[item_id]['count'] += count else: self._items[item_id]['count'] += count for _ in range(count): item = self._items[item_id]['class'].new_instance(metadata) self._items[item_id]['items'][item.get_hash()] = item return self._items[item_id]['count']
def update_status_effects(self, types): animations = [] # Evaluate condition if CONDITION not in self._status_effects: return animations dead_effects = [] # Update condition and get dead effects conditions = self._status_effects[CONDITION] for effect_name in conditions.keys(): condition = conditions[effect_name] if condition.get_type() in types: Refs.log(f'Update afflictions for {effect_name}') if self.reduce_condition(conditions, condition, effect_name): dead_effects.append(effect_name) # Remove status effect for every dead_effect remove_types = [] for effect_type in EFFECT_TYPES: if effect_type not in self._status_effects: continue remove_effects = [] for effect_name in dead_effects: for effect_id, effect in self._status_effects[ effect_type].items(): if effect_name != EFFECT_TYPES[effect_type][ effect.get_amount()]: continue remove_effects.append(effect_id) for effect_id in remove_effects: animations.append({ 'entity': self, 'type': f'end_status_effect', 'effect': effect_type }) self._status_effects[effect_type].pop(effect_id) if len(self._status_effects[effect_type]) == 0: remove_types.append(effect_type) for effect_type in remove_types: self._status_effects.pop(effect_type) # For every effect, remove sub-effects remove_types = [] for effect_type, effects in self._status_effects.items(): for dead_effect in dead_effects: if dead_effect in effects: effects.pop(dead_effect) if len(self._status_effects[effect_type]) == 0: remove_types.append(effect_type) for effect_type in remove_types: self._status_effects.pop(effect_type) return animations
def _on_keyboard_down(self, keyboard, keycode, text, modifiers): if self._keycode != keycode: self._keycode = keycode Refs.log(f'Key was pressed - {keycode}') key_name = self.map_key_name(keycode[1]) if key_name is not None: if key_name == 'screenshot': self.take_screenshot() else: for callback in self._keyboard_bindings['on_key_down']: callback(keyboard, key_name, text, modifiers)
def update(self, dt): self._canvas.canvas.clear() for lwf in list(self._lwfs.values()): if lwf.visible: lwf.exec(dt) lwf.render() for lwf_name in self._destroy: if lwf_name not in self._lwfs: continue lwf = self._lwfs.pop(lwf_name) self._paths.pop(lwf_name) if self._debug: Refs.log(f'Destroy {lwf_name}', tag='LwfRenderer') lwf.destroy() self._destroy.clear()
def on_data(self, *args): self.textures = {} for widget in self.data: image_id = widget['id'] source = widget['source'] try: image = CoreImage(source) except Exception: Refs.log(f'Image: Error loading {source}', 'error') continue self.images.append(image) self.textures[image_id] = image.texture del image # print(self.textures) self.get_image_sizes() self.get_image_poses()
def register_lwf(self, lwf_name, lwf_specific_name, texture_handler): self._texture_handlers[lwf_specific_name] = texture_handler if self._debug: Refs.log(f'Create {lwf_specific_name}', tag='LwfRenderer') data = Cache.get('lwf_data', lwf_name) if data is None: lwf_name = 'res/lwf/' + lwf_name path = lwf_name[:lwf_name.rindex('/') + 1] self._paths[lwf_specific_name] = path data = Data(lwf_name) Cache.append('lwf_data', lwf_name, data) lwf = LWF(data, self._factory, lwf_specific_name) self._lwfs[lwf_specific_name] = lwf return lwf
def reduce_condition(self, conditions, condition, effect_name): result = condition.reduce() Refs.log(f'Reduced condition counter for {effect_name} - {condition}') if result: Refs.log('Condition Complete') if condition.get_child(): Refs.log('Going to next child') conditions[effect_name] = condition.get_child() return False else: Refs.log('Destroying status effect') return True return False
def display_screen(self, next_screen, direction, track, *args, **kwargs): old_screen = None if isinstance(next_screen, str): screen = Cache.get('screens', next_screen) if screen is None or next_screen in SCREEN_BLACKLIST: screen = self._create_screen(next_screen, *args, **kwargs) else: screen.reload(*args, **kwargs) next_screen = screen if len(self.children) > 0: old_screen = self.children[0] if not direction: if len(self.list) > 0: next_screen = self.list.pop() next_screen.reload(*args, **kwargs) else: print("No more screens to backtrack.") return if old_screen is None: Refs.log(f'Display {next_screen.name}') else: Refs.log(f'{old_screen.name} → {next_screen.name}') if next_screen not in self.screens: self.add_widget(next_screen) self.current = next_screen.name if old_screen is not None: if old_screen.name == 'dungeon_battle' and old_screen.boss_encounter: Refs.log(f'Battle from boss encounter - Dont delete') return self.remove_widget(old_screen) if track and old_screen.name not in SCREEN_BLACKLIST: self.list.append(old_screen) if old_screen.name in SCREEN_BLACKLIST: Cache.remove('screens', old_screen)
def clear_negative_effects(self): animations = [] for effect_type, effects in self._status_effects.items(): if effect_type == CONDITION: continue dead_effects = [] for effect_name, effect in effects.items(): if effect.get_amount() < 0: dead_effects.append(effect_name) if effect_type in EFFECT_TYPES: animations.append({ 'entity': self, 'type': f'end_status_effect', 'effect': effect_type }) dead_effects.append(effect_name) for dead_effect in dead_effects: Refs.log( f'Remove dead effect {dead_effect} from {self.get_name()}', tag='BattleEntity') effects.pop(dead_effect) return animations
def display_popup(self, previous, popup_name, *args, **kwargs): Refs.log(f'Display popup {popup_name}') popup = None for saved_popup in self.list: if saved_popup.name.startswith(popup_name): # if popup_name + str(args[0]) == saved_popup.name: # Refs.log(popup_name + str(args[0]), saved_popup.name) popup = saved_popup popup.previous = previous popup.refresh(*args) Refs.log('Found saved popup') if popup is None: Refs.log('Create popup') popup = self._create_popup(previous, popup_name, *args, **kwargs) popup.open() self.open_popups.append(popup) Refs.log('Open popup') return popup
def update_effects(self, delta=1): Refs.log(f'Update effects for {self.get_name()}', tag='BattleEntity') dead_effect_types = [] for effect_type, effects in self._status_effects.items(): if effect_type == CONDITION: continue dead_effects = [] if effect_type in STAT_TYPES: for effect_name, effect in effects.items(): if effect.get_duration() <= 0: continue Refs.log(f'{STAT_TYPES[effect_type]} -= {delta} turns') effect.reduce_duration(delta) if effect.get_duration() <= 0: dead_effects.append(effect_name) elif effect_type in COUNTER_TYPES: for effect_name, effect in effects.items(): if effect.get_amount() <= 0: dead_effects.append(effect_name) elif effect_type in DURATION_TYPES: for effect_name, effect in effects.items(): Refs.log(f'{STAT_TYPES[effect_type]} -= {delta} turns') effect.reduce_duration(delta) if effect.get_duration() <= 0: dead_effects.append(effect_name) elif effect_type in EFFECT_TYPES: pass for dead_effect in dead_effects: Refs.log( f'Remove dead effect {dead_effect} from {self.get_name()}', tag='BattleEntity') effects.pop(dead_effect) if len(effects) == 0: dead_effect_types.append(effect_type) for dead_effect_type in dead_effect_types: self._status_effects.pop(dead_effect_type) return self.update_counting_status_effect()
def destroy_lwf(self, lwf_specific_name): if self._debug: Refs.log(f'Flag to destroy {lwf_specific_name}', tag='LwfRenderer') self._destroy.append(lwf_specific_name)
def load_texture(filename, path): try: return Image(f'{path}{filename}').texture except AttributeError: Refs.log(f'Not found <{path}{filename}>', 'error')
def get_animation_state(self): if self._animation_state is None: Refs.log("Skeleton is not yet loaded!", 'error') return return self._animation_state
def append(self, layer, key, value, debug=False): if debug: Refs.log(f'Loader Add {key} - {value}') self.layers[layer][key] = value
def done_loading(self, loader): Refs.log(f"{loader.triggers_finished} / {loader.triggers_total} - {LOADING_SECTIONS[loader.triggers_finished - 1]}") if loader.triggers_finished == loader.triggers_total: Refs.app.finished_loading()
def reload(self, is_new_game=True): self.is_new_game = is_new_game self.saves = [False, False, False] Refs.log(f'Reload: {is_new_game}')
def make_turn(self, targeted): animation_queue = [] self._log += f'Turn {self._turn}\n' win = loss = False for entity in self._get_turn_order(): if entity.is_character(): entity.increase_special_amount(uniform(0.25, 1.25)) target = targeted[entity] else: target = None for animation in self._process_move(entity, False, target): animation_queue.append(animation) # Check for win or loss win, loss = self.check_end() if loss or win: break self._turn += 1 # Do HP Regen and MP Regen and DOT queues = [[], [], [], []] # HP Regen, MP Regen, HP DOT, MP DOT for entity in self._get_alive_enemies() + self._get_alive_characters(): health_regen = entity.get_total_boost(HEALTH_REGEN) if health_regen != 0: health_regen = min(entity.get_health() - entity.get_battle_health(), health_regen * entity.get_health()) if health_regen > 0: self._log += entity.get_name() + f' +{round(health_regen, 1)} health.\n' queues[0].append({'entity': entity, 'type': 'health_rog', 'markers': {entity: [('health', health_regen)]}, 'targets': [entity]}) entity.decrease_health(-health_regen) mana_regen = entity.get_total_boost(MANA_REGEN) if mana_regen != 0: mana_regen = min(entity.get_mana() - entity.get_battle_mana(), mana_regen * entity.get_mana()) if mana_regen > 0: self._log += entity.get_name() + f' +{round(mana_regen, 1)} mana.\n' queues[1].append({'entity': entity, 'type': 'mana_rog', 'markers': {entity: [('mana', mana_regen)]}, 'targets': [entity]}) entity.decrease_mana(-mana_regen) health_dot = entity.get_total_boost(HEALTH_DOT) if health_dot != 0: self._log += entity.get_name() + f' -{round(health_dot * entity.get_health(), 1)} health.\n' entity.decrease_health(health_dot * entity.get_health()) queues[2].append({'entity': entity, 'type': 'health_dot', 'markers': {entity: [('dot', health_dot * entity.get_health())]}, 'targets': [entity]}) Refs.gc.get_floor_data().increase_stat(entity.get_index(), 0, Refs.gc.get_random_stat_increase()) Refs.gc.get_floor_data().increase_stat(entity.get_index(), 4, Refs.gc.get_random_stat_increase()) mana_dot = entity.get_total_boost(MANA_DOT) if mana_dot != 0: self._log += entity.get_name() + f' -{round(mana_dot * entity.get_mana(), 1)} mana.\n' entity.decrease_mana(mana_dot * entity.get_mana()) queues[3].append({'entity': entity, 'type': 'mana_dot', 'markers': {entity: [('dot', mana_dot * entity.get_mana())]}, 'targets': [entity]}) Refs.gc.get_floor_data().increase_stat(entity.get_index(), 1, Refs.gc.get_random_stat_increase()) # Update Conditions for afflictions Refs.log(f'Update status effects for {entity.get_name()}') animation_queue += entity.update_recurring_status_effect() for queue in queues: animation_queue += queue # Decrease effect counters for entity in self._get_alive_enemies() + self._get_alive_characters(): animation_queue += entity.update_effects() if loss: result = False elif win: result = True else: result = None return result, animation_queue
def respawn_boss(self): Refs.log(f'Floor {self._floor_id} boss has respawned') self._boss_spawn_timer = 0 self._boss_defeated = False
def apply_effect(self, effect_id, effect_type, effect): if effect_type not in self._status_effects: self._status_effects[effect_type] = {} if effect_id in self._status_effects[effect_type]: if effect_type in EFFECT_TYPES: Refs.log( f'Do not apply {EFFECT_TYPES[effect_type][effect.get_amount()]} to {self.get_name()}', tag='BattleEntity') elif effect_type in STAT_TYPES: Refs.log( f'Apply diminishing {STAT_TYPES[effect_type]} to {self.get_name()}', tag='BattleEntity') elif effect_type in COUNTER_TYPES: Refs.log( f'Apply diminishing {COUNTER_TYPES[effect_type]} to {self.get_name()}', tag='BattleEntity') elif effect_type in DURATION_TYPES: Refs.log( f'Apply diminishing {DURATION_TYPES[effect_type]} to {self.get_name()}', tag='BattleEntity') else: Refs.log(f'Unknown status effect, {effect_type}', 'error', 'BattleEntity') else: if effect_type in EFFECT_TYPES: name = EFFECT_TYPES[effect_type][effect.get_amount()] Refs.log(f'Apply effect {name} to {self.get_name()}', tag='BattleEntity') for (sub_effect_type, sub_effect) in effect.build(effect_type).items(): if sub_effect_type != CONDITION: sub_effect.set_info(None, name) self._apply_effect(name, sub_effect_type, sub_effect) elif effect_type in STAT_TYPES: Refs.log( f'Apply effect {STAT_TYPES[effect_type]} to {self.get_name()}', tag='BattleEntity') elif effect_type in COUNTER_TYPES: Refs.log( f'Apply effect {COUNTER_TYPES[effect_type]} to {self.get_name()}', tag='BattleEntity') elif effect_type in DURATION_TYPES: Refs.log( f'Apply effect {DURATION_TYPES[effect_type]} to {self.get_name()}', tag='BattleEntity') else: Refs.log(f'Unknown status effect, {effect_type}', 'error', 'BattleEntity') self._apply_effect(effect_id, effect_type, effect)
def get_skeleton(self): if self._skeleton is None: Refs.log("Skeleton is not yet loaded!", 'error') return return self._skeleton