text: # uncompyle6 version 3.7.4
  # Python bytecode 3.7 (3394)
  # Decompiled from: Python 3.7.9 (tags/v3.7.9:13c94747c7, Aug 17 2020, 18:58:18) [MSC v.1900 64 bit (AMD64)]
  # Embedded file name: T:\InGame\Gameplay\Scripts\Server\vet\vet_employee_situation.py
  # Compiled at: 2017-10-09 21:55:41
  # Size of source mod 2**32: 16006 bytes
  import functools
  from business.business_employee_situation_mixin import BusinessEmployeeSituationMixin
  from event_testing.test_events import TestEvent
  from interactions import ParticipantType
  from sims4 import random
  from sims4.resources import Types
  from sims4.tuning.dynamic_enum import DynamicEnum
  from sims4.tuning.instances import lock_instance_tunables
  from sims4.tuning.tunable import TunableTuple, TunableMapping, OptionalTunable, TunableReference
  from sims4.tuning.tunable_base import GroupNames
  from situations.situation import Situation, TunableEnumEntry, TunableRange
  from situations.situation_complex import CommonSituationState, TunableInteractionOfInterest, SituationComplexCommon, SituationStateData
  from situations.situation_types import SituationCreationUIOption
  from vet.vet_clinic_handlers import log_vet_flow_entry
  import services, sims4, situations.bouncer
  logger = sims4.log.Logger('VetEmployeeSituation', default_owner='jdimailig')
  
  class VetEmployeeSituationStates(DynamicEnum):
      DEFAULT = 0
  
  
  class VetManagedEmployeeSituationState(CommonSituationState):
      FACTORY_TUNABLES = {'transition_out_interaction':OptionalTunable(description='\n             When this interaction is run, this state can be transitioned out of;\n             we will try to advance to another state.  This can be used as a way \n             to switch states before the timeout occurs.\n             ',
         tunable=TunableInteractionOfInterest()), 
       'state_specific_transitions':TunableMapping(description='\n            Mapping to allow direct transitions to other states using interactions.\n            ',
         key_type=TunableEnumEntry(VetEmployeeSituationStates, default=(VetEmployeeSituationStates.DEFAULT)),
         value_type=TunableInteractionOfInterest()), 
       'locked_args':{'allow_join_situation': False}}
  
      def __init__(self, state_type, *args, enable_disable=None, transition_out_interaction=None, state_specific_transitions=None, **kwargs):
          (super().__init__)(*args, **kwargs)
          self._state_type = state_type
          self._transition_out_interaction = transition_out_interaction
          self._state_specific_transitions = state_specific_transitions
          self._test_custom_keys = set()
          if self._transition_out_interaction is not None:
              self._transition_out_interaction = transition_out_interaction
              self._test_custom_keys.update(self._transition_out_interaction.custom_keys_gen())
          for state_specific_transition in self._state_specific_transitions.values():
              self._test_custom_keys.update(state_specific_transition.custom_keys_gen())
  
      @property
      def state_type(self):
          return self._state_type
  
      def on_activate(self, reader=None):
          super().on_activate(reader=reader)
          for custom_key in self._test_custom_keys:
              self._test_event_register(TestEvent.InteractionComplete, custom_key)
  
      def handle_event(self, sim_info, event, resolver):
          if not self.owner.is_sim_info_in_situation(sim_info):
              target_sim_info = resolver.get_participant(ParticipantType.TargetSim)
              return target_sim_info is None or self.owner.is_sim_info_in_situation(target_sim_info) or None
          elif event == TestEvent.InteractionComplete:
              for state_type, state_specific_transition in self._state_specific_transitions.items():
                  if resolver(state_specific_transition):
                      self.owner.try_set_next_state(state_type)
                      return
  
              if self._transition_out_interaction is not None:
                  if resolver(self._transition_out_interaction):
                      self.owner.try_set_next_state()
  
      def timer_expired(self):
          self.owner.try_set_next_state()
  
  
  class VetEmployeeSituation(BusinessEmployeeSituationMixin, SituationComplexCommon):
      INSTANCE_TUNABLES = {'_default_state':VetManagedEmployeeSituationState.TunableFactory(description='\n                Default state for the vet employee, which can never be disabled.\n                ',
         locked_args={'state_type': VetEmployeeSituationStates.DEFAULT},
         tuning_group=GroupNames.SITUATION), 
       '_managed_states':TunableMapping(description='\n            A mapping of state types to states.\n            ',
         key_type=TunableEnumEntry(VetEmployeeSituationStates, default=(VetEmployeeSituationStates.DEFAULT),
         invalid_enums=(
        VetEmployeeSituationStates.DEFAULT,)),
         value_type=TunableTuple(state=(VetManagedEmployeeSituationState.TunableFactory()),
         enable_disable=OptionalTunable(display_name='Enable/Disable Support',
         tunable=TunableTuple(enable_interaction=TunableInteractionOfInterest(description='\n                            Interaction of interest which will cause this state to be enabled.\n                            '),
         disable_interaction=TunableInteractionOfInterest(description='\n                            Interaction of interest which will cause this state to be disabled.\n                            '),
         disabling_buff=TunableReference(description='\n                            The Buff that disables the state, used to set\n                            the state from the load.\n                            ',
         manager=(services.get_instance_manager(Types.BUFF))))),
         weight=TunableRange(description='\n                    A weight to use to choose to run this state in a random lottery.\n                    ',
         tunable_type=int,
         minimum=0,
         default=1)),
         tuning_group=GroupNames.SITUATION), 
       '_default_state_weight':TunableRange(description='\n            A weight to use to choose to for the default state in a random\n            lottery of which state to run.\n            ',
         tunable_type=int,
         minimum=1,
         default=1)}
      REMOVE_INSTANCE_TUNABLES = Situation.NON_USER_FACING_REMOVE_INSTANCE_TUNABLES
  
      @classmethod
      def _states(cls):
          state_data = []
          state_data.append(SituationStateData((VetEmployeeSituationStates.DEFAULT.value), VetManagedEmployeeSituationState,
            factory=(cls._default_state)))
          for state_type, state_tuning in cls._managed_states.items():
              state_data.append(SituationStateData((state_type.value), VetManagedEmployeeSituationState,
                factory=(functools.partial(state_tuning.state, state_type))))
  
          return state_data
  
      @classmethod
      def default_job(cls):
          pass
  
      @classmethod
      def _state_to_uid(cls, state_to_find):
          return state_to_find.state_type.value
  
      @classmethod
      def _get_tuned_job_and_default_role_state_tuples(cls):
          return list(cls._default_state._tuned_values.job_and_role_changes.items())
  
      def __init__(self, *args, **kwargs):
          (super().__init__)(*args, **kwargs)
          self._locked_states = set()
          self._type_to_disable_interaction = {}
          self._type_to_enable_interaction = {}
          self._state_disabling_buffs = set()
          for state_type, state_tuning in self._managed_states.items():
              enable_disable = state_tuning.enable_disable
              if enable_disable is None:
                  continue
              self._register_test_event_for_keys(TestEvent.InteractionComplete, enable_disable.disable_interaction.custom_keys_gen())
              self._type_to_disable_interaction[state_type] = enable_disable.disable_interaction
              self._register_test_event_for_keys(TestEvent.InteractionComplete, enable_disable.enable_interaction.custom_keys_gen())
              self._type_to_enable_interaction[state_type] = enable_disable.enable_interaction
              self._state_disabling_buffs.add(enable_disable.disabling_buff)
  
      def start_situation(self):
          super().start_situation()
          self._change_state(self._default_state())
  
      def _on_set_sim_job(self, sim, job_type):
          super()._on_set_sim_job(sim, job_type)
          self._start_work_duration()
  
      def _on_add_sim_to_situation(self, sim, job_type, role_state_type_override=None):
          super()._on_add_sim_to_situation(sim, job_type, role_state_type_override)
          sim.Buffs.on_buff_added.append(self._updated_disabled_states)
  
      def _on_remove_sim_from_situation(self, sim):
          super()._on_remove_sim_from_situation(sim)
          sim.Buffs.on_buff_added.remove(self._updated_disabled_states)
  
      def _updated_disabled_states(self, buff_type, sim_id):
          if buff_type not in self._state_disabling_buffs:
              return
          for state_type in self._managed_states:
              state_tuning = self._managed_states[state_type]
              if state_tuning.enable_disable is None:
                  continue
              if state_tuning.enable_disable.disabling_buff == buff_type:
                  self._disable_state(state_type)
  
      def get_employee(self):
          return next(iter(self.all_sims_in_situation_gen()), None)
  
      def get_employee_sim_info(self):
          employee = self.get_employee()
          if employee is None:
              return
          return employee.sim_info
  
      def handle_event(self, sim_info, event, resolver):
          super().handle_event(sim_info, event, resolver)
          target_sim_info = resolver.get_participant(ParticipantType.TargetSim)
          return target_sim_info is sim_info and self.is_sim_info_in_situation(sim_info) or None
          for state_type, interaction_test in self._type_to_disable_interaction.items():
              if resolver(interaction_test):
                  self._disable_state(state_type)
  
          for state_type, interaction_test in self._type_to_enable_interaction.items():
              if resolver(interaction_test):
                  self._enable_state(state_type)
  
      def try_set_next_state(self, next_state_type=None):
          if next_state_type is None or next_state_type in self._locked_states:
              next_state_type = self._choose_next_state(invalid_states=(next_state_type,))
          self._change_to_state_type(next_state_type)
  
      def _change_to_state_type(self, state_type):
          self.log_flow_entry('Changing to state {}'.format(state_type.name))
          if state_type == VetEmployeeSituationStates.DEFAULT:
              self._change_state(self._default_state())
          else:
              self._change_state(self._managed_states[state_type].state(state_type))
  
      def _choose_next_state(self, invalid_states=None):
          available_states = set(self._managed_states.keys()) - self._locked_states
          if invalid_states is not None:
              available_states = available_states - set(invalid_states)
          else:
              return available_states or VetEmployeeSituationStates.DEFAULT
          weighted = [(self._managed_states[key].weight, key) for key in available_states]
          weighted.append((self._default_state_weight, VetEmployeeSituationStates.DEFAULT))
          return random.weighted_random_item(weighted)
  
      def _enable_state(self, state_type):
          if state_type in self._locked_states:
              self._locked_states.remove(state_type)
  
      def _disable_state(self, state_type):
          self._locked_states.add(state_type)
          if self._cur_state.state_type == state_type:
              self.try_set_next_state()
  
      def get_phase_state_name_for_gsi(self):
          if self._cur_state is None:
              return 'None'
          return self._cur_state.state_type.name
  
      def _gsi_additional_data_gen(self):
          yield (
           'Locked States', str(self._locked_states))
  
      def log_flow_entry(self, message):
          log_vet_flow_entry(repr(self.get_employee()), type(self).__name__, message)
  
  
  lock_instance_tunables(VetEmployeeSituation, duration=0,
    creation_ui_option=(SituationCreationUIOption.NOT_AVAILABLE),
    exclusivity=(situations.bouncer.bouncer_types.BouncerExclusivityCategory.VENUE_EMPLOYEE))