diff --git a/pkg/landscape/config.go b/pkg/landscape/config.go index 5ef880a..22c01b2 100644 --- a/pkg/landscape/config.go +++ b/pkg/landscape/config.go @@ -6,12 +6,11 @@ type Config struct { // base map height Height uint - Rain *rainfallSettings - Vegetation *vegetationSettings - Temp *tempSettings - Rivers *riverSettings - Land *landSettings - Sea *seaSettings + Rain *rainfallSettings + Temp *tempSettings + Rivers *riverSettings + Land *landSettings + Sea *seaSettings } // tempSettings @@ -19,19 +18,13 @@ type tempSettings struct { // in c, where 100 => 0c EquatorAverageTemp uint8 PoleAverageTemp uint8 + EquatorWidth float64 } type rainfallSettings struct { RainfallVariance float64 } -type vegetationSettings struct { - TempMin uint8 - TempMax uint8 - RainMin uint8 - RainMax uint8 -} - type riverSettings struct { // number of rivers (max), we do not guarantee this many Number uint @@ -67,15 +60,10 @@ func DefaultConfig() *Config { Rain: &rainfallSettings{ RainfallVariance: 0.03, }, - Vegetation: &vegetationSettings{ - TempMin: 101, - TempMax: 150, - RainMin: 50, - RainMax: 255, - }, Temp: &tempSettings{ - EquatorAverageTemp: 140, // 40c - PoleAverageTemp: 60, // -40c + EquatorAverageTemp: 140, // 40c + PoleAverageTemp: 60, // -40c + EquatorWidth: 0.05, // % of height }, Rivers: &riverSettings{ Number: 1, diff --git a/pkg/landscape/geography.go b/pkg/landscape/geography.go index fe37213..3d7fd0c 100644 --- a/pkg/landscape/geography.go +++ b/pkg/landscape/geography.go @@ -11,33 +11,6 @@ func determineRainfall(hmap *MapImage, rs *rainfallSettings) *MapImage { return &MapImage{im: perlin.Perlin(x, y, rs.RainfallVariance)} } -// determineVegetation picks out where forests should be. -// - not in sea -// - not in rivers -// - between certain temps -// - between certain rainfall values -func determineVegetation(sea, rvr, temp, rain *MapImage, vs *vegetationSettings) *MapImage { - x, y := sea.Dimensions() - vege := mutateImage(NewMapImage(x, y), func(dx, dy int, _ uint8) uint8 { - if sea.Value(dx, dy) == 255 || rvr.Value(dx, dy) == 255 { - return 0 - } - rv := rain.Value(dx, dy) - tv := temp.Value(dx, dy) - - if rv > vs.RainMin && rv < vs.RainMax && tv > vs.TempMin && tv < vs.TempMax { - // we're saying that rainfall is more important than - // temperature when determining vegetation - return toUint8((float64(rv) * 0.75) + (float64(tv) * 0.25)) - } - - return 0 - - }) - - return vege -} - // determineTemp returns a map of average temperatures in degrees Celcius, // where 100 => 0 degress (putting our min at -100c and max 155c .. seems // wide enough for an earth like planet) @@ -58,27 +31,27 @@ func determineTemp(hm *MapImage, sealevel uint8, cfg *tempSettings) *MapImage { _, y := hm.Dimensions() equator := y / 2 + // how wide the equator 'band' is + band := cfg.EquatorWidth * float64(y) + // difference in temp per pixel as we move out from the equator - dty := float64(cfg.EquatorAverageTemp-cfg.PoleAverageTemp) / float64(y/2) + dty := float64(cfg.EquatorAverageTemp-cfg.PoleAverageTemp) / ((float64(y) - band) / 2) return mutateImage(hm, func(dx, dy int, z uint8) uint8 { temp := cfg.EquatorAverageTemp - dueToZ := decrement(z, sealevel) / 2 - if z < sealevel { - dueToZ = decrement(sealevel, z) / 2 - dueToZ = increment(dueToZ, 10) - } - - dueToY := float64(equator-dy) * dty + dueToY := 0.0 if dy > equator { - dueToY = float64(dy-equator) * dty + dueToY = float64(dy - equator) + } else { + dueToY = float64(equator - dy) + } + if dueToY <= band { + // we're inside the equator + return temp } - temp = decrement(temp, dueToZ) - temp = decrement(temp, toUint8(dueToY)) - - return temp + return decrement(temp, toUint8(dueToY*dty)) }) } diff --git a/pkg/landscape/land.go b/pkg/landscape/land.go index ba04cd5..96e1869 100644 --- a/pkg/landscape/land.go +++ b/pkg/landscape/land.go @@ -27,12 +27,6 @@ type Landscape struct { // map of average rainfall .. unsure on exactly what this means .. // but higher values imply more regular / more rain rainfall *MapImage - - // map of expected vegetation, where higher numbers indicated - // increasingly more lush vegetation. - // Values of 0 indicate barren desert, tundra, ice or similarly - // vegetation poor (or utterly lifeless) areas. - vegetation *MapImage } // Area represents a specific small area of the map @@ -40,7 +34,6 @@ type Area struct { // 0-255, where higher is more/higher/better Height uint8 Rainfall uint8 - Vegetation uint8 Temperature uint8 // in degress c, offset so 100 => 0 degrees cel // if the square contains fresh/salt water @@ -63,7 +56,6 @@ func (l *Landscape) At(x, y int) *Area { return &Area{ Height: l.height.Value(x, y), Rainfall: l.rainfall.Value(x, y), - Vegetation: l.vegetation.Value(x, y), Sea: l.sea.Value(x, y) == 255, River: l.rivers.Value(x, y) == 255, Temperature: l.temperature.Value(x, y), @@ -84,7 +76,6 @@ func (w *Landscape) DebugRender() (string, error) { {"rivers.png", w.rivers}, {"temperature.png", w.temperature}, {"rainfall.png", w.rainfall}, - {"vegetation.png", w.vegetation}, } { err := savePng(filepath.Join(d, i.Name), i.Img) if err != nil { diff --git a/pkg/landscape/perlinworld.go b/pkg/landscape/perlinworld.go index 5d2c0b5..56815be 100644 --- a/pkg/landscape/perlinworld.go +++ b/pkg/landscape/perlinworld.go @@ -45,14 +45,11 @@ func PerlinLandscape(cfg *Config) (*Landscape, error) { }() wg.Wait() - vege := determineVegetation(sea, rvrs, temp, rain, cfg.Vegetation) - return &Landscape{ height: hmap, sea: sea, rivers: rvrs, temperature: temp, rainfall: rain, - vegetation: vege, }, nil }