65 lines
1.6 KiB
C#

// Copyright 2014-2017 ClassicalSharp | Licensed under BSD-3
using System;
using System.Collections.Generic;
using ClassicalSharp.Map;
#if USE16_BIT
using BlockID = System.UInt16;
#else
using BlockID = System.Byte;
#endif
namespace ClassicalSharp.Singleplayer {
public class FallingPhysics {
Game game;
PhysicsBase physics;
World map;
int width, length, height, oneY;
public FallingPhysics(Game game, PhysicsBase physics) {
this.game = game;
map = game.World;
this.physics = physics;
physics.OnPlace[Block.Sand] = DoFalling;
physics.OnPlace[Block.Gravel] = DoFalling;
physics.OnActivate[Block.Sand] = DoFalling;
physics.OnActivate[Block.Gravel] = DoFalling;
physics.OnRandomTick[Block.Sand] = DoFalling;
physics.OnRandomTick[Block.Gravel] = DoFalling;
}
public void ResetMap() {
width = map.Width;
height = map.Height;
length = map.Length;
oneY = width * length;
}
void DoFalling(int index, BlockID block) {
int found = -1, start = index;
// Find lowest air block
while (index >= oneY) {
index -= oneY;
BlockID other = map.blocks[index];
if (other == Block.Air || (other >= Block.Water && other <= Block.StillLava))
found = index;
else
break;
}
if (found == -1) return;
int x = found % width;
int y = found / oneY; // posIndex / (width * length)
int z = (found / width) % length;
game.UpdateBlock(x, y, z, block);
x = start % width;
y = start / oneY; // posIndex / (width * length)
z = (start / width) % length;
game.UpdateBlock(x, y, z, Block.Air);
physics.ActivateNeighbours(x, y, z, start);
}
}
}