Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- using UnityEngine;
- using System.Linq;
- using System.Collections;
- using System.Collections.Generic;
- using UnityEngine.UI;
- using DarkTonic.MasterAudio;
- using Devdog.InventorySystem;
- public class Character : MonoBehaviour
- {
- public List<CharacterState> states = new List<CharacterState>();
- public static List<Character> characters = new List<Character>();
- public static List<Character> playerCharacters = new List<Character>();
- public static List<Character> aiCharacters = new List<Character>();
- public string name;
- public string[] abilityNames;
- public List<string> weaponIDs = new List<string>(); // this will help associate which ability is from what weapon
- public List<Ability> uninitializedAbilities = new List<Ability>();
- public List<Buff> buffs = new List<Buff>();
- public List<Buffable> buffables = new List<Buffable>();
- public Color targetColor = Color.white;
- private bool _initialized = false;
- private bool followFinger = false;
- [Header ("Primary Stats")]
- // Use combatStats, as they calculate final values.
- public int currentHealth = 100;
- public int maxHealth = 100;
- public int strength = 0;
- public int dexterity = 0;
- public int will = 0;
- [Header ("Secondary Stats")]
- public CharacterShields characterShields = new CharacterShields();
- public float meleeEvasionChance = 0.0f;
- public CombatStats combatStats = null;
- [Header ("Interface Elements")]
- public Text healthLabel = null;
- public GameObject powerIcon = null;
- [Header ("Casting Stuff")]
- public GameObject castingCanvas = null;
- public Image castingAbilityImage = null;
- public Text castingAbilityTimerLabel = null;
- public Image castingAbilityBar = null;
- public GameObject portrait = null;
- public PortraitCallbackHandler portraitCallbackHandler = null;
- private float snapSpeed = 5.0f;
- private List<GameObject> validTargets = new List<GameObject>();
- public List<GameObject> abilityDocks = new List<GameObject>();
- public List<Ability> abilities = new List<Ability>();
- public Ability currentAbilityInUse = null;
- public GameObject dock = null;
- public EncounterNode node = null;
- public List<GameObject> deathEffects = new List<GameObject>();
- public Animator animator = null;
- private StateMachineEngine _stateMachine = null;
- public string ID = "";
- #region Events and Delegates
- public delegate void PlayerDeathEventHandler(string name);
- public event PlayerDeathEventHandler onPlayerDeath;
- public event PlayerDeathEventHandler onAIDeath;
- public delegate void InitializedEventHandler(Character character);
- public event InitializedEventHandler onInitialized;
- public delegate void SpawnedEventHandler(Character character);
- public event SpawnedEventHandler onSpawned;
- public delegate void MadeActiveEventHandler();
- public event MadeActiveEventHandler onMadeActive;
- public delegate void MadeInactiveEventHandler();
- public event MadeInactiveEventHandler onMadeInactive;
- public delegate void OnDamagedByHandler(Character character);
- public event OnDamagedByHandler onDamagedByHandler;
- public event OnDamagedByHandler onDamagedByOnceHandler;
- public delegate void OnHealedByHandler(Character character);
- public event OnHealedByHandler onHealedByHandler;
- #endregion
- #region Properties
- public StateMachineEngine StateMachine{get{if (_stateMachine == null){_stateMachine = gameObject.AddComponent<StateMachineEngine>();}return _stateMachine;}}
- public bool Initialized {get{return _initialized;}set{_initialized = value;}}
- #endregion
- #region Unity Callbacks
- protected virtual void Awake()
- {
- characters.Add(this);
- targetColor = new Color(1.5f, 1.5f, 1.5f, 1.5f);
- StateMachine.Initialize<CharacterState>(this);
- StateMachine.ChangeState(CharacterState.NONE); // HACK: Possible, to force AI to have abilities to display, however, when ability used it disappears
- }
- // Use this for initialization
- protected virtual void Start ()
- {
- AddBuff(new Flying(this));
- }
- // Update is called once per frame
- protected virtual void Update ()
- {
- states = StateMachine.GetStates<CharacterState>();
- Renderer renderer = portrait.GetComponent<Renderer>();
- renderer.material.color = Color.Lerp(renderer.material.color, targetColor, Time.deltaTime * 10.0f);
- }
- protected virtual void OnMouseDown()
- {
- }
- protected virtual void OnMouseUp()
- {
- }
- protected virtual void OnTriggerEnter(Collider other)
- {
- if (other.gameObject.tag == "Player")
- {
- validTargets.Add (other.gameObject);
- }
- }
- protected virtual void OnTriggerExit(Collider other)
- {
- if (other.gameObject.tag == "Player")
- {
- validTargets.Remove (other.gameObject);
- }
- }
- protected virtual void OnDestroy ()
- {
- Character.characters.Remove(this);
- Destroy(this._stateMachine);
- }
- public virtual void Destroy()
- {
- this.OnDestroy();
- GameObject.Destroy(this.gameObject);
- }
- #endregion
- #region Event Callbacks
- public virtual void OnAbilitySelectingTarget(Ability ability)
- {
- if (Ability.CheckTarget(ability, this))
- {
- StateMachine.AddConcurrentState(CharacterState.TARGETABLE);
- }
- if (!StateMachine.GetState<CharacterState>(CharacterState.TARGETABLE))
- {
- StateMachine.AddConcurrentState(CharacterState.UNTARGETABLE);
- }
- }
- public virtual void OnAbilityFinishedSelectingTarget(Ability ability)
- {
- StateMachine.RemoveConcurrentState(CharacterState.TARGETABLE);
- StateMachine.RemoveConcurrentState(CharacterState.UNTARGETABLE);
- }
- // Not sure if this kind of specifics is needed, maybe one will suffice
- public virtual void OnDamagedBy(Character character)
- {
- if(onDamagedByOnceHandler != null)
- {
- onDamagedByOnceHandler(character);
- onDamagedByOnceHandler = null;
- }
- if(onDamagedByHandler != null)
- onDamagedByHandler(character);
- }
- public virtual void OnHealedBy(Character character)
- {
- if(onHealedByHandler != null)
- onHealedByHandler(character);
- }
- #endregion
- #region Instance Methods
- public virtual void Initialize(PartyMemberData partyMember, GameObject dock)
- {
- this.name = partyMember.name.Replace("*", "");
- this.dock = dock;
- node = this.dock.GetComponent<EncounterNode>();
- node.Occupy(this);
- gameObject.transform.localScale = new Vector3(0.15f, 0.15f, 0.15f);
- LoadCharacterData(partyMember);
- this.SetupCombatStats();
- }
- public virtual void Initialize(string name, GameObject dock)
- {
- this.name = name;
- this.dock = dock;
- node = this.dock.GetComponent<EncounterNode>();
- node.Occupy(this);
- gameObject.transform.localScale = new Vector3(0.15f, 0.15f, 0.15f);
- LoadCharacterData(name);
- this.SetupCombatStats();
- }
- private void UpdateCombatStats()
- {
- this.strength = this.combatStats.str;
- this.dexterity = this.combatStats.dex;
- this.will = this.combatStats.will;
- }
- private void SetupCombatStats()
- {
- // ONLY FOR PLAYER FOR THE TIME BEING TILL STATS GET UNIFIED BETTER
- //
- // HACK: No nice way of collectively getting an accurate reading of stats
- // and this is mainly to get it for the test scenario stat input way.
- // if(PlayerPrefs.HasKey(ScenarioTestV3UIManager.combat_stats_key) && this.gameObject.tag == "Player")
- // {
- // JSON.JSONObject jo = JSON.JSONObject.Parse(PlayerPrefs.GetString(ScenarioTestV3UIManager.combat_stats_key));
- // Debug.Log(this.name);
- // JSON.JSONObject hero = jo[this.name].Obj;
- //
- // int health = 0;
- // int spirit = 0;
- // int strength = 0;
- // int dexerity = 0;
- // int will = 0;
- //
- // if(hero.ContainsKey("health"))
- // health = (int)hero["health"].Number;
- //
- // if(hero.ContainsKey("spirit"))
- // spirit = (int)hero["spirit"].Number;
- //
- // if(hero.ContainsKey("strength"))
- // strength = (int)hero["strength"].Number;
- //
- // if(hero.ContainsKey("dexerity"))
- // dexerity = (int)hero["dexerity"].Number;
- //
- // if(hero.ContainsKey("will"))
- // will = (int)hero["will"].Number;
- //
- // // load up combat stats
- // this.combatStats = this.gameObject.AddComponent<CombatStats>(); // Probably doesn't need MonoBehaviour
- // this.combatStats.Initialize(health, spirit, strength, dexerity, will);
- //
- // // now setup stats for player
- // this.currentHealth = this.maxHealth = this.combatStats.hp;
- //
- // // HACK very coupling. Currently in place till stat stuff gets in place
- //// GameManager.Instance.playerCurrentSpirit = GameManager.Instance.playerMaxSpirit = this.combatStats.spirit;
- // GameManager.Instance.playerMaxSpirit = this.combatStats.spirit;
- // this.UpdateCombatStats();
- // }
- // Not using GetStatsForPartyMember since the testing tool would currently just be overwritting it
- // this.combatStats.Initialize(GameStateManager.instance.GetStatsForPartyMember(this.name), this.maxHealth, 0);
- }
- public void MoveToEncounterNode(EncounterNode encounterNode)
- {
- dock = encounterNode.gameObject;
- node.Vacate(this);
- node = encounterNode;
- node.Occupy(this);
- }
- public virtual void ApplyDamageBy(Character character, int damage)
- {
- // this.ApplyDamage(damage);
- this.OnDamagedBy(character);
- }
- public virtual void ApplyDamage (int damage)
- {
- if (currentHealth <= 0)
- {
- if(tag == "Player")
- {
- if (onPlayerDeath != null)
- {
- onPlayerDeath(name);
- }
- }
- else if(tag == "AI")
- {
- if(onAIDeath != null)
- {
- onAIDeath(name);
- }
- }
- }
- }
- public virtual void ApplyHealth(int amount)
- {
- // this.currentHealth = Mathf.Clamp(this.currentHealth + amount, 0, this.maxHealth);
- }
- public virtual void ApplyHealthBy(Character character, int amount)
- {
- // this.ApplyHealth(amount);
- this.OnHealedBy(character);
- }
- public void CharacterGUIText(string message, Color color = new Color(), float speed = 1f, float duration = 1f)
- {
- GameObject prefab = (GameObject) Resources.Load("FloatingText");
- GameObject go = (GameObject)Instantiate(prefab);
- go.transform.position = gameObject.transform.position + Vector3.up ;
- go.GetComponent<FloatingText>().Initialize(message, color, speed, duration);
- }
- public void DamageGUIText(int damage)
- {
- if(damage == int.MaxValue || damage == 0) return;
- this.CharacterGUIText(damage.ToString(), Color.white, 1.0f, 2.0f);
- }
- public void EffectGUIText(string message)
- {
- this.CharacterGUIText(message, Color.yellow, 2.0f, 1.0f);
- }
- public void HealthGUIText(int amount)
- {
- if(amount == int.MaxValue || amount == 0) return;
- this.CharacterGUIText(amount.ToString(), Color.green, 1.0f, 2.0f);
- }
- public virtual void UpdateHealthLabel()
- {
- healthLabel.text = currentHealth.ToString();
- }
- public static bool CheckAvailability(Character character)
- {
- if (character.StateMachine.GetState(CharacterState.INACTIVE))
- {
- foreach(Ability ability in character.abilities)
- {
- List<Character> targets = new List<Character>(Ability.GetTargets(ability));
- if (targets.Count > 0)
- {
- return true;
- }
- // if (targets.Count <= 0)
- // {
- // return false; // shouldn't be returning false so soon, check other abilities
- // }
- // return true;
- }
- }
- return false;
- }
- public void AddBuff(Buff buff)
- {
- buff.Initialize();
- buffs.Add(buff);
- }
- #endregion
- #region Event Callbacks
- public virtual void OnAbilityInitialized(Ability ability)
- {
- abilities.Add(ability);
- // if(ability.isPowerAbility && this.powerIcon != null)
- // {
- // this.powerIcon.SetActive(true);
- // }
- }
- public virtual void OnEncounterFinishedInitializing()
- {
- }
- #endregion
- #region Server Methods and Callbacks
- public virtual void LoadCharacterData(string name)
- {
- }
- public virtual void LoadCharacterData(PartyMemberData partyMember)
- {
- }
- public virtual void OnCharacterDataLoaded(Response response)
- {
- StateMachine.ChangeState(CharacterState.INITIALIZING);
- }
- #endregion
- #region Animation Callbacks
- public virtual void OnFinishedSpawning()
- {
- if (onSpawned != null)
- {
- onSpawned(this);
- }
- }
- public virtual void OnFlipLiveFinished()
- {
- CameraController.Instance.RemoveLookTarget();
- GameObject prefab = (GameObject) Resources.Load("FloatingText");
- GameObject go = (GameObject)Instantiate(prefab);
- go.transform.position = gameObject.transform.position + Vector3.up ;
- go.GetComponent<FloatingText>().Initialize("Second Wind!", Color.yellow, 1.0f, 2.0f);
- animator.CrossFade("Idle", 0.1f);
- StateMachine.ChangeState(CharacterState.INACTIVE);
- }
- public virtual void OnFlipDieFinished()
- {
- CameraController.Instance.RemoveLookTarget();
- animator.CrossFade("Idle", 0.1f);
- foreach (GameObject deathEffect in deathEffects)
- {
- Instantiate(deathEffect, transform.position, Quaternion.identity);
- }
- if (onPlayerDeath != null)
- {
- onPlayerDeath(name);
- }
- StateMachine.ChangeState(CharacterState.DEAD);
- }
- #endregion
- #region INITIALIZING State Callbacks
- protected virtual void INITIALIZING_Enter()
- {
- //GUIManager.Instance.RegisterPlayer(this);
- portraitCallbackHandler.onFlipLiveFinished += OnFlipLiveFinished;
- portraitCallbackHandler.onFlipDieFinished += OnFlipDieFinished;
- portraitCallbackHandler.onFinishedSpawning += OnFinishedSpawning;
- UpdateHealthLabel();
- AbilityTable abilityTable = TableManager.Instance.GetUserTable<AbilityTable>("AbilityTable");
- for (int i = 0; i < abilityNames.Length; i++)
- {
- if (i < abilityDocks.Count)
- {
- if(abilityNames[i].Length == 0)
- {
- continue;
- };
- GameObject go = null;
- Debug.Log(abilityNames[i]);
- try
- {
- AbilityTableItem item = abilityTable.TableData.GetItem(abilityNames[i]);
- go = (GameObject)Instantiate((Resources.Load("Abilities/" + item.ResourcePath, typeof(GameObject))) as GameObject, abilityDocks[i].transform.position, transform.rotation);
- Ability ability = go.GetComponent<Ability>();
- // update values from database, currently ID is the path to the ability. EX) _Marc's Proposed Abilities/...
- ability.ID = item.ID;
- }
- catch(System.Exception e)
- {
- Debug.LogError(string.Format("Ability error {0}: {1}", abilityNames[i], e));
- // Error gets thrown when ally comed into play but ability still gets load and works. idk wtf
- Debug.Log(this.name);
- return;
- }
- go.transform.Rotate(Vector3.up * 180.0f);
- uninitializedAbilities.Add (go.GetComponent<Ability>());
- uninitializedAbilities[uninitializedAbilities.Count - 1].Initialize(this, abilityDocks[i]);
- uninitializedAbilities[uninitializedAbilities.Count - 1].onInitialized += this.OnAbilityInitialized;
- EquipmentTable equipmentTable = TableManager.Instance.GetUserTable<EquipmentTable>("WeaponTable");
- if(equipmentTable != null && this.weaponIDs.Count > 0)
- {
- if(equipmentTable.TableData.ContainsItem(this.weaponIDs[i]))
- {
- EquipmentTableItem item = equipmentTable.TableData.GetItem(this.weaponIDs[i]);
- if(item.Stats.ContainsKey("MINDMG") && item.Stats.ContainsKey("MAXDMG"))
- {
- uninitializedAbilities[uninitializedAbilities.Count - 1].SetItemBaseDamageLimit(item.Stats["MINDMG"], item.Stats["MAXDMG"]);
- }
- }
- }
- // NOT SURE IF THIS IS BEST WAY TO DO THIS
- if(uninitializedAbilities[uninitializedAbilities.Count - 1].abilityChargeUI != null)
- {
- uninitializedAbilities[uninitializedAbilities.Count - 1].abilityChargeUI.Initialize();
- switch(i)
- {
- case 0:
- case 1:
- uninitializedAbilities[uninitializedAbilities.Count - 1].abilityChargeUI.SetChargePosition(AbilityChargeUI.AbilityChargePosition.LEFT);
- break;
- case 2:
- uninitializedAbilities[uninitializedAbilities.Count - 1].abilityChargeUI.SetChargePosition(AbilityChargeUI.AbilityChargePosition.TOP);
- break;
- case 3:
- case 4:
- uninitializedAbilities[uninitializedAbilities.Count - 1].abilityChargeUI.SetChargePosition(AbilityChargeUI.AbilityChargePosition.RIGHT);
- break;
- }
- }
- }
- else
- {
- Debug.LogError ("Character has more abilities than ability slots!");
- Debug.Log(this.name);
- }
- }
- }
- protected virtual void INITIALIZING_Update()
- {
- if (abilities.Count >= uninitializedAbilities.Count)
- {
- uninitializedAbilities = new List<Ability>();
- if (onInitialized != null)
- {
- onInitialized(this);
- }
- }
- }
- protected virtual void INITIALIZING_Exit()
- {
- uninitializedAbilities.Clear();
- }
- #endregion
- #region SPAWNING State Callbacks
- protected virtual void SPAWNING_Enter()
- {
- transform.position = dock.transform.position;
- animator.Play("SpawnFromGround");
- }
- protected virtual void SPAWNING_Update()
- {
- }
- protected virtual void SPAWNING_Exit()
- {
- }
- #endregion
- #region ACTIVE State Callbacks
- protected virtual void ACTIVE_Enter()
- {
- //CharacterGreetingAudio
- MasterAudio.PlaySound (name +"Greeting");
- if (onMadeActive != null)
- {
- onMadeActive();
- }
- }
- protected virtual void ACTIVE_Update()
- {
- gameObject.transform.localScale = Vector3.Lerp(gameObject.transform.localScale, new Vector3(0.3f, 0.3f, 0.3f), Time.deltaTime * 5.0f);
- foreach (Ability ability in abilities)
- {
- ability.gameObject.transform.localScale = Vector3.Lerp(ability.gameObject.transform.localScale, new Vector3(0.07f, 0.07f, 0.07f), Time.deltaTime * 5.0f);
- }
- if (followFinger)
- {
- Vector3 v3 = Input.mousePosition;
- v3.z = 10.0f;
- v3 = Camera.main.ScreenToWorldPoint(v3);
- transform.position = new Vector3(v3.x, dock.transform.position.y, v3.z) + Vector3.up * 0.1f;
- }
- else
- {
- transform.position = Vector3.Slerp(transform.position, dock.transform.position, Time.deltaTime * snapSpeed);
- }
- }
- protected virtual void ACTIVE_Exit()
- {
- }
- #endregion
- #region INACTIVE State Callbacks
- protected virtual void INACTIVE_Enter()
- {
- }
- protected virtual void INACTIVE_Update()
- {
- transform.position = Vector3.Slerp(transform.position, dock.transform.position, Time.deltaTime * snapSpeed);
- gameObject.transform.localScale = Vector3.Lerp(gameObject.transform.localScale, new Vector3(0.15f, 0.15f, 0.15f), Time.deltaTime * 5.0f);
- foreach (Ability ability in abilities)
- {
- ability.gameObject.transform.localScale = Vector3.Lerp(ability.gameObject.transform.localScale, Vector3.zero, Time.deltaTime * 5.0f);
- }
- }
- protected virtual void INACTIVE_Exit()
- {
- }
- #endregion
- #region TARGETABLE State Callbacks
- protected virtual void TARGETABLE_Enter()
- {
- targetColor = new Color(targetColor.r + Globals.DIMMER_VALUE, targetColor.g + Globals.DIMMER_VALUE, targetColor.b + Globals.DIMMER_VALUE, targetColor.a);
- }
- protected virtual void TARGETABLE_Update()
- {
- }
- protected virtual void TARGETABLE_Exit()
- {
- targetColor = new Color(targetColor.r - Globals.DIMMER_VALUE, targetColor.g - Globals.DIMMER_VALUE, targetColor.b - Globals.DIMMER_VALUE, targetColor.a);
- }
- #endregion
- #region TARGETABLE State Callbacks
- protected virtual void UNTARGETABLE_Enter()
- {
- targetColor = new Color(targetColor.r - Globals.DIMMER_VALUE, targetColor.g - Globals.DIMMER_VALUE, targetColor.b - Globals.DIMMER_VALUE, targetColor.a);
- gameObject.GetComponent<Collider>().enabled = false;
- }
- protected virtual void UNTARGETABLE_Update()
- {
- }
- protected virtual void UNTARGETABLE_Exit()
- {
- targetColor = new Color(targetColor.r + Globals.DIMMER_VALUE, targetColor.g + Globals.DIMMER_VALUE, targetColor.b + Globals.DIMMER_VALUE, targetColor.a);
- gameObject.GetComponent<Collider>().enabled = true;
- }
- #endregion
- #region DEAD State Callbacks
- protected virtual void DEAD_Enter()
- {
- foreach (Ability ability in Ability.abilities)
- {
- ability.onSelectingTarget -= this.OnAbilitySelectingTarget;
- ability.onFinishedSelectingTarget -= this.OnAbilityFinishedSelectingTarget;
- }
- node.Vacate(this);
- gameObject.SetActive(false);
- }
- protected virtual void DEAD_Update()
- {
- }
- protected virtual void DEAD_Exit()
- {
- }
- #endregion
- #region LOOTING State Callbacks
- protected virtual void LOOTING_Enter()
- {
- }
- protected virtual void LOOTING_Update()
- {
- gameObject.transform.localScale = Vector3.Lerp(gameObject.transform.localScale, new Vector3(0.15f, 0.15f, 0.15f), Time.deltaTime * 5.0f);
- transform.position = Vector3.Slerp(transform.position, dock.transform.position, Time.deltaTime * snapSpeed);
- foreach (Ability ability in abilities)
- {
- ability.gameObject.transform.localScale = Vector3.Lerp(ability.gameObject.transform.localScale, Vector3.zero, Time.deltaTime * 5.0f);
- }
- }
- protected virtual void LOOTING_Exit()
- {
- }
- #endregion
- }
- public enum CharacterState{ NONE, INITIALIZING, SPAWNING, INACTIVE, ACTIVE, DEAD, TARGETABLE, UNTARGETABLE, CASTING, LOOTING}
Advertisement
Add Comment
Please, Sign In to add comment