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 ChallegeStageManager = @import("../manager/battle_mgr.zig").ChallegeStageManager; 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 var challenge_stageID: u32 = 0; pub var challenge_mode: u32 = 0; pub var on_challenge: bool = false; pub const ChallengeBlessing = ArrayList(u32); pub var challenge_blessing: []const u32 = &.{}; 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, }); on_challenge = false; challenge_mode = 0; try session.send(CmdID.CmdLeaveChallengeScRsp, protocol.LeaveChallengeScRsp{ .retcode = 0, }); } pub fn onStartChallenge(session: *Session, packet: *const Packet, allocator: Allocator) !void { var challenge_blessing_list = ChallengeBlessing{ .allocator = std.heap.page_allocator, .items = &.{}, .capacity = 0, }; 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 lineup = protocol.LineupInfo.init(allocator); lineup.mp = 5; lineup.max_mp = 5; lineup.extra_lineup_type = if (NodeCheck.challenge_node == 0) protocol.ExtraLineupType.LINEUP_CHALLENGE else protocol.ExtraLineupType.LINEUP_CHALLENGE_2; if (NodeCheck.challenge_node == 0) { 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 lineup.avatar_list.append(list); } try rsp.lineup_list.append(lineup); } else { for (req.second_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 lineup.avatar_list.append(list); } try rsp.lineup_list.append(lineup); } 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 eventID: 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)) { if (req.challenge_id > 20000 and req.challenge_id < 30000) { var story_buff = protocol.ChallengeStoryBuffList{ .buff_list = ArrayList(u32).init(allocator), }; try story_buff.buff_list.append(challengeConf.maze_buff_id); try story_buff.buff_list.append(req.stage_info.?.IEICDGGELNE.?.story_info.buff_one); try challenge_blessing_list.appendSlice(story_buff.buff_list.items); cur_challenge_info.stage_info = .{ .IEICDGGELNE = .{ .cur_story_buffs = story_buff, }, }; challenge_mode = 1; } else if (req.challenge_id > 30000) { var boss_buff = protocol.ChallengeBossBuffList{ .buff_list = ArrayList(u32).init(allocator), .challenge_boss_const = 1, }; try boss_buff.buff_list.append(challengeConf.maze_buff_id); try boss_buff.buff_list.append(req.stage_info.?.IEICDGGELNE.?.boss_info.buff_one); try challenge_blessing_list.appendSlice(boss_buff.buff_list.items); cur_challenge_info.stage_info = .{ .IEICDGGELNE = .{ .cur_boss_buffs = boss_buff, }, }; challenge_mode = 2; } floorID = entrance.floor_id; worldID = maze.world_id; monsterID = challengeConf.npc_monster_id_list1.items[challengeConf.npc_monster_id_list1.items.len - 1]; eventID = challengeConf.event_id_list1.items[challengeConf.event_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)) { if (challengeConf.maze_group_id2) |id| { if (req.challenge_id > 20000 and req.challenge_id < 30000) { var story_buff = protocol.ChallengeStoryBuffList{ .buff_list = ArrayList(u32).init(allocator), }; try story_buff.buff_list.append(challengeConf.maze_buff_id); try story_buff.buff_list.append(req.stage_info.?.IEICDGGELNE.?.story_info.buff_two); try challenge_blessing_list.appendSlice(story_buff.buff_list.items); cur_challenge_info.stage_info = .{ .IEICDGGELNE = .{ .cur_story_buffs = story_buff, }, }; challenge_mode = 1; } else if (req.challenge_id > 30000) { var boss_buff = protocol.ChallengeBossBuffList{ .buff_list = ArrayList(u32).init(allocator), .challenge_boss_const = 1, }; try boss_buff.buff_list.append(challengeConf.maze_buff_id); try boss_buff.buff_list.append(req.stage_info.?.IEICDGGELNE.?.boss_info.buff_two); try challenge_blessing_list.appendSlice(boss_buff.buff_list.items); cur_challenge_info.stage_info = .{ .IEICDGGELNE = .{ .cur_boss_buffs = boss_buff, }, }; challenge_mode = 2; } floorID = entrance.floor_id; worldID = maze.world_id; monsterID = challengeConf.npc_monster_id_list2.items[challengeConf.npc_monster_id_list2.items.len - 1]; eventID = challengeConf.event_id_list2.items[challengeConf.event_id_list2.items.len - 1]; groupID = id; maze_groupID = id; planeID = maze.challenge_plane_id; entryID = challengeConf.map_entrance_id2; } else { std.debug.print("THIS CHALLENGE ID: {} DOES NOT SUPPORT 2ND NODE. PLEASE DO COMMAND /node TO SWITCH BACK TO FIRST NODE\n", .{req.challenge_id}); } } } } } } } } var scene_PF_manager = ChallengeSceneManager.init(allocator); const scene_info = try scene_PF_manager.createScene( avatarList, planeID, floorID, entryID, worldID, monsterID, eventID, groupID, maze_groupID, ); rsp.retcode = 0; rsp.scene = scene_info; rsp.cur_challenge = cur_challenge_info; on_challenge = true; challenge_stageID = eventID; challenge_blessing = challenge_blessing_list.items[0..challenge_blessing_list.items.len]; 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 }); }