def get_score(self, position, orientation, routing_surface):
     target_sim = self._target_sim_ref() if self._target_sim_ref is not None else None
     if target_sim is None:
         return 1
     accum = accumulator.HarmonicMeanAccumulator()
     candidate_facing = sims4.math.yaw_quaternion_to_angle(orientation)
     other_facing = sims4.math.yaw_quaternion_to_angle(target_sim.intended_transform.orientation)
     delta = target_sim.intended_transform.translation - position
     socials.geometry.score_facing(accum, candidate_facing, other_facing, delta)
     return accum.value()
Example #2
0
def score_transform(transform, sim, group_geometry, r, base_focus, base_field):
    accum = accumulator.HarmonicMeanAccumulator()
    dist = group_geometry.minimum_distance(transform.translation,
                                           group_geometry.members,
                                           skip=sim)
    in_group_dist_score = SocialGeometry.GROUP_DISTANCE_CURVE.get(dist)
    accum.add(in_group_dist_score)
    if accum.fault():
        return 0
    candidate_geometry = create_from_transform(transform, base_focus,
                                               base_field, r)
    candidate_area = candidate_geometry.field.area()
    if candidate_area <= sims4.math.EPSILON:
        return 0
    candidate_facing = sims4.math.yaw_quaternion_to_angle(
        transform.orientation)
    for (other_sim, geometry) in group_geometry.members.items():
        if other_sim is sim:
            continue
        other_facing = sims4.math.yaw_quaternion_to_angle(
            geometry.transform.orientation)
        delta = geometry.transform.translation - transform.translation
        score_facing(accum, candidate_facing, other_facing, delta)
        intersection = geometry.field.intersect(candidate_geometry.field)
        fraction = intersection.area() / candidate_area
        fraction = SocialGeometry.OVERLAP_SCORE_MULTIPLIER * max(
            fraction, SocialGeometry.NON_OVERLAPPING_SCORE_MULTIPLIER)
        accum.add(fraction)
        if accum.fault():
            return 0
    nearby_non_members = list(
        placement.get_nearby_sims_gen(transform.translation,
                                      sim.routing_surface,
                                      exclude=group_geometry,
                                      check_all_surfaces_on_level=True))
    if sim in nearby_non_members:
        nearby_non_members.remove(sim)
    if nearby_non_members:
        nearest = group_geometry.minimum_distance(transform.translation,
                                                  nearby_non_members)
        not_in_group_score = SocialGeometry.NON_GROUP_DISTANCE_CURVE.get(
            nearest)
        accum.add(not_in_group_score)
    return accum.value()
Example #3
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
Example #4
0
 def build_relationship_bonuses(sim,
                                sim_affinity_posture_scoring_data,
                                sims_to_consider=None):
     if sim_affinity_posture_scoring_data is None:
         return
     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
     for other_sim in sims_to_consider:
         if other_sim is sim:
             pass
         if other_sim.posture.unconstrained:
             pass
         if other_sim.is_moving:
             pass
         if not other_sim.posture.allow_affinity:
             pass
         scores = []
         other_sim_cluster = None
         other_sim_body_target = other_sim.posture_state.body_target
         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)
         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 = False
                 for si in other_sim.si_state:
                     while si.sim_affinity_posture_scoring_data is not None and match_tag in si.sim_affinity_posture_scoring_data.my_tags:
                         if not scoring_strategy.negate_tag:
                             match = True
                         break
                 if scoring_strategy.negate_tag:
                     match = True
             if not match:
                 pass
             (affinity,
              message) = scoring_strategy.affinity_strategy(sim, other_sim)
             if not affinity:
                 pass
             scores.append((affinity, message))
         if not (other_sim_body_target is not None and scores):
             pass
         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[BODY_INDEX]
             goal_body_target = goal_body[BODY_TARGET_INDEX]
             goal_posture_type = goal_body[BODY_POSTURE_TYPE_INDEX]
             while not goal_body_target is None:
                 if goal_posture_type.mobile:
                     pass
                 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:
                         pass
                     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 = []
                 for (affinity, message) in scores:
                     affinity_weighted = affinity / distance
                     bonus += affinity_weighted
                 if not bonus:
                     pass
                 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)
                 while current_bonus_info is None or bonus < current_bonus_info[
                         0]:
                     formatted_message = ''
                     bonuses[goal_body_target] = (bonus, formatted_message)
     obj_to_cluster.clear()
     return bonuses