public GrassTask(World world) : base(world) { int w, l; lock (world.SyncRoot) { w = _map.Width; l = _map.Length; } _rndCoords = new Coords[w * l]; //up to 250K per world with grass physics for (short i = 0; i < w; ++i) { for (short j = 0; j < l; ++j) { _rndCoords[i * l + j] = new Coords() { X = i, Y = j } } } ; Util.RndPermutate(_rndCoords); }
private bool Explosion() { List <BData> toClean = _explosion; if (++_currentR <= R) { _explosion = new List <BData>(); int rPrev = 0; for (int z = _currentR; z >= 0; --z) { double r2 = _currentR * _currentR - z * z; double r = Math.Sqrt(r2); double yPrev = r; for (double x = 0; x <= Math.Round(r); ++x) { if (x > r) { x = r; } double y = Math.Sqrt(r2 - x * x); int ix = (int)Math.Round(x); for (int iy = ix > rPrev?0:(int)Math.Round(y); iy < Math.Max(Math.Round(y) + 1, Math.Round(yPrev)); ++iy) { for (int mx = -1; mx < 2; mx += 2) { for (int my = -1; my < 2; my += 2) { for (int mz = -1; mz < 2; mz += 2) { TryAddPoint(mx * ix + _pos.X, my * iy + _pos.Y, mz * z + _pos.Z); } } } } yPrev = y; } rPrev = (int)Math.Round(r); } Util.RndPermutate(_explosion); foreach (BData pt in _explosion) { UpdateMap(new BlockUpdate(null, (short)pt.X, (short)pt.Y, (short)pt.Z, Block.Lava)); foreach (Player p in _world.Players) { if (p.CanBeKilled() && p.Position.DistanceSquaredTo((new Vector3I(pt.X, pt.Y, pt.Z)).ToPlayerCoords()) <= 64 * 64) //less or equal than 2 blocks { HitPlayer(_world, p, _owner); } } } } if (null != toClean) { foreach (BData pt in toClean) { UpdateMap(new BlockUpdate(null, (short)pt.X, (short)pt.Y, (short)pt.Z, pt.PrevBlock == Block.Water ? Block.Water : Block.Air)); } } return(_currentR <= R); }