Advertisement
Guest User

Untitled

a guest
Nov 21st, 2018
46
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
C# 10.81 KB | None | 0 0
  1. using Chronicles.Data.Mapping;
  2. using System.Collections;
  3. using System.Collections.Generic;
  4. using UnityEngine;
  5. using UnityEngine.Events;
  6.  
  7. [RequireComponent(typeof(Collider2D))]
  8. public class InteractableObject : MonoBehaviour {
  9.     #region Inspector Fields
  10.     [Header("Interactable Object Settings")]
  11.     /// <summary>
  12.     /// If set to <code>true</code>, only the player is able to interact
  13.     /// </summary>
  14.     [SerializeField]
  15.     [Tooltip("If set, only the player is able to interact")]
  16.     private bool requiresPlayer = true;
  17.  
  18.     /// <summary>
  19.     /// The name of a tag that is required in order to interact
  20.     /// </summary>
  21.     [SerializeField]
  22.     [Tooltip("(optional) The name of a tag that is required in order to interact (Leave empty if no tag is required!)")]
  23.     private string requiresTag = "";
  24.  
  25.     /// <summary>
  26.     /// The type of interaction that is required in order to trigger the interaction
  27.     /// </summary>
  28.     [SerializeField]
  29.     [Tooltip("The type of interaction that is required in order to trigger the interaction")]
  30.     private InteractionType interactionType;
  31.  
  32.     /// <summary>
  33.     /// If set to <code>true</code> with this Interactable Object only one interaction is possible
  34.     /// </summary>
  35.     [SerializeField]
  36.     [Tooltip("Set this flag to allow this Interactable Object to be interacted with only one time")]
  37.     private bool oneTimeInteraction = false;
  38.  
  39.     /// <summary>
  40.     /// If you need more than one but not infinite interactions you can set this value to your needs
  41.     /// </summary>
  42.     [SerializeField]
  43.     [Tooltip("If you need more than one but not infinite interactions you can set this value to your needs")]
  44.     private int maxInteractionCount = 0;
  45.  
  46.     /// <summary>
  47.     /// The GameObject this InteractableObject component is attached to will be destroyed after interaction
  48.     /// </summary>
  49.     [Header("Interaction Behaviour")]
  50.     [SerializeField]
  51.     [Tooltip("The GameObject this InteractableObject component is attached to will be destroyed after interaction")]
  52.     private bool destroyAfterInteraction = false;
  53.  
  54.     /// <summary>
  55.     /// If Destroy After Interaction is enabled this amount of seconds will be used as delay before destroying the parent GameObject
  56.     /// </summary>
  57.     [SerializeField]
  58.     [Tooltip("If Destroy After Interaction is enabled this amount of seconds will be used as delay before destroying the parent GameObject")]
  59.     private float destroyDelay = 0.0f;
  60.     #endregion Inspector Fields
  61.  
  62.     #region Public Unity Events
  63.     [Header("Events")]
  64.     [SerializeField]
  65.     [Tooltip("Will be invoked on Interaction")]
  66.     private UnityEvent onInteraction;
  67.     #endregion Public Unity Events
  68.  
  69.     #region Public Properties
  70.     /// <summary>
  71.     /// Will be <code>true</code> if with this Interactable Object was interacted at least one time
  72.     /// </summary>
  73.     public bool Interacted
  74.     {
  75.         get
  76.         {
  77.             return InteractionCount > 0;
  78.         }
  79.     }
  80.  
  81.     /// <summary>
  82.     /// The amount of interactions done on this InteractableObject
  83.     /// </summary>
  84.     public int InteractionCount
  85.     {
  86.         get;
  87.         private set;
  88.     }
  89.  
  90.     /// <summary>
  91.     /// Will return the OneTimeInteraction flag
  92.     /// </summary>
  93.     public bool OneTimeInteraction
  94.     {
  95.         get
  96.         {
  97.             return this.oneTimeInteraction;
  98.         }
  99.     }
  100.     #endregion Public Properties
  101.  
  102.     #region Public Fields
  103.     /// <summary>
  104.     /// The InteractionSheet contains detail informations about what will happen on interaction
  105.     /// </summary>
  106.     [HideInInspector]
  107.     public InteractionSheet interactionSheet;
  108.     #endregion
  109.  
  110.     #region MonoBehaviour Overrides
  111.     private void OnValidate()
  112.     {
  113.         if (this.oneTimeInteraction)
  114.         {
  115.             this.maxInteractionCount = 1;
  116.         }
  117.  
  118.         if (this.maxInteractionCount != 1)
  119.         {
  120.             this.oneTimeInteraction = false;
  121.         }
  122.     }
  123.  
  124.     private void OnTriggerEnter2D(Collider2D collision)
  125.     {
  126.         // Ignore, if InteractionType is not Trigger
  127.         if (this.interactionType != InteractionType.Trigger) return;
  128.  
  129.         InternalInteract(collision.transform);
  130.     }
  131.     #endregion MonoBehaviour Overrides
  132.  
  133.     #region Public Methods
  134.     /// <summary>
  135.     /// Invokes the interaction with the InteractableObject
  136.     /// </summary>
  137.     /// <param name="interactor">The interacting object</param>
  138.     public void Interact(Transform interactor)
  139.     {
  140.         if (this.interactionType == InteractionType.Trigger) return;
  141.  
  142.         this.InternalInteract(interactor);
  143.     }
  144.  
  145.     public bool CanInteract(Transform interactor)
  146.     {
  147.         // No Interactor -> false
  148.         if (!interactor)
  149.         {
  150.             return false;
  151.         }
  152.  
  153.         // Tag is required but not matching
  154.         else if (string.IsNullOrWhiteSpace(requiresTag) == false && (interactor.tag.ToLower().Trim() != requiresTag.ToLower().Trim()))
  155.         {
  156.             return false;
  157.         }
  158.  
  159.         // Player is required but not interacting
  160.         else if (this.requiresPlayer && !Utils.IsPlayer(interactor.gameObject))
  161.         {
  162.             return false;
  163.         }
  164.  
  165.         // OTI is enabled and interaction already happened
  166.         else if (this.oneTimeInteraction && Interacted)
  167.         {
  168.             return false;
  169.         }
  170.  
  171.         // Max Interaction Count is > 0 and the maximum was reached
  172.         else if (this.maxInteractionCount > 0 && InteractionCount >= this.maxInteractionCount)
  173.         {
  174.             return false;
  175.         }
  176.  
  177.         // If none of the conditions above are matching, interaction is possible
  178.         else
  179.         {
  180.             return true;
  181.         }
  182.     }
  183.     #endregion
  184.  
  185.     #region Private Methods
  186.     /// <summary>
  187.     /// Executes the interaction independent from the source
  188.     /// </summary>
  189.     /// <param name="interactor">The interacting object</param>
  190.     private void InternalInteract(Transform interactor)
  191.     {
  192.         // Cancel interaction if interaction is not possible
  193.         if (CanInteract(interactor) == false)
  194.         {
  195.             return;
  196.         }
  197.  
  198.         // Debug info
  199.         Debug.Log(interactor.name + " started interaction with " + gameObject.name);
  200.  
  201.         // Increase interaction count
  202.         InteractionCount++;
  203.  
  204.         // Invoke UnityEvent event
  205.         if (onInteraction != null)
  206.         {
  207.             onInteraction.Invoke();
  208.         }
  209.  
  210.         // Interaction!
  211.         this.ApplyInteractionSheet(interactor);
  212.  
  213.         // Destroy object after Interaction
  214.         if (destroyAfterInteraction)
  215.         {
  216.             Destroy(gameObject, destroyDelay);
  217.         }
  218.     }
  219.  
  220.     /// <summary>
  221.     /// Applies the attached InteractionSheet
  222.     /// </summary>
  223.     /// <param name="interactor"></param>
  224.     private void ApplyInteractionSheet(Transform interactor)
  225.     {
  226.         if (!interactionSheet)
  227.         {
  228.             Debug.LogWarning("No Interaction Sheet attached!");
  229.             return;
  230.         }
  231.  
  232.         LivingEntity interactorEntity = interactor.GetComponent<LivingEntity>();
  233.         InventoryController interactorInventory = interactor.GetComponent<InventoryController>();
  234.         PlayerJournalController journalController = interactor.GetComponent<PlayerJournalController>();
  235.  
  236.         // Add / Remove Items
  237.         if (interactionSheet.enableItemAdding)
  238.         {
  239.             if (interactorInventory)
  240.             {
  241.                 interactorInventory.AddItemByID(interactionSheet.itemToBeAdded, interactionSheet.itemToBeAddedAmount);
  242.             } else
  243.             {
  244.                 Debug.LogWarning("Can't execute InteractionSheet: Target has no Inventory component");
  245.             }
  246.         }
  247.  
  248.         if (interactionSheet.enableItemRemoval && interactorInventory)
  249.         {
  250.             if (interactorInventory)
  251.             {
  252.                 interactorInventory.RemoveItemsByID(interactionSheet.itemToBeRemoved, interactionSheet.itemToBeRemovedAmount);
  253.             }
  254.             else
  255.             {
  256.                 Debug.LogWarning("Can't execute InteractionSheet: Target has no Inventory component");
  257.             }
  258.         }
  259.  
  260.         // Restore / Drain Health
  261.         if (interactionSheet.enableHealthRestore && interactorEntity)
  262.         {
  263.             if (interactorEntity)
  264.             {
  265.                 interactorEntity.RestoreHealth(interactionSheet.healthToRestore);
  266.             }
  267.             else
  268.             {
  269.                 Debug.LogWarning("Can't execute InteractionSheet: Target has no LivingEntity component");
  270.             }
  271.         }
  272.  
  273.         if (interactionSheet.enableHealthDrain && interactorEntity)
  274.         {
  275.             if (interactorEntity)
  276.             {
  277.                 interactorEntity.DrainHealth(interactionSheet.healthToDrain);
  278.             }
  279.             else
  280.             {
  281.                 Debug.LogWarning("Can't execute InteractionSheet: Target has no LivingEntity component");
  282.             }
  283.         }
  284.  
  285.         // Restore / Drain Stamina
  286.         if (interactionSheet.enableStaminaRestore && interactorEntity)
  287.         {
  288.             if (interactorEntity)
  289.             {
  290.                 interactorEntity.RestoreStamina(interactionSheet.staminaToRestore);
  291.             }
  292.             else
  293.             {
  294.                 Debug.LogWarning("Can't execute InteractionSheet: Target has no LivingEntity component");
  295.             }
  296.         }
  297.  
  298.         if (interactionSheet.enableStaminaDrain && interactorEntity)
  299.         {
  300.             if (interactorEntity)
  301.             {
  302.                 interactorEntity.DrainStamina(interactionSheet.staminaToDrain);
  303.             }
  304.             else
  305.             {
  306.                 Debug.LogWarning("Can't execute InteractionSheet: Target has no LivingEntity component");
  307.             }
  308.         }
  309.        
  310.         // Restore / Drain Satiation
  311.         if (interactionSheet.enableSatiationRestore && interactorEntity)
  312.         {
  313.             if (interactorEntity)
  314.             {
  315.                 interactorEntity.RestoreSatiation(interactionSheet.satiationToRestore);
  316.             }
  317.             else
  318.             {
  319.                 Debug.LogWarning("Can't execute InteractionSheet: Target has no LivingEntity component");
  320.             }
  321.         }
  322.  
  323.         if (interactionSheet.enableSatiationDrain && interactorEntity)
  324.         {
  325.             if (interactorEntity)
  326.             {
  327.                 interactorEntity.DrainSatiation(interactionSheet.satiationToDrain);
  328.             }
  329.             else
  330.             {
  331.                 Debug.LogWarning("Can't execute InteractionSheet: Target has no LivingEntity component");
  332.             }
  333.         }
  334.  
  335.         // Storytelling
  336.         if (interactionSheet.enableJournalEntry && journalController)
  337.         {
  338.             journalController.AddJournalEntry(interactionSheet.addJournalEntryID);
  339.         }
  340.     }
  341.     #endregion Private Methods
  342. }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement