using Cal.DataTable; using ET.EventType; using System; using System.Collections.Generic; using UnityEngine; namespace ET { public class MainStoryAIDestroySystem: DestroySystem { public override void Destroy(MainStoryAI self) { self.sceneId = 0; self.layer = 0; self.currProdurce = MainStoryAI.Produrce.Idle; self.nextProdurce = MainStoryAI.Produrce.Idle; self.targetPos = default (Vector2); TimerComponent.Instance.Remove(ref self.timerId); try { Unit leader = self.team.GetLeader(); if (leader) leader.isAI = false; } catch (Exception e) { Log.Error(e); } self.team = null; } } public class MainStoryAIAwakeSystem: AwakeSystem { public override void Awake(MainStoryAI self) { self.currProdurce = MainStoryAI.Produrce.Idle; self.nextProdurce = MainStoryAI.Produrce.Idle; self.timerId = TimerComponent.Instance.NewRepeatedTimer(2000L, (Action) self.Update); } } public static class MainStoryAISystem { class BattleEndEvent: AEvent { public override async ETTask Run(BattleEnd args) { if (!args.unit.IsTeamLeader) return; if (!args.unit.isAI) return; var unit = args.team.GetLeader(); var oldAI = MainStoryAIComponent.instance.GetAI(unit); if (oldAI == null) { Log.Error($"{unit.Id.GetPlayerFormatName()} ai == null"); return; } oldAI.OnBattleEnd().Coroutine(); } } public static bool Init(this MainStoryAI self, Team team, int mapId, AutoBattleAIType autoBattleAIType) { Unit leader = team.GetLeader(); leader.isAI = true; self.team = team; self.sceneId = mapId / 100; self.layer = mapId % 100; self.battleAIType = autoBattleAIType; if (autoBattleAIType == AutoBattleAIType.MainStory) { self.nextProdurce = MainStoryAI.Produrce.MoveToMonster; self.mapType = MainStoryAI.MapType.Map; self.MoveNextProdurce(); } else { self.nextProdurce = MainStoryAI.Produrce.MoveToMonster; self.mapType = MainStoryAI.MapType.Map; var config = leader.GetOrAddComponent(); self.type = config.type; self.diffculty = config.difficulty; self.StarSoulMoveNextProdurce(); } return true; } public static async ETVoid OnBattleEnd(this MainStoryAI self) { if (self.battleAIType == AutoBattleAIType.MainStory) { await TimerComponent.Instance.WaitAsync(1000); self.state = MainStoryAI.State.Idle; JuageMapType(self); if (self.mapType == MainStoryAI.MapType.City) { self.MoveNextProdurce(MainStoryAI.Produrce.MoveToCityTransPoint); return; } self.MoveNextProdurce(); } else { await TimerComponent.Instance.WaitAsync(3000); if (!self.team) { self.state = MainStoryAI.State.Idle; return; } self.state = MainStoryAI.State.Idle; JuageMapType(self); if (self.mapType == MainStoryAI.MapType.City) { self.StarSoulMoveNextProdurce(MainStoryAI.Produrce.CityTrans); return; } self.StarSoulMoveNextProdurce(); } } public static void Update(this MainStoryAI self) { try { ReduceAITime(self); switch (self.state) { case MainStoryAI.State.Idle: break; case MainStoryAI.State.Transfer: { bool flag = true; foreach (Unit unit in self.team.GetUnits()) { flag = !unit.IsTransfer && flag; } if (flag) { self.state = MainStoryAI.State.Idle; if (self.battleAIType == AutoBattleAIType.MainStory) self.MoveNextProdurce(); else { self.StarSoulMoveNextProdurce(); } } break; } case MainStoryAI.State.Move: Move(self); break; } } catch (Exception e) { Log.Error(e); MainStoryAIComponent.instance.DestoryAI(self); } } private static void ReduceAITime(MainStoryAI self) { LinkedList units = self.team.GetUnits(); foreach (Unit item in units) { try { if (!item) continue; PlayerData data = item.GetComponent(); if (data.ForbidExp) continue; if (data.HasMainstoryVIPAITime()) { data.mainstoryVIPAITime -= 2000; if (data.mainstoryVIPAITime <= 0) { data.mainstoryVIPAITime = 0L; } } else if (data.HasMainstoryAITime()) { data.mainstoryAITime -= 2000; if (data.mainstoryAITime <= 0) { data.mainstoryAITime = 0L; } } UnitHelper.SaveComponenet(data); } catch (Exception e) { Log.Error(e); } } } private static void Move(MainStoryAI self) { Unit leader = self.team.GetLeader(); if (!leader) { Log.Error($"leader is null"); MainStoryAIComponent.instance.DestoryAI(self); return; } UnitScene component = leader.GetComponent(); Vector2 position = component.Position; if (Vector2.DistanceSquared(position, self.targetPos) <= 0.01f) { self.state = MainStoryAI.State.Idle; if (self.battleAIType == AutoBattleAIType.MainStory) self.MoveNextProdurce(); else { self.StarSoulMoveNextProdurce(); } } } private static void JuageMapType(MainStoryAI self) { Unit leader = self.team.GetLeader(); UnitScene component = leader.GetComponent(); int mapId = component.MapId; UnitSceneType unitSceneType = MapHelper.GetMapType(mapId / 100); if (mapId / 100 == 10004) { self.mapType = MainStoryAI.MapType.City; } else { self.mapType = MainStoryAI.MapType.Map; } } public static void StarSoulMoveNextProdurce(this MainStoryAI self, MainStoryAI.Produrce next = MainStoryAI.Produrce.Idle) { if (next == MainStoryAI.Produrce.Idle) { self.currProdurce = self.nextProdurce; } else { self.currProdurce = next; } switch (self.currProdurce) { case MainStoryAI.Produrce.CityTrans: self.nextProdurce = MainStoryAI.Produrce.MoveToMonster; break; case MainStoryAI.Produrce.MoveToMonster: self.nextProdurce = MainStoryAI.Produrce.Battle; break; case MainStoryAI.Produrce.Battle: JuageMapType(self); if (self.mapType == MainStoryAI.MapType.Map) { self.nextProdurce = MainStoryAI.Produrce.MoveToMonster; } else if (self.mapType == MainStoryAI.MapType.City) { self.nextProdurce = MainStoryAI.Produrce.CityTrans; } break; } StarSoulMoveNext(self); } public static void MoveNextProdurce(this MainStoryAI self, MainStoryAI.Produrce next = MainStoryAI.Produrce.Idle) { if (next == MainStoryAI.Produrce.Idle) { self.currProdurce = self.nextProdurce; } else { self.currProdurce = next; } switch (self.currProdurce) { case MainStoryAI.Produrce.MoveToCityTransPoint: self.nextProdurce = MainStoryAI.Produrce.CityTrans; break; case MainStoryAI.Produrce.CityTrans: self.nextProdurce = MainStoryAI.Produrce.MoveToMonster; break; case MainStoryAI.Produrce.MoveToMonster: self.nextProdurce = MainStoryAI.Produrce.Battle; break; case MainStoryAI.Produrce.Battle: self.nextProdurce = MainStoryAI.Produrce.MoveToMapTransPoint; break; case MainStoryAI.Produrce.MoveToMapTransPoint: self.nextProdurce = MainStoryAI.Produrce.MapTrans; break; case MainStoryAI.Produrce.MapTrans: JuageMapType(self); if (self.mapType == MainStoryAI.MapType.Map) { self.nextProdurce = MainStoryAI.Produrce.MoveToMonster; } else if (self.mapType == MainStoryAI.MapType.City) { self.nextProdurce = MainStoryAI.Produrce.MoveToCityTransPoint; } break; } MoveNext(self); } private static void StarSoulMoveNext(MainStoryAI self) { switch (self.currProdurce) { case MainStoryAI.Produrce.Idle: break; case MainStoryAI.Produrce.CityTrans: StarCityTrans(self); break; case MainStoryAI.Produrce.MoveToMonster: StarMoveToMonster(self); break; case MainStoryAI.Produrce.Battle: CheckVIPAIService(self); StarBattle(self); break; } } private static void MoveNext(MainStoryAI self) { switch (self.currProdurce) { case MainStoryAI.Produrce.Idle: break; case MainStoryAI.Produrce.MoveToCityTransPoint: MoveToCityTransPoint(self); CheckVIPAIService(self); break; case MainStoryAI.Produrce.CityTrans: CityTrans(self); break; case MainStoryAI.Produrce.MoveToMonster: MoveToMonster(self); break; case MainStoryAI.Produrce.Battle: Battle(self); break; case MainStoryAI.Produrce.MoveToMapTransPoint: MoveToMapTransPoint(self); CheckVIPAIService(self); break; case MainStoryAI.Produrce.MapTrans: MapTrans(self); break; } } private static void CheckVIPAIService(MainStoryAI self) { LinkedList units = self.team.GetUnits(); foreach (Unit unit in units) { try { if (!unit) continue; PlayerData data = unit.GetComponent(); if (data.HasMainstoryVIPAITime()) { Bag bag = unit.GetComponent(); //检查经验卡 if (self.battleAIType == AutoBattleAIType.MainStory && data.battleExpSpeedLeastTime <= TimeHelper.ClientNow()) { BagHelper.UserGoods(bag, BagHelper.GoodAutoUseType.Exp); } //检查血球 if (data.hpAutoFullCapatial.Key <= 0) { BagHelper.UserGoods(bag, BagHelper.GoodAutoUseType.Hp); } //检查蓝球 if (data.mpAutoFullCapatial.Key <= 0) { BagHelper.UserGoods(bag, BagHelper.GoodAutoUseType.Mp); } //检查背包容量 if (self.battleAIType == AutoBattleAIType.MainStory && bag.ItemCount >= (bag.MaxItemCount - 8)) { BagHelper.AutoMoveItemToStore(bag, 8).Coroutine(); } } UnitHelper.SaveComponenet(data); } catch (Exception e) { Log.Error(e); } } } private static void MoveToCityTransPoint(MainStoryAI self) { Unit leader = self.team.GetLeader(); if (AppConfig.inst.isTest) Log.Info($"【{UserComponent.Instance.Get(leader.Id)?.NickName} ({leader.Id})】移动到城镇传送点"); SceneTransConfig sceneTransConfig = SceneTransConfigCategory.Instance.Get(SceneTransConfigId.Scene_MainCity); SceneTransConfig.TransPos transPos = sceneTransConfig.TransPosArr[0]; self.targetPos = new Vector2(transPos.TransPos_x, transPos.TransPos_y); MoveHelper.TeamMoveTo(self.team, self.targetPos).Coroutine(); self.state = MainStoryAI.State.Move; } private static void CityTrans(MainStoryAI self) { Unit leader = self.team.GetLeader(); if (AppConfig.inst.isTest) Log.Info($"【{UserComponent.Instance.Get(leader.Id)?.NickName} ({leader.Id})】城镇传送"); if (leader.teamState == TeamState.Fight) { Log.Error($"【{UserComponent.Instance.Get(leader.Id)?.NickName} ({leader.Id})】战斗状态"); return; } PlayerData component = leader.GetComponent(); if ((bool) component && component.IsBattleIdle) { Log.Error($"【{UserComponent.Instance.Get(leader.Id)?.NickName} ({leader.Id})】挂机状态"); return; } self.layer = 1; int mapId = self.sceneId * 100 + self.layer; Game.EventSystem.Publish(new ChangeMap { unit = leader, mapId = mapId }).Coroutine(); self.state = MainStoryAI.State.Transfer; } private static void MoveToMonster(MainStoryAI self) { Unit leader = self.team.GetLeader(); if (AppConfig.inst.isTest) Log.Info($"【{UserComponent.Instance.Get(leader.Id)?.NickName} ({leader.Id})】移动到怪物"); int mapId = self.sceneId * 100 + self.layer; MainStory byMapId = MainStoryCategory.Instance.GetByMapId(mapId); MainStory.MonsterPos monsterPos = byMapId.MonsterPosArr[0]; self.targetPos = new Vector2(monsterPos.MonsterPos_X, monsterPos.MonsterPos_Y); MoveHelper.TeamMoveTo(self.team, self.targetPos).Coroutine(); self.state = MainStoryAI.State.Move; } private static void Battle(MainStoryAI self) { Unit leader = self.team.GetLeader(); if (AppConfig.inst.isTest) Log.Info($"【{UserComponent.Instance.Get(leader.Id)?.NickName} ({leader.Id})】战斗"); if (self.team.TeamState == TeamState.Fight) { Log.Error($"*【{UserComponent.Instance.Get(leader.Id)?.NickName} ({leader.Id})】多次进行主线战斗"); return; } UnitScene unitScene = leader.GetComponent(); MainStory mainStory = MainStoryMap.Instance.GetMainStoryData(unitScene.MapId); int layer = unitScene.MapId % 100; int copyId = layer switch { < 6 => CopyConfigId.MainStoryNormalBattle, < 10 => CopyConfigId.MainStoryEliteBattle, _ => CopyConfigId.MainStoryBossBattle }; CopyBattle battle = BattleMgrCompnent.Instance.CreateBattle(self.team); MonsterFactoryHelper.MainstoryGenerate(battle, mainStory); battle.Init(battle.team, battle.targetTeam, copyId, mainStory.Id); self.state = MainStoryAI.State.Battle; } private static void MoveToMapTransPoint(MainStoryAI self) { Unit leader = self.team.GetLeader(); if (AppConfig.inst.isTest) Log.Info($"【{UserComponent.Instance.Get(leader.Id)?.NickName} ({leader.Id})】移动到地图传送点"); SceneTransConfig sceneTransConfig = SceneTransConfigCategory.Instance.Get(self.sceneId); SceneTransConfig.TransPos transPos = sceneTransConfig.TransPosArr[0]; self.targetPos = new Vector2(transPos.TransPos_x, transPos.TransPos_y); MoveHelper.TeamMoveTo(self.team, self.targetPos).Coroutine(); self.state = MainStoryAI.State.Move; } private static void MapTrans(MainStoryAI self) { Unit leader = self.team.GetLeader(); if (AppConfig.inst.isTest) Log.Info($"【{UserComponent.Instance.Get(leader.Id)?.NickName} ({leader.Id})】地图传送"); self.layer++; int mapId = self.sceneId * 100 + self.layer; if (self.layer == 11) { mapId = 1000401; } Game.EventSystem.Publish(new ChangeMap { unit = leader, mapId = mapId }).Coroutine(); self.state = MainStoryAI.State.Transfer; } private static void StarCityTrans(MainStoryAI self) { Unit leader = self.team.GetLeader(); if (AppConfig.inst.isTest) Log.Info($"【{UserComponent.Instance.Get(leader.Id)?.NickName} ({leader.Id})】城镇传送"); if (leader.teamState == TeamState.Fight) { Log.Error($"【{UserComponent.Instance.Get(leader.Id)?.NickName} ({leader.Id})】战斗状态"); return; } PlayerData component = leader.GetComponent(); if ((bool) component && component.IsBattleIdle) { Log.Error($"【{UserComponent.Instance.Get(leader.Id)?.NickName} ({leader.Id})】挂机状态"); return; } self.layer = 1; int mapId = self.sceneId * 100 + self.layer; Game.EventSystem.Publish(new ChangeMap { unit = leader, mapId = mapId }).Coroutine(); self.state = MainStoryAI.State.Transfer; } private static void StarMoveToMonster(MainStoryAI self) { Unit leader = self.team.GetLeader(); if (AppConfig.inst.isTest) Log.Info($"【{UserComponent.Instance.Get(leader.Id)?.NickName} ({leader.Id})】移动到怪物"); var unitScene = leader.GetComponent(); MapMonsterConfig byMapId = MapMonsterConfigCategory.Instance.GetStarSoulCopyMapMonster(unitScene.layer); self.targetPos = new Vector2(byMapId.X, byMapId.Y); MoveHelper.TeamMoveTo(self.team, self.targetPos).Coroutine(); self.state = MainStoryAI.State.Move; } private static void StarBattle(MainStoryAI self) { Unit leader = self.team.GetLeader(); if (AppConfig.inst.isTest) Log.Info($"【{UserComponent.Instance.Get(leader.Id)?.NickName} ({leader.Id})】战斗"); if (self.team.TeamState == TeamState.Fight) { Log.Error($"*【{UserComponent.Instance.Get(leader.Id)?.NickName} ({leader.Id})】多次进行主线战斗"); return; } var config = leader.GetOrAddComponent(); config.type = self.type; config.difficulty = self.diffculty; var unitScene = leader.GetComponent(); StarSoulCopyConfig mainStory = StarSoulCopyConfigCategory.Instance.GetByTypeAndDifficultyAndIndex(config.type, config.difficulty, (byte) unitScene.layer); if (mainStory == null) { bool ret = MainStoryAIComponent.instance.DestoryAI(self); if (!ret) { Log.Error("结束AI出错"); Game.EventSystem.Publish(new ET.EventType.BackMainCity { unit = leader, isForce = true }).Coroutine(); return; } Game.EventSystem.Publish(new ET.EventType.BackMainCity { unit = leader, isForce = true }).Coroutine(); return; } CopyBattle battle = BattleMgrCompnent.Instance.CreateBattle(self.team); MonsterFactoryHelper.StarSoulGenerate(battle, mainStory); battle.Init(battle.team, battle.targetTeam, CopyConfigId.StarSoulBattle, mainStory.Id); self.state = MainStoryAI.State.Battle; } } }