using System;
using System.Collections.Generic;
using System.IO;
namespace OpenVIII.Kernel
{
public class KernelBin
{
#region Fields
public const ushort MaxHPValue = 9999;
public const byte MaxStatValue = 255;
#endregion Fields
#region Constructors
///
/// Read binary data from into structures and arrays
///
///
///
///
public KernelBin()
{
Memory.Log.WriteLine($"{nameof(KernelBin)} :: new ");
ArchiveBase aw = ArchiveWorker.Load(ArchiveString);
byte[] buffer = aw.GetBinaryFile(Memory.Strings[Strings.FileID.KERNEL].GetFilenames()[0]);
List subPositions = Memory.Strings[Strings.FileID.KERNEL].GetFiles().subPositions;
MemoryStream ms;
if (buffer == null) return;
using (BinaryReader br = new BinaryReader(ms = new MemoryStream(buffer)))
{
ms.Seek(subPositions[BattleCommand.ID], SeekOrigin.Begin);
BattleCommands = BattleCommand.Read(br);
ms.Seek(subPositions[Magic_Data.id], SeekOrigin.Begin);
MagicData = Magic_Data.Read(br);
ms.Seek(subPositions[Junctionable_GFs_Data.id], SeekOrigin.Begin);
JunctionableGFsData = Junctionable_GFs_Data.Read(br);
ms.Seek(subPositions[Enemy_Attacks_Data.id], SeekOrigin.Begin);
EnemyAttacksData = Enemy_Attacks_Data.Read(br);
ms.Seek(subPositions[Weapons_Data.id], SeekOrigin.Begin);
WeaponsData = Weapons_Data.Read(br);
ms.Seek(subPositions[Renzokuken_Finishers_Data.id], SeekOrigin.Begin);
RenzokukenFinishersData = Renzokuken_Finishers_Data.Read(br);
ms.Seek(subPositions[Character_Stats.id], SeekOrigin.Begin);
CharacterStats = Character_Stats.Read(br);
ms.Seek(subPositions[BattleItemData.ID], SeekOrigin.Begin);
BattleItemsData = BattleItemData.Read(br);
NonBattleItemsData = Non_battle_Items_Data.Read();
ms.Seek(subPositions[Non_Junctionable_GFs_Attacks_Data.id], SeekOrigin.Begin);
NonJunctionableGFsAttacksData = Non_Junctionable_GFs_Attacks_Data.Read(br);
ms.Seek(subPositions[Command_ability_data.id], SeekOrigin.Begin);
CommandAbilityData = Command_ability_data.Read(br);
ms.Seek(subPositions[Kernel.JunctionAbilities.ID], SeekOrigin.Begin);
JunctionAbilities = Kernel.JunctionAbilities.Read(br);
ms.Seek(subPositions[Kernel.CommandAbilities.ID], SeekOrigin.Begin);
CommandAbilities = Kernel.CommandAbilities.Read(br);
ms.Seek(subPositions[StatPercentageAbilities.ID], SeekOrigin.Begin);
StatPercentAbilities = StatPercentageAbilities.Read(br);
ms.Seek(subPositions[Kernel.CharacterAbilities.ID], SeekOrigin.Begin);
CharacterAbilities = Kernel.CharacterAbilities.Read(br);
ms.Seek(subPositions[Kernel.PartyAbilities.ID], SeekOrigin.Begin);
PartyAbilities = Kernel.PartyAbilities.Read(br);
ms.Seek(subPositions[Kernel.GFAbilities.ID], SeekOrigin.Begin);
GFAbilities = Kernel.GFAbilities.Read(br);
ms.Seek(subPositions[Kernel.MenuAbilities.ID], SeekOrigin.Begin);
MenuAbilities = Kernel.MenuAbilities.Read(br);
ms.Seek(subPositions[Temporary_character_limit_breaks.id], SeekOrigin.Begin);
TemporaryCharacterLimitBreaks = Temporary_character_limit_breaks.Read(br);
ms.Seek(subPositions[Blue_Magic_Quistis_limit_break.id], SeekOrigin.Begin);
BlueMagicQuistisLimitBreak = Blue_Magic_Quistis_limit_break.Read(br);
//ms.Seek(subPositions[Quistis_limit_break_parameters.BattleID], SeekOrigin.Begin);
//QuistisLimitBreakParameters = Quistis_limit_break_parameters.Read(br);
ms.Seek(subPositions[Shot_Irvine_limit_break.id], SeekOrigin.Begin);
ShotIrvineLimitBreak = Shot_Irvine_limit_break.Read(br);
ms.Seek(subPositions[Duel_Zell_limit_break.id], SeekOrigin.Begin);
DuelZellLimitBreak = Duel_Zell_limit_break.Read(br);
ms.Seek(subPositions[Zell_limit_break_parameters.id], SeekOrigin.Begin);
ZellLimitBreakParameters = Zell_limit_break_parameters.Read(br);
ms.Seek(subPositions[Rinoa_limit_breaks_part_1.id], SeekOrigin.Begin);
RinoaLimitBreaksPart1 = Rinoa_limit_breaks_part_1.Read(br);
ms.Seek(subPositions[Rinoa_limit_breaks_part_2.id], SeekOrigin.Begin);
RinoaLimitBreaksPart2 = Rinoa_limit_breaks_part_2.Read(br);
ms.Seek(subPositions[Slot_array.id], SeekOrigin.Begin);
SlotArray = Slot_array.Read(br);
ms.Seek(subPositions[Selphie_limit_break_sets.id], SeekOrigin.Begin);
SelphieLimitBreakSets = Selphie_limit_break_sets.Read(br);
ms.Seek(subPositions[Kernel.Devour.id], SeekOrigin.Begin);
List tmp = Kernel.Devour.Read(br);
tmp.Add(new Devour { Description = Memory.Strings.Read(Strings.FileID.KERNEL, 30, 112) });
Devour = tmp;
ms.Seek(subPositions[Misc_section.id], SeekOrigin.Begin);
MiscSection = Misc_section.Read(br);
MiscTextPointers = Misc_text_pointers.Read();
Dictionary allAbilities = new Dictionary(Kernel.MenuAbilities.Count + Kernel.JunctionAbilities.Count + Kernel.CommandAbilities.Count + StatPercentageAbilities.Count + Kernel.CharacterAbilities.Count + Kernel.PartyAbilities.Count + Kernel.GFAbilities.Count);
foreach (Abilities ability in (Abilities[])(Enum.GetValues(typeof(Abilities))))
{
combine(MenuAbilities);
combine(StatPercentAbilities);
combine(JunctionAbilities);
combine(CommandAbilities);
combine(CharacterAbilities);
combine(PartyAbilities);
combine(GFAbilities);
void combine(IReadOnlyDictionary dict)
where T : Ability
{
if (!dict.TryGetValue(ability, out T a)) return;
allAbilities.Add(ability, a);
}
}
AllAbilities = allAbilities;
Dictionary equippableAbilities = new Dictionary(
StatPercentageAbilities.Count +
Kernel.CharacterAbilities.Count +
Kernel.PartyAbilities.Count +
Kernel.GFAbilities.Count);
foreach (Abilities ability in (Abilities[])(Enum.GetValues(typeof(Abilities))))
{
if (StatPercentAbilities.ContainsKey(ability))
equippableAbilities[ability] = StatPercentAbilities[ability];
else if (CharacterAbilities.ContainsKey(ability))
equippableAbilities[ability] = CharacterAbilities[ability];
else if (PartyAbilities.ContainsKey(ability))
equippableAbilities[ability] = PartyAbilities[ability];
else if (CharacterAbilities.ContainsKey(ability))
equippableAbilities[ability] = CharacterAbilities[ability];
}
EquippableAbilities = equippableAbilities;
}
}
#endregion Constructors
#region Properties
public static IReadOnlyList AutoAtk { get; } = new List
{
Stat.STR,
Stat.HIT,
Stat.EL_Atk,
Stat.ST_Atk,
Stat.MAG,
Stat.SPD,
Stat.LUCK,
Stat.HP,
Stat.VIT,
Stat.SPR,
Stat.EVA,
Stat.EL_Def_1,
Stat.ST_Def_1,
Stat.EL_Def_2,
Stat.ST_Def_2,
Stat.EL_Def_3,
Stat.ST_Def_3,
Stat.EL_Def_4,
Stat.ST_Def_4
};
public static IReadOnlyList AutoDef { get; } = new List
{
Stat.HP,
Stat.VIT,
Stat.SPR,
Stat.EVA,
Stat.EL_Def_1,
Stat.ST_Def_1,
Stat.EL_Def_2,
Stat.ST_Def_2,
Stat.EL_Def_3,
Stat.ST_Def_3,
Stat.EL_Def_4,
Stat.ST_Def_4,
Stat.SPD,
Stat.LUCK,
Stat.MAG,
Stat.STR,
Stat.HIT,
Stat.EL_Atk,
Stat.ST_Atk
};
public static IReadOnlyList AutoMAG { get; } = new List
{
Stat.MAG,
Stat.SPR,
Stat.SPD,
Stat.LUCK,
Stat.HP,
Stat.VIT,
Stat.EVA,
Stat.EL_Def_1,
Stat.ST_Def_1,
Stat.EL_Def_2,
Stat.ST_Def_2,
Stat.EL_Def_3,
Stat.ST_Def_3,
Stat.EL_Def_4,
Stat.ST_Def_4,
Stat.STR,
Stat.HIT,
Stat.EL_Atk,
Stat.ST_Atk
};
///
/// Convert stat to stat junction
///
public static IReadOnlyDictionary Stat2Ability { get; } = new Dictionary
{
{ Stat.HP, Abilities.HPJ },
{ Stat.STR, Abilities.StrJ },
{ Stat.VIT, Abilities.VitJ},
{ Stat.MAG, Abilities.MagJ},
{ Stat.SPR, Abilities.SprJ },
{ Stat.SPD, Abilities.SpdJ },
{ Stat.EVA, Abilities.EvaJ },
{ Stat.LUCK, Abilities.LuckJ },
{ Stat.HIT, Abilities.HitJ },
{ Stat.EL_Atk, Abilities.ElAtkJ },
{ Stat.ST_Atk, Abilities.StAtkJ },
{ Stat.EL_Def_1, Abilities.ElDefJ },//or Elem_Def_Jx2 or Elem_Def_Jx4
{ Stat.EL_Def_2, Abilities.ElDefJ2 },//or Elem_Def_Jx4
{ Stat.EL_Def_3, Abilities.ElDefJ4 },
{ Stat.EL_Def_4, Abilities.ElDefJ4 },
{ Stat.ST_Def_1, Abilities.StDefJ },//or ST_Def_Jx2 or ST_Def_Jx4
{ Stat.ST_Def_2, Abilities.StDefJ2 },//or ST_Def_Jx4
{ Stat.ST_Def_3, Abilities.StDefJ4 },
{ Stat.ST_Def_4, Abilities.StDefJ4 }
};
public IReadOnlyDictionary AllAbilities { get; }
public IReadOnlyList BattleCommands { get; }
public IReadOnlyList BattleItemsData { get; }
public IReadOnlyDictionary BlueMagicQuistisLimitBreak { get; }
public IReadOnlyDictionary CharacterAbilities { get; }
public IReadOnlyDictionary CharacterStats { get; }
public IReadOnlyDictionary CommandAbilities { get; }
public IReadOnlyDictionary CommandAbilityData { get; }
public IReadOnlyList Devour { get; }
public IReadOnlyList DuelZellLimitBreak { get; }
public IReadOnlyList EnemyAttacksData { get; }
// should contain all abilities
public IReadOnlyDictionary EquippableAbilities { get; }
public IReadOnlyDictionary GFAbilities { get; }
//10
public IReadOnlyDictionary JunctionAbilities { get; }
public IReadOnlyDictionary JunctionableGFsData { get; }
public IReadOnlyList MagicData { get; }
//16
public IReadOnlyDictionary MenuAbilities { get; }
//28
public IReadOnlyList MiscSection { get; }
//29 //only_strings
public IReadOnlyList MiscTextPointers { get; }
//6
//7
public IReadOnlyList NonBattleItemsData { get; }
//8 //only strings
public IReadOnlyList NonJunctionableGFsAttacksData { get; }
//14
public IReadOnlyDictionary PartyAbilities { get; }
public IReadOnlyDictionary RenzokukenFinishersData { get; }
public IReadOnlyList RinoaLimitBreaksPart1 { get; }
//24
public IReadOnlyList RinoaLimitBreaksPart2 { get; }
public IReadOnlyList SelphieLimitBreakSets { get; }
//public static List QuistisLimitBreakParameters { get; private set; }//20
public IReadOnlyList ShotIrvineLimitBreak { get; }
//25
public IReadOnlyList SlotArray { get; }
//5
//9
//11
//12
public IReadOnlyDictionary StatPercentAbilities { get; }
//13
//15
//17
public IReadOnlyList TemporaryCharacterLimitBreaks { get; }
//0
//1
//2
//3
public IReadOnlyList WeaponsData { get; }
//22
public IReadOnlyList ZellLimitBreakParameters { get; }
private Memory.Archive ArchiveString { get; } = Memory.Archives.A_MAIN;
#endregion Properties
//4
//18
//19
//21
//23
//26
//27
//30
// contains 4 types;
}
}