From bb78b9c49b91ad9d9a10f641e2645c0984759d4d Mon Sep 17 00:00:00 2001 From: Bloop <13398309+vinylspiders@users.noreply.github.com> Date: Mon, 1 Dec 2025 18:40:16 -0500 Subject: [PATCH] Axes harvest products into procs instead of lists (#94233) ## About The Pull Request ###### Get it? Cause you're chopping down trees... Why do this at all? Well, we have been looking into memory consumption and found an unexpectedly high amount of lists on flora objects. Was talking about it with Melbert, we agreed this would be a good way of removing needless lists on every blade of grass that are just taking up memory. Instead, these lists will be generated and consumed when the actually chopping down of a tree occurs. ## Why It's Good For The Game Uploads some more RAM ## Changelog Not player-facing, things will function the same as they always have. --- code/game/objects/structures/flora.dm | 51 ++++++++++++++--------- code/modules/mining/lavaland/ash_flora.dm | 32 ++++++++++---- 2 files changed, 56 insertions(+), 27 deletions(-) diff --git a/code/game/objects/structures/flora.dm b/code/game/objects/structures/flora.dm index 4565cd1b09a..a836886da62 100644 --- a/code/game/objects/structures/flora.dm +++ b/code/game/objects/structures/flora.dm @@ -11,9 +11,6 @@ /// If set, the flora will have this as its description after being harvested. When the flora becomes harvestable again, it regerts to its initial(desc) var/harvested_desc - /// A lazylist of products that could be created when harvesting this flora, syntax is (type = weight) - /// Because of how this works, it can spawn in anomalies if you want it to. Or wall girders - var/product_types /// If the user is able to harvest this with their hands var/harvest_with_hands = FALSE /// The "verb" to use when the user harvests the flora @@ -27,9 +24,9 @@ /// If false, the flora won't be able to be harvested at all. If it's true, go through checks normally to determine if the flora is able to be harvested var/harvestable = TRUE - /// The low end of how many product_type items you get + /// The low end of how many harvested items you get var/harvest_amount_low = 1 - /// The high end of how many product_type items you get + /// The high end of how many harvested items you get var/harvest_amount_high = 3 //Messages to show to the user depending on how many items they get when harvesting the flora @@ -133,24 +130,34 @@ if(use_default_sound) return ..() -/* +/** + * A helper proc for getting the products that could be created when harvesting this flora, list syntax is (type = weight) + * Because of how this works, it can spawn in anomalies if you want it to. Or wall girders + * Returns: An assoc list of obj typepaths and their weights e.g. list(/obj/item/food/grass = 1), or null + */ +/obj/structure/flora/proc/get_potential_products() + return null + +/** * A helper proc for getting a random amount of products, associated with the flora's product list. - * Returns: A list where each value is (product_type = amount_of_products) + * Returns: A list where each value is (harvested_item_typepath = amount_of_products) */ /obj/structure/flora/proc/get_products_list() - if(!LAZYLEN(product_types)) - return list() + var/list/potential_product_list = get_potential_products() + if(isnull(potential_product_list)) + return + var/list/product_list = list() var/harvest_amount = rand(harvest_amount_low, harvest_amount_high) for(var/iteration in 1 to harvest_amount) - var/chosen_product = pick_weight(product_types) + var/chosen_product = pick_weight(potential_product_list) if(!product_list[chosen_product]) product_list[chosen_product] = 0 product_list[chosen_product]++ return product_list -/* +/** * A helper proc that determines if a user can currently harvest this flora with whatever tool they're trying to use. * Returns: TRUE if they can harvest, FALSE if not. Null if it's not harvestable at all. */ @@ -177,7 +184,7 @@ return FALSE -/* +/** * This gets called after a mob tries to harvest this flora with the correct tool. * It displays a flavor message to whoever's harvesting this flora, then creates new products depending on the flora's product list. * Also renames the flora if harvested_name or harvested_desc is set in the variables @@ -185,11 +192,11 @@ */ /obj/structure/flora/proc/harvest(user, product_amount_multiplier = 1) . = FALSE - if(harvested && !LAZYLEN(product_types)) + if(harvested) return FALSE var/list/products_to_create = get_products_list() - if(!products_to_create.len) + if(!LAZYLEN(products_to_create)) return FALSE var/products_created = 0 @@ -250,7 +257,7 @@ desc = initial(desc) harvested = FALSE -/* +/** * Called after the user uproots the flora with a shovel. */ /obj/structure/flora/proc/uproot(mob/living/user) @@ -260,7 +267,7 @@ previous_rotation = pick(-90, 90) transform = M.Turn(previous_rotation) -/* +/** * Called after the user plants the flora back into the ground after uprooted */ /obj/structure/flora/proc/replant(mob/living/user) @@ -289,7 +296,6 @@ layer = FLY_LAYER plane = ABOVE_GAME_PLANE drag_slowdown = 1.5 - product_types = list(/obj/item/grown/log/tree = 1) harvest_amount_low = 6 harvest_amount_high = 10 harvest_message_low = "You manage to gather a few logs from the tree." @@ -304,6 +310,9 @@ . = ..() AddComponent(/datum/component/seethrough, get_seethrough_map()) +/obj/structure/flora/tree/get_potential_products() + return list(/obj/item/grown/log/tree = 1) + ///Return a see_through_map, examples in seethrough.dm /obj/structure/flora/tree/proc/get_seethrough_map() return SEE_THROUGH_MAP_DEFAULT @@ -536,7 +545,6 @@ desc = "A patch of overgrown grass." icon = 'icons/obj/fluff/flora/snowflora.dmi' gender = PLURAL //"this is grass" not "this is a grass" - product_types = list(/obj/item/food/grown/grass = 10, /obj/item/seeds/grass = 1) harvest_with_hands = TRUE harvest_amount_low = 0 harvest_amount_high = 2 @@ -546,6 +554,9 @@ can_uproot = TRUE flora_flags = FLORA_HERBAL +/obj/structure/flora/grass/get_potential_products() + return list(/obj/item/food/grown/grass = 10, /obj/item/seeds/grass = 1) + /obj/structure/flora/grass/brown icon_state = "snowgrass1bb" @@ -1006,7 +1017,6 @@ icon = 'icons/obj/fluff/flora/rocks.dmi' density = TRUE resistance_flags = FIRE_PROOF - product_types = list(/obj/item/stack/ore/glass/basalt = 1) harvest_amount_low = 10 harvest_amount_high = 20 harvest_message_med = "You finish mining the rock." @@ -1015,6 +1025,9 @@ can_uproot = FALSE delete_on_harvest = TRUE +/obj/structure/flora/rock/get_potential_products() + return list(/obj/item/stack/ore/glass/basalt = 1) + /obj/structure/flora/rock/style_2 icon_state = "basalt2" diff --git a/code/modules/mining/lavaland/ash_flora.dm b/code/modules/mining/lavaland/ash_flora.dm index 7242c24be29..0fdebbed0ce 100644 --- a/code/modules/mining/lavaland/ash_flora.dm +++ b/code/modules/mining/lavaland/ash_flora.dm @@ -10,7 +10,6 @@ resistance_flags = LAVA_PROOF gender = PLURAL layer = PROJECTILE_HIT_THRESHHOLD_LAYER //sporangiums up don't shoot - product_types = list(/obj/item/food/grown/ash_flora/shavings = 1) harvest_with_hands = TRUE harvested_name = "shortened mushrooms" harvested_desc = "Some quickly regrowing mushrooms, formerly known to be quite large." @@ -27,6 +26,9 @@ base_icon_state = "[base_icon_state][rand(1, number_of_variants)]" icon_state = base_icon_state +/obj/structure/flora/ash/get_potential_products() + return list(/obj/item/food/grown/ash_flora/shavings = 1) + /obj/structure/flora/ash/harvest(user, product_amount_multiplier) if(!..()) return FALSE @@ -45,7 +47,6 @@ desc = "A number of mushrooms, each of which surrounds a greenish sporangium with a number of leaf-like structures." icon_state = "s_mushroom1" base_icon_state = "s_mushroom" - product_types = list(/obj/item/food/grown/ash_flora/mushroom_leaf = 1) harvested_name = "leafless mushrooms" harvested_desc = "A bunch of formerly-leafed mushrooms, with their sporangiums exposed. Scandalous?" harvest_amount_high = 4 @@ -56,12 +57,14 @@ regrowth_time_low = 2400 regrowth_time_high = 6000 +/obj/structure/flora/ash/leaf_shroom/get_potential_products() + return list(/obj/item/food/grown/ash_flora/mushroom_leaf = 1) + /obj/structure/flora/ash/cap_shroom name = "tall mushrooms" desc = "Several mushrooms, the larger of which have a ring of conks at the midpoint of their stems." icon_state = "r_mushroom1" base_icon_state = "r_mushroom" - product_types = list(/obj/item/food/grown/ash_flora/mushroom_cap = 1) harvested_name = "small mushrooms" harvested_desc = "Several small mushrooms near the stumps of what likely were larger mushrooms." harvest_amount_high = 4 @@ -72,6 +75,9 @@ regrowth_time_low = 3000 regrowth_time_high = 5400 +/obj/structure/flora/ash/cap_shroom/get_potential_products() + return list(/obj/item/food/grown/ash_flora/mushroom_cap = 1) + /obj/structure/flora/ash/stem_shroom name = "numerous mushrooms" desc = "A large number of mushrooms, some of which have long, fleshy stems. They're radiating light!" @@ -79,7 +85,6 @@ base_icon_state = "t_mushroom" light_range = 1.5 light_power = 2.1 - product_types = list(/obj/item/food/grown/ash_flora/mushroom_stem = 1) harvested_name = "tiny mushrooms" harvested_desc = "A few tiny mushrooms around larger stumps. You can already see them growing back." harvest_amount_high = 4 @@ -90,12 +95,14 @@ regrowth_time_low = 3000 regrowth_time_high = 6000 +/obj/structure/flora/ash/stem_shroom/get_potential_products() + return list(/obj/item/food/grown/ash_flora/mushroom_stem = 1) + /obj/structure/flora/ash/cacti name = "fruiting cacti" desc = "Several prickly cacti, brimming with ripe fruit and covered in a thin layer of ash." icon_state = "cactus1" base_icon_state = "cactus" - product_types = list(/obj/item/food/grown/ash_flora/cactus_fruit = 20, /obj/item/seeds/lavaland/cactus = 1) harvested_name = "cacti" harvested_desc = "A bunch of prickly cacti. You can see fruits slowly growing beneath the covering of ash." harvest_amount_high = 2 @@ -111,12 +118,14 @@ . = ..() AddComponent(/datum/component/caltrop, min_damage = 3, max_damage = 6, probability = 70) +/obj/structure/flora/ash/cacti/get_potential_products() + return list(/obj/item/food/grown/ash_flora/cactus_fruit = 20, /obj/item/seeds/lavaland/cactus = 1) + /obj/structure/flora/ash/seraka name = "seraka mushrooms" desc = "A small cluster of seraka mushrooms. These must have come with the ashlizards." icon_state = "seraka_mushroom1" base_icon_state = "seraka_mushroom" - product_types = list(/obj/item/food/grown/ash_flora/seraka = 1) harvested_name = "harvested seraka mushrooms" harvested_desc = "A couple of small seraka mushrooms, with the larger ones clearly having been recently removed. They'll grow back... eventually." harvest_amount_high = 6 @@ -129,6 +138,9 @@ number_of_variants = 2 harvest_message_true_thresholds = FALSE +/obj/structure/flora/ash/seraka/get_potential_products() + return list(/obj/item/food/grown/ash_flora/seraka = 1) + /obj/structure/flora/ash/fireblossom name = "fire blossom" desc = "An odd flower that grows commonly near bodies of lava." @@ -137,7 +149,6 @@ light_range = LIGHT_FIRE_BLOSSOM light_power = LIGHT_FIRE_BLOSSOM light_color = COLOR_BIOLUMINESCENCE_YELLOW - product_types = list(/obj/item/food/grown/ash_flora/fireblossom = 1) harvested_name = "fire blossom stems" harvested_desc = "A few fire blossom stems, missing their flowers." harvest_amount_high = 3 @@ -148,6 +159,9 @@ regrowth_time_high = 4000 number_of_variants = 2 +/obj/structure/flora/ash/fireblossom/get_potential_products() + return list(/obj/item/food/grown/ash_flora/fireblossom = 1) + /obj/structure/flora/ash/fireblossom/after_harvest() set_light_power(LIGHT_RANGE_FIRE_BLOSSOM_HARVESTED) set_light_range(LIGHT_POWER_FIRE_BLOSSOM_HARVESTED) @@ -166,7 +180,6 @@ desc = "A number of bright, springy blue fruiting plants. They seem to be unconcerned with the hardy, cold environment." icon_state = "chilly_pepper1" base_icon_state = "chilly_pepper" - product_types = list(/obj/item/food/grown/icepepper = 1) harvested_name = "springy grass" harvested_desc = "A bunch of springy, bouncy fruiting grass, all picked. Or maybe they were never fruiting at all?" harvest_amount_high = 3 @@ -178,6 +191,9 @@ regrowth_time_high = 5500 number_of_variants = 2 +/obj/structure/flora/ash/chilly/get_potential_products() + return list(/obj/item/food/grown/icepepper = 1) + //SNACKS /obj/item/food/grown/ash_flora