diff --git a/code/controllers/subsystem/job.dm b/code/controllers/subsystem/job.dm index 88c19401..6aea7611 100644 --- a/code/controllers/subsystem/job.dm +++ b/code/controllers/subsystem/job.dm @@ -454,7 +454,9 @@ SUBSYSTEM_DEF(job) to_chat(M, "[job.custom_spawn_text]") if(CONFIG_GET(number/minimal_access_threshold)) to_chat(M, "As this station was initially staffed with a [CONFIG_GET(flag/jobs_have_minimal_access) ? "full crew, only your job's necessities" : "skeleton crew, additional access may"] have been added to your ID card.") - + + job.after_spawn(H, M, joined_late) + //Account ID. ID is handled by human initialization if(ishuman(H)) var/mob/living/carbon/human/wageslave = H diff --git a/code/modules/atmospherics/machinery/other/meter.dm b/code/modules/atmospherics/machinery/other/meter.dm index 9870a895..37081453 100644 --- a/code/modules/atmospherics/machinery/other/meter.dm +++ b/code/modules/atmospherics/machinery/other/meter.dm @@ -134,6 +134,9 @@ else to_chat(user, status()) +/obj/machinery/meter/attack_ghost(mob/user) + to_chat(user, status()) + /obj/machinery/meter/singularity_pull(S, current_size) ..() if(current_size >= STAGE_FIVE) @@ -141,6 +144,7 @@ // TURF METER - REPORTS A TILE'S AIR CONTENTS // why are you yelling? +// i hope they aren't mad /obj/machinery/meter/turf /obj/machinery/meter/turf/reattach_to_layer() diff --git a/code/modules/atmospherics/machinery/portable/canister.dm b/code/modules/atmospherics/machinery/portable/canister.dm index a0e3dd38..afd1e918 100644 --- a/code/modules/atmospherics/machinery/portable/canister.dm +++ b/code/modules/atmospherics/machinery/portable/canister.dm @@ -377,6 +377,17 @@ air_update_turf() // Update the environment if needed. update_icon() +/obj/machinery/portable_atmospherics/canister/attack_ghost(mob/user) + if(user.client) + if(IsAdminGhost(user)) + attack_ai(user) + return FALSE + else if(user.client.prefs.inquisitive_ghost) + user.examinate(src) + return FALSE + atmosanalyzer_scan(air_contents, user, src, FALSE) + return FALSE + /obj/machinery/portable_atmospherics/canister/ui_interact(mob/user, ui_key = "main", datum/tgui/ui = null, force_open = FALSE, \ datum/tgui/master_ui = null, datum/ui_state/state = GLOB.physical_state) ui = SStgui.try_update_ui(user, src, ui_key, ui, force_open) diff --git a/code/modules/food_and_drinks/kitchen_machinery/gibber.dm b/code/modules/food_and_drinks/kitchen_machinery/gibber.dm index e5c5a4f9..b76beaa5 100644 --- a/code/modules/food_and_drinks/kitchen_machinery/gibber.dm +++ b/code/modules/food_and_drinks/kitchen_machinery/gibber.dm @@ -23,7 +23,7 @@ /obj/machinery/gibber/RefreshParts() var/gib_time = 40 for(var/obj/item/stock_parts/matter_bin/B in component_parts) - meat_produced += B.rating + meat_produced += 1.6 * B.rating for(var/obj/item/stock_parts/manipulator/M in component_parts) gib_time -= 5 * M.rating gibtime = gib_time diff --git a/code/modules/food_and_drinks/kitchen_machinery/monkeyrecycler.dm b/code/modules/food_and_drinks/kitchen_machinery/monkeyrecycler.dm index c25cb228..789c54f7 100644 --- a/code/modules/food_and_drinks/kitchen_machinery/monkeyrecycler.dm +++ b/code/modules/food_and_drinks/kitchen_machinery/monkeyrecycler.dm @@ -1,6 +1,8 @@ +GLOBAL_LIST_EMPTY(monkey_recyclers) + /obj/machinery/monkey_recycler name = "monkey recycler" - desc = "A machine used for recycling dead monkeys into monkey cubes. It currently produces 1 cube for every 5 monkeys inserted." // except it literally never does + desc = "A machine used for recycling dead monkeys into monkey cubes. You can use a multitool to link it to a xenobiology console. It currently produces 0.2 cubes for every monkey inserted." icon = 'icons/obj/kitchen.dmi' icon_state = "grinder" layer = BELOW_OBJ_LAYER @@ -9,20 +11,29 @@ idle_power_usage = 5 active_power_usage = 50 circuit = /obj/item/circuitboard/machine/monkey_recycler - var/grinded = 0 - var/required_grind = 5 - var/cube_production = 1 + var/stored_matter = 0 + var/cube_production = 0.2 + var/list/connected = list() //Xenobio consoles + +/obj/machinery/monkey_recycler/Initialize(mapload) + . = ..() + GLOB.monkey_recyclers += src -/obj/machinery/monkey_recycler/RefreshParts() - var/req_grind = 5 - var/cubes_made = 1 +/obj/machinery/monkey_recycler/Destroy() + if(src in GLOB.monkey_recyclers) + GLOB.monkey_recyclers -= src + for(var/obj/machinery/computer/camera_advanced/xenobio/C in connected) + var/obj/machinery/computer/camera_advanced/xenobio/console = C + console.connected_recycler = null + return ..() + +/obj/machinery/monkey_recycler/RefreshParts() //Ranges from 0.2 to 0.8 per monkey recycled + cube_production = 0 for(var/obj/item/stock_parts/manipulator/B in component_parts) - req_grind -= B.rating + cube_production += B.rating * 0.1 for(var/obj/item/stock_parts/matter_bin/M in component_parts) - cubes_made = M.rating - cube_production = cubes_made - required_grind = req_grind - src.desc = "A machine used for recycling dead monkeys into monkey cubes. It currently produces [cubes_made] cube(s) for every [required_grind] monkey(s) inserted." + cube_production += M.rating * 0.1 + desc = "A machine used for recycling dead monkeys into monkey cubes. You can use a multitool to link it to a xenobiology console. It currently produces [cube_production] cubes for every monkey inserted." /obj/machinery/monkey_recycler/attackby(obj/item/O, mob/user, params) if(default_deconstruction_screwdriver(user, "grinder_open", "grinder", O)) @@ -64,17 +75,22 @@ var/offset = prob(50) ? -2 : 2 animate(src, pixel_x = pixel_x + offset, time = 0.2, loop = 200) //start shaking use_power(500) - grinded++ + stored_matter += cube_production addtimer(VARSET_CALLBACK(src, pixel_x, initial(pixel_x))) - addtimer(CALLBACK(GLOBAL_PROC, /proc/to_chat, user, "The machine now has [grinded] monkey\s worth of material stored.")) + addtimer(CALLBACK(GLOBAL_PROC, /proc/to_chat, user, "The machine now has [stored_matter] monkey\s worth of material stored.")) /obj/machinery/monkey_recycler/interact(mob/user) - if(grinded >= required_grind) - to_chat(user, "The machine hisses loudly as it condenses the grinded monkey meat. After a moment, it dispenses a brand new monkey cube.") + if(stored_matter >= 1) + to_chat(user, "The machine hisses loudly as it condenses the ground monkey meat. After a moment, it dispenses a brand new monkey cube.") playsound(src.loc, 'sound/machines/hiss.ogg', 50, 1) - grinded -= required_grind - for(var/i = 0, i < cube_production, i++) - new /obj/item/reagent_containers/food/snacks/monkeycube(src.loc) - to_chat(user, "The machine's display flashes that it has [grinded] monkeys worth of material left.") + for(var/i in 1 to max(stored_matter, 1)) + new /obj/item/reagent_containers/food/snacks/monkeycube(loc) + to_chat(user, "The machine's display flashes that it has [stored_matter] monkeys worth of material left.") else - to_chat(user, "The machine needs at least [required_grind] monkey(s) worth of material to produce a monkey cube. It only has [grinded].") + to_chat(user, "The machine needs at least 1 monkey worth of material to produce a monkey cube. It currently has [stored_matter].") + +/obj/machinery/monkey_recycler/multitool_act(mob/living/user, obj/item/multitool/I) + if(istype(I)) + to_chat(user, "You log [src] in the multitool's buffer.") + I.buffer = src + return TRUE diff --git a/code/modules/holiday/halloween/jacqueen.dm b/code/modules/holiday/halloween/jacqueen.dm index 3cdd4798..5b3b7077 100644 --- a/code/modules/holiday/halloween/jacqueen.dm +++ b/code/modules/holiday/halloween/jacqueen.dm @@ -368,7 +368,7 @@ C.reagents.add_reagent(/datum/reagent/fermi/eigenstate, 30) if(5) visible_message("[src] waves their arms around, \"A new familiar for me, and you'll see it's thee!\"") - C.reagents.add_reagent("secretcatchem", 30) + C.reagents.add_reagent(/datum/reagent/fermi/secretcatchem, 30) if(6) visible_message("[src] waves their arms around, \"While you may not be a ghost, for this sheet you'll always be it's host.\"") var/mob/living/carbon/human/H = C diff --git a/code/modules/jobs/job_types/civilian.dm b/code/modules/jobs/job_types/civilian.dm index feca1a40..7d97858f 100644 --- a/code/modules/jobs/job_types/civilian.dm +++ b/code/modules/jobs/job_types/civilian.dm @@ -18,7 +18,7 @@ Clown minimal_access = list(ACCESS_THEATRE) /datum/job/clown/after_spawn(mob/living/carbon/human/H, mob/M) - . = ..() + ..() H.apply_pref_name("clown", M.client) /datum/outfit/job/clown @@ -83,6 +83,7 @@ Mime minimal_access = list(ACCESS_THEATRE) /datum/job/mime/after_spawn(mob/living/carbon/human/H, mob/M) + ..() H.apply_pref_name("mime", M.client) /datum/outfit/job/mime diff --git a/code/modules/jobs/job_types/job.dm b/code/modules/jobs/job_types/job.dm index d593bfd8..7b4ed75c 100644 --- a/code/modules/jobs/job_types/job.dm +++ b/code/modules/jobs/job_types/job.dm @@ -66,7 +66,7 @@ //Only override this proc //H is usually a human unless an /equip override transformed it /datum/job/proc/after_spawn(mob/living/H, mob/M, latejoin = FALSE) - //do actions on H but send messages to M as the key may not have been transferred_yet + //do actions on H but send messages to M as the key may not have been transferred yet if(mind_traits) for(var/t in mind_traits) ADD_TRAIT(H.mind, t, JOB_TRAIT) diff --git a/code/modules/jobs/job_types/silicon.dm b/code/modules/jobs/job_types/silicon.dm index 31f0c87f..4d0b4d66 100644 --- a/code/modules/jobs/job_types/silicon.dm +++ b/code/modules/jobs/job_types/silicon.dm @@ -21,7 +21,7 @@ AI . = H.AIize(latejoin) /datum/job/ai/after_spawn(mob/H, mob/M, latejoin) - . = ..() + ..() if(latejoin) var/obj/structure/AIcore/latejoin_inactive/lateJoinCore for(var/obj/structure/AIcore/latejoin_inactive/P in GLOB.latejoin_ai_cores) diff --git a/code/modules/mob/living/silicon/robot/robot_modules.dm b/code/modules/mob/living/silicon/robot/robot_modules.dm index f3ee17a4..b842ba42 100644 --- a/code/modules/mob/living/silicon/robot/robot_modules.dm +++ b/code/modules/mob/living/silicon/robot/robot_modules.dm @@ -437,11 +437,11 @@ var/obj/item/reagent_containers/spray/cyborg_drying/CD = locate(/obj/item/reagent_containers/spray/cyborg_drying) in basic_modules if(CD) - CD.reagents.add_reagent("drying_agent", 5 * coeff) + CD.reagents.add_reagent(/datum/reagent/drying_agent, 5 * coeff) var/obj/item/reagent_containers/spray/cyborg_lube/CL = locate(/obj/item/reagent_containers/spray/cyborg_lube) in emag_modules if(CL) - CL.reagents.add_reagent("lube", 2 * coeff) + CL.reagents.add_reagent(/datum/reagent/lube, 2 * coeff) /obj/item/robot_module/clown name = "Clown" diff --git a/code/modules/mob/living/simple_animal/hostile/floor_cluwne.dm b/code/modules/mob/living/simple_animal/hostile/floor_cluwne.dm index 9013468f..459747e0 100644 --- a/code/modules/mob/living/simple_animal/hostile/floor_cluwne.dm +++ b/code/modules/mob/living/simple_animal/hostile/floor_cluwne.dm @@ -316,9 +316,9 @@ GLOBAL_VAR_INIT(floor_cluwnes, 0) to_chat(H, "WHAT THE FUCK IS THAT?!") to_chat(H, ".KNOH !nuf hcum os si uoy htiw gniyalP .KNOH KNOH KNOH") H.playsound_local(src,'sound/hallucinations/im_here1.ogg', 25) - H.reagents.add_reagent("mindbreaker", 3) - H.reagents.add_reagent("laughter", 5) - H.reagents.add_reagent("mercury", 3) + H.reagents.add_reagent(/datum/reagent/toxin/mindbreaker, 3) + H.reagents.add_reagent(/datum/reagent/consumable/laughter, 5) + H.reagents.add_reagent(/datum/reagent/mercury, 3) Appear() manifested = FALSE addtimer(CALLBACK(src, /mob/living/simple_animal/hostile/floor_cluwne/.proc/Manifest), 2) diff --git a/code/modules/pool/pool_main.dm b/code/modules/pool/pool_main.dm index f5ccc40f..a15f3427 100644 --- a/code/modules/pool/pool_main.dm +++ b/code/modules/pool/pool_main.dm @@ -171,7 +171,7 @@ /turf/open/pool/attackby(obj/item/W, mob/living/user) if(istype(W, /obj/item/mop) && filled) - W.reagents.add_reagent("water", 5) + W.reagents.add_reagent(/datum/reagent/water, 5) to_chat(user, "You wet [W] in [src].") playsound(src, 'sound/effects/slosh.ogg', 25, TRUE) else diff --git a/code/modules/research/xenobiology/xenobio_camera.dm b/code/modules/research/xenobiology/xenobio_camera.dm index 5aebd1ba..04cf006e 100644 --- a/code/modules/research/xenobiology/xenobio_camera.dm +++ b/code/modules/research/xenobiology/xenobio_camera.dm @@ -1,6 +1,6 @@ //Xenobio control console /mob/camera/aiEye/remote/xenobio - visible_icon = 1 + visible_icon = TRUE icon = 'icons/obj/abductor.dmi' icon_state = "camera_target" var/allowed_area = null @@ -22,15 +22,11 @@ desc = "A computer used for remotely handling slimes." networks = list("ss13") circuit = /obj/item/circuitboard/computer/xenobiology - var/datum/action/innate/slime_place/slime_place_action - var/datum/action/innate/slime_pick_up/slime_up_action - var/datum/action/innate/feed_slime/feed_slime_action - var/datum/action/innate/monkey_recycle/monkey_recycle_action - var/datum/action/innate/slime_scan/scan_action - var/datum/action/innate/feed_potion/potion_action + var/datum/action/innate/hotkey_help/hotkey_help var/datum/component/redirect/listener + var/obj/machinery/monkey_recycler/connected_recycler var/list/stored_slimes var/obj/item/slimepotion/slime/current_potion var/max_slimes = 5 @@ -43,14 +39,13 @@ /obj/machinery/computer/camera_advanced/xenobio/Initialize() . = ..() - slime_place_action = new - slime_up_action = new - feed_slime_action = new - monkey_recycle_action = new - scan_action = new - potion_action = new + hotkey_help = new stored_slimes = list() listener = AddComponent(/datum/component/redirect, list(COMSIG_ATOM_CONTENTS_DEL = CALLBACK(src, .proc/on_contents_del))) + for(var/obj/machinery/monkey_recycler/recycler in GLOB.monkey_recyclers) + if(get_area(src) == get_area(recycler)) + connected_recycler = recycler + connected_recycler.connected += src /obj/machinery/computer/camera_advanced/xenobio/Destroy() stored_slimes = null @@ -61,45 +56,56 @@ S.forceMove(drop_location()) return ..() +/obj/machinery/computer/camera_advanced/xenobio/examine(mob/user) + . = ..() + var/thing = "It has " + if((upgradetier & XENOBIO_UPGRADE_SLIMEADV)) + thing += "an advanced slime upgrade disk " + if((upgradetier & XENOBIO_UPGRADE_MONKEYS)) + thing += "and a monkey upgrade disk " + else if((upgradetier & XENOBIO_UPGRADE_SLIMEBASIC)) + thing += "a basic slime upgrade disk " + if((upgradetier & XENOBIO_UPGRADE_MONKEYS)) + thing += "and a monkey upgrade disk " + else if((upgradetier & XENOBIO_UPGRADE_MONKEYS)) + thing += "a monkey upgrade disk " + else + thing += "no upgrades installed." + . += thing + return + thing += "installed." + . += thing + /obj/machinery/computer/camera_advanced/xenobio/CreateEye() eyeobj = new /mob/camera/aiEye/remote/xenobio(get_turf(src)) eyeobj.origin = src - eyeobj.visible_icon = 1 + eyeobj.visible_icon = TRUE eyeobj.icon = 'icons/obj/abductor.dmi' eyeobj.icon_state = "camera_target" /obj/machinery/computer/camera_advanced/xenobio/GrantActions(mob/living/user) ..() - if(slime_up_action && (upgradetier & XENOBIO_UPGRADE_SLIMEBASIC)) //CIT CHANGE - makes slime-related actions require XENOBIO_UPGRADE_SLIMEBASIC - slime_up_action.target = src - slime_up_action.Grant(user) - actions += slime_up_action + if(hotkey_help) + hotkey_help.target = src + hotkey_help.Grant(user) + actions += hotkey_help - if(slime_place_action && (upgradetier & XENOBIO_UPGRADE_SLIMEBASIC)) //CIT CHANGE - makes slime-related actions require XENOBIO_UPGRADE_SLIMEBASIC - slime_place_action.target = src - slime_place_action.Grant(user) - actions += slime_place_action + RegisterSignal(user, COMSIG_XENO_SLIME_CLICK_CTRL, .proc/XenoSlimeClickCtrl) + RegisterSignal(user, COMSIG_XENO_SLIME_CLICK_ALT, .proc/XenoSlimeClickAlt) + RegisterSignal(user, COMSIG_XENO_SLIME_CLICK_SHIFT, .proc/XenoSlimeClickShift) + RegisterSignal(user, COMSIG_XENO_TURF_CLICK_SHIFT, .proc/XenoTurfClickShift) + RegisterSignal(user, COMSIG_XENO_TURF_CLICK_CTRL, .proc/XenoTurfClickCtrl) + RegisterSignal(user, COMSIG_XENO_MONKEY_CLICK_CTRL, .proc/XenoMonkeyClickCtrl) - if(feed_slime_action && (upgradetier & XENOBIO_UPGRADE_MONKEYS)) //CIT CHANGE - makes monkey-related actions require XENOBIO_UPGRADE_MONKEYS - feed_slime_action.target = src - feed_slime_action.Grant(user) - actions += feed_slime_action - - if(monkey_recycle_action && (upgradetier & XENOBIO_UPGRADE_MONKEYS)) //CIT CHANGE - makes monkey-related actions require XENOBIO_UPGRADE_MONKEYS - monkey_recycle_action.target = src - monkey_recycle_action.Grant(user) - actions += monkey_recycle_action - - if(scan_action) - scan_action.target = src - scan_action.Grant(user) - actions += scan_action - - if(potion_action && (upgradetier & XENOBIO_UPGRADE_SLIMEADV)) // CIT CHANGE - makes giving slimes potions via console require XENOBIO_UPGRADE_SLIMEADV - potion_action.target = src - potion_action.Grant(user) - actions += potion_action +/obj/machinery/computer/camera_advanced/xenobio/remove_eye_control(mob/living/user) + UnregisterSignal(user, COMSIG_XENO_SLIME_CLICK_CTRL) + UnregisterSignal(user, COMSIG_XENO_SLIME_CLICK_ALT) + UnregisterSignal(user, COMSIG_XENO_SLIME_CLICK_SHIFT) + UnregisterSignal(user, COMSIG_XENO_TURF_CLICK_SHIFT) + UnregisterSignal(user, COMSIG_XENO_TURF_CLICK_CTRL) + UnregisterSignal(user, COMSIG_XENO_MONKEY_CLICK_CTRL) + ..() /obj/machinery/computer/camera_advanced/xenobio/proc/on_contents_del(atom/deleted) if(current_potion == deleted) @@ -134,135 +140,161 @@ current_potion = O to_chat(user, "You load [O] in the console's potion slot[replaced ? ", replacing the one that was there before" : ""].") return + else if(istype(O, /obj/item/multitool)) + var/obj/item/multitool/M = O + if(istype(M.buffer)) + to_chat(user, "You link [src] with [M.buffer] in [M] buffer.") + connected_recycler = M.buffer + connected_recycler += src + return + else + to_chat(user, "[M] has no buffer.") + return ..() -/datum/action/innate/slime_place - name = "Place Slimes" +/datum/action/innate/hotkey_help + name = "Hotkey Help" icon_icon = 'icons/mob/actions/actions_silicon.dmi' - button_icon_state = "slime_down" + button_icon_state = "hotkey_help" -/datum/action/innate/slime_place/Activate() +/datum/action/innate/hotkey_help/Activate() if(!target || !isliving(owner)) return - var/mob/living/C = owner - var/mob/camera/aiEye/remote/xenobio/remote_eye = C.remote_control - var/obj/machinery/computer/camera_advanced/xenobio/X = target + to_chat(owner, "Click shortcuts:") + to_chat(owner, "Shift-click a slime to pick it up, or the floor to drop all held slimes.") + to_chat(owner, "Ctrl-click a slime to scan it.") + to_chat(owner, "Alt-click a slime to feed it a potion.") + to_chat(owner, "Ctrl-click on a dead monkey to recycle it, or the floor to place a new monkey.") - if(GLOB.cameranet.checkTurfVis(remote_eye.loc)) - for(var/mob/living/simple_animal/slime/S in X.stored_slimes) - S.forceMove(remote_eye.loc) +// +// Alternate clicks for slime, monkey and open turf if using a xenobio console + +//Picks up slime +/mob/living/simple_animal/slime/ShiftClick(mob/user) + SEND_SIGNAL(user, COMSIG_XENO_SLIME_CLICK_SHIFT, src) + ..() + +//Place slimes +/turf/open/ShiftClick(mob/user) + SEND_SIGNAL(user, COMSIG_XENO_TURF_CLICK_SHIFT, src) + ..() + +//Place monkey +/turf/open/CtrlClick(mob/user) + SEND_SIGNAL(user, COMSIG_XENO_TURF_CLICK_CTRL, src) + ..() + +//Pick up monkey +/mob/living/carbon/monkey/CtrlClick(mob/user) + SEND_SIGNAL(user, COMSIG_XENO_MONKEY_CLICK_CTRL, src) + ..() + +// Scans slime +/mob/living/simple_animal/slime/CtrlClick(mob/user) + SEND_SIGNAL(user, COMSIG_XENO_SLIME_CLICK_CTRL, src) + ..() + +//Feeds a potion to slime +/mob/living/simple_animal/slime/AltClick(mob/user) + SEND_SIGNAL(user, COMSIG_XENO_SLIME_CLICK_ALT, src) + ..() + +//Picks up slime +/obj/machinery/computer/camera_advanced/xenobio/proc/XenoSlimeClickShift(mob/living/user, mob/living/simple_animal/slime/S) + if(!(upgradetier & XENOBIO_UPGRADE_SLIMEBASIC)) + return + if(!GLOB.cameranet.checkTurfVis(S.loc)) + to_chat(user, "Target is not near a camera. Cannot proceed.") + return + var/area/mobarea = get_area(S.loc) + var/mob/camera/aiEye/remote/xenobio/X = eyeobj + if(mobarea.name == X.allowed_area || mobarea.xenobiology_compatible) + if(stored_slimes.len >= max_slimes) + to_chat(user, "Slime storage is full.") + return + if(S.ckey) + to_chat(user, "The slime wiggled free!") + return + if(S.buckled) + S.Feedstop(silent = TRUE) + S.visible_message("[S] vanishes in a flash of light!") + S.forceMove(src) + stored_slimes += S + +//Place slimes +/obj/machinery/computer/camera_advanced/xenobio/proc/XenoTurfClickShift(mob/living/user, turf/open/T) + if(!(upgradetier & XENOBIO_UPGRADE_SLIMEBASIC)) + return + if(!GLOB.cameranet.checkTurfVis(T)) + to_chat(user, "Target is not near a camera. Cannot proceed.") + return + var/area/turfarea = get_area(T) + var/mob/camera/aiEye/remote/xenobio/X = eyeobj + if(turfarea.name == X.allowed_area || turfarea.xenobiology_compatible) + for(var/mob/living/simple_animal/slime/S in stored_slimes) + S.forceMove(T) S.visible_message("[S] warps in!") - X.stored_slimes -= S - else - to_chat(owner, "Target is not near a camera. Cannot proceed.") + stored_slimes -= S -/datum/action/innate/slime_pick_up - name = "Pick up Slime" - icon_icon = 'icons/mob/actions/actions_silicon.dmi' - button_icon_state = "slime_up" - -/datum/action/innate/slime_pick_up/Activate() - if(!target || !isliving(owner)) +//Place monkey +/obj/machinery/computer/camera_advanced/xenobio/proc/XenoTurfClickCtrl(mob/living/user, turf/open/T) + if(!(upgradetier & XENOBIO_UPGRADE_MONKEYS)) return - var/mob/living/C = owner - var/mob/camera/aiEye/remote/xenobio/remote_eye = C.remote_control - var/obj/machinery/computer/camera_advanced/xenobio/X = target - - if(GLOB.cameranet.checkTurfVis(remote_eye.loc)) - for(var/mob/living/simple_animal/slime/S in remote_eye.loc) - if(X.stored_slimes.len >= X.max_slimes) - break - if(!S.ckey) - if(S.buckled) - S.Feedstop(silent = TRUE) - S.visible_message("[S] vanishes in a flash of light!") - S.forceMove(X) - X.stored_slimes += S - else - to_chat(owner, "Target is not near a camera. Cannot proceed.") - - -/datum/action/innate/feed_slime - name = "Feed Slimes" - icon_icon = 'icons/mob/actions/actions_silicon.dmi' - button_icon_state = "monkey_down" - -/datum/action/innate/feed_slime/Activate() - if(!target || !isliving(owner)) + if(!GLOB.cameranet.checkTurfVis(T)) + to_chat(user, "Target is not near a camera. Cannot proceed.") return - var/mob/living/C = owner - var/mob/camera/aiEye/remote/xenobio/remote_eye = C.remote_control - var/obj/machinery/computer/camera_advanced/xenobio/X = target + var/area/turfarea = get_area(T) + var/mob/camera/aiEye/remote/xenobio/X = eyeobj + if(turfarea.name == X.allowed_area || turfarea.xenobiology_compatible) + if(monkeys >= 1) + var/mob/living/carbon/monkey/food = new/mob/living/carbon/monkey(T, TRUE, user) + if(!QDELETED(food)) + food.LAssailant = user + monkeys = round(monkeys-1, 0.1) + to_chat(user, "[src] now has [monkeys] monkeys stored.") - if(GLOB.cameranet.checkTurfVis(remote_eye.loc)) - if(X.monkeys >= 1) - var/mob/living/carbon/monkey/food = new /mob/living/carbon/monkey(remote_eye.loc, TRUE, owner) - if (!QDELETED(food)) - food.LAssailant = C - X.monkeys -- - to_chat(owner, "[X] now has [X.monkeys] monkeys left.") - else - to_chat(owner, "Target is not near a camera. Cannot proceed.") - - -/datum/action/innate/monkey_recycle - name = "Recycle Monkeys" - icon_icon = 'icons/mob/actions/actions_silicon.dmi' - button_icon_state = "monkey_up" - -/datum/action/innate/monkey_recycle/Activate() - if(!target || !isliving(owner)) +//Pick up monkey +/obj/machinery/computer/camera_advanced/xenobio/proc/XenoMonkeyClickCtrl(mob/living/user, mob/living/carbon/monkey/M) + if(!(upgradetier & XENOBIO_UPGRADE_MONKEYS)) return - var/mob/living/C = owner - var/mob/camera/aiEye/remote/xenobio/remote_eye = C.remote_control - var/obj/machinery/computer/camera_advanced/xenobio/X = target - - if(GLOB.cameranet.checkTurfVis(remote_eye.loc)) - for(var/mob/living/carbon/monkey/M in remote_eye.loc) - if(M.stat) - M.visible_message("[M] vanishes as [M.p_theyre()] reclaimed for recycling!") - X.monkeys = round(X.monkeys + 0.2,0.1) - qdel(M) - else - to_chat(owner, "Target is not near a camera. Cannot proceed.") - -/datum/action/innate/slime_scan - name = "Scan Slime" - icon_icon = 'icons/mob/actions/actions_silicon.dmi' - button_icon_state = "slime_scan" - -/datum/action/innate/slime_scan/Activate() - if(!target || !isliving(owner)) + if(!connected_recycler) + to_chat(user, "There is no connected monkey recycler. You can connect one with a multitool.") return - var/mob/living/C = owner - var/mob/camera/aiEye/remote/xenobio/remote_eye = C.remote_control - - if(GLOB.cameranet.checkTurfVis(remote_eye.loc)) - for(var/mob/living/simple_animal/slime/S in remote_eye.loc) - slime_scan(S, C) - else - to_chat(owner, "Target is not near a camera. Cannot proceed.") - -/datum/action/innate/feed_potion - name = "Apply Potion" - icon_icon = 'icons/mob/actions/actions_silicon.dmi' - button_icon_state = "slime_potion" - -/datum/action/innate/feed_potion/Activate() - if(!target || !isliving(owner)) + if(!GLOB.cameranet.checkTurfVis(M.loc)) + to_chat(user, "Target is not near a camera. Cannot proceed.") return + var/area/mobarea = get_area(M.loc) + var/mob/camera/aiEye/remote/xenobio/X = eyeobj + if(mobarea.name == X.allowed_area || mobarea.xenobiology_compatible) + if(!M.stat) + return + M.visible_message("[M] vanishes as [M.p_theyre()] reclaimed for recycling!") + connected_recycler.use_power(500) + monkeys += connected_recycler.cube_production + to_chat(user, "[src] now has [monkeys] monkeys available.") + qdel(M) - var/mob/living/C = owner - var/mob/camera/aiEye/remote/xenobio/remote_eye = C.remote_control - var/obj/machinery/computer/camera_advanced/xenobio/X = target - - if(QDELETED(X.current_potion)) - to_chat(owner, "No potion loaded.") +// Scans slime +/obj/machinery/computer/camera_advanced/xenobio/proc/XenoSlimeClickCtrl(mob/living/user, mob/living/simple_animal/slime/S) + if(!GLOB.cameranet.checkTurfVis(S.loc)) + to_chat(user, "Target is not near a camera. Cannot proceed.") return + var/area/mobarea = get_area(S.loc) + var/mob/camera/aiEye/remote/xenobio/X = eyeobj + if(mobarea.name == X.allowed_area || mobarea.xenobiology_compatible) + slime_scan(S, user) - if(GLOB.cameranet.checkTurfVis(remote_eye.loc)) - for(var/mob/living/simple_animal/slime/S in remote_eye.loc) - X.current_potion.attack(S, C) - break - else - to_chat(owner, "Target is not near a camera. Cannot proceed.") +//Feeds a potion to slime +/obj/machinery/computer/camera_advanced/xenobio/proc/XenoSlimeClickAlt(mob/living/user, mob/living/simple_animal/slime/S) + if(!(upgradetier & XENOBIO_UPGRADE_SLIMEBASIC)) + return + if(!GLOB.cameranet.checkTurfVis(S.loc)) + to_chat(user, "Target is not near a camera. Cannot proceed.") + return + var/area/mobarea = get_area(S.loc) + if(QDELETED(current_potion)) + to_chat(user, "No potion loaded.") + return + var/mob/camera/aiEye/remote/xenobio/X = eyeobj + if(mobarea.name == X.allowed_area || mobarea.xenobiology_compatible) + current_potion.attack(S, user) diff --git a/icons/mob/actions/actions_silicon.dmi b/icons/mob/actions/actions_silicon.dmi index cd997a25..cf3d7a2a 100644 Binary files a/icons/mob/actions/actions_silicon.dmi and b/icons/mob/actions/actions_silicon.dmi differ diff --git a/modular_citadel/code/datums/status_effects/chems.dm b/modular_citadel/code/datums/status_effects/chems.dm index 9a1a46fe..ef45e07b 100644 --- a/modular_citadel/code/datums/status_effects/chems.dm +++ b/modular_citadel/code/datums/status_effects/chems.dm @@ -105,7 +105,7 @@ o.add_movespeed_modifier(BREAST_MOVEMENT_SPEED, TRUE, 100, NONE, override = TRUE, multiplicative_slowdown = moveCalc) sizeMoveMod(moveCalc) */ - if((B.cached_size) < 40) + if((B?.cached_size) < 40) ..() /*