Example #1
0
class Game:
    def __init__(self):
        # initialize imported components
        pygame.init()
        # number of frames rendered per second
        # (equal to number of loop turns)
        self.FPS = 60
        # clock to synchronize ticks with desired FPS
        self.clock = pygame.time.Clock()
        # main loop condition
        self.running = True

        # initialize subsystems
        self.drawer = Drawer()
        self.handler = EventHandler(self)
        self.game_state = GameState()
        self.manager = Manager()
        self.ticker = Ticker(self)

    def initialize(self):
        # create game objects from scaffold
        # and add them to proper subsystems
        scaffold = Scaffold()
        for obj in scaffold.objects:
            self.manager.add_object(obj)

        for obs in scaffold.observers:
            self.game_state.add_observer(obs)

        for e in scaffold.recurring_events:
            self.ticker.add_event(e)

    def shutdown(self):
        # this will break main loop
        self.running = False

    def exit(self):
        # close all imported components
        pygame.quit()
        # force exit program
        exit(1)

    def loop(self):
        self.initialize()

        # main loop
        while self.running:
            # synchronize
            self.clock.tick(self.FPS)
            # notify ticker
            self.ticker.tick()

            # render game objects
            self.drawer.draw(self.manager)
            # respond to events
            self.handler.handle()

        self.exit()
Example #2
0
 def take_damage(self, val):
     if self.dmg_reduction > 0:
         val -= self.dmg_reduction
     if val > 0:
         self.hp -= val
         if self.hp <= 0:
             f = self.death_function
             if f is not None:
                 EventHandler.add_death_event('death', (f, self.owner))
Example #3
0
 def picked_up(self, entity_picker, objects):
     assert entity_picker.inventory is not None, 'cannot pick up items without an inventory'
     if len(entity_picker.inventory) >= 26:
         EventHandler.add_inventory_event(ActionType.PICK_UP_FAIL,
                                          (self.owner, entity_picker))
         return ActionType.PICK_UP_FAIL
     else:
         entity_picker.inventory.items.append(self.owner)
         objects.remove(self.owner)
         EventHandler.add_inventory_event(ActionType.PICK_UP_GAIN,
                                          (self.owner, entity_picker))
         return ActionType.PICK_UP_GAIN
Example #4
0
    def __init__(self):
        # initialize imported components
        pygame.init()
        # number of frames rendered per second
        # (equal to number of loop turns)
        self.FPS = 60
        # clock to synchronize ticks with desired FPS
        self.clock = pygame.time.Clock()
        # main loop condition
        self.running = True

        # initialize subsystems
        self.drawer = Drawer()
        self.handler = EventHandler(self)
        self.game_state = GameState()
        self.manager = Manager()
        self.ticker = Ticker(self)
Example #5
0
 def move_or_attack(dx, dy, objects, player, tilemap):
     x = player.x + dx
     y = player.y + dy
     target = None
     for o in objects:
         if o.fighter and o.x == x and o.y == y:
             target = o
             break
     if target is not None:
         results = Combat.melee_attack(player, target)
         EventHandler.add_combat_event(ActionType.MELEE_COMBAT,
                                       (player, target, results))
         return ActionType.MELEE_COMBAT
     else:
         player.move(dx, dy, tilemap, objects)
         RenderFunctions.fov_recompute = True
         EventHandler.add_move_event(ActionType.MOVE, None)
         return ActionType.MOVE
Example #6
0
    def update(self, action):

        if action in (ActionType.MELEE_COMBAT, ActionType.RANGED_COMBAT):
            self.game_state = GameState.ENEMY_TURN

        elif action == ActionType.PICK_UP_GAIN:
            self.game_state = GameState.ENEMY_TURN

        elif action == ActionType.MOVE:
            self.game_state = GameState.ENEMY_TURN
            RenderFunctions.compute_fov(self)

        # event updates and messages

        EventHandler.update()

        # enemy turn

        if self.game_state == GameState.ENEMY_TURN:
            for o in self.objects:
                if o.fighter and o.ai and o.timeobj:
                    o.timeobj.tick()
            self.__game_time += 1
            self.game_state = GameState.PLAYING
Example #7
0
    def attack_closest(objects, player, fov_map, max_range=10):
        closest = None
        closest_dist = max_range + 1

        for o in objects:
            if o.fighter and o != player and libtcod.map_is_in_fov(
                    fov_map, o.x, o.y):
                dist = player.distance_to_entity(o)
                if dist < closest_dist:
                    closest = o
                    closest_dist = dist

        if closest is not None and libtcod.map_is_in_fov(
                fov_map, closest.x, closest.y):
            if player.distance_to_entity(closest) >= 2:
                if player.inventory.get_equipped_in_slot(Slot.RANGED) is None:
                    player.move_astar(closest)
                    RenderFunctions.fov_recompute = True
                    EventHandler.add_move_event(ActionType.MOVE, None)
                    return ActionType.MOVE
                else:
                    if player.distance_to_entity(
                            closest) <= player.fighter.firing_range:
                        result = Combat.ranged_attack(player, closest)
                        RenderFunctions.fov_recompute = True
                        EventHandler.add_combat_event(
                            ActionType.RANGED_COMBAT,
                            (player, closest, result))
                        return ActionType.RANGED_COMBAT
                    else:
                        player.move_astar(closest)
                        RenderFunctions.fov_recompute = True
                        EventHandler.add_move_event(ActionType.MOVE, None)
                        return ActionType.MOVE
            elif closest.fighter.hp > 0:
                result = Combat.melee_attack(player, closest)
                EventHandler.add_combat_event(ActionType.MELEE_COMBAT,
                                              (player, closest, result))
                return ActionType.MELEE_COMBAT
Example #8
0
 def melee_attack(self, target):
     result = Combat.melee_attack(self.owner, target)
     EventHandler.add_combat_event(ActionType.MELEE_COMBAT, (self.owner, target, result))
Example #9
0
    def take_turn(self):
        entity = self.owner
        player = self.world.player
        cost = 0

        if self.state == EntityState.SLEEPING:
            if libtcod.map_is_in_fov(self.world.fov_map, entity.x, entity.y) or \
               entity.distance_to_entity(player) + player.fighter.stealthiness <= 10:
                if Rolls.wake_up_roll(entity, player):
                    self.state = EntityState.IDLE
                    if libtcod.map_is_in_fov(self.world.fov_map, entity.x,
                                             entity.y):
                        EventHandler.add_entity_event('wake_up', entity)
            cost = 100

        elif self.state == EntityState.IDLE:
            if libtcod.map_is_in_fov(self.world.fov_map, entity.x, entity.y):
                self.target = player
                self.timer = 10
                self.state = EntityState.CHASING
                self.target_coord = player.x, player.y
                EventHandler.add_entity_event('spotted', entity)
                cost = 50
            else:
                wander_chance = libtcod.random_get_int(0, 0, 100)
                if wander_chance <= 10:
                    self.state = EntityState.WANDERING
                elif wander_chance <= 20 and self.sleep_timer == 0:
                    self.state = EntityState.SLEEPING
                    self.sleep_timer += self.sleep_cooldown
                else:
                    cost = 100

        elif self.state == EntityState.CHASING:
            if libtcod.map_is_in_fov(self.world.fov_map, entity.x, entity.y):
                if entity.distance_to_entity(player) >= 2:
                    entity.move_astar(player, self.world.tilemap,
                                      self.world.objects)
                    self.target_coord = player.x, player.y
                    cost = 100
                elif self.target.fighter.hp > 0:
                    entity.fighter.melee_attack(self.target)
                    cost = 100
            elif self.target_coord != (None, None) and self.timer > 0:
                if entity.x == self.target_coord[
                        0] and entity.y == self.target_coord[1]:
                    self.target_coord = (None, None)
                    self.state = EntityState.IDLE
                else:
                    entity.move_towards(self.target_coord[0],
                                        self.target_coord[1],
                                        self.world.tilemap, self.world.objects)
                    self.timer -= 1
                    cost = 100
            elif self.timer <= 0:
                self.timer = 0
                self.target_coord = (None, None)
                self.state = EntityState.IDLE

        elif self.state == EntityState.WANDERING:
            if libtcod.map_is_in_fov(self.world.fov_map, entity.x, entity.y):
                self.target = player
                self.timer = 10
                self.state = EntityState.CHASING
                self.target_coord = player.x, player.y
                EventHandler.add_entity_event('spotted', entity)
                cost = 50
            else:
                if self.target_coord != (None, None):
                    if entity.x == self.target_coord[
                            0] and entity.y == self.target_coord[1]:
                        self.target_coord = (None, None)
                        self.state = EntityState.IDLE
                    else:
                        old_x, old_y = entity.x, entity.y
                        entity.move_towards(self.target_coord[0],
                                            self.target_coord[1],
                                            self.world.tilemap,
                                            self.world.objects)
                        if entity.x == old_x and entity.y == old_y:
                            self.target_coord = (None, None)
                            self.state = EntityState.IDLE
                    cost = 100
                else:
                    dx = libtcod.random_get_int(0, -8, 8)
                    dy = libtcod.random_get_int(0, -8, 8)
                    if 0 <= entity.x + dx < Constants.consts['MAP_WIDTH'] and \
                       0 <= entity.y + dy < Constants.consts['MAP_HEIGHT']:
                        if not self.world.tilemap[entity.x + dx][entity.y +
                                                                 dy].blocked:
                            self.target_coord = entity.x + dx, entity.y + dy

        if self.state != EntityState.SLEEPING and self.sleep_timer > 0:
            self.sleep_timer -= 1
        return cost