1using System.Globalization;
2using System.Reflection;
18 public override bool Equals(
object obj) {
22 return imageExtrusionKey.Slot ==
Slot;
52 [Obsolete(
"Use BlockTypeToOriginalIndex.")]
67 ArgumentNullException.ThrowIfNull(u1);
68 ArgumentNullException.ThrowIfNull(u2);
70 int blockAllocate = (u1.Allocated ? 1 : 0) - (u2.
Allocated ? 1 : 0);
71 if (blockAllocate != 0) {
76 if (modEntitySub != 0) {
81 return blockIndexSub != 0
85 string.Compare(u1.
Block.GetType().Name, u2.
Block.GetType().Name, CultureInfo.InvariantCulture, CompareOptions.None);
99 allocateData.Block.BlockIndex = Index;
100 allocateData.Allocated =
true;
101 allocateData.Index = Index;
103#pragma warning disable IL2072
104 FieldInfo fieldInfo = block.GetType().GetRuntimeFields().FirstOrDefault(p => p.Name ==
"Index" && p.IsPublic && p.IsStatic);
105#pragma warning restore IL2072
106 if (fieldInfo !=
null
107 && fieldInfo.FieldType == typeof(
int)
108 && !fieldInfo.IsLiteral) {
112 catch (Exception ex) {
113 Log.
Error($
"Failed to edit Index of <{block.GetType().AssemblyQualifiedName}>! {ex}");
127 for (
int i = 0; i <
m_blocks.Length; i++) {
128#pragma warning disable IL2072
130#pragma warning restore IL2072
165 public static int GetBlockIndex(
string BlockName,
bool throwIfNotFound =
false) {
170 if (throwIfNotFound) {
171 throw new KeyNotFoundException($
"Block with name <{BlockName}> is not found.");
195 public static
int GetBlockIndex(Type blockType,
bool throwIfNotFound = false,
bool mustBeInSameType = false) {
197 if (blockIndexByType >= 0
198 && blockIndexByType < 1024) {
199 return blockIndexByType;
201 if (mustBeInSameType) {
202 if (throwIfNotFound) {
203 throw new KeyNotFoundException($
"Block with type <{blockType.AssemblyQualifiedName}> is not found.");
219 && blockIndex < 1024) {
220 return Blocks[blockIndex];
225 public static Block GetBlock(
string BlockName,
bool throwIfNotFound =
false) {
228 && blockIndex < 1024) {
242 public static T
GetBlock<T>(
bool throwIfNotFound =
false,
bool mustBeInSameType =
false) where T :
Block {
244 if (blockIndex < 0) {
247 T blockT =
Blocks[blockIndex] as T;
248 if (blockT ==
null && throwIfNotFound) {
249 throw new InvalidCastException(
250 $
"Block <{typeof(T).AssemblyQualifiedName}> is modified into <{Blocks[blockIndex].GetType().AssemblyQualifiedName}> thus not capable for type."
262 public static Block GetBlock(Type blockType,
bool throwIfNotFound =
false,
bool mustBeInSameType =
false) {
263 int blockIndex =
GetBlockIndex(blockType, throwIfNotFound, mustBeInSameType);
264 if (blockIndex < 0) {
268 if (throwIfNotFound && block.GetType() == blockType) {
269 throw new InvalidCastException(
270 $
"Block <{blockType.AssemblyQualifiedName}> is modified into <{block.GetType().AssemblyQualifiedName}> thus not capable for type."
277 for (
int i = 0; i <
m_blocks.Length; i++) {
282 for (
int i = 0; i < entity.
BlockTypes.Count; i++) {
284#pragma warning disable IL2072
285 Block block = (
Block)Activator.CreateInstance(type);
289 FieldInfo fieldInfo = type.GetRuntimeFields().FirstOrDefault(p => p.Name ==
"Index" && p.IsPublic && p.IsStatic);
290#pragma warning restore IL2072
291 if (fieldInfo !=
null
292 && fieldInfo.FieldType == typeof(
int)) {
293 int staticIndex = (int)fieldInfo.GetValue(
null)!;
294 block.BlockIndex = staticIndex;
297 block.BlockIndex = -1;
300 bool staticBlockIndexBefore =
false;
303 BlocksAllocateData.FirstOrDefault(b => b.Block.GetType().Name == block.GetType().Name);
304 if (blockAllocateDataToRemove !=
null) {
314 StaticBlockIndex = !block.IsIndexDynamic
316 || staticBlockIndexBefore,
332 if (originalIndex == 0) {
341 if (subsystemBlocksManager !=
null) {
348 catch (Exception ex) {
355 if (subsystemBlocksManager !=
null) {
356 subsystemBlocksManager.CallAllocate();
361 bool containsKey = subsystemBlocksManager.DynamicBlockNameToIndex.TryGetValue(
362 allocateData.
Block.GetType().Name,
372 int allocateDataIndex = 0;
375 throw new Exception(
"Too many blocks! Please reduce the mods count.");
387 if (subsystemBlocksManager !=
null) {
388 subsystemBlocksManager.DynamicBlockNameToIndex[
m_blocks[num].GetType().Name] = num;
397 for (
int num = 0; num <
m_blocks.Length; num++) {
411 catch (Exception e) {
422 modLoader.BlocksInitalized();
434 [Obsolete(
"Use BlocksManager.GetBlock() instead.")]
436 Block block =
Blocks.FirstOrDefault(b => b.GetType().Name == typeName);
437 if (block ==
null && throwIfNotFound) {
438 throw new InvalidOperationException(
string.Format(
LanguageControl.
Get(
"BlocksManager", 1), typeName));
444 List<Block> blocks = [];
450 return blocks.ToArray();
520 Vector3 translation = matrix.Translation;
521 Vector3 vector = matrix.Right * size.
X;
522 Vector3 v = matrix.Up * size.Y * height;
523 Vector3 v2 = matrix.Forward * size.
Z;
524 Vector3 v3 = translation + 0.5f * (-vector - v - v2);
525 Vector3 v4 = translation + 0.5f * (vector - v - v2);
526 Vector3 v5 = translation + 0.5f * (-vector + v - v2);
527 Vector3 v6 = translation + 0.5f * (vector + v - v2);
528 Vector3 v7 = translation + 0.5f * (-vector - v + v2);
529 Vector3 v8 = translation + 0.5f * (vector - v + v2);
530 Vector3 v9 = translation + 0.5f * (-vector + v + v2);
531 Vector3 v10 = translation + 0.5f * (vector + v + v2);
548 vector2.X = (float)(textureSlot % textureSlotCount) / textureSlotCount;
549 vector2.Y = (float)(textureSlot / textureSlotCount) / textureSlotCount;
550 vector2.W = vector2.Y + 1f / textureSlotCount;
551 vector2.Z = vector2.X + 1f / textureSlotCount;
559 texCoord1:
new Vector2(vector2.
X, vector2.
W),
560 texCoord2:
new Vector2(vector2.
X, vector2.
Y),
561 texCoord3:
new Vector2(vector2.
Z, vector2.
Y),
562 texCoord4:
new Vector2(vector2.
Z, vector2.
W)
565 vector2.X = (float)(textureSlot % textureSlotCount) / textureSlotCount;
566 vector2.Y = (float)(textureSlot / textureSlotCount) / textureSlotCount;
567 vector2.W = vector2.Y + 1f / textureSlotCount;
568 vector2.Z = vector2.X + 1f / textureSlotCount;
576 texCoord1:
new Vector2(vector2.
Z, vector2.
W),
577 texCoord2:
new Vector2(vector2.
X, vector2.
W),
578 texCoord3:
new Vector2(vector2.
X, vector2.
Y),
579 texCoord4:
new Vector2(vector2.
Z, vector2.
Y)
582 vector2.X = (float)(textureSlot % textureSlotCount) / textureSlotCount;
583 vector2.Y = (float)(textureSlot / textureSlotCount) / textureSlotCount;
584 vector2.W = vector2.Y + 1f / textureSlotCount;
585 vector2.Z = vector2.X + 1f / textureSlotCount;
592 texCoord1:
new Vector2(vector2.
X, vector2.
Y),
593 texCoord2:
new Vector2(vector2.
Z, vector2.
Y),
594 texCoord3:
new Vector2(vector2.
Z, vector2.
W),
595 texCoord4:
new Vector2(vector2.
X, vector2.
W)
598 vector2.X = (float)(textureSlot % textureSlotCount) / textureSlotCount;
599 vector2.Y = (float)(textureSlot / textureSlotCount) / textureSlotCount;
600 vector2.W = vector2.Y + 1f / textureSlotCount;
601 vector2.Z = vector2.X + 1f / textureSlotCount;
608 texCoord1:
new Vector2(vector2.
X, vector2.
W),
609 texCoord2:
new Vector2(vector2.
X, vector2.
Y),
610 texCoord3:
new Vector2(vector2.
Z, vector2.
Y),
611 texCoord4:
new Vector2(vector2.
Z, vector2.
W)
614 vector2.X = (float)(textureSlot % textureSlotCount) / textureSlotCount;
615 vector2.Y = (float)(textureSlot / textureSlotCount) / textureSlotCount;
616 vector2.W = vector2.Y + 1f / textureSlotCount;
617 vector2.Z = vector2.X + 1f / textureSlotCount;
625 texCoord1:
new Vector2(vector2.
Z, vector2.
W),
626 texCoord2:
new Vector2(vector2.
X, vector2.
W),
627 texCoord3:
new Vector2(vector2.
X, vector2.
Y),
628 texCoord4:
new Vector2(vector2.
Z, vector2.
Y)
631 vector2.X = (float)(textureSlot % textureSlotCount) / textureSlotCount;
632 vector2.Y = (float)(textureSlot / textureSlotCount) / textureSlotCount;
633 vector2.W = vector2.Y + 1f / textureSlotCount;
634 vector2.Z = vector2.X + 1f / textureSlotCount;
642 texCoord1:
new Vector2(vector2.
X, vector2.
W),
643 texCoord2:
new Vector2(vector2.
X, vector2.
Y),
644 texCoord3:
new Vector2(vector2.
Z, vector2.
Y),
645 texCoord4:
new Vector2(vector2.
Z, vector2.
W)
711 texture ??= environmentData.SubsystemTerrain !=
null
712 ? environmentData.SubsystemTerrain.SubsystemAnimatedTextures.AnimatedBlocksTexture
716 if (textureSlotCount == 16) {
720 float tx = (float)(textureSlot % textureSlotCount) / textureSlotCount;
721 float ty = (float)(textureSlot / textureSlotCount) / textureSlotCount;
722 vector =
new Vector4(tx, ty, tx + 1f / textureSlotCount, ty + 1f / textureSlotCount);
728 Vector3 translation = matrix.Translation;
736 vector2 = matrix.Right;
739 Vector3 v = translation + 0.85f * size * (-vector2 - vector3);
740 Vector3 v2 = translation + 0.85f * size * (vector2 - vector3);
741 Vector3 v3 = translation + 0.85f * size * (-vector2 + vector3);
742 Vector3 v4 = translation + 0.85f * size * (vector2 + vector3);
795 Image image = environmentData.SubsystemTerrain !=
null
799 DrawMeshBlock(primitivesRenderer, imageExtrusionBlockMesh, color, 1.7f * size, ref matrix, environmentData);
808 imageExtrusionKey.Image = image;
809 imageExtrusionKey.Slot = slot;
817 value.AppendImageExtrusion(
819 new Rectangle(num, num2, num3 - num, num4 - num2),
820 new Vector3(1f / num5, 1f / num5, 0.0833333358f),
835 Texture2D texture = environmentData.SubsystemTerrain !=
null
836 ? environmentData.SubsystemTerrain.SubsystemAnimatedTextures.AnimatedBlocksTexture
856 Texture2D texture = environmentData.SubsystemTerrain !=
null
857 ? environmentData.SubsystemTerrain.SubsystemAnimatedTextures.AnimatedBlocksTexture
905 DynamicArray<VertexPositionColorTexture> triangleVertices = texturedBatch3D.
TriangleVertices;
906 int count3 = triangleVertices.
Count;
907 int count4 = triangleVertices.
Count;
908 triangleVertices.Count += count;
909 for (
int i = 0; i < count; i++) {
914 float num2 = 1f / v2.
W;
915 blockMeshVertex.Position =
new Vector3(v2.
X * num2, v2.
Y * num2, v2.
Z * num2);
920 Color color2 = !blockMeshVertex.IsEmissive
922 (
byte)(blockMeshVertex.
Color.
R * vector2.
X),
923 (
byte)(blockMeshVertex.
Color.
G * vector2.
Y),
924 (
byte)(blockMeshVertex.
Color.
B * vector2.
Z),
925 (
byte)(blockMeshVertex.
Color.
A * vector2.
W)
928 (
byte)(blockMeshVertex.
Color.
R * vector.
X),
929 (
byte)(blockMeshVertex.
Color.
G * vector.
Y),
930 (
byte)(blockMeshVertex.
Color.
B * vector.
Z),
931 (
byte)(blockMeshVertex.
Color.
A * vector.
W)
940 int count5 = triangleIndices.
Count;
941 triangleIndices.Count += count2;
942 for (
int j = 0; j < count2; j++) {
943 triangleIndices.
Array[count5++] = count3 + array2[j];
951 bool skipVanilla =
false;
955 result = modLoader.DamageItem(block, value, damageCount, owner, out skipVanilla);
963 if (durability >= 0) {
964 int num2 = block.
GetDamage(value) + damageCount;
965 if (num2 <= durability) {
974 blocksDataString = blocksDataString.Replace(
"\r",
string.Empty);
975 string[] lines = blocksDataString.Split(
'\n', StringSplitOptions.RemoveEmptyEntries);
976 string[] firstLine = lines[0].Split(
';');
977 for (
int i = 1; i < lines.Length; i++) {
978 string line = lines[i];
979 if (
string.IsNullOrEmpty(line)) {
982 string[] array = line.Split(
';');
983 if (array.Length != firstLine.Length) {
984 throw new InvalidOperationException(
985 $
"{string.Format(LanguageControl.Get("BlocksManager", "2
"), array.Length > 0 ? array[0] : LanguageControl.Unknown)}{string.Format(LanguageControl.Get("BlocksManager", "7
"), firstLine.Length, array.Length)}"
988 string typeName = array[0];
989 if (
string.IsNullOrEmpty(typeName)) {
992 Block block =
m_blocks.FirstOrDefault(v => v.GetType().Name == typeName);
997 Dictionary<string, FieldInfo> fieldInfos =
new();
998#pragma warning disable IL2072
999 foreach (FieldInfo runtimeField
in block.GetType().GetRuntimeFields()) {
1000#pragma warning disable IL2072
1001 if (runtimeField.IsPublic
1002 && !runtimeField.IsStatic) {
1003 fieldInfos.Add(runtimeField.Name, runtimeField);
1006 for (
int j = 1; j < array.Length; j++) {
1007 string fieldName = firstLine[j];
1008 string data = array[j];
1009 if (!
string.IsNullOrEmpty(data)) {
1010 if (!fieldInfos.TryGetValue(fieldName, out FieldInfo value)) {
1011 throw new InvalidOperationException(
string.Format(
LanguageControl.
Get(
"BlocksManager",
"8"), fieldName, typeName));
1014 if (data.StartsWith(
'#')) {
1015 string refTypeName = data.Substring(1);
1016 obj = !
string.IsNullOrEmpty(refTypeName)
1017 ? (
m_blocks.FirstOrDefault(v => v.GetType().Name == refTypeName)
1018 ??
throw new InvalidOperationException(
string.Format(
LanguageControl.
Get(
"BlocksManager",
"9"), refTypeName, typeName, fieldName)))
1025 value.SetValue(block, obj);
1032 for (
int i = 0; i < 256; i++) {
1038 int num = slot % 16;
1039 int num2 = slot / 16;
1040 float x = (num + 0.001f) / 16f;
1041 float y = (num2 + 0.001f) / 16f;
1042 float z = (num + 1 - 0.001f) / 16f;
1043 float w = (num2 + 1 - 0.001f) / 16f;
1044 return new Vector4(x, y, z, w);
1048 int totalCount = textureSlotCount * textureSlotCount;
1050 for (
int i = 0; i < totalCount; i++) {
1051 int num = i % textureSlotCount;
1052 int num2 = i / textureSlotCount;
1053 float x = (num + 0.001f) / textureSlotCount;
1054 float y = (num2 + 0.001f) / textureSlotCount;
1055 float z = (num + 1 - 0.001f) / textureSlotCount;
1056 float w = (num2 + 1 - 0.001f) / textureSlotCount;
1057 slotTexCoords[i] =
new Vector4(x, y, z, w);
1059 return slotTexCoords;
1062 [Obsolete(
"Use BlocksManager.GetBlock() instead.")]
1065 Type type = modEntity.BlockTypes.Find(p => p.Name == TypeFullName);
1067 if (block !=
null) {
readonly DynamicArray< int > TriangleIndices
readonly DynamicArray< VertexPositionColorTexture > TriangleVertices
static readonly BlendState AlphaBlend
TexturedBatch3D TexturedBatch(Texture2D texture, bool useAlphaTest=false, int layer=0, DepthStencilState depthStencilState=null, RasterizerState rasterizerState=null, BlendState blendState=null, SamplerState samplerState=null)
static readonly RasterizerState CullCounterClockwiseScissor
static SamplerState PointClamp
void QueueQuad(Vector3 p1, Vector3 p2, Vector3 p3, Vector3 p4, Vector2 texCoord1, Vector2 texCoord2, Vector2 texCoord3, Vector2 texCoord4, Color color)
static void Error(object message)
static void Information(object message)
static void Warning(object message)
static int Max(int x1, int x2)
static float Lerp(float x1, float x2, float f)
static object ConvertFromString(Type type, string data)
virtual string GetCategory(int value)
virtual int GetTextureSlotCount(int value)
设置材质(正方形)单行格子(分割后每个材质)数,对放置后的方块无效
virtual int SetDamage(int value, int damage)
virtual void Initialize()
virtual int GetDamage(int value)
virtual int GetFaceTextureSlot(int face, int value)
virtual int GetDurability(int value)
virtual IEnumerable< int > GetCreativeValues()
virtual bool ShouldBeAddedToProject(SubsystemBlocksManager subsystemBlocksManager)
virtual bool MatchCrafingId(string CraftId)
virtual int GetDamageDestructionValue(int value)
DynamicArray< BlockMeshVertex > Vertices
DynamicArray< int > Indices
int Compare(BlockAllocateData u1, BlockAllocateData u2)
static BlockAllocateDataComparer Instance
static Block GetBlockGeneral< T >(bool throwIfNotFound=false)
获取一个方块的通用Block类,具有较好的模组兼容稳定性
static Block GetBlock(Type blockType, bool throwIfNotFound=false, bool mustBeInSameType=false)
static Dictionary< Type, int > BlockTypeToIndex
static Dictionary< string, int > BlockNameToIndex
static int GetBlockIndex< T >(bool throwIfNotFound=false, bool mustBeInSameType=false)
获取方块的Index
static Vector4[] m_slotTexCoords
static void DrawMeshBlock(PrimitivesRenderer3D primitivesRenderer, BlockMesh blockMesh, Color color, float size, ref Matrix matrix, DrawBlockEnvironmentData environmentData)
static void LoadBlocksData(string blocksDataString)
static Dictionary< ImageExtrusionKey, BlockMesh > m_imageExtrusionsCache
static int DamageItem(int value, int damageCount, Entity owner=null)
static ReadOnlyList< string > Categories
static void CalculateSlotTexCoordTables()
static void DrawCubeBlock(PrimitivesRenderer3D primitivesRenderer, int value, Vector3 size, ref Matrix matrix, Color color, Color topColor, DrawBlockEnvironmentData environmentData, Texture2D texture)
static bool DrawImageExtrusionEnabled
static void DrawMeshBlock(PrimitivesRenderer3D primitivesRenderer, BlockMesh blockMesh, float size, ref Matrix matrix, DrawBlockEnvironmentData environmentData)
static DrawBlockEnvironmentData m_defaultEnvironmentData
static void InitializeCategories()
static FluidBlock[] m_fluidBlocks
static Block GetBlockInMod(string ModSpace, string TypeFullName)
static void DrawMeshBlock(PrimitivesRenderer3D primitivesRenderer, BlockMesh blockMesh, Texture2D texture, Color color, float size, ref Matrix matrix, DrawBlockEnvironmentData environmentData)
static List< BlockAllocateData > BlocksAllocateData
static void DrawFlatBlock(PrimitivesRenderer3D primitivesRenderer, int value, float size, ref Matrix matrix, Texture2D texture, Color color, bool isEmissive, DrawBlockEnvironmentData environmentData)
static Vector4[] GetslotTexCoords(int textureSlotCount)
static void DrawCubeBlock(PrimitivesRenderer3D primitivesRenderer, int value, Vector3 size, ref Matrix matrix, Color color, Color topColor, DrawBlockEnvironmentData environmentData)
static List< string > m_categories
static int GetBlockIndex(string BlockName, bool throwIfNotFound=false)
通过方块名称来获取方块的Index
static Block GetBlock(string BlockName, bool throwIfNotFound=false)
static Block[] FindBlocksByCraftingId(string craftingId)
static void ResetBlocks()
static BlockMesh GetImageExtrusionBlockMesh(Image image, int slot)
static void PostProcessBlocksLoad()
static void DrawImageExtrusionBlock(PrimitivesRenderer3D primitivesRenderer, int value, float size, ref Matrix matrix, Color color, DrawBlockEnvironmentData environmentData)
static void DrawCubeBlock(PrimitivesRenderer3D primitivesRenderer, int value, Vector3 size, float height, ref Matrix matrix, Color color, Color topColor, DrawBlockEnvironmentData environmentData)
static void DrawFlatOrImageExtrusionBlock(PrimitivesRenderer3D primitivesRenderer, int value, float size, ref Matrix matrix, Texture2D texture, Color color, bool isEmissive, DrawBlockEnvironmentData environmentData)
static bool LoadBlocksStaticly
const int SurvivalCraftBlockCount
static int[] m_originalBlockIndex
static Dictionary< Type, int > BlockTypeToOriginalIndex
static T GetBlock< T >(bool throwIfNotFound=false, bool mustBeInSameType=false)
static void InitializeBlocks(SubsystemBlocksManager subsystemBlocksManager)
static void AllocateBlock(BlockAllocateData allocateData, int Index)
static Vector4 TextureSlotToTextureCoords(int slot)
static FluidBlock[] FluidBlocks
static Block FindBlockByTypeName(string typeName, bool throwIfNotFound)
static void DrawCubeBlock(PrimitivesRenderer3D primitivesRenderer, int value, Vector3 size, float height, ref Matrix matrix, Color color, Color topColor, DrawBlockEnvironmentData environmentData, Texture2D texture)
static void AddCategory(string category)
static Texture2D DefaultBlocksTexture
Matrix? ViewProjectionMatrix
Vector3? BillboardDirection
DrawBlockMode DrawBlockMode
SubsystemTerrain SubsystemTerrain
static Action< Project > ProjectDisposed
static string Get(string className, int key)
获取在当前语言类名键对应的字符串
static readonly float[] LightIntensityByLightValue
static float CalculateLighting(Vector3 normal)
static void Warning(string mesg)
virtual void LoadBlocksData()
初始化BlocksData资源
override int GetHashCode()
Texture2D AnimatedBlocksTexture
virtual SubsystemAnimatedTextures SubsystemAnimatedTextures
static int ExtractContents(int value)
static void HookAction(string HookName, Func< ModLoader, bool > action)
执行Hook
static bool GetModEntity(string packagename, out ModEntity modEntity)
static ModEntity SurvivalCraftModEntity
static List< ModEntity > ModList
所有已启用的模组
static Color MultiplyColorOnlyNotSaturated(Color c, float s)
static Color MultiplyColorOnly(Color c, float s)
static Matrix CreateScale(float scale)
static Vector3 Transform(Vector3 v, Matrix m)
static Vector3 Cross(Vector3 v1, Vector3 v2)
static Vector3 Normalize(Vector3 v)
static readonly Vector3 UnitY
static Vector4 Transform(Vector4 v, Matrix m)
static readonly Vector4 Zero
Vector2 TextureCoordinates
override int GetHashCode()
override bool Equals(object obj)