You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
 
 
 
 
 
 

550 lines
18 KiB

using System;
using System.Collections.Generic;
using Ai;
using UnityEngine;
using Ability;
using Dialogs;
using Equip;
using Game;
using Meta;
using Player;
using TMPro;
using UnityEngine.SceneManagement;
using Utils;
public enum CharacterState
{
DEFAULT,
MOVE_STATE,
}
public class MainCharacter : MonoBehaviour
{
GameBoard m_gameBoard = null;
CharacterState m_state = CharacterState.DEFAULT;
[SerializeField] GameObject[] _skinObj;
[SerializeField] Material _racconSkin;
[SerializeField] Material _foxSkin;
[SerializeField] Material _skunkSkin;
[SerializeField] float m_speed = 2;
[SerializeField] int m_startHealth = 500;
[SerializeField] Rigidbody m_rigidbody;
[SerializeField] private MainCharacter m_self;
[Header("Animations")]
[SerializeField] private Animator[] m_characterAnimator;
[SerializeField] private string m_runName;
[SerializeField] private string m_shootName;
[SerializeField] private string m_deathName;
[Header("Shooting Mechanics")]
[SerializeField] private Shooting m_shooting;
[SerializeField] private ShootingManager m_shootingManager;
[Header("Other Stuff")]
[SerializeField] private HealthBar m_bar;
[SerializeField] private TextMeshPro m_health;
public static int MCurrentHealth = -1;
public static Vector3 MCurrentPosition = Vector3.zero;
public static int MMaxHealth = -1;
public static bool MainAbilityApplied;
public static bool Respawned;
float m_slowMult = 1f;
float m_timeToSpikesDamege = 0f;
bool m_isDead = false;
bool m_needUpdateSpikesDmg = false;
Vector3 m_moveDir = new Vector3(0, 0, 1);
Vector3 m_dirDotStartPos;
List<GameObstacles> m_triggeredObstacles = new List<GameObstacles>();
private Animator m_currentAnimator;
public static readonly Dictionary<InGameAbType, InGameAbInfo> MInGameAb = new Dictionary<InGameAbType, InGameAbInfo>();
public static bool Equipped;
//-----------------------------------------------------------------------------------------
private void OnEnable()
{
if (SceneManager.GetActiveScene().name != "MainMenu")
{
if (MMaxHealth < 0)
MMaxHealth = m_startHealth;
AiController.Instance.Player = this;
PlayerResources.Instance.Player = this;
}
Repaint();
}
public void Repaint()
{
SetCurrentSkin();
Equip();
}
//-----------------------------------------------------------------------------------------
private void SetCurrentSkin()
{
PlayerResources.Instance.SkinExp = 0;
Material mat = _racconSkin;
SkinType type = GlobalsVar.gUser.CurrentSkin;
if (type == SkinType.RACCOON)
mat = _racconSkin;
else if (type == SkinType.FOX)
{
mat = _foxSkin;
PlayerResources.Instance.SkinExp = 0.1f;
}
else if (type == SkinType.SKUNK)
{
mat = _skunkSkin;
if (MCurrentHealth > 0)
MCurrentHealth = Mathf.Min(MMaxHealth, MCurrentHealth + 50);
}
foreach (var obj in _skinObj)
{
obj.GetComponent<SkinnedMeshRenderer>().material = mat;
}
}
//-----------------------------------------------------------------------------------------
private void Equip()
{
var items = EquipSettings.GetItems();
if (m_currentAnimator != null)
m_currentAnimator.gameObject.SetActive(false);
m_currentAnimator = m_characterAnimator[0];
m_currentAnimator.gameObject.SetActive(true);
m_shootingManager.SetShoota(0);
foreach (var item in items)
{
if (item.WeaponType != WeaponType.Gun)
{
m_currentAnimator.gameObject.SetActive(false);
m_currentAnimator = m_characterAnimator[(int) item.WeaponType];
m_currentAnimator.gameObject.SetActive(true);
m_shootingManager.SetShoota((int) item.WeaponType);
}
if (!Equipped && SceneManager.GetActiveScene().name != "MainMenu")
{
MMaxHealth += (int)item.AddHp;
}
m_shootingManager.ApplyEquip(item);
}
Equipped = true;
}
//-----------------------------------------------------------------------------------------
public void Init()
{
MCurrentPosition = transform.position;
PlayerResources.Instance.Repaint();
foreach (KeyValuePair<InGameAbType, InGameAbInfo> ability in MInGameAb)
ApplyAbility(ability.Key, ability.Value);
foreach (MainAbilityType mainAbType in Enum.GetValues(typeof(MainAbilityType)))
ApplyMainAb(mainAbType);
MainAbilityApplied = true;
m_shootingManager.ShootEvent += OnShoot;
SetHealthProgress();
}
//-----------------------------------------------------------------------------------------
void OnShoot()
{
if (GlobalsVar.gBoard.DialogsCount > 0)
return;
m_currentAnimator.SetTrigger(m_shootName);
PlayShotSound();
}
//-----------------------------------------------------------------------------------------
private void PlayShotSound()
{
List<EquipItem> weapon = EquipSettings.GetItems();
string shotName = "";
if (weapon[0].WeaponType == WeaponType.Gun)
shotName = "shot_revolver";
else if (weapon[0].WeaponType == WeaponType.Auto)
shotName = "shot_rifle";
else if (weapon[0].WeaponType == WeaponType.Shotgun)
shotName = "shot_shotgun";
else if (weapon[0].WeaponType == WeaponType.Rocket)
shotName = "shot_bazuka";
SoundsManager.Instance.PlaySound(shotName);
}
//-----------------------------------------------------------------------------------------
public GameBoard GameBoard
{
set { m_gameBoard = value; }
}
//-----------------------------------------------------------------------------------------
public bool IsDead
{
get { return m_isDead; }
}
//-----------------------------------------------------------------------------------------
public Dictionary<InGameAbType, InGameAbInfo> InGameAb
{
get { return MInGameAb; }
}
//-----------------------------------------------------------------------------------------
public bool NeedRollAb(InGameAbType type)
{
if (MInGameAb.ContainsKey(type))
{
if (MInGameAb[type].m_lvlUp < MInGameAb[type].m_maxLvlUp)
return true;
else
return false;
}
return true;
}
//-----------------------------------------------------------------------------------------
public void AddAbility(InGameAbType type)
{
if (MInGameAb.ContainsKey(type))
{
MInGameAb[type].m_lvlUp++;
}
else
{
if (GlobalsVar.gInGameAbilities == null)
{
GlobalsVar.gInGameAbilities = new InGameAbilities();
GlobalsVar.gInGameAbilities.Init();
}
InGameAbInfo info = GlobalsVar.gInGameAbilities.GetAbilityInfoByType(type);
if (type != InGameAbType.ADD_HEALTH && type != InGameAbType.HEAL && type != InGameAbType.DECAY &&
type != InGameAbType.ADD_DROP_GOLD && type != InGameAbType.ADD_XP)
MInGameAb.Add(type, info);
ApplyAbility(type, info);
}
}
//-----------------------------------------------------------------------------------------
private void ApplyAbility(InGameAbType type, InGameAbInfo info)
{
m_shootingManager.AddAbility(type, info.m_value);
switch (type)
{
case InGameAbType.ADD_XP:
PlayerResources.Instance.ExpMult += info.m_value;
break;
case InGameAbType.ADD_DROP_GOLD:
PlayerResources.Instance.CoinsMult += info.m_value;
break;
case InGameAbType.ADD_HEALTH:
MCurrentHealth += (int) info.m_value;
FlyingText.Init((int) info.m_value, FlyingText.State.Heal, transform.position);
MMaxHealth += (int) info.m_value;
SetHealthProgress();
break;
case InGameAbType.HEAL:
var healValue = Mathf.Min(MMaxHealth, MCurrentHealth + (int) (MMaxHealth * 0.3f));
if (MCurrentHealth != healValue)
FlyingText.Init(healValue - MCurrentHealth, FlyingText.State.Heal, transform.position);
MCurrentHealth = healValue;
SetHealthProgress();
break;
case InGameAbType.DECAY:
var decayValue = Mathf.Max(1, MCurrentHealth - (int) (MMaxHealth * 0.2f));
if (MCurrentHealth != decayValue)
FlyingText.Init(-(MCurrentHealth - decayValue), FlyingText.State.Danger, transform.position);
MCurrentHealth = decayValue;
SetHealthProgress();
break;
}
}
//-----------------------------------------------------------------------------------------
private void ApplyMainAb(MainAbilityType type)
{
float mainAbValue = GlobalsVar.gMainAbilities.GetAbilityValueByType(type);
m_shootingManager.AddMainAbility(type, mainAbValue);
switch (type)
{
case MainAbilityType.ADD_EQUIP:
if (!MainAbilityApplied)
PlayerResources.Instance.EquipChance += mainAbValue;
break;
case MainAbilityType.ADD_DROP_GOLD:
if (!MainAbilityApplied)
PlayerResources.Instance.CoinsMult += mainAbValue;
break;
case MainAbilityType.ADD_HEALTH:
if (!MainAbilityApplied)
MMaxHealth += (int)mainAbValue;
if (MCurrentHealth < 0)
MCurrentHealth = MMaxHealth;
break;
}
}
//-----------------------------------------------------------------------------------------
void SetHealthProgress()
{
float progress = MCurrentHealth / (float)MMaxHealth;
if (progress > 1f)
progress = 1f;
else if (progress < 0f)
progress = 0f;
m_health.text = MCurrentHealth.ToString();
m_bar.SetPercent(progress);
}
//-----------------------------------------------------------------------------------------
public void TakeDamage(int damage)
{
if (m_isDead)
return;
SoundsManager.Instance.PlaySound("damage");
MCurrentHealth -= damage;
FlyingText.Init(-damage, FlyingText.State.Normal, transform.position);
SetHealthProgress();
if (MCurrentHealth <= 0)
{
m_isDead = true;
if (m_gameBoard != null)
{
m_gameBoard.SetStickDefault();
m_gameBoard.StopRunSound();
}
m_currentAnimator.SetTrigger(m_deathName);
LeanTween.delayedCall(2f,
() =>
{
if (Respawned)
{
GameObject dlg = m_gameBoard.StartDialog("EndRunDialog");
dlg.GetComponent<EndRunDialog>().Init();
}
else
{
GameObject dlg = m_gameBoard.StartDialog("AfterDeathDialog");
dlg.GetComponent<AfterDeathDialog>().Init();
Respawned = true;
}
});
}
}
//-----------------------------------------------------------------------------------------
public void SetState(CharacterState state)
{
if (state != m_state)
{
m_currentAnimator.SetBool(m_runName, state == CharacterState.MOVE_STATE);
m_state = state;
if (state == CharacterState.DEFAULT)
m_shootingManager.ShootPermamently();
}
m_state = state;
}
//-----------------------------------------------------------------------------------------
public CharacterState GetState()
{
return m_state;
}
//-----------------------------------------------------------------------------------------
public void SetDir(Vector3 dir, float arrowYScale)
{
m_moveDir = dir;
if (dir == Vector3.zero)
return;
dir.y = dir.z;
dir.z = 0;
float angle = Vector3.Angle(dir, new Vector3(0, 1, 0));
if (dir.x < 0)
angle = -angle;
Vector3 characterAngle = transform.eulerAngles;
characterAngle.y = angle;
transform.eulerAngles = characterAngle;
}
//-----------------------------------------------------------------------------------------
void FixedUpdate ()
{
if (m_isDead)
return;
if (m_state == CharacterState.MOVE_STATE)
UpdateMoveState();
UpdateSpikesDamage();
}
//-----------------------------------------------------------------------------------------
void UpdateSpikesDamage()
{
if (!m_needUpdateSpikesDmg)
return;
GameObstacles obst = GetTriggeredObstacleByType(GameObstaclesType.SPIKES_FLOOR);
m_timeToSpikesDamege -= Time.deltaTime;
if (m_timeToSpikesDamege <= 0f)
{
m_timeToSpikesDamege = obst.TimeToDamage;
float abilityVal = GlobalsVar.gMainAbilities.GetAbilityValueByType(Ability.MainAbilityType.ADD_ARMOR_COLLISION_TRAP);
abilityVal /= 100f;
float damage = obst.SpikesDamage - obst.SpikesDamage * abilityVal;
TakeDamage(obst.SpikesDamage);
}
}
//-----------------------------------------------------------------------------------------
void UpdateMoveState()
{
m_rigidbody.MovePosition(m_rigidbody.position + m_moveDir * (m_speed * Time.deltaTime * m_slowMult));
}
//-----------------------------------------------------------------------------------------
void OnCollisionEnter(Collision collision)
{
GameObstacles gameObst = collision.gameObject.GetComponent<GameObstacles>();
if (gameObst)
{
}
}
//-----------------------------------------------------------------------------------------
void OnTriggerEnter(Collider other)
{
GameObstacles gameObst = other.gameObject.GetComponent<GameObstacles>();
if (gameObst)
{
if (gameObst.Type == GameObstaclesType.SLOW_FLOOR)
{
m_slowMult = gameObst.SlowMult;
if (!m_triggeredObstacles.Contains(gameObst))
m_triggeredObstacles.Add(gameObst);
}
else if (gameObst.Type == GameObstaclesType.SPIKES_FLOOR)
{
m_needUpdateSpikesDmg = true;
if (!m_triggeredObstacles.Contains(gameObst))
m_triggeredObstacles.Add(gameObst);
}
}
else
{
if (other.gameObject.name == "active_laser_part")
{
GameObstacles laserObst = other.transform.parent.GetComponent<GameObstacles>();
float abilityVal = GlobalsVar.gMainAbilities.GetAbilityValueByType(Ability.MainAbilityType.ADD_ARMOR_COLLISION_TRAP);
abilityVal /= 100f;
float damage = laserObst.LaserDamage - laserObst.LaserDamage * abilityVal;
TakeDamage((int)damage);
}
}
}
//-----------------------------------------------------------------------------------------
void OnTriggerExit(Collider other)
{
GameObstacles gameObst = other.gameObject.GetComponent<GameObstacles>();
if (gameObst)
{
if (gameObst.Type == GameObstaclesType.SLOW_FLOOR)
{
m_triggeredObstacles.Remove(gameObst);
if (GetOtherCollisionsCountByType(gameObst.Type) == 0)
m_slowMult = 1f;
}
else if (gameObst.Type == GameObstaclesType.SPIKES_FLOOR)
{
m_triggeredObstacles.Remove(gameObst);
if (GetOtherCollisionsCountByType(gameObst.Type) == 0)
m_needUpdateSpikesDmg = false;
}
}
}
//-----------------------------------------------------------------------------------------
int GetOtherCollisionsCountByType( GameObstaclesType type )
{
int collisionsCount = 0;
for (int i = 0; i < m_triggeredObstacles.Count; ++i)
{
if (m_triggeredObstacles[i].Type == type)
collisionsCount++;
}
return collisionsCount;
}
//-----------------------------------------------------------------------------------------
GameObstacles GetTriggeredObstacleByType(GameObstaclesType type)
{
for (int i = 0; i < m_triggeredObstacles.Count; ++i)
{
if (m_triggeredObstacles[i].Type == type)
return m_triggeredObstacles[i];
}
CommonFunctions.myassert(false);
return null;
}
public static void Clear()
{
MInGameAb.Clear();
MCurrentHealth = -1;
MMaxHealth = -1;
MainAbilityApplied = false;
Respawned = false;
Equipped = false;
}
public void Reload()
{
MCurrentHealth = -1;
var character = Instantiate(m_self);
Destroy(gameObject);
character.transform.position = MCurrentPosition;
GameBoard.Instance.InitMainCharacter(character);
}
}