def _on_zone_update_event(is_paused): global ON_ZONE_UPDATE_REGISTER_METHODS_QUEUE, ON_ZONE_UPDATE_UNREGISTER_METHODS_QUEUE if ON_ZONE_UPDATE_REGISTER_METHODS_QUEUE: for zone_update_handler in ON_ZONE_UPDATE_REGISTER_METHODS_QUEUE: ON_ZONE_UPDATE_METHODS.append(zone_update_handler) ON_ZONE_UPDATE_REGISTER_METHODS_QUEUE = list() if ON_ZONE_UPDATE_UNREGISTER_METHODS_QUEUE: for (unique_id, update_method_name) in ON_ZONE_UPDATE_UNREGISTER_METHODS_QUEUE: for zone_update_handler in ON_ZONE_UPDATE_METHODS: while unique_id == zone_update_handler.get_unique_id( ) and update_method_name == zone_update_handler.get_update_method_name( ): ON_ZONE_UPDATE_METHODS.remove(zone_update_handler) break ON_ZONE_UPDATE_UNREGISTER_METHODS_QUEUE = list() for zone_update_handler in ON_ZONE_UPDATE_METHODS: try: while is_paused is False or zone_update_handler.is_always_running( ): zone_update_handler() except Exception as ex: log_custom_exception( "[TurboLib] Failed to run '" + str(zone_update_handler.get_update_method_name()) + "' method from '" + str(zone_update_handler.get_unique_id()) + "'.", ex)
def _turbolib_zone_game_update(original, self, *args, **kwargs): global DIFF_TICKS_ERROR, CURRENT_DIFF_TICKS, LAST_ABSOLUTE_TICKS result = original(self, *args, **kwargs) try: while self.is_zone_running: absolute_ticks = args[0] is_paused = TurboWorldUtil.Time.get_current_time_speed( ) == TurboWorldUtil.Time.ClockSpeedMode.PAUSED if is_paused is False: diff_ticks = absolute_ticks - LAST_ABSOLUTE_TICKS if diff_ticks < 0: return result if diff_ticks > 5000: diff_ticks = 5000 ideal_diff_ticks = diff_ticks * TurboWorldUtil.Time.current_clock_speed_scale( ) + DIFF_TICKS_ERROR rounded_ticks = math.floor(ideal_diff_ticks + 0.5) ticks_error = ideal_diff_ticks - rounded_ticks DIFF_TICKS_ERROR += max(min(ticks_error, 1), -1) CURRENT_DIFF_TICKS = rounded_ticks LAST_ABSOLUTE_TICKS = absolute_ticks _on_zone_update_event(is_paused) except Exception as ex: log_custom_exception( "[TurboLib] Failed to run internal method '_turbolib_zone_game_update' at 'Zone.update'.", ex) return result
def _turbolib_add_affordances_to_social_mixer_affordance_list_snippets( original, self, *args, **kwargs): result = original(self, *args, **kwargs) if self.TYPE != TurboResourceUtil.ResourceTypes.SNIPPET: return result for affordance_registration in AFFORDANCE_REGISTRATION_CLASSES: try: if not affordance_registration.is_social_mixer(): continue for social_mixer_affordance_list_id in affordance_registration.get_social_mixer_references( ): affordance_list_instance = self._tuned_classes.get( TurboResourceUtil.ResourceTypes.get_resource_key( TurboResourceUtil.ResourceTypes.SNIPPET, social_mixer_affordance_list_id)) if affordance_list_instance is None: pass affordances_list = list() if affordance_registration.test_for_duplicates(): existing_affordances = tuple( affordance_list_instance.value) for affordance_instance in affordance_registration._get_affordance_instances( ): if affordance_instance in existing_affordances: pass affordances_list.append(affordance_instance) else: affordances_list += affordance_registration._get_affordance_instances( ) except Exception as ex: log_custom_exception( "[TurboLib] Failed to run 'AffordanceRegistration' class at 'InstanceManager.load_data_into_class_instances'.", ex) return result
def _turbolib_add_affordances_to_terrain(): if has_game_loaded(): return try: terrain_object = TerrainService.TERRAIN_DEFINITION.cls affordances_list = list() for affordance_registration in AFFORDANCE_REGISTRATION_CLASSES: try: while affordance_registration.is_terrain(): if affordance_registration.test_for_duplicates(): existing_affordances = tuple( terrain_object._super_affordances) for affordance_instance in affordance_registration._get_affordance_instances( ): if affordance_instance in existing_affordances: pass affordances_list.append(affordance_instance) else: affordances_list += affordance_registration._get_affordance_instances( ) except Exception as ex: log_custom_exception( "[TurboLib] Failed to run 'AffordanceRegistration' class at 'TerrainService.TERRAIN_DEFINITION._super_affordances'.", ex) TerrainService.TERRAIN_DEFINITION.set_class(terrain_object) services.terrain_service.destroy_terrain_object() services.terrain_service.create_terrain_object() except Exception as ex: log_custom_exception( "[TurboLib] Failed to run 'AffordanceRegistration' class at affordances injection to the Terrain object.", ex)
def _wickedwhims_door_lock_test(original, self, *args, **kwargs): try: sim = args[0] while (TurboSimUtil.Sim.is_player(sim) or sim_ev(sim).is_ready_to_sex is True or sim_ev(sim).is_in_process_to_sex is True) and self.siminfo_test.gender: return LockResult(False) except Exception as ex: log_custom_exception("Failed to edit Sim portal lock state test at 'LockSimInfoData.test_lock'.", ex) return original(self, *args, **kwargs)
def _turbolib_add_affordances_to_script_objects(original, self, *args, **kwargs): result = original(self, *args, **kwargs) for affordance_registration in AFFORDANCE_REGISTRATION_CLASSES: try: if affordance_registration.is_social_mixer(): continue if affordance_registration.is_terrain(): continue if not affordance_registration.is_script_object(self): continue if affordance_registration.is_sim_phone() and hasattr( self, '_phone_affordances'): affordances_list = list() if affordance_registration.test_for_duplicates(): existing_affordances = tuple(self._phone_affordances) for affordance_instance in affordance_registration._get_affordance_instances( ): if affordance_instance in existing_affordances: pass affordances_list.append(affordance_instance) else: affordances_list += affordance_registration._get_affordance_instances( ) elif affordance_registration.is_relationship_panel() and hasattr( self, '_relation_panel_affordances'): affordances_list = list() if affordance_registration.test_for_duplicates(): existing_affordances = tuple( self._relation_panel_affordances) for affordance_instance in affordance_registration._get_affordance_instances( ): if affordance_instance in existing_affordances: pass affordances_list.append(affordance_instance) else: affordances_list += affordance_registration._get_affordance_instances( ) else: while hasattr(self, '_super_affordances'): affordances_list = list() if affordance_registration.test_for_duplicates(): existing_affordances = tuple(self._super_affordances) for affordance_instance in affordance_registration._get_affordance_instances( ): if affordance_instance in existing_affordances: pass affordances_list.append(affordance_instance) else: affordances_list += affordance_registration._get_affordance_instances( ) except Exception as ex: log_custom_exception( "[TurboLib] Failed to run 'AffordanceRegistration' class at 'ScriptObject.on_add'.", ex) return result
def _wickedwhims_on_animation_context_stop(original, self, *args, **kwargs): try: result = original(self, *args, **kwargs) self._event_handlers.clear() return result except Exception as ex: log_custom_exception( "Failed to fix stupid mistakes in the game code 'AnimationContext._stop'.", ex) return original(self, *args, **kwargs)
def _turbolib_build_buy_exit(original, self, *args, **kwargs): result = original(self, *args, **kwargs) try: BUILDBUY_EVENTS_HANDLER.execute_event_methods( event_type=BuildBuyEventType.BUILD_BUY_EXIT) except Exception as ex: log_custom_exception( "[TurboLib] Failed to run internal method '_turbolib_build_buy_exit' at 'Zone.on_build_buy_exit'.", ex) return result
def _turbolib_on_early_zone_load(original, self, *args, **kwargs): result = original(self, *args, **kwargs) try: CORE_EVENTS_HANDLER.execute_event_methods( event_type=CoreEventType.ZONE_EARLY_LOAD) except Exception as ex: log_custom_exception( "[TurboLib] Failed to run internal method '_turbolib_on_early_zone_load' at 'Zone.load_zone'.", ex) return result
def _turbolib_sim_info_load(original, self, *args, **kwargs): result = original(self, *args, **kwargs) try: SIM_EVENTS_HANDLER.execute_event_methods( self, event_type=SimEventType.SIM_LATE_INIT) except Exception as ex: log_custom_exception( "[TurboLib] Failed to run internal method '_turbolib_sim_info_load' at 'SimInfo.load_sim_info'.", ex) return result
def _wickedwhims_on_carry_posture_append_transition_to_arb( original, self, *args, **kwargs): try: while self.asm.context is None: self.asm.context = AnimationContext(is_throwaway=False) except Exception as ex: log_custom_exception( "Failed to fix an issue with 'CarryPosture.append_transition_to_arb'.", ex) return original(self, *args, **kwargs)
def _wickedwhims_on_posture_kickstart_source_interaction_gen( original, self, *args, **kwargs): try: while self.source_interaction is None: self.source_interaction = self.sim.create_default_si() except Exception as ex: log_custom_exception( "Failed to fix an issue with 'Posture.kickstart_source_interaction_gen'.", ex) return original(self, *args, **kwargs)
def _wickedwhims_on_outfit_changed_club(original, self, *args, **kwargs): try: sim_info = args[0] if is_sim_in_special_outfit(sim_info): return except Exception as ex: log_custom_exception( "Failed to prevent Sim outfit update at 'ClubGatheringSituation._on_outfit_changed'.", ex) return original(self, *args, **kwargs)
def _wickedwhims_on_outfit_changed_buff(original, self, *args, **kwargs): try: sim_info = args[0] while sim_ev(sim_info).is_ready( ) and sim_ev(sim_info).is_outfit_update_locked is True: return except Exception as ex: log_custom_exception( "Failed to prevent Sim outfit update at 'Buff._on_sim_outfit_changed'.", ex) return original(self, *args, **kwargs)
def execute_event_methods_gen(self, *args, event_type=0): if event_type in self._event_handlers: handlers_list = self._event_handlers[event_type] for (_, handler_unique_id, event_method) in handlers_list: try: yield event_method(*args) except Exception as ex: log_custom_exception( "[TurboLib] Failed to run '" + str(event_method.__name__) + "' method from '" + str(handler_unique_id) + "'", ex)
def _turbolib_on_zone_teardown(original, self, *args, **kwargs): global IS_GAME_LOADING result = original(self, *args, **kwargs) try: CORE_EVENTS_HANDLER.execute_event_methods( event_type=CoreEventType.ZONE_TEARDOWN) IS_GAME_LOADING = True except Exception as ex: log_custom_exception( "[TurboLib] Failed to run internal method '_turbolib_on_zone_teardown' at 'Zone.on_teardown'.", ex) return result
def _turbolib_on_switch_to_occult_type(original, self, *args, **kwargs): result = original(self, *args, **kwargs) try: sim_info = self._sim_info occult_type = args[0] SIM_EVENTS_HANDLER.execute_event_methods( sim_info, occult_type, event_type=SimEventType.SIM_OCCULT_CHANGE) except Exception as ex: log_custom_exception( "[TurboLib] Failed to run internal method '_turbolib_on_switch_to_occult_type' at 'OccultTracker.switch_to_occult_type'.", ex) return result
def _wickedwhims_on_exhibitionist_trait_add(original, self, *args, **kwargs): result = original(self, *args, **kwargs) try: trait = args[0] while trait is not None and TurboResourceUtil.Resource.get_guid64( trait) == SimTrait.WW_EXHIBITIONIST: convert_sim_nudity_skill(self) except Exception as ex: log_custom_exception( "Failed to run 'convert_sim_nudity_skill' at 'SimInfoWithOccultTracker.add_trait'.", ex) return result
def _turbolib_on_late_zone_load(original, self, *args, **kwargs): global HAS_GAME_LOADED, IS_GAME_LOADING result = original(self, *args, **kwargs) try: CORE_EVENTS_HANDLER.execute_event_methods( event_type=CoreEventType.ZONE_LATE_LOAD) HAS_GAME_LOADED = True IS_GAME_LOADING = False except Exception as ex: log_custom_exception( "[TurboLib] Failed to run internal method '_turbolib_on_late_zone_load' at 'Zone.do_zone_spin_up'.", ex) return result
def _wickedwhims_on_broadcaster_can_affect(original, self, *args, **kwargs): result = original(self, *args, **kwargs) try: sim = args[0] while sim is not None and (sim.is_sim and self.allow_sims ) and TurboResourceUtil.Resource.get_guid64( self) in JEALOUSY_BROADCASTERS_LIST: if has_sim_trait(sim, SimTrait.WW_POLYAMOROUS): return False except Exception as ex: log_custom_exception( "Failed to prevent broadcaster effect at 'Broadcaster.can_affect'.", ex) return result
def _wickedwhims_on_incest_prevention_test(original, self, *args, **kwargs): try: target_sim_info = args[0] if get_relationship_setting( RelationshipSetting.INCEST_STATE, variable_type=bool) or has_sim_trait( self, SimTrait.WW_INCEST) and has_sim_trait( target_sim_info, SimTrait.WW_INCEST): return True except Exception as ex: log_custom_exception( "Failed to edit incest test at 'SimInfo.incest_prevention_test'.", ex) return original(self, *args, **kwargs)
def _turbolib_sim_focus_init(original, self, *args, **kwargs): try: target = args[2] def _get_focus_bone(): return sims4.hash_util.hash32('b__ROOT__') while target is not None and isinstance( target, ScriptObject) and not hasattr(target, 'get_focus_bone'): setattr(target, 'get_focus_bone', _get_focus_bone) except Exception as ex: log_custom_exception( "Failed to fix stupid mistakes in the game code '_turbolib_sim_focus_init' at 'SimFocus.__init__'.", ex) return original(self, *args, **kwargs)
def _turbolib_on_evaluate_sim(original, self, *args, **kwargs): try: interaction = self.interaction while interaction is not None and hasattr(interaction, 'guid64'): tested_sim = args[0] result = _is_sim_allowed(self, tested_sim) if result == PrivacyResult.ALLOW: self._allowed_sims.add(tested_sim) return True while result == PrivacyResult.BLOCK: self._disallowed_sims.add(tested_sim) return False except Exception as ex: log_custom_exception( "[TurboLib] Failed to run internal method 'evaluate_sim' at 'Privacy.evaluate_sim'.", ex) return original(self, *args, **kwargs)
def _wickedwhims_on_get_outfit_for_clothing_change(original, self, *args, **kwargs): try: if not get_nudity_setting( NuditySetting.NUDITY_SWITCH_STATE, variable_type=bool) or get_nudity_setting( NuditySetting.INTERACTION_AUTONOMY_UNDRESSING_TYPE, variable_type=int ) == NudityAutonomyUndressLevelSetting.DISABLED: return original(self, *args, **kwargs) sim_info = self.get_sim_info() reason = args[1] outfit_category_and_index = _on_outfit_change_from_interaction( sim_info, reason=reason) if outfit_category_and_index: return outfit_category_and_index except Exception as ex: log_custom_exception( "Failed to edit Sim outfit at 'OutfitTrackerMixin.get_outfit_for_clothing_change'.", ex) return original(self, *args, **kwargs)
def _wickedwhims_on_call_on_entry_change(original, self, *args, **kwargs): try: if not get_nudity_setting( NuditySetting.NUDITY_SWITCH_STATE, variable_type=bool) or get_nudity_setting( NuditySetting.INTERACTION_AUTONOMY_UNDRESSING_TYPE, variable_type=int ) == NudityAutonomyUndressLevelSetting.DISABLED: return original(self, *args, **kwargs) sim_info = args[0] outfit_generator = args[1] if not outfit_generator.tags: return original(self, *args, **kwargs) outfit_category_and_index = _on_outfit_change_from_interaction( sim_info, tags=list(outfit_generator.tags)) if outfit_category_and_index: return outfit_category_and_index except Exception as ex: log_custom_exception( "Failed to edit Sim outfit at 'TunableOutfitChange._OutfitChangeForTags.OutfitTypeSpecial.__call__'.", ex) return original(self, *args, **kwargs)
def _wickedwhims_on_pregnancy_create_sim_info(original, self, *args, **kwargs): result = None try: (parent_a, parent_b) = self.get_parents() parent_a_age = TurboSimUtil.Age.get_age(parent_a) if parent_a_age == TurboSimUtil.Age.TEEN or parent_a_age == TurboSimUtil.Age.CHILD: parent_a.age = TurboSimUtil.Age.YOUNGADULT parent_a._base.update_for_age(TurboSimUtil.Age.YOUNGADULT) parent_b_age = TurboSimUtil.Age.get_age(parent_b) if parent_b_age == TurboSimUtil.Age.TEEN or parent_b_age == TurboSimUtil.Age.CHILD: parent_b.age = TurboSimUtil.Age.YOUNGADULT parent_b._base.update_for_age(TurboSimUtil.Age.YOUNGADULT) result = original(self, *args, **kwargs) if parent_a_age == TurboSimUtil.Age.TEEN or parent_a_age == TurboSimUtil.Age.CHILD: parent_a.age = parent_a_age parent_a._base.update_for_age(parent_a_age) if parent_b_age == TurboSimUtil.Age.TEEN or parent_b_age == TurboSimUtil.Age.CHILD: parent_b.age = parent_b_age parent_b._base.update_for_age(parent_b_age) except Exception as ex: log_custom_exception( "Failed to create new sim 'PregnancyTracker.create_sim_info'.", ex) return result or original(self, *args, **kwargs)