void CollideWithTerrain(Player player, Vector3i position) { if (player != this.Controller) { return; } lock (this) { if (this.groundHits == null) { this.groundHits = new ThreadSafeHashSet <Vector3i>(); } } WorldLayer playerActivity = WorldLayerManager.GetLayer(LayerNames.PlayerActivity); // destroy plants and spawn dirt within a radius under the hit position int radius = 1; for (int x = -radius; x <= radius; x++) { for (int z = -radius; z <= radius; z++) { var offsetpos = position + new Vector3i(x, -1, z); if (!this.groundHits.Add(offsetpos)) { continue; } var abovepos = offsetpos + Vector3i.Up; var aboveblock = World.GetBlock(abovepos); var hitblock = World.GetBlock(offsetpos); if (!aboveblock.Is <Solid>()) { // turn soil into dirt if (hitblock.GetType() == typeof(GrassBlock) || hitblock.GetType() == typeof(ForestSoilBlock)) { player.SpawnBlockEffect(offsetpos, typeof(DirtBlock), BlockEffect.Delete); World.SetBlock <DirtBlock>(offsetpos); BiomePusher.AddFrozenColumn(offsetpos.XZ); } // kill any above plants if (aboveblock is PlantBlock) { // make sure there is a plant here, sometimes world/ecosim are out of sync var plant = EcoSim.PlantSim.GetPlant(abovepos); if (plant != null) { player.SpawnBlockEffect(abovepos, aboveblock.GetType(), BlockEffect.Delete); EcoSim.PlantSim.DestroyPlant(plant, DeathType.Deforestation); } else { World.DeleteBlock(abovepos); } } if (hitblock.Is <Solid>() && World.GetBlock(abovepos).Is <Empty>() && RandomUtil.Value < this.Species.ChanceToSpawnDebris) { Block placedBlock = World.SetBlock(typeof(TreeDebrisBlock), abovepos); player.SpawnBlockEffect(abovepos, typeof(TreeDebrisBlock), BlockEffect.Place); RoomData.QueueRoomTest(abovepos); } } } } }