Exemplo n.º 1
0
 def on_update(self):
     super().on_update()
     if not services.sim_spawner_service().batch_spawning_complete:
         return _ZoneSpinUpStateResult.WAITING
     client = services.client_manager().get_first_client()
     services.sim_info_manager().on_spawn_sim_for_zone_spin_up_completed(
         client)
     services.venue_service().get_zone_director(
     ).on_spawn_sim_for_zone_spin_up_completed()
     services.current_zone(
     ).venue_service.handle_active_lot_changing_edge_cases()
     services.get_zone_situation_manager(
     ).on_all_sims_spawned_during_zone_spin_up()
     club_service = services.get_club_service()
     if club_service is not None:
         club_service.on_finish_waiting_for_sim_spawner_service()
     else:
         current_zone_id = services.current_zone_id()
         household = services.active_household()
         if household.home_zone_id != current_zone_id:
             sim_info_manager = services.sim_info_manager()
             traveled_sims = sim_info_manager.get_traveled_to_zone_sim_infos(
             )
             if len(traveled_sims) > 1:
                 services.ensemble_service(
                 ).create_travel_ensemble_if_neccessary(traveled_sims)
     services.ensemble_service().on_all_sims_spawned_during_zone_spin_up()
     return _ZoneSpinUpStateResult.DONE
Exemplo n.º 2
0
 def _do_behavior(self, *args, **kwargs):
     subject = self.interaction.get_participant(self.subject)
     if subject is None:
         logger.error(
             "DestroyEnsemble: Trying to destroy a non-existent Sim's ensemble."
         )
         return
     services.ensemble_service().destroy_sims_ensemble(
         self.ensemble_type, subject)
Exemplo n.º 3
0
 def _do_behavior(self, *args, **kwargs):
     subject = self.interaction.get_participant(self.subject)
     if subject is None:
         logger.error(
             'RemoveFromEnsemble: Trying to remove a non-existent Sim from an ensemble.'
         )
         return
     services.ensemble_service().remove_sim_from_ensemble(
         self.ensemble_type, subject)
Exemplo n.º 4
0
 def _do_behavior(self, *args, **kwargs):
     actor = self.interaction.get_participant(self.actor)
     if actor is None:
         logger.error(
             "AddToEnsemble: Trying to add actor Sim who doesn't exist.")
         return
     target = self.interaction.get_participant(self.target)
     if target is None:
         logger.error(
             "AddToEnsemble: Trying to add target Sim who doesn't exist.")
         return
     services.ensemble_service().create_ensemble(self.ensemble_type,
                                                 (actor, target))
Exemplo n.º 5
0
def get_default_selection_data(actor_sim, filter_list):
    default_selection_data = []
    club_service = services.get_club_service()
    ensemble_service = services.ensemble_service()
    gathering = None
    ensemble = None
    if club_service is not None:
        gathering = club_service.sims_to_gatherings_map.get(actor_sim)
    if ensemble_service is not None:
        ensembles = ensemble_service.get_all_ensembles_for_sim(actor_sim)
    familiar_tracker = actor_sim.sim_info.familiar_tracker
    active_familiar_sim_id = None
    if familiar_tracker is not None:
        active_familiar_sim_id = familiar_tracker.active_familiar_id_pet_id
    for item in filter_list:
        sim_info = item.sim_info
        if sim_info.sim_id == active_familiar_sim_id:
            default_selection_data.append((sim_info, True))
        else:
            sim = sim_info.get_sim_instance()
            if sim is not None and (gathering and club_service.sims_to_gatherings_map.get(sim) is gathering or ensembles and any(sim in ensemble for ensemble in ensembles)):
                default_selection_data.append((sim_info, True))
            else:
                default_selection_data.append((sim_info, False))
    default_selection_data.sort(key=operator.itemgetter(1), reverse=True)
    return default_selection_data
Exemplo n.º 6
0
 def maybe_bring_group_along(self, **kwargs):
     if not self.should_rally:
         return
     anchor_object = self.target
     if anchor_object is not None:
         if anchor_object.is_part:
             anchor_object = anchor_object.part_owner
     if RallySource.SOCIAL_GROUP in self.rally_sources:
         main_group = self.sim.get_visible_group()
         if main_group:
             main_group.try_relocate_around_focus(self.sim,
                                                  priority=self.priority)
             for sim in main_group:
                 if sim is not self.sim:
                     self._do_rally_behavior(sim,
                                             main_group.get_constraint(sim))
     else:
         main_group = None
     if RallySource.ENSEMBLE in self.rally_sources:
         ensemble_sims = services.ensemble_service(
         ).get_ensemble_sims_for_rally(self.sim)
         if ensemble_sims:
             main_group_sims = set(
                 main_group) if main_group else singletons.EMPTY_SET
             ensemble_sims -= main_group_sims
             for sim in ensemble_sims:
                 if sim is not self.sim:
                     self._do_rally_behavior(sim, None)
Exemplo n.º 7
0
 def should_rally(self):
     if self._from_rally_interaction is None:
         if RallySource.SOCIAL_GROUP in self.rally_sources:
             main_group = self.sim.get_visible_group()
             if main_group is not None and not main_group.is_solo:
                 return True
             elif RallySource.ENSEMBLE in self.rally_sources:
                 ensemble_sims = services.ensemble_service(
                 ).get_ensemble_sims_for_rally(self.sim)
                 if ensemble_sims:
                     return True
         elif RallySource.ENSEMBLE in self.rally_sources:
             ensemble_sims = services.ensemble_service(
             ).get_ensemble_sims_for_rally(self.sim)
             if ensemble_sims:
                 return True
     return False
Exemplo n.º 8
0
 def _on_update(self):
     with Context(self.layer) as layer:
         for ensemble in services.ensemble_service().get_all_ensembles():
             color = pseudo_random_color(ensemble.guid)
             if ensemble.last_center_of_mass is None:
                 continue
             layer.add_circle(ensemble.last_center_of_mass,
                              radius=math.sqrt(
                                  ensemble.max_ensemble_radius),
                              color=color)
             for sim in ensemble:
                 layer.add_circle(sim.position, radius=0.3, color=color)
Exemplo n.º 9
0
 def _on_set_sim_job(self, sim, job_type):
     super()._on_set_sim_job(sim, job_type)
     if job_type is self.leader_job:
         for sim_info_id in sim.sim_info.squad_members:
             request = BouncerRequest(
                 self,
                 callback_data=_RequestUserData(),
                 requested_sim_id=sim_info_id,
                 job_type=self.squad_member_job,
                 request_priority=BouncerRequestPriority.BACKGROUND_HIGH,
                 user_facing=False,
                 exclusivity=self.exclusivity)
             self.manager.bouncer.submit_request(request)
     else:
         if self._ensemble is None:
             services.ensemble_service().create_ensemble(
                 self.ensemble_type, self._situation_sims.keys())
             self._ensemble = services.ensemble_service(
             ).get_ensemble_for_sim(self.ensemble_type, sim)
         else:
             self._ensemble.add_sim_to_ensemble(sim)
         if job_type.job_uniform is None:
             self._fixup_sims_outfit(sim)
Exemplo n.º 10
0
 def sim_breaking_curfew(self, sim, target, interaction=None):
     if interaction is not None and self.interaction_blacklisted(
             interaction):
         return False
     if sim.sim_info.is_in_travel_group():
         return False
     situation_manager = services.get_zone_situation_manager()
     sim_situations = situation_manager.get_situations_sim_is_in(sim)
     if any(situation.disallows_curfew_violation
            for situation in sim_situations):
         return False
     active_household = services.active_household()
     if active_household is None:
         return False
     home_zone_id = active_household.home_zone_id
     curfew_setting = self._zone_curfew_data.get(home_zone_id,
                                                 CurfewService.UNSET)
     if sim.sim_info not in active_household:
         return False
     if curfew_setting is not CurfewService.UNSET:
         if sim.sim_info.is_young_adult_or_older:
             return False
         elif self.past_curfew(curfew_setting):
             if not services.current_zone_id() == home_zone_id:
                 ensemble_service = services.ensemble_service()
                 ensemble = ensemble_service.get_visible_ensemble_for_sim(
                     sim)
                 if ensemble is not None and any(
                         sim.sim_info.is_young_adult_or_older
                         and sim.sim_info in active_household
                         for sim in ensemble):
                     return False
                 return True
             if target is not None and not target.is_in_inventory(
             ) and not services.active_lot().is_position_on_lot(
                     target.position):
                 return True
             elif target is None and not services.active_lot(
             ).is_position_on_lot(sim.position):
                 return True
         return True
         if target is not None and not target.is_in_inventory(
         ) and not services.active_lot().is_position_on_lot(
                 target.position):
             return True
         elif target is None and not services.active_lot(
         ).is_position_on_lot(sim.position):
             return True
     return False
Exemplo n.º 11
0
 def get_jig_definition(self):
     owner_sim = self.initiating_sim_info.get_sim_instance()
     ensemble_sims = services.ensemble_service(
     ).get_ensemble_sims_for_rally(owner_sim)
     sim_filter_service = services.sim_filter_service()
     filter_result_list = sim_filter_service.submit_filter(
         self.dance_member_job.filter,
         None,
         allow_yielding=False,
         sim_constraints=[sim.id for sim in ensemble_sims],
         requesting_sim_info=self.initiating_sim_info,
         gsi_source_fn=self.get_sim_filter_gsi_name)
     num_of_sims = len(filter_result_list)
     if num_of_sims not in self.jig_map:
         logger.error('Try to get jig for {} sims, which is not supported',
                      num_of_sims)
     return self.jig_map.get(num_of_sims, None)
Exemplo n.º 12
0
 def create_auto_ensembles(self):
     ensemble_service = services.ensemble_service()
     rel_tracker = self.owner.relationship_tracker
     for (relationship_bit,
          ensemble_type) in self._rel_bit_ensembles.items():
         target_sims = []
         for target in rel_tracker.get_target_sim_infos():
             if target is None:
                 continue
             target_instance = target.get_sim_instance()
             if target_instance is None:
                 continue
             if not rel_tracker.has_bit(target.sim_id, relationship_bit):
                 continue
             target_sims.append(target_instance)
         if not target_sims:
             pass
         else:
             target_sim = max(
                 target_sims,
                 key=lambda s: ensemble_service.get_ensemble_for_sim(
                     ensemble_type, s) is not None)
             ensemble_service.create_ensemble(ensemble_type,
                                              (self.owner, target_sim))
Exemplo n.º 13
0
 def build_relationship_bonuses(sim,
                                sim_affinity_posture_scoring_data,
                                sims_to_consider=None):
     bonuses = {}
     posture_graph = services.current_zone().posture_graph_service
     if not sims_to_consider:
         sims_to_consider = (
             other_sim_info.get_sim_instance()
             for other_sim_info in services.sim_info_manager().objects
             if other_sim_info.is_instanced())
     obj_to_cluster = {}
     clusters = list(
         services.social_group_cluster_service().get_clusters_gen())
     for cluster in clusters:
         for obj in cluster.objects_gen():
             obj_to_cluster[obj] = cluster
     relationship_tracker = sim.relationship_tracker
     most_important_ensemble = services.ensemble_service(
     ).get_most_important_ensemble_for_sim(sim)
     for other_sim in sims_to_consider:
         if other_sim is sim:
             continue
         if other_sim.posture.unconstrained:
             continue
         if other_sim.is_moving:
             continue
         if not other_sim.posture.allow_affinity:
             continue
         scores = []
         zone_director = services.venue_service().get_zone_director()
         if sim_affinity_posture_scoring_data is not None:
             if not zone_director.disable_sim_affinity_posture_scoring(sim):
                 tags = set()
                 for si in other_sim.si_state:
                     if si.sim_affinity_posture_scoring_data is not None:
                         tags.update(
                             si.sim_affinity_posture_scoring_data.my_tags)
                 for scoring_strategy in sim_affinity_posture_scoring_data.my_scoring:
                     match_tag = scoring_strategy.running_interaction_tag
                     if match_tag == InteractionPostureAffinityTag.ALL:
                         match = True
                     else:
                         match = (match_tag
                                  in tags) != scoring_strategy.negate_tag
                     if not match:
                         continue
                     (affinity,
                      message) = scoring_strategy.affinity_strategy(
                          sim, other_sim)
                     if not affinity:
                         continue
                     scores.append((affinity, message))
         if most_important_ensemble is not None and most_important_ensemble.is_sim_in_ensemble(
                 other_sim):
             scores.append((-PostureScoring.ENSEMBLE_BONUS,
                            PostureScoring.ENSEMBLE_BONUS_MESSAGE))
         elif not zone_director.disable_sim_affinity_posture_scoring(
                 sim) and not relationship_tracker.has_bit(
                     other_sim.sim_id,
                     RelationshipGlobalTuning.HAS_MET_RELATIONSHIP_BIT):
             scores.append((PostureScoring.HAS_NOT_MET_PENALTY,
                            PostureScoring.HAS_NOT_MET_COST_MESSAGE))
         if not scores:
             pass
         else:
             other_sim_cluster = None
             other_sim_body_target = other_sim.posture_state.body_target
             if other_sim_body_target is not None:
                 if other_sim_body_target.is_part:
                     other_sim_body_target = other_sim_body_target.part_owner
                 other_sim_cluster = obj_to_cluster.get(
                     other_sim_body_target)
             other_sim_facing = sims4.math.yaw_quaternion_to_angle(
                 other_sim.transform.orientation)
             distances = {}
             nodes_in_sight = posture_graph.nodes_matching_constraint_geometry(
                 other_sim.los_constraint)
             for goal_node in nodes_in_sight:
                 goal_body = goal_node[postures.posture_specs.BODY_INDEX]
                 goal_body_target = goal_body[
                     postures.posture_specs.BODY_TARGET_INDEX]
                 goal_posture_type = goal_body[
                     postures.posture_specs.BODY_POSTURE_TYPE_INDEX]
                 if not goal_body_target is None:
                     if goal_posture_type.mobile:
                         continue
                     distance = distances.get(goal_body_target)
                     if distance is None:
                         sim_facing = sims4.math.yaw_quaternion_to_angle(
                             goal_body_target.transform.orientation)
                         accum = accumulator.HarmonicMeanAccumulator()
                         delta = other_sim.transform.translation - goal_body_target.transform.translation
                         socials.geometry.score_facing(
                             accum, sim_facing, other_sim_facing, delta)
                         facing_score = accum.value()
                         if facing_score <= 0:
                             continue
                         distance = (goal_body_target.position -
                                     other_sim.position).magnitude_2d()
                         distance = max(distance, 1)
                         distance /= facing_score
                         distances[goal_body_target] = distance
                     bonus = 0
                     all_messages = []
                     distance_modifier = RelationshipSimAffinityStrategy.DISTANCE_TO_IMPACT_CURVE.get(
                         distance)
                     for (affinity, message) in scores:
                         affinity_weighted = affinity * distance_modifier
                         bonus += affinity_weighted
                     if not bonus:
                         pass
                     else:
                         if goal_body_target.is_part:
                             goal_object = goal_body_target.part_owner
                         else:
                             goal_object = goal_body_target
                         if goal_object in obj_to_cluster:
                             same_cluster = obj_to_cluster[
                                 goal_object] is other_sim_cluster
                         else:
                             same_cluster = False
                         if same_cluster:
                             bonus *= PostureScoring.SAME_CLUSTER_SIM_MULTIPLIER
                         current_bonus_info = bonuses.get(goal_body_target)
                         if not current_bonus_info is None:
                             if bonus < current_bonus_info[0]:
                                 formatted_message = ''
                                 bonuses[goal_body_target] = (
                                     bonus, formatted_message)
                         formatted_message = ''
                         bonuses[goal_body_target] = (bonus,
                                                      formatted_message)
     obj_to_cluster.clear()
     return bonuses
Exemplo n.º 14
0
def remove_sim_from_ensemble(ensemble_type:TunableInstanceParam(sims4.resources.Types.ENSEMBLE), sim:RequiredTargetParam, _connection=None):
    services.ensemble_service().remove_sim_from_ensemble(ensemble_type, sim.get_target())
    sims4.commands.output('Removed {} from ensembles.'.format(sim.get_target()), _connection)
Exemplo n.º 15
0
 def stop(self):
     services.ensemble_service().on_ensemble_center_of_mass_changed.remove(
         self._on_update)
Exemplo n.º 16
0
 def _start(self):
     services.ensemble_service().on_ensemble_center_of_mass_changed.append(
         self._on_update)
     self._on_update()
Exemplo n.º 17
0
def create_ensemble(ensemble_type:TunableInstanceParam(sims4.resources.Types.ENSEMBLE), *sims:RequiredTargetParam, _connection=None):
    ensemble_sims = [sim.get_target() for sim in sims]
    services.ensemble_service().create_ensemble(ensemble_type, ensemble_sims)
    sims4.commands.output('Created Ensemble with sims {}'.format(ensemble_sims), _connection)