Encounter.cs 4.3 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117
  1. using Microsoft.Xna.Framework;
  2. using System;
  3. using System.Collections;
  4. using System.Collections.Generic;
  5. using System.Diagnostics.CodeAnalysis;
  6. using System.IO;
  7. using System.Linq;
  8. namespace OpenVIII.Battle
  9. {
  10. /// <summary>
  11. /// 8 possible enemies. so there's 1 bit per enemy here.
  12. /// </summary>
  13. [Flags]
  14. [SuppressMessage("ReSharper", "UnusedMember.Global")]
  15. public enum EnemyFlags : byte
  16. {
  17. None,
  18. Enemy1 = 0x1,
  19. Enemy2 = 0x2,
  20. Enemy3 = 0x4,
  21. Enemy4 = 0x8,
  22. Enemy5 = 0x10,
  23. Enemy6 = 0x20,
  24. Enemy7 = 0x40,
  25. Enemy8 = 0x80,
  26. }
  27. public class Encounter
  28. {
  29. #region Fields
  30. public byte AlternativeCamera;
  31. public EncounterFlag BattleFlags;
  32. public byte[] BLevels;
  33. //public byte[] bUnk1;
  34. public ushort[] BUnk2;
  35. public byte[] BUnk3;
  36. public byte[] BUnk4;
  37. public BitArray EnabledEnemy;
  38. public EnemyCoordinates EnemyCoordinates;
  39. public BitArray HiddenEnemies;
  40. public int ID;
  41. public byte PrimaryCamera;
  42. public byte Scenario;
  43. public BitArray UnloadedEnemy;
  44. public BitArray UntargetableEnemy;
  45. private byte[] _enemies;
  46. #endregion Fields
  47. #region Properties
  48. public Vector3 AverageVector { get; set; }
  49. public byte[] BEnemies { get => _enemies.Select(x => (byte)(x - 0x10)).ToArray(); set => _enemies = value; }
  50. public IEnumerable<KeyValuePair<int, byte>> EnabledMonsters => BEnemies.Select((x, i) => new KeyValuePair<int, byte>(i, x)).Where(x => EnabledEnemy.Cast<bool>().Reverse().ElementAt(x.Key));
  51. public string Filename => $"a0stg{Scenario:000}.x";
  52. public Vector3 MaxVector { get; set; }
  53. public Vector3 MidVector { get; set; }
  54. public Vector3 MinVector { get; set; }
  55. public IEnumerable<byte> UniqueMonstersList => EnabledMonsters.Select(x => x.Value).Distinct();
  56. #endregion Properties
  57. #region Methods
  58. public static Encounter Read(BinaryReader br, int id)
  59. {
  60. var e = new Encounter
  61. {
  62. Scenario = br.ReadByte(),
  63. BattleFlags = (EncounterFlag)br.ReadByte(),
  64. PrimaryCamera = br.ReadByte(),
  65. AlternativeCamera = br.ReadByte(),
  66. HiddenEnemies = new BitArray(br.ReadBytes(1)),
  67. UnloadedEnemy = new BitArray(br.ReadBytes(1)),
  68. UntargetableEnemy = new BitArray(br.ReadBytes(1)),
  69. EnabledEnemy = new BitArray(br.ReadBytes(1)),
  70. EnemyCoordinates = EnemyCoordinates.Read(br).Reverse().ToList(), //was thinking if all the bytes are reversed maybe the locations are too.
  71. BEnemies = br.ReadBytes(8),
  72. BUnk2 = Enumerable.Range(0, 16).Select(x => br.ReadUInt16()).ToArray(),
  73. BUnk3 = br.ReadBytes(16),
  74. BUnk4 = br.ReadBytes(8),
  75. BLevels = br.ReadBytes(8).Reverse().ToArray(),
  76. ID = id
  77. };
  78. var total = Vector3.Zero;
  79. var enabledCoordinates = e.EnemyCoordinates.Select((x, i) => new {i, x})
  80. .Where(x => e.EnabledEnemy[7 - x.i]).Select(x => new Vector3(x.x.X, x.x.Y, x.x.Z)).ToList();
  81. if (enabledCoordinates.Count <= 0) return e;
  82. {
  83. enabledCoordinates.ForEach(x => total += x);
  84. e.AverageVector = total / 8f / Memory.EnemyCoordinateScale;
  85. e.MinVector =
  86. new Vector3(enabledCoordinates.Min(x => x.X), enabledCoordinates.Min(x => x.Y),
  87. enabledCoordinates.Min(x => x.Z)) / Memory.EnemyCoordinateScale;
  88. e.MaxVector =
  89. new Vector3(enabledCoordinates.Max(x => x.X), enabledCoordinates.Max(x => x.Y),
  90. enabledCoordinates.Max(x => x.Z)) / Memory.EnemyCoordinateScale;
  91. e.MidVector = (e.MinVector + e.MaxVector) / 2f / Memory.EnemyCoordinateScale;
  92. }
  93. return e;
  94. }
  95. public int ResolveCameraAnimation(byte cameraPointerValue) => cameraPointerValue & 0b1111;
  96. public int ResolveCameraSet(byte cameraPointerValue) => (cameraPointerValue >> 4) & 0b1111;
  97. public override string ToString() => $"{ID} - {Filename}";
  98. #endregion Methods
  99. }
  100. }