Fix Basic Challenge

This commit is contained in:
Somebody
2024-09-14 23:00:50 +08:00
parent b84800bc80
commit 6371472278
13 changed files with 266 additions and 44 deletions

View File

@@ -13,7 +13,7 @@ public class ChallengeBossExtraExcel : ExcelResource
return ID;
}
public override void Loaded()
public override void AfterAllDone()
{
if (GameData.ChallengeConfigData.ContainsKey(ID))
{

View File

@@ -14,6 +14,7 @@ public class ChallengeConfigExcel : ExcelResource
public int ID { get; set; }
public int GroupID { get; set; }
public int MapEntranceID { get; set; }
public int MapEntranceID2 { get; set; }
public int StageNum { get; set; }
public int ChallengeCountDown { get; set; }
public int MazeBuffID { get; set; }

View File

@@ -14,7 +14,7 @@ public class ChallengeStoryExtraExcel : ExcelResource
return ID;
}
public override void Loaded()
public override void AfterAllDone()
{
if (GameData.ChallengeConfigData.ContainsKey(ID))
{

View File

@@ -2,7 +2,7 @@
namespace EggLink.DanhengServer.Data.Excel;
[ResourceEntity("StageConfig.json", false)]
[ResourceEntity("StageConfig.json,StageTestConfig.json", true)]
public class StageConfigExcel : ExcelResource
{
public int StageID { get; set; } = 0;

View File

@@ -127,6 +127,35 @@ public class ItemData
};
}
public ChallengeBossEquipmentInfo ToChallengeEquipmentProto()
{
return new ChallengeBossEquipmentInfo
{
Tid = (uint)ItemId,
UniqueId = (uint)UniqueId,
Level = (uint)Level,
Promotion = (uint)Promotion,
Rank = (uint)Rank
};
}
public ChallengeBossRelicInfo ToChallengeRelicProto()
{
var proto = new ChallengeBossRelicInfo
{
Tid = (uint)ItemId,
UniqueId = (uint)UniqueId,
Level = (uint)Level,
MainAffixId = (uint)MainAffix
};
if (SubAffixes.Count < 1) return proto;
foreach (var subAffix in SubAffixes)
proto.SubAffixList.Add(subAffix.ToProto());
return proto;
}
public Item ToProto()
{
return new Item

View File

@@ -30,7 +30,9 @@ public class BattleInstance(PlayerInstance player, LineupInfo lineup, List<Stage
{
foreach (var id in monsters.Select(monster => monster.GetStageId()))
{
GameData.StageConfigData.TryGetValue(id, out var stage);
GameData.PlaneEventData.TryGetValue(id * 10 + player.Data.WorldLevel, out var planeEvent);
if (planeEvent == null) continue;
GameData.StageConfigData.TryGetValue(planeEvent.StageID, out var stage);
if (stage != null) Stages.Add(stage);
}
@@ -214,7 +216,8 @@ public class BattleInstance(PlayerInstance player, LineupInfo lineup, List<Stage
WorldLevel = (uint)WorldLevel,
RoundsLimit = (uint)RoundLimit,
StageId = (uint)StageId,
LogicRandomSeed = (uint)Random.Shared.Next()
LogicRandomSeed = (uint)Random.Shared.Next(),
GPNMHCNAODM = new()
};
foreach (var protoWave in Stages.Select(wave => wave.ToProto()))

View File

@@ -54,10 +54,10 @@ public class ChallengeEntityLoader(SceneInstance scene, PlayerInstance player) :
// Get current stage monster infos
Dictionary<int, ChallengeConfigExcel.ChallengeMonsterInfo> challengeMonsters;
if (instance.Excel.MazeGroupID1 == group.Id)
challengeMonsters = instance.Excel.ChallengeMonsters1;
else if (instance.Excel.MazeGroupID2 == group.Id)
challengeMonsters = instance.Excel.ChallengeMonsters2;
if (instance.Excel.MazeGroupID1 == group.Id || instance.Excel.MazeGroupID2 == group.Id)
{
challengeMonsters = instance.CurrentStage == 1 ? instance.Excel.ChallengeMonsters1 : instance.Excel.ChallengeMonsters2;
}
else
return null;

View File

@@ -2,6 +2,7 @@
using EggLink.DanhengServer.Data;
using EggLink.DanhengServer.Data.Excel;
using EggLink.DanhengServer.Database.Challenge;
using EggLink.DanhengServer.Enums.Item;
using EggLink.DanhengServer.Enums.Mission;
using EggLink.DanhengServer.GameServer.Game.Battle;
using EggLink.DanhengServer.GameServer.Game.Player;
@@ -132,13 +133,22 @@ public class ChallengeInstance
ScoreTwo = (uint)ScoreStage2,
RoundCount = (uint)GetRoundsElapsed(),
ExtraLineupType = (ExtraLineupType)CurrentExtraLineup,
StageInfo = new ChallengeStoryInfo
{
CurStoryBuffs = new ChallengeStoryBuffList(),
CurBossBuffs = new ChallengeBossBuffList()
}
StageInfo = new ChallengeStoryInfo()
};
if (Excel.IsBoss())
{
proto.StageInfo.CurBossBuffs = new ChallengeBossBuffList
{
ChallengeBossConst = 1
};
}
if (Excel.IsStory())
{
proto.StageInfo.CurStoryBuffs = new ChallengeStoryBuffList();
}
if (StoryBuffs.Count >= CurrentStage)
proto.StageInfo.CurStoryBuffs.BuffList.Add(StoryBuffs.Select(x => (uint)x));
@@ -148,6 +158,65 @@ public class ChallengeInstance
return proto;
}
public ChallengeStageInfo ToStageInfo()
{
var proto = new ChallengeStageInfo();
if (Excel.IsBoss())
{
proto.BossInfo = new ChallengeBossInfo
{
FirstNode = new ChallengeBossSingleNodeInfo
{
BuffId = (uint)BossBuffs[0]
},
SecondNode = new ChallengeBossSingleNodeInfo
{
BuffId = (uint)BossBuffs[1]
},
LBOJBINABDG = true
};
foreach (var lineupAvatar in Player.LineupManager?.GetExtraLineup(ExtraLineupType.LineupChallenge)?.BaseAvatars ?? [])
{
var avatar = Player.AvatarManager?.GetAvatar(lineupAvatar.BaseAvatarId);
if (avatar == null) continue;
proto.BossInfo.FirstLineup.Add((uint)avatar.GetAvatarId());
proto.BossInfo.ChallengeAvatarEquipmentMap.Add((uint)avatar.GetAvatarId(), Player.InventoryManager?.GetItem(0, avatar.GetCurPathInfo().EquipId, ItemMainTypeEnum.Equipment)?.ToChallengeEquipmentProto()); // it wont be null
var relicProto = new ChallengeBossAvatarRelicInfo();
foreach (var relicUniqueId in avatar.GetCurPathInfo().Relic)
{
var relic = Player.InventoryManager?.GetItem(0, relicUniqueId.Value, ItemMainTypeEnum.Relic);
if (relic == null) continue;
relicProto.AvatarRelicSlotMap.Add((uint)relicUniqueId.Key, relic.ToChallengeRelicProto());
}
proto.BossInfo.ChallengeAvatarRelicMap.Add((uint)avatar.GetAvatarId(), relicProto);
}
foreach (var lineupAvatar in Player.LineupManager?.GetExtraLineup(ExtraLineupType.LineupChallenge2)?.BaseAvatars ?? [])
{
var avatar = Player.AvatarManager?.GetAvatar(lineupAvatar.BaseAvatarId);
if (avatar == null) continue;
proto.BossInfo.FirstLineup.Add((uint)avatar.GetAvatarId());
proto.BossInfo.ChallengeAvatarEquipmentMap.Add((uint)avatar.GetAvatarId(), Player.InventoryManager?.GetItem(0, avatar.GetCurPathInfo().EquipId, ItemMainTypeEnum.Equipment)?.ToChallengeEquipmentProto()); // it wont be null
var relicProto = new ChallengeBossAvatarRelicInfo();
foreach (var relicUniqueId in avatar.GetCurPathInfo().Relic)
{
var relic = Player.InventoryManager?.GetItem(0, relicUniqueId.Value, ItemMainTypeEnum.Relic);
if (relic == null) continue;
relicProto.AvatarRelicSlotMap.Add((uint)relicUniqueId.Key, relic.ToChallengeRelicProto());
}
proto.BossInfo.ChallengeAvatarRelicMap.Add((uint)avatar.GetAvatarId(), relicProto);
}
}
return proto;
}
#endregion
#region Management
@@ -156,15 +225,12 @@ public class ChallengeInstance
{
battle.RoundLimit = RoundsLeft;
if (StoryBuffs != null)
{
battle.Buffs.Add(new MazeBuff(Excel.MazeBuffID, 1, -1));
battle.Buffs.Add(new MazeBuff(Excel.MazeBuffID, 1, -1));
if (StoryBuffs.Count >= CurrentStage)
{
var buffId = StoryBuffs[CurrentStage - 1];
battle.Buffs.Add(new MazeBuff(buffId, 1, -1));
}
if (StoryBuffs.Count >= CurrentStage)
{
var buffId = StoryBuffs[CurrentStage - 1];
battle.Buffs.Add(new MazeBuff(buffId, 1, -1));
}
if (Excel.StoryExcel != null)
@@ -173,6 +239,12 @@ public class ChallengeInstance
foreach (var id in Excel.StoryExcel.BattleTargetID!) battle.AddBattleTarget(5, id, GetTotalScore());
}
if (Excel.BossExcel != null)
{
battle.AddBattleTarget(1, 90004, 0);
battle.AddBattleTarget(1, 90005, 0);
}
}
public virtual async ValueTask OnBattleEnd(BattleInstance battle, PVEBattleResultCsReq req)
@@ -189,6 +261,22 @@ public class ChallengeInstance
ScoreStage2 = stageScore;
}
if (IsBoss())
{
// Calculate score for current stage
var stageScore = 0;
foreach (var battleTarget in req.Stt.BattleTargetInfo[1].BattleTargetList_)
{
stageScore += (int)battleTarget.Progress;
}
// Set score
if (CurrentStage == 1)
ScoreStage1 = stageScore;
else
ScoreStage2 = stageScore;
}
switch (req.EndStatus)
{
case BattleEndStatus.BattleEndWin:
@@ -200,7 +288,7 @@ public class ChallengeInstance
// Get monster count in stage
long monsters = Player.SceneInstance!.Entities.Values.OfType<EntityMonster>().Count();
if (monsters == 0) await AdvanceStage();
if (monsters == 0) await AdvanceStage(req);
// Calculate rounds left
if (IsStory()) RoundsLeft = (int)Math.Min(Math.Max(RoundsLeft - req.Stt.RoundCnt, 1), RoundsLeft);
@@ -219,7 +307,7 @@ public class ChallengeInstance
// Determine challenge result
if ((IsStory() || IsBoss()) && req.Stt.EndReason == BattleEndReason.TurnLimit)
{
await AdvanceStage();
await AdvanceStage(req);
}
else
{
@@ -234,7 +322,7 @@ public class ChallengeInstance
}
}
private async ValueTask AdvanceStage()
private async ValueTask AdvanceStage(PVEBattleResultCsReq req)
{
if (CurrentStage >= Excel.StageNum)
{
@@ -247,7 +335,7 @@ public class ChallengeInstance
// Send challenge result data
if (IsBoss())
await Player.SendPacket(new PacketChallengeBossPhaseSettleNotify(this));
await Player.SendPacket(new PacketChallengeBossPhaseSettleNotify(this, req.Stt.BattleTargetInfo[1]));
else
await Player.SendPacket(new PacketChallengeSettleNotify(this));
@@ -256,23 +344,62 @@ public class ChallengeInstance
}
else
{
// Increment and reset stage
CurrentStage++;
if (IsBoss())
{
await Player.SendPacket(new PacketChallengeBossPhaseSettleNotify(this, req.Stt.BattleTargetInfo[1]));
}
else
{
// Increment and reset stage
CurrentStage++;
// Load scene group for stage 2
await Player.SceneInstance!.EntityLoader!.LoadGroup(Excel.MazeGroupID2);
// Load scene group for stage 2
await Player.SceneInstance!.EntityLoader!.LoadGroup(Excel.MazeGroupID2);
// Change player line up
SetCurrentExtraLineup(ExtraLineupType.LineupChallenge2);
await Player.LineupManager!.SetCurLineup(CurrentExtraLineup + 10);
await Player.SendPacket(new PacketChallengeLineupNotify((ExtraLineupType)CurrentExtraLineup));
SavedMp = Player.LineupManager.GetCurLineup()!.Mp;
// Change player line up
SetCurrentExtraLineup(ExtraLineupType.LineupChallenge2);
await Player.LineupManager!.SetCurLineup(CurrentExtraLineup + 10);
await Player.SendPacket(new PacketChallengeLineupNotify((ExtraLineupType)CurrentExtraLineup));
SavedMp = Player.LineupManager.GetCurLineup()!.Mp;
// Move player
await Player.MoveTo(StartPos, StartRot);
// Move player
if (Excel.MapEntranceID2 != 0)
{
await Player.EnterScene(Excel.MapEntranceID2, 0, true);
StartPos = Player.Data.Pos!;
StartRot = Player.Data.Rot!;
await Player.SceneInstance!.EntityLoader!.LoadGroup(Excel.MazeGroupID2);
}
else
await Player.MoveTo(StartPos, StartRot);
}
}
}
public async ValueTask NextPhase()
{
// Increment and reset stage
CurrentStage++;
// Load scene group for stage 2
await Player.SceneInstance!.EntityLoader!.LoadGroup(Excel.MazeGroupID2);
// Change player line up
SetCurrentExtraLineup(ExtraLineupType.LineupChallenge2);
await Player.LineupManager!.SetCurLineup(CurrentExtraLineup + 10);
await Player.SendPacket(new PacketChallengeLineupNotify((ExtraLineupType)CurrentExtraLineup));
SavedMp = Player.LineupManager.GetCurLineup()!.Mp;
// Move player
if (Excel.MapEntranceID2 != 0)
{
await Player.EnterScene(Excel.MapEntranceID2, 0, false);
StartPos = Player.Data.Pos!;
StartRot = Player.Data.Rot!;
await Player.SceneInstance!.EntityLoader!.LoadGroup(Excel.MazeGroupID2);
}
else
await Player.MoveTo(StartPos, StartRot);
}
public void OnUpdate()
{
// End challenge if its done

View File

@@ -326,18 +326,26 @@ public class InventoryManager(PlayerInstance player) : BasePlayerManager(player)
return itemData;
}
public ItemData? GetItem(int itemId)
/// <summary>
/// Get item by itemId and uniqueId, if uniqueId provided, itemId will be ignored
/// </summary>
/// <param name="itemId"></param>
/// <param name="uniqueId"></param>
/// <returns></returns>
public ItemData? GetItem(int itemId, int uniqueId = 0, ItemMainTypeEnum mainType = ItemMainTypeEnum.Unknown)
{
GameData.ItemConfigData.TryGetValue(itemId, out var itemConfig);
if (itemConfig == null) return null;
switch (itemConfig.ItemMainType)
if (itemConfig == null && mainType == ItemMainTypeEnum.Unknown) return null;
if (itemConfig != null)
mainType = itemConfig.ItemMainType;
switch (mainType)
{
case ItemMainTypeEnum.Material:
return Data.MaterialItems.Find(x => x.ItemId == itemId);
case ItemMainTypeEnum.Equipment:
return Data.EquipmentItems.Find(x => x.ItemId == itemId);
return uniqueId > 0 ? Data.EquipmentItems.Find(x => x.UniqueId == uniqueId) : Data.EquipmentItems.Find(x => x.ItemId == itemId);
case ItemMainTypeEnum.Relic:
return Data.RelicItems.Find(x => x.ItemId == itemId);
return uniqueId > 0 ? Data.RelicItems.Find(x => x.UniqueId == uniqueId) : Data.RelicItems.Find(x => x.ItemId == itemId);
case ItemMainTypeEnum.Virtual:
switch (itemConfig.ID)
{

View File

@@ -0,0 +1,21 @@
using EggLink.DanhengServer.GameServer.Server.Packet.Send.Challenge;
using EggLink.DanhengServer.Kcp;
using EggLink.DanhengServer.Proto;
namespace EggLink.DanhengServer.GameServer.Server.Packet.Recv.Challenge;
[Opcode(CmdIds.EnterChallengeNextPhaseCsReq)]
public class HandlerEnterChallengeNextPhaseCsReq : Handler
{
public override async Task OnHandle(Connection connection, byte[] header, byte[] data)
{
if (connection.Player!.ChallengeManager?.ChallengeInstance == null)
{
await connection.SendPacket(new PacketEnterChallengeNextPhaseScRsp(Retcode.RetChallengeNotDoing));
return;
}
await connection.Player.ChallengeManager.ChallengeInstance.NextPhase();
await connection.SendPacket(new PacketEnterChallengeNextPhaseScRsp(connection.Player));
}
}

View File

@@ -1,12 +1,13 @@
using EggLink.DanhengServer.GameServer.Game.Challenge;
using EggLink.DanhengServer.Kcp;
using EggLink.DanhengServer.Proto;
using Google.Protobuf.Collections;
namespace EggLink.DanhengServer.GameServer.Server.Packet.Send.Challenge;
public class PacketChallengeBossPhaseSettleNotify : BasePacket
{
public PacketChallengeBossPhaseSettleNotify(ChallengeInstance challenge) : base(CmdIds
public PacketChallengeBossPhaseSettleNotify(ChallengeInstance challenge, BattleTargetList? targetLists = null) : base(CmdIds
.ChallengeBossPhaseSettleNotify)
{
var proto = new ChallengeBossPhaseSettleNotify
@@ -21,6 +22,8 @@ public class PacketChallengeBossPhaseSettleNotify : BasePacket
IsReward = true
};
proto.BattleTargetList.AddRange(targetLists?.BattleTargetList_ ?? []);
SetData(proto);
}
}

View File

@@ -0,0 +1,29 @@
using EggLink.DanhengServer.GameServer.Game.Challenge;
using EggLink.DanhengServer.GameServer.Game.Player;
using EggLink.DanhengServer.Kcp;
using EggLink.DanhengServer.Proto;
namespace EggLink.DanhengServer.GameServer.Server.Packet.Send.Challenge;
public class PacketEnterChallengeNextPhaseScRsp : BasePacket
{
public PacketEnterChallengeNextPhaseScRsp(PlayerInstance instance) : base(CmdIds.EnterChallengeNextPhaseScRsp)
{
var proto = new EnterChallengeNextPhaseScRsp
{
Scene = instance.SceneInstance!.ToProto()
};
SetData(proto);
}
public PacketEnterChallengeNextPhaseScRsp(Retcode code) : base(CmdIds.EnterChallengeNextPhaseScRsp)
{
var proto = new EnterChallengeNextPhaseScRsp
{
Retcode = (uint)code
};
SetData(proto);
}
}

View File

@@ -23,6 +23,7 @@ public class PacketStartChallengeScRsp : BasePacket
if (player.ChallengeManager!.ChallengeInstance != null)
{
proto.CurChallenge = player.ChallengeManager.ChallengeInstance.ToProto();
proto.StageInfo = player.ChallengeManager.ChallengeInstance.ToStageInfo();
proto.LineupList.Add(player.LineupManager!.GetExtraLineup(ExtraLineupType.LineupChallenge)!.ToProto());
proto.LineupList.Add(player.LineupManager!.GetExtraLineup(ExtraLineupType.LineupChallenge2)!.ToProto());
if (sendScene) proto.Scene = player.SceneInstance!.ToProto();