Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Tree harvesting #24110

Closed

Conversation

@ProfoundDarkness
Copy link
Contributor

commented Jun 27, 2018

This is my first real attempt at something kind of big so I hope I didn't mangle things too badly.

SUMMARY: Features "Tree harvesting."

Concept originally lifted from Wilderness Overhaul mod by MormonPartyboat.

Adds a new mod called treeharvesting which does the following:
-Can cut a tree via the construction interface. When done will replace the terrain tile and drop a cutting on the ground. For example if original terrain was t_tree_apple then will become t_tree_apple_cut.
-Trees that can be cut are Apple, Pear, Cherry, Peach, Apricot, Plum.
-A cut tree is not harvestable.
-It takes a year for a cut tree to recover from being cut (via code). After that year it reverts to the harvested type (json). Pre-existing code handles reverting the tree back to normal and then on the next harvesting season it can be harvested again. Original mod required tree to be in harvestable state so one had to choose between harvest or cut and wait a year to go again. Hence the 1 year delay in code.
-A cutting quickly rots unless placed into a pot (separate recipe for making pots using clay).
-After some time the potted tree becomes a sapling and can be planted, after some time the planted sapling grows to become a new tree.

Code changes are:
-Alterations to Construction code to support the option to drop items after transforming the terrain with the items coming from json.
-Alterations to Map code to support transforming cut trees much like how harvested trees work.
--Code changes should be inert without the mod.

The new stuff I've added in the last few days I've tried to stick to proper styling and such but some of this is from over a year ago. The seemingly recent start is due to rebasing the mod to a more recent cdda master. Code might be OK but pretty sure the json isn't properly linted/formatted and I don't know how to automatically handle/check that.

ProfoundDarkness added some commits Jun 17, 2017

Pulled the tree features from Wilderness_Overhaul (old mod).
Added a minimum amount of code to support the mod.  Basically adds a new field containing the various items that should be dropped under the player at the conclusion of the construction task.

Would like to enhance this in order to have some construction jobs yield resources but for now it's the minimum of support by adding a single function to support dropping a different item for each type of fruit tree.

Feature:
-Added id clay_plant_pot and construction recipe.
-For each type of fruit tree (apple, pear, cherry, peach, apricot, plum) added the following items:
--terrain type, id "t_tree_<fruit>_cut" which is basically just a clone of the id "t_tree<fruit>".  This is harvestable just like the original fruit tree after which it can be cut again.
--construction task to "Plant <fruit> Tree" utilizing a "<fruit>_sapling"
--construction task (this uses the new code) to take a cutting from the <fruit> tree turning it into the cut version and dropping a <fruit>_cutting item at the player's feet.
--Added a new COMESTIBLE named <fruit>_cutting, edible and fast rotting but not very filling nor enjoyable.
--Added a new COMESTIBLE named <fruit>_sapling, edible and fast rotting but not very filling nor enjoyable.
--Added a new TOOL item named "potted <fruit> tree" which takes about 2 weeks to become usable at which time the container "clay_plant_pot" and a "<fruit>_sapling" is available.
--A recipe to take a "<fruit>_cutting" and a "clay_plant_pot" to create a "<fruit>_cutting_potted".
Modified ChesHole32Tileset for cut trees.
It's probably not a complete work since I haven't been able to find a working tileset reader/editor so the changes were by hand via notepad++ to the json file.
Tweaked tree harvesting and code to be a bit closer to desired.
-Cut trees will now regenerate after quite a long while instead of just next season.
-Can't harvest cut trees.
-Cut trees now have proper flags and copy-from attributes.
-The choice to include harvested flag is to reduce amount of code changed outside of json files.

Currently the time required to regenerate is hard coded to 1 year and since the tree becomes a harvested variant (json controllable) it's technically 1 year and 1 season.  Debug tests seem to bear this out.

Tree harvesting stuff is still a mod rather than fully incorporated into the game.  With the new farm components showing up I am considering requiring fertilizer on top of current requirements.

Originally wanted trees to only be cut-able when they were harvestable so players had a clear choice and for balance purposes.  Would need to add yet more code to support seasonal construction limits so opted with the 1 year recovery time to keep some balance with code changes low.
Reverted a bunch of style mistakes I somehow (probably year ago) intr…
…oduced into this branch.

Also styled some of my code to match current style (probably not perfect).
@ZhilkinSerg

This comment has been minimized.

Copy link
Contributor

commented Jun 27, 2018

Please make use of online linter (http://dev.narc.ro/cataclysm/format.html) to format json files.

@@ -157,6 +157,7 @@ static const std::unordered_map<std::string, ter_bitflags> ter_bitflags_map = {
{ "NO_FLOOR", TFLAG_NO_FLOOR }, // Things should fall when placed on this tile
{ "SEEN_FROM_ABOVE", TFLAG_SEEN_FROM_ABOVE },// This should be visible if the tile above has no floor
{ "RAMP", TFLAG_RAMP }, // Can be used to move up a z-level
{ "CUT", TFLAG_CUT }, // cut plant, will not bear fruit this nor next year.

This comment has been minimized.

Copy link
@ZhilkinSerg

ZhilkinSerg Jun 27, 2018

Contributor

Please use whitespaces instead of tabs.

@@ -165,6 +165,7 @@ enum ter_bitflags : int {
TFLAG_NO_FLOOR,
TFLAG_SEEN_FROM_ABOVE,
TFLAG_RAMP,
TFLAG_CUT,

This comment has been minimized.

Copy link
@ZhilkinSerg

ZhilkinSerg Jun 27, 2018

Contributor

Please use whitespaces instead of tabs.

@Rivet-the-Zombie

This comment has been minimized.

Copy link
Member

commented Jun 27, 2018

Adds a new mod

This sounds like it should be mainline content.

@nexusmrsep

This comment has been minimized.

Copy link
Contributor

commented Jun 27, 2018

It would require years for cutting from a fruit producing tree to grow from a sapling to a mature tree, and even more to produce fruit IRL.

How long will it take here?

@Mecares

This comment has been minimized.

Copy link
Contributor

commented Jun 27, 2018

I personally would like if it would need a realistic time to grow unless you mix some plant mutagen and fertilizer for a growth accelerant to allow faster than realistic speed for the trees to grow.

@kevingranade

This comment has been minimized.

Copy link
Member

commented Jun 27, 2018

I agree with all of the above points, this belongs in mainline, by default it should take a IRL-based amount of time to mature, and we can certainly have a growth accelerant option.
For the accelerant though, I'm thinking something triffid-based rather than blob or mutagen based.

Also, see http://homeguides.sfgate.com/long-apple-trees-mature-produce-fruit-56479.html
http://homeguides.sfgate.com/fastest-growing-fruit-tree-50865.html
tl;dr

  • Trees grown from seed require six to 10 years to produce fruit. (I'm pretty sure this is dominated by sapling -> mature tree growth, so starting from a sapling doesn't reduce it by much)
  • A dwarf tree will begin producing fruit two to three years after you plant it.
@ZhilkinSerg

This comment has been minimized.

Copy link
Contributor

commented Jun 27, 2018

For the accelerant though, I'm thinking something triffid-based rather than blob or mutagen based.

With some kind of bio-lab to get required reagents.

Formatted json.
-Figured out from more reading of Makefile.

Also fixed several 'an' where 'a' is more apt in text.
@ProfoundDarkness

This comment has been minimized.

Copy link
Contributor Author

commented Jun 28, 2018

How long it takes to harvest?
So I did some careful tests (gotta remember to get the tree out of the reality bubble) just to be sure and it looks like the time from pot to harvest is 2 weeks (json) and 1 season (code). That is 201600 turns after putting cutting in pot and becoming a sapling (ready to plant). When planted (construction job) it becomes a full grown tree... It won't bear fruit if planted in the same season as can harvest (from tests) but if planted the day before harvest season starts it's good to go... I don't like that at all.

I'm digging around the code some to see if there's something I can use (ie young tree) or other ideas. I can use the existing code infrastructure (added by this PR to map and mapdata) and add additional terrain elements just with json. So when you do the construction that plants the tree a new terrain element (t_tree_apple_young) is generated. Could even do stages like t_tree_apple_sapling which points to t_tree_apple_young which points to t_tree_apple. Bonus to this approach is could also add a new t_tree_apple_seedling which points to t_tree_apple_sapling. If variability of each stage is desirable I need to figure out how to pull some more data in from json and/or store something more in a terrain element. Given some further quick reading beyond the resources that were posted I think variability is useful but I don't know if the cost of it is worth it (terrain bloat, code size).

Got lost in pre-post edits, thanks for the resources. I'm not in any way familiar IRL with what I'm fiddling with for the cdda.

Removed some forgotten tabs from mapdata
Added some previously planned fertilizer requirements to potting and planting steps.  I don't know if amounts are apt, the potting stage should probably not require a lot but the planting stage seems apt to require more.
return; // Plant isn't cut. Do nothing.
}
// Restore the tree to normal growth so that eventually it can bear fruit.
if( time_since_last_actualize >= calendar::year_length() ) {

This comment has been minimized.

Copy link
@Coolthulhu

Coolthulhu Jun 28, 2018

Contributor

Pretty sure that isn't what you want.
time_since_last_actualize depends on the time since you last loaded that map segment. So this will only trigger if you never load this map segment for a whole year. If you visit the tree every 90% of a year, for 10 years, it will not trigger.

Actually noting the date of when the cut was made is much harder than it sounds, so you're better off just making the cuttings always kill the tree and produce multiple cuttings at a time.

* Try to restore a cut static plant to normal.
* @param p Place to restore
* @param time_since_last_actualise Time since this function has been
* called the last time.

This comment has been minimized.

Copy link
@Coolthulhu

Coolthulhu Jun 28, 2018

Contributor

Time since this function has been called the last time.

Oh, I see where the misconception came from. The function above has same (wrong) comment.
The correct description would be:

Time since the map segment was last loaded

@ProfoundDarkness

This comment has been minimized.

Copy link
Contributor Author

commented Jun 28, 2018

Yeah, I figured out how that variable worked just before going to bed (grep is great). Thanks though, I was going to ask if I didn't figure out just how that var worked.

Turns out that I need a piece of data saved somewhere about that terrain. Either directly on the terrain's data (not in data/json file) or maybe something stored as part of the overmap tile. For the second case thinking of something like a dictionary of that particular terrain's position in the overmap tile.

Failing either of those being reasonable I'd need to look at a route for tree growth in the world that doesn't start out as a terrain via construction.

Still poking around. I'm open to suggestions though, particularly if there was a deliberate design decision NOT to do something like I'm thinking about.

As an aside turns out the code I have could be leveraged to allow things like turning water terrain to ice in winter... Something I was thinking about poking at later after the trees.

@Coolthulhu

This comment has been minimized.

Copy link
Contributor

commented Jun 29, 2018

I think there is a clever way around this problem:
Notice that a tree will only fruit once per year. You can limit the tree to 3 states:

  • Bearing fruit
  • Will bear fruit in less than a year
  • Will bear fruit in less than two years

By reusing the fruit timer for cuttings, you'd avoid a big rework.
Or even skip the third state and only allow cutting fruiting trees.

If not, you could copy the hack used for plants. Ensure the trees can't store items normal way (verify it on load, debugmsg if any cut tree can lacks appropriate flags), then on cutting, store a token item in it in some hacky way (I think it works if you change the terrain to grass, place the token, then change terrain to what you want). You can then use this item's birthday as a milestone.
Make sure that if the terrain type changes (map::ter_set is guaranteed to be called in all normal cases), you remove the token item from map.
This isn't very pretty, but it works, provided you handle all the cases.

If you want a bigger project, you could add a generic terrain descriptor feature to submap structure. I see it like this:

  • submap class gets a std::shared_ptr<tile_descriptor> get_{terrain,furniture}_descriptor<tile_descriptor>( x, y ) getter (and appropriate setters)
  • The getter returns a descriptor of the appropriate type on a given tile if one exists. Otherwise nullptr. Alternatively, this could use cata::optional to avoid nullptr.
  • submap class gets a field: std::unordered_map<descriptor_type, std::unique_ptr<tile_descriptor>> [SEEX][SEEY]
  • descriptor is an empty abstract class, derived classes have relevant data
  • Descriptors are reset on terrain/furniture change, saved and loaded with map

Descriptors could work for things like terrain damage, plant status (watered/fertilized/age/species/sex/nectar/sustained damage), door key shape, half-finished construction job, partial fungalization, hidden items (graves, stashes) etc. without having all other terrain types carry this information unintentionally.
Basically, attaching a class to terrain types - currently terrain is defined almost entirely by its type (which is an enum).

@@ -165,6 +165,7 @@ enum ter_bitflags : int {
TFLAG_NO_FLOOR,
TFLAG_SEEN_FROM_ABOVE,
TFLAG_RAMP,
TFLAG_CUT,

This comment has been minimized.

Copy link
@Coolthulhu

Coolthulhu Jun 29, 2018

Contributor

ter_bitflags is supposed to only have very frequently used flags in it. That is, flags that are read multiple times per turn.
Flags that are only read once per tile per load should be addressed by their string.

@ProfoundDarkness

This comment has been minimized.

Copy link
Contributor Author

commented Jun 29, 2018

Hmm... It's not a different terrain tile for bearing fruit, not even a different flag or such, bearing fruit is an outcropping of the json harvest info with season specified on the harvest... "harvest_by_season" json, that's it. (below edited for brevity)

On the more rapid approach to trees:

On cutting: I'm fond of the idea of returning to the rules of the original mod, can take cuttings on harvest season and only from unharvested plants. Still need the seasonal construction code added. This is less realistic though since cuttings in harvest season is a bad idea, best taken from spring with off harvest seasons summer/fall or winter being at least 25% slower for growth. Simpler code though with the map and mapdata changes not being necessary, cutting gets handled almost entirely from json and pre-this PR code.

On growing: Re-using the method present for crops, except when the crop is 'grown' the tile is replaced sounds like the more apt path of using what is already present. Though I seem to remember reading issues with crop times and abnormal game time settings, this was back in around 2016 or so though. Bonus of this path is a simpler system from what I was considering relating to ways of speeding up tree growth. Ideally instead of using ploughed tile one would construct a place to plant the sapling as the saplings being considered by this PR require support (early on).

I'll admit the bigger project sounds interesting to me. It would be my intent NOT to include such extra data on terrain that doesn't need it, kind of where the dictionary (OO languages) concept popped in.

I'm probably going to be reading for a bit as I need to look through the code to see what path is more appealing for trees... ie Better to step away from trees and pursue bigger project and then plug trees into that (well use trees as the base model to apply) or if current systems make more sense to hang off of. It sounds like the bigger project could exist side by side with other mechanics for a while as a compatibility measure, if there are other things to be moved over to it, so that's neat.

@DracoGriffin DracoGriffin added this to To do in farming improvements via automation Jul 8, 2018

@DracoGriffin DracoGriffin moved this from To do to In progress in farming improvements Jul 8, 2018

@ZhilkinSerg ZhilkinSerg removed the (P2 - High) label Aug 5, 2018

@ZhilkinSerg ZhilkinSerg referenced this pull request Aug 15, 2018

Merged

Improve crop farming. #24291

8 of 8 tasks complete
@ZhilkinSerg

This comment has been minimized.

Copy link
Contributor

commented Sep 10, 2018

Marking this PR as Stalled and closing to clean up PR queue. Feel free to ping me and I'll reopen it if you want to continue your work.

farming improvements automation moved this from In progress to Done Sep 10, 2018

@kevingranade

This comment has been minimized.

Copy link
Member

commented Jan 6, 2019

This pull request has been mentioned on Cataclysm: Dark Days Ahead. There might be relevant details there:

https://discourse.cataclysmdda.org/t/can-i-plant-a-tree/18220/4

@kevingranade

This comment has been minimized.

Copy link
Member

commented Apr 3, 2019

This pull request has been mentioned on Cataclysm: Dark Days Ahead. There might be relevant details there:

https://discourse.cataclysmdda.org/t/making-new-trees/19519/4

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
You can’t perform that action at this time.