Skip to content

Commit

Permalink
Skewer doesn't update when sims arrive or leave. #95 (#97)
Browse files Browse the repository at this point in the history
* Skewer doesn't update when sims arrive or leave.
  • Loading branch information
TitanNano authored Jun 14, 2024
1 parent d8ca1d6 commit d6e7ba6
Show file tree
Hide file tree
Showing 4 changed files with 103 additions and 2 deletions.
2 changes: 1 addition & 1 deletion src/control_any_sim/main.py
Original file line number Diff line number Diff line change
Expand Up @@ -249,6 +249,6 @@ def canys_client_get_selector_visual_type(
return original(self, sim_info)


Logger.log("starting control_any_sim")
Logger.log("starting control_any_sim...")

InteractionsService.bootstrap()
52 changes: 52 additions & 0 deletions src/control_any_sim/services/selection_group.py
Original file line number Diff line number Diff line change
Expand Up @@ -131,6 +131,8 @@ def __init__(

GameEvents.on_zone_teardown(self.on_zone_teardown)
GameEvents.on_active_sim_changed(self.on_active_sim_changed)
GameEvents.on_post_spawn_sim(self.on_spawn_sim)
GameEvents.on_travel_sim_out(self.on_sim_travel_out)

def persist_state(self: Self) -> None:
"""Write current state of the service to disk."""
Expand Down Expand Up @@ -311,3 +313,53 @@ def remove_household_npc(self: Self, sim_info: SimInfo) -> None:
def is_household_npc(self: Self, sim_info: SimInfo) -> bool:
"""Check if a given SimInfo is a household NPC."""
return sim_info.id in self.household_npcs

def on_spawn_sim(
self: Self,
sim: Sim,
) -> None:
"""
Event handler for when a sim finished spawning.
Send selectable sim update if the new sim is a controlled NPC.
"""
if not self.is_custom_sim(sim.id):
return

Logger.log(
f'Sending selectable sim update for spawned NPC "{sim.first_name} {sim.last_name}"',
)
Logger.log("".join(traceback.format_list(traceback.extract_stack())))
self.client.send_selectable_sims_update()

def on_sim_travel_out(
self: Self,
sim_info: SimInfo,
) -> None:
"""
Event handler for when a sim travels out of the current zone.
Send selectable sim update if the leaving sim is a controlled NPC.
"""
if not self.is_custom_sim(sim_info.id):
Logger.log(
"Traveling a sim out of the current zone, but it's not a custom selection NPC.",
)
return

sim_instance: Sim = sim_info.get_sim_instance(
allow_hidden_flags=ALL_HIDDEN_REASONS,
)

if not sim_instance:
Logger.log("there is no sim instance during travel")
if not sim_instance:
Logger.log("there is no sim instance during travel")

Logger.log(
f'Sending selectable sim update for traveling NPC "{sim_info.first_name} {sim_info.last_name}"',
)

sim_instance.schedule_destroy_asap(
post_delete_func=self.client.send_selectable_sims_update,
)
10 changes: 9 additions & 1 deletion src/control_any_sim/ts4_services/__init__.py
Original file line number Diff line number Diff line change
@@ -1,14 +1,17 @@
"""Wrapper for service module to add types."""

from __future__ import annotations

from typing import TYPE_CHECKING

import services
from sims.sim_info_manager import SimInfoManager

from .clientmanager import ClientManager

if TYPE_CHECKING:
import server
from sims.sim_info_manager import SimInfoManager
from sims.sim_spawner_service import SimSpawnerService


def client_manager() -> ClientManager:
Expand All @@ -21,3 +24,8 @@ def client_manager() -> ClientManager:
def sim_info_manager() -> SimInfoManager:
"""Typed version of services.sim_info_manager."""
return services.sim_info_manager()


def sim_spawner_service(zone_id: int | None = None) -> SimSpawnerService:
"""Typed version of services.sim_spawner_manager."""
return services.sim_spawner_service(zone_id)
41 changes: 41 additions & 0 deletions src/control_any_sim/util/game_events.py
Original file line number Diff line number Diff line change
Expand Up @@ -7,10 +7,13 @@

import services
from server.client import Client
from sims.self_interactions import TravelInteraction
from sims.sim import Sim
from sims.sim_info import SimInfo
from zone import Zone
from zone_types import ZoneState

from control_any_sim import ts4_services
from control_any_sim.util.inject import inject_method_to
from control_any_sim.util.logger import Logger

Expand All @@ -26,6 +29,8 @@ class GameEvents:
OnAddSim: TypeAlias = Callable[[Sim], None]
OnLoadingScreenAnimationFinished: TypeAlias = Callable[[Zone], None]
OnActiveSimChanged: TypeAlias = Callable[[Sim, Sim], None]
OnTravelSimOut: TypeAlias = Callable[[SimInfo], None]
OnPostSpawnSim: TypeAlias = Callable[[Sim], None]

C = TypeVar("C", bound="GameEvents")

Expand All @@ -35,6 +40,7 @@ class GameEvents:
loading_screen_animation_finished_handlers: ClassVar[
list[OnLoadingScreenAnimationFinished]
] = []
travel_sim_out_handlers: ClassVar[list[OnTravelSimOut]] = []

@classmethod
def on_zone_teardown(cls: type[C], handler: OnZoneTeardown) -> None:
Expand Down Expand Up @@ -108,6 +114,22 @@ def emit_loading_screen_animation_finished(
for handler in cls.loading_screen_animation_finished_handlers:
handler(current_zone)

@classmethod
def on_travel_sim_out(cls: type[C], handler: OnTravelSimOut) -> None:
"""Add a listener for the travel_sim_out event."""
cls.travel_sim_out_handlers.append(handler)

@classmethod
def emit_travel_sim_out(cls: type[C], sim_info: SimInfo) -> None:
"""Emit the travel sim out event."""
for handler in cls.travel_sim_out_handlers:
handler(sim_info)

@staticmethod
def on_post_spawn_sim(handler: OnPostSpawnSim) -> None:
"""Adda listener for the post spawn sim event."""
ts4_services.sim_spawner_service().register_sim_spawned_callback(handler)


@inject_method_to(Zone, "on_teardown")
def canys_zone_on_teardown(
Expand Down Expand Up @@ -177,3 +199,22 @@ def canys_zone_on_loading_screen_animation_finished(
Logger.error(traceback.format_exc())

return original(self)


@inject_method_to(TravelInteraction, "save_and_destroy_sim")
def canys_travel_internaction_save_and_destroy_sim(
original: Callable[[TravelInteraction, bool, SimInfo], None],
self: TravelInteraction,
on_reset: bool, # noqa: FBT001
sim_info: SimInfo,
) -> None:
"""Wrap the TravelInteraction::save_and_destroy_sim method to emit the corresponding event."""
try:
result = original(self, on_reset, sim_info)

GameEvents.emit_travel_sim_out(sim_info)
except Exception as err:
Logger.error(f"{err}")
Logger.error(traceback.format_exc())

return result

0 comments on commit d6e7ba6

Please sign in to comment.