mirror of
https://github.com/ConjureETS/VZ.git
synced 2026-03-24 10:21:14 +00:00
380 lines
11 KiB
C#
380 lines
11 KiB
C#
using System;
|
|
using UnityEngine;
|
|
using System.Collections;
|
|
using System.Collections.Generic;
|
|
using System.Linq;
|
|
|
|
public class Squad : Unit
|
|
{
|
|
#region class members
|
|
public float TimeBetweenAttacks = 0.5f;
|
|
public string TeamTag;
|
|
|
|
/// <summary>
|
|
/// List of non attackable units.
|
|
/// </summary>
|
|
public List<Unit> Humans;
|
|
|
|
/// <summary>
|
|
/// List of attackable units.
|
|
/// </summary>
|
|
public List<Squad> Soldiers;
|
|
|
|
private bool _playerInRange;
|
|
private Squad _enemySquad;
|
|
private float _timer;
|
|
private float _squadMaxHealth;
|
|
|
|
/// <summary>
|
|
/// The tag to assign for each soldiers in the squad
|
|
/// </summary>
|
|
//protected String SquadTag;
|
|
private int _numberOfAliveSoldiers;
|
|
|
|
#endregion
|
|
|
|
#region Unity functions
|
|
// Use this for initialization
|
|
void Start ()
|
|
{
|
|
Humans = new List<Unit>();
|
|
Soldiers = new List<Squad>();
|
|
|
|
InitializeSquad();
|
|
InitializeDefaultTagAndLayer();
|
|
CurrentHP = ComputeRemainingHP();
|
|
// Debug.Log("Current Zomb HP " + CurrentHP);
|
|
Attack = ComputeAttackDamage();
|
|
_numberOfAliveSoldiers = ComputeNumberOfAliveSoldiers();
|
|
_enemySquad = null;
|
|
_timer = 0f;
|
|
}
|
|
|
|
// Update is called once per frame
|
|
void Update ()
|
|
{
|
|
CurrentHP = ComputeRemainingHP();
|
|
_squadMaxHealth = ComputeTotalHP();
|
|
|
|
HealthImage.fillAmount = (CurrentHP / _squadMaxHealth);
|
|
_numberOfAliveSoldiers = ComputeNumberOfAliveSoldiers();
|
|
|
|
_timer += Time.deltaTime;
|
|
|
|
if (_timer >= TimeBetweenAttacks && _playerInRange && !IsDead)
|
|
{
|
|
AttackEnemySquad(_enemySquad);
|
|
}
|
|
|
|
// TODO execute movement command
|
|
// TODO Check if all the units are dead
|
|
// if yes destroy
|
|
|
|
if (_numberOfAliveSoldiers > 0) return;
|
|
// first release all humans ...
|
|
AbandonUnits(Humans.Count);
|
|
IsDead = true;
|
|
}
|
|
|
|
void OnTriggerEnter(Collider collider)
|
|
{
|
|
if (IsDead) return;
|
|
|
|
var unitComponent = collider.GetComponent<Unit>();
|
|
|
|
if (unitComponent == null)
|
|
return;
|
|
// check if the unit is not a friendly one
|
|
if (this.Tag == unitComponent.Tag)
|
|
return;
|
|
|
|
if (unitComponent.Tag.Equals(TagLayerManager.Human))
|
|
{
|
|
if (unitComponent.IsCaptured)
|
|
{
|
|
return;
|
|
}
|
|
else
|
|
{
|
|
CaptureHuman(unitComponent);
|
|
}
|
|
}
|
|
else // we know that it's an enemy
|
|
{
|
|
if (unitComponent.IsDead)
|
|
return;
|
|
|
|
_playerInRange = true;
|
|
_enemySquad = collider.GetComponent<Squad>();
|
|
}
|
|
}
|
|
|
|
void OnTriggerExit(Collider collider)
|
|
{
|
|
if (collider.gameObject.tag == Tag || collider.gameObject.tag == TagLayerManager.Human)
|
|
return;
|
|
|
|
_playerInRange = false;
|
|
this.gameObject.GetComponent<CharacterBehavior>().PlayAttackAnimation(false);
|
|
_enemySquad = null;
|
|
}
|
|
|
|
#endregion
|
|
|
|
#region squad related functions
|
|
|
|
public int ComputeNumberOfAliveSoldiers()
|
|
{
|
|
// LINQ + Resharper FTW!!!!!
|
|
return Soldiers.Count(soldier => !soldier.IsDead);
|
|
}
|
|
|
|
/// <summary>
|
|
/// Assign the corresponding squad tag to each soldiers.
|
|
/// </summary>
|
|
protected void InitializeSquad()
|
|
{
|
|
if (Soldiers.Count == 0)
|
|
{
|
|
this.Soldiers.Add(this.gameObject.GetComponent<Squad>());
|
|
}
|
|
}
|
|
|
|
private void InitializeDefaultTagAndLayer()
|
|
{
|
|
try
|
|
{
|
|
if (this.TeamTag.Length == 0)
|
|
{
|
|
this.Tag = TagLayerManager.VampirePlayer;
|
|
this.Layer = TagLayerManager.VampireLayerIndex;
|
|
}
|
|
else
|
|
{
|
|
if (TeamTag.Equals(TagLayerManager.VampirePlayer))
|
|
{
|
|
this.Tag = TagLayerManager.VampirePlayer; // set the tag to player 1
|
|
this.Layer = TagLayerManager.VampireLayerIndex;
|
|
}
|
|
else
|
|
{
|
|
this.Tag = TagLayerManager.ZombiePlayer; // set the tag to player 2
|
|
this.Layer = TagLayerManager.ZombieLayerIndex;
|
|
}
|
|
}
|
|
}
|
|
catch (IndexOutOfRangeException ex)
|
|
{
|
|
Debug.LogError("Please set a vampire Tag, check the Tag & layers in the inspector!\n" + ex);
|
|
}
|
|
|
|
// set the tag and the layer of the gameObject to vampire
|
|
if (this.gameObject.tag != Tag)
|
|
{
|
|
this.gameObject.tag = Tag;
|
|
}
|
|
if (this.gameObject.layer != Layer)
|
|
{
|
|
this.gameObject.layer = Layer;
|
|
}
|
|
}
|
|
|
|
/// <summary>
|
|
/// Add the human unit in the humans unit list.
|
|
/// </summary>
|
|
/// <param name="humanUnit">the human unit to add in the human unit list</param>
|
|
void AddHuman(Unit humanUnit)
|
|
{
|
|
Humans.Add(humanUnit);
|
|
}
|
|
|
|
/// <summary>
|
|
/// Add the human unit in the abandoned unit list.
|
|
/// </summary>
|
|
/// <param name="soldierUnit">the soldier unit to add in the soldier unit list</param>
|
|
void AddSoldier(Squad soldierUnit)
|
|
{
|
|
soldierUnit.IsCaptured = false;
|
|
Soldiers.Add(soldierUnit);
|
|
}
|
|
|
|
/// <summary>
|
|
/// Dispose of a human unit and heal all the soldiers with a percentage depending
|
|
/// of the number of remaining soldiers.
|
|
/// </summary>
|
|
/// <param name="humanUnit">The human to dispose</param>
|
|
public void HealSquad(Unit humanUnit)
|
|
{
|
|
|
|
var percentageOfHpToHeal = ( humanUnit.CurrentHP / Soldiers.Count );
|
|
|
|
foreach (var soldier in Soldiers)
|
|
{
|
|
soldier.CurrentHP += soldier.CurrentHP * ( 1 + percentageOfHpToHeal );
|
|
}
|
|
|
|
humanUnit.GetComponent<CharacterBehavior>().PlayFetchedAnimation();
|
|
// dispose of the human unit
|
|
RemoveHuman(humanUnit);
|
|
}
|
|
|
|
/// <summary>
|
|
/// Abandon a specified amount of units.
|
|
/// </summary>
|
|
/// <param name="nbUnits">The number of units to abandon</param>
|
|
public void AbandonUnits(int nbUnits)
|
|
{
|
|
if (nbUnits <= Humans.Count)
|
|
{
|
|
for (var i = 0; i < nbUnits; i++)
|
|
{
|
|
// retrieve the human at the specified index
|
|
var humanUnit = Humans.ElementAt(i);
|
|
// reassign the human attributes
|
|
humanUnit.Tag = TagLayerManager.Human;
|
|
humanUnit.Layer = TagLayerManager.HumanLayerIndex;
|
|
humanUnit.gameObject.GetComponent<Rigidbody>().useGravity = true;
|
|
|
|
// add the human to the abandoned Unit list
|
|
humanUnit.IsCaptured = false;
|
|
Debug.Log(string.Format("{0} has abandoned the unit {1}", this.gameObject.name, humanUnit.gameObject.name));
|
|
|
|
// remove the human from the humandUnit that was added to the abandoned unit list
|
|
RemoveHuman(humanUnit);
|
|
}
|
|
}
|
|
else
|
|
{
|
|
Debug.LogError("Exceeded the maximum numbers of units in the humans list!");
|
|
}
|
|
}
|
|
|
|
/// <summary>
|
|
/// Remove the selected soldier from the unit list.
|
|
/// </summary>
|
|
/// <param name="soldierUnit">the corresponding soldier that we want to remove</param>
|
|
void RemoveSoldier(Squad soldierUnit)
|
|
{
|
|
Soldiers.Remove(soldierUnit);
|
|
}
|
|
|
|
/// <summary>
|
|
/// Remove the selected human from the human list.
|
|
/// </summary>
|
|
/// <param name="humanUnit">the corresponding human that we want to remove</param>
|
|
void RemoveHuman(Unit humanUnit)
|
|
{
|
|
Humans.Remove(humanUnit);
|
|
}
|
|
|
|
/// <summary>
|
|
/// Transform the human to the corresponding type of the squad.
|
|
/// </summary>
|
|
/// <param name="nbHumans">the number of humans to transform</param>
|
|
public void TransformHuman(int nbHumans)
|
|
{
|
|
if (nbHumans <= Humans.Count)
|
|
{
|
|
for (var i = 0; i < nbHumans; i++)
|
|
{
|
|
// retrieve the human at the specified index
|
|
var humanUnit = Humans.ElementAt(i);
|
|
|
|
// remove the human from the human list
|
|
RemoveHuman(humanUnit);
|
|
|
|
// set the human tag to the same as the squad
|
|
humanUnit.Tag = Tag;
|
|
|
|
AddSoldier(humanUnit as Squad);
|
|
}
|
|
}
|
|
else
|
|
{
|
|
Debug.LogError("Exceeded the maximum number of humans in the humans list!");
|
|
}
|
|
|
|
}
|
|
|
|
public void ReceiveDamage(float amountOfDamage)
|
|
{
|
|
// apply the damage to the first soldier in the list
|
|
foreach (var soldier in Soldiers)
|
|
{
|
|
//soldier.CurrentHP -= amountOfDamage;
|
|
soldier.TakeDamage(amountOfDamage);
|
|
Debug.Log(string.Format("{0} received {1} damage!", soldier.name, amountOfDamage));
|
|
Debug.Log(string.Format("{0} remaining hp : {1}", soldier.name, soldier.CurrentHP));
|
|
}
|
|
}
|
|
|
|
protected void CaptureHuman(Unit unit)
|
|
{
|
|
// set the position of the squad as a target, so that
|
|
// the unit would always follow the squad leader
|
|
unit.TargetDestination = this.transform;
|
|
// specify that the unit is captured to that the captured animation plays at the next update.
|
|
unit.IsCaptured = true;
|
|
// add the caught human in the caught list.
|
|
AddHuman(unit);
|
|
|
|
Debug.Log(string.Format("{0} joined the squad of : {1} ", unit.gameObject.name, transform.gameObject.name));
|
|
}
|
|
|
|
protected void AttackEnemySquad(Squad targettedEnemySquad)
|
|
{
|
|
_timer = 0f;
|
|
|
|
if (targettedEnemySquad.CurrentHP > 0)
|
|
{
|
|
foreach (var soldier in Soldiers)
|
|
{
|
|
soldier.GetComponent<CharacterBehavior>().PlayAttackAnimation(true);
|
|
}
|
|
|
|
targettedEnemySquad.ReceiveDamage(ComputeAttackDamage());
|
|
Debug.Log(string.Format("{0} Attacked the enemy : {1} ", this.gameObject.name, targettedEnemySquad.gameObject.name));
|
|
}
|
|
else
|
|
{
|
|
foreach (var soldier in Soldiers)
|
|
{
|
|
soldier.GetComponent<CharacterBehavior>().PlayAttackAnimation(false);
|
|
}
|
|
}
|
|
}
|
|
|
|
/// <summary>
|
|
/// Compute to attack damage depending of the numbers of soldiers in the squad.
|
|
/// </summary>
|
|
/// <returns>the damage to apply to each enemy soldiers units</returns>
|
|
protected float ComputeAttackDamage()
|
|
{
|
|
// LINQ + Resharper FTW!!!!!
|
|
var sumOfAttack = Soldiers.Sum(soldier => soldier.Attack);
|
|
|
|
return ( 1 + (sumOfAttack / Soldiers.Count));
|
|
}
|
|
|
|
protected float ComputeRemainingHP()
|
|
{
|
|
var sumOfHp = Soldiers.Sum(x => x.CurrentHP);
|
|
|
|
return sumOfHp;
|
|
}
|
|
|
|
protected float ComputeTotalHP()
|
|
{
|
|
var sumOfHp = Soldiers.Sum(x => x.MaxHealth);
|
|
|
|
return sumOfHp;
|
|
}
|
|
|
|
#endregion
|
|
|
|
#region squad accessors and mutators
|
|
|
|
#endregion
|
|
|
|
}
|