mirror of
https://github.com/misternebula/quantum-space-buddies.git
synced 2025-01-25 06:35:45 +00:00
168 lines
3.8 KiB
C#
168 lines
3.8 KiB
C#
using GhostEnums;
|
|
using QSB.EchoesOfTheEye.Ghosts;
|
|
using QSB.Utility;
|
|
using System.Linq;
|
|
using UnityEngine;
|
|
|
|
/// <summary>
|
|
///
|
|
/// </summary>
|
|
public class QSBGuardAction : QSBGhostAction
|
|
{
|
|
private GhostNode _targetSearchNode;
|
|
|
|
private bool _searchingAtNode;
|
|
|
|
private bool _watchingPlayer;
|
|
|
|
private float _searchStartTime;
|
|
|
|
private float _lastSawPlayer;
|
|
|
|
private GhostNode[] _searchNodes;
|
|
|
|
private bool _hasReachedAnySearchNode;
|
|
|
|
public override GhostAction.Name GetName()
|
|
{
|
|
return GhostAction.Name.Guard;
|
|
}
|
|
|
|
public override float CalculateUtility()
|
|
{
|
|
if (!_controller.AttachedObject.GetNodeMap().HasSearchNodes(_controller.AttachedObject.GetNodeLayer()))
|
|
{
|
|
return -100f;
|
|
}
|
|
|
|
if (_data.threatAwareness < GhostData.ThreatAwareness.SomeoneIsInHere)
|
|
{
|
|
return -100f;
|
|
}
|
|
|
|
if (_data.reduceGuardUtility)
|
|
{
|
|
return 60f;
|
|
}
|
|
|
|
return 90f;
|
|
}
|
|
|
|
protected override void OnEnterAction()
|
|
{
|
|
_controller.SetLanternConcealed(true, true);
|
|
_sensors.AttachedObject.SetContactEdgeCatcherWidth(5f);
|
|
_effects.SetMovementStyle(GhostEffects.MovementStyle.Normal);
|
|
ContinueSearch();
|
|
}
|
|
|
|
protected override void OnExitAction()
|
|
{
|
|
if (_searchingAtNode)
|
|
{
|
|
_controller.FaceVelocity();
|
|
}
|
|
|
|
_sensors.AttachedObject.ResetContactEdgeCatcherWidth();
|
|
_targetSearchNode = null;
|
|
_searchingAtNode = false;
|
|
_watchingPlayer = false;
|
|
}
|
|
|
|
public override bool Update_Action()
|
|
{
|
|
if (_searchingAtNode && Time.time > _searchStartTime + 4f)
|
|
{
|
|
_controller.FaceVelocity();
|
|
_targetSearchNode.searchData.lastSearchTime = Time.time;
|
|
ContinueSearch();
|
|
}
|
|
|
|
var anyPlayerVisible = _data.players.Values.Any(x => x.sensor.isPlayerVisible);
|
|
var anyPlayerLanternVisible = _data.players.Values.Any(x => x.sensor.isPlayerHeldLanternVisible);
|
|
|
|
var flag = _hasReachedAnySearchNode && (anyPlayerVisible || anyPlayerLanternVisible);
|
|
if (flag)
|
|
{
|
|
_lastSawPlayer = Time.time;
|
|
}
|
|
|
|
if (!_watchingPlayer && flag)
|
|
{
|
|
_watchingPlayer = true;
|
|
_searchingAtNode = false;
|
|
_controller.StopMoving();
|
|
_controller.FacePlayer(_data.interestedPlayer.player, TurnSpeed.MEDIUM);
|
|
}
|
|
else if (_watchingPlayer && !flag && Time.time - _lastSawPlayer > 1f)
|
|
{
|
|
_watchingPlayer = false;
|
|
ContinueSearch();
|
|
}
|
|
|
|
return true;
|
|
}
|
|
|
|
public override void OnArriveAtPosition()
|
|
{
|
|
if (_searchNodes != null && _searchNodes.Length == 1)
|
|
{
|
|
_controller.FaceLocalPosition(_targetSearchNode.localPosition + (_targetSearchNode.localForward * 10f), TurnSpeed.MEDIUM);
|
|
}
|
|
else
|
|
{
|
|
_controller.Spin(TurnSpeed.MEDIUM);
|
|
}
|
|
|
|
_searchingAtNode = true;
|
|
_hasReachedAnySearchNode = true;
|
|
_searchStartTime = Time.time;
|
|
}
|
|
|
|
private void ContinueSearch()
|
|
{
|
|
_searchingAtNode = false;
|
|
_targetSearchNode = GetHighestPriorityNodeToSearch();
|
|
if (_targetSearchNode == null)
|
|
{
|
|
DebugLog.DebugWrite($"{_brain.Name} : Failed to find any nodes to search! Did we exhaust our existing options?", OWML.Common.MessageType.Error);
|
|
}
|
|
|
|
_controller.PathfindToNode(_targetSearchNode, MoveType.SEARCH);
|
|
_controller.FaceVelocity();
|
|
}
|
|
|
|
private GhostNode GetHighestPriorityNodeToSearch()
|
|
{
|
|
_searchNodes = _controller.AttachedObject.GetNodeMap().GetSearchNodesOnLayer(_controller.AttachedObject.GetNodeLayer());
|
|
var num = 0f;
|
|
var time = Time.time;
|
|
for (var i = 0; i < _searchNodes.Length; i++)
|
|
{
|
|
var num2 = time - _searchNodes[i].searchData.lastSearchTime;
|
|
num += num2;
|
|
}
|
|
|
|
num /= (float)_searchNodes.Length;
|
|
GhostNode ghostNode = null;
|
|
for (var j = 0; j < 5; j++)
|
|
{
|
|
ghostNode = _searchNodes[Random.Range(0, _searchNodes.Length)];
|
|
if (time - ghostNode.searchData.lastSearchTime > num)
|
|
{
|
|
break;
|
|
}
|
|
}
|
|
|
|
return ghostNode;
|
|
}
|
|
|
|
public override void DrawGizmos(bool isGhostSelected)
|
|
{
|
|
foreach (var item in _searchNodes)
|
|
{
|
|
Popcron.Gizmos.Sphere(_controller.AttachedObject.LocalToWorldPosition(item.localPosition), 1f, Color.red);
|
|
}
|
|
}
|
|
}
|