SHARE
TWEET

Untitled

a guest Feb 22nd, 2019 1,167 Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
  1. import itertools
  2. import random
  3. from buffs.tunable import TunableBuffReference
  4. from date_and_time import create_time_span
  5. from distributor.rollback import ProtocolBufferRollback
  6. from distributor.shared_messages import build_icon_info_msg, IconInfoData
  7. from event_testing.test_events import TestEvent
  8. from interactions.aop import AffordanceObjectPair
  9. from interactions.context import InteractionContext, QueueInsertStrategy, InteractionSource
  10. from interactions.priority import Priority
  11. from objects.components.state import TunableStateValueReference
  12. from sims4.localization import TunableLocalizedString
  13. from sims4.tuning.instances import lock_instance_tunables
  14. from sims4.tuning.tunable import TunableReference, TunableSimMinute, TunableResourceKey, TunableList
  15. from sims4.tuning.tunable_base import GroupNames
  16. from situations.base_situation import SituationDisplayPriority, _RequestUserData
  17. from situations.bouncer.bouncer_request import SelectableSimRequestFactory
  18. from situations.bouncer.bouncer_types import BouncerRequestPriority
  19. from situations.complex.mother_plant_battle_ops import MotherplantBattleStates
  20. from situations.situation_complex import SituationComplexCommon, SituationState, CommonSituationState, SituationStateData, TunableInteractionOfInterest
  21. from situations.situation_meter import StatBasedSituationMeterData
  22. from situations.situation_types import SituationDisplayType, SituationUserFacingType
  23. import alarms
  24. import interactions
  25. import services
  26. import sims4.resources
  27. logger = sims4.log.Logger('Situations', default_owner='jjacobson')
  28.  
  29. class PrepareForBattleSituationState(SituationState):
  30.  
  31.     def _on_set_sim_role_state(self, sim, *args, **kwargs):
  32.         super()._on_set_sim_role_state(sim, *args, **kwargs)
  33.         if self.owner.num_of_sims >= len(self.owner._guest_list):
  34.             self.owner._change_state(self.owner.base_battle_situation_state())
  35.  
  36.     @property
  37.     def zombie_attack_valid(self):
  38.         return False
  39.  
  40.     def _get_role_state_overrides(self, sim, job_type, role_state_type, role_affordance_target):
  41.         motherplant = self.owner._get_motherplant()
  42.         return (role_state_type, motherplant)
  43.  
  44.  
  45. class BattleThePlantSituationState(CommonSituationState):
  46.  
  47.     @property
  48.     def zombie_attack_valid(self):
  49.         return True
  50.  
  51.  
  52. class AttackBattleThePlantSituationState(CommonSituationState):
  53.  
  54.     @property
  55.     def zombie_attack_valid(self):
  56.         return True
  57.  
  58.     def timer_expired(self):
  59.         self.owner._change_state(self.owner.base_battle_situation_state())
  60.  
  61.  
  62. class InspireBattleThePlantSituationState(CommonSituationState):
  63.  
  64.     @property
  65.     def zombie_attack_valid(self):
  66.         return True
  67.  
  68.     def timer_expired(self):
  69.         self.owner._change_state(self.owner.base_battle_situation_state())
  70.  
  71.  
  72. class RallyBattleThePlantSituationState(CommonSituationState):
  73.  
  74.     @property
  75.     def zombie_attack_valid(self):
  76.         return True
  77.  
  78.     def timer_expired(self):
  79.         self.owner._change_state(self.owner.base_battle_situation_state())
  80.  
  81.  
  82. class WarblingWarcryBattleThePlantSituationState(CommonSituationState):
  83.  
  84.     @property
  85.     def zombie_attack_valid(self):
  86.         return False
  87.  
  88.     def timer_expired(self):
  89.         self.owner._change_state(self.owner.base_battle_situation_state())
  90.  
  91.  
  92. class MotherPlantBattleSituation(SituationComplexCommon):
  93.     MOTHER_PLANT_METER_ID = 1
  94.     PLAYER_HEALTH_METER_ID = 2
  95.     INSTANCE_TUNABLES = {'player_job': TunableReference(description='\n            Job for the main player sim that fights the plant.\n            ', manager=services.get_instance_manager(sims4.resources.Types.SITUATION_JOB)), 'player_sim_role_state': TunableReference(description='\n            Role state for the main player sim Role.\n            ', manager=services.get_instance_manager(sims4.resources.Types.ROLE_STATE)), 'other_player_jobs': TunableReference(description='\n            Job for the other player Sims that are not the main Sim and are not\n            participating as helpers.\n            ', manager=services.get_instance_manager(sims4.resources.Types.SITUATION_JOB)), 'other_player_sims_role_state': TunableReference(description='\n            Role state for the other player Sims.\n            ', manager=services.get_instance_manager(sims4.resources.Types.ROLE_STATE)), 'helper_1_job': TunableReference(description='\n            Job for one of the helper Sims for the fight.\n            ', manager=services.get_instance_manager(sims4.resources.Types.SITUATION_JOB)), 'helper_2_job': TunableReference(description='\n            Job for one of the helper Sims for the fight.\n            ', manager=services.get_instance_manager(sims4.resources.Types.SITUATION_JOB)), 'helper_3_job': TunableReference(description='\n            Job for one of the helper Sims for the fight.\n            ', manager=services.get_instance_manager(sims4.resources.Types.SITUATION_JOB)), 'helper_sim_prepare_role_state_1': TunableReference(description='\n            Role state for helper Sim 1 when preparing for battle.\n            ', manager=services.get_instance_manager(sims4.resources.Types.ROLE_STATE)), 'helper_sim_prepare_role_state_2': TunableReference(description='\n            Role state for helper Sim 2 when preparing for battle.\n            ', manager=services.get_instance_manager(sims4.resources.Types.ROLE_STATE)), 'helper_sim_prepare_role_state_3': TunableReference(description='\n            Role state for helper Sim 3 when preparing for battle.\n            ', manager=services.get_instance_manager(sims4.resources.Types.ROLE_STATE)), 'zombie_job': TunableReference(description='\n            Job for the Zombies for the fight.\n            ', manager=services.get_instance_manager(sims4.resources.Types.SITUATION_JOB)), 'zombie_prepare_role_state': TunableReference(description='\n            Role state for the zombie Sims when preparing for battle.\n            ', manager=services.get_instance_manager(sims4.resources.Types.ROLE_STATE)), 'zombie_fight_interaction': TunableReference(description='\n            Interaction pushed on zombies to get them to fight a Sim.\n            ', manager=services.get_instance_manager(sims4.resources.Types.INTERACTION)), 'zombie_fight_interaction_timer': TunableSimMinute(description='\n            Timer for the amount of time between zombie attacks.\n            ', minimum=1, default=30), 'player_health_statistic': TunableReference(description="\n            The statistic that we will use in order to determine the Sim's\n            health for the motherplant.\n            ", manager=services.get_instance_manager(sims4.resources.Types.STATISTIC)), 'motherplant_health_statisic': TunableReference(description="\n            The statistic that we will use in order to determine the Sim's\n            health for the motherplant.\n            ", manager=services.get_instance_manager(sims4.resources.Types.STATISTIC)), 'victory_interaction_of_interest': TunableInteractionOfInterest(description='\n            The interaction of interest that we are looking for to determine\n            victory.\n            '), 'retreat_interaction_of_interest': TunableInteractionOfInterest(description='\n            The interaction of interest that we are looking for to determine\n            retreat.\n            '), 'loss_interaction_mixer': TunableReference(description='\n            The affordance that will be pushed on the primary Sims if they\n            lose.\n            ', manager=services.get_instance_manager(sims4.resources.Types.INTERACTION)), 'fight_affordance': TunableReference(description='\n            The primary fight interaction that we will use to run the defeat\n            mixer the player Sim.\n            ', manager=services.get_instance_manager(sims4.resources.Types.INTERACTION)), 'helper_victory_affordance': TunableReference(description='\n            The affordance that will be pushed on the helper Sims if they\n            achieve victory.\n            ', manager=services.get_instance_manager(sims4.resources.Types.INTERACTION)), 'helper_lose_affordance': TunableReference(description='\n            The affordance that will be pushed on the helper Sims if they\n            lose.\n            ', manager=services.get_instance_manager(sims4.resources.Types.INTERACTION)), 'mother_plant_definition': TunableReference(description='\n            The actual mother plant itself.\n            ', manager=services.definition_manager()), 'base_battle_situation_state': BattleThePlantSituationState.TunableFactory(locked_args={'allow_join_situation': True, 'time_out': None}, tuning_group=GroupNames.STATE), 'attack_battle_situation_state': AttackBattleThePlantSituationState.TunableFactory(locked_args={'allow_join_situation': True}, tuning_group=GroupNames.STATE), 'inspire_battle_situation_state': InspireBattleThePlantSituationState.TunableFactory(locked_args={'allow_join_situation': True}, tuning_group=GroupNames.STATE), 'rally_battle_sitaution_state': RallyBattleThePlantSituationState.TunableFactory(locked_args={'allow_join_situation': True}, tuning_group=GroupNames.STATE), 'warbling_warcry_battle_situation_state': WarblingWarcryBattleThePlantSituationState.TunableFactory(locked_args={'allow_join_situation': True}, tuning_group=GroupNames.STATE), 'save_lock_tooltip': TunableLocalizedString(description='\n            The tooltip/message to show when the player tries to save the game\n            while this situation is running. Save is locked when situation starts.\n            ', tuning_group=GroupNames.UI), 'mother_plant_meter_settings': StatBasedSituationMeterData.TunableFactory(description='\n            The meter used to track the health of the mother plant.\n            ', tuning_group=GroupNames.SITUATION, locked_args={'_meter_id': MOTHER_PLANT_METER_ID}), 'player_health_meter_settings': StatBasedSituationMeterData.TunableFactory(description='\n            The meter used to track the health of the player team.\n            ', tuning_group=GroupNames.SITUATION, locked_args={'_meter_id': PLAYER_HEALTH_METER_ID}), 'mother_plant_icon': TunableResourceKey(description='\n            Icon to be displayed in the situation UI beside the mother plant\n            health bar.\n            ', resource_types=sims4.resources.CompoundTypes.IMAGE, default=None, allow_none=True, tuning_group=GroupNames.SITUATION), 'states_to_set_on_start': TunableList(description='\n            A list of states to set on the motherplant on start.\n            ', tunable=TunableStateValueReference(description='\n                The state to set.\n                ')), 'states_to_set_on_end': TunableList(description='\n            A list of states to set on the motherplant on end.\n            ', tunable=TunableStateValueReference(description='\n                The state to set.\n                ')), 'victory_reward': TunableReference(description='\n            The Reward received when the Sim wins the situation.\n            ', manager=services.get_instance_manager(sims4.resources.Types.REWARD)), 'victory_audio_sting': TunableResourceKey(description='\n            The sound to play when the Sim wins the battle.\n            ', resource_types=(sims4.resources.Types.PROPX,), default=None, tuning_group=GroupNames.AUDIO), 'defeat_audio_sting': TunableResourceKey(description='\n            The sound to play when the Sim loses the battle.\n            ', resource_types=(sims4.resources.Types.PROPX,), default=None, tuning_group=GroupNames.AUDIO), 'possessed_buff': TunableBuffReference(description='\n            Possessed Buff for zombie Sims. \n            ')}
  96.  
  97.     @property
  98.     def user_facing_type(self):
  99.         return SituationUserFacingType.MOTHER_PLANT_EVENT
  100.  
  101.     @property
  102.     def situation_display_type(self):
  103.         return SituationDisplayType.VET
  104.  
  105.     @property
  106.     def situation_display_priority(self):
  107.         return SituationDisplayPriority.VET
  108.  
  109.     @classmethod
  110.     def _states(cls):
  111.         return (SituationStateData(1, PrepareForBattleSituationState), SituationStateData.from_auto_factory(2, cls.base_battle_situation_state), SituationStateData.from_auto_factory(3, cls.attack_battle_situation_state), SituationStateData.from_auto_factory(4, cls.inspire_battle_situation_state), SituationStateData.from_auto_factory(5, cls.rally_battle_sitaution_state), SituationStateData.from_auto_factory(6, cls.warbling_warcry_battle_situation_state))
  112.  
  113.     @classmethod
  114.     def default_job(cls):
  115.         pass
  116.  
  117.     @classmethod
  118.     def _get_tuned_job_and_default_role_state_tuples(cls):
  119.         return ((cls.player_job, cls.player_sim_role_state), (cls.other_player_jobs, cls.other_player_sims_role_state), (cls.helper_1_job, cls.helper_sim_prepare_role_state_1), (cls.helper_2_job, cls.helper_sim_prepare_role_state_2), (cls.helper_3_job, cls.helper_sim_prepare_role_state_3), (cls.zombie_job, cls.zombie_prepare_role_state))
  120.  
  121.     def __init__(self, *args, **kwargs):
  122.         super().__init__(*args, **kwargs)
  123.         self._zombie_attack_alarm_handle = None
  124.         self._registered_test_events = set()
  125.         self._player_health_tracking_situation_goal = None
  126.         self._statistic_watcher_handle = None
  127.         self._victory = False
  128.  
  129.     @property
  130.     def end_audio_sting(self):
  131.         if self._victory:
  132.             return self.victory_audio_sting
  133.         return self.defeat_audio_sting
  134.  
  135.     def _get_reward(self):
  136.         if self._victory:
  137.             return self.victory_reward
  138.  
  139.     def _get_motherplant(self):
  140.         return next(iter(services.object_manager().get_objects_of_type_gen(self.mother_plant_definition)))
  141.  
  142.     def _push_loss_on_player(self):
  143.         motherplant = self._get_motherplant()
  144.         for (sim, situation_sim) in self._situation_sims.items():
  145.             if situation_sim.current_job_type is self.player_job:
  146.                 parent_si = sim.si_state.get_si_by_affordance(self.fight_affordance)
  147.                 if parent_si is not None:
  148.                     interaction_context = InteractionContext(sim, InteractionSource.PIE_MENU, Priority.Critical)
  149.                     aop = AffordanceObjectPair(self.loss_interaction_mixer, motherplant, self.fight_affordance, parent_si)
  150.                     if not aop.test_and_execute(interaction_context):
  151.                         logger.error('Attempting to push Motherplant Battle Ending Interaction, but failed.')
  152.         self._push_interaction_on_all_helpers(self.helper_lose_affordance)
  153.  
  154.     def on_goal_completed(self, goal):
  155.         super().on_goal_completed(goal)
  156.         self._push_loss_on_player()
  157.         self._self_destruct()
  158.  
  159.     def _on_set_sim_job(self, sim, job_type):
  160.         super()._on_set_sim_job(sim, job_type)
  161.         if job_type is self.zombie_job:
  162.             sim.add_buff_from_op(self.possessed_buff.buff_type, buff_reason=self.possessed_buff.buff_reason)
  163.  
  164.     def _on_statistic_updated(self, stat_type, old_value, new_value):
  165.         if stat_type is self.player_health_statistic:
  166.             self._player_health_tracking_situation_goal.set_count(new_value)
  167.             self._player_health_meter.send_update_if_dirty()
  168.         elif stat_type is self.motherplant_health_statisic:
  169.             self._mother_plant_meter.send_update_if_dirty()
  170.  
  171.     def _zombie_attack(self, _):
  172.         if not self._cur_state.zombie_attack_valid:
  173.             return
  174.         zombies = []
  175.         for (sim, situation_sim) in self._situation_sims.items():
  176.             if situation_sim.current_job_type is self.zombie_job:
  177.                 zombies.append(sim)
  178.         zombie_to_attack = random.choice(zombies)
  179.         context = InteractionContext(sim, InteractionContext.SOURCE_SCRIPT, interactions.priority.Priority.High, insert_strategy=QueueInsertStrategy.NEXT, bucket=interactions.context.InteractionBucketType.DEFAULT)
  180.         zombie_to_attack.push_super_affordance(self.zombie_fight_interaction, None, context)
  181.  
  182.     def _push_interaction_on_all_helpers(self, interaction_to_push):
  183.         for (sim, situation_sim) in self._situation_sims.items():
  184.             if not situation_sim.current_job_type is self.helper_2_job:
  185.                 if situation_sim.current_job_type is self.helper_3_job:
  186.                     context = InteractionContext(sim, InteractionContext.SOURCE_SCRIPT, interactions.priority.Priority.High, insert_strategy=QueueInsertStrategy.NEXT, bucket=interactions.context.InteractionBucketType.DEFAULT)
  187.                     sim.push_super_affordance(interaction_to_push, None, context)
  188.             context = InteractionContext(sim, InteractionContext.SOURCE_SCRIPT, interactions.priority.Priority.High, insert_strategy=QueueInsertStrategy.NEXT, bucket=interactions.context.InteractionBucketType.DEFAULT)
  189.             sim.push_super_affordance(interaction_to_push, None, context)
  190.  
  191.     def handle_event(self, sim_info, event, resolver):
  192.         super().handle_event(sim_info, event, resolver)
  193.         if event != TestEvent.InteractionComplete:
  194.             return
  195.         if resolver(self.victory_interaction_of_interest):
  196.             self._push_interaction_on_all_helpers(self.helper_victory_affordance)
  197.             self._victory = True
  198.             self._self_destruct()
  199.         elif resolver(self.retreat_interaction_of_interest):
  200.             self._push_loss_on_player()
  201.             self._self_destruct()
  202.  
  203.     def start_situation(self):
  204.         services.get_persistence_service().lock_save(self)
  205.         super().start_situation()
  206.         self._change_state(PrepareForBattleSituationState())
  207.         motherplant = self._get_motherplant()
  208.         motherplant.set_stat_value(self.player_health_statistic, 0, add=True)
  209.         motherplant.set_stat_value(self.motherplant_health_statisic, self.motherplant_health_statisic.max_value, add=True)
  210.         for state_value in self.states_to_set_on_start:
  211.             motherplant.set_state(state_value.state, state_value)
  212.         statistic_tracker = motherplant.statistic_tracker
  213.         self._statistic_watcher_handle = statistic_tracker.add_watcher(self._on_statistic_updated)
  214.         self._setup_situation_meters()
  215.         self._zombie_attack_alarm_handle = alarms.add_alarm(self, create_time_span(minutes=self.zombie_fight_interaction_timer), self._zombie_attack, repeating=True)
  216.         for custom_key in itertools.chain(self.victory_interaction_of_interest.custom_keys_gen(), self.retreat_interaction_of_interest.custom_keys_gen()):
  217.             custom_key_tuple = (TestEvent.InteractionComplete, custom_key)
  218.             self._registered_test_events.add(custom_key_tuple)
  219.             services.get_event_manager().register_with_custom_key(self, TestEvent.InteractionComplete, custom_key)
  220.  
  221.     def _setup_situation_meters(self):
  222.         motherplant = self._get_motherplant()
  223.         self._mother_plant_meter = self.mother_plant_meter_settings.create_meter_with_sim_info(self, motherplant)
  224.         self._player_health_meter = self.player_health_meter_settings.create_meter_with_sim_info(self, motherplant)
  225.  
  226.     def build_situation_start_message(self):
  227.         msg = super().build_situation_start_message()
  228.         with ProtocolBufferRollback(msg.meter_data) as meter_data_msg:
  229.             self.mother_plant_meter_settings.build_data_message(meter_data_msg)
  230.         with ProtocolBufferRollback(msg.meter_data) as meter_data_msg:
  231.             self.player_health_meter_settings.build_data_message(meter_data_msg)
  232.         build_icon_info_msg(IconInfoData(icon_resource=self.mother_plant_icon), None, msg.icon_info)
  233.         return msg
  234.  
  235.     def _destroy(self):
  236.         super()._destroy()
  237.         services.get_persistence_service().unlock_save(self)
  238.         for (event_type, custom_key) in self._registered_test_events:
  239.             services.get_event_manager().unregister_with_custom_key(self, event_type, custom_key)
  240.         motherplant = self._get_motherplant()
  241.         statistic_tracker = motherplant.statistic_tracker
  242.         statistic_tracker.remove_watcher(self._statistic_watcher_handle)
  243.         for state_value in self.states_to_set_on_end:
  244.             motherplant.set_state(state_value.state, state_value)
  245.         self._registered_test_events.clear()
  246.         if self._mother_plant_meter is not None:
  247.             self._mother_plant_meter.destroy()
  248.         if self._player_health_meter is not None:
  249.             self._player_health_meter.destroy()
  250.  
  251.     def get_lock_save_reason(self):
  252.         return self.save_lock_tooltip
  253.  
  254.     def set_motherplant_situation_state(self, motherplant_battle_state):
  255.         if motherplant_battle_state == MotherplantBattleStates.ATTACK:
  256.             self._change_state(self.attack_battle_situation_state())
  257.         elif motherplant_battle_state == MotherplantBattleStates.INSPIRE:
  258.             self._change_state(self.inspire_battle_situation_state())
  259.         elif motherplant_battle_state == MotherplantBattleStates.RALLY:
  260.             self._change_state(self.rally_battle_sitaution_state())
  261.         elif motherplant_battle_state == MotherplantBattleStates.WARBLING_WARCRY:
  262.             self._change_state(self.warbling_warcry_battle_situation_state())
  263.  
  264.     def _on_proxy_situation_goal_added(self, goal):
  265.         self._player_health_tracking_situation_goal = goal
  266.  
  267.     def _issue_requests(self):
  268.         super()._issue_requests()
  269.         request = SelectableSimRequestFactory(self, _RequestUserData(), self.other_player_jobs, self.exclusivity, request_priority=BouncerRequestPriority.EVENT_DEFAULT_JOB)
  270.         self.manager.bouncer.submit_request(request)
  271.  
  272. lock_instance_tunables(MotherPlantBattleSituation, audio_sting_on_start=None, main_goal_audio_sting=None)
RAW Paste Data
We use cookies for various purposes including analytics. By continuing to use Pastebin, you agree to our use of cookies as described in the Cookies Policy. OK, I Understand
 
Top