1using System.Globalization;
12 public static string fName =
"FurnitureDesign";
80 for (
int i = 0; i <
m_values.Length; i++) {
90 if (!
m_box.HasValue) {
143 if (value.Length > 0) {
145 || value[^1] ==
' ') {
156 if (value.Length > 20) {
157 value = value.Substring(0, 20);
203 Name = valuesDictionary.GetValue(
"Name",
string.Empty);
205 int value = valuesDictionary.GetValue<
int>(
"Resolution");
208 string value2 = valuesDictionary.GetValue<
string>(
"Values");
210 int[] array =
new int[value * value * value];
211 string[] array2 = value2.Split([
','], StringSplitOptions.RemoveEmptyEntries);
212 for (
int i = 0; i < array2.Length; i++) {
213 string[] array3 = array2[i].Split([
'*'], StringSplitOptions.None);
214 if (array3.Length != 2) {
217 int num2 =
int.Parse(array3[0], CultureInfo.InvariantCulture);
218 int num3 =
int.Parse(array3[1], CultureInfo.InvariantCulture);
220 while (num4 < num2) {
236 if (values.Length != resolution * resolution * resolution) {
241 ||
m_values.Length != resolution * resolution * resolution) {
242 m_values =
new int[resolution * resolution * resolution];
302 int[] array =
new int[
m_values.Length];
303 for (
int i = 0; i <
m_values.Length; i++) {
307 array[i] = paintableBlock?.
Paint(
null, num, color) ?? num;
320 int[] array =
new int[resolution * resolution * resolution];
321 for (
int i = 0; i < resolution; i++) {
322 for (
int j = 0; j < resolution; j++) {
323 for (
int k = 0; k < resolution; k++) {
330 array[k + j * resolution + i * resolution * resolution] =
347 int num = k + delta.
X;
348 int num2 = j + delta.
Y;
349 int num3 = i + delta.
Z;
365 public void Rotate(
int axis,
int steps) {
379 Point3 point =
new((int)MathF.Round(vector.
X), (
int)MathF.Round(vector.
Y), (
int)MathF.Round(vector.
Z));
402 Point3 point =
new((int)MathF.Round(vector.
X), (
int)MathF.Round(vector.
Y), (
int)MathF.Round(vector.
Z));
419 StringBuilder stringBuilder =
new();
422 for (
int i = 1; i <
m_values.Length; i++) {
424 stringBuilder.Append(num2.ToString(CultureInfo.InvariantCulture));
425 stringBuilder.Append(
'*');
426 stringBuilder.Append(num.ToString(CultureInfo.InvariantCulture));
427 stringBuilder.Append(
',');
435 stringBuilder.Append(num2.ToString(CultureInfo.InvariantCulture));
436 stringBuilder.Append(
'*');
437 stringBuilder.Append(num.ToString(CultureInfo.InvariantCulture));
438 stringBuilder.Append(
',');
440 if (!
string.IsNullOrEmpty(
Name)) {
441 valuesDictionary.SetValue(
"Name",
Name);
447 valuesDictionary.SetValue(
"LinkedDesign",
LinkedDesign.Index);
449 valuesDictionary.SetValue(
"Values", stringBuilder.ToString());
450 return valuesDictionary;
461 for (
int i = 0; i <
m_values.Length; i++) {
475 List<FurnitureDesign> list =
ListChain();
476 List<FurnitureDesign> list2 = other.
ListChain();
477 if (list.Count != list2.Count) {
480 for (
int i = 0; i < list.Count; i++) {
481 if (!list[i].
Compare(list2[i])) {
491 furnitureDesign.Name =
Name;
494 return furnitureDesign;
498 List<FurnitureDesign> list =
ListChain();
499 List<FurnitureDesign> list2 =
new(list.Count);
500 for (
int i = 0; i < list.Count; i++) {
501 list2.Add(list[i].
Clone());
503 for (
int j = 0; j < list2.Count - 1; j++) {
504 list2[j].LinkedDesign = list2[j + 1];
508 list2[^1].LinkedDesign = list2[num];
515 HashSet<FurnitureDesign> hashSet =
new();
516 List<FurnitureDesign> list =
new();
518 hashSet.Add(furnitureDesign);
519 list.Add(furnitureDesign);
522 while (furnitureDesign !=
null
523 && !hashSet.Contains(furnitureDesign));
527 public static List<List<FurnitureDesign>>
ListChains(IEnumerable<FurnitureDesign> designs) {
528 List<List<FurnitureDesign>> list =
new();
529 List<FurnitureDesign> list2 =
new(designs);
530 while (list2.Count > 0) {
531 List<FurnitureDesign> list3 = list2[0].ListChain();
541 byte[] array =
new byte[
m_values.Length];
548 num2 =
m_values[num] == 0 ? num2 + 1 : 0;
549 array[num] = (byte)num2;
559 int num =
int.MaxValue;
560 int num2 =
int.MaxValue;
561 int num3 =
int.MaxValue;
562 int num4 =
int.MinValue;
563 int num5 =
int.MinValue;
564 int num6 =
int.MinValue;
565 for (
int i = box.
Near; i < box.
Far; i++) {
566 int num7 = Math.Min(num3, i);
567 int num8 = Math.Max(num6, i);
570 while (num9 < box.
Bottom) {
571 int num11 = box.Right - 1 - precedingEmptySpaces[num10 + box.Right - 1];
572 if (num11 >= box.
Left) {
573 num4 = Math.Max(num4, num11);
574 num2 = Math.Min(num2, num9);
575 num5 = Math.Max(num5, num9);
579 for (
int j = box.
Left; j <= num12; j++) {
581 num = Math.Min(num, j);
590 return new Box(num, num2, num3, num4 - num + 1, num5 - num2 + 1, num6 - num3 + 1);
617 for (
int i = 0; i < 6; i++) {
626 point =
new Point3(0, 0, 1);
627 point2 =
new Point3(-1, 0, 0);
628 point3 =
new Point3(0, -1, 0);
633 point =
new Point3(1, 0, 0);
634 point2 =
new Point3(0, 0, 1);
635 point3 =
new Point3(0, -1, 0);
640 point =
new Point3(0, 0, -1);
641 point2 =
new Point3(1, 0, 0);
642 point3 =
new Point3(0, -1, 0);
647 point =
new Point3(-1, 0, 0);
648 point2 =
new Point3(0, 0, -1);
649 point3 =
new Point3(0, -1, 0);
654 point =
new Point3(0, 1, 0);
655 point2 =
new Point3(-1, 0, 0);
656 point3 =
new Point3(0, 0, 1);
661 point =
new Point3(0, -1, 0);
662 point2 =
new Point3(-1, 0, 0);
663 point3 =
new Point3(0, 0, -1);
674 int num2 = j * point.X + k * point3.X + l * point2.X + point5.
X;
675 int num3 = j * point.Y + k * point3.Y + l * point2.Y + point5.
Y;
676 int num4 = j * point.Z + k * point3.Z + l * point2.Z + point5.
Z;
704 float num9 = n - num8;
705 float num10 = n + point6.X + num8;
706 float num11 = m - num8;
707 float num12 = m + point6.Y + num8;
708 float x = j * point.X + num11 * point3.X + num9 * point2.X + point4.
X;
709 float y = j * point.Y + num11 * point3.Y + num9 * point2.Y + point4.
Y;
710 float z = j * point.Z + num11 * point3.Z + num9 * point2.Z + point4.
Z;
711 float x2 = j * point.X + num11 * point3.X + num10 * point2.X + point4.
X;
712 float y2 = j * point.Y + num11 * point3.Y + num10 * point2.Y + point4.
Y;
713 float z2 = j * point.Z + num11 * point3.Z + num10 * point2.Z + point4.
Z;
714 float x3 = j * point.X + num12 * point3.X + num10 * point2.X + point4.
X;
715 float y3 = j * point.Y + num12 * point3.Y + num10 * point2.Y + point4.
Y;
716 float z3 = j * point.Z + num12 * point3.Z + num10 * point2.Z + point4.
Z;
717 float x4 = j * point.X + num12 * point3.X + num9 * point2.X + point4.
X;
718 float y4 = j * point.Y + num12 * point3.Y + num9 * point2.Y + point4.
Y;
719 float z4 = j * point.Z + num12 * point3.Z + num9 * point2.Z + point4.
Z;
724 bool isEmissive =
false;
727 int? paintColor = paintableBlock.GetPaintColor(value2);
744 blockMesh3 = blockMesh2;
747 "SetFurnitureDesignColor",
749 loader.SetFurnitureDesignColor(
this, block, value2, ref num14, ref color);
753 int num15 = num14 % 16;
754 int num16 = num14 / 16;
756 blockMesh3.Vertices.Count += 4;
759 float x6 = ((n + point6.X - 0.01f) /
m_resolution + num15) / 16f;
761 float y6 = ((m + point6.Y - 0.01f) /
m_resolution + num16) / 16f;
766 TextureCoordinates =
new Vector2(x5, y5),
767 IsEmissive = isEmissive
773 TextureCoordinates =
new Vector2(x6, y5),
774 IsEmissive = isEmissive
780 TextureCoordinates =
new Vector2(x6, y6),
781 IsEmissive = isEmissive
787 TextureCoordinates =
new Vector2(x5, y6),
788 IsEmissive = isEmissive
791 blockMesh3.Indices.Count += 6;
793 array3[count2] = count;
794 array3[count2 + 1] = count + 1;
795 array3[count2 + 2] = count + 2;
796 array3[count2 + 3] = count + 2;
797 array3[count2 + 4] = count + 3;
798 array3[count2 + 5] = count;
811 m_geometry.SubsetAlphaTestByFace[i] = blockMesh2;
818 List<BoundingBox> list =
new(subdivision.
Boxes.Count);
819 for (
int i = 0; i < subdivision.
Boxes.Count; i++) {
826 for (
int j = 0; j < 4; j++) {
831 for (
int k = 0; k < list.Count; k++) {
838 List<BoundingBox> list2 =
new(list);
844 if (num < list2.Count) {
845 for (l = 0; l < list2.Count; l++) {
860 for (
int n = 0; n < list2.Count; n++) {
861 Vector3 vector2 = list2[n].Size();
862 flag |= vector2.X >= 0.6f && vector2.Y >= 0.6f;
863 flag |= vector2.X >= 0.6f && vector2.Z >= 0.6f;
864 flag |= vector2.Y >= 0.6f && vector2.Z >= 0.6f;
866 float minSize = flag ? 0.0625f : 0.6f;
867 for (
int num2 = 0; num2 < list2.Count; num2++) {
875 for (
int num3 = 0; num3 < 4; num3++) {
880 for (
int num4 = 0; num4 < list2.Count; num4++) {
892 list2.RemoveAt(num < l ? l - 1 : l);
898 List<BoundingBox> list =
new();
909 for (
int l = 0; l < list.Count; l++) {
913 vector2.X =
MathUtils.
Max(MathF.Abs(vector2.
X) - vector.
X / 2f, 0f);
914 vector2.Y =
MathUtils.
Max(MathF.Abs(vector2.
Y) - vector.
Y / 2f, 0f);
915 vector2.Z =
MathUtils.
Max(MathF.Abs(vector2.
Z) - vector.
Z / 2f, 0f);
916 if (vector2.
Length() < 0.15f) {
924 else if (list.Count < 4) {
925 list.Add(boundingBox);
931 for (
int m = 0; m < 4; m++) {
936 for (
int n = 0; n < list.Count; n++) {
945 Dictionary<int, int> dictionary =
new();
948 for (
int num =
Resolution - 1; num >= 0; num--) {
951 dictionary.TryGetValue(num2, out
int value);
952 dictionary[num2] = value + 1;
959 foreach (KeyValuePair<int, int> item
in dictionary) {
960 if (item.Value > num3) {
1035 result.TotalVolume = box.Width * box.Height * box.
Depth;
1037 result.Boxes = [box];
1039 for (
int num2 = box.
Bottom - 1; num2 >= box.
Top + 1; num2--) {
1044 int num3 = subdivision.Boxes.Count + subdivision2.
Boxes.Count;
1045 int num4 = subdivision.TotalVolume + subdivision2.
TotalVolume;
1047 int num6 = num3 > result.Boxes.Count ? num4 + num : num4;
1050 result.TotalVolume = num4;
1051 result.MinVolume = num5;
1052 result.Boxes = subdivision.
Boxes;
1056 for (
int i = box.
Near + 1; i < box.
Far; i++) {
1061 int num7 = subdivision3.Boxes.Count + subdivision4.
Boxes.Count;
1062 int num8 = subdivision3.TotalVolume + subdivision4.
TotalVolume;
1064 int num10 = num7 > result.Boxes.Count ? num8 + num : num8;
1067 result.TotalVolume = num8;
1068 result.MinVolume = num9;
1069 result.Boxes = subdivision3.
Boxes;
1073 for (
int j = box.
Left + 1; j < box.
Right; j++) {
1078 int num11 = subdivision5.Boxes.Count + subdivision6.
Boxes.Count;
1079 int num12 = subdivision5.TotalVolume + subdivision6.
TotalVolume;
1081 int num14 = num11 > result.Boxes.Count ? num12 + num : num12;
1084 result.TotalVolume = num12;
1085 result.MinVolume = num13;
1086 result.Boxes = subdivision5.
Boxes;
1098 for (
int j = start.
X; j <= num; j++) {
1102 Point2 point =
new(num - start.
X, i - start.Y + 1);
1103 if (point.
X * point.
Y > result.
X * result.
Y) {
1113 for (
int i = start.
Y; i < start.
Y + size.
Y; i++) {
1114 for (
int j = start.
X; j < start.
X + size.
X; j++) {
1121 for (
int i = 0; i < steps; i++) {
1123 case 0: p =
new Vector3(p.
X, p.
Z, 0f - p.
Y);
break;
1124 case 1: p =
new Vector3(0f - p.
Z, p.
Y, p.
X);
break;
1125 default: p =
new Vector3(0f - p.
Y, p.
X, p.
Z);
break;
1133 case 0: p =
new Vector3(p.
X, p.
Y, 0f - p.
Z);
break;
1134 case 1: p =
new Vector3(0f - p.
X, p.
Y, p.
Z);
break;
1135 default: p =
new Vector3(0f - p.
X, p.
Y, p.
Z);
break;
1141 float num = max - min;
1142 if (num < minSize) {
1143 float num2 = minSize - num;
1150 else if (max > 1f) {
static int Min(int x1, int x2)
static int Max(int x1, int x2)
Color Lookup(int temperature, int humidity)
static BlockColorsMap Water
virtual int GetFaceTextureSlot(int face, int value)
virtual void GenerateSidesData()
DynamicArray< BlockMeshVertex > Vertices
DynamicArray< int > Indices
static int GetColor(int data)
FurnitureDesign(int index, SubsystemTerrain subsystemTerrain, ValuesDictionary valuesDictionary)
void CalculateFacesMasks()
FurnitureInteractionMode m_interactionMode
void MarkUsed(Cell[] surface, Point2 start, Point2 size)
static Vector3 RotatePoint(Vector3 p, int axis, int steps)
FurnitureInteractionMode InteractionMode
FurnitureGeometry Geometry
BoundingBox[][] m_interactionBoxesByRotation
BoundingBox[][] m_collisionBoxesByRotation
List< FurnitureDesign > ListChain()
void Resize(int resolution)
BoundingBox[][] m_torchPointsByRotation
SubsystemTerrain m_subsystemTerrain
int? m_shadowStrengthFactor
bool CompareChain(FurnitureDesign other)
BoundingBox[] GetTorchPoints(int rotation)
static Vector3 MirrorPoint(Vector3 p, int axis)
FurnitureGeometry m_geometry
FurnitureSet FurnitureSet
FurnitureDesign m_linkedDesign
Subdivision CreateBoundingBoxesHelper(Box box, int depth, byte[] precedingEmptySpaces)
FurnitureDesign(SubsystemTerrain subsystemTerrain)
bool Compare(FurnitureDesign other)
FurnitureDesign LinkedDesign
Point2 FindLargestSize(Cell[] surface, Point2 start, int value)
void CalculateShadowStrengthFactor()
static List< List< FurnitureDesign > > ListChains(IEnumerable< FurnitureDesign > designs)
static bool IsValueTransparent(int value)
byte[] CreatePrecedingEmptySpacesArray()
BoundingBox[] GetCollisionBoxes(int rotation)
static void EnsureMinSize(ref float min, ref float max, float minSize)
FurnitureSet m_furnitureSet
Box CalculateBox(Box box, byte[] precedingEmptySpaces)
void SetValues(int resolution, int[] values)
int m_transparentFacesMask
List< FurnitureDesign > CloneChain()
int m_loadTimeLinkedDesignIndex
BoundingBox[] GetInteractionBoxes(int rotation)
void CalculateMainValue()
void Rotate(int axis, int steps)
void CreateCollisionAndInteractionBoxes()
static string Get(string className, int key)
获取在当前语言类名键对应的字符串
Color GetColor(int index)
Color GetFabricColor(int index)
static int ExtractContents(int value)
static int ExtractData(int value)
static void HookAction(string HookName, Func< ModLoader, bool > action)
执行Hook
int Paint(SubsystemTerrain subsystemTerrain, int value, int? color)
static BoundingBox Union(BoundingBox b1, BoundingBox b2)
static Matrix CreateTranslation(float x, float y, float z)
static Matrix CreateRotationY(float radians)
static readonly Point2 Zero
static readonly Point3 Zero
static Vector3 Transform(Vector3 v, Matrix m)
static Vector3 Max(Vector3 v, float f)
static Vector3 Min(Vector3 v, float f)
static int OppositeFace(int face)