def _send_goals_update(self): if not self._verify_goals(): return logger.debug('Sending whims update for {}. Current active whims: {}', self._sim_info, self._active_whims, owner='jjacobson') current_whims = [] for goal in self._active_whims: if goal is None: whim_goal = DistributorOps_pb2.WhimGoal() current_whims.append(whim_goal) goal_target_id = 0 goal_whimset = self._realized_goals[goal] goal_target = goal.get_required_target_sim_info() goal_target_id = goal_target.id if goal_target is not None else 0 whim_goal = DistributorOps_pb2.WhimGoal() whim_goal.whim_guid64 = goal.guid64 whim_goal.whim_name = goal.display_name whim_goal.whim_score = goal.score whim_goal.whim_noncancel = goal.noncancelable whim_goal.whim_icon_key.type = goal._icon.type whim_goal.whim_icon_key.group = goal._icon.group whim_goal.whim_icon_key.instance = goal._icon.instance whim_goal.whim_goal_count = goal.max_iterations whim_goal.whim_current_count = goal.completed_iterations whim_goal.whim_target_sim = goal_target_id whim_goal.whim_tooltip = goal.tooltip whim_goal.whim_mood_guid64 = self.get_emotion_guid(goal_whimset) whim_goal.whim_tooltip_reason = goal_whimset.whim_reason( *goal.get_localization_tokens()) current_whims.append(whim_goal) if self._goals_dirty: self._sim_info.current_whims = current_whims self._goals_dirty = False
def _send_goals_update(self): if not self._goals_dirty: return logger.debug('Sending whims update for {}. Current active whims: {}', self._sim_info, self._active_whims, owner='jjacobson') current_whims = [] for (index, whim_data) in enumerate(self._active_whims): whim = whim_data.whim if whim is None or self._hidden: whim_goal = DistributorOps_pb2.WhimGoal() current_whims.append(whim_goal) else: goal_target_id = 0 goal_whimset = whim_data.whimset goal_target = whim.get_required_target_sim_info() goal_target_id = goal_target.id if goal_target is not None else 0 whim_goal = DistributorOps_pb2.WhimGoal() whim_goal.whim_guid64 = whim.guid64 whim_name = whim.get_display_name() if whim_name is not None: whim_goal.whim_name = whim_name whim_goal.whim_score = self.get_score_for_whim(whim.score) whim_goal.whim_noncancel = whim.noncancelable whim_display_icon = whim.display_icon if whim_display_icon is not None: whim_goal.whim_icon_key.type = whim_display_icon.type whim_goal.whim_icon_key.group = whim_display_icon.group whim_goal.whim_icon_key.instance = whim_display_icon.instance whim_goal.whim_goal_count = whim.max_iterations whim_goal.whim_current_count = whim.completed_iterations whim_goal.whim_target_sim = goal_target_id whim_tooltip = whim.get_display_tooltip() if whim_tooltip is not None: whim_goal.whim_tooltip = whim_tooltip if index == self.emotional_whim_index: whim_goal.whim_mood_guid64 = self._sim_mood().guid64 else: whim_goal.whim_mood_guid64 = 0 whim_goal.whim_tooltip_reason = goal_whimset.whim_reason( *whim.get_localization_tokens()) whim_goal.whim_locked = whim.locked current_whims.append(whim_goal) if self._goals_dirty: self._sim_info.current_whims = current_whims self._goals_dirty = False
def _at_work_infos(self): at_work_infos = [] for career in self._careers.values(): at_work_info = DistributorOps_pb2.SetAtWorkInfo() at_work_info.career_uid = career.guid64 at_work_info.work_state = career.get_work_state() at_work_infos.append(at_work_info) return at_work_infos
def __init__(self, update_type, org_id, objective_ids, is_enrolled): super().__init__() self.op = DistributorOps_pb2.OrganizationUpdate() self.op.org_id = org_id self.op.update_type = update_type for objective_id in objective_ids: self.op.objective_ids.append(objective_id) self.op.is_enrolled = is_enrolled
def __init__(self, org_id, org_event_infos, no_events_string=None): super().__init__() self.op = DistributorOps_pb2.OrganizationEventUpdate() self.op.org_id = org_id if no_events_string is not None: self.op.no_events_are_scheduled_string = no_events_string for org_event_info in org_event_infos: with ProtocolBufferRollback(self.op.events) as event_info_msg: _create_org_event_info(event_info_msg, org_event_info)
def __init__(self, update_type, holiday_id, name, icon, time_off_for_work, time_off_for_school, traditions, can_be_modified, lot_decoration_preset): super().__init__() self.op = DistributorOps_pb2.SendActiveHolidayInfo() self.op.update_type = update_type self.op.holiday_info = _create_holiday_info( holiday_id, name, icon, time_off_for_work, time_off_for_school, traditions, can_be_modified, lot_decoration_preset)
def _create_make_memory_from_photo_op(self, memory_sim, canvas_component): make_memory_proto = DistributorOps_pb2.MakeMemoryFromPhoto() make_memory_proto.household_id = memory_sim.sim_info.household_id for sim in self.interaction.get_participants( participant_type=ParticipantType.PickedSim): make_memory_proto.sim_ids.append(sim.sim_id) make_memory_proto.texture_id = canvas_component.painting_state.texture_id make_memory_proto.filter_style = canvas_component.painting_effect make_memory_proto.time_stamp = canvas_component.time_stamp return GenericProtocolBufferOp( DistributorOps_pb2.Operation.MAKE_MEMORY_FROM_PHOTO, make_memory_proto)
def _event_handler_update_flipbook(self, event_data): asms = list(self._get_asms_from_arb_request_info()) (early_out, target) = get_animation_object_for_event(event_data, 'event_actor_id', 'object to be snapped', asms=asms) if early_out is not None: return op = GenericProtocolBufferOp(protocols.Operation.UPDATE_FLIPBOOK, protocols.UpdateFlipBook()) Distributor.instance().add_op(target, op)
def get_protocol_msg(self): msg = protocols.VideoSetPlaylist() msg.version_id = self.version_id msg.clip_keys.extend(self.clip_keys) msg.final_loop = self.loop_last msg.video_overlay = self.display_type == VideoDisplayType.LIGHT_OVERLAY msg.mute_speed = self.mute_speed msg.distortion_speed = self.distortion_speed if self.speed_audio_clip_replacement is not None: msg.speed_audio_clip_replacement = self.speed_audio_clip_replacement.instance msg.append_clip = self.append_clip return msg
def _create_holiday_info(holiday_id, name, icon, time_off_for_work, time_off_for_school, traditions, can_be_modified, lot_decoration_preset): distributor_op = DistributorOps_pb2.SendHolidayInfo() distributor_op.holiday_type = holiday_id distributor_op.name = name distributor_op.icon = get_protobuff_for_key(icon) distributor_op.time_off_for_work = time_off_for_work distributor_op.time_off_for_school = time_off_for_school for tradition_type in traditions: distributor_op.traditions.append(tradition_type.guid64) distributor_op.can_be_modified = can_be_modified if lot_decoration_preset is not None: distributor_op.lot_decoration_preset = lot_decoration_preset.guid64 return distributor_op
def _send_career_ui_update(self, is_add=True): audition_update_msg = DistributorOps_pb2.AuditionUpdate() if is_add: self.gig.build_gig_msg( audition_update_msg.audition_info, self._receiver_sim_info, gig_time=self._calculated_gig_time, audition_time=self._calculated_audition_time) op = GenericProtocolBufferOp(Operation.AUDITION_UPDATE, audition_update_msg) build_icon_info_msg( IconInfoData(icon_resource=self.audition_prep_icon), self.audition_prep_recommendation(), audition_update_msg.recommended_task) Distributor.instance().add_op(self._receiver_sim_info, op)
def write(self, msg): tan_level = None outfit_part_data_list = None force_update = None if self._suntan_data: tan_level = self._suntan_data.tan_level outfit_part_data_list = self._suntan_data.outfit_part_data_list force_update = self._suntan_data.force_update op = DistributorOps_pb2.SetTanLevel() if tan_level is not None: op.tan_level = tan_level if outfit_part_data_list is not None: for (part_id, body_type) in outfit_part_data_list: with ProtocolBufferRollback(op.outfit_part_data_list) as entry: entry.id = part_id entry.body_type = body_type if force_update is not None: op.force_update = force_update self.serialize_op(msg, op, protocol_constants.SET_TAN_LEVEL)
def _create_composite_operation_msg(self): msg = DistributorOps_pb2.CompositeParams() if self.signature is not None: msg.texture_hash = self.signature.instance if self.composite_params is not None: msg.base_scale_x = self.composite_params.base_scale_x msg.base_scale_y = self.composite_params.base_scale_y msg.base_offset_x = self.composite_params.base_offset_x msg.base_offset_y = self.composite_params.base_offset_y if self.portrait_type == PortraitType.GRADUATION: msg.overlay_scale_x = 0 msg.overlay_scale_y = 0 else: msg.overlay_scale_x = self.composite_params.overlay_scale_x msg.overlay_scale_y = self.composite_params.overlay_scale_y msg.overlay_offset_x = self.composite_params.overlay_offset_x msg.overlay_offset_y = self.composite_params.overlay_offset_y msg.technique = self.composite_params.technique (msg.overlay_color.x, msg.overlay_color.y, msg.overlay_color.z, _) = sims4.color.to_rgba(self.composite_params.overlay_color) return msg
def get_protocol_msg(self): msg = protocols.VideoSetPlaylist() msg.version_id = self.version_id msg.clip_keys.extend(self.clip_keys) msg.final_loop = self.loop_last return msg
def create_take_photo_op(self, sims, interaction): take_photo_proto = DistributorOps_pb2.TakePhoto() self._populate_take_photo_op(sims, interaction, take_photo_proto) take_photo_op = GenericProtocolBufferOp( DistributorOps_pb2.Operation.TAKE_PHOTO, take_photo_proto) return take_photo_op
def __init__(self, focus_score): super().__init__() self.op = DistributorOps_pb2.SetFocusScore() focus_score.populate_focus_score_msg(self.op)
def genealogy_show_family_tree(sim_info_id: int, antecedent_depth: int = 8, descendant_depth: int = 2, _connection=None): automation_output = sims4.commands.AutomationOutput(_connection) sim_info_manager = services.sim_info_manager() closed_set = set() def populate_family_tree_node(family_tree_node, sim_info_id, antecedent_depth, descendant_depth, extended_info_depth=0, include_spouse=False, step_depth=0, incoming_sim_id=0): family_tree_node.sim_id = sim_info_id sim_info = sim_info_manager.get(sim_info_id) if sim_info is None: return relationship_key = ( incoming_sim_id, sim_info_id) if incoming_sim_id < sim_info_id else ( sim_info_id, incoming_sim_id) if relationship_key in closed_set: return closed_set.add(relationship_key) automation_output( 'FamilyTreeInfo; Status:Data, Sim0:{}, Sim1:{}, AntDepth:{}, DesDepth:{}, Gender:{}' .format(relationship_key[0], relationship_key[1], antecedent_depth, descendant_depth, sim_info.gender)) if include_spouse: spouse_id = sim_info.spouse_sim_id if spouse_id: populate_family_tree_node(family_tree_node.spouse, spouse_id, 0, 1 if step_depth else 0, incoming_sim_id=sim_info_id) if antecedent_depth: for parent_id in sim_info.genealogy.get_parent_sim_ids_gen(): with ProtocolBufferRollback( family_tree_node.parents) as parent_family_tree_node: populate_family_tree_node( parent_family_tree_node, parent_id, antecedent_depth - 1, 1 if extended_info_depth else 0, extended_info_depth=extended_info_depth - 1 if extended_info_depth else 0, step_depth=step_depth - 1 if step_depth else 0, include_spouse=True, incoming_sim_id=sim_info_id) if descendant_depth: for child_id in sim_info.genealogy.get_children_sim_ids_gen(): with ProtocolBufferRollback( family_tree_node.children) as child_family_tree_node: populate_family_tree_node(child_family_tree_node, child_id, 1 if extended_info_depth else 0, descendant_depth - 1, include_spouse=True, incoming_sim_id=sim_info_id) if extended_info_depth or include_spouse: for relationship in sim_info.relationship_tracker: if extended_info_depth: if relationship.has_bit( sim_info.sim_id, FamilyRelationshipTuning.SIBLING_RELATIONSHIP_BIT): with ProtocolBufferRollback( family_tree_node.siblings ) as sibling_family_tree_node: populate_family_tree_node( sibling_family_tree_node, relationship.get_other_sim_id(sim_info_id), 1, 0, incoming_sim_id=sim_info_id) elif not incoming_sim_id and relationship.has_bit( sim_info.sim_id, FamilyRelationshipTuning. GRANDPARENT_RELATIONSHIP_BIT): with ProtocolBufferRollback( family_tree_node.grandparents ) as grandparent_family_tree_node: populate_family_tree_node( grandparent_family_tree_node, relationship.get_other_sim_id(sim_info_id), 0, 1, include_spouse=True, incoming_sim_id=sim_info_id) elif not incoming_sim_id: if relationship.has_bit( sim_info.sim_id, FamilyRelationshipTuning. GRANDCHILD_RELATIONSHIP_BIT): with ProtocolBufferRollback( family_tree_node.grandchildren ) as grandchild_family_tree_node: populate_family_tree_node( grandchild_family_tree_node, relationship.get_other_sim_id(sim_info_id), 1, 0, incoming_sim_id=sim_info_id) if include_spouse: if relationship.has_bit( sim_info.sim_id, FamilyRelationshipTuning. DIVORCED_SPOUSE_RELATIONSHIP_BIT): with ProtocolBufferRollback( family_tree_node.divorced_spouses ) as divorced_spouse_family_tree_node: populate_family_tree_node( divorced_spouse_family_tree_node, relationship.get_other_sim_id(sim_info_id), 0, 0, incoming_sim_id=sim_info_id) if relationship.has_bit( sim_info.sim_id, FamilyRelationshipTuning. DEAD_SPOUSE_RELATIONSHIP_BIT): with ProtocolBufferRollback( family_tree_node.dead_spouses ) as dead_spouse_family_tree_node: populate_family_tree_node( dead_spouse_family_tree_node, relationship.get_other_sim_id(sim_info_id), 0, 0, incoming_sim_id=sim_info_id) return family_tree_node family_tree_msg = DistributorOps_pb2.ShowFamilyTree() with genealogy_caching(): automation_output('FamilyTreeInfo; Status:Begin') populate_family_tree_node(family_tree_msg.root, sim_info_id, antecedent_depth, descendant_depth, extended_info_depth=2, include_spouse=True, step_depth=2) automation_output('FamilyTreeInfo; Status:End') distributor = Distributor.instance() family_tree_op = GenericProtocolBufferOp( DistributorOps_pb2.Operation.SHOW_FAMILY_TREE, family_tree_msg) distributor.add_op_with_no_owner(family_tree_op)
def advance_age(self, force_age=None) -> None: current_age = Age(self._base.age) next_age = Age(force_age) if force_age is not None else Age.next_age(current_age) self._relationship_tracker.update_bits_on_age_up(current_age) self.age_progress = 0 self._dirty_flags = sys.maxsize self._base.update_for_age(next_age) getOutfitsPB = DistributorOps_pb2.SetSimOutfits() getOutfitsPB.ParseFromString(self._base.outfits) self._outfits.load_sim_outfits_from_cas_proto(getOutfitsPB) self.resend_physical_attributes() self._update_age_trait(next_age, current_age) self._select_age_trait() self.age = next_age self.init_child_skills() if self.is_teen: self.remove_child_only_features() sim_instance = self.get_sim_instance(allow_hidden_flags=ALL_HIDDEN_REASONS) if sim_instance is not None: with telemetry_helper.begin_hook(writer_age, TELEMETRY_CHANGE_AGE, sim=sim_instance) as hook: hook.write_enum('agef', current_age) hook.write_enum('aget', next_age) sim_instance.schedule_element(services.time_service().sim_timeline, build_element(sim_instance._update_face_and_posture_gen)) sim_instance._update_multi_motive_buff_trackers() if current_age != Age.BABY: self.verify_school(from_age_up=True) self.remove_invalid_age_based_careers(current_age) self.reset_age_progress() if self.is_npc: if self.is_child or self.is_teen: available_aspirations = [] aspiration_track_manager = services.get_instance_manager(sims4.resources.Types.ASPIRATION_TRACK) for aspiration_track in aspiration_track_manager.types.values(): if aspiration_track.is_child_aspiration_track: if self.is_child: available_aspirations.append(aspiration_track.guid64) while self.is_teen: available_aspirations.append(aspiration_track.guid64) else: while self.is_teen: available_aspirations.append(aspiration_track.guid64) self.primary_aspiration = random.choice(available_aspirations) trait_tracker = self.trait_tracker empty_trait_slots = trait_tracker.empty_slot_number available_traits = [trait for trait in services.trait_manager().types.values() if trait.is_personality_trait] while True: while empty_trait_slots > 0 and available_traits: trait = random.choice(available_traits) available_traits.remove(trait) if not trait_tracker.can_add_trait(trait, display_warn=False): continue #ERROR: Unexpected statement: 770 POP_BLOCK | 771 JUMP_ABSOLUTE 812 if trait_tracker.add_trait(trait): empty_trait_slots -= 1 continue continue continue else: self.whim_tracker.validate_goals() services.social_service.post_aging_message(self, ready_to_age=False) client = services.client_manager().get_client_by_household_id(self._household_id) if client is None: return client.selectable_sims.notify_dirty()