Skip to content

Commit 50ca772

Browse files
Bee and insect swarm rework (beewrite).
1 parent b1eed04 commit 50ca772

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

47 files changed

+1216
-179
lines changed

code/__defines/hydroponics.dm

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,7 @@
44
// Defining these to point to the relevant decl types just to avoid a massive changeset.
55
// TODO: rename to PLANT_TRAIT or bare decls to avoid mixing up with GetTrait etc.
66
#define TRAIT_CHEMS /decl/plant_trait/chems
7+
#define TRAIT_POLLEN /decl/plant_trait/pollen
78
#define TRAIT_EXUDE_GASSES /decl/plant_trait/exude_gasses
89
#define TRAIT_ALTER_TEMP /decl/plant_trait/alter_temp
910
#define TRAIT_POTENCY /decl/plant_trait/potency

code/game/machinery/centrifuge.dm

Lines changed: 168 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,168 @@
1+
/datum/storage/hopper/industrial/centrifuge
2+
can_hold = list(/obj/item/food) // also handles hive frames; see insects modpack.
3+
expected_type = /obj/machinery/centrifuge
4+
5+
/datum/storage/hopper/industrial/centrifuge/can_be_inserted(obj/item/W, mob/user, stop_messages = 0, click_params = null)
6+
. = ..()
7+
if(. && !W.reagents?.total_volume)
8+
if(user)
9+
to_chat(user, SPAN_WARNING("\The [W] is empty."))
10+
return FALSE
11+
12+
/obj/machinery/centrifuge
13+
name = "industrial centrifuge"
14+
desc = "A machine used to extract reagents and materials from objects via spinning them at extreme speed."
15+
icon = 'icons/obj/machines/centrifuge.dmi'
16+
icon_state = ICON_STATE_WORLD
17+
anchored = TRUE
18+
density = TRUE
19+
construct_state = /decl/machine_construction/default/panel_closed
20+
uncreated_component_parts = null
21+
storage = /datum/storage/hopper/industrial/centrifuge
22+
base_type = /obj/machinery/centrifuge
23+
stat_immune = 0
24+
25+
// Reference to our reagent container. Set to a path to create on init.
26+
var/obj/item/loaded_beaker
27+
28+
// Stolen from fabricators.
29+
var/sound_id
30+
var/datum/sound_token/sound_token
31+
var/work_sound = 'sound/machines/fabricator_loop.ogg'
32+
33+
/obj/machinery/centrifuge/mapped
34+
loaded_beaker = /obj/item/chems/glass/beaker/large
35+
36+
/obj/machinery/centrifuge/Initialize()
37+
. = ..()
38+
if(ispath(loaded_beaker))
39+
loaded_beaker = new loaded_beaker
40+
41+
/obj/machinery/centrifuge/Destroy()
42+
QDEL_NULL(loaded_beaker)
43+
return ..()
44+
45+
/obj/machinery/centrifuge/dismantle()
46+
if(loaded_beaker)
47+
loaded_beaker.dropInto(loc)
48+
loaded_beaker = null
49+
return ..()
50+
51+
/obj/machinery/centrifuge/components_are_accessible(path)
52+
return use_power != POWER_USE_ACTIVE && ..()
53+
54+
/obj/machinery/centrifuge/cannot_transition_to(state_path, mob/user)
55+
if(use_power == POWER_USE_ACTIVE)
56+
return SPAN_NOTICE("You must wait for \the [src] to finish first!")
57+
return ..()
58+
59+
/obj/machinery/centrifuge/attackby(obj/item/used_item, mob/user)
60+
61+
if(use_power == POWER_USE_ACTIVE)
62+
to_chat(user, SPAN_NOTICE("\The [src] is currently spinning, wait until it's finished."))
63+
return TRUE
64+
65+
if((. = component_attackby(used_item, user)))
66+
return
67+
68+
// Load in a new container for products.
69+
if(istype(used_item, /obj/item/chems/glass/beaker))
70+
if(loaded_beaker)
71+
to_chat(user, SPAN_WARNING("\The [src] already has a beaker loaded."))
72+
return TRUE
73+
if(user.try_unequip(used_item, src))
74+
loaded_beaker = used_item
75+
to_chat(user, SPAN_NOTICE("You load \the [loaded_beaker] into \the [src]."))
76+
return TRUE
77+
78+
// Parent call handles inserting the frame into our contents,
79+
return ..()
80+
81+
/obj/machinery/centrifuge/attack_hand(mob/user)
82+
83+
if(use_power == POWER_USE_ACTIVE)
84+
user.visible_message("\The [user] disengages \the [src].")
85+
update_use_power(POWER_USE_IDLE)
86+
return TRUE
87+
88+
if(use_power == POWER_USE_IDLE)
89+
if(!loaded_beaker || QDELETED(loaded_beaker))
90+
to_chat(user, SPAN_WARNING("\The [src] has no beaker loaded to receive any products."))
91+
loaded_beaker = null // just in case
92+
return TRUE
93+
94+
if(length(get_stored_inventory()))
95+
user.visible_message("\The [user] engages \the [src].")
96+
update_use_power(POWER_USE_ACTIVE)
97+
else
98+
to_chat(user, SPAN_WARNING("\The [src]'s hopper is empty."))
99+
return TRUE
100+
101+
if(use_power == POWER_USE_OFF || !operable())
102+
to_chat(user, SPAN_WARNING("\The [src]'s interface is unresponsive."))
103+
return TRUE
104+
105+
return ..()
106+
107+
/obj/machinery/centrifuge/Process(wait, tick)
108+
..()
109+
110+
if(use_power != POWER_USE_ACTIVE)
111+
return
112+
113+
if(!loaded_beaker)
114+
visible_message("\The [src] stops spinning and flashes a red light.")
115+
update_use_power(POWER_USE_IDLE)
116+
return
117+
118+
var/list/processing_items = get_stored_inventory()
119+
if(!length(processing_items))
120+
visible_message("\The [src] stops spinning and flashes a green light.")
121+
update_use_power(POWER_USE_IDLE)
122+
return
123+
124+
var/obj/item/thing = processing_items[1]
125+
thing.handle_centrifuge_process(src)
126+
if(!QDELETED(thing) && loc)
127+
thing.dropInto(loc)
128+
129+
/obj/machinery/centrifuge/Initialize()
130+
sound_id = "[work_sound]"
131+
return ..()
132+
133+
/obj/machinery/centrifuge/Destroy()
134+
QDEL_NULL(sound_token)
135+
return ..()
136+
137+
/obj/machinery/centrifuge/update_use_power()
138+
. = ..()
139+
if(use_power == POWER_USE_ACTIVE)
140+
if(!sound_token)
141+
sound_token = play_looping_sound(src, sound_id, work_sound, volume = 30)
142+
else
143+
QDEL_NULL(sound_token)
144+
145+
/obj/machinery/centrifuge/on_update_icon()
146+
icon_state = initial(icon_state)
147+
if(stat & BROKEN)
148+
icon_state = "[icon_state]-broken"
149+
else if(use_power == POWER_USE_OFF || !operable())
150+
icon_state = "[icon_state]-off"
151+
else if(use_power == POWER_USE_ACTIVE)
152+
icon_state = "[icon_state]-working"
153+
154+
/obj/machinery/centrifuge/get_alt_interactions(var/mob/user)
155+
. = ..()
156+
if(loaded_beaker)
157+
LAZYADD(., list(/decl/interaction_handler/remove_centrifuge_beaker))
158+
159+
/decl/interaction_handler/remove_centrifuge_beaker
160+
name = "Remove Beaker"
161+
expected_target_type = /obj/machinery/centrifuge
162+
163+
/decl/interaction_handler/remove_centrifuge_beaker/invoked(atom/target, mob/user, obj/item/prop)
164+
var/obj/machinery/centrifuge/centrifuge = target
165+
if(centrifuge.loaded_beaker)
166+
centrifuge.loaded_beaker.dropInto(centrifuge.loc)
167+
user.put_in_hands(centrifuge.loaded_beaker)
168+
centrifuge.loaded_beaker = null

code/game/objects/items/__item.dm

Lines changed: 33 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1320,3 +1320,36 @@ modules/mob/living/human/life.dm if you die, you will be zoomed out.
13201320
coating_string = FONT_COLORED(coating.get_color(), coating_string)
13211321
return coating_string
13221322
return ..()
1323+
1324+
1325+
// Bespoke proc for handling when a centrifuge smooshes us, only currently used by growns and hive frames.
1326+
/obj/item/proc/handle_centrifuge_process(obj/machinery/centrifuge/centrifuge)
1327+
SHOULD_CALL_PARENT(TRUE)
1328+
return istype(centrifuge) && !QDELETED(centrifuge.loaded_beaker) && istype(centrifuge.loaded_beaker)
1329+
1330+
/obj/item/proc/convert_matter_to_lumps(skip_qdel = FALSE)
1331+
1332+
var/list/scrap_matter = list()
1333+
for(var/mat in matter)
1334+
var/mat_amount = matter[mat]
1335+
var/obj/item/stack/material/mat_stack = /obj/item/stack/material/lump
1336+
var/mat_per_stack = SHEET_MATERIAL_AMOUNT * initial(mat_stack.matter_multiplier)
1337+
var/sheet_amount = round(mat_amount / mat_per_stack)
1338+
if(sheet_amount)
1339+
var/obj/item/stack/material/lump/lump = new(loc, sheet_amount, mat)
1340+
LAZYADD(., lump)
1341+
mat_amount -= sheet_amount * mat_per_stack
1342+
if(mat_amount)
1343+
scrap_matter[mat] += mat_amount
1344+
1345+
if(length(scrap_matter))
1346+
var/obj/item/debris/scraps/scraps = new(loc)
1347+
scraps.matter = scrap_matter.Copy()
1348+
scraps.update_primary_material()
1349+
LAZYADD(., scraps)
1350+
1351+
matter = null
1352+
material = null
1353+
if(!skip_qdel)
1354+
qdel(src)
1355+

code/game/objects/items/circuitboards/machinery/biogenerator.dm

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -11,4 +11,4 @@
1111
/obj/item/stock_parts/console_screen = 1,
1212
/obj/item/stock_parts/keyboard = 1,
1313
/obj/item/stock_parts/power/apc/buildable = 1
14-
)
14+
)

code/game/objects/items/circuitboards/machinery/household.dm

Lines changed: 19 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -46,6 +46,25 @@
4646
/obj/item/stock_parts/circuitboard/cooker/get_buildable_types()
4747
return subtypesof(/obj/machinery/cooker)
4848

49+
/obj/item/stock_parts/circuitboard/centrifuge
50+
name = "circuitboard (industrial centrifuge)"
51+
build_path = /obj/machinery/centrifuge
52+
board_type = "machine"
53+
origin_tech = @'{"biotech":2,"engineering":1}'
54+
req_components = list(
55+
/obj/item/stock_parts/manipulator = 2,
56+
/obj/item/stock_parts/matter_bin = 2)
57+
58+
/obj/item/stock_parts/circuitboard/seed_extractor
59+
name = "circuitboard (seed extractor)"
60+
build_path = /obj/machinery/seed_extractor
61+
board_type = "machine"
62+
origin_tech = @'{"biotech":2,"engineering":1}'
63+
req_components = list(
64+
/obj/item/stock_parts/manipulator = 2,
65+
/obj/item/stock_parts/matter_bin = 2
66+
)
67+
4968
/obj/item/stock_parts/circuitboard/seed_storage
5069
name = "circuitboard (seed storage)"
5170
build_path = /obj/machinery/seed_storage

code/modules/fabrication/designs/imprinter/designs_misc_circuits.dm

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -345,7 +345,7 @@
345345
path = /obj/item/stock_parts/circuitboard/cooker
346346

347347
/datum/fabricator_recipe/imprinter/circuit/seed_extractor
348-
path = /obj/item/stock_parts/circuitboard/seed
348+
path = /obj/item/stock_parts/circuitboard/seed_extractor
349349

350350
/datum/fabricator_recipe/imprinter/circuit/vending
351351
path = /obj/item/stock_parts/circuitboard/vending
@@ -487,3 +487,6 @@
487487

488488
/datum/fabricator_recipe/imprinter/circuit/central_atmos
489489
path = /obj/item/stock_parts/circuitboard/central_atmos
490+
491+
/datum/fabricator_recipe/imprinter/circuit/centrifuge
492+
path = /obj/item/stock_parts/circuitboard/centrifuge

code/modules/genetics/plants/gene_biochemistry.dm

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -17,6 +17,8 @@
1717
if(seed.get_trait(trait) > 0)
1818
seed.set_trait(trait, seed.get_trait(trait), null, 1, 0.85)
1919

20+
seed.produces_pollen = LAZYACCESS(gene.values, TRAIT_POLLEN)
21+
2022
LAZYINITLIST(seed.chems)
2123
var/list/gene_value = LAZYACCESS(gene.values, TRAIT_CHEMS)
2224
for(var/rid in gene_value)
@@ -42,10 +44,12 @@
4244

4345
LAZYREMOVE(gene.values, TRAIT_EXUDE_GASSES)
4446
LAZYREMOVE(gene.values, TRAIT_CHEMS)
47+
LAZYREMOVE(gene.values, TRAIT_POLLEN)
4548

4649
return ..()
4750

4851
/decl/plant_gene/biochemistry/copy_initial_seed_values(datum/plantgene/gene, datum/seed/seed)
4952
LAZYSET(gene.values, TRAIT_CHEMS, seed.chems?.Copy())
5053
LAZYSET(gene.values, TRAIT_EXUDE_GASSES, seed.exude_gasses?.Copy())
54+
LAZYSET(gene.values, TRAIT_POLLEN, seed.produces_pollen)
5155
return ..()
Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,3 @@
1+
/decl/plant_trait/pollen
2+
name = "pollen"
3+
requires_master_gene = FALSE

code/modules/hydroponics/grown.dm

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -15,6 +15,18 @@
1515
var/seeds_extracted = FALSE
1616
var/datum/seed/seed
1717

18+
// This is sort of pointless while food is a valid input on the ChemMaster but maybe
19+
// in the future there will be some more interesting ways to process growns/food.
20+
/obj/item/food/grown/handle_centrifuge_process(obj/machinery/centrifuge/centrifuge)
21+
if(!(. = ..()))
22+
return
23+
if(reagents.total_volume)
24+
reagents.trans_to_holder(centrifuge.loaded_beaker.reagents, reagents.total_volume)
25+
for(var/obj/item/thing in contents)
26+
thing.dropInto(centrifuge.loc)
27+
for(var/atom/movable/thing in convert_matter_to_lumps())
28+
thing.dropInto(centrifuge.loc)
29+
1830
/obj/item/food/grown/examine(mob/user, distance)
1931
. = ..()
2032
if(user && distance <= 1 && seed && user.skill_check(work_skill, SKILL_BASIC))

code/modules/hydroponics/seed.dm

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -32,6 +32,7 @@
3232
var/scannable_result
3333
var/grown_is_seed = FALSE
3434
var/product_w_class = ITEM_SIZE_SMALL
35+
var/produces_pollen = 0
3536

3637
// Dissection values.
3738
var/min_seed_extracted = 1

0 commit comments

Comments
 (0)