fix rogue entrance

This commit is contained in:
Somebody
2024-04-06 17:31:57 +08:00
parent ac23eb3ce8
commit b42cdfde22
17 changed files with 483 additions and 13 deletions

View File

@@ -0,0 +1,46 @@
using Newtonsoft.Json;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
namespace EggLink.DanhengServer.Data.Excel
{
[ResourceEntity("RogueAreaConfig.json")]
public class RogueAreaConfigExcel : ExcelResource
{
public int RogueAreaID { get; set; }
public int AreaProgress { get; set; }
public int Difficulty { get; set; }
public int FirstReward { get; set; }
public Dictionary<int, int> ScoreMap { get; set; } = [];
[JsonIgnore]
public int MapId { get; set; }
[JsonIgnore]
public Dictionary<int, RogueMapExcel> RogueMaps { get; set; } = [];
public override int GetId()
{
return RogueAreaID;
}
public override void Loaded()
{
GameData.RogueAreaConfigData.Add(RogueAreaID, this);
MapId = AreaProgress * 100 + Difficulty;
}
public override void AfterAllDone()
{
GameData.RogueMapData.TryGetValue(MapId, out var map);
if (map != null)
{
RogueMaps = map;
}
}
}
}

View File

@@ -0,0 +1,38 @@
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
namespace EggLink.DanhengServer.Data.Excel
{
[ResourceEntity("RogueMap.json")]
public class RogueMapExcel : ExcelResource
{
public int RogueMapID { get; set; }
public int SiteID { get; set; }
public bool IsStart { get; set; }
public int PosX { get; set; }
public int PosY { get; set; }
public List<int> NextSiteIDList { get; set; } = [];
public List<int> LevelList { get; set; } = [];
public override int GetId()
{
return RogueMapID * 1000 + SiteID;
}
public override void Loaded()
{
if (GameData.RogueMapData.TryGetValue(RogueMapID, out var map))
{
map.Add(SiteID, this);
}
else
{
GameData.RogueMapData.Add(RogueMapID, new() { { SiteID, this } });
}
}
}
}

View File

@@ -0,0 +1,27 @@
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
namespace EggLink.DanhengServer.Data.Excel
{
[ResourceEntity("RogueRoom.json")]
public class RogueRoomExcel : ExcelResource
{
public int RogueRoomID { get; set; }
public int RogueRoomType { get; set; }
public int MapEntrance { get; set; }
public int GroupID { get; set; }
public override int GetId()
{
return RogueRoomID;
}
public override void Loaded()
{
GameData.RogueRoomData.Add(RogueRoomID, this);
}
}
}

View File

@@ -31,26 +31,33 @@ namespace EggLink.DanhengServer.Data.Excel
WaveId = (uint)waveId++,
StageId = (uint)StageID,
};
proto.MonsterList.Add(new SceneMonster()
{
MonsterId = (uint)monsters.Monster0,
});
proto.MonsterList.Add(new SceneMonster()
{
MonsterId = (uint)monsters.Monster1,
});
proto.MonsterList.Add(new SceneMonster()
{
MonsterId = (uint)monsters.Monster2,
});
proto.MonsterList.Add(new SceneMonster()
{
MonsterId = (uint)monsters.Monster3,
});
proto.MonsterList.Add(new SceneMonster()
{
MonsterId = (uint)monsters.Monster4,
});
proto.MonsterParam = new();
result.Add(proto);
}
return result;

View File

@@ -90,15 +90,19 @@ namespace EggLink.DanhengServer.Data
#region Rogue
public static Dictionary<int, RogueAeonExcel> RogueAeonData { get; private set; } = [];
public static Dictionary<int, RogueAreaConfigExcel> RogueAreaConfigData { get; private set; } = [];
public static Dictionary<int, RogueBonusExcel> RogueBonusData { get; private set; } = [];
public static Dictionary<int, RogueBuffExcel> RogueBuffData { get; private set; } = [];
public static Dictionary<int, RogueBuffGroupExcel> RogueBuffGroupData { get; private set; } = [];
public static Dictionary<int, RogueHandBookEventExcel> RogueHandBookEventData { get; private set; } = [];
public static Dictionary<int, RogueHandbookMiracleExcel> RogueHandbookMiracleData { get; private set; } = [];
public static Dictionary<int, RogueManagerExcel> RogueManagerData { get; private set; } = [];
public static Dictionary<int, Dictionary<int, RogueMapExcel>> RogueMapData { get; private set; } = [];
public static Dictionary<int, List<int>> RogueMapGenData { get; set; } = [];
public static Dictionary<int, RogueMazeBuffExcel> RogueMazeBuffData { get; private set; } = [];
public static Dictionary<int, RogueMiracleDisplayExcel> RogueMiracleDisplayData { get; private set; } = [];
public static Dictionary<int, RogueMiracleEffectExcel> RogueMiracleEffectData { get; private set; } = [];
public static Dictionary<int, RogueRoomExcel> RogueRoomData { get; private set; } = [];
#endregion

View File

@@ -22,6 +22,7 @@ namespace EggLink.DanhengServer.Data
LoadMissionInfo();
LoadMazeSkill();
LoadBanner();
LoadRogueMapGen();
}
public static void LoadExcel()
@@ -306,5 +307,30 @@ namespace EggLink.DanhengServer.Data
}
Logger.Info("Loaded " + count + " maze skill infos.");
}
public static void LoadRogueMapGen()
{
var path = ConfigManager.Config.Path.ConfigPath + "/RogueMapGen.json";
var file = new FileInfo(path);
if (!file.Exists)
{
Logger.Warn($"Rogue map gen infos are missing, please check your resources folder: {ConfigManager.Config.Path.ResourcePath}/Config/RogueMapGen.json. Rogue map gen may not work!");
return;
}
try
{
using var reader = file.OpenRead();
using StreamReader reader2 = new(reader);
var text = reader2.ReadToEnd();
var rogueMapGen = JsonConvert.DeserializeObject<Dictionary<int, List<int>>>(text);
if (rogueMapGen != null)
{
GameData.RogueMapGenData = rogueMapGen;
}
} catch (Exception ex)
{
Logger.Error("Error in reading" + file.Name, ex);
}
}
}
}

View File

@@ -19,6 +19,7 @@ namespace EggLink.DanhengServer.Game.Battle
public int MappingInfoId { get; set; }
public int RoundLimit { get; set; }
public int StageId { get; set; } = stages.Count > 0 ? stages[0].StageID : 0; // Set to 0 when hit monster
public int CustomLevel { get; set; }
public BattleEndStatus BattleEndStatus { get; set; }
public List<ItemData> MonsterDropItems { get; set; } = [];
@@ -69,7 +70,15 @@ namespace EggLink.DanhengServer.Game.Battle
foreach (var wave in Stages)
{
proto.MonsterWaveList.AddRange(wave.ToProto());
var protoWave = wave.ToProto();
if (CustomLevel > 0)
{
foreach (var item in protoWave)
{
item.MonsterParam.Level = (uint)CustomLevel;
}
}
proto.MonsterWaveList.AddRange(protoWave);
}
foreach (var avatar in Lineup.BaseAvatars!)

View File

@@ -155,6 +155,10 @@ namespace EggLink.DanhengServer.Game.Battle
}
battleInstance.AvatarInfo = avatarList;
// call battle start
Player.RogueManager!.RogueInstance?.OnBattleStart(battleInstance);
Player.BattleInstance = battleInstance;
Player.SendPacket(new PacketSceneCastSkillScRsp(req.CastEntityId, battleInstance));
} else
@@ -183,6 +187,9 @@ namespace EggLink.DanhengServer.Game.Battle
WorldLevel = Player.Data.WorldLevel,
};
// call battle start
Player.RogueManager!.RogueInstance?.OnBattleStart(battleInstance);
Player.BattleInstance = battleInstance;
Player.SendPacket(new PacketSceneEnterStageScRsp(battleInstance));
@@ -316,6 +323,8 @@ namespace EggLink.DanhengServer.Game.Battle
}
// call battle end
Player.MissionManager!.OnBattleFinish(req);
Player.RogueManager!.RogueInstance?.OnBattleEnd(battle, req);
battle.MonsterDropItems = dropItems;
Player.BattleInstance = null;

View File

@@ -134,6 +134,30 @@ namespace EggLink.DanhengServer.Game.Lineup
return true;
}
public void SetExtraLineup(Proto.ExtraLineupType type, List<int> baseAvatarIds)
{
var index = (int)type + 9;
// destroy old lineup
LineupData.Lineups.Remove(index);
// create new lineup
var lineup = new LineupInfo()
{
Name = "",
LineupType = (int)type,
BaseAvatars = [],
LineupData = LineupData,
AvatarData = Player.AvatarManager!.AvatarData,
};
foreach (var avatarId in baseAvatarIds)
{
lineup.BaseAvatars!.Add(new() { BaseAvatarId = avatarId });
}
LineupData.Lineups.Add(index, lineup);
DatabaseHelper.Instance?.UpdateInstance(LineupData);
}
public void AddAvatar(int lineupIndex, int avatarId, bool sendPacket = true)
{
if (lineupIndex < 0)
@@ -273,12 +297,15 @@ namespace EggLink.DanhengServer.Game.Lineup
Player.SendPacket(new PacketSceneCastSkillMpUpdateScNotify(entityId, LineupData.Mp));
}
public void GainMp(int count)
public void GainMp(int count, bool sendPacket = true)
{
LineupData.Mp += count;
LineupData.Mp = Math.Min(Math.Max(0, LineupData.Mp), 5);
DatabaseHelper.Instance?.UpdateInstance(LineupData);
Player.SendPacket(new PacketSyncLineupNotify(GetCurLineup()!));
if (sendPacket)
{
Player.SendPacket(new PacketSyncLineupNotify(GetCurLineup()!));
}
}
#endregion

View File

@@ -106,6 +106,11 @@ namespace EggLink.DanhengServer.Game.Player
{
EnterScene(2000101, 0, false);
}
if (LineupManager!.GetCurLineup()!.IsExtraLineup())
{
LineupManager!.SetCurLineup(0);
}
}
public T? InitializeDatabase<T>() where T : class, new()
@@ -386,6 +391,12 @@ namespace EggLink.DanhengServer.Game.Player
GameData.MazePlaneData.TryGetValue(planeId, out var plane);
if (plane == null) return;
if (plane.PlaneType == PlaneTypeEnum.Rogue && RogueManager!.RogueInstance == null)
{
EnterScene(801120102, 0, sendPacket);
return;
}
// TODO: Sanify check
Data.Pos = pos;
Data.Rot = rot;

View File

@@ -1,4 +1,5 @@
using EggLink.DanhengServer.Proto;
using EggLink.DanhengServer.Game.Battle;
using EggLink.DanhengServer.Proto;
using System;
using System.Collections.Generic;
using System.Linq;
@@ -12,6 +13,14 @@ namespace EggLink.DanhengServer.Game.Rogue.Buff
public int BuffId { get; set; } = buffId;
public int BuffLevel { get; set; } = buffLevel;
public void OnStartBattle(BattleInstance battle)
{
battle.Buffs.Add(new(BuffId, BuffLevel, -1)
{
WaveFlag = -1
});
}
public RogueBuff ToProto() => new()
{
BuffId = (uint)BuffId,

View File

@@ -0,0 +1,36 @@
using EggLink.DanhengServer.Data;
using EggLink.DanhengServer.Data.Excel;
using EggLink.DanhengServer.Proto;
using EggLink.DanhengServer.Util;
namespace EggLink.DanhengServer.Game.Rogue.Map
{
public class RogueRoomInstance
{
public int RoomId { get; set; }
public int SiteId { get; set; }
public RogueRoomStatus Status { get; set; } = RogueRoomStatus.Lock;
public List<int> NextSiteIds { get; set; } = [];
public RogueRoomExcel Excel { get; set; }
public RogueRoomInstance(RogueMapExcel excel)
{
SiteId = excel.SiteID;
NextSiteIds = excel.NextSiteIDList;
GameData.RogueMapGenData.TryGetValue(excel.SiteID, out var genData);
if (genData != null)
{
RoomId = genData.RandomElement();
}
Excel = GameData.RogueRoomData[RoomId];
}
public RogueRoom ToProto() => new()
{
RoomId = (uint)RoomId,
SiteId = (uint)SiteId,
CurStatus = Status
};
}
}

View File

@@ -1,4 +1,5 @@
using EggLink.DanhengServer.Proto;
using EggLink.DanhengServer.Game.Battle;
using EggLink.DanhengServer.Proto;
using System;
using System.Collections.Generic;
using System.Linq;
@@ -10,6 +11,16 @@ namespace EggLink.DanhengServer.Game.Rogue.Miracle
public class RogueMiracleInstance
{
public void OnStartBattle(BattleInstance battle)
{
}
public void OnEndBattle(BattleInstance battle)
{
}
public RogueMiracle ToProto() // TODO: Implement
{
return new()

View File

@@ -1,5 +1,10 @@
using EggLink.DanhengServer.Data.Excel;
using EggLink.DanhengServer.Data;
using EggLink.DanhengServer.Data.Config;
using EggLink.DanhengServer.Data.Excel;
using EggLink.DanhengServer.Game.Battle;
using EggLink.DanhengServer.Game.Player;
using EggLink.DanhengServer.Game.Rogue.Buff;
using EggLink.DanhengServer.Game.Rogue.Map;
using EggLink.DanhengServer.Game.Rogue.Miracle;
using EggLink.DanhengServer.Proto;
using EggLink.DanhengServer.Util;
@@ -15,15 +20,131 @@ namespace EggLink.DanhengServer.Game.Rogue
{
#region Properties
public PlayerInstance Player { get; set; }
public int RogueVersionId { get; set; } = 101;
public RogueStatus Status { get; set; } = RogueStatus.Doing;
public Dictionary<int, RogueMiracleInstance> RogueMiracles { get; set; } = [];
public int AeonId { get; set; } = 0;
public Database.Lineup.LineupInfo CurLineup { get; set; } = new();
public int CurReviveCost { get; set; } = 80;
public int CurRerollCost { get; set; } = 30;
public int CurReachedRoom { get; set; } = 0;
public int CurMoney { get; set; } = 100;
public int AeonId { get; set; } = 0;
public List<RogueBuffInstance> RogueBuffs { get; set; } = [];
public Dictionary<int, RogueMiracleInstance> RogueMiracles { get; set; } = [];
public RogueAeonExcel AeonExcel { get; set; }
public RogueAreaConfigExcel AreaExcel { get; set; }
public Dictionary<int, RogueRoomInstance> RogueRooms { get; set; } = [];
public RogueRoomInstance? CurRoom { get; set; }
public int StartSiteId { get; set; } = 0;
public SortedDictionary<int, RogueActionInstance> RogueActions { get; set; } = []; // queue_position -> action
public int CurActionQueuePosition { get; set; } = 0;
public int CurEventUniqueID { get; set; } = 100;
#endregion
#region Initialization
public RogueInstance(RogueAreaConfigExcel areaExcel, RogueAeonExcel aeonExcel, PlayerInstance player)
{
AreaExcel = areaExcel;
AeonExcel = aeonExcel;
Player = player;
CurLineup = player.LineupManager!.GetCurLineup()!;
foreach (var item in areaExcel.RogueMaps.Values)
{
RogueRooms.Add(item.SiteID, new(item));
if (item.IsStart)
{
StartSiteId = item.SiteID;
}
}
}
#endregion
#region Methods
public void RollBuff(int amount)
{
RollBuff(amount, 100005);
}
public void RollBuff(int amount, int buffGroupId, int buffHintType = 1)
{
}
public RogueRoomInstance? EnterRoom(int siteId)
{
var prevRoom = CurRoom;
if (prevRoom != null)
{
if (!prevRoom.NextSiteIds.Contains(siteId))
{
return null;
}
prevRoom.Status = RogueRoomStatus.Finish;
// send
}
// next room
CurReachedRoom++;
CurRoom = RogueRooms[siteId];
CurRoom.Status = RogueRoomStatus.Play;
Player.EnterScene(CurRoom.Excel.MapEntrance, 0, false);
// move
AnchorInfo? anchor = Player.SceneInstance!.FloorInfo?.GetAnchorInfo(CurRoom.Excel.GroupID, 1);
if (anchor != null)
{
Player.Data.Pos = anchor.ToPositionProto();
Player.Data.Rot = anchor.ToRotationProto();
}
// send
return CurRoom;
}
#endregion
#region Handlers
public void OnBattleStart(BattleInstance battle)
{
foreach (var miracle in RogueMiracles.Values)
{
miracle.OnStartBattle(battle);
}
foreach (var buff in RogueBuffs)
{
buff.OnStartBattle(battle);
}
GameData.RogueMapData.TryGetValue(AreaExcel.MapId, out var mapData);
if (mapData != null)
{
mapData.TryGetValue(CurRoom!.SiteId, out var mapInfo);
if (mapInfo != null && mapInfo.LevelList.Count > 0)
{
battle.CustomLevel = mapInfo.LevelList[0];
}
}
}
public void OnBattleEnd(BattleInstance battle, PVEBattleResultCsReq req)
{
foreach (var miracle in RogueMiracles.Values)
{
miracle.OnEndBattle(battle);
}
RollBuff(battle.Stages.Count);
}
#endregion
@@ -112,10 +233,20 @@ namespace EggLink.DanhengServer.Game.Rogue
public RogueMapInfo ToMapInfo()
{
return new()
var proto = new RogueMapInfo()
{
// need to implement
CurSiteId = (uint)CurRoom!.SiteId,
CurRoomId = (uint)CurRoom!.RoomId,
AreaId = (uint)AreaExcel.RogueAreaID,
MapId = (uint)AreaExcel.MapId,
};
foreach (var room in RogueRooms)
{
proto.RoomList.Add(room.Value.ToProto());
}
return proto;
}
#endregion

View File

@@ -2,6 +2,7 @@
using EggLink.DanhengServer.Data.Excel;
using EggLink.DanhengServer.Game.Player;
using EggLink.DanhengServer.Proto;
using EggLink.DanhengServer.Server.Packet.Send.Rogue;
using EggLink.DanhengServer.Util;
using System;
using System.Collections.Generic;
@@ -15,7 +16,7 @@ namespace EggLink.DanhengServer.Game.Rogue
{
#region Properties
public RogueInstance? RogueInstances { get; set; }
public RogueInstance? RogueInstance { get; set; }
#endregion
@@ -49,6 +50,36 @@ namespace EggLink.DanhengServer.Game.Rogue
#endregion
#region Actions
public void StartRogue(int areaId, int aeonId, List<int> disableAeonId, List<int> baseAvatarIds)
{
GameData.RogueAreaConfigData.TryGetValue(areaId, out var area);
GameData.RogueAeonData.TryGetValue(aeonId, out var aeon);
if (area == null || aeon == null)
{
return;
}
Player.LineupManager!.SetExtraLineup(ExtraLineupType.LineupRogue, baseAvatarIds);
Player.LineupManager!.GainMp(5, false);
foreach (var id in baseAvatarIds)
{
Player.AvatarManager!.GetAvatar(id)?.SetCurHp(10000, true);
Player.AvatarManager!.GetAvatar(id)?.SetCurSp(5000, true);
}
RogueInstance = new RogueInstance(area, aeon, Player);
RogueInstance.EnterRoom(RogueInstance.StartSiteId);
Player.SendPacket(new PacketStartRogueScRsp(Player));
}
#endregion
#region Serialization
public RogueInfo ToProto()
@@ -58,9 +89,9 @@ namespace EggLink.DanhengServer.Game.Rogue
RogueGetInfo = ToGetProto()
};
if (RogueInstances != null)
if (RogueInstance != null)
{
proto.RogueCurrentInfo = RogueInstances.ToProto();
proto.RogueCurrentInfo = RogueInstance.ToProto();
}
return proto;

View File

@@ -0,0 +1,23 @@
using EggLink.DanhengServer.Proto;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
namespace EggLink.DanhengServer.Server.Packet.Recv.Rogue
{
[Opcode(CmdIds.StartRogueCsReq)]
public class HandlerStartRogueCsReq : Handler
{
public override void OnHandle(Connection connection, byte[] header, byte[] data)
{
var req = StartRogueCsReq.Parser.ParseFrom(data);
var player = connection.Player!;
var disableAeonIdList = req.DisableAeonIdList.Select(x => (int)x).ToList();
var avatarIds = req.BaseAvatarIdList.Select(x => (int)x).ToList();
player.RogueManager!.StartRogue((int) req.AreaId, (int)req.AeonId, disableAeonIdList, avatarIds);
}
}
}

View File

@@ -0,0 +1,25 @@
using EggLink.DanhengServer.Game.Player;
using EggLink.DanhengServer.Proto;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
namespace EggLink.DanhengServer.Server.Packet.Send.Rogue
{
public class PacketStartRogueScRsp : BasePacket
{
public PacketStartRogueScRsp(PlayerInstance player) : base(CmdIds.StartRogueScRsp)
{
var proto = new StartRogueScRsp
{
RogueInfo = player.RogueManager!.ToProto(),
Lineup = player.LineupManager!.GetCurLineup()!.ToProto(),
Scene = player.SceneInstance!.ToProto(),
};
SetData(proto);
}
}
}