diff --git a/code/modules/hydroponics/beekeeping/beehive.dm b/code/modules/hydroponics/beekeeping/beehive.dm index 37f7c5cc79..20d544f701 100644 --- a/code/modules/hydroponics/beekeeping/beehive.dm +++ b/code/modules/hydroponics/beekeeping/beehive.dm @@ -9,7 +9,7 @@ var/bee_count = 0 // Percent var/smoked = 0 // Timer var/honeycombs = 0 // Percent - var/frames = 0 + var/list/frames = list() // List of frames inside. var/maxFrames = 5 /obj/machinery/beehive/update_icon() @@ -17,8 +17,8 @@ icon_state = "beehive" if(closed) add_overlay("lid") - if(frames) - add_overlay("empty[frames]") + if(length(frames)) + add_overlay("empty[length(frames)]") if(honeycombs >= 100) add_overlay("full[round(honeycombs / 100)]") if(!smoked) @@ -38,59 +38,59 @@ /obj/machinery/beehive/attackby(var/obj/item/I, var/mob/user) if(I.is_crowbar()) closed = !closed - user.visible_message("[user] [closed ? "closes" : "opens"] \the [src].", "You [closed ? "close" : "open"] \the [src].") + user.visible_message(SPAN_NOTICE("[user] [closed ? "closes" : "opens"] \the [src]."), SPAN_NOTICE("You [closed ? "close" : "open"] \the [src].")) update_icon() return else if(I.is_wrench()) anchored = !anchored playsound(src, I.usesound, 50, 1) - user.visible_message("[user] [anchored ? "wrenches" : "unwrenches"] \the [src].", "You [anchored ? "wrench" : "unwrench"] \the [src].") + user.visible_message(SPAN_NOTICE("[user] [anchored ? "wrenches" : "unwrenches"] \the [src]."), SPAN_NOTICE("You [anchored ? "wrench" : "unwrench"] \the [src].")) return else if(istype(I, /obj/item/bee_smoker)) if(closed) - to_chat(user, "You need to open \the [src] with a crowbar before smoking the bees.") + to_chat(user, SPAN_NOTICE("You need to open \the [src] with a crowbar before smoking the bees.")) return - user.visible_message("[user] smokes the bees in \the [src].", "You smoke the bees in \the [src].") + user.visible_message(SPAN_NOTICE("[user] smokes the bees in \the [src]."), SPAN_NOTICE("You smoke the bees in \the [src].")) smoked = 30 update_icon() return else if(istype(I, /obj/item/honey_frame)) if(closed) - to_chat(user, "You need to open \the [src] with a crowbar before inserting \the [I].") + to_chat(user, SPAN_NOTICE("You need to open \the [src] with a crowbar before inserting \the [I].")) return - if(frames >= maxFrames) - to_chat(user, "There is no place for an another frame.") + if(length(frames) >= maxFrames) + to_chat(user, SPAN_NOTICE("There is no place for an another frame.")) return var/obj/item/honey_frame/H = I if(H.honey) - to_chat(user, "\The [I] is full with beeswax and honey, empty it in the extractor first.") + to_chat(user, SPAN_NOTICE("\The [I] is full with beeswax and honey, empty it in the extractor first.")) return - ++frames - user.visible_message("[user] loads \the [I] into \the [src].", "You load \the [I] into \the [src].") + user.visible_message(SPAN_NOTICE("[user] loads \the [I] into \the [src]."), SPAN_NOTICE("You load \the [I] into \the [src].")) update_icon() - user.drop_from_inventory(I) - qdel(I) + user.drop_from_inventory(H) + H.forceMove(src) + frames.Add(H) return else if(istype(I, /obj/item/bee_pack)) var/obj/item/bee_pack/B = I if(B.full && bee_count) - to_chat(user, "\The [src] already has bees inside.") + to_chat(user, SPAN_NOTICE("\The [src] already has bees inside.")) return if(!B.full && bee_count < 90) - to_chat(user, "\The [src] is not ready to split.") + to_chat(user, SPAN_NOTICE("\The [src] is not ready to split.")) return if(!B.full && !smoked) - to_chat(user, "Smoke \the [src] first!") + to_chat(user, SPAN_NOTICE("Smoke \the [src] first!")) return if(closed) - to_chat(user, "You need to open \the [src] with a crowbar before moving the bees.") + to_chat(user, SPAN_NOTICE("You need to open \the [src] with a crowbar before moving the bees.")) return if(B.full) - user.visible_message("[user] puts the queen and the bees from \the [I] into \the [src].", "You put the queen and the bees from \the [I] into \the [src].") + user.visible_message(SPAN_NOTICE("[user] puts the queen and the bees from \the [I] into \the [src]."), SPAN_NOTICE("You put the queen and the bees from \the [I] into \the [src].")) bee_count = 20 B.empty() else - user.visible_message("[user] puts bees and larvae from \the [src] into \the [I].", "You put bees and larvae from \the [src] into \the [I].") + user.visible_message(SPAN_NOTICE("[user] puts bees and larvae from \the [src] into \the [I]."), SPAN_NOTICE("You put bees and larvae from \the [src] into \the [I].")) bee_count /= 2 B.fill() update_icon() @@ -98,9 +98,9 @@ else if(istype(I, /obj/item/device/analyzer/plant_analyzer)) to_chat(user, "Scan result of \the [src]...") to_chat(user, "Beehive is [bee_count ? "[round(bee_count)]% full" : "empty"].[bee_count > 90 ? " Colony is ready to split." : ""]") - if(frames) - to_chat(user, "[frames] frames installed, [round(honeycombs / 100)] filled.") - if(honeycombs < frames * 100) + if(length(frames)) + to_chat(user, "[length(frames)] frames installed, [round(honeycombs / 100)] filled.") + if(honeycombs < length(frames) * 100) to_chat(user, "Next frame is [round(honeycombs % 100)]% full.") else to_chat(user, "No frames installed.") @@ -109,12 +109,15 @@ return 1 else if(I.is_screwdriver()) if(bee_count) - to_chat(user, "You can't dismantle \the [src] with these bees inside.") + to_chat(user, SPAN_NOTICE("You can't dismantle \the [src] with these bees inside.")) return - to_chat(user, "You start dismantling \the [src]...") + if(length(frames)) + to_chat(user, SPAN_NOTICE("You can't dismantle \the [src] with [length(frames)] frames still inside!")) + return + to_chat(user, SPAN_NOTICE("You start dismantling \the [src]...")) playsound(src, I.usesound, 50, 1) if(do_after(user, 30)) - user.visible_message("[user] dismantles \the [src].", "You dismantle \the [src].") + user.visible_message(SPAN_NOTICE("[user] dismantles \the [src]."), SPAN_NOTICE("You dismantle \the [src].")) new /obj/item/beehive_assembly(loc) qdel(src) return @@ -122,19 +125,21 @@ /obj/machinery/beehive/attack_hand(var/mob/user) if(!closed) if(honeycombs < 100) - to_chat(user, "There are no filled honeycombs.") + to_chat(user, SPAN_NOTICE("There are no filled honeycombs.")) return if(!smoked && bee_count) - to_chat(user, "The bees won't let you take the honeycombs out like this, smoke them first.") + to_chat(user, SPAN_NOTICE("The bees won't let you take the honeycombs out like this, smoke them first.")) return - user.visible_message("[user] starts taking the honeycombs out of \the [src].", "You start taking the honeycombs out of \the [src]...") - while(honeycombs >= 100 && do_after(user, 30)) - new /obj/item/honey_frame/filled(loc) + user.visible_message(SPAN_NOTICE("[user] starts taking the honeycombs out of \the [src]."), SPAN_NOTICE("You start taking the honeycombs out of \the [src]...")) + while(honeycombs >= 100 && length(frames) && do_after(user, 30)) + var/obj/item/honey_frame/H = pop(frames) + H.honey = 20 honeycombs -= 100 - --frames + H.update_icon() + H.forceMove(get_turf(src)) update_icon() if(honeycombs < 100) - to_chat(user, "You take all filled honeycombs out.") + to_chat(user, SPAN_NOTICE("You take all filled honeycombs out.")) return /obj/machinery/beehive/process() @@ -153,45 +158,47 @@ if(H.seed && !H.dead) H.health += 0.05 * coef ++trays - honeycombs = min(honeycombs + 0.1 * coef * min(trays, 5), frames * 100) + honeycombs = min(honeycombs + 0.1 * coef * min(trays, 5), length(frames) * 100) /obj/machinery/honey_extractor name = "honey extractor" desc = "A machine used to turn honeycombs on the frame into honey and wax." - icon = 'icons/obj/virology_vr.dmi' //VOREStation Edit + icon = 'icons/obj/beekeeping.dmi' icon_state = "centrifuge" + density = TRUE + var/processing = 0 var/honey = 0 /obj/machinery/honey_extractor/attackby(var/obj/item/I, var/mob/user) if(processing) - to_chat(user, "\The [src] is currently spinning, wait until it's finished.") + to_chat(user, SPAN_NOTICE("\The [src] is currently spinning, wait until it's finished.")) return else if(istype(I, /obj/item/honey_frame)) var/obj/item/honey_frame/H = I if(!H.honey) - to_chat(user, "\The [H] is empty, put it into a beehive.") + to_chat(user, SPAN_NOTICE("\The [H] is empty, put it into a beehive.")) return - user.visible_message("[user] loads \the [H] into \the [src] and turns it on.", "You load \the [H] into \the [src] and turn it on.") + user.visible_message(SPAN_NOTICE("[user] loads \the [H]'s comb into \the [src] and turns it on."), SPAN_NOTICE("You load \the [H] into \the [src] and turn it on.")) processing = H.honey - icon_state = "centrifuge_moving" - qdel(H) + icon_state = "[initial(icon_state)]_moving" + H.honey = 0 + H.update_icon() spawn(50) - new /obj/item/honey_frame(loc) new /obj/item/stack/material/wax(loc) honey += processing processing = 0 - icon_state = "centrifuge" + icon_state = "[initial(icon_state)]" else if(istype(I, /obj/item/weapon/reagent_containers/glass)) if(!honey) - to_chat(user, "There is no honey in \the [src].") + to_chat(user, SPAN_NOTICE("There is no honey in \the [src].")) return var/obj/item/weapon/reagent_containers/glass/G = I var/transferred = min(G.reagents.maximum_volume - G.reagents.total_volume, honey) G.reagents.add_reagent("honey", transferred) honey -= transferred - user.visible_message("[user] collects honey from \the [src] into \the [G].", "You collect [transferred] units of honey from \the [src] into \the [G].") + user.visible_message(SPAN_NOTICE("[user] collects honey from \the [src] into \the [G]."), SPAN_NOTICE("You collect [transferred] units of honey from \the [src] into \the [G].")) return 1 /obj/item/bee_smoker @@ -210,15 +217,22 @@ var/honey = 0 +/obj/item/honey_frame/Initialize() + . = ..() + update_icon() + +/obj/item/honey_frame/update_icon() + ..() + + overlays.Cut() + if(honey > 0) + add_overlay("honeycomb") + /obj/item/honey_frame/filled name = "filled beehive frame" desc = "A frame for the beehive that the bees have filled with honeycombs." honey = 20 -/obj/item/honey_frame/filled/New() - ..() - add_overlay("honeycomb") - /obj/item/beehive_assembly name = "beehive assembly" desc = "Contains everything you need to build a beehive." @@ -226,9 +240,9 @@ icon_state = "apiary" /obj/item/beehive_assembly/attack_self(var/mob/user) - to_chat(user, "You start assembling \the [src]...") + to_chat(user, SPAN_NOTICE("You start assembling \the [src]...")) if(do_after(user, 30)) - user.visible_message("[user] constructs a beehive.", "You construct a beehive.") + user.visible_message(SPAN_NOTICE("[user] constructs a beehive."), SPAN_NOTICE("You construct a beehive.")) new /obj/machinery/beehive(get_turf(user)) user.drop_from_inventory(src) qdel(src) @@ -283,4 +297,4 @@ var/global/list/datum/stack_recipe/wax_recipes = list( \ name = initial(name) desc = initial(desc) cut_overlays() - add_overlay("beepack-full") \ No newline at end of file + add_overlay("beepack-full") diff --git a/code/modules/hydroponics/seed.dm b/code/modules/hydroponics/seed.dm index 027cfe6aa2..57d6b74376 100644 --- a/code/modules/hydroponics/seed.dm +++ b/code/modules/hydroponics/seed.dm @@ -414,7 +414,7 @@ roundstart = 0 mysterious = 1 - seed_noun = pick("spores","nodes","cuttings","seeds") + seed_noun = pick("spores","nodes","cuttings","seeds","pits") set_trait(TRAIT_POTENCY,rand(5,30),200,0) set_trait(TRAIT_PRODUCT_ICON,pick(SSplants.accessible_product_sprites)) diff --git a/code/modules/hydroponics/seed_gene_mut.dm b/code/modules/hydroponics/seed_gene_mut.dm index 35ced29739..861ad9598b 100644 --- a/code/modules/hydroponics/seed_gene_mut.dm +++ b/code/modules/hydroponics/seed_gene_mut.dm @@ -94,15 +94,23 @@ if(prob(50)) S.set_trait(TRAIT_BIOLUM, !S.get_trait(TRAIT_BIOLUM)) if(S.get_trait(TRAIT_BIOLUM)) - T.visible_message("\The [S.display_name] begins to glow!") + T.visible_message(SPAN_NOTICE("\The [S.display_name] begins to glow!")) if(prob(50)) S.set_trait(TRAIT_BIOLUM_COLOUR,get_random_colour(0,75,190)) T.visible_message("\The [S.display_name]'s glow changes colour!") - else - T.visible_message("\The [S.display_name]'s glow dims...") + else + T.visible_message(SPAN_NOTICE("\The [S.display_name]'s glow dims...")) if(prob(60)) S.set_trait(TRAIT_PRODUCES_POWER, !S.get_trait(TRAIT_PRODUCES_POWER)) + if(prob(30)) + S.set_trait(TRAIT_SPORING, !S.get_trait(TRAIT_SPORING)) + if(S.get_trait(TRAIT_SPORING)) + T.visible_message(SPAN_NOTICE("\The [S.display_name] releases a cloud of spores!")) + S.create_spores(T) + else + T.visible_message(SPAN_NOTICE("\The [S.display_name]'s spores no longer fall.")) + /decl/plantgene/atmosphere/mutate(var/datum/seed/S) if(prob(60)) S.set_trait(TRAIT_HEAT_TOLERANCE, S.get_trait(TRAIT_HEAT_TOLERANCE)+rand(-2,2),40,0) diff --git a/code/modules/hydroponics/spreading/spreading.dm b/code/modules/hydroponics/spreading/spreading.dm index 3c0424d06c..bc3774284a 100644 --- a/code/modules/hydroponics/spreading/spreading.dm +++ b/code/modules/hydroponics/spreading/spreading.dm @@ -120,7 +120,7 @@ if(seed.get_trait(TRAIT_CARNIVOROUS) >= 2) growth_type = 1 // WOOOORMS. else if(!(seed.seed_noun in list("seeds","pits"))) - if(seed.seed_noun == "nodes") + if(seed.seed_noun in list("nodes", "cuttings")) growth_type = 3 // Biomass else growth_type = 4 // Mold diff --git a/code/modules/hydroponics/spreading/spreading_growth.dm b/code/modules/hydroponics/spreading/spreading_growth.dm index 89002e3f49..8c120597f3 100644 --- a/code/modules/hydroponics/spreading/spreading_growth.dm +++ b/code/modules/hydroponics/spreading/spreading_growth.dm @@ -91,22 +91,27 @@ if(prob(chance)) sampled = 0 - if(is_mature() && !has_buckled_mobs()) - for(var/turf/neighbor in neighbors) - for(var/mob/living/M in neighbor) - if(seed.get_trait(TRAIT_SPREAD) >= 2 && (M.lying || prob(round(seed.get_trait(TRAIT_POTENCY))))) - entangle(M) + if(is_mature()) + if(!has_buckled_mobs()) + for(var/turf/neighbor in neighbors) + for(var/mob/living/M in neighbor) + if(seed.get_trait(TRAIT_SPREAD) >= 2 && (M.lying || prob(round(seed.get_trait(TRAIT_POTENCY))))) + entangle(M) - if(is_mature() && neighbors.len && prob(spread_chance)) - //spread to 1-3 adjacent turfs depending on yield trait. - var/max_spread = between(1, round(seed.get_trait(TRAIT_YIELD)*3/14), 3) + if(seed.get_trait(TRAIT_SPORING) && prob(1)) + visible_message(SPAN_WARNING("\The [src] hisses, releasing a cloud of spores!"), SPAN_WARNING("Something nearby hisses loudly!")) + seed.create_spores(get_turf(src)) - for(var/i in 1 to max_spread) - if(prob(spread_chance)) - sleep(rand(3,5)) - if(!neighbors.len) - break - spread_to(pick(neighbors)) + if(length(neighbors) && prob(spread_chance)) + //spread to 1-3 adjacent turfs depending on yield trait. + var/max_spread = between(1, round(seed.get_trait(TRAIT_YIELD)*3/14), 3) + + for(var/i in 1 to max_spread) + if(prob(spread_chance)) + sleep(rand(3,5)) + if(!length(neighbors)) + break + spread_to(pick(neighbors)) // We shouldn't have spawned if the controller doesn't exist. check_health() @@ -128,7 +133,7 @@ //move out to the destination child.anchored = FALSE - step_to(child, target_turf) + child.Move(target_turf) // Do a normal move, so we can cross and uncross things we need to. Stairs, Open space "falling", etc. child.anchored = TRUE child.update_icon() @@ -177,4 +182,4 @@ SSplants.add_plant(neighbor) spawn(1) if(src) qdel(src) -#undef NEIGHBOR_REFRESH_TIME \ No newline at end of file +#undef NEIGHBOR_REFRESH_TIME diff --git a/code/modules/projectiles/projectile/bullets.dm b/code/modules/projectiles/projectile/bullets.dm index efc3717dbc..2257cfb776 100644 --- a/code/modules/projectiles/projectile/bullets.dm +++ b/code/modules/projectiles/projectile/bullets.dm @@ -319,6 +319,16 @@ vacuum_traversal = 0 hud_state = "flame" +/obj/item/projectile/bullet/incendiary/flamethrower/after_move() + ..() + + + var/turf/T = get_turf(src) + if(istype(T)) + for(var/obj/effect/plant/Victim in T) + if(prob(max(20, 100 - (Victim.seed.get_trait(TRAIT_ENDURANCE))))) // Chance to immediately kill a vine or rampant growth, minimum of 20%. + Victim.die_off() + /obj/item/projectile/bullet/incendiary/flamethrower/large damage = 5 incendiary = 3 diff --git a/icons/obj/beekeeping.dmi b/icons/obj/beekeeping.dmi index 3fa8f15167..c8dc2fe2d7 100644 Binary files a/icons/obj/beekeeping.dmi and b/icons/obj/beekeeping.dmi differ