zxl
/
CTT
forked from Cal/CTT
1
0
Fork 0
CTT/Server/Hotfix/Game/System/Map/PvpMapSystem.cs

511 lines
19 KiB
C#
Raw Normal View History

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