def step_randomly(self, entity): import settings x, y = entity.component('Position').get() possible_steps = [(dx, dy) for dx in range(-1, 2) for dy in range(-1, 2) \ if settings.current_map.is_passable_for(entity, (x+dx, y+dy))] if len(possible_steps) != 0: dx, dy = random.choice(possible_steps) entity.component('Position').add(x=dx, y=dy)
def step_towards_player(self, entity): import settings passmap = settings.current_map.passability_map_for(entity) player = settings.current_map.entity('PLAYER') player_pos = player.component('Position').get() ent_pos = entity.component('Position').get() path = find_path(passmap, ent_pos, player_pos) if len(path) > 1 and not player_pos == path[1]: entity.component('Position').set(path[1][0], path[1][1])
def step_towards_target(self, entity): import settings passmap = settings.current_map.passability_map_for(entity) target = settings.current_map.entity(self._target) target_pos = target.component('Position').get() ent_pos = entity.component('Position').get() path = find_path(passmap, ent_pos, target_pos) if len(path) > 1 and not target_pos == path[1]: entity.component('Position').set(path[1][0], path[1][1])
def _name(self, entity): item = entity.component('Item') npc = entity.component('NPC') player = entity.component('PlayerLogic') if item is not None: return item.name() if npc is not None: return npc.name() if player is not None: return 'Player' return 'Unknown object'
def step_away_from_player(self, entity): import settings passmap = settings.current_map.passability_map_for(entity) player = settings.current_map.entity('PLAYER') player_pos = player.component('Position').get() ent_pos = entity.component('Position').get() (x, y) = ent_pos dx, dy = (player_pos[0] - ent_pos[0], player_pos[1] - ent_pos[1]) dx, dy = (-1 if dx < 0 else 1 if dx > 0 else 0, -1 if dy < 0 else 1 if dy > 0 else 0) if settings.current_map.is_passable_for(entity, (x-dx, y-dy)): entity.component('Position').sub(x=dx, y=dy)
def _use_item(self, index, menu): entity = self._mapp.entity(self._entity_ident) inventory = entity.component('Inventory') item_ent = inventory.items().as_list()[index] usable = item_ent.component('Usable') is_paralyzed = entity.component('Stats').has_status('PARALYZE') if usable is not None and not is_paralyzed: remove = usable.use(item_ent, entity, self._mapp, menu) if remove: self._remove_binding_for(index) inventory.remove(item_ent) return True self._mapp.end_turn() return False
def handle_event(self, entity, event, resident_map): event_type, event_data = event is_paralyzed = entity.component('Stats').has_status('PARALYZE') # Remove this creature's threatened positions after they die if event_type == 'KILLED_ENTITY' and event_data == entity and self._delayed_targets is not None: targeted_positions = self._delayed_targets[1] resident_map.remove_threatened_positions(entity.ident()) return False # Rest the target to None if the target died if event_type == 'KILLED_ENTITY' and event_data.ident() == self._target: self._target = None if event_type == 'ENDED_TURN': self._handle_passive_attacks(entity, resident_map) if is_paralyzed: return False elif self._delayed_attack is not None: if self._handle_delayed_attack(entity, resident_map) is False: return False # If no delayed attack, get action from state instead state = self._states.get(self._current_state) if state is not None: return state.handle_event(entity, self, event) return False
def _render(self, console, origin): x, y = origin yy = 1 old_fg = console.default_fg console.print_(x=x, y=y, string='Inventory') entity = self._mapp.entity(self._entity_ident) if entity is None: return itms = entity.component('Inventory').items().as_list() index = 0 for ent in itms: ent_origin = (x, yy + y) console.default_fg = tcod.cyan if (self._has_focus and self._selection_index == index) else \ tcod.orange if index in self._bindings.values() else \ console.default_fg if index in self._bindings.values(): sym = [ k for k in self._bindings if self._bindings[k] == index ][0] console.print_(x=x, y=yy + y, string=self._key_name(sym)) else: ent.component('Render').render(ent, console, ent_origin) console.print_(x=x + 2, y=yy + y, string=ent.component('Item').name()) console.default_fg = old_fg yy += 1 index += 1
def handle_event(self, event, menu): if not self._has_focus: return False entity = self._mapp.entity(self._entity_ident) equipment_slots = entity.component('EquipmentSlots') slots_size = sum(len(v) for v in equipment_slots.slots().values()) event_type, event_data = event if event_type == "TCOD" and slots_size > 0: if event_data.type == "KEYDOWN" and event_data.sym in [ tcod.event.K_KP_8, tcod.event.K_i ]: self._selection_index = max(self._selection_index - 1, 0) if event_data.type == "KEYDOWN" and event_data.sym in [ tcod.event.K_KP_2, tcod.event.K_k ]: self._selection_index = min(self._selection_index + 1, slots_size - 1) if event_data.type == "KEYDOWN" and event_data.sym == tcod.event.K_e: item_ent = self._selected_entity() if item_ent is None: return False equipment_slots.unequip(entity, item_ent, self._selected_slot(), settings.current_map) item_ent = self._selected_entity() menu.panel('EntityStatsPanel')[1].set_entity(item_ent) menu.panel('ModSlotPanel')[1].set_entity(item_ent)
def f(self, entity, ai, event_data): stats = entity.component('Stats') hp_prop = stats.get('cur_hp') / stats.get('max_hp') if hp_prop < proportion: handler(entity, ai, event_data) return should_stop return False
def distance_to_target(self, entity): import settings if self._target is None: return None target = settings.current_map.entity(self._target) my_position = entity.component('Position').get() target_position = target.component('Position').get() return distance(target_position, my_position)
def _selected_entity(self): entity = self._mapp.entity(self._entity_ident) slots = entity.component('EquipmentSlots').slots() index = 0 for slot_type in slots: for slot in slots[slot_type]: if index == self._selection_index: return slot index += 1
def _finalise_selection(self, menu): entity = self._mapp.entity(self._entity_ident) slots = entity.component('EquipmentSlots').slots() index = 0 for slot_type in slots: slot_index = 0 for slot in slots[slot_type]: if index == self._selection_index: menu.resolve((slot_type, slot_index)) return index += 1 slot_index += 1 menu.resolve()
def _keys(self, entity): import entity as entity_module stats = entity.component('Stats') all_stats = entity_module.Stats.all_stats - \ entity_module.Stats.primary_stats - \ entity_module.Stats.cur_stats - \ entity_module.Stats.resistance_stats - \ set(['level', 'max_exp']) resistances = entity_module.Stats.resistance_stats shown_stats = all_stats - set( [s for s in all_stats if stats.get(s) == 0]) return ['atk', 'dfn', 'itl', 'res', 'spd', 'hit'] + sorted( list(resistances)) + [None] * 2 + sorted(list(shown_stats))
def _render(self, console, origin): import entity as entity_module page = self._page x, y = origin console.print_(x=x, y=y, string="Statistics") y = y + 1 entity = self._get_entity() if entity is None: return stats = entity.component('Stats') keys = self._keys(entity) console.print_(x=x, y=y, string=self._name(entity)) y = y + 1 console.print_(x=x, y=y, string="Level : " + abbrev(stats.get_value('level'))) y = y + 1 old_fg = console.default_fg if stats.get_value('max_hp') > 0: ratio = stats.get_value('cur_hp') / stats.get_value('max_hp') if ratio < 0.25: console.default_fg = tcod.red elif ratio < 1.0: console.default_fg = tcod.yellow console.print_(x=x, y=y, string="HP : " + abbrev(stats.get_value('cur_hp')) + " / " + abbrev(stats.get_value('max_hp'))) console.default_fg = old_fg y = y + 1 if stats.get_value('max_sp') > 0: ratio = stats.get_value('cur_sp') / stats.get_value('max_sp') if ratio < 0.25: console.default_fg = tcod.red elif ratio < 1.0: console.default_fg = tcod.yellow console.print_(x=x, y=y, string="SP : " + abbrev(stats.get_value('cur_sp')) + " / " + abbrev(stats.get_value('max_sp'))) console.default_fg = old_fg y = y + 1 for key in keys[(page * 6):(page * 6 + 6)]: if key is not None: label = key.upper() value = stats.get_value(key) console.print_(x=x, y=y, string=label + ": " + abbrev(value)) y = y + 1
def _render(self, console, origin): x, y = origin yy = 1 entity = self._mapp.entity(self._entity_ident) old_fg = console.default_fg console.print_(x=x, y=y, string='Equipment slots') slots = entity.component('EquipmentSlots').slots() index = 0 for slot_type in slots: for slot in slots[slot_type]: if self._selection_index == index and self._has_focus: console.default_fg = tcod.orange console.print_(x=x, y=yy + y, string="({})".format(slot_type) if slot is None else slot.component('Item').name()) console.default_fg = old_fg yy += 1 index += 1
def handle_event(self, event, menu): if not self._has_focus: return False entity = self._mapp.entity(self._entity_ident) equipment_slots = entity.component('EquipmentSlots') slots_size = sum(len(v) for v in equipment_slots.slots().values()) event_type, event_data = event if event_type == "TCOD" and slots_size > 0: if event_data.type == "KEYDOWN" and event_data.sym in [ tcod.event.K_i, tcod.event.K_KP_8 ]: self._selection_index = max(self._selection_index - 1, 0) if event_data.type == "KEYDOWN" and event_data.sym in [ tcod.event.K_k, tcod.event.K_KP_2 ]: self._selection_index = min(self._selection_index + 1, slots_size - 1) if event_data.type == "KEYDOWN" and event_data.sym == tcod.event.K_e: self._finalise_selection(menu) return if event_data.type == "KEYDOWN" and event_data.sym == tcod.event.K_ESCAPE: self._cancel_selection(menu)
def handle_event(self, event, menu): # Run key bindings event_type, event_data = event if not self._bindings_disabled and event_type == "TCOD" and event_data.type == "KEYDOWN": binding = self._bindings.get(event_data.sym) if binding is not None: self._use_item(binding, menu) return True if not self._has_focus: return False entity = self._mapp.entity(self._entity_ident) if not entity: return False inventory = entity.component('Inventory') inventory_size = inventory.items().size() if event_type == "TCOD" and event_data.type == "KEYDOWN" and inventory_size > 0: items = inventory.items().as_list() item_ent = items[ self._selection_index] if self._selection_index < len( items) else None lshift_held = event_data.mod & tcod.event.KMOD_LSHIFT == 1 step = 5 if lshift_held else 1 if event_data.sym in [tcod.event.K_KP_8, tcod.event.K_i]: self._selection_index = max(self._selection_index - step, 0) item_ent = items[ self._selection_index] if self._selection_index < len( items) else None settings.root_menu.panel('EntityStatsPanel')[1].set_entity( item_ent) settings.root_menu.panel('ModSlotPanel')[1].set_entity( item_ent) menu.panel('HelpPanel')[1].set_text( item_ent.component('Item').description()) return True elif event_data.sym in [tcod.event.K_s, tcod.event.K_KP_MULTIPLY]: self.sort_inventory() elif event_data.sym in [tcod.event.K_KP_2, tcod.event.K_k]: self._selection_index = min(self._selection_index + step, inventory_size - 1) item_ent = items[ self._selection_index] if self._selection_index < len( items) else None settings.root_menu.panel('EntityStatsPanel')[1].set_entity( item_ent) settings.root_menu.panel('ModSlotPanel')[1].set_entity( item_ent) menu.panel('HelpPanel')[1].set_text( item_ent.component('Item').description()) return True elif event_data.sym in [tcod.event.K_KP_4, tcod.event.K_h]: stats_panel = menu.panel('EntityStatsPanel') if stats_panel is not None: stats_panel[1].prev_page() elif event_data.sym in [tcod.event.K_KP_6, tcod.event.K_l]: stats_panel = menu.panel('EntityStatsPanel') if stats_panel is not None: stats_panel[1].next_page() elif event_data.sym == tcod.event.K_d: item_ent = inventory.items().as_list()[self._selection_index] position = entity.component("Position").get() self._remove_binding_for(self._selection_index) inventory.drop(entity, item_ent, self._mapp, position) self._selection_index = max(self._selection_index - 1, 0) return True elif event_data.sym == tcod.event.K_f: res = self._use_item(self._selection_index, menu) if res: self._selection_index = max(self._selection_index - 1, 0) return True elif event_data.sym >= tcod.event.K_0 and event_data.sym <= tcod.event.K_9: key = event_data.sym self.set_key_bind(key, self._selection_index) if event_data.sym == tcod.event.K_e: if item_ent.component('Equipment') is not None: equipment_slots = entity.component('EquipmentSlots') choose_slot_menu = Menu( { 'ChooseEquipmentSlotPanel': ((0, 0), ChooseEquipmentSlotPanel(self._entity_ident, self._mapp)) }, ['ChooseEquipmentSlotPanel']) chosen_slot = choose_slot_menu.run(self._console) if chosen_slot is not None: equipment_slots.equip(entity, item_ent, chosen_slot, self._mapp) self._selection_index -= 1 return True elif item_ent.component('Mod') is not None: choose_item_menu = Menu( { 'ChooseItemPanel': ((0, 0), ChooseItemPanel(entity, ['Equipment'])) }, ['ChooseItemPanel']) chosen_item = choose_item_menu.run(self._console) if chosen_item is None or len( chosen_item.component( 'Equipment').mod_slots()) == 0: return True choose_mod_slot_menu = Menu( { 'ChooseModSlotPanel': ((0, 0), ChooseModSlotPanel(chosen_item)) }, ['ChooseModSlotPanel']) chosen_slot_index = choose_mod_slot_menu.run(self._console) if chosen_slot_index is None: return True chosen_item.component('Equipment').attach_mod( chosen_item, item_ent, chosen_slot_index, self._mapp) self._selection_index = max(self._selection_index - 1, 0) self._remove_binding_for(self._selection_index) inventory.remove(item_ent) return True return False item_ent = items[ self._selection_index] if self._selection_index < len( items) else None menu.panel('EntityStatsPanel')[1].set_entity(item_ent) menu.panel('ModSlotPanel')[1].set_entity(item_ent) menu.panel('HelpPanel')[1].set_text( item_ent.component('Item').description()) return False
def f(self, entity, ai, event_data): stats = entity.component('Stats') if self._turns_in_state == num_turns: handler(entity, ai, event_data) return should_stop return False
def perform_attack_against(self, entity, target): import settings my_combat = entity.component('Combat') my_combat.attack(entity, settings.current_map, target.component('Position').get())
def distance_to_player(self, entity): import settings player = settings.current_map.entity('PLAYER') my_position = entity.component('Position').get() player_position = player.component('Position').get() return distance(player_position, my_position)
def _render(self, console, origin): entity = settings.current_map.entity(self._entity_id) status_effects = entity.component('Stats').status_effects() self.set_text(" ".join(status_effects)) super()._render(console, origin)