using System.Collections.Generic; using Pathfinding; using Rewired; using UnityEngine; public class CommandUnits : MonoBehaviour { public static CommandUnits instance; public UnitCommandRadiusAnimation rangeIndicator; public GameObject commandingIndicator; public ParticleSystem dropWaypointFx; public int drowWaypointParticleCount = 100; public float attractRange; public string graphNameOfPlayerUnits; public float unitDistanceFromEachOther = 2f; public float unitDistanceMoveStep = 0.5f; public int maxPositioningRepeats = 5; public float holdToHoldPositionTime = 1f; private ThronefallAudioManager audioManager; private AudioSet audioSet; private NNConstraint nearestConstraint = new NNConstraint(); private List playerUnitsCommanding = new List(); private List playerUnitsCommandingBuffer = new List(); private Player input; [HideInInspector] public bool commanding; private TagManager tagManager; private AstarPath astarPath; private PlayerUpgradeManager playerUPgradeManager; private Hp hpPlayer; private float timeSincePlace; private bool switchedToHold; private List autoAttacksToEnable = new List(); private void Awake() { instance = this; } private void Start() { audioManager = ThronefallAudioManager.Instance; audioSet = audioManager.audioContent; input = ReInput.players.GetPlayer(0); tagManager = TagManager.instance; astarPath = AstarPath.active; nearestConstraint.graphMask = GraphMask.FromGraphName(graphNameOfPlayerUnits); playerUPgradeManager = PlayerUpgradeManager.instance; hpPlayer = GetComponent(); } private void Update() { if (!commanding) { if (input.GetButtonDown("Command Units")) { rangeIndicator.Activate(); } if (input.GetButton("Command Units") && hpPlayer.HpValue > 0f) { foreach (TaggedObject playerUnit in TagManager.instance.PlayerUnits) { if (tagManager.MeasureDistanceToTaggedObject(playerUnit, base.transform.position) <= attractRange) { OnUnitAdd(playerUnit); } } } else if (playerUnitsCommanding.Count > 0) { commanding = true; } } else { if (input.GetButtonDown("Command Units") || hpPlayer.HpValue <= 0f) { PlaceCommandedUnitsAndCalculateTargetPositions(); timeSincePlace = 0f; switchedToHold = false; } if (input.GetButton("Command Units") && hpPlayer.HpValue > 0f) { timeSincePlace += Time.deltaTime; if (timeSincePlace > holdToHoldPositionTime && !switchedToHold) { switchedToHold = true; MakeUnitsInBufferHoldPosition(); } } if (input.GetButtonUp("Command Units") || hpPlayer.HpValue <= 0f) { commanding = false; timeSincePlace = 0f; } } for (int num = playerUnitsCommanding.Count - 1; num >= 0; num--) { PathfindMovementPlayerunit pathfindMovementPlayerunit = playerUnitsCommanding[num]; pathfindMovementPlayerunit.HomePosition = base.transform.position; if (!pathfindMovementPlayerunit.enabled) { playerUnitsCommanding.RemoveAt(num); OnUnitRemove(pathfindMovementPlayerunit); } } if (playerUnitsCommanding.Count > 0 && !input.GetButton("Command Units")) { commandingIndicator.SetActive(value: true); } else { commandingIndicator.SetActive(value: false); } if (!input.GetButton("Command Units") && rangeIndicator.Active) { rangeIndicator.Deactivate(); } } public void MakeUnitsInBufferHoldPosition() { if (playerUnitsCommandingBuffer.Count > 0) { audioManager.PlaySoundAsOneShot(audioSet.HoldPosition, 0.45f, 0.9f + Random.value * 0.2f, audioManager.mgSFX, 10); } foreach (PathfindMovementPlayerunit item in playerUnitsCommandingBuffer) { item.HoldPosition = true; } } public void ForceCommandingEnd() { if (commanding) { PlaceCommandedUnitsAndCalculateTargetPositions(); } } public void PlaceCommandedUnitsAndCalculateTargetPositions() { if (!commanding) { return; } if (playerUnitsCommanding.Count > 0) { audioManager.PlaySoundAsOneShot(audioSet.PlaceCommandingUnits, 0.35f, 0.9f + Random.value * 0.2f, audioManager.mgSFX, 10); } dropWaypointFx.Emit(drowWaypointParticleCount); foreach (PathfindMovementPlayerunit item in playerUnitsCommanding) { OnUnitRemove(item); } foreach (AutoAttack item2 in autoAttacksToEnable) { if ((bool)item2 && item2.GetComponent().HpValue > 0f) { item2.enabled = true; } } autoAttacksToEnable.Clear(); for (int i = 0; i < playerUnitsCommanding.Count; i++) { Vector3 vector = Quaternion.AngleAxis((float)(i / playerUnitsCommanding.Count) * 360f, Vector3.up) * Vector3.right * unitDistanceMoveStep; playerUnitsCommanding[i].HomePosition = astarPath.GetNearest(base.transform.position + vector + new Vector3(Random.value - 0.5f, 0f, Random.value - 0.5f) * unitDistanceMoveStep * 0.1f, nearestConstraint).position; } for (int j = 0; j < maxPositioningRepeats; j++) { bool flag = false; for (int k = 0; k < playerUnitsCommanding.Count; k++) { for (int l = k + 1; l < playerUnitsCommanding.Count; l++) { if (!((playerUnitsCommanding[k].HomePosition - playerUnitsCommanding[l].HomePosition).magnitude > unitDistanceFromEachOther)) { Vector3 vector2 = (playerUnitsCommanding[k].HomePosition - playerUnitsCommanding[l].HomePosition).normalized * unitDistanceMoveStep; playerUnitsCommanding[k].HomePosition = astarPath.GetNearest(playerUnitsCommanding[k].HomePosition + vector2, nearestConstraint).position; playerUnitsCommanding[l].HomePosition = astarPath.GetNearest(playerUnitsCommanding[l].HomePosition - vector2, nearestConstraint).position; flag = true; } } } if (!flag) { break; } } playerUnitsCommandingBuffer.Clear(); playerUnitsCommandingBuffer.AddRange(playerUnitsCommanding); playerUnitsCommanding.Clear(); } public void OnUnitAdd(TaggedObject _t) { PathfindMovementPlayerunit pathfindMovementPlayerunit = (PathfindMovementPlayerunit)_t.Hp.PathfindMovement; if (!playerUnitsCommanding.Contains(pathfindMovementPlayerunit)) { audioManager.PlaySoundAsOneShot(audioSet.AddedUnitToCommanding, 0.55f, 0.7f + (float)playerUnitsCommanding.Count * 0.025f, audioManager.mgSFX, 50); playerUnitsCommanding.Add(pathfindMovementPlayerunit); pathfindMovementPlayerunit.FollowPlayer(_follow: true); MaterialFlasherFX componentInChildren = pathfindMovementPlayerunit.GetComponentInChildren(); if ((bool)componentInChildren) { componentInChildren.SetSelected(_selected: true); } _t.Tags.Add(TagManager.ETag.AUTO_Commanded); if (playerUPgradeManager.commander) { pathfindMovementPlayerunit.movementSpeed *= UpgradeCommander.instance.moveSpeedMultiplicator; } AutoAttack[] components = _t.GetComponents(); foreach (AutoAttack autoAttack in components) { autoAttack.enabled = false; autoAttacksToEnable.Add(autoAttack); } } } public void OnUnitRemove(PathfindMovementPlayerunit _p) { _p.FollowPlayer(_follow: false); MaterialFlasherFX componentInChildren = _p.GetComponentInChildren(); if ((bool)componentInChildren) { componentInChildren.SetSelected(_selected: false); } _p.GetComponent().Tags.Remove(TagManager.ETag.AUTO_Commanded); if (playerUPgradeManager.commander) { _p.movementSpeed /= UpgradeCommander.instance.moveSpeedMultiplicator; } } }