Beispiel #1
0
def random_point_surrounding(position):
    p = Position(libtcod.random_get_int(0, position.x - 1, position.x + 1),
                 libtcod.random_get_int(0, position.y - 1, position.y + 1))
    while p.x == position.x and p.y == position.y:
        p = Position(libtcod.random_get_int(0, position.x - 1, position.x + 1),
                     libtcod.random_get_int(0, position.y - 1, position.y + 1))
    return p
Beispiel #2
0
 def __init__(self, game):
     self.name = None
     self.glyph = None
     self._pos = Position()
     self.energy = Energy()
     self.game = game
     self.hp = 0
     self.base_max_hp = 0
     self.base_defense = 0
     self.base_power = 0
     self.xp = 0
     self.level = 1
     self.inventory = None
Beispiel #3
0
    def on_target(self, target):
        self.game.log.elemental(
            'The fireball explodes, burning everything within %d tiles!' %
            self._radius, Elements.FIRE)
        for actor in self.game.stage.actors:
            if actor.pos.distance_to(target.pos) <= self._radius:
                self.game.log.elemental(
                    '{1} gets burned for %d hit points.' % self._damage,
                    Elements.FIRE, actor)
                actor.take_damage(self, self._damage, self.actor)

        # Send events for the UI to render the explosion
        hit_on = [
            Tile.TYPE_FLOOR, Tile.TYPE_TALL_GRASS, Tile.TYPE_CRUSHED_GRASS
        ]
        for x in range(target.pos.x - self._radius,
                       target.pos.x + self._radius + 1):
            for y in range(target.pos.y - self._radius,
                           target.pos.y + self._radius + 1):
                if target.pos.distance(x, y) <= self._radius:
                    if self.game.stage.map.tile_at(x, y).type in hit_on:
                        self.add_event(
                            Event(Event.TYPE_BOLT,
                                  element=Elements.FIRE,
                                  position=Position(x, y)))
Beispiel #4
0
 def __init__(self, name, glyph, on_use=None, equip_slot=None):
     """An Item can be either usable or equipment, but not both.
     For a usable item, provide a Spell for on_use.
     For equipment, provide an equip slot string."""
     self.name = name
     self.glyph = glyph
     self.pos = Position()
     self.on_use = on_use
     self.owner = None
     self.equip_slot = equip_slot
     self.power_bonus = 0
     self.defense_bonus = 0
     self.max_hp_bonus = 0
     self.is_equipped = False
Beispiel #5
0
    def handle_mouse_click(self, mouse):
        if mouse.rbutton_pressed:
            self.__cancel()
            return

        # Assume it's a left-click

        pos = Position(mouse.cx, mouse.cy)
        if self._range is not None:
            distance = self._game_screen.game.player.pos.distance_to(pos)
            if distance > self._range:
                self._game_screen.game.log.notify('Out of range. Select again.')
                return

        target = Target(position=pos)
        if self._game_screen.game.stage.map.is_in_fov(pos):
            monster = self.__monster_at(pos)
            target.actor = monster

        self.ui.pop(target)
Beispiel #6
0
 def random_point_inside(self):
     return Position(libtcod.random_get_int(0, self.x1 + 1, self.x2 - 1),
                     libtcod.random_get_int(0, self.y1 + 1, self.y2 - 1))
Beispiel #7
0
 def center(self):
     return Position((self.x1 + self.x2) / 2, (self.y1 + self.y2) / 2)
Beispiel #8
0
class Actor(Noun):
    def __init__(self, game):
        self.name = None
        self.glyph = None
        self._pos = Position()
        self.energy = Energy()
        self.game = game
        self.hp = 0
        self.base_max_hp = 0
        self.base_defense = 0
        self.base_power = 0
        self.xp = 0
        self.level = 1
        self.inventory = None

    @property
    def pos(self):
        return self._pos

    @pos.setter
    def pos(self, other):
        if self._pos != other:
            self._pos.copy(other)

    def needs_input(self):
        return False

    def speed(self):
        return NORMAL_SPEED

    def get_action(self):
        action = self.on_get_action()
        if action:
            action.bind(self, True)
        return action

    def on_get_action(self):
        raise Exception('implement in subclass')

    def finish_turn(self, action):
        self.energy.spend()

    def create_melee_hit(self):
        hit = self.on_create_melee_hit()
        self.modify_hit(hit)
        return hit

    def on_create_melee_hit(self):
        raise Exception('implement in subclass')

    def modify_hit(self, hit):
        self.on_modify_hit(hit)

    def on_modify_hit(self, hit):
        pass

    @property
    def power(self):
        bonus = 0
        if self.inventory:
            equipped = filter(lambda i: i.is_equipped, self.inventory)
            bonus = sum(equipment.power_bonus for equipment in equipped)
        return self.base_power + bonus

    @property
    def defense(self):
        bonus = 0
        if self.inventory:
            equipped = filter(lambda i: i.is_equipped, self.inventory)
            bonus = sum(equipment.defense_bonus for equipment in equipped)
        return self.base_defense + bonus

    @property
    def max_hp(self):
        bonus = 0
        if self.inventory:
            equipped = filter(lambda i: i.is_equipped, self.inventory)
            bonus = sum(equipment.max_hp_bonus for equipment in equipped)
        return self.base_max_hp + bonus

    def take_damage(self, action, damage, attacker):
        self.hp -= damage
        self.on_damaged(action, damage, attacker)

        if self.hp <= 0:
            action.add_event(Event(Event.TYPE_DEATH, actor=self, other=attacker))
            attacker.on_killed(self)
            self.on_death(attacker)

    def on_give_damage(self, action, defender, damage):
        pass

    def on_damaged(self, action, damage, attacker):
        pass

    def on_death(self, attacker):
        pass

    def on_killed(self, defender):
        pass

    def heal(self, amount):
        # Heal by the given amount, without going over the maximum
        self.hp += amount
        if self.hp > self.max_hp:
            self.hp = self.max_hp

    def is_alive(self):
        return self.hp > 0

    def required_for_level_up(self):
        return LEVEL_UP_BASE + self.level * LEVEL_UP_FACTOR

    def can_level_up(self):
        return self.xp >= self.required_for_level_up()

    def level_up(self):
        required = self.required_for_level_up()
        self.level += 1
        self.xp -= required

    def is_player(self):
        return self == self.game.player