def pause(speed_change_source='USER', _connection=None): speed_change_source = speed_change_source.upper() change_source = GameSpeedChangeSource(speed_change_source) if change_source is not None: services.game_clock_service().set_clock_speed(ClockSpeedMode.PAUSED, change_source=change_source) return True return False
def on_update(self): super().on_update() if self._countdown <= 0: services.current_zone().on_hit_their_marks() return _ZoneSpinUpStateResult.DONE services.game_clock_service().advance_for_hitting_their_marks() return _ZoneSpinUpStateResult.WAITING
def toggle_pause_unpause(_connection=None): if services.game_clock_service().clock_speed() == ClockSpeedMode.PAUSED: speed = services.game_clock_service().previous_non_pause_speed() else: speed = ClockSpeedMode.PAUSED send_clock_telemetry_data(_connection, speed) services.game_clock_service().set_clock_speed(speed, change_source=GameSpeedChangeSource.USER)
def on_loading_screen_animation_finished(self): logger.debug('on_loading_screen_animation_finished') services.game_clock_service().restore_saved_clock_speed() services.sim_info_manager().on_loading_screen_animation_finished() services.get_event_manager().process_events_for_household( test_events.TestEvent.SimTravel, services.active_household(), zone_id=self.id)
def advance_game_time(hours:int=0, minutes:int=0, seconds:int=0, _connection=None): previous_time = services.time_service().sim_now services.game_clock_service().advance_game_time(hours=hours, minutes=minutes, seconds=seconds) new_time = services.time_service().sim_now services.sim_info_manager().auto_satisfy_sim_motives() output = sims4.commands.Output(_connection) output('previous time = {}'.format(previous_time)) output('new time = {}'.format(new_time))
def _on_dialog_accepted(self): if services.get_persistence_service().is_save_locked(): return travel_info = InteractionOps_pb2.TravelSimsToZone() travel_info.zone_id = self._target.household.home_zone_id travel_info.sim_ids.append(self._sim.id) distributor.system.Distributor.instance().add_event(Consts_pb2.MSG_TRAVEL_SIMS_TO_ZONE, travel_info) services.game_clock_service().set_clock_speed(ClockSpeedMode.PAUSED)
def unpause(speed_change_source='USER', _connection=None): speed_change_source = speed_change_source.upper() change_source = GameSpeedChangeSource(speed_change_source) if change_source is not None: previous_speed = services.game_clock_service().previous_non_pause_speed() if previous_speed is not None: services.game_clock_service().set_clock_speed(previous_speed, change_source=change_source) return True return False
def travel_player(self): sim = self.sim_info.get_sim_instance(allow_hidden_flags=ALL_HIDDEN_REASONS) travel_info = InteractionOps_pb2.TravelSimsToZone() travel_info.zone_id = self.to_zone_id travel_info.sim_ids.append(sim.id) self.interaction = None distributor.system.Distributor.instance().add_event(Consts_pb2.MSG_TRAVEL_SIMS_TO_ZONE, travel_info) if self.is_attend_career: self._attend_career() sim.queue.cancel_all() services.game_clock_service().set_clock_speed(ClockSpeedMode.PAUSED)
def set_speed(speed='one', _connection=None): output = sims4.commands.Output(_connection) speed = speed.lower() if speed == 'one': speed = ClockSpeedMode.NORMAL elif speed == 'two': speed = ClockSpeedMode.SPEED2 elif speed == 'three': speed = ClockSpeedMode.SPEED3 send_clock_telemetry_data(_connection, speed) services.game_clock_service().set_clock_speed(speed, change_source=GameSpeedChangeSource.USER)
def _run_interaction_gen(self, timeline): to_zone_id = get_zone_id_from_pick_location(self.context.pick) if to_zone_id is None: logger.error('Could not resolve lot id: {} into a valid zone id when traveling to adjacent lot.', self.context.pick.lot_id, owner='rmccord') return if services.get_persistence_service().is_save_locked(): return travel_info = InteractionOps_pb2.TravelSimsToZone() travel_info.zone_id = to_zone_id travel_info.sim_ids.append(self.sim.id) for traveling_sim_id in self._traveling_sim_ids: travel_info.sim_ids.append(traveling_sim_id) distributor.system.Distributor.instance().add_event(Consts_pb2.MSG_TRAVEL_SIMS_TO_ZONE, travel_info) services.game_clock_service().set_clock_speed(ClockSpeedMode.PAUSED)
def __init__(self, tracker, initial_value): super().__init__(tracker, initial_value) self._decay_enabled = False self._decay_rate_override = UNSET self._callbacks = [] self._suppress_update_active_callbacks = False self._alarm_handle = None self._active_callback = None if self.max_simulate_time_on_load is not None: now = services.time_service().sim_now if services.current_zone().is_zone_loading: world_game_time = services.game_clock_service().zone_init_world_game_time() neg_max_update_time = create_time_span(minutes=-self.max_simulate_time_on_load) diff = world_game_time + neg_max_update_time if diff > now: update_time = diff else: update_time = now self._last_update = update_time else: self._last_update = now else: self._last_update = services.time_service().sim_now self._decay_rate_modifier = 1 self._decay_rate_modifiers = [] self._convergence_value = self._default_convergence_value self._recalculate_modified_decay_rate()
def on_cleanup_zone_objects(self, client): zone = services.current_zone() if client.household_id != zone.lot.owner_household_id: time_elapsed = services.game_clock_service().time_elapsed_since_last_save() if time_elapsed.in_minutes() > self.ELAPSED_TIME_SINCE_LAST_VISIT_FOR_CLEANUP: cleanup = VenueService.VENUE_CLEANUP_ACTIONS() cleanup.modify_objects_on_active_lot()
def build_buy_pause_unpause(is_pause:bool=True, _connection=None): game_clock_service = services.game_clock_service() if is_pause: game_clock_service.request_pause(ENTER_BUILDBUY_PAUSE_HANDLE) else: game_clock_service.unrequest_pause(ENTER_BUILDBUY_PAUSE_HANDLE) return True
def on_add(self): game_clock_service = services.game_clock_service() for (state, changes) in self.state_changes.items(): current_state = None for change in changes: current_state = self._add_alarm(current_state, game_clock_service, state, change) while current_state is not None: self.owner.set_state(state, current_state[1])
def list_pause_requests(_connection=None): output = sims4.commands.Output(_connection) output('current pause requests:') index = 0 for pause_request in services.game_clock_service()._pause_requests: output('{}) {}'.format(index, pause_request)) index += 1 return True
def clear_pause_requests(_connection=None): output = sims4.commands.Output(_connection) output('Clearing all pause requests:') game_clock_service = services.game_clock_service() if game_clock_service._pause_requests: game_clock_service._pause_requests = [] game_clock_service._sync_clock_and_broadcast_gameclock() return True
def should_restore_sis(self): if services.game_clock_service( ).time_has_passed_in_world_since_zone_save() or ( self.venue_type_changed_between_save_and_load() or (self.lot_owner_household_changed_between_save_and_load() or self.active_household_changed_between_save_and_load( ))) or self.is_first_visit_to_zone: return False return True
def _do_behavior(self): if clock.GameClock.ignore_game_speed_requests: return set_speed_type = self._game_speed_change.set_speed_type game_speed = self._game_speed_change.game_speed if set_speed_type == self.SET_DIRECTLY: services.game_clock_service().set_clock_speed(game_speed) elif set_speed_type == self.REQUEST_SPEED: allow_ss3 = self._game_speed_change.allow_super_speed_three game_speed_params = (game_speed, allow_ss3 is not None) if allow_ss3 is not None and allow_ss3.unrequest_speed is not None: self.interaction.register_on_cancelled_callback(lambda _: self._unrequest_super_speed_three_mode(allow_ss3.unrequest_speed)) self._sim_id = self.interaction.sim.id services.game_clock_service().register_game_speed_change_request(self.interaction.sim, game_speed_params) elif set_speed_type == self.UNREQUEST_SS3: self._unrequest_super_speed_three_mode(game_speed) if clock_handlers.speed_change_archiver.enabled: clock_handlers.archive_speed_change(self.interaction, set_speed_type, game_speed, True)
def now(_connection=None): output = sims4.commands.Output(_connection) game_clock_ticks = services.time_service().sim_now.absolute_ticks() server_ticks = services.server_clock_service().ticks() output('Gameclock ticks: {} Server Ticks: {}'.format(game_clock_ticks, server_ticks)) timeline_now = services.time_service().sim_now game_clock_now = services.game_clock_service().now() output('Sim timeline now: {}'.format(timeline_now)) output('Game clock now: {}'.format(game_clock_now))
def on_enter(self): super().on_enter() caches.skip_cache = False first_visit_to_zone = services.current_zone().is_first_visit_to_zone if services.game_clock_service( ).time_has_passed_in_world_since_zone_save() or first_visit_to_zone: services.sim_info_manager().run_preroll_autonomy( first_time_load_zone=first_visit_to_zone) return _ZoneSpinUpStateResult.DONE
def start(self): sim_debugger = None self.sim_timeline = scheduling.Timeline( services.game_clock_service().now(), exception_reporter=self._on_exception, debugger=sim_debugger) self.wall_clock_timeline = scheduling.Timeline( services.server_clock_service().now(), exception_reporter=self._on_exception) self.sim_timeline.on_time_advanced.append(caches.clear_all_caches)
def show_ss3_info(_connection=None): (ss3_state, alarm, sims_in_open_streets, target_state) = services.get_super_speed_three_service().get_debug_information() game_clock = services.game_clock_service() output = sims4.commands.Output(_connection) output('-=-=-=-=-=-=-=-=-\nSUPER SPEED THREE INFORMATION:') output(' State: {}\n Alarm: {}\n Sims in Open Streets: {}\n Target State: {}'.format(ss3_state, alarm, sims_in_open_streets, target_state)) output(' Game Speed: {}'.format(game_clock.clock_speed())) output('TIME REQUESTS:') for time_request in game_clock.game_speed_requests_gen(): output(' {}\n'.format(time_request)) output('-=-=-=-=-=-=-=-=-')
def _with_skippable_animation_time(timeline): game_clock_service = services.game_clock_service() then = game_clock_service.now() yield element_utils.run_child(timeline, sequence) now = game_clock_service.now() duration = (now - then).in_real_world_seconds() arb_accumulator = services.current_zone().arb_accumulator_service for actor in actors: time_debt = arb_accumulator.get_time_debt((actor,)) new_time_debt = max(0, time_debt - duration) arb_accumulator.set_time_debt((actor,), new_time_debt)
def get_time_span_to_next_shift_time(self): if not self.shift_times_and_staffing: return sorted_times = self.get_sorted_shift_times() next_shift_hour = sorted_times[0][0] now_hour = services.time_service().sim_now.hour() for (shift_hour, _) in sorted_times: while shift_hour > now_hour: next_shift_hour = shift_hour break time_span_until = services.game_clock_service().precise_time_until_hour_of_day(next_shift_hour) return time_span_until
def _have_all_sims_requested_ss3(): sim_info_manager = services.sim_info_manager() game_clock = services.game_clock_service() for instanced_sim in sim_info_manager.instanced_sims_gen(allow_hidden_flags=objects.ALL_HIDDEN_REASONS): while instanced_sim.is_selectable or instanced_sim.is_on_active_lot(): speed_params = game_clock.get_game_speed_request_for_sim_id(instanced_sim.id) if speed_params is None: return False (_, sim_allows_super_speed_three) = speed_params if not sim_allows_super_speed_three: return False return True
def get_debugging_metrics(cls): game_clock = services.game_clock_service() game_clock_now_ticks = game_clock.now().absolute_ticks() deviance = game_clock.now().absolute_ticks() - services.time_service( ).sim_now.absolute_ticks() (threshold, duration) = cls._get_threshold_and_duration(game_clock) phase_duration = None if deviance > threshold: if first_tick_above_threshold is not None: phase_duration = game_clock_now_ticks - first_tick_above_threshold elif first_tick_below_threshold is not None: phase_duration = game_clock_now_ticks - first_tick_below_threshold return (deviance, threshold, phase_duration, duration)
def update(self, time_slice=True): max_time_ms = self.MAX_TIME_SLICE_MILLISECONDS if time_slice else None result = self.sim_timeline.simulate( services.game_clock_service().now(), max_time_ms=max_time_ms) if not result: logger.debug( 'Did not finish processing Sim Timeline. Current element: {}', self.sim_timeline.heap[0]) result = self.wall_clock_timeline.simulate( services.server_clock_service().now()) if not result: logger.error( 'Too many iterations processing wall-clock Timeline. Likely culprit: {}', self.wall_clock_timeline.heap[0])
def clock_status(_connection=None): stats = [] game_clock = services.game_clock_service() ss3_service = services.get_super_speed_three_service() clock_speed = None if ss3_service.in_super_speed_three_mode(): clock_speed = 'Super Speed 3' else: clock_speed = ClockSpeedMode(game_clock.clock_speed()) (deviance, threshold, current_duration, duration) = AdaptiveClockSpeed.get_debugging_metrics() output = sims4.commands.CheatOutput(_connection) stats.append(('Clock Speed', clock_speed, '(Current player-facing clock speed)')) stats.append(('Speed Multiplier Type', ClockSpeedMultiplierType(game_clock.clock_speed_multiplier_type), '(Decides the speed 2/3/SS3 multipliers for adaptive speed)')) stats.append(('Clock Speed Multiplier', game_clock.current_clock_speed_scale(), '(Current Speed scaled with appropriate speed settings)')) stats.append(('Simulation Deviance', '{:>7} / {:<7}'.format(deviance, threshold), '(Simulation clock deviance from time service clock / Tuning Threshold [units: ticks])')) stats.append(('Deviance Duration', '{:>7} / {:<7}'.format(current_duration, duration), '(Current duration in multiplier phase / Tuning Duration [units: ticks])')) for (name, value, description) in stats: output('{:25} {!s:40} {}'.format(name, value, description))
def update_adaptive_speed(cls): global first_tick_above_threshold, first_tick_below_threshold if not cls.TIME_DIFFERENCE_THRESHOLD: return game_clock = services.game_clock_service() game_speed = game_clock.clock_speed() if game_speed == clock.ClockSpeedMode.NORMAL or game_speed == clock.ClockSpeedMode.PAUSED: first_tick_above_threshold = None first_tick_below_threshold = None return game_clock_now_ticks = game_clock.now().absolute_ticks() diff = game_clock_now_ticks - services.time_service( ).sim_now.absolute_ticks() (threshold, duration) = cls._get_threshold_and_duration(game_clock) phase_duration = None if diff > threshold: first_tick_below_threshold = None if first_tick_above_threshold is None: first_tick_above_threshold = game_clock_now_ticks phase_duration = game_clock_now_ticks - first_tick_above_threshold if phase_duration > duration: multiplier_type = cls.TIME_DIFFERENCE_THRESHOLD.reduced_speed_multiplier.multipler_type if game_clock._set_clock_speed_multiplier_type( multiplier_type): first_tick_above_threshold = None logger.info( '[game_clock_now - sim_now] {} > {}. Switching speed multiplier type to {}.', diff, threshold, multiplier_type) else: first_tick_above_threshold = None if first_tick_below_threshold is None: first_tick_below_threshold = game_clock_now_ticks phase_duration = game_clock_now_ticks - first_tick_below_threshold if phase_duration > duration: multiplier_type = cls.TIME_DIFFERENCE_THRESHOLD.default_speed_multiplier.multipler_type if game_clock._set_clock_speed_multiplier_type( multiplier_type): first_tick_below_threshold = None logger.info( '[game_clock_now - sim_now] {} < {}. Switching speed multiplier type to {}.', diff, threshold, multiplier_type) logger.debug('{!s:35} {:7} {} {:7} Duration: {}'.format( game_clock.clock_speed_multiplier_type, diff, '<' if diff < threshold else '>', threshold, phase_duration))
def stop(self): if self._pause_handle is not None: pause_handle = self._pause_handle self._pause_handle = None services.game_clock_service().remove_request( pause_handle, source=GameSpeedChangeSource.SITUATION)
def on_enter(self): super().on_enter() clock_service = services.game_clock_service() clock_service.push_speed(ClockSpeedMode.INTERACTION_STARTUP_SPEED) clock_service.advance_for_hitting_their_marks() return _ZoneSpinUpStateResult.WAITING
def set_current_time_speed(speed_mode): services.game_clock_service().set_clock_speed(speed_mode)
def set_speed_multipliers( speed_multiplier_type: clock.ClockSpeedMultiplierType, _connection=None): services.game_clock_service()._set_clock_speed_multiplier_type( speed_multiplier_type)
def in_super_speed_three_mode(self): clock_service = services.game_clock_service() return clock_service.clock_speed() == clock.ClockSpeedMode.SPEED3 and self.super_speed_three_active
def send_clock_telemetry_data(_connection, speed): if services.game_clock_service().clock_speed() != speed: client = services.client_manager().get(_connection) with telemetry_helper.begin_hook(clock_telemetry_writer, TELEMETRY_HOOK_CHANGE_SPEED_GAME, household=client.household) as hook: hook.write_int(TELEMETRY_FIELD_CLOCK_SPEED, speed)
def add_tutorial_alarm(self, tip, callback, time_of_day): now = services.game_clock_service().now() time_till_satisfy = now.time_till_next_day_time(time_of_day) self._tutorial_alarms[tip] = add_alarm(self, time_till_satisfy, callback, cross_zone=True)
def situation_ended_callback(ended_situation_id, _callback_option, _data, request, situation_speed_requests): services.game_clock_service().remove_request(request) if ended_situation_id in situation_speed_requests: del situation_speed_requests[ended_situation_id]
def toggle_pause_unpause(pause_handle_name='From Command', _connection=None): logger.debug('clock.toggle_pause_unpause') if services.game_clock_service().clock_speed == ClockSpeedMode.PAUSED: unrequest_pause(pause_handle_name=pause_handle_name) else: request_pause(pause_handle_name=pause_handle_name)
def clear_ui_speed_requests(_connection=None): clock_service = services.game_clock_service() while clock_service.pop_speed( source=GameSpeedChangeSource.UI_MODAL) is not None: pass
def ignore_interaction_speed_change_requests(value: bool = True, _connection=None): services.game_clock_service().ignore_game_speed_requests = value
def unrequest_pause(pause_handle_name='Pause Handle From Command', _connection=None): services.game_clock_service().unrequest_pause(pause_handle_name) return False
def set_speed_multipliers(speed_multiplier_type, _connection=None): try: multiplier_type = clock.ClockSpeedMultiplierType(speed_multiplier_type) services.game_clock_service()._set_clock_speed_multiplier_type(multiplier_type) except ValueError: sims4.commands.CheatOutput(_connection)('{} is not a valid ClockSpeedMultiplierType entry'.format(speed_multiplier_type))
def archive_gsi_dump(filename_str, error_str): callstack = generate_message_with_callstack('GSI Dump') archive_data = {'game_time': str(services.game_clock_service().now()), 'gsi_filename': filename_str, 'error_log_or_exception': error_str, 'callstack': callstack} gsi_dump_archiver.archive(data=archive_data)
def _do_behavior(self): if clock.GameClock.ignore_game_speed_requests: return services.game_clock_service().set_clock_speed(self.game_speed)
def get_current_time_speed(): return services.game_clock_service().clock_speed
def current_clock_speed_scale(): return services.game_clock_service().current_clock_speed_scale()
def in_super_speed_three_mode(self): clock_service = services.game_clock_service() return clock_service.clock_speed( ) == clock.ClockSpeedMode.SPEED3 and self.super_speed_three_active
def _rerequest_speed_three(): clock_service = services.game_clock_service() if clock_service.clock_speed() == clock.ClockSpeedMode.SPEED3: clock_service.set_clock_speed(clock.ClockSpeedMode.SPEED3) clock_service.send_update()
def request_speed_change(self): sim = self.interaction.sim if self.new_game_speed == ClockSpeedMode.SUPER_SPEED3: situation_manager = services.get_zone_situation_manager() self._ss3_requests[sim].add(self) def validity_check(situations_to_ignore=None): business_manager = services.business_service( ).get_business_manager_for_zone() if business_manager is not None and business_manager.is_open: return False current_venue = services.get_current_venue() if current_venue is not None and not current_venue.allow_super_speed_three: return False for situation in situation_manager.get_all(): if situations_to_ignore and situation in situations_to_ignore: continue if situation.blocks_super_speed_three: return False def on_lot_check(test_sim): if not test_sim.is_on_active_lot(): return False plex_service = services.get_plex_service() zone_id = services.current_zone_id() if plex_service.is_zone_a_plex(zone_id): level = test_sim.level if plex_service.get_plex_zone_at_position( test_sim.position, level) != zone_id: return False if plex_service.get_plex_zone_at_position( test_sim.intended_position, level) != zone_id: return False return not services.get_zone_situation_manager( ).is_sim_ss3_safe(test_sim) def validate_household_sim(test_sim): if test_sim in self._ss3_requests or test_sim in self.special_case_sims: return True if test_sim.is_selectable: run_affordance = self.species_interaction_speed_requirements.species_affordance_mapping.get( test_sim.species) if run_affordance is not None: self.special_case_sims[test_sim] = run_affordance return True else: roommate_service = services.get_roommate_service() if roommate_service is not None and roommate_service.get_home_zone_id( test_sim.sim_id ) == services.current_zone_id(): run_affordance = roommate_service.get_ss3_affordance( ) if run_affordance is not None: self.special_case_sims[ test_sim] = run_affordance return True else: roommate_service = services.get_roommate_service() if roommate_service is not None and roommate_service.get_home_zone_id( test_sim.sim_id) == services.current_zone_id(): run_affordance = roommate_service.get_ss3_affordance( ) if run_affordance is not None: self.special_case_sims[ test_sim] = run_affordance return True return False sims = services.sim_info_manager().instanced_sims_gen( allow_hidden_flags=ALL_HIDDEN_REASONS) should_change_speed = all( validate_household_sim(sim) or sim.is_npc and not on_lot_check(sim) for sim in sims) if should_change_speed: self.handle_special_case_sims() return should_change_speed self.interaction.register_on_cancelled_callback( self._remove_liability) for (situation_id, speed_request, callback_fn) in tuple( self.situation_speed_request_data.values()): situation_manager.unregister_callback( situation_id, SituationCallbackOption.END_OF_SITUATION, callback_fn) del self.situation_speed_request_data[situation_id] def situation_ended_callback(ended_situation_id, _callback_option, _data, request, situation_speed_requests): services.game_clock_service().remove_request(request) if ended_situation_id in situation_speed_requests: del situation_speed_requests[ended_situation_id] for situation in situation_manager.running_situations(): if not situation.blocks_super_speed_three: continue if not situation.super_speed3_replacement_speed: continue replacement_request = services.game_clock_service().push_speed( situation.super_speed3_replacement_speed, validity_check=lambda s=situation: s in situation_manager. running_situations() and validity_check( situations_to_ignore=(s, )), reason='Situation alternate SS3 speed request') situation_id = situation.id callback_fn = functools.partial( situation_ended_callback, request=replacement_request, situation_speed_requests=self.situation_speed_request_data) situation_manager.register_for_callback( situation_id, SituationCallbackOption.END_OF_SITUATION, callback_fn) self.situation_speed_request_data[situation_id] = ( situation_id, replacement_request, callback_fn) else: validity_check = None self.speed_request = services.game_clock_service().push_speed( self.new_game_speed, validity_check=validity_check, reason='SS3 interaction')