def _can_access(self, sim): if self.test_set is not None: resolver = DoubleObjectResolver(sim, self.owner) result = self.test_set(resolver) if not result: return False return True
def do_route_fail_gen(self, timeline): if self.route_fail is None: yield target = self.get_target() if target is None: resolver = SingleObjectResolver(self._obj) else: resolver = DoubleObjectResolver(self._obj, target) balloons = self.route_fail.get_balloon_icons(resolver) if not balloons: yield balloon = weighted_random_item(balloons) if balloon is None: yield icon_info = balloon.icon(resolver, balloon_target_override=None) if icon_info[0] is None and icon_info[1] is None: yield category_icon = None if balloon.category_icon is not None: category_icon = balloon.category_icon(resolver, balloon_target_override=None) (balloon_type, priority) = BALLOON_TYPE_LOOKUP[balloon.balloon_type] balloon_overlay = balloon.overlay request = BalloonRequest(self._obj, icon_info[0], icon_info[1], balloon_overlay, balloon_type, priority, TunableBalloon.BALLOON_DURATION, 0, 0, category_icon) request.distribute()
def play_release_ghost_vfx(cls, sim_info): urnstone = cls.get_urnstone_for_sim_id(sim_info.sim_id) if urnstone is None: return resolver = DoubleObjectResolver(sim_info, urnstone) for vfx in cls.URNSTONE_RELEASE_VFX(resolver=resolver): vfx = vfx(urnstone) vfx.start_one_shot() break
def _callback(_): for o in objects: resolver = DoubleObjectResolver(obj, o) for loot_action in self.loot_success: loot_action.apply_to_resolver(resolver) o.remove_from_client(fade_duration=obj.FADE_DURATION) o.destroy( source=self, cause= 'Object being destroyed by ObjectRoutingBehaviorActionDestroyObjects' )
def run_action_gen(self, timeline, obj, target): if self.loot_actions is None: return True yield if target is None: resolver = SingleObjectResolver(obj) else: resolver = DoubleObjectResolver(obj, target) for loot_action in self.loot_actions: loot_action.apply_to_resolver(resolver) return True yield
def apply_live_drag_actions(self, live_drag_obj, action_entry=None): next_object_id = None if action_entry is None: (valid, entry) = self.test_live_drag(live_drag_obj) else: valid = True entry = action_entry if valid and entry is not None: resolver = DoubleObjectResolver(live_drag_obj, self.owner) for action in entry.actions: action.apply_to_resolver(resolver) if entry.destroy_live_drag_object: next_object_id = self._destroy_object(live_drag_obj) return (valid, next_object_id)
def test_live_drag(self, live_drag_obj): inventoryitem_component = live_drag_obj.inventoryitem_component if inventoryitem_component is None: return (False, None) resolver = DoubleObjectResolver(live_drag_obj, self.owner) can_add_to_inventory = self.test_inventory_addition(live_drag_obj) if not self.drop_tests_and_actions: return (can_add_to_inventory, None) for entry in self.drop_tests_and_actions: while inventoryitem_component.can_go_in_inventory_type( entry.drop_type): if entry.test_set.run_tests(resolver): if entry.actions or entry.destroy_live_drag_object or can_add_to_inventory: return (True, entry) return (False, None)
def loot_apply_to_sim_and_target(loot_type: TunableInstanceParam( sims4.resources.Types.ACTION), actor_sim: RequiredTargetParam = None, target_obj: RequiredTargetParam = None, _connection=None): actor = actor_sim.get_target(manager=services.sim_info_manager()) if actor is None: sims4.commands.output('No actor', _connection) return target = target_obj.get_target(manager=services.object_manager()) if target is None: sims4.commands.output('No target', _connection) return resolver = DoubleObjectResolver(actor, target) loot_type.apply_to_resolver(resolver)
def _find_target(self): all_objects = self.target_type.get_objects() objects = [] for o in all_objects: dist_sq = (o.position - self._obj.position).magnitude_squared() if dist_sq > self.radius: continue if o == self: continue if not o.is_sim and not o.may_reserve(self._obj): continue if self.target_selection_test: resolver = DoubleObjectResolver(self._obj, o) if not self.target_selection_test.run_tests(resolver): continue else: objects.append([o, dist_sq]) if not objects: return source_handles = [ routing.connectivity.Handle(self._obj.position, self._obj.routing_surface) ] dest_handles = [] for o in objects: obj = o[0] parent = obj.parent route_to_obj = parent if parent is not None else obj constraint = Anywhere() for tuned_constraint in self.constraints: constraint = constraint.intersect( tuned_constraint.create_constraint(self._obj, route_to_obj)) dests = constraint.get_connectivity_handles(self._obj, target=obj) if dests: dest_handles.extend(dests) if not dest_handles: return routing_context = self._obj.get_routing_context() connections = routing.estimate_path_batch( source_handles, dest_handles, routing_context=routing_context) if not connections: return connections.sort(key=lambda connection: connection[2]) best_connection = connections[0] best_dest_handle = best_connection[1] best_obj = best_dest_handle.target return best_obj
def do_target_action_rules_gen(self, timeline): if not self.target_action_rules or self._target is None: return resolver = DoubleObjectResolver(self._obj, self._target) for target_action_rule in self.target_action_rules: if random.random.random() >= target_action_rule.chance: continue if not target_action_rule.test.run_tests(resolver): continue if target_action_rule.actions is not None: for action in target_action_rule.actions: result = yield from action.run_action_gen( timeline, self._obj, self._target) if not result: return if target_action_rule.abort_if_applied: return
def supports_posture_spec(self, posture_spec, interaction=None, sim=None): if self._disabling_states: return False if interaction is not None and interaction.is_super: affordance = interaction.affordance if affordance.requires_target_support and not self.supports_affordance( affordance): return False is_sim_putdown = interaction.is_putdown and ( interaction.carry_target is not None and interaction.carry_target.is_sim) test_sim = sim or interaction.sim if (not is_sim_putdown or interaction.carry_target is test_sim ) and not self._supports_sim_buffs(test_sim): return False if not self._meets_trait_requirements(test_sim): return False part_supported_posture_types = None if self.part_definition: part_supported_posture_types = self.part_definition.supported_posture_types if part_supported_posture_types: if self.part_owner.affordancetuning_component is not None: if sim is not None: if posture_spec[BODY_INDEX] is not None: for supported_posture_info in part_supported_posture_types: if posture_spec[BODY_INDEX][ BODY_POSTURE_TYPE_INDEX] is supported_posture_info.posture_type: posture_providing_interactions = [ affordance for affordance in self.super_affordances() if affordance.provided_posture_type is posture_spec[BODY_INDEX] [BODY_POSTURE_TYPE_INDEX] ] for interaction in posture_providing_interactions: tests = self.affordancetuning_component.get_affordance_tests( interaction) if tests is not None: if not tests.run_tests( DoubleObjectResolver( sim, self.part_owner)): return False break return True
def _do_behavior(self): participant = self.interaction.get_participant(self.inventory_owner) inventory = participant.inventory_component if inventory is None: logger.error( 'Participant {} does not have an inventory to check for objects to destroy.', participant, owner='tastle') return objects_to_destroy = set() for obj in inventory: single_object_resolver = event_testing.resolver.SingleObjectResolver( obj) if not self.object_tests.run_tests(single_object_resolver): continue objects_to_destroy.add(obj) num_destroyed = 0 for obj in objects_to_destroy: if self.count == self.ALL: count = obj.stack_count() else: count = min(self.count - num_destroyed, obj.stack_count()) resolver = SingleActorAndObjectResolver( participant.sim_info, obj, self) if participant.is_sim else DoubleObjectResolver( obj, self) for loot in self.loots_to_run_before_destroy: loot.apply_to_resolver(resolver) if not inventory.try_destroy_object( obj, count=count, source=inventory, cause= 'Destroying specified objects from target inventory extra.' ): logger.error('Error trying to destroy object {}.', obj, owner='tastle') num_destroyed += count if self.count != self.ALL: if num_destroyed >= self.count: break objects_to_destroy.clear()
def _add_clothing_pile_to_hamper(self, sim): if not self._hampers: return False full_hamper_state = LaundryTuning.PUT_CLOTHING_PILE_ON_HAMPER.full_hamper_state available_hampers = set( obj for obj in self._hampers if not obj.state_value_active(full_hamper_state)) if not available_hampers: return False sim_resolver = SingleSimResolver(sim.sim_info) if not LaundryTuning.PUT_CLOTHING_PILE_ON_HAMPER.tests.run_tests( sim_resolver): return False if random.random() > LaundryTuning.PUT_CLOTHING_PILE_ON_HAMPER.chance: return True obj_def = LaundryTuning.PUT_CLOTHING_PILE_ON_HAMPER.clothing_pile.definition if obj_def is None: logger.error( 'Failed to create clothing pile on hamper for {} because the pile definition is None.', sim) return False obj = None try: obj = create_object(obj_def) except: logger.error('Failed to create clothing pile {} on hamper for {}.', obj_def, sim) if obj is not None: obj.destroy(source=self, cause='Transferred to hamper.') return False finally: for initial_state in LaundryTuning.PUT_CLOTHING_PILE_ON_HAMPER.clothing_pile.initial_states: if initial_state.tests.run_tests(sim_resolver): state_val = initial_state.state if obj.has_state(state_val.state): obj.set_state(state_val.state, state_val) closest_hamper = self._find_closest_hamper(sim, available_hampers) resolver = DoubleObjectResolver(obj, closest_hamper) for loot_action in LaundryTuning.PUT_CLOTHING_PILE_ON_HAMPER.loots_to_apply: loot_action.apply_to_resolver(resolver) obj.destroy(source=self, cause='Transferred to hamper.') return True
def get_objects(self, *args, preferred_slots=None, **kwargs): inventory_owner = self.resolver.get_participant( self.inventory_participant) if inventory_owner is None: logger.error( 'Inventory Participant {} is None for slot object selection {}', self.inventory_participant, self.resolver) return set() is_interaction_resolver = isinstance(self.resolver, InteractionResolver) if is_interaction_resolver: interaction_params = self.resolver.interaction_parameters.copy() inventory_owner = self.resolver.interaction.get_participant( self.inventory_participant) valid_objects = set() if inventory_owner.inventory_component is None: logger.error( 'Inventory Component for Participant {} is None for slot object selection {}', self.inventory_participant, self.resolver) return set() for obj in inventory_owner.inventory_component: if is_interaction_resolver: interaction_parameters = {'picked_item_ids': [obj.id]} self.resolver.interaction_parameters.update( interaction_parameters) resolver = self.resolver else: resolver = DoubleObjectResolver(obj, self.slot_target) if not self.object_tests.run_tests(resolver): continue if preferred_slots is not None and not any([ slot_type in obj.all_valid_slot_types for slot_type in preferred_slots ]): continue valid_objects.add(obj) if is_interaction_resolver: self.resolver.interaction_parameters = interaction_params return valid_objects
def get_resolver(self, affected_object): return DoubleObjectResolver(affected_object, self.broadcasting_object)
def test_formation(cls, master, slave): resolver = DoubleObjectResolver(master, slave) return cls.formation_tests.run_tests(resolver)
def __call__(self, timeline, obj, target, callback=None): executed_actions = False action_event_handle = None sleep_element = None _conditional_actions_manager = ConditionalActionManager() def _execute_actions(_): nonlocal executed_actions executed_actions = True if sleep_element and sleep_element.attached_to_timeline: sleep_element.trigger_soft_stop() if callback is not None: callback(None) if action_event_handle is not None: action_event_handle.release() if self.event_id is not None: animation_context = obj.get_idle_animation_context() action_event_handle = animation_context.register_event_handler( _execute_actions, handler_id=self.event_id) if self.loop_time > 0: sleep_element = OverrideResultElement( SoftSleepElement( date_and_time.create_time_span(minutes=self.loop_time)), True) sequence = build_element(sleep_element) else: sequence = () if self.loop_exit_conditions is not None: if target is None: exit_condition_test_resolver = SingleObjectResolver(obj) else: exit_condition_test_resolver = DoubleObjectResolver( obj, target) exit_conditions = (exit_condition for exit_condition in self.loop_exit_conditions if exit_condition.tests.run_tests( exit_condition_test_resolver)) if exit_conditions: if not sleep_element: sleep_element = OverrideResultElement( SoftSleepElement( date_and_time.create_time_span(days=1000)), True) _conditional_actions_manager.attach_conditions( obj, exit_conditions, _execute_actions) animation_element = self.reference(obj, target=target, sequence=sequence) animation_element = build_critical_section( (animation_element, flush_all_animations)) result = yield from element_utils.run_child(timeline, animation_element) if self.loop_exit_conditions: _conditional_actions_manager.detach_conditions(obj) if not result: return result yield if not executed_actions and callback is not None: fn_element = FunctionElement(callback) yield from element_utils.run_child(timeline, fn_element) return True yield