def on_update(self): super().on_update() self._countdown -= 1 if self._countdown <= 0: services.active_lot().on_hit_their_marks() services.sim_spawner_service().on_hit_their_marks() services.get_zone_situation_manager( ).on_hit_their_marks_during_zone_spin_up() services.current_zone().on_hit_their_marks() return _ZoneSpinUpStateResult.DONE services.game_clock_service().advance_for_hitting_their_marks() return _ZoneSpinUpStateResult.WAITING
def on_build_buy_exit(self): self._update_navmesh_id_if_neccessary() self.is_in_build_buy = False self._add_expenditures_and_do_post_bb_fixup() services.active_lot().flag_as_premade(False) services.get_event_manager().process_events_for_household( test_events.TestEvent.OnExitBuildBuy, None) self._should_perform_deferred_front_door_check = True laundry_service = services.get_laundry_service() if laundry_service is not None: laundry_service.on_build_buy_exit() save_game()
def _get_ungreeted_overrides(self, context, **kwargs): if context.pick.pick_type not in PICK_UNGREETED: return if not context.pick.lot_id or context.pick.lot_id != services.active_lot().lot_id: return if not services.get_zone_situation_manager().is_player_waiting_to_be_greeted(): return active_lot = services.active_lot() front_door = services.object_manager().get(active_lot.front_door_id) if front_door is None: return yield front_door.potential_interactions(context, **kwargs)
def _get_ungreeted_overrides(self, context, **kwargs): if context.pick.pick_type not in PICK_UNGREETED: return if not context.pick.lot_id or context.pick.lot_id != services.active_lot( ).lot_id: return if not services.get_zone_situation_manager( ).is_player_waiting_to_be_greeted(): return active_lot = services.active_lot() front_door = services.object_manager().get(active_lot.front_door_id) if front_door is None: return yield front_door.potential_interactions(context, **kwargs)
def sim_breaking_curfew(self, sim, target, interaction=None): if interaction is not None and self.interaction_blacklisted( interaction): return False if sim.sim_info.is_in_travel_group(): return False situation_manager = services.get_zone_situation_manager() sim_situations = situation_manager.get_situations_sim_is_in(sim) if any(situation.disallows_curfew_violation for situation in sim_situations): return False active_household = services.active_household() if active_household is None: return False home_zone_id = active_household.home_zone_id curfew_setting = self._zone_curfew_data.get(home_zone_id, CurfewService.UNSET) if sim.sim_info not in active_household: return False if curfew_setting is not CurfewService.UNSET: if sim.sim_info.is_young_adult_or_older: return False elif self.past_curfew(curfew_setting): if not services.current_zone_id() == home_zone_id: ensemble_service = services.ensemble_service() ensemble = ensemble_service.get_visible_ensemble_for_sim( sim) if ensemble is not None and any( sim.sim_info.is_young_adult_or_older and sim.sim_info in active_household for sim in ensemble): return False return True if target is not None and not target.is_in_inventory( ) and not services.active_lot().is_position_on_lot( target.position): return True elif target is None and not services.active_lot( ).is_position_on_lot(sim.position): return True return True if target is not None and not target.is_in_inventory( ) and not services.active_lot().is_position_on_lot( target.position): return True elif target is None and not services.active_lot( ).is_position_on_lot(sim.position): return True return False
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 apply_object_actions(cls, is_build_eco_effects_enabled): if not is_build_eco_effects_enabled: return if not cls.object_tag_to_actions: return object_tags = list(cls.object_tag_to_actions.keys()) curr_obj_tag_id_to_count = services.active_lot( ).get_object_count_by_tags(object_tags) if cls._obj_tag_id_to_count is None: delta_obj_tag_id_to_count = curr_obj_tag_id_to_count else: delta_obj_tag_id_to_count = { key: curr_obj_tag_id_to_count[key] - cls._obj_tag_id_to_count[key] for key in curr_obj_tag_id_to_count } zone = services.current_zone() for (obj_tag_id, obj_count) in delta_obj_tag_id_to_count.items(): if obj_count != 0: for action in cls.object_tag_to_actions[Tag(obj_tag_id)]: success = action.apply(obj_count) if not success: continue if action.action_type == ZoneModifierFromObjectsActionType.STATISTIC_CHANGE: zone.zone_architectural_stat_effects[ action.stat.guid64] += action.get_value(obj_count) cls._on_build_objects_environment_score_update() cls._obj_tag_id_to_count = curr_obj_tag_id_to_count
def set_advertising_type(self, advertising_type): commodity = RetailTuning.ADVERTISING_COMMODITY_MAP.get( advertising_type, None) if commodity is not None: tracker = services.active_lot().commodity_tracker tracker.remove_statistic(commodity) tracker.add_statistic(commodity)
def purchase_to_inventory(inventory_obj, def_id: str = None, mailman_purchase: bool = False, _connection=None): definition_manager = services.definition_manager() definition = definition_manager.get(def_id) if definition is None: return False client = services.client_manager().get(_connection) if client is None: return False household = client.household price = definition.price if household.funds.money < price: return False if mailman_purchase: obj = services.active_lot().create_object_in_hidden_inventory( definition) else: inventory = inventory_obj.get_target().inventory_component if inventory is None: return False obj = create_object(definition) if obj is None: return False if not inventory.player_try_add_object(obj): obj.destroy(source=inventory, cause='Failed to purchase object into inventory') return False obj.set_household_owner_id(household.id) obj.try_post_bb_fixup(force_fixup=True, active_household_id=services.active_household_id()) household.funds.remove(price, Consts_pb2.TELEMETRY_OBJECT_BUY) return True
def purchase_to_inventory(inventory_obj, def_id:str=None, mailman_purchase:bool=False, _connection=None): definition_manager = services.definition_manager() definition = definition_manager.get(def_id) if definition is None: return False client = services.client_manager().get(_connection) if client is None: return False household = client.household price = definition.price if household.funds.money < price: return False if mailman_purchase: obj = services.active_lot().create_object_in_hidden_inventory(definition) else: inventory = inventory_obj.get_target().inventory_component if inventory is None: return False obj = create_object(definition) if obj is None: return False if not inventory.player_try_add_object(obj): obj.destroy(source=inventory, cause='Failed to purchase object into inventory') return False obj.set_household_owner_id(household.id) obj.try_post_bb_fixup(force_fixup=True, active_household_id=services.active_household_id()) household.funds.remove(price, Consts_pb2.TELEMETRY_OBJECT_BUY) return True
def transfer_entire_inventory(source, recipient): if source is None or recipient is None: raise ValueError('Attempt to transfer items from {} to {}.'.format(source, recipient)) lot = services.active_lot() if isinstance(source, InventoryType): source_inventory = lot.get_object_inventory(source) else: source_inventory = source.inventory_component if source_inventory is None: raise ValueError('Failed to find inventory component for source of inventory transfer: {}'.format(source)) recipient_is_inventory_type = isinstance(recipient, InventoryType) if recipient_is_inventory_type: recipient_inventory = lot.get_object_inventory(recipient) else: recipient_inventory = recipient.inventory_component if recipient_inventory is None: raise ValueError('Attempt to transfer items to an object that has no inventory component: {}'.format(recipient)) for obj in list(source_inventory): if not source_inventory.try_remove_object_by_id(obj.id, force_remove_stack=True): logger.warn('Failed to remove object {} from {} inventory', obj, source) if recipient_inventory.can_add(obj): if not recipient_is_inventory_type and recipient.is_sim: obj.update_ownership(recipient) recipient_inventory.system_add_object(obj, None if recipient_is_inventory_type else recipient) else: obj.set_household_owner_id(services.active_household_id()) build_buy.move_object_to_household_inventory(obj, object_location_type=ObjectOriginLocation.SIM_INVENTORY)
def _get_lot_advertising_commodity_values(self): tracker = services.active_lot().commodity_tracker commodities = RetailTuning.ADVERTISING_COMMODITY_MAP.values() return [ tracker.get_value(c) for c in commodities if tracker.has_statistic(c) ]
def _spawn_fire(self, transform, routing_surface, run_placement_tests=True): if not fire_enabled: logger.info('Trying to spawn fire when fire is disabled. Please use |fire.toggle_enabled cheat to turn fire on.') return if not services.active_lot().is_position_on_lot(transform.translation): logger.info('Trying to spawn fire on a lot other than the active lot.') return if not services.venue_service().venue.allows_fire: logger.info("Trying to spawn a fire on a venue that doesn't allow fire.") return if not (run_placement_tests and self._placement_tests(transform.translation, routing_surface.secondary_id)): logger.info('Trying to spawn a fire on a lot at a position that is not valid.') return fire_object = system.create_object(self.FIRE_OBJECT_DEF) fire_object.move_to(transform=transform, routing_surface=routing_surface) first_fire_on_lot = False if self._fire_objects else True self._fire_objects.add(fire_object) fire_object.add_state_changed_callback(self._fire_object_state_changed_callback) self.start_objects_burning(fire_object) self.add_scorch_mark(fire_object.position, fire_object.location.level) self._derail_routing_sims_if_necessary(fire_object) if first_fire_on_lot: self._start_fire_situations() self.activate_fire_alarms() self.activate_sprinkler_system() self._show_fire_notification() self._create_or_replace_scorch_cleanup_alarm() services.get_persistence_service().lock_save(self) self.register_for_sim_active_lot_status_changed_callback() if self._fire_spread_alarm is None: time_span = date_and_time.create_time_span(minutes=self.FIRE_SPREAD_INTIAL_TIME_IN_SIM_MINUTES) repeating_time_span = date_and_time.create_time_span(minutes=self.FIRE_SPREAD_REPEATING_TIME_IN_SIM_MINUTES) self._fire_spread_alarm = alarms.add_alarm(self, time_span, self._fire_spread_alarm_callback, repeating=True, repeating_time_span=repeating_time_span)
def on_finalize_load(self): sim_info = services.sim_info_manager().get(self.sim_id) if sim_info is None or sim_info.household is not services.active_lot( ).get_household(): _replace_bassinet(sim_info, bassinet=self) else: self.set_sim_info(sim_info)
def try_open_npc_store(self): if self.owner_household_id is None: self._open_pure_npc_store(services.active_lot().get_premade_status() == PremadeLotStatus.IS_PREMADE) elif not self.is_owner_household_active: self._open_household_owned_npc_store() with telemetry_helper.begin_hook(business_telemetry_writer, TELEMETRY_HOOK_NPC_BUSINESS_VISITED, household=services.household_manager().get(self.owner_household_id)) as hook: hook.write_enum(TELEMETRY_HOOK_BUSINESS_TYPE, self.business_type)
def _calculate_valid_locations(self): self._valid_attractor_positions.clear() for attractor_tuning in self.attractors: terrain_tags = list(attractor_tuning.terrain_tags ) if attractor_tuning.terrain_tags else [] objects_to_ignore = self._attractor_ids[attractor_tuning] sample_points = services.active_lot( ).get_uniform_sampling_of_points(attractor_tuning.samples_per_axis, attractor_tuning.samples_per_axis) for point in sample_points: starting_location_for_sample = placement.create_starting_location( position=point) placement_polygon = sims4.geometry.generate_circle_constraint( attractor_tuning.placement_circle.number_of_sides, point, attractor_tuning.placement_circle.radius) fgl_context = placement.FindGoodLocationContext( starting_location_for_sample, object_polygons=(placement_polygon, ), ignored_object_ids=objects_to_ignore, max_distance=attractor_tuning.placement_radius, terrain_tags=terrain_tags, min_water_depth=attractor_tuning.min_water_depth, max_water_depth=attractor_tuning.max_water_depth, search_flags=placement.FGLSearchFlagsDefault | placement.FGLSearchFlag.ALLOW_GOALS_IN_SIM_POSITIONS | placement.FGLSearchFlag. ALLOW_GOALS_IN_SIM_INTENDED_POSITIONS) (position, orientation) = placement.find_good_location(fgl_context) if position: self._valid_attractor_positions[attractor_tuning].append( (position, orientation))
def routing_location(self): lot = services.active_lot() return routing.Location(lot.position, orientation=lot.orientation, routing_surface=routing.SurfaceIdentifier( services.current_zone().id, 0, routing.SurfaceType.SURFACETYPE_WORLD))
def create_and_place_baby(sim_info, **kwargs): bassinet = create_object(Baby.get_default_baby_def(), obj_id=sim_info.sim_id) bassinet.set_sim_info(sim_info, **kwargs) def try_to_place_bassinet(position, **kwargs): fgl_context = placement.FindGoodLocationContext(starting_position=position, object_id=sim_info.sim_id, search_flags=placement.FGLSearchFlagsDefault | placement.FGLSearchFlag.SHOULD_TEST_BUILDBUY, object_footprints=(bassinet.get_footprint(),), **kwargs) (translation, orientation) = placement.find_good_location(fgl_context) if translation is not None and orientation is not None: bassinet.move_to(translation=translation, orientation=orientation) return True return False lot = services.active_lot() for tag in Baby.BABY_PLACEMENT_TAGS: for (attempt, obj) in enumerate(services.object_manager().get_objects_with_tag_gen(tag)): position = obj.position if lot.is_position_on_lot(position) and try_to_place_bassinet(position, max_distance=10): return while attempt >= Baby.MAX_PLACEMENT_ATTEMPTS: break position = lot.get_default_position() if not try_to_place_bassinet(position): bassinet.update_ownership(sim_info, make_sim_owner=False) build_buy.move_object_to_household_inventory(bassinet) if sim_info.is_selectable: failed_placement_notification = Baby.FAILED_PLACEMENT_NOTIFICATION(sim_info, SingleSimResolver(sim_info)) failed_placement_notification.show_dialog()
def on_add(self): lot = services.active_lot() if self.is_shared_inventory: shared_inventory = lot.get_object_inventories( self.inventory_type)[0] self._storage = shared_inventory._storage self._hidden_storage = shared_inventory._hidden_storage self._update_inventory_count() for obj in self._storage: for state_trigger in self._inventory_state_triggers: state_trigger.on_object_added(obj) else: self._storage = InventoryStorage( self.inventory_type, self.default_item_location, max_size=InventoryTypeTuning. get_max_inventory_size_for_inventory_type(self.inventory_type), allow_ui=self.allow_ui) self._hidden_storage = InventoryStorage(self.inventory_type, self.default_item_location, allow_compaction=False, allow_ui=False, hidden_storage=True) lot.inventory_owners[self.inventory_type].add(self.owner) self._update_inventory_count() self._storage.register(self)
def check_collection_complete(self, collection_id): collection_data = ObjectCollectionData.get_collection_data(collection_id) collection_count = len(collection_data.object_list) collected_count = sum(1 for collection in self._collections.values() if collection == collection_id) if not collection_count or not collected_count: return client = services.client_manager().get_client_by_household(self._owner) if client is not None and client.active_sim is not None: message_owner_info = client.active_sim.sim_info else: message_owner_info = None if collection_data.first_collected_notification is not None and message_owner_info is not None and collected_count == 1: dialog = collection_data.first_collected_notification(message_owner_info, None) dialog.show_dialog() if collection_count == collected_count: if client is not None: with telemetry_helper.begin_hook(collection_telemetry_writer, TELEMETRY_HOOK_COLLECTION_COMPLETE, household=client.household) as hook: hook.write_int(TELEMETRY_COLLECTION_ID, collection_id) _sting = ObjectCollectionData.COLLECTION_COMPLETED_STING(client.active_sim) _sting.start() if message_owner_info is not None: dialog = collection_data.completed_award_notification(message_owner_info, None) dialog.show_dialog() if collection_data.screen_slam is not None: collection_data.screen_slam.send_screen_slam_message(message_owner_info, collection_data.collection_name) lot = services.active_lot() if lot is not None: lot.create_object_in_hidden_inventory(collection_data.completed_award) household = services.household_manager().get(self._owner.id) if household is not None: household.funds.add(collection_data.completed_award_money, Consts_pb2.TELEMETRY_MONEY_ASPIRATION_REWARD, None) elif client is not None: _sting = ObjectCollectionData.COLLECTION_COLLECTED_STING(client.active_sim) _sting.start()
def get_particpants_shared(participant_type): if participant_type == ParticipantType.Lot: return (services.active_lot(),) if participant_type == ParticipantType.LotOwners: owning_household = services.owning_household_of_active_lot() if owning_household is not None: return tuple(sim_info for sim_info in owning_household.sim_info_gen()) return ()
def get_advertising_type_for_gsi(self): if services.current_zone_id() == self._zone_id: tracker = services.active_lot().commodity_tracker commodities = RetailTuning.ADVERTISING_COMMODITY_MAP.values() return str([(c, tracker.get_value(c)) for c in commodities if tracker.has_statistic(c)]) else: return ''
def get_objects_gen(self, resolver): lot = services.active_lot() pos = lot.get_lot_position(self.lot_location_strategy) from objects.terrain import TerrainPoint yield TerrainPoint.create_for_position_and_orientation( position=pos, routing_surface=SurfaceIdentifier(services.current_zone_id(), 0, SurfaceType.SURFACETYPE_WORLD))
def get_particpants_shared(participant_type): if participant_type == ParticipantType.Lot: return (services.active_lot(), ) if participant_type == ParticipantType.LotOwners: owning_household = services.owning_household_of_active_lot() if owning_household is not None: return tuple(sim_info for sim_info in owning_household.sim_info_gen()) return ()
def list_objects_in_hidden_inventory(_connection=None): lot = services.active_lot() if lot is not None: hidden_inventory = lot.get_hidden_inventory() if hidden_inventory is not None: for obj in hidden_inventory: sims4.commands.output(str(obj), _connection) return True return False
def validate_front_door(_connection=None): active_lot = services.active_lot() if active_lot is None: return door = services.get_door_service().get_front_door() if door is None: sims4.commands.output('Lot has no front door set', _connection) else: sims4.commands.output('Front door found. Door {} on position {}'.format(str(door), door.position), _connection)
def get_current_lot() -> Lot: """get_current_lot() Retrieve the current lot. :return: The current Lot. :rtype: Lot """ return services.active_lot()
def has_choices(target_id:int=None, pick_type=PickType.PICK_TERRAIN, x:float=0.0, y:float=0.0, z:float=0.0, lot_id:int=0, level:int=0, control:int=0, alt:int=0, shift:int=0, reference_id:int=0, _connection=None): if target_id is None: return zone = services.current_zone() client = zone.client_manager.get(_connection) if client is None: return sim = _active_sim(client) shift_held = bool(shift) if shift_held: if client.household.cheats_enabled or __debug__: _send_interactable_message(client, target_id, True) else: _send_interactable_message(client, target_id, False) return context = None pick_type = int(pick_type) pick_pos = sims4.math.Vector3(x, y, z) routing_surface = routing.SurfaceIdentifier(zone.id, level, routing.SURFACETYPE_WORLD) target = zone.find_object(target_id) if pick_type in PICK_USE_TERRAIN_OBJECT or lot_id and lot_id != services.active_lot().lot_id: location = sims4.math.Location(sims4.math.Transform(pick_pos), routing_surface) target = objects.terrain.TerrainPoint(location) elif pick_type == PickType.PICK_SIM and target is None: target = sim elif pick_type == PickType.PICK_OBJECT and target is not None and target.object_routing_surface is not None: pick_type = int(pick_type) routing_surface = target.object_routing_surface location = sims4.math.Location(sims4.math.Transform(pick_pos), routing_surface) target = objects.terrain.TerrainPoint(location) is_interactable = False if target is not None: pick = PickInfo(pick_type, target, pick_pos, routing_surface, lot_id, bool(alt), bool(control)) context = client.create_interaction_context(sim, pick=pick) for aop in target.potential_interactions(context): result = ChoiceMenu.is_valid_aop(aop, context, False, user_pick_target=target) if not result and not result.tooltip: pass is_interactable = aop.affordance.allow_user_directed if not is_interactable: is_interactable = aop.affordance.has_pie_menu_sub_interactions(aop.target, context, **aop.interaction_parameters) while is_interactable: break if not is_interactable and sim is not None: while True: for si in sim.si_state: potential_targets = si.get_potential_mixer_targets() while True: for potential_target in potential_targets: if target is potential_target: break while potential_target.is_part and potential_target.part_owner is target: break while autonomy.content_sets.any_content_set_available(sim, si.super_affordance, si, context, potential_targets=(target,), include_failed_aops_with_tooltip=True): is_interactable = True break _send_interactable_message(client, target_id, is_interactable, True)
def list_objects_in_hidden_inventory(_connection=None): lot = services.active_lot() if lot is not None: hidden_inventory = lot.get_hidden_inventory() if hidden_inventory is not None: for obj in hidden_inventory: sims4.commands.output(str(obj), _connection) return True return False
def _get_target(self, _connection): if self._target_id is None: tgt_client = services.client_manager().get(_connection) if tgt_client is not None: return tgt_client.active_sim return if self._target_id == self.TARGET_ID_ACTIVE_LOT: return services.active_lot() return services.object_manager().get(self._target_id)
def test_lock(self, sim): if self.except_household and services.active_lot().get_household( ) is sim.household: return LockResult(False, 'all_lock', self.lock_priority, self.lock_sides) if self.except_sim_ids and sim.id in self.except_sim_ids: return LockResult(False, 'all_lock', self.lock_priority, self.lock_sides) return LockResult(True, 'all_lock', self.lock_priority, self.lock_sides)
def update(sim_id=None, target_position=None, camera_position=None, follow_mode=None): global _sim_id, _target_position, _camera_position, _follow_mode, _zone_id, _household_id _sim_id = sim_id _target_position = target_position _camera_position = camera_position _follow_mode = follow_mode _zone_id = sims4.zone_utils.get_zone_id() _household_id = services.active_lot().owner_household_id
def update(sim_id=None, target_position=None, camera_position=None, follow_mode=None): global _sim_id, _target_position, _camera_position, _follow_mode, _zone_id, _household_id _sim_id = sim_id _target_position = target_position _camera_position = camera_position _follow_mode = follow_mode _zone_id = services.current_zone_id() _household_id = services.active_lot().owner_household_id
def _get_lot_locator_transforms(self): persistence_service = services.get_persistence_service() current_zone_id = services.current_zone_id() house_description_id = persistence_service.get_house_description_id( current_zone_id) building_type = PlexBuildingType( services.get_building_type(house_description_id)) if building_type == PlexBuildingType.COASTAL: active_lot = services.active_lot() return active_lot.get_front_side_transforms() return []
def is_position_on_current_lot(position: Vector3) -> bool: """is_position_on_current_lot(position) Determine if a sim is on the current lot. :param position: The position to check. :type position: Vector3 :return: True, if the specified position is within the bounds of the current lot. False, if not. :rtype: bool """ return position is not None and services.active_lot().is_position_on_lot(position)
def on_finalize_load(self): sim_info = services.sim_info_manager().get(self.sim_id) if sim_info is None or sim_info.household is not services.active_lot( ).get_household(): replace_bassinet(sim_info, bassinet=self) else: self.set_sim_info(sim_info) self._validate_location() if self._pending_removal_moment is not None: self._pending_removal_moment.execute_removal_moment(self) self._pending_removal_moment = None super().on_finalize_load()
def test_all_venues(_connection=None): venue_manager = services.venue_manager() active_lot = services.active_lot() for venue_tuning_type in venue_manager.types: venue_tuning = venue_manager.get(venue_tuning_type) (result, result_message) = venue_tuning.lot_has_required_venue_objects(active_lot) venue_name = venue_tuning.__name__ if result: sims4.commands.output('{0}: Active lot can become venue'.format(venue_name), _connection) else: sims4.commands.output('{0}: Active lot cannot become venue.\nFailure Reasons: {1}'.format(venue_name, result_message), _connection) return True
def _recompute_street_convergence(self, *args): street_footprint_stat = self.get_street_footprint() street_service = services.street_service() lot = services.active_lot() lot_footprint_value = lot.commodity_tracker.get_value( EcoFootprintTunables.LOT_FOOTPRINT) aggregate = self.inactive_lots_total + self.active_lot_weight * lot_footprint_value aggregate *= EcoFootprintTunables.get_product_of_tested_modifiers( street_service.get_street(self)) street_footprint_stat.convergence_value = aggregate self._update_street_decay_rate() self._update_eco_footprint_effects()
def place_in_good_location(self, position=None, routing_surface=None): plex_service = services.get_plex_service() is_active_zone_a_plex = plex_service.is_active_zone_a_plex() def try_to_place_bassinet(position, routing_surface=None, **kwargs): starting_location = placement.create_starting_location( position=position, routing_surface=routing_surface) fgl_context = placement.create_fgl_context_for_object( starting_location, self, **kwargs) (translation, orientation) = placement.find_good_location(fgl_context) if translation is not None and orientation is not None: if is_active_zone_a_plex and ( routing_surface is None or plex_service.get_plex_zone_at_position( translation, routing_surface.secondary_id) is None): return False else: self.move_to(translation=translation, orientation=orientation) if routing_surface is not None: self.move_to(routing_surface=routing_surface) return True return False if position is not None and try_to_place_bassinet( position, routing_surface=routing_surface): return True lot = services.active_lot() for tag in Baby.BABY_PLACEMENT_TAGS: for (attempt, obj) in enumerate( services.object_manager().get_objects_with_tag_gen(tag)): position = obj.position routing_surface = obj.routing_surface if lot.is_position_on_lot(position) and try_to_place_bassinet( position, routing_surface=routing_surface, max_distance=10): return if attempt >= Baby.MAX_PLACEMENT_ATTEMPTS: break position = lot.get_default_position() if not try_to_place_bassinet(position): self.update_ownership(self.sim_info, make_sim_owner=False) if not build_buy.move_object_to_household_inventory(self): logger.error( 'Failed to place bassinet in household inventory.', owner='rmccord') if self.is_selectable: failed_placement_notification = Baby.FAILED_PLACEMENT_NOTIFICATION( self.sim_info, SingleSimResolver(self.sim_info)) failed_placement_notification.show_dialog()
def validate_front_door(_connection=None): active_lot = lot = services.active_lot() if active_lot is None: return door_id = active_lot.front_door_id if door_id is None: sims4.commands.output('Lot has no front door set', _connection) else: door = services.object_manager().get(door_id) if door is None: sims4.commands.output('Lot has a front door with an id of an object that doesnt exist', _connection) else: sims4.commands.output('Front door found. Door {} on position {}'.format(str(door), door.position), _connection)
def set_as_front_door(self): active_lot = services.active_lot() current_door_id = active_lot.front_door_id if current_door_id == self.id: return if current_door_id is not None: door = services.object_manager().get(current_door_id) door.remove_component(types.WELCOME_COMPONENT.instance_attr) self.add_dynamic_component(types.WELCOME_COMPONENT.instance_attr) self.welcome_component.affordance_links = Door.FRONT_DOOR_WELCOME_COMPONENT.affordance_links for affordance in self.welcome_component.affordance_links: self.add_dynamic_commodity_flags(affordance, affordance.commodity_flags) active_lot.front_door_id = self.id
def notify_result_and_push_bill_modifier(self): lot = services.active_lot() additional_tokens = () if self.policies_not_followed: additional_tokens = (LocalizationHelperTuning.get_bulleted_list(None, *self.policies_not_followed),) if self.follow_status == PolicyFollowing.NOT_FOLLOWED: lot.set_stat_value(self.commodity_notfollow, self.commodity_notfollow.max_value_tuning) self._show_inspection_notification(self.inspection_failure_notification, additional_tokens=additional_tokens) elif self.follow_status == PolicyFollowing.PARTIAL_FOLLOWED: self._show_inspection_notification(self.inspection_partial_success_notification, additional_tokens=additional_tokens) else: lot.set_stat_value(self.commodity_follow, self.commodity_follow.max_value_tuning) self._show_inspection_notification(self.inspection_successful_notification)
def purchase_picker_response(inventory_target, mailman_purchase:bool=False, *def_ids_and_amounts, _connection=None): total_price = 0 current_purchased = 0 objects_to_buy = [] definition_manager = services.definition_manager() for (def_id, amount) in zip(def_ids_and_amounts[::2], def_ids_and_amounts[1::2]): definition = definition_manager.get(def_id) if definition is None: sims4.commands.output('inventory.purchase_picker_response: Definition not found with id {}'.format(def_id), _connection) return False purchase_price = definition.price*amount total_price += purchase_price objects_to_buy.append((definition, amount)) client = services.client_manager().get(_connection) if client is None: sims4.commands.output('inventory.purchase_picker_response: No client found to make purchase.', _connection) return False household = client.household if household.funds.money < total_price: sims4.commands.output('inventory.purchase_picker_response: Insufficient funds for household to purchase items.', _connection) return False if mailman_purchase: inventory = services.active_lot().get_hidden_inventory() else: inventory_owner = inventory_target.get_target() inventory = inventory_owner.inventory_component if inventory is None: sims4.commands.output('inventory.purchase_picker_response: Inventory not found for items to be purchased into.', _connection) return False for (definition, amount) in objects_to_buy: obj = create_object(definition) if obj is None: sims4.commands.output('inventory.purchase_picker_response: Failed to create object with definition {}.'.format(definition), _connection) obj.set_stack_count(amount) if not inventory.player_try_add_object(obj): sims4.commands.output('inventory.purchase_picker_response: Failed to add object into inventory: {}'.format(obj), _connection) obj.destroy(source=inventory, cause='inventory.purchase_picker_response: Failed to add object into inventory.') obj.set_household_owner_id(household.id) obj.try_post_bb_fixup(force_fixup=True, active_household_id=services.active_household_id()) purchase_price = definition.price*amount current_purchased += purchase_price household.funds.remove(current_purchased, Consts_pb2.TELEMETRY_OBJECT_BUY) return True
def on_all_households_and_sim_infos_loaded(self, client): household = client.household if household is None: return if household.id != services.active_lot().owner_household_id: return all_hired_service_npcs = household.get_all_hired_service_npcs() for service_npc_resource_key in services.service_npc_manager().types: service_npc_tuning = services.service_npc_manager().get(service_npc_resource_key) while service_npc_tuning.auto_schedule_on_client_connect() or service_npc_tuning.guid64 in all_hired_service_npcs: is_recurring = False user_specified_data_id = None if service_npc_tuning.auto_schedule_on_client_connect(): is_recurring = True else: service_npc_record = household.get_service_npc_record(service_npc_tuning.guid64, add_if_no_record=False) if service_npc_record: is_recurring = service_npc_record.recurring user_specified_data_id = service_npc_record.user_specified_data_id self.request_service(household, service_npc_tuning, from_load=True, is_recurring=is_recurring, user_specified_data_id=user_specified_data_id)
def deserialize(client=None): global _sim_id, _target_position, _camera_position, _follow_mode, _zone_id save_slot_data_msg = services.get_persistence_service( ).get_save_slot_proto_buff() if save_slot_data_msg is not None and save_slot_data_msg.HasField( 'gameplay_data'): gameplay_data = save_slot_data_msg.gameplay_data if gameplay_data.HasField('camera_data'): camera_data = save_slot_data_msg.gameplay_data.camera_data if camera_data.HasField('target_id'): _sim_id = camera_data.target_id _target_position = camera_data.target_position _camera_position = camera_data.camera_position _follow_mode = camera_data.follow_mode _zone_id = camera_data.zone_id if camera_data.HasField( 'household_id') and services.active_lot( ).owner_household_id != camera_data.household_id: return False if _follow_mode and services.sim_info_manager().get( _sim_id) is None: _sim_id = None _target_position = None _camera_position = None _follow_mode = None _zone_id = None return False if _zone_id == sims4.zone_utils.get_zone_id(): op = FocusCamera(id=_sim_id, follow_mode=_follow_mode) op.set_location(_target_position) op.set_position(_camera_position) Distributor.instance().add_op_with_no_owner(op) return True _sim_id = None _target_position = None _camera_position = None _follow_mode = None _zone_id = None return False
def _place_object_no_fallback(self, created_object): participant = self.interaction.get_participant(self.location.location_target) if self.location.location == self.POSITION: offset_tuning = self.location.offset_tuning default_offset = sims4.math.Vector3(offset_tuning.default_offset.x, offset_tuning.default_offset.y, offset_tuning.default_offset.z) x_range = offset_tuning.x_randomization_range z_range = offset_tuning.z_randomization_range start_orientation = sims4.random.random_orientation() if x_range is not None: x_axis = start_orientation.transform_vector(sims4.math.Vector3.X_AXIS()) default_offset += x_axis*random.uniform(x_range.lower_bound, x_range.upper_bound) if z_range is not None: z_axis = start_orientation.transform_vector(sims4.math.Vector3.Z_AXIS()) default_offset += z_axis*random.uniform(z_range.lower_bound, z_range.upper_bound) offset = sims4.math.Transform(default_offset, sims4.math.Quaternion.IDENTITY()) start_position = sims4.math.Transform.concatenate(offset, participant.transform).translation routing_surface = participant.routing_surface active_lot = services.active_lot() search_flags = placement.FGLSearchFlagsDefault if self.location.allow_off_lot_placement and not active_lot.is_position_on_lot(start_position): created_object.location = sims4.math.Location(sims4.math.Transform(start_position, start_orientation), routing_surface) polygon = placement.get_accurate_placement_footprint_polygon(created_object.position, created_object.orientation, created_object.scale, created_object.get_footprint()) context = placement.FindGoodLocationContext(starting_position=start_position, starting_orientation=start_orientation, starting_routing_surface=routing_surface, ignored_object_ids=(created_object.id,), search_flags=search_flags, object_polygons=(polygon,)) else: if not self.location.ignore_bb_footprints: search_flags |= placement.FGLSearchFlag.SHOULD_TEST_BUILDBUY | placement.FGLSearchFlag.STAY_IN_CURRENT_BLOCK if not active_lot.is_position_on_lot(start_position): start_position = active_lot.get_default_position(position=start_position) context = placement.FindGoodLocationContext(starting_position=start_position, starting_orientation=start_orientation, starting_routing_surface=routing_surface, object_id=created_object.id, ignored_object_ids=self._get_ignored_object_ids(), search_flags=search_flags, object_footprints=(self.definition.get_footprint(0),)) (translation, orientation) = placement.find_good_location(context) if translation is not None: created_object.move_to(routing_surface=routing_surface, translation=translation, orientation=orientation) return True elif self.location.location == self.SLOT: parent_slot = self.location.parent_slot if participant.slot_object(parent_slot=parent_slot, slotting_object=created_object): return True return False
def on_finalize_load(self): sim_info = services.sim_info_manager().get(self.sim_id) if sim_info is None or sim_info.household is not services.active_lot().get_household(): _replace_bassinet(sim_info, bassinet=self) else: self.set_sim_info(sim_info)
def unset_as_front_door(self): self.remove_component(types.WELCOME_COMPONENT.instance_attr) active_lot = services.active_lot() active_lot.front_door_id = None
def generate_choices(target_id:int=None, pick_type=PickType.PICK_TERRAIN, x:float=0.0, y:float=0.0, z:float=0.0, lot_id:int=0, level:int=0, control:int=0, alt:int=0, shift:int=0, reference_id:int=0, preferred_object_id:int=0, _connection=None): if alt or control: return 0 if target_id is None: return 0 zone = services.current_zone() client = zone.client_manager.get(_connection) sim = _active_sim(client) shift_held = bool(shift) context = None choice_menu = None target = None preferred_object = None if preferred_object_id is not None: preferred_object = services.object_manager().get(preferred_object_id) preferred_objects = set() if preferred_object is None else {preferred_object} pie_menu_action = should_generate_pie_menu(client, sim, shift_held) show_pie_menu = pie_menu_action == PieMenuActions.SHOW_PIE_MENU show_debug_pie_menu = pie_menu_action == PieMenuActions.SHOW_DEBUG_PIE_MENU if show_pie_menu or show_debug_pie_menu: if show_pie_menu: shift_held = False pick_type = int(pick_type) pick_pos = sims4.math.Vector3(x, y, z) routing_surface = routing.SurfaceIdentifier(zone.id, level, routing.SURFACETYPE_WORLD) target = zone.find_object(target_id) if pick_type == PickType.PICK_PORTRAIT: sim_info = services.sim_info_manager().get(target_id) if sim_info is None or sim_info.is_dead: return 0 if sim is None: return 0 picked_item_ids = set([target_id]) context = client.create_interaction_context(sim, target_sim_id=target_id) context.add_preferred_objects(preferred_objects) potential_interactions = list(sim.potential_relation_panel_interactions(context, picked_item_ids=picked_item_ids)) choice_menu = ChoiceMenu(potential_interactions, context, user_pick_target=sim_info) client.set_choices(choice_menu) elif pick_type == PickType.PICK_SKEWER: sim_info = services.sim_info_manager().get(target_id) skewer_sim = None if sim_info is None or sim_info.is_dead: return 0 skewer_sim = sim_info.get_sim_instance() context = client.create_interaction_context(skewer_sim) context.add_preferred_objects(preferred_objects) potential_interactions = list(sim_info.sim_skewer_affordance_gen(context)) choice_menu = ChoiceMenu(potential_interactions, context) client.set_choices(choice_menu) else: if pick_type in PICK_USE_TERRAIN_OBJECT or pick_type == PickType.PICK_OBJECT and lot_id and lot_id != services.active_lot().lot_id: location = sims4.math.Location(sims4.math.Transform(pick_pos), routing_surface) target = objects.terrain.TerrainPoint(location) pick_type = PickType.PICK_TERRAIN elif pick_type == PickType.PICK_SIM and target is None: target = sim elif pick_type == PickType.PICK_OBJECT and target.object_routing_surface is not None: pick_type = int(pick_type) routing_surface = target.object_routing_surface location = sims4.math.Location(sims4.math.Transform(pick_pos), routing_surface) target = objects.terrain.TerrainPoint(location) else: preferred_objects.add(target) if target is not None: pick = PickInfo(pick_type, target, pick_pos, routing_surface, lot_id, bool(alt), bool(control), shift_held) context = client.create_interaction_context(sim, pick=pick, shift_held=shift_held) context.add_preferred_objects(preferred_objects) interaction_parameters = client.get_interaction_parameters() potential_interactions = list(target.potential_interactions(context, **interaction_parameters)) with sims4.callback_utils.invoke_enter_exit_callbacks(sims4.callback_utils.CallbackEvent.CONTENT_SET_GENERATE_ENTER, sims4.callback_utils.CallbackEvent.CONTENT_SET_GENERATE_EXIT): choice_menu = ChoiceMenu(potential_interactions, context, user_pick_target=target, make_pass=_make_pass) if not shift_held and sim is not None: for si in sim.si_state: potential_targets = si.get_potential_mixer_targets() while True: for potential_target in potential_targets: if target is potential_target: break while potential_target.is_part and potential_target.part_owner is target: break content_set = autonomy.content_sets.generate_content_set(sim, si.super_affordance, si, context, potential_targets=(target,), check_posture_compatibility=True, include_failed_aops_with_tooltip=True) for (_, aop, test_result) in content_set: choice_menu.add_aop(aop, result_override=test_result, do_test=False) client.set_choices(choice_menu) msg = create_pie_menu_message(sim, context, choice_menu, reference_id, pie_menu_action, target=target) distributor = Distributor.instance() distributor.add_event(Consts_pb2.MSG_PIE_MENU_CREATE, msg, True) num_choices = len(msg.items) if num_choices > 0: if pick_type in (PickType.PICK_PORTRAIT, PickType.PICK_SIM): with telemetry_helper.begin_hook(writer, TELEMETRY_HOOK_CREATE_PIE_MENU, sim=sim) as hook: hook.write_int('piid', reference_id) hook.write_enum('kind', pick_type) hook.write_int('tsim', target_id) else: with telemetry_helper.begin_hook(writer, TELEMETRY_HOOK_CREATE_PIE_MENU, sim=sim) as hook: hook.write_int('piid', reference_id) if target is not None and getattr(target, 'definition'): hook.write_guid('tobj', target.definition.id) else: hook.write_int('tobj', 0) hook.write_enum('kind', pick_type) return num_choices
def _do_behavior(self): lot = services.active_lot() if lot is None: return lot.create_object_in_hidden_inventory(self.object_to_be_mailed.id)
def create_object_in_hidden_inventory(definition_id, _connection=None): lot = services.active_lot() if lot is not None: return lot.create_object_in_hidden_inventory(definition_id) is not None return False
def on_remove(self): active_lot = services.active_lot() if active_lot.front_door_id == self.id: active_lot.front_door_id = None super().on_remove()
def is_position_on_lot(self, position): return services.active_lot().is_position_on_lot(position)
def routing_location(self): lot = services.active_lot() return routing.Location(lot.position, orientation=lot.orientation, routing_surface=routing.SurfaceIdentifier(services.current_zone().id, 0, routing.SURFACETYPE_WORLD))
def get_center(self): return services.active_lot().center