Beispiel #1
0
def create_wall(*args, **kwargs):
    '''
    recieves 3 kwargs: the_game, target_x, target_y 
    '''
    the_game = kwargs.get('the_game')
    target_x = kwargs.get('target_x')
    target_y = kwargs.get('target_y')

    entities = the_game.entities
    game_map = the_game.game_map
    fov_map = the_game.fov_map
    fov_recompute = the_game.fov_recompute


    results = []

    if get_blocking_entity(entities, target_x, target_y):
        msg = Message('It\'s too heavy for you to create a wall here', tcod.yellow)
        results.append({'acted': False, 'message':msg})
    else:
        msg = Message('CRUNCH! A wall is created', tcod.light_green)
        results.append({'acted': True, 'message': msg})
        game_map.tiles[target_x][target_y].create_wall()
        fov_map = set_tile_fov(target_x, target_y, game_map, fov_map)
        fov_recompute = True #do i need to do this here??

    return results
def get_item_parameters():

    parameters = {
        'heal': {
            'amount': 4
        },
        'lightning': {
            'damage': 20,
            'maximum_range': 5
        },
        'fireball': {
            'targeting':
            True,
            'damage':
            12,
            'radius':
            3,
            'targeting_message':
            Message(
                'Left-click a tile to cast a 3x3 fireball, or right-click to cancel',
                tcod.cyan)
        },
        'confusion': {
            'targeting':
            True,
            'targeting_message':
            Message(
                'Left-click a Creature to cast Confusion, or right-click to cancel',
                tcod.cyan)
        },
    }

    return parameters
def cast_fireball(*args, **kwargs):
    entities = kwargs.get('entities')
    fov_map = kwargs.get('fov_map')
    damage = kwargs.get('damage')
    radius = kwargs.get('radius')
    target_x = kwargs.get('target_x')
    target_y = kwargs.get('target_y')

    results = []

    if not tcod.map_is_in_fov(fov_map, target_x, target_y):
        results.append({
            'consumed': False,
            'message': Message('Out of range!', tcod.yellow)
        })
        return results

    results.append({
        'consumed':
        True,
        'message':
        Message(f'BOOM, burns a {radius}x{radius} area.', tcod.orange)
    })

    for entity in entities:
        if entity.distance(target_x, target_y) <= radius and entity.actor:
            results.append({
                'message':
                Message(f'The {entity.name} is burned for {damage} hitpoints',
                        tcod.red)
            })
            results.extend(entity.actor.take_dmg(damage))

    return results
Beispiel #4
0
def break_wall(*args, **kwargs):
    '''
    recieves 3 kwargs: the_game, target_x, target_y 
    '''
    the_game = kwargs.get('the_game')
    target_x = kwargs.get('target_x')
    target_y = kwargs.get('target_y')

    entities = the_game.entities
    game_map = the_game.game_map
    fov_map = the_game.fov_map
    fov_recompute = the_game.fov_recompute


    results = []

    wall = the_game.game_map.tiles[target_x][target_y].blocked
    if not wall:#there is a wall here
        msg = Message('There is no wall to break here', tcod.yellow)
        results.append({'acted': False, 'message':msg})
    elif wall:
        msg = Message('CRUNCH! A wall is broken', tcod.light_green)
        results.append({'acted': True, 'message': msg})
        game_map.tiles[target_x][target_y].destroy_wall()
        fov_map = set_tile_fov(target_x, target_y, game_map, fov_map)
        fov_recompute = True #do i need to do this here??

    return results
Beispiel #5
0
def teleport(*args, **kwargs):
    the_game = kwargs.get('the_game')
    target_x = kwargs.get('target_x')
    target_y = kwargs.get('target_y')

    results = []

    move = (target_x - the_game.player.x, target_y - the_game.player.y)
    move_result = move_action(the_game, move)
    if move_result.get('fail'):
        results.append({'message': Message('Cant move here!')})
    else:
        results.append({'message': Message('ZOOM, you teleported')})

    return results
Beispiel #6
0
def move_action(the_game, move):
    '''
    This func needs the absolute distance it will move in (x, y) parameters
    '''
    player_turn_results = []
    dx, dy = move
    goto_x = the_game.player.x + dx
    goto_y = the_game.player.y + dy

    #Check if tile is blocked, atk if able to, walk if not
    try:
        if not the_game.game_map.is_blocked(goto_x, goto_y):
            target = get_blocking_entity(the_game.entities, goto_x, goto_y)
            if target:
                attack_results = the_game.player.actor.attack_target(target)
                player_turn_results.extend(attack_results)
            else:
                the_game.player.move(dx, dy)
                the_game.fov_recompute = True

            the_game.game_state = GameStates.ENEMY_TURN
        else:
            return {'fail': True}
    except IndexError:
        msg = {
            'message':
            Message('You cannot move there, it is forbbiden', tcod.orange)
        }
        player_turn_results.append(msg)
    #This basically processes all msgs
    process_player_turn_results(the_game, player_turn_results)

    return {}
    def use(self, item_entity, **kwargs):
        results = []

        item_comp = item_entity.item

        if item_comp.use_function is None:
            results.append({
                'message':
                Message(f'The {item_entity.name} cannot be used', tcod.yellow)
            })
        else:
            if item_comp.targeting and not (kwargs.get('target_x')
                                            or kwargs.get('target_y')):
                results.append({'targeting': item_entity})
            else:
                kwargs = {**item_comp.function_kwargs, **kwargs}
                item_use_results = item_comp.use_function(self.owner, **kwargs)

                for item_use_result in item_use_results:
                    if item_use_result.get('consumed'):
                        self.remove_item(item_entity)

                results.extend(item_use_results)

        return results
Beispiel #8
0
    def learn_skill(self, skill):
        results = []

        if skill in self.skills:
            #I think I don't need this skill_learned part
            results.append({
                'skill_learned':
                False,
                'message':
                Message('You have already learned this skill.', tcod.yellow)
            })
        else:
            results.append({
                'skill_learned': True,
                'message': Message(f'You have learned {skill.name}')
            })
            self.skills.append(skill)

        return results
def cast_confuse(*args, **kwargs):
    entities = kwargs.get('entities')
    fov_map = kwargs.get('fov_map')
    target_x = kwargs.get('target_x')
    target_y = kwargs.get('target_y')

    results = []

    if not tcod.map_is_in_fov(fov_map, target_x, target_y):
        results.append({
            'consumed': False,
            'message': Message('Out of range!', tcod.yellow)
        })
        return results

    for entity in entities:
        if entity.x == target_x and entity.y == target_y and entity.ai:
            confused_ai = ConfusedMonster(entity.ai, 5)

            confused_ai.owner = entity
            entity.ai = confused_ai

            results.append({
                'consumed':
                True,
                'message':
                Message(f'{entity.name} is confused', tcod.light_green)
            })

            break

    else:
        results.append({
            'consumed':
            False,
            'message':
            Message('There is no targetable creature in this tile',
                    tcod.yellow)
        })

    return results
def cast_lightning(*args, **kwargs):
    caster = args[0]
    entities = kwargs.get('entities')
    fov_map = kwargs.get('fov_map')
    damage = kwargs.get('damage')
    maximum_range = kwargs.get('maximum_range')

    results = []

    target = None
    closest_distance = maximum_range + 1

    for entity in entities:
        if entity.actor and entity != caster and tcod.map_is_in_fov(
                fov_map, entity.x, entity.y):
            distance = caster.distance_to(entity)

            if distance < closest_distance:
                target = entity
                clostest_distance = distance

    if target:
        results.append({
            'consumed':
            True,
            'target':
            target,
            'message':
            Message(
                f'Pikachu use THUNDERBOLT! Deals {damage} to {target.name}',
                tcod.blue)
        })
        results.extend(target.actor.take_dmg(damage))
    else:
        results.append({
            'consumed': False,
            'target': None,
            'message': Message('No enemies in range.', tcod.red)
        })

    return results
Beispiel #11
0
def move_wall(*args, **kwargs):
    results = []

    the_game = kwargs.get('the_game')
    target_x = kwargs.get('target_x')
    target_y = kwargs.get('target_y')
    new_target_x = kwargs.get('new_target_x')
    new_target_y = kwargs.get('new_target_y')

    wall_to_be_moved = the_game.game_map.tiles[target_x][target_y].blocked
    tile_to_move_wall = the_game.game_map.tiles[new_target_x][new_target_y].blocked

    if not wall_to_be_moved or new_target_x is None or tile_to_move_wall:
        msg = Message('There is no wall to break here', tcod.yellow)
        results.append({'acted': False, 'message':msg})
    elif wall_to_be_moved:
        break_wall(the_game=the_game, target_x=target_x, target_y=target_y)
        create_wall(the_game=the_game, target_x=new_target_x, target_y=new_target_y)
        results.append({'acted': True, 'message': Message('Success', tcod.cyan)})

    return results
    def add_item(self, item):
        results = []

        if len(self.items) >= self.capacity:
            results.append({
                'item_added':
                None,
                'message':
                Message('You cannot carry any more, your inventory is full',
                        tcod.yellow)
            })
        else:
            results.append({
                'item_added':
                item,
                'message':
                Message(f'You pick up the {item.name}', tcod.blue)
            })
            self.items.append(item)

            return results
Beispiel #13
0
    def __init__(self):
        create_wall_comp = Skill(use_function=create_wall,
                                 targeting_skill=True,
                                 targeting_type='single',
                                 targeting_message=Message(
                                     'Select tile to make wall', tcod.cyan))
        create_wall_fact = Fact('Create Wall',
                                'Self explanatory',
                                skill=create_wall_comp)

        break_wall_comp = Skill(use_function=break_wall,
                                targeting_skill=True,
                                targeting_type='single',
                                targeting_message=Message(
                                    'Select tile to destoy wall', tcod.cyan))
        break_wall_fact = Fact('Break Wall',
                               'Self explanatory',
                               skill=break_wall_comp)

        move_wall_comp = Skill(use_function=move_wall,
                               targeting_skill=True,
                               targeting_type='multi',
                               targeting_message=Message(
                                   'Select tile to move wall', tcod.cyan))
        move_wall_fact = Fact('Move Wall',
                              'Self explanatory',
                              skill=move_wall_comp)

        teleport_comp = Skill(use_function=teleport,
                              targeting_skill=True,
                              targeting_type='single',
                              targeting_message=Message(
                                  'Select tile to teleport', tcod.cyan))
        teleport_fact = Fact('Teleport',
                             'Self explanatory',
                             skill=teleport_comp)

        self.skills = [
            create_wall_fact, break_wall_fact, move_wall_fact, teleport_fact
        ]
Beispiel #14
0
def pickup_action(the_game):
    player_turn_results = []
    for entity in the_game.entities:
        if entity.item and entity.x == the_game.player.x and entity.y == the_game.player.y:
            pickup_results = the_game.player.inventory.add_item(entity)
            player_turn_results.extend(pickup_results)

            break
    else:
        the_game.msg_log.add_msg(
            Message('There is nothing here to pickup.', tcod.yellow))

    process_player_turn_results(the_game, player_turn_results)
Beispiel #15
0
def kill_creature(creature):
    death_message = Message(f'{creature.name.capitalize()} is dead!',
                            tcod.orange)

    creature.char = '%'
    creature.color = tcod.dark_red
    creature.blocks = False

    creature.actor = None
    creature.ai = None
    creature.name = 'remains of ' + creature.name
    creature.render_order = RenderOrder.CORPSE

    return death_message
def heal(*args, **kwargs):
    entity = args[0]
    amount = kwargs.get('amount')

    results = []

    if entity.actor.hp == entity.actor.max_hp:
        results.append({
            'consumed':
            False,
            'message':
            Message('You are already at full health', tcod.yellow)
        })
    else:
        entity.actor.heal(amount)
        results.append({
            'consumed':
            True,
            'message':
            Message('Your wounds are healing.', tcod.green)
        })

    return results
Beispiel #17
0
def fire_action(the_game):
    '''
    This is repeating code, create a better attack func that covers both move and fire actions
    Maybe create a range_attack for it to be used on entity.actor??
    '''
    player_turn_results = []
    entities_in_fov = get_entities_in_fov(the_game.fov_map, the_game.entities)
    if entities_in_fov:

        #GOD MODE FIRING ALL TARGETS ON SIGHT
        if the_game.god.tog:
            for target in entities_in_fov:
                attack_results = the_game.player.actor.attack_target(target)
                player_turn_results.extend(attack_results)
            process_player_turn_results(the_game, player_turn_results)

        #NORMAL MODE FIRING 1 TARGET W/ MOUSE CLICK
        else:
            the_game.game_state = GameStates.TARGETING_MODE
            while the_game.game_state == GameStates.TARGETING_MODE:

                tcod.sys_check_for_event(
                    tcod.EVENT_KEY_PRESS | tcod.EVENT_MOUSE, the_game.key,
                    the_game.mouse)
                entities_under_mouse = get_entities_under_mouse(
                    the_game.god, the_game.mouse, the_game.entities,
                    the_game.fov_map)

                exit = handle_keys(the_game.key,
                                   the_game.game_state).get('exit')
                if the_game.mouse.lbutton_pressed or exit:
                    if exit:
                        the_game.game_state = GameStates.PLAYERS_TURN
                        return False
                    else:
                        the_game.game_state = GameStates.ENEMY_TURN
                        for entity in entities_under_mouse:
                            if entity.actor:
                                target = entity
                                attack_results = the_game.player.actor.attack_target(
                                    target)
                                player_turn_results.extend(attack_results)

            process_player_turn_results(the_game, player_turn_results)

    else:
        message = Message("There are no targets in range", tcod.red)
        the_game.msg_log.add_msg(message)

    the_game.game_state = GameStates.ENEMY_TURN
Beispiel #18
0
    def attack_target(self, target):
        results = []

        dmg = self.atk_stat - target.actor.def_stat

        name = self.owner.name.capitalize()

        if dmg > 0:
            results.append({
                'message':
                Message(
                    f'{name} attacks {target.name} for {str(dmg)} hit points.',
                    tcod.white)
            })
            results.extend(target.actor.take_dmg(dmg))
        else:
            results.append({
                'message':
                Message(f'{name} attacks {target.name} but deals no damage.',
                        tcod.white)
            })

        return results
    def drop_item(self, item):
        results = []

        item.x = self.owner.x
        item.y = self.owner.y

        self.remove_item(item)
        results.append({
            'item_dropped':
            item,
            'message':
            Message(f'You dropped {item.name}.', tcod.yellow)
        })

        return results
Beispiel #20
0
    def take_turn(self, target, fov_map, game_map, entities):
        results = []

        if self.turns_left > 0:
            random_x = self.owner.x + randint(0, 2) - 1
            random_y = self.owner.y + randint(0, 2) - 1

            if random_x != self.owner.x and random_y != self.owner.y:
                self.owner.move_towards(random_x, random_y, game_map, entities)

            self.turns_left -= 1

        else:
            self.owner.ai = self.prev_ai
            results.append({
                'message':
                Message(f'The {self.owner.name} is no longer confused',
                        tcod.red)
            })

        return results
Beispiel #21
0
def create_wall_action(the_game):
    player_turn_results = []
    the_game.game_state = GameStates.TARGETING_MODE
    '''
    ############## NOTE ##############
    THIS WHILE LOOP WILL GENERATE PROBLEMS IN THE FUTURE, specifically with rendering animations(if i so wish to implement it)
    Need to find a better solution, maybe do targeting function first, and then after u get the direction u activate break_wall()
    '''
    while the_game.game_state == GameStates.TARGETING_MODE:

        tcod.sys_check_for_event(tcod.EVENT_KEY_PRESS, the_game.key,
                                 the_game.mouse)
        x, y = handle_keys(the_game.key,
                           the_game.game_state).get('move', (None, None))
        if x is not None:
            the_game.game_state = GameStates.ENEMY_TURN
        if handle_keys(the_game.key, the_game.game_state).get('exit'):
            the_game.game_state = GameStates.PLAYERS_TURN
            return False

    dx, dy = the_game.player.x + x, the_game.player.y + y
    if get_blocking_entity(the_game.entities, dx, dy):
        msg = {
            'message':
            Message(
                "It's too heavy for you to create a wall here, there is someone there!",
                tcod.orange)
        }
        player_turn_results.append(msg)
        process_player_turn_results(the_game, player_turn_results)
        return None

    the_game.game_map.tiles[dx][dy].create_wall()
    the_game.fov_map = set_tile_fov(dx, dy, the_game.game_map,
                                    the_game.fov_map)
    the_game.fov_recompute = True
Beispiel #22
0
    def use_skill(self, skill_fact, **kwargs):
        results = []

        skill_comp = skill_fact.skill

        if skill_comp.use_function is None:
            results.append(
                {'message': Message(f'You cant use this skill', tcod.yellow)})

        else:
            if skill_comp.targeting_skill and not (kwargs.get('target_x')
                                                   or kwargs.get('target_y')):
                results.append({'targeting_skill': skill_fact})
            else:
                kwargs = {**skill_comp.function_kwargs, **kwargs}
                skill_use_results = skill_comp.use_function(**kwargs)

                #In inventory there is an extra step that is consuming the item
                #Not really needed here, but maybe it would be nice to check if
                #player has enough stamina/energy to do so...

                results.extend(skill_use_results)

        return results
Beispiel #23
0
def kill_player(player):
    player.char = '%'
    player.color = tcod.dark_red

    return Message('You died!', tcod.red), GameStates.PLAYER_DEAD
Beispiel #24
0
def process_player_turn_results(the_game, player_turn_results):
    for player_result in player_turn_results:
        message = player_result.get('message')
        dead_entity = player_result.get('dead')
        item_added = player_result.get('item_added')
        item_consumed = player_result.get('consumed')
        item_dropped = player_result.get('item_dropped')

        targeting = player_result.get('targeting')
        targeting_cancelled = player_result.get('targeting_cancelled')

        targeting_skill = player_result.get('targeting_skill')

        acted = player_result.get('acted')

        if message:
            the_game.msg_log.add_msg(message)

        if dead_entity:
            if dead_entity == the_game.player:
                message, the_game.game_state = kill_player(dead_entity)
            else:
                message = kill_creature(dead_entity)

            the_game.msg_log.add_msg(message)

        if item_added:
            the_game.entities.remove(item_added)

            the_game.game_state = GameStates.ENEMY_TURN

        if item_consumed:
            the_game.game_state = GameStates.ENEMY_TURN

        if item_dropped:
            the_game.entities.append(item_dropped)

            the_game.game_state = GameStates.ENEMY_TURN

        if targeting:
            the_game.prev_game_state = GameStates.PLAYERS_TURN
            the_game.game_state = GameStates.TARGETING_MODE

            the_game.targeting_item = targeting

            the_game.msg_log.add_msg(
                the_game.targeting_item.item.targeting_message)

        if targeting_skill:
            the_game.prev_game_state = GameStates.PLAYERS_TURN
            the_game.game_state = GameStates.TARGETING_MODE

            the_game.targeting_skill = targeting_skill

            the_game.msg_log.add_msg(
                the_game.targeting_skill.skill.targeting_message)

        if targeting_cancelled:
            the_game.game_state = the_game.prev_game_state

            the_game.msg_log.add_msg(Message('Targeting cancelled'))

        if acted:
            the_game.game_state = GameStates.ENEMY_TURN