Skip to content

Commit

Permalink
mt gulg fixes
Browse files Browse the repository at this point in the history
  • Loading branch information
CarnifexOptimus committed Jun 1, 2024
1 parent b90c036 commit cdd0baa
Show file tree
Hide file tree
Showing 5 changed files with 85 additions and 40 deletions.
17 changes: 5 additions & 12 deletions BossMod/BossModule/ArenaBounds.cs
Original file line number Diff line number Diff line change
Expand Up @@ -357,18 +357,11 @@ private static (WPos Center, float Radius, RelSimplifiedComplexPolygon Poly) Cal

private static string CreateCacheKey(IEnumerable<Shape> unionShapes, IEnumerable<Shape> differenceShapes, IEnumerable<Shape> additionalShapes)
{
using var sha512 = SHA512.Create();
var unionKey = string.Join(",", unionShapes.Select(s => ComputeShapeHash(s, sha512)));
var differenceKey = string.Join(",", differenceShapes.Select(s => ComputeShapeHash(s, sha512)));
var additionalKey = string.Join(",", additionalShapes.Select(s => ComputeShapeHash(s, sha512)));
return $"{unionKey}|{differenceKey}|{additionalKey}";
}

private static string ComputeShapeHash(Shape shape, SHA512 sha512)
{
var data = Encoding.UTF8.GetBytes(shape.ToString());
var hash = sha512.ComputeHash(data);
return BitConverter.ToString(hash).Replace("-", "", StringComparison.Ordinal);
var unionKey = string.Join(",", unionShapes.Select(s => s.ComputeHash()));
var differenceKey = string.Join(",", differenceShapes.Select(s => s.ComputeHash()));
var additionalKey = string.Join(",", additionalShapes.Select(s => s.ComputeHash()));
var combinedKey = $"{unionKey}|{differenceKey}|{additionalKey}";
return Shape.ComputeSHA512(combinedKey);
}

private static RelSimplifiedComplexPolygon CombinePolygons(List<RelSimplifiedComplexPolygon> unionPolygons, List<RelSimplifiedComplexPolygon> differencePolygons, List<RelSimplifiedComplexPolygon> secondUnionPolygons)
Expand Down
79 changes: 57 additions & 22 deletions BossMod/BossModule/Shapes.cs
Original file line number Diff line number Diff line change
Expand Up @@ -5,54 +5,72 @@ public abstract record class Shape
public static readonly Dictionary<object, RelSimplifiedComplexPolygon> StaticCache = [];
public abstract RelSimplifiedComplexPolygon ToPolygon(WPos center);
public const float MaxApproxError = 0.01f;
public abstract string ComputeHash();

public static string ComputeSHA512(string input)
{
var bytes = Encoding.UTF8.GetBytes(input);
var hash = SHA512.HashData(bytes);
return BitConverter.ToString(hash).Replace("-", "", StringComparison.Ordinal);
}
}

public record class Circle(WPos Center, float Radius) : Shape
{
public override RelSimplifiedComplexPolygon ToPolygon(WPos center)
{
if (StaticCache.TryGetValue((Center, center, Radius, typeof(Circle)), out var cachedResult))
if (StaticCache.TryGetValue((ComputeHash(), center), out var cachedResult))
return cachedResult;
var vertices = CurveApprox.Circle(Radius, MaxApproxError).Select(p => p + (Center - center)).ToList();
var result = new RelSimplifiedComplexPolygon([new RelPolygonWithHoles(vertices)]);
StaticCache[(Center, center, Radius, typeof(Circle))] = result;
StaticCache[(ComputeHash(), center)] = result;
return result;
}

public override string ComputeHash() => ComputeSHA512($"{nameof(Circle)}:{Center.X},{Center.Z},{Radius}");
}

// for custom polygons defined by a list of vertices
public record class PolygonCustom(IEnumerable<WPos> Vertices) : Shape
{
public override RelSimplifiedComplexPolygon ToPolygon(WPos center)
{
if (StaticCache.TryGetValue((center, Vertices, typeof(PolygonCustom)), out var cachedResult))
if (StaticCache.TryGetValue((ComputeHash(), center), out var cachedResult))
return cachedResult;
var relativeVertices = Vertices.Select(v => v - center).ToList();
var result = new RelSimplifiedComplexPolygon([new RelPolygonWithHoles(relativeVertices)]);
StaticCache[(center, Vertices, typeof(PolygonCustom))] = result;
StaticCache[(ComputeHash(), center)] = result;
return result;
}

public override string ComputeHash()
{
var verticesHash = string.Join(",", Vertices.Select(v => $"{v.X},{v.Z}"));
return ComputeSHA512($"{nameof(PolygonCustom)}:{verticesHash}");
}
}

public record class Donut(WPos Center, float InnerRadius, float OuterRadius) : Shape
{
public override RelSimplifiedComplexPolygon ToPolygon(WPos center)
{
if (StaticCache.TryGetValue((Center, center, InnerRadius, OuterRadius, typeof(Donut)), out var cachedResult))
if (StaticCache.TryGetValue((ComputeHash(), center), out var cachedResult))
return cachedResult;
var vertices = CurveApprox.Donut(InnerRadius, OuterRadius, MaxApproxError).Select(p => p + (Center - center)).ToList();
var result = new RelSimplifiedComplexPolygon([new RelPolygonWithHoles(vertices)]);
StaticCache[(Center, center, InnerRadius, OuterRadius, typeof(Donut))] = result;
StaticCache[(ComputeHash(), center)] = result;
return result;
}

public override string ComputeHash() => ComputeSHA512($"{nameof(Donut)}:{Center.X},{Center.Z},{InnerRadius},{OuterRadius}");
}

// for rectangles defined by a center, halfwidth, halfheight and optionally rotation
public record class Rectangle(WPos Center, float HalfWidth, float HalfHeight, Angle Rotation = default) : Shape
{
public override RelSimplifiedComplexPolygon ToPolygon(WPos center)
{
if (StaticCache.TryGetValue((Center, center, HalfWidth, HalfHeight, Rotation, typeof(Rectangle)), out var cachedResult))
if (StaticCache.TryGetValue((ComputeHash(), center), out var cachedResult))
return cachedResult;
var cos = MathF.Cos(Rotation.Rad);
var sin = MathF.Sin(Rotation.Rad);
Expand All @@ -64,9 +82,11 @@ public override RelSimplifiedComplexPolygon ToPolygon(WPos center)
new WDir(-HalfWidth * cos - HalfHeight * sin, -HalfWidth * sin + HalfHeight * cos) + (Center - center)
};
var result = new RelSimplifiedComplexPolygon([new RelPolygonWithHoles(vertices)]);
StaticCache[(Center, center, HalfWidth, HalfHeight, Rotation, typeof(Rectangle))] = result;
StaticCache[(ComputeHash(), center)] = result;
return result;
}

public override string ComputeHash() => ComputeSHA512($"{nameof(Rectangle)}:{Center.X},{Center.Z},{HalfWidth},{HalfHeight},{Rotation.Rad}");
}

// for rectangles defined by a start point, end point and halfwidth
Expand All @@ -76,13 +96,14 @@ public record class RectangleSE(WPos Start, WPos End, float HalfWidth) : Rectang
HalfHeight: (End - Start).Length() / 2,
Rotation: new Angle(MathF.Atan2(End.Z - Start.Z, End.X - Start.X)) + 90.Degrees()
);

public record class Square(WPos Center, float HalfSize, Angle Rotation = default) : Rectangle(Center, HalfSize, HalfSize, Rotation);

public record class Cross(WPos Center, float Length, float HalfWidth, Angle Rotation = default) : Shape
{
public override RelSimplifiedComplexPolygon ToPolygon(WPos center)
{
if (StaticCache.TryGetValue((Center, center, Length, HalfWidth, Rotation, typeof(Cross)), out var cachedResult))
if (StaticCache.TryGetValue((ComputeHash(), center), out var cachedResult))
return cachedResult;
var cos = MathF.Cos(Rotation.Rad);
var sin = MathF.Sin(Rotation.Rad);
Expand All @@ -109,17 +130,19 @@ public override RelSimplifiedComplexPolygon ToPolygon(WPos center)
new(horizontalVertices)
};
var result = new RelSimplifiedComplexPolygon(polygons);
StaticCache[(Center, center, Length, HalfWidth, Rotation, typeof(Cross))] = result;
StaticCache[(ComputeHash(), center)] = result;
return result;
}

public override string ComputeHash() => ComputeSHA512($"{nameof(Cross)}:{Center.X},{Center.Z},{Length},{HalfWidth},{Rotation.Rad}");
}

// Equilateral triangle defined by center, radius and rotation
public record class TriangleE(WPos Center, float Radius, Angle Rotation = default) : Shape
{
public override RelSimplifiedComplexPolygon ToPolygon(WPos center)
{
if (StaticCache.TryGetValue((Center, center, Radius, Rotation, typeof(TriangleE)), out var cachedResult))
if (StaticCache.TryGetValue((ComputeHash(), center), out var cachedResult))
return cachedResult;

var sqrt3 = MathF.Sqrt(3);
Expand All @@ -139,17 +162,19 @@ public override RelSimplifiedComplexPolygon ToPolygon(WPos center)
var rotatedVertices = vertices.Select(v => new WDir(v.X * cos - v.Z * sin, v.X * sin + v.Z * cos)).ToList();

var result = new RelSimplifiedComplexPolygon([new RelPolygonWithHoles(rotatedVertices)]);
StaticCache[(Center, center, Radius, Rotation, typeof(TriangleE))] = result;
StaticCache[(ComputeHash(), center)] = result;
return result;
}

public override string ComputeHash() => ComputeSHA512($"{nameof(TriangleE)}:{Center.X},{Center.Z},{Radius},{Rotation.Rad}");
}

// custom Triangle defined by three sides and rotation, mind the triangle inequality, side1 + side2 >= side3
public record class TriangleS(WPos Center, float SideA, float SideB, float SideC, Angle Rotation = default) : Shape
{
public override RelSimplifiedComplexPolygon ToPolygon(WPos center)
{
if (StaticCache.TryGetValue((Center, center, SideA, SideB, SideC, Rotation, typeof(TriangleS)), out var cachedResult))
if (StaticCache.TryGetValue((ComputeHash(), center), out var cachedResult))
return cachedResult;

var sides = new[] { SideA, SideB, SideC }.OrderByDescending(s => s).ToArray();
Expand All @@ -176,17 +201,19 @@ public override RelSimplifiedComplexPolygon ToPolygon(WPos center)
var adjustedVertices = rotatedVertices.Select(v => v + (Center - center)).ToList();

var result = new RelSimplifiedComplexPolygon([new RelPolygonWithHoles(adjustedVertices)]);
StaticCache[(Center, center, SideA, SideB, SideC, Rotation, typeof(TriangleS))] = result;
StaticCache[(ComputeHash(), center)] = result;
return result;
}

public override string ComputeHash() => ComputeSHA512($"{nameof(TriangleS)}:{Center.X},{Center.Z},{SideA},{SideB},{SideC},{Rotation.Rad}");
}

// Triangle definded by base length and angle at the apex, apex points north by default
public record class TriangleA(WPos Center, float BaseLength, Angle ApexAngle, Angle Rotation = default) : Shape
{
public override RelSimplifiedComplexPolygon ToPolygon(WPos center)
{
if (StaticCache.TryGetValue((Center, center, BaseLength, ApexAngle, Rotation, typeof(TriangleA)), out var cachedResult))
if (StaticCache.TryGetValue((ComputeHash(), center), out var cachedResult))
return cachedResult;

var apexAngleRad = ApexAngle.Rad;
Expand All @@ -212,17 +239,19 @@ public override RelSimplifiedComplexPolygon ToPolygon(WPos center)
var adjustedVertices = rotatedVertices.Select(v => v + (Center - center)).ToList();

var result = new RelSimplifiedComplexPolygon([new RelPolygonWithHoles(adjustedVertices)]);
StaticCache[(Center, center, BaseLength, ApexAngle, Rotation, typeof(TriangleA))] = result;
StaticCache[(ComputeHash(), center)] = result;
return result;
}

public override string ComputeHash() => ComputeSHA512($"{nameof(TriangleA)}:{Center.X},{Center.Z},{BaseLength},{ApexAngle.Rad},{Rotation.Rad}");
}

// for polygons defined by a radius and n amount of vertices
public record class Polygon(WPos Center, float Radius, int Vertices, Angle Rotation = default) : Shape
{
public override RelSimplifiedComplexPolygon ToPolygon(WPos center)
{
if (StaticCache.TryGetValue((Center, center, Radius, Vertices, Rotation, typeof(Polygon)), out var cachedResult))
if (StaticCache.TryGetValue((ComputeHash(), center), out var cachedResult))
return cachedResult;

var angleIncrement = 2 * MathF.PI / Vertices;
Expand All @@ -238,35 +267,41 @@ public override RelSimplifiedComplexPolygon ToPolygon(WPos center)
}

var result = new RelSimplifiedComplexPolygon([new RelPolygonWithHoles(vertices)]);
StaticCache[(Center, center, Radius, Vertices, Rotation, typeof(Polygon))] = result;
StaticCache[(ComputeHash(), center)] = result;
return result;
}

public override string ComputeHash() => ComputeSHA512($"{nameof(Polygon)}:{Center.X},{Center.Z},{Radius},{Vertices},{Rotation.Rad}");
}

public record class Cone(WPos Center, float Radius, Angle StartAngle, Angle EndAngle) : Shape
{
public override RelSimplifiedComplexPolygon ToPolygon(WPos center)
{
if (StaticCache.TryGetValue((Center, center, Radius, StartAngle, EndAngle, typeof(Cone)), out var cachedResult))
if (StaticCache.TryGetValue((ComputeHash(), center), out var cachedResult))
return cachedResult;

var vertices = CurveApprox.CircleSector(Center, Radius, StartAngle, EndAngle, MaxApproxError).Select(p => p - center).ToList();
var result = new RelSimplifiedComplexPolygon([new RelPolygonWithHoles(vertices)]);
StaticCache[(Center, center, Radius, StartAngle, EndAngle, typeof(Cone))] = result;
StaticCache[(ComputeHash(), center)] = result;
return result;
}

public override string ComputeHash() => ComputeSHA512($"{nameof(Cone)}:{Center.X},{Center.Z},{Radius},{StartAngle.Rad},{EndAngle.Rad}");
}

public record class DonutSegment(WPos Center, float InnerRadius, float OuterRadius, Angle StartAngle, Angle EndAngle) : Shape
{
public override RelSimplifiedComplexPolygon ToPolygon(WPos center)
{
if (StaticCache.TryGetValue((Center, center, InnerRadius, OuterRadius, StartAngle, EndAngle, typeof(DonutSegment)), out var cachedResult))
if (StaticCache.TryGetValue((ComputeHash(), center), out var cachedResult))
return cachedResult;

var vertices = CurveApprox.DonutSector(InnerRadius, OuterRadius, StartAngle, EndAngle, MaxApproxError).Select(p => p + (Center - center)).ToList();
var result = new RelSimplifiedComplexPolygon([new RelPolygonWithHoles(vertices)]);
StaticCache[(Center, center, InnerRadius, OuterRadius, StartAngle, EndAngle, typeof(DonutSegment))] = result;
StaticCache[(ComputeHash(), center)] = result;
return result;
}

public override string ComputeHash() => ComputeSHA512($"{nameof(DonutSegment)}:{Center.X},{Center.Z},{InnerRadius},{OuterRadius},{StartAngle.Rad},{EndAngle.Rad}");
}
8 changes: 6 additions & 2 deletions BossMod/Modules/Endwalker/Alliance/A23Halone/Octagons.cs
Original file line number Diff line number Diff line change
Expand Up @@ -7,8 +7,8 @@ namespace BossMod.Endwalker.Alliance.A23Halone;
class Octagons(BossModule module) : Components.GenericAOEs(module)
{
private ArenaBounds? _arena;
private const int InnerRadius = 11;
private const int OuterRadius = 12;
private const float InnerRadius = 11.5f;
private const float OuterRadius = 12.5f;
private const int Vertices = 8;
private static readonly WPos[] spears = [new(-686, 592), new(-700, 616.2f), new(-714, 592)];
private static readonly Angle[] angle = [37.5f.Degrees(), 22.5f.Degrees(), -37.5f.Degrees()];
Expand Down Expand Up @@ -70,4 +70,8 @@ private void RemoveOctagons(byte index)
break;
}
}
public override void AddAIHints(int slot, Actor actor, PartyRolesConfig.Assignment assignment, AIHints hints)
{
//TODO fix AI map creation
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -41,7 +41,7 @@ public D052ForgivenApathyStates(BossModule module) : base(module)
[ModuleInfo(BossModuleInfo.Maturity.Verified, Contributors = "Malediktus", GroupType = BossModuleInfo.GroupType.CFC, GroupID = 659, NameID = 8267)]
public class D052ForgivenApathy : BossModule
{
public D052ForgivenApathy(WorldState ws, Actor primary) : base(ws, primary, primary.Position.X > -100 ? arena1.Center : arena2.Center, primary.Position.X > -100 ? arena1 : arena2)
public D052ForgivenApathy(WorldState ws, Actor primary) : base(ws, primary, primary.Position.Z > -106 ? arena2.Center : arena1.Center, primary.Position.Z > -106 ? arena2 : arena1)
{
ForgivenPrejudice = Enemies(OID.ForgivenPrejudice);
ForgivenExtortion = Enemies(OID.ForgivenExtortion);
Expand All @@ -51,6 +51,7 @@ public D052ForgivenApathy(WorldState ws, Actor primary) : base(ws, primary, prim
private static readonly List<WPos> arenacoords1 = [new(21, -215.1f), new(16.3f, -213.2f), new(9.8f, -208.8f), new(4.4f, -206.3f), new(0.2f, -204.8f), new(-9.6f, -202.8f), new(-10, -202.5f),
new(-10.7f, -201.9f), new(-11.5f, -201.4f), new(-13.2f, -200.9f), new(-8.1f, -186.8f), new(-3.7f, -188.5f), new(-1.9f, -188.7f), new(2.5f, -190f), new(9.3f, -193.5f), new(18.8f, -198.8f),
new(27.1f, -203.2f)];

private static readonly List<WPos> arenacoords2 = [new(-176, -138.1f), new(-199.1f, -124.8f), new(-197.3f, -121.5f), new(-204.15f, -117.3f), new(-204f, -116.1f), new(-205, -114.5f),
new(-205.3f, -114.3f), new(-205.2f, -112.4f), new(-205.5f, -111.9f), new(-206.6f, -111f), new(-207f, -110.6f), new(-198.8f, -98.4f), new(-190, -103.5f), new(-190, -104.5f),
new(-187.1f, -106.1f), new(-186.3f, -105.7f), new(-177.1f, -111.1f), new(-177.2f, -111.7f), new(-174, -113.6f), new(-173.3f, -113.2f), new(-164.1f, -118.5f)];
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -62,11 +62,22 @@ class GoldChaser(BossModule module) : Components.GenericAOEs(module)
{
private DateTime _activation;
private readonly List<Actor> _casters = [];
private static readonly AOEShapeRect rect = new(100, 2.5f, 100);
private static readonly AOEShapeRect rect = new(100, 2.53f, 100); // halfwidth is 2.5, but +0.03 safety margin because ring position doesn't seem to be exactly caster position
private static readonly List<WPos> positionsSet1 = [new WPos(-227.5f, 253), new WPos(-232.5f, 251.5f)];
private static readonly List<WPos> positionsSet2 = [new WPos(-252.5f, 253), new WPos(-247.5f, 251.5f)];
private static readonly List<WPos> positionsSet3 = [new WPos(-242.5f, 253), new WPos(-237.5f, 253)];
private static readonly List<WPos> positionsSet4 = [new WPos(-252.5f, 253), new WPos(-227.5f, 253)];

private bool AreCastersInPositions(List<WPos> positions)
{
return _casters.Count >= 2 && positions.Count == 2 &&
(_casters[0].Position == positions[0] && _casters[1].Position == positions[1] ||
_casters[0].Position == positions[1] && _casters[1].Position == positions[0]);
}

public override IEnumerable<AOEInstance> ActiveAOEs(int slot, Actor actor)
{
if (_casters.Count > 1 && (_casters[0].Position.AlmostEqual(new(-227.5f, 253), 1) && _casters[1].Position.AlmostEqual(new(-232.5f, 251.5f), 1) || _casters[0].Position.AlmostEqual(new(-252.5f, 253), 1) && _casters[1].Position.AlmostEqual(new(-247.5f, 251.5f), 1)))
if (AreCastersInPositions(positionsSet1) || AreCastersInPositions(positionsSet2))
{
if (_casters.Count > 2)
{
Expand Down Expand Up @@ -106,7 +117,7 @@ public override IEnumerable<AOEInstance> ActiveAOEs(int slot, Actor actor)
yield return new(rect, _casters[5].Position, default, _activation.AddSeconds(11.1f), ArenaColor.Danger);
}
}
if (_casters.Count > 1 && (_casters[0].Position.AlmostEqual(new(-242.5f, 253), 1) && _casters[1].Position.AlmostEqual(new(-237.5f, 253), 1) || _casters[0].Position.AlmostEqual(new(-252.5f, 253), 1) && _casters[1].Position.AlmostEqual(new(-227.5f, 253), 1)))
if (AreCastersInPositions(positionsSet3) || AreCastersInPositions(positionsSet4))
{
if (_casters.Count > 2)
{
Expand Down Expand Up @@ -158,6 +169,7 @@ public override void OnEventCast(Actor caster, ActorCastEvent spell)
{
if ((AID)spell.Action.ID == AID.Ringsmith)
_activation = WorldState.CurrentTime;

if ((AID)spell.Action.ID == AID.VenaAmoris)
{
if (++NumCasts == 6)
Expand Down

0 comments on commit cdd0baa

Please sign in to comment.