Merge lp:~widelands-dev/widelands/terrain_affinity_as_int into lp:widelands

Proposed by GunChleoc
Status: Merged
Merged at revision: 8933
Proposed branch: lp:~widelands-dev/widelands/terrain_affinity_as_int
Merge into: lp:widelands
Diff against target: 1945 lines (+397/-389)
43 files modified
data/tribes/immovables/berry_bushes/blueberry/init.lua (+3/-3)
data/tribes/immovables/berry_bushes/currant_black/init.lua (+3/-3)
data/tribes/immovables/berry_bushes/currant_red/init.lua (+3/-3)
data/tribes/immovables/berry_bushes/desert_hackberry/init.lua (+3/-3)
data/tribes/immovables/berry_bushes/juniper/init.lua (+3/-3)
data/tribes/immovables/berry_bushes/raspberry/init.lua (+3/-3)
data/tribes/immovables/berry_bushes/sea_buckthorn/init.lua (+3/-3)
data/tribes/immovables/berry_bushes/strawberry/init.lua (+3/-3)
data/world/immovables/bush1/init.lua (+8/-8)
data/world/immovables/trees/alder/init.lua (+8/-8)
data/world/immovables/trees/aspen/init.lua (+3/-3)
data/world/immovables/trees/beech/init.lua (+3/-3)
data/world/immovables/trees/birch/init.lua (+3/-3)
data/world/immovables/trees/cirrus/init.lua (+3/-3)
data/world/immovables/trees/larch/init.lua (+3/-3)
data/world/immovables/trees/liana/init.lua (+3/-3)
data/world/immovables/trees/maple/init.lua (+3/-3)
data/world/immovables/trees/mushroom_dark/init.lua (+3/-3)
data/world/immovables/trees/mushroom_green/init.lua (+3/-3)
data/world/immovables/trees/mushroom_red/init.lua (+3/-3)
data/world/immovables/trees/oak/init.lua (+3/-3)
data/world/immovables/trees/palm_borassus/init.lua (+3/-3)
data/world/immovables/trees/palm_coconut/init.lua (+3/-3)
data/world/immovables/trees/palm_date/init.lua (+3/-3)
data/world/immovables/trees/palm_oil/init.lua (+3/-3)
data/world/immovables/trees/palm_roystonea/init.lua (+3/-3)
data/world/immovables/trees/rowan/init.lua (+3/-3)
data/world/immovables/trees/spruce/init.lua (+3/-3)
data/world/immovables/trees/twine/init.lua (+3/-3)
data/world/immovables/trees/umbrella_green/init.lua (+3/-3)
data/world/immovables/trees/umbrella_red/init.lua (+3/-3)
data/world/terrains/init.lua (+145/-145)
src/logic/game.cc (+0/-4)
src/logic/game.h (+0/-3)
src/logic/map_objects/immovable.cc (+3/-3)
src/logic/map_objects/terrain_affinity.cc (+62/-53)
src/logic/map_objects/terrain_affinity.h (+26/-20)
src/logic/map_objects/tribes/worker.cc (+11/-11)
src/logic/map_objects/world/terrain_description.cc (+10/-10)
src/logic/map_objects/world/terrain_description.h (+10/-10)
src/scripting/lua_map.cc (+10/-10)
test/maps/lua_testsuite.wmf/scripting/immovables_descriptions.lua (+9/-9)
test/maps/lua_testsuite.wmf/scripting/terrains_resources_descriptions.lua (+8/-8)
To merge this branch: bzr merge lp:~widelands-dev/widelands/terrain_affinity_as_int
Reviewer Review Type Date Requested Status
Arty Approve
Review via email: mp+358299@code.launchpad.net

Commit message

Fix desyncs caused by floating point arithmetic

- Floating point arithmetic can become inconsistent across platforms/compilers/hardware
- Upscale terrain affinity constants to turn them into ints
- Upscale the result of the affinity calculation and then use std::floor to cut it off at
  largely reduced precision for consistent rounding behavior. This should fix inconsistencies
  with double rounding and rounding direction.
- Catch a possible division by 0.

Description of the change

Fix cross-platform desyncs caused by floating point arithmetic. Further reading:

https://randomascii.wordpress.com/2012/03/21/intermediate-floating-point-precision/

https://arxiv.org/abs/cs/0701192

Test savegame:

https://bugs.launchpad.net/widelands/+bug/1800338/comments/3

With this savegame, I can cause a multiplayer desync on the same machine by compiling one copy of Widelands with GCC and another copy with Clang. The desync happens before the ship finishes building. With this branch, the desync is gone.

To post a comment you must log in.
Revision history for this message
bunnybot (widelandsofficial) wrote :

Continuous integration builds have changed state:

Travis build 4197. State: failed. Details: https://travis-ci.org/widelands/widelands/builds/452676073.
Appveyor build 3993. State: failed. Details: https://ci.appveyor.com/project/widelands-dev/widelands/build/_widelands_dev_widelands_terrain_affinity_as_int-3993.

Revision history for this message
bunnybot (widelandsofficial) wrote :

Continuous integration builds have changed state:

Travis build 4213. State: errored. Details: https://travis-ci.org/widelands/widelands/builds/453859920.
Appveyor build 4009. State: failed. Details: https://ci.appveyor.com/project/widelands-dev/widelands/build/_widelands_dev_widelands_terrain_affinity_as_int-4009.

Revision history for this message
bunnybot (widelandsofficial) wrote :

Continuous integration builds have changed state:

Travis build 4238. State: passed. Details: https://travis-ci.org/widelands/widelands/builds/455849882.
Appveyor build 4034. State: success. Details: https://ci.appveyor.com/project/widelands-dev/widelands/build/_widelands_dev_widelands_terrain_affinity_as_int-4034.

Revision history for this message
Arty (artydent) wrote :

I reviewed the code and also tested somewhat. Still has a few issues, most of them minor though. See diff comments.

The file data\world\immovables\bush1\init.lua still has a few comments (lines 86-94) referring to the floating point values, this should also be changed in this branch.

Overall it should be much less likely now to get different results based on platform/compiler dependent precision choices, but they might still happen. There are still things based on floating point calculations (like the main probability calculation in calculate_probability_to_grow) but they might be difficult to replace with pure integer based stuff.
That said, considering that the ratios of the final probabilities of the six best immovables already change significantly with this branch, we could possibly also change the basic probability calculation to somewhat that uses only integer operations but is not too far off from the current approach (which seems to have been based roughly on multivariate normal distributions).

Btw, where did those three weight constants in calculate_probability_to_grow originally come from? Their precision is too high to be from a simple "try and error until it feels right" approach. They still feel quite arbitrary though.

review: Needs Fixing
Revision history for this message
GunChleoc (gunchleoc) wrote :

Thanks for the excellent review :)

I have addressed most of your comments and left replies to the rest.

One of our math wizards spent a long time tweaking the system and the function, so I'm hesitant to change any semantics here. There is an e function involved, so there is no way to avoid floating point completely unless we radically change the system.

Revision history for this message
Arty (artydent) wrote :

Yes, the exponential function is the problem. Approximating it with highish precision using only integer calculations would require a lot of computation, which isn't really feasible. There are reasonable options though if we don't mind straying a little. The function we use here is basically a three-dimensional Gauß-curve, and I think we could find an alternative that roughly preserves the shape and can be done with a small number of integer operations.
It's probably not necessary though, but if we keep getting desyncs because of such platform/compiler-dependent computation differences, this would provide an option.

I also replied to your replies.

Revision history for this message
GunChleoc (gunchleoc) wrote :

Thanks for your math wizardry - I have now implemented both suggestions.

I think that greatly cutting the precision while forcing a uniform rounding strategy (round down) should be good enough for our purposes. Let's merge this and see if we're still getting desyncs. We can always decide to change the formula later if necessary.

@bunnybot merge

Revision history for this message
Arty (artydent) wrote :

Looks good now.

The comment with the assciativity is kinda obsolete now though.

And using int64_t wasn't really necessary now that you use the weights linearly.

review: Approve

Preview Diff

[H/L] Next/Prev Comment, [J/K] Next/Prev File, [N/P] Next/Prev Hunk
=== modified file 'data/tribes/immovables/berry_bushes/blueberry/init.lua'
--- data/tribes/immovables/berry_bushes/blueberry/init.lua 2018-02-17 15:41:29 +0000
+++ data/tribes/immovables/berry_bushes/blueberry/init.lua 2018-11-23 12:45:17 +0000
@@ -2,9 +2,9 @@
22
3terrain_affinity = {3terrain_affinity = {
4 preferred_temperature = 45, -- Temperature is in arbitrary units.4 preferred_temperature = 45, -- Temperature is in arbitrary units.
5 preferred_humidity = 0.75, -- In percent (1 being very wet).5 preferred_humidity = 750, -- Values between 0 and 1000 (1000 being very wet).
6 preferred_fertility = 0.4, -- In percent (1 being very fertile).6 preferred_fertility = 400, -- Values between 0 and 1000 (1000 being very fertile).
7 pickiness = 0.15, -- Lower means it is less picky, i.e. it can deal better.7 pickiness = 15, -- Lower means it is less picky, i.e. it can deal better.
8}8}
99
10tribes:new_immovable_type {10tribes:new_immovable_type {
1111
=== modified file 'data/tribes/immovables/berry_bushes/currant_black/init.lua'
--- data/tribes/immovables/berry_bushes/currant_black/init.lua 2018-02-17 15:41:29 +0000
+++ data/tribes/immovables/berry_bushes/currant_black/init.lua 2018-11-23 12:45:17 +0000
@@ -2,9 +2,9 @@
22
3terrain_affinity = {3terrain_affinity = {
4 preferred_temperature = 120,4 preferred_temperature = 120,
5 preferred_humidity = 0.1,5 preferred_humidity = 100,
6 preferred_fertility = 0.2,6 preferred_fertility = 200,
7 pickiness = 0.5,7 pickiness = 50,
8}8}
99
10tribes:new_immovable_type {10tribes:new_immovable_type {
1111
=== modified file 'data/tribes/immovables/berry_bushes/currant_red/init.lua'
--- data/tribes/immovables/berry_bushes/currant_red/init.lua 2018-02-17 15:41:29 +0000
+++ data/tribes/immovables/berry_bushes/currant_red/init.lua 2018-11-23 12:45:17 +0000
@@ -2,9 +2,9 @@
22
3terrain_affinity = {3terrain_affinity = {
4 preferred_temperature = 95,4 preferred_temperature = 95,
5 preferred_humidity = 0.55,5 preferred_humidity = 550,
6 preferred_fertility = 0.45,6 preferred_fertility = 450,
7 pickiness = 0.4,7 pickiness = 40,
8}8}
99
10tribes:new_immovable_type {10tribes:new_immovable_type {
1111
=== modified file 'data/tribes/immovables/berry_bushes/desert_hackberry/init.lua'
--- data/tribes/immovables/berry_bushes/desert_hackberry/init.lua 2018-02-17 15:41:29 +0000
+++ data/tribes/immovables/berry_bushes/desert_hackberry/init.lua 2018-11-23 12:45:17 +0000
@@ -2,9 +2,9 @@
22
3terrain_affinity = {3terrain_affinity = {
4 preferred_temperature = 170, -- Temperature is in arbitrary units.4 preferred_temperature = 170, -- Temperature is in arbitrary units.
5 preferred_humidity = 0.05, -- In percent (1 being very wet).5 preferred_humidity = 50, -- Values between 0 and 1000 (1000 being very wet).
6 preferred_fertility = 0.05, -- In percent (1 being very fertile).6 preferred_fertility = 50, -- Values between 0 and 1000 (1000 being very fertile).
7 pickiness = 0.3, -- Lower means it is less picky, i.e. it can deal better.7 pickiness = 30, -- Lower means it is less picky, i.e. it can deal better.
8}8}
99
10tribes:new_immovable_type {10tribes:new_immovable_type {
1111
=== modified file 'data/tribes/immovables/berry_bushes/juniper/init.lua'
--- data/tribes/immovables/berry_bushes/juniper/init.lua 2018-04-21 15:27:00 +0000
+++ data/tribes/immovables/berry_bushes/juniper/init.lua 2018-11-23 12:45:17 +0000
@@ -2,9 +2,9 @@
22
3terrain_affinity = {3terrain_affinity = {
4 preferred_temperature = 115,4 preferred_temperature = 115,
5 preferred_humidity = 0.6,5 preferred_humidity = 600,
6 preferred_fertility = 0.2,6 preferred_fertility = 200,
7 pickiness = 0.15,7 pickiness = 15,
8}8}
99
10tribes:new_immovable_type {10tribes:new_immovable_type {
1111
=== modified file 'data/tribes/immovables/berry_bushes/raspberry/init.lua'
--- data/tribes/immovables/berry_bushes/raspberry/init.lua 2018-02-17 15:41:29 +0000
+++ data/tribes/immovables/berry_bushes/raspberry/init.lua 2018-11-23 12:45:17 +0000
@@ -2,9 +2,9 @@
22
3terrain_affinity = {3terrain_affinity = {
4 preferred_temperature = 50,4 preferred_temperature = 50,
5 preferred_humidity = 0.3,5 preferred_humidity = 300,
6 preferred_fertility = 0.05,6 preferred_fertility = 50,
7 pickiness = 0.1,7 pickiness = 10,
8}8}
99
10tribes:new_immovable_type {10tribes:new_immovable_type {
1111
=== modified file 'data/tribes/immovables/berry_bushes/sea_buckthorn/init.lua'
--- data/tribes/immovables/berry_bushes/sea_buckthorn/init.lua 2018-02-17 15:41:29 +0000
+++ data/tribes/immovables/berry_bushes/sea_buckthorn/init.lua 2018-11-23 12:45:17 +0000
@@ -2,9 +2,9 @@
22
3terrain_affinity = {3terrain_affinity = {
4 preferred_temperature = 100, -- Temperature is in arbitrary units.4 preferred_temperature = 100, -- Temperature is in arbitrary units.
5 preferred_humidity = 0.95, -- In percent (1 being very wet).5 preferred_humidity = 950, -- Values between 0 and 1000 (1000 being very wet).
6 preferred_fertility = 0.05, -- In percent (1 being very fertile).6 preferred_fertility = 50, -- Values between 0 and 1000 (1000 being very fertile).
7 pickiness = 0.15, -- Lower means it is less picky, i.e. it can deal better.7 pickiness = 15, -- Lower means it is less picky, i.e. it can deal better.
8}8}
99
10tribes:new_immovable_type {10tribes:new_immovable_type {
1111
=== modified file 'data/tribes/immovables/berry_bushes/strawberry/init.lua'
--- data/tribes/immovables/berry_bushes/strawberry/init.lua 2018-05-02 08:13:07 +0000
+++ data/tribes/immovables/berry_bushes/strawberry/init.lua 2018-11-23 12:45:17 +0000
@@ -2,9 +2,9 @@
22
3terrain_affinity = {3terrain_affinity = {
4 preferred_temperature = 110, -- Temperature is in arbitrary units.4 preferred_temperature = 110, -- Temperature is in arbitrary units.
5 preferred_humidity = 0.6, -- In percent (1 being very wet).5 preferred_humidity = 600, -- Values between 0 and 1000 (1000 being very wet).
6 preferred_fertility = 0.8, -- In percent (1 being very fertile).6 preferred_fertility = 800, -- Values between 0 and 1000 (1000 being very fertile).
7 pickiness = 0.2, -- Lower means it is less picky, i.e. it can deal better.7 pickiness = 20, -- Lower means it is less picky, i.e. it can deal better.
8}8}
99
10tribes:new_immovable_type {10tribes:new_immovable_type {
1111
=== modified file 'data/world/immovables/bush1/init.lua'
--- data/world/immovables/bush1/init.lua 2017-09-02 16:12:50 +0000
+++ data/world/immovables/bush1/init.lua 2018-11-23 12:45:17 +0000
@@ -83,15 +83,15 @@
83-- -- Temperature is in arbitrary units.83-- -- Temperature is in arbitrary units.
84-- preferred_temperature = 125,84-- preferred_temperature = 125,
85--85--
86-- -- In percent (1 being very wet).86-- -- The preferred humibity. This is a value between 0 and 1000, with 1000 being very wet.
87-- preferred_humidity = 0.65,87-- preferred_humidity = 650,
88--88--
89-- -- In percent (1 being very fertile).89-- -- The preferred fertility. This is a value between 0 and 1000, with 1000 being very fertile.
90-- preferred_fertility = 0.6,90-- preferred_fertility = 600,
91--91--
92-- -- A value in [0, 1] that defines how well this immovable can deal with non-ideal terrain.92-- -- A value in [0, 99] that defines how well this immovable can deal with non-ideal terrain.
93-- -- A lower value means that it is less picky, i.e. it can deal better with it.93-- -- A lower value means that it is less picky, i.e. it can deal better with it.
94-- pickiness = 0.6,94-- pickiness = 60,
95-- }95-- }
96--96--
97-- **animations**97-- **animations**
9898
=== modified file 'data/world/immovables/trees/alder/init.lua'
--- data/world/immovables/trees/alder/init.lua 2016-02-10 19:50:13 +0000
+++ data/world/immovables/trees/alder/init.lua 2018-11-23 12:45:17 +0000
@@ -4,15 +4,15 @@
4 -- Temperature is in arbitrary units.4 -- Temperature is in arbitrary units.
5 preferred_temperature = 125,5 preferred_temperature = 125,
66
7 -- In percent (1 being very wet).7 -- Value between 0 and 1000 (1000 being very wet).
8 preferred_humidity = 0.65,8 preferred_humidity = 650,
99
10 -- In percent (1 being very fertile).10 -- Values between 0 and 1000 (1000 being very fertile).
11 preferred_fertility = 0.6,11 preferred_fertility = 600,
1212
13 -- A value in [0, 1] that defines how well this can deal with non-ideal13 -- A value in [0, 100] that defines how well this can deal with non-ideal
14 -- situations. Lower means it is less picky, i.e. it can deal better.14 -- situations. Lower means it is less picky, i.e. it can deal better.
15 pickiness = 0.6,15 pickiness = 60,
16}16}
1717
18world:new_immovable_type{18world:new_immovable_type{
1919
=== modified file 'data/world/immovables/trees/aspen/init.lua'
--- data/world/immovables/trees/aspen/init.lua 2016-02-10 19:50:13 +0000
+++ data/world/immovables/trees/aspen/init.lua 2018-11-23 12:45:17 +0000
@@ -2,9 +2,9 @@
22
3terrain_affinity = {3terrain_affinity = {
4 preferred_temperature = 100,4 preferred_temperature = 100,
5 preferred_humidity = 0.6,5 preferred_humidity = 600,
6 preferred_fertility = 0.7,6 preferred_fertility = 700,
7 pickiness = 0.8,7 pickiness = 80,
8}8}
99
10world:new_immovable_type{10world:new_immovable_type{
1111
=== modified file 'data/world/immovables/trees/beech/init.lua'
--- data/world/immovables/trees/beech/init.lua 2016-02-10 19:50:13 +0000
+++ data/world/immovables/trees/beech/init.lua 2018-11-23 12:45:17 +0000
@@ -2,9 +2,9 @@
22
3terrain_affinity = {3terrain_affinity = {
4 preferred_temperature = 110,4 preferred_temperature = 110,
5 preferred_humidity = 0.4,5 preferred_humidity = 400,
6 preferred_fertility = 0.6,6 preferred_fertility = 600,
7 pickiness = 0.6,7 pickiness = 60,
8}8}
99
10world:new_immovable_type{10world:new_immovable_type{
1111
=== modified file 'data/world/immovables/trees/birch/init.lua'
--- data/world/immovables/trees/birch/init.lua 2016-02-10 19:50:13 +0000
+++ data/world/immovables/trees/birch/init.lua 2018-11-23 12:45:17 +0000
@@ -2,9 +2,9 @@
22
3terrain_affinity = {3terrain_affinity = {
4 preferred_temperature = 80,4 preferred_temperature = 80,
5 preferred_humidity = 0.65,5 preferred_humidity = 650,
6 preferred_fertility = 0.6,6 preferred_fertility = 600,
7 pickiness = 0.6,7 pickiness = 60,
8}8}
99
10world:new_immovable_type{10world:new_immovable_type{
1111
=== modified file 'data/world/immovables/trees/cirrus/init.lua'
--- data/world/immovables/trees/cirrus/init.lua 2016-02-10 19:50:13 +0000
+++ data/world/immovables/trees/cirrus/init.lua 2018-11-23 12:45:17 +0000
@@ -2,9 +2,9 @@
22
3terrain_affinity = {3terrain_affinity = {
4 preferred_temperature = 110,4 preferred_temperature = 110,
5 preferred_humidity = 0.15,5 preferred_humidity = 150,
6 preferred_fertility = 0.95,6 preferred_fertility = 950,
7 pickiness = 0.8,7 pickiness = 80,
8}8}
99
10world:new_immovable_type{10world:new_immovable_type{
1111
=== modified file 'data/world/immovables/trees/larch/init.lua'
--- data/world/immovables/trees/larch/init.lua 2016-02-10 19:50:13 +0000
+++ data/world/immovables/trees/larch/init.lua 2018-11-23 12:45:17 +0000
@@ -2,9 +2,9 @@
22
3terrain_affinity = {3terrain_affinity = {
4 preferred_temperature = 50,4 preferred_temperature = 50,
5 preferred_humidity = 0.8,5 preferred_humidity = 800,
6 preferred_fertility = 0.45,6 preferred_fertility = 450,
7 pickiness = 0.8,7 pickiness = 80,
8}8}
99
10world:new_immovable_type{10world:new_immovable_type{
1111
=== modified file 'data/world/immovables/trees/liana/init.lua'
--- data/world/immovables/trees/liana/init.lua 2016-02-10 19:50:13 +0000
+++ data/world/immovables/trees/liana/init.lua 2018-11-23 12:45:17 +0000
@@ -2,9 +2,9 @@
22
3terrain_affinity = {3terrain_affinity = {
4 preferred_temperature = 120,4 preferred_temperature = 120,
5 preferred_humidity = 0.2,5 preferred_humidity = 200,
6 preferred_fertility = 0.7,6 preferred_fertility = 700,
7 pickiness = 0.6,7 pickiness = 60,
8}8}
99
10world:new_immovable_type{10world:new_immovable_type{
1111
=== modified file 'data/world/immovables/trees/maple/init.lua'
--- data/world/immovables/trees/maple/init.lua 2016-02-28 08:33:59 +0000
+++ data/world/immovables/trees/maple/init.lua 2018-11-23 12:45:17 +0000
@@ -2,9 +2,9 @@
22
3terrain_affinity = {3terrain_affinity = {
4 preferred_temperature = 110,4 preferred_temperature = 110,
5 preferred_humidity = 0.55,5 preferred_humidity = 550,
6 preferred_fertility = 0.8,6 preferred_fertility = 800,
7 pickiness = 0.8,7 pickiness = 80,
8}8}
99
10world:new_immovable_type{10world:new_immovable_type{
1111
=== modified file 'data/world/immovables/trees/mushroom_dark/init.lua'
--- data/world/immovables/trees/mushroom_dark/init.lua 2016-02-10 19:50:13 +0000
+++ data/world/immovables/trees/mushroom_dark/init.lua 2018-11-23 12:45:17 +0000
@@ -2,9 +2,9 @@
22
3terrain_affinity = {3terrain_affinity = {
4 preferred_temperature = 100,4 preferred_temperature = 100,
5 preferred_humidity = 0.2,5 preferred_humidity = 200,
6 preferred_fertility = 0.8,6 preferred_fertility = 800,
7 pickiness = 0.8,7 pickiness = 80,
8}8}
99
10world:new_immovable_type{10world:new_immovable_type{
1111
=== modified file 'data/world/immovables/trees/mushroom_green/init.lua'
--- data/world/immovables/trees/mushroom_green/init.lua 2016-02-10 19:50:13 +0000
+++ data/world/immovables/trees/mushroom_green/init.lua 2018-11-23 12:45:17 +0000
@@ -2,9 +2,9 @@
22
3terrain_affinity = {3terrain_affinity = {
4 preferred_temperature = 105,4 preferred_temperature = 105,
5 preferred_humidity = 0.2,5 preferred_humidity = 200,
6 preferred_fertility = 0.9,6 preferred_fertility = 900,
7 pickiness = 0.8,7 pickiness = 80,
8}8}
99
10world:new_immovable_type{10world:new_immovable_type{
1111
=== modified file 'data/world/immovables/trees/mushroom_red/init.lua'
--- data/world/immovables/trees/mushroom_red/init.lua 2016-02-10 19:50:13 +0000
+++ data/world/immovables/trees/mushroom_red/init.lua 2018-11-23 12:45:17 +0000
@@ -2,9 +2,9 @@
22
3terrain_affinity = {3terrain_affinity = {
4 preferred_temperature = 80,4 preferred_temperature = 80,
5 preferred_humidity = 0.35,5 preferred_humidity = 350,
6 preferred_fertility = 0.85,6 preferred_fertility = 850,
7 pickiness = 0.6,7 pickiness = 60,
8}8}
99
10world:new_immovable_type{10world:new_immovable_type{
1111
=== modified file 'data/world/immovables/trees/oak/init.lua'
--- data/world/immovables/trees/oak/init.lua 2016-02-10 19:50:13 +0000
+++ data/world/immovables/trees/oak/init.lua 2018-11-23 12:45:17 +0000
@@ -2,9 +2,9 @@
22
3terrain_affinity = {3terrain_affinity = {
4 preferred_temperature = 90,4 preferred_temperature = 90,
5 preferred_humidity = 0.7,5 preferred_humidity = 700,
6 preferred_fertility = 0.5,6 preferred_fertility = 500,
7 pickiness = 0.6,7 pickiness = 60,
8}8}
99
10world:new_immovable_type{10world:new_immovable_type{
1111
=== modified file 'data/world/immovables/trees/palm_borassus/init.lua'
--- data/world/immovables/trees/palm_borassus/init.lua 2016-02-10 19:50:13 +0000
+++ data/world/immovables/trees/palm_borassus/init.lua 2018-11-23 12:45:17 +0000
@@ -2,9 +2,9 @@
22
3terrain_affinity = {3terrain_affinity = {
4 preferred_temperature = 180,4 preferred_temperature = 180,
5 preferred_humidity = 0.4,5 preferred_humidity = 400,
6 preferred_fertility = 0.4,6 preferred_fertility = 400,
7 pickiness = 0.6,7 pickiness = 60,
8}8}
99
10world:new_immovable_type{10world:new_immovable_type{
1111
=== modified file 'data/world/immovables/trees/palm_coconut/init.lua'
--- data/world/immovables/trees/palm_coconut/init.lua 2016-02-10 19:50:13 +0000
+++ data/world/immovables/trees/palm_coconut/init.lua 2018-11-23 12:45:17 +0000
@@ -2,9 +2,9 @@
22
3terrain_affinity = {3terrain_affinity = {
4 preferred_temperature = 130,4 preferred_temperature = 130,
5 preferred_humidity = 0.5,5 preferred_humidity = 500,
6 preferred_fertility = 0.6,6 preferred_fertility = 600,
7 pickiness = 0.6,7 pickiness = 60,
8}8}
99
10world:new_immovable_type{10world:new_immovable_type{
1111
=== modified file 'data/world/immovables/trees/palm_date/init.lua'
--- data/world/immovables/trees/palm_date/init.lua 2016-02-10 19:50:13 +0000
+++ data/world/immovables/trees/palm_date/init.lua 2018-11-23 12:45:17 +0000
@@ -2,9 +2,9 @@
22
3terrain_affinity = {3terrain_affinity = {
4 preferred_temperature = 160,4 preferred_temperature = 160,
5 preferred_humidity = 0.5,5 preferred_humidity = 500,
6 preferred_fertility = 0.5,6 preferred_fertility = 500,
7 pickiness = 0.8,7 pickiness = 80,
8}8}
99
10world:new_immovable_type{10world:new_immovable_type{
1111
=== modified file 'data/world/immovables/trees/palm_oil/init.lua'
--- data/world/immovables/trees/palm_oil/init.lua 2016-02-10 19:50:13 +0000
+++ data/world/immovables/trees/palm_oil/init.lua 2018-11-23 12:45:17 +0000
@@ -2,9 +2,9 @@
22
3terrain_affinity = {3terrain_affinity = {
4 preferred_temperature = 150,4 preferred_temperature = 150,
5 preferred_humidity = 0.55,5 preferred_humidity = 550,
6 preferred_fertility = 0.5,6 preferred_fertility = 500,
7 pickiness = 0.8,7 pickiness = 80,
8}8}
99
10world:new_immovable_type{10world:new_immovable_type{
1111
=== modified file 'data/world/immovables/trees/palm_roystonea/init.lua'
--- data/world/immovables/trees/palm_roystonea/init.lua 2016-02-10 19:50:13 +0000
+++ data/world/immovables/trees/palm_roystonea/init.lua 2018-11-23 12:45:17 +0000
@@ -2,9 +2,9 @@
22
3terrain_affinity = {3terrain_affinity = {
4 preferred_temperature = 160,4 preferred_temperature = 160,
5 preferred_humidity = 0.6,5 preferred_humidity = 600,
6 preferred_fertility = 0.6,6 preferred_fertility = 600,
7 pickiness = 0.9,7 pickiness = 90,
8}8}
99
10world:new_immovable_type{10world:new_immovable_type{
1111
=== modified file 'data/world/immovables/trees/rowan/init.lua'
--- data/world/immovables/trees/rowan/init.lua 2016-02-10 19:50:13 +0000
+++ data/world/immovables/trees/rowan/init.lua 2018-11-23 12:45:17 +0000
@@ -2,9 +2,9 @@
22
3terrain_affinity = {3terrain_affinity = {
4 preferred_temperature = 105,4 preferred_temperature = 105,
5 preferred_humidity = 0.65,5 preferred_humidity = 650,
6 preferred_fertility = 0.75,6 preferred_fertility = 750,
7 pickiness = 0.8,7 pickiness = 80,
8}8}
99
10world:new_immovable_type{10world:new_immovable_type{
1111
=== modified file 'data/world/immovables/trees/spruce/init.lua'
--- data/world/immovables/trees/spruce/init.lua 2016-02-10 19:50:13 +0000
+++ data/world/immovables/trees/spruce/init.lua 2018-11-23 12:45:17 +0000
@@ -2,9 +2,9 @@
22
3terrain_affinity = {3terrain_affinity = {
4 preferred_temperature = 60,4 preferred_temperature = 60,
5 preferred_humidity = 0.7,5 preferred_humidity = 700,
6 preferred_fertility = 0.5,6 preferred_fertility = 500,
7 pickiness = 0.6,7 pickiness = 60,
8}8}
99
10world:new_immovable_type{10world:new_immovable_type{
1111
=== modified file 'data/world/immovables/trees/twine/init.lua'
--- data/world/immovables/trees/twine/init.lua 2016-02-10 19:50:13 +0000
+++ data/world/immovables/trees/twine/init.lua 2018-11-23 12:45:17 +0000
@@ -2,9 +2,9 @@
22
3terrain_affinity = {3terrain_affinity = {
4 preferred_temperature = 95,4 preferred_temperature = 95,
5 preferred_humidity = 0.2,5 preferred_humidity = 200,
6 preferred_fertility = 0.4,6 preferred_fertility = 400,
7 pickiness = 0.8,7 pickiness = 80,
8}8}
99
10world:new_immovable_type{10world:new_immovable_type{
1111
=== modified file 'data/world/immovables/trees/umbrella_green/init.lua'
--- data/world/immovables/trees/umbrella_green/init.lua 2016-02-10 19:50:13 +0000
+++ data/world/immovables/trees/umbrella_green/init.lua 2018-11-23 12:45:17 +0000
@@ -2,9 +2,9 @@
22
3terrain_affinity = {3terrain_affinity = {
4 preferred_temperature = 110,4 preferred_temperature = 110,
5 preferred_humidity = 0.2,5 preferred_humidity = 200,
6 preferred_fertility = 0.85,6 preferred_fertility = 850,
7 pickiness = 0.8,7 pickiness = 80,
8}8}
99
10world:new_immovable_type{10world:new_immovable_type{
1111
=== modified file 'data/world/immovables/trees/umbrella_red/init.lua'
--- data/world/immovables/trees/umbrella_red/init.lua 2016-02-29 17:10:00 +0000
+++ data/world/immovables/trees/umbrella_red/init.lua 2018-11-23 12:45:17 +0000
@@ -2,9 +2,9 @@
22
3terrain_affinity = {3terrain_affinity = {
4 preferred_temperature = 90,4 preferred_temperature = 90,
5 preferred_humidity = 0.15,5 preferred_humidity = 150,
6 preferred_fertility = 0.825,6 preferred_fertility = 825,
7 pickiness = 0.8,7 pickiness = 80,
8}8}
99
10world:new_immovable_type{10world:new_immovable_type{
1111
=== modified file 'data/world/terrains/init.lua'
--- data/world/terrains/init.lua 2017-09-02 16:12:50 +0000
+++ data/world/terrains/init.lua 2018-11-23 12:45:17 +0000
@@ -131,17 +131,17 @@
131--131--
132-- **humidity**132-- **humidity**
133-- *Mandatory*. A terrain affinity constant. These are used to model how well133-- *Mandatory*. A terrain affinity constant. These are used to model how well
134-- trees will grow on this terrain. Humidity is in percent (1 being very wet).134-- trees will grow on this terrain. Values range from 1 - 1000 (1000 being very wet).
135-- Example::135-- Example::
136--136--
137-- humidity = 0.6,137-- humidity = 600,
138--138--
139-- **fertility**139-- **fertility**
140-- *Mandatory*. A terrain affinity constant. These are used to model how well140-- *Mandatory*. A terrain affinity constant. These are used to model how well
141-- trees will grow on this terrain. Fertility is in percent (1 being very141-- trees will grow on this terrain. Values range from 1 - 1000 (1000 being very
142-- fertile). Example::142-- fertile). Example::
143--143--
144-- fertility = 0.7,144-- fertility = 700,
145--145--
146146
147------------------------147------------------------
@@ -167,8 +167,8 @@
167 dither_layer = 340,167 dither_layer = 340,
168168
169 temperature = 100,169 temperature = 100,
170 humidity = 0.6,170 humidity = 600,
171 fertility = 0.7,171 fertility = 700,
172}172}
173173
174174
@@ -187,8 +187,8 @@
187 textures = { pics_dir .. "summer/meadow2_00.png" },187 textures = { pics_dir .. "summer/meadow2_00.png" },
188 dither_layer = 350,188 dither_layer = 350,
189 temperature = 100,189 temperature = 100,
190 humidity = 0.6,190 humidity = 600,
191 fertility = 0.65,191 fertility = 650,
192192
193}193}
194194
@@ -208,8 +208,8 @@
208 textures = { pics_dir .. "summer/meadow3_00.png" },208 textures = { pics_dir .. "summer/meadow3_00.png" },
209 dither_layer = 350,209 dither_layer = 350,
210 temperature = 105,210 temperature = 105,
211 humidity = 0.55,211 humidity = 550,
212 fertility = 0.8,212 fertility = 800,
213}213}
214214
215215
@@ -228,8 +228,8 @@
228 textures = { pics_dir .. "summer/meadow4_00.png" },228 textures = { pics_dir .. "summer/meadow4_00.png" },
229 dither_layer = 350,229 dither_layer = 350,
230 temperature = 110,230 temperature = 110,
231 humidity = 0.65,231 humidity = 650,
232 fertility = 0.75,232 fertility = 750,
233}233}
234234
235235
@@ -244,8 +244,8 @@
244 textures = { pics_dir .. "summer/steppe_00.png" },244 textures = { pics_dir .. "summer/steppe_00.png" },
245 dither_layer = 330,245 dither_layer = 330,
246 temperature = 100,246 temperature = 100,
247 humidity = 0.4,247 humidity = 400,
248 fertility = 0.4,248 fertility = 400,
249}249}
250250
251251
@@ -260,8 +260,8 @@
260 textures = { pics_dir .. "summer/steppe_barren_00.png" },260 textures = { pics_dir .. "summer/steppe_barren_00.png" },
261 dither_layer = 320,261 dither_layer = 320,
262 temperature = 100,262 temperature = 100,
263 humidity = 0.15,263 humidity = 150,
264 fertility = 0.15,264 fertility = 150,
265}265}
266266
267267
@@ -276,8 +276,8 @@
276 textures = { pics_dir .. "summer/mountain_meadow_00.png" },276 textures = { pics_dir .. "summer/mountain_meadow_00.png" },
277 dither_layer = 160,277 dither_layer = 160,
278 temperature = 75,278 temperature = 75,
279 humidity = 0.8,279 humidity = 800,
280 fertility = 0.45,280 fertility = 450,
281}281}
282282
283world:new_terrain_type{283world:new_terrain_type{
@@ -296,8 +296,8 @@
296 textures = { pics_dir .. "summer/forested_mountain1_00.png" },296 textures = { pics_dir .. "summer/forested_mountain1_00.png" },
297 dither_layer = 71,297 dither_layer = 71,
298 temperature = 50,298 temperature = 50,
299 humidity = 0.75,299 humidity = 750,
300 fertility = 0.5,300 fertility = 500,
301}301}
302302
303world:new_terrain_type{303world:new_terrain_type{
@@ -316,8 +316,8 @@
316 textures = { pics_dir .. "summer/forested_mountain2_00.png" },316 textures = { pics_dir .. "summer/forested_mountain2_00.png" },
317 dither_layer = 71,317 dither_layer = 71,
318 temperature = 50,318 temperature = 50,
319 humidity = 0.75,319 humidity = 750,
320 fertility = 0.5,320 fertility = 500,
321}321}
322322
323world:new_terrain_type{323world:new_terrain_type{
@@ -331,8 +331,8 @@
331 textures = { pics_dir .. "summer/mountain1_00.png" },331 textures = { pics_dir .. "summer/mountain1_00.png" },
332 dither_layer = 70,332 dither_layer = 70,
333 temperature = 80,333 temperature = 80,
334 humidity = 0.1,334 humidity = 100,
335 fertility = 0.1,335 fertility = 100,
336}336}
337337
338338
@@ -347,8 +347,8 @@
347 textures = { pics_dir .. "summer/mountain2_00.png" },347 textures = { pics_dir .. "summer/mountain2_00.png" },
348 dither_layer = 70,348 dither_layer = 70,
349 temperature = 80,349 temperature = 80,
350 humidity = 0.1,350 humidity = 100,
351 fertility = 0.1,351 fertility = 100,
352}352}
353353
354354
@@ -363,8 +363,8 @@
363 textures = { pics_dir .. "summer/mountain3_00.png" },363 textures = { pics_dir .. "summer/mountain3_00.png" },
364 dither_layer = 70,364 dither_layer = 70,
365 temperature = 80,365 temperature = 80,
366 humidity = 0.1,366 humidity = 100,
367 fertility = 0.1,367 fertility = 100,
368}368}
369369
370370
@@ -379,8 +379,8 @@
379 textures = { pics_dir .. "summer/mountain4_00.png" },379 textures = { pics_dir .. "summer/mountain4_00.png" },
380 dither_layer = 70,380 dither_layer = 70,
381 temperature = 80,381 temperature = 80,
382 humidity = 0.1,382 humidity = 100,
383 fertility = 0.1,383 fertility = 100,
384}384}
385385
386world:new_terrain_type{386world:new_terrain_type{
@@ -394,8 +394,8 @@
394 textures = { pics_dir .. "summer/beach_00.png" },394 textures = { pics_dir .. "summer/beach_00.png" },
395 dither_layer = 60,395 dither_layer = 60,
396 temperature = 120,396 temperature = 120,
397 humidity = 0.6,397 humidity = 600,
398 fertility = 0.2,398 fertility = 200,
399}399}
400400
401world:new_terrain_type{401world:new_terrain_type{
@@ -410,8 +410,8 @@
410 dither_layer = 370,410 dither_layer = 370,
411 fps = 14,411 fps = 14,
412 temperature = 105,412 temperature = 105,
413 humidity = 0.999,413 humidity = 999,
414 fertility = 0.1,414 fertility = 100,
415}415}
416world:new_terrain_type{416world:new_terrain_type{
417 name = "summer_snow",417 name = "summer_snow",
@@ -424,8 +424,8 @@
424 textures = { pics_dir .. "summer/snow_00.png" },424 textures = { pics_dir .. "summer/snow_00.png" },
425 dither_layer = 220,425 dither_layer = 220,
426 temperature = 50,426 temperature = 50,
427 humidity = 0.999,427 humidity = 999,
428 fertility = 0.001,428 fertility = 1,
429}429}
430430
431431
@@ -440,9 +440,9 @@
440 textures = path.list_files(pics_dir .. "summer/lava/lava_??.png"),440 textures = path.list_files(pics_dir .. "summer/lava/lava_??.png"),
441 dither_layer = 30,441 dither_layer = 30,
442 fps = 4,442 fps = 4,
443 temperature = 1273.0,443 temperature = 1273,
444 humidity = 0.001,444 humidity = 1,
445 fertility = 0.001,445 fertility = 1,
446}446}
447447
448448
@@ -458,8 +458,8 @@
458 dither_layer = 180,458 dither_layer = 180,
459 fps = 14,459 fps = 14,
460 temperature = 100,460 temperature = 100,
461 humidity = 0.999,461 humidity = 999,
462 fertility = 0.001,462 fertility = 1,
463}463}
464464
465------------------------465------------------------
@@ -482,8 +482,8 @@
482 textures = { pics_dir .. "wasteland/ashes_00.png" },482 textures = { pics_dir .. "wasteland/ashes_00.png" },
483 dither_layer = 400,483 dither_layer = 400,
484 temperature = 120,484 temperature = 120,
485 humidity = 0.15,485 humidity = 150,
486 fertility = 0.9,486 fertility = 900,
487}487}
488488
489489
@@ -502,8 +502,8 @@
502 textures = { pics_dir .. "wasteland/ashes2_00.png" },502 textures = { pics_dir .. "wasteland/ashes2_00.png" },
503 dither_layer = 410,503 dither_layer = 410,
504 temperature = 118,504 temperature = 118,
505 humidity = 0.13,505 humidity = 130,
506 fertility = 0.999,506 fertility = 999,
507}507}
508508
509509
@@ -522,8 +522,8 @@
522 textures = { pics_dir .. "wasteland/hardground1_00.png" },522 textures = { pics_dir .. "wasteland/hardground1_00.png" },
523 dither_layer = 420,523 dither_layer = 420,
524 temperature = 100,524 temperature = 100,
525 humidity = 0.25,525 humidity = 250,
526 fertility = 0.8,526 fertility = 800,
527}527}
528528
529529
@@ -542,8 +542,8 @@
542 textures = { pics_dir .. "wasteland/hardground2_00.png" },542 textures = { pics_dir .. "wasteland/hardground2_00.png" },
543 dither_layer = 370,543 dither_layer = 370,
544 temperature = 95,544 temperature = 95,
545 humidity = 0.15,545 humidity = 150,
546 fertility = 0.85,546 fertility = 850,
547}547}
548548
549549
@@ -562,8 +562,8 @@
562 textures = { pics_dir .. "wasteland/hardground3_00.png" },562 textures = { pics_dir .. "wasteland/hardground3_00.png" },
563 dither_layer = 380,563 dither_layer = 380,
564 temperature = 105,564 temperature = 105,
565 humidity = 0.2,565 humidity = 200,
566 fertility = 0.9,566 fertility = 900,
567}567}
568568
569569
@@ -582,8 +582,8 @@
582 textures = { pics_dir .. "wasteland/hardground4_00.png" },582 textures = { pics_dir .. "wasteland/hardground4_00.png" },
583 dither_layer = 390,583 dither_layer = 390,
584 temperature = 90,584 temperature = 90,
585 humidity = 0.2,585 humidity = 200,
586 fertility = 0.8,586 fertility = 800,
587}587}
588588
589589
@@ -598,8 +598,8 @@
598 textures = { pics_dir .. "wasteland/hardlava_00.png" },598 textures = { pics_dir .. "wasteland/hardlava_00.png" },
599 dither_layer = 360,599 dither_layer = 360,
600 temperature = 120,600 temperature = 120,
601 humidity = 0.1,601 humidity = 100,
602 fertility = 0.2,602 fertility = 200,
603}603}
604604
605605
@@ -618,8 +618,8 @@
618 textures = { pics_dir .. "wasteland/forested_mountain1_00.png" },618 textures = { pics_dir .. "wasteland/forested_mountain1_00.png" },
619 dither_layer = 81,619 dither_layer = 81,
620 temperature = 110,620 temperature = 110,
621 humidity = 0.15,621 humidity = 150,
622 fertility = 0.95,622 fertility = 950,
623}623}
624624
625world:new_terrain_type{625world:new_terrain_type{
@@ -637,8 +637,8 @@
637 textures = { pics_dir .. "wasteland/forested_mountain2_00.png" },637 textures = { pics_dir .. "wasteland/forested_mountain2_00.png" },
638 dither_layer = 81,638 dither_layer = 81,
639 temperature = 95,639 temperature = 95,
640 humidity = 0.2,640 humidity = 200,
641 fertility = 0.4,641 fertility = 400,
642}642}
643643
644world:new_terrain_type{644world:new_terrain_type{
@@ -652,8 +652,8 @@
652 textures = { pics_dir .. "wasteland/mountain1_00.png" },652 textures = { pics_dir .. "wasteland/mountain1_00.png" },
653 dither_layer = 90,653 dither_layer = 90,
654 temperature = 80,654 temperature = 80,
655 humidity = 0.05,655 humidity = 50,
656 fertility = 0.2,656 fertility = 200,
657}657}
658658
659659
@@ -668,8 +668,8 @@
668 textures = { pics_dir .. "wasteland/mountain2_00.png" },668 textures = { pics_dir .. "wasteland/mountain2_00.png" },
669 dither_layer = 90,669 dither_layer = 90,
670 temperature = 80,670 temperature = 80,
671 humidity = 0.05,671 humidity = 50,
672 fertility = 0.2,672 fertility = 200,
673}673}
674674
675675
@@ -684,8 +684,8 @@
684 textures = { pics_dir .. "wasteland/mountain3_00.png" },684 textures = { pics_dir .. "wasteland/mountain3_00.png" },
685 dither_layer = 90,685 dither_layer = 90,
686 temperature = 80,686 temperature = 80,
687 humidity = 0.05,687 humidity = 50,
688 fertility = 0.2,688 fertility = 200,
689}689}
690690
691691
@@ -700,8 +700,8 @@
700 textures = { pics_dir .. "wasteland/mountain4_00.png" },700 textures = { pics_dir .. "wasteland/mountain4_00.png" },
701 dither_layer = 80,701 dither_layer = 80,
702 temperature = 80,702 temperature = 80,
703 humidity = 0.05,703 humidity = 50,
704 fertility = 0.2,704 fertility = 200,
705}705}
706706
707707
@@ -716,8 +716,8 @@
716 textures = { pics_dir .. "wasteland/beach_00.png" },716 textures = { pics_dir .. "wasteland/beach_00.png" },
717 dither_layer = 50,717 dither_layer = 50,
718 temperature = 60,718 temperature = 60,
719 humidity = 0.4,719 humidity = 400,
720 fertility = 0.2,720 fertility = 200,
721}721}
722722
723723
@@ -732,9 +732,9 @@
732 textures = path.list_files(pics_dir .. "wasteland/lava_stone1/lava-stone1_??.png"),732 textures = path.list_files(pics_dir .. "wasteland/lava_stone1/lava-stone1_??.png"),
733 dither_layer = 20,733 dither_layer = 20,
734 fps = 7,734 fps = 7,
735 temperature = 1273.0,735 temperature = 1273,
736 humidity = 0.001,736 humidity = 1,
737 fertility = 0.001,737 fertility = 1,
738}738}
739739
740740
@@ -749,9 +749,9 @@
749 textures = path.list_files(pics_dir .. "wasteland/lava_stone2/lava-stone2_??.png"),749 textures = path.list_files(pics_dir .. "wasteland/lava_stone2/lava-stone2_??.png"),
750 dither_layer = 10,750 dither_layer = 10,
751 fps = 7,751 fps = 7,
752 temperature = 1273.0,752 temperature = 1273,
753 humidity = 0.001,753 humidity = 1,
754 fertility = 0.001,754 fertility = 1,
755}755}
756756
757757
@@ -767,8 +767,8 @@
767 dither_layer = 170,767 dither_layer = 170,
768 fps = 14,768 fps = 14,
769 temperature = 100,769 temperature = 100,
770 humidity = 0.999,770 humidity = 999,
771 fertility = 0.001,771 fertility = 1,
772}772}
773773
774774
@@ -792,8 +792,8 @@
792 textures = { pics_dir .. "winter/tundra_00.png" },792 textures = { pics_dir .. "winter/tundra_00.png" },
793 dither_layer = 230,793 dither_layer = 230,
794 temperature = 50,794 temperature = 50,
795 humidity = 0.85,795 humidity = 850,
796 fertility = 0.45,796 fertility = 450,
797}797}
798798
799799
@@ -812,8 +812,8 @@
812 textures = { pics_dir .. "winter/tundra2_00.png" },812 textures = { pics_dir .. "winter/tundra2_00.png" },
813 dither_layer = 240,813 dither_layer = 240,
814 temperature = 55,814 temperature = 55,
815 humidity = 0.75,815 humidity = 750,
816 fertility = 0.45,816 fertility = 450,
817}817}
818818
819819
@@ -832,8 +832,8 @@
832 textures = { pics_dir .. "winter/tundra3_00.png" },832 textures = { pics_dir .. "winter/tundra3_00.png" },
833 dither_layer = 240,833 dither_layer = 240,
834 temperature = 50,834 temperature = 50,
835 humidity = 0.8,835 humidity = 800,
836 fertility = 0.4,836 fertility = 400,
837}837}
838838
839839
@@ -848,8 +848,8 @@
848 textures = { pics_dir .. "winter/tundra_taiga_00.png" },848 textures = { pics_dir .. "winter/tundra_taiga_00.png" },
849 dither_layer = 230,849 dither_layer = 230,
850 temperature = 40,850 temperature = 40,
851 humidity = 0.75,851 humidity = 750,
852 fertility = 0.4,852 fertility = 400,
853}853}
854854
855855
@@ -864,8 +864,8 @@
864 textures = { pics_dir .. "winter/taiga_00.png" },864 textures = { pics_dir .. "winter/taiga_00.png" },
865 dither_layer = 250,865 dither_layer = 250,
866 temperature = 35,866 temperature = 35,
867 humidity = 0.75,867 humidity = 750,
868 fertility = 0.3,868 fertility = 300,
869}869}
870870
871871
@@ -880,8 +880,8 @@
880 textures = { pics_dir .. "winter/snow_00.png" },880 textures = { pics_dir .. "winter/snow_00.png" },
881 dither_layer = 250,881 dither_layer = 250,
882 temperature = 25,882 temperature = 25,
883 humidity = 0.8,883 humidity = 800,
884 fertility = 0.1,884 fertility = 100,
885}885}
886886
887887
@@ -900,8 +900,8 @@
900 textures = { pics_dir .. "winter/forested_mountain1_00.png" },900 textures = { pics_dir .. "winter/forested_mountain1_00.png" },
901 dither_layer = 101,901 dither_layer = 101,
902 temperature = 35,902 temperature = 35,
903 humidity = 0.7,903 humidity = 700,
904 fertility = 0.4,904 fertility = 400,
905}905}
906906
907world:new_terrain_type{907world:new_terrain_type{
@@ -919,8 +919,8 @@
919 textures = { pics_dir .. "winter/forested_mountain2_00.png" },919 textures = { pics_dir .. "winter/forested_mountain2_00.png" },
920 dither_layer = 101,920 dither_layer = 101,
921 temperature = 35,921 temperature = 35,
922 humidity = 0.7,922 humidity = 700,
923 fertility = 0.4,923 fertility = 400,
924}924}
925925
926world:new_terrain_type{926world:new_terrain_type{
@@ -934,8 +934,8 @@
934 textures = { pics_dir .. "winter/mountain1_00.png" },934 textures = { pics_dir .. "winter/mountain1_00.png" },
935 dither_layer = 110,935 dither_layer = 110,
936 temperature = 20,936 temperature = 20,
937 humidity = 0.3,937 humidity = 300,
938 fertility = 0.05,938 fertility = 50,
939}939}
940940
941941
@@ -950,8 +950,8 @@
950 textures = { pics_dir .. "winter/mountain2_00.png" },950 textures = { pics_dir .. "winter/mountain2_00.png" },
951 dither_layer = 110,951 dither_layer = 110,
952 temperature = 20,952 temperature = 20,
953 humidity = 0.3,953 humidity = 300,
954 fertility = 0.05,954 fertility = 50,
955}955}
956956
957957
@@ -966,8 +966,8 @@
966 textures = { pics_dir .. "winter/mountain3_00.png" },966 textures = { pics_dir .. "winter/mountain3_00.png" },
967 dither_layer = 100,967 dither_layer = 100,
968 temperature = 20,968 temperature = 20,
969 humidity = 0.3,969 humidity = 300,
970 fertility = 0.05,970 fertility = 50,
971}971}
972972
973973
@@ -982,8 +982,8 @@
982 textures = { pics_dir .. "winter/mountain4_00.png" },982 textures = { pics_dir .. "winter/mountain4_00.png" },
983 dither_layer = 100,983 dither_layer = 100,
984 temperature = 20,984 temperature = 20,
985 humidity = 0.3,985 humidity = 300,
986 fertility = 0.05,986 fertility = 50,
987}987}
988world:new_terrain_type{988world:new_terrain_type{
989 name = "ice",989 name = "ice",
@@ -996,8 +996,8 @@
996 textures = { pics_dir .. "winter/ice_00.png" },996 textures = { pics_dir .. "winter/ice_00.png" },
997 dither_layer = 260,997 dither_layer = 260,
998 temperature = 25,998 temperature = 25,
999 humidity = 0.5,999 humidity = 500,
1000 fertility = 0.1,1000 fertility = 100,
1001}1001}
10021002
10031003
@@ -1012,8 +1012,8 @@
1012 textures = { pics_dir .. "winter/beach_00.png" },1012 textures = { pics_dir .. "winter/beach_00.png" },
1013 dither_layer = 40,1013 dither_layer = 40,
1014 temperature = 60,1014 temperature = 60,
1015 humidity = 0.5,1015 humidity = 500,
1016 fertility = 0.1,1016 fertility = 100,
1017}1017}
10181018
10191019
@@ -1029,8 +1029,8 @@
1029 dither_layer = 210,1029 dither_layer = 210,
1030 fps = 5,1030 fps = 5,
1031 temperature = 50,1031 temperature = 50,
1032 humidity = 0.999,1032 humidity = 999,
1033 fertility = 0.001,1033 fertility = 1,
1034}1034}
10351035
10361036
@@ -1046,8 +1046,8 @@
1046 dither_layer = 210,1046 dither_layer = 210,
1047 fps = 5,1047 fps = 5,
1048 temperature = 50,1048 temperature = 50,
1049 humidity = 0.999,1049 humidity = 999,
1050 fertility = 0.001,1050 fertility = 1,
1051}1051}
10521052
10531053
@@ -1063,8 +1063,8 @@
1063 dither_layer = 190,1063 dither_layer = 190,
1064 fps = 8,1064 fps = 8,
1065 temperature = 50,1065 temperature = 50,
1066 humidity = 0.999,1066 humidity = 999,
1067 fertility = 0.001,1067 fertility = 1,
1068}1068}
10691069
10701070
@@ -1083,8 +1083,8 @@
1083 textures = { pics_dir .. "desert/desert4_00.png" },1083 textures = { pics_dir .. "desert/desert4_00.png" },
1084 dither_layer = 270,1084 dither_layer = 270,
1085 temperature = 168,1085 temperature = 168,
1086 humidity = 0.001,1086 humidity = 1,
1087 fertility = 0.1,1087 fertility = 100,
1088}1088}
10891089
1090world:new_terrain_type{1090world:new_terrain_type{
@@ -1098,8 +1098,8 @@
1098 textures = { pics_dir .. "desert/drysoil_00.png" },1098 textures = { pics_dir .. "desert/drysoil_00.png" },
1099 dither_layer = 300,1099 dither_layer = 300,
1100 temperature = 172,1100 temperature = 172,
1101 humidity = 0.2,1101 humidity = 200,
1102 fertility = 0.2,1102 fertility = 200,
1103}1103}
1104world:new_terrain_type{1104world:new_terrain_type{
1105 name = "desert_steppe",1105 name = "desert_steppe",
@@ -1116,8 +1116,8 @@
1116 textures = { pics_dir .. "desert/steppe_00.png" },1116 textures = { pics_dir .. "desert/steppe_00.png" },
1117 dither_layer = 360,1117 dither_layer = 360,
1118 temperature = 155,1118 temperature = 155,
1119 humidity = 0.5,1119 humidity = 500,
1120 fertility = 0.5,1120 fertility = 500,
1121}1121}
11221122
11231123
@@ -1136,8 +1136,8 @@
1136 textures = { pics_dir .. "desert/meadow_00.png" },1136 textures = { pics_dir .. "desert/meadow_00.png" },
1137 dither_layer = 310,1137 dither_layer = 310,
1138 temperature = 160,1138 temperature = 160,
1139 humidity = 0.6,1139 humidity = 600,
1140 fertility = 0.6,1140 fertility = 600,
1141}1141}
11421142
11431143
@@ -1156,8 +1156,8 @@
1156 textures = { pics_dir .. "desert/mountainmeadow_00.png" },1156 textures = { pics_dir .. "desert/mountainmeadow_00.png" },
1157 dither_layer = 150,1157 dither_layer = 150,
1158 temperature = 145,1158 temperature = 145,
1159 humidity = 0.5,1159 humidity = 500,
1160 fertility = 0.5,1160 fertility = 500,
1161}1161}
11621162
11631163
@@ -1176,8 +1176,8 @@
1176 textures = { pics_dir .. "desert/highmountainmeadow_00.png" },1176 textures = { pics_dir .. "desert/highmountainmeadow_00.png" },
1177 dither_layer = 150,1177 dither_layer = 150,
1178 temperature = 140,1178 temperature = 140,
1179 humidity = 0.4,1179 humidity = 400,
1180 fertility = 0.4,1180 fertility = 400,
1181}1181}
11821182
11831183
@@ -1196,8 +1196,8 @@
1196 textures = { pics_dir .. "desert/forested_mountain1_00.png" },1196 textures = { pics_dir .. "desert/forested_mountain1_00.png" },
1197 dither_layer = 71,1197 dither_layer = 71,
1198 temperature = 141,1198 temperature = 141,
1199 humidity = 0.5,1199 humidity = 500,
1200 fertility = 0.5,1200 fertility = 500,
1201}1201}
12021202
1203world:new_terrain_type{1203world:new_terrain_type{
@@ -1215,8 +1215,8 @@
1215 textures = { pics_dir .. "desert/forested_mountain2_00.png" },1215 textures = { pics_dir .. "desert/forested_mountain2_00.png" },
1216 dither_layer = 141,1216 dither_layer = 141,
1217 temperature = 120,1217 temperature = 120,
1218 humidity = 0.5,1218 humidity = 500,
1219 fertility = 0.5,1219 fertility = 500,
1220}1220}
12211221
12221222
@@ -1231,8 +1231,8 @@
1231 textures = { pics_dir .. "desert/mountain1_00.png" },1231 textures = { pics_dir .. "desert/mountain1_00.png" },
1232 dither_layer = 120,1232 dither_layer = 120,
1233 temperature = 130,1233 temperature = 130,
1234 humidity = 0.05,1234 humidity = 50,
1235 fertility = 0.05,1235 fertility = 50,
1236}1236}
12371237
12381238
@@ -1247,8 +1247,8 @@
1247 textures = { pics_dir .. "desert/mountain2_00.png" },1247 textures = { pics_dir .. "desert/mountain2_00.png" },
1248 dither_layer = 120,1248 dither_layer = 120,
1249 temperature = 130,1249 temperature = 130,
1250 humidity = 0.05,1250 humidity = 50,
1251 fertility = 0.05,1251 fertility = 50,
1252}1252}
12531253
12541254
@@ -1263,8 +1263,8 @@
1263 textures = { pics_dir .. "desert/mountain3_00.png" },1263 textures = { pics_dir .. "desert/mountain3_00.png" },
1264 dither_layer = 130,1264 dither_layer = 130,
1265 temperature = 130,1265 temperature = 130,
1266 humidity = 0.05,1266 humidity = 50,
1267 fertility = 0.05,1267 fertility = 50,
1268}1268}
12691269
12701270
@@ -1279,8 +1279,8 @@
1279 textures = { pics_dir .. "desert/mountain4_00.png" },1279 textures = { pics_dir .. "desert/mountain4_00.png" },
1280 dither_layer = 140,1280 dither_layer = 140,
1281 temperature = 130,1281 temperature = 130,
1282 humidity = 0.05,1282 humidity = 50,
1283 fertility = 0.05,1283 fertility = 50,
1284}1284}
1285world:new_terrain_type{1285world:new_terrain_type{
1286 name = "desert1",1286 name = "desert1",
@@ -1293,8 +1293,8 @@
1293 textures = { pics_dir .. "desert/desert1_00.png" },1293 textures = { pics_dir .. "desert/desert1_00.png" },
1294 dither_layer = 290,1294 dither_layer = 290,
1295 temperature = 167,1295 temperature = 167,
1296 humidity = 0.001,1296 humidity = 1,
1297 fertility = 0.001,1297 fertility = 1,
1298}1298}
12991299
13001300
@@ -1309,8 +1309,8 @@
1309 textures = { pics_dir .. "desert/desert2_00.png" },1309 textures = { pics_dir .. "desert/desert2_00.png" },
1310 dither_layer = 280,1310 dither_layer = 280,
1311 temperature = 168,1311 temperature = 168,
1312 humidity = 0.001,1312 humidity = 1,
1313 fertility = 0.001,1313 fertility = 1,
1314}1314}
13151315
13161316
@@ -1325,8 +1325,8 @@
1325 textures = { pics_dir .. "desert/desert3_00.png" },1325 textures = { pics_dir .. "desert/desert3_00.png" },
1326 dither_layer = 280,1326 dither_layer = 280,
1327 temperature = 178,1327 temperature = 178,
1328 humidity = 0.001,1328 humidity = 1,
1329 fertility = 0.001,1329 fertility = 1,
1330}1330}
13311331
13321332
@@ -1341,8 +1341,8 @@
1341 textures = { pics_dir .. "desert/beach_00.png" },1341 textures = { pics_dir .. "desert/beach_00.png" },
1342 dither_layer = 60,1342 dither_layer = 60,
1343 temperature = 179,1343 temperature = 179,
1344 humidity = 0.5,1344 humidity = 500,
1345 fertility = 0.1,1345 fertility = 100,
1346}1346}
13471347
13481348
@@ -1358,6 +1358,6 @@
1358 dither_layer = 200,1358 dither_layer = 200,
1359 fps = 5,1359 fps = 5,
1360 temperature = 150,1360 temperature = 150,
1361 humidity = 0.999,1361 humidity = 999,
1362 fertility = 0.001,1362 fertility = 1,
1363}1363}
13641364
=== modified file 'src/logic/game.cc'
--- src/logic/game.cc 2018-11-23 08:20:36 +0000
+++ src/logic/game.cc 2018-11-23 12:45:17 +0000
@@ -1076,8 +1076,4 @@
1076 fw.unsigned_32(general_stats_[p - 1].custom_statistic[j]);1076 fw.unsigned_32(general_stats_[p - 1].custom_statistic[j]);
1077 }1077 }
1078}1078}
1079
1080double logic_rand_as_double(Game* game) {
1081 return static_cast<double>(game->logic_rand()) / std::numeric_limits<uint32_t>::max();
1082}
1083}1079}
10841080
=== modified file 'src/logic/game.h'
--- src/logic/game.h 2018-10-21 09:42:03 +0000
+++ src/logic/game.h 2018-11-23 12:45:17 +0000
@@ -347,9 +347,6 @@
347 location.y += logic_rand() % s - radius;347 location.y += logic_rand() % s - radius;
348 return location;348 return location;
349}349}
350
351// Returns a value between [0., 1].
352double logic_rand_as_double(Game* game);
353}350}
354351
355#endif // end of include guard: WL_LOGIC_GAME_H352#endif // end of include guard: WL_LOGIC_GAME_H
356353
=== modified file 'src/logic/map_objects/immovable.cc'
--- src/logic/map_objects/immovable.cc 2018-09-25 06:32:35 +0000
+++ src/logic/map_objects/immovable.cc 2018-11-23 12:45:17 +0000
@@ -943,7 +943,7 @@
943 FCoords const f = map.get_fcoords(immovable.get_position());943 FCoords const f = map.get_fcoords(immovable.get_position());
944 const ImmovableDescr& descr = immovable.descr();944 const ImmovableDescr& descr = immovable.descr();
945945
946 if (logic_rand_as_double(&game) <946 if ((game.logic_rand() % TerrainAffinity::kPrecisionFactor) <
947 probability_to_grow(descr.terrain_affinity(), f, map, game.world().terrains())) {947 probability_to_grow(descr.terrain_affinity(), f, map, game.world().terrains())) {
948 MapObjectDescr::OwnerType owner_type = descr.owner_type();948 MapObjectDescr::OwnerType owner_type = descr.owner_type();
949 Player* owner = immovable.get_owner();949 Player* owner = immovable.get_owner();
@@ -1030,7 +1030,7 @@
1030 FCoords const f = map.get_fcoords(immovable.get_position());1030 FCoords const f = map.get_fcoords(immovable.get_position());
1031 const ImmovableDescr& descr = immovable.descr();1031 const ImmovableDescr& descr = immovable.descr();
10321032
1033 if (logic_rand_as_double(&game) <1033 if ((game.logic_rand() % TerrainAffinity::kPrecisionFactor) <
1034 probability_to_grow(descr.terrain_affinity(), f, map, game.world().terrains())) {1034 probability_to_grow(descr.terrain_affinity(), f, map, game.world().terrains())) {
1035 // Seed a new tree.1035 // Seed a new tree.
1036 MapFringeRegion<> mr(map, Area<>(f, 0));1036 MapFringeRegion<> mr(map, Area<>(f, 0));
@@ -1047,7 +1047,7 @@
1047 const FCoords new_location = map.get_fcoords(mr.location());1047 const FCoords new_location = map.get_fcoords(mr.location());
1048 if (!new_location.field->get_immovable() &&1048 if (!new_location.field->get_immovable() &&
1049 (new_location.field->nodecaps() & MOVECAPS_WALK) &&1049 (new_location.field->nodecaps() & MOVECAPS_WALK) &&
1050 logic_rand_as_double(&game) < probability_to_grow(descr.terrain_affinity(), new_location,1050 (game.logic_rand() % TerrainAffinity::kPrecisionFactor) < probability_to_grow(descr.terrain_affinity(), new_location,
1051 map, game.world().terrains())) {1051 map, game.world().terrains())) {
1052 game.create_immovable_with_name(mr.location(), type_name, descr.owner_type(),1052 game.create_immovable_with_name(mr.location(), type_name, descr.owner_type(),
1053 nullptr /* owner */, nullptr /* former_building_descr */);1053 nullptr /* owner */, nullptr /* former_building_descr */);
10541054
=== modified file 'src/logic/map_objects/terrain_affinity.cc'
--- src/logic/map_objects/terrain_affinity.cc 2018-04-07 16:59:00 +0000
+++ src/logic/map_objects/terrain_affinity.cc 2018-11-23 12:45:17 +0000
@@ -33,113 +33,122 @@
3333
34namespace {34namespace {
3535
36constexpr double pow2(const double& a) {36// Literature on cross-platform floating point precision-problems:
37// https://arxiv.org/abs/cs/0701192
38// Monniaux, David (2008): "The pitfalls of verifying floating-point computations",
39// in: ACM Transactions on Programming Languages and Systems 30, 3 (2008) 12.
40//
41// Recommends using heximal float constants, but we'd need to switch to C++17 for that.
42//
43// https://randomascii.wordpress.com/2012/03/21/intermediate-floating-point-precision/
44
45constexpr double square(const double& a) {
37 return a * a;46 return a * a;
38}47}
3948
40// Helper function for probability_to_grow49// Helper function for probability_to_grow
41// Calculates the probability to grow for the given affinity and terrain values50// Calculates the probability to grow for the given affinity and terrain values
42double calculate_probability_to_grow(const TerrainAffinity& affinity,51inline unsigned int calculate_probability_to_grow(const TerrainAffinity& affinity,
43 double terrain_humidity,52 int terrain_humidity,
44 double terrain_fertility,53 int terrain_fertility,
45 double terrain_temperature) {54 int terrain_temperature) {
4655 constexpr double kHumidityWeight = 5.00086642549548;
47 constexpr double kHumidityWeight = 0.500086642549548;56 constexpr double kFertilityWeight = 5.292268046607387;
48 constexpr double kFertilityWeight = 0.5292268046607387;57 constexpr double kTemperatureWeight = 0.6131300863608306;
49 constexpr double kTemperatureWeight = 61.31300863608306;58
5059 // Avoid division by 0
51 const double sigma_humidity = (1. - affinity.pickiness());60 assert(affinity.pickiness() < 100);
52 const double sigma_temperature = (1. - affinity.pickiness());61 const double sigma = std::floor(100.0 - affinity.pickiness());
53 const double sigma_fertility = (1. - affinity.pickiness());62
5463 // Unlike real numbers, floating point multiplication/division is neither associative nor commutative. Fortunately, execution order is well-defined by the C++ standard.
55 return exp((-pow2((affinity.preferred_fertility() - terrain_fertility) /64 const double result = exp(-
56 (kFertilityWeight * sigma_fertility)) -65 (square((affinity.preferred_fertility() - terrain_fertility) / (kFertilityWeight * sigma)) +
57 pow2((affinity.preferred_humidity() - terrain_humidity) /66 square((affinity.preferred_humidity() - terrain_humidity) / (kHumidityWeight * sigma)) +
58 (kHumidityWeight * sigma_humidity)) -67 square((affinity.preferred_temperature() - terrain_temperature) / (kTemperatureWeight * sigma))) / 2.0);
59 pow2((affinity.preferred_temperature() - terrain_temperature) /68
60 (kTemperatureWeight * sigma_temperature))) /69 return static_cast<unsigned int>(std::max(0.0, std::floor(result * static_cast<double>(TerrainAffinity::kPrecisionFactor))));
61 2);
62}70}
6371
64} // namespace72} // namespace
6573
66TerrainAffinity::TerrainAffinity(const LuaTable& table, const std::string& immovable_name)74TerrainAffinity::TerrainAffinity(const LuaTable& table, const std::string& immovable_name)
67 : preferred_fertility_(table.get_double("preferred_fertility")),75 : preferred_fertility_(table.get_int("preferred_fertility")),
68 preferred_humidity_(table.get_double("preferred_humidity")),76 preferred_humidity_(table.get_int("preferred_humidity")),
69 preferred_temperature_(table.get_double("preferred_temperature")),77 preferred_temperature_(table.get_int("preferred_temperature")),
70 pickiness_(table.get_double("pickiness")) {78 pickiness_(table.get_int("pickiness")) {
71 if (!(0 <= preferred_fertility_ && preferred_fertility_ <= 1.)) {79 if (!(0 <= preferred_fertility_ && preferred_fertility_ <= 1000)) {
72 throw GameDataError("%s: preferred_fertility is not in [0, 1].", immovable_name.c_str());80 throw GameDataError("%s: preferred_fertility is not in [0, 1000].", immovable_name.c_str());
73 }81 }
74 if (!(0 <= preferred_humidity_ && preferred_humidity_ <= 1.)) {82 if (!(0 <= preferred_humidity_ && preferred_humidity_ <= 1000)) {
75 throw GameDataError("%s: preferred_humidity is not in [0, 1].", immovable_name.c_str());83 throw GameDataError("%s: preferred_humidity is not in [0, 1000].", immovable_name.c_str());
76 }84 }
77 if (!(0 <= pickiness_ && pickiness_ <= 1.)) {85 if (!(0 <= pickiness_ && pickiness_ < 100)) {
78 throw GameDataError("%s: pickiness is not in [0, 1].", immovable_name.c_str());86 throw GameDataError("%s: pickiness is not in [0, 99].", immovable_name.c_str());
79 }87 }
80 if (preferred_temperature_ < 0) {88 if (preferred_temperature_ < 0) {
81 throw GameDataError("%s: preferred_temperature is not possible.", immovable_name.c_str());89 throw GameDataError("%s: preferred_temperature is not possible.", immovable_name.c_str());
82 }90 }
83}91}
8492
85double TerrainAffinity::preferred_temperature() const {93int TerrainAffinity::preferred_temperature() const {
86 return preferred_temperature_;94 return preferred_temperature_;
87}95}
8896
89double TerrainAffinity::preferred_fertility() const {97int TerrainAffinity::preferred_fertility() const {
90 return preferred_fertility_;98 return preferred_fertility_;
91}99}
92100
93double TerrainAffinity::preferred_humidity() const {101int TerrainAffinity::preferred_humidity() const {
94 return preferred_humidity_;102 return preferred_humidity_;
95}103}
96104
97double TerrainAffinity::pickiness() const {105int TerrainAffinity::pickiness() const {
98 return pickiness_;106 return pickiness_;
99}107}
100108
101double probability_to_grow(const TerrainAffinity& affinity,109unsigned int probability_to_grow(const TerrainAffinity& affinity,
102 const FCoords& fcoords,110 const FCoords& fcoords,
103 const Map& map,111 const Map& map,
104 const DescriptionMaintainer<TerrainDescription>& terrains) {112 const DescriptionMaintainer<TerrainDescription>& terrains) {
105 double terrain_humidity = 0;113 // Initialize with 3 to get proper rounding with the integer division in the return statement
106 double terrain_fertility = 0;114 int terrain_humidity = 3;
107 double terrain_temperature = 0;115 int terrain_fertility = 3;
116 int terrain_temperature = 3;
108117
109 const auto average = [&terrain_humidity, &terrain_fertility, &terrain_temperature,118 const auto sum_up_values = [&terrain_humidity, &terrain_fertility, &terrain_temperature,
110 &terrains](const int terrain_index) {119 &terrains](const int terrain_index) {
111 const TerrainDescription& t = terrains.get(terrain_index);120 const TerrainDescription& t = terrains.get(terrain_index);
112 terrain_humidity += t.humidity() / 6.;121 terrain_humidity += t.humidity();
113 terrain_temperature += t.temperature() / 6.;122 terrain_temperature += t.temperature();
114 terrain_fertility += t.fertility() / 6.;123 terrain_fertility += t.fertility();
115 };124 };
116125
117 average(fcoords.field->terrain_d());126 sum_up_values(fcoords.field->terrain_d());
118 average(fcoords.field->terrain_r());127 sum_up_values(fcoords.field->terrain_r());
119 {128 {
120 FCoords tln;129 FCoords tln;
121 map.get_tln(fcoords, &tln);130 map.get_tln(fcoords, &tln);
122 average(tln.field->terrain_d());131 sum_up_values(tln.field->terrain_d());
123 average(tln.field->terrain_r());132 sum_up_values(tln.field->terrain_r());
124 }133 }
125134
126 {135 {
127 FCoords trn;136 FCoords trn;
128 map.get_trn(fcoords, &trn);137 map.get_trn(fcoords, &trn);
129 average(trn.field->terrain_d());138 sum_up_values(trn.field->terrain_d());
130 }139 }
131140
132 {141 {
133 FCoords ln;142 FCoords ln;
134 map.get_ln(fcoords, &ln);143 map.get_ln(fcoords, &ln);
135 average(ln.field->terrain_r());144 sum_up_values(ln.field->terrain_r());
136 }145 }
137146
138 return calculate_probability_to_grow(147 return calculate_probability_to_grow(
139 affinity, terrain_humidity, terrain_fertility, terrain_temperature);148 affinity, terrain_humidity / 6, terrain_fertility / 6, terrain_temperature / 6);
140}149}
141150
142double probability_to_grow(const TerrainAffinity& affinity, const TerrainDescription& terrain) {151unsigned int probability_to_grow(const TerrainAffinity& affinity, const TerrainDescription& terrain) {
143152
144 return calculate_probability_to_grow(153 return calculate_probability_to_grow(
145 affinity, terrain.humidity(), terrain.fertility(), terrain.temperature());154 affinity, terrain.humidity(), terrain.fertility(), terrain.temperature());
146155
=== modified file 'src/logic/map_objects/terrain_affinity.h'
--- src/logic/map_objects/terrain_affinity.h 2018-04-07 16:59:00 +0000
+++ src/logic/map_objects/terrain_affinity.h 2018-11-23 12:45:17 +0000
@@ -31,7 +31,6 @@
3131
32class Map;32class Map;
33class TerrainDescription;33class TerrainDescription;
34class World;
35struct FCoords;34struct FCoords;
3635
37// Describes the parameters and the pickiness of Immovables towards terrain36// Describes the parameters and the pickiness of Immovables towards terrain
@@ -39,39 +38,46 @@
39// define this.38// define this.
40class TerrainAffinity {39class TerrainAffinity {
41public:40public:
41 static constexpr int kPrecisionFactor = 1 << 26;
42
42 explicit TerrainAffinity(const LuaTable& table, const std::string& immovable_name);43 explicit TerrainAffinity(const LuaTable& table, const std::string& immovable_name);
4344
44 // Preferred temperature is in arbitrary units.45 // Preferred temperature is in arbitrary units.
45 double preferred_temperature() const;46 int preferred_temperature() const;
4647
47 // Preferred fertility in percent [0, 1].48 // Preferred fertility, ranging from 0 to 1000.
48 double preferred_fertility() const;49 int preferred_fertility() const;
4950
50 // Preferred humidity in percent [0, 1].51 // Preferred humidity, ranging from 0 to 1000.
51 double preferred_humidity() const;52 int preferred_humidity() const;
5253
53 // A value in [0, 1] that defines how well this can deal with non-ideal54 // A value in [0, 99] that defines how well this can deal with non-ideal
54 // situations. Lower means it is less picky, i.e. it can deal better.55 // situations. Lower means it is less picky, i.e. it can deal better.
55 double pickiness() const;56 int pickiness() const;
5657
57private:58private:
58 double preferred_fertility_;59 const int preferred_fertility_;
59 double preferred_humidity_;60 const int preferred_humidity_;
60 double preferred_temperature_;61 const int preferred_temperature_;
61 double pickiness_;62 const int pickiness_;
6263
63 DISALLOW_COPY_AND_ASSIGN(TerrainAffinity);64 DISALLOW_COPY_AND_ASSIGN(TerrainAffinity);
64};65};
6566
66// Returns a value in [0., 1.] that describes the suitability for the67/**
67// 'immovable_affinity' for 'field'. Higher is better suited.68 * Returns a value in [0, TerrainAffinity::kPrecisionFactor] that describes the suitability for the 'immovable_affinity' for all 6 terrains around 'field'.
68double probability_to_grow(const TerrainAffinity& immovable_affinity,69 * Higher is better suited, with TerrainAffinity::kPrecisionFactor representing a probability of 1.
70 * */
71unsigned int probability_to_grow(const TerrainAffinity& immovable_affinity,
69 const FCoords& fcoords,72 const FCoords& fcoords,
70 const Map& map,73 const Map& map,
71 const DescriptionMaintainer<TerrainDescription>& terrains);74 const DescriptionMaintainer<TerrainDescription>& terrains);
7275
73// Probability to grow for a single terrain76/**
74double probability_to_grow(const TerrainAffinity& immovable_affinity,77 * Returns a value in [0, TerrainAffinity::kPrecisionFactor] that describes the suitability for the 'immovable_affinity' for a single 'terrain'.
78 * Higher is better suited, with TerrainAffinity::kPrecisionFactor representing a probability of 1.
79 * */
80unsigned int probability_to_grow(const TerrainAffinity& immovable_affinity,
75 const TerrainDescription& terrain);81 const TerrainDescription& terrain);
7682
77} // namespace Widelands83} // namespace Widelands
7884
=== modified file 'src/logic/map_objects/tribes/worker.cc'
--- src/logic/map_objects/tribes/worker.cc 2018-11-07 10:19:29 +0000
+++ src/logic/map_objects/tribes/worker.cc 2018-11-23 12:45:17 +0000
@@ -452,11 +452,11 @@
452 const uint32_t attribute_id = ImmovableDescr::get_attribute_id("tree_sapling");452 const uint32_t attribute_id = ImmovableDescr::get_attribute_id("tree_sapling");
453453
454 const DescriptionMaintainer<TerrainDescription>& terrains = game.world().terrains();454 const DescriptionMaintainer<TerrainDescription>& terrains = game.world().terrains();
455 double best = 0.0;455 int best = 0;
456 for (DescriptionIndex i = 0; i < immovables.size(); ++i) {456 for (DescriptionIndex i = 0; i < immovables.size(); ++i) {
457 const ImmovableDescr& immovable_descr = immovables.get(i);457 const ImmovableDescr& immovable_descr = immovables.get(i);
458 if (immovable_descr.has_attribute(attribute_id) && immovable_descr.has_terrain_affinity()) {458 if (immovable_descr.has_attribute(attribute_id) && immovable_descr.has_terrain_affinity()) {
459 double probability =459 int probability =
460 probability_to_grow(immovable_descr.terrain_affinity(), fpos, map, terrains);460 probability_to_grow(immovable_descr.terrain_affinity(), fpos, map, terrains);
461 if (probability > best) {461 if (probability > best) {
462 best = probability;462 best = probability;
@@ -464,7 +464,7 @@
464 }464 }
465 }465 }
466 // normalize value to int16 range466 // normalize value to int16 range
467 const int16_t correct_val = (std::numeric_limits<int16_t>::max() - 1) * best;467 const int16_t correct_val = (std::numeric_limits<int16_t>::max() - 1) * (static_cast<double>(best) / TerrainAffinity::kPrecisionFactor);
468468
469 if (x_check && (correct_val != cache_entry)) {469 if (x_check && (correct_val != cache_entry)) {
470 forester_cache.clear();470 forester_cache.clear();
@@ -798,7 +798,7 @@
798 // affinity). We will pick one of them at random later. The container is798 // affinity). We will pick one of them at random later. The container is
799 // picked to be a stable sorting one, so that no deyncs happen in799 // picked to be a stable sorting one, so that no deyncs happen in
800 // multiplayer.800 // multiplayer.
801 std::set<std::tuple<double, DescriptionIndex, MapObjectDescr::OwnerType>>801 std::set<std::tuple<int, DescriptionIndex, MapObjectDescr::OwnerType>>
802 best_suited_immovables_index;802 best_suited_immovables_index;
803803
804 // Checks if the 'immovable_description' has a terrain_affinity, if so use it. Otherwise assume804 // Checks if the 'immovable_description' has a terrain_affinity, if so use it. Otherwise assume
@@ -809,7 +809,7 @@
809 if (!immovable_description.has_attribute(attribute_id)) {809 if (!immovable_description.has_attribute(attribute_id)) {
810 return;810 return;
811 }811 }
812 double p = 1.;812 int p = TerrainAffinity::kPrecisionFactor;
813 if (immovable_description.has_terrain_affinity()) {813 if (immovable_description.has_terrain_affinity()) {
814 p = probability_to_grow(814 p = probability_to_grow(
815 immovable_description.terrain_affinity(), fpos, map, game.world().terrains());815 immovable_description.terrain_affinity(), fpos, map, game.world().terrains());
@@ -856,18 +856,18 @@
856 // Randomly pick one of the immovables to be planted.856 // Randomly pick one of the immovables to be planted.
857857
858 // Each candidate is weighted by its probability to grow.858 // Each candidate is weighted by its probability to grow.
859 double total_weight = 0.0;859 int total_weight = 0;
860 for (const auto& bsii : best_suited_immovables_index) {860 for (const auto& bsii : best_suited_immovables_index) {
861 double weight = std::get<0>(bsii);861 const int weight = std::get<0>(bsii);
862 total_weight += weight * weight;862 total_weight += weight;
863 }863 }
864864
865 double choice = logic_rand_as_double(&game) * total_weight;865 int choice = game.logic_rand() % total_weight;
866 for (const auto& bsii : best_suited_immovables_index) {866 for (const auto& bsii : best_suited_immovables_index) {
867 double weight = std::get<0>(bsii);867 const int weight = std::get<0>(bsii);
868 state.ivar2 = std::get<1>(bsii);868 state.ivar2 = std::get<1>(bsii);
869 state.ivar3 = static_cast<int>(std::get<2>(bsii));869 state.ivar3 = static_cast<int>(std::get<2>(bsii));
870 choice -= weight * weight;870 choice -= weight;
871 if (0 > choice) {871 if (0 > choice) {
872 break;872 break;
873 }873 }
874874
=== modified file 'src/logic/map_objects/world/terrain_description.cc'
--- src/logic/map_objects/world/terrain_description.cc 2018-04-07 16:59:00 +0000
+++ src/logic/map_objects/world/terrain_description.cc 2018-11-23 12:45:17 +0000
@@ -105,19 +105,19 @@
105 default_resource_index_(world.get_resource(table.get_string("default_resource").c_str())),105 default_resource_index_(world.get_resource(table.get_string("default_resource").c_str())),
106 default_resource_amount_(table.get_int("default_resource_amount")),106 default_resource_amount_(table.get_int("default_resource_amount")),
107 dither_layer_(table.get_int("dither_layer")),107 dither_layer_(table.get_int("dither_layer")),
108 temperature_(table.get_double("temperature")),108 temperature_(table.get_int("temperature")),
109 fertility_(table.get_double("fertility")),109 fertility_(table.get_int("fertility")),
110 humidity_(table.get_double("humidity")) {110 humidity_(table.get_int("humidity")) {
111111
112 if (table.has_key("tooltips")) {112 if (table.has_key("tooltips")) {
113 custom_tooltips_ = table.get_table("tooltips")->array_entries<std::string>();113 custom_tooltips_ = table.get_table("tooltips")->array_entries<std::string>();
114 }114 }
115115
116 if (!(0 < fertility_ && fertility_ < 1.)) {116 if (!(0 < fertility_ && fertility_ < 1000)) {
117 throw GameDataError("%s: fertility is not in (0, 1).", name_.c_str());117 throw GameDataError("%s: fertility is not in (0, 1000).", name_.c_str());
118 }118 }
119 if (!(0 < humidity_ && humidity_ < 1.)) {119 if (!(0 < humidity_ && humidity_ < 1000)) {
120 throw GameDataError("%s: humidity is not in (0, 1).", name_.c_str());120 throw GameDataError("%s: humidity is not in (0, 1000).", name_.c_str());
121 }121 }
122 if (temperature_ < 0) {122 if (temperature_ < 0) {
123 throw GameDataError("%s: temperature is not possible.", name_.c_str());123 throw GameDataError("%s: temperature is not possible.", name_.c_str());
@@ -244,15 +244,15 @@
244 return dither_layer_;244 return dither_layer_;
245}245}
246246
247double TerrainDescription::temperature() const {247int TerrainDescription::temperature() const {
248 return temperature_;248 return temperature_;
249}249}
250250
251double TerrainDescription::humidity() const {251int TerrainDescription::humidity() const {
252 return humidity_;252 return humidity_;
253}253}
254254
255double TerrainDescription::fertility() const {255int TerrainDescription::fertility() const {
256 return fertility_;256 return fertility_;
257}257}
258258
259259
=== modified file 'src/logic/map_objects/world/terrain_description.h'
--- src/logic/map_objects/world/terrain_description.h 2018-04-27 06:11:05 +0000
+++ src/logic/map_objects/world/terrain_description.h 2018-11-23 12:45:17 +0000
@@ -115,13 +115,13 @@
115115
116 /// Parameters for terrain affinity of immovables.116 /// Parameters for terrain affinity of immovables.
117 /// Temperature is in arbitrary units.117 /// Temperature is in arbitrary units.
118 double temperature() const;118 int temperature() const;
119119
120 /// Humidity in percent [0, 1].120 /// Humidity, ranging from 0 to 1000.
121 double humidity() const;121 int humidity() const;
122122
123 /// Fertility in percent [0, 1].123 /// Fertility, ranging from 0 to 1000.
124 double fertility() const;124 int fertility() const;
125125
126 /// Additional tooptip entries for the editor126 /// Additional tooptip entries for the editor
127 const std::vector<std::string>& custom_tooltips() const {127 const std::vector<std::string>& custom_tooltips() const {
@@ -139,9 +139,9 @@
139 int default_resource_amount_;139 int default_resource_amount_;
140 int dither_layer_;140 int dither_layer_;
141 int frame_length_;141 int frame_length_;
142 double temperature_;142 int temperature_;
143 double fertility_;143 int fertility_;
144 double humidity_;144 int humidity_;
145 std::vector<std::string> texture_paths_;145 std::vector<std::string> texture_paths_;
146 std::vector<const Image*> textures_;146 std::vector<const Image*> textures_;
147 RGBColor minimap_colors_[256];147 RGBColor minimap_colors_[256];
148148
=== modified file 'src/scripting/lua_map.cc'
--- src/scripting/lua_map.cc 2018-11-09 01:26:21 +0000
+++ src/scripting/lua_map.cc 2018-11-23 12:45:17 +0000
@@ -1927,8 +1927,8 @@
19271927
1928 returns the terrain affinity values for this immovable1928 returns the terrain affinity values for this immovable
19291929
1930 (RO) a table containing numbers labeled as pickiness (double), preferred_fertility (double),1930 (RO) a table containing numbers labeled as pickiness (uint), preferred_fertility (uint),
1931 preferred_humidity (double), and preferred_temperature (uint),1931 preferred_humidity (uint), and preferred_temperature (uint),
1932 or nil if the immovable has no terrain affinity.1932 or nil if the immovable has no terrain affinity.
1933*/1933*/
1934int LuaImmovableDescription::get_terrain_affinity(lua_State* L) {1934int LuaImmovableDescription::get_terrain_affinity(lua_State* L) {
@@ -1936,13 +1936,13 @@
1936 const TerrainAffinity& affinity = get()->terrain_affinity();1936 const TerrainAffinity& affinity = get()->terrain_affinity();
1937 lua_newtable(L);1937 lua_newtable(L);
1938 lua_pushstring(L, "pickiness");1938 lua_pushstring(L, "pickiness");
1939 lua_pushdouble(L, affinity.pickiness());1939 lua_pushuint32(L, affinity.pickiness());
1940 lua_settable(L, -3);1940 lua_settable(L, -3);
1941 lua_pushstring(L, "preferred_fertility");1941 lua_pushstring(L, "preferred_fertility");
1942 lua_pushdouble(L, affinity.preferred_fertility());1942 lua_pushuint32(L, affinity.preferred_fertility());
1943 lua_settable(L, -3);1943 lua_settable(L, -3);
1944 lua_pushstring(L, "preferred_humidity");1944 lua_pushstring(L, "preferred_humidity");
1945 lua_pushdouble(L, affinity.preferred_humidity());1945 lua_pushuint32(L, affinity.preferred_humidity());
1946 lua_settable(L, -3);1946 lua_settable(L, -3);
1947 lua_pushstring(L, "preferred_temperature");1947 lua_pushstring(L, "preferred_temperature");
1948 lua_pushuint32(L, affinity.preferred_temperature());1948 lua_pushuint32(L, affinity.preferred_temperature());
@@ -2034,7 +2034,7 @@
2034 if (get()->has_terrain_affinity()) {2034 if (get()->has_terrain_affinity()) {
2035 const TerrainDescription* terrain =2035 const TerrainDescription* terrain =
2036 (*get_user_class<LuaMaps::LuaTerrainDescription>(L, 2))->get();2036 (*get_user_class<LuaMaps::LuaTerrainDescription>(L, 2))->get();
2037 lua_pushdouble(L, Widelands::probability_to_grow(get()->terrain_affinity(), *terrain));2037 lua_pushdouble(L, Widelands::probability_to_grow(get()->terrain_affinity(), *terrain) / static_cast<double>(Widelands::TerrainAffinity::kPrecisionFactor));
2038 } else {2038 } else {
2039 lua_pushnil(L);2039 lua_pushnil(L);
2040 }2040 }
@@ -3513,22 +3513,22 @@
3513/* RST3513/* RST
3514 .. attribute:: fertility3514 .. attribute:: fertility
35153515
3516 (RO) the :class:`double` fertility value for this terrain3516 (RO) the :class:`uint` fertility value for this terrain
3517*/3517*/
35183518
3519int LuaTerrainDescription::get_fertility(lua_State* L) {3519int LuaTerrainDescription::get_fertility(lua_State* L) {
3520 lua_pushdouble(L, get()->fertility());3520 lua_pushuint32(L, get()->fertility());
3521 return 1;3521 return 1;
3522}3522}
35233523
3524/* RST3524/* RST
3525 .. attribute:: humidity3525 .. attribute:: humidity
35263526
3527 (RO) the :class:`double` humidity value for this terrain3527 (RO) the :class:`uint` humidity value for this terrain
3528*/3528*/
35293529
3530int LuaTerrainDescription::get_humidity(lua_State* L) {3530int LuaTerrainDescription::get_humidity(lua_State* L) {
3531 lua_pushdouble(L, get()->humidity());3531 lua_pushuint32(L, get()->humidity());
3532 return 1;3532 return 1;
3533}3533}
35343534
35353535
=== modified file 'test/maps/lua_testsuite.wmf/scripting/immovables_descriptions.lua'
--- test/maps/lua_testsuite.wmf/scripting/immovables_descriptions.lua 2018-09-29 05:10:39 +0000
+++ test/maps/lua_testsuite.wmf/scripting/immovables_descriptions.lua 2018-11-23 12:45:17 +0000
@@ -75,22 +75,22 @@
75 local aff_umbrella_green_mature = egbase:get_immovable_description("umbrella_green_wasteland_mature").terrain_affinity75 local aff_umbrella_green_mature = egbase:get_immovable_description("umbrella_green_wasteland_mature").terrain_affinity
7676
77 -- Pickiness77 -- Pickiness
78 assert_near(0.6, aff_alder_sapling["pickiness"], 0.01)78 assert_equal(60, aff_alder_sapling["pickiness"])
79 assert_equal(aff_alder_sapling["pickiness"], aff_alder_old["pickiness"])79 assert_equal(aff_alder_sapling["pickiness"], aff_alder_old["pickiness"])
80 assert_near(0.6, aff_mushroom_red_pole["pickiness"], 0.01)80 assert_equal(60, aff_mushroom_red_pole["pickiness"])
81 assert_near(0.8, aff_umbrella_green_mature["pickiness"], 0.01)81 assert_equal(80, aff_umbrella_green_mature["pickiness"])
8282
83 -- preferred_fertility83 -- preferred_fertility
84 assert_near(0.6, aff_alder_sapling["preferred_fertility"], 0.01)84 assert_equal(600, aff_alder_sapling["preferred_fertility"])
85 assert_equal(aff_alder_sapling["preferred_fertility"], aff_alder_old["preferred_fertility"])85 assert_equal(aff_alder_sapling["preferred_fertility"], aff_alder_old["preferred_fertility"])
86 assert_near(0.85, aff_mushroom_red_pole["preferred_fertility"], 0.01)86 assert_equal(850, aff_mushroom_red_pole["preferred_fertility"])
87 assert_near(0.85, aff_umbrella_green_mature["preferred_fertility"], 0.01)87 assert_equal(850, aff_umbrella_green_mature["preferred_fertility"])
8888
89 -- preferred_humidity89 -- preferred_humidity
90 assert_near(0.65, aff_alder_sapling["preferred_humidity"], 0.01)90 assert_equal(650, aff_alder_sapling["preferred_humidity"])
91 assert_equal(aff_alder_sapling["preferred_humidity"], aff_alder_old["preferred_humidity"])91 assert_equal(aff_alder_sapling["preferred_humidity"], aff_alder_old["preferred_humidity"])
92 assert_near(0.35, aff_mushroom_red_pole["preferred_humidity"], 0.01)92 assert_equal(350, aff_mushroom_red_pole["preferred_humidity"])
93 assert_near(0.2, aff_umbrella_green_mature["preferred_humidity"], 0.01)93 assert_equal(200, aff_umbrella_green_mature["preferred_humidity"])
9494
95 -- preferred_temperature95 -- preferred_temperature
96 assert_equal(125, aff_alder_sapling["preferred_temperature"])96 assert_equal(125, aff_alder_sapling["preferred_temperature"])
9797
=== modified file 'test/maps/lua_testsuite.wmf/scripting/terrains_resources_descriptions.lua'
--- test/maps/lua_testsuite.wmf/scripting/terrains_resources_descriptions.lua 2016-07-10 19:03:33 +0000
+++ test/maps/lua_testsuite.wmf/scripting/terrains_resources_descriptions.lua 2018-11-23 12:45:17 +0000
@@ -141,17 +141,17 @@
141end141end
142142
143function test_terrains_resource_descr:test_terrain_fertility()143function test_terrains_resource_descr:test_terrain_fertility()
144 assert_near(0.7, egbase:get_terrain_description("summer_meadow1").fertility, 0.01)144 assert_equal(700, egbase:get_terrain_description("summer_meadow1").fertility)
145 assert_near(0.2, egbase:get_terrain_description("wasteland_beach").fertility, 0.01)145 assert_equal(200, egbase:get_terrain_description("wasteland_beach").fertility)
146 assert_near(0.5, egbase:get_terrain_description("desert_forested_mountain2").fertility, 0.01)146 assert_equal(500, egbase:get_terrain_description("desert_forested_mountain2").fertility)
147 assert_near(0.001, egbase:get_terrain_description("winter_water").fertility, 0.0001)147 assert_equal(1, egbase:get_terrain_description("winter_water").fertility)
148end148end
149149
150function test_terrains_resource_descr:test_terrain_humidity()150function test_terrains_resource_descr:test_terrain_humidity()
151 assert_near(0.6, egbase:get_terrain_description("summer_meadow1").humidity, 0.01)151 assert_equal(600, egbase:get_terrain_description("summer_meadow1").humidity)
152 assert_near(0.4, egbase:get_terrain_description("wasteland_beach").humidity, 0.01)152 assert_equal(400, egbase:get_terrain_description("wasteland_beach").humidity)
153 assert_near(0.5, egbase:get_terrain_description("desert_forested_mountain2").humidity, 0.01)153 assert_equal(500, egbase:get_terrain_description("desert_forested_mountain2").humidity)
154 assert_near(0.999, egbase:get_terrain_description("winter_water").humidity, 0.0001)154 assert_equal(999, egbase:get_terrain_description("winter_water").humidity)
155end155end
156156
157function test_terrains_resource_descr:test_terrain_temperature()157function test_terrains_resource_descr:test_terrain_temperature()

Subscribers

People subscribed via source and target branches

to status/vote changes: