Пример #1
0
    def __init__(self,
                 use_function=None,
                 uses=-99,
                 item_type=ItemType.NONE,
                 equip_effects=None,
                 strength=0,
                 defense=0,
                 price=0,
                 description="",
                 **kwargs):
        self.use_function = use_function
        self.uses = uses
        self.function_kwargs = kwargs
        self.item_type = item_type
        self.equip_effects = equip_effects
        self.price = price
        self.description = description

        if strength != 0:
            ammo = kwargs['ammo'] if 'ammo' in kwargs else 0
            self.weapon = Weapon(strength, ammo)
        else:
            self.weapon = None

        if defense != 0:
            self.armor = Armor(defense)
        else:
            self.armor = None
Пример #2
0
def create_component(component):
    """
    Return the desired component.
    """
    # Weapon components.
    if component == WeaponComponent.LASER:
        return Weapon(name='pulse laser',
                      damage=5,
                      min_targets=1,
                      max_targets=5,
                      color=libtcod.green,
                      range=10,
                      cost=2,
                      rate_of_fire=10,
                      projectile=ProjectileType.LASER_PROJECTILE)

    elif component == WeaponComponent.GUN:
        return Weapon(name='gattling gun',
                      damage=5,
                      min_targets=1,
                      max_targets=3,
                      color=libtcod.red,
                      range=10,
                      cost=1,
                      rate_of_fire=4,
                      projectile=ProjectileType.BASIC_PROJECTILE)

    # Chassis components.
    elif component == ChassisComponent.BASIC_CHASSIS:
        return Chassis(max_hp=30)
    elif component == ChassisComponent.WEAK_CHASSIS:
        return Chassis(max_hp=20)

    # Propulsion components.
    elif component == PropulsionComponent.BASIC_PROPULSION:
        return Propulsion(max_speed=12, max_impulse=2)
    elif component == PropulsionComponent.WEAK_PROPULSION:
        return Propulsion(max_speed=4, max_impulse=1)

    # AI components.
    elif component == AIComponent.DEBUG:
        return DoNothing()
    elif component == AIComponent.PROJECTILE:
        return ProjectileAI()

    return None
Пример #3
0
 def __init__(self, *groups):
     SHEET = sprite_sheet((100,100), 'assets/ship-death.png')
     super().__init__(pygame.transform.scale(PLAYER, (125, 125)), (200, 800, 120), (WIDTH/2, HEIGHT-50), groups)
     self.hp = 6
     self.mask = pygame.mask.from_surface(self.image, 200)
     self.image.fill((5, 5, 5, 10), special_flags=pygame.BLEND_RGB_ADD)
     self.sheet = SHEET
     self.rect = self.image.get_rect()
     self.weapon = Weapon(Bullet)
     self.direction = 'stop'
     self.death_animation_timer = Timer(60)
     self.destruction_sound = pygame.mixer.Sound('assets/sounds/enemy_hit.ogg')
     self.current_sprite_index = 0
     self.dying = False
     self.post_death_timer = Timer(500)
     self.health_bar = PlayerHealthBar(self.hp)
     self.regen_cooldown_timer = Timer(50*100)
     self.regen_timer = Timer(500)
Пример #4
0
 def __init__(self):
     super().__init__(PLAYER, (130, 200, 120))
     self.mask = pygame.mask.from_surface(self.image)
     self.rect = self.image.get_rect()
     self.rect.x = 700 / 2 - 40
     self.rect.y = 330
     # self.rect.centerx = self.rect.width / 2
     self.speed = 4
     self.weapon = Weapon(Bullet)
     self.pos = (350, 350)
     self.direction = 'stop'
Пример #5
0
def build_long_sword():
    _long_sword = Item(
        uid="long_sword",
        name="Longsword",
        description="A longsword.",
        display=Display(Colors.DARK_GRAY, Colors.BLACK_COLOR, "!"),
    )
    _long_sword.register_component(data.python_templates.material.Iron.copy())
    _long_sword.register_component(Stats(health=1, size=Size.Medium))
    _long_sword.register_component(
        Weapon(weapon_category=item_enums.WeaponCategory.Martial,
               weapon_type=item_enums.WeaponType.Melee,
               size=Size.Medium,
               melee_damage_type=DamageType.Slash,
               damage_dice=DiceStack(1, Dice(8))))

    return _long_sword
Пример #6
0
def main():
    screen_width = 80
    screen_height = 50

    bar_width = 20
    panel_height = 7
    panel_y = screen_height - panel_height

    message_x = bar_width + 2
    message_width = screen_width - bar_width - 2
    message_height = panel_height - 1

    map_width = 80
    map_height = 43

    fov_algorithm = 'BASIC'
    fov_light_walls = True
    fov_radius = 10

    colors = {
        'dark_wall': (0, 0, 100),
        'dark_ground': (50, 50, 150),
        'light_wall': (130, 110, 50),
        'light_ground': (200, 180, 50),
        'white': (255, 255, 255),
        'black': (0, 0, 0),
        'light red': (255, 100, 100),
        'red': (255, 0, 0),
        'yellow': (255, 255, 0),
        'orange': (255, 127, 0),
        'green': (
            0,
            255,
            0,
        ),
        'light_red': (255, 114, 114),
        'darker_red': (127, 0, 0),
        'highlight': (199, 234, 70)
    }

    mech_component = Mech(hp=30, peak_momentum=6)
    weapon_component = Weapon(name="Laser",
                              damage=5,
                              min_targets=0,
                              max_targets=5,
                              color=colors.get('green'),
                              range=10)
    player = Entity(int(screen_width / 2),
                    int(screen_height / 2),
                    '@',
                    colors.get('white'),
                    "player",
                    mech=mech_component,
                    weapon=weapon_component)
    npc = Entity(int(screen_width / 2 - 5), int(screen_height / 2), '@',
                 colors.get('yellow'), "NPC")
    cursor_component = Cursor()
    cursor = Entity(
        -1, -1, ' ', colors.get('red'), "cursor", cursor=cursor_component
    )  # The ' ' isn't actually "nothing". To have nothing, I would have to mess with a render order.
    entities = [npc, player, cursor]

    tdl.set_font('arial10x10.png', greyscale=True, altLayout=True)

    root_console = tdl.init(screen_width, screen_height, title='MVP v0.0')
    con = tdl.Console(screen_width, screen_height)
    panel = tdl.Console(screen_width, panel_height)

    game_map = GameMap(map_width, map_height)
    make_map(game_map)

    message_log = MessageLog(message_x, message_width, message_height)

    mouse_coordinates = (0, 0)

    game_state = GameStates.PLAYER_TURN
    previous_game_state = game_state
    turn_state = TurnStates.UPKEEP_PHASE

    fov_recompute = True

    while not tdl.event.is_window_closed():
        if fov_recompute:
            game_map.compute_fov(player.x,
                                 player.y,
                                 fov=fov_algorithm,
                                 radius=fov_radius,
                                 light_walls=fov_light_walls)

        render_all(con, panel, entities, game_map, fov_recompute, root_console,
                   message_log, screen_width, screen_height, bar_width,
                   panel_height, panel_y, mouse_coordinates, colors)

        tdl.flush()

        clear_all(con, entities)

        for event in tdl.event.get():
            if event.type == 'KEYDOWN':
                user_input = event
                break
            elif event.type == 'MOUSEMOTION':
                mouse_coordinates = event.cell
        else:
            user_input = None

        fov_recompute = False

        action = handle_keys(user_input, game_state)
        impulse = None  # This is to avoid logic problems.
        change_game_state = None  # This is to avoid logic problems.

        move = action.get('move')  # Attempt to move.
        impulse = action.get('impulse')  # Adjust mech impulse.
        next_turn_phase = action.get(
            'next turn phase')  # Move to the next phase.
        change_game_state = action.get(
            'change game state')  # Go to different game_state
        select = action.get(
            'select')  # A target has been selected via keyboard.
        exit = action.get('exit')  # Exit whatever screen is open.
        fullscreen = action.get('fullscreen')  # Set game to full screen.

        if exit:
            if game_state == GameStates.TARGETING:
                # Turn off cursor
                cursor.char = ' '
                cursor.x = -1
                cursor.y = -1

                fov_recompute = True
                game_state = previous_game_state

            else:
                return True

        if fullscreen:
            tdl.set_fullscreen(not tdl.get_fullscreen())

        if game_state == GameStates.PLAYER_TURN:
            # See game_states.py for the turn structure.
            # Turns order is reversed so ensure that the loop runs once for each
            if turn_state == TurnStates.POST_ATTACK_PHASE:
                # Reset map flags and remove targets.
                reset_flags(game_map)
                for x, y in player.weapon.targets:
                    erase_cell(con, x, y)
                turn_state = TurnStates.UPKEEP_PHASE
                game_state = GameStates.ENEMY_TURN

            if turn_state == TurnStates.ATTACK_PHASE:
                if change_game_state == GameStates.TARGETING:
                    # Turn on cursor.
                    cursor.char = 'X'
                    # If there were no previous targets, start on the player.
                    if len(player.weapon.targets) == 0:
                        cursor.x = player.x
                        cursor.y = player.y
                    else:
                        cursor.x, cursor.y = player.weapon.targets[-1]

                    fov_recompute = True
                    previous_game_state = game_state
                    game_state = GameStates.TARGETING

                if next_turn_phase:
                    turn_state = TurnStates.POST_ATTACK_PHASE

            if turn_state == TurnStates.PRE_ATTACK_PHASE:
                message_log.add_message(
                    Message('Begin ATTACK PHASE.', colors.get('white')))
                message_log.add_message(
                    Message(
                        'Press f to target. Press ESC to stop targeting. Enter to change phase.',
                        colors.get('orange')))
                fov_recompute = True

                turn_state = TurnStates.ATTACK_PHASE

            if turn_state == TurnStates.POST_MOVEMENT_PHASE:
                reset_flags(game_map)
                player.reset(
                )  # Reset the mech for the next turn. ### Move this to the post-attack phase
                fov_recompute = True

                turn_state = TurnStates.PRE_ATTACK_PHASE

            if turn_state == TurnStates.MOVEMENT_PHASE:
                if move:
                    dx, dy = move
                    if game_map.walkable[player.x + dx, player.y + dy]:
                        player.move(dx, dy)

                        fov_recompute = True

                if next_turn_phase and player.mech.has_spent_minimum_momentum(
                ):
                    turn_state = TurnStates.POST_MOVEMENT_PHASE
                elif next_turn_phase and not player.mech.has_spent_minimum_momentum(
                ):
                    message_log.add_message(
                        Message('Must spend more momentum.',
                                colors.get('red')))

            if turn_state == TurnStates.PRE_MOVEMENT_PHASE:
                if impulse is not None:
                    player.mech.impulse = impulse
                    turn_state = TurnStates.MOVEMENT_PHASE
                    message_log.add_message(
                        Message('Impulse set to {0}.'.format(impulse),
                                colors.get('orange')))
                    fov_recompute = True
                    highlight_legal_moves(player, game_map)

            if turn_state == TurnStates.UPKEEP_PHASE and game_state == GameStates.PLAYER_TURN:  # This is added to avoid starting the Upkeep Phase when the turn just ended.
                message_log.add_message(
                    Message('Begin PLAYER TURN.', colors.get('white')))
                message_log.add_message(
                    Message('Begin MOVEMENT PHASE.', colors.get('white')))
                message_log.add_message(
                    Message('Choose impulse. PAGEUP, PAGEDOWN or HOME.',
                            colors.get('orange')))
                turn_state = TurnStates.PRE_MOVEMENT_PHASE
                fov_recompute = True

        if game_state == GameStates.ENEMY_TURN:
            message_log.add_message(
                Message('Begin ENEMY TURN.', colors.get('white')))
            fov_recompute = True

            game_state = GameStates.PLAYER_TURN

        if game_state == GameStates.TARGETING:
            if move:
                dx, dy = move
                # Ensure the first target is in firing range.
                if len(player.weapon.targets) == 0:
                    if player.distance(cursor.x + dx,
                                       cursor.y + dy) <= player.weapon.range:
                        cursor.fly(dx, dy)
                        fov_recompute = True
                    else:
                        message_log.add_message(
                            Message('Out of range.', colors.get('red')))
                # Ensure that the next targets are adjacent to the previous target
                elif len(player.weapon.targets) > 0:
                    tar_x, tar_y = player.weapon.targets[
                        -1]  # Get the most recent target added.
                    if abs(tar_x -
                           (cursor.x + dx)) + abs(tar_y -
                                                  (cursor.y + dy)) <= 1:
                        cursor.fly(dx, dy)
                        fov_recompute = True
                    else:
                        message_log.add_message(
                            Message('Invalid target.', colors.get('red')))

            if select:
                if len(player.weapon.targets) < player.weapon.max_targets:
                    if set_targeted(
                            game_map, cursor.x, cursor.y
                    ):  # At the moment, this always returns True. In the future, this may change.
                        fov_recompute = True
                        player.weapon.targets.append((cursor.x, cursor.y))
                else:
                    message_log.add_message(
                        Message('Targeting failed.', colors.get('red')))
Пример #7
0
class Player(Entity):
    """ represents the Player. """

    def __init__(self, *groups):
        SHEET = sprite_sheet((100,100), 'assets/ship-death.png')
        super().__init__(pygame.transform.scale(PLAYER, (125, 125)), (200, 800, 120), (WIDTH/2, HEIGHT-50), groups)
        self.hp = 6
        self.mask = pygame.mask.from_surface(self.image, 200)
        self.image.fill((5, 5, 5, 10), special_flags=pygame.BLEND_RGB_ADD)
        self.sheet = SHEET
        self.rect = self.image.get_rect()
        self.weapon = Weapon(Bullet)
        self.direction = 'stop'
        self.death_animation_timer = Timer(60)
        self.destruction_sound = pygame.mixer.Sound('assets/sounds/enemy_hit.ogg')
        self.current_sprite_index = 0
        self.dying = False
        self.post_death_timer = Timer(500)
        self.health_bar = PlayerHealthBar(self.hp)
        self.regen_cooldown_timer = Timer(50*100)
        self.regen_timer = Timer(500)

    def get_event(self, event, **state):
        if event.type == pygame.MOUSEBUTTONDOWN:
            can_fire = self.weapon.ammo > 0 and not self.dying
            if can_fire and event.button == 1:
                self.weapon.begin_fire(self.rect.center)
                state['shots_fired'] += 1

            elif can_fire and event.button == 3:
                for i in range(3):
                    bullet = Chain_Lightning(self.rect.center, self.weapon.bullets)
                    bullet.find_next_target(state['enemy_list'].sprites() + state['boss_list'].sprites())
                    state['shots_fired'] += 1
                    self.weapon.ammo -= 1

            elif event.button == 2:
                self.weapon.ammo += 30

            elif not can_fire:
                print('you loose')
                pygame.mixer.music.fadeout(1000)
                # message_display('YOU LOOSE OUT OF AMMO!!!', WHITE, pygame.display.get_surface(), (700, 400))
                signaly.emit('GAME_OVER')

                # self.done = True

        elif event.type == pygame.MOUSEBUTTONUP:
            if event.button == 1:
                self.weapon.cease_fire()

        elif event.type == pygame.KEYDOWN:
            if event.key == pygame.K_a:
                self.move('left')

            if event.key == pygame.K_d:
                self.move('right')

        elif event.type == pygame.KEYUP:
            if event.key == pygame.K_a:
                self.move('stop')

            if event.key == pygame.K_d:
                self.move('stop')

    def collision_detected(self, hp_delta):
        self.hp -= hp_delta

        self.regen_timer.reset()
        self.regen_cooldown_timer.start()

    def handle_regen(self):
        if self.regen_cooldown_timer.is_finished():
            self.regen_timer.start_repeating()
            signaly.emit('PLAYER_MSSG', 'REGEN!')

        if self.regen_timer.is_finished():
            crit_roll = randint(1, 101)
            will_crit = crit_roll > 96
            if will_crit:
                amt = 0.15*10
            else:
                amt = 0.15
            if self.hp < self.health_bar.starting_hp and not self.dying:
                self.hp += amt
                signaly.emit('PLAYER_MSSG', amt)

        if self.hp == self.health_bar.starting_hp:
            # self.hp = self.health_bar.starting_hp
            self.regen_timer.reset()

    def explode(self):
        if not self.dying:
            self.destruction_sound.play()
            self.dying = True
            self.max_speed = 45
            self.death_animation_timer.start_repeating()
            self.weapon.cease_fire()
            self.image = pygame.transform.scale(self.sheet[self.current_sprite_index], (125, 125))
        
    def sprite_animation(self):
        cap = 11

        if (self.death_animation_timer.is_finished()):
            self.current_sprite_index+=1

            if self.current_sprite_index == cap-1:
                self.post_death_timer.start()
            elif self.current_sprite_index >= cap:
                self.current_sprite_index = cap
                

            self.image = pygame.transform.scale(self.sheet[self.current_sprite_index], (125, 125))

    def draw(self, screen):
        """ draw player specifically """
        mouse_pos = pygame.mouse.get_pos()
        des = self.pos - vec(mouse_pos)
        angle = angle_from_vec(des)
        img, rect = self.rot_center(self.image, self.rect, angle)
        rect.center = self.rect.center

        screen.blit(img, rect)

    def move(self, direction):
        self.direction = direction

    def update(self, dt):
        """ update the player's position to the mouse x position """
        self.handle_regen()
        self.sprite_animation()
        self.weapon.bullets.update(dt)
        self.health_bar.update(self.hp)


        if self.post_death_timer.is_finished():
            self.kill()
            signaly.remove_subscriber('PLAYER_MSSG')
            signaly.emit('GAME_OVER')

        if self.direction == 'left':
            self.acc = vec(-1, 0).normalize() * self.max_speed
        elif self.direction == 'right':
            self.acc = vec(701, 0).normalize() * self.max_speed
        elif self.direction == 'stop':
            self.acc = vec(0 ,0)

        # give edges of screen a little bounce when hit
        if self.pos[0] >= (WIDTH -30):
            self.pos[0] = WIDTH -30
            self.acc = vec(-1, 0).normalize() * 2000
        elif self.pos[0] <= 30:
            self.pos[0] = 30
            self.acc = vec(701, 0).normalize() * 2000

        super().update(dt)