const std = @import("std"); const protocol = @import("protocol"); const Session = @import("../Session.zig"); const Packet = @import("../Packet.zig"); const Config = @import("config.zig"); const Res_config = @import("res_config.zig"); const Data = @import("../data.zig"); const SceneManager = @import("../manager/scene_mgr.zig").SceneManager; const ChallengeSceneManager = @import("../manager/scene_mgr.zig").ChallengeSceneManager; const LineupManager = @import("../manager/lineup_mgr.zig").LineupManager; const NodeCheck = @import("../commands/value.zig"); const ArrayList = std.ArrayList; const Allocator = std.mem.Allocator; const CmdID = protocol.CmdID; pub fn UidGenerator() type { return struct { current_id: u32, const Self = @This(); pub fn init() Self { return Self{ .current_id = 100000 }; } pub fn nextId(self: *Self) u32 { self.current_id +%= 1; // Using wrapping addition return self.current_id; } }; } fn contains(list: *const std.ArrayListAligned(u32, null), value: u32) bool { for (list.items) |item| { if (item == value) { return true; } } return false; } pub fn onGetChallenge(session: *Session, _: *const Packet, allocator: Allocator) !void { const challenge_config = try Config.loadChallengeConfig(allocator, "resources/ChallengeMazeConfig.json"); var rsp = protocol.GetChallengeScRsp.init(allocator); rsp.retcode = 0; for (challenge_config.challenge_config.items) |ids| { var challenge = protocol.Challenge.init(allocator); challenge.challenge_id = ids.id; challenge.star = 1; if (ids.id > 20000 and ids.id < 30000) { challenge.score_id = 40000; challenge.score_two = 40000; } try rsp.challenge_list.append(challenge); } try session.send(CmdID.CmdGetChallengeScRsp, rsp); } pub fn onGetChallengeGroupStatistics(session: *Session, packet: *const Packet, allocator: Allocator) !void { const req = try packet.getProto(protocol.GetChallengeGroupStatisticsCsReq, allocator); var rsp = protocol.GetChallengeGroupStatisticsScRsp.init(allocator); rsp.retcode = 0; rsp.group_id = req.group_id; try session.send(CmdID.CmdGetChallengeGroupStatisticsScRsp, rsp); } pub fn onLeaveChallenge(session: *Session, _: *const Packet, allocator: Allocator) !void { var lineup_mgr = LineupManager.init(allocator); const lineup = try lineup_mgr.createLineup(); var scene_manager = SceneManager.init(allocator); const scene_info = try scene_manager.createScene(20432, 20432001, 2043201, 1213); try session.send(CmdID.CmdQuitBattleScNotify, protocol.QuitBattleScNotify{}); try session.send(CmdID.CmdEnterSceneByServerScNotify, protocol.EnterSceneByServerScNotify{ .reason = protocol.EnterSceneReason.ENTER_SCENE_REASON_NONE, .lineup = lineup, .scene = scene_info, }); try session.send(CmdID.CmdLeaveChallengeScRsp, protocol.LeaveChallengeScRsp{ .retcode = 0, }); } //TODO: IMPLEMENT CHALLENGE BUFF AND FIX MENU pub fn onStartChallenge(session: *Session, packet: *const Packet, allocator: Allocator) !void { const req = try packet.getProto(protocol.StartChallengeCsReq, allocator); var rsp = protocol.StartChallengeScRsp.init(allocator); const challenge_config = try Config.loadChallengeConfig(allocator, "resources/ChallengeMazeConfig.json"); const entrance_config = try Config.loadMapEntranceConfig(allocator, "resources/MapEntrance.json"); const maze_config = try Config.loadMazePlaneConfig(allocator, "resources/MazePlane.json"); var avatarList = std.ArrayList(u32).init(allocator); var lineup1 = protocol.LineupInfo.init(allocator); lineup1.mp = 5; lineup1.max_mp = 5; lineup1.extra_lineup_type = protocol.ExtraLineupType.LINEUP_CHALLENGE; for (req.first_lineup.items, 0..) |avt, idx| { var list = protocol.LineupAvatar.init(allocator); try avatarList.append(avt); list.id = avt; list.slot = @intCast(idx); list.satiety = 0; list.avatar_type = protocol.AvatarType.AVATAR_FORMAL_TYPE; list.hp = 10000; list.sp_bar = .{ .sp_cur = 10000, .sp_max = 10000 }; try lineup1.avatar_list.append(list); } try rsp.lineup_list.append(lineup1); var avatarList2 = std.ArrayList(u32).init(allocator); var lineup2 = protocol.LineupInfo.init(allocator); lineup2.mp = 5; lineup2.max_mp = 5; lineup2.extra_lineup_type = protocol.ExtraLineupType.LINEUP_CHALLENGE_2; for (req.second_lineup.items, 0..) |avt, idx| { var list = protocol.LineupAvatar.init(allocator); try avatarList2.append(avt); list.id = avt; list.slot = @intCast(idx); list.satiety = 0; list.avatar_type = protocol.AvatarType.AVATAR_FORMAL_TYPE; list.hp = 10000; list.sp_bar = .{ .sp_cur = 10000, .sp_max = 10000 }; try lineup2.avatar_list.append(list); } try rsp.lineup_list.append(lineup2); var cur_challenge_info = protocol.CurChallenge.init(allocator); cur_challenge_info.challenge_id = req.challenge_id; cur_challenge_info.score_id = if (req.challenge_id > 20000 and req.challenge_id < 30000) 40000 else 0; cur_challenge_info.score_two = 0; cur_challenge_info.status = protocol.ChallengeStatus.CHALLENGE_DOING; cur_challenge_info.extra_lineup_type = if (NodeCheck.challenge_node == 0) protocol.ExtraLineupType.LINEUP_CHALLENGE else protocol.ExtraLineupType.LINEUP_CHALLENGE_2; var planeID: u32 = 0; var floorID: u32 = 0; var entryID: u32 = 0; var worldID: u32 = 0; var monsterID: u32 = 0; var groupID: u32 = 0; var maze_groupID: u32 = 0; if (NodeCheck.challenge_node == 0) { for (challenge_config.challenge_config.items) |challengeConf| { if (challengeConf.id == req.challenge_id) { std.debug.print("TRACING CONFIG ID {} WITH CHALLENGE ID {}\n", .{ challengeConf.id, req.challenge_id }); for (entrance_config.map_entrance_config.items) |entrance| { if (entrance.id == challengeConf.map_entrance_id) { for (maze_config.maze_plane_config.items) |maze| { if (contains(&maze.floor_id_list, entrance.floor_id)) { floorID = entrance.floor_id; worldID = maze.world_id; monsterID = challengeConf.npc_monster_id_list1.items[challengeConf.npc_monster_id_list1.items.len - 1]; groupID = challengeConf.maze_group_id1; maze_groupID = challengeConf.maze_group_id1; planeID = maze.challenge_plane_id; entryID = challengeConf.map_entrance_id; } } } } } } } else { for (challenge_config.challenge_config.items) |challengeConf| { if (challengeConf.id == req.challenge_id) { std.debug.print("TRACING CONFIG ID {} WITH CHALLENGE ID {}\n", .{ challengeConf.id, req.challenge_id }); for (entrance_config.map_entrance_config.items) |entrance| { if (entrance.id == challengeConf.map_entrance_id2) { for (maze_config.maze_plane_config.items) |maze| { if (contains(&maze.floor_id_list, entrance.floor_id)) { floorID = entrance.floor_id; worldID = maze.world_id; monsterID = challengeConf.npc_monster_id_list2.items[challengeConf.npc_monster_id_list2.items.len - 1]; groupID = challengeConf.maze_group_id2; maze_groupID = challengeConf.maze_group_id2; planeID = maze.challenge_plane_id; entryID = challengeConf.map_entrance_id2; } } } } } } } var scene_PF_manager = ChallengeSceneManager.init(allocator); const scene_info = try scene_PF_manager.createScene( if (NodeCheck.challenge_node == 0) avatarList else avatarList2, planeID, floorID, entryID, worldID, monsterID, groupID, maze_groupID, ); rsp.retcode = 0; rsp.scene = scene_info; rsp.cur_challenge = cur_challenge_info; try session.send(CmdID.CmdStartChallengeScRsp, rsp); std.debug.print("SEND PLANE ID {} FLOOR ID {} ENTRY ID {} GROUP ID {} MAZE GROUP ID {}\n", .{ planeID, floorID, entryID, groupID, maze_groupID }); try session.send(CmdID.CmdEnterSceneByServerScNotify, protocol.EnterSceneByServerScNotify{ .lineup = if (NodeCheck.challenge_node == 0) lineup1 else lineup2, .reason = protocol.EnterSceneReason.ENTER_SCENE_REASON_DIMENSION_MERGE, .scene = scene_info, }); }