示例#1
0
 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)
示例#2
0
 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])
示例#3
0
 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])
示例#4
0
 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'
示例#5
0
 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)
示例#6
0
 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
示例#7
0
    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
示例#8
0
    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
示例#9
0
 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)
示例#10
0
 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
示例#11
0
 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)
示例#12
0
 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
示例#13
0
 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()
示例#14
0
 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))
示例#15
0
 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
示例#16
0
 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
示例#17
0
 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)
示例#18
0
    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
示例#19
0
 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
示例#20
0
 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())
示例#21
0
 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)
示例#22
0
 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)