using Arknights.Scripts.Manager; using Spine.Unity; using System.Collections.Generic; using static Arknights.Scripts.Manager.EnemyManager; using static Arknights.Scripts.Manager.GameManager; using UnityEngine; using static UnityEngine.Object; using System; //using static Arknights.Scripts.Manager.SceneUtils; using System.Text; using Arknights.Scripts.UI.GameCanva; namespace Arknights.Scripts.ObjectClass{ { public class Enemy2 : Enemy { public float HP { get; set; } public float maxHP { get; set; } public route route { get; set; } public GameObject gameObject { get; set; } public int chkptIndex = 0; public double stayTime = 0; public float speed; public float gspeed; public float ogspeed; bool stchng = false; public SkeletonAnimation animation = null; Spine.Animation idle; Spine.Animation move; Spine.Animation Die; GameObject Spine; GameObject shadow; public bool isDisappear = false; List talents = new List(); public bool yuanshiFloorHit = false; public bool isDead = false; public bool showHealthLine = false; public GameObject healthLine; public GameObject infectionIcon = null; public bool hasAnimation = false; private Coroutine DisApOrAppear; public bool isSpeedUpping = false; public hasHurtSpeedUp hasHurtSpeed = null; private float lastHp; public Enemy2(GameObject gameObject, string name, float maxHP, float speed, int routeIndex) { this.maxHP = maxHP; HP = maxHP; lastHp = HP; route = GameData.routes[routeIndex]; this.speed = speed; gspeed = speed; ogspeed=gspeed; this.gameObject = gameObject; foreach (var child1 in LoadScene.GetAllChild(gameObject)) { child1.layer = 7; if (child1.name.Equals("Sprite")) { child1.transform.localScale = new Vector3(1, 1); var sprite = child1.GetComponent(); sprite.sprite = ShadowSprite; sprite.sharedMaterial.shader = Shader.Find("Sprites/Default"); sprite.sharedMaterial.renderQueue = 2500; shadow = child1; sprite.sortingLayerName = "Default"; sprite.sortingOrder = 0; } } var child = gameObject.transform.Find("Graphic/FaceSwitcher/Spine"); if (child != null) { if (child.GetComponent() != null && child.GetComponent() != null) { child.gameObject.layer = 7; var material = child.GetComponent().sharedMaterial; material.renderQueue = 3500; Spine = child.gameObject; material.shader = Shader.Find("Custom/Skeleton2"); if (material.GetTexture("_AlphaTex") != null) { material.SetInt("_USE_ALPHA", 1); } animation = child.GetComponent(); child.GetComponent().loop = true; hasAnimation = true; } var animations = animation != null ? animation.Skeleton.Data.Animations : null; foreach (var animationS in animations) { if (animationS.Name.ToLower().Contains("die") && Die == null) { Die = animationS; } if (animationS.Name.ToLower().Contains("idle") && idle == null) { idle = animationS; } if (animationS.Name.ToLower().Contains("move")) { if (animationS.Name.ToLower().Contains("loop") && move == null) { move = animationS; } else if (!animationS.Name.ToLower().Contains("begin") && !animationS.Name.ToLower().Contains("end") && move == null) { move = animationS; } } if (animationS.Name.ToLower().Contains("run") && move == null) { if (animationS.Name.ToLower().Contains("loop") && move == null) { move = animationS; } else if (!animationS.Name.ToLower().Contains("begin") && !animationS.Name.ToLower().Contains("end") && move == null) { move = animationS; } } } animation.timeScale = SpeedButton.tspeed ? 2 : 1; } talents = enemydataD[name][0].enemyData.talentBlackboard; if (talents != null) { foreach (var talent in talents) { if (talent.key.ToLower().Contains("periodic_damage.damage") || talent.key.ToLower().Contains("bleed.damage")) { Debug.Log($"Enemy Talent Hurt {gameObject.name} damage {float.Parse(talent.value.ToString())}"); _this.HurtEnemy(this, float.Parse(talent.value.ToString()), 1f, 9999f); } if (talent.key.ToLower().Contains("rush") && talent.key.ToLower().Contains("move_speed")) { float addSpeed = float.Parse(talent.value.ToString()); float delay = 999; int maxFrequency = 0; foreach (var talent1 in talents) { if (talent1.key.ToLower().Contains("rush") && talent1.key.ToLower().Contains("interval")) { delay = float.Parse(talent1.value.ToString()); } if (talent1.key.ToLower().Contains("rush") && talent1.key.ToLower().Contains("trig_cnt")) { maxFrequency = int.Parse(talent1.value.ToString()); } } _this.EnemySpeedUp(this, addSpeed, delay, maxFrequency, false); isSpeedUpping = true; } if (talent.key.ToLower().Contains("passive")) { var time = 0; var addSpeed = 0; foreach (var talent1 in talents) { if (talent1.key.ToLower().Contains("passive") && talent1.key.ToLower().Contains("speed_time")) { time = int.Parse(talent1.value.ToString()); } if (talent1.key.ToLower().Contains("passive") && talent1.key.ToLower().Contains("move_speed")) { addSpeed = int.Parse(talent1.value.ToString()); } } hasHurtSpeed = new hasHurtSpeedUp { has = true, xSpeed = addSpeed, time = time }; } } } if (Spine != null) { Spine.GetComponent().material = new Material(Spine.GetComponent().sharedMaterial); Spine.GetComponent().sharedMaterial = null; Spine.GetComponent().material.color = Color.black; DisApOrAppear = _this.Appear(Spine, shadow); } } public void update() { if (HP != maxHP) { if (showHealthLine && healthLine != null) { var pos = CameraViewer.camera.WorldToScreenPoint(gameObject.transform.position); var uiElement = healthLine.GetComponent(); Vector2 localPoint; if (RectTransformUtility.ScreenPointToLocalPointInRectangle(gameCanva.GetComponent(), pos, CameraViewer.camera, out localPoint)) { uiElement.anchoredPosition3D = new Vector3(localPoint.x, localPoint.y - 8, 0); } healthLine.GetComponent().localScale = new Vector3(1, 1, 1); healthLine.GetComponent().rotation = Quaternion.Euler(0, 0, 0); var line = healthLine.transform.Find("Line").GetComponent(); var a = HP / maxHP; line.sizeDelta = new Vector2((float)(35.002 * a), line.sizeDelta.y); line.anchoredPosition = new Vector2((float)(35.002 * a) / 2, line.anchoredPosition.y); } else { healthLine = Instantiate(EnemyManager.healthLine); healthLine.transform.SetParent(gameCanva.transform); var line = healthLine.transform.Find("Line").GetComponent(); var a = HP / maxHP; line.sizeDelta = new Vector2((float)(35.002 * a), line.sizeDelta.y); line.anchoredPosition = new Vector2((float)(35.002 * a) / 2, line.anchoredPosition.y); var pos = CameraViewer.camera.WorldToScreenPoint(gameObject.transform.position); var uiElement = healthLine.GetComponent(); Vector2 localPoint; if (RectTransformUtility.ScreenPointToLocalPointInRectangle(gameCanva.GetComponent(), pos, CameraViewer.camera, out localPoint)) { uiElement.anchoredPosition = new Vector2(localPoint.x, localPoint.y - 8); } healthLine.GetComponent().rotation = Quaternion.Euler(0, 0, 0); healthLine.GetComponent().localScale = new Vector3(1, 1, 1); showHealthLine = true; } } if (HP == 0 && !isDead) { if (hasAnimation && Die != null) { animation.loop = false; animation.AnimationName = Die.Name; _this.Die(this); } isDead = true; if (infectionIcon != null) { Destroy(infectionIcon); } return; } if (isDead) { return; } if (HP != lastHp) { onHurt(); lastHp = HP; } speed = gspeed * playSpeed * deltaTime * 0.5f; MoveUpdate(); // Debug.Log($"Enemy {gameObject.name} position {getMapPosition(gameObject.transform.position, orgPoint)} HP {HP} isOnYuanshi {isOnYuanShiFloor(getMapPosition(gameObject.transform.position, orgPoint))} Yuanshi Hit {yuanshiFloorHit}"); if (isOnYuanShiFloor(getMapPosition(gameObject.transform.position, orgPoint)) && !yuanshiFloorHit) { var pos = getMapPosition(gameObject.transform.position, orgPoint); var tile = GameData.mapdata.tiles[GameData.mapdata.map[(int)pos.y][(int)pos.x]]; if (tile.blackboard != null) { Debug.Log($"{gameObject.name} tile {tile.tileKey} Damage {tile.blackboard[0].value} ContinueDelay {tile.blackboard[1].value} 1"); float damage = float.Parse(tile.blackboard[0].value.ToString()); float continueDelay = float.Parse(tile.blackboard[1].value.ToString()); _this.HurtEnemy(this, damage, 1f, continueDelay); } yuanshiFloorHit = true; if (infectionIcon == null) { GameObject icon = Instantiate(_this.InfectionObject); icon.transform.SetParent(gameObject.transform); icon.transform.localPosition = new Vector3(0, 0, 0); } } } public void MoveUpdate() { if (chkptIndex >= route.checkpoints.Count) { return; } CPoint chkp = route.checkpoints[chkptIndex]; if (gameObject.transform.position == new Vector3(p2v(route.endPosition).x, p2v(route.endPosition).y, gameObject.transform.position.z) && !isDisappear) { if (animation != null && idle != null) { animation.loop = false; animation.AnimationName = idle.Name; animation.timeScale = 0; } _this.StopC(DisApOrAppear); DisApOrAppear = _this.Disappear(Spine, this, shadow, true); isDisappear = true; } switch (chkp.type) { case "WAIT_FOR_SECONDS": if (!stchng) { stayTime = CounterManager.gameTime + chkp.time; if (animation != null && idle != null) { animation.AnimationName = idle.Name; } stchng = true; } if (CounterManager.gameTime >= stayTime && stchng) { chkptIndex++; stchng = false; animation.AnimationName = move.Name; } break; case "DISAPPEAR": if (isArrive(gameObject.transform.position, chkp.position) && !stchng) { if (!isDisappear) { _this.StopC(DisApOrAppear); DisApOrAppear = _this.Disappear(Spine, this, shadow, false); isDisappear = true; } chkptIndex++; } break; case "APPEAR_AT_POS": isDisappear = false; _this.StopC(DisApOrAppear); gameObject.transform.position = new Vector3(p2v(chkp.position).x, p2v(chkp.position).y, gameObject.transform.position.z); if (Spine != null) { DisApOrAppear = _this.Appear(Spine, shadow); } chkptIndex++; break; } if (isArrive(gameObject.transform.position, chkp.position) && !stchng && chkp.type != "WAIT_FOR_SECONDS" && chkp.type != "APPEAR_AT_POS") { chkptIndex += 1; } if (!stchng && chkptIndex < route.checkpoints.Count) { if (hasAnimation && move != null) { animation.AnimationName = move.Name; } MoveToCheckpoint(chkp); } } public void onHurt() { if (hasHurtSpeed != null && !isSpeedUpping) { _this.EnemySpeedUp(this, hasHurtSpeed.xSpeed * ogspeed, hasHurtSpeed.time, 1, true, ogspeed); isSpeedUpping = true; } } public static bool isOnYuanShiFloor(Vector2 pos) { var tile = GameData.mapdata.tiles[GameData.mapdata.map[(int)pos.y][(int)pos.x]]; //Debug.Log($"Tile {pos} Key {tile.tileKey}"); if (tile.tileKey.Contains("infection")) { return true; } return false; } public static position v2po(Vector2 vector2) { return new position(vector2.y, vector2.x); } public static Vector2 p2v(position position) { return new Vector2(orgPoint.x + (float)position.col, orgPoint.y + (float)position.row); } public static position v2p(Vector2 position) { return new position(position.y - orgPoint.y, position.x - orgPoint.x); } public static Vector2 p2vNA(position position) { return new Vector2((float)position.col, (float)position.row); } private void MoveToCheckpoint(CPoint chkp) { Rotate(chkp); gameObject.transform.position = Vector3.MoveTowards(gameObject.transform.position, new Vector3(p2v(route.checkpoints[chkptIndex].position).x, p2v(route.checkpoints[chkptIndex].position).y, gameObject.transform.position.z), speed); } public static bool isArrive(Vector3 a, position b) { float ax = p2v(b).x; float ay = p2v(b).y; return ax == a.x && ay == a.y; } private void Rotate(CPoint chkp) { if (gameObject.transform.position.x > p2v(chkp.position).x) { if (hasAnimation) { _this.rotate(Spine, true); } } else if (gameObject.transform.position.x < p2v(chkp.position).x) { if (hasAnimation) { _this.rotate(Spine, false); } } } public static Vector2 getMapPosition(Vector2 position, Vector2 orgPoint) { return new Vector2((float)Math.Round(position.x - orgPoint.x), (float)Math.Round(position.y - orgPoint.y)); } public class hasHurtSpeedUp { public bool has { get; set; } = false; public int xSpeed { get; set; } = 0; public int time { get; set; } = 0; } } }