using Cal.DataTable; using ET.EventType; using System; using System.Collections.Generic; namespace ET { public class PvpMapAwakeSystem : AwakeSystem { public override void Awake(PvpMap self) { PvpMap.inatance = self; self.timerId = TimerComponent.Instance.NewRepeatedTimer(30 * 1000, self.UpdatePer30); } } public class PvpMapDestroySystem : DestroySystem { public override void Destroy(PvpMap self) { TimerComponent.Instance.Remove(ref self.timerId); } } public static class PvpMapSystem { class SendReword : AEvent { public override async ETTask Run(UpdatePer1HourOfDay args) { DateTime dateTime = DateTime.Now; if (dateTime.DayOfWeek != DayOfWeek.Wednesday && dateTime.DayOfWeek != DayOfWeek.Friday) { return; } DateTime now = Game.TimeInfo.ToDateTime(args.now).ToLocalTime(); if (now.Hour == 22) { await PvpMap.inatance.SettlePvp(); } await ETTask.CompletedTask; } } public static void UpdatePer30(this PvpMap self) { if (PvpMap.inatance.CanPvp() != null) return; // Log.Info($"{PvpMap.inatance.matchGoldList.ToCustomString()}"); // Log.Info($"{PvpMap.inatance.matchSliverList.ToCustomString()}"); // Log.Info($"{PvpMap.inatance.matchCupperList.ToCustomString()}"); PvpMap.inatance.MatchBattle(PvpMap.inatance.matchGoldList); PvpMap.inatance.MatchBattle(PvpMap.inatance.matchSliverList); PvpMap.inatance.MatchBattle(PvpMap.inatance.matchCupperList); ClearNotInSceneUnit(PersonalPvpType.Cupper, PvpMap.inatance.matchCupperList); ClearNotInSceneUnit(PersonalPvpType.Sliver, PvpMap.inatance.matchSliverList); ClearNotInSceneUnit(PersonalPvpType.Gold, PvpMap.inatance.matchGoldList); } private static void ClearNotInSceneUnit(PersonalPvpType type, List list) { try { MapScene mapScene = null; switch (type) { case PersonalPvpType.Cupper: mapScene = MapSceneComponent.Instance.GetMap(Sys_SceneId.Scene_PersonalPvp1 * 100 + 1); break; case PersonalPvpType.Sliver: mapScene = MapSceneComponent.Instance.GetMap(Sys_SceneId.Scene_PersonalPvp2 * 100 + 1); break; case PersonalPvpType.Gold: mapScene = MapSceneComponent.Instance.GetMap(Sys_SceneId.Scene_PersonalPvp3 * 100 + 1); break; default: break; } if (mapScene == null) return; using ListComponent listComponent = ListComponent.Create(); listComponent.List.AddRange(mapScene.GetAll()); for (int i = list.Count - 1; i >= 0; i--) { Unit unit = list[i]; if (!listComponent.List.Contains(unit)) { list.RemoveAt(i); } } } catch (Exception e) { Log.Error(e); } } public static async ETTask SettlePvp(this PvpMap self) { self.rankList.Clear(); List list = await DBComponent.Instance.QueryJson("{}"); using ListComponent<(long, int, int)> listComponent = ListComponent<(long, int, int)>.Create(); foreach (PlayerData data in list) { try { if (data.personalPvpCount > 0) listComponent.List.Add((data.Id, data.personalScord, data.personalPvpCount)); data.personalPvpCount = 0; data.personalScord = 0; Unit _unit = MapUnitComponent.Instance.Get(data.Id); if (_unit) { _unit.RemoveComponent(); _unit.AddComponent(data); } UnitHelper.SaveComponenet(data).Coroutine(); } catch (Exception e) { Log.Error(e); } } listComponent.List.Sort((a, b) => -a.Item2.CompareTo(b.Item2)); try { Log.Info($"1 : {listComponent.List?[0].Item1} {listComponent.List?[0].Item2}"); Log.Info($"2 : {listComponent.List?[1].Item1} {listComponent.List?[1].Item2}"); Log.Info($"3 : {listComponent.List?[2].Item1} {listComponent.List?[2].Item2}"); } catch (Exception e) { Log.Error(e); } int goldRank = 0, sliverRank = 0, cupperRank = 0; for (int i = 0; i < listComponent.List.Count; i++) { (long id, int pvpScord, int pvpCount) = listComponent.List[i]; try { if (pvpScord >= 100) { int voucher = 500 - (10*goldRank); goldRank++; if (voucher < 300) voucher = 300; await MailHelper.AddItem(id, BagHelper.VoucherId, voucher, true, "", "竞技场奖励", "黄金段位的奖励", "系统"); continue; } if (pvpScord >= 50) { int voucher = 300 - (5 * sliverRank); sliverRank++; if (voucher < 50) voucher = 50; await MailHelper.AddItem(id, BagHelper.VoucherId, voucher, true, "", "竞技场奖励", "白银段位的奖励", "系统"); } else { if (pvpCount >= 20) { int voucher = 50 - (2 * cupperRank); cupperRank++; if(voucher>0) await MailHelper.AddItem(id, BagHelper.VoucherId, voucher, true, "", "竞技场奖励", $"青铜段位的奖励,你战斗了{pvpCount}次", "系统"); } } } catch (Exception e) { Log.Error(e); } } } public static string CanPvp(this PvpMap self) { DateTime dateTime = DateTime.Now; if (AppConfig.inst.isTest) return null; if (dateTime.DayOfWeek != DayOfWeek.Wednesday && dateTime.DayOfWeek != DayOfWeek.Friday) { return $"周三、周五 开启!"; } DateTime start = new(dateTime.Year, dateTime.Month, dateTime.Day, 19, 00, 0, DateTimeKind.Local); DateTime end = start.AddHours(2); if (dateTime < start || dateTime > end) { return $"周三、周五 {start:HH:mm}~{end:HH:mm}开启!"; } return null; } public static bool CanEnterPvpMap(this PvpMap self, PlayerData data, int mapId) { try { int sceneId = mapId / 100; PersonalPvpType pvpType = sceneId switch { Sys_SceneId.Scene_PersonalPvp1 => PersonalPvpType.Cupper, Sys_SceneId.Scene_PersonalPvp2 => PersonalPvpType.Sliver, Sys_SceneId.Scene_PersonalPvp3 => PersonalPvpType.Gold, _ => throw new Exception($"scene is wrong => {mapId}") }; PersonalPvpType canEnterLevel = GetLevelType(self, data.personalScord); if (canEnterLevel == pvpType) return true; } catch (Exception e) { Log.Error(e); } return false; } public static async ETTask SettleBattle(this PvpMap self, Team win, Team fail) { try { Unit winner = MapUnitComponent.Instance.Get(win.LeaderId); Unit failer = MapUnitComponent.Instance.Get(fail.LeaderId); await SettleBattle(self, winner, failer); } catch (Exception e) { Log.Error(e); } } /// /// 结算积分 /// /// /// /// public static async ETTask SettleBattle(this PvpMap self, Unit winner, Unit failer) { try { PlayerData winData, failData; if (!winner) winData = await DBComponent.Instance.Query(winner.Id); else winData = winner.GetComponent(); if (!failer) failData = await DBComponent.Instance.Query(failer.Id); else failData = failer.GetComponent(); winData.personalPvpCount++; failData.personalPvpCount++; NumericComponent num = winner.GetComponent(); NumericComponent failNum = failer.GetComponent(); switch (GetLevelType(self, winData.personalScord)) { case PersonalPvpType.Cupper: winData.personalScord += 4; num.AddSet(NumericType.PvpMoney, 5); failNum.AddSet(NumericType.PvpMoney, 3); break; case PersonalPvpType.Sliver: winData.personalScord += 2; failData.personalScord -= 1; num.AddSet(NumericType.PvpMoney, 8); failNum.AddSet(NumericType.PvpMoney, 5); break; case PersonalPvpType.Gold: winData.personalScord += 1; failData.personalScord -= 1; num.AddSet(NumericType.PvpMoney, 12); failNum.AddSet(NumericType.PvpMoney, 8); break; default: break; } UnitHelper.SaveComponenet(num).Coroutine(); UnitHelper.SaveComponenet(failNum).Coroutine(); UnitHelper.SaveComponenet(winData).Coroutine(); UnitHelper.SaveComponenet(failData).Coroutine(); ModifyData(self, winData); ModifyData(self, failData); if (failData.personalScord < 0) failData.personalScord = 0; SetPvpMap(self, winner, winData); SetPvpMap(self, failer, failData); } catch (Exception e) { Log.Error(e); } } private static void ModifyData(PvpMap self, PlayerData data) { for (LinkedListNode<(long, int)>? item = self.rankList.First; item != null; item = item.Next) { if (item.Value.Item1 == data.Id) { self.rankList.Remove(item); break; } } LinkedListHelper.InsertToLinkedListAndSort(self.rankList, (data.Id, data.personalScord), (a, b) => a.Item2 > b.Item2); } private static void SetPvpMap(this PvpMap self, Unit unit, PlayerData data) { try { if (data.personalPvpCount > ConstDefine.PersonalMaxBattleCount) { Game.EventSystem.Publish(new ET.EventType.BackMainCity { unit = unit, }).Coroutine(); return; } int sceneId = GetLevelType(self, data.personalScord) switch { PersonalPvpType.Cupper => Sys_SceneId.Scene_PersonalPvp1, PersonalPvpType.Sliver => Sys_SceneId.Scene_PersonalPvp2, PersonalPvpType.Gold => Sys_SceneId.Scene_PersonalPvp3, _ => throw new Exception($"{GetLevelType(self, data.personalScord)} scord = {data.personalScord}"), }; UnitScene unitScene = unit.GetComponent(); if (unitScene.MapId / 100 == sceneId) return; Game.EventSystem.Publish(new ET.EventType.ChangeMap { unit = unit, mapId = sceneId * 100 + 1 }).Coroutine(); } catch (Exception e) { Log.Error(e); } } public static PersonalPvpType GetLevelType(this PvpMap self, int scord) { int index = (int)PersonalPvpType.Gold; for (int i = 0; i < ConstDefine.PersonalPvpScordArr.Length; i++) { if (ConstDefine.PersonalPvpScordArr[i] > scord) { index = i - 1; break; } } if (index < 0) index = 0; return (PersonalPvpType)index; } public static string RequestMatch(this PvpMap self, Unit unit) { PlayerData data = unit.GetComponent(); if (data == null) { Log.Error($"【{UserComponent.Instance.Get(unit.Id)?.NickName}({unit.Id})】无 data"); return "系统错误"; } if (data.personalPvpCount > ConstDefine.PersonalMaxBattleCount) { return "战斗次数达到上限"; } UnitScene unitScene = unit.GetComponent(); UnitSceneType unitSceneType = MapHelper.GetMapType(unitScene.MapId / 100); if (unitSceneType != UnitSceneType.PersonalPvp) { return "只能在竞技场匹配"; } if (unit.teamState == TeamState.Fight) { return "战斗中..."; } PersonalPvpType type = GetLevelType(self, data.personalScord); return Mathch(self, unit, type); } private static string Mathch(PvpMap self, Unit unit, PersonalPvpType type) { List list = null; switch (type) { case PersonalPvpType.Cupper: list = self.matchCupperList; break; case PersonalPvpType.Sliver: list = self.matchSliverList; break; case PersonalPvpType.Gold: list = self.matchGoldList; break; default: break; } if (list == null) { Log.Error($"list = null"); return "系统错误"; } if (list.Contains(unit)) { return "正在匹配中"; } list.Add(unit); return "正在匹配..."; } static void MatchBattle(this PvpMap self, List list) { if (list.Count < 2) return; using ListComponent listComponent = ListComponent.Create(); listComponent.List.AddRange(list.FindAll(t => t && t.teamState != TeamState.Fight)); listComponent.List.Sort((a, b) => { try { if (!a) return -1; if (!b) return 1; PlayerData dataA = a.GetComponent(); PlayerData dataB = b.GetComponent(); if (dataA.personalScord != dataB.personalScord) { return -dataA.personalScord.CompareTo(dataB.personalScord); } NumericComponent numA = a.GetComponent(); NumericComponent numB = b.GetComponent(); int levelA = numA.GetAsInt(NumericType.Level); int levelB = numB.GetAsInt(NumericType.Level); return -levelA.CompareTo(levelB); } catch (Exception e) { Log.Error(e); } return -1; }); for (int i = 1; i < listComponent.List.Count; i += 2) { Unit unitA = listComponent.List[i - 1]; Unit unitB = listComponent.List[i]; StartBattle(unitA, unitB).Coroutine(); } } private static async ETTask StartBattle(Unit unit, Unit target) { await TimerComponent.Instance.WaitFrameAsync(); Team team = TeamComponent.Instance.Get(unit.TeamLeaderId); Team targetTeam = TeamComponent.Instance.Get(target.TeamLeaderId); CopyBattle battle = BattleMgrCompnent.Instance.CreateBattle(team); battle.Init(team,targetTeam,CopyConfigId.PersonalPvpBattle,0); } public static void Remove(this PvpMap self, Unit unit) { if (self.CanPvp() != null) return; self.matchCupperList.Remove(unit); self.matchSliverList.Remove(unit); self.matchGoldList.Remove(unit); } public static async ETTask GetRankList(this PvpMap self, List list) { for (LinkedListNode<(long, int)>? item = self.rankList.First; item != null; item = item.Next) { try { User user = await UserComponent.Instance.Query(item.Value.Item1); list.Add(new PvpRankInfo { name = user.NickName, jobIs = user.JobId, level = user.Level, scord = item.Value.Item2 }); } catch (Exception e) { Log.Error(e); } } return null; } } }