Terraria v1.4.4.9
Terraria source code documentation
Loading...
Searching...
No Matches
Collision.cs
Go to the documentation of this file.
1using System;
5using Terraria.ID;
6
7namespace Terraria;
8
9public class Collision
10{
11 public struct HurtTile
12 {
13 public int type;
14
15 public int x;
16
17 public int y;
18 }
19
20 public static bool stair;
21
22 public static bool stairFall;
23
24 public static bool honey;
25
26 public static bool shimmer;
27
28 public static bool sloping;
29
30 public static bool landMine = false;
31
32 public static bool up;
33
34 public static bool down;
35
36 public static float Epsilon = (float)Math.E;
37
39
41 {
42 if (a1.Equals(a2) && b1.Equals(b2))
43 {
44 if (a1.Equals(b1))
45 {
46 return new Vector2[1] { a1 };
47 }
48 return new Vector2[0];
49 }
50 if (b1.Equals(b2))
51 {
52 if (PointOnLine(b1, a1, a2))
53 {
54 return new Vector2[1] { b1 };
55 }
56 return new Vector2[0];
57 }
58 if (a1.Equals(a2))
59 {
60 if (PointOnLine(a1, b1, b2))
61 {
62 return new Vector2[1] { a1 };
63 }
64 return new Vector2[0];
65 }
66 float num = (b2.X - b1.X) * (a1.Y - b1.Y) - (b2.Y - b1.Y) * (a1.X - b1.X);
67 float num2 = (a2.X - a1.X) * (a1.Y - b1.Y) - (a2.Y - a1.Y) * (a1.X - b1.X);
68 float num3 = (b2.Y - b1.Y) * (a2.X - a1.X) - (b2.X - b1.X) * (a2.Y - a1.Y);
69 if (!(0f - Epsilon < num3) || !(num3 < Epsilon))
70 {
71 float num4 = num / num3;
72 float num5 = num2 / num3;
73 if (0f <= num4 && num4 <= 1f && 0f <= num5 && num5 <= 1f)
74 {
75 return new Vector2[1]
76 {
77 new Vector2(a1.X + num4 * (a2.X - a1.X), a1.Y + num4 * (a2.Y - a1.Y))
78 };
79 }
80 return new Vector2[0];
81 }
82 if ((0f - Epsilon < num && num < Epsilon) || (0f - Epsilon < num2 && num2 < Epsilon))
83 {
84 if (a1.Equals(a2))
85 {
87 }
89 }
90 return new Vector2[0];
91 }
92
93 private static double DistFromSeg(Vector2 p, Vector2 q0, Vector2 q1, double radius, ref float u)
94 {
95 double num = q1.X - q0.X;
96 double num2 = q1.Y - q0.Y;
97 double num3 = q0.X - p.X;
98 double num4 = q0.Y - p.Y;
99 double num5 = Math.Sqrt(num * num + num2 * num2);
100 if (num5 < (double)Epsilon)
101 {
102 throw new Exception("Expected line segment, not point.");
103 }
104 return Math.Abs(num * num4 - num3 * num2) / num5;
105 }
106
107 private static bool PointOnLine(Vector2 p, Vector2 a1, Vector2 a2)
108 {
109 float u = 0f;
110 return DistFromSeg(p, a1, a2, Epsilon, ref u) < (double)Epsilon;
111 }
112
114 {
115 float num = a2.X - a1.X;
116 float num2 = a2.Y - a1.Y;
117 float relativePoint;
118 float relativePoint2;
119 if (Math.Abs(num) > Math.Abs(num2))
120 {
121 relativePoint = (b1.X - a1.X) / num;
122 relativePoint2 = (b2.X - a1.X) / num;
123 }
124 else
125 {
126 relativePoint = (b1.Y - a1.Y) / num2;
127 relativePoint2 = (b2.Y - a1.Y) / num2;
128 }
131 foreach (float num3 in array)
132 {
133 float x = a2.X * num3 + a1.X * (1f - num3);
134 float y = a2.Y * num3 + a1.Y * (1f - num3);
135 list.Add(new Vector2(x, y));
136 }
137 return list.ToArray();
138 }
139
140 private static float[] FindOverlapPoints(float relativePoint1, float relativePoint2)
141 {
144 float num = Math.Max(0f, val);
145 float num2 = Math.Min(1f, val2);
146 if (num > num2)
147 {
148 return new float[0];
149 }
150 if (num != num2)
151 {
152 return new float[2] { num, num2 };
153 }
154 return new float[1] { num };
155 }
156
158 {
160 {
161 return position1.Y + dimensions1.Y > position2.Y;
162 }
163 return false;
164 }
165
167 {
168 float num = aabbPosition.X + aabbDimensions.X;
169 float num2 = aabbPosition.Y + aabbDimensions.Y;
170 int num3 = 0;
171 if (aabbDimensions.X <= 0f)
172 {
173 num3 |= 5;
174 }
175 else if (point.X < aabbPosition.X)
176 {
177 num3 |= 1;
178 }
179 else if (point.X - num > 0f)
180 {
181 num3 |= 4;
182 }
183 if (aabbDimensions.Y <= 0f)
184 {
185 num3 |= 0xA;
186 }
187 else if (point.Y < aabbPosition.Y)
188 {
189 num3 |= 2;
190 }
191 else if (point.Y - num2 > 0f)
192 {
193 num3 |= 8;
194 }
195 return num3;
196 }
197
199 {
200 int num;
202 {
203 return true;
204 }
205 int num2;
207 {
208 if ((num2 & num) != 0)
209 {
210 return false;
211 }
212 if (((uint)num2 & 5u) != 0)
213 {
214 float num3 = aabbPosition.X;
215 if (((uint)num2 & 4u) != 0)
216 {
217 num3 += aabbDimensions.X;
218 }
219 lineStart.Y += (num3 - lineStart.X) * (lineEnd.Y - lineStart.Y) / (lineEnd.X - lineStart.X);
220 lineStart.X = num3;
221 }
222 else
223 {
224 float num4 = aabbPosition.Y;
225 if (((uint)num2 & 8u) != 0)
226 {
227 num4 += aabbDimensions.Y;
228 }
229 lineStart.X += (num4 - lineStart.Y) * (lineEnd.X - lineStart.X) / (lineEnd.Y - lineStart.Y);
230 lineStart.Y = num4;
231 }
232 }
233 return true;
234 }
235
245
247 {
248 float num = lineWidth * 0.5f;
249 Vector2 position = lineStart;
250 Vector2 dimensions = lineEnd - lineStart;
251 if (dimensions.X > 0f)
252 {
253 dimensions.X += lineWidth;
254 position.X -= num;
255 }
256 else
257 {
258 position.X += dimensions.X - num;
259 dimensions.X = 0f - dimensions.X + lineWidth;
260 }
261 if (dimensions.Y > 0f)
262 {
263 dimensions.Y += lineWidth;
264 position.Y -= num;
265 }
266 else
267 {
268 position.Y += dimensions.Y - num;
269 dimensions.Y = 0f - dimensions.Y + lineWidth;
270 }
271 if (!CheckAABBvAABBCollision(objectPosition, objectDimensions, position, dimensions))
272 {
273 return false;
274 }
280 float num2 = vector2.Length();
281 float num3 = (float)Math.Atan2(vector2.Y, vector2.X);
282 Vector2[] array = new Vector2[4]
283 {
284 vector.RotatedBy(0f - num3),
285 spinningpoint3.RotatedBy(0f - num3),
286 spinningpoint.RotatedBy(0f - num3),
287 spinningpoint2.RotatedBy(0f - num3)
288 };
290 bool result = false;
291 for (int i = 0; i < array.Length; i++)
292 {
293 if (Math.Abs(array[i].Y) < num && array[i].X < collisionPoint && array[i].X >= 0f)
294 {
295 collisionPoint = array[i].X;
296 result = true;
297 }
298 }
299 Vector2 vector3 = new Vector2(0f, num);
300 Vector2 vector4 = new Vector2(num2, num);
301 Vector2 vector5 = new Vector2(0f, 0f - num);
302 Vector2 vector6 = new Vector2(num2, 0f - num);
303 for (int j = 0; j < array.Length; j++)
304 {
305 int num4 = (j + 1) % array.Length;
308 float num5 = vector7.X * vector8.Y - vector7.Y * vector8.X;
309 if (num5 != 0f)
310 {
312 float num6 = (vector9.X * vector8.Y - vector9.Y * vector8.X) / num5;
313 if (num6 >= 0f && num6 <= 1f)
314 {
315 float num7 = (vector9.X * vector7.Y - vector9.Y * vector7.X) / num5;
316 if (num7 >= 0f && num7 <= 1f)
317 {
318 result = true;
320 }
321 }
322 }
324 num5 = vector7.X * vector8.Y - vector7.Y * vector8.X;
325 if (num5 == 0f)
326 {
327 continue;
328 }
330 float num8 = (vector10.X * vector8.Y - vector10.Y * vector8.X) / num5;
331 if (num8 >= 0f && num8 <= 1f)
332 {
333 float num9 = (vector10.X * vector7.Y - vector10.Y * vector7.X) / num5;
334 if (num9 >= 0f && num9 <= 1f)
335 {
336 result = true;
338 }
339 }
340 }
341 return result;
342 }
343
344 public static bool CanHit(Entity source, Entity target)
345 {
346 return CanHit(source.position, source.width, source.height, target.position, target.width, target.height);
347 }
348
349 public static bool CanHit(Entity source, NPCAimedTarget target)
350 {
351 return CanHit(source.position, source.width, source.height, target.Position, target.Width, target.Height);
352 }
353
354 public static bool CanHit(Vector2 Position1, int Width1, int Height1, Vector2 Position2, int Width2, int Height2)
355 {
356 return CanHit(Position1.ToPoint(), Width1, Height1, Position2.ToPoint(), Width2, Height2);
357 }
358
359 public static bool CanHit(Point Position1, int Width1, int Height1, Point Position2, int Width2, int Height2)
360 {
361 int num = (Position1.X + Width1 / 2) / 16;
362 int num2 = (Position1.Y + Height1 / 2) / 16;
363 int num3 = (Position2.X + Width2 / 2) / 16;
364 int num4 = (Position2.Y + Height2 / 2) / 16;
365 if (num <= 1)
366 {
367 num = 1;
368 }
369 if (num >= Main.maxTilesX)
370 {
371 num = Main.maxTilesX - 1;
372 }
373 if (num3 <= 1)
374 {
375 num3 = 1;
376 }
377 if (num3 >= Main.maxTilesX)
378 {
379 num3 = Main.maxTilesX - 1;
380 }
381 if (num2 <= 1)
382 {
383 num2 = 1;
384 }
385 if (num2 >= Main.maxTilesY)
386 {
387 num2 = Main.maxTilesY - 1;
388 }
389 if (num4 <= 1)
390 {
391 num4 = 1;
392 }
393 if (num4 >= Main.maxTilesY)
394 {
395 num4 = Main.maxTilesY - 1;
396 }
397 try
398 {
399 do
400 {
401 int num5 = Math.Abs(num - num3);
402 int num6 = Math.Abs(num2 - num4);
403 if (num == num3 && num2 == num4)
404 {
405 return true;
406 }
407 if (num5 > num6)
408 {
409 num = ((num >= num3) ? (num - 1) : (num + 1));
410 if (Main.tile[num, num2 - 1] == null)
411 {
412 return false;
413 }
414 if (Main.tile[num, num2 + 1] == null)
415 {
416 return false;
417 }
418 if (!Main.tile[num, num2 - 1].inActive() && Main.tile[num, num2 - 1].active() && Main.tileSolid[Main.tile[num, num2 - 1].type] && !Main.tileSolidTop[Main.tile[num, num2 - 1].type] && Main.tile[num, num2 - 1].slope() == 0 && !Main.tile[num, num2 - 1].halfBrick() && !Main.tile[num, num2 + 1].inActive() && Main.tile[num, num2 + 1].active() && Main.tileSolid[Main.tile[num, num2 + 1].type] && !Main.tileSolidTop[Main.tile[num, num2 + 1].type] && Main.tile[num, num2 + 1].slope() == 0 && !Main.tile[num, num2 + 1].halfBrick())
419 {
420 return false;
421 }
422 }
423 else
424 {
425 num2 = ((num2 >= num4) ? (num2 - 1) : (num2 + 1));
426 if (Main.tile[num - 1, num2] == null)
427 {
428 return false;
429 }
430 if (Main.tile[num + 1, num2] == null)
431 {
432 return false;
433 }
434 if (!Main.tile[num - 1, num2].inActive() && Main.tile[num - 1, num2].active() && Main.tileSolid[Main.tile[num - 1, num2].type] && !Main.tileSolidTop[Main.tile[num - 1, num2].type] && Main.tile[num - 1, num2].slope() == 0 && !Main.tile[num - 1, num2].halfBrick() && !Main.tile[num + 1, num2].inActive() && Main.tile[num + 1, num2].active() && Main.tileSolid[Main.tile[num + 1, num2].type] && !Main.tileSolidTop[Main.tile[num + 1, num2].type] && Main.tile[num + 1, num2].slope() == 0 && !Main.tile[num + 1, num2].halfBrick())
435 {
436 return false;
437 }
438 }
439 if (Main.tile[num, num2] == null)
440 {
441 return false;
442 }
443 }
444 while (Main.tile[num, num2].inActive() || !Main.tile[num, num2].active() || !Main.tileSolid[Main.tile[num, num2].type] || Main.tileSolidTop[Main.tile[num, num2].type]);
445 return false;
446 }
447 catch
448 {
449 return false;
450 }
451 }
452
454 {
455 int num = (int)((Position1.X + (float)(Width1 / 2)) / 16f);
456 int num2 = (int)((Position1.Y + (float)(Height1 / 2)) / 16f);
457 int num3 = (int)((Position2.X + (float)(Width2 / 2)) / 16f);
458 int num4 = (int)((Position2.Y + (float)(Height2 / 2)) / 16f);
459 if (num <= 1)
460 {
461 num = 1;
462 }
463 if (num >= Main.maxTilesX)
464 {
465 num = Main.maxTilesX - 1;
466 }
467 if (num3 <= 1)
468 {
469 num3 = 1;
470 }
471 if (num3 >= Main.maxTilesX)
472 {
473 num3 = Main.maxTilesX - 1;
474 }
475 if (num2 <= 1)
476 {
477 num2 = 1;
478 }
479 if (num2 >= Main.maxTilesY)
480 {
481 num2 = Main.maxTilesY - 1;
482 }
483 if (num4 <= 1)
484 {
485 num4 = 1;
486 }
487 if (num4 >= Main.maxTilesY)
488 {
489 num4 = Main.maxTilesY - 1;
490 }
491 try
492 {
493 do
494 {
495 int num5 = Math.Abs(num - num3);
496 int num6 = Math.Abs(num2 - num4);
497 if (num == num3 && num2 == num4)
498 {
499 return true;
500 }
501 if (num5 > num6)
502 {
503 num = ((num >= num3) ? (num - 1) : (num + 1));
504 if (Main.tile[num, num2 - 1] == null)
505 {
506 return false;
507 }
508 if (Main.tile[num, num2 + 1] == null)
509 {
510 return false;
511 }
512 if (!Main.tile[num, num2 - 1].inActive() && Main.tile[num, num2 - 1].active() && Main.tileSolid[Main.tile[num, num2 - 1].type] && !Main.tileSolidTop[Main.tile[num, num2 - 1].type] && Main.tile[num, num2 - 1].slope() == 0 && !Main.tile[num, num2 - 1].halfBrick() && !Main.tile[num, num2 + 1].inActive() && Main.tile[num, num2 + 1].active() && Main.tileSolid[Main.tile[num, num2 + 1].type] && !Main.tileSolidTop[Main.tile[num, num2 + 1].type] && Main.tile[num, num2 + 1].slope() == 0 && !Main.tile[num, num2 + 1].halfBrick())
513 {
514 return false;
515 }
516 }
517 else
518 {
519 num2 = ((num2 >= num4) ? (num2 - 1) : (num2 + 1));
520 if (Main.tile[num - 1, num2] == null)
521 {
522 return false;
523 }
524 if (Main.tile[num + 1, num2] == null)
525 {
526 return false;
527 }
528 if (!Main.tile[num - 1, num2].inActive() && Main.tile[num - 1, num2].active() && Main.tileSolid[Main.tile[num - 1, num2].type] && !Main.tileSolidTop[Main.tile[num - 1, num2].type] && Main.tile[num - 1, num2].slope() == 0 && !Main.tile[num - 1, num2].halfBrick() && !Main.tile[num + 1, num2].inActive() && Main.tile[num + 1, num2].active() && Main.tileSolid[Main.tile[num + 1, num2].type] && !Main.tileSolidTop[Main.tile[num + 1, num2].type] && Main.tile[num + 1, num2].slope() == 0 && !Main.tile[num + 1, num2].halfBrick())
529 {
530 return false;
531 }
532 }
533 if (Main.tile[num, num2] == null)
534 {
535 return false;
536 }
537 if (!Main.tile[num, num2].inActive() && Main.tile[num, num2].active() && Main.tileSolid[Main.tile[num, num2].type] && !Main.tileSolidTop[Main.tile[num, num2].type])
538 {
539 return false;
540 }
541 }
542 while (check(num, num2));
543 return false;
544 }
545 catch
546 {
547 return false;
548 }
549 }
550
551 public static bool CanHitLine(Vector2 Position1, int Width1, int Height1, Vector2 Position2, int Width2, int Height2)
552 {
553 int num = (int)((Position1.X + (float)(Width1 / 2)) / 16f);
554 int num2 = (int)((Position1.Y + (float)(Height1 / 2)) / 16f);
555 int num3 = (int)((Position2.X + (float)(Width2 / 2)) / 16f);
556 int num4 = (int)((Position2.Y + (float)(Height2 / 2)) / 16f);
557 if (num <= 1)
558 {
559 num = 1;
560 }
561 if (num >= Main.maxTilesX)
562 {
563 num = Main.maxTilesX - 1;
564 }
565 if (num3 <= 1)
566 {
567 num3 = 1;
568 }
569 if (num3 >= Main.maxTilesX)
570 {
571 num3 = Main.maxTilesX - 1;
572 }
573 if (num2 <= 1)
574 {
575 num2 = 1;
576 }
577 if (num2 >= Main.maxTilesY)
578 {
579 num2 = Main.maxTilesY - 1;
580 }
581 if (num4 <= 1)
582 {
583 num4 = 1;
584 }
585 if (num4 >= Main.maxTilesY)
586 {
587 num4 = Main.maxTilesY - 1;
588 }
589 float num5 = Math.Abs(num - num3);
590 float num6 = Math.Abs(num2 - num4);
591 if (num5 == 0f && num6 == 0f)
592 {
593 return true;
594 }
595 float num7 = 1f;
596 float num8 = 1f;
597 if (num5 == 0f || num6 == 0f)
598 {
599 if (num5 == 0f)
600 {
601 num7 = 0f;
602 }
603 if (num6 == 0f)
604 {
605 num8 = 0f;
606 }
607 }
608 else if (num5 > num6)
609 {
610 num7 = num5 / num6;
611 }
612 else
613 {
614 num8 = num6 / num5;
615 }
616 float num9 = 0f;
617 float num10 = 0f;
618 int num11 = 1;
619 if (num2 < num4)
620 {
621 num11 = 2;
622 }
623 int num12 = (int)num5;
624 int num13 = (int)num6;
625 int num14 = Math.Sign(num3 - num);
626 int num15 = Math.Sign(num4 - num2);
627 bool flag = false;
628 bool flag2 = false;
629 try
630 {
631 do
632 {
633 switch (num11)
634 {
635 case 2:
636 {
637 num9 += num7;
638 int num17 = (int)num9;
639 num9 %= 1f;
640 for (int j = 0; j < num17; j++)
641 {
642 if (Main.tile[num, num2 - 1] == null)
643 {
644 return false;
645 }
646 if (Main.tile[num, num2] == null)
647 {
648 return false;
649 }
650 if (Main.tile[num, num2 + 1] == null)
651 {
652 return false;
653 }
654 Tile tile4 = Main.tile[num, num2 - 1];
655 Tile tile5 = Main.tile[num, num2 + 1];
656 Tile tile6 = Main.tile[num, num2];
657 if ((!tile4.inActive() && tile4.active() && Main.tileSolid[tile4.type] && !Main.tileSolidTop[tile4.type]) || (!tile5.inActive() && tile5.active() && Main.tileSolid[tile5.type] && !Main.tileSolidTop[tile5.type]) || (!tile6.inActive() && tile6.active() && Main.tileSolid[tile6.type] && !Main.tileSolidTop[tile6.type]))
658 {
659 return false;
660 }
661 if (num12 == 0 && num13 == 0)
662 {
663 flag = true;
664 break;
665 }
666 num += num14;
667 num12--;
668 if (num12 == 0 && num13 == 0 && num17 == 1)
669 {
670 flag2 = true;
671 }
672 }
673 if (num13 != 0)
674 {
675 num11 = 1;
676 }
677 break;
678 }
679 case 1:
680 {
681 num10 += num8;
682 int num16 = (int)num10;
683 num10 %= 1f;
684 for (int i = 0; i < num16; i++)
685 {
686 if (Main.tile[num - 1, num2] == null)
687 {
688 return false;
689 }
690 if (Main.tile[num, num2] == null)
691 {
692 return false;
693 }
694 if (Main.tile[num + 1, num2] == null)
695 {
696 return false;
697 }
698 Tile tile = Main.tile[num - 1, num2];
699 Tile tile2 = Main.tile[num + 1, num2];
700 Tile tile3 = Main.tile[num, num2];
701 if ((!tile.inActive() && tile.active() && Main.tileSolid[tile.type] && !Main.tileSolidTop[tile.type]) || (!tile2.inActive() && tile2.active() && Main.tileSolid[tile2.type] && !Main.tileSolidTop[tile2.type]) || (!tile3.inActive() && tile3.active() && Main.tileSolid[tile3.type] && !Main.tileSolidTop[tile3.type]))
702 {
703 return false;
704 }
705 if (num12 == 0 && num13 == 0)
706 {
707 flag = true;
708 break;
709 }
710 num2 += num15;
711 num13--;
712 if (num12 == 0 && num13 == 0 && num16 == 1)
713 {
714 flag2 = true;
715 }
716 }
717 if (num12 != 0)
718 {
719 num11 = 2;
720 }
721 break;
722 }
723 }
724 if (Main.tile[num, num2] == null)
725 {
726 return false;
727 }
728 Tile tile7 = Main.tile[num, num2];
729 if (!tile7.inActive() && tile7.active() && Main.tileSolid[tile7.type] && !Main.tileSolidTop[tile7.type])
730 {
731 return false;
732 }
733 }
734 while (!(flag || flag2));
735 return true;
736 }
737 catch
738 {
739 return false;
740 }
741 }
742
743 public static bool TupleHitLine(int x1, int y1, int x2, int y2, int ignoreX, int ignoreY, List<Tuple<int, int>> ignoreTargets, out Tuple<int, int> col)
744 {
745 int value = x1;
746 int value2 = y1;
747 int value3 = x2;
748 int value4 = y2;
749 value = Utils.Clamp(value, 1, Main.maxTilesX - 1);
750 value3 = Utils.Clamp(value3, 1, Main.maxTilesX - 1);
751 value2 = Utils.Clamp(value2, 1, Main.maxTilesY - 1);
752 value4 = Utils.Clamp(value4, 1, Main.maxTilesY - 1);
753 float num = Math.Abs(value - value3);
754 float num2 = Math.Abs(value2 - value4);
755 if (num == 0f && num2 == 0f)
756 {
758 return true;
759 }
760 float num3 = 1f;
761 float num4 = 1f;
762 if (num == 0f || num2 == 0f)
763 {
764 if (num == 0f)
765 {
766 num3 = 0f;
767 }
768 if (num2 == 0f)
769 {
770 num4 = 0f;
771 }
772 }
773 else if (num > num2)
774 {
775 num3 = num / num2;
776 }
777 else
778 {
779 num4 = num2 / num;
780 }
781 float num5 = 0f;
782 float num6 = 0f;
783 int num7 = 1;
784 if (value2 < value4)
785 {
786 num7 = 2;
787 }
788 int num8 = (int)num;
789 int num9 = (int)num2;
790 int num10 = Math.Sign(value3 - value);
791 int num11 = Math.Sign(value4 - value2);
792 bool flag = false;
793 bool flag2 = false;
794 try
795 {
796 do
797 {
798 switch (num7)
799 {
800 case 2:
801 {
802 num5 += num3;
803 int num13 = (int)num5;
804 num5 %= 1f;
805 for (int j = 0; j < num13; j++)
806 {
807 if (Main.tile[value, value2 - 1] == null)
808 {
809 col = new Tuple<int, int>(value, value2 - 1);
810 return false;
811 }
812 if (Main.tile[value, value2 + 1] == null)
813 {
814 col = new Tuple<int, int>(value, value2 + 1);
815 return false;
816 }
817 Tile tile4 = Main.tile[value, value2 - 1];
818 Tile tile5 = Main.tile[value, value2 + 1];
821 {
822 if (ignoreY != -1 && num11 < 0 && !tile4.inActive() && tile4.active() && Main.tileSolid[tile4.type] && !Main.tileSolidTop[tile4.type])
823 {
824 col = new Tuple<int, int>(value, value2 - 1);
825 return true;
826 }
827 if (ignoreY != 1 && num11 > 0 && !tile5.inActive() && tile5.active() && Main.tileSolid[tile5.type] && !Main.tileSolidTop[tile5.type])
828 {
829 col = new Tuple<int, int>(value, value2 + 1);
830 return true;
831 }
832 if (!tile6.inActive() && tile6.active() && Main.tileSolid[tile6.type] && !Main.tileSolidTop[tile6.type])
833 {
835 return true;
836 }
837 }
838 if (num8 == 0 && num9 == 0)
839 {
840 flag = true;
841 break;
842 }
843 value += num10;
844 num8--;
845 if (num8 == 0 && num9 == 0 && num13 == 1)
846 {
847 flag2 = true;
848 }
849 }
850 if (num9 != 0)
851 {
852 num7 = 1;
853 }
854 break;
855 }
856 case 1:
857 {
858 num6 += num4;
859 int num12 = (int)num6;
860 num6 %= 1f;
861 for (int i = 0; i < num12; i++)
862 {
863 if (Main.tile[value - 1, value2] == null)
864 {
865 col = new Tuple<int, int>(value - 1, value2);
866 return false;
867 }
868 if (Main.tile[value + 1, value2] == null)
869 {
870 col = new Tuple<int, int>(value + 1, value2);
871 return false;
872 }
873 Tile tile = Main.tile[value - 1, value2];
874 Tile tile2 = Main.tile[value + 1, value2];
877 {
878 if (ignoreX != -1 && num10 < 0 && !tile.inActive() && tile.active() && Main.tileSolid[tile.type] && !Main.tileSolidTop[tile.type])
879 {
880 col = new Tuple<int, int>(value - 1, value2);
881 return true;
882 }
883 if (ignoreX != 1 && num10 > 0 && !tile2.inActive() && tile2.active() && Main.tileSolid[tile2.type] && !Main.tileSolidTop[tile2.type])
884 {
885 col = new Tuple<int, int>(value + 1, value2);
886 return true;
887 }
888 if (!tile3.inActive() && tile3.active() && Main.tileSolid[tile3.type] && !Main.tileSolidTop[tile3.type])
889 {
891 return true;
892 }
893 }
894 if (num8 == 0 && num9 == 0)
895 {
896 flag = true;
897 break;
898 }
899 value2 += num11;
900 num9--;
901 if (num8 == 0 && num9 == 0 && num12 == 1)
902 {
903 flag2 = true;
904 }
905 }
906 if (num8 != 0)
907 {
908 num7 = 2;
909 }
910 break;
911 }
912 }
913 if (Main.tile[value, value2] == null)
914 {
916 return false;
917 }
919 if (!ignoreTargets.Contains(new Tuple<int, int>(value, value2)) && !tile7.inActive() && tile7.active() && Main.tileSolid[tile7.type] && !Main.tileSolidTop[tile7.type])
920 {
922 return true;
923 }
924 }
925 while (!(flag || flag2));
927 return true;
928 }
929 catch
930 {
931 col = new Tuple<int, int>(x1, y1);
932 return false;
933 }
934 }
935
936 public static Tuple<int, int> TupleHitLineWall(int x1, int y1, int x2, int y2)
937 {
938 int num = x1;
939 int num2 = y1;
940 int num3 = x2;
941 int num4 = y2;
942 if (num <= 1)
943 {
944 num = 1;
945 }
946 if (num >= Main.maxTilesX)
947 {
948 num = Main.maxTilesX - 1;
949 }
950 if (num3 <= 1)
951 {
952 num3 = 1;
953 }
954 if (num3 >= Main.maxTilesX)
955 {
956 num3 = Main.maxTilesX - 1;
957 }
958 if (num2 <= 1)
959 {
960 num2 = 1;
961 }
962 if (num2 >= Main.maxTilesY)
963 {
964 num2 = Main.maxTilesY - 1;
965 }
966 if (num4 <= 1)
967 {
968 num4 = 1;
969 }
970 if (num4 >= Main.maxTilesY)
971 {
972 num4 = Main.maxTilesY - 1;
973 }
974 float num5 = Math.Abs(num - num3);
975 float num6 = Math.Abs(num2 - num4);
976 if (num5 == 0f && num6 == 0f)
977 {
978 return new Tuple<int, int>(num, num2);
979 }
980 float num7 = 1f;
981 float num8 = 1f;
982 if (num5 == 0f || num6 == 0f)
983 {
984 if (num5 == 0f)
985 {
986 num7 = 0f;
987 }
988 if (num6 == 0f)
989 {
990 num8 = 0f;
991 }
992 }
993 else if (num5 > num6)
994 {
995 num7 = num5 / num6;
996 }
997 else
998 {
999 num8 = num6 / num5;
1000 }
1001 float num9 = 0f;
1002 float num10 = 0f;
1003 int num11 = 1;
1004 if (num2 < num4)
1005 {
1006 num11 = 2;
1007 }
1008 int num12 = (int)num5;
1009 int num13 = (int)num6;
1010 int num14 = Math.Sign(num3 - num);
1011 int num15 = Math.Sign(num4 - num2);
1012 bool flag = false;
1013 bool flag2 = false;
1014 try
1015 {
1016 do
1017 {
1018 switch (num11)
1019 {
1020 case 2:
1021 {
1022 num9 += num7;
1023 int num17 = (int)num9;
1024 num9 %= 1f;
1025 for (int j = 0; j < num17; j++)
1026 {
1027 _ = Main.tile[num, num2];
1028 if (HitWallSubstep(num, num2))
1029 {
1030 return new Tuple<int, int>(num, num2);
1031 }
1032 if (num12 == 0 && num13 == 0)
1033 {
1034 flag = true;
1035 break;
1036 }
1037 num += num14;
1038 num12--;
1039 if (num12 == 0 && num13 == 0 && num17 == 1)
1040 {
1041 flag2 = true;
1042 }
1043 }
1044 if (num13 != 0)
1045 {
1046 num11 = 1;
1047 }
1048 break;
1049 }
1050 case 1:
1051 {
1052 num10 += num8;
1053 int num16 = (int)num10;
1054 num10 %= 1f;
1055 for (int i = 0; i < num16; i++)
1056 {
1057 _ = Main.tile[num, num2];
1058 if (HitWallSubstep(num, num2))
1059 {
1060 return new Tuple<int, int>(num, num2);
1061 }
1062 if (num12 == 0 && num13 == 0)
1063 {
1064 flag = true;
1065 break;
1066 }
1067 num2 += num15;
1068 num13--;
1069 if (num12 == 0 && num13 == 0 && num16 == 1)
1070 {
1071 flag2 = true;
1072 }
1073 }
1074 if (num12 != 0)
1075 {
1076 num11 = 2;
1077 }
1078 break;
1079 }
1080 }
1081 if (Main.tile[num, num2] == null)
1082 {
1083 return new Tuple<int, int>(-1, -1);
1084 }
1085 _ = Main.tile[num, num2];
1086 if (HitWallSubstep(num, num2))
1087 {
1088 return new Tuple<int, int>(num, num2);
1089 }
1090 }
1091 while (!(flag || flag2));
1092 return new Tuple<int, int>(num, num2);
1093 }
1094 catch
1095 {
1096 return new Tuple<int, int>(-1, -1);
1097 }
1098 }
1099
1100 public static bool HitWallSubstep(int x, int y)
1101 {
1102 if (Main.tile[x, y].wall == 0)
1103 {
1104 return false;
1105 }
1106 bool flag = false;
1107 if (Main.wallHouse[Main.tile[x, y].wall])
1108 {
1109 flag = true;
1110 }
1111 if (!flag)
1112 {
1113 for (int i = -1; i < 2; i++)
1114 {
1115 for (int j = -1; j < 2; j++)
1116 {
1117 if ((i != 0 || j != 0) && Main.tile[x + i, y + j].wall == 0)
1118 {
1119 flag = true;
1120 }
1121 }
1122 }
1123 }
1124 if (Main.tile[x, y].active() && flag)
1125 {
1126 bool flag2 = true;
1127 for (int k = -1; k < 2; k++)
1128 {
1129 for (int l = -1; l < 2; l++)
1130 {
1131 if (k != 0 || l != 0)
1132 {
1133 Tile tile = Main.tile[x + k, y + l];
1134 if (!tile.active() || !Main.tileSolid[tile.type] || Main.tileSolidTop[tile.type])
1135 {
1136 flag2 = false;
1137 }
1138 }
1139 }
1140 }
1141 if (flag2)
1142 {
1143 flag = false;
1144 }
1145 }
1146 return flag;
1147 }
1148
1149 public static bool EmptyTile(int i, int j, bool ignoreTiles = false)
1150 {
1151 Rectangle rectangle = new Rectangle(i * 16, j * 16, 16, 16);
1152 if (Main.tile[i, j].active() && !ignoreTiles)
1153 {
1154 return false;
1155 }
1156 for (int k = 0; k < 255; k++)
1157 {
1158 if (Main.player[k].active && !Main.player[k].dead && !Main.player[k].ghost && rectangle.Intersects(new Rectangle((int)Main.player[k].position.X, (int)Main.player[k].position.Y, Main.player[k].width, Main.player[k].height)))
1159 {
1160 return false;
1161 }
1162 }
1163 for (int l = 0; l < 200; l++)
1164 {
1165 if (Main.npc[l].active && rectangle.Intersects(new Rectangle((int)Main.npc[l].position.X, (int)Main.npc[l].position.Y, Main.npc[l].width, Main.npc[l].height)))
1166 {
1167 return false;
1168 }
1169 }
1170 return true;
1171 }
1172
1173 public static bool DrownCollision(Vector2 Position, int Width, int Height, float gravDir = -1f, bool includeSlopes = false)
1174 {
1175 Vector2 vector = new Vector2(Position.X + (float)(Width / 2), Position.Y + (float)(Height / 2));
1176 int num = 10;
1177 int num2 = 12;
1178 if (num > Width)
1179 {
1180 num = Width;
1181 }
1182 if (num2 > Height)
1183 {
1184 num2 = Height;
1185 }
1186 vector = new Vector2(vector.X - (float)(num / 2), Position.Y + -2f);
1187 if (gravDir == -1f)
1188 {
1189 vector.Y += Height / 2 - 6;
1190 }
1191 int value = (int)(Position.X / 16f) - 1;
1192 int value2 = (int)((Position.X + (float)Width) / 16f) + 2;
1193 int value3 = (int)(Position.Y / 16f) - 1;
1194 int value4 = (int)((Position.Y + (float)Height) / 16f) + 2;
1195 int num3 = Utils.Clamp(value, 0, Main.maxTilesX - 1);
1196 value2 = Utils.Clamp(value2, 0, Main.maxTilesX - 1);
1197 value3 = Utils.Clamp(value3, 0, Main.maxTilesY - 1);
1198 value4 = Utils.Clamp(value4, 0, Main.maxTilesY - 1);
1199 int num4 = ((gravDir == 1f) ? value3 : (value4 - 1));
1200 Vector2 vector2 = default(Vector2);
1201 for (int i = num3; i < value2; i++)
1202 {
1203 for (int j = value3; j < value4; j++)
1204 {
1205 Tile tile = Main.tile[i, j];
1206 if (tile != null && tile.liquid > 0 && !tile.lava() && !tile.shimmer() && (j != num4 || !tile.active() || !Main.tileSolid[tile.type] || Main.tileSolidTop[tile.type] || (includeSlopes && tile.blockType() != 0)))
1207 {
1208 vector2.X = i * 16;
1209 vector2.Y = j * 16;
1210 int num5 = 16;
1211 float num6 = 256 - Main.tile[i, j].liquid;
1212 num6 /= 32f;
1213 vector2.Y += num6 * 2f;
1214 num5 -= (int)(num6 * 2f);
1215 if (vector.X + (float)num > vector2.X && vector.X < vector2.X + 16f && vector.Y + (float)num2 > vector2.Y && vector.Y < vector2.Y + (float)num5)
1216 {
1217 return true;
1218 }
1219 }
1220 }
1221 }
1222 return false;
1223 }
1224
1225 public static bool IsWorldPointSolid(Vector2 pos, bool treatPlatformsAsNonSolid = false)
1226 {
1227 Point point = pos.ToTileCoordinates();
1228 if (!WorldGen.InWorld(point.X, point.Y, 1))
1229 {
1230 return false;
1231 }
1232 Tile tile = Main.tile[point.X, point.Y];
1233 if (tile == null || !tile.active() || tile.inActive() || !Main.tileSolid[tile.type])
1234 {
1235 return false;
1236 }
1237 if (treatPlatformsAsNonSolid && tile.type > 0 && tile.type <= TileID.Count && (TileID.Sets.Platforms[tile.type] || tile.type == 380))
1238 {
1239 return false;
1240 }
1241 int num = tile.blockType();
1242 switch (num)
1243 {
1244 case 0:
1245 if (pos.X >= (float)(point.X * 16) && pos.X <= (float)(point.X * 16 + 16) && pos.Y >= (float)(point.Y * 16))
1246 {
1247 return pos.Y <= (float)(point.Y * 16 + 16);
1248 }
1249 return false;
1250 case 1:
1251 if (pos.X >= (float)(point.X * 16) && pos.X <= (float)(point.X * 16 + 16) && pos.Y >= (float)(point.Y * 16 + 8))
1252 {
1253 return pos.Y <= (float)(point.Y * 16 + 16);
1254 }
1255 return false;
1256 case 2:
1257 case 3:
1258 case 4:
1259 case 5:
1260 {
1261 if (pos.X < (float)(point.X * 16) && pos.X > (float)(point.X * 16 + 16) && pos.Y < (float)(point.Y * 16) && pos.Y > (float)(point.Y * 16 + 16))
1262 {
1263 return false;
1264 }
1265 float num2 = pos.X % 16f;
1266 float num3 = pos.Y % 16f;
1267 switch (num)
1268 {
1269 case 3:
1270 return num2 + num3 >= 16f;
1271 case 2:
1272 return num3 >= num2;
1273 case 5:
1274 return num3 <= num2;
1275 case 4:
1276 return num2 + num3 <= 16f;
1277 }
1278 break;
1279 }
1280 }
1281 return false;
1282 }
1283
1284 public static bool GetWaterLine(Point pt, out float waterLineHeight)
1285 {
1286 return GetWaterLine(pt.X, pt.Y, out waterLineHeight);
1287 }
1288
1289 public static bool GetWaterLine(int X, int Y, out float waterLineHeight)
1290 {
1291 waterLineHeight = 0f;
1292 if (Main.tile[X, Y - 2] == null)
1293 {
1294 Main.tile[X, Y - 2] = new Tile();
1295 }
1296 if (Main.tile[X, Y - 1] == null)
1297 {
1298 Main.tile[X, Y - 1] = new Tile();
1299 }
1300 if (Main.tile[X, Y] == null)
1301 {
1302 Main.tile[X, Y] = new Tile();
1303 }
1304 if (Main.tile[X, Y + 1] == null)
1305 {
1306 Main.tile[X, Y + 1] = new Tile();
1307 }
1308 if (Main.tile[X, Y - 2].liquid > 0)
1309 {
1310 return false;
1311 }
1312 if (Main.tile[X, Y - 1].liquid > 0)
1313 {
1314 waterLineHeight = Y * 16;
1315 waterLineHeight -= Main.tile[X, Y - 1].liquid / 16;
1316 return true;
1317 }
1318 if (Main.tile[X, Y].liquid > 0)
1319 {
1320 waterLineHeight = (Y + 1) * 16;
1321 waterLineHeight -= Main.tile[X, Y].liquid / 16;
1322 return true;
1323 }
1324 if (Main.tile[X, Y + 1].liquid > 0)
1325 {
1326 waterLineHeight = (Y + 2) * 16;
1327 waterLineHeight -= Main.tile[X, Y + 1].liquid / 16;
1328 return true;
1329 }
1330 return false;
1331 }
1332
1334 {
1336 }
1337
1338 public static bool GetWaterLineIterate(int X, int Y, out float waterLineHeight)
1339 {
1340 waterLineHeight = 0f;
1341 while (Y > 0 && Framing.GetTileSafely(X, Y).liquid > 0)
1342 {
1343 Y--;
1344 }
1345 Y++;
1346 if (Main.tile[X, Y] == null)
1347 {
1348 Main.tile[X, Y] = new Tile();
1349 }
1350 if (Main.tile[X, Y].liquid > 0)
1351 {
1352 waterLineHeight = Y * 16;
1353 waterLineHeight -= Main.tile[X, Y - 1].liquid / 16;
1354 return true;
1355 }
1356 return false;
1357 }
1358
1359 public static bool WetCollision(Vector2 Position, int Width, int Height)
1360 {
1361 honey = false;
1362 shimmer = false;
1363 Vector2 vector = new Vector2(Position.X + (float)(Width / 2), Position.Y + (float)(Height / 2));
1364 int num = 10;
1365 int num2 = Height / 2;
1366 if (num > Width)
1367 {
1368 num = Width;
1369 }
1370 if (num2 > Height)
1371 {
1372 num2 = Height;
1373 }
1374 vector = new Vector2(vector.X - (float)(num / 2), vector.Y - (float)(num2 / 2));
1375 int value = (int)(Position.X / 16f) - 1;
1376 int value2 = (int)((Position.X + (float)Width) / 16f) + 2;
1377 int value3 = (int)(Position.Y / 16f) - 1;
1378 int value4 = (int)((Position.Y + (float)Height) / 16f) + 2;
1379 int num3 = Utils.Clamp(value, 0, Main.maxTilesX - 1);
1380 value2 = Utils.Clamp(value2, 0, Main.maxTilesX - 1);
1381 value3 = Utils.Clamp(value3, 0, Main.maxTilesY - 1);
1382 value4 = Utils.Clamp(value4, 0, Main.maxTilesY - 1);
1383 Vector2 vector2 = default(Vector2);
1384 for (int i = num3; i < value2; i++)
1385 {
1386 for (int j = value3; j < value4; j++)
1387 {
1388 if (Main.tile[i, j] == null)
1389 {
1390 continue;
1391 }
1392 if (Main.tile[i, j].liquid > 0)
1393 {
1394 vector2.X = i * 16;
1395 vector2.Y = j * 16;
1396 int num4 = 16;
1397 float num5 = 256 - Main.tile[i, j].liquid;
1398 num5 /= 32f;
1399 vector2.Y += num5 * 2f;
1400 num4 -= (int)(num5 * 2f);
1401 if (vector.X + (float)num > vector2.X && vector.X < vector2.X + 16f && vector.Y + (float)num2 > vector2.Y && vector.Y < vector2.Y + (float)num4)
1402 {
1403 if (Main.tile[i, j].honey())
1404 {
1405 honey = true;
1406 }
1407 if (Main.tile[i, j].shimmer())
1408 {
1409 shimmer = true;
1410 }
1411 return true;
1412 }
1413 }
1414 else
1415 {
1416 if (!Main.tile[i, j].active() || Main.tile[i, j].slope() == 0 || j <= 0 || Main.tile[i, j - 1] == null || Main.tile[i, j - 1].liquid <= 0)
1417 {
1418 continue;
1419 }
1420 vector2.X = i * 16;
1421 vector2.Y = j * 16;
1422 int num6 = 16;
1423 if (vector.X + (float)num > vector2.X && vector.X < vector2.X + 16f && vector.Y + (float)num2 > vector2.Y && vector.Y < vector2.Y + (float)num6)
1424 {
1425 if (Main.tile[i, j - 1].honey())
1426 {
1427 honey = true;
1428 }
1429 else if (Main.tile[i, j - 1].shimmer())
1430 {
1431 shimmer = true;
1432 }
1433 return true;
1434 }
1435 }
1436 }
1437 }
1438 return false;
1439 }
1440
1441 public static bool LavaCollision(Vector2 Position, int Width, int Height)
1442 {
1443 int value = (int)(Position.X / 16f) - 1;
1444 int value2 = (int)((Position.X + (float)Width) / 16f) + 2;
1445 int value3 = (int)(Position.Y / 16f) - 1;
1446 int value4 = (int)((Position.Y + (float)Height) / 16f) + 2;
1447 int num = Utils.Clamp(value, 0, Main.maxTilesX - 1);
1448 value2 = Utils.Clamp(value2, 0, Main.maxTilesX - 1);
1449 value3 = Utils.Clamp(value3, 0, Main.maxTilesY - 1);
1450 value4 = Utils.Clamp(value4, 0, Main.maxTilesY - 1);
1451 Vector2 vector = default(Vector2);
1452 for (int i = num; i < value2; i++)
1453 {
1454 for (int j = value3; j < value4; j++)
1455 {
1456 if (Main.tile[i, j] != null && Main.tile[i, j].liquid > 0 && Main.tile[i, j].lava())
1457 {
1458 vector.X = i * 16;
1459 vector.Y = j * 16;
1460 int num2 = 16;
1461 float num3 = 256 - Main.tile[i, j].liquid;
1462 num3 /= 32f;
1463 vector.Y += num3 * 2f;
1464 num2 -= (int)(num3 * 2f);
1465 if (Position.X + (float)Width > vector.X && Position.X < vector.X + 16f && Position.Y + (float)Height > vector.Y && Position.Y < vector.Y + (float)num2)
1466 {
1467 return true;
1468 }
1469 }
1470 }
1471 }
1472 return false;
1473 }
1474
1475 public static Vector4 WalkDownSlope(Vector2 Position, Vector2 Velocity, int Width, int Height, float gravity = 0f)
1476 {
1477 if (Velocity.Y != gravity)
1478 {
1479 return new Vector4(Position, Velocity.X, Velocity.Y);
1480 }
1482 int value = (int)(vector.X / 16f);
1483 int value2 = (int)((vector.X + (float)Width) / 16f);
1484 int value3 = (int)((Position.Y + (float)Height + 4f) / 16f);
1485 value = Utils.Clamp(value, 0, Main.maxTilesX - 1);
1486 value2 = Utils.Clamp(value2, 0, Main.maxTilesX - 1);
1487 value3 = Utils.Clamp(value3, 0, Main.maxTilesY - 3);
1488 float num = (value3 + 3) * 16;
1489 int num2 = -1;
1490 int num3 = -1;
1491 int num4 = 1;
1492 if (Velocity.X < 0f)
1493 {
1494 num4 = 2;
1495 }
1496 for (int i = value; i <= value2; i++)
1497 {
1498 for (int j = value3; j <= value3 + 1; j++)
1499 {
1500 if (Main.tile[i, j] == null)
1501 {
1502 Main.tile[i, j] = new Tile();
1503 }
1504 if (!Main.tile[i, j].nactive() || (!Main.tileSolid[Main.tile[i, j].type] && !Main.tileSolidTop[Main.tile[i, j].type]))
1505 {
1506 continue;
1507 }
1508 int num5 = j * 16;
1509 if (Main.tile[i, j].halfBrick())
1510 {
1511 num5 += 8;
1512 }
1513 if (!new Rectangle(i * 16, j * 16 - 17, 16, 16).Intersects(new Rectangle((int)Position.X, (int)Position.Y, Width, Height)) || !((float)num5 <= num))
1514 {
1515 continue;
1516 }
1517 if (num == (float)num5)
1518 {
1519 if (Main.tile[i, j].slope() == 0)
1520 {
1521 continue;
1522 }
1523 if (num2 != -1 && num3 != -1 && Main.tile[num2, num3] != null && Main.tile[num2, num3].slope() != 0)
1524 {
1525 if (Main.tile[i, j].slope() == num4)
1526 {
1527 num = num5;
1528 num2 = i;
1529 num3 = j;
1530 }
1531 }
1532 else
1533 {
1534 num = num5;
1535 num2 = i;
1536 num3 = j;
1537 }
1538 }
1539 else
1540 {
1541 num = num5;
1542 num2 = i;
1543 num3 = j;
1544 }
1545 }
1546 }
1547 int num6 = num2;
1548 int num7 = num3;
1549 if (num2 != -1 && num3 != -1 && Main.tile[num6, num7] != null && Main.tile[num6, num7].slope() > 0)
1550 {
1551 int num8 = Main.tile[num6, num7].slope();
1552 Vector2 vector2 = default(Vector2);
1553 vector2.X = num6 * 16;
1554 vector2.Y = num7 * 16;
1555 switch (num8)
1556 {
1557 case 2:
1558 {
1559 float num9 = vector2.X + 16f - (Position.X + (float)Width);
1560 if (Position.Y + (float)Height >= vector2.Y + num9 && Velocity.X < 0f)
1561 {
1562 Velocity.Y += Math.Abs(Velocity.X);
1563 }
1564 break;
1565 }
1566 case 1:
1567 {
1568 float num9 = Position.X - vector2.X;
1569 if (Position.Y + (float)Height >= vector2.Y + num9 && Velocity.X > 0f)
1570 {
1571 Velocity.Y += Math.Abs(Velocity.X);
1572 }
1573 break;
1574 }
1575 }
1576 }
1577 return new Vector4(Position, Velocity.X, Velocity.Y);
1578 }
1579
1580 public static Vector4 SlopeCollision(Vector2 Position, Vector2 Velocity, int Width, int Height, float gravity = 0f, bool fall = false)
1581 {
1582 stair = false;
1583 stairFall = false;
1584 bool[] array = new bool[5];
1585 float y = Position.Y;
1586 float y2 = Position.Y;
1587 sloping = false;
1590 Vector2 vector3 = Velocity;
1591 int value = (int)(Position.X / 16f) - 1;
1592 int value2 = (int)((Position.X + (float)Width) / 16f) + 2;
1593 int value3 = (int)(Position.Y / 16f) - 1;
1594 int value4 = (int)((Position.Y + (float)Height) / 16f) + 2;
1595 int num = Utils.Clamp(value, 0, Main.maxTilesX - 1);
1596 value2 = Utils.Clamp(value2, 0, Main.maxTilesX - 1);
1597 value3 = Utils.Clamp(value3, 0, Main.maxTilesY - 1);
1598 value4 = Utils.Clamp(value4, 0, Main.maxTilesY - 1);
1599 Vector2 vector4 = default(Vector2);
1600 for (int i = num; i < value2; i++)
1601 {
1602 for (int j = value3; j < value4; j++)
1603 {
1604 if (Main.tile[i, j] == null || !Main.tile[i, j].active() || Main.tile[i, j].inActive() || (!Main.tileSolid[Main.tile[i, j].type] && (!Main.tileSolidTop[Main.tile[i, j].type] || Main.tile[i, j].frameY != 0)))
1605 {
1606 continue;
1607 }
1608 vector4.X = i * 16;
1609 vector4.Y = j * 16;
1610 int num2 = 16;
1611 if (Main.tile[i, j].halfBrick())
1612 {
1613 vector4.Y += 8f;
1614 num2 -= 8;
1615 }
1616 if (!(Position.X + (float)Width > vector4.X) || !(Position.X < vector4.X + 16f) || !(Position.Y + (float)Height > vector4.Y) || !(Position.Y < vector4.Y + (float)num2))
1617 {
1618 continue;
1619 }
1620 bool flag = true;
1621 if (TileID.Sets.Platforms[Main.tile[i, j].type])
1622 {
1623 if (Velocity.Y < 0f)
1624 {
1625 flag = false;
1626 }
1627 if (Position.Y + (float)Height < (float)(j * 16) || Position.Y + (float)Height - (1f + Math.Abs(Velocity.X)) > (float)(j * 16 + 16))
1628 {
1629 flag = false;
1630 }
1631 if (((Main.tile[i, j].slope() == 1 && Velocity.X >= 0f) || (Main.tile[i, j].slope() == 2 && Velocity.X <= 0f)) && (Position.Y + (float)Height) / 16f - 1f == (float)j)
1632 {
1633 flag = false;
1634 }
1635 }
1636 if (!flag)
1637 {
1638 continue;
1639 }
1640 bool flag2 = false;
1641 if (fall && TileID.Sets.Platforms[Main.tile[i, j].type])
1642 {
1643 flag2 = true;
1644 }
1645 int num3 = Main.tile[i, j].slope();
1646 vector4.X = i * 16;
1647 vector4.Y = j * 16;
1648 if (!(Position.X + (float)Width > vector4.X) || !(Position.X < vector4.X + 16f) || !(Position.Y + (float)Height > vector4.Y) || !(Position.Y < vector4.Y + 16f))
1649 {
1650 continue;
1651 }
1652 float num4 = 0f;
1653 if (num3 == 3 || num3 == 4)
1654 {
1655 if (num3 == 3)
1656 {
1657 num4 = Position.X - vector4.X;
1658 }
1659 if (num3 == 4)
1660 {
1661 num4 = vector4.X + 16f - (Position.X + (float)Width);
1662 }
1663 if (num4 >= 0f)
1664 {
1665 if (Position.Y <= vector4.Y + 16f - num4)
1666 {
1667 float num5 = vector4.Y + 16f - vector.Y - num4;
1668 if (Position.Y + num5 > y2)
1669 {
1670 vector2.Y = Position.Y + num5;
1671 y2 = vector2.Y;
1672 if (vector3.Y < 0.0101f)
1673 {
1674 vector3.Y = 0.0101f;
1675 }
1676 array[num3] = true;
1677 }
1678 }
1679 }
1680 else if (Position.Y > vector4.Y)
1681 {
1682 float num6 = vector4.Y + 16f;
1683 if (vector2.Y < num6)
1684 {
1685 vector2.Y = num6;
1686 if (vector3.Y < 0.0101f)
1687 {
1688 vector3.Y = 0.0101f;
1689 }
1690 }
1691 }
1692 }
1693 if (num3 != 1 && num3 != 2)
1694 {
1695 continue;
1696 }
1697 if (num3 == 1)
1698 {
1699 num4 = Position.X - vector4.X;
1700 }
1701 if (num3 == 2)
1702 {
1703 num4 = vector4.X + 16f - (Position.X + (float)Width);
1704 }
1705 if (num4 >= 0f)
1706 {
1707 if (!(Position.Y + (float)Height >= vector4.Y + num4))
1708 {
1709 continue;
1710 }
1711 float num7 = vector4.Y - (vector.Y + (float)Height) + num4;
1712 if (!(Position.Y + num7 < y))
1713 {
1714 continue;
1715 }
1716 if (flag2)
1717 {
1718 stairFall = true;
1719 continue;
1720 }
1721 if (TileID.Sets.Platforms[Main.tile[i, j].type])
1722 {
1723 stair = true;
1724 }
1725 else
1726 {
1727 stair = false;
1728 }
1729 vector2.Y = Position.Y + num7;
1730 y = vector2.Y;
1731 if (vector3.Y > 0f)
1732 {
1733 vector3.Y = 0f;
1734 }
1735 array[num3] = true;
1736 continue;
1737 }
1738 if (TileID.Sets.Platforms[Main.tile[i, j].type] && !(Position.Y + (float)Height - 4f - Math.Abs(Velocity.X) <= vector4.Y))
1739 {
1740 if (flag2)
1741 {
1742 stairFall = true;
1743 }
1744 continue;
1745 }
1746 float num8 = vector4.Y - (float)Height;
1747 if (!(vector2.Y > num8))
1748 {
1749 continue;
1750 }
1751 if (flag2)
1752 {
1753 stairFall = true;
1754 continue;
1755 }
1756 if (TileID.Sets.Platforms[Main.tile[i, j].type])
1757 {
1758 stair = true;
1759 }
1760 else
1761 {
1762 stair = false;
1763 }
1764 vector2.Y = num8;
1765 if (vector3.Y > 0f)
1766 {
1767 vector3.Y = 0f;
1768 }
1769 }
1770 }
1771 Vector2 position = Position;
1772 Vector2 velocity = vector2 - Position;
1773 Vector2 vector5 = TileCollision(position, velocity, Width, Height);
1774 if (vector5.Y > velocity.Y)
1775 {
1776 float num9 = velocity.Y - vector5.Y;
1777 vector2.Y = Position.Y + vector5.Y;
1778 if (array[1])
1779 {
1780 vector2.X = Position.X - num9;
1781 }
1782 if (array[2])
1783 {
1784 vector2.X = Position.X + num9;
1785 }
1786 vector3.X = 0f;
1787 vector3.Y = 0f;
1788 up = false;
1789 }
1790 else if (vector5.Y < velocity.Y)
1791 {
1792 float num10 = vector5.Y - velocity.Y;
1793 vector2.Y = Position.Y + vector5.Y;
1794 if (array[3])
1795 {
1796 vector2.X = Position.X - num10;
1797 }
1798 if (array[4])
1799 {
1800 vector2.X = Position.X + num10;
1801 }
1802 vector3.X = 0f;
1803 vector3.Y = 0f;
1804 }
1805 return new Vector4(vector2, vector3.X, vector3.Y);
1806 }
1807
1808 public static Vector2 noSlopeCollision(Vector2 Position, Vector2 Velocity, int Width, int Height, bool fallThrough = false, bool fall2 = false)
1809 {
1810 up = false;
1811 down = false;
1812 Vector2 result = Velocity;
1813 Vector2 vector = Velocity;
1814 Vector2 vector2 = Position + Velocity;
1816 int value = (int)(Position.X / 16f) - 1;
1817 int value2 = (int)((Position.X + (float)Width) / 16f) + 2;
1818 int value3 = (int)(Position.Y / 16f) - 1;
1819 int value4 = (int)((Position.Y + (float)Height) / 16f) + 2;
1820 int num = -1;
1821 int num2 = -1;
1822 int num3 = -1;
1823 int num4 = -1;
1824 int num5 = Utils.Clamp(value, 0, Main.maxTilesX - 1);
1825 value2 = Utils.Clamp(value2, 0, Main.maxTilesX - 1);
1826 value3 = Utils.Clamp(value3, 0, Main.maxTilesY - 1);
1827 value4 = Utils.Clamp(value4, 0, Main.maxTilesY - 1);
1828 float num6 = (value4 + 3) * 16;
1829 Vector2 vector4 = default(Vector2);
1830 for (int i = num5; i < value2; i++)
1831 {
1832 for (int j = value3; j < value4; j++)
1833 {
1834 if (Main.tile[i, j] == null || !Main.tile[i, j].active() || (!Main.tileSolid[Main.tile[i, j].type] && (!Main.tileSolidTop[Main.tile[i, j].type] || Main.tile[i, j].frameY != 0)))
1835 {
1836 continue;
1837 }
1838 vector4.X = i * 16;
1839 vector4.Y = j * 16;
1840 int num7 = 16;
1841 if (Main.tile[i, j].halfBrick())
1842 {
1843 vector4.Y += 8f;
1844 num7 -= 8;
1845 }
1846 if (!(vector2.X + (float)Width > vector4.X) || !(vector2.X < vector4.X + 16f) || !(vector2.Y + (float)Height > vector4.Y) || !(vector2.Y < vector4.Y + (float)num7))
1847 {
1848 continue;
1849 }
1850 if (vector3.Y + (float)Height <= vector4.Y)
1851 {
1852 down = true;
1853 if ((!(Main.tileSolidTop[Main.tile[i, j].type] && fallThrough) || !(Velocity.Y <= 1f || fall2)) && num6 > vector4.Y)
1854 {
1855 num3 = i;
1856 num4 = j;
1857 if (num7 < 16)
1858 {
1859 num4++;
1860 }
1861 if (num3 != num)
1862 {
1863 result.Y = vector4.Y - (vector3.Y + (float)Height);
1864 num6 = vector4.Y;
1865 }
1866 }
1867 }
1868 else if (vector3.X + (float)Width <= vector4.X && !Main.tileSolidTop[Main.tile[i, j].type])
1869 {
1870 num = i;
1871 num2 = j;
1872 if (num2 != num4)
1873 {
1874 result.X = vector4.X - (vector3.X + (float)Width);
1875 }
1876 if (num3 == num)
1877 {
1878 result.Y = vector.Y;
1879 }
1880 }
1881 else if (vector3.X >= vector4.X + 16f && !Main.tileSolidTop[Main.tile[i, j].type])
1882 {
1883 num = i;
1884 num2 = j;
1885 if (num2 != num4)
1886 {
1887 result.X = vector4.X + 16f - vector3.X;
1888 }
1889 if (num3 == num)
1890 {
1891 result.Y = vector.Y;
1892 }
1893 }
1894 else if (vector3.Y >= vector4.Y + (float)num7 && !Main.tileSolidTop[Main.tile[i, j].type])
1895 {
1896 up = true;
1897 num3 = i;
1898 num4 = j;
1899 result.Y = vector4.Y + (float)num7 - vector3.Y + 0.01f;
1900 if (num4 == num2)
1901 {
1902 result.X = vector.X;
1903 }
1904 }
1905 }
1906 }
1907 return result;
1908 }
1909
1910 public static Vector2 TileCollision(Vector2 Position, Vector2 Velocity, int Width, int Height, bool fallThrough = false, bool fall2 = false, int gravDir = 1)
1911 {
1912 up = false;
1913 down = false;
1914 Vector2 result = Velocity;
1915 Vector2 vector = Velocity;
1916 Vector2 vector2 = Position + Velocity;
1918 int value = (int)(Position.X / 16f) - 1;
1919 int value2 = (int)((Position.X + (float)Width) / 16f) + 2;
1920 int value3 = (int)(Position.Y / 16f) - 1;
1921 int value4 = (int)((Position.Y + (float)Height) / 16f) + 2;
1922 int num = -1;
1923 int num2 = -1;
1924 int num3 = -1;
1925 int num4 = -1;
1926 int num5 = Utils.Clamp(value, 0, Main.maxTilesX - 1);
1927 value2 = Utils.Clamp(value2, 0, Main.maxTilesX - 1);
1928 value3 = Utils.Clamp(value3, 0, Main.maxTilesY - 1);
1929 value4 = Utils.Clamp(value4, 0, Main.maxTilesY - 1);
1930 float num6 = (value4 + 3) * 16;
1931 Vector2 vector4 = default(Vector2);
1932 for (int i = num5; i < value2; i++)
1933 {
1934 for (int j = value3; j < value4; j++)
1935 {
1936 if (Main.tile[i, j] == null || !Main.tile[i, j].active() || Main.tile[i, j].inActive() || (!Main.tileSolid[Main.tile[i, j].type] && (!Main.tileSolidTop[Main.tile[i, j].type] || Main.tile[i, j].frameY != 0)))
1937 {
1938 continue;
1939 }
1940 vector4.X = i * 16;
1941 vector4.Y = j * 16;
1942 int num7 = 16;
1943 if (Main.tile[i, j].halfBrick())
1944 {
1945 vector4.Y += 8f;
1946 num7 -= 8;
1947 }
1948 if (!(vector2.X + (float)Width > vector4.X) || !(vector2.X < vector4.X + 16f) || !(vector2.Y + (float)Height > vector4.Y) || !(vector2.Y < vector4.Y + (float)num7))
1949 {
1950 continue;
1951 }
1952 bool flag = false;
1953 bool flag2 = false;
1954 if (Main.tile[i, j].slope() > 2)
1955 {
1956 if (Main.tile[i, j].slope() == 3 && vector3.Y + Math.Abs(Velocity.X) >= vector4.Y && vector3.X >= vector4.X)
1957 {
1958 flag2 = true;
1959 }
1960 if (Main.tile[i, j].slope() == 4 && vector3.Y + Math.Abs(Velocity.X) >= vector4.Y && vector3.X + (float)Width <= vector4.X + 16f)
1961 {
1962 flag2 = true;
1963 }
1964 }
1965 else if (Main.tile[i, j].slope() > 0)
1966 {
1967 flag = true;
1968 if (Main.tile[i, j].slope() == 1 && vector3.Y + (float)Height - Math.Abs(Velocity.X) <= vector4.Y + (float)num7 && vector3.X >= vector4.X)
1969 {
1970 flag2 = true;
1971 }
1972 if (Main.tile[i, j].slope() == 2 && vector3.Y + (float)Height - Math.Abs(Velocity.X) <= vector4.Y + (float)num7 && vector3.X + (float)Width <= vector4.X + 16f)
1973 {
1974 flag2 = true;
1975 }
1976 }
1977 if (flag2)
1978 {
1979 continue;
1980 }
1981 if (vector3.Y + (float)Height <= vector4.Y)
1982 {
1983 down = true;
1984 if ((!(Main.tileSolidTop[Main.tile[i, j].type] && fallThrough) || !(Velocity.Y <= 1f || fall2)) && num6 > vector4.Y)
1985 {
1986 num3 = i;
1987 num4 = j;
1988 if (num7 < 16)
1989 {
1990 num4++;
1991 }
1992 if (num3 != num && !flag)
1993 {
1994 result.Y = vector4.Y - (vector3.Y + (float)Height) + ((gravDir == -1) ? (-0.01f) : 0f);
1995 num6 = vector4.Y;
1996 }
1997 }
1998 }
1999 else if (vector3.X + (float)Width <= vector4.X && !Main.tileSolidTop[Main.tile[i, j].type])
2000 {
2001 if (i >= 1 && Main.tile[i - 1, j] == null)
2002 {
2003 Main.tile[i - 1, j] = new Tile();
2004 }
2005 if (i < 1 || (Main.tile[i - 1, j].slope() != 2 && Main.tile[i - 1, j].slope() != 4))
2006 {
2007 num = i;
2008 num2 = j;
2009 if (num2 != num4)
2010 {
2011 result.X = vector4.X - (vector3.X + (float)Width);
2012 }
2013 if (num3 == num)
2014 {
2015 result.Y = vector.Y;
2016 }
2017 }
2018 }
2019 else if (vector3.X >= vector4.X + 16f && !Main.tileSolidTop[Main.tile[i, j].type])
2020 {
2021 if (Main.tile[i + 1, j] == null)
2022 {
2023 Main.tile[i + 1, j] = new Tile();
2024 }
2025 if (Main.tile[i + 1, j].slope() != 1 && Main.tile[i + 1, j].slope() != 3)
2026 {
2027 num = i;
2028 num2 = j;
2029 if (num2 != num4)
2030 {
2031 result.X = vector4.X + 16f - vector3.X;
2032 }
2033 if (num3 == num)
2034 {
2035 result.Y = vector.Y;
2036 }
2037 }
2038 }
2039 else if (vector3.Y >= vector4.Y + (float)num7 && !Main.tileSolidTop[Main.tile[i, j].type])
2040 {
2041 up = true;
2042 num3 = i;
2043 num4 = j;
2044 result.Y = vector4.Y + (float)num7 - vector3.Y + ((gravDir == 1) ? 0.01f : 0f);
2045 if (num4 == num2)
2046 {
2047 result.X = vector.X;
2048 }
2049 }
2050 }
2051 }
2052 return result;
2053 }
2054
2055 public static bool IsClearSpotTest(Vector2 position, float testMagnitude, int Width, int Height, bool fallThrough = false, bool fall2 = false, int gravDir = 1, bool checkCardinals = true, bool checkSlopes = false)
2056 {
2057 if (checkCardinals)
2058 {
2059 Vector2 vector = Vector2.UnitX * testMagnitude;
2060 if (TileCollision(position - vector, vector, Width, Height, fallThrough, fall2, gravDir) != vector)
2061 {
2062 return false;
2063 }
2064 vector = -Vector2.UnitX * testMagnitude;
2065 if (TileCollision(position - vector, vector, Width, Height, fallThrough, fall2, gravDir) != vector)
2066 {
2067 return false;
2068 }
2069 vector = Vector2.UnitY * testMagnitude;
2070 if (TileCollision(position - vector, vector, Width, Height, fallThrough, fall2, gravDir) != vector)
2071 {
2072 return false;
2073 }
2074 vector = -Vector2.UnitY * testMagnitude;
2075 if (TileCollision(position - vector, vector, Width, Height, fallThrough, fall2, gravDir) != vector)
2076 {
2077 return false;
2078 }
2079 }
2080 if (checkSlopes)
2081 {
2082 Vector2 vector = Vector2.UnitX * testMagnitude;
2083 Vector4 vector2 = new Vector4(position, testMagnitude, 0f);
2084 if (SlopeCollision(position, vector, Width, Height, gravDir, fallThrough) != vector2)
2085 {
2086 return false;
2087 }
2088 vector = -Vector2.UnitX * testMagnitude;
2089 vector2 = new Vector4(position, 0f - testMagnitude, 0f);
2090 if (SlopeCollision(position, vector, Width, Height, gravDir, fallThrough) != vector2)
2091 {
2092 return false;
2093 }
2094 vector = Vector2.UnitY * testMagnitude;
2095 vector2 = new Vector4(position, 0f, testMagnitude);
2096 if (SlopeCollision(position, vector, Width, Height, gravDir, fallThrough) != vector2)
2097 {
2098 return false;
2099 }
2100 vector = -Vector2.UnitY * testMagnitude;
2101 vector2 = new Vector4(position, 0f, 0f - testMagnitude);
2102 if (SlopeCollision(position, vector, Width, Height, gravDir, fallThrough) != vector2)
2103 {
2104 return false;
2105 }
2106 }
2107 return true;
2108 }
2109
2110 public static List<Point> FindCollisionTile(int Direction, Vector2 position, float testMagnitude, int Width, int Height, bool fallThrough = false, bool fall2 = false, int gravDir = 1, bool checkCardinals = true, bool checkSlopes = false)
2111 {
2113 if ((uint)Direction > 1u)
2114 {
2115 if ((uint)(Direction - 2) <= 1u)
2116 {
2117 Vector2 vector = ((Direction == 2) ? (Vector2.UnitY * testMagnitude) : (-Vector2.UnitY * testMagnitude));
2118 Vector4 vec = new Vector4(position, vector.X, vector.Y);
2119 int y = (int)(position.Y + (float)((Direction == 2) ? Height : 0)) / 16;
2120 float num = Math.Min(16f - position.X % 16f, Width);
2121 float num2 = num;
2122 if (checkCardinals && TileCollision(position - vector, vector, (int)num, Height, fallThrough, fall2, gravDir) != vector)
2123 {
2124 list.Add(new Point((int)position.X / 16, y));
2125 }
2126 else if (checkSlopes && SlopeCollision(position, vector, (int)num, Height, gravDir, fallThrough).YZW() != vec.YZW())
2127 {
2128 list.Add(new Point((int)position.X / 16, y));
2129 }
2130 for (; num2 + 16f <= (float)(Width - 16); num2 += 16f)
2131 {
2132 if (checkCardinals && TileCollision(position - vector + Vector2.UnitX * num2, vector, 16, Height, fallThrough, fall2, gravDir) != vector)
2133 {
2134 list.Add(new Point((int)(position.X + num2) / 16, y));
2135 }
2136 else if (checkSlopes && SlopeCollision(position + Vector2.UnitX * num2, vector, 16, Height, gravDir, fallThrough).YZW() != vec.YZW())
2137 {
2138 list.Add(new Point((int)(position.X + num2) / 16, y));
2139 }
2140 }
2141 int width = Width - (int)num2;
2142 if (checkCardinals && TileCollision(position - vector + Vector2.UnitX * num2, vector, width, Height, fallThrough, fall2, gravDir) != vector)
2143 {
2144 list.Add(new Point((int)(position.X + num2) / 16, y));
2145 }
2146 else if (checkSlopes && SlopeCollision(position + Vector2.UnitX * num2, vector, width, Height, gravDir, fallThrough).YZW() != vec.YZW())
2147 {
2148 list.Add(new Point((int)(position.X + num2) / 16, y));
2149 }
2150 }
2151 }
2152 else
2153 {
2154 Vector2 vector = ((Direction == 0) ? (Vector2.UnitX * testMagnitude) : (-Vector2.UnitX * testMagnitude));
2155 Vector4 vec = new Vector4(position, vector.X, vector.Y);
2156 int y = (int)(position.X + (float)((Direction == 0) ? Width : 0)) / 16;
2157 float num3 = Math.Min(16f - position.Y % 16f, Height);
2158 float num4 = num3;
2159 if (checkCardinals && TileCollision(position - vector, vector, Width, (int)num3, fallThrough, fall2, gravDir) != vector)
2160 {
2161 list.Add(new Point(y, (int)position.Y / 16));
2162 }
2163 else if (checkSlopes && SlopeCollision(position, vector, Width, (int)num3, gravDir, fallThrough).XZW() != vec.XZW())
2164 {
2165 list.Add(new Point(y, (int)position.Y / 16));
2166 }
2167 for (; num4 + 16f <= (float)(Height - 16); num4 += 16f)
2168 {
2169 if (checkCardinals && TileCollision(position - vector + Vector2.UnitY * num4, vector, Width, 16, fallThrough, fall2, gravDir) != vector)
2170 {
2171 list.Add(new Point(y, (int)(position.Y + num4) / 16));
2172 }
2173 else if (checkSlopes && SlopeCollision(position + Vector2.UnitY * num4, vector, Width, 16, gravDir, fallThrough).XZW() != vec.XZW())
2174 {
2175 list.Add(new Point(y, (int)(position.Y + num4) / 16));
2176 }
2177 }
2178 int height = Height - (int)num4;
2179 if (checkCardinals && TileCollision(position - vector + Vector2.UnitY * num4, vector, Width, height, fallThrough, fall2, gravDir) != vector)
2180 {
2181 list.Add(new Point(y, (int)(position.Y + num4) / 16));
2182 }
2183 else if (checkSlopes && SlopeCollision(position + Vector2.UnitY * num4, vector, Width, height, gravDir, fallThrough).XZW() != vec.XZW())
2184 {
2185 list.Add(new Point(y, (int)(position.Y + num4) / 16));
2186 }
2187 }
2188 return list;
2189 }
2190
2191 public static bool FindCollisionDirection(out int Direction, Vector2 position, int Width, int Height, bool fallThrough = false, bool fall2 = false, int gravDir = 1)
2192 {
2193 Vector2 vector = Vector2.UnitX * 16f;
2194 if (TileCollision(position - vector, vector, Width, Height, fallThrough, fall2, gravDir) != vector)
2195 {
2196 Direction = 0;
2197 return true;
2198 }
2199 vector = -Vector2.UnitX * 16f;
2200 if (TileCollision(position - vector, vector, Width, Height, fallThrough, fall2, gravDir) != vector)
2201 {
2202 Direction = 1;
2203 return true;
2204 }
2205 vector = Vector2.UnitY * 16f;
2206 if (TileCollision(position - vector, vector, Width, Height, fallThrough, fall2, gravDir) != vector)
2207 {
2208 Direction = 2;
2209 return true;
2210 }
2211 vector = -Vector2.UnitY * 16f;
2212 if (TileCollision(position - vector, vector, Width, Height, fallThrough, fall2, gravDir) != vector)
2213 {
2214 Direction = 3;
2215 return true;
2216 }
2217 Direction = -1;
2218 return false;
2219 }
2220
2221 public static bool SolidCollision(Vector2 Position, int Width, int Height)
2222 {
2223 int value = (int)(Position.X / 16f) - 1;
2224 int value2 = (int)((Position.X + (float)Width) / 16f) + 2;
2225 int value3 = (int)(Position.Y / 16f) - 1;
2226 int value4 = (int)((Position.Y + (float)Height) / 16f) + 2;
2227 int num = Utils.Clamp(value, 0, Main.maxTilesX - 1);
2228 value2 = Utils.Clamp(value2, 0, Main.maxTilesX - 1);
2229 value3 = Utils.Clamp(value3, 0, Main.maxTilesY - 1);
2230 value4 = Utils.Clamp(value4, 0, Main.maxTilesY - 1);
2231 Vector2 vector = default(Vector2);
2232 for (int i = num; i < value2; i++)
2233 {
2234 for (int j = value3; j < value4; j++)
2235 {
2236 if (Main.tile[i, j] != null && !Main.tile[i, j].inActive() && Main.tile[i, j].active() && Main.tileSolid[Main.tile[i, j].type] && !Main.tileSolidTop[Main.tile[i, j].type])
2237 {
2238 vector.X = i * 16;
2239 vector.Y = j * 16;
2240 int num2 = 16;
2241 if (Main.tile[i, j].halfBrick())
2242 {
2243 vector.Y += 8f;
2244 num2 -= 8;
2245 }
2246 if (Position.X + (float)Width > vector.X && Position.X < vector.X + 16f && Position.Y + (float)Height > vector.Y && Position.Y < vector.Y + (float)num2)
2247 {
2248 return true;
2249 }
2250 }
2251 }
2252 }
2253 return false;
2254 }
2255
2256 public static bool SolidCollision(Vector2 Position, int Width, int Height, bool acceptTopSurfaces)
2257 {
2258 int value = (int)(Position.X / 16f) - 1;
2259 int value2 = (int)((Position.X + (float)Width) / 16f) + 2;
2260 int value3 = (int)(Position.Y / 16f) - 1;
2261 int value4 = (int)((Position.Y + (float)Height) / 16f) + 2;
2262 int num = Utils.Clamp(value, 0, Main.maxTilesX - 1);
2263 value2 = Utils.Clamp(value2, 0, Main.maxTilesX - 1);
2264 value3 = Utils.Clamp(value3, 0, Main.maxTilesY - 1);
2265 value4 = Utils.Clamp(value4, 0, Main.maxTilesY - 1);
2266 Vector2 vector = default(Vector2);
2267 for (int i = num; i < value2; i++)
2268 {
2269 for (int j = value3; j < value4; j++)
2270 {
2271 Tile tile = Main.tile[i, j];
2272 if (tile == null || !tile.active() || tile.inActive())
2273 {
2274 continue;
2275 }
2276 bool flag = Main.tileSolid[tile.type] && !Main.tileSolidTop[tile.type];
2278 {
2279 flag |= Main.tileSolidTop[tile.type] && tile.frameY == 0;
2280 }
2281 if (flag)
2282 {
2283 vector.X = i * 16;
2284 vector.Y = j * 16;
2285 int num2 = 16;
2286 if (tile.halfBrick())
2287 {
2288 vector.Y += 8f;
2289 num2 -= 8;
2290 }
2291 if (Position.X + (float)Width > vector.X && Position.X < vector.X + 16f && Position.Y + (float)Height > vector.Y && Position.Y < vector.Y + (float)num2)
2292 {
2293 return true;
2294 }
2295 }
2296 }
2297 }
2298 return false;
2299 }
2300
2301 public static Vector2 WaterCollision(Vector2 Position, Vector2 Velocity, int Width, int Height, bool fallThrough = false, bool fall2 = false, bool lavaWalk = true)
2302 {
2303 Vector2 result = Velocity;
2304 Vector2 vector = Position + Velocity;
2306 int value = (int)(Position.X / 16f) - 1;
2307 int value2 = (int)((Position.X + (float)Width) / 16f) + 2;
2308 int value3 = (int)(Position.Y / 16f) - 1;
2309 int value4 = (int)((Position.Y + (float)Height) / 16f) + 2;
2310 int num = Utils.Clamp(value, 0, Main.maxTilesX - 1);
2311 value2 = Utils.Clamp(value2, 0, Main.maxTilesX - 1);
2312 value3 = Utils.Clamp(value3, 0, Main.maxTilesY - 1);
2313 value4 = Utils.Clamp(value4, 0, Main.maxTilesY - 1);
2314 Vector2 vector3 = default(Vector2);
2315 for (int i = num; i < value2; i++)
2316 {
2317 for (int j = value3; j < value4; j++)
2318 {
2319 if (Main.tile[i, j] != null && Main.tile[i, j].liquid > 0 && Main.tile[i, j - 1].liquid == 0 && (!Main.tile[i, j].lava() || lavaWalk))
2320 {
2321 int num2 = Main.tile[i, j].liquid / 32 * 2 + 2;
2322 vector3.X = i * 16;
2323 vector3.Y = j * 16 + 16 - num2;
2324 if (vector.X + (float)Width > vector3.X && vector.X < vector3.X + 16f && vector.Y + (float)Height > vector3.Y && vector.Y < vector3.Y + (float)num2 && vector2.Y + (float)Height <= vector3.Y && !fallThrough)
2325 {
2326 result.Y = vector3.Y - (vector2.Y + (float)Height);
2327 }
2328 }
2329 }
2330 }
2331 return result;
2332 }
2333
2334 public static Vector2 AnyCollisionWithSpecificTiles(Vector2 Position, Vector2 Velocity, int Width, int Height, bool[] tilesWeCanCollideWithByType, bool evenActuated = false)
2335 {
2336 Vector2 result = Velocity;
2337 Vector2 vector = Velocity;
2338 Vector2 vector2 = Position + Velocity;
2340 int num = (int)(Position.X / 16f) - 1;
2341 int num2 = (int)((Position.X + (float)Width) / 16f) + 2;
2342 int num3 = (int)(Position.Y / 16f) - 1;
2343 int num4 = (int)((Position.Y + (float)Height) / 16f) + 2;
2344 int num5 = -1;
2345 int num6 = -1;
2346 int num7 = -1;
2347 int num8 = -1;
2348 if (num < 0)
2349 {
2350 num = 0;
2351 }
2352 if (num2 > Main.maxTilesX)
2353 {
2355 }
2356 if (num3 < 0)
2357 {
2358 num3 = 0;
2359 }
2360 if (num4 > Main.maxTilesY)
2361 {
2363 }
2364 Vector2 vector4 = default(Vector2);
2365 for (int i = num; i < num2; i++)
2366 {
2367 for (int j = num3; j < num4; j++)
2368 {
2369 Tile tile = Main.tile[i, j];
2370 if (tile == null || !tile.active() || (!evenActuated && tile.inActive()) || !tilesWeCanCollideWithByType[tile.type])
2371 {
2372 continue;
2373 }
2374 vector4.X = i * 16;
2375 vector4.Y = j * 16;
2376 int num9 = 16;
2377 if (tile.halfBrick())
2378 {
2379 vector4.Y += 8f;
2380 num9 -= 8;
2381 }
2382 if (!(vector2.X + (float)Width > vector4.X) || !(vector2.X < vector4.X + 16f) || !(vector2.Y + (float)Height > vector4.Y) || !(vector2.Y < vector4.Y + (float)num9))
2383 {
2384 continue;
2385 }
2386 if (vector3.Y + (float)Height <= vector4.Y)
2387 {
2388 num7 = i;
2389 num8 = j;
2390 if (num7 != num5)
2391 {
2392 result.Y = vector4.Y - (vector3.Y + (float)Height);
2393 }
2394 }
2395 else if (vector3.X + (float)Width <= vector4.X && !Main.tileSolidTop[tile.type])
2396 {
2397 num5 = i;
2398 num6 = j;
2399 if (num6 != num8)
2400 {
2401 result.X = vector4.X - (vector3.X + (float)Width);
2402 }
2403 if (num7 == num5)
2404 {
2405 result.Y = vector.Y;
2406 }
2407 }
2408 else if (vector3.X >= vector4.X + 16f && !Main.tileSolidTop[tile.type])
2409 {
2410 num5 = i;
2411 num6 = j;
2412 if (num6 != num8)
2413 {
2414 result.X = vector4.X + 16f - vector3.X;
2415 }
2416 if (num7 == num5)
2417 {
2418 result.Y = vector.Y;
2419 }
2420 }
2421 else if (vector3.Y >= vector4.Y + (float)num9 && !Main.tileSolidTop[tile.type])
2422 {
2423 num7 = i;
2424 num8 = j;
2425 result.Y = vector4.Y + (float)num9 - vector3.Y + 0.01f;
2426 if (num8 == num6)
2427 {
2428 result.X = vector.X + 0.01f;
2429 }
2430 }
2431 }
2432 }
2433 return result;
2434 }
2435
2436 public static Vector2 AnyCollision(Vector2 Position, Vector2 Velocity, int Width, int Height, bool evenActuated = false)
2437 {
2438 Vector2 result = Velocity;
2439 Vector2 vector = Velocity;
2440 Vector2 vector2 = Position + Velocity;
2442 int num = (int)(Position.X / 16f) - 1;
2443 int num2 = (int)((Position.X + (float)Width) / 16f) + 2;
2444 int num3 = (int)(Position.Y / 16f) - 1;
2445 int num4 = (int)((Position.Y + (float)Height) / 16f) + 2;
2446 int num5 = -1;
2447 int num6 = -1;
2448 int num7 = -1;
2449 int num8 = -1;
2450 if (num < 0)
2451 {
2452 num = 0;
2453 }
2454 if (num2 > Main.maxTilesX)
2455 {
2457 }
2458 if (num3 < 0)
2459 {
2460 num3 = 0;
2461 }
2462 if (num4 > Main.maxTilesY)
2463 {
2465 }
2466 Vector2 vector4 = default(Vector2);
2467 for (int i = num; i < num2; i++)
2468 {
2469 for (int j = num3; j < num4; j++)
2470 {
2471 if (Main.tile[i, j] == null || !Main.tile[i, j].active() || (!evenActuated && Main.tile[i, j].inActive()))
2472 {
2473 continue;
2474 }
2475 vector4.X = i * 16;
2476 vector4.Y = j * 16;
2477 int num9 = 16;
2478 if (Main.tile[i, j].halfBrick())
2479 {
2480 vector4.Y += 8f;
2481 num9 -= 8;
2482 }
2483 if (!(vector2.X + (float)Width > vector4.X) || !(vector2.X < vector4.X + 16f) || !(vector2.Y + (float)Height > vector4.Y) || !(vector2.Y < vector4.Y + (float)num9))
2484 {
2485 continue;
2486 }
2487 if (vector3.Y + (float)Height <= vector4.Y)
2488 {
2489 num7 = i;
2490 num8 = j;
2491 if (num7 != num5)
2492 {
2493 result.Y = vector4.Y - (vector3.Y + (float)Height);
2494 }
2495 }
2496 else if (vector3.X + (float)Width <= vector4.X && !Main.tileSolidTop[Main.tile[i, j].type])
2497 {
2498 num5 = i;
2499 num6 = j;
2500 if (num6 != num8)
2501 {
2502 result.X = vector4.X - (vector3.X + (float)Width);
2503 }
2504 if (num7 == num5)
2505 {
2506 result.Y = vector.Y;
2507 }
2508 }
2509 else if (vector3.X >= vector4.X + 16f && !Main.tileSolidTop[Main.tile[i, j].type])
2510 {
2511 num5 = i;
2512 num6 = j;
2513 if (num6 != num8)
2514 {
2515 result.X = vector4.X + 16f - vector3.X;
2516 }
2517 if (num7 == num5)
2518 {
2519 result.Y = vector.Y;
2520 }
2521 }
2522 else if (vector3.Y >= vector4.Y + (float)num9 && !Main.tileSolidTop[Main.tile[i, j].type])
2523 {
2524 num7 = i;
2525 num8 = j;
2526 result.Y = vector4.Y + (float)num9 - vector3.Y + 0.01f;
2527 if (num8 == num6)
2528 {
2529 result.X = vector.X + 0.01f;
2530 }
2531 }
2532 }
2533 }
2534 return result;
2535 }
2536
2537 public static void HitTiles(Vector2 Position, Vector2 Velocity, int Width, int Height)
2538 {
2539 Vector2 vector = Position + Velocity;
2540 int num = (int)(Position.X / 16f) - 1;
2541 int num2 = (int)((Position.X + (float)Width) / 16f) + 2;
2542 int num3 = (int)(Position.Y / 16f) - 1;
2543 int num4 = (int)((Position.Y + (float)Height) / 16f) + 2;
2544 if (num < 0)
2545 {
2546 num = 0;
2547 }
2548 if (num2 > Main.maxTilesX)
2549 {
2551 }
2552 if (num3 < 0)
2553 {
2554 num3 = 0;
2555 }
2556 if (num4 > Main.maxTilesY)
2557 {
2559 }
2560 Vector2 vector2 = default(Vector2);
2561 for (int i = num; i < num2; i++)
2562 {
2563 for (int j = num3; j < num4; j++)
2564 {
2565 if (Main.tile[i, j] != null && !Main.tile[i, j].inActive() && Main.tile[i, j].active() && (Main.tileSolid[Main.tile[i, j].type] || (Main.tileSolidTop[Main.tile[i, j].type] && Main.tile[i, j].frameY == 0)))
2566 {
2567 vector2.X = i * 16;
2568 vector2.Y = j * 16;
2569 int num5 = 16;
2570 if (Main.tile[i, j].halfBrick())
2571 {
2572 vector2.Y += 8f;
2573 num5 -= 8;
2574 }
2575 if (vector.X + (float)Width >= vector2.X && vector.X <= vector2.X + 16f && vector.Y + (float)Height >= vector2.Y && vector.Y <= vector2.Y + (float)num5)
2576 {
2577 WorldGen.KillTile(i, j, fail: true, effectOnly: true);
2578 }
2579 }
2580 }
2581 }
2582 }
2583
2584 public static bool AnyHurtingTiles(Vector2 Position, int Width, int Height)
2585 {
2586 return HurtTiles(Position, Width, Height, null).type >= 0;
2587 }
2588
2589 public static HurtTile HurtTiles(Vector2 Position, int Width, int Height, Player player)
2590 {
2591 int num = (int)(Position.X / 16f) - 1;
2592 int num2 = (int)((Position.X + (float)Width) / 16f) + 2;
2593 int num3 = (int)(Position.Y / 16f) - 1;
2594 int num4 = (int)((Position.Y + (float)Height) / 16f) + 2;
2595 if (num < 0)
2596 {
2597 num = 0;
2598 }
2599 if (num2 > Main.maxTilesX)
2600 {
2602 }
2603 if (num3 < 0)
2604 {
2605 num3 = 0;
2606 }
2607 if (num4 > Main.maxTilesY)
2608 {
2610 }
2611 Vector2 vector = default(Vector2);
2612 HurtTile result;
2613 for (int i = num; i < num2; i++)
2614 {
2615 for (int j = num3; j < num4; j++)
2616 {
2617 Tile tile = Main.tile[i, j];
2618 if (tile == null || tile.inActive() || !tile.active())
2619 {
2620 continue;
2621 }
2622 vector.X = i * 16;
2623 vector.Y = j * 16;
2624 int num5 = 16;
2625 if (tile.halfBrick())
2626 {
2627 vector.Y += 8f;
2628 num5 -= 8;
2629 }
2630 int num6 = 0;
2631 if (TileID.Sets.Suffocate[tile.type])
2632 {
2633 num6 = 2;
2634 }
2635 if (Position.X + (float)Width - (float)num6 < vector.X || Position.X + (float)num6 > vector.X + 16f || Position.Y + (float)Height - (float)num6 < vector.Y - 0.5f || Position.Y + (float)num6 > vector.Y + (float)num5 + 0.5f || !CanTileHurt(tile.type, i, j, player))
2636 {
2637 continue;
2638 }
2639 if (tile.slope() > 0)
2640 {
2641 if (num6 > 0)
2642 {
2643 continue;
2644 }
2645 int num7 = 0;
2646 if (tile.rightSlope() && Position.X > vector.X)
2647 {
2648 num7++;
2649 }
2650 if (tile.leftSlope() && Position.X + (float)Width < vector.X + 16f)
2651 {
2652 num7++;
2653 }
2654 if (tile.bottomSlope() && Position.Y > vector.Y)
2655 {
2656 num7++;
2657 }
2658 if (tile.topSlope() && Position.Y + (float)Height < vector.Y + (float)num5)
2659 {
2660 num7++;
2661 }
2662 if (num7 == 2)
2663 {
2664 continue;
2665 }
2666 }
2667 result = default(HurtTile);
2668 result.type = tile.type;
2669 result.x = i;
2670 result.y = j;
2671 return result;
2672 }
2673 }
2674 result = default(HurtTile);
2675 result.type = -1;
2676 return result;
2677 }
2678
2679 public static bool CanTileHurt(ushort type, int i, int j, Player player)
2680 {
2681 if (type == 230 && !Main.getGoodWorld)
2682 {
2683 return false;
2684 }
2685 if (type == 80 && !Main.dontStarveWorld)
2686 {
2687 return false;
2688 }
2690 {
2691 return true;
2692 }
2693 if (TileID.Sets.TouchDamageHot[type] && (player == null || !player.fireWalk))
2694 {
2695 return true;
2696 }
2697 return false;
2698 }
2699
2700 public static bool SwitchTiles(Vector2 Position, int Width, int Height, Vector2 oldPosition, int objType)
2701 {
2702 int num = (int)(Position.X / 16f) - 1;
2703 int num2 = (int)((Position.X + (float)Width) / 16f) + 2;
2704 int num3 = (int)(Position.Y / 16f) - 1;
2705 int num4 = (int)((Position.Y + (float)Height) / 16f) + 2;
2706 if (num < 0)
2707 {
2708 num = 0;
2709 }
2710 if (num2 > Main.maxTilesX)
2711 {
2713 }
2714 if (num3 < 0)
2715 {
2716 num3 = 0;
2717 }
2718 if (num4 > Main.maxTilesY)
2719 {
2721 }
2722 Vector2 vector = default(Vector2);
2723 for (int i = num; i < num2; i++)
2724 {
2725 for (int j = num3; j < num4; j++)
2726 {
2727 if (Main.tile[i, j] == null)
2728 {
2729 continue;
2730 }
2731 int type = Main.tile[i, j].type;
2732 if (!Main.tile[i, j].active() || (type != 135 && type != 210 && type != 443 && type != 442))
2733 {
2734 continue;
2735 }
2736 vector.X = i * 16;
2737 vector.Y = j * 16 + 12;
2738 bool flag = false;
2739 if (type == 442)
2740 {
2741 if (objType == 4)
2742 {
2743 float r1StartX = 0f;
2744 float r1StartY = 0f;
2745 float r1Width = 0f;
2746 float r1Height = 0f;
2747 switch (Main.tile[i, j].frameX / 22)
2748 {
2749 case 0:
2750 r1StartX = i * 16;
2751 r1StartY = j * 16 + 16 - 10;
2752 r1Width = 16f;
2753 r1Height = 10f;
2754 break;
2755 case 1:
2756 r1StartX = i * 16;
2757 r1StartY = j * 16;
2758 r1Width = 16f;
2759 r1Height = 10f;
2760 break;
2761 case 2:
2762 r1StartX = i * 16;
2763 r1StartY = j * 16;
2764 r1Width = 10f;
2765 r1Height = 16f;
2766 break;
2767 case 3:
2768 r1StartX = i * 16 + 16 - 10;
2769 r1StartY = j * 16;
2770 r1Width = 10f;
2771 r1Height = 16f;
2772 break;
2773 }
2774 if (Utils.FloatIntersect(r1StartX, r1StartY, r1Width, r1Height, Position.X, Position.Y, Width, Height) && !Utils.FloatIntersect(r1StartX, r1StartY, r1Width, r1Height, oldPosition.X, oldPosition.Y, Width, Height))
2775 {
2776 Wiring.HitSwitch(i, j);
2777 NetMessage.SendData(59, -1, -1, null, i, j);
2778 return true;
2779 }
2780 }
2781 flag = true;
2782 }
2783 if (flag || !(Position.X + (float)Width > vector.X) || !(Position.X < vector.X + 16f) || !(Position.Y + (float)Height > vector.Y) || !((double)Position.Y < (double)vector.Y + 4.01))
2784 {
2785 continue;
2786 }
2787 if (type == 210)
2788 {
2789 WorldGen.ExplodeMine(i, j, fromWiring: false);
2790 }
2791 else
2792 {
2793 if (oldPosition.X + (float)Width > vector.X && oldPosition.X < vector.X + 16f && oldPosition.Y + (float)Height > vector.Y && (double)oldPosition.Y < (double)vector.Y + 16.01)
2794 {
2795 continue;
2796 }
2797 if (type == 443)
2798 {
2799 if (objType == 1)
2800 {
2801 Wiring.HitSwitch(i, j);
2802 NetMessage.SendData(59, -1, -1, null, i, j);
2803 }
2804 continue;
2805 }
2806 int num5 = Main.tile[i, j].frameY / 18;
2807 bool flag2 = true;
2808 if ((num5 == 4 || num5 == 2 || num5 == 3 || num5 == 6 || num5 == 7) && objType != 1)
2809 {
2810 flag2 = false;
2811 }
2812 if (num5 == 5 && (objType == 1 || objType == 4))
2813 {
2814 flag2 = false;
2815 }
2816 if (!flag2)
2817 {
2818 continue;
2819 }
2820 Wiring.HitSwitch(i, j);
2821 NetMessage.SendData(59, -1, -1, null, i, j);
2822 if (num5 == 7)
2823 {
2824 WorldGen.KillTile(i, j);
2825 if (Main.netMode == 1)
2826 {
2827 NetMessage.SendData(17, -1, -1, null, 0, i, j);
2828 }
2829 }
2830 return true;
2831 }
2832 }
2833 }
2834 return false;
2835 }
2836
2837 public bool SwitchTilesNew(Vector2 Position, int Width, int Height, Vector2 oldPosition, int objType)
2838 {
2839 Point point = Position.ToTileCoordinates();
2840 Point point2 = (Position + new Vector2(Width, Height)).ToTileCoordinates();
2841 int num = Utils.Clamp(point.X, 0, Main.maxTilesX - 1);
2842 int num2 = Utils.Clamp(point.Y, 0, Main.maxTilesY - 1);
2843 int num3 = Utils.Clamp(point2.X, 0, Main.maxTilesX - 1);
2844 int num4 = Utils.Clamp(point2.Y, 0, Main.maxTilesY - 1);
2845 for (int i = num; i <= num3; i++)
2846 {
2847 for (int j = num2; j <= num4; j++)
2848 {
2849 if (Main.tile[i, j] != null)
2850 {
2851 _ = Main.tile[i, j].type;
2852 _ = 130;
2853 }
2854 }
2855 }
2856 return false;
2857 }
2858
2859 public static Vector2 StickyTiles(Vector2 Position, Vector2 Velocity, int Width, int Height)
2860 {
2862 int num = (int)(Position.X / 16f) - 1;
2863 int num2 = (int)((Position.X + (float)Width) / 16f) + 2;
2864 int num3 = (int)(Position.Y / 16f) - 1;
2865 int num4 = (int)((Position.Y + (float)Height) / 16f) + 2;
2866 if (num < 0)
2867 {
2868 num = 0;
2869 }
2870 if (num2 > Main.maxTilesX)
2871 {
2873 }
2874 if (num3 < 0)
2875 {
2876 num3 = 0;
2877 }
2878 if (num4 > Main.maxTilesY)
2879 {
2881 }
2882 Vector2 vector2 = default(Vector2);
2883 for (int i = num; i < num2; i++)
2884 {
2885 for (int j = num3; j < num4; j++)
2886 {
2887 if (Main.tile[i, j] == null || !Main.tile[i, j].active() || Main.tile[i, j].inActive())
2888 {
2889 continue;
2890 }
2891 if (Main.tile[i, j].type == 51)
2892 {
2893 int num5 = 0;
2894 vector2.X = i * 16;
2895 vector2.Y = j * 16;
2896 if (vector.X + (float)Width > vector2.X - (float)num5 && vector.X < vector2.X + 16f + (float)num5 && vector.Y + (float)Height > vector2.Y && (double)vector.Y < (double)vector2.Y + 16.01)
2897 {
2898 if (Main.tile[i, j].type == 51 && (double)(Math.Abs(Velocity.X) + Math.Abs(Velocity.Y)) > 0.7 && Main.rand.Next(30) == 0)
2899 {
2900 Dust.NewDust(new Vector2(i * 16, j * 16), 16, 16, 30);
2901 }
2902 return new Vector2(i, j);
2903 }
2904 }
2905 else
2906 {
2907 if (Main.tile[i, j].type != 229 || Main.tile[i, j].slope() != 0)
2908 {
2909 continue;
2910 }
2911 int num6 = 1;
2912 vector2.X = i * 16;
2913 vector2.Y = j * 16;
2914 float num7 = 16.01f;
2915 if (Main.tile[i, j].halfBrick())
2916 {
2917 vector2.Y += 8f;
2918 num7 -= 8f;
2919 }
2920 if (vector.X + (float)Width > vector2.X - (float)num6 && vector.X < vector2.X + 16f + (float)num6 && vector.Y + (float)Height > vector2.Y && vector.Y < vector2.Y + num7)
2921 {
2922 if (Main.tile[i, j].type == 51 && (double)(Math.Abs(Velocity.X) + Math.Abs(Velocity.Y)) > 0.7 && Main.rand.Next(30) == 0)
2923 {
2924 Dust.NewDust(new Vector2(i * 16, j * 16), 16, 16, 30);
2925 }
2926 return new Vector2(i, j);
2927 }
2928 }
2929 }
2930 }
2931 return new Vector2(-1f, -1f);
2932 }
2933
2934 public static bool SolidTilesVersatile(int startX, int endX, int startY, int endY)
2935 {
2936 if (startX > endX)
2937 {
2938 Utils.Swap(ref startX, ref endX);
2939 }
2940 if (startY > endY)
2941 {
2942 Utils.Swap(ref startY, ref endY);
2943 }
2944 return SolidTiles(startX, endX, startY, endY);
2945 }
2946
2947 public static bool SolidTiles(Vector2 position, int width, int height)
2948 {
2949 return SolidTiles((int)(position.X / 16f), (int)((position.X + (float)width) / 16f), (int)(position.Y / 16f), (int)((position.Y + (float)height) / 16f));
2950 }
2951
2952 public static bool SolidTiles(int startX, int endX, int startY, int endY)
2953 {
2954 if (startX < 0)
2955 {
2956 return true;
2957 }
2958 if (endX >= Main.maxTilesX)
2959 {
2960 return true;
2961 }
2962 if (startY < 0)
2963 {
2964 return true;
2965 }
2966 if (endY >= Main.maxTilesY)
2967 {
2968 return true;
2969 }
2970 for (int i = startX; i < endX + 1; i++)
2971 {
2972 for (int j = startY; j < endY + 1; j++)
2973 {
2974 if (Main.tile[i, j] == null)
2975 {
2976 return false;
2977 }
2978 if (Main.tile[i, j].active() && !Main.tile[i, j].inActive() && Main.tileSolid[Main.tile[i, j].type] && !Main.tileSolidTop[Main.tile[i, j].type])
2979 {
2980 return true;
2981 }
2982 }
2983 }
2984 return false;
2985 }
2986
2987 public static bool SolidTiles(Vector2 position, int width, int height, bool allowTopSurfaces)
2988 {
2989 return SolidTiles((int)(position.X / 16f), (int)((position.X + (float)width) / 16f), (int)(position.Y / 16f), (int)((position.Y + (float)height) / 16f), allowTopSurfaces);
2990 }
2991
2992 public static bool SolidTiles(int startX, int endX, int startY, int endY, bool allowTopSurfaces)
2993 {
2994 if (startX < 0)
2995 {
2996 return true;
2997 }
2998 if (endX >= Main.maxTilesX)
2999 {
3000 return true;
3001 }
3002 if (startY < 0)
3003 {
3004 return true;
3005 }
3006 if (endY >= Main.maxTilesY)
3007 {
3008 return true;
3009 }
3010 for (int i = startX; i < endX + 1; i++)
3011 {
3012 for (int j = startY; j < endY + 1; j++)
3013 {
3014 Tile tile = Main.tile[i, j];
3015 if (tile == null)
3016 {
3017 return false;
3018 }
3019 if (tile.active() && !Main.tile[i, j].inActive())
3020 {
3021 ushort type = tile.type;
3022 bool flag = Main.tileSolid[type] && !Main.tileSolidTop[type];
3023 if (allowTopSurfaces)
3024 {
3025 flag |= Main.tileSolidTop[type] && tile.frameY == 0;
3026 }
3027 if (flag)
3028 {
3029 return true;
3030 }
3031 }
3032 }
3033 }
3034 return false;
3035 }
3036
3037 public static void StepDown(ref Vector2 position, ref Vector2 velocity, int width, int height, ref float stepSpeed, ref float gfxOffY, int gravDir = 1, bool waterWalk = false)
3038 {
3039 Vector2 vector = position;
3040 vector.X += velocity.X;
3041 vector.Y = (float)Math.Floor((vector.Y + (float)height) / 16f) * 16f - (float)height;
3042 bool flag = false;
3043 int num = (int)(vector.X / 16f);
3044 int num2 = (int)((vector.X + (float)width) / 16f);
3045 int num3 = (int)((vector.Y + (float)height + 4f) / 16f);
3046 int num4 = height / 16 + ((height % 16 != 0) ? 1 : 0);
3047 float num5 = (num3 + num4) * 16;
3048 float num6 = Main.bottomWorld / 16f - 42f;
3049 for (int i = num; i <= num2; i++)
3050 {
3051 for (int j = num3; j <= num3 + 1; j++)
3052 {
3053 if (!WorldGen.InWorld(i, j, 1))
3054 {
3055 continue;
3056 }
3057 if (Main.tile[i, j] == null)
3058 {
3059 Main.tile[i, j] = new Tile();
3060 }
3061 if (Main.tile[i, j - 1] == null)
3062 {
3063 Main.tile[i, j - 1] = new Tile();
3064 }
3065 if (waterWalk && Main.tile[i, j].liquid > 0 && Main.tile[i, j - 1].liquid == 0)
3066 {
3067 int num7 = Main.tile[i, j].liquid / 32 * 2 + 2;
3068 int num8 = j * 16 + 16 - num7;
3069 if (new Rectangle(i * 16, j * 16 - 17, 16, 16).Intersects(new Rectangle((int)position.X, (int)position.Y, width, height)) && (float)num8 < num5)
3070 {
3071 num5 = num8;
3072 }
3073 }
3074 if ((float)j >= num6 || (Main.tile[i, j].nactive() && (Main.tileSolid[Main.tile[i, j].type] || Main.tileSolidTop[Main.tile[i, j].type])))
3075 {
3076 int num9 = j * 16;
3077 if (Main.tile[i, j].halfBrick())
3078 {
3079 num9 += 8;
3080 }
3081 if (Utils.FloatIntersect(i * 16, j * 16 - 17, 16f, 16f, position.X, position.Y, width, height) && (float)num9 < num5)
3082 {
3083 num5 = num9;
3084 }
3085 }
3086 }
3087 }
3088 float num10 = num5 - (position.Y + (float)height);
3089 if (num10 > 7f && num10 < 17f && !flag)
3090 {
3091 stepSpeed = 1.5f;
3092 if (num10 > 9f)
3093 {
3094 stepSpeed = 2.5f;
3095 }
3096 gfxOffY += position.Y + (float)height - num5;
3097 position.Y = num5 - (float)height;
3098 }
3099 }
3100
3101 public static void StepUp(ref Vector2 position, ref Vector2 velocity, int width, int height, ref float stepSpeed, ref float gfxOffY, int gravDir = 1, bool holdsMatching = false, int specialChecksMode = 0)
3102 {
3103 int num = 0;
3104 if (velocity.X < 0f)
3105 {
3106 num = -1;
3107 }
3108 if (velocity.X > 0f)
3109 {
3110 num = 1;
3111 }
3112 Vector2 vector = position;
3113 vector.X += velocity.X;
3114 int num2 = (int)((vector.X + (float)(width / 2) + (float)((width / 2 + 1) * num)) / 16f);
3115 int num3 = (int)(((double)vector.Y + 0.1) / 16.0);
3116 if (gravDir == 1)
3117 {
3118 num3 = (int)((vector.Y + (float)height - 1f) / 16f);
3119 }
3120 int num4 = height / 16 + ((height % 16 != 0) ? 1 : 0);
3121 bool flag = true;
3122 bool flag2 = true;
3123 if (Main.tile[num2, num3] == null)
3124 {
3125 return;
3126 }
3127 for (int i = 1; i < num4 + 2; i++)
3128 {
3129 if (!WorldGen.InWorld(num2, num3 - i * gravDir) || Main.tile[num2, num3 - i * gravDir] == null)
3130 {
3131 return;
3132 }
3133 }
3134 if (!WorldGen.InWorld(num2 - num, num3 - num4 * gravDir) || Main.tile[num2 - num, num3 - num4 * gravDir] == null)
3135 {
3136 return;
3137 }
3138 Tile tile;
3139 for (int j = 2; j < num4 + 1; j++)
3140 {
3141 if (!WorldGen.InWorld(num2, num3 - j * gravDir) || Main.tile[num2, num3 - j * gravDir] == null)
3142 {
3143 return;
3144 }
3145 tile = Main.tile[num2, num3 - j * gravDir];
3146 flag = flag && (!tile.nactive() || !Main.tileSolid[tile.type] || Main.tileSolidTop[tile.type]);
3147 }
3148 tile = Main.tile[num2 - num, num3 - num4 * gravDir];
3149 flag2 = flag2 && (!tile.nactive() || !Main.tileSolid[tile.type] || Main.tileSolidTop[tile.type]);
3150 bool flag3 = true;
3151 bool flag4 = true;
3152 bool flag5 = true;
3153 Tile tile2;
3154 if (gravDir == 1)
3155 {
3156 if (Main.tile[num2, num3 - gravDir] == null || Main.tile[num2, num3 - (num4 + 1) * gravDir] == null)
3157 {
3158 return;
3159 }
3160 tile = Main.tile[num2, num3 - gravDir];
3161 tile2 = Main.tile[num2, num3 - (num4 + 1) * gravDir];
3162 flag3 = flag3 && (!tile.nactive() || !Main.tileSolid[tile.type] || Main.tileSolidTop[tile.type] || (tile.slope() == 1 && position.X + (float)(width / 2) > (float)(num2 * 16)) || (tile.slope() == 2 && position.X + (float)(width / 2) < (float)(num2 * 16 + 16)) || (tile.halfBrick() && (!tile2.nactive() || !Main.tileSolid[tile2.type] || Main.tileSolidTop[tile2.type])));
3163 tile = Main.tile[num2, num3];
3164 tile2 = Main.tile[num2, num3 - 1];
3165 if (specialChecksMode == 1)
3166 {
3167 flag5 = tile.type != 16 && tile.type != 18 && tile.type != 14 && tile.type != 469 && tile.type != 134;
3168 }
3169 flag4 = flag4 && ((tile.nactive() && (!tile.topSlope() || (tile.slope() == 1 && position.X + (float)(width / 2) < (float)(num2 * 16)) || (tile.slope() == 2 && position.X + (float)(width / 2) > (float)(num2 * 16 + 16))) && (!tile.topSlope() || position.Y + (float)height > (float)(num3 * 16)) && ((Main.tileSolid[tile.type] && !Main.tileSolidTop[tile.type]) || (holdsMatching && ((Main.tileSolidTop[tile.type] && tile.frameY == 0) || TileID.Sets.Platforms[tile.type]) && (!Main.tileSolid[tile2.type] || !tile2.nactive()) && flag5))) || (tile2.halfBrick() && tile2.nactive()));
3170 flag4 &= !Main.tileSolidTop[tile.type] || !Main.tileSolidTop[tile2.type];
3171 }
3172 else
3173 {
3174 tile = Main.tile[num2, num3 - gravDir];
3175 tile2 = Main.tile[num2, num3 - (num4 + 1) * gravDir];
3176 flag3 = flag3 && (!tile.nactive() || !Main.tileSolid[tile.type] || Main.tileSolidTop[tile.type] || tile.slope() != 0 || (tile.halfBrick() && (!tile2.nactive() || !Main.tileSolid[tile2.type] || Main.tileSolidTop[tile2.type])));
3177 tile = Main.tile[num2, num3];
3178 tile2 = Main.tile[num2, num3 + 1];
3179 flag4 = flag4 && ((tile.nactive() && ((Main.tileSolid[tile.type] && !Main.tileSolidTop[tile.type]) || (holdsMatching && Main.tileSolidTop[tile.type] && tile.frameY == 0 && (!Main.tileSolid[tile2.type] || !tile2.nactive())))) || (tile2.halfBrick() && tile2.nactive()));
3180 }
3181 if (!((float)(num2 * 16) < vector.X + (float)width) || !((float)(num2 * 16 + 16) > vector.X))
3182 {
3183 return;
3184 }
3185 if (gravDir == 1)
3186 {
3187 if (!(flag4 && flag3 && flag && flag2))
3188 {
3189 return;
3190 }
3191 float num5 = num3 * 16;
3192 if (Main.tile[num2, num3 - 1].halfBrick())
3193 {
3194 num5 -= 8f;
3195 }
3196 else if (Main.tile[num2, num3].halfBrick())
3197 {
3198 num5 += 8f;
3199 }
3200 if (!(num5 < vector.Y + (float)height))
3201 {
3202 return;
3203 }
3204 float num6 = vector.Y + (float)height - num5;
3205 if ((double)num6 <= 16.1)
3206 {
3207 gfxOffY += position.Y + (float)height - num5;
3208 position.Y = num5 - (float)height;
3209 if (num6 < 9f)
3210 {
3211 stepSpeed = 1f;
3212 }
3213 else
3214 {
3215 stepSpeed = 2f;
3216 }
3217 }
3218 }
3219 else
3220 {
3221 if (!(flag4 && flag3 && flag && flag2) || Main.tile[num2, num3].bottomSlope() || TileID.Sets.Platforms[tile2.type])
3222 {
3223 return;
3224 }
3225 float num7 = num3 * 16 + 16;
3226 if (!(num7 > vector.Y))
3227 {
3228 return;
3229 }
3230 float num8 = num7 - vector.Y;
3231 if ((double)num8 <= 16.1)
3232 {
3233 gfxOffY -= num7 - position.Y;
3234 position.Y = num7;
3235 velocity.Y = 0f;
3236 if (num8 < 9f)
3237 {
3238 stepSpeed = 1f;
3239 }
3240 else
3241 {
3242 stepSpeed = 2f;
3243 }
3244 }
3245 }
3246 }
3247
3248 public static bool InTileBounds(int x, int y, int lx, int ly, int hx, int hy)
3249 {
3251 {
3252 return false;
3253 }
3254 return true;
3255 }
3256
3257 public static float GetTileRotation(Vector2 position)
3258 {
3259 float num = position.Y % 16f;
3260 int num2 = (int)(position.X / 16f);
3261 int num3 = (int)(position.Y / 16f);
3262 Tile tile = Main.tile[num2, num3];
3263 bool flag = false;
3264 for (int num4 = 2; num4 >= 0; num4--)
3265 {
3266 if (tile.active())
3267 {
3268 if (Main.tileSolid[tile.type])
3269 {
3270 int num5 = tile.blockType();
3271 if (tile.type != 19)
3272 {
3273 return num5 switch
3274 {
3275 1 => 0f,
3276 2 => (float)Math.PI / 4f,
3277 3 => -(float)Math.PI / 4f,
3278 _ => 0f,
3279 };
3280 }
3281 int num6 = tile.frameX / 18;
3282 if (((num6 >= 0 && num6 <= 7) || (num6 >= 12 && num6 <= 16)) && (num == 0f || flag))
3283 {
3284 return 0f;
3285 }
3286 switch (num6)
3287 {
3288 case 8:
3289 case 19:
3290 case 21:
3291 case 23:
3292 return -(float)Math.PI / 4f;
3293 case 10:
3294 case 20:
3295 case 22:
3296 case 24:
3297 return (float)Math.PI / 4f;
3298 case 25:
3299 case 26:
3300 if (!flag)
3301 {
3302 switch (num5)
3303 {
3304 case 2:
3305 return (float)Math.PI / 4f;
3306 case 3:
3307 return -(float)Math.PI / 4f;
3308 }
3309 break;
3310 }
3311 return 0f;
3312 }
3313 }
3314 else if (Main.tileSolidTop[tile.type] && tile.frameY == 0 && flag)
3315 {
3316 return 0f;
3317 }
3318 }
3319 num3++;
3320 tile = Main.tile[num2, num3];
3321 flag = true;
3322 }
3323 return 0f;
3324 }
3325
3326 public static void GetEntityEdgeTiles(List<Point> p, Entity entity, bool left = true, bool right = true, bool up = true, bool down = true)
3327 {
3328 int num = (int)entity.position.X;
3329 int num2 = (int)entity.position.Y;
3330 _ = num % 16;
3331 _ = num2 % 16;
3332 int num3 = (int)entity.Right.X;
3333 int num4 = (int)entity.Bottom.Y;
3334 if (num % 16 == 0)
3335 {
3336 num--;
3337 }
3338 if (num2 % 16 == 0)
3339 {
3340 num2--;
3341 }
3342 if (num3 % 16 == 0)
3343 {
3344 num3++;
3345 }
3346 if (num4 % 16 == 0)
3347 {
3348 num4++;
3349 }
3350 int num5 = num3 / 16 - num / 16;
3351 int num6 = num4 / 16 - num2 / 16;
3352 num /= 16;
3353 num2 /= 16;
3354 for (int i = num; i <= num + num5; i++)
3355 {
3356 if (up)
3357 {
3358 p.Add(new Point(i, num2));
3359 }
3360 if (down)
3361 {
3362 p.Add(new Point(i, num2 + num6));
3363 }
3364 }
3365 for (int j = num2; j < num2 + num6; j++)
3366 {
3367 if (left)
3368 {
3369 p.Add(new Point(num, j));
3370 }
3371 if (right)
3372 {
3373 p.Add(new Point(num + num5, j));
3374 }
3375 }
3376 }
3377
3378 public static void StepConveyorBelt(Entity entity, float gravDir)
3379 {
3380 Player player = null;
3381 if (entity is Player)
3382 {
3383 player = (Player)entity;
3384 if (Math.Abs(player.gfxOffY) > 2f || player.grapCount > 0 || player.pulley)
3385 {
3386 return;
3387 }
3388 entity.height -= 5;
3389 entity.position.Y += 5f;
3390 }
3391 int num = 0;
3392 int num2 = 0;
3393 bool flag = false;
3394 int num3 = (int)entity.position.Y + entity.height;
3395 entity.Hitbox.Inflate(2, 2);
3396 _ = entity.TopLeft;
3397 _ = entity.TopRight;
3398 _ = entity.BottomLeft;
3399 _ = entity.BottomRight;
3402 GetEntityEdgeTiles(cacheForConveyorBelts, entity, left: false, right: false);
3403 Vector2 vector = new Vector2(0.0001f);
3404 Vector2 lineStart = default(Vector2);
3405 Vector2 lineStart2 = default(Vector2);
3406 Vector2 lineEnd = default(Vector2);
3407 Vector2 lineEnd2 = default(Vector2);
3408 for (int i = 0; i < cacheForConveyorBelts.Count; i++)
3409 {
3410 Point point = cacheForConveyorBelts[i];
3411 if (!WorldGen.InWorld(point.X, point.Y) || (player != null && player.onTrack && point.Y < num3))
3412 {
3413 continue;
3414 }
3415 Tile tile = Main.tile[point.X, point.Y];
3416 if (tile == null || !tile.active() || !tile.nactive())
3417 {
3418 continue;
3419 }
3421 if (num4 == 0)
3422 {
3423 continue;
3424 }
3425 lineStart.X = (lineStart2.X = point.X * 16);
3426 lineEnd.X = (lineEnd2.X = point.X * 16 + 16);
3427 switch (tile.slope())
3428 {
3429 case 1:
3430 lineStart2.Y = point.Y * 16;
3431 lineEnd2.Y = (lineEnd.Y = (lineStart.Y = point.Y * 16 + 16));
3432 break;
3433 case 2:
3434 lineEnd2.Y = point.Y * 16;
3435 lineStart2.Y = (lineEnd.Y = (lineStart.Y = point.Y * 16 + 16));
3436 break;
3437 case 3:
3438 lineEnd.Y = (lineStart2.Y = (lineEnd2.Y = point.Y * 16));
3439 lineStart.Y = point.Y * 16 + 16;
3440 break;
3441 case 4:
3442 lineStart.Y = (lineStart2.Y = (lineEnd2.Y = point.Y * 16));
3443 lineEnd.Y = point.Y * 16 + 16;
3444 break;
3445 default:
3446 if (tile.halfBrick())
3447 {
3448 lineStart2.Y = (lineEnd2.Y = point.Y * 16 + 8);
3449 }
3450 else
3451 {
3452 lineStart2.Y = (lineEnd2.Y = point.Y * 16);
3453 }
3454 lineStart.Y = (lineEnd.Y = point.Y * 16 + 16);
3455 break;
3456 }
3457 int num5 = 0;
3458 if (!TileID.Sets.Platforms[tile.type] && CheckAABBvLineCollision2(entity.position - vector, entity.Size + vector * 2f, lineStart, lineEnd))
3459 {
3460 num5--;
3461 }
3462 if (CheckAABBvLineCollision2(entity.position - vector, entity.Size + vector * 2f, lineStart2, lineEnd2))
3463 {
3464 num5++;
3465 }
3466 if (num5 != 0)
3467 {
3468 flag = true;
3469 num += num4 * num5 * (int)gravDir;
3470 if (tile.leftSlope())
3471 {
3472 num2 += (int)gravDir * -num4;
3473 }
3474 if (tile.rightSlope())
3475 {
3476 num2 -= (int)gravDir * -num4;
3477 }
3478 }
3479 }
3480 if (entity is Player)
3481 {
3482 entity.height += 5;
3483 entity.position.Y -= 5f;
3484 }
3485 if (flag && num != 0)
3486 {
3487 num = Math.Sign(num);
3488 num2 = Math.Sign(num2);
3489 Vector2 velocity = Vector2.Normalize(new Vector2((float)num * gravDir, num2)) * 2.5f;
3490 Vector2 vector2 = TileCollision(entity.position, velocity, entity.width, entity.height, fallThrough: false, fall2: false, (int)gravDir);
3491 entity.position += vector2;
3492 vector2 = TileCollision(Velocity: new Vector2(0f, 2.5f * gravDir), Position: entity.position, Width: entity.width, Height: entity.height, fallThrough: false, fall2: false, gravDir: (int)gravDir);
3493 entity.position += vector2;
3494 }
3495 }
3496
3497 public static List<Point> GetTilesIn(Vector2 TopLeft, Vector2 BottomRight)
3498 {
3500 Point point = TopLeft.ToTileCoordinates();
3501 Point point2 = BottomRight.ToTileCoordinates();
3502 int num = Utils.Clamp(point.X, 0, Main.maxTilesX - 1);
3503 int num2 = Utils.Clamp(point.Y, 0, Main.maxTilesY - 1);
3504 int num3 = Utils.Clamp(point2.X, 0, Main.maxTilesX - 1);
3505 int num4 = Utils.Clamp(point2.Y, 0, Main.maxTilesY - 1);
3506 for (int i = num; i <= num3; i++)
3507 {
3508 for (int j = num2; j <= num4; j++)
3509 {
3510 if (Main.tile[i, j] != null)
3511 {
3512 list.Add(new Point(i, j));
3513 }
3514 }
3515 }
3516 return list;
3517 }
3518
3519 public static void ExpandVertically(int startX, int startY, out int topY, out int bottomY, int maxExpandUp = 100, int maxExpandDown = 100)
3520 {
3521 topY = startY;
3522 bottomY = startY;
3523 if (!WorldGen.InWorld(startX, startY, 10))
3524 {
3525 return;
3526 }
3527 for (int i = 0; i < maxExpandUp; i++)
3528 {
3529 if (topY <= 0)
3530 {
3531 break;
3532 }
3533 if (topY < 10)
3534 {
3535 break;
3536 }
3537 if (Main.tile[startX, topY] == null)
3538 {
3539 break;
3540 }
3542 {
3543 break;
3544 }
3545 topY--;
3546 }
3547 for (int j = 0; j < maxExpandDown; j++)
3548 {
3549 if (bottomY >= Main.maxTilesY - 10)
3550 {
3551 break;
3552 }
3553 if (bottomY > Main.maxTilesY - 10)
3554 {
3555 break;
3556 }
3557 if (Main.tile[startX, bottomY] == null)
3558 {
3559 break;
3560 }
3562 {
3563 break;
3564 }
3565 bottomY++;
3566 }
3567 }
3568
3569 public static Vector2 AdvancedTileCollision(bool[] forcedIgnoredTiles, Vector2 Position, Vector2 Velocity, int Width, int Height, bool fallThrough = false, bool fall2 = false, int gravDir = 1)
3570 {
3571 up = false;
3572 down = false;
3573 Vector2 result = Velocity;
3574 Vector2 vector = Velocity;
3575 Vector2 vector2 = Position + Velocity;
3577 int value = (int)(Position.X / 16f) - 1;
3578 int value2 = (int)((Position.X + (float)Width) / 16f) + 2;
3579 int value3 = (int)(Position.Y / 16f) - 1;
3580 int value4 = (int)((Position.Y + (float)Height) / 16f) + 2;
3581 int num = -1;
3582 int num2 = -1;
3583 int num3 = -1;
3584 int num4 = -1;
3585 int num5 = Utils.Clamp(value, 0, Main.maxTilesX - 1);
3586 value2 = Utils.Clamp(value2, 0, Main.maxTilesX - 1);
3587 value3 = Utils.Clamp(value3, 0, Main.maxTilesY - 1);
3588 value4 = Utils.Clamp(value4, 0, Main.maxTilesY - 1);
3589 float num6 = (value4 + 3) * 16;
3590 Vector2 vector4 = default(Vector2);
3591 for (int i = num5; i < value2; i++)
3592 {
3593 for (int j = value3; j < value4; j++)
3594 {
3595 Tile tile = Main.tile[i, j];
3596 if (tile == null || !tile.active() || tile.inActive() || forcedIgnoredTiles[tile.type] || (!Main.tileSolid[tile.type] && (!Main.tileSolidTop[tile.type] || tile.frameY != 0)))
3597 {
3598 continue;
3599 }
3600 vector4.X = i * 16;
3601 vector4.Y = j * 16;
3602 int num7 = 16;
3603 if (tile.halfBrick())
3604 {
3605 vector4.Y += 8f;
3606 num7 -= 8;
3607 }
3608 if (!(vector2.X + (float)Width > vector4.X) || !(vector2.X < vector4.X + 16f) || !(vector2.Y + (float)Height > vector4.Y) || !(vector2.Y < vector4.Y + (float)num7))
3609 {
3610 continue;
3611 }
3612 bool flag = false;
3613 bool flag2 = false;
3614 if (tile.slope() > 2)
3615 {
3616 if (tile.slope() == 3 && vector3.Y + Math.Abs(Velocity.X) >= vector4.Y && vector3.X >= vector4.X)
3617 {
3618 flag2 = true;
3619 }
3620 if (tile.slope() == 4 && vector3.Y + Math.Abs(Velocity.X) >= vector4.Y && vector3.X + (float)Width <= vector4.X + 16f)
3621 {
3622 flag2 = true;
3623 }
3624 }
3625 else if (tile.slope() > 0)
3626 {
3627 flag = true;
3628 if (tile.slope() == 1 && vector3.Y + (float)Height - Math.Abs(Velocity.X) <= vector4.Y + (float)num7 && vector3.X >= vector4.X)
3629 {
3630 flag2 = true;
3631 }
3632 if (tile.slope() == 2 && vector3.Y + (float)Height - Math.Abs(Velocity.X) <= vector4.Y + (float)num7 && vector3.X + (float)Width <= vector4.X + 16f)
3633 {
3634 flag2 = true;
3635 }
3636 }
3637 if (flag2)
3638 {
3639 continue;
3640 }
3641 if (vector3.Y + (float)Height <= vector4.Y)
3642 {
3643 down = true;
3644 if ((!(Main.tileSolidTop[tile.type] && fallThrough) || !(Velocity.Y <= 1f || fall2)) && num6 > vector4.Y)
3645 {
3646 num3 = i;
3647 num4 = j;
3648 if (num7 < 16)
3649 {
3650 num4++;
3651 }
3652 if (num3 != num && !flag)
3653 {
3654 result.Y = vector4.Y - (vector3.Y + (float)Height) + ((gravDir == -1) ? (-0.01f) : 0f);
3655 num6 = vector4.Y;
3656 }
3657 }
3658 }
3659 else if (vector3.X + (float)Width <= vector4.X && !Main.tileSolidTop[tile.type])
3660 {
3661 if (Main.tile[i - 1, j] == null)
3662 {
3663 Main.tile[i - 1, j] = new Tile();
3664 }
3665 if (Main.tile[i - 1, j].slope() != 2 && Main.tile[i - 1, j].slope() != 4)
3666 {
3667 num = i;
3668 num2 = j;
3669 if (num2 != num4)
3670 {
3671 result.X = vector4.X - (vector3.X + (float)Width);
3672 }
3673 if (num3 == num)
3674 {
3675 result.Y = vector.Y;
3676 }
3677 }
3678 }
3679 else if (vector3.X >= vector4.X + 16f && !Main.tileSolidTop[tile.type])
3680 {
3681 if (Main.tile[i + 1, j] == null)
3682 {
3683 Main.tile[i + 1, j] = new Tile();
3684 }
3685 if (Main.tile[i + 1, j].slope() != 1 && Main.tile[i + 1, j].slope() != 3)
3686 {
3687 num = i;
3688 num2 = j;
3689 if (num2 != num4)
3690 {
3691 result.X = vector4.X + 16f - vector3.X;
3692 }
3693 if (num3 == num)
3694 {
3695 result.Y = vector.Y;
3696 }
3697 }
3698 }
3699 else if (vector3.Y >= vector4.Y + (float)num7 && !Main.tileSolidTop[tile.type])
3700 {
3701 up = true;
3702 num3 = i;
3703 num4 = j;
3704 result.Y = vector4.Y + (float)num7 - vector3.Y + ((gravDir == 1) ? 0.01f : 0f);
3705 if (num4 == num2)
3706 {
3707 result.X = vector.X;
3708 }
3709 }
3710 }
3711 }
3712 return result;
3713 }
3714
3716 {
3717 for (int i = 0; i < samples.Length; i++)
3718 {
3719 float num = (float)i / (float)(samples.Length - 1);
3720 Vector2 vector = samplingPoint + directionUnit.RotatedBy(1.5707963705062866) * (num - 0.5f) * samplingWidth;
3721 int num2 = (int)vector.X / 16;
3722 int num3 = (int)vector.Y / 16;
3724 int num4 = (int)vector2.X / 16;
3725 int num5 = (int)vector2.Y / 16;
3726 float num6 = 0f;
3727 num6 = (TupleHitLine(num2, num3, num4, num5, 0, 0, new List<Tuple<int, int>>(), out var col) ? ((col.Item1 != num4 || col.Item2 != num5) ? (new Vector2(Math.Abs(num2 - col.Item1), Math.Abs(num3 - col.Item2)).Length() * 16f) : maxDistance) : (new Vector2(Math.Abs(num2 - col.Item1), Math.Abs(num3 - col.Item2)).Length() * 16f));
3728 samples[i] = num6;
3729 }
3730 }
3731
3738}
bool ICollection< KeyValuePair< TKey, TValue > >. Contains(KeyValuePair< TKey, TValue > keyValuePair)
void Add(TKey key, TValue value)
static byte Min(byte val1, byte val2)
Definition Math.cs:912
static double Atan2(double y, double x)
static double Sqrt(double d)
const double E
Definition Math.cs:14
static double Abs(double value)
const double PI
Definition Math.cs:16
static double Floor(double d)
static int Sign(decimal value)
Definition Math.cs:1202
static byte Max(byte val1, byte val2)
Definition Math.cs:738
static bool CanHit(Entity source, Entity target)
Definition Collision.cs:344
static bool InTileBounds(int x, int y, int lx, int ly, int hx, int hy)
static bool SolidTiles(int startX, int endX, int startY, int endY, bool allowTopSurfaces)
static bool CanHitWithCheck(Vector2 Position1, int Width1, int Height1, Vector2 Position2, int Width2, int Height2, Utils.TileActionAttempt check)
Definition Collision.cs:453
static bool down
Definition Collision.cs:34
static float[] FindOverlapPoints(float relativePoint1, float relativePoint2)
Definition Collision.cs:140
static bool SolidTiles(int startX, int endX, int startY, int endY)
static Vector2[] OneDimensionalIntersection(Vector2 a1, Vector2 a2, Vector2 b1, Vector2 b2)
Definition Collision.cs:113
static bool WetCollision(Vector2 Position, int Width, int Height)
static bool stair
Definition Collision.cs:20
static Vector2 WaterCollision(Vector2 Position, Vector2 Velocity, int Width, int Height, bool fallThrough=false, bool fall2=false, bool lavaWalk=true)
static Vector2[] CheckLinevLine(Vector2 a1, Vector2 a2, Vector2 b1, Vector2 b2)
Definition Collision.cs:40
static bool DrownCollision(Vector2 Position, int Width, int Height, float gravDir=-1f, bool includeSlopes=false)
static bool CanTileHurt(ushort type, int i, int j, Player player)
static int collisionOutcode(Vector2 aabbPosition, Vector2 aabbDimensions, Vector2 point)
Definition Collision.cs:166
static float GetTileRotation(Vector2 position)
static bool GetWaterLineIterate(Point pt, out float waterLineHeight)
static List< Point > FindCollisionTile(int Direction, Vector2 position, float testMagnitude, int Width, int Height, bool fallThrough=false, bool fall2=false, int gravDir=1, bool checkCardinals=true, bool checkSlopes=false)
static void HitTiles(Vector2 Position, Vector2 Velocity, int Width, int Height)
static bool SolidTiles(Vector2 position, int width, int height, bool allowTopSurfaces)
static void ExpandVertically(int startX, int startY, out int topY, out int bottomY, int maxExpandUp=100, int maxExpandDown=100)
static void AimingLaserScan(Vector2 startPoint, Vector2 endPoint, float samplingWidth, int samplesToTake, out Vector2 vectorTowardsTarget, out float[] samples)
static bool GetWaterLine(int X, int Y, out float waterLineHeight)
static bool up
Definition Collision.cs:32
static bool honey
Definition Collision.cs:24
static bool stairFall
Definition Collision.cs:22
static bool CheckAABBvLineCollision(Vector2 aabbPosition, Vector2 aabbDimensions, Vector2 lineStart, Vector2 lineEnd)
Definition Collision.cs:198
static bool CanHitLine(Vector2 Position1, int Width1, int Height1, Vector2 Position2, int Width2, int Height2)
Definition Collision.cs:551
static bool AnyHurtingTiles(Vector2 Position, int Width, int Height)
static bool FindCollisionDirection(out int Direction, Vector2 position, int Width, int Height, bool fallThrough=false, bool fall2=false, int gravDir=1)
static Vector4 WalkDownSlope(Vector2 Position, Vector2 Velocity, int Width, int Height, float gravity=0f)
static bool IsWorldPointSolid(Vector2 pos, bool treatPlatformsAsNonSolid=false)
static bool sloping
Definition Collision.cs:28
static Vector2 TileCollision(Vector2 Position, Vector2 Velocity, int Width, int Height, bool fallThrough=false, bool fall2=false, int gravDir=1)
static bool CheckAABBvLineCollision2(Vector2 aabbPosition, Vector2 aabbDimensions, Vector2 lineStart, Vector2 lineEnd)
Definition Collision.cs:236
static bool EmptyTile(int i, int j, bool ignoreTiles=false)
static List< Point > _cacheForConveyorBelts
Definition Collision.cs:38
static bool CanHit(Entity source, NPCAimedTarget target)
Definition Collision.cs:349
static HurtTile HurtTiles(Vector2 Position, int Width, int Height, Player player)
static bool SolidCollision(Vector2 Position, int Width, int Height, bool acceptTopSurfaces)
static void StepDown(ref Vector2 position, ref Vector2 velocity, int width, int height, ref float stepSpeed, ref float gfxOffY, int gravDir=1, bool waterWalk=false)
static Vector4 SlopeCollision(Vector2 Position, Vector2 Velocity, int Width, int Height, float gravity=0f, bool fall=false)
static double DistFromSeg(Vector2 p, Vector2 q0, Vector2 q1, double radius, ref float u)
Definition Collision.cs:93
static bool CheckAABBvLineCollision(Vector2 objectPosition, Vector2 objectDimensions, Vector2 lineStart, Vector2 lineEnd, float lineWidth, ref float collisionPoint)
Definition Collision.cs:246
static Vector2 StickyTiles(Vector2 Position, Vector2 Velocity, int Width, int Height)
static Vector2 AdvancedTileCollision(bool[] forcedIgnoredTiles, Vector2 Position, Vector2 Velocity, int Width, int Height, bool fallThrough=false, bool fall2=false, int gravDir=1)
static Vector2 noSlopeCollision(Vector2 Position, Vector2 Velocity, int Width, int Height, bool fallThrough=false, bool fall2=false)
static Tuple< int, int > TupleHitLineWall(int x1, int y1, int x2, int y2)
Definition Collision.cs:936
static bool GetWaterLineIterate(int X, int Y, out float waterLineHeight)
static List< Point > GetTilesIn(Vector2 TopLeft, Vector2 BottomRight)
static bool shimmer
Definition Collision.cs:26
static void LaserScan(Vector2 samplingPoint, Vector2 directionUnit, float samplingWidth, float maxDistance, float[] samples)
static void StepUp(ref Vector2 position, ref Vector2 velocity, int width, int height, ref float stepSpeed, ref float gfxOffY, int gravDir=1, bool holdsMatching=false, int specialChecksMode=0)
static bool LavaCollision(Vector2 Position, int Width, int Height)
static bool SolidTilesVersatile(int startX, int endX, int startY, int endY)
static bool SolidCollision(Vector2 Position, int Width, int Height)
static bool landMine
Definition Collision.cs:30
static bool SwitchTiles(Vector2 Position, int Width, int Height, Vector2 oldPosition, int objType)
static bool TupleHitLine(int x1, int y1, int x2, int y2, int ignoreX, int ignoreY, List< Tuple< int, int > > ignoreTargets, out Tuple< int, int > col)
Definition Collision.cs:743
static Vector2 AnyCollision(Vector2 Position, Vector2 Velocity, int Width, int Height, bool evenActuated=false)
static bool PointOnLine(Vector2 p, Vector2 a1, Vector2 a2)
Definition Collision.cs:107
static bool CanHit(Vector2 Position1, int Width1, int Height1, Vector2 Position2, int Width2, int Height2)
Definition Collision.cs:354
static Vector2 AnyCollisionWithSpecificTiles(Vector2 Position, Vector2 Velocity, int Width, int Height, bool[] tilesWeCanCollideWithByType, bool evenActuated=false)
bool SwitchTilesNew(Vector2 Position, int Width, int Height, Vector2 oldPosition, int objType)
static void StepConveyorBelt(Entity entity, float gravDir)
static bool IsClearSpotTest(Vector2 position, float testMagnitude, int Width, int Height, bool fallThrough=false, bool fall2=false, int gravDir=1, bool checkCardinals=true, bool checkSlopes=false)
static bool SolidTiles(Vector2 position, int width, int height)
static float Epsilon
Definition Collision.cs:36
static bool HitWallSubstep(int x, int y)
static bool CheckAABBvAABBCollision(Vector2 position1, Vector2 dimensions1, Vector2 position2, Vector2 dimensions2)
Definition Collision.cs:157
static void GetEntityEdgeTiles(List< Point > p, Entity entity, bool left=true, bool right=true, bool up=true, bool down=true)
static bool GetWaterLine(Point pt, out float waterLineHeight)
static bool CanHit(Point Position1, int Width1, int Height1, Point Position2, int Width2, int Height2)
Definition Collision.cs:359
static int NewDust(Vector2 Position, int Width, int Height, int Type, float SpeedX=0f, float SpeedY=0f, int Alpha=0, Color newColor=default(Color), float Scale=1f)
Definition Dust.cs:73
Vector2 BottomRight
Definition Entity.cs:139
Vector2 TopRight
Definition Entity.cs:103
Vector2 Size
Definition Entity.cs:151
Vector2 BottomLeft
Definition Entity.cs:127
Vector2 TopLeft
Definition Entity.cs:91
Vector2 Bottom
Definition Entity.cs:115
Rectangle Hitbox
Definition Entity.cs:164
Vector2 position
Definition Entity.cs:14
Vector2 Right
Definition Entity.cs:67
static Tile GetTileSafely(Vector2 position)
Definition Framing.cs:419
static bool[] TouchDamageBleeding
Definition TileID.cs:285
static bool[] TouchDamageHot
Definition TileID.cs:283
static int[] TouchDamageImmediate
Definition TileID.cs:287
static bool[] Platforms
Definition TileID.cs:163
static bool[] Suffocate
Definition TileID.cs:281
static int[] ConveyorDirection
Definition TileID.cs:177
static readonly ushort Count
Definition TileID.cs:1698
static int maxTilesY
Definition Main.cs:1116
static bool[] tileSolidTop
Definition Main.cs:1469
static int netMode
Definition Main.cs:2095
static bool[] wallHouse
Definition Main.cs:1441
static int maxTilesX
Definition Main.cs:1114
static bool getGoodWorld
Definition Main.cs:341
static bool[] tileSolid
Definition Main.cs:1471
static Tile[,] tile
Definition Main.cs:1675
static UnifiedRandom rand
Definition Main.cs:1387
static NPC[] npc
Definition Main.cs:1685
static bool dontStarveWorld
Definition Main.cs:345
static Player[] player
Definition Main.cs:1803
static void SendData(int msgType, int remoteClient=-1, int ignoreClient=-1, NetworkText text=null, int number=0, float number2=0f, float number3=0f, float number4=0f, int number5=0, int number6=0, int number7=0)
Definition NetMessage.cs:88
bool leftSlope()
Definition Tile.cs:327
bool bottomSlope()
Definition Tile.cs:317
bool rightSlope()
Definition Tile.cs:337
bool nactive()
Definition Tile.cs:257
bool topSlope()
Definition Tile.cs:307
byte liquid
Definition Tile.cs:12
bool inActive()
Definition Tile.cs:582
short frameY
Definition Tile.cs:24
ushort type
Definition Tile.cs:8
bool active()
Definition Tile.cs:565
int blockType()
Definition Tile.cs:219
byte slope()
Definition Tile.cs:684
bool lava()
Definition Tile.cs:362
bool shimmer()
Definition Tile.cs:396
bool halfBrick()
Definition Tile.cs:650
delegate bool TileActionAttempt(int x, int y)
static bool FloatIntersect(float r1StartX, float r1StartY, float r1Width, float r1Height, float r2StartX, float r2StartY, float r2Width, float r2Height)
Definition Utils.cs:627
static bool RectangleLineCollision(Vector2 rectTopLeft, Vector2 rectBottomRight, Vector2 lineStart, Vector2 lineEnd)
Definition Utils.cs:1304
static void HitSwitch(int i, int j)
Definition Wiring.cs:237
static void KillTile(int i, int j, bool fail=false, bool effectOnly=false, bool noItem=false)
static bool SolidTile3(int i, int j)
static void ExplodeMine(int i, int j, bool fromWiring)
static bool InWorld(int x, int y, int fluff=0)
Definition WorldGen.cs:5816
void Inflate(int horizontalAmount, int verticalAmount)
Definition Rectangle.cs:84