7QKPEDFDFQJFTXM4BFJ4CFHOOZKOI6NKRRSBDLMP7SELPJMFOQRAC JMMGK6VQWZOLY6C6YWUPAIHLQXUZ2ZZTVJQAL7ODPZAWUSZQIJJAC AHVLR4STJDGDBXUW23XPHTTP24T6BMWG3FYIY7S26YYVAQYZ4CDAC VPXUP5WZTVC3OVD73TNKPK43IAGFXGUGCEJT56JM4IT4APYQXUHAC XF52N4U7HWXOF4PDSCR7LCUENLTSXLWEZGS2IJ6562KYI567Z2GAC 7BZ73FLUK5ANK44V7EMAROTHHVE2IGJ65GTA26DRWY65566HMNPAC HUULCHM5GFGZ7GKLCULFHC333LQ3LBI62VKII3YL5O4C5CDGCT4AC VZRSH4U473FCZOP5EXURPXXN5J6F3ZLT435YY7A2JHLG2ZZB5KLQC IDXWT3DH3C3X7PP4VVKUZTCGDALW6NH7KREI4E2VFQVMCBJKDMTAC XIPU27GAVXMAKDP42DDSYNA6DSN5WBHH6AG4EK6YIIM43AQQHQAAC ZZLU6UG75ALN7BYLP4SLGT4SIHDKJPFZPMNSYST25RQT3KLTFHPAC WKHLLZ3K732M7VJ5KWDSLRWZUARDNDP6ODAXD6SW43CHCT5DX5SAC QOAVQCDV2MRAPUX62ZLDTUB6AXYSAGEEWIEZIG4TGIQKCLP5T5GAC DGUHVA7XX4HWCIXCARJCI7T6VTXEJUOPUYZOLDOOOWIZYFEJQYFQC R5JJA7VQ5HCQ6TZEFMORFMPYBXTMIOBAH6YMDCG4QZKBJZCQLR4AC S5OSCH7CRN2YEKVTCTJXNLYR2B3PEGCCBUGTN2M6QOCKBNJR62NAC J75RIWLT42QXABT6GQMAVIOP5XDUF7UAGFQUSSKDIULB3LEB22EQC 62YQ7EMUYX7GS3AB6FAJDKNX53LVG6T2EH6NMVS6JV36J5VCOKIAC FNS4LRFQNFM4BCB23CYHOWA2N4MG2DEUMNK6D55BQ26TX6OJLIBQC MHN2B5YZ2Y4G3O7UOZJKFQ3SSP5HTNJCXFKCO3KYY46I2GHM3TIQC G4XIS2NEM4WHRP2775YBCLFDT7JZZS52CMEHY3PA43QSXL45XNDAC JCJJQHBBV2KJGV46NWH3RHF5XSFVZUB56DVGR5XTCUOXHWD2KCJAC JZVIQ3IPEXQ5OWCAKZQW666LXIZLMP5U247YI6Y2EJ7MDNWPGCZQC 2RUZ7TTRT7SMZT2V7YWUCCTJJXNRT2LNJ2QBBVN4RMREMOGMGMHQC MQD6ISMHW27RCHAGJUINEULYXSY3JQ3UKVQPEM5PYDMM32TUYAYQC 6TAXWREAGU2AW2MHM447UBAE6FNJFTBEGHZCAMVYRI4RKAODDLIQC RZAMG2H2NY73KZJIV4VXLJHJVSRGJDRWWZJERAI6O7AVDW64JEQQC 3JTZIZGE6WPLZCIWXXLG3SQA2LVSVP26P7U52YBMBTY2VCC6LBLAC DGC7DHJWSP6BZMDKZ6FG6YS7P2RXZWKFROBYHEX4KZCG7HFBLSUQC P5O6MKCMZL3DK7ZO5SBWTCHOQB6O2MZA5VPSCQX6X4LJQVOWYV7AC UZML3EYZI5YSVYMADFBG3HBQUQAAYVLAS4R2BIR7BOVWQKIHE4IAC FQZF2IY4T2F7KEVSHMFID35WNAU55CRRDF6XEXZB7PYZH26UGYPQC 426KOWJWOX7ZE24UIJCIHRI5KUZYO6NIGK7KC2HOONFDX242UYIQC AZN3UTBQLTKMGIHW5UCAMLC4GGHG6MAORBQ7OIR2U7NTZ53GWGNQC OXMN3LHBNH7CWHEZRPSZTN244O3ACTOEKZEAKQNKFXQ7VQSM26YQC MML56TWYWB6SUY5JEWHG2PNLAH3JY72PGCEXIGOYE54EAC2WSWBAC 4PLSNSVW4VOQW5ZXXZGUWB56WI33SXTGWOCD7PNE36OWDGD7NRJAC G4ODCLUUQ6V23B2DSMLQTRVLSBVBVO5CFZBXVZ6C3S63N7TECDHAC 4JF2MUNF23IFAVVECZNP3JJLFPEB36V7FDRQOKIZNF6Q2FAGOFRQC DTKCWM4J7PFNWAAES3RZHQGDA6PTDNX4TZVOXAKF5V7LCZBI3XUAC 2SLVO3SYIJQOEV2YNSD73BSUSWQNZVROQCGHJCPCDSMCCNKZTQFQC EF6FXKYIVJCURLSC2CLS27FCTECIIIU2EEPI352ZTCIKYKW5VOBQC VU32ZIRYU6LCQJFGN4ZA3IQ5HNY5J4PNI5OCPW24L7YBOI3BOTYAC A6K2SVTQ3JQ3TC3F44H3ERSX47TRQ6R5EJGIRJKFGKZG6I4HOATQC M2C63XUU3TKYAUPPSPEFVF4CMBQMCVLZATANFWQW35MMYNRB2SEAC VUAVVMQEUYSXHBIUJHGRX237EZFT5MCB73ZKVWMGJDRHYZH4XZKAC R475KN7MR3OG7EBLVNOO7QRIKXDGY2PIDXXV3HW4KBD5QM7B5OJQC TKLR43RQKXB47J2YVVSJ7CAZAJZYOKXSDUXAUOVQMFUN73KZVUVQC R6RQ2RKQV3YFYIRN5JED6NAFB4E34WQJRDHHKZ4JO7KLBXRKNFYAC HMDPEJRZK3PO6M5Z655Y4HWCUKC5I35GRMVVQOZYXWWCIH5ZWNPQC GBGS6RTZTCKRMLLDVCBGMRTJNNOSAUTXN5D2EMEQMQAREORE54PAC L2SE4UCTEU4R7JSHG2J5H6RZPRN4SGBMXK3WCRED2HARX5JEN2AQC UBKE7KXKA35CBKZLD366TUQXK72GYT7RLPEMMLCR4XC3TLMXD7EQC R52YYK6WMYXCCIMHE4CKMSAQO7I4AHTJ2UHK4Z3V5UHI5KQWV5IAC CD5FF75KTOBTMVMTMCKMR6F5DFKOF26I5K43ITNHGBI3ZAZHA4RAC G6KBRZNCPEBI5YF2ZJYRAFCYDO3CDGFPQBDC3I4JQEYJ4DNT234AC using System.Collections;using TagFighter;using TagFighter.Resources;using Testing.Line;using Testing.TimeDialation;using UnityEngine;using UnityEngine.AI;using UnityEngine.EventSystems;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;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();}}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;}}}if (Input.GetKeyDown(KeyCode.M)) {SystemsHandler.EffectSystem.ApplyTagsEffect(new TagCounter() { }, _affected, _affected.transform.rotation, new CircleArea() { Radius = 15 });}}void TestPhysics() {if (Input.GetKeyDown(KeyCode.T)) {if (Input.GetKey(KeyCode.LeftShift)) {Test();}else {_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;}}void Test() {TimeDialationTester timeDialationTester = new(_eventAggregator);timeDialationTester.TestAll();LineTester lineTester = new();lineTester.TestAll();}}namespace Testing.TimeDialation{public class TimeDialationTester{EventAggregator _eventAggregator;public TimeDialationTester(EventAggregator eventAggregator) {_eventAggregator = eventAggregator;}public void TestAll() {TestTimeDialationSpeedUp();TestTimeDialationSpeedDown();TestTimeDialationSpeedPause();TestTimeDialationSpeedReset();}public void TestTimeDialationSpeedUp() {var currentTimeScale = Time.timeScale;var testName = System.Reflection.MethodBase.GetCurrentMethod().Name;_eventAggregator.OnTimeDilationSpeedUp(this, System.EventArgs.Empty);if (Time.timeScale > currentTimeScale) {Debug.Log($"<color=green>PASSED: {testName}</color>");}else {Debug.Log($"<color=red>FAILED: {testName}</color>");}}public void TestTimeDialationSpeedDown() {var currentTimeScale = Time.timeScale;var testName = System.Reflection.MethodBase.GetCurrentMethod().Name;_eventAggregator.OnTimeDilationSpeedDown(this, System.EventArgs.Empty);if (Time.timeScale < currentTimeScale) {Debug.Log($"<color=green>PASSED: {testName}</color>");}else {Debug.Log($"<color=red>FAILED: {testName}</color>");}}public void TestTimeDialationSpeedPause() {var testName = System.Reflection.MethodBase.GetCurrentMethod().Name;_eventAggregator.OnTimeDilationSpeedPause(this, System.EventArgs.Empty);if (Time.timeScale == 0) {Debug.Log($"<color=green>PASSED: {testName}</color>");}else {Debug.Log($"<color=red>FAILED: {testName}</color>");}}public void TestTimeDialationSpeedReset() {var testName = System.Reflection.MethodBase.GetCurrentMethod().Name;Time.timeScale = 4;_eventAggregator.OnTimeDilationSpeedReset(this, System.EventArgs.Empty);if (Time.timeScale == 1) {Debug.Log($"<color=green>PASSED: {testName}</color>");}else {Debug.Log($"<color=red>FAILED: {testName}</color>");}}}}namespace Testing.Line{public class LineTester{public void TestAll() {TestWaitInLine();TestCutInLine();TestTryRemoveAt();TestCircularInsert();}public void TestWaitInLine() {var testName = System.Reflection.MethodBase.GetCurrentMethod().Name;var anyFail = false;int insert;int[] insertArr = { 5, 4, 3, 2, 1 };Line<int> l = new(insertArr.Length);foreach (var item in insertArr) {if (l.TryWaitInLine(item) == false) {Debug.Log($"<color=red>FAILED: {testName} {item} </color>");anyFail = true;}}insert = 0;if (l.TryWaitInLine(insert) == true) {Debug.Log($"<color=red>FAILED: {testName} {insert} </color>");anyFail = true;}if (!l.TryGetFirstOutOfLine(out var n) || (n != insertArr[0])) {Debug.Log($"<color=red>FAILED: {testName} TryGetFirstOutOfLine {insertArr[0]} </color>");anyFail = true;}int[] resultArr = { 4, 3, 2, 1 };var count = 1;foreach (var item in l) {if (item != insertArr[count]) {Debug.Log($"<color=red>FAILED: {testName} foreach {item} != {insertArr[count]} </color>");anyFail = true;}count++;}if (count != insertArr.Length) {Debug.Log($"<color=red>FAILED: {testName} incorrect number of items in Line {count != resultArr.Length}</color>");anyFail = true;}if (anyFail == false) {Debug.Log($"<color=green>PASSED: {testName} </color>");}}public void TestCutInLine() {var testName = System.Reflection.MethodBase.GetCurrentMethod().Name;var anyFail = false;int[] insertArr = { 1, 2, 3, 4, 5 };Line<int> l = new(insertArr.Length);foreach (var item in insertArr) {if (l.TryWaitInLine(item) == false) {Debug.Log($"<color=red>FAILED: {testName} {item} </color>");anyFail = true;}}var insert = 6;l.CutInLine(insert);if (l.TryWaitInLine(insert) == true) {}if (!l.TryGetFirstOutOfLine(out var n) || (n != insert)) {Debug.Log($"<color=red>FAILED: {testName} get out {insert} </color>");anyFail = true;}int[] resultArr = { 1, 2, 3, 4 };var count = 0;foreach (var item in l) {if (item != resultArr[count]) {Debug.Log($"<color=red>FAILED: {testName} foreach {item} != {resultArr[count]} </color>");anyFail = true;}count++;}if (count != resultArr.Length) {Debug.Log($"<color=red>FAILED: {testName} incorrect number of items in Line {count != resultArr.Length}</color>");anyFail = true;}if (anyFail == false) {Debug.Log($"<color=green>PASSED: {testName} </color>");}}public void TestTryRemoveAt() {var testName = System.Reflection.MethodBase.GetCurrentMethod().Name;var anyFail = false;int[] insertArr = { 1, 2, 3, 4, 5 };Line<int> l = new(insertArr.Length);foreach (var item in insertArr) {if (l.TryWaitInLine(item) == false) {Debug.Log($"<color=red>FAILED: TryWaitInLine foreach {testName} {item} </color>");anyFail = true;}}var position = 2;if (!l.TryRemoveAt(position, out var n) || n != insertArr[position]) {Debug.Log($"<color=red>FAILED: TryRemoveAt {testName} {insertArr[position]} </color>");anyFail = true;}if (l.TryWaitInLine(insertArr[position]) == false) {Debug.Log($"<color=red>FAILED: TryWaitInLine {testName} {insertArr[position]} </color>");anyFail = true;}l.CutInLine(insertArr[position]);int[] resultArr = { 3, 1, 2, 4, 5 };position = 4;if (!l.TryRemoveAt(position, out n) || n != resultArr[position]) {Debug.Log($"<color=red>FAILED: TryRemoveAt {testName} {n} != {resultArr[position]} </color>");anyFail = true;}if (l.TryWaitInLine(insertArr[position]) == false) {Debug.Log($"<color=red>FAILED: TryWaitInLine {testName} {insertArr[position]} </color>");anyFail = true;}resultArr = new int[] { 3, 1, 2, 4, insertArr[position] };if (!l.TryRemoveAt(position, out n) || n != resultArr[position]) {Debug.Log($"<color=red>FAILED: TryRemoveAt {testName} {n} != {resultArr[position]} </color>");anyFail = true;}resultArr = new int[] { 3, 1, 2, 4 };var count = 0;foreach (var item in l) {if (item != resultArr[count]) {Debug.Log($"<color=red>FAILED: {testName} foreach {item} != {resultArr[count]} </color>");anyFail = true;}count++;}if (count != resultArr.Length) {Debug.Log($"<color=red>FAILED: {testName} incorrect number of items in Line {count != resultArr.Length}</color>");anyFail = true;}if (anyFail == false) {Debug.Log($"<color=green>PASSED: {testName} </color>");}}public void TestCircularInsert() {var testName = System.Reflection.MethodBase.GetCurrentMethod().Name;var anyFail = false;int[] insertArr = { 1, 2, 3, 4, 5 };Line<int> l = new(insertArr);l.TryGetFirstOutOfLine(out var _);l.TryGetFirstOutOfLine(out var _);l.TryWaitInLine(6);l.TryWaitInLine(7);int[] resultArr = { 3, 4, 5, 6, 7 };var count = 0;foreach (var item in l) {if (item != resultArr[count]) {Debug.Log($"<color=red>FAILED: {testName} foreach {item} != {resultArr[count]} </color>");anyFail = true;}count++;}if (count != resultArr.Length) {Debug.Log($"<color=red>FAILED: {testName} incorrect number of items in Line {count != resultArr.Length} </color>");anyFail = true;}if (anyFail == false) {Debug.Log($"<color=green>PASSED: {testName} </color>");}}}}
using System.Collections;using TagFighter;using TagFighter.Resources;using Testing.Line;using Testing.TimeDialation;using UnityEngine;using UnityEngine.AI;using UnityEngine.EventSystems;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;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();}}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 TestPhysics() {if (Input.GetKeyDown(KeyCode.T)) {if (Input.GetKey(KeyCode.LeftShift)) {Test();}else {_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;}}void Test() {TimeDialationTester timeDialationTester = new(_eventAggregator);timeDialationTester.TestAll();LineTester lineTester = new();lineTester.TestAll();}}namespace Testing.TimeDialation{public class TimeDialationTester{EventAggregator _eventAggregator;public TimeDialationTester(EventAggregator eventAggregator) {_eventAggregator = eventAggregator;}public void TestAll() {TestTimeDialationSpeedUp();TestTimeDialationSpeedDown();TestTimeDialationSpeedPause();TestTimeDialationSpeedReset();}public void TestTimeDialationSpeedUp() {var currentTimeScale = Time.timeScale;var testName = System.Reflection.MethodBase.GetCurrentMethod().Name;_eventAggregator.OnTimeDilationSpeedUp(this, System.EventArgs.Empty);if (Time.timeScale > currentTimeScale) {Debug.Log($"<color=green>PASSED: {testName}</color>");}else {Debug.Log($"<color=red>FAILED: {testName}</color>");}}public void TestTimeDialationSpeedDown() {var currentTimeScale = Time.timeScale;var testName = System.Reflection.MethodBase.GetCurrentMethod().Name;_eventAggregator.OnTimeDilationSpeedDown(this, System.EventArgs.Empty);if (Time.timeScale < currentTimeScale) {Debug.Log($"<color=green>PASSED: {testName}</color>");}else {Debug.Log($"<color=red>FAILED: {testName}</color>");}}public void TestTimeDialationSpeedPause() {var testName = System.Reflection.MethodBase.GetCurrentMethod().Name;_eventAggregator.OnTimeDilationSpeedPause(this, System.EventArgs.Empty);if (Time.timeScale == 0) {Debug.Log($"<color=green>PASSED: {testName}</color>");}else {Debug.Log($"<color=red>FAILED: {testName}</color>");}}public void TestTimeDialationSpeedReset() {var testName = System.Reflection.MethodBase.GetCurrentMethod().Name;Time.timeScale = 4;_eventAggregator.OnTimeDilationSpeedReset(this, System.EventArgs.Empty);if (Time.timeScale == 1) {Debug.Log($"<color=green>PASSED: {testName}</color>");}else {Debug.Log($"<color=red>FAILED: {testName}</color>");}}}}namespace Testing.Line{public class LineTester{public void TestAll() {TestWaitInLine();TestCutInLine();TestTryRemoveAt();TestCircularInsert();}public void TestWaitInLine() {var testName = System.Reflection.MethodBase.GetCurrentMethod().Name;var anyFail = false;int insert;int[] insertArr = { 5, 4, 3, 2, 1 };Line<int> l = new(insertArr.Length);foreach (var item in insertArr) {if (l.TryWaitInLine(item) == false) {Debug.Log($"<color=red>FAILED: {testName} {item} </color>");anyFail = true;}}insert = 0;if (l.TryWaitInLine(insert) == true) {Debug.Log($"<color=red>FAILED: {testName} {insert} </color>");anyFail = true;}if (!l.TryGetFirstOutOfLine(out var n) || (n != insertArr[0])) {Debug.Log($"<color=red>FAILED: {testName} TryGetFirstOutOfLine {insertArr[0]} </color>");anyFail = true;}int[] resultArr = { 4, 3, 2, 1 };var count = 1;foreach (var item in l) {if (item != insertArr[count]) {Debug.Log($"<color=red>FAILED: {testName} foreach {item} != {insertArr[count]} </color>");anyFail = true;}count++;}if (count != insertArr.Length) {Debug.Log($"<color=red>FAILED: {testName} incorrect number of items in Line {count != resultArr.Length}</color>");anyFail = true;}if (anyFail == false) {Debug.Log($"<color=green>PASSED: {testName} </color>");}}public void TestCutInLine() {var testName = System.Reflection.MethodBase.GetCurrentMethod().Name;var anyFail = false;int[] insertArr = { 1, 2, 3, 4, 5 };Line<int> l = new(insertArr.Length);foreach (var item in insertArr) {if (l.TryWaitInLine(item) == false) {Debug.Log($"<color=red>FAILED: {testName} {item} </color>");anyFail = true;}}var insert = 6;l.CutInLine(insert);if (l.TryWaitInLine(insert) == true) {}if (!l.TryGetFirstOutOfLine(out var n) || (n != insert)) {Debug.Log($"<color=red>FAILED: {testName} get out {insert} </color>");anyFail = true;}int[] resultArr = { 1, 2, 3, 4 };var count = 0;foreach (var item in l) {if (item != resultArr[count]) {Debug.Log($"<color=red>FAILED: {testName} foreach {item} != {resultArr[count]} </color>");anyFail = true;}count++;}if (count != resultArr.Length) {Debug.Log($"<color=red>FAILED: {testName} incorrect number of items in Line {count != resultArr.Length}</color>");anyFail = true;}if (anyFail == false) {Debug.Log($"<color=green>PASSED: {testName} </color>");}}public void TestTryRemoveAt() {var testName = System.Reflection.MethodBase.GetCurrentMethod().Name;var anyFail = false;int[] insertArr = { 1, 2, 3, 4, 5 };Line<int> l = new(insertArr.Length);foreach (var item in insertArr) {if (l.TryWaitInLine(item) == false) {Debug.Log($"<color=red>FAILED: TryWaitInLine foreach {testName} {item} </color>");anyFail = true;}}var position = 2;if (!l.TryRemoveAt(position, out var n) || n != insertArr[position]) {Debug.Log($"<color=red>FAILED: TryRemoveAt {testName} {insertArr[position]} </color>");anyFail = true;}if (l.TryWaitInLine(insertArr[position]) == false) {Debug.Log($"<color=red>FAILED: TryWaitInLine {testName} {insertArr[position]} </color>");anyFail = true;}l.CutInLine(insertArr[position]);int[] resultArr = { 3, 1, 2, 4, 5 };position = 4;if (!l.TryRemoveAt(position, out n) || n != resultArr[position]) {Debug.Log($"<color=red>FAILED: TryRemoveAt {testName} {n} != {resultArr[position]} </color>");anyFail = true;}if (l.TryWaitInLine(insertArr[position]) == false) {Debug.Log($"<color=red>FAILED: TryWaitInLine {testName} {insertArr[position]} </color>");anyFail = true;}resultArr = new int[] { 3, 1, 2, 4, insertArr[position] };if (!l.TryRemoveAt(position, out n) || n != resultArr[position]) {Debug.Log($"<color=red>FAILED: TryRemoveAt {testName} {n} != {resultArr[position]} </color>");anyFail = true;}resultArr = new int[] { 3, 1, 2, 4 };var count = 0;foreach (var item in l) {if (item != resultArr[count]) {Debug.Log($"<color=red>FAILED: {testName} foreach {item} != {resultArr[count]} </color>");anyFail = true;}count++;}if (count != resultArr.Length) {Debug.Log($"<color=red>FAILED: {testName} incorrect number of items in Line {count != resultArr.Length}</color>");anyFail = true;}if (anyFail == false) {Debug.Log($"<color=green>PASSED: {testName} </color>");}}public void TestCircularInsert() {var testName = System.Reflection.MethodBase.GetCurrentMethod().Name;var anyFail = false;int[] insertArr = { 1, 2, 3, 4, 5 };Line<int> l = new(insertArr);l.TryGetFirstOutOfLine(out var _);l.TryGetFirstOutOfLine(out var _);l.TryWaitInLine(6);l.TryWaitInLine(7);int[] resultArr = { 3, 4, 5, 6, 7 };var count = 0;foreach (var item in l) {if (item != resultArr[count]) {Debug.Log($"<color=red>FAILED: {testName} foreach {item} != {resultArr[count]} </color>");anyFail = true;}count++;}if (count != resultArr.Length) {Debug.Log($"<color=red>FAILED: {testName} incorrect number of items in Line {count != resultArr.Length} </color>");anyFail = true;}if (anyFail == false) {Debug.Log($"<color=green>PASSED: {testName} </color>");}}}}
using UnityEngine;public interface IEffectSystem{void ApplyTagsEffect(TagCounter tags, Transform origin, Quaternion direction, IAreaOfEffect areaOfEffect);Color GetEffectColor(TagCounter tags);Mesh CreateArcMesh(Vector3 direction, float arc, float length, int numberOfVerticesInArc, Vector3 rotationAxis);Mesh CreateQuadMesh(Vector3 direction, float width, float length, Vector3 rotationAxis);}
using System.Collections.Generic;using TagFighter.Resources;using UnityEngine;using System;public interface IEffectSystem{void ApplyTagsEffect(IEnumerable<(Type, IUnit)> tags, Transform origin, Quaternion direction, IAreaOfEffect areaOfEffect);Color GetEffectColor(IEnumerable<(Type, IUnit)> tags);Mesh CreateArcMesh(Vector3 direction, float arc, float length, int numberOfVerticesInArc, Vector3 rotationAxis);Mesh CreateQuadMesh(Vector3 direction, float width, float length, Vector3 rotationAxis);}
using System;using System.Collections;using UnityEngine;[Serializable]public class EffectSystem : IEffectSystem{ParticleSystem _rippleOutVfx;const string PulseMaterial = "Materials/PulseMaterial2";class EffectRunner : MonoBehaviour{public GameObject EffectObj;public Material Material;public float PlayTime;public void Run(GameObject effectObj, Material material, float playTime) {EffectObj = effectObj;Material = material;PlayTime = playTime;Material.SetFloat("_Phase", 0);EffectObj.SetActive(true);StartCoroutine("PlayEffect");}public IEnumerator PlayEffect() {float totalTime = 0;float phase = 0;while (phase < 0.98) {totalTime += Time.deltaTime;phase = totalTime / PlayTime;Material.SetFloat("_Phase", phase);yield return null;}Destroy(EffectObj);}}public EffectSystem() {}public void ApplyTagsEffect(TagCounter tags, Transform origin, Quaternion direction, IAreaOfEffect areaOfEffect) {switch (areaOfEffect) {case SingleTarget: ApplyTagsEffectSingle(); break;case CircleArea aoe: ApplyTagsEffectRadius(tags, origin, direction, aoe); break;case ConeArea aoe: ApplyTagsEffectCone(tags, origin, direction, aoe); break;case PathArea aoe: ApplyTagsEffectPath(tags, origin, direction, aoe); break;}}void ApplyTagsEffectSingle() {Debug.Log("ApplyTagsEffectSingle");}void ApplyTagsEffectPath(TagCounter tags, Transform origin, Quaternion direction, PathArea areaOfEffect) {var color = GetEffectColor(tags);var mesh = CreateQuadMeshForUnit(origin, areaOfEffect.Width, areaOfEffect.Length);// Add a new to clone the shared resourceMaterial material = new(Resources.Load<Material>(PulseMaterial));material.SetColor("_Color", color);DisplayEffect(origin, direction, mesh, material);}void ApplyTagsEffectRadius(TagCounter tags, Transform origin, Quaternion direction, CircleArea areaOfEffect) {var color = GetEffectColor(tags);var mesh = CreateArcMeshForUnit(origin, 360, areaOfEffect.Radius);// Add a new to clone the shared resourceMaterial material = new(Resources.Load<Material>(PulseMaterial));material.SetColor("_Color", color);DisplayEffect(origin, direction, mesh, material);}void ApplyTagsEffectCone(TagCounter tags, Transform origin, Quaternion direction, ConeArea areaOfEffect) {Debug.Log("ApplyTagsEffectCone");var color = GetEffectColor(tags);var mesh = CreateArcMeshForUnit(origin, areaOfEffect.Angle, areaOfEffect.Radius);// Add a new to clone the shared resourceMaterial material = new(Resources.Load<Material>(PulseMaterial));material.SetColor("_Color", color);DisplayEffect(origin, direction, mesh, material);}public Color GetEffectColor(TagCounter tags) {var total = tags[TagColor.Red] + tags[TagColor.Green] + tags[TagColor.Blue];var red = tags[TagColor.Red] / total;var green = tags[TagColor.Green] / total;var blue = tags[TagColor.Blue] / total;Color color = new(red, green, blue);return color;}public Mesh CreateArcMeshForUnit(Transform unit, float arc, float length, int numberOfVerticesInArc = 100) {return CreateArcMesh(unit.forward, arc, length, numberOfVerticesInArc, Vector3.up);}public Mesh CreateQuadMeshForUnit(Transform unit, float width, float length) {return CreateQuadMesh(unit.forward, width, length, Vector3.up);}void DisplayEffect(Transform originUnit, Quaternion direction, Mesh mesh, Material material) {GameObject effectObj = new();effectObj.SetActive(false);effectObj.transform.position = originUnit.position;effectObj.transform.rotation = direction;var meshRenderer = effectObj.AddComponent<MeshRenderer>();meshRenderer.sharedMaterial = material;meshRenderer.shadowCastingMode = 0;meshRenderer.receiveShadows = false;var meshFilter = effectObj.AddComponent<MeshFilter>();meshFilter.mesh = mesh;effectObj.AddComponent<EffectRunner>();var effectRunner = effectObj.GetComponent<EffectRunner>();effectRunner.Run(effectObj, material, 1f);}public Mesh CreateArcMesh(Vector3 direction, float arc, float length, int numberOfVerticesInArc, Vector3 rotationAxis) {var origin = Vector3.zero;Mesh mesh = new();var n = numberOfVerticesInArc + 1;var arcStep = arc / (n - 2);var currentDegrees = -arc / 2;var vertices = new Vector3[n];var uv = new Vector2[n];vertices[0] = origin;uv[0] = origin;for (var i = 1; i < n; i++) {vertices[i] = Quaternion.AngleAxis(currentDegrees, rotationAxis) * direction * length;uv[i] = new Vector2(0, 1);//Debug.Log($"Current Degrees: {currentDegrees} -> {vertices[i]}");currentDegrees += arcStep;}mesh.vertices = vertices;mesh.uv = uv;var tris = new int[(n - 2) * 3];for (var i = 0; i < n - 2; i++) {tris[i * 3] = 0;tris[i * 3 + 1] = i + 1;tris[i * 3 + 2] = i + 2;}mesh.triangles = tris;var normals = new Vector3[n];for (var i = 0; i < n; i++) {normals[i] = rotationAxis;}mesh.normals = normals;return mesh;}public Mesh CreateQuadMesh(Vector3 direction, float width, float length, Vector3 rotationAxis) {Mesh mesh = new();var origin = Vector3.zero;// TODO: how to calculate local rotation? directionvar vertices = new Vector3[4]{new Vector3(-width/2, 0, 0) + origin,new Vector3(width/2, 0, 0) + origin,new Vector3(-width/2, 0, length) + origin,new Vector3(width/2, 0, length) + origin};mesh.vertices = vertices;var tris = new int[6]{// lower left triangle0, 2, 1,// upper right triangle2, 3, 1};mesh.triangles = tris;var normals = new Vector3[4]{rotationAxis,rotationAxis,rotationAxis,rotationAxis};mesh.normals = normals;var uv = new Vector2[4]{new Vector2(0, 0),new Vector2(1, 0),new Vector2(0, 1),new Vector2(1, 1)};mesh.uv = uv;return mesh;}}
using System;using System.Collections;using System.Collections.Generic;using System.Linq;using TagFighter.Resources;using UnityEngine;[Serializable]public class EffectSystem : IEffectSystem{ParticleSystem _rippleOutVfx;[SerializeField] TagFighter.Effects.EffectColors _colorMapping;const string PulseMaterial = "Materials/PulseMaterial2";class EffectRunner : MonoBehaviour{public GameObject EffectObj;public Material Material;public float PlayTime;public void Run(GameObject effectObj, Material material, float playTime) {EffectObj = effectObj;Material = material;PlayTime = playTime;Material.SetFloat("_Phase", 0);EffectObj.SetActive(true);StartCoroutine("PlayEffect");}public IEnumerator PlayEffect() {float totalTime = 0;float phase = 0;while (phase < 0.98) {totalTime += Time.deltaTime;phase = totalTime / PlayTime;Material.SetFloat("_Phase", phase);yield return null;}Destroy(EffectObj);}}public EffectSystem() {}public void ApplyTagsEffect(IEnumerable<(Type, IUnit)> tags, Transform origin, Quaternion direction, IAreaOfEffect areaOfEffect) {switch (areaOfEffect) {case SingleTarget: ApplyTagsEffectSingle(); break;case CircleArea aoe: ApplyTagsEffectRadius(tags, origin, direction, aoe); break;case ConeArea aoe: ApplyTagsEffectCone(tags, origin, direction, aoe); break;case PathArea aoe: ApplyTagsEffectPath(tags, origin, direction, aoe); break;}}void ApplyTagsEffectSingle() {Debug.Log("ApplyTagsEffectSingle");}void ApplyTagsEffectPath(IEnumerable<(Type, IUnit)> tags, Transform origin, Quaternion direction, PathArea areaOfEffect) {var color = GetEffectColor(tags);var mesh = CreateQuadMeshForUnit(origin, areaOfEffect.Width, areaOfEffect.Length);// Add a new to clone the shared resourceMaterial material = new(Resources.Load<Material>(PulseMaterial));material.SetColor("_Color", color);DisplayEffect(origin, direction, mesh, material);}void ApplyTagsEffectRadius(IEnumerable<(Type, IUnit)> tags, Transform origin, Quaternion direction, CircleArea areaOfEffect) {var color = GetEffectColor(tags);var mesh = CreateArcMeshForUnit(origin, 360, areaOfEffect.Radius);// Add a new to clone the shared resourceMaterial material = new(Resources.Load<Material>(PulseMaterial));material.SetColor("_Color", color);DisplayEffect(origin, direction, mesh, material);}void ApplyTagsEffectCone(IEnumerable<(Type, IUnit)> tags, Transform origin, Quaternion direction, ConeArea areaOfEffect) {Debug.Log("ApplyTagsEffectCone");var color = GetEffectColor(tags);var mesh = CreateArcMeshForUnit(origin, areaOfEffect.Angle, areaOfEffect.Radius);// Add a new to clone the shared resourceMaterial material = new(Resources.Load<Material>(PulseMaterial));material.SetColor("_Color", color);DisplayEffect(origin, direction, mesh, material);}public Color GetEffectColor(IEnumerable<(Type, IUnit)> tags) {Debug.Log("GetEffectColor");var color = new Color();Debug.Log($"GetEffectColor length {tags.Count()}");foreach (var tag in tags) {Debug.Log("GetEffectColor tag");if (_colorMapping.ContainsKey(tag.Item1)) {Debug.Log("GetEffectColor mapping found");var mappedColor = _colorMapping[tag.Item1];// TODO: scale color by amountcolor += mappedColor ;}}Debug.Log("GetEffectColor Finished");return color;}public Mesh CreateArcMeshForUnit(Transform unit, float arc, float length, int numberOfVerticesInArc = 100) {return CreateArcMesh(unit.forward, arc, length, numberOfVerticesInArc, Vector3.up);}public Mesh CreateQuadMeshForUnit(Transform unit, float width, float length) {return CreateQuadMesh(unit.forward, width, length, Vector3.up);}void DisplayEffect(Transform originUnit, Quaternion direction, Mesh mesh, Material material) {GameObject effectObj = new();effectObj.SetActive(false);effectObj.transform.position = originUnit.position;effectObj.transform.rotation = direction;var meshRenderer = effectObj.AddComponent<MeshRenderer>();meshRenderer.sharedMaterial = material;meshRenderer.shadowCastingMode = 0;meshRenderer.receiveShadows = false;var meshFilter = effectObj.AddComponent<MeshFilter>();meshFilter.mesh = mesh;effectObj.AddComponent<EffectRunner>();var effectRunner = effectObj.GetComponent<EffectRunner>();effectRunner.Run(effectObj, material, 1f);}public Mesh CreateArcMesh(Vector3 direction, float arc, float length, int numberOfVerticesInArc, Vector3 rotationAxis) {var origin = Vector3.zero;Mesh mesh = new();var n = numberOfVerticesInArc + 1;var arcStep = arc / (n - 2);var currentDegrees = -arc / 2;var vertices = new Vector3[n];var uv = new Vector2[n];vertices[0] = origin;uv[0] = origin;for (var i = 1; i < n; i++) {vertices[i] = Quaternion.AngleAxis(currentDegrees, rotationAxis) * direction * length;uv[i] = new Vector2(0, 1);//Debug.Log($"Current Degrees: {currentDegrees} -> {vertices[i]}");currentDegrees += arcStep;}mesh.vertices = vertices;mesh.uv = uv;var tris = new int[(n - 2) * 3];for (var i = 0; i < n - 2; i++) {tris[i * 3] = 0;tris[i * 3 + 1] = i + 1;tris[i * 3 + 2] = i + 2;}mesh.triangles = tris;var normals = new Vector3[n];for (var i = 0; i < n; i++) {normals[i] = rotationAxis;}mesh.normals = normals;return mesh;}public Mesh CreateQuadMesh(Vector3 direction, float width, float length, Vector3 rotationAxis) {Mesh mesh = new();var origin = Vector3.zero;// TODO: how to calculate local rotation? directionvar vertices = new Vector3[4]{new Vector3(-width/2, 0, 0) + origin,new Vector3(width/2, 0, 0) + origin,new Vector3(-width/2, 0, length) + origin,new Vector3(width/2, 0, length) + origin};mesh.vertices = vertices;var tris = new int[6]{// lower left triangle0, 2, 1,// upper right triangle2, 3, 1};mesh.triangles = tris;var normals = new Vector3[4]{rotationAxis,rotationAxis,rotationAxis,rotationAxis};mesh.normals = normals;var uv = new Vector2[4]{new Vector2(0, 0),new Vector2(1, 0),new Vector2(0, 1),new Vector2(1, 1)};mesh.uv = uv;return mesh;}}
using UnityEngine;class DummyEffectSystem : IEffectSystem{public void ApplyTagsEffect(TagCounter tags, Transform origin, Quaternion direction, IAreaOfEffect areaOfEffect) {Debug.Log("Dummy:ApplyTagsEffect");}public Color GetEffectColor(TagCounter tags) {Debug.Log("Dummy:GetEffectColor");return Color.cyan;}public Mesh CreateArcMesh(Vector3 direction, float arc, float length, int numberOfVerticesInArc, Vector3 rotationAxis) {Debug.Log("Dummy:CreateArcMesh");return null;}public Mesh CreateQuadMesh(Vector3 direction, float width, float length, Vector3 rotationAxis) {Debug.Log("Dummy:CreateQuadMesh");return null;}}
using System.Collections.Generic;using TagFighter.Resources;using UnityEngine;using System;class DummyEffectSystem : IEffectSystem{public void ApplyTagsEffect(IEnumerable<(Type, IUnit)> tags, Transform origin, Quaternion direction, IAreaOfEffect areaOfEffect) {Debug.Log("Dummy:ApplyTagsEffect");}public Color GetEffectColor(IEnumerable<(Type, IUnit)> tags) {Debug.Log("Dummy:GetEffectColor");return Color.cyan;}public Mesh CreateArcMesh(Vector3 direction, float arc, float length, int numberOfVerticesInArc, Vector3 rotationAxis) {Debug.Log("Dummy:CreateArcMesh");return null;}public Mesh CreateQuadMesh(Vector3 direction, float width, float length, Vector3 rotationAxis) {Debug.Log("Dummy:CreateQuadMesh");return null;}}
using System;using UnityEngine;namespace TagFighter.Resources{public interface IUnit { }[Serializable]public struct Unit<TUnitType> : IUnit, IEquatable<Unit<TUnitType>>, IComparable<Unit<TUnitType>> where TUnitType : IUnitType{[SerializeField] int _value;Unit(int value) => _value = value;public int AsPrimitive() => _value;public static explicit operator Unit<TUnitType>(int value) => new(value);public static explicit operator int(Unit<TUnitType> resource) => resource._value;public static bool operator ==(Unit<TUnitType> a, Unit<TUnitType> b) => a._value == b._value;public int CompareTo(Unit<TUnitType> other) => _value.CompareTo(other._value);public static bool operator >(Unit<TUnitType> a, Unit<TUnitType> b) => a._value > b._value;public static bool operator <(Unit<TUnitType> a, Unit<TUnitType> b) => a._value < b._value;public static bool operator !=(Unit<TUnitType> a, Unit<TUnitType> b) => !(a == b);public static bool operator >=(Unit<TUnitType> a, Unit<TUnitType> b) => !(a < b);public static bool operator <=(Unit<TUnitType> a, Unit<TUnitType> b) => !(a > b);public static Unit<TUnitType> operator ++(in Unit<TUnitType> a) => (Unit<TUnitType>)(a._value + 1);public static Unit<TUnitType> operator --(in Unit<TUnitType> a) => (Unit<TUnitType>)(a._value - 1);public static Unit<TUnitType> operator +(Unit<TUnitType> a, Unit<TUnitType> b) => (Unit<TUnitType>)(a._value + b._value);public static Unit<TUnitType> operator -(Unit<TUnitType> a, Unit<TUnitType> b) => (Unit<TUnitType>)(a._value - b._value);public static float operator /(Unit<TUnitType> a, Unit<TUnitType> b) => a._value / (float)b._value;public static Unit<TUnitType> operator /(Unit<TUnitType> a, int b) => a / (float)b;public static Unit<TUnitType> operator /(Unit<TUnitType> a, float b) => a / (float)b;public static Unit<TUnitType> operator *(Unit<TUnitType> a, float b) => (Unit<TUnitType>)(int)(a._value * b);public override bool Equals(object obj) => obj is Unit<TUnitType> other && _value.Equals(other._value);public bool Equals(Unit<TUnitType> other) => _value.Equals(other._value);public override int GetHashCode() => HashCode.Combine(_value);public override string ToString() => _value.ToString();public static Unit<TUnitType> Min(Unit<TUnitType> a, Unit<TUnitType> b) => (Unit<TUnitType>)Math.Min(a._value, b._value);public static Unit<TUnitType> Max(Unit<TUnitType> a, Unit<TUnitType> b) => (Unit<TUnitType>)Math.Max(a._value, b._value);public static Unit<TUnitType> Clamp(Unit<TUnitType> value, Unit<TUnitType> min, Unit<TUnitType> max) => (Unit<TUnitType>)Math.Clamp(value._value, min._value, max._value);}public interface IUnitType { }public sealed class PainUnit : IUnitType { }public sealed class FatigueUnit : IUnitType { }// public class StrainUnit : IUnit { }public sealed class RedTagUnit : IUnitType { }public sealed class BlueTagUnit : IUnitType { }public sealed class GreenTagUnit : IUnitType { }public sealed class Centimeter : IUnitType { }public sealed class RecklessFormKP : IUnitType { }public sealed class SwordKP : IUnitType { }public sealed class ShieldKP : IUnitType { }}
using System;using UnityEngine;namespace TagFighter.Resources{public interface IUnit { public int AsPrimitive(); }[Serializable]public struct Unit<TUnitType> : IUnit, IEquatable<Unit<TUnitType>>, IComparable<Unit<TUnitType>> where TUnitType : IUnitType{[SerializeField] int _value;Unit(int value) => _value = value;public int AsPrimitive() => _value;public static explicit operator Unit<TUnitType>(int value) => new(value);public static explicit operator int(Unit<TUnitType> resource) => resource._value;public static bool operator ==(Unit<TUnitType> a, Unit<TUnitType> b) => a._value == b._value;public int CompareTo(Unit<TUnitType> other) => _value.CompareTo(other._value);public static bool operator >(Unit<TUnitType> a, Unit<TUnitType> b) => a._value > b._value;public static bool operator <(Unit<TUnitType> a, Unit<TUnitType> b) => a._value < b._value;public static bool operator !=(Unit<TUnitType> a, Unit<TUnitType> b) => !(a == b);public static bool operator >=(Unit<TUnitType> a, Unit<TUnitType> b) => !(a < b);public static bool operator <=(Unit<TUnitType> a, Unit<TUnitType> b) => !(a > b);public static Unit<TUnitType> operator ++(in Unit<TUnitType> a) => (Unit<TUnitType>)(a._value + 1);public static Unit<TUnitType> operator --(in Unit<TUnitType> a) => (Unit<TUnitType>)(a._value - 1);public static Unit<TUnitType> operator +(Unit<TUnitType> a, Unit<TUnitType> b) => (Unit<TUnitType>)(a._value + b._value);public static Unit<TUnitType> operator -(Unit<TUnitType> a, Unit<TUnitType> b) => (Unit<TUnitType>)(a._value - b._value);public static float operator /(Unit<TUnitType> a, Unit<TUnitType> b) => a._value / (float)b._value;public static Unit<TUnitType> operator /(Unit<TUnitType> a, int b) => a / (float)b;public static Unit<TUnitType> operator /(Unit<TUnitType> a, float b) => a / (float)b;public static Unit<TUnitType> operator *(Unit<TUnitType> a, float b) => (Unit<TUnitType>)(int)(a._value * b);public override bool Equals(object obj) => obj is Unit<TUnitType> other && _value.Equals(other._value);public bool Equals(Unit<TUnitType> other) => _value.Equals(other._value);public override int GetHashCode() => HashCode.Combine(_value);public override string ToString() => _value.ToString();public static Unit<TUnitType> Min(Unit<TUnitType> a, Unit<TUnitType> b) => (Unit<TUnitType>)Math.Min(a._value, b._value);public static Unit<TUnitType> Max(Unit<TUnitType> a, Unit<TUnitType> b) => (Unit<TUnitType>)Math.Max(a._value, b._value);public static Unit<TUnitType> Clamp(Unit<TUnitType> value, Unit<TUnitType> min, Unit<TUnitType> max) => (Unit<TUnitType>)Math.Clamp(value._value, min._value, max._value);}public interface IUnitType { }public sealed class PainUnit : IUnitType { }public sealed class FatigueUnit : IUnitType { }// public class StrainUnit : IUnit { }public sealed class RedTagUnit : IUnitType { }public sealed class BlueTagUnit : IUnitType { }public sealed class GreenTagUnit : IUnitType { }public sealed class Centimeter : IUnitType { }public sealed class RecklessFormKP : IUnitType { }public sealed class SwordKP : IUnitType { }public sealed class ShieldKP : IUnitType { }}
using System;namespace TagFighter.Resources{[Serializable]public sealed class SwordKnowledge : Resource<SwordKP> { }}
using System;using System.Runtime.InteropServices;using CareBoo.Serially;namespace TagFighter.Resources{[Guid("F18D2C2B-4AA0-45EA-8137-70D85F067FFA")][Serializable][ProvideSourceInfo()]public sealed class SwordKnowledge : Resource<SwordKP> { }}
using System;namespace TagFighter.Resources{[Serializable]public sealed class ShieldKnowledge : Resource<ShieldKP> { }}
using System;using System.Runtime.InteropServices;using CareBoo.Serially;namespace TagFighter.Resources{[Guid("18751303-04F3-47B4-B66D-9E734E55F0E8")][Serializable][ProvideSourceInfo()]public sealed class ShieldKnowledge : Resource<ShieldKP> { }}
using System;namespace TagFighter.Resources{[Serializable]public sealed class RedTag : Resource<RedTagUnit> { }}
using System;using System.Runtime.InteropServices;using CareBoo.Serially;namespace TagFighter.Resources{[Guid("7F412C19-18FE-476F-92E4-469FFAD0C5D4")][Serializable][ProvideSourceInfo()]public sealed class RedTag : Resource<RedTagUnit> { }}
using System;namespace TagFighter.Resources{[Serializable]public sealed class RecklessFormKnowledge : Resource<RecklessFormKP> { }}
using System;using System.Runtime.InteropServices;using CareBoo.Serially;namespace TagFighter.Resources{[Guid("4B8E4C4F-03D6-4102-9936-AC66DD899EE2")][Serializable][ProvideSourceInfo()]public sealed class RecklessFormKnowledge : Resource<RecklessFormKP> { }}
using System;namespace TagFighter.Resources{[Serializable]public sealed class Range : Resource<Centimeter> { }public static class CentimeterExtensions{public static float ToMeter(this Unit<Centimeter> source) {return source.AsPrimitive() * 0.01f;}}}
using System;using System.Runtime.InteropServices;using CareBoo.Serially;namespace TagFighter.Resources{[Guid("CF53C617-F396-4C4F-9317-F935188D525C")][Serializable][ProvideSourceInfo()]public sealed class Range : Resource<Centimeter> { }public static class CentimeterExtensions{public static float ToMeter(this Unit<Centimeter> source) {return source.AsPrimitive() * 0.01f;}}}
using System;namespace TagFighter.Resources{[Serializable]public sealed class Pain : Resource<PainUnit> { }}
using System;using System.Runtime.InteropServices;using CareBoo.Serially;namespace TagFighter.Resources{[Guid("30A0DDC8-3FCF-496A-B578-81DBF333C7EC")][Serializable][ProvideSourceInfo()]public sealed class Pain : Resource<PainUnit> { }}
using System;namespace TagFighter.Resources{[Serializable]public sealed class GreenTag : Resource<GreenTagUnit> { }}
using System;using System.Runtime.InteropServices;using CareBoo.Serially;namespace TagFighter.Resources{[Guid("DA13F1C1-4359-4EB9-B969-7DB50AFE6423")][Serializable][ProvideSourceInfo()]public sealed class GreenTag : Resource<GreenTagUnit> { }}
using System;namespace TagFighter.Resources{[Serializable]public sealed class Fatigue : Resource<FatigueUnit> { }}
using System;using System.Runtime.InteropServices;using CareBoo.Serially;namespace TagFighter.Resources{[Guid("59A26139-CA50-4E6F-8AC0-27DFB70CCB8B")][Serializable][ProvideSourceInfo()]public sealed class Fatigue : Resource<FatigueUnit> { }}
using System;namespace TagFighter.Resources{[Serializable]public sealed class BlueTag : Resource<BlueTagUnit> { }}
using System;using System.Runtime.InteropServices;using CareBoo.Serially;namespace TagFighter.Resources{[Guid("AECC1739-A0DF-4013-B430-22D2EB13F0FF")][Serializable][ProvideSourceInfo()]public sealed class BlueTag : Resource<BlueTagUnit> { }}
using System;using System.Collections.Generic;using System.Linq;using TagFighter.Effects;using TagFighter.Martial;using UnityEngine;[Serializable]public class MartialSequence : ISequence{[UnityEngine.Serialization.FormerlySerializedAs("combatMoveRefs")][SerializeField] List<CombatMoveRef> _combatMoveRefs;public MartialSequence(IEnumerable<CombatMoveRef> combatMoveRefsSequence) {_combatMoveRefs = combatMoveRefsSequence.ToList();}public bool Advance(ITimeContextContainer timeContextContainer, EffectContext effectContext, float deltaTime) {var timeContext = timeContextContainer.GetTimeContext<MartialSequence>();if (timeContext.CurrentIdx >= _combatMoveRefs.Count) {Debug.Log($"Executed Martial Sequence {timeContext.CurrentIdx}/{_combatMoveRefs.Count} moves in {timeContext.CurrentTime} seconds");return false;}timeContext.CurrentTime += deltaTime;while ((timeContext.CurrentIdx < _combatMoveRefs.Count) && (timeContext.CurrentTime - timeContext.LastTime >= _combatMoveRefs[timeContext.CurrentIdx].CombatMove.Speed)) {Debug.Log($"Finished executing Martial move {_combatMoveRefs[timeContext.CurrentIdx].CombatMove.MoveName} {timeContext.CurrentIdx + 1}/{_combatMoveRefs.Count} at {timeContext.CurrentTime}");// TODO : Actual Execute MovetimeContext.LastTime += _combatMoveRefs[timeContext.CurrentIdx].CombatMove.Speed;timeContext.CurrentIdx++;}SetReleaseMultiplier(timeContextContainer, effectContext);return true;}void SetReleaseMultiplier(ITimeContextContainer timeContextContainer, EffectContext context) {var currentMove = GetCurrentMove(timeContextContainer);if (currentMove == null) {return;}var caster = context.Caster;var animator = caster.gameObject.GetComponentInChildren<Animator>();var currentAnimationState = animator.GetCurrentAnimatorStateInfo(0);var posInAnimation = currentAnimationState.normalizedTime;Debug.Log($"posInAnimation {posInAnimation}");var positionalReleaseMultiplier = 1f;if ((currentMove.StartReleaseNormalized < posInAnimation) && (posInAnimation < currentMove.EndReleaseNormalized)) {// this means we're in the maximal release sectionpositionalReleaseMultiplier = 1f;}else if (posInAnimation < currentMove.StartReleaseNormalized) {// otherwise, get a partial bonus in reletaion to how close we are to the relesepositionalReleaseMultiplier = posInAnimation / currentMove.StartReleaseNormalized;}else if (currentMove.EndReleaseNormalized < posInAnimation) {// otherwise, get a partial bonus in reletaion to how far we are from the releasepositionalReleaseMultiplier = (1 - posInAnimation) / (1 - currentMove.EndReleaseNormalized);}// Debug.Log($"positionalReleaseMultiplier {positionalReleaseMultiplier}");context.ReleaseMultiplier = new() {MatchingAoe = currentMove.MatchingAoe,MatchingAoeReleaseMultiplier = currentMove.MatchingAoeReleaseMultiplier * positionalReleaseMultiplier,NonMatchingAoeReleaseMultiplier = currentMove.NonMatchingAoeReleaseMultiplier * positionalReleaseMultiplier,};}public void Simulate() {}public CombatMove GetCurrentMove(ITimeContextContainer timeContextContainer) {if (timeContextContainer == null) {return null;}var timeContext = timeContextContainer.GetTimeContext<MartialSequence>();CombatMove move = default;if (timeContext.CurrentIdx < _combatMoveRefs.Count) {move = _combatMoveRefs[timeContext.CurrentIdx];}return move;}public IEnumerable<CombatMoveRef> GetSequence() => _combatMoveRefs;public float CompletionStatus(ITimeContextContainer timeContextContainer) {if (timeContextContainer == null) {return 0;}var timeContext = timeContextContainer.GetTimeContext<MartialSequence>();return timeContext.CurrentTime / _combatMoveRefs.Sum((move) => move.CombatMove.Speed);}}
using System;using System.Collections.Generic;using System.Linq;using TagFighter.Effects;using TagFighter.Martial;using UnityEngine;[Serializable]public class MartialSequence : ISequence{[UnityEngine.Serialization.FormerlySerializedAs("combatMoveRefs")][SerializeField] List<CombatMoveRef> _combatMoveRefs;public MartialSequence(IEnumerable<CombatMoveRef> combatMoveRefsSequence) {_combatMoveRefs = combatMoveRefsSequence.ToList();}public bool Advance(ITimeContextContainer timeContextContainer, EffectContext effectContext, float deltaTime) {var timeContext = timeContextContainer.GetTimeContext<MartialSequence>();if (timeContext.CurrentIdx >= _combatMoveRefs.Count) {Debug.Log($"Executed Martial Sequence {timeContext.CurrentIdx}/{_combatMoveRefs.Count} moves in {timeContext.CurrentTime} seconds");return false;}timeContext.CurrentTime += deltaTime;while ((timeContext.CurrentIdx < _combatMoveRefs.Count) && (timeContext.CurrentTime - timeContext.LastTime >= _combatMoveRefs[timeContext.CurrentIdx].CombatMove.Speed)) {Debug.Log($"Finished executing Martial move {_combatMoveRefs[timeContext.CurrentIdx].CombatMove.MoveName} {timeContext.CurrentIdx + 1}/{_combatMoveRefs.Count} at {timeContext.CurrentTime}");// TODO : Actual Execute MovetimeContext.LastTime += _combatMoveRefs[timeContext.CurrentIdx].CombatMove.Speed;timeContext.CurrentIdx++;}SetReleaseMultiplier(timeContextContainer, effectContext);return true;}void SetReleaseMultiplier(ITimeContextContainer timeContextContainer, EffectContext context) {var currentMove = GetCurrentMove(timeContextContainer);if (currentMove == null) {return;}var caster = context.Caster;var animator = caster.gameObject.GetComponentInChildren<Animator>();var currentAnimationState = animator.GetCurrentAnimatorStateInfo(0);var posInAnimation = currentAnimationState.normalizedTime;//Debug.Log($"posInAnimation {posInAnimation}");var positionalReleaseMultiplier = 1f;if ((currentMove.StartReleaseNormalized < posInAnimation) && (posInAnimation < currentMove.EndReleaseNormalized)) {// this means we're in the maximal release sectionpositionalReleaseMultiplier = 1f;}else if (posInAnimation < currentMove.StartReleaseNormalized) {// otherwise, get a partial bonus in reletaion to how close we are to the relesepositionalReleaseMultiplier = posInAnimation / currentMove.StartReleaseNormalized;}else if (currentMove.EndReleaseNormalized < posInAnimation) {// otherwise, get a partial bonus in reletaion to how far we are from the releasepositionalReleaseMultiplier = (1 - posInAnimation) / (1 - currentMove.EndReleaseNormalized);}// Debug.Log($"positionalReleaseMultiplier {positionalReleaseMultiplier}");context.ReleaseMultiplier = new() {MatchingAoe = currentMove.MatchingAoe,MatchingAoeReleaseMultiplier = currentMove.MatchingAoeReleaseMultiplier * positionalReleaseMultiplier,NonMatchingAoeReleaseMultiplier = currentMove.NonMatchingAoeReleaseMultiplier * positionalReleaseMultiplier,};}public void Simulate() {}public CombatMove GetCurrentMove(ITimeContextContainer timeContextContainer) {if (timeContextContainer == null) {return null;}var timeContext = timeContextContainer.GetTimeContext<MartialSequence>();CombatMove move = default;if (timeContext.CurrentIdx < _combatMoveRefs.Count) {move = _combatMoveRefs[timeContext.CurrentIdx];}return move;}public IEnumerable<CombatMoveRef> GetSequence() => _combatMoveRefs;public float CompletionStatus(ITimeContextContainer timeContextContainer) {if (timeContextContainer == null) {return 0;}var timeContext = timeContextContainer.GetTimeContext<MartialSequence>();return timeContext.CurrentTime / _combatMoveRefs.Sum((move) => move.CombatMove.Speed);}}
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, TRegisterType>();}public void Set<TResource, TUnit>(EffectContext context, Unit<TUnit> value)where TResource : Resource<TUnit>where TUnit : IUnitType {context.SetResource<TResource, TUnit, TRegisterType>(value);}public override string ToString() => typeof(TRegisterType).Name;}[Serializable] public sealed class Current : ContextRegister<CurrentRegisterType> { }[Serializable] public sealed class Added : ContextRegister<AddedRegisterType> { }[Serializable] public sealed class Removed : ContextRegister<RemovedRegisterType> { }}namespace Get{using ContextRegisters;[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;[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 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;}[Serializable] public sealed class Current : ContextRegister<CurrentRegisterType> { }[Serializable] public sealed class Added : ContextRegister<AddedRegisterType> { }[Serializable] public sealed class Removed : ContextRegister<RemovedRegisterType> { }}namespace Get{using ContextRegisters;[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;[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.Linq;using CareBoo.Serially;using TagFighter.Resources;using UnityEngine;namespace TagFighter.Effects{public interface IDelayedEffect{void DelayedAction(EffectInput data);}public interface IImmediateEffect{void ImmediateAction(EffectContext context, IEffect effect);}public interface IEffectMode{void Apply(EffectContext context);void Effect(EffectContext context, IEffect effect);}[Serializable]public class DelayedEffect : IImmediateEffect, IDelayedEffect{IEffect _effect;public void DelayedAction(EffectInput data) {_effect.Apply(data);TagCounter c = new();c[TagColor.Red] = 1;// direction towards targetvar directionVector = (data.Context.EffectLocation.position - data.Context.Caster.position).normalized;directionVector.y = 0;var direction = Quaternion.LookRotation(directionVector, Vector3.up);data.Context.EffectSystem.ApplyTagsEffect(c, data.Context.EffectLocation, direction, data.Context.AreaOfEffect);}public void ImmediateAction(EffectContext context, IEffect effect) {if (effect != null) {_effect = effect;context.EffectsToTrigger.Add(this);}}}[Serializable]public class ImmediateEffect : IImmediateEffect{[SerializeReference, ShowSerializeReference]AoeShapes.IAoeShape _areaOfEffect;public void ImmediateAction(EffectContext context, IEffect effect) {if (effect != null) {// direction towards targetvar directionVector = (context.EffectLocation.position - context.Caster.position).normalized;directionVector.y = 0;var direction = Quaternion.LookRotation(directionVector, Vector3.up);EffectInput data = new(context, Enumerable.Empty<Transform>(), StatModifierAccessor.Permanent);var areaOfEffect = _areaOfEffect.AreaOfEffect(data);// Copy the location of the effect and merge with the direction caster -> targetGameObject tmpGo = new();tmpGo.transform.position = context.EffectLocation.position;tmpGo.transform.rotation = direction;data.Affected = areaOfEffect.GetAffectedUnits(tmpGo.transform);GameObject.Destroy(tmpGo);effect.Apply(data);TagCounter c = new();c[TagColor.Red] = 1;context.EffectSystem.ApplyTagsEffect(c, context.EffectLocation, direction, areaOfEffect);}}}[Serializable]public class ImmediateWeave : IImmediateEffect{public void ImmediateAction(EffectContext context, IEffect effect) {EffectInput data = new(context, context.GetAffectedUnits(), StatModifierAccessor.Permanent);if (effect != null) {effect.Apply(data);data.Affected = context.GetAffectedUnits();}Materialize(data);}void Materialize(EffectInput data) {foreach (var effect in data.Context.EffectsToTrigger) {effect.DelayedAction(data);}data.Context.EffectsToTrigger.Clear();}}[Serializable]public class PeriodicWeave : IImmediateEffect{[SerializeReference, ShowSerializeReference]public AoeShapes.IAoeShape AreaOfEffect;[SerializeReference, ShowSerializeReference]public Triggers.ITrigger ApplyTrigger;[SerializeReference, ShowSerializeReference]public Triggers.ITrigger EndTrigger;public bool IsPermanent;public void ImmediateAction(EffectContext context, IEffect effect) {EffectInput data = new(context, context.GetAffectedUnits(), StatModifierAccessor.Permanent);if (effect != null) {effect.Apply(data);data.Affected = context.GetAffectedUnits();}Materialize(data);}void Materialize(EffectInput data) {var areaOfEffect = AreaOfEffect.AreaOfEffect(data);/// Move all effects in context to condition context.List<IDelayedEffect> effectsToTrigger = new(data.Context.EffectsToTrigger);data.Context.EffectsToTrigger.Clear();var origin = data.Context.Caster;foreach (var affectedPawn in data.Affected) {var condition = IsPermanent ? affectedPawn.gameObject.AddComponent<PawnCondition>() : affectedPawn.gameObject.AddComponent<TransientPawnCondition>();condition.EndTrigger = EndTrigger?.ShallowCopy();condition.ApplyTrigger = ApplyTrigger?.ShallowCopy();condition.Origin = origin;condition.Context = new EffectContext() {AreaOfEffect = areaOfEffect,Caster = affectedPawn,EffectLocation = affectedPawn,EffectsToTrigger = effectsToTrigger};condition.Apply();}}}}
using System;using System.Collections.Generic;using System.Linq;using CareBoo.Serially;using TagFighter.Effects.ResourceLocationAccessors.ContextRegisters;using TagFighter.Resources;using UnityEngine;namespace TagFighter.Effects{public interface IDelayedEffect{void DelayedAction(EffectInput data);}public interface IImmediateEffect{void ImmediateAction(EffectContext context, IEffect effect);}public interface IEffectMode{void Apply(EffectContext context);void Effect(EffectContext context, IEffect effect);}[Serializable]public class DelayedEffect : IImmediateEffect, IDelayedEffect{IEffect _effect;public void DelayedAction(EffectInput data) {_effect.Apply(data);// direction towards targetvar directionVector = (data.Context.EffectLocation.position - data.Context.Caster.position).normalized;directionVector.y = 0;var direction = Quaternion.LookRotation(directionVector, Vector3.up);var appliedResource = data.Context.GetAllResourcesInRegister<Added>();data.Context.EffectSystem.ApplyTagsEffect(appliedResource, data.Context.EffectLocation, direction, data.Context.AreaOfEffect);}public void ImmediateAction(EffectContext context, IEffect effect) {if (effect != null) {_effect = effect;context.EffectsToTrigger.Add(this);}}}[Serializable]public class ImmediateEffect : IImmediateEffect{[SerializeReference, ShowSerializeReference]AoeShapes.IAoeShape _areaOfEffect;public void ImmediateAction(EffectContext context, IEffect effect) {if (effect != null) {// direction towards targetvar directionVector = (context.EffectLocation.position - context.Caster.position).normalized;directionVector.y = 0;var direction = Quaternion.LookRotation(directionVector, Vector3.up);EffectInput data = new(context, Enumerable.Empty<Transform>(), StatModifierAccessor.Permanent);var areaOfEffect = _areaOfEffect.AreaOfEffect(data);// Copy the location of the effect and merge with the direction caster -> targetGameObject tmpGo = new();tmpGo.transform.position = context.EffectLocation.position;tmpGo.transform.rotation = direction;data.Affected = areaOfEffect.GetAffectedUnits(tmpGo.transform);GameObject.Destroy(tmpGo);effect.Apply(data);var appliedResource = context.GetAllResourcesInRegister<Added>();context.EffectSystem.ApplyTagsEffect(appliedResource, context.EffectLocation, direction, areaOfEffect);}}}[Serializable]public class ImmediateWeave : IImmediateEffect{public void ImmediateAction(EffectContext context, IEffect effect) {EffectInput data = new(context, context.GetAffectedUnits(), StatModifierAccessor.Permanent);if (effect != null) {effect.Apply(data);data.Affected = context.GetAffectedUnits();}Materialize(data);}void Materialize(EffectInput data) {foreach (var effect in data.Context.EffectsToTrigger) {effect.DelayedAction(data);}data.Context.EffectsToTrigger.Clear();}}[Serializable]public class PeriodicWeave : IImmediateEffect{[SerializeReference, ShowSerializeReference]public AoeShapes.IAoeShape AreaOfEffect;[SerializeReference, ShowSerializeReference]public Triggers.ITrigger ApplyTrigger;[SerializeReference, ShowSerializeReference]public Triggers.ITrigger EndTrigger;public bool IsPermanent;public void ImmediateAction(EffectContext context, IEffect effect) {EffectInput data = new(context, context.GetAffectedUnits(), StatModifierAccessor.Permanent);if (effect != null) {effect.Apply(data);data.Affected = context.GetAffectedUnits();}Materialize(data);}void Materialize(EffectInput data) {var areaOfEffect = AreaOfEffect.AreaOfEffect(data);/// Move all effects in context to condition context.List<IDelayedEffect> effectsToTrigger = new(data.Context.EffectsToTrigger);data.Context.EffectsToTrigger.Clear();var origin = data.Context.Caster;foreach (var affectedPawn in data.Affected) {var condition = IsPermanent ? affectedPawn.gameObject.AddComponent<PawnCondition>() : affectedPawn.gameObject.AddComponent<TransientPawnCondition>();condition.EndTrigger = EndTrigger?.ShallowCopy();condition.ApplyTrigger = ApplyTrigger?.ShallowCopy();condition.Origin = origin;condition.Context = new EffectContext() {AreaOfEffect = areaOfEffect,Caster = affectedPawn,EffectLocation = affectedPawn,EffectsToTrigger = effectsToTrigger};condition.Apply();}}}}
using System;using System.Collections.Generic;using System.Linq;using TagFighter.Effects.ResourceLocationAccessors.ContextRegisters;using TagFighter.Resources;using UnityEngine;namespace TagFighter.Effects{public class ReleaseMultiplier{public Type MatchingAoe { get; set; }public float MatchingAoeReleaseMultiplier { get; set; } = 1f;public float NonMatchingAoeReleaseMultiplier { get; set; } = 1f;}public class EffectContext{Dictionary<System.Type, IUnit> _resourceRegistry = new();public Transform Caster { get; set; }public Transform EffectLocation { get; set; }public IAreaOfEffect AreaOfEffect;public List<IDelayedEffect> EffectsToTrigger { get; set; } = new();public IEffectSystem EffectSystem { get; private set; }public ReleaseMultiplier ReleaseMultiplier { get; set; }public EffectContext() {EffectSystem = SystemsHandler.EffectSystem;ReleaseMultiplier = new();}public Unit<TUnit> GetResource<TResource, TUnit, TRegister>()where TResource : Resource<TUnit>where TUnit : IUnitTypewhere TRegister : IRegisterType {var key = typeof((TResource, TRegister));var value = (Unit<TUnit>)_resourceRegistry.GetValueOrDefault(key, (Unit<TUnit>)0);Debug.Log($"{nameof(GetResource)} ({typeof(TResource).Name},{typeof(TRegister).Name}) = {value}");return value;}public Unit<TUnit> SetResource<TResource, TUnit, TRegister>(Unit<TUnit> value)where TResource : Resource<TUnit>where TUnit : IUnitTypewhere TRegister : IRegisterType {var key = typeof((TResource, TRegister));var newValue = (Unit<TUnit>)(_resourceRegistry[key] = value);Debug.Log($"{nameof(SetResource)} ({typeof(TResource).Name},{typeof(TRegister).Name}) = {newValue}");return newValue;}public IEnumerable<Transform> GetAffectedUnits() {if (AreaOfEffect == null) {return Enumerable.Empty<Transform>();}var directionVector = (EffectLocation.position - Caster.position).normalized;directionVector.y = 0;var direction = Quaternion.LookRotation(directionVector, Vector3.up);GameObject tmpGo = new();tmpGo.transform.position = EffectLocation.position;tmpGo.transform.rotation = direction;var affectedUnits = AreaOfEffect.GetAffectedUnits(EffectLocation);GameObject.Destroy(tmpGo);return affectedUnits;}void ResetEffects() {EffectsToTrigger.Clear();}public void Reset() {ResetEffects();}}}
using System;using System.Collections.Generic;using System.Linq;using Mono.Cecil;using TagFighter.Effects.ResourceLocationAccessors.ContextRegisters;using TagFighter.Resources;using Unity.VisualScripting.FullSerializer.Internal;using UnityEngine;namespace TagFighter.Effects{public class ReleaseMultiplier{public Type MatchingAoe { get; set; }public float MatchingAoeReleaseMultiplier { get; set; } = 1f;public float NonMatchingAoeReleaseMultiplier { get; set; } = 1f;}public class RegistryKey{public Type ContextRegisterType;public Type ResourceType;public RegistryKey(Type contextRegisterType, Type resourceType) {ContextRegisterType = contextRegisterType;ResourceType = resourceType;}}public class EffectContext{Dictionary<RegistryKey, IUnit> _resourceRegistry = new();public Transform Caster { get; set; }public Transform EffectLocation { get; set; }public IAreaOfEffect AreaOfEffect;public List<IDelayedEffect> EffectsToTrigger { get; set; } = new();public IEffectSystem EffectSystem { get; private set; }public ReleaseMultiplier ReleaseMultiplier { get; set; }public EffectContext() {EffectSystem = SystemsHandler.EffectSystem;ReleaseMultiplier = new();}public Unit<TUnit> GetResource<TResource, TUnit, TContextRegister>()where TResource : Resource<TUnit>where TUnit : IUnitTypewhere TContextRegister : IContextRegister {var key = new RegistryKey(typeof(TContextRegister), typeof(TResource));var value = (Unit<TUnit>)_resourceRegistry.GetValueOrDefault(key, (Unit<TUnit>)0);Debug.Log($"{nameof(GetResource)} ({typeof(TResource).Name},{typeof(TContextRegister).Name}) = {value}");return value;}public Unit<TUnit> SetResource<TResource, TUnit, TContextRegister>(Unit<TUnit> value)where TResource : Resource<TUnit>where TUnit : IUnitTypewhere TContextRegister : IContextRegister {var key = new RegistryKey(typeof(TContextRegister), typeof(TResource));var newValue = (Unit<TUnit>)(_resourceRegistry[key] = value);Debug.Log($"{nameof(SetResource)} ({typeof(TResource).Name},{typeof(TContextRegister).Name}) = {newValue}");return newValue;}public IEnumerable<(Type, IUnit)> GetAllResourcesInRegister<TContextRegister>() where TContextRegister : IContextRegister {Type t = typeof(TContextRegister).BaseType;return _resourceRegistry.Where(x => x.Key.ContextRegisterType == t).Select(x => (x.Key.ResourceType, x.Value));}public IEnumerable<Transform> GetAffectedUnits() {if (AreaOfEffect == null) {return Enumerable.Empty<Transform>();}var directionVector = (EffectLocation.position - Caster.position).normalized;directionVector.y = 0;var direction = Quaternion.LookRotation(directionVector, Vector3.up);GameObject tmpGo = new();tmpGo.transform.position = EffectLocation.position;tmpGo.transform.rotation = direction;var affectedUnits = AreaOfEffect.GetAffectedUnits(EffectLocation);GameObject.Destroy(tmpGo);return affectedUnits;}void ResetEffects() {EffectsToTrigger.Clear();}public void Reset() {ResetEffects();}}}
Addend: 1- rid: 1353921146486259729type: {class: Pawn, ns: TagFighter.Effects.ResourceLocationAccessors.Set, asm: Assembly-CSharp}
Addend: 10- rid: 2536212716021350404type: {class: Context, ns: TagFighter.Effects.ResourceLocationAccessors.Set,asm: Assembly-CSharp}
Property:rid: 1452634394371555352- rid: 1353921146486259730
Register:rid: 2536212716021350405SetAs:rid: 2536212716021350406- rid: 2536212716021350405type: {class: Added, ns: TagFighter.Effects.ResourceLocationAccessors.ContextRegisters,asm: Assembly-CSharp}- rid: 2536212716021350406type: {class: Sum, ns: TagFighter.Effects.Operators, asm: Assembly-CSharp}- rid: 2536212716021350407
- rid: 1452634394371555352type: {class: Current, ns: TagFighter.Effects.ResourceLocationAccessors.PawnProperties,
- rid: 2536212716021350408type: {class: Context, ns: TagFighter.Effects.ResourceLocationAccessors.Get,asm: Assembly-CSharp}data:Register:rid: 2536212716021350409- rid: 2536212716021350409type: {class: Current, ns: TagFighter.Effects.ResourceLocationAccessors.ContextRegisters,
- rid: 2536212716021350418type: {class: BlueTag, ns: TagFighter.Effects.ResourceTypeAccessors, asm: Assembly-CSharp}