cdrandin

Untitled

Mar 8th, 2017
109
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
C# 7.68 KB | None | 0 0
  1. using UnityEngine;
  2. using System.Collections;
  3. using System.Collections.Generic;
  4.  
  5. public class Buffable : MonoBehaviour
  6. {
  7.     public static List<Buffable> buffables = new List<Buffable>();
  8.     public static List<Buffable> playerBuffables = new List<Buffable>();
  9.     public static List<Buffable> aiBuffables = new List<Buffable>();
  10.  
  11.     public string name = string.Empty;
  12.     public Character owner; // who caused the buffable
  13.     public Character affected; // afflicted with the buffable
  14.  
  15.     public int damage = 0;
  16.  
  17.     [Tooltip("Keywords will be replaced: (STR, DEX, WILL, ABILITY_BASE_DAMAGE, BUFFABLE_BASE_DAMAGE, ITEM_BASE_DAMAGE)")]
  18.     // Put in basic mathematical expressions
  19.     // Use method to calculate string to a final damage value
  20.     public string damageFormula = string.Empty;
  21.     private int _finalDamage = 0;
  22.     public virtual int finalDamage { get { return this._finalDamage; } }
  23.  
  24.     public BuffDuration buffDuration = BuffDuration.NONE;
  25.     public TargetType targetType = TargetType.NONE;
  26.     public float timedDuration = 0.0f;
  27.  
  28.     public ElapseType elapseType = ElapseType.NONE;
  29.     public float interval = 0;
  30.    
  31.     [Header ("Conditions for applying")]
  32.     [Range (0f, 1f)]
  33.     public float applyChance = 1f;
  34.  
  35.     public bool lessThan;
  36.     public bool equalTo;
  37.     public bool greaterThan;
  38.  
  39.     public bool checkCurrentHealth;
  40.     public int currentHealth;
  41.    
  42.     public bool checkPercentageCurrentHealth;
  43.     [Range (0f, 1f)]
  44.     public float percentageCurrentHealth;
  45.    
  46.     public delegate void OnInitializeEffect();
  47.     public OnInitializeEffect onInitializeEffect;
  48.  
  49.     public delegate void OnStartEffect(Character target);
  50.     public OnStartEffect onStartEffect;
  51.  
  52.     public delegate void OnUpdateEffect(Character target);
  53.     public OnStartEffect onUpdateEffect;
  54.  
  55.     public delegate void OnEndEffect(Character target);
  56.     public OnStartEffect onEndEffect;
  57.  
  58.     public Ability ability = null; // ability that applied the buffable
  59.     private bool forceQuit = false;
  60.  
  61.     protected virtual void Awake ()
  62.     {
  63.         buffables.Add(this);
  64.  
  65.         if (gameObject.tag == "PlayerBuffable")
  66.             playerBuffables.Add(this);
  67.         else if (gameObject.tag == "AIBuffable")
  68.             aiBuffables.Add(this);
  69.     }
  70.    
  71.     // Update is called once per frame
  72.     protected virtual void Update () {
  73.  
  74.     }
  75.  
  76.     public void CalculateFinalDamage()
  77.     {
  78.         /*
  79.          * Keywords will be replaced: (STR, DEX, WILL, ABILITY_BASE_DAMAGE, BUFFABLE_BASE_DAMAGE, ITEM_BASE_DAMAGE)
  80.          * EXCLUDED: (HERO_BASE_PHYSICAL_DAMAGE, HERO_BASE_RANGED_DAMAGE, HERO_BASE_WILL_DAMAGE)
  81.          * Format must be: "STR"
  82.          * Example: "2 * STR + BASE_DAMAGE"
  83.          */
  84.        
  85.         int amount = 0;
  86.         CombatStats stats = this.owner.GetComponent<CombatStats>();
  87.        
  88.         if(stats == null)
  89.         {
  90.             Debug.LogErrorFormat("Missing combat stats from {0}", this.owner);
  91.             amount = this.damage;
  92.         }
  93.         else
  94.         {
  95.             if(this.damageFormula == "")
  96.             {
  97.                 amount = this.damage;
  98.             }
  99.             else
  100.             {
  101.                 try
  102.                 {
  103.                     string expression = damageFormula;
  104.                     expression = expression.Replace("STR", stats.str.ToString());
  105.                     expression = expression.Replace("DEX", stats.dex.ToString());
  106.                     expression = expression.Replace("WILL", stats.will.ToString());
  107.                    
  108.                     expression = expression.Replace("ABILITY_BASE_DAMAGE", this.ability.damage.ToString());
  109.                     expression = expression.Replace("BUFFABLE_BASE_DAMAGE", this.damage.ToString());
  110.                     expression = expression.Replace("ITEM_BASE_DAMAGE", this.ability.finalItemBaseDamage.ToString());
  111.                
  112. //                  expression = expression.Replace("HERO_BASE_PHYSICAL_DAMAGE", stats.physicalDamage.ToString());
  113. //                  expression = expression.Replace("HERO_BASE_RANGED_DAMAGE", stats.rangedDamage.ToString());
  114. //                  expression = expression.Replace("HERO_BASE_WILL_DAMAGE", stats.willDamage.ToString());
  115.                     amount = (int)MathfExtension.Evaluate(expression);
  116.                 }
  117.                 catch(System.Exception e)
  118.                 {
  119.                     Debug.LogError(e);
  120.                     amount = this.damage;
  121.                 }
  122.             }
  123.         }
  124.  
  125.         this._finalDamage = amount;
  126.     }
  127.  
  128.     private bool CheckSuccessfulApplication(Character target)
  129.     {
  130.         float r = Random.value;
  131.         if(r > this.applyChance)
  132.         {
  133.             return false;
  134.         }
  135.  
  136.         if(this.checkCurrentHealth)
  137.         {
  138.             if(!LogicOperator<int>(target.currentHealth, this.currentHealth))
  139.             {
  140.                 return false;
  141.             }
  142.         }
  143.  
  144.         if(this.checkPercentageCurrentHealth)
  145.         {
  146.             if(!LogicOperator<float>((float)target.currentHealth/(float)target.maxHealth, this.percentageCurrentHealth))
  147.             {
  148.                 return false;
  149.             }
  150.         }
  151.  
  152.         return true;
  153.     }
  154.  
  155.     private bool LogicOperator<T>(T lhs, T rhs)
  156.     {
  157.         bool v = false;
  158.  
  159.         if(this.lessThan)
  160.         {
  161.             v = Comparer<T>.Default.Compare(lhs, rhs) < 0;
  162.         }
  163.  
  164.         else if(this.greaterThan)
  165.         {
  166.             v = Comparer<T>.Default.Compare(lhs, rhs) > 0;
  167.         }
  168.  
  169.         if(this.equalTo)
  170.         {
  171.             v = v || Comparer<T>.Default.Compare(lhs, rhs) == 0;
  172.         }
  173.  
  174.         return v;
  175.     }
  176.  
  177.     public void Initialize(Character affected, Character owner, Ability ability)
  178.     {
  179.         // check if it gets applied
  180.         if(!this.CheckSuccessfulApplication(affected))
  181.         {
  182.             // failed, don't apply buffable
  183.             GameObject.Destroy(this.gameObject);
  184.             return;
  185.         }
  186.  
  187.         this.affected = affected;
  188.         this.owner = owner;
  189.         this.ability = ability;
  190.  
  191.         // terminate buff when character is dead
  192.         this.affected.onAIDeath += (string name) => { this.ForceQuit(); };
  193.         this.affected.onPlayerDeath += (string name) => { this.ForceQuit(); };
  194.  
  195.         this.onInitializeEffect(); // calls BuffStart
  196.     }
  197.  
  198.     protected virtual void BuffStart()
  199.     {
  200.         Debug.Log(string.Format("Starting buffable: {0}", this.name));
  201.  
  202.         foreach(Character target in this.afflictedTargets)
  203.         {
  204.             this.onStartEffect(target);
  205.             target.buffables.Add(this);
  206.         }
  207.  
  208.         // Handle interval buff
  209.         if(elapseType == ElapseType.INTERVAL)
  210.         {
  211.             if(interval == 0)
  212.             {
  213.                 Debug.LogWarning("interval is set to 0 while elapseType == ElapseType.INTERVAL");
  214.             }
  215.  
  216.             StartCoroutine(UpdateDelay(interval));
  217.         }
  218.         else if(elapseType == ElapseType.CONSTANT)
  219.         {
  220.             StartCoroutine(EndDelay(timedDuration));
  221.         }
  222.     }
  223.  
  224.     private IEnumerator UpdateDelay(float delay)
  225.     {
  226.         float time = 0;
  227.         while(true)
  228.         {
  229.             if(this.forceQuit) break;
  230.  
  231.             yield return new WaitForSeconds(delay);
  232.             time += delay;
  233.            
  234.             // check buff duration
  235.             if(buffDuration == BuffDuration.TIMED)
  236.             {
  237.                 if(time >= timedDuration)
  238.                 {
  239.                     break;
  240.                 }
  241.             }
  242.            
  243.             foreach(Character target in this.afflictedTargets)
  244.             {
  245.                 this.onUpdateEffect(target);
  246.             }
  247.         }
  248.        
  249.         BuffEnd();
  250.     }
  251.  
  252.     private IEnumerator EndDelay(float delay)
  253.     {
  254.         yield return new WaitForSeconds(delay);
  255.         BuffEnd();
  256.     }
  257.  
  258.     protected virtual void ForceQuit()
  259.     {
  260.         this.forceQuit = true;
  261.     }
  262.  
  263.     protected virtual void BuffEnd()
  264.     {
  265.         if(buffDuration == BuffDuration.TIMED)
  266.         {
  267.             foreach(Character target in this.afflictedTargets)
  268.             {
  269.                 this.onEndEffect(target);
  270.                 target.buffables.Remove(this);
  271.             }
  272.            
  273.             Remove();
  274.         }
  275.     }
  276.  
  277.     protected virtual void Remove()
  278.     {
  279.         Debug.Log(string.Format("Buffable: {0} has ended", this.name));
  280.         GameObject.Destroy(this.gameObject);
  281.     }
  282.  
  283.     public List<Character> afflictedTargets
  284.     {
  285.         get
  286.         {
  287.             List<Character> targets = new List<Character>();
  288.            
  289.             // Decide target
  290.             switch(targetType)
  291.             {
  292.             case TargetType.BOTH:
  293.                 targets.Add(owner);
  294.                 targets.Add(affected);
  295.                 break;
  296.             case TargetType.SELF:
  297.                 targets.Add(owner);
  298.                 break;
  299.             case TargetType.ENEMY:
  300.                 targets.Add(affected);
  301.                 break;
  302.             }
  303.            
  304.             return targets;
  305.         }
  306.     }
  307. }
  308.  
  309. public enum BuffDuration { NONE, PERMANENT, TIMED }
  310. public enum TargetType { NONE, SELF, ENEMY, BOTH }
  311. public enum ElapseType { NONE, CONSTANT, INTERVAL }
  312. /*
  313.  * ElapseType:
  314.  * None - None
  315.  * Constant: Effects will only be active once in the begining and removed at the end
  316.  * Interval: The effects will continue to apply on every internal, set above, then will end
  317.  */
Advertisement
Add Comment
Please, Sign In to add comment