using System;
using System.Collections.Generic;
using System.IO;
using ACE.Common;
using ACE.DatLoader.Entity;
using ACE.Entity.Enum;
namespace ACE.DatLoader.FileTypes
{
///
/// These are client_portal.dat files starting with 0x30.
///
[DatFileType(DatFileType.CombatTable)]
public class CombatManeuverTable : FileType
{
public List CMT { get; } = new List();
public Dictionary Stances;
public override void Unpack(BinaryReader reader)
{
Id = reader.ReadUInt32(); // This should always equal the fileId
CMT.Unpack(reader);
Stances = new Dictionary();
foreach (var maneuver in CMT)
{
if (!Stances.TryGetValue(maneuver.Style, out var attackHeights))
{
attackHeights = new AttackHeights();
Stances.Add(maneuver.Style, attackHeights);
}
if (!attackHeights.Table.TryGetValue(maneuver.AttackHeight, out var attackTypes))
{
attackTypes = new AttackTypes();
attackHeights.Table.Add(maneuver.AttackHeight, attackTypes);
}
if (!attackTypes.Table.TryGetValue(maneuver.AttackType, out var motionCommands))
{
motionCommands = new List();
attackTypes.Table.Add(maneuver.AttackType, motionCommands);
}
motionCommands.Add(maneuver.Motion);
}
}
public class AttackHeights
{
public Dictionary Table = new Dictionary();
}
public class AttackTypes
{
// technically there is another MinSkillLevels here in the data,
// but every MinSkillLevel in the client dats are always 0
public Dictionary> Table = new Dictionary>();
}
public static readonly List Invalid = new List() { MotionCommand.Invalid };
public List GetMotion(MotionStance stance, AttackHeight attackHeight, AttackType attackType, MotionCommand prevMotion)
{
if (!Stances.TryGetValue(stance, out var attackHeights))
return Invalid;
if (!attackHeights.Table.TryGetValue(attackHeight, out var attackTypes))
return Invalid;
if (!attackTypes.Table.TryGetValue(attackType, out var maneuvers))
return Invalid;
//if (maneuvers.Count == 1)
//return maneuvers[0];
/*Console.WriteLine($"CombatManeuverTable({Id:X8}).GetMotion({stance}, {attackHeight}, {attackType}) - found {maneuvers.Count} maneuvers");
foreach (var maneuver in maneuvers)
Console.WriteLine(maneuver);*/
// CombatManeuverTable(30000000).GetMotion(SwordCombat, Medium, Slash) - found 2 maneuvers
// SlashMed
// BackhandMed
// rng, or alternate?
/*for (var i = 0; i < maneuvers.Count; i++)
{
var maneuver = maneuvers[i];
if (maneuver == prevMotion)
{
if (i < maneuvers.Count - 1)
return maneuvers[i + 1];
else
return maneuvers[0];
}
}
return maneuvers[0];*/
// if the CMT contains > 1 entries for this lookup, return both
// the code determines which motion to use based on the power bar
return maneuvers;
}
public void ShowCombatTable()
{
foreach (var stance in Stances)
{
Console.WriteLine($"- {stance.Key}");
foreach (var attackHeight in stance.Value.Table)
{
Console.WriteLine($" - {attackHeight.Key}");
foreach (var attackType in attackHeight.Value.Table)
{
Console.WriteLine($" - {attackType.Key}");
foreach (var motion in attackType.Value)
Console.WriteLine($" - {motion}");
}
}
}
}
}
}