1
0
Fork 0
forked from aly/qstbak

muffin v7.5.5

This commit is contained in:
alydev 2026-08-17 20:25:32 +10:00
parent a8f2c1df37
commit 6266f9e6b7
110 changed files with 14907 additions and 6073 deletions

View file

@ -53,9 +53,19 @@ public sealed class VectorConverter : JsonConverter<Vector3>
public override void Write(Utf8JsonWriter writer, Vector3 value, JsonSerializerOptions options)
{
writer.WriteStartObject();
writer.WriteNumber("X", value.X);
writer.WriteNumber("Y", value.Y);
writer.WriteNumber("Z", value.Z);
writer.WriteNumber("X", RoundValue(value.X));
writer.WriteNumber("Y", RoundValue(value.Y));
writer.WriteNumber("Z", RoundValue(value.Z));
writer.WriteEndObject();
}
private static float RoundValue(float value)
{
float num = MathF.Round(value, 6);
if (!(MathF.Abs(num) < 1E-06f))
{
return num;
}
return 0f;
}
}

View file

@ -17,6 +17,13 @@ public sealed class ElementIdConverter : JsonConverter<ElementId>
public override void Write(Utf8JsonWriter writer, ElementId value, JsonSerializerOptions options)
{
throw new NotImplementedException();
if (value is QuestId)
{
writer.WriteNumberValue(value.Value);
}
else
{
writer.WriteStringValue(value.ToString());
}
}
}

View file

@ -32,6 +32,18 @@ public sealed class ElementIdListConverter : JsonConverter<List<ElementId>>
public override void Write(Utf8JsonWriter writer, List<ElementId> value, JsonSerializerOptions options)
{
throw new NotImplementedException();
writer.WriteStartArray();
foreach (ElementId item in value)
{
if (item is QuestId)
{
writer.WriteNumberValue(item.Value);
}
else
{
writer.WriteStringValue(item.ToString());
}
}
writer.WriteEndArray();
}
}

View file

@ -57,6 +57,26 @@ public sealed class QuestWorkConfigConverter : JsonConverter<QuestWorkValue>
public override void Write(Utf8JsonWriter writer, QuestWorkValue value, JsonSerializerOptions options)
{
throw new NotImplementedException();
if (value != null && value.High.HasValue && value.Low.HasValue && value.Mode == EQuestWorkMode.Bitwise)
{
byte value2 = (byte)((value.High.Value << 4) + value.Low.Value);
writer.WriteNumberValue(value2);
return;
}
writer.WriteStartObject();
if (value.High.HasValue)
{
writer.WriteNumber("High", value.High.Value);
}
if (value.Low.HasValue)
{
writer.WriteNumber("Low", value.Low.Value);
}
if (value.Mode != EQuestWorkMode.Bitwise)
{
writer.WritePropertyName("Mode");
new QuestWorkModeConverter().Write(writer, value.Mode, options);
}
writer.WriteEndObject();
}
}

View file

@ -0,0 +1,19 @@
using System.Collections.Generic;
using System.Numerics;
using System.Text.Json.Serialization;
using Questionable.Model.Common.Converter;
namespace Questionable.Model.Questing;
public sealed class LandingZone
{
[JsonConverter(typeof(VectorListConverter))]
public List<Vector3> Vertices { get; set; } = new List<Vector3>();
public float? YTolerance { get; set; }
public float CalculateYTolerance()
{
return YTolerance ?? 2f;
}
}

View file

@ -1,10 +1,12 @@
using System.Collections.Generic;
using System.Linq;
using System.Text.Json.Serialization;
namespace Questionable.Model.Questing;
public sealed class QuestSequence
{
[JsonIgnore(Condition = JsonIgnoreCondition.Never)]
public byte Sequence { get; set; }
public string? Comment { get; set; }

View file

@ -25,6 +25,8 @@ public sealed class QuestStep
public float? StopDistance { get; set; }
public List<LandingZone>? LandingZones { get; set; }
public ushort TerritoryId { get; set; }
[JsonIgnore(Condition = JsonIgnoreCondition.Never)]

View file

@ -0,0 +1,164 @@
using System;
using System.Collections.Generic;
using System.Numerics;
using Questionable.Model.Questing;
namespace Questionable.Model;
public static class LandingZoneMath
{
private static readonly Random Rng = new Random();
public static Vector3 CalculateLandingLocation(IReadOnlyList<LandingZone> zones)
{
if (zones.Count == 0)
{
throw new ArgumentException("At least one landing zone is required.", "zones");
}
if (zones.Count == 1)
{
return RandomPointInConvexPolygon(zones[0].Vertices);
}
float num = 0f;
Span<float> span = stackalloc float[zones.Count];
for (int i = 0; i < zones.Count; i++)
{
span[i] = CalculatePolygonArea(zones[i].Vertices);
num += span[i];
}
float num2 = (float)(Rng.NextDouble() * (double)num);
float num3 = 0f;
for (int j = 0; j < zones.Count; j++)
{
num3 += span[j];
if (num2 <= num3)
{
return RandomPointInConvexPolygon(zones[j].Vertices);
}
}
return RandomPointInConvexPolygon(zones[zones.Count - 1].Vertices);
}
public static Vector3 RandomPointInConvexPolygon(IReadOnlyList<Vector3> vertices)
{
if (vertices.Count < 3)
{
throw new ArgumentException("Polygon must have at least 3 vertices.", "vertices");
}
if (vertices.Count == 3)
{
return RandomPointInTriangle(vertices[0], vertices[1], vertices[2]);
}
int num = vertices.Count - 2;
Span<float> span = stackalloc float[num];
float num2 = 0f;
for (int i = 0; i < num; i++)
{
span[i] = TriangleAreaXZ(vertices[0], vertices[i + 1], vertices[i + 2]);
num2 += span[i];
}
float num3 = (float)(Rng.NextDouble() * (double)num2);
float num4 = 0f;
for (int j = 0; j < num; j++)
{
num4 += span[j];
if (num3 <= num4)
{
return RandomPointInTriangle(vertices[0], vertices[j + 1], vertices[j + 2]);
}
}
return RandomPointInTriangle(vertices[0], vertices[vertices.Count - 2], vertices[vertices.Count - 1]);
}
private static Vector3 RandomPointInTriangle(Vector3 a, Vector3 b, Vector3 c)
{
float num = (float)Rng.NextDouble();
float num2 = (float)Rng.NextDouble();
if (num + num2 > 1f)
{
num = 1f - num;
num2 = 1f - num2;
}
return a + num * (b - a) + num2 * (c - a);
}
private static float TriangleAreaXZ(Vector3 a, Vector3 b, Vector3 c)
{
return MathF.Abs((b.X - a.X) * (c.Z - a.Z) - (c.X - a.X) * (b.Z - a.Z)) * 0.5f;
}
public static float CalculatePolygonArea(IReadOnlyList<Vector3> vertices)
{
if (vertices.Count < 3)
{
return 0f;
}
float num = 0f;
for (int i = 0; i < vertices.Count; i++)
{
int index = (i + 1) % vertices.Count;
num += vertices[i].X * vertices[index].Z;
num -= vertices[index].X * vertices[i].Z;
}
return MathF.Abs(num) * 0.5f;
}
public static bool IsConvex(IReadOnlyList<Vector3> vertices)
{
if (vertices.Count < 3)
{
return false;
}
bool? flag = null;
int count = vertices.Count;
for (int i = 0; i < count; i++)
{
Vector3 vector = vertices[i];
Vector3 vector2 = vertices[(i + 1) % count];
Vector3 vector3 = vertices[(i + 2) % count];
float num = (vector2.X - vector.X) * (vector3.Z - vector2.Z) - (vector2.Z - vector.Z) * (vector3.X - vector2.X);
if (!(MathF.Abs(num) < 1E-06f))
{
bool flag2 = num > 0f;
if (!flag.HasValue)
{
flag = flag2;
}
else if (flag != flag2)
{
return false;
}
}
}
return flag.HasValue;
}
public static bool IsPointInConvexPolygon(Vector2 point, IReadOnlyList<Vector3> vertices)
{
if (vertices.Count < 3)
{
return false;
}
bool? flag = null;
int count = vertices.Count;
for (int i = 0; i < count; i++)
{
Vector3 vector = vertices[i];
Vector3 vector2 = vertices[(i + 1) % count];
float num = (vector2.X - vector.X) * (point.Y - vector.Z) - (vector2.Z - vector.Z) * (point.X - vector.X);
if (!(MathF.Abs(num) < 1E-06f))
{
bool flag2 = num > 0f;
if (!flag.HasValue)
{
flag = flag2;
}
else if (flag != flag2)
{
return false;
}
}
}
return true;
}
}