Bay 12 Games Forum

Please login or register.

Login with username, password and session length
Advanced search  

Author Topic: [DF Hack] [Tiletypes/lua data] Forced Plant Growth  (Read 4304 times)

Kyphis

  • Bay Watcher
    • View Profile
[DF Hack] [Tiletypes/lua data] Forced Plant Growth
« on: October 18, 2013, 04:19:57 pm »

[I'm useing Vanilla DF 34.11 with Ironhand's Graphics pack. Results may vary, but should not]

So I have been trying to force trees to grow in specific tiles.

Tiletypes lets me force saplings/trees where ever I want, but these plants lack any sort of plant association.

Useing lua, I can open the tile and find the following information:
printall(tile.plants) gives me a list of typically 0-5 plant entries for each tile.
printall(tile.plants[ x]) gives me the individual plant information.

printall(tile.plants[ x]) shows me a list of information, the ones that seem to be relevant are:
tile.plants[ x].material=
tile.plants[ x].grow_counter=
tile.plants[ x].update_order=
tile.plants[ x].hitpoints=
tile.plants[ x].flags.is_shrub=

"material" is definitely needed, that tells you what type of plant it is.
"grow_counter" is fairly optional, but it may result in dead bushes if left too high for bushes; or saplings if left too low for trees.
"update_order" is a complete mystery as to whether it is needed or not, any advice should be useful. So far I am assuming I can safely ignore this.
"hitpoints" is a little relevant, bushes/grasses seem to have 100000; while trees/saplings seem to have 400000. I have not tested this extensively, values may vary (although fiddling with it hasn't really caused any issues so far)
"flags.is_shrub" is important. It needs to be [false] if you want a tree, and [true] in all other circumstances.

Fiddling with these settings however, I find that instead of turning my [Tiletypes] fake plant into a real one, plants in other tiles instead turn into impossible configurations (usually resulting in a dead bush with no image data).
Further investigation turns up that for each "tile.plants[ x]" entry there is also a ".pos" entry. These entries contain the actual coordinates for each plant the tile stores. To get the correct result, "tile.plants[ x].pos" needs to be altered to reflect the tile of the fake plant as well.

However, when we mess with the ".pos" entries we find that the tile it used to point to now displays a problem plant.

Further investigation of the ".pos" scatter shows that the referenced plant tile can have a maximum x/y variance of +/-12 from the target tile (so say your starting tile was x=275 and y=465, you could have x values from 263 to 287, and y values from 453 to 477). This means that there are 625 possible squares for you to search to find the correct one to edit without breaking any other tile. This gives 3750 "tile.plants[ x].pos" entries to check at most.

Because each tile has multiple entries and they are restricted to areas within 12 of the source tile, it should be possible to determine some sort of pattern with further testing.
Sadly I do not have significant data as yet, only having looked at two tiles. Any further data is welcome.
Spoiler (click to show/hide)

Ignoring problems with altering ".pos" for now, I have examined the data further and determined the following:
Setting "tile.plants[ x].flags.is_shrub=" does not prevent you from creating shrubs or trees if you use the wrong settings. It determines what the game calls the tile, as well as possibly what rate it decays over time (more experimentation is need to see if shrubs with is_shrub=false will remain intact forever, or die as normal)
The only information that must be in place to create a plant is:
tile.plants[ x].material=
tile.plants[ x].pos.x=
tile.plants[ x].pos.y=
tile.plants[ x].pos.z=

"tile.plants[ x].pos.z" has always turned up correctly for me so far, although I have not looked near slopes (I do expect it to always be correct).




Thoughts/contributions/contradictions? I am hoping we can gather enough data to see proper plant growth added to the tiletypes plugin.
« Last Edit: October 20, 2013, 04:23:58 am by Kyphis »
Logged

Quietust

  • Bay Watcher
  • Does not suffer fools gladly
    • View Profile
    • QMT Productions
Re: [DF Hack] [Tiletypes/lua data] Forced Plant Growth
« Reply #1 on: October 30, 2013, 12:18:30 pm »

Technically, we already have all of the data we need; it just wasn't documented in detail.

Plant objects are stored in multiple locations - they are stored in world.plants.all, world.plants.[shrub|tree]_[dry|wet] (according to the "watery" and "is_shrub" flags inside the plant itself), and inside the map_block which contains them.

As for the fields within the object itself, you really should be populating all of them with proper values.
* "name" gives the plant a name - if you ever played version 0.28.181.39a or older and visited an Elven forest retreat, you would have observed that every tree there had a name.
* "flags" identifies whether it's a tree or shrub and whether it was placed in a dry or wet region. As mentioned above, this is for categorization (so the game can access them more quickly) and must be set consistently.
* "material" identifies what type of plant it is.
* "pos" indicates the plant's location. As noted above, the plant object pointer must also be stored within the appropriate map_block in order for it to work correctly.
* "grow_counter" is the plant's age in tens of ticks (i.e. 120 ticks is one day) - newly created plants have a value of 0, and saplings grow into trees once this value reaches 120960 (3 years, contrary to the "1.5 years" figure mentioned on the wiki).
* "temperature" is the plant's current temperature. If it gets too hot or cold, the plant will start to take damage (i.e. its hitpoints will start to decrease). Newly created plants should have a temperature matching the environment, though a value of 10050 will probably work fine.
* "damage_flags" indicates if the plant is taking ongoing damage of some type - "is_burning" means it's on fire, and "is_drowning" means it's submerged under water whose depth is greater or equal than the plant's corresponding DROWN_LEVEL in the raws.
* "hitpoints" is how much health the plant has. As you observed, shrubs start with 100,000 hitpoints and trees start with 400,000 hitpoints. Once this value reaches zero, the plant will die.
* "update_order" determines when the plant gets updated - every 10 frames, the game processes plants whose update_order matches "(cur_year_tick / 10) % 10" in order to reduce lag (older versions updated every plant every frame). Valid values are 0 thru 9, inclusive.
* "contaminants" lists all contaminants on the plant. In practice, this only contains water when it is raining, and it's used to prevent you from setting it on fire.
* "temperature_tile_tick" appears to keep track of the last time temperature_tile was updated. This should be initialized to -1.
* "temperature_tile" appears to be the cached temperature of the tile in which the plant is located. This should be initialized to 60001.
* "min_safe_temp" is the cached minimum safe temperature in which the plant can survive - if the tile temperature goes below this, it will start to take damage. This should be initialized to 9900.
* "max_safe_temp" is the cached maximum safe temperature in which the plant can survive - if the tile temperature goes above this, it will start to take damage, catch fire, or melt/evaporate. This should be initialized to 60001.

[edit] I've written a "createplant" command within the Plants plugin which allows creation of shrubs and saplings (if you want to make it into a tree, use the "grow" command afterwards).
« Last Edit: October 30, 2013, 10:56:23 pm by Quietust »
Logged
P.S. If you don't get this note, let me know and I'll write you another.
It's amazing how dwarves can make a stack of bones completely waterproof and magmaproof.
It's amazing how they can make an entire floodgate out of the bones of 2 cats.