mirror of
https://github.com/Bubberstation/Bubberstation.git
synced 2026-08-27 07:08:00 +01:00
Force LF line endings with gitattributes and convert repo (#52266)
Co-authored-by: Aleksej Komarov <stylemistake@gmail.com>
This commit is contained in:
co-authored by
Aleksej Komarov
parent
39e8bd721f
commit
62676e72a8
@@ -1,343 +1,343 @@
|
||||
/obj/machinery/biogenerator
|
||||
name = "biogenerator"
|
||||
desc = "Converts plants into biomass, which can be used to construct useful items."
|
||||
icon = 'icons/obj/machines/biogenerator.dmi'
|
||||
icon_state = "biogen-empty"
|
||||
density = TRUE
|
||||
use_power = IDLE_POWER_USE
|
||||
idle_power_usage = 40
|
||||
circuit = /obj/item/circuitboard/machine/biogenerator
|
||||
ui_x = 550
|
||||
ui_y = 380
|
||||
var/processing = FALSE
|
||||
var/obj/item/reagent_containers/glass/beaker = null
|
||||
var/points = 0
|
||||
var/efficiency = 0
|
||||
var/productivity = 0
|
||||
var/max_items = 40
|
||||
var/datum/techweb/stored_research
|
||||
var/list/show_categories = list("Food", "Botany Chemicals", "Organic Materials")
|
||||
/// Currently selected category in the UI
|
||||
var/selected_cat
|
||||
|
||||
/obj/machinery/biogenerator/Initialize()
|
||||
. = ..()
|
||||
stored_research = new /datum/techweb/specialized/autounlocking/biogenerator
|
||||
create_reagents(1000)
|
||||
|
||||
/obj/machinery/biogenerator/Destroy()
|
||||
QDEL_NULL(beaker)
|
||||
return ..()
|
||||
|
||||
/obj/machinery/biogenerator/contents_explosion(severity, target)
|
||||
..()
|
||||
if(beaker)
|
||||
switch(severity)
|
||||
if(EXPLODE_DEVASTATE)
|
||||
SSexplosions.highobj += beaker
|
||||
if(EXPLODE_HEAVY)
|
||||
SSexplosions.medobj += beaker
|
||||
if(EXPLODE_LIGHT)
|
||||
SSexplosions.lowobj += beaker
|
||||
|
||||
/obj/machinery/biogenerator/handle_atom_del(atom/A)
|
||||
..()
|
||||
if(A == beaker)
|
||||
beaker = null
|
||||
update_icon()
|
||||
|
||||
/obj/machinery/biogenerator/RefreshParts()
|
||||
var/E = 0
|
||||
var/P = 0
|
||||
var/max_storage = 40
|
||||
for(var/obj/item/stock_parts/matter_bin/B in component_parts)
|
||||
P += B.rating
|
||||
max_storage = 40 * B.rating
|
||||
for(var/obj/item/stock_parts/manipulator/M in component_parts)
|
||||
E += M.rating
|
||||
efficiency = E
|
||||
productivity = P
|
||||
max_items = max_storage
|
||||
|
||||
/obj/machinery/biogenerator/examine(mob/user)
|
||||
. = ..()
|
||||
if(in_range(user, src) || isobserver(user))
|
||||
. += "<span class='notice'>The status display reads: Productivity at <b>[productivity*100]%</b>.<br>Matter consumption reduced by <b>[(efficiency*25)-25]</b>%.<br>Machine can hold up to <b>[max_items]</b> pieces of produce.</span>"
|
||||
|
||||
/obj/machinery/biogenerator/on_reagent_change(changetype) //When the reagents change, change the icon as well.
|
||||
update_icon()
|
||||
|
||||
/obj/machinery/biogenerator/update_icon_state()
|
||||
if(panel_open)
|
||||
icon_state = "biogen-empty-o"
|
||||
else if(!src.beaker)
|
||||
icon_state = "biogen-empty"
|
||||
else if(!src.processing)
|
||||
icon_state = "biogen-stand"
|
||||
else
|
||||
icon_state = "biogen-work"
|
||||
|
||||
/obj/machinery/biogenerator/attackby(obj/item/O, mob/user, params)
|
||||
if(user.a_intent == INTENT_HARM)
|
||||
return ..()
|
||||
|
||||
if(processing)
|
||||
to_chat(user, "<span class='warning'>The biogenerator is currently processing.</span>")
|
||||
return
|
||||
|
||||
if(default_deconstruction_screwdriver(user, "biogen-empty-o", "biogen-empty", O))
|
||||
if(beaker)
|
||||
var/obj/item/reagent_containers/glass/B = beaker
|
||||
B.forceMove(drop_location())
|
||||
beaker = null
|
||||
update_icon()
|
||||
return
|
||||
|
||||
if(default_deconstruction_crowbar(O))
|
||||
return
|
||||
|
||||
if(istype(O, /obj/item/reagent_containers/glass))
|
||||
. = 1 //no afterattack
|
||||
if(!panel_open)
|
||||
if(beaker)
|
||||
to_chat(user, "<span class='warning'>A container is already loaded into the machine.</span>")
|
||||
else
|
||||
if(!user.transferItemToLoc(O, src))
|
||||
return
|
||||
beaker = O
|
||||
to_chat(user, "<span class='notice'>You add the container to the machine.</span>")
|
||||
update_icon()
|
||||
else
|
||||
to_chat(user, "<span class='warning'>Close the maintenance panel first.</span>")
|
||||
return
|
||||
|
||||
else if(istype(O, /obj/item/storage/bag/plants))
|
||||
var/obj/item/storage/bag/plants/PB = O
|
||||
var/i = 0
|
||||
for(var/obj/item/reagent_containers/food/snacks/grown/G in contents)
|
||||
i++
|
||||
if(i >= max_items)
|
||||
to_chat(user, "<span class='warning'>The biogenerator is already full! Activate it.</span>")
|
||||
else
|
||||
for(var/obj/item/reagent_containers/food/snacks/grown/G in PB.contents)
|
||||
if(i >= max_items)
|
||||
break
|
||||
if(SEND_SIGNAL(PB, COMSIG_TRY_STORAGE_TAKE, G, src))
|
||||
i++
|
||||
if(i<max_items)
|
||||
to_chat(user, "<span class='info'>You empty the plant bag into the biogenerator.</span>")
|
||||
else if(PB.contents.len == 0)
|
||||
to_chat(user, "<span class='info'>You empty the plant bag into the biogenerator, filling it to its capacity.</span>")
|
||||
else
|
||||
to_chat(user, "<span class='info'>You fill the biogenerator to its capacity.</span>")
|
||||
return TRUE //no afterattack
|
||||
|
||||
else if(istype(O, /obj/item/reagent_containers/food/snacks/grown))
|
||||
var/i = 0
|
||||
for(var/obj/item/reagent_containers/food/snacks/grown/G in contents)
|
||||
i++
|
||||
if(i >= max_items)
|
||||
to_chat(user, "<span class='warning'>The biogenerator is full! Activate it.</span>")
|
||||
else
|
||||
if(user.transferItemToLoc(O, src))
|
||||
to_chat(user, "<span class='info'>You put [O.name] in [src.name]</span>")
|
||||
return TRUE //no afterattack
|
||||
else if (istype(O, /obj/item/disk/design_disk))
|
||||
user.visible_message("<span class='notice'>[user] begins to load \the [O] in \the [src]...</span>",
|
||||
"<span class='notice'>You begin to load a design from \the [O]...</span>",
|
||||
"<span class='hear'>You hear the chatter of a floppy drive.</span>")
|
||||
processing = TRUE
|
||||
var/obj/item/disk/design_disk/D = O
|
||||
if(do_after(user, 10, target = src))
|
||||
for(var/B in D.blueprints)
|
||||
if(B)
|
||||
stored_research.add_design(B)
|
||||
processing = FALSE
|
||||
return TRUE
|
||||
else
|
||||
to_chat(user, "<span class='warning'>You cannot put this in [src.name]!</span>")
|
||||
|
||||
/obj/machinery/biogenerator/AltClick(mob/living/user)
|
||||
. = ..()
|
||||
if(user.canUseTopic(src, BE_CLOSE, FALSE, NO_TK) && can_interact(user))
|
||||
detach(user)
|
||||
|
||||
/**
|
||||
* activate: Activates biomass processing and converts all inserted grown products into biomass
|
||||
*
|
||||
* Arguments:
|
||||
* * user The mob starting the biomass processing
|
||||
*/
|
||||
/obj/machinery/biogenerator/proc/activate(mob/user)
|
||||
if(user.stat != CONSCIOUS)
|
||||
return
|
||||
if(machine_stat != NONE)
|
||||
return
|
||||
if(processing)
|
||||
to_chat(user, "<span class='warning'>The biogenerator is in the process of working.</span>")
|
||||
return
|
||||
var/S = 0
|
||||
for(var/obj/item/reagent_containers/food/snacks/grown/I in contents)
|
||||
S += 5
|
||||
if(I.reagents.get_reagent_amount(/datum/reagent/consumable/nutriment) < 0.1)
|
||||
points += 1 * productivity
|
||||
else
|
||||
points += I.reagents.get_reagent_amount(/datum/reagent/consumable/nutriment) * 10 * productivity
|
||||
qdel(I)
|
||||
if(S)
|
||||
processing = TRUE
|
||||
update_icon()
|
||||
playsound(loc, 'sound/machines/blender.ogg', 50, TRUE)
|
||||
use_power(S * 30)
|
||||
sleep(S + 15 / productivity)
|
||||
processing = FALSE
|
||||
update_icon()
|
||||
|
||||
/obj/machinery/biogenerator/proc/check_cost(list/materials, multiplier = 1, remove_points = TRUE)
|
||||
if(materials.len != 1 || materials[1] != SSmaterials.GetMaterialRef(/datum/material/biomass))
|
||||
return FALSE
|
||||
if (materials[SSmaterials.GetMaterialRef(/datum/material/biomass)]*multiplier/efficiency > points)
|
||||
return FALSE
|
||||
else
|
||||
if(remove_points)
|
||||
points -= materials[SSmaterials.GetMaterialRef(/datum/material/biomass)]*multiplier/efficiency
|
||||
update_icon()
|
||||
return TRUE
|
||||
|
||||
/obj/machinery/biogenerator/proc/check_container_volume(list/reagents, multiplier = 1)
|
||||
var/sum_reagents = 0
|
||||
for(var/R in reagents)
|
||||
sum_reagents += reagents[R]
|
||||
sum_reagents *= multiplier
|
||||
|
||||
if(beaker.reagents.total_volume + sum_reagents > beaker.reagents.maximum_volume)
|
||||
return FALSE
|
||||
|
||||
return TRUE
|
||||
|
||||
/obj/machinery/biogenerator/proc/create_product(datum/design/D, amount)
|
||||
if(!beaker || !loc)
|
||||
return FALSE
|
||||
|
||||
if(ispath(D.build_path, /obj/item/stack))
|
||||
if(!check_container_volume(D.make_reagents, amount))
|
||||
return FALSE
|
||||
if(!check_cost(D.materials, amount))
|
||||
return FALSE
|
||||
|
||||
new D.build_path(drop_location(), amount)
|
||||
for(var/R in D.make_reagents)
|
||||
beaker.reagents.add_reagent(R, D.make_reagents[R]*amount)
|
||||
else
|
||||
var/i = amount
|
||||
while(i > 0)
|
||||
if(!check_container_volume(D.make_reagents))
|
||||
say("Warning: Attached container does not have enough free capacity!")
|
||||
return .
|
||||
if(!check_cost(D.materials))
|
||||
return .
|
||||
if(D.build_path)
|
||||
new D.build_path(loc)
|
||||
for(var/R in D.make_reagents)
|
||||
beaker.reagents.add_reagent(R, D.make_reagents[R])
|
||||
. = 1
|
||||
--i
|
||||
update_icon()
|
||||
return .
|
||||
|
||||
/obj/machinery/biogenerator/proc/detach(mob/living/user)
|
||||
if(beaker)
|
||||
if(can_interact(user))
|
||||
user.put_in_hands(beaker)
|
||||
else
|
||||
beaker.drop_location(get_turf(src))
|
||||
beaker = null
|
||||
update_icon()
|
||||
|
||||
/obj/machinery/biogenerator/ui_status(mob/user)
|
||||
if(machine_stat & BROKEN || panel_open)
|
||||
return UI_CLOSE
|
||||
return ..()
|
||||
|
||||
/obj/machinery/biogenerator/ui_base_html(html)
|
||||
var/datum/asset/spritesheet/simple/assets = get_asset_datum(/datum/asset/spritesheet/research_designs)
|
||||
. = replacetext(html, "<!--customheadhtml-->", assets.css_tag())
|
||||
|
||||
/obj/machinery/biogenerator/ui_interact(mob/user, ui_key = "main", datum/tgui/ui = null, force_open = FALSE, \
|
||||
datum/tgui/master_ui = null, datum/ui_state/state = GLOB.default_state)
|
||||
ui = SStgui.try_update_ui(user, src, ui_key, ui, force_open)
|
||||
if(!ui)
|
||||
var/datum/asset/assets = get_asset_datum(/datum/asset/spritesheet/research_designs)
|
||||
assets.send(user)
|
||||
ui = new(user, src, ui_key, "Biogenerator", name, ui_x, ui_y, master_ui, state)
|
||||
ui.open()
|
||||
|
||||
/obj/machinery/biogenerator/ui_data(mob/user)
|
||||
var/list/data = list()
|
||||
data["beaker"] = beaker ? TRUE : FALSE
|
||||
data["biomass"] = points
|
||||
data["processing"] = processing
|
||||
if(locate(/obj/item/reagent_containers/food/snacks/grown) in contents)
|
||||
data["can_process"] = TRUE
|
||||
else
|
||||
data["can_process"] = FALSE
|
||||
return data
|
||||
|
||||
/obj/machinery/biogenerator/ui_static_data(mob/user)
|
||||
var/list/data = list()
|
||||
data["categories"] = list()
|
||||
|
||||
var/categories = show_categories.Copy()
|
||||
for(var/V in categories)
|
||||
categories[V] = list()
|
||||
for(var/V in stored_research.researched_designs)
|
||||
var/datum/design/D = SSresearch.techweb_design_by_id(V)
|
||||
for(var/C in categories)
|
||||
if(C in D.category)
|
||||
categories[C] += D
|
||||
|
||||
for(var/category in categories)
|
||||
var/list/cat = list(
|
||||
"name" = category,
|
||||
"items" = (category == selected_cat ? list() : null))
|
||||
for(var/item in categories[category])
|
||||
var/datum/design/D = item
|
||||
cat["items"] += list(list(
|
||||
"id" = D.id,
|
||||
"name" = D.name,
|
||||
"cost" = D.materials[SSmaterials.GetMaterialRef(/datum/material/biomass)]/efficiency,
|
||||
))
|
||||
data["categories"] += list(cat)
|
||||
|
||||
return data
|
||||
|
||||
/obj/machinery/biogenerator/ui_act(action, list/params)
|
||||
if(..())
|
||||
return
|
||||
|
||||
switch(action)
|
||||
if("activate")
|
||||
activate(usr)
|
||||
return TRUE
|
||||
if("detach")
|
||||
detach(usr)
|
||||
return TRUE
|
||||
if("create")
|
||||
var/amount = text2num(params["amount"])
|
||||
amount = clamp(amount, 1, 10)
|
||||
if(!amount)
|
||||
return
|
||||
var/id = params["id"]
|
||||
if(!stored_research.researched_designs.Find(id))
|
||||
stack_trace("ID did not map to a researched datum [id]")
|
||||
return
|
||||
var/datum/design/D = SSresearch.techweb_design_by_id(id)
|
||||
if(D && !istype(D, /datum/design/error_design))
|
||||
create_product(D, amount)
|
||||
else
|
||||
stack_trace("ID could not be turned into a valid techweb design datum [id]")
|
||||
return
|
||||
return TRUE
|
||||
if("select")
|
||||
selected_cat = params["category"]
|
||||
return TRUE
|
||||
/obj/machinery/biogenerator
|
||||
name = "biogenerator"
|
||||
desc = "Converts plants into biomass, which can be used to construct useful items."
|
||||
icon = 'icons/obj/machines/biogenerator.dmi'
|
||||
icon_state = "biogen-empty"
|
||||
density = TRUE
|
||||
use_power = IDLE_POWER_USE
|
||||
idle_power_usage = 40
|
||||
circuit = /obj/item/circuitboard/machine/biogenerator
|
||||
ui_x = 550
|
||||
ui_y = 380
|
||||
var/processing = FALSE
|
||||
var/obj/item/reagent_containers/glass/beaker = null
|
||||
var/points = 0
|
||||
var/efficiency = 0
|
||||
var/productivity = 0
|
||||
var/max_items = 40
|
||||
var/datum/techweb/stored_research
|
||||
var/list/show_categories = list("Food", "Botany Chemicals", "Organic Materials")
|
||||
/// Currently selected category in the UI
|
||||
var/selected_cat
|
||||
|
||||
/obj/machinery/biogenerator/Initialize()
|
||||
. = ..()
|
||||
stored_research = new /datum/techweb/specialized/autounlocking/biogenerator
|
||||
create_reagents(1000)
|
||||
|
||||
/obj/machinery/biogenerator/Destroy()
|
||||
QDEL_NULL(beaker)
|
||||
return ..()
|
||||
|
||||
/obj/machinery/biogenerator/contents_explosion(severity, target)
|
||||
..()
|
||||
if(beaker)
|
||||
switch(severity)
|
||||
if(EXPLODE_DEVASTATE)
|
||||
SSexplosions.highobj += beaker
|
||||
if(EXPLODE_HEAVY)
|
||||
SSexplosions.medobj += beaker
|
||||
if(EXPLODE_LIGHT)
|
||||
SSexplosions.lowobj += beaker
|
||||
|
||||
/obj/machinery/biogenerator/handle_atom_del(atom/A)
|
||||
..()
|
||||
if(A == beaker)
|
||||
beaker = null
|
||||
update_icon()
|
||||
|
||||
/obj/machinery/biogenerator/RefreshParts()
|
||||
var/E = 0
|
||||
var/P = 0
|
||||
var/max_storage = 40
|
||||
for(var/obj/item/stock_parts/matter_bin/B in component_parts)
|
||||
P += B.rating
|
||||
max_storage = 40 * B.rating
|
||||
for(var/obj/item/stock_parts/manipulator/M in component_parts)
|
||||
E += M.rating
|
||||
efficiency = E
|
||||
productivity = P
|
||||
max_items = max_storage
|
||||
|
||||
/obj/machinery/biogenerator/examine(mob/user)
|
||||
. = ..()
|
||||
if(in_range(user, src) || isobserver(user))
|
||||
. += "<span class='notice'>The status display reads: Productivity at <b>[productivity*100]%</b>.<br>Matter consumption reduced by <b>[(efficiency*25)-25]</b>%.<br>Machine can hold up to <b>[max_items]</b> pieces of produce.</span>"
|
||||
|
||||
/obj/machinery/biogenerator/on_reagent_change(changetype) //When the reagents change, change the icon as well.
|
||||
update_icon()
|
||||
|
||||
/obj/machinery/biogenerator/update_icon_state()
|
||||
if(panel_open)
|
||||
icon_state = "biogen-empty-o"
|
||||
else if(!src.beaker)
|
||||
icon_state = "biogen-empty"
|
||||
else if(!src.processing)
|
||||
icon_state = "biogen-stand"
|
||||
else
|
||||
icon_state = "biogen-work"
|
||||
|
||||
/obj/machinery/biogenerator/attackby(obj/item/O, mob/user, params)
|
||||
if(user.a_intent == INTENT_HARM)
|
||||
return ..()
|
||||
|
||||
if(processing)
|
||||
to_chat(user, "<span class='warning'>The biogenerator is currently processing.</span>")
|
||||
return
|
||||
|
||||
if(default_deconstruction_screwdriver(user, "biogen-empty-o", "biogen-empty", O))
|
||||
if(beaker)
|
||||
var/obj/item/reagent_containers/glass/B = beaker
|
||||
B.forceMove(drop_location())
|
||||
beaker = null
|
||||
update_icon()
|
||||
return
|
||||
|
||||
if(default_deconstruction_crowbar(O))
|
||||
return
|
||||
|
||||
if(istype(O, /obj/item/reagent_containers/glass))
|
||||
. = 1 //no afterattack
|
||||
if(!panel_open)
|
||||
if(beaker)
|
||||
to_chat(user, "<span class='warning'>A container is already loaded into the machine.</span>")
|
||||
else
|
||||
if(!user.transferItemToLoc(O, src))
|
||||
return
|
||||
beaker = O
|
||||
to_chat(user, "<span class='notice'>You add the container to the machine.</span>")
|
||||
update_icon()
|
||||
else
|
||||
to_chat(user, "<span class='warning'>Close the maintenance panel first.</span>")
|
||||
return
|
||||
|
||||
else if(istype(O, /obj/item/storage/bag/plants))
|
||||
var/obj/item/storage/bag/plants/PB = O
|
||||
var/i = 0
|
||||
for(var/obj/item/reagent_containers/food/snacks/grown/G in contents)
|
||||
i++
|
||||
if(i >= max_items)
|
||||
to_chat(user, "<span class='warning'>The biogenerator is already full! Activate it.</span>")
|
||||
else
|
||||
for(var/obj/item/reagent_containers/food/snacks/grown/G in PB.contents)
|
||||
if(i >= max_items)
|
||||
break
|
||||
if(SEND_SIGNAL(PB, COMSIG_TRY_STORAGE_TAKE, G, src))
|
||||
i++
|
||||
if(i<max_items)
|
||||
to_chat(user, "<span class='info'>You empty the plant bag into the biogenerator.</span>")
|
||||
else if(PB.contents.len == 0)
|
||||
to_chat(user, "<span class='info'>You empty the plant bag into the biogenerator, filling it to its capacity.</span>")
|
||||
else
|
||||
to_chat(user, "<span class='info'>You fill the biogenerator to its capacity.</span>")
|
||||
return TRUE //no afterattack
|
||||
|
||||
else if(istype(O, /obj/item/reagent_containers/food/snacks/grown))
|
||||
var/i = 0
|
||||
for(var/obj/item/reagent_containers/food/snacks/grown/G in contents)
|
||||
i++
|
||||
if(i >= max_items)
|
||||
to_chat(user, "<span class='warning'>The biogenerator is full! Activate it.</span>")
|
||||
else
|
||||
if(user.transferItemToLoc(O, src))
|
||||
to_chat(user, "<span class='info'>You put [O.name] in [src.name]</span>")
|
||||
return TRUE //no afterattack
|
||||
else if (istype(O, /obj/item/disk/design_disk))
|
||||
user.visible_message("<span class='notice'>[user] begins to load \the [O] in \the [src]...</span>",
|
||||
"<span class='notice'>You begin to load a design from \the [O]...</span>",
|
||||
"<span class='hear'>You hear the chatter of a floppy drive.</span>")
|
||||
processing = TRUE
|
||||
var/obj/item/disk/design_disk/D = O
|
||||
if(do_after(user, 10, target = src))
|
||||
for(var/B in D.blueprints)
|
||||
if(B)
|
||||
stored_research.add_design(B)
|
||||
processing = FALSE
|
||||
return TRUE
|
||||
else
|
||||
to_chat(user, "<span class='warning'>You cannot put this in [src.name]!</span>")
|
||||
|
||||
/obj/machinery/biogenerator/AltClick(mob/living/user)
|
||||
. = ..()
|
||||
if(user.canUseTopic(src, BE_CLOSE, FALSE, NO_TK) && can_interact(user))
|
||||
detach(user)
|
||||
|
||||
/**
|
||||
* activate: Activates biomass processing and converts all inserted grown products into biomass
|
||||
*
|
||||
* Arguments:
|
||||
* * user The mob starting the biomass processing
|
||||
*/
|
||||
/obj/machinery/biogenerator/proc/activate(mob/user)
|
||||
if(user.stat != CONSCIOUS)
|
||||
return
|
||||
if(machine_stat != NONE)
|
||||
return
|
||||
if(processing)
|
||||
to_chat(user, "<span class='warning'>The biogenerator is in the process of working.</span>")
|
||||
return
|
||||
var/S = 0
|
||||
for(var/obj/item/reagent_containers/food/snacks/grown/I in contents)
|
||||
S += 5
|
||||
if(I.reagents.get_reagent_amount(/datum/reagent/consumable/nutriment) < 0.1)
|
||||
points += 1 * productivity
|
||||
else
|
||||
points += I.reagents.get_reagent_amount(/datum/reagent/consumable/nutriment) * 10 * productivity
|
||||
qdel(I)
|
||||
if(S)
|
||||
processing = TRUE
|
||||
update_icon()
|
||||
playsound(loc, 'sound/machines/blender.ogg', 50, TRUE)
|
||||
use_power(S * 30)
|
||||
sleep(S + 15 / productivity)
|
||||
processing = FALSE
|
||||
update_icon()
|
||||
|
||||
/obj/machinery/biogenerator/proc/check_cost(list/materials, multiplier = 1, remove_points = TRUE)
|
||||
if(materials.len != 1 || materials[1] != SSmaterials.GetMaterialRef(/datum/material/biomass))
|
||||
return FALSE
|
||||
if (materials[SSmaterials.GetMaterialRef(/datum/material/biomass)]*multiplier/efficiency > points)
|
||||
return FALSE
|
||||
else
|
||||
if(remove_points)
|
||||
points -= materials[SSmaterials.GetMaterialRef(/datum/material/biomass)]*multiplier/efficiency
|
||||
update_icon()
|
||||
return TRUE
|
||||
|
||||
/obj/machinery/biogenerator/proc/check_container_volume(list/reagents, multiplier = 1)
|
||||
var/sum_reagents = 0
|
||||
for(var/R in reagents)
|
||||
sum_reagents += reagents[R]
|
||||
sum_reagents *= multiplier
|
||||
|
||||
if(beaker.reagents.total_volume + sum_reagents > beaker.reagents.maximum_volume)
|
||||
return FALSE
|
||||
|
||||
return TRUE
|
||||
|
||||
/obj/machinery/biogenerator/proc/create_product(datum/design/D, amount)
|
||||
if(!beaker || !loc)
|
||||
return FALSE
|
||||
|
||||
if(ispath(D.build_path, /obj/item/stack))
|
||||
if(!check_container_volume(D.make_reagents, amount))
|
||||
return FALSE
|
||||
if(!check_cost(D.materials, amount))
|
||||
return FALSE
|
||||
|
||||
new D.build_path(drop_location(), amount)
|
||||
for(var/R in D.make_reagents)
|
||||
beaker.reagents.add_reagent(R, D.make_reagents[R]*amount)
|
||||
else
|
||||
var/i = amount
|
||||
while(i > 0)
|
||||
if(!check_container_volume(D.make_reagents))
|
||||
say("Warning: Attached container does not have enough free capacity!")
|
||||
return .
|
||||
if(!check_cost(D.materials))
|
||||
return .
|
||||
if(D.build_path)
|
||||
new D.build_path(loc)
|
||||
for(var/R in D.make_reagents)
|
||||
beaker.reagents.add_reagent(R, D.make_reagents[R])
|
||||
. = 1
|
||||
--i
|
||||
update_icon()
|
||||
return .
|
||||
|
||||
/obj/machinery/biogenerator/proc/detach(mob/living/user)
|
||||
if(beaker)
|
||||
if(can_interact(user))
|
||||
user.put_in_hands(beaker)
|
||||
else
|
||||
beaker.drop_location(get_turf(src))
|
||||
beaker = null
|
||||
update_icon()
|
||||
|
||||
/obj/machinery/biogenerator/ui_status(mob/user)
|
||||
if(machine_stat & BROKEN || panel_open)
|
||||
return UI_CLOSE
|
||||
return ..()
|
||||
|
||||
/obj/machinery/biogenerator/ui_base_html(html)
|
||||
var/datum/asset/spritesheet/simple/assets = get_asset_datum(/datum/asset/spritesheet/research_designs)
|
||||
. = replacetext(html, "<!--customheadhtml-->", assets.css_tag())
|
||||
|
||||
/obj/machinery/biogenerator/ui_interact(mob/user, ui_key = "main", datum/tgui/ui = null, force_open = FALSE, \
|
||||
datum/tgui/master_ui = null, datum/ui_state/state = GLOB.default_state)
|
||||
ui = SStgui.try_update_ui(user, src, ui_key, ui, force_open)
|
||||
if(!ui)
|
||||
var/datum/asset/assets = get_asset_datum(/datum/asset/spritesheet/research_designs)
|
||||
assets.send(user)
|
||||
ui = new(user, src, ui_key, "Biogenerator", name, ui_x, ui_y, master_ui, state)
|
||||
ui.open()
|
||||
|
||||
/obj/machinery/biogenerator/ui_data(mob/user)
|
||||
var/list/data = list()
|
||||
data["beaker"] = beaker ? TRUE : FALSE
|
||||
data["biomass"] = points
|
||||
data["processing"] = processing
|
||||
if(locate(/obj/item/reagent_containers/food/snacks/grown) in contents)
|
||||
data["can_process"] = TRUE
|
||||
else
|
||||
data["can_process"] = FALSE
|
||||
return data
|
||||
|
||||
/obj/machinery/biogenerator/ui_static_data(mob/user)
|
||||
var/list/data = list()
|
||||
data["categories"] = list()
|
||||
|
||||
var/categories = show_categories.Copy()
|
||||
for(var/V in categories)
|
||||
categories[V] = list()
|
||||
for(var/V in stored_research.researched_designs)
|
||||
var/datum/design/D = SSresearch.techweb_design_by_id(V)
|
||||
for(var/C in categories)
|
||||
if(C in D.category)
|
||||
categories[C] += D
|
||||
|
||||
for(var/category in categories)
|
||||
var/list/cat = list(
|
||||
"name" = category,
|
||||
"items" = (category == selected_cat ? list() : null))
|
||||
for(var/item in categories[category])
|
||||
var/datum/design/D = item
|
||||
cat["items"] += list(list(
|
||||
"id" = D.id,
|
||||
"name" = D.name,
|
||||
"cost" = D.materials[SSmaterials.GetMaterialRef(/datum/material/biomass)]/efficiency,
|
||||
))
|
||||
data["categories"] += list(cat)
|
||||
|
||||
return data
|
||||
|
||||
/obj/machinery/biogenerator/ui_act(action, list/params)
|
||||
if(..())
|
||||
return
|
||||
|
||||
switch(action)
|
||||
if("activate")
|
||||
activate(usr)
|
||||
return TRUE
|
||||
if("detach")
|
||||
detach(usr)
|
||||
return TRUE
|
||||
if("create")
|
||||
var/amount = text2num(params["amount"])
|
||||
amount = clamp(amount, 1, 10)
|
||||
if(!amount)
|
||||
return
|
||||
var/id = params["id"]
|
||||
if(!stored_research.researched_designs.Find(id))
|
||||
stack_trace("ID did not map to a researched datum [id]")
|
||||
return
|
||||
var/datum/design/D = SSresearch.techweb_design_by_id(id)
|
||||
if(D && !istype(D, /datum/design/error_design))
|
||||
create_product(D, amount)
|
||||
else
|
||||
stack_trace("ID could not be turned into a valid techweb design datum [id]")
|
||||
return
|
||||
return TRUE
|
||||
if("select")
|
||||
selected_cat = params["category"]
|
||||
return TRUE
|
||||
|
||||
+189
-189
@@ -1,189 +1,189 @@
|
||||
// ***********************************************************
|
||||
// Foods that are produced from hydroponics ~~~~~~~~~~
|
||||
// Data from the seeds carry over to these grown foods
|
||||
// ***********************************************************
|
||||
|
||||
// Base type. Subtypes are found in /grown dir. Lavaland-based subtypes can be found in mining/ash_flora.dm
|
||||
/obj/item/reagent_containers/food/snacks/grown
|
||||
icon = 'icons/obj/hydroponics/harvest.dmi'
|
||||
name = "fresh produce" // so recipe text doesn't say 'snack'
|
||||
var/obj/item/seeds/seed = null // type path, gets converted to item on New(). It's safe to assume it's always a seed item.
|
||||
var/plantname = ""
|
||||
var/bitesize_mod = 0
|
||||
var/splat_type = /obj/effect/decal/cleanable/food/plant_smudge
|
||||
// If set, bitesize = 1 + round(reagents.total_volume / bitesize_mod)
|
||||
dried_type = -1
|
||||
// Saves us from having to define each stupid grown's dried_type as itself.
|
||||
// If you don't want a plant to be driable (watermelons) set this to null in the time definition.
|
||||
resistance_flags = FLAMMABLE
|
||||
var/dry_grind = FALSE //If TRUE, this object needs to be dry to be ground up
|
||||
var/can_distill = TRUE //If FALSE, this object cannot be distilled into an alcohol.
|
||||
var/distill_reagent //If NULL and this object can be distilled, it uses a generic fruit_wine reagent and adjusts its variables.
|
||||
var/wine_flavor //If NULL, this is automatically set to the fruit's flavor. Determines the flavor of the wine if distill_reagent is NULL.
|
||||
var/wine_power = 10 //Determines the boozepwr of the wine if distill_reagent is NULL.
|
||||
volume = 100
|
||||
|
||||
/obj/item/reagent_containers/food/snacks/grown/Initialize(mapload, obj/item/seeds/new_seed)
|
||||
. = ..()
|
||||
if(!tastes)
|
||||
tastes = list("[name]" = 1)
|
||||
|
||||
if(new_seed)
|
||||
seed = new_seed.Copy()
|
||||
else if(ispath(seed))
|
||||
// This is for adminspawn or map-placed growns. They get the default stats of their seed type.
|
||||
seed = new seed()
|
||||
seed.adjust_potency(50-seed.potency)
|
||||
|
||||
pixel_x = rand(-5, 5)
|
||||
pixel_y = rand(-5, 5)
|
||||
|
||||
if(dried_type == -1)
|
||||
dried_type = src.type
|
||||
|
||||
if(seed)
|
||||
for(var/datum/plant_gene/trait/T in seed.genes)
|
||||
T.on_new(src, loc)
|
||||
seed.prepare_result(src)
|
||||
transform *= TRANSFORM_USING_VARIABLE(seed.potency, 100) + 0.5 //Makes the resulting produce's sprite larger or smaller based on potency!
|
||||
add_juice()
|
||||
|
||||
|
||||
|
||||
/obj/item/reagent_containers/food/snacks/grown/proc/add_juice()
|
||||
if(reagents)
|
||||
if(bitesize_mod)
|
||||
bitesize = 1 + round(reagents.total_volume / bitesize_mod)
|
||||
return 1
|
||||
return 0
|
||||
|
||||
/obj/item/reagent_containers/food/snacks/grown/examine(user)
|
||||
. = ..()
|
||||
if(seed)
|
||||
for(var/datum/plant_gene/trait/T in seed.genes)
|
||||
if(T.examine_line)
|
||||
. += T.examine_line
|
||||
|
||||
/obj/item/reagent_containers/food/snacks/grown/attackby(obj/item/O, mob/user, params)
|
||||
..()
|
||||
if (istype(O, /obj/item/plant_analyzer))
|
||||
var/obj/item/plant_analyzer/P_analyzer = O
|
||||
var/msg = "<span class='info'>*---------*\n This is \a <span class='name'>[src]</span>.\n"
|
||||
if(seed && P_analyzer.scan_mode == PLANT_SCANMODE_STATS)
|
||||
msg += seed.get_analyzer_text()
|
||||
var/reag_txt = ""
|
||||
if(seed && P_analyzer.scan_mode == PLANT_SCANMODE_CHEMICALS)
|
||||
msg += "<br><span class='info'>*Plant Reagents*</span>"
|
||||
var/chem_cap = 0
|
||||
for(var/reagent_id in reagents.reagent_list)
|
||||
var/datum/reagent/R = reagent_id
|
||||
var/amt = R.volume
|
||||
chem_cap += R.volume
|
||||
reag_txt += "\n<span class='info'>- [R.name]: [amt]</span>"
|
||||
if(chem_cap > 100)
|
||||
msg += "<br><span class='warning'>- Reagent Traits Over 100% Production</span></br>"
|
||||
|
||||
if(reag_txt)
|
||||
msg += "<br><span class='info'>*---------*</span>"
|
||||
msg += reag_txt
|
||||
msg += "<br><span class='info'>*---------*</span>"
|
||||
to_chat(user, msg)
|
||||
else
|
||||
if(seed)
|
||||
for(var/datum/plant_gene/trait/T in seed.genes)
|
||||
T.on_attackby(src, O, user)
|
||||
|
||||
|
||||
// Various gene procs
|
||||
/obj/item/reagent_containers/food/snacks/grown/attack_self(mob/user)
|
||||
if(seed && seed.get_gene(/datum/plant_gene/trait/squash))
|
||||
squash(user)
|
||||
..()
|
||||
|
||||
/obj/item/reagent_containers/food/snacks/grown/throw_impact(atom/hit_atom, datum/thrownthing/throwingdatum)
|
||||
if(!..()) //was it caught by a mob?
|
||||
if(seed)
|
||||
for(var/datum/plant_gene/trait/T in seed.genes)
|
||||
T.on_throw_impact(src, hit_atom)
|
||||
if(seed.get_gene(/datum/plant_gene/trait/squash))
|
||||
squash(hit_atom)
|
||||
|
||||
/obj/item/reagent_containers/food/snacks/grown/proc/squash(atom/target)
|
||||
var/turf/T = get_turf(target)
|
||||
forceMove(T)
|
||||
if(ispath(splat_type, /obj/effect/decal/cleanable/food/plant_smudge))
|
||||
if(filling_color)
|
||||
var/obj/O = new splat_type(T)
|
||||
O.color = filling_color
|
||||
O.name = "[name] smudge"
|
||||
else if(splat_type)
|
||||
new splat_type(T)
|
||||
|
||||
if(trash)
|
||||
generate_trash(T)
|
||||
|
||||
visible_message("<span class='warning'>[src] is squashed.</span>","<span class='hear'>You hear a smack.</span>")
|
||||
if(seed)
|
||||
for(var/datum/plant_gene/trait/trait in seed.genes)
|
||||
trait.on_squash(src, target)
|
||||
|
||||
reagents.expose(T)
|
||||
for(var/A in T)
|
||||
reagents.expose(A)
|
||||
|
||||
qdel(src)
|
||||
|
||||
/obj/item/reagent_containers/food/snacks/grown/On_Consume()
|
||||
if(iscarbon(usr))
|
||||
if(seed)
|
||||
for(var/datum/plant_gene/trait/T in seed.genes)
|
||||
T.on_consume(src, usr)
|
||||
..()
|
||||
|
||||
/obj/item/reagent_containers/food/snacks/grown/generate_trash(atom/location)
|
||||
if(trash && (ispath(trash, /obj/item/grown) || ispath(trash, /obj/item/reagent_containers/food/snacks/grown)))
|
||||
. = new trash(location, seed)
|
||||
trash = null
|
||||
return
|
||||
return ..()
|
||||
|
||||
/obj/item/reagent_containers/food/snacks/grown/grind_requirements()
|
||||
if(dry_grind && !dry)
|
||||
to_chat(usr, "<span class='warning'>[src] needs to be dry before it can be ground up!</span>")
|
||||
return
|
||||
return TRUE
|
||||
|
||||
/obj/item/reagent_containers/food/snacks/grown/on_grind()
|
||||
var/nutriment = reagents.get_reagent_amount(/datum/reagent/consumable/nutriment)
|
||||
if(grind_results&&grind_results.len)
|
||||
for(var/i in 1 to grind_results.len)
|
||||
grind_results[grind_results[i]] = nutriment
|
||||
reagents.del_reagent(/datum/reagent/consumable/nutriment)
|
||||
reagents.del_reagent(/datum/reagent/consumable/nutriment/vitamin)
|
||||
|
||||
/obj/item/reagent_containers/food/snacks/grown/on_juice()
|
||||
var/nutriment = reagents.get_reagent_amount(/datum/reagent/consumable/nutriment)
|
||||
if(juice_results&&juice_results.len)
|
||||
for(var/i in 1 to juice_results.len)
|
||||
juice_results[juice_results[i]] = nutriment
|
||||
reagents.del_reagent(/datum/reagent/consumable/nutriment)
|
||||
reagents.del_reagent(/datum/reagent/consumable/nutriment/vitamin)
|
||||
|
||||
/*
|
||||
* Attack self for growns
|
||||
*
|
||||
* Spawns the trash item at the growns drop_location()
|
||||
*
|
||||
* Then deletes the grown object
|
||||
*
|
||||
* Then puts trash item into the hand of user attack selfing, or drops it back on the ground
|
||||
*/
|
||||
/obj/item/reagent_containers/food/snacks/grown/shell/attack_self(mob/user)
|
||||
var/obj/item/T
|
||||
if(trash)
|
||||
T = generate_trash(drop_location())
|
||||
//Delete grown so our hand is free
|
||||
qdel(src)
|
||||
//put trash obj in hands or drop to ground
|
||||
user.put_in_hands(T, user.active_hand_index, TRUE)
|
||||
to_chat(user, "<span class='notice'>You open [src]\'s shell, revealing \a [T].</span>")
|
||||
// ***********************************************************
|
||||
// Foods that are produced from hydroponics ~~~~~~~~~~
|
||||
// Data from the seeds carry over to these grown foods
|
||||
// ***********************************************************
|
||||
|
||||
// Base type. Subtypes are found in /grown dir. Lavaland-based subtypes can be found in mining/ash_flora.dm
|
||||
/obj/item/reagent_containers/food/snacks/grown
|
||||
icon = 'icons/obj/hydroponics/harvest.dmi'
|
||||
name = "fresh produce" // so recipe text doesn't say 'snack'
|
||||
var/obj/item/seeds/seed = null // type path, gets converted to item on New(). It's safe to assume it's always a seed item.
|
||||
var/plantname = ""
|
||||
var/bitesize_mod = 0
|
||||
var/splat_type = /obj/effect/decal/cleanable/food/plant_smudge
|
||||
// If set, bitesize = 1 + round(reagents.total_volume / bitesize_mod)
|
||||
dried_type = -1
|
||||
// Saves us from having to define each stupid grown's dried_type as itself.
|
||||
// If you don't want a plant to be driable (watermelons) set this to null in the time definition.
|
||||
resistance_flags = FLAMMABLE
|
||||
var/dry_grind = FALSE //If TRUE, this object needs to be dry to be ground up
|
||||
var/can_distill = TRUE //If FALSE, this object cannot be distilled into an alcohol.
|
||||
var/distill_reagent //If NULL and this object can be distilled, it uses a generic fruit_wine reagent and adjusts its variables.
|
||||
var/wine_flavor //If NULL, this is automatically set to the fruit's flavor. Determines the flavor of the wine if distill_reagent is NULL.
|
||||
var/wine_power = 10 //Determines the boozepwr of the wine if distill_reagent is NULL.
|
||||
volume = 100
|
||||
|
||||
/obj/item/reagent_containers/food/snacks/grown/Initialize(mapload, obj/item/seeds/new_seed)
|
||||
. = ..()
|
||||
if(!tastes)
|
||||
tastes = list("[name]" = 1)
|
||||
|
||||
if(new_seed)
|
||||
seed = new_seed.Copy()
|
||||
else if(ispath(seed))
|
||||
// This is for adminspawn or map-placed growns. They get the default stats of their seed type.
|
||||
seed = new seed()
|
||||
seed.adjust_potency(50-seed.potency)
|
||||
|
||||
pixel_x = rand(-5, 5)
|
||||
pixel_y = rand(-5, 5)
|
||||
|
||||
if(dried_type == -1)
|
||||
dried_type = src.type
|
||||
|
||||
if(seed)
|
||||
for(var/datum/plant_gene/trait/T in seed.genes)
|
||||
T.on_new(src, loc)
|
||||
seed.prepare_result(src)
|
||||
transform *= TRANSFORM_USING_VARIABLE(seed.potency, 100) + 0.5 //Makes the resulting produce's sprite larger or smaller based on potency!
|
||||
add_juice()
|
||||
|
||||
|
||||
|
||||
/obj/item/reagent_containers/food/snacks/grown/proc/add_juice()
|
||||
if(reagents)
|
||||
if(bitesize_mod)
|
||||
bitesize = 1 + round(reagents.total_volume / bitesize_mod)
|
||||
return 1
|
||||
return 0
|
||||
|
||||
/obj/item/reagent_containers/food/snacks/grown/examine(user)
|
||||
. = ..()
|
||||
if(seed)
|
||||
for(var/datum/plant_gene/trait/T in seed.genes)
|
||||
if(T.examine_line)
|
||||
. += T.examine_line
|
||||
|
||||
/obj/item/reagent_containers/food/snacks/grown/attackby(obj/item/O, mob/user, params)
|
||||
..()
|
||||
if (istype(O, /obj/item/plant_analyzer))
|
||||
var/obj/item/plant_analyzer/P_analyzer = O
|
||||
var/msg = "<span class='info'>*---------*\n This is \a <span class='name'>[src]</span>.\n"
|
||||
if(seed && P_analyzer.scan_mode == PLANT_SCANMODE_STATS)
|
||||
msg += seed.get_analyzer_text()
|
||||
var/reag_txt = ""
|
||||
if(seed && P_analyzer.scan_mode == PLANT_SCANMODE_CHEMICALS)
|
||||
msg += "<br><span class='info'>*Plant Reagents*</span>"
|
||||
var/chem_cap = 0
|
||||
for(var/reagent_id in reagents.reagent_list)
|
||||
var/datum/reagent/R = reagent_id
|
||||
var/amt = R.volume
|
||||
chem_cap += R.volume
|
||||
reag_txt += "\n<span class='info'>- [R.name]: [amt]</span>"
|
||||
if(chem_cap > 100)
|
||||
msg += "<br><span class='warning'>- Reagent Traits Over 100% Production</span></br>"
|
||||
|
||||
if(reag_txt)
|
||||
msg += "<br><span class='info'>*---------*</span>"
|
||||
msg += reag_txt
|
||||
msg += "<br><span class='info'>*---------*</span>"
|
||||
to_chat(user, msg)
|
||||
else
|
||||
if(seed)
|
||||
for(var/datum/plant_gene/trait/T in seed.genes)
|
||||
T.on_attackby(src, O, user)
|
||||
|
||||
|
||||
// Various gene procs
|
||||
/obj/item/reagent_containers/food/snacks/grown/attack_self(mob/user)
|
||||
if(seed && seed.get_gene(/datum/plant_gene/trait/squash))
|
||||
squash(user)
|
||||
..()
|
||||
|
||||
/obj/item/reagent_containers/food/snacks/grown/throw_impact(atom/hit_atom, datum/thrownthing/throwingdatum)
|
||||
if(!..()) //was it caught by a mob?
|
||||
if(seed)
|
||||
for(var/datum/plant_gene/trait/T in seed.genes)
|
||||
T.on_throw_impact(src, hit_atom)
|
||||
if(seed.get_gene(/datum/plant_gene/trait/squash))
|
||||
squash(hit_atom)
|
||||
|
||||
/obj/item/reagent_containers/food/snacks/grown/proc/squash(atom/target)
|
||||
var/turf/T = get_turf(target)
|
||||
forceMove(T)
|
||||
if(ispath(splat_type, /obj/effect/decal/cleanable/food/plant_smudge))
|
||||
if(filling_color)
|
||||
var/obj/O = new splat_type(T)
|
||||
O.color = filling_color
|
||||
O.name = "[name] smudge"
|
||||
else if(splat_type)
|
||||
new splat_type(T)
|
||||
|
||||
if(trash)
|
||||
generate_trash(T)
|
||||
|
||||
visible_message("<span class='warning'>[src] is squashed.</span>","<span class='hear'>You hear a smack.</span>")
|
||||
if(seed)
|
||||
for(var/datum/plant_gene/trait/trait in seed.genes)
|
||||
trait.on_squash(src, target)
|
||||
|
||||
reagents.expose(T)
|
||||
for(var/A in T)
|
||||
reagents.expose(A)
|
||||
|
||||
qdel(src)
|
||||
|
||||
/obj/item/reagent_containers/food/snacks/grown/On_Consume()
|
||||
if(iscarbon(usr))
|
||||
if(seed)
|
||||
for(var/datum/plant_gene/trait/T in seed.genes)
|
||||
T.on_consume(src, usr)
|
||||
..()
|
||||
|
||||
/obj/item/reagent_containers/food/snacks/grown/generate_trash(atom/location)
|
||||
if(trash && (ispath(trash, /obj/item/grown) || ispath(trash, /obj/item/reagent_containers/food/snacks/grown)))
|
||||
. = new trash(location, seed)
|
||||
trash = null
|
||||
return
|
||||
return ..()
|
||||
|
||||
/obj/item/reagent_containers/food/snacks/grown/grind_requirements()
|
||||
if(dry_grind && !dry)
|
||||
to_chat(usr, "<span class='warning'>[src] needs to be dry before it can be ground up!</span>")
|
||||
return
|
||||
return TRUE
|
||||
|
||||
/obj/item/reagent_containers/food/snacks/grown/on_grind()
|
||||
var/nutriment = reagents.get_reagent_amount(/datum/reagent/consumable/nutriment)
|
||||
if(grind_results&&grind_results.len)
|
||||
for(var/i in 1 to grind_results.len)
|
||||
grind_results[grind_results[i]] = nutriment
|
||||
reagents.del_reagent(/datum/reagent/consumable/nutriment)
|
||||
reagents.del_reagent(/datum/reagent/consumable/nutriment/vitamin)
|
||||
|
||||
/obj/item/reagent_containers/food/snacks/grown/on_juice()
|
||||
var/nutriment = reagents.get_reagent_amount(/datum/reagent/consumable/nutriment)
|
||||
if(juice_results&&juice_results.len)
|
||||
for(var/i in 1 to juice_results.len)
|
||||
juice_results[juice_results[i]] = nutriment
|
||||
reagents.del_reagent(/datum/reagent/consumable/nutriment)
|
||||
reagents.del_reagent(/datum/reagent/consumable/nutriment/vitamin)
|
||||
|
||||
/*
|
||||
* Attack self for growns
|
||||
*
|
||||
* Spawns the trash item at the growns drop_location()
|
||||
*
|
||||
* Then deletes the grown object
|
||||
*
|
||||
* Then puts trash item into the hand of user attack selfing, or drops it back on the ground
|
||||
*/
|
||||
/obj/item/reagent_containers/food/snacks/grown/shell/attack_self(mob/user)
|
||||
var/obj/item/T
|
||||
if(trash)
|
||||
T = generate_trash(drop_location())
|
||||
//Delete grown so our hand is free
|
||||
qdel(src)
|
||||
//put trash obj in hands or drop to ground
|
||||
user.put_in_hands(T, user.active_hand_index, TRUE)
|
||||
to_chat(user, "<span class='notice'>You open [src]\'s shell, revealing \a [T].</span>")
|
||||
|
||||
@@ -1,61 +1,61 @@
|
||||
// **********************
|
||||
// Other harvested materials from plants (that are not food)
|
||||
// **********************
|
||||
|
||||
/obj/item/grown // Grown weapons
|
||||
name = "grown_weapon"
|
||||
icon = 'icons/obj/hydroponics/harvest.dmi'
|
||||
resistance_flags = FLAMMABLE
|
||||
var/obj/item/seeds/seed = null // type path, gets converted to item on New(). It's safe to assume it's always a seed item.
|
||||
|
||||
/obj/item/grown/Initialize(newloc, obj/item/seeds/new_seed)
|
||||
. = ..()
|
||||
create_reagents(100)
|
||||
|
||||
if(new_seed)
|
||||
seed = new_seed.Copy()
|
||||
else if(ispath(seed))
|
||||
// This is for adminspawn or map-placed growns. They get the default stats of their seed type.
|
||||
seed = new seed()
|
||||
seed.adjust_potency(50-seed.potency)
|
||||
|
||||
pixel_x = rand(-5, 5)
|
||||
pixel_y = rand(-5, 5)
|
||||
|
||||
if(seed)
|
||||
for(var/datum/plant_gene/trait/T in seed.genes)
|
||||
T.on_new(src, newloc)
|
||||
|
||||
if(istype(src, seed.product)) // no adding reagents if it is just a trash item
|
||||
seed.prepare_result(src)
|
||||
transform *= TRANSFORM_USING_VARIABLE(seed.potency, 100) + 0.5
|
||||
add_juice()
|
||||
|
||||
|
||||
/obj/item/grown/attackby(obj/item/O, mob/user, params)
|
||||
..()
|
||||
if (istype(O, /obj/item/plant_analyzer))
|
||||
var/msg = "<span class='info'>*---------*\n This is \a <span class='name'>[src]</span>\n"
|
||||
if(seed)
|
||||
msg += seed.get_analyzer_text()
|
||||
msg += "</span>"
|
||||
to_chat(usr, msg)
|
||||
return
|
||||
|
||||
/obj/item/grown/proc/add_juice()
|
||||
if(reagents)
|
||||
return 1
|
||||
return 0
|
||||
|
||||
/obj/item/grown/throw_impact(atom/hit_atom, datum/thrownthing/throwingdatum)
|
||||
if(!..()) //was it caught by a mob?
|
||||
if(seed)
|
||||
for(var/datum/plant_gene/trait/T in seed.genes)
|
||||
T.on_throw_impact(src, hit_atom)
|
||||
|
||||
/obj/item/grown/microwave_act(obj/machinery/microwave/M)
|
||||
return
|
||||
|
||||
/obj/item/grown/on_grind()
|
||||
for(var/i in 1 to grind_results.len)
|
||||
grind_results[grind_results[i]] = round(seed.potency)
|
||||
// **********************
|
||||
// Other harvested materials from plants (that are not food)
|
||||
// **********************
|
||||
|
||||
/obj/item/grown // Grown weapons
|
||||
name = "grown_weapon"
|
||||
icon = 'icons/obj/hydroponics/harvest.dmi'
|
||||
resistance_flags = FLAMMABLE
|
||||
var/obj/item/seeds/seed = null // type path, gets converted to item on New(). It's safe to assume it's always a seed item.
|
||||
|
||||
/obj/item/grown/Initialize(newloc, obj/item/seeds/new_seed)
|
||||
. = ..()
|
||||
create_reagents(100)
|
||||
|
||||
if(new_seed)
|
||||
seed = new_seed.Copy()
|
||||
else if(ispath(seed))
|
||||
// This is for adminspawn or map-placed growns. They get the default stats of their seed type.
|
||||
seed = new seed()
|
||||
seed.adjust_potency(50-seed.potency)
|
||||
|
||||
pixel_x = rand(-5, 5)
|
||||
pixel_y = rand(-5, 5)
|
||||
|
||||
if(seed)
|
||||
for(var/datum/plant_gene/trait/T in seed.genes)
|
||||
T.on_new(src, newloc)
|
||||
|
||||
if(istype(src, seed.product)) // no adding reagents if it is just a trash item
|
||||
seed.prepare_result(src)
|
||||
transform *= TRANSFORM_USING_VARIABLE(seed.potency, 100) + 0.5
|
||||
add_juice()
|
||||
|
||||
|
||||
/obj/item/grown/attackby(obj/item/O, mob/user, params)
|
||||
..()
|
||||
if (istype(O, /obj/item/plant_analyzer))
|
||||
var/msg = "<span class='info'>*---------*\n This is \a <span class='name'>[src]</span>\n"
|
||||
if(seed)
|
||||
msg += seed.get_analyzer_text()
|
||||
msg += "</span>"
|
||||
to_chat(usr, msg)
|
||||
return
|
||||
|
||||
/obj/item/grown/proc/add_juice()
|
||||
if(reagents)
|
||||
return 1
|
||||
return 0
|
||||
|
||||
/obj/item/grown/throw_impact(atom/hit_atom, datum/thrownthing/throwingdatum)
|
||||
if(!..()) //was it caught by a mob?
|
||||
if(seed)
|
||||
for(var/datum/plant_gene/trait/T in seed.genes)
|
||||
T.on_throw_impact(src, hit_atom)
|
||||
|
||||
/obj/item/grown/microwave_act(obj/machinery/microwave/M)
|
||||
return
|
||||
|
||||
/obj/item/grown/on_grind()
|
||||
for(var/i in 1 to grind_results.len)
|
||||
grind_results[grind_results[i]] = round(seed.potency)
|
||||
|
||||
@@ -1,276 +1,276 @@
|
||||
|
||||
// Plant analyzer
|
||||
/obj/item/plant_analyzer
|
||||
name = "plant analyzer"
|
||||
desc = "A scanner used to evaluate a plant's various areas of growth, and genetic traits."
|
||||
icon = 'icons/obj/device.dmi'
|
||||
icon_state = "hydro"
|
||||
inhand_icon_state = "analyzer"
|
||||
worn_icon_state = "analyzer"
|
||||
lefthand_file = 'icons/mob/inhands/equipment/tools_lefthand.dmi'
|
||||
righthand_file = 'icons/mob/inhands/equipment/tools_righthand.dmi'
|
||||
w_class = WEIGHT_CLASS_TINY
|
||||
slot_flags = ITEM_SLOT_BELT
|
||||
custom_materials = list(/datum/material/iron=30, /datum/material/glass=20)
|
||||
var/scan_mode = PLANT_SCANMODE_STATS
|
||||
|
||||
/obj/item/plant_analyzer/attack_self(mob/user)
|
||||
. = ..()
|
||||
scan_mode = !scan_mode
|
||||
to_chat(user, "<span class='notice'>You switch [src] to [scan_mode == PLANT_SCANMODE_CHEMICALS ? "scan for chemical reagents and traits" : "scan for plant growth statistics"].</span>")
|
||||
|
||||
/obj/item/plant_analyzer/attack(mob/living/M, mob/living/carbon/human/user)
|
||||
//Checks if target is a podman
|
||||
if(ispodperson(M))
|
||||
user.visible_message("<span class='notice'>[user] analyzes [M]'s vitals.</span>", \
|
||||
"<span class='notice'>You analyze [M]'s vitals.</span>")
|
||||
if(scan_mode== PLANT_SCANMODE_STATS)
|
||||
healthscan(user, M, advanced = TRUE)
|
||||
else
|
||||
chemscan(user, M)
|
||||
add_fingerprint(user)
|
||||
return
|
||||
return ..()
|
||||
|
||||
// *************************************
|
||||
// Hydroponics Tools
|
||||
// *************************************
|
||||
|
||||
/obj/item/reagent_containers/spray/weedspray // -- Skie
|
||||
desc = "It's a toxic mixture, in spray form, to kill small weeds."
|
||||
icon = 'icons/obj/hydroponics/equipment.dmi'
|
||||
name = "weed spray"
|
||||
icon_state = "weedspray"
|
||||
inhand_icon_state = "spraycan"
|
||||
lefthand_file = 'icons/mob/inhands/equipment/hydroponics_lefthand.dmi'
|
||||
righthand_file = 'icons/mob/inhands/equipment/hydroponics_righthand.dmi'
|
||||
volume = 100
|
||||
list_reagents = list(/datum/reagent/toxin/plantbgone/weedkiller = 100)
|
||||
|
||||
/obj/item/reagent_containers/spray/weedspray/suicide_act(mob/user)
|
||||
user.visible_message("<span class='suicide'>[user] is huffing [src]! It looks like [user.p_theyre()] trying to commit suicide!</span>")
|
||||
return (TOXLOSS)
|
||||
|
||||
/obj/item/reagent_containers/spray/pestspray // -- Skie
|
||||
desc = "It's some pest eliminator spray! <I>Do not inhale!</I>"
|
||||
icon = 'icons/obj/hydroponics/equipment.dmi'
|
||||
name = "pest spray"
|
||||
icon_state = "pestspray"
|
||||
inhand_icon_state = "plantbgone"
|
||||
lefthand_file = 'icons/mob/inhands/equipment/hydroponics_lefthand.dmi'
|
||||
righthand_file = 'icons/mob/inhands/equipment/hydroponics_righthand.dmi'
|
||||
volume = 100
|
||||
list_reagents = list(/datum/reagent/toxin/pestkiller = 100)
|
||||
|
||||
/obj/item/reagent_containers/spray/pestspray/suicide_act(mob/user)
|
||||
user.visible_message("<span class='suicide'>[user] is huffing [src]! It looks like [user.p_theyre()] trying to commit suicide!</span>")
|
||||
return (TOXLOSS)
|
||||
|
||||
/obj/item/cultivator
|
||||
name = "cultivator"
|
||||
desc = "It's used for removing weeds or scratching your back."
|
||||
icon = 'icons/obj/items_and_weapons.dmi'
|
||||
icon_state = "cultivator"
|
||||
inhand_icon_state = "cultivator"
|
||||
lefthand_file = 'icons/mob/inhands/equipment/hydroponics_lefthand.dmi'
|
||||
righthand_file = 'icons/mob/inhands/equipment/hydroponics_righthand.dmi'
|
||||
flags_1 = CONDUCT_1
|
||||
force = 5
|
||||
throwforce = 7
|
||||
w_class = WEIGHT_CLASS_SMALL
|
||||
custom_materials = list(/datum/material/iron=50)
|
||||
attack_verb = list("slashed", "sliced", "cut", "clawed")
|
||||
hitsound = 'sound/weapons/bladeslice.ogg'
|
||||
|
||||
/obj/item/cultivator/suicide_act(mob/user)
|
||||
user.visible_message("<span class='suicide'>[user] is scratching [user.p_their()] back as hard as [user.p_they()] can with \the [src]! It looks like [user.p_theyre()] trying to commit suicide!</span>")
|
||||
return (BRUTELOSS)
|
||||
|
||||
/obj/item/cultivator/rake
|
||||
name = "rake"
|
||||
icon_state = "rake"
|
||||
w_class = WEIGHT_CLASS_NORMAL
|
||||
attack_verb = list("slashed", "sliced", "bashed", "clawed")
|
||||
hitsound = null
|
||||
custom_materials = list(/datum/material/wood = MINERAL_MATERIAL_AMOUNT * 1.5)
|
||||
flags_1 = NONE
|
||||
resistance_flags = FLAMMABLE
|
||||
|
||||
/obj/item/cultivator/rake/Crossed(atom/movable/AM)
|
||||
. = ..()
|
||||
if(!ishuman(AM))
|
||||
return
|
||||
var/mob/living/carbon/human/H = AM
|
||||
if(has_gravity(loc) && HAS_TRAIT(H, TRAIT_CLUMSY) && !H.resting)
|
||||
H.confused = max(H.confused, 10)
|
||||
H.Stun(20)
|
||||
playsound(src, 'sound/weapons/punch4.ogg', 50, TRUE)
|
||||
H.visible_message("<span class='warning'>[H] steps on [src] causing the handle to hit [H.p_them()] right in the face!</span>", \
|
||||
"<span class='userdanger'>You step on [src] causing the handle to hit you right in the face!</span>")
|
||||
|
||||
/obj/item/hatchet
|
||||
name = "hatchet"
|
||||
desc = "A very sharp axe blade upon a short fibremetal handle. It has a long history of chopping things, but now it is used for chopping wood."
|
||||
icon = 'icons/obj/items_and_weapons.dmi'
|
||||
icon_state = "hatchet"
|
||||
inhand_icon_state = "hatchet"
|
||||
lefthand_file = 'icons/mob/inhands/equipment/hydroponics_lefthand.dmi'
|
||||
righthand_file = 'icons/mob/inhands/equipment/hydroponics_righthand.dmi'
|
||||
flags_1 = CONDUCT_1
|
||||
force = 12
|
||||
w_class = WEIGHT_CLASS_SMALL
|
||||
throwforce = 15
|
||||
throw_speed = 3
|
||||
throw_range = 4
|
||||
custom_materials = list(/datum/material/iron = 15000)
|
||||
attack_verb = list("chopped", "tore", "lacerated", "cut")
|
||||
hitsound = 'sound/weapons/bladeslice.ogg'
|
||||
sharpness = IS_SHARP
|
||||
|
||||
/obj/item/hatchet/Initialize()
|
||||
. = ..()
|
||||
AddComponent(/datum/component/butchering, 70, 100)
|
||||
|
||||
/obj/item/hatchet/suicide_act(mob/user)
|
||||
user.visible_message("<span class='suicide'>[user] is chopping at [user.p_them()]self with [src]! It looks like [user.p_theyre()] trying to commit suicide!</span>")
|
||||
playsound(src, 'sound/weapons/bladeslice.ogg', 50, TRUE, -1)
|
||||
return (BRUTELOSS)
|
||||
|
||||
/obj/item/hatchet/wooden
|
||||
desc = "A crude axe blade upon a short wooden handle."
|
||||
icon_state = "woodhatchet"
|
||||
custom_materials = null
|
||||
flags_1 = NONE
|
||||
|
||||
/obj/item/scythe
|
||||
icon_state = "scythe0"
|
||||
lefthand_file = 'icons/mob/inhands/weapons/polearms_lefthand.dmi'
|
||||
righthand_file = 'icons/mob/inhands/weapons/polearms_righthand.dmi'
|
||||
name = "scythe"
|
||||
desc = "A sharp and curved blade on a long fibremetal handle, this tool makes it easy to reap what you sow."
|
||||
force = 13
|
||||
throwforce = 5
|
||||
throw_speed = 2
|
||||
throw_range = 3
|
||||
w_class = WEIGHT_CLASS_BULKY
|
||||
flags_1 = CONDUCT_1
|
||||
armour_penetration = 20
|
||||
slot_flags = ITEM_SLOT_BACK
|
||||
attack_verb = list("chopped", "sliced", "cut", "reaped")
|
||||
hitsound = 'sound/weapons/bladeslice.ogg'
|
||||
var/swiping = FALSE
|
||||
|
||||
/obj/item/scythe/Initialize()
|
||||
. = ..()
|
||||
AddComponent(/datum/component/butchering, 90, 105)
|
||||
|
||||
/obj/item/scythe/suicide_act(mob/user)
|
||||
user.visible_message("<span class='suicide'>[user] is beheading [user.p_them()]self with [src]! It looks like [user.p_theyre()] trying to commit suicide!</span>")
|
||||
if(iscarbon(user))
|
||||
var/mob/living/carbon/C = user
|
||||
var/obj/item/bodypart/BP = C.get_bodypart(BODY_ZONE_HEAD)
|
||||
if(BP)
|
||||
BP.drop_limb()
|
||||
playsound(src, "desecration" ,50, TRUE, -1)
|
||||
return (BRUTELOSS)
|
||||
|
||||
/obj/item/scythe/pre_attack(atom/A, mob/living/user, params)
|
||||
if(swiping || !istype(A, /obj/structure/spacevine) || get_turf(A) == get_turf(user))
|
||||
return ..()
|
||||
var/turf/user_turf = get_turf(user)
|
||||
var/dir_to_target = get_dir(user_turf, get_turf(A))
|
||||
swiping = TRUE
|
||||
var/static/list/scythe_slash_angles = list(0, 45, 90, -45, -90)
|
||||
for(var/i in scythe_slash_angles)
|
||||
var/turf/T = get_step(user_turf, turn(dir_to_target, i))
|
||||
for(var/obj/structure/spacevine/V in T)
|
||||
if(user.Adjacent(V))
|
||||
melee_attack_chain(user, V)
|
||||
swiping = FALSE
|
||||
return TRUE
|
||||
|
||||
/obj/item/secateurs
|
||||
name = "secateurs"
|
||||
desc = "It's a tool for cutting grafts off plants."
|
||||
icon = 'icons/obj/hydroponics/equipment.dmi'
|
||||
icon_state = "secateurs"
|
||||
inhand_icon_state = "secateurs"
|
||||
lefthand_file = 'icons/mob/inhands/equipment/hydroponics_lefthand.dmi'
|
||||
righthand_file = 'icons/mob/inhands/equipment/hydroponics_righthand.dmi'
|
||||
flags_1 = CONDUCT_1
|
||||
force = 5
|
||||
throwforce = 6
|
||||
w_class = WEIGHT_CLASS_SMALL
|
||||
slot_flags = ITEM_SLOT_BELT
|
||||
custom_materials = list(/datum/material/iron=4000)
|
||||
attack_verb = list("slashed", "sliced", "cut", "clawed")
|
||||
hitsound = 'sound/weapons/bladeslice.ogg'
|
||||
|
||||
/obj/item/geneshears
|
||||
name = "Botanogenetic Plant Shears"
|
||||
desc = "A high tech, high fidelity pair of plant shears, capable of cutting genetic traits out of a plant."
|
||||
icon = 'icons/obj/hydroponics/equipment.dmi'
|
||||
icon_state = "genesheers"
|
||||
inhand_icon_state = "secateurs"
|
||||
lefthand_file = 'icons/mob/inhands/equipment/hydroponics_lefthand.dmi'
|
||||
righthand_file = 'icons/mob/inhands/equipment/hydroponics_righthand.dmi'
|
||||
flags_1 = CONDUCT_1
|
||||
force = 10
|
||||
throwforce = 8
|
||||
w_class = WEIGHT_CLASS_SMALL
|
||||
slot_flags = ITEM_SLOT_BELT
|
||||
material_flags = MATERIAL_NO_EFFECTS
|
||||
custom_materials = list(/datum/material/iron=4000, /datum/material/uranium=1500, /datum/material/gold=500)
|
||||
attack_verb = list("slashed", "sliced", "cut")
|
||||
hitsound = 'sound/weapons/bladeslice.ogg'
|
||||
|
||||
|
||||
// *************************************
|
||||
// Nutrient defines for hydroponics
|
||||
// *************************************
|
||||
|
||||
|
||||
/obj/item/reagent_containers/glass/bottle/nutrient
|
||||
name = "bottle of nutrient"
|
||||
volume = 50
|
||||
amount_per_transfer_from_this = 10
|
||||
possible_transfer_amounts = list(1,2,5,10,15,25,50)
|
||||
|
||||
/obj/item/reagent_containers/glass/bottle/nutrient/Initialize()
|
||||
. = ..()
|
||||
pixel_x = rand(-5, 5)
|
||||
pixel_y = rand(-5, 5)
|
||||
|
||||
|
||||
/obj/item/reagent_containers/glass/bottle/nutrient/ez
|
||||
name = "bottle of E-Z-Nutrient"
|
||||
desc = "Contains a fertilizer that causes mild mutations and gradual plant growth with each harvest."
|
||||
list_reagents = list(/datum/reagent/plantnutriment/eznutriment = 50)
|
||||
|
||||
/obj/item/reagent_containers/glass/bottle/nutrient/l4z
|
||||
name = "bottle of Left 4 Zed"
|
||||
desc = "Contains a fertilizer that lightly heals the plant but causes significant mutations in plants over generations."
|
||||
list_reagents = list(/datum/reagent/plantnutriment/left4zednutriment = 50)
|
||||
|
||||
/obj/item/reagent_containers/glass/bottle/nutrient/rh
|
||||
name = "bottle of Robust Harvest"
|
||||
desc = "Contains a fertilizer that increases the yield of a plant while gradually preventing mutations."
|
||||
list_reagents = list(/datum/reagent/plantnutriment/robustharvestnutriment = 50)
|
||||
|
||||
/obj/item/reagent_containers/glass/bottle/nutrient/empty
|
||||
name = "bottle"
|
||||
|
||||
/obj/item/reagent_containers/glass/bottle/killer
|
||||
volume = 30
|
||||
amount_per_transfer_from_this = 1
|
||||
possible_transfer_amounts = list(1,2,5)
|
||||
|
||||
/obj/item/reagent_containers/glass/bottle/killer/weedkiller
|
||||
name = "bottle of weed killer"
|
||||
desc = "Contains a herbicide."
|
||||
list_reagents = list(/datum/reagent/toxin/plantbgone/weedkiller = 30)
|
||||
|
||||
/obj/item/reagent_containers/glass/bottle/killer/pestkiller
|
||||
name = "bottle of pest spray"
|
||||
desc = "Contains a pesticide."
|
||||
list_reagents = list(/datum/reagent/toxin/pestkiller = 30)
|
||||
|
||||
// Plant analyzer
|
||||
/obj/item/plant_analyzer
|
||||
name = "plant analyzer"
|
||||
desc = "A scanner used to evaluate a plant's various areas of growth, and genetic traits."
|
||||
icon = 'icons/obj/device.dmi'
|
||||
icon_state = "hydro"
|
||||
inhand_icon_state = "analyzer"
|
||||
worn_icon_state = "analyzer"
|
||||
lefthand_file = 'icons/mob/inhands/equipment/tools_lefthand.dmi'
|
||||
righthand_file = 'icons/mob/inhands/equipment/tools_righthand.dmi'
|
||||
w_class = WEIGHT_CLASS_TINY
|
||||
slot_flags = ITEM_SLOT_BELT
|
||||
custom_materials = list(/datum/material/iron=30, /datum/material/glass=20)
|
||||
var/scan_mode = PLANT_SCANMODE_STATS
|
||||
|
||||
/obj/item/plant_analyzer/attack_self(mob/user)
|
||||
. = ..()
|
||||
scan_mode = !scan_mode
|
||||
to_chat(user, "<span class='notice'>You switch [src] to [scan_mode == PLANT_SCANMODE_CHEMICALS ? "scan for chemical reagents and traits" : "scan for plant growth statistics"].</span>")
|
||||
|
||||
/obj/item/plant_analyzer/attack(mob/living/M, mob/living/carbon/human/user)
|
||||
//Checks if target is a podman
|
||||
if(ispodperson(M))
|
||||
user.visible_message("<span class='notice'>[user] analyzes [M]'s vitals.</span>", \
|
||||
"<span class='notice'>You analyze [M]'s vitals.</span>")
|
||||
if(scan_mode== PLANT_SCANMODE_STATS)
|
||||
healthscan(user, M, advanced = TRUE)
|
||||
else
|
||||
chemscan(user, M)
|
||||
add_fingerprint(user)
|
||||
return
|
||||
return ..()
|
||||
|
||||
// *************************************
|
||||
// Hydroponics Tools
|
||||
// *************************************
|
||||
|
||||
/obj/item/reagent_containers/spray/weedspray // -- Skie
|
||||
desc = "It's a toxic mixture, in spray form, to kill small weeds."
|
||||
icon = 'icons/obj/hydroponics/equipment.dmi'
|
||||
name = "weed spray"
|
||||
icon_state = "weedspray"
|
||||
inhand_icon_state = "spraycan"
|
||||
lefthand_file = 'icons/mob/inhands/equipment/hydroponics_lefthand.dmi'
|
||||
righthand_file = 'icons/mob/inhands/equipment/hydroponics_righthand.dmi'
|
||||
volume = 100
|
||||
list_reagents = list(/datum/reagent/toxin/plantbgone/weedkiller = 100)
|
||||
|
||||
/obj/item/reagent_containers/spray/weedspray/suicide_act(mob/user)
|
||||
user.visible_message("<span class='suicide'>[user] is huffing [src]! It looks like [user.p_theyre()] trying to commit suicide!</span>")
|
||||
return (TOXLOSS)
|
||||
|
||||
/obj/item/reagent_containers/spray/pestspray // -- Skie
|
||||
desc = "It's some pest eliminator spray! <I>Do not inhale!</I>"
|
||||
icon = 'icons/obj/hydroponics/equipment.dmi'
|
||||
name = "pest spray"
|
||||
icon_state = "pestspray"
|
||||
inhand_icon_state = "plantbgone"
|
||||
lefthand_file = 'icons/mob/inhands/equipment/hydroponics_lefthand.dmi'
|
||||
righthand_file = 'icons/mob/inhands/equipment/hydroponics_righthand.dmi'
|
||||
volume = 100
|
||||
list_reagents = list(/datum/reagent/toxin/pestkiller = 100)
|
||||
|
||||
/obj/item/reagent_containers/spray/pestspray/suicide_act(mob/user)
|
||||
user.visible_message("<span class='suicide'>[user] is huffing [src]! It looks like [user.p_theyre()] trying to commit suicide!</span>")
|
||||
return (TOXLOSS)
|
||||
|
||||
/obj/item/cultivator
|
||||
name = "cultivator"
|
||||
desc = "It's used for removing weeds or scratching your back."
|
||||
icon = 'icons/obj/items_and_weapons.dmi'
|
||||
icon_state = "cultivator"
|
||||
inhand_icon_state = "cultivator"
|
||||
lefthand_file = 'icons/mob/inhands/equipment/hydroponics_lefthand.dmi'
|
||||
righthand_file = 'icons/mob/inhands/equipment/hydroponics_righthand.dmi'
|
||||
flags_1 = CONDUCT_1
|
||||
force = 5
|
||||
throwforce = 7
|
||||
w_class = WEIGHT_CLASS_SMALL
|
||||
custom_materials = list(/datum/material/iron=50)
|
||||
attack_verb = list("slashed", "sliced", "cut", "clawed")
|
||||
hitsound = 'sound/weapons/bladeslice.ogg'
|
||||
|
||||
/obj/item/cultivator/suicide_act(mob/user)
|
||||
user.visible_message("<span class='suicide'>[user] is scratching [user.p_their()] back as hard as [user.p_they()] can with \the [src]! It looks like [user.p_theyre()] trying to commit suicide!</span>")
|
||||
return (BRUTELOSS)
|
||||
|
||||
/obj/item/cultivator/rake
|
||||
name = "rake"
|
||||
icon_state = "rake"
|
||||
w_class = WEIGHT_CLASS_NORMAL
|
||||
attack_verb = list("slashed", "sliced", "bashed", "clawed")
|
||||
hitsound = null
|
||||
custom_materials = list(/datum/material/wood = MINERAL_MATERIAL_AMOUNT * 1.5)
|
||||
flags_1 = NONE
|
||||
resistance_flags = FLAMMABLE
|
||||
|
||||
/obj/item/cultivator/rake/Crossed(atom/movable/AM)
|
||||
. = ..()
|
||||
if(!ishuman(AM))
|
||||
return
|
||||
var/mob/living/carbon/human/H = AM
|
||||
if(has_gravity(loc) && HAS_TRAIT(H, TRAIT_CLUMSY) && !H.resting)
|
||||
H.confused = max(H.confused, 10)
|
||||
H.Stun(20)
|
||||
playsound(src, 'sound/weapons/punch4.ogg', 50, TRUE)
|
||||
H.visible_message("<span class='warning'>[H] steps on [src] causing the handle to hit [H.p_them()] right in the face!</span>", \
|
||||
"<span class='userdanger'>You step on [src] causing the handle to hit you right in the face!</span>")
|
||||
|
||||
/obj/item/hatchet
|
||||
name = "hatchet"
|
||||
desc = "A very sharp axe blade upon a short fibremetal handle. It has a long history of chopping things, but now it is used for chopping wood."
|
||||
icon = 'icons/obj/items_and_weapons.dmi'
|
||||
icon_state = "hatchet"
|
||||
inhand_icon_state = "hatchet"
|
||||
lefthand_file = 'icons/mob/inhands/equipment/hydroponics_lefthand.dmi'
|
||||
righthand_file = 'icons/mob/inhands/equipment/hydroponics_righthand.dmi'
|
||||
flags_1 = CONDUCT_1
|
||||
force = 12
|
||||
w_class = WEIGHT_CLASS_SMALL
|
||||
throwforce = 15
|
||||
throw_speed = 3
|
||||
throw_range = 4
|
||||
custom_materials = list(/datum/material/iron = 15000)
|
||||
attack_verb = list("chopped", "tore", "lacerated", "cut")
|
||||
hitsound = 'sound/weapons/bladeslice.ogg'
|
||||
sharpness = IS_SHARP
|
||||
|
||||
/obj/item/hatchet/Initialize()
|
||||
. = ..()
|
||||
AddComponent(/datum/component/butchering, 70, 100)
|
||||
|
||||
/obj/item/hatchet/suicide_act(mob/user)
|
||||
user.visible_message("<span class='suicide'>[user] is chopping at [user.p_them()]self with [src]! It looks like [user.p_theyre()] trying to commit suicide!</span>")
|
||||
playsound(src, 'sound/weapons/bladeslice.ogg', 50, TRUE, -1)
|
||||
return (BRUTELOSS)
|
||||
|
||||
/obj/item/hatchet/wooden
|
||||
desc = "A crude axe blade upon a short wooden handle."
|
||||
icon_state = "woodhatchet"
|
||||
custom_materials = null
|
||||
flags_1 = NONE
|
||||
|
||||
/obj/item/scythe
|
||||
icon_state = "scythe0"
|
||||
lefthand_file = 'icons/mob/inhands/weapons/polearms_lefthand.dmi'
|
||||
righthand_file = 'icons/mob/inhands/weapons/polearms_righthand.dmi'
|
||||
name = "scythe"
|
||||
desc = "A sharp and curved blade on a long fibremetal handle, this tool makes it easy to reap what you sow."
|
||||
force = 13
|
||||
throwforce = 5
|
||||
throw_speed = 2
|
||||
throw_range = 3
|
||||
w_class = WEIGHT_CLASS_BULKY
|
||||
flags_1 = CONDUCT_1
|
||||
armour_penetration = 20
|
||||
slot_flags = ITEM_SLOT_BACK
|
||||
attack_verb = list("chopped", "sliced", "cut", "reaped")
|
||||
hitsound = 'sound/weapons/bladeslice.ogg'
|
||||
var/swiping = FALSE
|
||||
|
||||
/obj/item/scythe/Initialize()
|
||||
. = ..()
|
||||
AddComponent(/datum/component/butchering, 90, 105)
|
||||
|
||||
/obj/item/scythe/suicide_act(mob/user)
|
||||
user.visible_message("<span class='suicide'>[user] is beheading [user.p_them()]self with [src]! It looks like [user.p_theyre()] trying to commit suicide!</span>")
|
||||
if(iscarbon(user))
|
||||
var/mob/living/carbon/C = user
|
||||
var/obj/item/bodypart/BP = C.get_bodypart(BODY_ZONE_HEAD)
|
||||
if(BP)
|
||||
BP.drop_limb()
|
||||
playsound(src, "desecration" ,50, TRUE, -1)
|
||||
return (BRUTELOSS)
|
||||
|
||||
/obj/item/scythe/pre_attack(atom/A, mob/living/user, params)
|
||||
if(swiping || !istype(A, /obj/structure/spacevine) || get_turf(A) == get_turf(user))
|
||||
return ..()
|
||||
var/turf/user_turf = get_turf(user)
|
||||
var/dir_to_target = get_dir(user_turf, get_turf(A))
|
||||
swiping = TRUE
|
||||
var/static/list/scythe_slash_angles = list(0, 45, 90, -45, -90)
|
||||
for(var/i in scythe_slash_angles)
|
||||
var/turf/T = get_step(user_turf, turn(dir_to_target, i))
|
||||
for(var/obj/structure/spacevine/V in T)
|
||||
if(user.Adjacent(V))
|
||||
melee_attack_chain(user, V)
|
||||
swiping = FALSE
|
||||
return TRUE
|
||||
|
||||
/obj/item/secateurs
|
||||
name = "secateurs"
|
||||
desc = "It's a tool for cutting grafts off plants."
|
||||
icon = 'icons/obj/hydroponics/equipment.dmi'
|
||||
icon_state = "secateurs"
|
||||
inhand_icon_state = "secateurs"
|
||||
lefthand_file = 'icons/mob/inhands/equipment/hydroponics_lefthand.dmi'
|
||||
righthand_file = 'icons/mob/inhands/equipment/hydroponics_righthand.dmi'
|
||||
flags_1 = CONDUCT_1
|
||||
force = 5
|
||||
throwforce = 6
|
||||
w_class = WEIGHT_CLASS_SMALL
|
||||
slot_flags = ITEM_SLOT_BELT
|
||||
custom_materials = list(/datum/material/iron=4000)
|
||||
attack_verb = list("slashed", "sliced", "cut", "clawed")
|
||||
hitsound = 'sound/weapons/bladeslice.ogg'
|
||||
|
||||
/obj/item/geneshears
|
||||
name = "Botanogenetic Plant Shears"
|
||||
desc = "A high tech, high fidelity pair of plant shears, capable of cutting genetic traits out of a plant."
|
||||
icon = 'icons/obj/hydroponics/equipment.dmi'
|
||||
icon_state = "genesheers"
|
||||
inhand_icon_state = "secateurs"
|
||||
lefthand_file = 'icons/mob/inhands/equipment/hydroponics_lefthand.dmi'
|
||||
righthand_file = 'icons/mob/inhands/equipment/hydroponics_righthand.dmi'
|
||||
flags_1 = CONDUCT_1
|
||||
force = 10
|
||||
throwforce = 8
|
||||
w_class = WEIGHT_CLASS_SMALL
|
||||
slot_flags = ITEM_SLOT_BELT
|
||||
material_flags = MATERIAL_NO_EFFECTS
|
||||
custom_materials = list(/datum/material/iron=4000, /datum/material/uranium=1500, /datum/material/gold=500)
|
||||
attack_verb = list("slashed", "sliced", "cut")
|
||||
hitsound = 'sound/weapons/bladeslice.ogg'
|
||||
|
||||
|
||||
// *************************************
|
||||
// Nutrient defines for hydroponics
|
||||
// *************************************
|
||||
|
||||
|
||||
/obj/item/reagent_containers/glass/bottle/nutrient
|
||||
name = "bottle of nutrient"
|
||||
volume = 50
|
||||
amount_per_transfer_from_this = 10
|
||||
possible_transfer_amounts = list(1,2,5,10,15,25,50)
|
||||
|
||||
/obj/item/reagent_containers/glass/bottle/nutrient/Initialize()
|
||||
. = ..()
|
||||
pixel_x = rand(-5, 5)
|
||||
pixel_y = rand(-5, 5)
|
||||
|
||||
|
||||
/obj/item/reagent_containers/glass/bottle/nutrient/ez
|
||||
name = "bottle of E-Z-Nutrient"
|
||||
desc = "Contains a fertilizer that causes mild mutations and gradual plant growth with each harvest."
|
||||
list_reagents = list(/datum/reagent/plantnutriment/eznutriment = 50)
|
||||
|
||||
/obj/item/reagent_containers/glass/bottle/nutrient/l4z
|
||||
name = "bottle of Left 4 Zed"
|
||||
desc = "Contains a fertilizer that lightly heals the plant but causes significant mutations in plants over generations."
|
||||
list_reagents = list(/datum/reagent/plantnutriment/left4zednutriment = 50)
|
||||
|
||||
/obj/item/reagent_containers/glass/bottle/nutrient/rh
|
||||
name = "bottle of Robust Harvest"
|
||||
desc = "Contains a fertilizer that increases the yield of a plant while gradually preventing mutations."
|
||||
list_reagents = list(/datum/reagent/plantnutriment/robustharvestnutriment = 50)
|
||||
|
||||
/obj/item/reagent_containers/glass/bottle/nutrient/empty
|
||||
name = "bottle"
|
||||
|
||||
/obj/item/reagent_containers/glass/bottle/killer
|
||||
volume = 30
|
||||
amount_per_transfer_from_this = 1
|
||||
possible_transfer_amounts = list(1,2,5)
|
||||
|
||||
/obj/item/reagent_containers/glass/bottle/killer/weedkiller
|
||||
name = "bottle of weed killer"
|
||||
desc = "Contains a herbicide."
|
||||
list_reagents = list(/datum/reagent/toxin/plantbgone/weedkiller = 30)
|
||||
|
||||
/obj/item/reagent_containers/glass/bottle/killer/pestkiller
|
||||
name = "bottle of pest spray"
|
||||
desc = "Contains a pesticide."
|
||||
list_reagents = list(/datum/reagent/toxin/pestkiller = 30)
|
||||
|
||||
File diff suppressed because it is too large
Load Diff
@@ -1,199 +1,199 @@
|
||||
/**
|
||||
* Finds and extracts seeds from an object
|
||||
*
|
||||
* Checks if the object is such that creates a seed when extracted. Used by seed
|
||||
* extractors or posably anything that would create seeds in some way. The seeds
|
||||
* are dropped either at the extractor, if it exists, or where the original object
|
||||
* was and it qdel's the object
|
||||
*
|
||||
* Arguments:
|
||||
* * O - Object containing the seed, can be the loc of the dumping of seeds
|
||||
* * t_max - Amount of seed copies to dump, -1 is ranomized
|
||||
* * extractor - Seed Extractor, used as the dumping loc for the seeds and seed multiplier
|
||||
* * user - checks if we can remove the object from the inventory
|
||||
* *
|
||||
*/
|
||||
/proc/seedify(obj/item/O, t_max, obj/machinery/seed_extractor/extractor, mob/living/user)
|
||||
var/t_amount = 0
|
||||
var/list/seeds = list()
|
||||
if(t_max == -1)
|
||||
if(extractor)
|
||||
t_max = rand(1,4) * extractor.seed_multiplier
|
||||
else
|
||||
t_max = rand(1,4)
|
||||
|
||||
var/seedloc = O.loc
|
||||
if(extractor)
|
||||
seedloc = extractor.loc
|
||||
|
||||
if(istype(O, /obj/item/reagent_containers/food/snacks/grown/))
|
||||
var/obj/item/reagent_containers/food/snacks/grown/F = O
|
||||
if(F.seed)
|
||||
if(user && !user.temporarilyRemoveItemFromInventory(O)) //couldn't drop the item
|
||||
return
|
||||
while(t_amount < t_max)
|
||||
var/obj/item/seeds/t_prod = F.seed.Copy()
|
||||
seeds.Add(t_prod)
|
||||
t_prod.forceMove(seedloc)
|
||||
t_amount++
|
||||
qdel(O)
|
||||
return seeds
|
||||
|
||||
else if(istype(O, /obj/item/grown))
|
||||
var/obj/item/grown/F = O
|
||||
if(F.seed)
|
||||
if(user && !user.temporarilyRemoveItemFromInventory(O))
|
||||
return
|
||||
while(t_amount < t_max)
|
||||
var/obj/item/seeds/t_prod = F.seed.Copy()
|
||||
t_prod.forceMove(seedloc)
|
||||
t_amount++
|
||||
qdel(O)
|
||||
return 1
|
||||
|
||||
return 0
|
||||
|
||||
|
||||
/obj/machinery/seed_extractor
|
||||
name = "seed extractor"
|
||||
desc = "Extracts and bags seeds from produce."
|
||||
icon = 'icons/obj/hydroponics/equipment.dmi'
|
||||
icon_state = "sextractor"
|
||||
density = TRUE
|
||||
circuit = /obj/item/circuitboard/machine/seed_extractor
|
||||
/// Associated list of seeds, they are all weak refs. We check the len to see how many refs we have for each
|
||||
// seed
|
||||
var/list/piles = list()
|
||||
var/max_seeds = 1000
|
||||
var/seed_multiplier = 1
|
||||
ui_x = 1000
|
||||
ui_y = 400
|
||||
|
||||
/obj/machinery/seed_extractor/RefreshParts()
|
||||
for(var/obj/item/stock_parts/matter_bin/B in component_parts)
|
||||
max_seeds = initial(max_seeds) * B.rating
|
||||
for(var/obj/item/stock_parts/manipulator/M in component_parts)
|
||||
seed_multiplier = initial(seed_multiplier) * M.rating
|
||||
|
||||
/obj/machinery/seed_extractor/examine(mob/user)
|
||||
. = ..()
|
||||
if(in_range(user, src) || isobserver(user))
|
||||
. += "<span class='notice'>The status display reads: Extracting <b>[seed_multiplier]</b> seed(s) per piece of produce.<br>Machine can store up to <b>[max_seeds]%</b> seeds.</span>"
|
||||
|
||||
/obj/machinery/seed_extractor/attackby(obj/item/O, mob/user, params)
|
||||
|
||||
if(default_deconstruction_screwdriver(user, "sextractor_open", "sextractor", O))
|
||||
return
|
||||
|
||||
if(default_pry_open(O))
|
||||
return
|
||||
|
||||
if(default_unfasten_wrench(user, O))
|
||||
return
|
||||
|
||||
if(default_deconstruction_crowbar(O))
|
||||
return
|
||||
|
||||
if(istype(O, /obj/item/storage/bag/plants))
|
||||
var/obj/item/storage/P = O
|
||||
var/loaded = 0
|
||||
for(var/obj/item/seeds/G in P.contents)
|
||||
if(contents.len >= max_seeds)
|
||||
break
|
||||
++loaded
|
||||
add_seed(G)
|
||||
if (loaded)
|
||||
to_chat(user, "<span class='notice'>You put as many seeds from \the [O.name] into [src] as you can.</span>")
|
||||
else
|
||||
to_chat(user, "<span class='notice'>There are no seeds in \the [O.name].</span>")
|
||||
return
|
||||
|
||||
else if(seedify(O,-1, src, user))
|
||||
to_chat(user, "<span class='notice'>You extract some seeds.</span>")
|
||||
return
|
||||
else if (istype(O, /obj/item/seeds))
|
||||
if(add_seed(O))
|
||||
to_chat(user, "<span class='notice'>You add [O] to [src.name].</span>")
|
||||
updateUsrDialog()
|
||||
return
|
||||
else if(user.a_intent != INTENT_HARM)
|
||||
to_chat(user, "<span class='warning'>You can't extract any seeds from \the [O.name]!</span>")
|
||||
else
|
||||
return ..()
|
||||
|
||||
/**
|
||||
* Generate seed string
|
||||
*
|
||||
* Creates a string based of the traits of a seed. We use this string as a bucket for all
|
||||
* seeds that match as well as the key the ui uses to get the seed. We also use the key
|
||||
* for the data shown in the ui. Javascript parses this string to display
|
||||
*
|
||||
* Arguments:
|
||||
* * O - seed to generate the string from
|
||||
*/
|
||||
/obj/machinery/seed_extractor/proc/generate_seed_string(obj/item/seeds/O)
|
||||
return "name=[O.name];lifespan=[O.lifespan];endurance=[O.endurance];maturation=[O.maturation];production=[O.production];yield=[O.yield];potency=[O.potency];instability=[O.instability]"
|
||||
|
||||
|
||||
/** Add Seeds Proc.
|
||||
*
|
||||
* Adds the seeds to the contents and to an associated list that pregenerates the data
|
||||
* needed to go to the ui handler
|
||||
*
|
||||
**/
|
||||
/obj/machinery/seed_extractor/proc/add_seed(obj/item/seeds/O)
|
||||
if(contents.len >= 999)
|
||||
to_chat(usr, "<span class='notice'>\The [src] is full.</span>")
|
||||
return FALSE
|
||||
|
||||
var/datum/component/storage/STR = O.loc.GetComponent(/datum/component/storage)
|
||||
if(STR)
|
||||
if(!STR.remove_from_storage(O,src))
|
||||
return FALSE
|
||||
else if(ismob(O.loc))
|
||||
var/mob/M = O.loc
|
||||
if(!M.transferItemToLoc(O, src))
|
||||
return FALSE
|
||||
|
||||
var/seed_string = generate_seed_string(O)
|
||||
if(piles[seed_string])
|
||||
piles[seed_string] += WEAKREF(O)
|
||||
else
|
||||
piles[seed_string] = list(WEAKREF(O))
|
||||
|
||||
. = TRUE
|
||||
|
||||
/obj/machinery/seed_extractor/ui_interact(mob/user, ui_key = "main", datum/tgui/ui = null, force_open = FALSE, \
|
||||
datum/tgui/master_ui = null, datum/ui_state/state = GLOB.notcontained_state)
|
||||
ui = SStgui.try_update_ui(user, src, ui_key, ui, force_open)
|
||||
if(!ui)
|
||||
ui = new(user, src, ui_key, "SeedExtractor", name, ui_x, ui_y, master_ui, state)
|
||||
ui.open()
|
||||
|
||||
/obj/machinery/seed_extractor/ui_data()
|
||||
var/list/V = list()
|
||||
for(var/key in piles)
|
||||
if(piles[key])
|
||||
var/len = length(piles[key])
|
||||
if(len)
|
||||
V[key] = len
|
||||
|
||||
. = list()
|
||||
.["seeds"] = V
|
||||
|
||||
/obj/machinery/seed_extractor/ui_act(action, params)
|
||||
if(..())
|
||||
return
|
||||
|
||||
switch(action)
|
||||
if("select")
|
||||
var/item = params["item"]
|
||||
if(piles[item] && length(piles[item]) > 0)
|
||||
var/datum/weakref/WO = piles[item][1]
|
||||
var/obj/item/seeds/O = WO.resolve()
|
||||
if(O)
|
||||
piles[item] -= WO
|
||||
O.forceMove(drop_location())
|
||||
. = TRUE
|
||||
//to_chat(usr, "<span class='notice'>[src] clanks to life briefly before vending [prize.equipment_name]!</span>")
|
||||
|
||||
/**
|
||||
* Finds and extracts seeds from an object
|
||||
*
|
||||
* Checks if the object is such that creates a seed when extracted. Used by seed
|
||||
* extractors or posably anything that would create seeds in some way. The seeds
|
||||
* are dropped either at the extractor, if it exists, or where the original object
|
||||
* was and it qdel's the object
|
||||
*
|
||||
* Arguments:
|
||||
* * O - Object containing the seed, can be the loc of the dumping of seeds
|
||||
* * t_max - Amount of seed copies to dump, -1 is ranomized
|
||||
* * extractor - Seed Extractor, used as the dumping loc for the seeds and seed multiplier
|
||||
* * user - checks if we can remove the object from the inventory
|
||||
* *
|
||||
*/
|
||||
/proc/seedify(obj/item/O, t_max, obj/machinery/seed_extractor/extractor, mob/living/user)
|
||||
var/t_amount = 0
|
||||
var/list/seeds = list()
|
||||
if(t_max == -1)
|
||||
if(extractor)
|
||||
t_max = rand(1,4) * extractor.seed_multiplier
|
||||
else
|
||||
t_max = rand(1,4)
|
||||
|
||||
var/seedloc = O.loc
|
||||
if(extractor)
|
||||
seedloc = extractor.loc
|
||||
|
||||
if(istype(O, /obj/item/reagent_containers/food/snacks/grown/))
|
||||
var/obj/item/reagent_containers/food/snacks/grown/F = O
|
||||
if(F.seed)
|
||||
if(user && !user.temporarilyRemoveItemFromInventory(O)) //couldn't drop the item
|
||||
return
|
||||
while(t_amount < t_max)
|
||||
var/obj/item/seeds/t_prod = F.seed.Copy()
|
||||
seeds.Add(t_prod)
|
||||
t_prod.forceMove(seedloc)
|
||||
t_amount++
|
||||
qdel(O)
|
||||
return seeds
|
||||
|
||||
else if(istype(O, /obj/item/grown))
|
||||
var/obj/item/grown/F = O
|
||||
if(F.seed)
|
||||
if(user && !user.temporarilyRemoveItemFromInventory(O))
|
||||
return
|
||||
while(t_amount < t_max)
|
||||
var/obj/item/seeds/t_prod = F.seed.Copy()
|
||||
t_prod.forceMove(seedloc)
|
||||
t_amount++
|
||||
qdel(O)
|
||||
return 1
|
||||
|
||||
return 0
|
||||
|
||||
|
||||
/obj/machinery/seed_extractor
|
||||
name = "seed extractor"
|
||||
desc = "Extracts and bags seeds from produce."
|
||||
icon = 'icons/obj/hydroponics/equipment.dmi'
|
||||
icon_state = "sextractor"
|
||||
density = TRUE
|
||||
circuit = /obj/item/circuitboard/machine/seed_extractor
|
||||
/// Associated list of seeds, they are all weak refs. We check the len to see how many refs we have for each
|
||||
// seed
|
||||
var/list/piles = list()
|
||||
var/max_seeds = 1000
|
||||
var/seed_multiplier = 1
|
||||
ui_x = 1000
|
||||
ui_y = 400
|
||||
|
||||
/obj/machinery/seed_extractor/RefreshParts()
|
||||
for(var/obj/item/stock_parts/matter_bin/B in component_parts)
|
||||
max_seeds = initial(max_seeds) * B.rating
|
||||
for(var/obj/item/stock_parts/manipulator/M in component_parts)
|
||||
seed_multiplier = initial(seed_multiplier) * M.rating
|
||||
|
||||
/obj/machinery/seed_extractor/examine(mob/user)
|
||||
. = ..()
|
||||
if(in_range(user, src) || isobserver(user))
|
||||
. += "<span class='notice'>The status display reads: Extracting <b>[seed_multiplier]</b> seed(s) per piece of produce.<br>Machine can store up to <b>[max_seeds]%</b> seeds.</span>"
|
||||
|
||||
/obj/machinery/seed_extractor/attackby(obj/item/O, mob/user, params)
|
||||
|
||||
if(default_deconstruction_screwdriver(user, "sextractor_open", "sextractor", O))
|
||||
return
|
||||
|
||||
if(default_pry_open(O))
|
||||
return
|
||||
|
||||
if(default_unfasten_wrench(user, O))
|
||||
return
|
||||
|
||||
if(default_deconstruction_crowbar(O))
|
||||
return
|
||||
|
||||
if(istype(O, /obj/item/storage/bag/plants))
|
||||
var/obj/item/storage/P = O
|
||||
var/loaded = 0
|
||||
for(var/obj/item/seeds/G in P.contents)
|
||||
if(contents.len >= max_seeds)
|
||||
break
|
||||
++loaded
|
||||
add_seed(G)
|
||||
if (loaded)
|
||||
to_chat(user, "<span class='notice'>You put as many seeds from \the [O.name] into [src] as you can.</span>")
|
||||
else
|
||||
to_chat(user, "<span class='notice'>There are no seeds in \the [O.name].</span>")
|
||||
return
|
||||
|
||||
else if(seedify(O,-1, src, user))
|
||||
to_chat(user, "<span class='notice'>You extract some seeds.</span>")
|
||||
return
|
||||
else if (istype(O, /obj/item/seeds))
|
||||
if(add_seed(O))
|
||||
to_chat(user, "<span class='notice'>You add [O] to [src.name].</span>")
|
||||
updateUsrDialog()
|
||||
return
|
||||
else if(user.a_intent != INTENT_HARM)
|
||||
to_chat(user, "<span class='warning'>You can't extract any seeds from \the [O.name]!</span>")
|
||||
else
|
||||
return ..()
|
||||
|
||||
/**
|
||||
* Generate seed string
|
||||
*
|
||||
* Creates a string based of the traits of a seed. We use this string as a bucket for all
|
||||
* seeds that match as well as the key the ui uses to get the seed. We also use the key
|
||||
* for the data shown in the ui. Javascript parses this string to display
|
||||
*
|
||||
* Arguments:
|
||||
* * O - seed to generate the string from
|
||||
*/
|
||||
/obj/machinery/seed_extractor/proc/generate_seed_string(obj/item/seeds/O)
|
||||
return "name=[O.name];lifespan=[O.lifespan];endurance=[O.endurance];maturation=[O.maturation];production=[O.production];yield=[O.yield];potency=[O.potency];instability=[O.instability]"
|
||||
|
||||
|
||||
/** Add Seeds Proc.
|
||||
*
|
||||
* Adds the seeds to the contents and to an associated list that pregenerates the data
|
||||
* needed to go to the ui handler
|
||||
*
|
||||
**/
|
||||
/obj/machinery/seed_extractor/proc/add_seed(obj/item/seeds/O)
|
||||
if(contents.len >= 999)
|
||||
to_chat(usr, "<span class='notice'>\The [src] is full.</span>")
|
||||
return FALSE
|
||||
|
||||
var/datum/component/storage/STR = O.loc.GetComponent(/datum/component/storage)
|
||||
if(STR)
|
||||
if(!STR.remove_from_storage(O,src))
|
||||
return FALSE
|
||||
else if(ismob(O.loc))
|
||||
var/mob/M = O.loc
|
||||
if(!M.transferItemToLoc(O, src))
|
||||
return FALSE
|
||||
|
||||
var/seed_string = generate_seed_string(O)
|
||||
if(piles[seed_string])
|
||||
piles[seed_string] += WEAKREF(O)
|
||||
else
|
||||
piles[seed_string] = list(WEAKREF(O))
|
||||
|
||||
. = TRUE
|
||||
|
||||
/obj/machinery/seed_extractor/ui_interact(mob/user, ui_key = "main", datum/tgui/ui = null, force_open = FALSE, \
|
||||
datum/tgui/master_ui = null, datum/ui_state/state = GLOB.notcontained_state)
|
||||
ui = SStgui.try_update_ui(user, src, ui_key, ui, force_open)
|
||||
if(!ui)
|
||||
ui = new(user, src, ui_key, "SeedExtractor", name, ui_x, ui_y, master_ui, state)
|
||||
ui.open()
|
||||
|
||||
/obj/machinery/seed_extractor/ui_data()
|
||||
var/list/V = list()
|
||||
for(var/key in piles)
|
||||
if(piles[key])
|
||||
var/len = length(piles[key])
|
||||
if(len)
|
||||
V[key] = len
|
||||
|
||||
. = list()
|
||||
.["seeds"] = V
|
||||
|
||||
/obj/machinery/seed_extractor/ui_act(action, params)
|
||||
if(..())
|
||||
return
|
||||
|
||||
switch(action)
|
||||
if("select")
|
||||
var/item = params["item"]
|
||||
if(piles[item] && length(piles[item]) > 0)
|
||||
var/datum/weakref/WO = piles[item][1]
|
||||
var/obj/item/seeds/O = WO.resolve()
|
||||
if(O)
|
||||
piles[item] -= WO
|
||||
O.forceMove(drop_location())
|
||||
. = TRUE
|
||||
//to_chat(usr, "<span class='notice'>[src] clanks to life briefly before vending [prize.equipment_name]!</span>")
|
||||
|
||||
|
||||
+624
-624
File diff suppressed because it is too large
Load Diff
Reference in New Issue
Block a user