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 apples(_connection=None): output = sims4.commands.CheatOutput(_connection) output('Loading fire mod...') tgt_client = services.client_manager().get(_connection) my_sim = tgt_client.active_sim output('Active Sim Loaded...') fire_service = services.get_fire_service() sim_info_manager = services.sim_info_manager() for sim in sim_info_manager.instanced_sims_gen(): current_zone = services.current_zone() sim_obj = current_zone.find_object(sim.id) if sim_obj is not None: output('Sim Obj Loaded...') orig_allowed = fire_service.is_fire_allowed output('Orig is_fire_allowed stored...') fire_service.is_fire_allowed = types.MethodType( _fire_allowed_override, fire_service) try: output('Orig is_fire_allowed overrided...') fire_object = fire_service._spawn_fire(sim_obj.transform, sim_obj.routing_surface) output('Fire spawned...') except Exception as ex: output('HMM...') output(str(ex)) fire_service.is_fire_allowed = orig_allowed output('Orig is_fire_allowed returned...')
def spawn_fire_at_object(target:RequiredTargetParam, num_fires:int=1, _connection=None): target_object = target.get_target() if target_object is None: sims4.commands.output(f'Invalid target object id {target_object}') return fire_service = services.get_fire_service() fire_service.spawn_fire_at_object(target_object, num_fires=num_fires)
def handle_event(self, sim_info, event, resolver): if event is TestEvent.InteractionComplete: if not self.owner.is_sim_info_in_situation(sim_info): return if resolver(self.owner.got_to_safety_interaction): self._change_state(_SafeState()) elif resolver(self.owner.panic_interaction) and services.get_fire_service().has_toddler_to_save_for_sim(sim_info): self._change_state(_SaveToddlerState())
def on_activate(self, reader=None): logger.debug('Sim is entering the Unaware state during a fire.') super().on_activate(reader) self.owner._set_job_role_state( self.owner.victim_job.situation_job, self.owner.victim_job.fire_unaware_state) fire_service = services.get_fire_service() fire_service.register_for_panic_callback()
def create_pie_menu_message(sim, context, choice_menu, reference_id, pie_menu_action, target=None): msg = interaction_protocol.PieMenuCreate() msg.sim = sim.id if sim is not None else 0 msg.client_reference_id = reference_id msg.server_reference_id = 0 if not choice_menu: fire_service = services.get_fire_service() if fire_service.fire_is_active: msg.disabled_tooltip = fire_service.INTERACTION_UNAVAILABLE_DUE_TO_FIRE_TOOLTIP() return msg if pie_menu_action == PieMenuActions.INTERACTION_QUEUE_FULL_TOOLTIP: msg.disabled_tooltip = PieMenuActions.INTERACTION_QUEUE_FULL_STR(sim) return msg create_tokens(msg.category_tokens, sim, target, None if target is None else target.get_stored_sim_info()) if choice_menu is not None: msg.server_reference_id = choice_menu.revision for (option_id, item) in choice_menu: with ProtocolBufferRollback(msg.items) as item_msg: item_msg.id = item.choice.aop_id choice = item.choice logger.debug('%3d: %s' % (option_id, choice)) name = choice.affordance.get_name(choice.target, context, **choice.interaction_parameters) (name_override_tunable, name_override_result) = choice.affordance.get_name_override_tunable_and_result(target=choice.target, context=context) if _make_pass: name = InteractionCommandsTuning.MAKE_PASS_INTERACTION_NAME(name) if _show_interaction_tuning_name: affordance_tuning_name = str(choice.affordance.__name__) name = InteractionCommandsTuning.INTERACTION_TUNING_NAME(name, affordance_tuning_name) item_msg.loc_string = name tooltip = item.result.tooltip if tooltip is not None: tooltip = choice.affordance.create_localized_string(tooltip, context=context, target=choice.target, **choice.interaction_parameters) item_msg.disabled_text = tooltip else: success_tooltip = choice.affordance.get_display_tooltip(override=name_override_tunable, context=context, target=choice.target, **choice.interaction_parameters) if success_tooltip is not None: item_msg.success_tooltip = success_tooltip pie_menu_icon = choice.affordance.pie_menu_icon category_key = item.category_key if name_override_tunable.new_pie_menu_icon is not None: pie_menu_icon = name_override_tunable.new_pie_menu_icon if name_override_tunable is not None and name_override_tunable.new_pie_menu_category is not None: category_key = name_override_tunable.new_pie_menu_category.guid64 if pie_menu_icon is not None: item_msg.icon_infos.append(create_icon_info_msg(IconInfoData(icon_resource=pie_menu_icon))) if category_key is not None: item_msg.category_key = category_key if item.result.icon is not None: item_msg.icon_infos.append(create_icon_info_msg(IconInfoData(icon_resource=item.result.icon))) if choice.show_posture_incompatible_icon: item_msg.icon_infos.append(create_icon_info_msg(IconInfoData(icon_resource=PieMenuActions.POSTURE_INCOMPATIBLE_ICON))) handle_pie_menu_item_coloring(item_msg, item, sim, choice, name_override_result) for visual_target in choice.affordance.visual_targets_gen(choice.target, context, **choice.interaction_parameters): while visual_target is not None: item_msg.target_ids.append(visual_target.id) item_msg.score = item.choice.content_score if item.choice.content_score is not None else 0 item_msg.pie_menu_priority = choice.affordance.pie_menu_priority return msg
def _on_set_sim_role_state(self, sim, job_type, role_state_type, role_affordance_target): super()._on_set_sim_role_state(sim, job_type, role_state_type, role_affordance_target) toddler = services.get_fire_service().get_toddler_to_save_for_sim(sim.sim_info) if toddler is None: self._change_state(_PanicState()) InteractionCancelCompatibility.cancel_interactions_for_reason(sim, InteractionCancelReason.DEATH, FinishingType.FIRE, 'Interaction was canceled due to saving a toddler from a fire.', additional_cancel_sources=(InteractionSource.SCRIPT,)) InteractionCancelCompatibility.cancel_interactions_for_reason(toddler, InteractionCancelReason.DEATH, FinishingType.FIRE, 'Interaction was canceled due to a toddler being saved from a fire.', additional_cancel_sources=(InteractionSource.SCRIPT,)) context = InteractionContext(sim, InteractionContext.SOURCE_SCRIPT, Priority.High, client=None, pick=None) sim.push_super_affordance(self.owner.save_toddler_interaction, toddler, context)
def on_remove(self): super().on_remove() self._remove_from_world() self.unregister_on_location_changed(self.inside_status_change) self.unregister_on_location_changed(self.natural_ground_status_change) if self.flammable and not self.is_sim: fire_service = services.get_fire_service() if fire_service: self.unregister_on_location_changed(fire_service.flammable_object_location_changed)
def on_add(self): super().on_add() self._add_to_world() self.register_on_location_changed(self.inside_status_change) self.register_on_location_changed(self.natural_ground_status_change) if (self.flammable or self.fire_retardant) and not self.is_sim: fire_service = services.get_fire_service() self.register_on_location_changed(fire_service.flammable_object_location_changed) self.object_addition_complete()
def raycast_context(self, for_carryable=False): if self._raycast_context_dirty: self._create_raycast_context(for_carryable=for_carryable) burning_objects = services.get_fire_service().objects_burning_from_fire_object(self) for obj in burning_objects: object_footprint_id = obj.routing_context.object_footprint_id while object_footprint_id is not None: self._raycast_context.ignore_footprint_contour(object_footprint_id) self._raycast_context_dirty = False return super().raycast_context(for_carryable=for_carryable)
def finalize(self, **kwargs): super().finalize(**kwargs) self.try_post_bb_fixup(**kwargs) if self.is_fire_related_object: fire_service = services.get_fire_service() if fire_service is not None: fire_service.flammable_object_location_changed(self) if posture_graph.is_object_mobile_posture_compatible(self): posture_graph_service = services.current_zone().posture_graph_service posture_graph_service.mobile_posture_object_location_changed(self)
def _apply_to_subject_and_target(self, subject, target, resolver): if subject is None: logger.error('Invalid subject specified for this loot operation. {} Please fix in tuning.', self) return subject_obj = self._get_object_from_recipient(subject) if subject_obj is None: logger.error('No valid object for subject specified for this loot operation. {} Please fix in tuning.', resolver) return fire_service = services.get_fire_service() fire_service.spawn_fire_at_object(subject_obj)
def _on_quadtree_changed(self): fire_service = services.get_fire_service() fire_quadtree = fire_service.fire_quadtree flammable_quadtree = fire_service.flammable_objects_quadtree zone = services.current_zone() pos = sims4.math.Vector2(0, 0) bounds = sims4.geometry.QtCircle(pos, 10000) if fire_quadtree is not None: fire_objects = fire_quadtree.query(bounds) else: fire_objects = [] if flammable_quadtree is not None: flammable_objects = flammable_quadtree.query(bounds) else: flammable_objects = [] with Context(self.layer) as layer: layer.set_color(Color.RED) for obj in fire_objects: level = obj.location.level height = terrain.get_lot_level_height( obj.position.x, obj.position.z, level, zone.id) + 0.1 radius = FireService.FIRE_QUADTREE_RADIUS pos = sims4.math.Vector3(obj.position.x, height, obj.position.z) layer.add_circle(pos, radius, altitude=KEEP_ALTITUDE) layer.set_color(Color.YELLOW) for obj in flammable_objects: if obj.location.world_routing_surface is None: pass level = obj.location.level height = terrain.get_lot_level_height( obj.position.x, obj.position.z, level, zone.id) + 0.1 radius = obj.object_radius if obj.fire_retardant: radius += FireService.FIRE_RETARDANT_EXTRA_OBJECT_RADIUS location = sims4.math.Vector2(obj.position.x, obj.position.z) object_bounds = obj.object_bounds_for_flammable_object( location=location, fire_retardant_bonus=FireService. FIRE_RETARDANT_EXTRA_OBJECT_RADIUS) if isinstance(object_bounds, QtCircle): pos = sims4.math.Vector3(obj.position.x, height, obj.position.z) layer.add_circle(pos, radius, altitude=KEEP_ALTITUDE) else: while isinstance(object_bounds, QtRect): v0 = sims4.math.Vector3(object_bounds.a.x, height, object_bounds.a.y) v2 = sims4.math.Vector3(object_bounds.b.x, height, object_bounds.b.y) delta = v2 - v0 v1 = v0 + sims4.math.Vector3(delta.x, 0, 0) v3 = v0 + sims4.math.Vector3(0, 0, delta.z) vertices = [v0, v1, v2, v3] layer.add_polygon(vertices, altitude=KEEP_ALTITUDE)
def flammable_object_location_changed(obj, old_loc, new_loc): fire_service = services.get_fire_service() if fire_service is not None: translation = new_loc.world_transform.translation location = sims4.math.Vector2(translation.x, translation.z) if isinstance(obj, Fire): fire_service._remove_fire_from_quadtree(obj) fire_service._add_fire_to_quadtree(obj, location) else: fire_service.remove_from_flammable_quadtree(obj) fire_service.add_to_flammable_quadtree(obj, location)
def _apply_to_subject_and_target(self, subject, target, resolver): if subject is None: logger.error('Subject {} is None for the loot {}..', self.subject, self) return fire_service = services.get_fire_service() if fire_service is None: logger.error('Fire Service in none when calling the lootop: {}.', self) return subject = self._get_object_from_recipient(subject) fire_service.extinguish_nearby_fires(subject) return True
def debugvis_fire_quadtree_start(_connection=None): fire_service = services.get_fire_service() fire_quadtree = fire_service.fire_quadtree flammable_quadtree = fire_service.flammable_objects_quadtree if fire_quadtree is not None or flammable_quadtree is not None: fire_vis_name = 'fire_quadtree' handle = 1 fire_layer = _create_layer(fire_vis_name, handle) fire_visualizer = FireQuadTreeVisualizer(fire_layer) if not _start_visualizer(_connection, fire_vis_name, _quadtree_layer_visualizers, handle, fire_visualizer, layer=fire_layer): return 0 return 1
def raycast_context(self, for_carryable=False): if self._raycast_context_dirty: self._create_raycast_context(for_carryable=for_carryable) burning_objects = services.get_fire_service( ).objects_burning_from_fire_object(self) for obj in burning_objects: object_footprint_id = obj.routing_context.object_footprint_id while object_footprint_id is not None: self._raycast_context.ignore_footprint_contour( object_footprint_id) self._raycast_context_dirty = False return super().raycast_context(for_carryable=for_carryable)
def _finalize_death(self): if self._has_finalized_death: return self._has_finalized_death = True sim_info = self.sim.sim_info current_household = sim_info.household death_object = self._death_object_data[0] if death_object is not None: death_object.add_dynamic_component(types.STORED_SIM_INFO_COMPONENT, sim_id=sim_info.id) death_object.update_object_tooltip() active_household = services.active_household() death_object.set_household_owner_id(active_household.id) if self._death_object_data[1]: try: if not build_buy.move_object_to_household_inventory( death_object): logger.error( 'Failed to place an urnstone for {} in household inventory: {}', sim_info, sim_info.household.id) except KeyError: logger.exception( 'Failed to place an urnstone for {} in household inventory: {}', sim_info, sim_info.household.id) death_tracker = sim_info.death_tracker death_type = None if self.death_info is not None: death_type = self.death_info.death_type death_tracker.set_death_type(death_type) if self.death_info is None or self.death_info.set_to_minimum_lod: sim_info.request_lod(SimInfoLODLevel.MINIMUM) if self._client is not None: self._client.set_next_sim_or_none( only_if_this_active_sim_info=sim_info) self._client.selectable_sims.remove_selectable_sim_info(sim_info) kill_all_fires = False if any(sim.can_live_alone for sim in self._client.selectable_sims): if self._show_off_lot_death_notification(): kill_all_fires = True else: kill_all_fires = True self._disband_travel_group() self._show_death_dialog() self._client.clear_selectable_sims() if kill_all_fires: fire_service = services.get_fire_service() if fire_service is not None: fire_service.kill() current_household.handle_adultless_household() services.daycare_service().refresh_household_daycare_nanny_status( sim_info)
def on_add(self): super().on_add() self._add_to_world() self.register_on_location_changed(self._location_changed) if self.is_fire_related_object: fire_service = services.get_fire_service() self.register_on_location_changed(fire_service.flammable_object_location_changed) posture_graph_service = services.posture_graph_service() if posture_graph.is_object_mobile_posture_compatible(self): self.register_on_location_changed(posture_graph_service.mobile_posture_object_location_changed) if self.provided_mobile_posture_affordances: posture_graph_service.add_mobile_posture_provider(self) services.call_to_action_service().object_created(self) self.try_mark_as_new_object()
def debugvis_fire_quadtree_start(_connection=None): fire_service = services.get_fire_service() fire_quadtree = fire_service.fire_quadtree flammable_quadtree = fire_service.flammable_objects_quadtree if fire_quadtree is not None or flammable_quadtree is not None: fire_vis_name = 'fire_quadtree' handle = 1 fire_layer = _create_layer(fire_vis_name, handle) fire_visualizer = FireQuadTreeVisualizer(fire_layer) if not _start_visualizer(_connection, fire_vis_name, _quadtree_layer_visualizers, handle, fire_visualizer, layer=fire_layer): return 0 return 1
def _on_quadtree_changed(self): fire_service = services.get_fire_service() fire_quadtree = fire_service.fire_quadtree flammable_quadtree = fire_service.flammable_objects_quadtree zone = services.current_zone() pos = sims4.math.Vector2(0, 0) bounds = sims4.geometry.QtCircle(pos, 10000) if fire_quadtree is not None: fire_objects = fire_quadtree.query(bounds) else: fire_objects = [] if flammable_quadtree is not None: flammable_objects = flammable_quadtree.query(bounds) else: flammable_objects = [] with Context(self.layer) as layer: layer.set_color(Color.RED) for obj in fire_objects: level = obj.location.level height = terrain.get_lot_level_height(obj.position.x, obj.position.z, level, zone.id) + 0.1 radius = FireService.FIRE_QUADTREE_RADIUS pos = sims4.math.Vector3(obj.position.x, height, obj.position.z) layer.add_circle(pos, radius, altitude=KEEP_ALTITUDE) layer.set_color(Color.YELLOW) for obj in flammable_objects: if obj.location.world_routing_surface is None: pass level = obj.location.level height = terrain.get_lot_level_height(obj.position.x, obj.position.z, level, zone.id) + 0.1 radius = obj.object_radius if obj.fire_retardant: radius += FireService.FIRE_RETARDANT_EXTRA_OBJECT_RADIUS location = sims4.math.Vector2(obj.position.x, obj.position.z) object_bounds = obj.object_bounds_for_flammable_object(location=location, fire_retardant_bonus=FireService.FIRE_RETARDANT_EXTRA_OBJECT_RADIUS) if isinstance(object_bounds, QtCircle): pos = sims4.math.Vector3(obj.position.x, height, obj.position.z) layer.add_circle(pos, radius, altitude=KEEP_ALTITUDE) else: while isinstance(object_bounds, QtRect): v0 = sims4.math.Vector3(object_bounds.a.x, height, object_bounds.a.y) v2 = sims4.math.Vector3(object_bounds.b.x, height, object_bounds.b.y) delta = v2 - v0 v1 = v0 + sims4.math.Vector3(delta.x, 0, 0) v3 = v0 + sims4.math.Vector3(0, 0, delta.z) vertices = [v0, v1, v2, v3] layer.add_polygon(vertices, altitude=KEEP_ALTITUDE)
def _finalize_death(self): if self._has_finalized_death: return self._has_finalized_death = True sim_info = self.sim.sim_info current_household = sim_info.household death_object = self._death_object_data[0] if death_object is not None: death_object.add_dynamic_component( types.STORED_SIM_INFO_COMPONENT.instance_attr, sim_id=sim_info.id) death_object.update_object_tooltip() death_object.set_household_owner_id(sim_info.household.id) if self._death_object_data[1]: build_buy.move_object_to_household_inventory(death_object) death_tracker = sim_info.death_tracker death_tracker.set_death_type(self.death_type) if self._client is not None: self._client.set_next_sim_or_none( only_if_this_active_sim_info=sim_info) self._client.selectable_sims.remove_selectable_sim_info(sim_info) if not any(sim.is_teen_or_older for sim in self._client.selectable_sims): self._show_death_dialog() persistence_service = services.get_persistence_service() sim_info_manager = services.sim_info_manager() for selectable_sim_info in self._client.selectable_sims: sim_id = selectable_sim_info.id sim_to_destroy = selectable_sim_info.get_sim_instance( allow_hidden_flags=ALL_HIDDEN_REASONS) if sim_to_destroy is not None: sim_to_destroy.destroy( source=sim_to_destroy, cause= 'Last adult sim dieing, destroying dependent sims.' ) persistence_service.del_sim_proto_buff(sim_id) sim_info_manager.remove_permanently(selectable_sim_info) self._client.clear_selectable_sims() zone_id = services.current_zone_id() current_household.clear_household_lot_ownership(zone_id) current_household.hidden = True fire_service = services.get_fire_service() if fire_service is not None: fire_service.kill()
def on_remove(self): zone = services.current_zone() if zone is not None and not zone.is_zone_shutting_down: services.get_event_manager().process_event(test_events.TestEvent.ObjectDestroyed, obj=self) super().on_remove() if not zone.is_zone_shutting_down: self._remove_from_world() self.unregister_on_location_changed(self._location_changed) if self.is_fire_related_object: fire_service = services.get_fire_service() if fire_service is not None: self.unregister_on_location_changed(fire_service.flammable_object_location_changed) posture_graph_service = services.posture_graph_service() if self.provided_mobile_posture_affordances: posture_graph_service.remove_mobile_posture_provider(self) if posture_graph.is_object_mobile_posture_compatible(self): posture_graph_service.remove_object_from_mobile_posture_quadtree(self) self.unregister_on_location_changed(posture_graph_service.mobile_posture_object_location_changed) else: self._on_location_changed_callbacks = None
def _apply_to_subject_and_target(self, subject, target, resolver): if subject is None: logger.error('Subject {} is None for the loot {}..', self.subject, self) return if not subject.is_sim: logger.error('Subject {} is not Sim for the loot {}.', self.subject, self) return fire_service = services.get_fire_service() if fire_service is None: logger.error('Fire Service in none when calling the lootop: {}.', self) return sim = self._get_object_from_recipient(subject) location = sims4.math.Vector3(*sim.location.transform.translation) + sim.forward level = sim.location.level scorch_locations = fire_service.find_cleanable_scorch_mark_locations_within_radius(location, level, fire_service.SCORCH_TERRAIN_CLEANUP_RADIUS) if scorch_locations: zone_id = sims4.zone_utils.get_zone_id() build_buy.begin_update_floor_features(zone_id, build_buy.FloorFeatureType.BURNT) for scorch_location in scorch_locations: build_buy.set_floor_feature(zone_id, build_buy.FloorFeatureType.BURNT, scorch_location, level, 0) build_buy.end_update_floor_features(zone_id, build_buy.FloorFeatureType.BURNT)
def strike_terrain(position=None): lightning_strike_tuning = LightningTuning.STRIKE_TERRAIN_TUNING if position is None: (position, routing_surface) = LightningStrike._get_terrain_position_and_routing_surface_for_lightning_strike() if position is None: return else: routing_surface = routing.SurfaceIdentifier(services.current_zone_id(), 0, routing.SurfaceType.SURFACETYPE_WORLD) terrain_point = TerrainPoint.create_for_position_and_orientation(position, routing_surface) lot = services.active_lot() if lot.is_position_on_lot(position): fire_service = services.get_fire_service() fire_service.add_delayed_scorch_mark(position, routing_surface, clock.interval_in_real_seconds(lightning_strike_tuning.scorch_mark_delay)) effect = lightning_strike_tuning.effect_on_lot(None, transform_override=terrain_point.transform) else: effect = lightning_strike_tuning.effect_off_lot(None, transform_override=terrain_point.transform) effect.start_one_shot() broadcaster_request = lightning_strike_tuning.broadcaster(terrain_point) broadcaster_request.start_one_shot() create_tuning = lightning_strike_tuning.create_object_tuning if random.random() < create_tuning.chance: weather_service = services.weather_service() weather_service.create_lightning_collectible_alarm(clock.interval_in_real_seconds(lightning_strike_tuning.scorch_mark_delay), terrain_point.location)
def _finalize_death(self): if self._has_finalized_death: return self._has_finalized_death = True sim_info = self.sim.sim_info current_household = sim_info.household death_object = self._death_object_data[0] if death_object is not None: death_object.add_dynamic_component(types.STORED_SIM_INFO_COMPONENT.instance_attr, sim_id=sim_info.id) death_object.update_object_tooltip() death_object.set_household_owner_id(sim_info.household.id) if self._death_object_data[1]: build_buy.move_object_to_household_inventory(death_object) death_tracker = sim_info.death_tracker death_tracker.set_death_type(self.death_type) if self._client is not None: self._client.set_next_sim_or_none(only_if_this_active_sim_info=sim_info) self._client.selectable_sims.remove_selectable_sim_info(sim_info) if not any(sim.is_teen_or_older for sim in self._client.selectable_sims): self._show_death_dialog() persistence_service = services.get_persistence_service() sim_info_manager = services.sim_info_manager() for selectable_sim_info in self._client.selectable_sims: sim_id = selectable_sim_info.id sim_to_destroy = selectable_sim_info.get_sim_instance(allow_hidden_flags=ALL_HIDDEN_REASONS) if sim_to_destroy is not None: sim_to_destroy.destroy(source=sim_to_destroy, cause='Last adult sim dieing, destroying dependent sims.') persistence_service.del_sim_proto_buff(sim_id) sim_info_manager.remove_permanently(selectable_sim_info) self._client.clear_selectable_sims() zone_id = services.current_zone_id() current_household.clear_household_lot_ownership(zone_id) current_household.hidden = True fire_service = services.get_fire_service() if fire_service is not None: fire_service.kill()
def modify_objects(self, object_criteria=None): objects_to_destroy = [] num_modified = 0 modifications = defaultdict(CompoundTestList) for mod in self.modifications: if not random_chance(mod.chance * 100): continue if mod.global_tests and not mod.global_tests.run_tests( GlobalResolver()): continue if mod.tests: modifications[mod.action].extend(mod.tests) if mod.weighted_tests: weighted_tests = [] for test_weight_pair in mod.weighted_tests: weighted_tests.append( (test_weight_pair.weight, test_weight_pair.tests)) modifications[mod.action].extend( weighted_random_item(weighted_tests)) if not modifications: return num_modified all_objects = list(services.object_manager().values()) for obj in all_objects: if obj.is_sim: continue if object_criteria is not None and not object_criteria(obj): continue resolver = SingleObjectResolver(obj) modified = False for (action, tests) in modifications.items(): if not tests.run_tests(resolver): continue modified = True 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() elif action_type == ModifyAllLotItems.SET_ON_FIRE: fire_service = services.get_fire_service() fire_service.spawn_fire_at_object(obj) elif action_type == ModifyAllLotItems.CLEANUP_VEHICLE: if self._should_cleanup_vehicle(obj): objects_to_destroy.append(obj) if action_type == ModifyAllLotItems.LOOT: for loot_action in action.loot_actions: loot_action.apply_to_resolver(resolver) else: raise NotImplementedError else: raise NotImplementedError elif action_type == ModifyAllLotItems.LOOT: for loot_action in action.loot_actions: loot_action.apply_to_resolver(resolver) else: raise NotImplementedError else: raise NotImplementedError elif action_type in (ModifyAllLotItems.INVENTORY_TRANSFER, ModifyAllLotItems.DELIVER_BILLS): element = action.action_value() element._do_behavior() elif action_type == ModifyAllLotItems.SET_ON_FIRE: fire_service = services.get_fire_service() fire_service.spawn_fire_at_object(obj) elif action_type == ModifyAllLotItems.CLEANUP_VEHICLE: if self._should_cleanup_vehicle(obj): objects_to_destroy.append(obj) if action_type == ModifyAllLotItems.LOOT: for loot_action in action.loot_actions: loot_action.apply_to_resolver(resolver) else: raise NotImplementedError else: raise NotImplementedError elif action_type == ModifyAllLotItems.LOOT: for loot_action in action.loot_actions: loot_action.apply_to_resolver(resolver) else: raise NotImplementedError else: raise NotImplementedError if 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 alert_all_sims(_connection=None): fire_service = services.get_fire_service() fire_service.alert_all_sims()
def on_remove(self): fire_service = services.get_fire_service() fire_service.remove_fire_object(self) super().on_remove()
def _start(self): services.get_fire_service().on_quadtree_changed.append(self._on_quadtree_changed) self._on_quadtree_changed()
def _do_transition(self, timeline) -> bool: source = self._source dest = self._dest sim = dest.sim posture_track = dest.track starting_position = sim.position def do_auto_exit(timeline): auto_exit_element = get_auto_exit((sim, ), asm=source.asm) if auto_exit_element is not None: yield from element_utils.run_child(timeline, auto_exit_element) if self._transition_spec is not None and self._transition_spec.portal_obj is not None: portal_obj = self._transition_spec.portal_obj if self._transition_spec.portal_id is not None: new_routing_surface = portal_obj.get_target_surface( self._transition_spec.portal_id) elif not dest.unconstrained and dest.target is not None: new_routing_surface = dest.target.routing_surface elif self._constraint is not None: new_routing_surface = self._constraint.routing_surface else: new_routing_surface = sim.routing_surface arb = animation.arb.Arb() if dest.external_transition: dest_begin = dest.begin(None, self._dest_state, self._context, new_routing_surface) result = yield from element_utils.run_child( timeline, must_run(dest_begin)) return result yield try: sim.active_transition = self posture_idle_started = False def start_posture_idle(*_, **__): nonlocal posture_idle_started if posture_idle_started: return dest.log_info('Idle') posture_idle_started = True idle_arb = animation.arb.Arb() dest.append_idle_to_arb(idle_arb) distribute_arb_element(idle_arb, master=sim) arb.register_event_handler(start_posture_idle, handler_id=self.IDLE_TRANSITION_XEVT) if self._transition_spec is not None: if sim.posture.mobile and self._transition_spec.path is not None: yield from element_utils.run_child(timeline, do_auto_exit) result = yield from self.do_transition_route( timeline, sim, source, dest) if not result: if self._transition_spec.is_failure_path: ( failure_reason, failure_target ) = sim.transition_controller.get_failure_reason_and_target( sim) if failure_reason is not None or failure_target is not None: if self._interaction is not None: yield from element_utils.run_child( timeline, handle_transition_failure( sim, self._interaction.target, self._interaction, failure_reason=failure_reason, failure_object_id=failure_target)) sim.transition_controller.cancel( cancel_reason_msg= 'Transition canceled due to successful route failure.' ) return result yield else: result = self._transition_spec.do_reservation(sim) if not result: return result yield if source is dest: sim.on_posture_event(PostureEvent.POSTURE_CHANGED, self._dest_state, dest.track, source, dest) return TestResult.TRUE yield self._status = self.Status.ANIMATING source_locked_params = frozendict() dest_locked_params = frozendict() if self._transition_spec is not None: source_locked_params = self._transition_spec.locked_params dest_locked_params = self._transition_spec.locked_params dest_posture_spec = None import services zone = services.current_zone() fire_service = services.get_fire_service() lot_on_fire = fire_service.fire_is_active distance_param = PostureTransition.calculate_distance_param( source.target, dest.target) if self._transition_spec is not None: if dest.track == PostureTrack.BODY: if not source.mobile: source_locked_params += {'onFire': lot_on_fire} if distance_param is not None: source_locked_params += { 'distance': distance_param } if not dest.mobile: dest_locked_params += {'onFire': lot_on_fire} if self._interaction is not None: transition_asm_params = sim.get_transition_asm_params( ) dest_locked_params += transition_asm_params source_locked_params += transition_asm_params if distance_param is not None: dest_locked_params += {'distance': distance_param} elif self._transition_spec.portal_obj is not None: transition_asm_params = sim.get_transition_asm_params() dest_locked_params += transition_asm_params source_locked_params += transition_asm_params transition_global_asm_params = sim.get_transition_global_asm_params( ) dest_locked_params += transition_global_asm_params source_locked_params += transition_global_asm_params dest_posture_spec = self._transition_spec.posture_spec source_locked_params += self._locked_params dest_locked_params += self._locked_params if self._transition_spec is not None and self._transition_spec.portal_obj is not None: target_override = self._transition_spec.portal_obj portal_params = self._transition_spec.portal_obj.get_portal_asm_params( self._transition_spec.portal_id, sim) source_locked_params += portal_params dest_locked_params += portal_params else: target_override = None def do_transition_animation(timeline): yield from element_utils.run_child(timeline, do_auto_exit) if PostureTrack.is_carry( dest.track ) and dest.target is not None and dest.target.is_sim: auto_exit_element = get_auto_exit((dest.target, ), asm=source.asm) if auto_exit_element is not None: yield from element_utils.run_child( timeline, auto_exit_element) source.append_exit_to_arb(arb, self._dest_state, dest, self._var_map, locked_params=source_locked_params, target_override=target_override) dest.append_transition_to_arb(arb, source, locked_params=dest_locked_params, posture_spec=dest_posture_spec, target_override=target_override) dest_begin = dest.begin(arb, self._dest_state, self._context, new_routing_surface) result = yield from element_utils.run_child( timeline, [do_auto_exit, dest_begin]) return result yield sequence = (do_transition_animation, ) from carry.carry_utils import interact_with_carried_object, holster_carried_object, maybe_holster_objects_through_sequence if dest.track.is_carry(dest.track): if dest.target is not None: carry_target = dest.target carry_posture_state = self._dest_state carry_animation_context = dest.asm.context else: carry_target = source.target carry_posture_state = sim.posture_state carry_animation_context = source.asm.context sequence = interact_with_carried_object( sim, carry_target, posture_state=carry_posture_state, interaction=dest.source_interaction, animation_context=carry_animation_context, sequence=sequence) if sim.is_required_to_holster_for_transition(source, dest): sequence = maybe_holster_objects_through_sequence( sim, sequence=sequence, unholster_after_predicate=self. _get_unholster_after_predicate(sim, dest.source_interaction)) else: sequence = holster_carried_object( sim, dest.source_interaction, self._get_unholster_predicate(sim, dest.source_interaction), flush_before_sequence=True, sequence=sequence) sequence = dest.add_transition_extras(sequence, arb=arb) mutex_key = self.get_entry_exit_mutex_key() if mutex_key is not None: sequence = mutex.with_mutex( mutex_key, element_utils.build_element(sequence)) sis = set() sis.add(source.source_interaction) sis.add(dest.source_interaction) sis.update(source.owning_interactions) sis.update(dest.owning_interactions) for si in sis: if si is None: continue with si.cancel_deferred(sis): result = yield from element_utils.run_child( timeline, must_run(sequence)) break else: result = yield from element_utils.run_child( timeline, must_run(sequence)) if result: start_posture_idle() yield from sim.si_state.process_gen(timeline) finally: sim.active_transition = None self._status = self.Status.FINISHED if self._transition_spec is not None: self._transition_spec.release_additional_reservation_handlers() self._transition_spec.remove_props_created_to_reserve_slots( sim) if self._transition_spec.portal_obj is not None: self._transition_spec.portal_obj.clear_portal_cost_override( self._transition_spec.portal_id, sim=sim) if sim.posture_state.get_aspect(posture_track) is not dest: logger.debug( "{}: _do_transition failed: after transition Sim's posture state aspect isn't destination posture." ) if dest.source_interaction is not None: dest.source_interaction.cancel( FinishingType.TRANSITION_FAILURE, cancel_reason_msg='Transition canceled during transition.') return TestResult( False, "After transition Sim's posture state aspect isn't destination posture." ) yield if not dest.unconstrained and not not ( sim.transition_controller is not None and sims4.math.vector3_almost_equal( sim.position, starting_position, epsilon=sims4.geometry.ANIMATION_SLOT_EPSILON)): sim.transition_controller.release_stand_slot_reservations((sim, )) return TestResult.TRUE yield
def on_remove(self): fire_service = services.get_fire_service() if fire_service is not None: for sim in self.all_sims_in_situation_gen(): fire_service.remove_fire_situation(sim) super().on_remove()
def on_activate(self, reader=None): logger.debug('Sim is entering the Unaware state during a fire.') super().on_activate(reader) self.owner._set_job_role_state(self.owner.victim_job.situation_job, self.owner.victim_job.fire_unaware_state) fire_service = services.get_fire_service() fire_service.register_for_panic_callback()
def _apply_broadcaster_effect(self, broadcaster, affected_object): if random.random() <= self.percent_chance: fire_service = services.get_fire_service() fire_service.spawn_fire_at_object(affected_object)
def kill(_connection=None): fire_service = services.get_fire_service() fire_service.kill()
def on_remove(self): fire_service = services.get_fire_service() if fire_service is not None: for sim in self.all_sims_in_situation_gen(): fire_service.remove_fire_situation(sim) super().on_remove()
def start(self, *_, **__): if random.random() < self.chance: fire_service = services.get_fire_service() fire_service.spawn_fire_at_object(self.target)
def flammable(self): fire_service = services.get_fire_service() if fire_service is not None: return fire_service.is_object_flammable(self) return False
def _apply_to_subject_and_target(self, subject, target, resolver): fire_service = services.get_fire_service() if fire_service is not None: fire_service.deactivate_sprinkler_system()
def on_remove(self): fire_service = services.get_fire_service() fire_service.remove_fire_object(self) super().on_remove()
def stop(self): services.get_fire_service().on_quadtree_changed.remove(self._on_quadtree_changed)
def __call__(self, test_target=None): for target in test_target: if isinstance(target, sims.sim_info.SimInfo): target = target.get_sim_instance(allow_hidden_flags=ALL_HIDDEN_REASONS) if target is None: return TestResult(False, 'Testing Location an uninstantiated Sim.', tooltip=self.tooltip) if self.location_tests.is_outside is not None: is_outside = not target.is_hidden() and target.is_outside if self.location_tests.is_outside != is_outside: return TestResult(False, 'Object failed outside location test', tooltip=self.tooltip) if self.location_tests.is_natural_ground is not None and self.location_tests.is_natural_ground != target.is_on_natural_ground(): return TestResult(False, 'Object failed natural ground location test.', tooltip=self.tooltip) if self.location_tests.is_in_slot is not None: (slot_test_passed, slot_test_reason) = self.location_tests.is_in_slot.slot_test_type.run_slot_test(target) if not slot_test_passed: return TestResult(False, slot_test_reason, tooltip=self.tooltip) if self.location_tests.is_venue_type is not None: required_venue_tuning = self.location_tests.is_venue_type.venue_type venue_zone = services.get_zone(target.zone_id) if venue_zone is None: return TestResult(False, 'Object is not in an active zone', tooltip=self.tooltip) if self.location_tests.is_venue_type.use_source_venue: venue = venue_zone.venue_service.source_venue else: venue = venue_zone.venue_service.active_venue if self.location_tests.is_venue_type.negate: if required_venue_tuning is not None and isinstance(venue, required_venue_tuning): return TestResult(False, 'Object failed venue type test.', tooltip=self.tooltip) elif required_venue_tuning is None or not isinstance(venue, self.location_tests.is_venue_type.venue_type): return TestResult(False, 'Object failed venue type test.', tooltip=self.tooltip) if self.location_tests.is_on_active_lot is not None and not self.test_is_on_active_lot(self.location_tests.is_on_active_lot, target.position): return TestResult(False, 'Object failed on active lot test', tooltip=self.tooltip) if self.location_tests.is_fire_allowed is not None: fire_service = services.get_fire_service() allowed = fire_service.is_fire_allowed(target.transform, target.routing_surface) if self.location_tests.is_fire_allowed != allowed: return TestResult(False, 'Object failed is_fire_allowed test', tooltip=self.tooltip) if self.location_tests.in_common_area is not None: plex_service = services.get_plex_service() if self.location_tests.in_common_area != (plex_service.is_active_zone_a_plex() and plex_service.get_plex_zone_at_position(target.position, target.level) is None): return TestResult(False, 'Object failed in common area test.', tooltip=self.tooltip) if self.location_tests.is_on_level is not None: level = target.level if target.is_sim: if target.in_pool: level += 1 if not self.location_tests.is_on_level.compare(level): return TestResult(False, 'Object not on required level.', tooltip=self.tooltip) if self.location_tests.has_terrain_tag is not None: position = target.position is_terrain_tag_at_position = terrain.is_terrain_tag_at_position(position.x, position.z, self.location_tests.has_terrain_tag.terrain_tags, level=target.routing_surface.secondary_id, test_floor_tiles=self.location_tests.has_terrain_tag.test_floor_tiles) if self.location_tests.has_terrain_tag.negate: if is_terrain_tag_at_position: return TestResult(False, 'Object on required terrain tag, but negate is checked', tooltip=self.tooltip) elif not is_terrain_tag_at_position: return TestResult(False, 'Object not on required terrain tag.', tooltip=self.tooltip) if self.location_tests.valid_surface_types is not None: if not target.routing_surface is None: if not self.location_tests.valid_surface_types.test_item(target.routing_surface.type): return TestResult(False, 'Object routing surface is incorrect.', tooltip=self.tooltip) return TestResult(False, 'Object routing surface is incorrect.', tooltip=self.tooltip) return TestResult.TRUE