Terraria v1.4.4.9
Terraria source code documentation
Loading...
Searching...
No Matches
HitTile.cs
Go to the documentation of this file.
1using System;
6
7namespace Terraria;
8
9public class HitTile
10{
11 public class HitTileObject
12 {
13 public int X;
14
15 public int Y;
16
17 public int damage;
18
19 public int type;
20
21 public int timeToLive;
22
23 public int crackStyle;
24
26
28
30 {
31 Clear();
32 }
33
34 public void Clear()
35 {
36 X = 0;
37 Y = 0;
38 damage = 0;
39 type = 0;
40 timeToLive = 0;
41 if (rand == null)
42 {
43 rand = new UnifiedRandom((int)DateTime.Now.Ticks);
44 }
45 for (crackStyle = rand.Next(4); crackStyle == lastCrack; crackStyle = rand.Next(4))
46 {
47 }
49 }
50 }
51
52 internal const int UNUSED = 0;
53
54 internal const int TILE = 1;
55
56 internal const int WALL = 2;
57
58 internal const int MAX_HITTILES = 500;
59
60 internal const int TIMETOLIVE = 60;
61
62 private static UnifiedRandom rand;
63
64 private static int lastCrack = -1;
65
67
68 private int[] order;
69
70 private int bufferLocation;
71
72 public static void ClearAllTilesAtThisLocation(int x, int y)
73 {
74 for (int i = 0; i < 255; i++)
75 {
76 if (Main.player[i].active)
77 {
78 Main.player[i].hitTile.ClearThisTile(x, y);
79 }
80 }
81 }
82
83 public void ClearThisTile(int x, int y)
84 {
85 for (int i = 0; i <= 500; i++)
86 {
87 int num = order[i];
88 HitTileObject hitTileObject = data[num];
89 if (hitTileObject.X == x && hitTileObject.Y == y)
90 {
91 Clear(i);
92 Prune();
93 }
94 }
95 }
96
97 public HitTile()
98 {
99 rand = new UnifiedRandom();
100 data = new HitTileObject[501];
101 order = new int[501];
102 for (int i = 0; i <= 500; i++)
103 {
104 data[i] = new HitTileObject();
105 order[i] = i;
106 }
107 bufferLocation = 0;
108 }
109
110 public int TryFinding(int x, int y, int hitType)
111 {
112 for (int i = 0; i <= 500; i++)
113 {
114 int num = order[i];
115 HitTileObject hitTileObject = data[num];
116 if (hitTileObject.type == hitType)
117 {
118 if (hitTileObject.X == x && hitTileObject.Y == y)
119 {
120 return num;
121 }
122 }
123 else if (i != 0 && hitTileObject.type == 0)
124 {
125 break;
126 }
127 }
128 return -1;
129 }
130
131 public void TryClearingAndPruning(int x, int y, int hitType)
132 {
133 int num = TryFinding(x, y, hitType);
134 if (num != -1)
135 {
136 Clear(num);
137 Prune();
138 }
139 }
140
141 public int HitObject(int x, int y, int hitType)
142 {
143 HitTileObject hitTileObject;
144 for (int i = 0; i <= 500; i++)
145 {
146 int num = order[i];
147 hitTileObject = data[num];
148 if (hitTileObject.type == hitType)
149 {
150 if (hitTileObject.X == x && hitTileObject.Y == y)
151 {
152 return num;
153 }
154 }
155 else if (i != 0 && hitTileObject.type == 0)
156 {
157 break;
158 }
159 }
160 hitTileObject = data[bufferLocation];
161 hitTileObject.X = x;
162 hitTileObject.Y = y;
163 hitTileObject.type = hitType;
164 return bufferLocation;
165 }
166
167 public void UpdatePosition(int tileId, int x, int y)
168 {
169 if (tileId >= 0 && tileId <= 500)
170 {
171 HitTileObject obj = data[tileId];
172 obj.X = x;
173 obj.Y = y;
174 }
175 }
176
177 public int AddDamage(int tileId, int damageAmount, bool updateAmount = true)
178 {
179 if (tileId < 0 || tileId > 500)
180 {
181 return 0;
182 }
183 if (tileId == bufferLocation && damageAmount == 0)
184 {
185 return 0;
186 }
187 HitTileObject hitTileObject = data[tileId];
188 if (!updateAmount)
189 {
190 return hitTileObject.damage + damageAmount;
191 }
192 hitTileObject.damage += damageAmount;
193 hitTileObject.timeToLive = 60;
194 hitTileObject.animationTimeElapsed = 0;
195 hitTileObject.animationDirection = (Main.rand.NextFloat() * ((float)Math.PI * 2f)).ToRotationVector2() * 2f;
196 SortSlots(tileId);
197 return hitTileObject.damage;
198 }
199
200 private void SortSlots(int tileId)
201 {
202 if (tileId == bufferLocation)
203 {
204 bufferLocation = order[500];
205 if (tileId != bufferLocation)
206 {
208 }
209 for (int num = 500; num > 0; num--)
210 {
211 order[num] = order[num - 1];
212 }
214 }
215 else
216 {
217 int num;
218 for (num = 0; num <= 500 && order[num] != tileId; num++)
219 {
220 }
221 while (num > 1)
222 {
223 int num2 = order[num - 1];
224 order[num - 1] = order[num];
225 order[num] = num2;
226 num--;
227 }
228 order[1] = tileId;
229 }
230 }
231
232 public void Clear(int tileId)
233 {
234 if (tileId >= 0 && tileId <= 500)
235 {
236 data[tileId].Clear();
237 int i;
238 for (i = 0; i < 500 && order[i] != tileId; i++)
239 {
240 }
241 for (; i < 500; i++)
242 {
243 order[i] = order[i + 1];
244 }
245 order[500] = tileId;
246 }
247 }
248
249 public void Prune()
250 {
251 bool flag = false;
252 for (int i = 0; i <= 500; i++)
253 {
254 HitTileObject hitTileObject = data[i];
255 if (hitTileObject.type == 0)
256 {
257 continue;
258 }
259 Tile tile = Main.tile[hitTileObject.X, hitTileObject.Y];
260 if (hitTileObject.timeToLive <= 1)
261 {
262 hitTileObject.Clear();
263 flag = true;
264 continue;
265 }
266 hitTileObject.timeToLive--;
267 if ((double)hitTileObject.timeToLive < 12.0)
268 {
269 hitTileObject.damage -= 10;
270 }
271 else if ((double)hitTileObject.timeToLive < 24.0)
272 {
273 hitTileObject.damage -= 7;
274 }
275 else if ((double)hitTileObject.timeToLive < 36.0)
276 {
277 hitTileObject.damage -= 5;
278 }
279 else if ((double)hitTileObject.timeToLive < 48.0)
280 {
281 hitTileObject.damage -= 2;
282 }
283 if (hitTileObject.damage < 0)
284 {
285 hitTileObject.Clear();
286 flag = true;
287 }
288 else if (hitTileObject.type == 1)
289 {
290 if (!tile.active())
291 {
292 hitTileObject.Clear();
293 flag = true;
294 }
295 }
296 else if (tile.wall == 0)
297 {
298 hitTileObject.Clear();
299 flag = true;
300 }
301 }
302 if (!flag)
303 {
304 return;
305 }
306 int num = 1;
307 while (flag)
308 {
309 flag = false;
310 for (int j = num; j < 500; j++)
311 {
312 if (data[order[j]].type == 0 && data[order[j + 1]].type != 0)
313 {
314 int num2 = order[j];
315 order[j] = order[j + 1];
316 order[j + 1] = num2;
317 flag = true;
318 }
319 }
320 }
321 }
322
323 public void DrawFreshAnimations(SpriteBatch spriteBatch)
324 {
325 for (int i = 0; i < data.Length; i++)
326 {
328 }
330 {
331 return;
332 }
333 int num = 1;
334 Vector2 vector = new Vector2(Main.offScreenRange);
335 if (Main.drawToScreen)
336 {
337 vector = Vector2.Zero;
338 }
339 vector = Vector2.Zero;
340 bool flag = Main.ShouldShowInvisibleWalls();
341 for (int j = 0; j < data.Length; j++)
342 {
343 if (data[j].type != num)
344 {
345 continue;
346 }
347 int damage = data[j].damage;
348 if (damage < 20)
349 {
350 continue;
351 }
352 int x = data[j].X;
353 int y = data[j].Y;
354 if (!WorldGen.InWorld(x, y))
355 {
356 continue;
357 }
358 Tile tile = Main.tile[x, y];
359 bool flag2 = tile != null;
360 if (flag2 && num == 1)
361 {
362 flag2 = flag2 && tile.active() && Main.tileSolid[Main.tile[x, y].type] && (!tile.invisibleBlock() || flag);
363 }
364 if (flag2 && num == 2)
365 {
366 flag2 = flag2 && tile.wall != 0 && (!tile.invisibleWall() || flag);
367 }
368 if (!flag2)
369 {
370 continue;
371 }
372 bool flag3 = false;
373 bool flag4 = false;
374 if (tile.type == 10)
375 {
376 flag3 = false;
377 }
378 else if (Main.tileSolid[tile.type] && !Main.tileSolidTop[tile.type])
379 {
380 flag3 = true;
381 }
382 else if (WorldGen.IsTreeType(tile.type))
383 {
384 flag4 = true;
385 int num2 = tile.frameX / 22;
386 int num3 = tile.frameY / 22;
387 if (num3 < 9)
388 {
389 flag3 = ((num2 != 1 && num2 != 2) || num3 < 6 || num3 > 8) && (num2 != 3 || num3 > 2) && (num2 != 4 || num3 < 3 || num3 > 5) && ((num2 != 5 || num3 < 6 || num3 > 8) ? true : false);
390 }
391 }
392 else if (tile.type == 72)
393 {
394 flag4 = true;
395 if (tile.frameX <= 34)
396 {
397 flag3 = true;
398 }
399 }
400 if (!flag3 || tile.slope() != 0 || tile.halfBrick())
401 {
402 continue;
403 }
404 int num4 = 0;
405 if (damage >= 80)
406 {
407 num4 = 3;
408 }
409 else if (damage >= 60)
410 {
411 num4 = 2;
412 }
413 else if (damage >= 40)
414 {
415 num4 = 1;
416 }
417 else if (damage >= 20)
418 {
419 num4 = 0;
420 }
421 Rectangle value = new Rectangle(data[j].crackStyle * 18, num4 * 18, 16, 16);
422 value.Inflate(-2, -2);
423 if (flag4)
424 {
425 value.X = (4 + data[j].crackStyle / 2) * 18;
426 }
427 int animationTimeElapsed = data[j].animationTimeElapsed;
428 if (!((float)animationTimeElapsed >= 10f))
429 {
430 float num5 = (float)animationTimeElapsed / 10f;
431 Color color = Lighting.GetColor(x, y);
432 float rotation = 0f;
433 Vector2 zero = Vector2.Zero;
434 float num6 = 0.5f;
435 float num7 = num5 % num6;
436 num7 *= 1f / num6;
437 if ((int)(num5 / num6) % 2 == 1)
438 {
439 num7 = 1f - num7;
440 }
441 Tile tileSafely = Framing.GetTileSafely(x, y);
442 Tile tile2 = tileSafely;
443 Texture2D texture2D = Main.instance.TilePaintSystem.TryGetTileAndRequestIfNotReady(tileSafely.type, 0, tileSafely.color());
444 if (texture2D != null)
445 {
446 Vector2 vector2 = new Vector2(8f);
447 Vector2 vector3 = new Vector2(1f);
448 float num8 = num7 * 0.2f + 1f;
449 float num9 = 1f - num7;
450 num9 = 1f;
451 color *= num9 * num9 * 0.8f;
452 Vector2 scale = num8 * vector3;
453 Vector2 position = (new Vector2(x * 16 - (int)Main.screenPosition.X, y * 16 - (int)Main.screenPosition.Y) + vector + vector2 + zero).Floor();
454 spriteBatch.Draw(texture2D, position, new Rectangle(tile2.frameX, tile2.frameY, 16, 16), color, rotation, vector2, scale, SpriteEffects.None, 0f);
455 color.A = 180;
456 spriteBatch.Draw(TextureAssets.TileCrack.Value, position, value, color, rotation, vector2, scale, SpriteEffects.None, 0f);
457 }
458 }
459 }
460 }
461}
void Draw(Texture2D texture, Vector2 position, Color color)
const double PI
Definition Math.cs:16
static Tile GetTileSafely(Vector2 position)
Definition Framing.cs:419
static Asset< Texture2D > TileCrack
const int TILE
Definition HitTile.cs:54
static void ClearAllTilesAtThisLocation(int x, int y)
Definition HitTile.cs:72
const int MAX_HITTILES
Definition HitTile.cs:58
static int lastCrack
Definition HitTile.cs:64
void DrawFreshAnimations(SpriteBatch spriteBatch)
Definition HitTile.cs:323
void Clear(int tileId)
Definition HitTile.cs:232
void TryClearingAndPruning(int x, int y, int hitType)
Definition HitTile.cs:131
int TryFinding(int x, int y, int hitType)
Definition HitTile.cs:110
void SortSlots(int tileId)
Definition HitTile.cs:200
static UnifiedRandom rand
Definition HitTile.cs:62
int AddDamage(int tileId, int damageAmount, bool updateAmount=true)
Definition HitTile.cs:177
const int WALL
Definition HitTile.cs:56
const int UNUSED
Definition HitTile.cs:52
int HitObject(int x, int y, int hitType)
Definition HitTile.cs:141
const int TIMETOLIVE
Definition HitTile.cs:60
void UpdatePosition(int tileId, int x, int y)
Definition HitTile.cs:167
void ClearThisTile(int x, int y)
Definition HitTile.cs:83
HitTileObject[] data
Definition HitTile.cs:66
static Color GetColor(Point tileCoords)
Definition Lighting.cs:182
static bool[] tileSolidTop
Definition Main.cs:1469
static bool ShouldShowInvisibleWalls()
Definition Main.cs:54895
static bool drawToScreen
Definition Main.cs:600
static bool SettingsEnabled_MinersWobble
Definition Main.cs:245
static Main instance
Definition Main.cs:283
static Vector2 screenPosition
Definition Main.cs:1715
static int offScreenRange
Definition Main.cs:836
static bool[] tileSolid
Definition Main.cs:1471
static Tile[,] tile
Definition Main.cs:1675
static UnifiedRandom rand
Definition Main.cs:1387
static Player[] player
Definition Main.cs:1803
byte color()
Definition Tile.cs:555
bool invisibleWall()
Definition Tile.cs:521
short frameY
Definition Tile.cs:24
ushort type
Definition Tile.cs:8
short frameX
Definition Tile.cs:22
bool invisibleBlock()
Definition Tile.cs:504
bool active()
Definition Tile.cs:565
byte slope()
Definition Tile.cs:684
ushort wall
Definition Tile.cs:10
bool halfBrick()
Definition Tile.cs:650
static bool IsTreeType(int tree)
static bool InWorld(int x, int y, int fluff=0)
Definition WorldGen.cs:5816
static DateTime Now
Definition DateTime.cs:103