mirror of
https://github.com/ClassiCube/ClassiCube.git
synced 2025-09-08 14:56:12 -04:00
All sections complete :)
parent
9efff51e4a
commit
6a7efd5504
@ -31,7 +31,7 @@ Generation of a Classic Minecraft map, as seen on the sadly defunct browser-embe
|
||||
* create ore veins
|
||||
* flood fill-water, _"Watering..."_
|
||||
* flood fill-lava, _"Melting..."_
|
||||
* create surface layers, _"Growing..."_
|
||||
* create surface layer, _"Growing..."_
|
||||
* create plants, _"Planting..."_
|
||||
|
||||
## Choose map size
|
||||
@ -52,13 +52,13 @@ For each column in the x,z plane assign an elevation value to heightMap computed
|
||||
Let heightLow be noise1.compute( x*1.3, z*1.3) / 6 - 4
|
||||
Let heightHigh be noise2.compute( x*1.3, z*1.3) / 5 + 6
|
||||
|
||||
if noise3.compute(x,z) /8 > 0 {
|
||||
If noise3.compute(x,z) /8 > 0 {
|
||||
set heightResult to heightLow
|
||||
} else {
|
||||
set heightResult to the maximum of heightLow and heightHigh
|
||||
}
|
||||
|
||||
if heightResult < 0 {
|
||||
If heightResult < 0 {
|
||||
set heightResult to 8/10 its value
|
||||
}
|
||||
|
||||
@ -79,9 +79,9 @@ Let stoneTransition be dirtTransition + dirtThickness
|
||||
|
||||
for y in height {
|
||||
Let blockType be AIR
|
||||
if y equals 0 then blockType is LAVA
|
||||
else if y <= stoneTransition then blockType is STONE
|
||||
else if y <= dirtTransition then blockType is DIRT
|
||||
If y equals 0 then blockType is LAVA
|
||||
else If y <= stoneTransition then blockType is STONE
|
||||
else If y <= dirtTransition then blockType is DIRT
|
||||
|
||||
set block(x,y,z) to blockType
|
||||
}
|
||||
@ -116,7 +116,7 @@ for len in caveLength {
|
||||
set phi to previous value/2 + deltaPhi/4
|
||||
set deltaPhi to (previous value * 0.75) + randomFloat() - randomFloat()
|
||||
|
||||
if randomFloat >= 0.25 {
|
||||
If randomFloat >= 0.25 {
|
||||
Let centerPos be a new point with each component equal to
|
||||
cavePos.n + (randomInteger(4) - 2) * 0.2
|
||||
// eg. centerPos.x = cavePos.x + (randomInteger(4) - 2) * 0.2
|
||||
@ -130,7 +130,7 @@ for len in caveLength {
|
||||
}
|
||||
```
|
||||
|
||||
where fillOblateSpheroid is a method which takes a central point, a radius and a fillBlockID to use on the block array.
|
||||
Where **fillOblateSpheroid()** is a method which takes a central point, a radius and a fillBlockID to use on the block array.
|
||||
|
||||
For each entry (x,y,z) within -radius to +radius in the block array:
|
||||
```
|
||||
@ -138,8 +138,8 @@ dx = x - center.x
|
||||
dy = y - center.y
|
||||
dz = z - center.z
|
||||
|
||||
if (dx^2 + 2 * dy^2 + dz^2) < radius^2 and point (x,y,z) falls within level bounds {
|
||||
if block(x,y,z) is STONE then replace block(x,y,z) with fillBlockID
|
||||
If (dx^2 + 2 * dy^2 + dz^2) < radius^2 and point (x,y,z) falls within level bounds {
|
||||
If block(x,y,z) is STONE then replace block(x,y,z) with fillBlockID
|
||||
}
|
||||
```
|
||||
Due to the multiplication of dy^2 by 2 this results in spaces which are wider than they are high.
|
||||
@ -153,7 +153,7 @@ Number of veins is given by width x height x depth x abundance / 16384
|
||||
|
||||
For each ore vein:
|
||||
```
|
||||
Let veinPos be a random point (x,y,z) within the (width,height,depth) space.
|
||||
Let veinPos be a random point (x,y,z) within the (width,height,depth) space
|
||||
Let veinLength be randomFloat() * randomFloat() * 75 * abundance
|
||||
|
||||
Let theta be randomFloat() * Pi * 2
|
||||
@ -193,9 +193,138 @@ The lowest layer of the block array is always lava, having been set so during st
|
||||
|
||||
For each lava source a random x and z coordinate value is chosen and the y coordinate is set to (water level - 3) x randomFloat() x randomFloat(). If the position is AIR then lava is flood-filled from that point.
|
||||
|
||||
## Create surface layers
|
||||
// Todo
|
||||
## Create surface layer
|
||||
|
||||
Using:
|
||||
* noise1, an octave noise function (of octave 8)
|
||||
* noise2, an octave noise function (of octave 8)
|
||||
|
||||
For each column in the x,z plane, determine block type of highest point in block array:
|
||||
```
|
||||
Let sandChance be (noise1.compute(x,z) > 8)
|
||||
Let gravelChance be (noise2.compute(x,z) >12)
|
||||
|
||||
Let y be heightMap(x,z)
|
||||
Let blockAbove be block(x, y+1, z)
|
||||
|
||||
If blockAbove is WATER and gravelChance is true {
|
||||
Set block(x,y,z) to GRAVEL
|
||||
}
|
||||
|
||||
If blockAbove is AIR {
|
||||
If y <= water level and sandChance is true {
|
||||
Set block(x,y,z) to SAND
|
||||
} else {
|
||||
Set block(x,y,z) to GRASS
|
||||
}
|
||||
}
|
||||
```
|
||||
## Create plants
|
||||
// Todo
|
||||
|
||||
Classic Minecraft maps include flowers on the surface, mushrooms underground and trees with a simple shape.
|
||||
|
||||
### Flowers
|
||||
|
||||
Flowers are created in patches, the total number of which is set to width x depth / 3000.
|
||||
|
||||
For each flower Patch:
|
||||
```
|
||||
Let flowerType be randomly chosen from Dandelion or Rose
|
||||
Let patchPos be a random point(x,z) in x,z plane
|
||||
|
||||
Repeat 10 times {
|
||||
Let flowerPos equal the patchPos
|
||||
|
||||
Repeat 5 times {
|
||||
Set flowerPos (x,z) components to previous values + randomInteger(6) - randomInteger(6)
|
||||
|
||||
If flowerPos is within level bounds {
|
||||
Set flowerPos.y to heightMap( flowerPos ) + 1
|
||||
Set blockBelow to be block( flowerPos.x, flowerPos.y-1, flowerPos.z )
|
||||
|
||||
If block( flowerPos ) is AIR and blockBelow is grass {
|
||||
Set block( flowerPos ) to flowerType
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
### Mushrooms
|
||||
|
||||
Mushrooms are created in much the same way as flowers except they can be placed underground and not on the surface. There will be width x height x depth / 2000 patches of mushrooms.
|
||||
|
||||
For each mushroom patch:
|
||||
```
|
||||
Let mushroomType be randomly chosen from Red or Brown
|
||||
Let patchPos be be a random point (x,y,z) within the (width,height,depth) space
|
||||
|
||||
Repeat 20 times {
|
||||
Let mushPos equal the patchPos
|
||||
|
||||
Repeat 5 times {
|
||||
Set mushPos (x,z) components to previous values + randomInteger(6) - randomInteger(6)
|
||||
|
||||
If mushPos is within level bounds and mushPos.y < heightMap( mushPos )-1 {
|
||||
Set blockBelow to be block( mushPos.x, mushPos.y-1, mushPos.z )
|
||||
|
||||
if block( mushPos ) is AIR and block( blockBelow ) is STONE {
|
||||
Set block( mushPos ) to mushroomType
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
### Trees
|
||||
|
||||
Finally trees are added to the map, there will be width x height x depth / 4000 patches of trees created.
|
||||
|
||||
For each tree patch:
|
||||
```
|
||||
Let patchPos be a random point(x,z) in x,z plane
|
||||
|
||||
Repeat 20 times {
|
||||
Set treePos to patchPos
|
||||
|
||||
Repeat 20 times {
|
||||
Set treePos (x,z) components to previous values + randomInteger(6) - randomInteger(6)
|
||||
|
||||
If treePos is within level bounds and randomFloat <= 0.25 {
|
||||
Set treePos.y = heightMap( treePos ) + 1
|
||||
Let treeHeight be randomInteger(3) + 4
|
||||
|
||||
If isSpaceForTree( treePos, treeHeight ) is true {
|
||||
growTree( treePos, treeHeight )
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
```
|
||||
|
||||
Where **isSpaceForTree()** is a method which checks for an empty region of AIR blocks treeHeight high and with a width and depth of 3 by 3 for the trunk and 5 by 5 for the canopy (the last 3 layers). This position is centered on the given position x,z coordinates and upwards from the y coordinate.
|
||||
|
||||
If such a space is found then isSpaceForTree() returns true, otherwise false.
|
||||
|
||||
**growTree()** creates a tree of given height upwards from the position given. The highest four x,z layers will contain leaves in the following pattern:
|
||||
```
|
||||
L: max max-1 max-2 max-3
|
||||
..... ..... %###% %###%
|
||||
..#.. .%#%. ##### #####
|
||||
.###. .#O#. ##O## ##O##
|
||||
..#.. .%#%. ##### #####
|
||||
..... ..... %###% %###%
|
||||
|
||||
Key:
|
||||
. air
|
||||
# leaves
|
||||
O tree trunk
|
||||
% contains leaves 50% of the time
|
||||
```
|
||||
|
||||
# Final adjustments to returned object
|
||||
// Todo
|
||||
|
||||
Once map generation is complete the resulting block array is put into a new Minecraft Level object along with the width, height, depth and water level. The level create time is set to system clock time in milliseconds, the level creator to creator's name and the level name set to the place-holder text "A Nice World".
|
||||
|
||||
The Level object is then returned to the object which called the Map generator.
|
Loading…
x
Reference in New Issue
Block a user