158 {
162 {
163 _cache =
new LiquidCache[rectangle.Width * rectangle.Height + 1];
164 }
166 {
167 _drawCache =
new LiquidDrawCache[drawArea.Width * drawArea.Height + 1];
168 }
170 {
172 }
174 {
176 }
178 fixed (LiquidCache* ptr = &
_cache[1])
179 {
180 LiquidCache* ptr2 = ptr;
181 int num = rectangle.Height * 2 + 2;
182 ptr2 = ptr;
183 for (
int i = rectangle.
X;
i < rectangle.X + rectangle.
Width;
i++)
184 {
185 for (
int j = rectangle.
Y; j < rectangle.Y + rectangle.
Height; j++)
186 {
188 if (tile == null)
189 {
191 }
192 ptr2->LiquidLevel = (float)(int)tile.liquid / 255f;
193 ptr2->IsHalfBrick = tile.halfBrick() && ptr2[-1].HasLiquid && !
TileID.
Sets.
Platforms[tile.type];
194 ptr2->IsSolid =
WorldGen.SolidOrSlopedTile(tile);
195 ptr2->HasLiquid = tile.liquid != 0;
196 ptr2->VisibleLiquidLevel = 0f;
197 ptr2->HasWall = tile.wall != 0;
198 ptr2->Type = tile.liquidType();
199 if (ptr2->IsHalfBrick && !ptr2->HasLiquid)
200 {
201 ptr2->Type = ptr2[-1].Type;
202 }
203 ptr2++;
204 }
205 }
206 ptr2 = ptr;
207 float num2 = 0f;
208 ptr2 += num;
209 for (int k = 2; k < rectangle.Width - 2; k++)
210 {
211 for (int l = 2; l < rectangle.Height - 2; l++)
212 {
213 num2 = 0f;
214 if (ptr2->IsHalfBrick && ptr2[-1].HasLiquid)
215 {
216 num2 = 1f;
217 }
218 else if (!ptr2->HasLiquid)
219 {
220 LiquidCache liquidCache = ptr2[-1];
221 LiquidCache liquidCache2 = ptr2[1];
222 LiquidCache liquidCache3 = ptr2[-rectangle.
Height];
223 LiquidCache liquidCache4 = ptr2[rectangle.
Height];
224 if (liquidCache.HasLiquid && liquidCache2.HasLiquid && liquidCache.Type == liquidCache2.Type && !liquidCache.IsSolid && !liquidCache2.IsSolid)
225 {
226 num2 = liquidCache.LiquidLevel + liquidCache2.LiquidLevel;
227 ptr2->Type = liquidCache.Type;
228 }
229 if (liquidCache3.HasLiquid && liquidCache4.HasLiquid && liquidCache3.Type == liquidCache4.Type && !liquidCache3.IsSolid && !liquidCache4.IsSolid)
230 {
231 num2 =
Math.
Max(num2, liquidCache3.LiquidLevel + liquidCache4.LiquidLevel);
232 ptr2->Type = liquidCache3.Type;
233 }
234 num2 *= 0.5f;
235 }
236 else
237 {
238 num2 = ptr2->LiquidLevel;
239 }
240 ptr2->VisibleLiquidLevel = num2;
241 ptr2->HasVisibleLiquid = num2 != 0f;
242 ptr2++;
243 }
244 ptr2 += 4;
245 }
246 ptr2 = ptr;
247 for (
int m = 0; m < rectangle.
Width; m++)
248 {
249 for (int n = 0; n < rectangle.Height - 10; n++)
250 {
251 if (ptr2->HasVisibleLiquid && (!ptr2->IsSolid || ptr2->IsHalfBrick))
252 {
253 ptr2->Opacity = 1f;
254 ptr2->VisibleType = ptr2->Type;
256 float num4 = 1f;
258 {
259 num4 -= num3;
260 if (ptr2[num5].IsSolid)
261 {
262 break;
263 }
264 ptr2[num5].VisibleLiquidLevel =
Math.
Max(ptr2[num5].VisibleLiquidLevel, ptr2->VisibleLiquidLevel * num4);
265 ptr2[num5].Opacity = num4;
266 ptr2[num5].VisibleType = ptr2->Type;
267 }
268 }
269 if (ptr2->IsSolid && !ptr2->IsHalfBrick)
270 {
271 ptr2->VisibleLiquidLevel = 1f;
272 ptr2->HasVisibleLiquid = false;
273 }
274 else
275 {
276 ptr2->HasVisibleLiquid = ptr2->VisibleLiquidLevel != 0f;
277 }
278 ptr2++;
279 }
280 ptr2 += 10;
281 }
282 ptr2 = ptr;
283 ptr2 += num;
284 for (int num6 = 2; num6 < rectangle.Width - 2; num6++)
285 {
286 for (int num7 = 2; num7 < rectangle.Height - 2; num7++)
287 {
288 if (!ptr2->HasVisibleLiquid)
289 {
290 ptr2->HasLeftEdge = false;
291 ptr2->HasTopEdge = false;
292 ptr2->HasRightEdge = false;
293 ptr2->HasBottomEdge = false;
294 }
295 else
296 {
297 LiquidCache liquidCache = ptr2[-1];
298 LiquidCache liquidCache2 = ptr2[1];
299 LiquidCache liquidCache3 = ptr2[-rectangle.
Height];
300 LiquidCache liquidCache4 = ptr2[rectangle.
Height];
301 float num8 = 0f;
302 float num9 = 1f;
303 float num10 = 0f;
304 float num11 = 1f;
305 float visibleLiquidLevel = ptr2->VisibleLiquidLevel;
306 if (!liquidCache.HasVisibleLiquid)
307 {
308 num10 += liquidCache2.VisibleLiquidLevel * (1f - visibleLiquidLevel);
309 }
310 if (!liquidCache2.HasVisibleLiquid && !liquidCache2.IsSolid && !liquidCache2.IsHalfBrick)
311 {
312 num11 -= liquidCache.VisibleLiquidLevel * (1f - visibleLiquidLevel);
313 }
314 if (!liquidCache3.HasVisibleLiquid && !liquidCache3.IsSolid && !liquidCache3.IsHalfBrick)
315 {
316 num8 += liquidCache4.VisibleLiquidLevel * (1f - visibleLiquidLevel);
317 }
318 if (!liquidCache4.HasVisibleLiquid && !liquidCache4.IsSolid && !liquidCache4.IsHalfBrick)
319 {
320 num9 -= liquidCache3.VisibleLiquidLevel * (1f - visibleLiquidLevel);
321 }
322 ptr2->LeftWall = num8;
323 ptr2->RightWall = num9;
324 ptr2->BottomWall = num11;
325 ptr2->TopWall = num10;
327 ptr2->HasTopEdge = (!liquidCache.HasVisibleLiquid && !liquidCache.IsSolid) || num10 != 0f;
328 ptr2->HasBottomEdge = (!liquidCache2.HasVisibleLiquid && !liquidCache2.IsSolid) || num11 != 1f;
329 ptr2->HasLeftEdge = (!liquidCache3.HasVisibleLiquid && !liquidCache3.IsSolid) || num8 != 0f;
330 ptr2->HasRightEdge = (!liquidCache4.HasVisibleLiquid && !liquidCache4.IsSolid) || num9 != 1f;
331 if (!ptr2->HasLeftEdge)
332 {
333 if (ptr2->HasRightEdge)
334 {
335 zero.X += 32;
336 }
337 else
338 {
339 zero.X += 16;
340 }
341 }
342 if (ptr2->HasLeftEdge && ptr2->HasRightEdge)
343 {
344 zero.X = 16;
345 zero.Y += 32;
346 if (ptr2->HasTopEdge)
347 {
348 zero.Y = 16;
349 }
350 }
351 else if (!ptr2->HasTopEdge)
352 {
353 if (!ptr2->HasLeftEdge && !ptr2->HasRightEdge)
354 {
355 zero.Y += 48;
356 }
357 else
358 {
359 zero.Y += 16;
360 }
361 }
362 if (zero.
Y == 16 && (ptr2->HasLeftEdge ^ ptr2->HasRightEdge) && (num7 + rectangle.
Y) % 2 == 0)
363 {
364 zero.Y += 16;
365 }
366 ptr2->FrameOffset = zero;
367 }
368 ptr2++;
369 }
370 ptr2 += 4;
371 }
372 ptr2 = ptr;
373 ptr2 += num;
374 for (int num12 = 2; num12 < rectangle.Width - 2; num12++)
375 {
376 for (int num13 = 2; num13 < rectangle.Height - 2; num13++)
377 {
378 if (ptr2->HasVisibleLiquid)
379 {
380 LiquidCache liquidCache = ptr2[-1];
381 LiquidCache liquidCache2 = ptr2[1];
382 LiquidCache liquidCache3 = ptr2[-rectangle.
Height];
383 LiquidCache liquidCache4 = ptr2[rectangle.
Height];
384 ptr2->VisibleLeftWall = ptr2->LeftWall;
385 ptr2->VisibleRightWall = ptr2->RightWall;
386 ptr2->VisibleTopWall = ptr2->TopWall;
387 ptr2->VisibleBottomWall = ptr2->BottomWall;
388 if (liquidCache.HasVisibleLiquid && liquidCache2.HasVisibleLiquid)
389 {
390 if (ptr2->HasLeftEdge)
391 {
392 ptr2->VisibleLeftWall = (ptr2->LeftWall * 2f + liquidCache.LeftWall + liquidCache2.LeftWall) * 0.25f;
393 }
394 if (ptr2->HasRightEdge)
395 {
396 ptr2->VisibleRightWall = (ptr2->RightWall * 2f + liquidCache.RightWall + liquidCache2.RightWall) * 0.25f;
397 }
398 }
399 if (liquidCache3.HasVisibleLiquid && liquidCache4.HasVisibleLiquid)
400 {
401 if (ptr2->HasTopEdge)
402 {
403 ptr2->VisibleTopWall = (ptr2->TopWall * 2f + liquidCache3.TopWall + liquidCache4.TopWall) * 0.25f;
404 }
405 if (ptr2->HasBottomEdge)
406 {
407 ptr2->VisibleBottomWall = (ptr2->BottomWall * 2f + liquidCache3.BottomWall + liquidCache4.BottomWall) * 0.25f;
408 }
409 }
410 }
411 ptr2++;
412 }
413 ptr2 += 4;
414 }
415 ptr2 = ptr;
416 ptr2 += num;
417 for (int num14 = 2; num14 < rectangle.Width - 2; num14++)
418 {
419 for (int num15 = 2; num15 < rectangle.Height - 2; num15++)
420 {
421 if (ptr2->HasLiquid)
422 {
423 LiquidCache liquidCache = ptr2[-1];
424 LiquidCache liquidCache2 = ptr2[1];
425 LiquidCache liquidCache3 = ptr2[-rectangle.
Height];
426 LiquidCache liquidCache4 = ptr2[rectangle.
Height];
427 if (ptr2->HasTopEdge && !ptr2->HasBottomEdge && (ptr2->HasLeftEdge ^ ptr2->HasRightEdge))
428 {
429 if (ptr2->HasRightEdge)
430 {
431 ptr2->VisibleRightWall = liquidCache2.VisibleRightWall;
432 ptr2->VisibleTopWall = liquidCache3.VisibleTopWall;
433 }
434 else
435 {
436 ptr2->VisibleLeftWall = liquidCache2.VisibleLeftWall;
437 ptr2->VisibleTopWall = liquidCache4.VisibleTopWall;
438 }
439 }
440 else if (liquidCache2.FrameOffset.X == 16 && liquidCache2.FrameOffset.Y == 32)
441 {
442 if (ptr2->VisibleLeftWall > 0.5f)
443 {
444 ptr2->VisibleLeftWall = 0f;
445 ptr2->FrameOffset =
new Point(0, 0);
446 }
447 else if (ptr2->VisibleRightWall < 0.5f)
448 {
449 ptr2->VisibleRightWall = 1f;
450 ptr2->FrameOffset =
new Point(32, 0);
451 }
452 }
453 }
454 ptr2++;
455 }
456 ptr2 += 4;
457 }
458 ptr2 = ptr;
459 ptr2 += num;
460 for (int num16 = 2; num16 < rectangle.Width - 2; num16++)
461 {
462 for (int num17 = 2; num17 < rectangle.Height - 2; num17++)
463 {
464 if (ptr2->HasLiquid)
465 {
466 LiquidCache liquidCache = ptr2[-1];
467 LiquidCache liquidCache2 = ptr2[1];
468 LiquidCache liquidCache3 = ptr2[-rectangle.
Height];
469 LiquidCache liquidCache4 = ptr2[rectangle.
Height];
470 if (!ptr2->HasBottomEdge && !ptr2->HasLeftEdge && !ptr2->HasTopEdge && !ptr2->HasRightEdge)
471 {
472 if (liquidCache3.HasTopEdge && liquidCache.HasLeftEdge)
473 {
474 ptr2->FrameOffset.X =
Math.
Max(4, (
int)(16f - liquidCache.VisibleLeftWall * 16f)) - 4;
475 ptr2->FrameOffset.Y = 48 +
Math.
Max(4, (
int)(16f - liquidCache3.VisibleTopWall * 16f)) - 4;
476 ptr2->VisibleLeftWall = 0f;
477 ptr2->VisibleTopWall = 0f;
478 ptr2->VisibleRightWall = 1f;
479 ptr2->VisibleBottomWall = 1f;
480 }
481 else if (liquidCache4.HasTopEdge && liquidCache.HasRightEdge)
482 {
483 ptr2->FrameOffset.X = 32 -
Math.
Min(16, (
int)(liquidCache.VisibleRightWall * 16f) - 4);
484 ptr2->FrameOffset.Y = 48 +
Math.
Max(4, (
int)(16f - liquidCache4.VisibleTopWall * 16f)) - 4;
485 ptr2->VisibleLeftWall = 0f;
486 ptr2->VisibleTopWall = 0f;
487 ptr2->VisibleRightWall = 1f;
488 ptr2->VisibleBottomWall = 1f;
489 }
490 }
491 }
492 ptr2++;
493 }
494 ptr2 += 4;
495 }
496 ptr2 = ptr;
497 ptr2 += num;
498 fixed (LiquidDrawCache* ptr3 = &
_drawCache[0])
499 {
501 {
502 LiquidDrawCache* ptr4 = ptr3;
504 for (int num18 = 2; num18 < rectangle.Width - 2; num18++)
505 {
506 for (int num19 = 2; num19 < rectangle.Height - 2; num19++)
507 {
508 if (ptr2->HasVisibleLiquid)
509 {
510 float num20 =
Math.
Min(0.75f, ptr2->VisibleLeftWall);
511 float num21 =
Math.
Max(0.25f, ptr2->VisibleRightWall);
512 float num22 =
Math.
Min(0.75f, ptr2->VisibleTopWall);
513 float num23 =
Math.
Max(0.25f, ptr2->VisibleBottomWall);
514 if (ptr2->IsHalfBrick && ptr2->IsSolid && num23 > 0.5f)
515 {
516 num23 = 0.5f;
517 }
518 ptr4->IsVisible = ptr2->HasWall || !ptr2->IsHalfBrick || !ptr2->HasLiquid || !(ptr2->LiquidLevel < 1f);
519 ptr4->SourceRectangle =
new Rectangle((
int)(16f - num21 * 16f) + ptr2->FrameOffset.X, (
int)(16f - num23 * 16f) + ptr2->FrameOffset.Y, (
int)
Math.
Ceiling((num21 - num20) * 16f), (
int)
Math.
Ceiling((num23 - num22) * 16f));
520 ptr4->IsSurfaceLiquid = ptr2->FrameOffset.X == 16 && ptr2->FrameOffset.Y == 0 && (double)(num19 + rectangle.
Y) > Main.worldSurface - 40.0;
521 ptr4->Opacity = ptr2->Opacity;
523 ptr4->Type = ptr2->VisibleType;
524 ptr4->HasWall = ptr2->HasWall;
526 byte g = (ptr6->
R = (byte)(b >> 1));
530 LiquidCache* ptr7 = ptr2 - 1;
531 if (num19 != 2 && !ptr7->HasVisibleLiquid && !ptr7->IsSolid && !ptr7->IsHalfBrick)
532 {
533 *(ptr6 - 1) = *ptr6;
534 }
535 }
536 else
537 {
538 ptr4->IsVisible = false;
539 int num24 = ((!ptr2->IsSolid && !ptr2->IsHalfBrick) ? 4 : 3);
541 byte g2 = (ptr6->
R = (byte)(b3 >> 1));
545 }
546 ptr2++;
547 ptr4++;
548 ptr6++;
549 }
550 ptr2 += 4;
551 }
552 }
553 }
554 ptr2 = ptr;
555 for (
int num25 = rectangle.
X; num25 < rectangle.X + rectangle.
Width; num25++)
556 {
557 for (
int num26 = rectangle.
Y; num26 < rectangle.Y + rectangle.
Height; num26++)
558 {
559 if (ptr2->VisibleType == 1 && ptr2->HasVisibleLiquid && Dust.lavaBubbles < 200)
560 {
562 {
563 Dust.NewDust(
new Vector2(num25 * 16, num26 * 16), 16, 16, 35, 0f, 0f, 0,
Color.
White);
564 }
566 {
567 int num27 = Dust.NewDust(
new Vector2(num25 * 16, num26 * 16), 16, 8, 35, 0f, 0f, 50,
Color.
White, 1.5f);
568 Main.dust[num27].velocity *= 0.8f;
569 Main.dust[num27].velocity.X *= 2f;
570 Main.dust[num27].velocity.Y -= (float)
_random.
Next(1, 7) * 0.1f;
572 {
574 }
575 Main.dust[num27].noGravity = true;
576 }
577 }
578 ptr2++;
579 }
580 }
581 fixed (LiquidDrawCache* ptr8 = &
_drawCache[0])
582 {
584 {
585 LiquidDrawCache* ptr9 = ptr8;
586 SpecialLiquidDrawCache* ptr11 = ptr10;
587 for (int num28 = 2; num28 < rectangle.Width - 2; num28++)
588 {
589 for (int num29 = 2; num29 < rectangle.Height - 2; num29++)
590 {
591 if (ptr9->IsVisible && ptr9->Type == 3)
592 {
593 ptr11->X = num28;
594 ptr11->Y = num29;
595 ptr11->IsVisible = ptr9->IsVisible;
596 ptr11->HasWall = ptr9->HasWall;
597 ptr11->IsSurfaceLiquid = ptr9->IsSurfaceLiquid;
598 ptr11->LiquidOffset = ptr9->LiquidOffset;
599 ptr11->Opacity = ptr9->Opacity;
600 ptr11->SourceRectangle = ptr9->SourceRectangle;
601 ptr11->Type = ptr9->Type;
602 ptr9->IsVisible = false;
603 ptr11++;
604 }
605 ptr9++;
606 }
607 }
608 ptr11->IsVisible = false;
609 }
610 }
611 }
613 {
615 }
616 }
static byte Min(byte val1, byte val2)
static double Ceiling(double a)
static double Floor(double d)
static byte Max(byte val1, byte val2)
static readonly int[] WATERFALL_LENGTH
SpecialLiquidDrawCache[] _drawCacheForShimmer
LiquidDrawCache[] _drawCache
Action< Color[], Rectangle > WaveFilters
static readonly byte[] WAVE_MASK_STRENGTH
readonly UnifiedRandom _random
static readonly byte[] VISCOSITY_MASK
Rectangle GetCachedDrawArea()