DLEUGO4VYTO63GD26UI3AZURQLUS44AEFAGFHSRHNODMVW6OBGZAC
33YYBTSQFQMGO5RYBAFYGX3L4N7YS4DT4CEJKB6ZVYCIIZGDQD2QC
CD5FF75KTOBTMVMTMCKMR6F5DFKOF26I5K43ITNHGBI3ZAZHA4RAC
XF52N4U7HWXOF4PDSCR7LCUENLTSXLWEZGS2IJ6562KYI567Z2GAC
VZRSH4U473FCZOP5EXURPXXN5J6F3ZLT435YY7A2JHLG2ZZB5KLQC
P5O6MKCMZL3DK7ZO5SBWTCHOQB6O2MZA5VPSCQX6X4LJQVOWYV7AC
754VCJRLAZAVIQP7STLUIHP3U7PUHBTYAHLNQK4A2H6IKYVNTDKAC
GBGS6RTZTCKRMLLDVCBGMRTJNNOSAUTXN5D2EMEQMQAREORE54PAC
J5CTPTTJ22V4MMQ3IZ2LUJE7GP35I4NS2JIZ2HQRNIVJF3ERYELAC
VUAVVMQEUYSXHBIUJHGRX237EZFT5MCB73ZKVWMGJDRHYZH4XZKAC
NPTXIY5PL7XQUOFJ2WRAZUBHMC4OFZVF4EA74GBI63TJ4QXDKMAAC
HXTSBPAP75A7EC4RKWYQMVPPHPNZFPHUORBZWDHGEB6MPAGI7G7AC
VVKEQMFYXC4F72W2RS5ZAVRCROH4NDFOI4DIAWGGEID2YFPQTSSAC
using System;
using System.Collections;
using TagFighter;
using TagFighter.Events;
using TagFighter.Resources;
using TagFighter.Testing.Optics;
using Testing.Actions;
using Testing.Line;
using Testing.TimeDialation;
using UnityEngine;
using UnityEngine.AI;
using UnityEngine.EventSystems;
namespace TagFighter.Testing
{
public class Tester : MonoBehaviour
{
[SerializeField] Vector3 _forceToApply;
[SerializeField] Transform _affected;
[SerializeField] LayerMask _unitMovementLayerMask;
[SerializeField] ForceMode _forceMode;
[SerializeField] EventAggregator _eventAggregator;
[SerializeField] bool _shouldTestTags = false;
[SerializeField] bool _shouldTestPhysics = false;
[SerializeField] bool _shouldTestPawnConditions = false;
[SerializeField] bool _shouldRunAutoTests = false;
Renderer _r;
Rigidbody _rb;
NavMeshAgent _nma;
bool _pushed;
Vector3 _resetPosition;
protected void Start() {
if (_affected) {
_r = _affected.GetComponent<Renderer>();
_rb = _affected.GetComponent<Rigidbody>();
_nma = _affected.GetComponent<NavMeshAgent>();
_resetPosition = _affected.transform.position;
}
Reset();
}
protected void Update() {
if (_shouldTestTags) {
TestTags();
}
if (_shouldTestPhysics) {
TestPhysics();
}
if (_shouldTestPawnConditions) {
TestAddPawnCondition();
}
if (_shouldRunAutoTests) {
AutoTests();
}
}
void TestAddPawnCondition() {
if (Input.GetKeyDown(KeyCode.T)) {
var condition = _affected.gameObject.AddComponent<TagFighter.Effects.PawnCondition>();
condition.Apply();
}
}
void TestTags() {
if (Input.GetKeyDown(KeyCode.L)) {
var color = UnityEngine.Random.Range(0, 3);
switch (color) {
case 0: {
var modifier = new StatModifier<BlueTagUnit> {
Amount = (Unit<BlueTagUnit>)1
};
_affected.GetComponent<BlueTag>().AddCurrentModifier(modifier, System.Threading.CancellationToken.None);
break;
}
case 1: {
var modifier = new StatModifier<RedTagUnit> {
Amount = (Unit<RedTagUnit>)1
};
_affected.GetComponent<RedTag>().AddCurrentModifier(modifier, System.Threading.CancellationToken.None);
break;
}
case 2: {
var modifier = new StatModifier<GreenTagUnit> {
Amount = (Unit<GreenTagUnit>)1
};
_affected.GetComponent<GreenTag>().AddCurrentModifier(modifier, System.Threading.CancellationToken.None);
break;
}
}
}
}
void AutoTests() {
if (Input.GetKeyDown(KeyCode.T)) {
if (Input.GetKey(KeyCode.LeftShift)) {
Test();
}
}
}
void TestPhysics() {
if (Input.GetKeyDown(KeyCode.T)) {
if (!Input.GetKey(KeyCode.LeftShift)) {
_pushed = true;
}
}
if (Input.GetKeyDown(KeyCode.B) && !EventSystem.current.IsPointerOverGameObject()) {
var ray = Camera.main.ScreenPointToRay(Input.mousePosition);
if (Physics.Raycast(ray, out var hit)) {
var objectHit = hit.transform;
if (_unitMovementLayerMask.IsLayerInMask(objectHit.gameObject.layer)) {
_nma.Warp(hit.point);
}
}
}
if (Input.GetKeyDown(KeyCode.R)) {
Reset();
}
if (Input.GetKeyDown(KeyCode.P)) {
print($"Velocity ({_rb.velocity}), Magnitude {_rb.velocity.magnitude}");
print($"world bounds {_r.bounds} local bounds {_r.localBounds}");
}
}
protected void FixedUpdate() {
if (_rb != null && !_rb.isKinematic && _nma.isOnNavMesh && _rb.velocity.sqrMagnitude < 0.25f) {
if (Physics.Raycast(_affected.transform.position, Vector3.down, _r.bounds.extents.y + 0.1f, _unitMovementLayerMask)) {
_rb.isKinematic = true;
_nma.updatePosition = true;
_nma.updateRotation = true;
_nma.Warp(_affected.transform.position);
}
//nma.enabled = true;
}
if (_pushed) {
// nma.enabled = false;
_nma.updatePosition = false;
_nma.updateRotation = false;
_rb.isKinematic = false;
_rb.AddForce(_forceToApply, _forceMode);
_pushed = false;
}
}
void Reset() {
if (_rb != null) {
_rb.isKinematic = true;
}
if (_nma) {
_nma.updatePosition = true;
_nma.updateRotation = true;
_nma.enabled = true;
_pushed = false;
}
if (_affected) {
_affected.transform.position = _resetPosition;
}
}
[ContextMenuItem("TestPawn", "TestPawnOptics")]
[ContextMenuItem("TestContext", "TestContextOptics")]
[SerializeField]
OpticsTester opticsTester;
[SerializeField] ActionsTester actionsTester;
void Test() {
//TimeDialationTester timeDialationTester = new(_eventAggregator);
//timeDialationTester.TestAll();
//LineTester lineTester = new();
//lineTester.TestAll();
//ActionsTester actionsTester = new(_actionTesterWeaver, _actionTesterTransform1, _actionTesterTransform2);
//actionsTester.TestAll();
opticsTester.TestAll();
}
void TestPawnOptics() {
opticsTester.TestPawn();
}
void TestContextOptics() {
opticsTester.TestContext();
}
}
}
namespace TagFighter.Testing.Optics
{
using CareBoo.Serially;
using System;
using System.Linq;
using System.Linq.Expressions;
using System.Reflection;
using System.Reflection.Emit;
using TagFighter.Effects;
using TagFighter.Effects.ResourceLocationAccessors.ContextRegisters;
using TagFighter.Optics;
using TagFighter.Resources;
public interface IPawnAccessor
{
public Lens<Transform, int> Create();
public Lens<Transform, int> CreateSpecific<TResource, TUnitType>() where TResource : Resource<TUnitType> where TUnitType : IUnitType;
};
[Serializable]
public class PawnAccessor : IPawnAccessor
{
[SerializeReference, ShowSerializeReference]
public IResourceStatLensCreator ResourceLensCreator; // Current/Capacity
[TypeFilter(derivedFrom: typeof(Resource<>))]
[SerializeField]
public SerializableType Resource;
public Lens<Transform, int> Create() {
var createSpecificLensMethod = typeof(PawnAccessor).GetMethod(nameof(CreateSpecific)).
MakeGenericMethod(Resource.Type, Resource.Type.BaseType.GetGenericArguments()[0]);
var lens = createSpecificLensMethod.Invoke(this, null);
return (Lens<Transform, int>)lens;
}
public Lens<Transform, int> CreateSpecific<TResource, TUnitType>()
where TResource : Resource<TUnitType>
where TUnitType : IUnitType {
var resource = new Lens<Transform, TResource>(t => t.GetComponent<TResource>(), (t, r) => t);
var statLens = ResourceLensCreator.Create<TResource, TUnitType>();
var valueLens = new Lens<Unit<TUnitType>, int>(u => u.AsPrimitive(), (u, v) => u = (Unit<TUnitType>)v);
var lens = resource.Compose(statLens).Compose(valueLens);
return lens;
}
}
public interface IContextAccessor
{
public Lens<EffectContext, int> Create();
public Lens<EffectContext, int> CreateSpecific<TResource, TUnitType>() where TResource : Resource<TUnitType> where TUnitType : IUnitType;
}
[Serializable]
public class ContextAccessor : IContextAccessor
{
// Register
[SerializeReference, ShowSerializeReference]
public IRegisterTypeLensCreator RegisterTypeLensCreator;
[TypeFilter(derivedFrom: typeof(Resource<>))]
[SerializeField]
public SerializableType Resource;
public Lens<EffectContext, int> Create() {
var createSpecificLensMethod = typeof(ContextAccessor).GetMethod(nameof(CreateSpecific)).
MakeGenericMethod(Resource.Type, Resource.Type.BaseType.GetGenericArguments()[0]);
var lens = createSpecificLensMethod.Invoke(this, null);
return (Lens<EffectContext, int>)lens;
}
public Lens<EffectContext, int> CreateSpecific<TResource, TUnitType>()
where TResource : Resource<TUnitType>
where TUnitType : IUnitType {
var registerLens = RegisterTypeLensCreator.Create<TResource, TUnitType>();
var valueLens = new Lens<Unit<TUnitType>, int>(u => u.AsPrimitive(), (u, v) => u = (Unit<TUnitType>)v);
return registerLens.Compose(valueLens);
}
}
public interface IRegisterTypeLensCreator
{
public Lens<EffectContext, Unit<TUnitType>> Create<TResource, TUnitType>()
where TResource : Resource<TUnitType>
where TUnitType : IUnitType;
}
[Serializable]
public class CurrentRegisterTypeLensCreator : IRegisterTypeLensCreator
{
public Lens<EffectContext, Unit<TUnitType>> Create<TResource, TUnitType>()
where TResource : Resource<TUnitType>
where TUnitType : IUnitType {
return new Lens<EffectContext, Unit<TUnitType>>(
context => context.GetResource<TResource, TUnitType, Current>(),
(context, v) => {
context.SetResource<TResource, TUnitType, Current>(v);
return context;
}
);
}
}
[Serializable]
public class OpticsTester
{
[SerializeField] Transform _transform;
[SerializeReference, ShowSerializeReference] IPawnAccessor _accessor;
[SerializeReference, ShowSerializeReference] IContextAccessor _contextAccessor;
Lens<Transform, int> CreateDynamicResourceLens(Type TResource, Type TUnit) {
var lensType = typeof(Lens<,>).MakeGenericType(typeof(Transform), typeof(int));
var lensCtor = lensType.GetConstructors().First();
ParameterExpression t = Expression.Parameter(typeof(Transform), "t");
Expression getResource = Expression.Call(t, "GetComponent", new Type[] { TResource });
Expression getCurrent = Expression.Call(getResource, "GetCurrent", Type.EmptyTypes);
Expression asPrimitive = Expression.Call(getCurrent, "AsPrimitive", Type.EmptyTypes);
var getterLambda = Expression.Lambda(asPrimitive, new ParameterExpression[] { t }).Compile();
ParameterExpression v = Expression.Parameter(typeof(int), "v");
//Expression assignValueExpression = Expression.Assign(getCurrent, Expression.ConvertChecked(v, TUnit));
LabelTarget returnTarget = Expression.Label(typeof(Transform));
var returnExpression = Expression.Return(returnTarget, t, typeof(Transform));
LabelExpression returnLabel = Expression.Label(returnTarget, t);
var block = Expression.Block(
//assignValueExpression,
returnExpression,
returnLabel
);
var setterLambda = Expression.Lambda(block, new ParameterExpression[] { t, v }).Compile();
var resourceLens = lensCtor.Invoke(new object[] { getterLambda, setterLambda });
return (Lens<Transform, int>)resourceLens;
}
public void TestAll() {
}
public void TestPawn() {
var lens = _accessor.Create();
Debug.Log(lens.Get(_transform));
}
public void TestContext() {
EffectContext effectContext = new EffectContext();
var lens = _contextAccessor.Create();
lens.Set(effectContext, 5);
effectContext.SetResource<RedTag, RedTagUnit, Current>((Unit<RedTagUnit>)1);
foreach (var a in effectContext.GetAllResourcesInRegister<Current>()) {
Debug.Log($"In foreach {a}");
}
Debug.Log($"{lens.Get(effectContext)}");
}
}
}
namespace Testing.Actions
{
[Serializable]
public class ActionsTester
{
[SerializeField] Weaver _weaver;
[SerializeField] Transform _transform1;
[SerializeField] Transform _transform2;
public void TestAll() {
TestFollowActionConcreteEqual();
TestFollowActionInterfaceEqual();
TestActionInterfaceNotEqual();
TestMoveToActionConcreteEqual();
TestMoveToActionInterfaceEqual();
}
public void TestFollowActionConcreteEqual() {
var testName = System.Reflection.MethodBase.GetCurrentMethod().Name;
var action1 = new FollowAction(_weaver, _transform1);
var action2 = new FollowAction(_weaver, _transform1);
if (action1.IsSimilarAction(action2)) {
Debug.Log($"<color=green>PASSED: {testName}</color>");
}
else {
Debug.Log($"<color=red>FAILED: {testName}</color>");
}
}
public void TestFollowActionInterfaceEqual() {
var testName = System.Reflection.MethodBase.GetCurrentMethod().Name;
IAction action1 = new FollowAction(_weaver, _transform1);
IAction action2 = new FollowAction(_weaver, _transform1);
if (action1.IsSimilarAction(action2)) {
Debug.Log($"<color=green>PASSED: {testName}</color>");
}
else {
Debug.Log($"<color=red>FAILED: {testName}</color>");
}
}
public void TestActionInterfaceNotEqual() {
var testName = System.Reflection.MethodBase.GetCurrentMethod().Name;
IAction action1 = new FollowAction(_weaver, _transform1);
IAction action2 = new MoveToAction(_weaver, _transform1.position);
if (!action1.IsSimilarAction(action2)) {
Debug.Log($"<color=green>PASSED: {testName}</color>");
}
else {
Debug.Log($"<color=red>FAILED: {testName}</color>");
}
}
public void TestMoveToActionConcreteEqual() {
var testName = System.Reflection.MethodBase.GetCurrentMethod().Name;
var action1 = new MoveToAction(_weaver, _transform1.position);
var action2 = new MoveToAction(_weaver, _transform1.position);
if (action1.IsSimilarAction(action2)) {
Debug.Log($"<color=green>PASSED: {testName}</color>");
}
else {
using System;
using System.Collections;
using TagFighter;
using TagFighter.Events;
using TagFighter.Resources;
using TagFighter.Testing.Optics;
using Testing.Actions;
using Testing.Line;
using Testing.TimeDialation;
using UnityEngine;
using UnityEngine.AI;
using UnityEngine.EventSystems;
namespace TagFighter.Testing
{
public class Tester : MonoBehaviour
{
[SerializeField] Vector3 _forceToApply;
[SerializeField] Transform _affected;
[SerializeField] LayerMask _unitMovementLayerMask;
[SerializeField] ForceMode _forceMode;
[SerializeField] EventAggregator _eventAggregator;
[SerializeField] bool _shouldTestTags = false;
[SerializeField] bool _shouldTestPhysics = false;
[SerializeField] bool _shouldTestPawnConditions = false;
[SerializeField] bool _shouldRunAutoTests = false;
Renderer _r;
Rigidbody _rb;
NavMeshAgent _nma;
bool _pushed;
Vector3 _resetPosition;
protected void Start() {
if (_affected) {
_r = _affected.GetComponent<Renderer>();
_rb = _affected.GetComponent<Rigidbody>();
_nma = _affected.GetComponent<NavMeshAgent>();
_resetPosition = _affected.transform.position;
}
Reset();
}
protected void Update() {
if (_shouldTestTags) {
TestTags();
}
if (_shouldTestPhysics) {
TestPhysics();
}
if (_shouldTestPawnConditions) {
TestAddPawnCondition();
}
if (_shouldRunAutoTests) {
AutoTests();
}
}
void TestAddPawnCondition() {
if (Input.GetKeyDown(KeyCode.T)) {
var condition = _affected.gameObject.AddComponent<TagFighter.Effects.PawnCondition>();
condition.Apply();
}
}
void TestTags() {
if (Input.GetKeyDown(KeyCode.L)) {
var color = UnityEngine.Random.Range(0, 3);
switch (color) {
case 0: {
var modifier = new StatModifier<BlueTagUnit> {
Amount = (Unit<BlueTagUnit>)1
};
_affected.GetComponent<BlueTag>().AddCurrentModifier(modifier, System.Threading.CancellationToken.None);
break;
}
case 1: {
var modifier = new StatModifier<RedTagUnit> {
Amount = (Unit<RedTagUnit>)1
};
_affected.GetComponent<RedTag>().AddCurrentModifier(modifier, System.Threading.CancellationToken.None);
break;
}
case 2: {
var modifier = new StatModifier<GreenTagUnit> {
Amount = (Unit<GreenTagUnit>)1
};
_affected.GetComponent<GreenTag>().AddCurrentModifier(modifier, System.Threading.CancellationToken.None);
break;
}
}
}
}
void AutoTests() {
if (Input.GetKeyDown(KeyCode.T)) {
if (Input.GetKey(KeyCode.LeftShift)) {
Test();
}
}
}
void TestPhysics() {
if (Input.GetKeyDown(KeyCode.T)) {
if (!Input.GetKey(KeyCode.LeftShift)) {
_pushed = true;
}
}
if (Input.GetKeyDown(KeyCode.B) && !EventSystem.current.IsPointerOverGameObject()) {
var ray = Camera.main.ScreenPointToRay(Input.mousePosition);
if (Physics.Raycast(ray, out var hit)) {
var objectHit = hit.transform;
if (_unitMovementLayerMask.IsLayerInMask(objectHit.gameObject.layer)) {
_nma.Warp(hit.point);
}
}
}
if (Input.GetKeyDown(KeyCode.R)) {
Reset();
}
if (Input.GetKeyDown(KeyCode.P)) {
print($"Velocity ({_rb.velocity}), Magnitude {_rb.velocity.magnitude}");
print($"world bounds {_r.bounds} local bounds {_r.localBounds}");
}
}
protected void FixedUpdate() {
if (_rb != null && !_rb.isKinematic && _nma.isOnNavMesh && _rb.velocity.sqrMagnitude < 0.25f) {
if (Physics.Raycast(_affected.transform.position, Vector3.down, _r.bounds.extents.y + 0.1f, _unitMovementLayerMask)) {
_rb.isKinematic = true;
_nma.updatePosition = true;
_nma.updateRotation = true;
_nma.Warp(_affected.transform.position);
}
//nma.enabled = true;
}
if (_pushed) {
// nma.enabled = false;
_nma.updatePosition = false;
_nma.updateRotation = false;
_rb.isKinematic = false;
_rb.AddForce(_forceToApply, _forceMode);
_pushed = false;
}
}
void Reset() {
if (_rb != null) {
_rb.isKinematic = true;
}
if (_nma) {
_nma.updatePosition = true;
_nma.updateRotation = true;
_nma.enabled = true;
_pushed = false;
}
if (_affected) {
_affected.transform.position = _resetPosition;
}
}
[ContextMenuItem("TestEffectInput", "TestEffectInputOptics")]
[SerializeField]
OpticsTester _opticsTester;
[SerializeField] ActionsTester _actionsTester;
void Test() {
TimeDialationTester timeDialationTester = new(_eventAggregator);
timeDialationTester.TestAll();
LineTester lineTester = new();
lineTester.TestAll();
_actionsTester.TestAll();
_opticsTester.TestAll();
}
void TestEffectInputOptics() {
_opticsTester.TestEffectInput();
}
}
}
namespace TagFighter.Testing.Optics
{
using System;
[Serializable]
public class OpticsTester
{
// [SerializeField] List<Transform> _transforms = new();
// [SerializeField] EffectDataAccessor _from;
// [SerializeField] EffectDataAccessor _to;
// [SerializeField] ResourceInfoGet<IResourceTypeAccessor, Effects.ResourceLocationAccessors.Get.Context> _rg;
// [SerializeField] ResourceInfoSet<IResourceTypeAccessor, Effects.ResourceLocationAccessors.Set.Context> _rs;
public void TestAll() {
}
public void TestEffectInput() {
//effectContext.SetResource<RedTag, RedTagUnit, Current>((Unit<RedTagUnit>)1);
// var input = new EffectInput(new EffectContext(), _transforms, null);
// foreach (var val in _from.Get(input)) {
// Debug.Log(val);
// }
// _to.Set(input, _from.Get(input));
// _to.Set(input, Enumerable.Empty<int>().Append(20));
// _to.Set(input, Enumerable.Empty<int>().Append(30));
}
}
}
namespace Testing.Actions
{
[Serializable]
public class ActionsTester
{
[SerializeField] Weaver _weaver;
[SerializeField] Transform _transform1;
[SerializeField] Transform _transform2;
public void TestAll() {
TestFollowActionConcreteEqual();
TestFollowActionInterfaceEqual();
TestActionInterfaceNotEqual();
TestMoveToActionConcreteEqual();
TestMoveToActionInterfaceEqual();
}
public void TestFollowActionConcreteEqual() {
var testName = System.Reflection.MethodBase.GetCurrentMethod().Name;
var action1 = new FollowAction(_weaver, _transform1);
var action2 = new FollowAction(_weaver, _transform1);
if (action1.IsSimilarAction(action2)) {
Debug.Log($"<color=green>PASSED: {testName}</color>");
}
else {
Debug.Log($"<color=red>FAILED: {testName}</color>");
}
}
public void TestFollowActionInterfaceEqual() {
var testName = System.Reflection.MethodBase.GetCurrentMethod().Name;
IAction action1 = new FollowAction(_weaver, _transform1);
IAction action2 = new FollowAction(_weaver, _transform1);
if (action1.IsSimilarAction(action2)) {
Debug.Log($"<color=green>PASSED: {testName}</color>");
}
else {
Debug.Log($"<color=red>FAILED: {testName}</color>");
}
}
public void TestActionInterfaceNotEqual() {
var testName = System.Reflection.MethodBase.GetCurrentMethod().Name;
IAction action1 = new FollowAction(_weaver, _transform1);
IAction action2 = new MoveToAction(_weaver, _transform1.position);
if (!action1.IsSimilarAction(action2)) {
Debug.Log($"<color=green>PASSED: {testName}</color>");
}
else {
Debug.Log($"<color=red>FAILED: {testName}</color>");
}
}
public void TestMoveToActionConcreteEqual() {
var testName = System.Reflection.MethodBase.GetCurrentMethod().Name;
var action1 = new MoveToAction(_weaver, _transform1.position);
var action2 = new MoveToAction(_weaver, _transform1.position);
if (action1.IsSimilarAction(action2)) {
Debug.Log($"<color=green>PASSED: {testName}</color>");
}
else {
using System;
using System.Collections.Generic;
using System.Linq;
using CareBoo.Serially;
using UnityEngine;
/// <summary>
///
/// When Getting or Setting a resource, three attributes must by chosen
/// 1. Which resource should be manipulated
/// 2. What is the location of the resource (Pawn / Context) to be manipulated
/// 3. Which property of the location should be manipulated
///
/// <example>
/// 1. Get (1)Pain resource from (2)Context (3)Current Register
/// 2. Get (1)RedTag (3)Capacity from all (2)Pawns
/// </example>
///
/// In Order to allow Serialization in the editor, all three attributes have a corresponding accessor classes.
/// These are all consolidated and expected under
/// <see cref="TagFighter.Effects.ResourceInfoGet{TTypeAccessor, TLocationAccessor}"/>
/// <see cref="TagFighter.Effects.ResourceInfoSet{TTypeAccessor, TLocationAccessor}"/>
///
/// Resources are accessed through <see cref="TagFighter.Effects.ResourceTypeAccessor{TResource, TUnit}"/> with specific types encoded per resource.
/// For example: <see cref="TagFighter.Resources.Pain"/> is accessed through <see cref="TagFighter.Effects.ResourceTypeAccessors.Pain"/>
///
/// Locations are accessed through <see cref=TagFighter.Effects.IResourceLocationGet"/> and <see cref="TagFighter.Effects.IResourceLocationSet"/>
/// <example>
/// <see cref="TagFighter.Effects.EffectContext"/> is accessed through <see cref="TagFighter.Effects.ResourceLocationAccessors.Get.Context"/> and <see cref="TagFighter.Effects.ResourceLocationAccessors.Set.Context"/>
/// Pawn (Any Gameobject) is accessed through <see cref="TagFighter.Effects.ResourceLocationAccessors.Get.Pawn"/> and <see cref="TagFighter.Effects.ResourceLocationAccessors.Set.Pawn"/>
/// </example>
///
/// As each Location has different properties - Location properties have specialized accessors:
/// 1. Context - <see cref="TagFighter.Effects.ResourceLocationAccessors.ContextRegisters.IContextRegister"/>
/// 2. Pawn - <see cref="TagFighter.Effects.ResourceLocationAccessors.PawnProperties.IPawnResourceProperty"/>
/// <example>
/// Context <see cref="TagFighter.Effects.EffectContext.GetResource{TResource, TUnit, TContextRegister}"/> is accessed through <see cref="TagFighter.Effects.ResourceLocationAccessors.ContextRegisters.ContextRegister{TRegisterType}"/>
/// with specialized registers such as <see cref="TagFighter.Effects.ResourceLocationAccessors.ContextRegisters.Current"/>, <see cref="TagFighter.Effects.ResourceLocationAccessors.ContextRegisters.Removed"/>
/// or <see cref="TagFighter.Effects.ResourceLocationAccessors.ContextRegisters.Added"/>
/// Pawn <see cref="TagFighter.Resources.Resource{TUnitType}.GetCapacity"/> is accessed through <see cref="TagFighter.Effects.ResourceLocationAccessors.PawnProperties.Capacity"/>
/// and Pawn <see cref="TagFighter.Resources.Resource{TUnitType}.GetCurrent"/> is accessed through <see cref="TagFighter.Effects.ResourceLocationAccessors.PawnProperties.Current"/>
/// </example>
///
/// In addition, Context and Pawn are different in regards to amount of instances. There is always a single weave Context while there can be 0 or more pawns affected.
/// As a result, when Setting to Context, an aggregation operation method must be chosen from <see cref="TagFighter.Effects.IResourceOperator"/>
/// <example>
/// <see cref="TagFighter.Effects.Operators.Sum"/>, <see cref="TagFighter.Effects.Operators.Multiply"/>
/// </example>
///
/// Serializing Pawn Resource Accessor in a MonoBehavior without a Context:
/// [SerializeReference, ShowSerializeReference]
/// public <see cref="TagFighter.Effects.IResourceGetter"/> Resource;
/// [SerializeReference, ShowSerializeReference]
/// public <see cref="TagFighter.Effects.ResourceLocationAccessors.PawnProperties.IPawnResourceProperty"/> Stat;
/// Resource.GetStat(transform, Stat);
///
/// </summary>
namespace TagFighter.Effects
{
[Serializable]
public class ResourceInfoGet<TTypeAccessor, TLocationAccessor> where TTypeAccessor : IResourceTypeAccessor where TLocationAccessor : IResourceLocationGet
{
[SerializeReference, ShowSerializeReference]
public TTypeAccessor Resource;
[SerializeReference, ShowSerializeReference]
public TLocationAccessor Location;
public double Multiplier = 1;
public double Addend = 0;
public bool IsInit {
get {
return (Resource != null) && (Location != null);
}
}
public IEnumerable<double> Get(EffectInput data) {
return IsInit ? Resource.Get(data, Location).Select(resource => (Multiplier * resource) + Addend) :
Enumerable.Repeat(Addend, 1);
}
public override string ToString() => $"{Resource}.{Location}";
}
[Serializable]
public class ResourceInfoSet<TTypeAccessor, TLocationAccessor> where TTypeAccessor : IResourceTypeAccessor where TLocationAccessor : IResourceLocationSet
{
[SerializeReference, ShowSerializeReference]
public TTypeAccessor Resource;
[SerializeReference, ShowSerializeReference]
public TLocationAccessor Location;
public double Multiplier = 1;
public double Addend = 0;
public bool IsInit {
get {
return (Resource != null) && (Location != null);
}
}
public void Set(EffectInput data, IEnumerable<double> value) {
if (!IsInit) {
Debug.Log("Set Resource missing Type or Location, skipping");
return;
}
var manipulatedValue = value.Select(resource => (int)((Multiplier * resource) + Addend));
Resource.Set(data, Location, manipulatedValue);
}
public override string ToString() => $"{Resource}.{Location}";
}
}
using System;
using System.Collections.Generic;
using System.Linq;
using CareBoo.Serially;
using UnityEngine;
/// <summary>
///
/// When Getting or Setting a resource, three attributes must by chosen
/// 1. Which resource should be manipulated
/// 2. What is the location of the resource (Pawn / Context) to be manipulated
/// 3. Which property of the location should be manipulated
///
/// <example>
/// 1. Get (1)Pain resource from (2)Context (3)Current Register
/// 2. Get (1)RedTag (3)Capacity from all (2)Pawns
/// </example>
///
/// In Order to allow Serialization in the editor, all three attributes have a corresponding accessor classes.
/// These are all consolidated and expected under
/// <see cref="TagFighter.Effects.ResourceInfoGet{TTypeAccessor, TLocationAccessor}"/>
/// <see cref="TagFighter.Effects.ResourceInfoSet{TTypeAccessor, TLocationAccessor}"/>
///
/// Resources are accessed through <see cref="TagFighter.Effects.ResourceTypeAccessor{TResource, TUnit}"/> with specific types encoded per resource.
/// For example: <see cref="TagFighter.Resources.Pain"/> is accessed through <see cref="TagFighter.Effects.ResourceTypeAccessors.Pain"/>
///
/// Locations are accessed through <see cref=TagFighter.Effects.IResourceLocationGet"/> and <see cref="TagFighter.Effects.IResourceLocationSet"/>
/// <example>
/// <see cref="TagFighter.Effects.EffectContext"/> is accessed through <see cref="TagFighter.Effects.ResourceLocationAccessors.Get.Context"/> and <see cref="TagFighter.Effects.ResourceLocationAccessors.Set.Context"/>
/// Pawn (Any Gameobject) is accessed through <see cref="TagFighter.Effects.ResourceLocationAccessors.Get.Pawn"/> and <see cref="TagFighter.Effects.ResourceLocationAccessors.Set.Pawn"/>
/// </example>
///
/// As each Location has different properties - Location properties have specialized accessors:
/// 1. Context - <see cref="TagFighter.Effects.ResourceLocationAccessors.ContextRegisters.IContextRegister"/>
/// 2. Pawn - <see cref="TagFighter.Effects.ResourceLocationAccessors.PawnProperties.IPawnResourceProperty"/>
/// <example>
/// Context <see cref="TagFighter.Effects.EffectContext.GetResource{TResource, TUnit, TContextRegister}"/> is accessed through <see cref="TagFighter.Effects.ResourceLocationAccessors.ContextRegisters.ContextRegister{TRegisterType}"/>
/// with specialized registers such as <see cref="TagFighter.Effects.ResourceLocationAccessors.ContextRegisters.Current"/>, <see cref="TagFighter.Effects.ResourceLocationAccessors.ContextRegisters.Removed"/>
/// or <see cref="TagFighter.Effects.ResourceLocationAccessors.ContextRegisters.Added"/>
/// Pawn <see cref="TagFighter.Resources.Resource{TUnitType}.GetCapacity"/> is accessed through <see cref="TagFighter.Effects.ResourceLocationAccessors.PawnProperties.Capacity"/>
/// and Pawn <see cref="TagFighter.Resources.Resource{TUnitType}.GetCurrent"/> is accessed through <see cref="TagFighter.Effects.ResourceLocationAccessors.PawnProperties.Current"/>
/// </example>
///
/// In addition, Context and Pawn are different in regards to amount of instances. There is always a single weave Context while there can be 0 or more pawns affected.
/// As a result, when Setting to Context, an aggregation operation method must be chosen from <see cref="TagFighter.Effects.IResourceOperator"/>
/// <example>
/// <see cref="TagFighter.Effects.Operators.Sum"/>, <see cref="TagFighter.Effects.Operators.Multiply"/>
/// </example>
///
/// Serializing Pawn Resource Accessor in a MonoBehavior without a Context:
/// [SerializeReference, ShowSerializeReference]
/// public <see cref="TagFighter.Effects.IResourceGetter"/> Resource;
/// [SerializeReference, ShowSerializeReference]
/// public <see cref="TagFighter.Effects.ResourceLocationAccessors.PawnProperties.IPawnResourceProperty"/> Stat;
/// Resource.GetStat(transform, Stat);
///
/// </summary>
namespace TagFighter.Effects
{
[Serializable]
public class ResourceInfoGet<TTypeAccessor, TLocationAccessor> where TTypeAccessor : IResourceTypeAccessor where TLocationAccessor : IResourceLocationGet
{
[SerializeReference, ShowSerializeReference]
public TTypeAccessor Resource;
[SerializeReference, ShowSerializeReference]
public TLocationAccessor Location;
[TypeFilter(derivedFrom: typeof(Resources.Resource<>))]
[SerializeField]
public SerializableType ResourceType;
public double Multiplier = 1;
public double Addend = 0;
public bool IsInit {
get {
return (Resource != null) && (Location != null);
}
}
public IEnumerable<double> Get(EffectInput data) {
return IsInit ? Resource.Get(data, Location).Select(resource => (Multiplier * resource) + Addend) :
Enumerable.Repeat(Addend, 1);
}
public override string ToString() => $"{Resource}.{Location}";
}
[Serializable]
public class ResourceInfoSet<TTypeAccessor, TLocationAccessor> where TTypeAccessor : IResourceTypeAccessor where TLocationAccessor : IResourceLocationSet
{
[SerializeReference, ShowSerializeReference]
public TTypeAccessor Resource;
[SerializeReference, ShowSerializeReference]
public TLocationAccessor Location;
public double Multiplier = 1;
public double Addend = 0;
public bool IsInit {
get {
return (Resource != null) && (Location != null);
}
}
public void Set(EffectInput data, IEnumerable<double> value) {
if (!IsInit) {
Debug.Log("Set Resource missing Type or Location, skipping");
return;
}
var manipulatedValue = value.Select(resource => (int)((Multiplier * resource) + Addend));
Resource.Set(data, Location, manipulatedValue);
}
public override string ToString() => $"{Resource}.{Location}";
}
}
using System.Collections.Generic;
using TagFighter.Resources;
namespace TagFighter.Effects
{
public interface IResourceLocationAccessor { }
public interface IResourceLocationGet : IResourceLocationAccessor
{
public IEnumerable<Unit<TUnit>> Get<TResource, TUnit>(EffectInput data)
where TResource : Resource<TUnit>
where TUnit : IUnitType;
}
public interface IResourceLocationSet : IResourceLocationAccessor
{
public void Set<TResource, TUnit>(EffectInput data, IEnumerable<Unit<TUnit>> values)
where TResource : Resource<TUnit>
where TUnit : IUnitType;
}
}
namespace TagFighter.Optics
{
using System;
using CareBoo.Serially;
using Resources;
public interface ILens<Whole, Part>
{
Part Get(Whole whole);
Whole Set(Part part, Whole whole);
}
public readonly struct Lens<TWhole, TPart>
{
public readonly Func<TWhole, TPart> Get;
public readonly Func<TWhole, TPart, TWhole> Set;
public Lens(Func<TWhole, TPart> getter, Func<TWhole, TPart, TWhole> setter) {
Get = getter ?? throw new ArgumentNullException(nameof(getter));
Set = setter ?? throw new ArgumentNullException(nameof(setter));
}
}
public static class LensExtensions
{
public static Lens<TWhole, TPart> Lens<TWhole, TPart>(
this TWhole _,
Func<TWhole, TPart> getter, Func<TWhole, TPart, TWhole> setter) =>
new Lens<TWhole, TPart>(getter, setter);
//public static TWhole Update<TWhole, TPart>(
// this Lens<TWhole, TPart> lens,
// TWhole whole, Func<TPart, TPart> update) =>
// lens.Set(whole, update(lens.Get(whole)));
public static Lens<TWhole, TSubPart> Compose<TWhole, TPart, TSubPart>(
this Lens<TWhole, TPart> parent, Lens<TPart, TSubPart> child) =>
new Lens<TWhole, TSubPart>(
whole => child.Get(parent.Get(whole)),
(whole, part) => parent.Set(whole, child.Set(parent.Get(whole), part)));
}
public interface IResourceStatLensCreator
{
public Lens<TResource, Unit<TUnitType>> Create<TResource, TUnitType>()
where TResource : Resource<TUnitType>
where TUnitType : IUnitType;
}
[ProvideSourceInfo]
[Serializable]
public class ResourceCurrentLensCreator : IResourceStatLensCreator
{
public Lens<TResource, Unit<TUnitType>> Create<TResource, TUnitType>()
where TResource : Resource<TUnitType>
where TUnitType : IUnitType {
return new Lens<TResource, Unit<TUnitType>>(r => r.GetCurrent(), (r, u) => r);
}
}
[ProvideSourceInfo]
[Serializable]
public class ResourceCapacityLensCreator : IResourceStatLensCreator
{
public Lens<TResource, Unit<TUnitType>> Create<TResource, TUnitType>()
where TResource : Resource<TUnitType>
where TUnitType : IUnitType {
return new Lens<TResource, Unit<TUnitType>>(r => r.GetCapacity(), (r, u) => r);
}
}
}
using System.Collections.Generic;
using TagFighter.Resources;
namespace TagFighter.Effects
{
public interface IResourceLocationAccessor { }
public interface IResourceLocationGet : IResourceLocationAccessor
{
public IEnumerable<Unit<TUnit>> Get<TResource, TUnit>(EffectInput data)
where TResource : Resource<TUnit>
where TUnit : IUnitType;
}
public interface IResourceLocationSet : IResourceLocationAccessor
{
public void Set<TResource, TUnit>(EffectInput data, IEnumerable<Unit<TUnit>> values)
where TResource : Resource<TUnit>
where TUnit : IUnitType;
}
}
using System;
using System.Collections.Generic;
using CareBoo.Serially;
using TagFighter.Resources;
using UnityEngine;
namespace TagFighter.Effects.ResourceLocationAccessors
{
namespace ContextRegisters
{
public interface IRegisterType { }
public class CurrentRegisterType : IRegisterType { }
public class AddedRegisterType : IRegisterType { }
public class RemovedRegisterType : IRegisterType { }
public interface IContextRegister
{
public IEnumerable<Unit<TUnit>> Get<TResource, TUnit>(EffectContext context)
where TResource : Resource<TUnit>
where TUnit : IUnitType;
public void Set<TResource, TUnit>(EffectContext context, Unit<TUnit> value)
where TResource : Resource<TUnit>
where TUnit : IUnitType;
}
public class ContextRegister<TRegisterType> : IContextRegister where TRegisterType : IRegisterType
{
public IEnumerable<Unit<TUnit>> Get<TResource, TUnit>(EffectContext context)
where TResource : Resource<TUnit>
where TUnit : IUnitType {
yield return context.GetResource<TResource, TUnit, ContextRegister<TRegisterType>>();
}
public void Set<TResource, TUnit>(EffectContext context, Unit<TUnit> value)
where TResource : Resource<TUnit>
where TUnit : IUnitType {
context.SetResource<TResource, TUnit, ContextRegister<TRegisterType>>(value);
}
public override string ToString() => typeof(TRegisterType).Name;
}
[ProvideSourceInfo][Serializable] public sealed class Current : ContextRegister<CurrentRegisterType> { }
[ProvideSourceInfo][Serializable] public sealed class Added : ContextRegister<AddedRegisterType> { }
[ProvideSourceInfo][Serializable] public sealed class Removed : ContextRegister<RemovedRegisterType> { }
}
namespace Get
{
using ContextRegisters;
[ProvideSourceInfo]
[Serializable]
public class Context : IResourceLocationGet
{
[SerializeReference, ShowSerializeReference]
public IContextRegister Register;
public IEnumerable<Unit<TUnit>> Get<TResource, TUnit>(EffectInput data)
where TResource : Resource<TUnit>
where TUnit : IUnitType {
return Register.Get<TResource, TUnit>(data.Context);
}
public override string ToString() => $"{nameof(Context)}.{Register}";
}
}
namespace Set
{
using ContextRegisters;
[ProvideSourceInfo]
[Serializable]
public class Context : IResourceLocationSet
{
[SerializeReference, ShowSerializeReference]
public IContextRegister Register;
[SerializeReference, ShowSerializeReference]
public IResourceOperator SetAs;
public void Set<TResource, TUnit>(EffectInput data, IEnumerable<Unit<TUnit>> values)
where TResource : Resource<TUnit>
where TUnit : IUnitType {
Register.Set<TResource, TUnit>(data.Context, SetAs.OperateEnum(values));
}
public override string ToString() => $"{nameof(Context)}.{Register}";
}
}
}
using System;
using System.Collections.Generic;
using System.Runtime.InteropServices;
using CareBoo.Serially;
using TagFighter.Resources;
using UnityEngine;
namespace TagFighter.Effects.ResourceLocationAccessors
{
namespace ContextRegisters
{
public interface IRegisterType { }
public class CurrentRegisterType : IRegisterType { }
public class AddedRegisterType : IRegisterType { }
public class RemovedRegisterType : IRegisterType { }
public interface IContextRegister
{
public IEnumerable<Unit<TUnit>> Get<TResource, TUnit>(EffectContext context)
where TResource : Resource<TUnit>
where TUnit : IUnitType;
public void Set<TResource, TUnit>(EffectContext context, Unit<TUnit> value)
where TResource : Resource<TUnit>
where TUnit : IUnitType;
}
public class ContextRegister<TRegisterType> : IContextRegister where TRegisterType : IRegisterType
{
public IEnumerable<Unit<TUnit>> Get<TResource, TUnit>(EffectContext context)
where TResource : Resource<TUnit>
where TUnit : IUnitType {
yield return context.GetResource<TResource, TUnit, ContextRegister<TRegisterType>>();
}
public void Set<TResource, TUnit>(EffectContext context, Unit<TUnit> value)
where TResource : Resource<TUnit>
where TUnit : IUnitType {
context.SetResource<TResource, TUnit, ContextRegister<TRegisterType>>(value);
}
public override string ToString() => typeof(TRegisterType).Name;
}
[Guid("47EAE1FF-9FF5-41FD-B08E-0F674B3848E6")][ProvideSourceInfo][Serializable] public sealed class Current : ContextRegister<CurrentRegisterType> { }
[Guid("F61D55E0-7CE7-4C9A-B241-00B296A36CF3")][ProvideSourceInfo][Serializable] public sealed class Added : ContextRegister<AddedRegisterType> { }
[Guid("AAB1BF8C-B85E-4EFE-AB12-F24966BEBDAF")][ProvideSourceInfo][Serializable] public sealed class Removed : ContextRegister<RemovedRegisterType> { }
}
namespace Get
{
using ContextRegisters;
[ProvideSourceInfo]
[Serializable]
public class Context : IResourceLocationGet
{
[SerializeReference, ShowSerializeReference]
public IContextRegister Register;
public IEnumerable<Unit<TUnit>> Get<TResource, TUnit>(EffectInput data)
where TResource : Resource<TUnit>
where TUnit : IUnitType {
return Register.Get<TResource, TUnit>(data.Context);
}
public override string ToString() => $"{nameof(Context)}.{Register}";
}
}
namespace Set
{
using ContextRegisters;
[ProvideSourceInfo]
[Serializable]
public class Context : IResourceLocationSet
{
[SerializeReference, ShowSerializeReference]
public IContextRegister Register;
[SerializeReference, ShowSerializeReference]
public IResourceOperator SetAs;
public void Set<TResource, TUnit>(EffectInput data, IEnumerable<Unit<TUnit>> values)
where TResource : Resource<TUnit>
where TUnit : IUnitType {
Register.Set<TResource, TUnit>(data.Context, SetAs.OperateEnum(values));
}
public override string ToString() => $"{nameof(Context)}.{Register}";
}
}
}
using System.Collections;
using System.Collections.Generic;
using System.Linq;
using CareBoo.Serially;
using UnityEngine;
using TagFighter.Events;
using TagFighter.Actions;
namespace TagFighter.UnitControl
{
public class TestAIController : MonoBehaviour
{
[SerializeField] UnitControllerType _controllingUnitsOfType;
[SerializeField] EventAggregator _eventAggregator;
[SerializeField] float _decisionFrequency = 0.2f;
List<Transform> _alertedPawns = new();
List<Transform> _allControlledPawns = new();
LayerMask _unitsLayerMask;
protected void Awake() {
_eventAggregator.UnitControllerStarted += OnUnitControllerStarted;
_unitsLayerMask = LayerMask.NameToLayer("units");
if (_controllingUnitsOfType == null) {
Debug.LogWarning($"{transform.name} missing controllingUnitsOfType. Did you forget to set?");
}
if (_eventAggregator == null) {
Debug.LogWarning($"{transform.name} missing eventAggregator. Did you forget to set?");
}
}
protected void Start() {
StartCoroutine(DecideActionForAllAlertedUnits());
}
protected void OnDestroy() {
_eventAggregator.UnitControllerStarted -= OnUnitControllerStarted;
StopCoroutine(DecideActionForAllAlertedUnits());
}
void OnUnitControllerStarted(object sender, UnitControllerTargetStartedEventArgs e) {
if (_controllingUnitsOfType != e.ControlledBy) {
return;
}
_alertedPawns.Add(e.UnitTransform);
_allControlledPawns.Add(e.UnitTransform);
Debug.Log($"<color=green>{e.UnitTransform.name} : Added</color>");
}
IEnumerator DecideActionForAllAlertedUnits() {
// Waiting for a couple of frames before starting so all Start() events are called
yield return new WaitForEndOfFrame();
yield return new WaitForEndOfFrame();
//var a = ProduceMoveLocations().GetEnumerator();
while (true) {
foreach (var unit in _alertedPawns) {
if (unit.TryGetComponent(out ActionPlan actionPlan)) {
var currentAction = actionPlan.FirstOrDefault();
if (currentAction == default) {
//a.MoveNext();
//actionPlan.TryAddActionToPlan(new MoveToAction(unit.GetComponent<Weaver>(), a.Current
var sightedEnemy = GetEnemiesInRange(unit).FirstOrDefault();
//Debug.Log($"Sighted: {sightedEnemy}");
if (sightedEnemy != default) {
actionPlan.TryAddActionToPlan(new FollowAction(unit.GetComponent<Weaver>(), sightedEnemy, 1f));
}
}
}
}
yield return new WaitForSeconds(_decisionFrequency);
//Debug.Log("DecideActionForAllAlertedUnits");
}
}
IEnumerable<Vector3> ProduceMoveLocations() {
while (true) {
yield return new(55, 0, 60);
yield return new(55, 0, 65);
yield return new(50, 0, 65);
yield return new(50, 0, 60);
}
}
IEnumerable<Transform> GetEnemiesInRange(Transform actingUnit) {
var hits = Physics.SphereCastAll(actingUnit.position, 5f, actingUnit.forward, 0, _unitsLayerMask);
return hits.Select(hit => hit.transform).
Where(unit => unit.TryGetComponent(out UnitControllerTarget unitControllerTarget) && unitControllerTarget.ControlledBy != _controllingUnitsOfType);
}
//protected void OnDrawGizmos() {
// LayerMask _unitsLayerMask = LayerMask.NameToLayer("units");
// Gizmos.color = Color.yellow;
// Gizmos.DrawWireSphere(transform.position, 5f);
// var hits = Physics.SphereCastAll(transform.position, 5f, transform.forward, 0, _unitsLayerMask);
// foreach (var hit in hits.Where(hit => hit.transform != transform)) {
// Gizmos.DrawLine(transform.position, hit.transform.position);
// }
//}
}
}
using System.Collections;
using System.Collections.Generic;
using System.Linq;
using UnityEngine;
using TagFighter.Events;
using TagFighter.Actions;
namespace TagFighter.UnitControl
{
public class TestAIController : MonoBehaviour
{
[SerializeField] UnitControllerType _controllingUnitsOfType;
[SerializeField] EventAggregator _eventAggregator;
[SerializeField] float _decisionFrequency = 0.2f;
List<Transform> _alertedPawns = new();
List<Transform> _allControlledPawns = new();
LayerMask _unitsLayerMask;
protected void Awake() {
_eventAggregator.UnitControllerStarted += OnUnitControllerStarted;
_unitsLayerMask = LayerMask.NameToLayer("units");
if (_controllingUnitsOfType == null) {
Debug.LogWarning($"{transform.name} missing controllingUnitsOfType. Did you forget to set?");
}
if (_eventAggregator == null) {
Debug.LogWarning($"{transform.name} missing eventAggregator. Did you forget to set?");
}
}
protected void Start() {
StartCoroutine(DecideActionForAllAlertedUnits());
}
protected void OnDestroy() {
_eventAggregator.UnitControllerStarted -= OnUnitControllerStarted;
StopCoroutine(DecideActionForAllAlertedUnits());
}
void OnUnitControllerStarted(object sender, UnitControllerTargetStartedEventArgs e) {
if (_controllingUnitsOfType != e.ControlledBy) {
return;
}
_alertedPawns.Add(e.UnitTransform);
_allControlledPawns.Add(e.UnitTransform);
Debug.Log($"<color=green>{e.UnitTransform.name} : Added</color>");
}
IEnumerator DecideActionForAllAlertedUnits() {
// Waiting for a couple of frames before starting so all Start() events are called
yield return new WaitForEndOfFrame();
yield return new WaitForEndOfFrame();
//var a = ProduceMoveLocations().GetEnumerator();
while (true) {
foreach (var unit in _alertedPawns) {
if (unit.TryGetComponent(out ActionPlan actionPlan)) {
var currentAction = actionPlan.FirstOrDefault();
if (currentAction == default) {
//a.MoveNext();
//actionPlan.TryAddActionToPlan(new MoveToAction(unit.GetComponent<Weaver>(), a.Current
var sightedEnemy = GetEnemiesInRange(unit).FirstOrDefault();
//Debug.Log($"Sighted: {sightedEnemy}");
if (sightedEnemy != default) {
actionPlan.TryAddActionToPlan(new FollowAction(unit.GetComponent<Weaver>(), sightedEnemy, 1f));
}
}
}
}
yield return new WaitForSeconds(_decisionFrequency);
//Debug.Log("DecideActionForAllAlertedUnits");
}
}
IEnumerable<Vector3> ProduceMoveLocations() {
while (true) {
yield return new(55, 0, 60);
yield return new(55, 0, 65);
yield return new(50, 0, 65);
yield return new(50, 0, 60);
}
}
IEnumerable<Transform> GetEnemiesInRange(Transform actingUnit) {
var hits = Physics.SphereCastAll(actingUnit.position, 5f, actingUnit.forward, 0, _unitsLayerMask);
return hits.Select(hit => hit.transform).
Where(unit => unit.TryGetComponent(out UnitControllerTarget unitControllerTarget) && unitControllerTarget.ControlledBy != _controllingUnitsOfType);
}
//protected void OnDrawGizmos() {
// LayerMask _unitsLayerMask = LayerMask.NameToLayer("units");
// Gizmos.color = Color.yellow;
// Gizmos.DrawWireSphere(transform.position, 5f);
// var hits = Physics.SphereCastAll(transform.position, 5f, transform.forward, 0, _unitsLayerMask);
// foreach (var hit in hits.Where(hit => hit.transform != transform)) {
// Gizmos.DrawLine(transform.position, hit.transform.position);
// }
//}
}
}
_transform: {fileID: 1683100414}
_accessor:
rid: 5865794024626716703
_contextAccessor:
rid: 5865794024626716705
_transforms:
- {fileID: 1683100414}
- {fileID: 1190570253}
_from:
Resource:
typeId: 7f412c19-18fe-476f-92e4-469ffad0c5d4
_location:
rid: 8942665896105607170
_to:
Resource:
typeId: da13f1c1-4359-4eb9-b969-7db50afe6423
_location:
rid: 8942665896105607172
_rg:
Resource:
rid: 8942665896105607182
Location:
rid: 8942665896105607183
ResourceType:
typeId: 7f412c19-18fe-476f-92e4-469ffad0c5d4
Multiplier: 1
Addend: 0
_rs:
Resource:
rid: 8942665896105607178
Location:
rid: 8942665896105607179
Multiplier: 1
Addend: 0
rid: 5865794024626716704
Resource:
typeId: aecc1739-a0df-4013-b430-22d2eb13f0ff
- rid: 5865794024626716704
rid: 8942665896105607171
- rid: 8942665896105607171
RegisterTypeLensCreator:
rid: 5865794024626716706
Resource:
typeId: aecc1739-a0df-4013-b430-22d2eb13f0ff
- rid: 5865794024626716706
type: {class: CurrentRegisterTypeLensCreator, ns: TagFighter.Testing.Optics,
Register:
typeId: 47eae1ff-9ff5-41fd-b08e-0f674b3848e6
Fold:
rid: 8942665896105607176
- rid: 8942665896105607176
type: {class: Max, ns: TagFighter.Effects.Operators, asm: Assembly-CSharp}
- rid: 8942665896105607178
type: {class: RedTag, ns: TagFighter.Effects.ResourceTypeAccessors, asm: Assembly-CSharp}
- rid: 8942665896105607179
type: {class: Context, ns: TagFighter.Effects.ResourceLocationAccessors.Set,
asm: Assembly-CSharp}
data:
Register:
rid: 8942665896105607180
SetAs:
rid: 8942665896105607181
- rid: 8942665896105607180
type: {class: Current, ns: TagFighter.Effects.ResourceLocationAccessors.ContextRegisters,
- rid: 8942665896105607181
type: {class: Sum, ns: TagFighter.Effects.Operators, asm: Assembly-CSharp}
- rid: 8942665896105607182
type: {class: RedTag, ns: TagFighter.Effects.ResourceTypeAccessors, asm: Assembly-CSharp}
- rid: 8942665896105607183
type: {class: Context, ns: TagFighter.Effects.ResourceLocationAccessors.Get,
asm: Assembly-CSharp}
data:
Register:
rid: 8942665896105607184
- rid: 8942665896105607184
type: {class: Current, ns: TagFighter.Effects.ResourceLocationAccessors.ContextRegisters,
asm: Assembly-CSharp}