LogicBattle.cs 16 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514
  1. using UnityEngine;
  2. using System.Collections.Generic;
  3. //战斗结束传递信息
  4. public class BattleEndInfo
  5. {
  6. public bool IsPlayRecord { get; set; }
  7. }
  8. /// <summary>
  9. ///挂机战斗逻辑
  10. /// </summary>
  11. public class LogicBattle : BaseBattle
  12. {
  13. LogicBattleStartInfo mStartInfo;
  14. LogicBattleState mState;
  15. #region properties
  16. public float PreviousFightingTime { get; set; } //上一次的战斗时长
  17. public int SceneId { get { return mStartInfo.SceneId; } }
  18. public int LevelId { get { return mStartInfo.LevelId; } }
  19. public int LevelType { get { return mStartInfo.LevelType; } }
  20. public override LevelItem CurLevelItem { get { return mStartInfo.curLevelItem; } }
  21. public SceneItem CurSceneItem { get { return mStartInfo.curSceneItem; } }
  22. public LogicBattleField CurrentBattleField { get { return BattleScene.CurrentBattleField; } }
  23. public LogicBattleStartInfo StartInfo { get { return mStartInfo; } }
  24. public LogicBattleScene BattleScene { get; set; }
  25. public override List<ActorData> MyFighters { get { return mStartInfo.GetMyFighters(); } }
  26. public override List<ActorData> EnemyFighters { get { return mStartInfo.GetEnemyFighters(BattleScene); } }
  27. private List<ActorData> mTeamPlayerActors;
  28. public override List<ActorData> TeamPlayerActors
  29. {
  30. get { return mTeamPlayerActors; }
  31. }
  32. public GameMode GameMode { get { return BattleScene.GameMode; } }
  33. public Transform TeamCenterPoint
  34. {
  35. get; private set;
  36. }
  37. public string BgMusic { get { return BattleScene.MapData == null || string.IsNullOrEmpty(BattleScene.MapData.bgmusic)
  38. ? MusicMgr.music_battle_default : BattleScene.MapData.bgmusic; } }
  39. public LogicBattleStateType CurrentState
  40. {
  41. get { return mState == null ? LogicBattleStateType.None : mState.State; }
  42. set
  43. {
  44. if (CurrentState == value)
  45. return;
  46. int oldState = (int)CurrentState;
  47. if (mState != null)
  48. mState.OnLeave();
  49. mState = LogicBattleState.Create(this, value);
  50. if (mState != null)
  51. mState.OnEnter();
  52. }
  53. }
  54. public int BattleIdx { get { return BattleScene.CurrentBattleIdx; } }
  55. public override int CurLevelMonsterLv
  56. {
  57. get { return CurLevelItem != null ? CurLevelItem.MonsterLv : 1; }
  58. }
  59. public override Vector3 BattleBossCamPos
  60. {
  61. get { return CurrentBattleField.CurrentWavePoint.BossCamPos; }
  62. }
  63. public override Vector3 BattleBossCamRot
  64. {
  65. get { return CurrentBattleField.CurrentWavePoint.BossCamRot; }
  66. }
  67. public override float BattleCamFar
  68. {
  69. get { return CurrentBattleField.CurrentWavePoint.CamFar; }
  70. }
  71. public override bool IsKillingBoss
  72. {
  73. get { return CurrentBattleField.killBoss; }
  74. }
  75. public bool IsAllFighterIdle
  76. {
  77. get { return CurrentBattleField.bIsAllFighterIdle(); }
  78. }
  79. private bool bNeedBackToLastPos = false;
  80. public bool NeedBackToLastPos
  81. {
  82. get { return bNeedBackToLastPos; }
  83. set { bNeedBackToLastPos = value; }
  84. }
  85. public Vector3 BackToPos
  86. {
  87. get;set;
  88. }
  89. #endregion //properties
  90. public LogicBattle(LogicBattleStartInfo startData, bool logicOnly, List<BattleEndCondition> endCondList)
  91. :base(BattleMode.Normal,endCondList)
  92. {
  93. IsLogicOnly = logicOnly;
  94. mStartInfo = startData;
  95. }
  96. public override void Start(int randSeed = 0, ValType[] factors = null)
  97. {
  98. base.Start(randSeed,factors);
  99. ChallengeBoss = false;
  100. CurrentState = LogicBattleStateType.Start;
  101. BattleMgr.Instance.SyncTeams(false);
  102. if (TeamCenterPoint == null)
  103. {
  104. GameObject point = new GameObject("TeamCenterPoint");
  105. point.layer = LayerMask.NameToLayer("Hide");
  106. TeamCenterPoint = point.transform;
  107. GameObject.DontDestroyOnLoad(point);
  108. }
  109. }
  110. public override void Update(float deltaTime)
  111. {
  112. base.Update(deltaTime);
  113. if(TeamCenterPoint!=null && !BattleMgr.Instance.IsRotatingCam)
  114. {
  115. TeamCenterPoint.position = TeamCenter;
  116. }
  117. #if PROFILE
  118. UnityEngine.Profiling.Profiler.BeginSample("LogicBattleState Update:"+ mState.ToString());
  119. #endif
  120. if (mState != null)
  121. mState.Update(deltaTime);
  122. #if PROFILE
  123. UnityEngine.Profiling.Profiler.EndSample();
  124. #endif
  125. }
  126. public override void Dispose()
  127. {
  128. base.Dispose();
  129. if (BattleScene != null)
  130. {
  131. BattleScene.Dispose();
  132. BattleScene = null;
  133. }
  134. }
  135. public override void ShutDown()
  136. {
  137. if (TeamCenterPoint != null)
  138. {
  139. GameObject.Destroy(TeamCenterPoint.gameObject);
  140. TeamCenterPoint = null;
  141. }
  142. base.ShutDown();
  143. CurrentState = LogicBattleStateType.None;
  144. mStartInfo = null;
  145. }
  146. public override void EnterNextBattle()
  147. {
  148. SetRandSeed(Random.Range(1, int.MaxValue));
  149. BattleScene.NextBattle();
  150. StartBattleField();
  151. if (BattleIdx > 0)
  152. {
  153. EventMgr.DispatchEvent<string>(new CoreEvent<string>(ECoreEventType.EID_BATTLE_NEW_NEXT_WAVE, CurrentBattleField.BattleInfo.Name));
  154. }
  155. if(BattleMgr.Instance.Battle.CanPrintLog)
  156. {
  157. DebugHelper.LogError("curMapId:" + CurLevelItem.MapId + " curLevelId:" + CurLevelItem.LevelId);
  158. }
  159. }
  160. public override void ContinueCurrentBattle()
  161. {
  162. SetRandSeed(Random.Range(1, int.MaxValue));
  163. BattleScene.ReopenBattle();
  164. StartBattleField();
  165. EventMgr.DispatchEvent<bool>(new CoreEvent<bool>(ECoreEventType.EID_BATTLE_CONTINUE_WAVE, true));
  166. }
  167. void StartBattleField()
  168. {
  169. if (CurrentBattleField != null)
  170. {
  171. BackToLastPos();
  172. CurrentBattleField.Start();
  173. }
  174. }
  175. public override void MoveToNextBattleField(bool setStopDistance)
  176. {
  177. if (CurrentBattleField == null) return;
  178. ReadyPoint nextWaveSP = BattleScene.ActorBornPoint;
  179. List<Fighter> heros = FighterMgr.TeamHeroFighters;
  180. for (int idx = 0; idx < heros.Count && idx < 4; idx++)
  181. {
  182. Fighter hero = heros[idx];
  183. if (hero.IsDestroy || hero.IsDisposed)
  184. continue;
  185. hero.Ctrl.EnableNavAgent(true);
  186. float stopDist = setStopDistance ? CurrentBattleField.CurrentWavePoint.ActorReadyDist : 0;
  187. var pointCfg = nextWaveSP.GetReadyPointPos(hero.Actor.Profession, hero.ReadyPosOrder);
  188. Vector3 destPos = pointCfg.heroPos;
  189. hero.AutoMoveTo(destPos);
  190. hero.SyncPetMoveDestPos(pointCfg.petPos, true, true);
  191. }
  192. }
  193. public void ReadyTransfer()
  194. {
  195. List<Fighter> members = FighterMgr.TeamFighters;
  196. for (int idx = 0; idx < members.Count; idx++)
  197. {
  198. Fighter member = members[idx];
  199. member.Ctrl.OnEnterTransfer();
  200. member.Ctrl.EnableNavAgent(false);
  201. member.ForceIdle();
  202. }
  203. BattleCamera.Instance.DisableDynamicCamera();
  204. int effectId = GlobalConfig.Instance.GetConfigIntValue(GlobalConfig.c_transfer_effectid);
  205. if(effectId > 0)
  206. {
  207. EffectManager.Instance.PlayEffect(effectId);
  208. }
  209. }
  210. //拉到传送点
  211. public void GoToTransferPoint()
  212. {
  213. ReadyPoint nextWaveSp = BattleScene.ActorBornPoint;
  214. List<Fighter> heros = FighterMgr.TeamHeroFighters;
  215. for (int idx = 0; idx < heros.Count; idx++)
  216. {
  217. Fighter hero = heros[idx];
  218. var pointCfg = nextWaveSp.GetReadyPointPos(hero.Actor.Profession, hero.ReadyPosOrder);
  219. hero.SyncPosition(pointCfg.heroPos);
  220. hero.SyncPetPosition(pointCfg.petPos);
  221. }
  222. Vector3 forward = CurrentBattleField.EnemyFighters[0].Ctrl.transform.forward;
  223. Vector3 rot = CurrentBattleField.CurrentWavePoint.Rot;
  224. rot.y = 180 + rot.y;
  225. Vector3 center = CurrentBattleField.CurrentWavePoint.Pos + forward * CurrentBattleField.CurrentWavePoint.ActorReadyDist;
  226. CurrentBattleField.Battle.BattleScene.ActorBornPoint.CalcNextBattleFieldPoints(center, rot);
  227. BattleMgr.Instance.SetBossBattleCamera();
  228. }
  229. //回到传送之前的位置点
  230. public void BackToLastPos()
  231. {
  232. if (!bNeedBackToLastPos) return;
  233. Vector3 rot = BattleScene.MapMonsterSpawnPoint.Rot;
  234. rot.y = 180 + rot.y;
  235. BattleScene.ActorBornPoint.CalcNextBattleFieldPoints(BackToPos, rot);
  236. List<Fighter> Heros = FighterMgr.TeamHeroFighters;
  237. for (int idx = 0; idx < Heros.Count && idx < 4; idx++)
  238. {
  239. Fighter hero = Heros[idx];
  240. hero.Ctrl.EnableNavAgent(false);
  241. var pointCfg = BattleScene.ActorBornPoint.GetReadyPointPos(hero.Actor.Profession, hero.ReadyPosOrder);
  242. hero.SyncPosition(pointCfg.heroPos);
  243. hero.SyncPetPosition(pointCfg.petPos,true,false);
  244. }
  245. BattleMgr.Instance.SetFollowCamera(BattleScene.ActorBornPoint.transform.forward,true);
  246. }
  247. public override bool IsAllFightersReady()
  248. {
  249. List<Fighter> Members = FighterMgr.TeamFighters;
  250. for (int idx = 0; idx < Members.Count; idx++)
  251. {
  252. if (!Members[idx].IsIdle)
  253. return false;
  254. }
  255. return true;
  256. }
  257. public bool IsSelfReady()
  258. {
  259. List<Fighter> Members = FighterMgr.TeamFighters;
  260. if (Members.Count == 0) return false;
  261. return Members[0].IsIdle;
  262. }
  263. public void CheckTeamPlayerActors()
  264. {
  265. if(mTeamPlayerActors == null)
  266. {
  267. mTeamPlayerActors = new List<ActorData>();
  268. }
  269. else
  270. {
  271. mTeamPlayerActors.Clear();
  272. }
  273. for(int idx =0; idx < FighterMgr.TeamFighters.Count;idx++)
  274. {
  275. if (!FighterMgr.TeamFighters[idx].IsPet)
  276. {
  277. mTeamPlayerActors.Add(FighterMgr.TeamFighters[idx].Actor);
  278. }
  279. }
  280. }
  281. int actorCnt = 0;
  282. int curLoadCnt = 0;
  283. public override bool AddNewActors(List<ActorData> actors,eTeamType teamside=eTeamType.Friend,bool spawn =true)
  284. {
  285. if (actors == null || actors.Count == 0) return false;
  286. List<ActorData> tempPetActors = new List<ActorData>();
  287. for(int idx =0; idx < actors.Count;idx++)
  288. {
  289. if(actors[idx].HasPet)
  290. {
  291. tempPetActors.Add(actors[idx].PetData);
  292. }
  293. }
  294. //销毁 现有队伍中不存在 或者 已转职的角色 (包括其宠物) 否则重置数据
  295. for(int idx = FighterMgr.TeamHeroFighters.Count-1; idx >=0;idx--)
  296. {
  297. Fighter f = FighterMgr.TeamHeroFighters[idx];
  298. ActorData ad = NeedRemove(actors, f.Actor);
  299. if (ad == null || ad.IsTransferred)
  300. {
  301. if(ad == null && f.UsedPetId > 0)
  302. {
  303. Fighter pet = FighterMgr.GetTeamMemberById(f.UsedPetId);
  304. pet.Destroy();
  305. FighterMgr.RemoveFighter(pet);
  306. }
  307. f.Destroy();
  308. FighterMgr.RemoveFighter(f);
  309. }
  310. else
  311. {
  312. f.ResetActor(ad);
  313. }
  314. }
  315. for (int idx = actors.Count - 1; idx >= 0; idx--)
  316. {
  317. if (FighterMgr.HasTeamHero(actors[idx].ID) && !actors[idx].IsTransferred)
  318. {
  319. actors.RemoveAt(idx);
  320. }
  321. }
  322. //删除在新数据中不存在的宠物 同步已有宠物信息
  323. for (int idx = FighterMgr.TeamPetFighters.Count -1;idx>=0;idx--)
  324. {
  325. Fighter pet = FighterMgr.TeamPetFighters[idx];
  326. ActorData petData = NeedRemove(tempPetActors, pet.Actor);
  327. if(petData == null)
  328. {
  329. pet.Destroy();
  330. FighterMgr.RemoveFighter(pet);
  331. }
  332. else
  333. {
  334. pet.ResetActor(petData);
  335. }
  336. }
  337. //删除新数据 已经同步过得宠物数据
  338. for(int idx = tempPetActors.Count -1; idx >= 0;idx--)
  339. {
  340. if (FighterMgr.HasPet(tempPetActors[idx].ID))
  341. {
  342. tempPetActors.RemoveAt(idx);
  343. }
  344. }
  345. actorCnt = actors.Count + tempPetActors.Count;
  346. if(actorCnt > 0)//创建新数据角色
  347. {
  348. fighterResOk = false;
  349. FighterMgr.AddFighters(actors.ToArray(), teamside);
  350. FighterMgr.AddFighters(tempPetActors.ToArray(), teamside);
  351. for(int idx =0; idx < FighterMgr.TeamHeroFighters.Count;idx++)
  352. {
  353. if(FighterMgr.TeamHeroFighters[idx].Actor.PetData!=null)
  354. {
  355. var pet = FighterMgr.GetTeamMemberById(FighterMgr.TeamHeroFighters[idx].Actor.PetData.ID);
  356. pet.OwnerId = FighterMgr.TeamHeroFighters[idx].Id;
  357. FighterMgr.TeamHeroFighters[idx].UsedPetId = pet.Id;
  358. }
  359. }
  360. curLoadCnt = 0;
  361. IsLoadingActor = true;
  362. EventMgr.DispatchEvent<bool>(new CoreEvent<bool>(ECoreEventType.EID_FIGHTERS_LOAD_OK, false));
  363. EventMgr.AddEventListener<Fighter>(ECoreEventType.EID_FIGHTER_ASYNC_LOADED, OnFighterAsyncLoaded);
  364. for (int idx = 0; idx < actors.Count; idx++)
  365. {
  366. Fighter f = FighterMgr.GetFighterByID(actors[idx].ID, teamside);
  367. if (f!=null && f.Ctrl != null)
  368. f.Ctrl.AsyncLoad();
  369. else
  370. DebugHelper.LogError("fighter id:" + actors[idx].ID+" not exist");
  371. }
  372. for(int idx =0; idx < tempPetActors.Count;idx++)
  373. {
  374. Fighter pet = FighterMgr.GetFighterByID(tempPetActors[idx].ID, teamside);
  375. if (pet != null && pet.Ctrl != null)
  376. pet.Ctrl.AsyncLoad();
  377. }
  378. }
  379. else
  380. {
  381. for (int idx = 0; idx < FighterMgr.TeamHeroFighters.Count; idx++)
  382. {
  383. if (FighterMgr.TeamHeroFighters[idx].Actor.PetData != null)
  384. {
  385. var pet = FighterMgr.GetTeamMemberById(FighterMgr.TeamHeroFighters[idx].Actor.PetData.ID);
  386. pet.OwnerId = FighterMgr.TeamHeroFighters[idx].Id;
  387. FighterMgr.TeamHeroFighters[idx].UsedPetId = pet.Id;
  388. }
  389. }
  390. }
  391. if (actorCnt > 0)
  392. {
  393. prepareResOk = false;
  394. EventMgr.AddEventListener<bool>(ECoreEventType.EID_PREPARE_LOAD_OK, OnPrepareLoadOk);
  395. BattlePrepareManager.Instance.StartLoad();
  396. return true;
  397. }
  398. return false;
  399. }
  400. ActorData NeedRemove(List<ActorData> actors, ActorData ad)
  401. {
  402. for(int idx =0; idx < actors.Count;idx++)
  403. {
  404. if (actors[idx].ID == ad.ID) return actors[idx];
  405. }
  406. return null;
  407. }
  408. bool prepareResOk = false;
  409. bool fighterResOk = false;
  410. void OnFighterAsyncLoaded(CoreEvent<Fighter> ce)
  411. {
  412. Fighter f = ce.Data;
  413. if (f.IsPlayer || f.IsPet)
  414. {
  415. curLoadCnt++;
  416. Vector3 forward = FighterMgr.TeamFighters[0].Forward;
  417. Vector3 pos = FighterMgr.TeamFighters[0].Position + forward * Random.Range(-3,3);
  418. f.Spawn(pos, forward, Quaternion.identity);
  419. if (curLoadCnt == actorCnt)
  420. {
  421. IsLoadingActor = false;
  422. fighterResOk = true;
  423. EventMgr.RemoveEventListener<Fighter>(ECoreEventType.EID_FIGHTER_ASYNC_LOADED, OnFighterAsyncLoaded);
  424. CheckLoadOK();
  425. }
  426. }
  427. }
  428. void OnPrepareLoadOk(CoreEvent<bool> ce)
  429. {
  430. EventMgr.RemoveEventListener<bool>(ECoreEventType.EID_PREPARE_LOAD_OK, OnPrepareLoadOk);
  431. prepareResOk = true;
  432. CheckLoadOK();
  433. }
  434. void CheckLoadOK()
  435. {
  436. if(prepareResOk && fighterResOk)
  437. EventMgr.DispatchEvent<bool>(new CoreEvent<bool>(ECoreEventType.EID_FIGHTERS_LOAD_OK, true));
  438. }
  439. }