264 lines
7.4 KiB
C#
264 lines
7.4 KiB
C#
using System.Collections;
|
|
using System.Collections.Generic;
|
|
using UnityEngine;
|
|
|
|
public class PirateCommand : MonoBehaviour
|
|
{
|
|
[Header("Ñïèñêè îáúåêòîâ êîìàíäû")]
|
|
public List<Pirate> pirates = new();
|
|
public List<AmmoCrate> ammoCrates = new();
|
|
public List<BoxingMachine> boxingMachines = new();
|
|
|
|
|
|
|
|
public PointsManager pointsManager;
|
|
|
|
[Header("Ññûëêà íà âðàæåñêóþ êîìàíäó")]
|
|
public EnemyCommand enemyTeam;
|
|
|
|
private void Start()
|
|
{
|
|
StartCoroutine(DanceRoutine());
|
|
StartCoroutine(BoxingRoutine());
|
|
StartCoroutine(ShootingRoutine());
|
|
}
|
|
|
|
public void ResetAllPiratesToHome()
|
|
{
|
|
foreach (var p in pirates)
|
|
if (p) p.ResetByIdleHome();
|
|
}
|
|
|
|
|
|
// ==========================================================
|
|
// Óíèâåðñàëüíûå ìåòîäû ôèëüòðàöèè è âûáîðà ïèðàòîâ
|
|
// ==========================================================
|
|
|
|
private List<Pirate> GetFreePirates(params System.Type[] busyTypes)
|
|
{
|
|
var freePirates = new List<Pirate>();
|
|
|
|
foreach (var p in pirates)
|
|
{
|
|
bool busy = false;
|
|
foreach (var t in busyTypes)
|
|
{
|
|
if (p.IsBusy(t))
|
|
{
|
|
busy = true;
|
|
break;
|
|
}
|
|
}
|
|
|
|
if (!busy)
|
|
freePirates.Add(p);
|
|
}
|
|
|
|
return freePirates;
|
|
}
|
|
|
|
private Pirate GetRandomPirate(List<Pirate> list)
|
|
{
|
|
if (list.Count == 0) return null;
|
|
return list[Random.Range(0, list.Count)];
|
|
}
|
|
|
|
// ==========================================================
|
|
// Ñòðåëüáà
|
|
// ==========================================================
|
|
private IEnumerator ShootingRoutine()
|
|
{
|
|
while (true)
|
|
{
|
|
float waitTime = Random.Range(5f, 10f);
|
|
yield return new WaitForSeconds(waitTime);
|
|
|
|
AssignRandomPirateToShoot();
|
|
}
|
|
}
|
|
|
|
public void AssignRandomPirateToShoot()
|
|
{
|
|
|
|
if (pointsManager == null || enemyTeam == null || enemyTeam.enemies.Count == 0) return;
|
|
|
|
var freePirates = GetFreePirates(typeof(PirateLoader), typeof(PirateDance), typeof(PirateBoxer), typeof(PirateShooter));
|
|
Pirate pirate = GetRandomPirate(freePirates);
|
|
if (pirate == null) return;
|
|
|
|
Transform shootPoint = null;
|
|
EnemyCombat targetEnemy = null;
|
|
int attempts = 10;
|
|
|
|
while (attempts-- > 0)
|
|
{
|
|
// ïîëó÷àåì ñëó÷àéíóþ ñâîáîäíóþ òî÷êó
|
|
shootPoint = pointsManager.GetRandomFreePoint("shoot", pointsManager.shootPoints);
|
|
if (shootPoint == null) return;
|
|
|
|
// èùåì àêòèâíîãî âðàãà, êîòîðîãî âèäíî ñ ýòîé òî÷êè
|
|
foreach (var enemy in enemyTeam.enemies)
|
|
{
|
|
if (enemy != null && enemy.IsActiveTarget() &&
|
|
pointsManager.HasLineOfSight(shootPoint, enemy.transform))
|
|
{
|
|
targetEnemy = enemy;
|
|
break;
|
|
}
|
|
}
|
|
|
|
if (targetEnemy != null)
|
|
break; // íàøëè ïîäõîäÿùóþ òî÷êó è âðàãà
|
|
|
|
// òî÷êà íå ïîäõîäèò, îñâîáîæäàåì
|
|
pointsManager.FreePoint("shoot", shootPoint);
|
|
shootPoint = null;
|
|
}
|
|
|
|
if (shootPoint == null || targetEnemy == null) return;
|
|
|
|
pirate.SetBehavior<PirateShooter>();
|
|
if (pirate.CurrentBehavior is PirateShooter shooter)
|
|
{
|
|
shooter.ActivateWithTarget(shootPoint, targetEnemy.gameObject, (point) =>
|
|
{
|
|
pointsManager.FreePoint("shoot", point);
|
|
});
|
|
}
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
// ==========================================================
|
|
// Áîêñ
|
|
// ==========================================================
|
|
private IEnumerator BoxingRoutine()
|
|
{
|
|
while (true)
|
|
{
|
|
float waitTime = Random.Range(10f, 20f);
|
|
yield return new WaitForSeconds(waitTime);
|
|
|
|
AssignRandomPirateToBox();
|
|
}
|
|
}
|
|
|
|
public void AssignRandomPirateToBox()
|
|
{
|
|
if (boxingMachines.Count == 0) return;
|
|
|
|
var freePirates = GetFreePirates(typeof(PirateLoader), typeof(PirateDance), typeof(PirateBoxer), typeof(PirateShooter));
|
|
Pirate pirate = GetRandomPirate(freePirates);
|
|
if (pirate == null) return;
|
|
|
|
BoxingMachine machine = boxingMachines[Random.Range(0, boxingMachines.Count)];
|
|
|
|
pirate.SetBehavior<PirateBoxer>();
|
|
if (pirate.CurrentBehavior is PirateBoxer boxer)
|
|
{
|
|
boxer.targetMachine = machine;
|
|
boxer.Activate();
|
|
|
|
|
|
}
|
|
}
|
|
|
|
// ==========================================================
|
|
// Òàíöû
|
|
// ==========================================================
|
|
private IEnumerator DanceRoutine()
|
|
{
|
|
while (true)
|
|
{
|
|
float waitTime = Random.Range(5f, 15f);
|
|
yield return new WaitForSeconds(waitTime);
|
|
|
|
AssignRandomPirateToDance();
|
|
}
|
|
}
|
|
|
|
public void AssignRandomPirateToDance()
|
|
{
|
|
var freePirates = GetFreePirates(typeof(PirateLoader), typeof(PirateDance), typeof(PirateShooter), typeof(PirateBoxer));
|
|
Pirate pirate = GetRandomPirate(freePirates);
|
|
if (pirate == null) return;
|
|
|
|
// Ïîëó÷àåì áëèæàéøóþ ñâîáîäíóþ òî÷êó äëÿ òàíöà
|
|
Transform dancePoint = pointsManager.GetNearestFreePoint("dance", pointsManager.dancePoints, pirate.transform.position);
|
|
if (dancePoint == null) return;
|
|
|
|
pirate.SetBehavior<PirateDance>();
|
|
|
|
if (pirate.CurrentBehavior is PirateDance dancer)
|
|
{
|
|
// Èíèöèàëèçàöèÿ òî÷êè è êîëáýêà, çàïóñêàåì Activate óæå ñ íóæíîé òî÷êîé
|
|
dancer.Init(dancePoint, (point) =>
|
|
{
|
|
pointsManager.FreePoint("dance", point);
|
|
});
|
|
}
|
|
}
|
|
|
|
|
|
// ==========================================================
|
|
// Çàãðóçêà ïóøåê
|
|
// ==========================================================
|
|
public Pirate GetNearestIdlePirate(Vector3 position)
|
|
{
|
|
Pirate nearest = null;
|
|
float minDist = float.MaxValue;
|
|
|
|
foreach (var pirate in pirates)
|
|
{
|
|
if (pirate.IsBusy<PirateLoader>()) continue;
|
|
|
|
float dist = Vector3.Distance(pirate.transform.position, position);
|
|
if (dist < minDist)
|
|
{
|
|
minDist = dist;
|
|
nearest = pirate;
|
|
}
|
|
}
|
|
|
|
return nearest;
|
|
}
|
|
|
|
public AmmoCrate GetNearestCrate(Vector3 position)
|
|
{
|
|
AmmoCrate nearest = null;
|
|
float minDist = float.MaxValue;
|
|
|
|
foreach (var crate in ammoCrates)
|
|
{
|
|
float dist = Vector3.Distance(crate.transform.position, position);
|
|
if (dist < minDist)
|
|
{
|
|
minDist = dist;
|
|
nearest = crate;
|
|
}
|
|
}
|
|
|
|
return nearest;
|
|
}
|
|
|
|
public void AssignPirateToCannon(Cannon cannon)
|
|
{
|
|
Pirate pirate = GetNearestIdlePirate(cannon.transform.position);
|
|
if (pirate == null) return;
|
|
|
|
AmmoCrate crate = GetNearestCrate(cannon.transform.position);
|
|
if (crate == null) return;
|
|
|
|
Transform approach = crate.GetNearestFreePosition(pirate.transform.position);
|
|
|
|
pirate.SetBehavior<PirateLoader>();
|
|
if (pirate.CurrentBehavior is PirateLoader loader)
|
|
{
|
|
loader.ActivateWithTarget(cannon, approach);
|
|
}
|
|
|
|
}
|
|
}
|