/// <summary> /// Load and Parse the Battle Video /// </summary> /// <param name="raw">Byte array containing the entire (decrypted) battle video's data.</param> private void OpenBV(byte[] raw) { Reset(); lastdata = (byte[])raw.Clone(); var bvid = new BV6(raw); var trainers = bvid.PlayerNames; var pkms = bvid.BattlePKMs; var teams = bvid.PlayerTeams; LoadBattleInfo(bvid, trainers); LoadTeamData(pkms, trainers); LoadPreviewPics(pkms, raw); // Move Instructions (0xC00 Max) int instructionLength = BitConverter.ToInt32(raw, 0x210); byte[] instructions = raw.Skip(0x214).Take(instructionLength).ToArray(); byte order = raw[0]; if (order != 0x20) // Switched { BVidUtil.ReorderTeams(order, bvid.Style, teams, trainers); } L_Uploader.Location = (order == 0x20) ? new Point(98, 0) : new Point(9, 61); var parser = new BVidParser(bvid, teams, trainers); RTB_Parse.Lines = parser.Parse(instructions); lastParse = parser; }
/// <summary> /// Carrying out battle instructions. /// </summary> /// <param name="Player">Which Player is carrying out the action.</param> /// <param name="data">Instruction data to carry out.</param> private IEnumerable <string> PerformAction(int Player, byte[] data) { var parse = $"[{trainers[Player]}]: "; //for (int i = 0; i < data.Length; i++) // parse += data[i].ToString("X2") + " "; int user = 0; for (int i = 0; i < data.Length / 4; i++) { var val = data[i * 4]; var OpCode = val & 0xF; var Targeting = val >> 4; string target = ((MoveTarget)Targeting).ToString(); var action = (TurnActionCode)OpCode; switch (action) { case TurnActionCode.None: isOut[Player] = true; parse += "Nothing"; break; case TurnActionCode.Fight: { int move = BitConverter.ToUInt16(data, 1 + (4 * i)); int targetval = BVidUtil.movedata[move][0x14]; if (trainers[Player] == "NPC" && targetval == 0) { target = "Opposite Enemy"; } parse += string.Format(action + ": {3} uses {0} @ {1}{2}", GameInfo.Strings.Move[move], target, data[3 + (4 * i)] > 0 ? " - " + data[3 + (4 * i)] : "", teams[Player][user++].Nickname); break; } case TurnActionCode.Switch: var val2 = BitConverter.ToUInt16(data, i * 4); var SlotIn = val2 >> 7 & 0x7; var SlotOut = val2 >> 10; parse += $"Out: {teams[Player][SlotOut].Nickname}, In: {teams[Player][SlotIn].Nickname}"; BVidUtil.PerformSwap(ref teams[Player][SlotOut], ref teams[Player][SlotIn]); break; case TurnActionCode.Rotate: { string rot = ((RotateDirection)Targeting).ToString(); // ushort un12 = BitConverter.ToUInt16(data, 1 + (4 * i)); // byte un3 = data[3 + (4 * i)]; string curIn = teams[Player][user].Nickname; BVidUtil.PerformRotation(teams[Player], Targeting); parse += string.Format(action + ": {1} rotates {0} to {2}", rot, curIn, teams[Player][user++].Nickname); break; } case TurnActionCode.MegaEvolve: { var arg = BitConverter.ToUInt16(data, 1 + (4 * i)).ToString("X4") + data[3 + (4 * i)].ToString("X2"); parse += string.Format(action + ": {1}{2}", OpCode, target, arg == "000000" ? "" : " - " + arg); break; } default: { var arg = BitConverter.ToUInt16(data, 1 + (4 * i)).ToString("X4") + data[3 + (4 * i)].ToString("X2"); parse += string.Format(action + ": {1}{2}", OpCode, target, arg == "000000" ? "" : " - " + arg); user++; break; } } if ((i + 1) * 4 != data.Length) { parse += " & "; } } yield return(parse); }
/// <summary> /// Switch Instruction /// </summary> /// <param name="Player">Which Player is carrying out the action.</param> /// <param name="data">Instruction data to carry out.</param> private IEnumerable <string> PerformSwitch(int Player, byte[] data) { var parse = $"[{trainers[Player]}]: "; //for (int i = 0; i < data.Length; i++) // parse += data[i].ToString("X2") + " "; for (int i = 0; i < data.Length / 4; i++) { byte[] instruct = data.Skip(i * 4).Take(4).ToArray(); if (instruct.All(z => z == 0)) { parse += "None"; continue; } var val = BitConverter.ToUInt16(data, i * 4); var Op = val & 0x7F; var OpCode = Op & 0xF; var SlotIn = val >> 7 & 0x7; var SlotOut = val >> 4 & 0x7; bool nothing = val >> 10 == 1; var Targeting = val >> 4; switch (OpCode) { case 3: if (isOut[Player]) { parse += "None**"; // When defeated, they echo switches out. } else if (nothing) { parse += $"Out: {teams[Player][SlotOut].Nickname}, In: Nothing"; } else { parse += $"Out: {teams[Player][SlotOut].Nickname}, In: {teams[Player][SlotIn].Nickname}"; BVidUtil.PerformSwap(ref teams[Player][SlotOut], ref teams[Player][SlotIn]); } break; case 6: string curActive = teams[Player][0].Nickname; BVidUtil.PerformRotation(teams[Player], Targeting); string nowActive = teams[Player][0].Nickname; parse += $"Rotates: Out {curActive}, In: {nowActive}"; break; default: parse = data.Aggregate(parse, (current, t) => current + (t.ToString("X2") + " ")); break; } // Output raw bytes if ((i + 1) * 4 != data.Length) { parse += " & "; // Another action is present. } } yield return(parse); }