Scriptum/Assets/Scripts/REFACTORING/Story/Thugs/ThugNPCFollowing.cs

370 lines
10 KiB
C#
Raw Normal View History

using System;
using System.Collections;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using UnityEngine;
[RequireComponent(typeof(NPC))]
[RequireComponent(typeof(Enemy))]
public class ThugNPCFollowing : MonoBehaviour
{
public const string ACTION_KEY = "ATTACKING";
private Rigidbody2D myRigidbody;
public Animator anim;
private Vector2 movement;
public bool shouldRotate;
public Vector3 dir;
[Header("Following Logic")]
public Vector3 homePosition;
public Transform targetPosition;
public AStarPathfindingAgent agent;
public bool isDuringFollowing = false; // var is setted by trigger range
//public GameObject player;
[Header("Core Logic")]
public bool approaching = false;
public bool isAfterAction = false;
public float chasingRadius = 6f; // radious where Npc start attacking ! ! !
[Header("Attacking Logic")] // TRASH - dupplicated from Following Enemy - move params to Enemy
public float attackingRadius = 1.5f; // radious where Npc start attacking ! ! !
public bool hit = false;
public bool firstAttack = false;
public float timerDmg = 0f;
public float waitTime = 1.0f;
public float timerHit = 0f;
public float hitWaitTime = 0.55f;
public float expValue;
public float thrust;
public float knockTime;
//public int isKilled; - movet do Enemy
//isKilled = 0 - mob ALIVE
//isKilled = 1 - mob DEAD
public int isKilled2;
public bool isPanelEnabled = true;
void Awake()
{
agent = GetComponent<AStarPathfindingAgent>();
homePosition = new Vector3(gameObject.transform.position.x, gameObject.transform.position.y, gameObject.transform.position.z);
}
// Start is called before the first frame update
void Start()
{
targetPosition = GameObject.FindWithTag("Player").transform;
//Copy from Eollwoing
if (OnMapAppearanceMethod.IsNewGame())
{
gameObject.GetComponent<Enemy>().isKilled = 0;
}
if (gameObject.GetComponent<Enemy>().health <= 0)
gameObject.GetComponent<Enemy>().isKilled = 1;
else // Else read saved value
gameObject.GetComponent<Enemy>().isKilled = PlayerPrefs.GetInt(gameObject.GetComponent<Enemy>().enemyName + "-S");
if (gameObject.GetComponent<Enemy>().isKilled == 1)
{
gameObject.SetActive(false);
gameObject.GetComponent<Enemy>().isKilled = 0;
}
myRigidbody = GetComponent<Rigidbody2D>();
anim = GetComponent<Animator>();
}
// Update is called once per frame
public void Update()
{
// 0 Cofigure Animator
if (Vector2.Distance(targetPosition.position, transform.position) <= chasingRadius)
{
Debug.Log("Chase");
dir = targetPosition.position - transform.position;
float angle = Mathf.Atan2(dir.y, dir.x) * Mathf.Rad2Deg;
dir.Normalize();
movement = dir;
anim.SetBool("isRunning", movement != Vector2.zero);
Debug.Log(shouldRotate);
if (shouldRotate)
{
anim.SetFloat("Xinfo", dir.x);
anim.SetFloat("Yinfo", dir.y);
}
}
// 1. Check range and decide which action do
// Following player detection
if (IsInChassingRadious())
{
// 2'nd state alow us to brak going to hom,e action to follow player again
if (gameObject.GetComponent<NPC>().State == NPCStateEnum.Pending || gameObject.GetComponent<NPC>().State == NPCStateEnum.Walking)
{
approaching = true;
gameObject.GetComponent<NPC>().State = NPCStateEnum.Walking;
}
} else
{
// Turn around and go to home position
if (approaching)
{
approaching = false;
2023-01-05 13:24:58 +01:00
anim.SetBool("isRunning", true);
gameObject.GetComponent<NPC>().State = NPCStateEnum.Walking;
}
}
// 2.Take action based on conditions around
HandleState();
// 3.
// COPIED FROM Following Enemy scripts
// Taking hit logic
timerHit += Time.deltaTime;
if (hit == true)
{
if (timerHit >= hitWaitTime)
{
TakeDamage(PlayerPrefs.GetFloat("attackValue"));
hit = false;
timerHit = 0f;
TakeKnockback();
}
}
// Detecting "is alive" logic
if (gameObject.active == false)
{
gameObject.GetComponent<Enemy>().isKilled = 1;
PlayerPrefs.SetInt(gameObject.GetComponent<Enemy>().enemyName, gameObject.GetComponent<Enemy>().isKilled);
}
}
public void CheckDistance()
{
StopAllCoroutines();
// isDuringFollowing - avr is setted by trigger range
if (approaching && !IsInActionRadious())
{
agent.FindPath();
StartCoroutine(agent.FollowPath());
}
else if (approaching)
{
// in this script we set attacking mode
SetActionAfterMetConditions();
agent.path.Clear(); // if we are able to talgk we dont want go go further player
}
else if (!approaching)
{
if (Vector2.Distance(transform.position, homePosition) > 0.8f) // cont vale - path finding stop moving them before reachin position well..
{
agent.point = homePosition;
agent.FindPoint();
StartCoroutine(agent.FollowPath());
}
else
{
2023-01-05 13:24:58 +01:00
anim.SetBool("isRunning", false);
gameObject.GetComponent<NPC>().State = NPCStateEnum.Pending;
2023-01-05 13:24:58 +01:00
}
}
}
#region Taking damage from Player detection
public void OnTriggerEnter2D(Collider2D collision)
{
// Hit logic
if (collision.gameObject.tag == "AttackHitbox" || collision.gameObject.tag == "PickaxeHitbox")
{
hit = true;
}
}
public void OnTriggerExit2D(Collider2D other)
{
// Hit logic
if (other.tag == "AttackHitbox" || other.tag == "PickaxeHitbox")
{
timerDmg = 0f;
hit = false;
}
}
#endregion
public void HandleState()
{
switch (gameObject.GetComponent<NPC>().State)
{
case NPCStateEnum.Walking:
{
CheckDistance();
break;
}
case NPCStateEnum.Talking:
{
TalkingAction();
break;
}
case NPCStateEnum.Pending:
{
break;
}
case NPCStateEnum.Attacking:
{
AttackingAction();
break;
}
default:
{
Debug.Log("Nieopisane zachowanie NPC ! ! !");
break;
}
}
}
public bool IsInChassingRadious()
{
if (Vector2.Distance(targetPosition.position, transform.position) >= chasingRadius)
return false;
return true;
}
public bool IsInActionRadious()
{
if (Vector2.Distance(targetPosition.position, transform.position) >= attackingRadius)
return false;
return true;
}
public void SetActionAfterMetConditions()
{
gameObject.GetComponent<NPC>().State = NPCStateEnum.Attacking;
}
public void TalkingAction()
{
// Not required in this script
}
public void AttackingAction()
{
// if during Attacking mode player GO OUT of the attacking radious
if(!IsInActionRadious())
{
gameObject.GetComponent<NPC>().State = NPCStateEnum.Walking;
return;
}
// Attacking logic
if (firstAttack == false)
{
if (timerDmg >= 0.15f)
{
firstAttack = true;
GameObject.FindGameObjectWithTag("Player").GetComponent<Player>().TakeDamage(
gameObject.GetComponent<Enemy>().baseAttack,
isPanelEnabled
);
timerDmg = 0f;
}
}
if (timerDmg >= waitTime)
{
timerDmg = 0f;
GameObject.FindGameObjectWithTag("Player").GetComponent<Player>().TakeDamage(
gameObject.GetComponent<Enemy>().baseAttack,
isPanelEnabled
);
}
timerDmg += Time.deltaTime;
}
#region dupplicated from Following :)
public void TakeDamage(float damage)
{
Debug.Log("TakeDamage");
gameObject.GetComponent<Enemy>().health -= damage;
if (gameObject.GetComponent<Enemy>().health <= 0)
{
gameObject.SetActive(false);
gameObject.GetComponent<Enemy>().isKilled = 1;
GameObject.FindGameObjectWithTag("Player").GetComponent<Player>().GetExp(expValue);
// pass info about killing assigned enemy to mission manager listener
// pass enemy name from script NOT object name (thats allow to have many different objects variantsa with this same aggregate key (private name - not preffab name) )
ConditionManager.Instance.UpdateKillCondition(gameObject.GetComponent<Enemy>().MinionName);
}
}
public void TakeKnockback()
{
Rigidbody2D enemy = gameObject.GetComponent<Rigidbody2D>();
Rigidbody2D player = GameObject.FindGameObjectWithTag("Player").GetComponent<Rigidbody2D>();
if (enemy != null)
{
enemy.isKinematic = false;
Vector2 difference = enemy.transform.position - player.transform.position;
difference = difference.normalized * thrust;
enemy.AddForce(difference, ForceMode2D.Impulse);
//StartCoroutine(KnockCo(enemy));
}
}
#endregion
public void AfterAction()
{
approaching = false;
isAfterAction = true;
//isDuringConversation = false;
//PlayerPrefs.SetInt(gameObject.name + ".FirstDialogue", System.Convert.ToInt32(isAfterAction));
gameObject.GetComponent<NPC>().State = NPCStateEnum.Walking;
}
}