def enable(self, value): if not value: if self.enabled: if self.owner.manager is not None and services.current_zone( ).is_zone_running: self._update_location(disabling=True) if self.owner.is_sim: resolver = SingleSimResolver(self.owner.sim_info) else: resolver = SingleObjectResolver(self.owner) loot_ops_list = LootOperationList(resolver, self.disable_loot) loot_ops_list.apply_operations() self.on_remove() self._disabled_count += 1 else: self._disabled_count -= 1 if self.enabled: if self.owner.is_sim: resolver = SingleSimResolver(self.owner.sim_info) else: resolver = SingleObjectResolver(self.owner) loot_ops_list = LootOperationList(resolver, self.enable_loot) loot_ops_list.apply_operations() self.on_add() if self._inside_sensitive: self.on_location_changed_callback() elif self._disabled_count < 0: logger.error( 'Unbalanced enabled/disable in weathercomponent. Called disable once more than enable.' ) self._disabled_count = 0
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 start(self, *_, **__): if self._target.is_prop: return current_zone = services.current_zone() broadcaster_service = current_zone.broadcaster_service broadcaster_service_real_time = current_zone.broadcaster_real_time_service if broadcaster_service is not None: if broadcaster_service_real_time is not None: if self._interaction is not None: resolver = self._interaction.get_resolver() else: resolver = SingleObjectResolver(self._target) for broadcaster_type in self.broadcaster_types( resolver=resolver): broadcaster = broadcaster_type( broadcasting_object=self._target, interaction=self._interaction) self._broadcasters.append(broadcaster) if broadcaster.clock_type == BroadcasterClockType.GAME_TIME: broadcaster_service.add_broadcaster(broadcaster) elif broadcaster.clock_type == BroadcasterClockType.REAL_TIME: broadcaster_service_real_time.add_broadcaster( broadcaster) else: raise NotImplementedError
def prune_stale_events_and_get_failed_types(self, actor, path, current_time): self._route_events_to_schedule.clear() failed_events = [] failed_event_types = set() if actor.is_sim: resolver = SingleSimResolver(actor.sim_info) else: resolver = SingleObjectResolver(actor) for (route_event, time) in self._scheduled_events: if type(route_event) in failed_event_types or not route_event.test( resolver, from_update=True): failed_events.append((route_event, time)) failed_event_types.add(type(route_event)) elif not route_event.is_route_event_valid(route_event, time, actor, path): failed_events.append((route_event, time)) gsi_path_log = None if gsi_handlers.route_event_handlers.archiver.enabled: gsi_path_log = gsi_handlers.route_event_handlers.get_path_route_events_log( path) for (route_event, time) in failed_events: if gsi_path_log is not None: gsi_event_data = {'status': 'Removed'} gsi_handlers.route_event_handlers.gsi_fill_route_event_data( route_event, gsi_path_log, gsi_event_data) self.remove_route_event(route_event, time) return (failed_events, failed_event_types)
def increment_statistics(self, obj, statistic_values): tests_to_run = collections.defaultdict(TestSetStats) tags = {t for t in self._relevant_tags if obj.definition.has_build_buy_tag(t)} if tags: for tag in tags: test_list = self._tag_to_test_mapping[tag] for (test_set, statistic) in test_list: test_set_stats = tests_to_run[id(test_set)] test_set_stats.test_set = test_set test_set_stats.stats.append(statistic) state_component = obj.state_component if state_component is not None: for (state, test_list) in self._state_to_test_mapping.items(): if state_component.has_state(state): for (test_set, statistic) in test_list: test_set_stats = tests_to_run[id(test_set)] test_set_stats.test_set = test_set test_set_stats.stats.append(statistic) if not tests_to_run: return resolver = SingleObjectResolver(obj) incremented_statistics = set() for test_set_stats in tests_to_run.values(): if test_set_stats.test_set.run_tests(resolver): for statistic in test_set_stats.stats: if statistic not in incremented_statistics: statistic_values[statistic] += 1 incremented_statistics.add(statistic)
def get_lightning_strike_multiplier(self): if not self.enabled: return 0 elif self.lightning_strike_multiplier is not None: return self.lightning_strike_multiplier.get_multiplier( SingleObjectResolver(self.owner)) return 1.0
def _cache_valid_objects(self): debt_value = self.get_debt_value() if debt_value is None: self._self_destruct() return target_amount = debt_value * self.repo_amount.target_amount unsorted = [] plex_service = services.get_plex_service() check_common_area = plex_service.is_active_zone_a_plex() debtor_household_id = self.debtor_sim().household_id for obj in services.object_manager().valid_objects(): if not obj.get_household_owner_id() == debtor_household_id: continue if not obj.is_on_active_lot(): continue if check_common_area and plex_service.get_plex_zone_at_position( obj.position, obj.level) is None: continue if not obj.is_connected(self.repo_person()): continue if obj.children: continue resolver = SingleObjectResolver(obj) if self.valid_object_tests.run_tests(resolver): delta = abs(obj.depreciated_value - target_amount) unsorted.append((obj.id, delta)) self.objects_to_take = sorted(unsorted, key=operator.itemgetter(1))
def strike_object(obj_to_strike=None): lightning_strike_tuning = LightningTuning.STRIKE_OBJECT_TUNING if obj_to_strike is None: obj_to_strike = LightningStrike._get_object_for_lightning_strike() if obj_to_strike is None: LightningStrike.strike_terrain() return lot = services.active_lot() position = obj_to_strike.position if lot.is_position_on_lot(position): fire_service = services.get_fire_service() fire_service.add_delayed_scorch_mark(position, obj_to_strike.routing_surface, clock.interval_in_real_seconds(lightning_strike_tuning.scorch_mark_delay)) effect = lightning_strike_tuning.effect(obj_to_strike) weather_aware_component = obj_to_strike.weather_aware_component if weather_aware_component is not None: lightning_effect_override = weather_aware_component.lightning_effect_override if lightning_effect_override is not None: effect = lightning_effect_override(obj_to_strike) effect.start_one_shot() broadcaster_request = lightning_strike_tuning.broadcaster(obj_to_strike) broadcaster_request.start_one_shot() loot_ops_list = LootOperationList(SingleObjectResolver(obj_to_strike), lightning_strike_tuning.generic_loot_on_strike) loot_ops_list.apply_operations() if weather_aware_component is not None: weather_aware_component.on_struck_by_lightning()
def cleanup_objects(cls, lot=None): if lot is None: logger.error('Lot is None when trying to run lot cleanup.', owner='jjacobson') return cls.objects_to_destroy = set() for cleanup in GlobalLotTuningAndCleanup.OBJECT_CLEANUP_TUNING: items_to_cleanup = cleanup.count(lot) if items_to_cleanup == 0: continue items_cleaned_up = 0 for obj in services.object_manager().values(): if items_cleaned_up >= items_to_cleanup: break if obj.is_sim: continue resolver = SingleObjectResolver(obj) run_action = False for possible_action in cleanup.possible_actions: if possible_action.tests.run_tests(resolver): for action in possible_action.actions: action(obj, lot) run_action = True if run_action: items_cleaned_up += 1 for obj in cls.objects_to_destroy: obj.destroy(source=lot, cause='Cleaning up the lot') cls.objects_to_destroy = None
def handle_privacy_violation(self, privacy): if not self.privacy_rules: return resolver = SingleObjectResolver(self.owner) loots = LootOperationList(resolver, self.privacy_rules.on_enter.loot_list) loots.apply_operations() if privacy not in self._privacy_violations: self._privacy_violations.add(privacy)
def _handle_inventory_changed(self): obj_resolver = SingleObjectResolver(self.owner) for trigger in self.inventory_state_triggers: if obj_resolver(trigger.inventory_test): if self.owner.has_state(trigger.set_state.state): self.owner.set_state(trigger.set_state.state, trigger.set_state) break
def _ui_metadata_gen(self): owner = self.owner resolver = SingleObjectResolver(owner) for tooltip_data in self.custom_tooltips: object_tests = tooltip_data.object_tests if not not object_tests and not not object_tests.run_tests( resolver): continue self.owner.hover_tip = tooltip_data.tooltip_style for (tooltip_key, tooltip_text) in tooltip_data.tooltip_fields.items(): if tooltip_text.text_tokens is not None: tokens = tooltip_text.text_tokens.get_tokens(resolver) else: tokens = () if tooltip_key == TooltipFields.rel_override_id: logger.error( 'Attempting to set rel_override_id without a required token of type Game Object Property, Object Type Rel Id. Tooltip Field not created on object' ) break yield (TooltipFieldsComplete(tooltip_key).name, tokens[0], tooltip_text.override_component_information) else: yield (TooltipFieldsComplete(tooltip_key).name, tooltip_text.text(*tokens), tooltip_text.override_component_information) if tooltip_data.tooltip_main_icon is not None: icon_data = sims4.resources.get_protobuff_for_key( tooltip_data.tooltip_main_icon) yield (TooltipFieldsComplete.main_icon.name, icon_data, None) if tooltip_data.display_object_preference is not None and not owner.is_sim: icon_infos = [] object_preference_tracker = services.object_preference_tracker( ) if object_preference_tracker is not None: object_id = owner.id for part in owner.parts: if not part.restrict_autonomy_preference: continue self._get_restriction_icon_info_msg( object_preference_tracker, object_id, icon_infos, tooltip_data.display_object_preference, subroot_index=part.subroot_index, description=part.part_name) if not icon_infos: self._get_restriction_icon_info_msg( object_preference_tracker, object_id, icon_infos, tooltip_data.display_object_preference) if icon_infos: yield (TooltipFieldsComplete.icon_infos.name, icon_infos, None) if owner.non_deletable_by_user and owner.is_in_inventory(): non_sellable_text_data = TooltipComponent.NON_SELLABLE_BY_PLAYER_TEXT yield (TooltipFieldsComplete.stolen_from_text.name, non_sellable_text_data.text(), non_sellable_text_data.override_component_information)
def start_situation(self): if self._target_object is None: self._self_destruct() resolver = SingleObjectResolver(self._target_object) self.object_creation.initialize_helper(resolver) self._created_object = self.object_creation.create_object(resolver) self._claim_object(self._created_object.id) super().start_situation() self._change_state(self.initial_state())
def execute_helper(self, interaction): if self.desired_state is not None: objects = list(services.object_manager().get_objects_with_tags_gen( *self.object_tags)) for obj in self.object_target.get_object_target_gen( interaction, objects): resolver = SingleObjectResolver(obj) if self.tests.run_tests(resolver): obj.set_state(self.desired_state.state, self.desired_state)
def _apply_state_change(self, state, change): resolver = SingleObjectResolver(self.owner) chance = change.chance.get_chance(resolver) if random.random() > chance: return if not change.tests.run_tests(resolver): return self.owner.set_state(state, change.value) for loot_action in change.loot_list: loot_action.apply_to_resolver(resolver)
def register_calbacks(self): if self.update_on_game_option_changed: services.get_event_manager().register_single_event( self, TestEvent.TestedGameOptionChanged) if self.update_if_stat_or_buck_changes: resolver = SingleObjectResolver(self.owner) always_true_threshold = Threshold(-1, operator.ne) for custom_tooltip in self.custom_tooltips: for tooltip_value in custom_tooltip.tooltip_fields.values(): if tooltip_value.text_tokens is not None: for text_token in tooltip_value.text_tokens.tokens: if text_token.token_type == LocalizationTokens.TOKEN_STATISTIC: participant = text_token.participant statistic = text_token.statistic for obj in resolver.get_participants( participant): if obj.has_component( objects.components.types. STATISTIC_COMPONENT): statistic_tracker = obj.get_component( objects.components.types. STATISTIC_COMPONENT ).get_statistic_tracker() statistic_listener = statistic_tracker.create_and_add_listener( statistic, always_true_threshold, lambda _: self. update_object_tooltip()) self._stat_update_listeners[ statistic_tracker].append( statistic_listener) if text_token.token_type == LocalizationTokens.TOKEN_BUCK: participant = text_token.participant bucks_type = text_token.bucks_type for obj in resolver.get_participants( participant): tracker = BucksUtils.get_tracker_for_bucks_type( bucks_type, owner_id=obj.id) callback = lambda: self.update_object_tooltip( ) tracker.add_bucks_modified_callback( bucks_type, callback) self._buck_callback_datas.append( (tracker, bucks_type, callback))
def get_tooltip_field(self, field, context=None, target=None): if field == TooltipFields.relic_description: sim = context.sim if sim is None: return return sim.sim_info.relic_tracker.get_description_for_objects( self.owner, target) name = TooltipFieldsComplete(field).name existing_handle = self._ui_metadata_handles.get(name, None) if existing_handle is not None: (_, _, value) = self.owner.get_ui_metadata(existing_handle) return value tooltip_component = None tooltip_override = self.owner.get_tooltip_override() if tooltip_override is not None: tooltip_component = tooltip_override.get_component( types.TOOLTIP_COMPONENT) if tooltip_component is None: tooltip_component = self tooltip_text = None resolver = SingleObjectResolver(self.owner) for tooltip_data in tooltip_component.custom_tooltips: object_tests = tooltip_data.object_tests if object_tests and not object_tests.run_tests(resolver): continue tooltip_text = tooltip_data.tooltip_fields.get(field, tooltip_text) if tooltip_text is not None: if tooltip_text.text_tokens is not None: tokens = tooltip_text.text_tokens.get_tokens(resolver) if None in tokens: return else: tokens = () text = tooltip_text.text(*tokens) external_field_data_tuple = tooltip_component._external_field_to_data.get( name) if external_field_data_tuple: tooltip_override_data = tooltip_text.override_component_information if tooltip_override_data is not None: if tooltip_override_data.concatenation_type == TooltipFieldConcatenationType.CONCATENATE_BEFORE: text = LocalizationHelperTuning.get_separated_string_by_style( tooltip_override_data.concatenation_style, text, external_field_data_tuple.field_data) else: text = LocalizationHelperTuning.get_separated_string_by_style( tooltip_override_data.concatenation_style, external_field_data_tuple.field_data, text) if name == self.SUBTEXT_HANDLE: if tooltip_component._ui_metadata_handles: subtext = tooltip_component.get_state_strings(text) if subtext is not None: text = subtext handle = self.owner.add_ui_metadata(name, text) self._ui_metadata_handles[name] = handle return text
def get_target(self, actor): if self.target_participant is None: return else: if actor.is_sim: resolver = SingleSimResolver(actor.sim_info) else: resolver = SingleObjectResolver(actor) targets = resolver.get_participants(self.target_participant) if targets: return next(iter(targets))
def provide_route_events(self, route_event_context, sim, path, failed_types=None, start_time=0, end_time=None, **kwargs): if self._target.is_sim: resolver = SingleSimResolver(self._target.sim_info) else: resolver = SingleObjectResolver(self._target) for route_event_cls in self.route_events.single_events: if route_event_cls is not None: if not failed_types is None: if route_event_cls not in failed_types: if not route_event_context.route_event_already_scheduled( route_event_cls): if not route_event_context.route_event_already_fully_considered( route_event_cls, self): if route_event_cls.test(resolver): route_event_context.add_route_event( RouteEventType.LOW_SINGLE, route_event_cls( provider=self, provider_required=True)) if not route_event_context.route_event_already_scheduled( route_event_cls): if not route_event_context.route_event_already_fully_considered( route_event_cls, self): if route_event_cls.test(resolver): route_event_context.add_route_event( RouteEventType.LOW_SINGLE, route_event_cls(provider=self, provider_required=True)) for route_event_cls in self.route_events.repeating_events: if route_event_cls is not None: if not failed_types is None: if route_event_cls not in failed_types: if not route_event_context.route_event_already_fully_considered( route_event_cls, self): if route_event_cls.test(resolver): route_event_context.add_route_event( RouteEventType.LOW_REPEAT, route_event_cls(provider=self, provider_required=True)) if not route_event_context.route_event_already_fully_considered( route_event_cls, self): if route_event_cls.test(resolver): route_event_context.add_route_event( RouteEventType.LOW_REPEAT, route_event_cls(provider=self, provider_required=True))
def vehicle_violates_privacy(self, vehicle): if vehicle.objectrouting_component is None: return False if self._vehicle_tests is not None: resolver = SingleObjectResolver(vehicle) if self._vehicle_tests.run_tests(resolver): return False elif not self.intersects_with_object(vehicle): return False elif not self.intersects_with_object(vehicle): return False return True
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 check_if_policies_followed(self): object_manager = services.object_manager() followed = 0 total_policies = 0 inspector_resolver = SingleSimResolver(self.owner.inspector_person()) for policy in self.civic_policy_follow_rules: current_policy_followed = False if len(policy.skip_test_condition) > 0: if not policy.skip_test_condition.run_tests(inspector_resolver): if not policy.street_civic_policy_test(): continue total_policies += 1 for obj in object_manager.get_objects_with_filter_gen(policy.whitelist_filter): resolver = SingleObjectResolver(obj) if policy.test.run_tests(resolver): followed += 1 current_policy_followed = True break if not current_policy_followed: self.owner.policies_not_followed.append(policy.policy_display_name) if not policy.street_civic_policy_test(): continue total_policies += 1 for obj in object_manager.get_objects_with_filter_gen(policy.whitelist_filter): resolver = SingleObjectResolver(obj) if policy.test.run_tests(resolver): followed += 1 current_policy_followed = True break if not current_policy_followed: self.owner.policies_not_followed.append(policy.policy_display_name) if total_policies == 0: return PolicyFollowing.FULL_FOLLOWED follow_fraction = float(followed)/total_policies if follow_fraction == 0: return PolicyFollowing.NOT_FOLLOWED if follow_fraction < 1: return PolicyFollowing.PARTIAL_FOLLOWED else: return PolicyFollowing.FULL_FOLLOWED
def _test_gathered_events_for_chance(self, actor): if actor.is_sim: resolver = SingleSimResolver(actor.sim_info) else: resolver = SingleObjectResolver(actor) for (route_event_type, route_events) in self._route_events_to_schedule.items(): for route_event in tuple(route_events): self._events_already_considered[route_event.provider_ref].add( type(route_event)) if route_event_type != RouteEventType.LOW_REPEAT and random( ) > route_event.chance.get_chance(resolver): route_events.remove(route_event)
def _apply_loots(self, loots): sim_info = None if self._staff_member is None else self._staff_member.sim_info obj = self._staffed_object if sim_info is not None: if obj is not None: resolver = SingleActorAndObjectResolver(sim_info, obj, self) else: resolver = SingleSimResolver(sim_info) elif obj is not None: resolver = SingleObjectResolver(obj) else: return for loot_action in loots: loot_action.apply_to_resolver(resolver)
def _run_gen(self, timeline): if self.pre_route_animation is not None: animation_element = self.pre_route_animation(self._obj) self._element = build_element( (animation_element, flush_all_animations)) result = yield from element_utils.run_child( timeline, self._element) if not result: return result yield def do_routes(timeline): result = False for route in self._route_data.get_routes_gen(): result = yield from self._do_single_route_gen(timeline, route) if not result: break if not result: yield from element_utils.run_child( timeline, element_utils.sleep_until_next_tick_element()) return result yield if self.walkstyle_override is None: yield from do_routes(timeline) else: walkstyle_request = self.walkstyle_override(self._obj) yield from element_utils.run_child( timeline, walkstyle_request(sequence=do_routes)) target = self._route_data.get_target() if target: if target.is_sim: yield from self._route_data.do_target_action_rules_gen( timeline) else: reservation_handler = target.get_reservation_handler(self._obj) if reservation_handler and reservation_handler.may_reserve(): reservation_handler.begin_reservation() try: yield from self._route_data.do_target_action_rules_gen( timeline) finally: reservation_handler.end_reservation() else: self._route_data.on_no_target() resolver = SingleObjectResolver(self._obj) for loot_action in self.completion_loot: loot_action.apply_to_resolver(resolver) return True yield
def calculate_object_quantity_statistic_values(cls, lot): for set_statatistic in cls.SET_STATISTIC_TUNING: lot.set_stat_value(set_statatistic.statistic, set_statatistic.amount) new_statistic_values = collections.defaultdict(int) for obj in services.object_manager().values(): if obj.is_sim: pass if not obj.is_on_active_lot(): pass resolver = SingleObjectResolver(obj) for (statistic, tests) in cls.OBJECT_COUNT_TUNING.items(): while tests.run_tests(resolver): new_statistic_values[statistic] += 1 for (statistic, value) in new_statistic_values.items(): lot.set_stat_value(statistic, value)
def _ui_metadata_gen(self): resolver = SingleObjectResolver(self.owner) for tooltip_data in self.custom_tooltips: object_tests = tooltip_data.object_tests if not (object_tests is not None and object_tests.run_tests(resolver)): pass self.owner.hover_tip = tooltip_data.tooltip_style for (tooltip_key, tooltip_text) in tooltip_data.tooltip_fields.items(): if tooltip_text.text_tokens is not None: tokens = tooltip_text.text_tokens.get_tokens(resolver) else: tokens = () yield (TooltipFields(tooltip_key).name, tooltip_text.text(*tokens))
def modify_objects_on_active_lot(self, modify_open_streets=False): objects_to_destroy = [] num_modified = 0 for obj in services.object_manager().values(): if obj.is_sim: pass while not (modify_open_streets and obj.is_on_active_lot()): if obj.in_use: pass resolver = SingleObjectResolver(obj) modified = False for action_and_test in self.modifications: if not action_and_test.tests.run_tests(resolver): pass modified = True action = action_and_test.action action_type = action.action_type if action_type == ModifyAllLotItems.DESTROY_OBJECT: objects_to_destroy.append(obj) break elif action_type == ModifyAllLotItems.SET_STATE: new_state_value = action.action_value if obj.state_component and obj.has_state( new_state_value.state): obj.set_state(new_state_value.state, new_state_value, immediate=True) if action_type in ( ModifyAllLotItems.INVENTORY_TRANSFER, ModifyAllLotItems.DELIVER_BILLS): element = action.action_value() element._do_behavior() else: raise NotImplementedError elif action_type in (ModifyAllLotItems.INVENTORY_TRANSFER, ModifyAllLotItems.DELIVER_BILLS): element = action.action_value() element._do_behavior() else: raise NotImplementedError while modified: num_modified += 1 for obj in objects_to_destroy: obj.destroy(source=self, cause='Destruction requested by modify lot tuning') objects_to_destroy = None return num_modified
def try_grow_puddle(self): if self.puddle_size == PuddleSize.LargePuddle: return resolver = SingleObjectResolver(self) chance = self.puddle_grow_chance.get_multiplier(resolver) if random.random() > chance: return else: if self.puddle_size == PuddleSize.MediumPuddle: puddle = create_puddle(PuddleSize.LargePuddle, puddle_liquid=self.puddle_liquid) else: puddle = create_puddle(PuddleSize.MediumPuddle, puddle_liquid=self.puddle_liquid) if puddle.place_puddle(self, 1, ids_to_ignore=[self.id]): if self._evaporate_callback_handle is not None: self.commodity_tracker.remove_listener(self._evaporate_callback_handle) self.destroy(self, cause='Puddle is growing.', fade_duration=ClientObjectMixin.FADE_DURATION) return puddle
def give_weather_loot(self, weather_types, is_start): if self._is_outside is not None: if self.owner.is_sim: resolver = SingleSimResolver(self.owner.sim_info) else: resolver = SingleObjectResolver(self.owner) if not is_start: self._give_loot(weather_types, self.anywhere_loot, resolver, is_start) if self._is_outside: self._give_loot(weather_types, self.outside_loot, resolver, is_start) else: self._give_loot(weather_types, self.inside_loot, resolver, is_start) if is_start: self._give_loot(weather_types, self.anywhere_loot, resolver, is_start)