001/* 002 * Trident - A Multithreaded Server Alternative 003 * Copyright 2014 The TridentSDK Team 004 * 005 * Licensed under the Apache License, Version 2.0 (the "License"); 006 * you may not use this file except in compliance with the License. 007 * You may obtain a copy of the License at 008 * 009 * http://www.apache.org/licenses/LICENSE-2.0 010 * 011 * Unless required by applicable law or agreed to in writing, software 012 * distributed under the License is distributed on an "AS IS" BASIS, 013 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 014 * See the License for the specific language governing permissions and 015 * limitations under the License. 016 */ 017 018package net.tridentsdk.server.world.gen; 019 020import net.tridentsdk.base.Substance; 021import net.tridentsdk.concurrent.SelectableThreadPool; 022import net.tridentsdk.server.concurrent.ThreadsHandler; 023import net.tridentsdk.server.world.ChunkSection; 024import net.tridentsdk.server.world.WorldUtils; 025import net.tridentsdk.util.TridentLogger; 026import net.tridentsdk.world.ChunkLocation; 027import net.tridentsdk.world.gen.ChunkGenerator; 028 029import java.util.concurrent.CountDownLatch; 030import java.util.concurrent.atomic.AtomicReferenceArray; 031 032/** 033 * Default world generator engine for Trident 034 * 035 * @author The TridentSDK Team 036 */ 037public class DefaultWorldGen extends ChunkGenerator { 038 private final SimplexOctaveGenerator generator = new SimplexOctaveGenerator(12, 0.5, (int) seed); 039 private final SelectableThreadPool executor = ThreadsHandler.genExecutor(); 040 041 public DefaultWorldGen(long seed) { 042 super(seed); 043 } 044 045 @Override 046 public char[][] generateBlocks(final ChunkLocation location, AtomicReferenceArray<Integer> heights) { 047 final char[][] data = new char[16][ChunkSection.LENGTH]; 048 final CountDownLatch release = new CountDownLatch(16); 049 050 for (int x = 0; x < 16; x++) { 051 final int finalX = x; 052 053 executor.execute(() -> { 054 for (int z = 0; z < 16; z++) { 055 final int i = WorldUtils.intScale(0, 140, generator.noise(finalX + (location.x() << 4), z + (location.z() << 4))) - 20; 056 heights.set(WorldUtils.heightIndex(finalX, z), i); 057 058 if (i < 40) { 059 for (int j = i; j <= 40; j++) { 060 data[j / 16][WorldUtils.blockArrayIndex(finalX, j % 16, z)] = Substance.WATER.asExtended(); 061 } 062 } 063 064 for (int y = 0; y <= i; y++) { 065 if (i < 40) { 066 if (y == i) { 067 data[y / 16][WorldUtils.blockArrayIndex(finalX, y % 16, z)] = Substance.SAND.asExtended(); 068 continue; 069 } 070 } 071 072 if (y == i) { 073 data[y / 16][WorldUtils.blockArrayIndex(finalX, i % 16, z)] = Substance.GRASS.asExtended(); 074 } else 075 data[y / 16][WorldUtils.blockArrayIndex(finalX, y % 16, z)] = Substance.DIRT.asExtended(); 076 } 077 } 078 079 release.countDown(); 080 }); 081 } 082 083 try { 084 release.await(); 085 } catch (InterruptedException e) { 086 TridentLogger.get().error(e); 087 return null; 088 } 089 090 return data; 091 } 092 093 @Override 094 public byte[][] generateData(ChunkLocation location) { 095 return new byte[0][]; 096 } 097}