Ejemplo n.º 1
0
 def __init__(
     self,
     name: str,
     background: BaseTexture,
     pass_map: PassMap,
     triggers: List[Trigger],
     player_position: Vector,
     scripts: Mapping[str, Callable[[], None]],
     path: Path,
     save_point: Optional[Object],
 ):
     self.name = name
     self.background = background
     self.pass_map = pass_map
     self.trigger_event_watchers = [
         TriggerEventWatcher(trigger) for trigger in triggers
     ]
     self.player = Player(player_position)
     self.scripts = scripts
     self.path = path
     self.objects: WalList[Object] = WalList([])
     self.named_objects: Dict[str, Object] = {}
     self.state: dict = {}
     self.sprites: WalList[BaseSprite] = WalList([])
     self.save_point = save_point
     if save_point is not None:
         self.add_object(save_point)
     self._update_callbacks: WalList[Callable[[float], None]] = WalList([])
     get_event_manager().subscribe('key:confirm',
                                   Subscriber(self.on_interact))
Ejemplo n.º 2
0
 def finalize(self):
     get_event_manager().subscribe(
         'end_of_cycle',
         Subscriber(lambda *args: get_game().overworld.unfreeze()),
     )
     self.kill()
     self.on_finish_callback()
Ejemplo n.º 3
0
 def hide(self, on_finish: Callable):
     self.spawn(
         RoomTransitionFadeIn(
             self.game.screen.get_size()).start_animation())
     get_event_manager().subscribe(
         'room_exit_animation_finished',
         Subscriber(lambda event_id, arg: on_finish()),
     )
Ejemplo n.º 4
0
 async def _run_wrapper(self):
     try:
         await self.run()
     except BulletSpawner.TerminateCoroutine:
         pass
     except StopIteration:
         pass
     get_event_manager().raise_event('attack_finished')
Ejemplo n.º 5
0
 def update(self, time_delta):
     delta = Vector(self.moving_x,
                    self.moving_y) * (self.speed * time_delta)
     self.move(delta)
     if self._is_walking() and self._should_stop():
         assert self._stop_event is not None
         get_event_manager().raise_event(self._stop_event, None)
         self._stop_event = None
Ejemplo n.º 6
0
 def on_confirm(self, event, arg):
     del event, arg
     if not self.is_alive():
         return
     if self.pages[self.page_index].has_animation_finished():
         self.next()
     get_event_manager().subscribe('key:confirm',
                                   Subscriber(self.on_confirm))
Ejemplo n.º 7
0
 def handler(event, arg):
     del event, arg
     nonlocal counter
     counter += 1
     if counter == num_awaitables:
         get_event_manager().raise_event(all_finished_event)
     else:
         get_event_manager().subscribe(one_finished_event,
                                       Subscriber(handler))
Ejemplo n.º 8
0
 def _on_interact_somewhere(self, *args):
     del args
     if not self.is_alive():
         return
     if not get_game().overworld.is_frozen():
         player = get_game().overworld.room.player
         if self.get_hitbox_with_position().colliderect(
                 player.get_extended_hitbox()):
             self.on_interact()
     get_event_manager().subscribe('key:confirm',
                                   Subscriber(self._on_interact_somewhere))
Ejemplo n.º 9
0
    def update(self, time_delta: float):
        # Handle events that occured since last check
        self.process_events()

        # Run scheduled callbacks
        get_pending_callback_queue().update()

        # Delegate the main update logic to the current game mode
        self.current_game_mode.update(time_delta)

        # Finalize the update cycle
        get_event_manager().raise_event('end_of_cycle', None, silent=True)
Ejemplo n.º 10
0
 def load_room(self, room_name: str):
     logger.debug('Loading room {}', room_name)
     self._room_ready = False
     self.freeze()
     self.spawn(
         RoomTransitionFadeIn(
             self.game.screen.get_size()).start_animation())
     get_event_manager().subscribe(
         'room_exit_animation_finished',
         Subscriber(
             lambda event_id, arg: self._run_room_loading_logic(room_name)),
     )
Ejemplo n.º 11
0
 async def run(self):
     if not DEBUG_SKIP:
         await display_text(
             load_text('fight/pre-lyceum/itt_test_cariel_tutorial'))
     menu = self.get_main_menu()
     while True:
         choice = await menu.choose()
         action = await self.get_action_for_choice(choice)
         if action is not None:
             await action()
             break
     get_event_manager().raise_event('fight_finished')
Ejemplo n.º 12
0
 def on_interact(self, *args):
     del args
     if get_game().overworld.room is not self:
         return
     if not get_game().overworld.is_frozen():
         affected_rect = get_game(
         ).overworld.room.player.get_extended_hitbox()
         for watcher in self.trigger_event_watchers:
             if affected_rect.colliderect(watcher.trigger.rect):
                 watcher.pass_event(Event('interact'))
     get_event_manager().subscribe('key:confirm',
                                   Subscriber(self.on_interact))
Ejemplo n.º 13
0
 def __init__(
     self,
     pos: Vector,
     texture: Optional[BaseTexture] = None,
     is_passable: bool = False,
     hitbox: Optional[pg.Rect] = None,
 ):
     super().__init__(pos)
     self.texture = texture
     self.is_passable = is_passable
     self.hitbox = hitbox if hitbox is not None else generate_hitbox(20, 20)
     get_event_manager().subscribe('key:confirm',
                                   Subscriber(self._on_interact_somewhere))
     self.on_interact: Callable[[], Any] = lambda: None
Ejemplo n.º 14
0
    async def run(self):
        await display_text(self.get_battle_entry_text())
        while True:
            menu = self.get_main_menu()
            choice = await self.choose_from_menu_tree(menu)
            action = await self.get_action_for_choice(choice)
            await action()

            if self.has_battle_finished():
                break
            await self.process_enemy_attack()
            if self.has_battle_finished():
                break
        await self.on_finish()
        get_event_manager().raise_event('fight_finished')
Ejemplo n.º 15
0
    def _run_room_loading_logic(self,
                                room_name: str,
                                player_pos: Optional[Vector] = None):
        if self._room_loaded:
            prev_room_name = self.room.name
            self.room.kill()
        else:
            prev_room_name = 'default'

        self.room = load_room(
            Path('.') / 'assets' / 'rooms' / room_name,
            prev_room_name,
            player_pos,
        )
        self._room_screen = pg.Surface(self.room.get_size())
        self.spawn(
            RoomTransitionFadeOut(
                self.game.screen.get_size()).start_animation())
        subscriber = Subscriber(
            lambda event_id, arg: self._finalize_room_loading())
        get_event_manager().subscribe('room_enter_animation_finished',
                                      subscriber)
Ejemplo n.º 16
0
    async def walk(self, delta: Vector):
        assert self._target is None
        self._target = self.pos + delta

        direction = delta.normalized()
        self.set_moving(direction.x, direction.y)

        self._stop_event = get_event_manager().unique_id()
        await wait_for_event(self._stop_event)

        self.set_moving(0, 0)
        self.pos = self._target
        self._target = None
Ejemplo n.º 17
0
    def process_events(self):
        for event in pg.event.get():
            if event.type == pg.QUIT:
                raise GameExited()
            if event.type == pg.KEYDOWN:
                # Process all keys
                get_event_manager().raise_event('key:any', event)

                # Process special keys
                if event.key in (pg.K_z, pg.K_RETURN):
                    get_event_manager().raise_event('key:confirm', event)
                if event.key in (pg.K_x, pg.K_LSHIFT, pg.K_RSHIFT):
                    get_event_manager().raise_event('key:cancel', event)
                if event.key in (pg.K_c, pg.K_LCTRL, pg.K_RCTRL):
                    get_event_manager().raise_event('key:menu', event)
Ejemplo n.º 18
0
async def gather(*awaitables):
    # XXX: This code is fascinatingly awful, but it serves for a good purpose,
    # allowing awaiting multiple coroutines at the same time
    one_finished_event = get_event_manager().unique_id()
    all_finished_event = get_event_manager().unique_id()

    counter = 0
    num_awaitables = len(awaitables)

    def handler(event, arg):
        del event, arg
        nonlocal counter
        counter += 1
        if counter == num_awaitables:
            get_event_manager().raise_event(all_finished_event)
        else:
            get_event_manager().subscribe(one_finished_event,
                                          Subscriber(handler))

    get_event_manager().subscribe(one_finished_event, Subscriber(handler))

    for aw in awaitables:
        # WARNING: this code is potentially dangerous, since `aw`, which is changed
        # by the outer loop, is captured by the inner function. In this very case,
        # however, everything is fine, because that function is called immediately
        # and is then discarded.
        #
        # TODO: refactor this code to make it more robust and to silence Pylint's
        # cell-var-from-import warning
        async def await_and_notify(*args, **kwargs):
            del args, kwargs
            await aw
            get_event_manager().raise_event(one_finished_event)

        SimpleScript(await_and_notify)()

    await wait_for_event(all_finished_event)
Ejemplo n.º 19
0
 async def await_and_notify(*args, **kwargs):
     del args, kwargs
     await aw
     get_event_manager().raise_event(one_finished_event)
Ejemplo n.º 20
0
 def initialize(self):
     get_game().overworld.freeze()
     get_event_manager().subscribe('key:confirm',
                                   Subscriber(self.on_confirm))
     get_event_manager().subscribe('key:cancel', Subscriber(self.on_cancel))
     self.next()
Ejemplo n.º 21
0
def make_callback():
    event_id = get_event_manager().unique_id()
    callback = lambda *args, **kwargs: get_event_manager().raise_event(event_id, None)
    return event_id, callback
Ejemplo n.º 22
0
async def display_text(text):
    get_game().current_game_mode.spawn(text)
    event_id = get_event_manager().unique_id()
    text.on_finish_callback = lambda: get_event_manager().raise_event(event_id, None)
    text.initialize()
    await wait_for_event(event_id)
Ejemplo n.º 23
0
def wait_for_any_event():
    script = get_game().current_script
    get_event_manager().subscribe_to_any_event(Subscriber(lambda event, arg: script((event, arg))))
    return (yield)
Ejemplo n.º 24
0
def wait_for_event(event_id):
    script = get_game().current_script
    get_event_manager().subscribe(event_id, Subscriber(lambda event, arg: script((event, arg))))
    return (yield)
Ejemplo n.º 25
0
def notify_after(delay: float, event_id: EventId, argument: Any = None):
    get_pending_callback_queue().fire_after(
        delay,
        lambda *args: get_event_manager().raise_event(event_id, argument),
    )
Ejemplo n.º 26
0
 def set_timeout(self, new_timeout: float):
     self._timeout_event = get_event_manager().unique_id()
     notify_after(new_timeout, self._timeout_event)
Ejemplo n.º 27
0
 def on_kill(self):
     get_event_manager().raise_event('hit_animation_finished')
Ejemplo n.º 28
0
 def on_cancel(self, event, arg):
     del event, arg
     if not self.is_alive():
         return
     self.pages[self.page_index].try_force_finish()
     get_event_manager().subscribe('key:cancel', Subscriber(self.on_cancel))