Survivalcraft API 1.8.2.3 v1.8.2.3
Survivalcraft 2.4
载入中...
搜索中...
未找到
ClothingBlock.cs
浏览该文件的文档.
1using System.Xml.Linq;
2using Engine;
5
6namespace Game {
7 public class ClothingBlock : Block {
8 public static int Index = 203;
9
10 public Dictionary<int, ClothingData> m_clothingData = [];
11
13
14 public int m_displayIndex;
15
17
18 public static Matrix[] m_slotTransforms = [
19 Matrix.CreateTranslation(0f, -1.5f, 0f) * Matrix.CreateScale(2.7f),
20 Matrix.CreateTranslation(0f, -1.1f, 0f) * Matrix.CreateScale(2.7f),
21 Matrix.CreateTranslation(0f, -0.5f, 0f) * Matrix.CreateScale(2.7f),
22 Matrix.CreateTranslation(0f, -0.1f, 0f) * Matrix.CreateScale(2.7f)
23 ];
24
25 public virtual void LoadClothingData(XElement item) {
26 if (item.Name.LocalName == "ClothingData") {
27 XAttribute index = item.Attribute("Index");
28 if (index == null) {
29 return;
30 }
31 int.TryParse(index.Value, out int ClothIndex);
32 ClothIndex &= 0x3FF;
33 ClothingData clothingData = new(item);
34 string className = item.Attribute("Class")?.Value ?? typeof(ClothingData).FullName;
35 if (!string.IsNullOrEmpty(className)) {
36 try {
37 Type type = TypeCache.FindType(className, false, true);
38#pragma warning disable IL2072
39 clothingData = (ClothingData)Activator.CreateInstance(type, item);
40#pragma warning restore IL2072
41 if (clothingData == null) {
42 throw new Exception("ClothingData is not assignable to Game.ClothingData.");
43 }
44 }
45 catch (Exception ex) {
46 Log.Error($"ClothingData from class {className} create failed! {ex}");
47 }
48 }
49 if (clothingData == null) {
50 return;
51 }
52 clothingData.DisplayIndex = m_displayIndex++;
53 m_clothingData[ClothIndex] = clothingData;
54 }
55 foreach (XElement xElement1 in item.Elements()) {
56 LoadClothingData(xElement1);
57 }
58 }
59
60 public override void Initialize() {
62 XElement xElement = null;
63 ModsManager.ModListAllDo(modEntity => { modEntity.LoadClo(this, ref xElement); });
64 LoadClothingData(xElement);
66 Matrix[] array = new Matrix[playerModel.Bones.Count];
67 playerModel.CopyAbsoluteBoneTransformsTo(array);
68 int index = playerModel.FindBone("Hand1").Index;
69 int index2 = playerModel.FindBone("Hand2").Index;
70 array[index] = Matrix.CreateRotationY(0.1f) * array[index];
71 array[index2] = Matrix.CreateRotationY(-0.1f) * array[index2];
72 m_innerMesh = new BlockMesh();
73 foreach (ModelMesh mesh in playerModel.Meshes) {
74 Matrix matrix = array[mesh.ParentBone.Index];
75 foreach (ModelMeshPart meshPart in mesh.MeshParts) {
76 Color color = Color.White * 0.8f;
77 color.A = byte.MaxValue;
78 m_innerMesh.AppendModelMeshPart(
79 meshPart,
80 matrix,
81 false,
82 false,
83 false,
84 false,
86 );
87 m_innerMesh.AppendModelMeshPart(
88 meshPart,
89 matrix,
90 false,
91 true,
92 false,
93 true,
94 color
95 );
96 }
97 }
99 Matrix[] array2 = new Matrix[outerClothingModel.Bones.Count];
100 outerClothingModel.CopyAbsoluteBoneTransformsTo(array2);
101 int index3 = outerClothingModel.FindBone("Leg1").Index;
102 int index4 = outerClothingModel.FindBone("Leg2").Index;
103 array2[index3] = Matrix.CreateTranslation(-0.02f, 0f, 0f) * array2[index3];
104 array2[index4] = Matrix.CreateTranslation(0.02f, 0f, 0f) * array2[index4];
105 m_outerMesh = new BlockMesh();
106 foreach (ModelMesh mesh2 in outerClothingModel.Meshes) {
107 Matrix matrix2 = array2[mesh2.ParentBone.Index];
108 foreach (ModelMeshPart meshPart2 in mesh2.MeshParts) {
109 Color color2 = Color.White * 0.8f;
110 color2.A = byte.MaxValue;
111 m_outerMesh.AppendModelMeshPart(
112 meshPart2,
113 matrix2,
114 false,
115 false,
116 false,
117 false,
119 );
120 m_outerMesh.AppendModelMeshPart(
121 meshPart2,
122 matrix2,
123 false,
124 true,
125 false,
126 true,
127 color2
128 );
129 }
130 }
131 base.Initialize();
132 }
133
134 public override string GetDisplayName(SubsystemTerrain subsystemTerrain, int value) {
135 int data = Terrain.ExtractData(value);
136 ClothingData clothingData = GetClothingData(value);
137 if (clothingData == null) {
138 return string.Empty;
139 }
140 int clothingColor = GetClothingColor(data);
141 string displayName = clothingData.DisplayName;
142 if (clothingColor != 0) {
143 return SubsystemPalette.GetName(subsystemTerrain, clothingColor, displayName);
144 }
145 return displayName;
146 }
147
148 public override string GetDescription(int value) {
149 ClothingData clothingData = GetClothingData(value);
150 return clothingData == null ? string.Empty : clothingData.Description;
151 }
152
153 public override string GetCategory(int value) {
154 if (GetClothingColor(Terrain.ExtractData(value)) == 0) {
155 return base.GetCategory(value);
156 }
157 return "Dyed";
158 }
159
160 public override int GetDamage(int value) => (Terrain.ExtractData(value) >> 8) & 0xF;
161
162 public override int GetDisplayOrder(int value) => GetClothingData(value)?.DisplayIndex ?? int.MaxValue;
163
164 public override int SetDamage(int value, int damage) {
165 int num1 = Terrain.ExtractData(value);
166 num1 = (num1 & -3841) | ((damage & 0xF) << 8);
167 return Terrain.ReplaceData(value, num1);
168 }
169
170 public override bool CanWear(int value) => true;
171
172 public override ClothingData GetClothingData(int value) {
173 int data = Terrain.ExtractData(value);
174 int num1 = GetClothingIndex(data);
175 return m_clothingData.TryGetValue(num1, out ClothingData clothingData) ? clothingData : null;
176 }
177
178 public override IEnumerable<int> GetCreativeValues() {
179 foreach (ClothingData clothingData in m_clothingData.Values.ToList().OrderBy(cd => cd.DisplayIndex)) {
180 //if (clothingData == null) continue;
181 int colorsCount = !clothingData.CanBeDyed ? 1 : 16;
182 int color = 0;
183 while (color < colorsCount) {
184 int data = SetClothingColor(SetClothingIndex(0, clothingData.Index), color);
185 yield return Terrain.MakeBlockValue(203, 0, data);
186 color = color + 1;
187 }
188 }
189 }
190
191 public override CraftingRecipe GetAdHocCraftingRecipe(SubsystemTerrain terrain, string[] ingredients, float heatLevel, float playerLevel) {
192 if (heatLevel < 1f) {
193 return null;
194 }
195 List<string> list = ingredients.Where(i => !string.IsNullOrEmpty(i)).ToList();
196 if (list.Count == 2) {
197 int num1 = 0;
198 int num2 = 0;
199 int num3 = 0;
200 foreach (string item in list) {
201 CraftingRecipesManager.DecodeIngredient(item, out string craftingId, out int? data);
202 if (craftingId == BlocksManager.Blocks[203].CraftingId) {
203 num3 = Terrain.MakeBlockValue(203, 0, data ?? 0);
204 }
205 else if (craftingId == BlocksManager.Blocks[129].CraftingId) {
206 num1 = Terrain.MakeBlockValue(129, 0, data ?? 0);
207 }
208 else if (craftingId == BlocksManager.Blocks[128].CraftingId) {
209 num2 = Terrain.MakeBlockValue(128, 0, data ?? 0);
210 }
211 }
212 if (num1 != 0
213 && num3 != 0) {
214 int data2 = Terrain.ExtractData(num3);
215 int clothingColor = GetClothingColor(data2);
216 int clothingIndex = GetClothingIndex(data2);
217 bool canBeDyed = GetClothingData(data2)?.CanBeDyed ?? false;
218 int damage = BlocksManager.Blocks[203].GetDamage(num3);
219 int color = PaintBucketBlock.GetColor(Terrain.ExtractData(num1));
220 int damage2 = BlocksManager.Blocks[129].GetDamage(num1);
221 Block block = BlocksManager.Blocks[129];
222 Block block2 = BlocksManager.Blocks[203];
223 if (!canBeDyed) {
224 return null;
225 }
226 int num4 = PaintBucketBlock.CombineColors(clothingColor, color);
227 if (num4 != clothingColor) {
228 return new CraftingRecipe {
229 ResultCount = 1,
230 ResultValue =
231 block2.SetDamage(Terrain.MakeBlockValue(203, 0, SetClothingIndex(SetClothingColor(0, num4), clothingIndex)), damage),
232 RemainsCount = 1,
233 RemainsValue =
234 BlocksManager.DamageItem(Terrain.MakeBlockValue(129, 0, color), damage2 + MathUtils.Max(block.Durability / 4, 1)),
235 RequiredHeatLevel = 1f,
236 Description = $"{LanguageControl.Get("BlocksManager", "Dyed")} {SubsystemPalette.GetName(terrain, color, null)}",
237 Ingredients = (string[])ingredients.Clone()
238 };
239 }
240 }
241 if (num2 != 0
242 && num3 != 0) {
243 int data3 = Terrain.ExtractData(num3);
244 int clothingColor2 = GetClothingColor(data3);
245 int clothingIndex2 = GetClothingIndex(data3);
246 bool canBeDyed2 = GetClothingData(data3)?.CanBeDyed ?? false;
247 int damage3 = BlocksManager.Blocks[203].GetDamage(num3);
248 int damage4 = BlocksManager.Blocks[128].GetDamage(num2);
249 Block block3 = BlocksManager.Blocks[128];
250 Block block4 = BlocksManager.Blocks[203];
251 if (!canBeDyed2) {
252 return null;
253 }
254 if (clothingColor2 != 0) {
255 return new CraftingRecipe {
256 ResultCount = 1,
257 ResultValue =
258 block4.SetDamage(Terrain.MakeBlockValue(203, 0, SetClothingIndex(SetClothingColor(0, 0), clothingIndex2)), damage3),
259 RemainsCount = 1,
260 RemainsValue =
261 BlocksManager.DamageItem(Terrain.MakeBlockValue(128, 0, 0), damage4 + MathUtils.Max(block3.Durability / 4, 1)),
262 RequiredHeatLevel = 1f,
263 Description = $"{LanguageControl.Get("BlocksManager", "Not Dyed")} {LanguageControl.Get("BlocksManager", "Clothes")}",
264 Ingredients = (string[])ingredients.Clone()
265 };
266 }
267 }
268 }
269 return null;
270 }
271
272 //分成了1~4、17~18位储存
273 public static int GetClothingIndex(int data) => (data & 0xFF) | ((data >> 8) & 0x300);
274
275 public static int SetClothingIndex(int data, int clothingIndex) {
276 clothingIndex &= 0x3FF;
277 return (data & -196864) | (clothingIndex & 0xFF) | ((clothingIndex & 0x300) << 8);
278 }
279
280 public static int GetClothingColor(int data) => (data >> 12) & 0xF;
281
282 public static int SetClothingColor(int data, int color) => (data & -61441) | ((color & 0xF) << 12);
283
284 public override void GenerateTerrainVertices(BlockGeometryGenerator generator, TerrainGeometry geometry, int value, int x, int y, int z) { }
285
286 public override void DrawBlock(PrimitivesRenderer3D primitivesRenderer,
287 int value,
288 Color color,
289 float size,
290 ref Matrix matrix,
291 DrawBlockEnvironmentData environmentData) {
292 int data = Terrain.ExtractData(value);
293 int clothingColor = GetClothingColor(data);
294 ClothingData clothingData = GetClothingData(value);
295 if (clothingData == null) {
296 return;
297 }
298 clothingData.Texture ??= ContentManager.Get<Texture2D>(clothingData._textureName);
299 Matrix matrix2 = m_slotTransforms[(int)clothingData.Slot] * Matrix.CreateScale(size) * matrix;
300 if (clothingData.IsOuter) {
302 primitivesRenderer,
304 clothingData.Texture,
305 color * SubsystemPalette.GetFabricColor(environmentData, clothingColor),
306 1f,
307 ref matrix2,
308 environmentData
309 );
310 }
311 else {
313 primitivesRenderer,
315 clothingData.Texture,
316 color * SubsystemPalette.GetFabricColor(environmentData, clothingColor),
317 1f,
318 ref matrix2,
319 environmentData
320 );
321 }
322 }
323 }
324}
ReadOnlyList< ModelBone > Bones
ModelBone FindBone(string name, bool throwIfNotFound=true)
void CopyAbsoluteBoneTransformsTo(Matrix[] absoluteTransforms)
ReadOnlyList< ModelMeshPart > MeshParts
static void Error(object message)
定义 Log.cs:80
static int Max(int x1, int x2)
static Type FindType(string typeName, bool skipSystemAssemblies, bool throwIfNotFound)
virtual int SetDamage(int value, int damage)
string CraftingId
virtual int GetDamage(int value)
static int DamageItem(int value, int damageCount, Entity owner=null)
static void DrawMeshBlock(PrimitivesRenderer3D primitivesRenderer, BlockMesh blockMesh, float size, ref Matrix matrix, DrawBlockEnvironmentData environmentData)
static Model GetOuterClothingModel(PlayerClass playerClass)
static Model GetPlayerModel(PlayerClass playerClass)
override ClothingData GetClothingData(int value)
static int SetClothingColor(int data, int color)
override IEnumerable< int > GetCreativeValues()
virtual void LoadClothingData(XElement item)
override int GetDamage(int value)
static int SetClothingIndex(int data, int clothingIndex)
override bool CanWear(int value)
override int GetDisplayOrder(int value)
override string GetDescription(int value)
static Matrix[] m_slotTransforms
override string GetCategory(int value)
override void DrawBlock(PrimitivesRenderer3D primitivesRenderer, int value, Color color, float size, ref Matrix matrix, DrawBlockEnvironmentData environmentData)
override string GetDisplayName(SubsystemTerrain subsystemTerrain, int value)
override void Initialize()
override int SetDamage(int value, int damage)
static int GetClothingIndex(int data)
override void GenerateTerrainVertices(BlockGeometryGenerator generator, TerrainGeometry geometry, int value, int x, int y, int z)
Dictionary< int, ClothingData > m_clothingData
static int GetClothingColor(int data)
override CraftingRecipe GetAdHocCraftingRecipe(SubsystemTerrain terrain, string[] ingredients, float heatLevel, float playerLevel)
static object Get(Type type, string name)
static void DecodeIngredient(string ingredient, out string craftingId, out int? data)
static int GetColor(int data)
static int CombineColors(int color1, int color2)
static int ReplaceData(int value, int data)
static int MakeBlockValue(int contents)
static int ExtractData(int value)
static void ModListAllDo(Action< ModEntity > entity)
static Color White
static Matrix CreateTranslation(float x, float y, float z)
static Matrix CreateRotationY(float radians)
static Matrix CreateScale(float scale)