Beispiel #1
0
    def sample_success(self, *attrs: AttributeType) -> bool:
        """Sample success probability accounting for player skill modifiers."""
        player = get_player()
        modifier = sum(player.status.get_attribute(a)
                       for a in attrs)  # type: ignore

        return random.random() < (self - modifier).success_prob
    def __init__(self,
                 enemies: Sequence[Character] = None,
                 win_resolution: Resolution = None,
                 loss_resolution: Resolution = None,
                 background_image: str = None) -> None:
        if enemies is None:
            enemies = (build_character(data=CharacterTypes.DRONE.data), )
        self._enemies: Tuple[Character, ...] = tuple(enemies)
        super().__init__()
        self._player = get_player()

        self._combat_logic = CombatLogic((self._player, ) + self._enemies)

        self._win_resolution = win_resolution
        self._loss_resolution = loss_resolution

        self._selected_char: Optional[Character] = None

        self._update_layout()

        # Rect positions
        if background_image is None:
            self._background_image = BackgroundImages.CITY.path
        else:
            self._background_image = background_image

        # Animation data
        self._animation_progress: Optional[float] = None
        self._first_turn = True
Beispiel #3
0
def test_combat_scene_to_decision_scene():
    game = Game()  # noqa: F841
    view_manager = ViewManager()  # noqa: F841

    # dummy decision scene to which will will transision
    def dummy_scene():
        return DecisionScene('dummy scene for testing purposes', {})

    # combat scene with two 1 health enemies
    enemies = [_one_health_enemy() for _ in range(2)]
    scene = combat_scene.CombatScene(
        enemies, win_resolution=BasicResolution(dummy_scene))
    event_utils.post_scene_change(scene)

    assert isinstance(_get_active_controller(), CombatSceneController)

    # Start with player holding nothing
    player = get_player()
    [player.chassis.remove_mod(mod) for mod in player.chassis.all_mods()]
    assert len(list(player.chassis.all_mods())) == 1  # Base mod only

    # give player ability to fire laser

    shoot_laser = direct_damage(1,
                                label='laser',
                                time_to_resolve=0,
                                cpu_slots=0)
    laser_mod = build_mod(subroutines_granted=shoot_laser,
                          valid_slots=tuple(s for s in SlotTypes
                                            if s != SlotTypes.STORAGE))
    assert player.chassis.can_store(laser_mod)
    player.chassis.attempt_store(laser_mod)
    assert laser_mod in player.chassis.all_active_mods()

    # Kill each enemy
    for enemy in enemies:
        # click enemy
        click_on_char(enemy, scene.layout)

        assert enemy is selected_char(scene.layout)

        # select the fire laser ability
        laser_ind = [
            ind for ind, move in enumerate(scene.available_moves())
            if move.subroutine is shoot_laser
        ][0]
        event_utils.simulate_key_press(str(laser_ind + 1))
        assert is_dead(enemy)

    # check that scene has ended
    assert scene.is_resolved()

    # update the scene by waiting a tick, confirm that we've switched to a
    # Decision scene
    EventManager.post(BasicEvents.TICK)
    assert isinstance(_get_active_controller(), DecisionSceneController)
Beispiel #4
0
def increment_attribute(attribute: AttributeType, amount: int,
                        target: Stateful = None) -> None:
    """Increment an attribute of some Stateful object.

    Args:
        attribute: Attribute to increment.
        amount: Amount.
        target: Stateful target. By default this is the player character.
    """
    target = target if target is not None else get_player()
    target.status.increment_attribute(attribute, amount)
Beispiel #5
0
def _slot_header_position(slot: SlotTypes,
                          scene: InventoryScene) -> Tuple[int, int]:
    chassis = get_player().chassis

    capacity = chassis.slot_capacities[slot]
    mods = chassis.mods_in_slot(slot)
    header = SlotHeaderInfo(slot, capacity, mods)

    rects = scene.layout.get_rects(header)
    assert len(rects) == 1

    return rects[0].center
Beispiel #6
0
def second_scene() -> DecisionScene:
    player = get_player()
    main_text = ('Player HP: {}. Player Max HP: {}.'.format(
        player.status.get_attribute(Attributes.HEALTH),
        player.status.get_attribute(Attributes.MAX_HEALTH)))

    options = {
        '1':
        DecisionOption('Gain 1 HP', second_scene,
                       partial(increment_attribute, Attributes.HEALTH, 1)),
        '2':
        DecisionOption('Lose 1 HP', second_scene,
                       partial(increment_attribute, Attributes.HEALTH, -1))
    }
    return DecisionScene(main_text, options)
Beispiel #7
0
    def notify(self, event: EventType) -> None:

        # toggle between settings scene and game scene
        if event == BasicEvents.SETTINGS:
            new_scene: Optional[Scene] = None
            # go to temp scene
            if self._current_scene is self._current_game_scene:
                new_scene = SettingsScene()
            # go back to game scene
            elif isinstance(self._current_scene, SettingsScene):
                new_scene = self._current_game_scene

            if new_scene is not None:
                post_scene_change(new_scene)

        # Check for scene resolution:
        if event == BasicEvents.TICK:
            assert self._current_scene is not None, 'No scene loaded.'
            if self._current_scene.is_resolved():
                resolution = self._current_scene.get_resolution()
                for effect in resolution.effects:
                    effect()
                logging.debug('Scene {} resolved.'.format(self._current_scene))

                if is_dead(get_player()):
                    post_scene_change(game_over_scene())
                    return

                post_scene_change(resolution.next_scene())

        # Update scene and current controller
        if isinstance(event, NewSceneEvent):

            if not isinstance(event.scene, (SettingsScene, )):
                self._current_game_scene = event.scene
            self._current_scene = event.scene

            # The previous controller may not disappear after a new controller
            # is assigned, so we must explicitly deactivate it.
            if self._current_controller is not None:
                self._current_controller.deactivate()
            self._current_controller = build_controller(event.scene)
Beispiel #8
0
    def __init__(self,
                 prev_scene_loader: Callable[[], Scene],
                 loot_mods: Callable[[], Iterable[Mod]] = None) -> None:
        """

        Args:
            prev_scene_loader: Zero-argument function that returns the previous
                scene.
            loot_mods: Zero-argument function that returns the mods on the
                ground.
        """
        super().__init__()
        self._background_image = BackgroundImages.INVENTORY.path
        self._player = get_player()
        self._selected_mod: Optional[Mod] = None
        if loot_mods is not None:
            self._mods_on_ground = list(loot_mods())
        else:
            self._mods_on_ground = []
        self._update_layout()
        self._resolution = BasicResolution(prev_scene_loader)
        self._is_resolved = False
        self._UI_error_message: str = ''
Beispiel #9
0
def test_restart_game(player):
    player.status.increment_attribute(Attributes.HEALTH, -1)
    old_health = player.status.get_attribute(Attributes.HEALTH)
    restart_game()
    assert old_health is not get_player().status.get_attribute(
        Attributes.HEALTH)
Beispiel #10
0
def player():
    return get_player()
Beispiel #11
0
def test_inventory_scene_control_flow():
    game = Game()  # noqa: F841
    view_manager = ViewManager()  # noqa: F841

    # Start with player holding nothing
    chassis = get_player().chassis

    [chassis.remove_mod(mod) for mod in chassis.all_mods()]
    assert len(list(chassis.all_mods())) == 1  # Base mod only

    # Setup start scene that loads the loot scene
    mod_locs = [
        SlotTypes.HEAD, SlotTypes.HEAD, SlotTypes.CHEST, SlotTypes.LEGS
    ]
    ground_mods = _typical_mods(mod_locs)

    def start_scene() -> DecisionScene:
        loot_scene = partial(InventoryScene, start_scene, lambda: ground_mods)
        return DecisionScene('dummy scene for testing purposes',
                             {'1': DecisionOption('Loot', loot_scene)})

    # Load loot scene
    event_utils.post_scene_change(start_scene())
    event_utils.simulate_key_press('1')
    # The scene machine only changes scenes during a game tick
    EventManager.post(BasicEvents.TICK)

    assert isinstance(_get_active_controller(), InventoryController)
    inv_scene = _get_current_scene()
    assert isinstance(inv_scene, InventoryScene)

    # Player selectes head 1 and moves it to head slot
    head_mod_1 = ground_mods[0]
    event_utils.simulate_mouse_click(
        *_mod_slot_position(head_mod_1, inv_scene))

    assert head_mod_1 is inv_scene.selected_mod

    head_slot_position = _slot_header_position(SlotTypes.HEAD, inv_scene)
    event_utils.simulate_mouse_click(*(head_slot_position))

    assert inv_scene.selected_mod is None
    assert head_mod_1 in chassis.all_mods()

    # Player selects head_mod_2 and tries to move it to head slot, but it is
    # full so it remains on the ground.
    assert chassis.slot_capacities[SlotTypes.HEAD] == 1
    head_mod_2 = ground_mods[1]

    head_2_slot_pos = _mod_slot_position(head_mod_2, inv_scene)
    event_utils.simulate_mouse_click(*head_2_slot_pos)

    assert head_mod_2 is inv_scene.selected_mod

    head_slot_position = _slot_header_position(SlotTypes.HEAD, inv_scene)
    event_utils.simulate_mouse_click(*(head_slot_position))

    assert inv_scene.selected_mod is None
    assert head_mod_2 not in chassis.all_mods()
    assert head_2_slot_pos == _mod_slot_position(head_mod_2, inv_scene)

    # Player moves leg mod to storage
    leg_mod = ground_mods[3]
    assert leg_mod not in chassis.all_mods()

    event_utils.simulate_mouse_click(*_mod_slot_position(leg_mod, inv_scene))
    assert leg_mod is inv_scene.selected_mod

    storage_slot_pos = _slot_header_position(SlotTypes.STORAGE, inv_scene)
    event_utils.simulate_mouse_click(*storage_slot_pos)

    assert inv_scene.selected_mod is None
    assert leg_mod in chassis.all_mods()
    assert leg_mod in chassis.mods_in_slot(SlotTypes.STORAGE)

    # Player tries to move chest mod to arms slot, so nothing happens
    chest_mod = ground_mods[2]
    assert SlotTypes.CHEST in chest_mod.valid_slots()
    assert chest_mod not in chassis.all_mods()

    event_utils.simulate_mouse_click(*_mod_slot_position(chest_mod, inv_scene))

    assert inv_scene.selected_mod is chest_mod

    arms_slot_pos = _slot_header_position(SlotTypes.ARMS, inv_scene)
    event_utils.simulate_mouse_click(*arms_slot_pos)

    assert inv_scene.selected_mod is None
    assert chest_mod not in chassis.all_mods()