From 5518efebea12561a1f26965c0c851463c85fb0c7 Mon Sep 17 00:00:00 2001 From: Poojawa Date: Mon, 23 Apr 2018 01:06:17 -0500 Subject: [PATCH] everything but mob stuff --- code/modules/admin/admin.dm | 8 +- code/modules/admin/admin_verbs.dm | 7 +- code/modules/admin/fun_balloon.dm | 17 +- code/modules/admin/player_panel.dm | 2 + code/modules/admin/topic.dm | 14 +- code/modules/admin/verbs/adminhelp.dm | 24 +- code/modules/admin/verbs/adminjump.dm | 9 +- code/modules/admin/verbs/borgpanel.dm | 217 ++++ code/modules/admin/verbs/buildmode.dm | 43 +- code/modules/admin/verbs/getlogs.dm | 14 +- code/modules/admin/verbs/randomverbs.dm | 19 - .../antagonists/blob/blob/blobs/blob_mobs.dm | 1 + code/modules/antagonists/borer/borer.dm | 1099 ----------------- .../antagonists/borer/borer_chemicals.dm | 82 -- code/modules/antagonists/borer/borer_event.dm | 49 - code/modules/antagonists/borer/borer_html.dm | 125 -- code/modules/antagonists/borer/borer_topic.dm | 42 - code/modules/antagonists/borer/syndi_borer.dm | 34 - .../antagonists/changeling/changeling.dm | 20 +- .../antagonists/changeling/powers/absorb.dm | 9 +- .../changeling/powers/regenerate.dm | 1 - .../antagonists/changeling/powers/revive.dm | 2 +- .../clock_mobs/clockwork_marauder.dm | 1 + .../clockcult/clock_structures/stargazer.dm | 70 -- code/modules/antagonists/cult/cult.dm | 6 +- code/modules/antagonists/devil/imp/imp.dm | 1 + code/modules/antagonists/revenant/revenant.dm | 1 + .../antagonists/slaughter/slaughter.dm | 1 + code/modules/antagonists/swarmer/swarmer.dm | 1 + .../traitor/equipment/Malf_Modules.dm | 2 +- code/modules/assembly/assembly.dm | 10 +- .../atmospherics/machinery/airalarm.dm | 7 +- .../components/unary_devices/cryo.dm | 8 +- .../machinery/portable/canister.dm | 14 +- code/modules/cargo/exports/large_objects.dm | 2 +- code/modules/cargo/packs.dm | 4 +- code/modules/cargo/vg_clothing_packs.dm | 34 - code/modules/client/client_procs.dm | 64 +- code/modules/clothing/chameleon.dm | 9 +- code/modules/clothing/clothing.dm | 64 +- .../clothing/glasses/engine_goggles.dm | 39 +- code/modules/clothing/head/jobs.dm | 6 +- code/modules/clothing/head/misc.dm | 2 +- code/modules/clothing/outfits/event.dm | 3 +- code/modules/clothing/outfits/standard.dm | 10 +- code/modules/clothing/shoes/miscellaneous.dm | 14 +- .../modules/clothing/spacesuits/flightsuit.dm | 6 +- code/modules/clothing/under/accessories.dm | 35 +- code/modules/detectivework/evidence.dm | 5 +- code/modules/events/pirates.dm | 9 +- code/modules/events/wizard/rpgloot.dm | 5 +- code/modules/flufftext/TextFilters.dm | 64 - .../kitchen_machinery/food_cart.dm | 11 +- .../kitchen_machinery/microwave.dm | 5 +- .../kitchen_machinery/monkeyrecycler.dm | 16 +- .../kitchen_machinery/processor.dm | 102 +- .../kitchen_machinery/smartfridge.dm | 13 +- code/modules/holiday/easter.dm | 12 +- code/modules/hydroponics/biogenerator.dm | 4 +- code/modules/hydroponics/hydroponics.dm | 5 +- code/modules/hydroponics/seed_extractor.dm | 21 +- .../integrated_electronics/subtypes/input.dm | 3 +- code/modules/keybindings/bindings_human.dm | 8 +- code/modules/library/lib_items.dm | 11 +- code/modules/lighting/lighting_area.dm | 4 +- code/modules/mapping/map_template.dm | 2 +- code/modules/mining/aux_base.dm | 2 - code/modules/mining/fulton.dm | 3 +- .../mining/lavaland/necropolis_chests.dm | 73 +- code/modules/mining/money_bag.dm | 14 +- code/modules/mining/satchel_ore_boxdm.dm | 14 +- .../modular_computers/documentation.dm | 40 - .../file_system/programs/sm_monitor.dm | 10 +- .../ninja/suit/n_suit_verbs/ninja_stealth.dm | 8 +- .../suit/n_suit_verbs/ninja_teleporting.dm | 71 -- code/modules/ninja/suit/suit.dm | 4 +- code/modules/ninja/suit/suit_process.dm | 2 +- .../modules/ninja/suit/suit_verbs_handlers.dm | 26 - code/modules/paperwork/photography.dm | 6 +- code/modules/power/apc.dm | 79 +- code/modules/power/singularity/singularity.dm | 2 +- code/modules/power/supermatter/supermatter.dm | 162 ++- code/modules/power/switch.dm | 84 -- .../procedural_mapping/mapGenerator.dm | 11 +- .../guns/energy/kinetic_accelerator.dm | 17 +- code/modules/reagents/chemistry/holder.dm | 2 +- .../chemistry/machinery/chem_master.dm | 39 +- .../chemistry/machinery/reagentgrinder.dm | 16 +- code/modules/reagents/chemistry/reagents.dm | 4 - .../chemistry/reagents/food_reagents.dm | 3 +- .../chemistry/reagents/other_reagents.dm | 47 +- .../chemistry/reagents/toxin_reagents.dm | 43 +- .../reagents/reagent_containers/borghydro.dm | 15 + code/modules/recycling/conveyor2.dm | 41 +- code/modules/recycling/disposal/bin.dm | 16 +- code/modules/research/message_server.dm | 140 --- code/modules/research/stock_parts.dm | 72 +- .../xenobiology/crossbreeding/reproductive.dm | 26 +- .../research/xenobiology/xenobio_camera.dm | 44 +- code/modules/shuttle/assault_pod.dm | 2 +- code/modules/shuttle/docking.dm | 28 +- code/modules/shuttle/emergency.dm | 2 +- code/modules/shuttle/manipulator.dm | 3 +- code/modules/shuttle/on_move.dm | 23 +- code/modules/shuttle/shuttle.dm | 42 +- code/modules/surgery/organs/autoimplanter.dm | 64 - code/modules/surgery/organs/liver.dm | 19 +- code/modules/surgery/organs/lungs.dm | 20 - code/modules/telesci/telepad.dm | 170 --- code/modules/telesci/telesci_computer.dm | 363 ------ code/modules/vending/snack.dm | 2 +- 111 files changed, 978 insertions(+), 3448 deletions(-) create mode 100644 code/modules/admin/verbs/borgpanel.dm delete mode 100644 code/modules/antagonists/borer/borer.dm delete mode 100644 code/modules/antagonists/borer/borer_chemicals.dm delete mode 100644 code/modules/antagonists/borer/borer_event.dm delete mode 100644 code/modules/antagonists/borer/borer_html.dm delete mode 100644 code/modules/antagonists/borer/borer_topic.dm delete mode 100644 code/modules/antagonists/borer/syndi_borer.dm delete mode 100644 code/modules/antagonists/clockcult/clock_structures/stargazer.dm delete mode 100644 code/modules/cargo/vg_clothing_packs.dm delete mode 100644 code/modules/flufftext/TextFilters.dm delete mode 100644 code/modules/modular_computers/documentation.dm delete mode 100644 code/modules/ninja/suit/n_suit_verbs/ninja_teleporting.dm delete mode 100644 code/modules/ninja/suit/suit_verbs_handlers.dm delete mode 100644 code/modules/power/switch.dm delete mode 100644 code/modules/research/message_server.dm delete mode 100644 code/modules/surgery/organs/autoimplanter.dm delete mode 100644 code/modules/telesci/telepad.dm delete mode 100644 code/modules/telesci/telesci_computer.dm diff --git a/code/modules/admin/admin.dm b/code/modules/admin/admin.dm index 3d22385513..577cca303b 100644 --- a/code/modules/admin/admin.dm +++ b/code/modules/admin/admin.dm @@ -43,7 +43,6 @@ body += "

Show related accounts by: " body += "\[ CID | " body += "IP \]" - var/rep = 0 rep += SSpersistence.antag_rep[M.ckey] body += "

Antagonist reputation: [rep]" @@ -52,12 +51,15 @@ body += "\[set\] " body += "\[zero\]" + body += "

\[ " body += "VV - " if(M.mind) body += "TP - " else body += "Init Mind - " + if (iscyborg(M)) + body += "BP - " body += "PM - " body += "SM - " body += "FLW - " @@ -177,9 +179,9 @@ body += "Thunderdome 2 | " body += "Thunderdome Admin | " body += "Thunderdome Observer | " - + body += usr.client.citaPPoptions(M) // CITADEL - + body += "
" body += "" diff --git a/code/modules/admin/admin_verbs.dm b/code/modules/admin/admin_verbs.dm index c99f568086..eb4d102914 100644 --- a/code/modules/admin/admin_verbs.dm +++ b/code/modules/admin/admin_verbs.dm @@ -1,4 +1,5 @@ //admin verb groups - They can overlap if you so wish. Only one of each verb will exist in the verbs list regardless +//admin verb groups - They can overlap if you so wish. Only one of each verb will exist in the verbs list regardless //the procs are cause you can't put the comments in the GLOB var define GLOBAL_PROTECT(admin_verbs_default) GLOBAL_LIST_INIT(admin_verbs_default, world.AVerbsDefault()) @@ -6,7 +7,6 @@ GLOBAL_LIST_INIT(admin_verbs_default, world.AVerbsDefault()) return list( /client/proc/deadmin, /*destroys our own admin datum so we can play as a regular player*/ /client/proc/cmd_admin_say, /*admin-only ooc chat*/ - /client/proc/cmd_admin_ticket_panel, /client/proc/dsay, /*talk in deadchat using our ckey/fakekey*/ /client/proc/deadchat, /client/proc/investigate_show, /*various admintools for investigation. Such as a singulo grief-log*/ @@ -39,6 +39,7 @@ GLOBAL_LIST_INIT(admin_verbs_admin, world.AVerbsAdmin()) /client/proc/check_antagonists, /*shows all antags*/ /datum/admins/proc/access_news_network, /*allows access of newscasters*/ /client/proc/jumptocoord, /*we ghost and jump to a coordinate*/ + /client/proc/getcurrentlogs, /*for accessing server logs for the current round*/ /client/proc/Getmob, /*teleports a mob to our location*/ /client/proc/Getkey, /*teleports a mob with a certain ckey to our location*/ // /client/proc/sendmob, /*sends a mob somewhere*/ -Removed due to it needing two sorting procs to work, which were executed every time an admin right-clicked. ~Errorage @@ -56,7 +57,6 @@ GLOBAL_LIST_INIT(admin_verbs_admin, world.AVerbsAdmin()) /client/proc/cmd_admin_create_centcom_report, /client/proc/cmd_change_command_name, /client/proc/cmd_admin_check_player_exp, /* shows players by playtime */ - /client/proc/toggle_antag_hud, /*toggle display of the admin antag hud*/ /client/proc/toggle_combo_hud, // toggle display of the combination pizza antag and taco sci/med/eng hud /client/proc/toggle_AI_interact, /*toggle admin ability to interact with machines as an AI*/ /client/proc/open_shuttle_manipulator, /* Opens shuttle manipulator UI */ @@ -228,7 +228,6 @@ GLOBAL_LIST_INIT(admin_verbs_hideable, list( /client/proc/admin_change_sec_level, /client/proc/toggle_nuke, /client/proc/cmd_display_del_log, - /client/proc/toggle_antag_hud, /client/proc/toggle_combo_hud, /client/proc/debug_huds, /client/proc/cmd_admin_man_up, //CIT CHANGE - adds man up verb @@ -622,7 +621,7 @@ GLOBAL_LIST_INIT(admin_verbs_hideable, list( return if(has_antag_hud()) - toggle_antag_hud() + toggle_combo_hud() holder.deactivate() diff --git a/code/modules/admin/fun_balloon.dm b/code/modules/admin/fun_balloon.dm index 6ce6188590..b5dfbf7817 100644 --- a/code/modules/admin/fun_balloon.dm +++ b/code/modules/admin/fun_balloon.dm @@ -119,21 +119,13 @@ /obj/effect/forcefield/arena_shuttle name = "portal" + timeleft = 0 var/list/warp_points /obj/effect/forcefield/arena_shuttle/Initialize() . = ..() - warp_points = get_area_turfs(/area/shuttle/escape) - for(var/thing in warp_points) - CHECK_TICK - var/turf/T = thing - if(istype(T.loc, /area/shuttle/escape/backup)) - warp_points -= T - continue - for(var/atom/movable/TAM in T) - if(TAM.density && TAM.anchored) - warp_points -= T - break + for(var/obj/effect/landmark/shuttle_arena_safe/exit in GLOB.landmarks_list) + warp_points += exit /obj/effect/forcefield/arena_shuttle/CollidedWith(atom/movable/AM) if(!isliving(AM)) @@ -143,7 +135,7 @@ if(L.pulling && istype(L.pulling, /obj/item/bodypart/head)) to_chat(L, "Your offering is accepted. You may pass.") qdel(L.pulling) - var/turf/LA = pick(warp_points) + var/turf/LA = get_turf(pick(warp_points)) L.forceMove(LA) L.hallucination = 0 to_chat(L, "The battle is won. Your bloodlust subsides.") @@ -163,6 +155,7 @@ /obj/effect/forcefield/arena_shuttle_entrance name = "portal" + timeleft = 0 var/list/warp_points = list() /obj/effect/forcefield/arena_shuttle_entrance/CollidedWith(atom/movable/AM) diff --git a/code/modules/admin/player_panel.dm b/code/modules/admin/player_panel.dm index 8ddcc1b593..03bd08f750 100644 --- a/code/modules/admin/player_panel.dm +++ b/code/modules/admin/player_panel.dm @@ -80,6 +80,8 @@ body += "N - " body += "VV - " body += "TP - " + if (job == "Cyborg") + body += "BP - " body += "PM - " body += "SM - " body += "FLW - " diff --git a/code/modules/admin/topic.dm b/code/modules/admin/topic.dm index eaa8ea908c..fb5c6eb2b6 100644 --- a/code/modules/admin/topic.dm +++ b/code/modules/admin/topic.dm @@ -21,9 +21,9 @@ if(!CheckAdminHref(href, href_list)) return - + citaTopic(href, href_list) //CITADEL EDIT, MENTORS - + if(href_list["ahelp"]) if(!check_rights(R_ADMIN, TRUE)) return @@ -1921,6 +1921,16 @@ else show_traitor_panel(M) + else if(href_list["borgpanel"]) + if(!check_rights(R_ADMIN)) + return + + var/mob/M = locate(href_list["borgpanel"]) + if(!iscyborg(M)) + to_chat(usr, "This can only be used on cyborgs") + else + open_borgopanel(M) + else if(href_list["initmind"]) if(!check_rights(R_ADMIN)) return diff --git a/code/modules/admin/verbs/adminhelp.dm b/code/modules/admin/verbs/adminhelp.dm index a7cddae2d5..2a6b4448d2 100644 --- a/code/modules/admin/verbs/adminhelp.dm +++ b/code/modules/admin/verbs/adminhelp.dm @@ -398,7 +398,7 @@ GLOBAL_DATUM_INIT(ahelp_tickets, /datum/admin_help_tickets, new) message_admins(msg) log_admin_private(msg) AddInteraction("Being handled by [key_name]") - + //Show the ticket panel /datum/admin_help/proc/TicketPanel() var/list/dat = list("Ticket #[id]") @@ -534,28 +534,6 @@ GLOBAL_DATUM_INIT(ahelp_tickets, /datum/admin_help_tickets, new) new /datum/admin_help(msg, src, FALSE) -//admin proc -/client/proc/cmd_admin_ticket_panel() - set name = "Show Ticket List" - set category = "Admin" - - if(!check_rights(R_ADMIN, TRUE)) - return - - var/browse_to - - switch(input("Display which ticket list?") as null|anything in list("Active Tickets", "Closed Tickets", "Resolved Tickets")) - if("Active Tickets") - browse_to = AHELP_ACTIVE - if("Closed Tickets") - browse_to = AHELP_CLOSED - if("Resolved Tickets") - browse_to = AHELP_RESOLVED - else - return - - GLOB.ahelp_tickets.BrowseTickets(browse_to) - // // LOGGING // diff --git a/code/modules/admin/verbs/adminjump.dm b/code/modules/admin/verbs/adminjump.dm index 779ea64640..1e96cc507e 100644 --- a/code/modules/admin/verbs/adminjump.dm +++ b/code/modules/admin/verbs/adminjump.dm @@ -10,11 +10,10 @@ return var/list/turfs = list() - for(var/area/Ar in A.related) - for(var/turf/T in Ar) - if(T.density) - continue - turfs.Add(T) + for(var/turf/T in A) + if(T.density) + continue + turfs.Add(T) var/turf/T = safepick(turfs) if(!T) diff --git a/code/modules/admin/verbs/borgpanel.dm b/code/modules/admin/verbs/borgpanel.dm new file mode 100644 index 0000000000..8a162e7794 --- /dev/null +++ b/code/modules/admin/verbs/borgpanel.dm @@ -0,0 +1,217 @@ +/datum/admins/proc/open_borgopanel(borgo in GLOB.silicon_mobs) + set category = "Admin" + set name = "Show Borg Panel" + set desc = "Show borg panel" + + if(!check_rights(R_ADMIN)) + return + + if (!istype(borgo, /mob/living/silicon/robot)) + borgo = input("Select a borg", "Select a borg", null, null) as null|anything in GLOB.silicon_mobs + if (!istype(borgo, /mob/living/silicon/robot)) + to_chat(usr, "Borg is required for borgpanel") + + var/datum/borgpanel/borgpanel = new(usr, borgo) + + borgpanel.ui_interact(usr) + + + +/datum/borgpanel + var/mob/living/silicon/robot/borg + var/user + +/datum/borgpanel/New(user, mob/living/silicon/robot/borg) + if(!istype(borg)) + CRASH("Borg panel is only available for borgs") + qdel(src) + if (istype(user, /mob)) + var/mob/M = user + if (!M.client) + CRASH("Borg panel attempted to open to a mob without a client") + src.user = M.client + else + src.user = user + src.borg = borg + +/datum/borgpanel/ui_interact(mob/user, ui_key = "main", datum/tgui/ui = null, force_open = FALSE, datum/tgui/master_ui = null, datum/ui_state/state = GLOB.admin_state) + ui = SStgui.try_update_ui(user, src, ui_key, ui, force_open) + if(!ui) + ui = new(user, src, ui_key, "borgopanel", "Borg Panel", 700, 700, master_ui, state) + ui.open() + +/datum/borgpanel/ui_data(mob/user) + . = list() + .["borg"] = list( + "ref" = REF(borg), + "name" = "[borg]", + "emagged" = borg.emagged, + "active_module" = "[borg.module.type]", + "lawupdate" = borg.lawupdate, + "lockdown" = borg.lockcharge, + "scrambledcodes" = borg.scrambledcodes + ) + .["upgrades"] = list() + for (var/upgradetype in subtypesof(/obj/item/borg/upgrade)-/obj/item/borg/upgrade/hypospray) //hypospray is a dummy parent for hypospray upgrades + var/obj/item/borg/upgrade/upgrade = upgradetype + if (initial(upgrade.module_type) && !istype(borg.module, initial(upgrade.module_type))) // Upgrade requires a different module + continue + var/installed = FALSE + if (locate(upgradetype) in borg) + installed = TRUE + .["upgrades"] += list(list("name" = initial(upgrade.name), "installed" = installed, "type" = upgradetype)) + .["laws"] = borg.laws ? borg.laws.get_law_list(include_zeroth = TRUE) : list() + .["channels"] = list() + for (var/k in GLOB.radiochannels) + if (k == "Common") + continue + .["channels"] += list(list("name" = k, "installed" = (k in borg.radio.channels))) + .["cell"] = borg.cell ? list("missing" = FALSE, "maxcharge" = borg.cell.maxcharge, "charge" = borg.cell.charge) : list("missing" = TRUE, "maxcharge" = 1, "charge" = 0) + .["modules"] = list() + for(var/moduletype in typesof(/obj/item/robot_module)) + var/obj/item/robot_module/module = moduletype + .["modules"] += list(list( + "name" = initial(module.name), + "type" = "[module]" + )) + .["ais"] = list(list("name" = "None", "ref" = "null", "connected" = isnull(borg.connected_ai))) + for(var/mob/living/silicon/ai/ai in GLOB.ai_list) + .["ais"] += list(list("name" = ai.name, "ref" = REF(ai), "connected" = (borg.connected_ai == ai))) + + +/datum/borgpanel/ui_act(action, params) + if(..()) + return + switch (action) + if ("set_charge") + var/newcharge = input("New charge (0-[borg.cell.maxcharge]):", borg.name, borg.cell.charge) as num|null + if (newcharge) + borg.cell.charge = CLAMP(newcharge, 0, borg.cell.maxcharge) + message_admins("[key_name_admin(user)] set the charge of [key_name_admin(borg)][ADMIN_FLW(borg)] to [borg.cell.charge].") + log_admin("[key_name(user)] set the charge of [key_name(borg)] to [borg.cell.charge].") + if ("remove_cell") + QDEL_NULL(borg.cell) + message_admins("[key_name_admin(user)] deleted the cell of [key_name_admin(borg)][ADMIN_FLW(borg)].") + log_admin("[key_name(user)] deleted the cell of [key_name(borg)].") + if ("change_cell") + var/chosen = pick_closest_path(null, make_types_fancy(typesof(/obj/item/stock_parts/cell))) + if (!ispath(chosen)) + chosen = text2path(chosen) + if (chosen) + if (borg.cell) + QDEL_NULL(borg.cell) + var/new_cell = new chosen(borg) + borg.cell = new_cell + borg.cell.charge = borg.cell.maxcharge + borg.diag_hud_set_borgcell() + message_admins("[key_name_admin(user)] changed the cell of [key_name_admin(borg)][ADMIN_FLW(borg)] to [new_cell].") + log_admin("[key_name(user)] changed the cell of [key_name(borg)] to [new_cell].") + if ("toggle_emagged") + borg.SetEmagged(!borg.emagged) + if (borg.emagged) + message_admins("[key_name_admin(user)] emagged [key_name_admin(borg)][ADMIN_FLW(borg)].") + log_admin("[key_name(user)] emagged [key_name(borg)].") + else + message_admins("[key_name_admin(user)] un-emagged [key_name_admin(borg)][ADMIN_FLW(borg)].") + log_admin("[key_name(user)] un-emagged [key_name(borg)].") + if ("toggle_lawupdate") + borg.lawupdate = !borg.lawupdate + if (borg.lawupdate) + message_admins("[key_name_admin(user)] enabled lawsync on [key_name_admin(borg)][ADMIN_FLW(borg)].") + log_admin("[key_name(user)] enabled lawsync on [key_name(borg)].") + else + message_admins("[key_name_admin(user)] disabled lawsync on [key_name_admin(borg)][ADMIN_FLW(borg)].") + log_admin("[key_name(user)] disabled lawsync on [key_name(borg)].") + if ("toggle_lockdown") + borg.SetLockdown(!borg.lockcharge) + if (borg.lockcharge) + message_admins("[key_name_admin(user)] locked down [key_name_admin(borg)][ADMIN_FLW(borg)].") + log_admin("[key_name(user)] locked down [key_name(borg)].") + else + message_admins("[key_name_admin(user)] released [key_name_admin(borg)][ADMIN_FLW(borg)] from lockdown.") + log_admin("[key_name(user)] released [key_name(borg)] from lockdown.") + if ("toggle_scrambledcodes") + borg.scrambledcodes = !borg.scrambledcodes + if (borg.scrambledcodes) + message_admins("[key_name_admin(user)] enabled scrambled codes on [key_name_admin(borg)][ADMIN_FLW(borg)].") + log_admin("[key_name(user)] enabled scrambled codes on [key_name(borg)].") + else + message_admins("[key_name_admin(user)] disabled scrambled codes on [key_name_admin(borg)][ADMIN_FLW(borg)].") + log_admin("[key_name(user)] disabled scrambled codes on [key_name(borg)].") + if ("rename") + var/new_name = stripped_input(user,"What would you like to name this cyborg?","Input a name",borg.real_name,MAX_NAME_LEN) + if(!new_name) + return + message_admins("[key_name_admin(user)] renamed [key_name_admin(borg)][ADMIN_FLW(borg)] to [new_name].") + log_admin("[key_name(user)] renamed [key_name(borg)] to [new_name].") + borg.fully_replace_character_name(borg.real_name,new_name) + if ("toggle_upgrade") + var/upgradepath = text2path(params["upgrade"]) + var/obj/item/borg/upgrade/installedupgrade = locate(upgradepath) in borg + if (installedupgrade) + installedupgrade.deactivate(borg, user) + borg.upgrades -= installedupgrade + message_admins("[key_name_admin(user)] removed the [installedupgrade] upgrade from [key_name_admin(borg)][ADMIN_FLW(borg)].") + log_admin("[key_name(user)] removed the [installedupgrade] upgrade from [key_name(borg)].") + qdel(installedupgrade) + else + var/obj/item/borg/upgrade/upgrade = new upgradepath(borg) + upgrade.action(borg, user) + borg.upgrades += upgrade + message_admins("[key_name_admin(user)] added the [upgrade] borg upgrade to [key_name_admin(borg)][ADMIN_FLW(borg)].") + log_admin("[key_name(user)] added the [upgrade] borg upgrade to [key_name(borg)].") + if ("toggle_radio") + var/channel = params["channel"] + if (channel in borg.radio.channels) // We're removing a channel + if (!borg.radio.keyslot) // There's no encryption key. This shouldn't happen but we can cope + borg.radio.channels -= channel + if (channel == "Syndicate") + borg.radio.syndie = FALSE + else if (channel == "CentCom") + borg.radio.independent = FALSE + else + borg.radio.keyslot.channels -= channel + if (channel == "Syndicate") + borg.radio.keyslot.syndie = FALSE + else if (channel == "CentCom") + borg.radio.keyslot.independent = FALSE + message_admins("[key_name_admin(user)] removed the [channel] radio channel from [key_name_admin(borg)][ADMIN_FLW(borg)].") + log_admin("[key_name(user)] removed the [channel] radio channel from [key_name(borg)].") + else // We're adding a channel + if (!borg.radio.keyslot) // Assert that an encryption key exists + borg.radio.keyslot = new (borg.radio) + borg.radio.keyslot.channels[channel] = 1 + if (channel == "Syndicate") + borg.radio.keyslot.syndie = TRUE + else if (channel == "CentCom") + borg.radio.keyslot.independent = TRUE + message_admins("[key_name_admin(user)] added the [channel] radio channel to [key_name_admin(borg)][ADMIN_FLW(borg)].") + log_admin("[key_name(user)] added the [channel] radio channel to [key_name(borg)].") + borg.radio.recalculateChannels() + if ("setmodule") + var/newmodulepath = text2path(params["module"]) + if (ispath(newmodulepath)) + borg.module.transform_to(newmodulepath) + message_admins("[key_name_admin(user)] changed the module of [key_name_admin(borg)][ADMIN_FLW(borg)] to [newmodulepath].") + log_admin("[key_name(user)] changed the module of [key_name(borg)] to [newmodulepath].") + if ("slavetoai") + var/mob/living/silicon/ai/newai = locate(params["slavetoai"]) in GLOB.ai_list + if (newai && newai != borg.connected_ai) + borg.notify_ai(DISCONNECT) + if(borg.shell) + borg.undeploy() + borg.connected_ai = newai + borg.notify_ai(TRUE) + message_admins("[key_name_admin(user)] slaved [key_name_admin(borg)][ADMIN_FLW(borg)] to the AI [key_name_admin(newai)][ADMIN_FLW(newai)].") + log_admin("[key_name(user)] slaved [key_name(borg)] to the AI [key_name(newai)].") + else if (params["slavetoai"] == "null") + borg.notify_ai(DISCONNECT) + if(borg.shell) + borg.undeploy() + borg.connected_ai = null + message_admins("[key_name_admin(user)] freed [key_name_admin(borg)][ADMIN_FLW(borg)] from being slaved to an AI.") + log_admin("[key_name(user)] freed [key_name(borg)] from being slaved to an AI.") + if (borg.lawupdate) + borg.lawsync() + + . = TRUE diff --git a/code/modules/admin/verbs/buildmode.dm b/code/modules/admin/verbs/buildmode.dm index 3907c87bab..be95af9291 100644 --- a/code/modules/admin/verbs/buildmode.dm +++ b/code/modules/admin/verbs/buildmode.dm @@ -270,25 +270,20 @@ if(isturf(object) && left_click && !alt_click && !ctrl_click) var/turf/T = object if(isspaceturf(object)) - T.ChangeTurf(/turf/open/floor/plasteel) + T.PlaceOnTop(/turf/open/floor/plating) + else if(isplatingturf(object)) + T.PlaceOnTop(/turf/open/floor/plasteel) else if(isfloorturf(object)) - T.ChangeTurf(/turf/closed/wall) + T.PlaceOnTop(/turf/closed/wall) else if(iswallturf(object)) - T.ChangeTurf(/turf/closed/wall/r_wall) - T.assemble_baseturfs(initial(T.baseturfs)) + T.PlaceOnTop(/turf/closed/wall/r_wall) log_admin("Build Mode: [key_name(user)] built [T] at ([T.x],[T.y],[T.z])") return else if(right_click) log_admin("Build Mode: [key_name(user)] deleted [object] at ([object.x],[object.y],[object.z])") - if(iswallturf(object)) + if(isturf(object)) var/turf/T = object - T.ChangeTurf(/turf/open/floor/plasteel) - else if(isfloorturf(object)) - var/turf/T = object - T.ChangeTurf(/turf/open/space) - else if(istype(object, /turf/closed/wall/r_wall)) - var/turf/T = object - T.ChangeTurf(/turf/closed/wall) + T.ScrapeAway() else if(isobj(object)) qdel(object) return @@ -296,29 +291,19 @@ log_admin("Build Mode: [key_name(user)] built an airlock at ([object.x],[object.y],[object.z])") new/obj/machinery/door/airlock(get_turf(object)) else if(isturf(object) && ctrl_click && left_click) - switch(build_dir) - if(NORTH) - var/obj/structure/window/reinforced/WIN = new/obj/structure/window/reinforced(get_turf(object)) - WIN.setDir(NORTH) - if(SOUTH) - var/obj/structure/window/reinforced/WIN = new/obj/structure/window/reinforced(get_turf(object)) - WIN.setDir(SOUTH) - if(EAST) - var/obj/structure/window/reinforced/WIN = new/obj/structure/window/reinforced(get_turf(object)) - WIN.setDir(EAST) - if(WEST) - var/obj/structure/window/reinforced/WIN = new/obj/structure/window/reinforced(get_turf(object)) - WIN.setDir(WEST) - if(NORTHWEST) - var/obj/structure/window/reinforced/WIN = new/obj/structure/window/reinforced/fulltile(get_turf(object)) - WIN.setDir(NORTHWEST) + var/obj/structure/window/reinforced/window + if(build_dir == NORTHWEST) + window = new /obj/structure/window/reinforced/fulltile(get_turf(object)) + else + window = new /obj/structure/window/reinforced(get_turf(object)) + window.setDir(build_dir) log_admin("Build Mode: [key_name(user)] built a window at ([object.x],[object.y],[object.z])") if(ADV_BUILDMODE) if(left_click) if(ispath(objholder, /turf)) var/turf/T = get_turf(object) log_admin("Build Mode: [key_name(user)] modified [T] ([T.x],[T.y],[T.z]) to [objholder]") - T.ChangeTurf(objholder) + T.PlaceOnTop(objholder) else var/obj/A = new objholder (get_turf(object)) A.setDir(build_dir) diff --git a/code/modules/admin/verbs/getlogs.dm b/code/modules/admin/verbs/getlogs.dm index 062d045862..5f7b7becc6 100644 --- a/code/modules/admin/verbs/getlogs.dm +++ b/code/modules/admin/verbs/getlogs.dm @@ -4,7 +4,17 @@ set desc = "View/retrieve logfiles." set category = "Admin" - var/path = browse_files("data/logs/") + browseserverlogs() + +/client/proc/getcurrentlogs() + set name = "Get Current Logs" + set desc = "View/retrieve logfiles for the current round." + set category = "Admin" + + browseserverlogs("[GLOB.log_directory]/") + +/client/proc/browseserverlogs(path = "data/logs/") + path = browse_files(path) if(!path) return @@ -22,4 +32,4 @@ else return to_chat(src, "Attempting to send [path], this may take a fair few minutes if the file is very large.") - return + return \ No newline at end of file diff --git a/code/modules/admin/verbs/randomverbs.dm b/code/modules/admin/verbs/randomverbs.dm index c1061aff5d..83d4f64748 100644 --- a/code/modules/admin/verbs/randomverbs.dm +++ b/code/modules/admin/verbs/randomverbs.dm @@ -1001,25 +1001,6 @@ GLOBAL_LIST_EMPTY(custom_outfits) //Admin created outfits "} usr << browse(dat, "window=dressup;size=550x600") -/client/proc/toggle_antag_hud() - set category = "Admin" - set name = "Toggle AntagHUD" - set desc = "Toggles the Admin AntagHUD" - - if(!check_rights(R_ADMIN)) - return - - var/adding_hud = !has_antag_hud() - - for(var/datum/atom_hud/H in GLOB.huds) - if(istype(H, /datum/atom_hud/antag)) - (adding_hud) ? H.add_hud_to(usr) : H.remove_hud_from(usr) - - to_chat(usr, "You toggled your admin antag HUD [adding_hud ? "ON" : "OFF"].") - message_admins("[key_name_admin(usr)] toggled their admin antag HUD [adding_hud ? "ON" : "OFF"].") - log_admin("[key_name(usr)] toggled their admin antag HUD [adding_hud ? "ON" : "OFF"].") - SSblackbox.record_feedback("nested tally", "admin_toggle", 1, list("Toggle Antag HUD", "[adding_hud ? "Enabled" : "Disabled"]")) //If you are copy-pasting this, ensure the 2nd parameter is unique to the new proc! - /client/proc/toggle_combo_hud() set category = "Admin" set name = "Toggle Combo HUD" diff --git a/code/modules/antagonists/blob/blob/blobs/blob_mobs.dm b/code/modules/antagonists/blob/blob/blobs/blob_mobs.dm index cb61eec921..69af4bf584 100644 --- a/code/modules/antagonists/blob/blob/blobs/blob_mobs.dm +++ b/code/modules/antagonists/blob/blob/blobs/blob_mobs.dm @@ -120,6 +120,7 @@ health = maxHealth name = "blob zombie" desc = "A shambling corpse animated by the blob." + mob_biotypes += MOB_HUMANOID melee_damage_lower += 8 melee_damage_upper += 11 movement_type = GROUND diff --git a/code/modules/antagonists/borer/borer.dm b/code/modules/antagonists/borer/borer.dm deleted file mode 100644 index 4bcbaa455e..0000000000 --- a/code/modules/antagonists/borer/borer.dm +++ /dev/null @@ -1,1099 +0,0 @@ -/mob/living/captive_brain - name = "host brain" - real_name = "host brain" - -/mob/living/captive_brain/say(var/message) - - if(client) - if(client.prefs.muted & MUTE_IC) - to_chat(src, "You cannot speak in IC (muted).") - return - if(client.handle_spam_prevention(message,MUTE_IC)) - return - - if(isborer(loc)) - - message = sanitize(message) - if(!message) - return - log_say("[key_name(src)] : [message]") - if(stat == 2) - return say_dead(message) - - var/mob/living/simple_animal/borer/B = loc - to_chat(src, "You whisper silently, \"[message]\"") - to_chat(B.victim, "The captive mind of [src] whispers, \"[message]\"") - - for (var/mob/M in GLOB.player_list) - if(isnewplayer(M)) - continue - else if(M.stat == 2 && M.client.prefs.toggles & CHAT_GHOSTEARS) - to_chat(M, "Thought-speech, [src] -> [B.truename]: [message]") - -/mob/living/captive_brain/emote(var/message) - return - -/mob/living/captive_brain/resist() - - var/mob/living/simple_animal/borer/B = loc - - to_chat(src, "You begin doggedly resisting the parasite's control (this will take approximately 40 seconds).") - to_chat(B.victim, "You feel the captive mind of [src] begin to resist your control.") - - var/delay = rand(150,250) + B.victim.getBrainLoss() - addtimer(CALLBACK(src, .proc/return_control, src.loc), delay) - -/mob/living/captive_brain/proc/return_control(mob/living/simple_animal/borer/B) - if(!B || !B.controlling) - return - - B.victim.adjustBrainLoss(rand(5,10)) - to_chat(src, "With an immense exertion of will, you regain control of your body!") - to_chat(B.victim, "You feel control of the host brain ripped from your grasp, and retract your probosci before the wild neural impulses can damage you.") - B.detatch() - -GLOBAL_LIST_EMPTY(borers) -GLOBAL_VAR_INIT(total_borer_hosts_needed, 10) - -/mob/living/simple_animal/borer - name = "cortical borer" - real_name = "cortical borer" - desc = "A small, quivering, slug-like creature." - icon = 'icons/mob/borer.dmi' - icon_state = "brainslug" - icon_living = "brainslug" - icon_dead = "brainslug_dead" - health = 20 - maxHealth = 20 - melee_damage_lower = 5 - melee_damage_upper = 5 - stop_automated_movement = TRUE - attacktext = "chomps" - attack_sound = 'sound/weapons/bite.ogg' - pass_flags = PASSTABLE | PASSMOB - mob_size = MOB_SIZE_SMALL - faction = list("creature") - ventcrawler = VENTCRAWLER_ALWAYS - atmos_requirements = list("min_oxy" = 0, "max_oxy" = 0, "min_tox" = 0, "max_tox" = 0, "min_co2" = 0, "max_co2" = 0, "min_n2" = 0, "max_n2" = 0) - minbodytemp = 0 - maxbodytemp = 1500 - - var/generation = 1 - var/static/list/borer_names = list( - "Primary", "Secondary", "Tertiary", "Quaternary", "Quinary", "Senary", - "Septenary", "Octonary", "Novenary", "Decenary", "Undenary", "Duodenary", - ) - - var/mob/living/carbon/victim = null - var/mob/living/captive_brain/host_brain = null - var/truename - var/docile = FALSE - var/bonding = FALSE - var/controlling = FALSE - var/chemicals = 10 - var/used_dominate - var/borer_chems = list() - var/leaving = FALSE - var/hiding = FALSE - var/waketimerid = null - - var/docile_chem = "sugar" - var/list/wakeup_objectives = list() //Used to store objectives until the borer wakes up - - var/datum/action/innate/borer/talk_to_host/talk_to_host_action = new - var/datum/action/innate/borer/infest_host/infest_host_action = new - var/datum/action/innate/borer/toggle_hide/toggle_hide_action = new - var/datum/action/innate/borer/talk_to_borer/talk_to_borer_action = new - var/datum/action/innate/borer/talk_to_brain/talk_to_brain_action = new - var/datum/action/innate/borer/take_control/take_control_action = new - var/datum/action/innate/borer/give_back_control/give_back_control_action = new - var/datum/action/innate/borer/leave_body/leave_body_action = new - var/datum/action/innate/borer/make_chems/make_chems_action = new - var/datum/action/innate/borer/make_larvae/make_larvae_action = new - var/datum/action/innate/borer/freeze_victim/freeze_victim_action = new - var/datum/action/innate/borer/punish_victim/punish_victim_action = new - var/datum/action/innate/borer/jumpstart_host/jumpstart_host_action = new - - var/is_team_borer = TRUE - var/borer_alert = "Become a cortical borer? (Warning, You can no longer be cloned!)" - -/mob/living/simple_animal/borer/Initialize(mapload, gen=1) - ..() - generation = gen - if(is_team_borer) - notify_ghosts("A cortical borer has been created in [get_area(src)]!", enter_link = "(Click to enter)", source = src, action = NOTIFY_ATTACK) - real_name = "Cortical Borer [rand(1000,9999)]" - truename = "[borer_names[min(generation, borer_names.len)]] [rand(1000,9999)]" - borer_chems += /datum/borer_chem/epinephrine - borer_chems += /datum/borer_chem/leporazine - borer_chems += /datum/borer_chem/mannitol - borer_chems += /datum/borer_chem/bicaridine - borer_chems += /datum/borer_chem/kelotane - borer_chems += /datum/borer_chem/charcoal - borer_chems += /datum/borer_chem/methamphetamine - borer_chems += /datum/borer_chem/salbutamol - borer_chems += /datum/borer_chem/spacedrugs - //borer_chems += /datum/borer_chem/creagent - borer_chems += /datum/borer_chem/ethanol - borer_chems += /datum/borer_chem/rezadone - borer_chems += /datum/borer_chem/crocin - borer_chems += /datum/borer_chem/camphor - - GLOB.borers += src - - GrantBorerActions() - -/mob/living/simple_animal/borer/Destroy() - GLOB.borers -= src - - host_brain = null - victim = null - - QDEL_NULL(talk_to_host_action) - QDEL_NULL(infest_host_action) - QDEL_NULL(toggle_hide_action) - QDEL_NULL(talk_to_borer_action) - QDEL_NULL(talk_to_brain_action) - QDEL_NULL(take_control_action) - QDEL_NULL(give_back_control_action) - QDEL_NULL(leave_body_action) - QDEL_NULL(make_chems_action) - QDEL_NULL(make_larvae_action) - QDEL_NULL(freeze_victim_action) - QDEL_NULL(punish_victim_action) - QDEL_NULL(jumpstart_host_action) - - return ..() - -/mob/living/simple_animal/borer/Topic(href, href_list)//not entirely sure if this is even required - if(href_list["ghostjoin"]) - var/mob/dead/observer/ghost = usr - if(istype(ghost)) - attack_ghost(ghost) - -/mob/living/simple_animal/borer/attack_ghost(mob/user) - if(jobban_isbanned(user, ROLE_BORER) || jobban_isbanned(user, "Syndicate")) - return - if(key) - return - if(stat != CONSCIOUS) - return - var/be_borer = alert(borer_alert,,"Yes","No") - if(be_borer == "No" || !src || QDELETED(src)) - return - if(key) - return - transfer_personality(user.client) - -/mob/living/simple_animal/borer/Stat() - ..() - - if(statpanel("Status")) - stat(null, "Chemicals: [chemicals]") - - src << output(chemicals, "ViewBorer\ref[src]Chems.browser:update_chemicals") - -/mob/living/simple_animal/borer/verb/Communicate() - set category = "Borer" - set name = "Converse with Host" - set desc = "Send a silent message to your host." - - if(!victim) - to_chat(src, "You do not have a host to communicate with!") - return - - if(stat) - to_chat(src, "You cannot do that in your current state.") - return - - var/input = stripped_input(src, "Please enter a message to tell your host.", "Borer", null) - if(!input) - return - - if(src && !QDELETED(src) && !QDELETED(victim)) - var/say_string = (docile) ? "slurs" :"states" - if(victim) - to_chat(victim, "[truename] [say_string]: [input]") - log_say("Borer Communication: [key_name(src)] -> [key_name(victim)] : [input]") - for(var/M in GLOB.dead_mob_list) - if(isobserver(M)) - var/rendered = "Borer Communication from [truename] : [input]" - var/link = FOLLOW_LINK(M, src) - to_chat(M, "[link] [rendered]") - to_chat(src, "[truename] [say_string]: [input]") - victim.verbs += /mob/living/proc/borer_comm - talk_to_borer_action.Grant(victim) - -/mob/living/proc/borer_comm() - set name = "Converse with Borer" - set category = "Borer" - set desc = "Communicate mentally with your borer." - - - var/mob/living/simple_animal/borer/B = has_brain_worms() - if(!B) - return - - var/input = stripped_input(src, "Please enter a message to tell the borer.", "Message", null) - if(!input) - return - - to_chat(B, "[src] says: [input]") - log_say("Borer Communication: [key_name(src)] -> [key_name(B)] : [input]") - - for(var/M in GLOB.dead_mob_list) - if(isobserver(M)) - var/rendered = "Borer Communication from [src] : [input]" - var/link = FOLLOW_LINK(M, src) - to_chat(M, "[link] [rendered]") - to_chat(src, "[src] says: [input]") - -/mob/living/proc/trapped_mind_comm() - set name = "Converse with Trapped Mind" - set category = "Borer" - set desc = "Communicate mentally with the trapped mind of your host." - - - var/mob/living/simple_animal/borer/B = has_brain_worms() - if(!B || !B.host_brain) - return - var/mob/living/captive_brain/CB = B.host_brain - var/input = stripped_input(src, "Please enter a message to tell the trapped mind.", "Message", null) - if(!input) - return - - to_chat(CB, "[B.truename] says: [input]") - log_say("Borer Communication: [key_name(B)] -> [key_name(CB)] : [input]") - - for(var/M in GLOB.dead_mob_list) - if(isobserver(M)) - var/rendered = "Borer Communication from [B] : [input]" - var/link = FOLLOW_LINK(M, src) - to_chat(M, "[link] [rendered]") - to_chat(src, "[B.truename] says: [input]") - -/mob/living/simple_animal/borer/Life() - - ..() - - if(victim) - if(stat != DEAD) - if(victim.stat == DEAD) - chemicals++ - else if(chemicals < 250) - chemicals+=2 - chemicals = min(250, chemicals) - - - if(stat != DEAD && victim.stat != DEAD) - - if(victim.reagents.has_reagent(docile_chem)) - if(!docile || waketimerid) - if(controlling) - to_chat(victim, "You feel the soporific flow of [docile_chem] in your host's blood, lulling you into docility.") - else - to_chat(src, "You feel the soporific flow of [docile_chem] in your host's blood, lulling you into docility.") - if(waketimerid) - deltimer(waketimerid) - waketimerid = null - docile = TRUE - else - if(docile && !waketimerid) - if(controlling) - to_chat(victim, "You start shaking off your lethargy as the [docile_chem] leaves your host's blood. This will take about 10 seconds...") - else - to_chat(src, "You start shaking off your lethargy as the [docile_chem] leaves your host's blood. This will take about 10 seconds...") - - waketimerid = addtimer(CALLBACK(src, "wakeup"), 10, TIMER_STOPPABLE) - if(controlling) - - if(docile) - to_chat(victim, "You are feeling far too docile to continue controlling your host...") - victim.release_control() - return - - if(prob(5)) - victim.adjustBrainLoss(rand(1,2)) - - if(prob(victim.getBrainLoss()/10)) - victim.say("*[pick(list("blink","blink_r","choke","aflap","drool","twitch","twitch_s","gasp"))]") - -/mob/living/simple_animal/borer/proc/wakeup() - if(controlling) - to_chat(victim, "You finish shaking off your lethargy.") - else - to_chat(src, "You finish shaking off your lethargy.") - docile = FALSE - if(waketimerid) - waketimerid = null - -/mob/living/simple_animal/borer/say(message) - if(dd_hasprefix(message, ";")) - message = copytext(message,2) - for(var/borer in GLOB.borers) - to_chat(borer, "Cortical Link: [truename] sings, \"[message]\"") - for(var/mob/D in GLOB.dead_mob_list) - to_chat(D, "Cortical Link: [truename] sings, \"[message]\"") - return - if(!victim) - to_chat(src, "You cannot speak without a host!") - return - if(message == "") - return - -/mob/living/simple_animal/borer/UnarmedAttack(atom/A) - if(isliving(A)) - healthscan(usr, A) - chemscan(usr, A) - -/mob/living/simple_animal/borer/ex_act() - if(victim) - return - - ..() - -/mob/living/simple_animal/borer/verb/infect_victim() - set name = "Infest" - set category = "Borer" - set desc = "Infest a suitable humanoid host." - - if(victim) - to_chat(src, "You are already within a host.") - - if(stat == DEAD) - return - - var/list/choices = list() - for(var/mob/living/carbon/H in view(1,src)) - if(H!=src && Adjacent(H)) - choices += H - - if(!choices.len) - return - var/mob/living/carbon/H = choices.len > 1 ? input(src,"Who do you wish to infest?") in null|choices : choices[1] - if(!H || !src) - return - - if(!Adjacent(H)) - return FALSE - - if(stat != CONSCIOUS) - to_chat(src, "You cannot do that in your current state.") - return FALSE - - if(H.has_brain_worms()) - to_chat(src, "[victim] is already infested!") - return - - to_chat(src, "You slither up [H] and begin probing at their ear canal...") - if(!do_mob(src, H, 30)) - to_chat(src, "As [H] moves away, you are dislodged and fall to the ground.") - return - - if(!H || !src) - return - - Infect(H) - -/mob/living/simple_animal/borer/proc/Infect(mob/living/carbon/C) - - if(!C) - return - - if(C.has_brain_worms()) - to_chat(src, "[C] is already infested!") - return - - if(!C.key || !C.mind) - to_chat(src, "[C]'s mind seems unresponsive. Try someone else!") - return - - if(C && C.dna && istype(C.dna.species, /datum/species/skeleton)) - to_chat(src, "[C] does not possess the vital systems needed to support us.") - return - - victim = C - forceMove(victim) - - - RemoveBorerActions() - GrantInfestActions() - - log_game("[src]/([src.ckey]) has infested [victim]/([victim.ckey]") - -/mob/living/simple_animal/borer/verb/secrete_chemicals() - set category = "Borer" - set name = "Secrete Chemicals" - set desc = "Push some chemicals into your host's bloodstream." - - if(!victim) - to_chat(src, "You are not inside a host body.") - return - - if(stat != CONSCIOUS) - to_chat(src, "You cannot secrete chemicals in your current state.") - - if(docile) - to_chat(src, "You are feeling far too docile to do that.") - return - - var content = "" - content += "

Chemicals: [chemicals]

" - - content += "" - - for(var/datum in typesof(/datum/borer_chem)) - var/datum/borer_chem/C = new datum() - if(C.chemname) - content += "" - - content += "
[C.chemname] ([C.chemuse])

[C.chem_desc]

" - - var/html = get_html_template(content) - - usr << browse(null, "window=ViewBorer\ref[src]Chems;size=600x800") - usr << browse(html, "window=ViewBorer\ref[src]Chems;size=600x800") - - return - -/mob/living/simple_animal/borer/verb/hide() - set category = "Borer" - set name = "Hide" - set desc = "Become invisible to the common eye." - - if(victim) - to_chat(src, "You cannot do this while you're inside a host.") - - if(stat != CONSCIOUS) - return - - if(!hiding) - layer = LATTICE_LAYER - visible_message("[src] scurries to the ground!", \ - "You are now hiding.") - hiding = TRUE - else - layer = MOB_LAYER - visible_message("[src] slowly peaks up from the ground...", \ - "You stop hiding.") - hiding = FALSE - -/mob/living/simple_animal/borer/verb/dominate_victim() - set category = "Borer" - set name = "Paralyze Victim" - set desc = "Freeze the limbs of a potential host with supernatural fear." - - if(world.time - used_dominate < 150) - to_chat(src, "You cannot use that ability again so soon.") - return - - if(victim) - to_chat(src, "You cannot do that from within a host body.") - return - - if(stat != CONSCIOUS) - to_chat(src, "You cannot do that in your current state.") - return - - var/list/choices = list() - for(var/mob/living/carbon/C in view(1,src)) - if(C.stat == CONSCIOUS) - choices += C - - if(!choices.len) - return - var/mob/living/carbon/M = choices.len > 1 ? input(src,"Who do you wish to dominate?") in null|choices : choices[1] - - - if(!M || !src || stat != CONSCIOUS || victim || (world.time - used_dominate < 150)) - return - if(!Adjacent(M)) - return - - if(M.has_brain_worms()) - to_chat(src, "You cannot paralyze someone who is already infested!") - return - - layer = MOB_LAYER - - to_chat(src, "You focus your psychic lance on [M] and freeze their limbs with a wave of terrible dread.") - to_chat(M, "You feel a creeping, horrible sense of dread come over you, freezing your limbs and setting your heart racing.") - M.Stun(60) - - used_dominate = world.time - -/mob/living/simple_animal/borer/verb/release_victim() - set category = "Borer" - set name = "Release Host" - set desc = "Slither out of your host." - - if(!victim) - to_chat(src, "You are not inside a host body.") - return - - if(stat != CONSCIOUS) - to_chat(src, "You cannot leave your host in your current state.") - - if(leaving) - leaving = FALSE - to_chat(src, "You decide against leaving your host.") - return - - to_chat(src, "You begin disconnecting from [victim]'s synapses and prodding at their internal ear canal.") - - if(victim.stat != DEAD) - to_chat(victim, "An odd, uncomfortable pressure begins to build inside your skull, behind your ear...") - - leaving = TRUE - - addtimer(CALLBACK(src, .proc/release_host), 100) - -/mob/living/simple_animal/borer/proc/release_host() - if(!victim || !src || QDELETED(victim) || QDELETED(src)) - return - if(!leaving) - return - if(controlling) - return - - if(stat != CONSCIOUS) - to_chat(src, "You cannot release your host in your current state.") - return - - to_chat(src, "You wiggle out of [victim]'s ear and plop to the ground.") - if(victim.mind) - to_chat(victim, "Something slimy wiggles out of your ear and plops to the ground!") - to_chat(victim, "As though waking from a dream, you shake off the insidious mind control of the brain worm. Your thoughts are your own again.") - - leaving = FALSE - - leave_victim() - -/mob/living/simple_animal/borer/proc/leave_victim() - if(!victim) - return - - if(controlling) - detatch() - - GrantBorerActions() - RemoveInfestActions() - - forceMove(get_turf(victim)) - - reset_perspective(null) - machine = null - - victim.reset_perspective(null) - victim.machine = null - - var/mob/living/V = victim - V.verbs -= /mob/living/proc/borer_comm - talk_to_borer_action.Remove(victim) - victim = null - return - -/mob/living/simple_animal/borer/verb/jumpstart() - set category = "Borer" - set name = "Jumpstart Host" - set desc = "Bring your host back to life." - - if(!victim) - to_chat(src, "You need a host to be able to use this.") - return - - if(docile) - to_chat(src, "You are feeling too docile to use this!") - return - - if(victim.stat != DEAD) - to_chat(src, "Your host is already alive!") - return - - if(chemicals < 250) - to_chat(src, "You need 250 chemicals to use this!") - return - - if(victim.stat == DEAD) - victim.tod = null - victim.setToxLoss(0) - victim.setOxyLoss(0) - victim.setCloneLoss(0) - victim.SetUnconscious(0) - victim.SetStun(0) - victim.SetKnockdown(0) - victim.radiation = 0 - victim.heal_overall_damage(victim.getBruteLoss(), victim.getFireLoss()) - victim.reagents.clear_reagents() - if(ishuman(victim)) - var/mob/living/carbon/human/H = victim - H.restore_blood() - H.remove_all_embedded_objects() - victim.revive() - log_game("[src]/([src.ckey]) has revived [victim]/([victim.ckey]") - chemicals -= 250 - to_chat(src, "You send a jolt of energy to your host, reviving them!") - victim.grab_ghost(force = TRUE) //brings the host back, no eggscape - to_chat(victim, "You bolt upright, gasping for breath!") - -/mob/living/simple_animal/borer/verb/bond_brain() - set category = "Borer" - set name = "Assume Control" - set desc = "Fully connect to the brain of your host." - - if(!victim) - to_chat(src, "You are not inside a host body.") - return - - if(stat != CONSCIOUS) - to_chat(src, "You cannot do that in your current state.") - return - - if(docile) - to_chat(src, "You are feeling far too docile to do that.") - return - - if(victim.stat == DEAD) - to_chat(src, "This host lacks enough brain function to control.") - return - - if(bonding) - bonding = FALSE - to_chat(src, "You stop attempting to take control of your host.") - return - - to_chat(src, "You begin delicately adjusting your connection to the host brain...") - - if(QDELETED(src) || QDELETED(victim)) - return - - bonding = TRUE - - var/delay = 200+(victim.getBrainLoss()*5) - addtimer(CALLBACK(src, .proc/assume_control), delay) - -/mob/living/simple_animal/borer/proc/assume_control() - if(!victim || !src || controlling || victim.stat == DEAD) - return - if(!bonding) - return - if(docile) - to_chat(src, "You are feeling far too docile to do that.") - return - if(is_servant_of_ratvar(victim) || iscultist(victim) || victim.isloyal()) - to_chat(src, "[victim]'s mind seems to be blocked by some unknown force!") - return - - else - - log_game("[src]/([src.ckey]) assumed control of [victim]/([victim.ckey] with borer powers.") - to_chat(src, "You plunge your probosci deep into the cortex of the host brain, interfacing directly with their nervous system.") - to_chat(victim, "You feel a strange shifting sensation behind your eyes as an alien consciousness displaces yours.") - - // host -> brain - var/h2b_id = victim.computer_id - var/h2b_ip= victim.lastKnownIP - victim.computer_id = null - victim.lastKnownIP = null - - qdel(host_brain) - host_brain = new(src) - - host_brain.ckey = victim.ckey - - host_brain.name = victim.name - - if(victim.mind) - host_brain.mind = victim.mind - - if(!host_brain.computer_id) - host_brain.computer_id = h2b_id - - if(!host_brain.lastKnownIP) - host_brain.lastKnownIP = h2b_ip - - to_chat(host_brain, "You are trapped in your own mind. You feel that there must be a way to resist!") - - // self -> host - var/s2h_id = src.computer_id - var/s2h_ip= src.lastKnownIP - src.computer_id = null - src.lastKnownIP = null - - victim.ckey = src.ckey - victim.mind = src.mind - - if(!victim.computer_id) - victim.computer_id = s2h_id - - if(!victim.lastKnownIP) - victim.lastKnownIP = s2h_ip - - bonding = FALSE - controlling = TRUE - - victim.verbs += /mob/living/carbon/proc/release_control - if(is_team_borer) - victim.verbs += /mob/living/carbon/proc/spawn_larvae - victim.verbs -= /mob/living/proc/borer_comm - victim.verbs += /mob/living/proc/trapped_mind_comm - GrantControlActions() - talk_to_borer_action.Remove(victim) - - victim.med_hud_set_status() - -/mob/living/simple_animal/borer/verb/punish() - set category = "Borer" - set name = "Punish" - set desc = "Punish your victim." - - if(!victim) - to_chat(src, "You are not inside a host body.") - return - - if(stat != CONSCIOUS) - to_chat(src, "You cannot do that in your current state.") - return - - if(docile) - to_chat(src, "You are feeling far too docile to do that.") - return - - if(chemicals < 75) - to_chat(src, "You need 75 chems to punish your host.") - return - - var/punishment = input("Select a punishment:.", "Punish") as null|anything in list("Blindness","Deafness","Stun") - - if(!punishment) - return - - if(chemicals < 75) - to_chat(src, "You need 75 chems to punish your host.") - return - - switch(punishment) //Hardcoding this stuff. - if("Blindness") - victim.blind_eyes(4) - to_chat(victim, "Your vision fades away suddenly, as your borer robs you of your sight.") - if("Deafness") - victim.minimumDeafTicks(40) - to_chat(victim, "Your hearing fades away suddenly, as your borer robs you of your hearing.") - if("Stun") - victim.Knockdown(100) - to_chat(victim, "You are wracked with unbearable pain, as your borer takes control of your pain-center!") - - log_game("[src]/([src.ckey]) punished [victim]/([victim.ckey] with [punishment]") - - chemicals -= 75 - - -/mob/living/carbon/proc/release_control() - - set category = "Borer" - set name = "Release Control" - set desc = "Release control of your host's body." - - var/mob/living/simple_animal/borer/B = has_brain_worms() - if(B && B.host_brain) - to_chat(src, "You withdraw your probosci, releasing control of [B.host_brain]") - - B.detatch() - -//Check for brain worms in head. -/mob/proc/has_brain_worms() - - for(var/I in contents) - if(isborer(I)) - return I - - return FALSE - -/mob/living/carbon/proc/spawn_larvae() - set category = "Borer" - set name = "Reproduce" - set desc = "Spawn several young." - - var/mob/living/simple_animal/borer/B = has_brain_worms() - - if(isbrain(src)) - to_chat(src, "You need a mouth to be able to do this.") - return - if(!B) - return - - if(B.chemicals >= 200) - visible_message("[src] heaves violently, expelling a rush of vomit and a wriggling, sluglike creature!") - B.chemicals -= 200 - - new /obj/effect/decal/cleanable/vomit(get_turf(src)) - playsound(loc, 'sound/effects/splat.ogg', 50, 1) - var/mob/living/simple_animal/borer/Baby = new /mob/living/simple_animal/borer(get_turf(src), B.generation + 1) - - Baby.wakeup_objectives = src.mind.objectives //Save them for later, since we lack a mind for them right now - - log_game("[src]/([src.ckey]) has spawned a new borer via reproducing.") - else - to_chat(src, "You need 200 chemicals stored to reproduce.") - return - - -/mob/living/simple_animal/borer/proc/transfer_personality(var/client/candidate) - if(!candidate || !candidate.mob) - return - - if(!QDELETED(candidate) || !QDELETED(candidate.mob)) - var/datum/mind/M = create_borer_mind(candidate.ckey) - M.transfer_to(src) - - candidate.mob = src - ckey = candidate.ckey - - to_chat(src, "You are a cortical borer!") - to_chat(src, "You are a brain slug that worms its way into the head of its victim. Use stealth, persuasion and your powers of mind control to keep you, your host and your eventual spawn safe and warm.") - to_chat(src, "[docile_chem] nullifies your abilities, avoid it at all costs!") - to_chat(src, "You can speak to your fellow borers by prefixing your messages with ';'. Check out your Borer tab to see your abilities.") - - if(mind) - if(!(wakeup_objectives.len)) //No objectives, use default? - var/datum/objective/normal_borer/new_objective - new_objective = new /datum/objective/normal_borer - new_objective.owner = mind - new_objective.target_amount = GLOB.total_borer_hosts_needed - new_objective.explanation_text = "You must escape with at least [GLOB.total_borer_hosts_needed] borer[new_objective.target_amount > 1 ? "s" : ""] with host[new_objective.target_amount > 1 ? "s" : ""] on the shuttle." - mind.objectives += new_objective - to_chat(src, "Objective #1: [new_objective.explanation_text]") - else - mind.objectives += wakeup_objectives - var/count = 1 - for(var/datum/objective/O in mind.objectives) - to_chat(src, "Objective #[count]: [O.explanation_text]") - count++ - -/mob/living/simple_animal/borer/proc/detatch() - if(!victim || !controlling) - return - - controlling = FALSE - - victim.verbs -= /mob/living/carbon/proc/release_control - if(is_team_borer) - victim.verbs -= /mob/living/carbon/proc/spawn_larvae - victim.verbs += /mob/living/proc/borer_comm - victim.verbs -= /mob/living/proc/trapped_mind_comm - RemoveControlActions() - talk_to_borer_action.Grant(victim) - - victim.med_hud_set_status() - - if(host_brain) - - // these are here so bans and multikey warnings are not triggered on the wrong people when ckey is changed. - // computer_id and IP are not updated magically on their own in offline mobs -walter0o - - // host -> self - var/h2s_id = victim.computer_id - var/h2s_ip= victim.lastKnownIP - victim.computer_id = null - victim.lastKnownIP = null - - ckey = victim.ckey - mind = victim.mind - - - if(!computer_id) - computer_id = h2s_id - - if(!host_brain.lastKnownIP) - lastKnownIP = h2s_ip - - // brain -> host - var/b2h_id = host_brain.computer_id - var/b2h_ip= host_brain.lastKnownIP - host_brain.computer_id = null - host_brain.lastKnownIP = null - - victim.ckey = host_brain.ckey - - victim.mind = host_brain.mind - - if(!victim.computer_id) - victim.computer_id = b2h_id - - if(!victim.lastKnownIP) - victim.lastKnownIP = b2h_ip - - log_game("[src]/([src.ckey]) released control of [victim]/([victim.ckey]") - - qdel(host_brain) - -/proc/create_borer_mind(key) - var/datum/mind/M = new /datum/mind(key) - M.assigned_role = "Cortical Borer" - M.special_role = "Cortical Borer" - return M - -/mob/living/simple_animal/borer/proc/GrantBorerActions() - infest_host_action.Grant(src) - toggle_hide_action.Grant(src) - freeze_victim_action.Grant(src) - -/mob/living/simple_animal/borer/proc/RemoveBorerActions() - infest_host_action.Remove(src) - toggle_hide_action.Remove(src) - freeze_victim_action.Remove(src) - -/mob/living/simple_animal/borer/proc/GrantInfestActions() - talk_to_host_action.Grant(src) - leave_body_action.Grant(src) - take_control_action.Grant(src) - punish_victim_action.Grant(src) - make_chems_action.Grant(src) - jumpstart_host_action.Grant(src) - -/mob/living/simple_animal/borer/proc/RemoveInfestActions() - talk_to_host_action.Remove(src) - take_control_action.Remove(src) - leave_body_action.Remove(src) - punish_victim_action.Remove(src) - make_chems_action.Remove(src) - jumpstart_host_action.Remove(src) - -/mob/living/simple_animal/borer/proc/GrantControlActions() - talk_to_brain_action.Grant(victim) - give_back_control_action.Grant(victim) - make_larvae_action.Grant(victim) - -/mob/living/simple_animal/borer/proc/RemoveControlActions() - talk_to_brain_action.Remove(victim) - make_larvae_action.Remove(victim) - give_back_control_action.Remove(victim) - -/datum/action/innate/borer - background_icon_state = "bg_alien" - -/datum/action/innate/borer/talk_to_host - name = "Converse with Host" - desc = "Send a silent message to your host." - button_icon_state = "alien_whisper" - -/datum/action/innate/borer/talk_to_host/Activate() - var/mob/living/simple_animal/borer/B = owner - B.Communicate() - -/datum/action/innate/borer/infest_host - name = "Infest" - desc = "Infest a suitable humanoid host." - button_icon_state = "infest" - -/datum/action/innate/borer/infest_host/Activate() - var/mob/living/simple_animal/borer/B = owner - B.infect_victim() - -/datum/action/innate/borer/toggle_hide - name = "Toggle Hide" - desc = "Become invisible to the common eye. Toggled on or off." - button_icon_state = "borer_hiding_false" - -/datum/action/innate/borer/toggle_hide/Activate() - var/mob/living/simple_animal/borer/B = owner - B.hide() - button_icon_state = "borer_hiding_[B.hiding ? "true" : "false"]" - UpdateButtonIcon() - -/datum/action/innate/borer/talk_to_borer - name = "Converse with Borer" - desc = "Communicate mentally with your borer." - button_icon_state = "alien_whisper" - -/datum/action/innate/borer/talk_to_borer/Activate() - var/mob/living/simple_animal/borer/B = owner.has_brain_worms() - B.victim = owner - B.victim.borer_comm() - - -/datum/action/innate/borer/talk_to_brain - name = "Converse with Trapped Mind" - desc = "Communicate mentally with the trapped mind of your host." - button_icon_state = "alien_whisper" - -/datum/action/innate/borer/talk_to_brain/Activate() - var/mob/living/simple_animal/borer/B = owner.has_brain_worms() - B.victim = owner - B.victim.trapped_mind_comm() - -/datum/action/innate/borer/take_control - name = "Assume Control" - desc = "Fully connect to the brain of your host." - button_icon_state = "borer_brain" - -/datum/action/innate/borer/take_control/Activate() - var/mob/living/simple_animal/borer/B = owner - B.bond_brain() - -/datum/action/innate/borer/give_back_control - name = "Release Control" - desc = "Release control of your host's body." - button_icon_state = "borer_leave" - -/datum/action/innate/borer/give_back_control/Activate() - var/mob/living/simple_animal/borer/B = owner.has_brain_worms() - B.victim = owner - B.victim.release_control() - -/datum/action/innate/borer/leave_body - name = "Release Host" - desc = "Slither out of your host." - button_icon_state = "borer_leave" - -/datum/action/innate/borer/leave_body/Activate() - var/mob/living/simple_animal/borer/B = owner - B.release_victim() - -/datum/action/innate/borer/make_chems - name = "Secrete Chemicals" - desc = "Push some chemicals into your host's bloodstream." - icon_icon = 'icons/obj/chemical.dmi' - button_icon_state = "minidispenser" - -/datum/action/innate/borer/make_chems/Activate() - var/mob/living/simple_animal/borer/B = owner - B.secrete_chemicals() - -/datum/action/innate/borer/make_larvae - name = "Reproduce" - desc = "Spawn several young." - button_icon_state = "borer_reproduce" - -/datum/action/innate/borer/make_larvae/Activate() - var/mob/living/simple_animal/borer/B = owner.has_brain_worms() - B.victim = owner - B.victim.spawn_larvae() - -/datum/action/innate/borer/freeze_victim - name = "Paralyze Victim" - desc = "Freeze the limbs of a potential host with supernatural fear." - button_icon_state = "freeze" - -/datum/action/innate/borer/freeze_victim/Activate() - var/mob/living/simple_animal/borer/B = owner - B.dominate_victim() - -/datum/action/innate/borer/punish_victim - name = "Punish" - desc = "Punish your victim." - button_icon_state = "blind" - -/datum/action/innate/borer/punish_victim/Activate() - var/mob/living/simple_animal/borer/B = owner - B.punish() - -/datum/action/innate/borer/jumpstart_host - name = "Jumpstart Host" - desc = "Bring your host back to life." - icon_icon = 'icons/obj/items_and_weapons.dmi' - button_icon_state = "defibpaddles0" - -/datum/action/innate/borer/jumpstart_host/Activate() - var/mob/living/simple_animal/borer/B = owner - B.jumpstart() diff --git a/code/modules/antagonists/borer/borer_chemicals.dm b/code/modules/antagonists/borer/borer_chemicals.dm deleted file mode 100644 index c405468b4f..0000000000 --- a/code/modules/antagonists/borer/borer_chemicals.dm +++ /dev/null @@ -1,82 +0,0 @@ -/datum/borer_chem - var/chemname - var/chem_desc = "This is a chemical" - var/chem_message //Text sent to the host when injecting chemicals - var/chemuse = 30 - var/quantity = 10 - -/datum/borer_chem/epinephrine - chemname = "epinephrine" - chem_desc = "Stabilizes critical condition and slowly restores oxygen damage. If overdosed, it will deal toxin and oxyloss damage." - chem_message = "You feel your energy being replenished and it becomes easier to breathe!" - -/datum/borer_chem/leporazine - chemname = "leporazine" - chem_desc = "This keeps a patient's body temperature stable. High doses can allow short periods of unprotected EVA." - chemuse = 75 - chem_message = "You no longer feel heat or cold, as leporazine floods your system." - -/datum/borer_chem/mannitol - chemname = "mannitol" - chem_desc = "Heals brain damage." - chem_message = "You feel your mind focus more easily, as your system is flooded with mannitol." - -/datum/borer_chem/bicaridine - chemname = "bicaridine" - chem_desc = "Heals brute damage." - chem_message = "A wave of flesh-knitting bicaridine flows through your bloodstream." - -/datum/borer_chem/kelotane - chemname = "kelotane" - chem_desc = "Heals burn damage." - chem_message = "A stream of burn-healing kelotane spreads throughout your body." - -/datum/borer_chem/charcoal - chemname = "charcoal" - chem_desc = "Slowly heals toxin damage, will also slowly remove any other chemicals." - chem_message = "A measure of toxin-purging charcoal cleanses your bloodstream." - -/datum/borer_chem/methamphetamine - chemname = "methamphetamine" - chem_desc = "Reduces stun times, increases stamina and run speed while dealing brain damage. If overdosed it will deal toxin and brain damage." - chemuse = 50 - quantity = 9 - chem_message = "Your mind races, your heartrate skyrockets as methamphetamines enters your bloodstream!" - -/datum/borer_chem/salbutamol - chemname = "salbutamol" - chem_desc = "Heals suffocation damage." - chem_message = "Your breathing becomes lighter, as oxygen fills your lungs from the inside." - -/datum/borer_chem/spacedrugs - chemname = "space_drugs" - chem_desc = "Get your host high as a kite." - chemuse = 75 - chem_message = "You feel like you can taste the colours of the wind." - -/*/datum/borer_chem/creagent - chemname = "colorful_reagent" - chem_desc = "Change the colour of your host." - chemuse = 50 - chem_message = "Your body suddenly changes colour from the inside out."*/ - -/datum/borer_chem/ethanol - chemname = "ethanol" - chem_desc = "The most potent alcoholic 'beverage', with the fastest toxicity." - chemuse = 50 - chem_message = "You feel like you've downed a shot of 200 proof vodka." - -/datum/borer_chem/rezadone - chemname = "rezadone" - chem_desc = "Heals cellular damage." - chem_message = "You feel a warmth spread throughout your body as rezadone repairs corrupted DNA." - -/datum/borer_chem/crocin - chemname = "aphro" - chem_desc = "Increases host arousal without overdosing." - chem_message = "You feel your pulse quicken and your body begins to feel warmer." - -/datum/borer_chem/camphor - chemname = "anaphro" - chem_desc = "Decreases host arousal without overdosing." - chem_message = "Your pulse calms down and you feel more focused as the fog of lust clears." diff --git a/code/modules/antagonists/borer/borer_event.dm b/code/modules/antagonists/borer/borer_event.dm deleted file mode 100644 index 94af2f1be7..0000000000 --- a/code/modules/antagonists/borer/borer_event.dm +++ /dev/null @@ -1,49 +0,0 @@ -/datum/round_event_control/borer - name = "Borer" - typepath = /datum/round_event/borer - weight = 0 - max_occurrences = 0 - min_players = 20 //10 is MINIMUM needed, but this is not a gamemode that does well in lowpop - earliest_start = 24000 //40 min, double default timer - -/datum/round_event/borer - announceWhen = 2400 //Borers get 4 minutes till the crew tries to murder them. - var/successSpawn = 0 - - var/spawncount = 2 - -/datum/round_event/borer/setup() - spawncount = rand(2, 4) - -/datum/round_event/borer/announce() - if(successSpawn) - priority_announce("Unidentified lifesigns detected coming aboard [station_name()]. Secure any exterior access, including ducting and ventilation.", "Lifesign Alert", 'sound/AI/aliens.ogg') //Borers seem like normal xenomorphs. - - -/datum/round_event/borer/start() - - var/list/vents = list() - for(var/obj/machinery/atmospherics/components/unary/vent_pump/temp_vent in GLOB.machines) - if(QDELETED(temp_vent)) - continue - if(temp_vent.loc.z == SSmapping.station_start && !temp_vent.welded) - var/datum/pipeline/temp_vent_parent = temp_vent.parents[1] - if(temp_vent_parent.other_atmosmch.len > 20) - vents += temp_vent - - if(!vents.len) - message_admins("An event attempted to spawn a borer but no suitable vents were found. Shutting down.") - return kill() - - var/total_humans = 0 - for(var/mob/living/carbon/human/H in GLOB.mob_list) - if(H.stat != DEAD) - total_humans++ - - GLOB.total_borer_hosts_needed = round(1 + total_humans/6) - - while(spawncount >= 1 && vents.len) - var/obj/vent = pick_n_take(vents) - new /mob/living/simple_animal/borer(vent.loc) - successSpawn = TRUE - spawncount-- diff --git a/code/modules/antagonists/borer/borer_html.dm b/code/modules/antagonists/borer/borer_html.dm deleted file mode 100644 index e2544a1d0b..0000000000 --- a/code/modules/antagonists/borer/borer_html.dm +++ /dev/null @@ -1,125 +0,0 @@ - -/mob/living/simple_animal/borer/proc/get_html_template(content) - var/html = {" - - - Borer Chemicals - - - - - - - -
-

Borer Chemicals

-
- - [content] - -
"} - return html \ No newline at end of file diff --git a/code/modules/antagonists/borer/borer_topic.dm b/code/modules/antagonists/borer/borer_topic.dm deleted file mode 100644 index 80efefdaf8..0000000000 --- a/code/modules/antagonists/borer/borer_topic.dm +++ /dev/null @@ -1,42 +0,0 @@ - -/mob/living/simple_animal/borer/Topic(href, href_list, hsrc) - if(href_list["borer_use_chem"]) - locate(href_list["src"]) - if(!istype(src, /mob/living/simple_animal/borer)) - return - - var/topic_chem = href_list["borer_use_chem"] - var/datum/borer_chem/C - - for(var/datum in typesof(/datum/borer_chem)) - var/datum/borer_chem/test = new datum() - if(test.chemname == topic_chem) - C = test - break - - if(!istype(C, /datum/borer_chem)) - return - - if(!C || !victim || controlling || !src || stat) - return - - if(!istype(C, /datum/borer_chem)) - return - - if(chemicals < C.chemuse) - to_chat(src, "You need [C.chemuse] chemicals stored to use this chemical!") - return - - to_chat(src, "You squirt a measure of [C.chemname] from your reservoirs into [victim]'s bloodstream.") - if(C.chemname=="aphro" || C.chemname=="anaphro") - if(victim.canbearoused) //snowflake exception as these chems interact with client-specific optional stuff :S - to_chat(victim,C.chem_message) - else - to_chat(victim,C.chem_message) - victim.reagents.add_reagent(C.chemname, C.quantity) - chemicals -= C.chemuse - log_game("[src]/([src.ckey]) has injected [C.chemname] into their host [victim]/([victim.ckey])") - - src << output(chemicals, "ViewBorer\ref[src]Chems.browser:update_chemicals") - - ..() \ No newline at end of file diff --git a/code/modules/antagonists/borer/syndi_borer.dm b/code/modules/antagonists/borer/syndi_borer.dm deleted file mode 100644 index 5a0abff216..0000000000 --- a/code/modules/antagonists/borer/syndi_borer.dm +++ /dev/null @@ -1,34 +0,0 @@ -/mob/living/simple_animal/borer/syndi_borer - var/mob/owner = null - is_team_borer = FALSE - borer_alert = "Serve as a syndicate cortical borer? (Warning, You can no longer be cloned!)" - -/mob/living/simple_animal/borer/syndi_borer/Initialize(mapload, gen=1) - ..() - real_name = "Syndicate Borer [rand(1000,9999)]" - truename = "[borer_names[min(generation, borer_names.len)]] [rand(1000,9999)]" - - GrantBorerActions() - make_larvae_action.Remove(src) - -/mob/living/simple_animal/borer/syndi_borer/GrantControlActions() - talk_to_brain_action.Grant(victim) - give_back_control_action.Grant(victim) - -/mob/living/simple_animal/borer/syndi_borer/RemoveControlActions() - talk_to_brain_action.Remove(victim) - give_back_control_action.Remove(victim) - -//Syndicate borer objective, relies on their owner getting a greentext, no matter if they themselves did anything really. -/datum/objective/syndi_borer - explanation_text = "You are a modified syndicate cortical borer, assist your owner with their objectives." - martyr_compatible = 1 - -/datum/objective/syndi_borer/check_completion() - if(target) - for(var/datum/objective/objective in target.objectives) - if(!objective.check_completion()) - return 0 - return 1 - else - return 1 //Not sure if we should greentext if we somehow don't even have an owner. \ No newline at end of file diff --git a/code/modules/antagonists/changeling/changeling.dm b/code/modules/antagonists/changeling/changeling.dm index dca2a364a9..fae342e93d 100644 --- a/code/modules/antagonists/changeling/changeling.dm +++ b/code/modules/antagonists/changeling/changeling.dm @@ -367,11 +367,21 @@ if(!CTO.escape_objective_compatible) escape_objective_possible = FALSE break - - var/datum/objective/absorb/absorb_objective = new - absorb_objective.owner = owner - absorb_objective.gen_amount_goal(6, 8) - objectives += absorb_objective + var/changeling_objective = rand(1,3) + switch(changeling_objective) + if(1) + var/datum/objective/absorb/absorb_objective = new + absorb_objective.owner = owner + absorb_objective.gen_amount_goal(6, 8) + objectives += absorb_objective + if(2) + var/datum/objective/absorb_changeling/ac = new + ac.owner = owner + objectives += ac + if(3) + var/datum/objective/absorb_most/ac = new + ac.owner = owner + objectives += ac if(prob(60)) if(prob(85)) diff --git a/code/modules/antagonists/changeling/powers/absorb.dm b/code/modules/antagonists/changeling/powers/absorb.dm index 4857975d6e..c3d9d4e9f0 100644 --- a/code/modules/antagonists/changeling/powers/absorb.dm +++ b/code/modules/antagonists/changeling/powers/absorb.dm @@ -89,9 +89,16 @@ var/datum/antagonist/changeling/target_ling = target.mind.has_antag_datum(/datum/antagonist/changeling) if(target_ling)//If the target was a changeling, suck out their extra juice and objective points! + to_chat(user, "[target] was one of us. We have absorbed their power.") + target_ling.remove_changeling_powers() + changeling.geneticpoints += round(target_ling.geneticpoints/2) + target_ling.geneticpoints = 0 + target_ling.canrespec = 0 + changeling.chem_storage += round(target_ling.chem_storage/2) changeling.chem_charges += min(target_ling.chem_charges, changeling.chem_storage) + target_ling.chem_charges = 0 + target_ling.chem_storage = 0 changeling.absorbedcount += (target_ling.absorbedcount) - target_ling.stored_profiles.len = 1 target_ling.absorbedcount = 0 diff --git a/code/modules/antagonists/changeling/powers/regenerate.dm b/code/modules/antagonists/changeling/powers/regenerate.dm index 99050417b8..c86bf271d4 100644 --- a/code/modules/antagonists/changeling/powers/regenerate.dm +++ b/code/modules/antagonists/changeling/powers/regenerate.dm @@ -8,7 +8,6 @@ chemical_cost = 10 dna_cost = 0 req_stat = UNCONSCIOUS - always_keep = TRUE /obj/effect/proc_holder/changeling/regenerate/sting_action(mob/living/user) to_chat(user, "You feel an itching, both inside and \ diff --git a/code/modules/antagonists/changeling/powers/revive.dm b/code/modules/antagonists/changeling/powers/revive.dm index 673f49863b..4fb28b4904 100644 --- a/code/modules/antagonists/changeling/powers/revive.dm +++ b/code/modules/antagonists/changeling/powers/revive.dm @@ -29,7 +29,7 @@ return TRUE /obj/effect/proc_holder/changeling/revive/can_be_used_by(mob/living/user) - if((user.stat != DEAD) && !(user.has_trait(TRAIT_FAKEDEATH))) + if(user.has_trait(CHANGELING_DRAIN) || ((user.stat != DEAD) && !(user.has_trait(TRAIT_FAKEDEATH)))) var/datum/antagonist/changeling/changeling = user.mind.has_antag_datum(/datum/antagonist/changeling) changeling.purchasedpowers -= src return 0 diff --git a/code/modules/antagonists/clockcult/clock_mobs/clockwork_marauder.dm b/code/modules/antagonists/clockcult/clock_mobs/clockwork_marauder.dm index 73bcd6b47f..4be5f7d4e6 100644 --- a/code/modules/antagonists/clockcult/clock_mobs/clockwork_marauder.dm +++ b/code/modules/antagonists/clockcult/clock_mobs/clockwork_marauder.dm @@ -6,6 +6,7 @@ name = "clockwork marauder" desc = "The stalwart apparition of a soldier, blazing with crimson flames. It's armed with a gladius and shield." icon_state = "clockwork_marauder" + mob_biotypes = list(MOB_INORGANIC, MOB_HUMANOID) health = 120 maxHealth = 120 force_threshold = 8 diff --git a/code/modules/antagonists/clockcult/clock_structures/stargazer.dm b/code/modules/antagonists/clockcult/clock_structures/stargazer.dm deleted file mode 100644 index 4f04fcb82b..0000000000 --- a/code/modules/antagonists/clockcult/clock_structures/stargazer.dm +++ /dev/null @@ -1,70 +0,0 @@ -#define STARGAZER_RANGE 3 //How many tiles the stargazer can see out to -#define STARGAZER_POWER 20 //How many watts will be produced per second when the stargazer sees starlight - -//Stargazer: A very fragile but cheap generator that creates power from starlight. -/obj/structure/destructible/clockwork/stargazer - name = "stargazer" - desc = "A large lantern-shaped machine made of thin brass. It looks fragile." - clockwork_desc = "A lantern-shaped generator that produces power when near starlight." - icon_state = "stargazer" - unanchored_icon = "stargazer_unwrenched" - max_integrity = 40 - construction_value = 5 - layer = WALL_OBJ_LAYER - break_message = "The stargazer's fragile body shatters into pieces!" - resistance_flags = LAVA_PROOF | FIRE_PROOF | ACID_PROOF - light_color = "#DAAA18" - var/star_light_star_bright = FALSE //If this stargazer can see starlight - -/obj/structure/destructible/clockwork/stargazer/Initialize() - . = ..() - START_PROCESSING(SSprocessing, src) - -/obj/structure/destructible/clockwork/stargazer/Destroy() - STOP_PROCESSING(SSprocessing, src) - . = ..() - -/obj/structure/destructible/clockwork/stargazer/examine(mob/user) - ..() - if(is_servant_of_ratvar(user)) - to_chat(user, "Generates [DisplayPower(STARGAZER_POWER)] per second while viewing starlight within [STARGAZER_RANGE] tiles.") - if(star_light_star_bright) - to_chat(user, "[is_servant_of_ratvar(user) ? "It can see starlight!" : "It's shining brilliantly!"]") - -/obj/structure/destructible/clockwork/stargazer/process() - star_light_star_bright = check_starlight() - if(star_light_star_bright) - adjust_clockwork_power(STARGAZER_POWER) - -/obj/structure/destructible/clockwork/stargazer/update_anchored(mob/living/user, damage) - . = ..() - star_light_star_bright = check_starlight() - -/obj/structure/destructible/clockwork/stargazer/proc/check_starlight() - var/old_status = star_light_star_bright - var/has_starlight - if(!anchored) - has_starlight = FALSE - else - for(var/turf/T in view(3, src)) - if(isspaceturf(T)) - has_starlight = TRUE - break - if(has_starlight && anchored) - var/area/A = get_area(src) - if(A.outdoors || A.map_name == "Space" || !A.blob_allowed) - has_starlight = FALSE - if(old_status != has_starlight) - if(has_starlight) - visible_message("[src] hums and shines brilliantly!") - playsound(src, 'sound/machines/clockcult/stargazer_activate.ogg', 50, TRUE) - add_overlay("stargazer_light") - set_light(1.5, 5) - else - if(anchored) //We lost visibility somehow - visible_message("[src] flickers, and falls dark.") - else - visible_message("[src] whooshes quietly as it slides into a less bulky form.") - cut_overlays() - set_light(0) - return has_starlight diff --git a/code/modules/antagonists/cult/cult.dm b/code/modules/antagonists/cult/cult.dm index 80947fec16..b7f0b002ec 100644 --- a/code/modules/antagonists/cult/cult.dm +++ b/code/modules/antagonists/cult/cult.dm @@ -95,10 +95,8 @@ else to_chat(mob, "You have a [item_name] in your [where].") if(where == "backpack") - var/obj/item/storage/B = mob.back - B.orient2hud(mob) - B.show_to(mob) - return 1 + mob.back.SendSignal(COMSIG_TRY_STORAGE_SHOW, mob) + return TRUE /datum/antagonist/cult/apply_innate_effects(mob/living/mob_override) . = ..() diff --git a/code/modules/antagonists/devil/imp/imp.dm b/code/modules/antagonists/devil/imp/imp.dm index ffa3828bad..7752d0449f 100644 --- a/code/modules/antagonists/devil/imp/imp.dm +++ b/code/modules/antagonists/devil/imp/imp.dm @@ -13,6 +13,7 @@ icon = 'icons/mob/mob.dmi' icon_state = "imp" icon_living = "imp" + mob_biotypes = list(MOB_ORGANIC, MOB_HUMANOID) speed = 1 a_intent = INTENT_HARM stop_automated_movement = 1 diff --git a/code/modules/antagonists/revenant/revenant.dm b/code/modules/antagonists/revenant/revenant.dm index 079bfb093e..34d30603d6 100644 --- a/code/modules/antagonists/revenant/revenant.dm +++ b/code/modules/antagonists/revenant/revenant.dm @@ -16,6 +16,7 @@ var/icon_stun = "revenant_stun" var/icon_drain = "revenant_draining" var/stasis = FALSE + mob_biotypes = list(MOB_SPIRIT) incorporeal_move = INCORPOREAL_MOVE_JAUNT invisibility = INVISIBILITY_REVENANT health = INFINITY //Revenants don't use health, they use essence instead diff --git a/code/modules/antagonists/slaughter/slaughter.dm b/code/modules/antagonists/slaughter/slaughter.dm index e8eb95aa7b..9457e3a8c8 100644 --- a/code/modules/antagonists/slaughter/slaughter.dm +++ b/code/modules/antagonists/slaughter/slaughter.dm @@ -12,6 +12,7 @@ icon = 'icons/mob/mob.dmi' icon_state = "daemon" icon_living = "daemon" + mob_biotypes = list(MOB_ORGANIC, MOB_HUMANOID) speed = 1 a_intent = INTENT_HARM stop_automated_movement = 1 diff --git a/code/modules/antagonists/swarmer/swarmer.dm b/code/modules/antagonists/swarmer/swarmer.dm index 1a55afa755..817cbf75c0 100644 --- a/code/modules/antagonists/swarmer/swarmer.dm +++ b/code/modules/antagonists/swarmer/swarmer.dm @@ -60,6 +60,7 @@ speak_emote = list("tones") initial_language_holder = /datum/language_holder/swarmer bubble_icon = "swarmer" + mob_biotypes = list(MOB_ROBOTIC) health = 40 maxHealth = 40 status_flags = CANPUSH diff --git a/code/modules/antagonists/traitor/equipment/Malf_Modules.dm b/code/modules/antagonists/traitor/equipment/Malf_Modules.dm index 46891b420d..6322ad1584 100644 --- a/code/modules/antagonists/traitor/equipment/Malf_Modules.dm +++ b/code/modules/antagonists/traitor/equipment/Malf_Modules.dm @@ -3,7 +3,7 @@ GLOBAL_LIST_INIT(blacklisted_malf_machines, typecacheof(list( /obj/machinery/field/containment, - /obj/machinery/power/supermatter_shard, + /obj/machinery/power/supermatter_crystal, /obj/machinery/doomsday_device, /obj/machinery/nuclearbomb, /obj/machinery/nuclearbomb/selfdestruct, diff --git a/code/modules/assembly/assembly.dm b/code/modules/assembly/assembly.dm index 5af72b4261..1e6fdc2fd4 100644 --- a/code/modules/assembly/assembly.dm +++ b/code/modules/assembly/assembly.dm @@ -1,8 +1,8 @@ -#define WIRE_RECEIVE 1 -#define WIRE_PULSE 2 -#define WIRE_PULSE_SPECIAL 4 -#define WIRE_RADIO_RECEIVE 8 -#define WIRE_RADIO_PULSE 16 +#define WIRE_RECEIVE (1<<0) +#define WIRE_PULSE (1<<1) +#define WIRE_PULSE_SPECIAL (1<<2) +#define WIRE_RADIO_RECEIVE (1<<3) +#define WIRE_RADIO_PULSE (1<<4) /obj/item/device/assembly name = "assembly" diff --git a/code/modules/atmospherics/machinery/airalarm.dm b/code/modules/atmospherics/machinery/airalarm.dm index 4a003ad84f..a62a448a70 100644 --- a/code/modules/atmospherics/machinery/airalarm.dm +++ b/code/modules/atmospherics/machinery/airalarm.dm @@ -643,10 +643,9 @@ var/area/A = get_area(src) var/new_area_danger_level = 0 - for(var/area/R in A.related) - for(var/obj/machinery/airalarm/AA in R) - if (!(AA.stat & (NOPOWER|BROKEN)) && !AA.shorted) - new_area_danger_level = max(new_area_danger_level,AA.danger_level) + for(var/obj/machinery/airalarm/AA in A) + if (!(AA.stat & (NOPOWER|BROKEN)) && !AA.shorted) + new_area_danger_level = max(new_area_danger_level,AA.danger_level) if(A.atmosalert(new_area_danger_level,src)) //if area was in normal state or if area was in alert state post_alert(new_area_danger_level) diff --git a/code/modules/atmospherics/machinery/components/unary_devices/cryo.dm b/code/modules/atmospherics/machinery/components/unary_devices/cryo.dm index d48f0d1f93..d3dde7a18e 100644 --- a/code/modules/atmospherics/machinery/components/unary_devices/cryo.dm +++ b/code/modules/atmospherics/machinery/components/unary_devices/cryo.dm @@ -12,6 +12,7 @@ state_open = FALSE circuit = /obj/item/circuitboard/machine/cryo_tube pipe_flags = PIPING_ONE_PER_TURF | PIPING_DEFAULT_LAYER_ONLY + occupant_typecache = list(/mob/living/carbon, /mob/living/simple_animal) var/on = FALSE var/autoeject = FALSE @@ -276,7 +277,12 @@ /obj/machinery/atmospherics/components/unary/cryo_cell/MouseDrop_T(mob/target, mob/user) if(user.stat || user.lying || !Adjacent(user) || !user.Adjacent(target) || !iscarbon(target) || !user.IsAdvancedToolUser()) return - close_machine(target) + if (target.IsKnockdown() || target.IsStun() || target.IsSleeping() || target.IsUnconscious()) + close_machine(target) + else + user.visible_message("[user] starts shoving [target] inside [src].", "You start shoving [target] inside [src].") + if (do_after(user, 25, target=target)) + close_machine(target) /obj/machinery/atmospherics/components/unary/cryo_cell/attackby(obj/item/I, mob/user, params) if(istype(I, /obj/item/reagent_containers/glass)) diff --git a/code/modules/atmospherics/machinery/portable/canister.dm b/code/modules/atmospherics/machinery/portable/canister.dm index 20ec34e3a0..132e750343 100644 --- a/code/modules/atmospherics/machinery/portable/canister.dm +++ b/code/modules/atmospherics/machinery/portable/canister.dm @@ -207,13 +207,13 @@ air_contents.gases[/datum/gas/oxygen][MOLES] = (O2STANDARD * maximum_pressure * filled) * air_contents.volume / (R_IDEAL_GAS_EQUATION * air_contents.temperature) air_contents.gases[/datum/gas/nitrogen][MOLES] = (N2STANDARD * maximum_pressure * filled) * air_contents.volume / (R_IDEAL_GAS_EQUATION * air_contents.temperature) -#define HOLDING 1 -#define CONNECTED 2 -#define EMPTY 4 -#define LOW 8 -#define MEDIUM 16 -#define FULL 32 -#define DANGER 64 +#define HOLDING (1<<0) +#define CONNECTED (1<<1) +#define EMPTY (1<<2) +#define LOW (1<<3) +#define MEDIUM (1<<4) +#define FULL (1<<5) +#define DANGER (1<<6) /obj/machinery/portable_atmospherics/canister/update_icon() if(stat & BROKEN) cut_overlays() diff --git a/code/modules/cargo/exports/large_objects.dm b/code/modules/cargo/exports/large_objects.dm index 7e02048f18..37afb31a6b 100644 --- a/code/modules/cargo/exports/large_objects.dm +++ b/code/modules/cargo/exports/large_objects.dm @@ -92,7 +92,7 @@ /datum/export/large/supermatter cost = 9000 unit_name = "supermatter shard" - export_types = list(/obj/machinery/power/supermatter_shard) + export_types = list(/obj/machinery/power/supermatter_crystal/shard) // Misc /datum/export/large/iv diff --git a/code/modules/cargo/packs.dm b/code/modules/cargo/packs.dm index c2b0aa8a7f..8ba650241f 100644 --- a/code/modules/cargo/packs.dm +++ b/code/modules/cargo/packs.dm @@ -756,12 +756,12 @@ crate_name = "solar panel crate" crate_type = /obj/structure/closet/crate/engineering/electrical -/datum/supply_pack/engineering/engine/supermatter_shard +/datum/supply_pack/engineering/engine/supermatter_crystal name = "Supermatter Shard Crate" desc = "The power of the heavens condensed into a single crystal. Requires CE access to open." cost = 10000 access = ACCESS_CE - contains = list(/obj/machinery/power/supermatter_shard) + contains = list(/obj/machinery/power/supermatter_crystal/shard) crate_name = "supermatter shard crate" crate_type = /obj/structure/closet/crate/secure/engineering dangerous = TRUE diff --git a/code/modules/cargo/vg_clothing_packs.dm b/code/modules/cargo/vg_clothing_packs.dm deleted file mode 100644 index 99812627e3..0000000000 --- a/code/modules/cargo/vg_clothing_packs.dm +++ /dev/null @@ -1,34 +0,0 @@ -/* // Can't be bothered to maintain this, mostly just memes anyway. -/datum/supply_pack/misc/vidyacon - name = "Vidya-Con Surplus Crate" - cost = 3250 - contains = list(/obj/item/clothing/shoes/megaboots,/obj/item/clothing/gloves/megagloves,/obj/item/clothing/head/helmet/megahelmet, /obj/item/clothing/under/mega, - /obj/item/clothing/shoes/protoboots,/obj/item/clothing/gloves/protogloves,/obj/item/clothing/head/helmet/protohelmet,/obj/item/clothing/under/proto, - /obj/item/clothing/shoes/megaxboots,/obj/item/clothing/gloves/megaxgloves,/obj/item/clothing/head/helmet/megaxhelmet,/obj/item/clothing/under/megax, - /obj/item/clothing/shoes/joeboots,/obj/item/clothing/gloves/joegloves,/obj/item/clothing/head/helmet/joehelmet,/obj/item/clothing/under/joe, - /obj/item/clothing/under/roll, - /obj/item/clothing/head/helmet/biker,/obj/item/clothing/under/bikersuit,/obj/item/clothing/gloves/bikergloves, - /obj/item/clothing/under/jacketsuit,/obj/item/clothing/head/helmet/richard, - /obj/item/clothing/under/vault13) - crate_name = "vidya-con surplus crate" - - -datum/supply_pack/misc/memes - name = "Nanotrasen Approved Internet Humor Crate" - cost = 5000 - contains = list(/obj/item/clothing/suit/doshjacket, - /obj/item/clothing/under/squatter_outfit,/obj/item/clothing/head/squatter_hat, - /obj/item/clothing/under/cia, - /obj/item/clothing/under/russobluecamooutfit,/obj/item/clothing/head/russobluecamohat, - /obj/item/clothing/under/rottensuit,/obj/item/clothing/shoes/rottenshoes, - /obj/item/clothing/suit/raincoat) - crate_name = "nanotrasen internet humor crate" - -datum/supply_pack/misc/reenactor - name = "Historical Reanactor Crate" - cost = 17500 - contains = list(/obj/item/clothing/under/soldieruniform,/obj/item/clothing/head/stalhelm,/obj/item/clothing/suit/soldiercoat, - /obj/item/clothing/under/officeruniform,/obj/item/clothing/head/naziofficer,/obj/item/clothing/suit/officercoat, - /obj/item/clothing/head/panzer, - /obj/item/clothing/suit/russofurcoat,/obj/item/clothing/head/russofurhat,/obj/item/clothing/under/soviet) - crate_name = "historical reanactor crate" */ diff --git a/code/modules/client/client_procs.dm b/code/modules/client/client_procs.dm index 42c92908e7..49d6c4b04a 100644 --- a/code/modules/client/client_procs.dm +++ b/code/modules/client/client_procs.dm @@ -92,7 +92,7 @@ GLOBAL_LIST_INIT(blacklisted_builds, list( if (citadel_client_procs(href_list)) return // CITADEL End - + switch(href_list["_src_"]) if("holder") hsrc = holder @@ -391,9 +391,9 @@ GLOBAL_LIST_EMPTY(external_rsc_urls) var/datum/verbs/menu/menuitem = GLOB.menulist[thing] if (menuitem) menuitem.Load_checked(src) - + hook_vr("client_new",list(src)) // CIT CHANGE - hook for client/New() changes - + Master.UpdateTickRate() ////////////// @@ -638,50 +638,6 @@ GLOBAL_LIST_EMPTY(external_rsc_urls) return create_message("note", ckey, system_ckey, message, null, null, 0, 0) -/client/Click(atom/object, atom/location, control, params) - var/ab = FALSE - var/list/L = params2list(params) - if (object && object == middragatom && L["left"]) - ab = max(0, 5 SECONDS-(world.time-middragtime)*0.1) - var/mcl = CONFIG_GET(number/minute_click_limit) - if (!holder && mcl) - var/minute = round(world.time, 600) - if (!clicklimiter) - clicklimiter = new(LIMITER_SIZE) - if (minute != clicklimiter[CURRENT_MINUTE]) - clicklimiter[CURRENT_MINUTE] = minute - clicklimiter[MINUTE_COUNT] = 0 - clicklimiter[MINUTE_COUNT] += 1+(ab) - if (clicklimiter[MINUTE_COUNT] > mcl) - var/msg = "Your previous click was ignored because you've done too many in a minute." - if (minute != clicklimiter[ADMINSWARNED_AT]) //only one admin message per-minute. (if they spam the admins can just boot/ban them) - clicklimiter[ADMINSWARNED_AT] = minute - - msg += " Administrators have been informed." - if (ab) - log_game("[key_name(src)] is using the middle click aimbot exploit") - message_admins("[key_name_admin(src)] [ADMIN_FLW(usr)] [ADMIN_KICK(usr)] is using the middle click aimbot exploit") - add_system_note("aimbot", "Is using the middle click aimbot exploit") - - log_game("[key_name(src)] Has hit the per-minute click limit of [mcl] clicks in a given game minute") - message_admins("[key_name_admin(src)] [ADMIN_FLW(usr)] [ADMIN_KICK(usr)] Has hit the per-minute click limit of [mcl] clicks in a given game minute") - to_chat(src, "[msg]") - return - - var/scl = CONFIG_GET(number/second_click_limit) - if (!holder && scl) - var/second = round(world.time, 10) - if (!clicklimiter) - clicklimiter = new(LIMITER_SIZE) - if (second != clicklimiter[CURRENT_SECOND]) - clicklimiter[CURRENT_SECOND] = second - clicklimiter[SECOND_COUNT] = 0 - clicklimiter[SECOND_COUNT] += 1+(!!ab) - if (clicklimiter[SECOND_COUNT] > scl) - to_chat(src, "Your previous click was ignored because you've done too many in a second") - return - ..() - /client/proc/check_ip_intel() set waitfor = 0 //we sleep when getting the intel, no need to hold up the client connection while we sleep @@ -742,9 +698,7 @@ GLOBAL_LIST_EMPTY(external_rsc_urls) verbs += /client/proc/self_playtime -#undef TOPIC_SPAM_DELAY #undef UPLOAD_LIMIT -#undef MIN_CLIENT_VERSION //checks if a client is afk //3000 frames = 5 minutes @@ -753,17 +707,6 @@ GLOBAL_LIST_EMPTY(external_rsc_urls) return inactivity return FALSE -// Byond seemingly calls stat, each tick. -// Calling things each tick can get expensive real quick. -// So we slow this down a little. -// See: http://www.byond.com/docs/ref/info.html#/client/proc/Stat -/client/Stat() - . = ..() - if (holder) - stoplag(1) - else - stoplag(5) - //send resources to the client. It's here in its own proc so we can move it around easiliy if need be /client/proc/send_resources() #if (PRELOAD_RSC == 0) @@ -820,7 +763,6 @@ GLOBAL_LIST_EMPTY(external_rsc_urls) /client/proc/change_view(new_size) if (isnull(new_size)) CRASH("change_view called without argument.") - //CIT CHANGES START HERE - makes change_view change DEFAULT_VIEW to 15x15 depending on preferences if(prefs && CONFIG_GET(string/default_view)) if(!prefs.widescreenpref && new_size == CONFIG_GET(string/default_view)) diff --git a/code/modules/clothing/chameleon.dm b/code/modules/clothing/chameleon.dm index 609d341243..03bb1eeb13 100644 --- a/code/modules/clothing/chameleon.dm +++ b/code/modules/clothing/chameleon.dm @@ -387,8 +387,8 @@ desc = "A pair of black shoes." permeability_coefficient = 0.05 resistance_flags = NONE - pockets = /obj/item/storage/internal/pocket/shoes armor = list("melee" = 10, "bullet" = 10, "laser" = 10, "energy" = 0, "bomb" = 0, "bio" = 0, "rad" = 0, "fire" = 50, "acid" = 50) + pocket_storage_component_path = /datum/component/storage/concrete/pockets/shoes var/datum/action/item_action/chameleon/change/chameleon_action @@ -579,16 +579,21 @@ /obj/item/storage/belt/chameleon name = "toolbelt" desc = "Holds tools." - silent = TRUE var/datum/action/item_action/chameleon/change/chameleon_action /obj/item/storage/belt/chameleon/Initialize() . = ..() + chameleon_action = new(src) chameleon_action.chameleon_type = /obj/item/storage/belt chameleon_action.chameleon_name = "Belt" chameleon_action.initialize_disguises() +/obj/item/storage/belt/chameleon/ComponentInitialize() + . = ..() + GET_COMPONENT(STR, /datum/component/storage) + STR.silent = TRUE + /obj/item/storage/belt/chameleon/emp_act(severity) chameleon_action.emp_randomise() diff --git a/code/modules/clothing/clothing.dm b/code/modules/clothing/clothing.dm index 26c20d0082..9c7a86cfc2 100644 --- a/code/modules/clothing/clothing.dm +++ b/code/modules/clothing/clothing.dm @@ -28,7 +28,7 @@ var/list/user_vars_to_edit = list() //VARNAME = VARVALUE eg: "name" = "butts" var/list/user_vars_remembered = list() //Auto built by the above + dropped() + equipped() - var/obj/item/storage/internal/pocket/pockets = null + var/pocket_storage_component_path //These allow head/mask items to dynamically alter the user's hair // and facial hair, checking hair_extensions.dmi and facialhair_extensions.dmi @@ -37,17 +37,15 @@ var/dynamic_hair_suffix = ""//head > mask for head hair var/dynamic_fhair_suffix = ""//mask > head for facial hair -/obj/item/clothing/New() - ..() - if(ispath(pockets)) - pockets = new pockets(src) +/obj/item/clothing/Initialize() + . = ..() + if(ispath(pocket_storage_component_path)) + LoadComponent(pocket_storage_component_path) /obj/item/clothing/MouseDrop(atom/over_object) + . = ..() var/mob/M = usr - if(pockets && over_object == M) - return pockets.MouseDrop(over_object) - if(ismecha(M.loc)) // stops inventory actions in a mech return @@ -56,25 +54,6 @@ if(M.putItemFromInventoryInHandIfPossible(src, H.held_index)) add_fingerprint(usr) -/obj/item/clothing/throw_at(atom/target, range, speed, mob/thrower, spin=1, diagonals_first = 0, datum/callback/callback) - if(pockets) - pockets.close_all() - return ..() - -/obj/item/clothing/attack_hand(mob/user) - if(pockets && pockets.priority && ismob(loc)) - //If we already have the pockets open, close them. - if (user.s_active == pockets) - pockets.close(user) - //Close whatever the user has open and show them the pockets. - else - if (user.s_active) - user.s_active.close(user) - pockets.orient2hud(user) - pockets.show_to(user) - else - return ..() - /obj/item/clothing/attackby(obj/item/W, mob/user, params) if(damaged_clothes && istype(W, /obj/item/stack/sheet/cloth)) var/obj/item/stack/sheet/cloth/C = W @@ -83,36 +62,12 @@ obj_integrity = max_integrity to_chat(user, "You fix the damage on [src] with [C].") return 1 - if(pockets) - var/i = pockets.attackby(W, user, params) - if(i) - return i return ..() -/obj/item/clothing/AltClick(mob/user) - if(istype(user) && user.canUseTopic(src, BE_CLOSE, ismonkey(user)) && pockets && pockets.quickdraw && pockets.contents.len) - var/obj/item/I = pockets.contents[1] - if(!I) - return - pockets.remove_from_storage(I, get_turf(src)) - - if(!user.put_in_hands(I)) - to_chat(user, "You fumble for [I] and it falls on the floor.") - return 1 - user.visible_message("[user] draws [I] from [src]!", "You draw [I] from [src].") - return 1 - else - return ..() - - /obj/item/clothing/Destroy() - if(pockets) - qdel(pockets) - pockets = null user_vars_remembered = null //Oh god somebody put REFERENCES in here? not to worry, we'll clean it up return ..() - /obj/item/clothing/dropped(mob/user) ..() if(!istype(user)) @@ -124,7 +79,6 @@ user.vars[variable] = user_vars_remembered[variable] user_vars_remembered = list() - /obj/item/clothing/equipped(mob/user, slot) ..() @@ -134,18 +88,18 @@ user_vars_remembered[variable] = user.vars[variable] user.vars[variable] = user_vars_to_edit[variable] - /obj/item/clothing/examine(mob/user) ..() if(damaged_clothes) to_chat(user, "It looks damaged!") + GET_COMPONENT(pockets, /datum/component/storage) if(pockets) var/list/how_cool_are_your_threads = list("") - if(pockets.priority) + if(pockets.attack_hand_interact) how_cool_are_your_threads += "[src]'s storage opens when clicked.\n" else how_cool_are_your_threads += "[src]'s storage opens when dragged to yourself.\n" - how_cool_are_your_threads += "[src] can store [pockets.storage_slots] item\s.\n" + how_cool_are_your_threads += "[src] can store [pockets.max_items] item\s.\n" how_cool_are_your_threads += "[src] can store items that are [weightclass2text(pockets.max_w_class)] or smaller.\n" if(pockets.quickdraw) how_cool_are_your_threads += "You can quickly remove an item from [src] using Alt-Click.\n" diff --git a/code/modules/clothing/glasses/engine_goggles.dm b/code/modules/clothing/glasses/engine_goggles.dm index 53616f4c6a..439197f285 100644 --- a/code/modules/clothing/glasses/engine_goggles.dm +++ b/code/modules/clothing/glasses/engine_goggles.dm @@ -4,6 +4,7 @@ #define MODE_MESON "meson" #define MODE_TRAY "t-ray" #define MODE_RAD "radiation" +#define MODE_SHUTTLE "shuttle" /obj/item/clothing/glasses/meson/engine name = "engineering scanner goggles" @@ -63,10 +64,13 @@ var/mob/living/carbon/human/user = loc if(user.glasses != src || !user.client) return - if(mode == MODE_TRAY) - t_ray_scan(user, 8, range) - else if(mode == MODE_RAD) - show_rads() + switch(mode) + if(MODE_TRAY) + t_ray_scan(user, 8, range) + if(MODE_RAD) + show_rads() + if(MODE_SHUTTLE) + show_shuttle() /obj/item/clothing/glasses/meson/engine/proc/show_rads() var/mob/living/carbon/human/user = loc @@ -93,6 +97,24 @@ pic.appearance = MA flick_overlay(pic, list(user.client), 8) +/obj/item/clothing/glasses/meson/engine/proc/show_shuttle() + var/mob/living/carbon/human/user = loc + var/obj/docking_port/mobile/port = SSshuttle.get_containing_shuttle(user) + if(!port) + return + var/list/shuttle_areas = port.shuttle_areas + for(var/r in shuttle_areas) + var/area/region = r + for(var/turf/place in region.contents) + if(get_dist(user, place) > 7) + continue + var/image/pic + if(isshuttleturf(place)) + pic = new('icons/turf/overlays.dmi', place, "greenOverlay", AREA_LAYER) + else + pic = new('icons/turf/overlays.dmi', place, "redOverlay", AREA_LAYER) + flick_overlay(pic, list(user.client), 8) + /obj/item/clothing/glasses/meson/engine/update_icon() icon_state = "trayson-[mode]" update_mob() @@ -115,7 +137,16 @@ modes = list(MODE_NONE = MODE_TRAY, MODE_TRAY = MODE_NONE) +/obj/item/clothing/glasses/meson/engine/shuttle + name = "shuttle region scanner" + icon_state = "trayson-shuttle" + item_state = "trayson-shuttle" + desc = "Used to see the boundaries of shuttle regions." + + modes = list(MODE_NONE = MODE_SHUTTLE, MODE_SHUTTLE = MODE_NONE) + #undef MODE_NONE #undef MODE_MESON #undef MODE_TRAY #undef MODE_RAD +#undef MODE_SHUTTLE diff --git a/code/modules/clothing/head/jobs.dm b/code/modules/clothing/head/jobs.dm index 37e392b7d8..613b40d19b 100644 --- a/code/modules/clothing/head/jobs.dm +++ b/code/modules/clothing/head/jobs.dm @@ -79,9 +79,13 @@ desc = "There's only one man who can sniff out the dirty stench of crime, and he's likely wearing this hat." icon_state = "detective" var/candy_cooldown = 0 - pockets = /obj/item/storage/internal/pocket/small/detective + pocket_storage_component_path = /datum/component/storage/concrete/pockets/small/detective dog_fashion = /datum/dog_fashion/head/detective +/obj/item/clothing/head/fedora/Initialize() + . = ..() + new /obj/item/reagent_containers/food/drinks/flask/det(src) + /obj/item/clothing/head/fedora/det_hat/examine(mob/user) ..() to_chat(user, "Alt-click to take a candy corn.") diff --git a/code/modules/clothing/head/misc.dm b/code/modules/clothing/head/misc.dm index 0e4acfe983..74d8a43347 100644 --- a/code/modules/clothing/head/misc.dm +++ b/code/modules/clothing/head/misc.dm @@ -187,7 +187,7 @@ item_state = "fedora" armor = list("melee" = 25, "bullet" = 5, "laser" = 25, "energy" = 10, "bomb" = 0, "bio" = 0, "rad" = 0, "fire" = 30, "acid" = 50) desc = "A really cool hat if you're a mobster. A really lame hat if you're not." - pockets = /obj/item/storage/internal/pocket/small + pocket_storage_component_path = /datum/component/storage/concrete/pockets/small /obj/item/clothing/head/fedora/suicide_act(mob/user) if(user.gender == FEMALE) diff --git a/code/modules/clothing/outfits/event.dm b/code/modules/clothing/outfits/event.dm index 72edf7a358..caa473f6dc 100644 --- a/code/modules/clothing/outfits/event.dm +++ b/code/modules/clothing/outfits/event.dm @@ -26,6 +26,5 @@ var/obj/item/storage/backpack/bag = H.back var/obj/item/a_gift/gift = new(H) - while(bag.can_be_inserted(gift, 1)) - bag.handle_item_insertion(gift, 1) + while(bag.SendSignal(COMSIG_TRY_STORAGE_INSERT, gift, null, TRUE, FALSE)) gift = new(H) diff --git a/code/modules/clothing/outfits/standard.dm b/code/modules/clothing/outfits/standard.dm index 050c2fdc87..6fdbb183a3 100644 --- a/code/modules/clothing/outfits/standard.dm +++ b/code/modules/clothing/outfits/standard.dm @@ -182,11 +182,11 @@ for(var/obj/item/briefcase_item in sec_briefcase) qdel(briefcase_item) for(var/i = 3 to 0 step -1) - sec_briefcase.handle_item_insertion(new /obj/item/stack/spacecash/c1000,1) - sec_briefcase.handle_item_insertion(new /obj/item/gun/energy/kinetic_accelerator/crossbow,1) - sec_briefcase.handle_item_insertion(new /obj/item/gun/ballistic/revolver/mateba,1) - sec_briefcase.handle_item_insertion(new /obj/item/ammo_box/a357,1) - sec_briefcase.handle_item_insertion(new /obj/item/grenade/plastic/x4,1) + sec_briefcase.SendSignal(COMSIG_TRY_STORAGE_INSERT, new /obj/item/stack/spacecash/c1000, null, TRUE, TRUE) + sec_briefcase.SendSignal(COMSIG_TRY_STORAGE_INSERT, new /obj/item/gun/energy/kinetic_accelerator/crossbow, null, TRUE, TRUE) + sec_briefcase.SendSignal(COMSIG_TRY_STORAGE_INSERT, new /obj/item/gun/ballistic/revolver/mateba, null, TRUE, TRUE) + sec_briefcase.SendSignal(COMSIG_TRY_STORAGE_INSERT, new /obj/item/ammo_box/a357, null, TRUE, TRUE) + sec_briefcase.SendSignal(COMSIG_TRY_STORAGE_INSERT, new /obj/item/grenade/plastic/x4, null, TRUE, TRUE) var/obj/item/device/pda/heads/pda = H.belt pda.owner = H.real_name diff --git a/code/modules/clothing/shoes/miscellaneous.dm b/code/modules/clothing/shoes/miscellaneous.dm index d5e75d4bad..3dad0d464e 100644 --- a/code/modules/clothing/shoes/miscellaneous.dm +++ b/code/modules/clothing/shoes/miscellaneous.dm @@ -17,7 +17,7 @@ strip_delay = 70 resistance_flags = NONE permeability_coefficient = 0.05 //Thick soles, and covers the ankle - pockets = /obj/item/storage/internal/pocket/shoes + pocket_storage_component_path = /datum/component/storage/concrete/pockets/shoes /obj/item/clothing/shoes/combat/swat //overpowered boots for death squads name = "\improper SWAT boots" @@ -73,7 +73,7 @@ item_state = "clown_shoes" slowdown = SHOES_SLOWDOWN+1 item_color = "clown" - pockets = /obj/item/storage/internal/pocket/shoes/clown + pocket_storage_component_path = /datum/component/storage/concrete/pockets/shoes/clown /obj/item/clothing/shoes/clown_shoes/Initialize() . = ..() @@ -106,7 +106,7 @@ equip_delay_other = 50 resistance_flags = NONE permeability_coefficient = 0.05 //Thick soles, and covers the ankle - pockets = /obj/item/storage/internal/pocket/shoes + pocket_storage_component_path = /datum/component/storage/concrete/pockets/shoes /obj/item/clothing/shoes/jackboots/fast slowdown = -1 @@ -121,7 +121,7 @@ min_cold_protection_temperature = SHOES_MIN_TEMP_PROTECT heat_protection = FEET|LEGS max_heat_protection_temperature = SHOES_MAX_TEMP_PROTECT - pockets = /obj/item/storage/internal/pocket/shoes + pocket_storage_component_path = /datum/component/storage/concrete/pockets/shoes /obj/item/clothing/shoes/workboots name = "work boots" @@ -133,7 +133,7 @@ permeability_coefficient = 0.15 strip_delay = 40 equip_delay_other = 40 - pockets = /obj/item/storage/internal/pocket/shoes + pocket_storage_component_path = /datum/component/storage/concrete/pockets/shoes /obj/item/clothing/shoes/workboots/mining name = "mining boots" @@ -184,7 +184,7 @@ desc = "A pair of costume boots fashioned after bird talons." icon_state = "griffinboots" item_state = "griffinboots" - pockets = /obj/item/storage/internal/pocket/shoes + pocket_storage_component_path = /datum/component/storage/concrete/pockets/shoes /obj/item/clothing/shoes/bhop name = "jump boots" @@ -193,7 +193,7 @@ item_state = "jetboots" item_color = "hosred" resistance_flags = FIRE_PROOF - pockets = /obj/item/storage/internal/pocket/shoes + pocket_storage_component_path = /datum/component/storage/concrete/pockets/shoes actions_types = list(/datum/action/item_action/bhop) permeability_coefficient = 0.05 var/jumpdistance = 5 //-1 from to see the actual distance, e.g 4 goes over 3 tiles diff --git a/code/modules/clothing/spacesuits/flightsuit.dm b/code/modules/clothing/spacesuits/flightsuit.dm index adff70bd29..3a5198080f 100644 --- a/code/modules/clothing/spacesuits/flightsuit.dm +++ b/code/modules/clothing/spacesuits/flightsuit.dm @@ -823,13 +823,13 @@ if(shoes) shoes.relink_suit(src) -/obj/item/clothing/suit/space/hardsuit/flightsuit/attack_hand(mob/user) +/obj/item/clothing/suit/space/hardsuit/flightsuit/allow_attack_hand_drop(user) if(ishuman(user)) var/mob/living/carbon/human/H = user if(src == H.wear_suit && locked) usermessage("You can not take a locked hardsuit off! Unlock it first!", "boldwarning") - return - ..() + return FALSE + return ..() /obj/item/clothing/suit/space/hardsuit/flightsuit/dropped() if(deployedpack) diff --git a/code/modules/clothing/under/accessories.dm b/code/modules/clothing/under/accessories.dm index 3d9c3c8017..05ce843ff9 100644 --- a/code/modules/clothing/under/accessories.dm +++ b/code/modules/clothing/under/accessories.dm @@ -9,15 +9,15 @@ w_class = WEIGHT_CLASS_SMALL var/above_suit = FALSE var/minimize_when_attached = TRUE // TRUE if shown as a small icon in corner, FALSE if overlayed + var/datum/component/storage/detached_pockets /obj/item/clothing/accessory/proc/attach(obj/item/clothing/under/U, user) - if(pockets) // Attach storage to jumpsuit - if(U.pockets) // storage items conflict + GET_COMPONENT(storage, /datum/component/storage) + if(storage) + if(U.SendSignal(COMSIG_CONTAINS_STORAGE)) return FALSE - - pockets.forceMove(U) - U.pockets = pockets - + U.TakeComponent(storage) + detached_pockets = storage U.attached_accessory = src forceMove(U) layer = FLOAT_LAYER @@ -41,11 +41,9 @@ return TRUE - /obj/item/clothing/accessory/proc/detach(obj/item/clothing/under/U, user) - if(pockets && pockets == U.pockets) - pockets.forceMove(src) - U.pockets = null + if(detached_pockets && detached_pockets.parent == U) + TakeComponent(detached_pockets) U.armor = U.armor.detachArmor(armor) @@ -301,14 +299,18 @@ desc = "Can protect your clothing from ink stains, but you'll look like a nerd if you're using one." icon_state = "pocketprotector" item_color = "pocketprotector" - pockets = /obj/item/storage/internal/pocket/pocketprotector + pocket_storage_component_path = /datum/component/storage/concrete/pockets/pocketprotector -/obj/item/clothing/accessory/pocketprotector/full - pockets = /obj/item/storage/internal/pocket/pocketprotector/full - -/obj/item/clothing/accessory/pocketprotector/cosmetology - pockets = /obj/item/storage/internal/pocket/pocketprotector/cosmetology +/obj/item/clothing/accessory/pocketprotector/full/Initialize() + . = ..() + new /obj/item/pen/red(src) + new /obj/item/pen(src) + new /obj/item/pen/blue(src) +/obj/item/clothing/accessory/pocketprotector/cosmetology/Initialize() + . = ..() + for(var/i in 1 to 3) + new /obj/item/lipstick/random(src) //////////////// //OONGA BOONGA// @@ -321,7 +323,6 @@ item_color = "talisman" armor = list("melee" = 5, "bullet" = 5, "laser" = 5, "energy" = 5, "bomb" = 20, "bio" = 20, "rad" = 5, "fire" = 0, "acid" = 25) - /obj/item/clothing/accessory/skullcodpiece name = "skull codpiece" desc = "A skull shaped ornament, intended to protect the important things in life." diff --git a/code/modules/detectivework/evidence.dm b/code/modules/detectivework/evidence.dm index 9c98677291..d17090816c 100644 --- a/code/modules/detectivework/evidence.dm +++ b/code/modules/detectivework/evidence.dm @@ -40,9 +40,8 @@ return if(!isturf(I.loc)) //If it isn't on the floor. Do some checks to see if it's in our hands or a box. Otherwise give up. - if(istype(I.loc, /obj/item/storage)) //in a container. - var/obj/item/storage/U = I.loc - U.remove_from_storage(I, src) + if(I.loc.SendSignal(COMSIG_CONTAINS_STORAGE)) //in a container. + I.loc.SendSignal(COMSIG_TRY_STORAGE_TAKE, I, src) if(!user.dropItemToGround(I)) return diff --git a/code/modules/events/pirates.dm b/code/modules/events/pirates.dm index 07110b5aea..09ae59503e 100644 --- a/code/modules/events/pirates.dm +++ b/code/modules/events/pirates.dm @@ -28,7 +28,7 @@ /datum/round_event/pirates/announce() priority_announce("A report has been downloaded and printed out at all communications consoles.", "Incoming Classified Message", 'sound/ai/commandreport.ogg') // CITADEL EDIT metabreak - + if(!control) //Means this is false alarm, todo : explicit checks instead of using announceWhen return threat = new @@ -63,7 +63,7 @@ var/list/candidates = pollGhostCandidates("Do you wish to be considered for pirate crew ?", ROLE_TRAITOR) shuffle_inplace(candidates) - var/datum/map_template/pirate_event_ship/ship = new + var/datum/map_template/shuttle/pirate/default/ship = new var/x = rand(TRANSITIONEDGE,world.maxx - TRANSITIONEDGE - ship.width) var/y = rand(TRANSITIONEDGE,world.maxy - TRANSITIONEDGE - ship.height) var/z = SSmapping.empty_space.z_value @@ -84,7 +84,6 @@ priority_announce("A report has been downloaded and printed out at all communications consoles.", "Incoming Classified Message", 'sound/ai/commandreport.ogg') //CITADEL EDIT also metabreak here too - //Shuttle equipment /obj/machinery/shuttle_scrambler @@ -175,10 +174,6 @@ QDEL_NULL(gps) return ..() -/datum/map_template/pirate_event_ship - name = "Pirate Ship" - mappath = "_maps/templates/pirate_ship.dmm" - /obj/item/device/gps/internal/pirate gpstag = "Nautical Signal" desc = "You can hear shanties over the static." diff --git a/code/modules/events/wizard/rpgloot.dm b/code/modules/events/wizard/rpgloot.dm index 01195a5f23..cabcc57f0c 100644 --- a/code/modules/events/wizard/rpgloot.dm +++ b/code/modules/events/wizard/rpgloot.dm @@ -13,9 +13,10 @@ if(istype(I, /obj/item/storage)) var/obj/item/storage/S = I - if(prob(upgrade_scroll_chance) && S.contents.len < S.storage_slots && !S.invisibility) + GET_COMPONENT_FROM(STR, /datum/component/storage, S) + if(prob(upgrade_scroll_chance) && S.contents.len < STR.max_items && !S.invisibility) var/obj/item/upgradescroll/scroll = new - S.handle_item_insertion(scroll,1) + S.SendSignal(COMSIG_TRY_STORAGE_INSERT, scroll, null, TRUE, TRUE) upgrade_scroll_chance = max(0,upgrade_scroll_chance-100) upgrade_scroll_chance += 25 diff --git a/code/modules/flufftext/TextFilters.dm b/code/modules/flufftext/TextFilters.dm deleted file mode 100644 index fe8bffa60f..0000000000 --- a/code/modules/flufftext/TextFilters.dm +++ /dev/null @@ -1,64 +0,0 @@ - - -//is this shit even used at all -/proc/NewStutter(phrase,stun) - phrase = html_decode(phrase) - - var/list/split_phrase = splittext(phrase," ") //Split it up into words. - - var/list/unstuttered_words = split_phrase.Copy() - var/i = rand(1,3) - if(stun) i = split_phrase.len - for(,i > 0,i--) //Pick a few words to stutter on. - - if (!unstuttered_words.len) - break - var/word = pick(unstuttered_words) - unstuttered_words -= word //Remove from unstuttered words so we don't stutter it again. - var/index = split_phrase.Find(word) //Find the word in the split phrase so we can replace it. - - //Search for dipthongs (two letters that make one sound.) - var/first_sound = copytext(word,1,3) - var/first_letter = copytext(word,1,2) - if(lowertext(first_sound) in list("ch","th","sh")) - first_letter = first_sound - - //Repeat the first letter to create a stutter. - var/rnum = rand(1,3) - switch(rnum) - if(1) - word = "[first_letter]-[word]" - if(2) - word = "[first_letter]-[first_letter]-[word]" - if(3) - word = "[first_letter]-[word]" - - split_phrase[index] = word - - return sanitize(jointext(split_phrase," ")) - -/proc/Stagger(mob/M,d) //Technically not a filter, but it relates to drunkenness. - step(M, pick(d,turn(d,90),turn(d,-90))) - -/proc/Ellipsis(original_msg, chance = 50, keep_words) - if(chance <= 0) - return "..." - if(chance >= 100) - return original_msg - - var/list - words = splittext(original_msg," ") - new_words = list() - - var/new_msg = "" - - for(var/w in words) - if(prob(chance)) - new_words += "..." - if(!keep_words) - continue - new_words += w - - new_msg = jointext(new_words," ") - - return new_msg diff --git a/code/modules/food_and_drinks/kitchen_machinery/food_cart.dm b/code/modules/food_and_drinks/kitchen_machinery/food_cart.dm index 7b67129dba..42da7e226b 100644 --- a/code/modules/food_and_drinks/kitchen_machinery/food_cart.dm +++ b/code/modules/food_and_drinks/kitchen_machinery/food_cart.dm @@ -30,6 +30,7 @@ return ..() /obj/machinery/food_cart/ui_interact(mob/user) + . = ..() var/dat dat += "
STORED INGREDIENTS AND DRINKS
" dat += "Remaining glasses: [glasses]
" @@ -91,11 +92,11 @@ to_chat(user, "[src] is at full capacity.") break else - T.remove_from_storage(S, src) - if(stored_food[sanitize(S.name)]) - stored_food[sanitize(S.name)]++ - else - stored_food[sanitize(S.name)] = 1 + if(T.SendSignal(COMSIG_TRY_STORAGE_TAKE, S, src)) + if(stored_food[sanitize(S.name)]) + stored_food[sanitize(S.name)]++ + else + stored_food[sanitize(S.name)] = 1 else if(O.is_drainable()) return else diff --git a/code/modules/food_and_drinks/kitchen_machinery/microwave.dm b/code/modules/food_and_drinks/kitchen_machinery/microwave.dm index 7139f20d91..8330c9feed 100644 --- a/code/modules/food_and_drinks/kitchen_machinery/microwave.dm +++ b/code/modules/food_and_drinks/kitchen_machinery/microwave.dm @@ -132,8 +132,8 @@ if (contents.len>=max_n_of_items) to_chat(user, "[src] is full, you can't put anything in!") return 1 - T.remove_from_storage(S, src) - loaded++ + if(T.SendSignal(COMSIG_TRY_STORAGE_TAKE, S, src)) + loaded++ if(loaded) to_chat(user, "You insert [loaded] items into [src].") @@ -165,6 +165,7 @@ ********************/ /obj/machinery/microwave/ui_interact(mob/user) // The microwave Menu + . = ..() if(panel_open || !anchored) return var/dat = "
" diff --git a/code/modules/food_and_drinks/kitchen_machinery/monkeyrecycler.dm b/code/modules/food_and_drinks/kitchen_machinery/monkeyrecycler.dm index d1896c03fc..23466305f1 100644 --- a/code/modules/food_and_drinks/kitchen_machinery/monkeyrecycler.dm +++ b/code/modules/food_and_drinks/kitchen_machinery/monkeyrecycler.dm @@ -56,7 +56,7 @@ /obj/machinery/monkey_recycler/proc/stuff_monkey_in(mob/living/carbon/monkey/target, mob/living/user) if(!istype(target)) return - if(target.stat == 0) + if(target.stat == CONSCIOUS) to_chat(user, "The monkey is struggling far too much to put it in the recycler.") return if(target.buckled || target.has_buckled_mobs()) @@ -69,17 +69,10 @@ animate(src, pixel_x = pixel_x + offset, time = 0.2, loop = 200) //start shaking use_power(500) grinded++ - sleep(50) - pixel_x = initial(pixel_x) //return to its spot after shaking - to_chat(user, "The machine now has [grinded] monkey\s worth of material stored.") + 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.")) - -/obj/machinery/monkey_recycler/attack_hand(mob/user) - . = ..() - if(.) - return - if(stat != 0) //NOPOWER etc - return +/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.") playsound(src.loc, 'sound/machines/hiss.ogg', 50, 1) @@ -89,4 +82,3 @@ to_chat(user, "The machine's display flashes that it has [grinded] 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].") - return diff --git a/code/modules/food_and_drinks/kitchen_machinery/processor.dm b/code/modules/food_and_drinks/kitchen_machinery/processor.dm index 1937ee2695..e07a957cfb 100644 --- a/code/modules/food_and_drinks/kitchen_machinery/processor.dm +++ b/code/modules/food_and_drinks/kitchen_machinery/processor.dm @@ -22,27 +22,6 @@ for(var/obj/item/stock_parts/manipulator/M in component_parts) rating_speed = M.rating -/obj/machinery/processor/process() - ..() - if(processing) - return - var/mob/living/simple_animal/slime/picked_slime - for(var/mob/living/simple_animal/slime/slime in range(1,src)) - if(slime.loc == src) - continue - if(istype(slime, /mob/living/simple_animal/slime)) - if(slime.stat) - picked_slime = slime - break - if(!picked_slime) - return - var/datum/food_processor_process/P = select_recipe(picked_slime) - if (!P) - return - - src.visible_message("[picked_slime] is sucked into [src].") - picked_slime.forceMove(src) - /obj/machinery/processor/proc/process_food(datum/food_processor_process/recipe, atom/movable/what) if (recipe.output && loc && !QDELETED(src)) for(var/i = 0, i < rating_amount, i++) @@ -53,22 +32,6 @@ else qdel(what) - -/obj/machinery/processor/slime/process_food(datum/food_processor_process/recipe, atom/movable/what) - var/mob/living/simple_animal/slime/S = what - if (istype(S)) - var/C = S.cores - if(S.stat != DEAD) - S.forceMove(drop_location()) - S.visible_message("[C] crawls free of the processor!") - return - for(var/i in 1 to (C+rating_amount-1)) - var/atom/movable/item = new S.coretype(drop_location()) - adjust_item_drop_location(item) - SSblackbox.record_feedback("tally", "slime_core_harvested", 1, S.colour) - ..() - - /obj/machinery/processor/proc/select_recipe(X) for (var/type in subtypesof(/datum/food_processor_process) - /datum/food_processor_process/mob) var/datum/food_processor_process/recipe = new type() @@ -77,9 +40,9 @@ return recipe /obj/machinery/processor/attackby(obj/item/O, mob/user, params) - if(src.processing) + if(processing) to_chat(user, "[src] is in the process of processing!") - return 1 + return TRUE if(default_deconstruction_screwdriver(user, "processor", "processor1", O)) return @@ -101,8 +64,8 @@ for(var/obj/item/reagent_containers/food/snacks/S in T.contents) var/datum/food_processor_process/P = select_recipe(S) if(P) - T.remove_from_storage(S, src) - loaded++ + if(T.SendSignal(COMSIG_TRY_STORAGE_TAKE, S, src)) + loaded++ if(loaded) to_chat(user, "You insert [loaded] items into [src].") @@ -121,16 +84,11 @@ else return ..() -/obj/machinery/processor/attack_hand(mob/user) - . = ..() - if(.) - return - if(stat & (NOPOWER|BROKEN)) - return - if(src.processing) +/obj/machinery/processor/interact(mob/user) + if(processing) to_chat(user, "[src] is in the process of processing!") - return 1 - if(user.a_intent == INTENT_GRAB && user.pulling && select_recipe(user.pulling)) + return TRUE + if(user.a_intent == INTENT_GRAB && ismob(user.pulling) && select_recipe(user.pulling)) if(user.grab_state < GRAB_AGGRESSIVE) to_chat(user, "You need a better grip to do that!") return @@ -139,9 +97,9 @@ pushed_mob.forceMove(src) user.stop_pulling() return - if(src.contents.len == 0) + if(contents.len == 0) to_chat(user, "[src] is empty!") - return 1 + return TRUE processing = TRUE user.visible_message("[user] turns on [src].", \ "You turn on [src].", \ @@ -166,7 +124,7 @@ process_food(P, O) pixel_x = initial(pixel_x) //return to its spot after shaking processing = FALSE - src.visible_message("\The [src] finishes processing.") + visible_message("\The [src] finishes processing.") /obj/machinery/processor/verb/eject() set category = "Object" @@ -175,16 +133,14 @@ if(usr.stat || !usr.canmove || usr.restrained()) return - src.empty() + empty() add_fingerprint(usr) - return /obj/machinery/processor/proc/empty() for (var/obj/O in src) O.forceMove(drop_location()) for (var/mob/M in src) M.forceMove(drop_location()) - return /obj/machinery/processor/slime name = "slime processor" @@ -208,3 +164,37 @@ AM.pixel_x = -8 + ((ii%3)*8) AM.pixel_y = -8 + (round(ii/3)*8) return i + +/obj/machinery/processor/slime/process() + if(processing) + return + var/mob/living/simple_animal/slime/picked_slime + for(var/mob/living/simple_animal/slime/slime in range(1,src)) + if(slime.loc == src) + continue + if(istype(slime, /mob/living/simple_animal/slime)) + if(slime.stat) + picked_slime = slime + break + if(!picked_slime) + return + var/datum/food_processor_process/P = select_recipe(picked_slime) + if (!P) + return + + visible_message("[picked_slime] is sucked into [src].") + picked_slime.forceMove(src) + +/obj/machinery/processor/slime/process_food(datum/food_processor_process/recipe, atom/movable/what) + var/mob/living/simple_animal/slime/S = what + if (istype(S)) + var/C = S.cores + if(S.stat != DEAD) + S.forceMove(drop_location()) + S.visible_message("[C] crawls free of the processor!") + return + for(var/i in 1 to (C+rating_amount-1)) + var/atom/movable/item = new S.coretype(drop_location()) + adjust_item_drop_location(item) + SSblackbox.record_feedback("tally", "slime_core_harvested", 1, S.colour) + ..() diff --git a/code/modules/food_and_drinks/kitchen_machinery/smartfridge.dm b/code/modules/food_and_drinks/kitchen_machinery/smartfridge.dm index 8be93e88bf..1149d917dd 100644 --- a/code/modules/food_and_drinks/kitchen_machinery/smartfridge.dm +++ b/code/modules/food_and_drinks/kitchen_machinery/smartfridge.dm @@ -125,12 +125,15 @@ var/mob/M = O.loc if(!M.transferItemToLoc(O, src)) to_chat(usr, "\the [O] is stuck to your hand, you cannot put it in \the [src]!") - return + return FALSE + else + return TRUE else - if(istype(O.loc, /obj/item/storage)) - var/obj/item/storage/S = O.loc - S.remove_from_storage(O,src) - O.forceMove(src) + if(O.loc.SendSignal(COMSIG_CONTAINS_STORAGE)) + return O.loc.SendSignal(COMSIG_TRY_STORAGE_TAKE, O, src) + else + O.forceMove(src) + return TRUE /obj/machinery/smartfridge/attack_ai(mob/user) return FALSE diff --git a/code/modules/holiday/easter.dm b/code/modules/holiday/easter.dm index c9fc793d0d..6cc3f56461 100644 --- a/code/modules/holiday/easter.dm +++ b/code/modules/holiday/easter.dm @@ -65,18 +65,22 @@ name = "Easter Basket" icon = 'icons/mob/easter.dmi' icon_state = "basket" - can_hold = list(/obj/item/reagent_containers/food/snacks/egg, /obj/item/reagent_containers/food/snacks/chocolateegg, /obj/item/reagent_containers/food/snacks/boiledegg) + +/obj/item/storage/bag/easterbasket/Initialize() + . = ..() + GET_COMPONENT(STR, /datum/component/storage) + STR.can_hold = typecacheof(list(/obj/item/reagent_containers/food/snacks/egg, /obj/item/reagent_containers/food/snacks/chocolateegg, /obj/item/reagent_containers/food/snacks/boiledegg)) /obj/item/storage/bag/easterbasket/proc/countEggs() cut_overlays() add_overlay("basket-grass") add_overlay("basket-egg[min(contents.len, 5)]") -/obj/item/storage/bag/easterbasket/remove_from_storage(obj/item/W as obj, atom/new_location) - ..() +/obj/item/storage/bag/easterbasket/Exited() + . = ..() countEggs() -/obj/item/storage/bag/easterbasket/handle_item_insertion(obj/item/I, prevent_warning = 0) +/obj/item/storage/bag/easterbasket/Entered() . = ..() countEggs() diff --git a/code/modules/hydroponics/biogenerator.dm b/code/modules/hydroponics/biogenerator.dm index b69e5e6302..65aaba95e7 100644 --- a/code/modules/hydroponics/biogenerator.dm +++ b/code/modules/hydroponics/biogenerator.dm @@ -116,8 +116,8 @@ for(var/obj/item/reagent_containers/food/snacks/grown/G in PB.contents) if(i >= max_items) break - PB.remove_from_storage(G, src) - i++ + if(PB.SendSignal(COMSIG_TRY_STORAGE_TAKE, G, src)) + i++ if(iYou empty the plant bag into the biogenerator.") else if(PB.contents.len == 0) diff --git a/code/modules/hydroponics/hydroponics.dm b/code/modules/hydroponics/hydroponics.dm index f460b3fbed..44ec4d56ee 100644 --- a/code/modules/hydroponics/hydroponics.dm +++ b/code/modules/hydroponics/hydroponics.dm @@ -787,11 +787,8 @@ else if(istype(O, /obj/item/storage/bag/plants)) attack_hand(user) - var/obj/item/storage/bag/plants/S = O for(var/obj/item/reagent_containers/food/snacks/grown/G in locate(user.x,user.y,user.z)) - if(!S.can_be_inserted(G)) - return - S.handle_item_insertion(G, 1) + O.SendSignal(COMSIG_TRY_STORAGE_INSERT, G, user, TRUE) else if(istype(O, /obj/item/wrench) && unwrenchable) if(using_irrigation) diff --git a/code/modules/hydroponics/seed_extractor.dm b/code/modules/hydroponics/seed_extractor.dm index cd8268c596..f188466434 100644 --- a/code/modules/hydroponics/seed_extractor.dm +++ b/code/modules/hydroponics/seed_extractor.dm @@ -74,7 +74,7 @@ if(default_deconstruction_crowbar(O)) return - if (istype(O, /obj/item/storage/bag/plants)) + 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) @@ -83,7 +83,7 @@ ++loaded add_seed(G) if (loaded) - to_chat(user, "You put the seeds from \the [O.name] into [src].") + to_chat(user, "You put as many seeds from \the [O.name] into [src] as you can.") else to_chat(user, "There are no seeds in \the [O.name].") return @@ -122,6 +122,7 @@ src.amount = am /obj/machinery/seed_extractor/ui_interact(mob/user) + . = ..() if (stat) return FALSE @@ -175,21 +176,21 @@ /obj/machinery/seed_extractor/proc/add_seed(obj/item/seeds/O) if(contents.len >= 999) to_chat(usr, "\The [src] is full.") - return 0 + return FALSE - if(ismob(O.loc)) + GET_COMPONENT_FROM(STR, /datum/component/storage, O.loc) + 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 0 - else if(istype(O.loc, /obj/item/storage)) - var/obj/item/storage/S = O.loc - S.remove_from_storage(O,src) + return FALSE - . = 1 + . = TRUE for (var/datum/seed_pile/N in piles) if (O.plantname == N.name && O.lifespan == N.lifespan && O.endurance == N.endurance && O.maturation == N.maturation && O.production == N.production && O.yield == N.yield && O.potency == N.potency) ++N.amount return piles += new /datum/seed_pile(O.plantname, O.lifespan, O.endurance, O.maturation, O.production, O.yield, O.potency) - return diff --git a/code/modules/integrated_electronics/subtypes/input.dm b/code/modules/integrated_electronics/subtypes/input.dm index 86d85f7876..a61dc18d34 100644 --- a/code/modules/integrated_electronics/subtypes/input.dm +++ b/code/modules/integrated_electronics/subtypes/input.dm @@ -817,7 +817,8 @@ return FALSE var/ignore_bags = get_pin_data(IC_INPUT, 1) if(ignore_bags) - if(istype(A, /obj/item/storage)) + GET_COMPONENT_FROM(STR, /datum/component/storage, A) + if(STR) return FALSE set_pin_data(IC_OUTPUT, 1, WEAKREF(A)) push_data() diff --git a/code/modules/keybindings/bindings_human.dm b/code/modules/keybindings/bindings_human.dm index b0e2994ffc..7c52917386 100644 --- a/code/modules/keybindings/bindings_human.dm +++ b/code/modules/keybindings/bindings_human.dm @@ -17,9 +17,7 @@ to_chat(user, "You can't fit anything in.") return if(thing) // put thing in belt - if(equipped_belt.can_be_inserted(thing)) - equipped_belt.handle_item_insertion(thing) - else + if(!equipped_belt.SendSignal(COMSIG_TRY_STORAGE_INSERT, thing, user.mob)) to_chat(user, "You can't fit anything in.") return if(!equipped_belt.contents.len) // nothing to take out @@ -47,9 +45,7 @@ to_chat(user, "You can't fit anything in.") return if(thing) // put thing in backpack - if(equipped_backpack.can_be_inserted(thing)) - equipped_backpack.handle_item_insertion(thing) - else + if(!equipped_backpack.SendSignal(COMSIG_TRY_STORAGE_INSERT, thing, user.mob)) to_chat(user, "You can't fit anything in.") return if(!equipped_backpack.contents.len) // nothing to take out diff --git a/code/modules/library/lib_items.dm b/code/modules/library/lib_items.dm index de7edc69b1..4126cc4768 100644 --- a/code/modules/library/lib_items.dm +++ b/code/modules/library/lib_items.dm @@ -24,7 +24,6 @@ var/state = 0 var/list/allowed_books = list(/obj/item/book, /obj/item/spellbook, /obj/item/storage/book) //Things allowed in the bookcase - /obj/structure/bookcase/examine(mob/user) ..() if(!anchored) @@ -39,7 +38,6 @@ if(2) to_chat(user, "There's a small crack visible on the shelf.") - /obj/structure/bookcase/Initialize(mapload) . = ..() if(!mapload) @@ -52,7 +50,6 @@ I.forceMove(src) update_icon() - /obj/structure/bookcase/attackby(obj/item/I, mob/user, params) switch(state) if(0) @@ -81,15 +78,15 @@ state = 0 if(2) + GET_COMPONENT_FROM(STR, /datum/component/storage, I) if(is_type_in_list(I, allowed_books)) if(!user.transferItemToLoc(I, src)) return update_icon() - else if(istype(I, /obj/item/storage/bag/books)) - var/obj/item/storage/bag/books/B = I - for(var/obj/item/T in B.contents) + else if(STR) + for(var/obj/item/T in I.contents) if(istype(T, /obj/item/book) || istype(T, /obj/item/spellbook)) - B.remove_from_storage(T, src) + STR.remove_from_storage(T, src) to_chat(user, "You empty \the [I] into \the [src].") update_icon() else if(istype(I, /obj/item/pen)) diff --git a/code/modules/lighting/lighting_area.dm b/code/modules/lighting/lighting_area.dm index b581956307..58e9a4337a 100644 --- a/code/modules/lighting/lighting_area.dm +++ b/code/modules/lighting/lighting_area.dm @@ -10,13 +10,13 @@ if (IS_DYNAMIC_LIGHTING(src)) cut_overlay(/obj/effect/fullbright) - for (var/turf/T in area_contents(src)) + for (var/turf/T in src) if (IS_DYNAMIC_LIGHTING(T)) T.lighting_build_overlay() else add_overlay(/obj/effect/fullbright) - for (var/turf/T in area_contents(src)) + for (var/turf/T in src) if (T.lighting_object) T.lighting_clear_overlay() diff --git a/code/modules/mapping/map_template.dm b/code/modules/mapping/map_template.dm index b9dbb42d28..b5b2091eb9 100644 --- a/code/modules/mapping/map_template.dm +++ b/code/modules/mapping/map_template.dm @@ -88,7 +88,7 @@ initTemplateBounds(bounds) log_game("[name] loaded at at [T.x],[T.y],[T.z]") - return TRUE + return bounds /datum/map_template/proc/get_affected_turfs(turf/T, centered = FALSE) var/turf/placement = T diff --git a/code/modules/mining/aux_base.dm b/code/modules/mining/aux_base.dm index ccd9784448..8acaf2e495 100644 --- a/code/modules/mining/aux_base.dm +++ b/code/modules/mining/aux_base.dm @@ -174,7 +174,6 @@ interface with the mining shuttle at the landing site if a mobile beacon is also landing_zone.width = base_dock.width landing_zone.height = base_dock.height landing_zone.setDir(base_dock.dir) - landing_zone.turf_type = T.type landing_zone.area_type = A.type possible_destinations += "[landing_zone.id];" @@ -320,7 +319,6 @@ obj/docking_port/stationary/public_mining_dock Mport.width = SM.width Mport.height = SM.height Mport.setDir(dir) - Mport.turf_type = landing_spot.type Mport.area_type = A.type break diff --git a/code/modules/mining/fulton.dm b/code/modules/mining/fulton.dm index 61940b4044..a6cbbfcedd 100644 --- a/code/modules/mining/fulton.dm +++ b/code/modules/mining/fulton.dm @@ -63,8 +63,7 @@ GLOBAL_LIST_EMPTY(total_extraction_beacons) to_chat(user, "You attach the pack to [A] and activate it.") if(loc == user && istype(user.back, /obj/item/storage/backpack)) var/obj/item/storage/backpack/B = user.back - if(B.can_be_inserted(src,stop_messages = 1)) - B.handle_item_insertion(src) + B.SendSignal(COMSIG_TRY_STORAGE_INSERT, src, user, FALSE, FALSE) uses_left-- if(uses_left <= 0) user.transferItemToLoc(src, A, TRUE) diff --git a/code/modules/mining/lavaland/necropolis_chests.dm b/code/modules/mining/lavaland/necropolis_chests.dm index 330c0cbf2a..cfffef59fc 100644 --- a/code/modules/mining/lavaland/necropolis_chests.dm +++ b/code/modules/mining/lavaland/necropolis_chests.dm @@ -433,25 +433,13 @@ //Shared Bag -//Internal - -/obj/item/storage/backpack/shared - name = "paradox bag" - desc = "Somehow, it's in two places at once." - max_combined_w_class = 60 - max_w_class = WEIGHT_CLASS_NORMAL - - -//External - /obj/item/device/shared_storage name = "paradox bag" desc = "Somehow, it's in two places at once." icon = 'icons/obj/storage.dmi' icon_state = "cultpack" slot_flags = SLOT_BACK - var/obj/item/storage/backpack/shared/bag - + resistance_flags = INDESTRUCTIBLE /obj/item/device/shared_storage/red name = "paradox bag" @@ -459,53 +447,20 @@ /obj/item/device/shared_storage/red/Initialize() . = ..() - if(!bag) - var/obj/item/storage/backpack/shared/S = new(src) - var/obj/item/device/shared_storage/blue = new(src.loc) - - src.bag = S - blue.bag = S - - -/obj/item/device/shared_storage/attackby(obj/item/W, mob/user, params) - if(bag) - bag.forceMove(user) - bag.attackby(W, user, params) - - -/obj/item/device/shared_storage/attack_hand(mob/living/carbon/user) - if(!iscarbon(user)) - return - if(loc == user && user.back && user.back == src) - if(bag) - bag.forceMove(user) - bag.attack_hand(user) - else - ..() - - -/obj/item/device/shared_storage/MouseDrop(atom/over_object) - if(iscarbon(usr) || isdrone(usr)) - var/mob/M = usr - - if(!over_object) - return - - if(ismecha(usr.loc)) - return - - if(!M.incapacitated()) - playsound(loc, "rustle", 50, 1, -5) - - - if(istype(over_object, /obj/screen/inventory/hand)) - var/obj/screen/inventory/hand/H = over_object - M.putItemFromInventoryInHandIfPossible(src, H.held_index) - - add_fingerprint(usr) - - + var/datum/component/storage/STR = AddComponent(/datum/component/storage/concrete) + STR.max_w_class = WEIGHT_CLASS_NORMAL + STR.max_combined_w_class = 60 + STR.max_items = 21 + new /obj/item/device/shared_storage/blue(drop_location(), STR) +/obj/item/device/shared_storage/blue/Initialize(mapload, datum/component/storage/concrete/master) + . = ..() + if(!istype(master)) + return INITIALIZE_HINT_QDEL + var/datum/component/storage/STR = AddComponent(/datum/component/storage, master) + STR.max_w_class = WEIGHT_CLASS_NORMAL + STR.max_combined_w_class = 60 + STR.max_items = 21 //Book of Babel diff --git a/code/modules/mining/money_bag.dm b/code/modules/mining/money_bag.dm index befaef31a2..f567bd1daf 100644 --- a/code/modules/mining/money_bag.dm +++ b/code/modules/mining/money_bag.dm @@ -8,14 +8,16 @@ resistance_flags = FLAMMABLE max_integrity = 100 w_class = WEIGHT_CLASS_BULKY - max_w_class = WEIGHT_CLASS_NORMAL - storage_slots = 80 - max_combined_w_class = 40 - can_hold = list(/obj/item/coin, /obj/item/stack/spacecash) - -/obj/item/storage/bag/money/vault/Initialize() +/obj/item/storage/bag/money/Initialize() . = ..() + GET_COMPONENT(STR, /datum/component/storage) + STR.max_w_class = WEIGHT_CLASS_NORMAL + STR.max_items = 40 + STR.max_combined_w_class = 40 + STR.can_hold = typecacheof(list(/obj/item/coin, /obj/item/stack/spacecash)) + +/obj/item/storage/bag/money/vault/PopulateContents() new /obj/item/coin/silver(src) new /obj/item/coin/silver(src) new /obj/item/coin/silver(src) diff --git a/code/modules/mining/satchel_ore_boxdm.dm b/code/modules/mining/satchel_ore_boxdm.dm index a12d56fbbb..78f4676d4e 100644 --- a/code/modules/mining/satchel_ore_boxdm.dm +++ b/code/modules/mining/satchel_ore_boxdm.dm @@ -9,14 +9,12 @@ density = TRUE pressure_resistance = 5*ONE_ATMOSPHERE -/obj/structure/ore_box/attackby(obj/item/I, mob/user, params) - if(istype(I, /obj/item/ore)) - user.transferItemToLoc(I, src) - else if(istype(I, /obj/item/storage)) - var/obj/item/storage/S = I - for(var/obj/item/stack/ore/O in S.contents) - S.remove_from_storage(O, src) //This will move the item to this item's contents - to_chat(user, "You empty the ore in [S] into \the [src].") +/obj/structure/ore_box/attackby(obj/item/W, mob/user, params) + if (istype(W, /obj/item/stack/ore)) + user.transferItemToLoc(W, src) + else if(W.SendSignal(COMSIG_CONTAINS_STORAGE)) + W.SendSignal(COMSIG_TRY_STORAGE_TAKE_TYPE, /obj/item/stack/ore, src) + to_chat(user, "You empty the ore in [W] into \the [src].") else return ..() diff --git a/code/modules/modular_computers/documentation.dm b/code/modules/modular_computers/documentation.dm deleted file mode 100644 index 94e02f8125..0000000000 --- a/code/modules/modular_computers/documentation.dm +++ /dev/null @@ -1,40 +0,0 @@ -/* - -Ok. so a quick rundown on how to make a program. This is kind of a shitty documentation, but oh well I was asked to. - - -This is how the base program is setup. the rest is mostly tgui stuff. I'll use the ntnetmonitor as a base - -/datum/computer_file/program/ntnetmonitor - filename = "ntmonitor" <- This is obviously the name of the file itself. not much to be said - filedesc = "NTNet Diagnostics and Monitoring" <- This sort of the official name. it's what shows up on the main menu - program_icon_state = "comm_monitor" <- This is what the screen will look like when the program is active - extended_desc = "This program is a dummy. <- This is a sort of description, visible when looking on the ntnet - size = 12 <- size of the program. Big programs need more hard drive space. Don't make it too big though. - requires_ntnet = 1 <- if this is set, the program will not run and will close if ntnet connection is lost. mainly for primarily online programs. - required_access = access_network <- This is access required to run the program itself. ONLY SET THIS FOR SUPER SECURE SHIT. This also acts as transfer_access as well. - transfer_access = access_change_ids <- this is the access needed to download from ntnet or host on the ptp program. This is what you want to use most of the time. - available_on_ntnet = 1 <- If it's available to download on ntnet. pretty self explanatory. - available_on_syndinet = 0 <- ditto but on emagged syndie net. Use this for antag programs - usage_flags = PROGRAM_ALL // Bitflags (PROGRAM_CONSOLE, PROGRAM_LAPTOP, PROGRAM_TABLET combination) or PROGRAM_ALL - ^^- The comment above sorta explains it. Use this to limit what kind of machines can run the program. For example, comms program should be limited to consoles and laptops. - var/ui_header = "downloader_finished.gif" <- this one is kinda cool. If you have the program minimized, this will show up in the header of the computer screen. - you can even have the program change what the header is based on the situation! see alarm.dm for an example. - - -Now. for pre-installing stuff. - -Primarily done for consoles, there's an install_programs() proc in the console presets file in the machines folder. - -for example, the command console one. - -/obj/machinery/modular_computer/console/preset/command/install_programs() - cpu.hard_drive.store_file(new/datum/computer_file/program/chatclient()) - cpu.hard_drive.store_file(new/datum/computer_file/program/card_mod()) - -Basically, you want to do cpu.hard_drive.store_file(new/*program path here*()) and put it in the subtype's install_programs(). -Probably pretty self explanatory, but just in case. - -Will probably be expanded when new features come around or I get asked to mention something. - -*/ \ No newline at end of file diff --git a/code/modules/modular_computers/file_system/programs/sm_monitor.dm b/code/modules/modular_computers/file_system/programs/sm_monitor.dm index c2cbd5afec..138e8bb9dd 100644 --- a/code/modules/modular_computers/file_system/programs/sm_monitor.dm +++ b/code/modules/modular_computers/file_system/programs/sm_monitor.dm @@ -13,7 +13,7 @@ ui_y = 400 var/last_status = SUPERMATTER_INACTIVE var/list/supermatters - var/obj/machinery/power/supermatter_shard/active // Currently selected supermatter crystal. + var/obj/machinery/power/supermatter_crystal/active // Currently selected supermatter crystal. /datum/computer_file/program/supermatter_monitor/process_tick() @@ -41,7 +41,7 @@ var/turf/T = get_turf(ui_host()) if(!T) return - for(var/obj/machinery/power/supermatter_shard/S in GLOB.machines) + for(var/obj/machinery/power/supermatter_crystal/S in GLOB.machines) // Delaminating, not within coverage, not on a tile. if (!isturf(S.loc) || !(is_station_level(S.z) || is_mining_level(S.z) || S.z == T.z)) continue @@ -52,7 +52,7 @@ /datum/computer_file/program/supermatter_monitor/proc/get_status() . = SUPERMATTER_INACTIVE - for(var/obj/machinery/power/supermatter_shard/S in supermatters) + for(var/obj/machinery/power/supermatter_crystal/S in supermatters) . = max(., S.get_status()) /datum/computer_file/program/supermatter_monitor/ui_data() @@ -93,7 +93,7 @@ data["gases"] = gasdata else var/list/SMS = list() - for(var/obj/machinery/power/supermatter_shard/S in supermatters) + for(var/obj/machinery/power/supermatter_crystal/S in supermatters) var/area/A = get_area(S) if(A) SMS.Add(list(list( @@ -120,7 +120,7 @@ return TRUE if("PRG_set") var/newuid = text2num(params["target"]) - for(var/obj/machinery/power/supermatter_shard/S in supermatters) + for(var/obj/machinery/power/supermatter_crystal/S in supermatters) if(S.uid == newuid) active = S return TRUE \ No newline at end of file diff --git a/code/modules/ninja/suit/n_suit_verbs/ninja_stealth.dm b/code/modules/ninja/suit/n_suit_verbs/ninja_stealth.dm index 8103fa2415..1c3fbd8147 100644 --- a/code/modules/ninja/suit/n_suit_verbs/ninja_stealth.dm +++ b/code/modules/ninja/suit/n_suit_verbs/ninja_stealth.dm @@ -11,13 +11,13 @@ Contents: var/mob/living/carbon/human/U = affecting if(!U) return - if(s_active) + if(stealth) cancel_stealth() else if(cell.charge <= 0) to_chat(U, "You don't have enough power to enable Stealth!") return - s_active=!s_active + stealth = !stealth animate(U, alpha = 50,time = 15) U.visible_message("[U.name] vanishes into thin air!", \ "You are now mostly invisible to normal detection.") @@ -27,8 +27,8 @@ Contents: var/mob/living/carbon/human/U = affecting if(!U) return 0 - if(s_active) - s_active=!s_active + if(stealth) + stealth = !stealth animate(U, alpha = 255, time = 15) U.visible_message("[U.name] appears from thin air!", \ "You are now visible.") diff --git a/code/modules/ninja/suit/n_suit_verbs/ninja_teleporting.dm b/code/modules/ninja/suit/n_suit_verbs/ninja_teleporting.dm deleted file mode 100644 index 74dcec12ce..0000000000 --- a/code/modules/ninja/suit/n_suit_verbs/ninja_teleporting.dm +++ /dev/null @@ -1,71 +0,0 @@ - - -/* - -Contents: -- Proc for handling teleporting while grabbing someone -- Telport Ability -- Right-Click Teleport Ability - -*/ - - -//Handles elporting while grabbing someone -/obj/item/clothing/suit/space/space_ninja/proc/handle_teleport_grab(turf/T, mob/living/H) - if(H.pulling && (isliving(H.pulling))) - var/mob/living/victim = H.pulling - if(!victim.anchored) - victim.forceMove(locate(T.x+rand(-1,1),T.y+rand(-1,1),T.z)) - - -//Jaunt -/obj/item/clothing/suit/space/space_ninja/proc/ninjajaunt() - if(!ninjacost(100,N_STEALTH_CANCEL)) - var/mob/living/carbon/human/H = affecting - var/turf/destination = get_teleport_loc(H.loc,H,9,1,3,1,0,1) - var/turf/mobloc = get_turf(H.loc)//Safety - - if(destination && isturf(mobloc))//So we don't teleport out of containers - playsound(H.loc, "sparks", 50, 1) - new /obj/effect/temp_visual/dir_setting/ninja/phase/out(get_turf(H), H.dir) - - handle_teleport_grab(destination, H) - H.loc = destination - - spark_system.start() - playsound(H.loc, 'sound/effects/phasein.ogg', 25, 1) - playsound(H.loc, "sparks", 50, 1) - new /obj/effect/temp_visual/dir_setting/ninja/phase(get_turf(H), H.dir) - - destination.phase_damage_creatures(20,H)//Paralyse and damage mobs and mechas on the turf - s_coold = 1 - else - to_chat(H, "The VOID-shift device is malfunctioning, teleportation failed.") - - -//Right-Click teleport: It's basically admin "jump to turf" -/obj/item/clothing/suit/space/space_ninja/proc/ninjashift(turf/T in oview()) - set name = "Phase Shift (20E)" - set desc = "Utilizes the internal VOID-shift device to rapidly transit to a destination in view." - set category = null//So it does not show up on the panel but can still be right-clicked. - set src = usr.contents//Fixes verbs not attaching properly for objects. Praise the DM reference guide! - - if(!ninjacost(200,N_STEALTH_CANCEL)) - var/mob/living/carbon/human/H = affecting - var/turf/mobloc = get_turf(H.loc)//To make sure that certain things work properly below. - if(!T.density && isturf(mobloc)) - playsound(H.loc, "sparks", 50, 1) - new /obj/effect/temp_visual/dir_setting/ninja/phase/out(get_turf(H), H.dir) - - handle_teleport_grab(T, H) - H.forceMove(T) - - spark_system.start() - playsound(H.loc, 'sound/effects/phasein.ogg', 25, 1) - playsound(H.loc, "sparks", 50, 1) - new /obj/effect/temp_visual/dir_setting/ninja/phase(get_turf(H), H.dir) - - T.phase_damage_creatures(20,H)//Paralyse and damage mobs and mechas on the turf - s_coold = 1 - else - to_chat(H, "You cannot teleport into solid walls or from solid matter") diff --git a/code/modules/ninja/suit/suit.dm b/code/modules/ninja/suit/suit.dm index 8b0b4cd256..5886e1723d 100644 --- a/code/modules/ninja/suit/suit.dm +++ b/code/modules/ninja/suit/suit.dm @@ -48,7 +48,7 @@ Contents: var/s_maxamount = 20//Maximum number of smoke bombs. //Support function variables. - var/s_active = 0//Stealth off. + var/stealth = FALSE//Stealth off. var/s_busy = FALSE//Is the suit busy with a process? Like AI hacking. Used for safety functions. //Ability function variables. @@ -152,7 +152,7 @@ Contents: if(s_initialized) if(user == affecting) to_chat(user, "All systems operational. Current energy capacity: [DisplayEnergy(cell.charge)].") - to_chat(user, "The CLOAK-tech device is [s_active?"active":"inactive"].") + to_chat(user, "The CLOAK-tech device is [stealth?"active":"inactive"].") to_chat(user, "There are [s_bombs] smoke bomb\s remaining.") to_chat(user, "There are [a_boost] adrenaline booster\s remaining.") diff --git a/code/modules/ninja/suit/suit_process.dm b/code/modules/ninja/suit/suit_process.dm index c9e955b359..4a89a59f75 100644 --- a/code/modules/ninja/suit/suit_process.dm +++ b/code/modules/ninja/suit/suit_process.dm @@ -10,7 +10,7 @@ s_coold--//Checks for ability s_cooldown first. cell.charge -= s_cost//s_cost is the default energy cost each ntick, usually 5. - if(s_active)//If stealth is active. + if(stealth)//If stealth is active. cell.charge -= s_acost else diff --git a/code/modules/ninja/suit/suit_verbs_handlers.dm b/code/modules/ninja/suit/suit_verbs_handlers.dm deleted file mode 100644 index 35070a52dd..0000000000 --- a/code/modules/ninja/suit/suit_verbs_handlers.dm +++ /dev/null @@ -1,26 +0,0 @@ -/* - -Contents: -- Procs that add ninja verbs to ninjas -- Procs that remove ninja verbs from ninjas -- Procs that add ninjasuit verbs to ninjas -- Procs that remove ninjasuit verbs from ninjas - -*/ - -/obj/item/clothing/suit/space/space_ninja/proc/grant_equip_verbs() - n_gloves.verbs += /obj/item/clothing/gloves/space_ninja/proc/toggledrain - - s_initialized = 1 - - -/obj/item/clothing/suit/space/space_ninja/proc/remove_equip_verbs() - if(n_gloves) - n_gloves.verbs -= /obj/item/clothing/gloves/space_ninja/proc/toggledrain - - s_initialized = 0 - - -/obj/item/clothing/suit/space/space_ninja/proc/grant_ninja_verbs() - s_initialized=1 - slowdown=0 \ No newline at end of file diff --git a/code/modules/paperwork/photography.dm b/code/modules/paperwork/photography.dm index 31bcc537e9..dac5ba3b52 100644 --- a/code/modules/paperwork/photography.dm +++ b/code/modules/paperwork/photography.dm @@ -110,9 +110,13 @@ item_state = "briefcase" lefthand_file = 'icons/mob/inhands/equipment/briefcase_lefthand.dmi' righthand_file = 'icons/mob/inhands/equipment/briefcase_righthand.dmi' - can_hold = list(/obj/item/photo) resistance_flags = FLAMMABLE +/obj/item/storage/photo_album/Initialize() + . = ..() + GET_COMPONENT(STR, /datum/component/storage) + STR.can_hold = typecacheof(list(/obj/item/photo)) + /* * Camera */ diff --git a/code/modules/power/apc.dm b/code/modules/power/apc.dm index f764a38d64..7694387975 100644 --- a/code/modules/power/apc.dm +++ b/code/modules/power/apc.dm @@ -1,30 +1,30 @@ //update_state -#define UPSTATE_CELL_IN 1 -#define UPSTATE_OPENED1 2 -#define UPSTATE_OPENED2 4 -#define UPSTATE_MAINT 8 -#define UPSTATE_BROKE 16 -#define UPSTATE_BLUESCREEN 32 -#define UPSTATE_WIREEXP 64 -#define UPSTATE_ALLGOOD 128 +#define UPSTATE_CELL_IN (1<<0) +#define UPSTATE_OPENED1 (1<<1) +#define UPSTATE_OPENED2 (1<<2) +#define UPSTATE_MAINT (1<<3) +#define UPSTATE_BROKE (1<<4) +#define UPSTATE_BLUESCREEN (1<<5) +#define UPSTATE_WIREEXP (1<<6) +#define UPSTATE_ALLGOOD (1<<7) #define APC_RESET_EMP "emp" //update_overlay -#define APC_UPOVERLAY_CHARGEING0 1 -#define APC_UPOVERLAY_CHARGEING1 2 -#define APC_UPOVERLAY_CHARGEING2 4 -#define APC_UPOVERLAY_EQUIPMENT0 8 -#define APC_UPOVERLAY_EQUIPMENT1 16 -#define APC_UPOVERLAY_EQUIPMENT2 32 -#define APC_UPOVERLAY_LIGHTING0 64 -#define APC_UPOVERLAY_LIGHTING1 128 -#define APC_UPOVERLAY_LIGHTING2 256 -#define APC_UPOVERLAY_ENVIRON0 512 -#define APC_UPOVERLAY_ENVIRON1 1024 -#define APC_UPOVERLAY_ENVIRON2 2048 -#define APC_UPOVERLAY_LOCKED 4096 -#define APC_UPOVERLAY_OPERATING 8192 +#define APC_UPOVERLAY_CHARGEING0 (1<<0) +#define APC_UPOVERLAY_CHARGEING1 (1<<1) +#define APC_UPOVERLAY_CHARGEING2 (1<<2) +#define APC_UPOVERLAY_EQUIPMENT0 (1<<3) +#define APC_UPOVERLAY_EQUIPMENT1 (1<<4) +#define APC_UPOVERLAY_EQUIPMENT2 (1<<5) +#define APC_UPOVERLAY_LIGHTING0 (1<<6) +#define APC_UPOVERLAY_LIGHTING1 (1<<7) +#define APC_UPOVERLAY_LIGHTING2 (1<<8) +#define APC_UPOVERLAY_ENVIRON0 (1<<9) +#define APC_UPOVERLAY_ENVIRON1 (1<<10) +#define APC_UPOVERLAY_ENVIRON2 (1<<11) +#define APC_UPOVERLAY_LOCKED (1<<12) +#define APC_UPOVERLAY_OPERATING (1<<13) // the Area Power Controller (APC), formerly Power Distribution Unit (PDU) @@ -911,12 +911,11 @@ update() if("emergency_lighting") emergency_lights = !emergency_lights - for(var/area/A in area.related) - for(var/obj/machinery/light/L in A) - if(!initial(L.no_emergency)) //If there was an override set on creation, keep that override - L.no_emergency = emergency_lights - INVOKE_ASYNC(L, /obj/machinery/light/.proc/update, FALSE) - CHECK_TICK + for(var/obj/machinery/light/L in area) + if(!initial(L.no_emergency)) //If there was an override set on creation, keep that override + L.no_emergency = emergency_lights + INVOKE_ASYNC(L, /obj/machinery/light/.proc/update, FALSE) + CHECK_TICK return 1 /obj/machinery/power/apc/proc/toggle_breaker() @@ -1281,12 +1280,11 @@ INVOKE_ASYNC(src, .proc/break_lights) /obj/machinery/power/apc/proc/break_lights() - for(var/area/A in area.related) - for(var/obj/machinery/light/L in A) - L.on = TRUE - L.break_light_tube() - L.on = FALSE - stoplag() + for(var/obj/machinery/light/L in area) + L.on = TRUE + L.break_light_tube() + L.on = FALSE + stoplag() /obj/machinery/power/apc/proc/shock(mob/user, prb) if(!prob(prb)) @@ -1322,12 +1320,11 @@ /obj/machinery/power/apc/proc/set_nightshift(on) set waitfor = FALSE nightshift_lights = on - for(var/area/A in area.related) - for(var/obj/machinery/light/L in A) - if(L.nightshift_allowed) - L.nightshift_enabled = nightshift_lights - L.update(FALSE) - CHECK_TICK + for(var/obj/machinery/light/L in area) + if(L.nightshift_allowed) + L.nightshift_enabled = nightshift_lights + L.update(FALSE) + CHECK_TICK #undef UPSTATE_CELL_IN #undef UPSTATE_OPENED1 @@ -1356,8 +1353,6 @@ #undef APC_UPOVERLAY_LOCKED #undef APC_UPOVERLAY_OPERATING -#undef APC_UPDATE_ICON_COOLDOWN - /*Power module, used for APC construction*/ /obj/item/electronics/apc name = "power control module" diff --git a/code/modules/power/singularity/singularity.dm b/code/modules/power/singularity/singularity.dm index 2a7fd37c65..ff9c79d069 100644 --- a/code/modules/power/singularity/singularity.dm +++ b/code/modules/power/singularity/singularity.dm @@ -272,7 +272,7 @@ /obj/singularity/proc/consume(atom/A) var/gain = A.singularity_act(current_size, src) src.energy += gain - if(istype(A, /obj/machinery/power/supermatter_shard) && !consumedSupermatter) + if(istype(A, /obj/machinery/power/supermatter_crystal) && !consumedSupermatter) desc = "[initial(desc)] It glows fiercely with inner fire." name = "supermatter-charged [initial(name)]" consumedSupermatter = 1 diff --git a/code/modules/power/supermatter/supermatter.dm b/code/modules/power/supermatter/supermatter.dm index ed238f7fb7..d20754c4cb 100644 --- a/code/modules/power/supermatter/supermatter.dm +++ b/code/modules/power/supermatter/supermatter.dm @@ -22,7 +22,7 @@ #define SEVERE_POWER_PENALTY_THRESHOLD 7000 //Same as above, but causes more dangerous effects #define CRITICAL_POWER_PENALTY_THRESHOLD 9000 //Even more dangerous effects, threshold for tesla delamination #define HEAT_PENALTY_THRESHOLD 40 //Higher == Crystal safe operational temperature is higher. -#define DAMAGE_HARDCAP 0.0025 +#define DAMAGE_HARDCAP 0.002 #define DAMAGE_INCREASE_MULTIPLIER 0.25 @@ -54,15 +54,17 @@ #define SUPERMATTER_DANGER_PERCENT 50 #define SUPERMATTER_WARNING_PERCENT 100 -GLOBAL_DATUM(main_supermatter_engine, /obj/machinery/power/supermatter_shard) +#define SUPERMATTER_COUNTDOWN_TIME 30 SECONDS -/obj/machinery/power/supermatter_shard - name = "supermatter shard" - desc = "A strangely translucent and iridescent crystal that looks like it used to be part of a larger structure." +GLOBAL_DATUM(main_supermatter_engine, /obj/machinery/power/supermatter_crystal) + +/obj/machinery/power/supermatter_crystal + name = "supermatter crystal" + desc = "A strangely translucent and iridescent crystal." icon = 'icons/obj/supermatter.dmi' - icon_state = "darkmatter_shard" + icon_state = "darkmatter" density = TRUE - anchored = FALSE + anchored = TRUE var/uid = 1 var/static/gl_uid = 1 light_range = 4 @@ -70,9 +72,11 @@ GLOBAL_DATUM(main_supermatter_engine, /obj/machinery/power/supermatter_shard) critical_machine = TRUE - var/gasefficency = 0.125 + var/gasefficency = 0.15 - var/base_icon_state = "darkmatter_shard" + var/base_icon_state = "darkmatter" + + var/final_countdown = FALSE var/damage = 0 var/damage_archived = 0 @@ -86,7 +90,7 @@ GLOBAL_DATUM(main_supermatter_engine, /obj/machinery/power/supermatter_shard) var/emergency_issued = FALSE - var/explosion_power = 12 + var/explosion_power = 35 var/temp_factor = 30 var/lastwarning = 0 // Time in 1/10th of seconds since the last sent warning @@ -137,9 +141,9 @@ GLOBAL_DATUM(main_supermatter_engine, /obj/machinery/power/supermatter_shard) var/datum/looping_sound/supermatter/soundloop - var/moveable = TRUE + var/moveable = FALSE -/obj/machinery/power/supermatter_shard/Initialize() +/obj/machinery/power/supermatter_crystal/Initialize() . = ..() uid = gl_uid++ SSair.atmos_machinery += src @@ -156,7 +160,7 @@ GLOBAL_DATUM(main_supermatter_engine, /obj/machinery/power/supermatter_shard) soundloop = new(list(src), TRUE) -/obj/machinery/power/supermatter_shard/Destroy() +/obj/machinery/power/supermatter_crystal/Destroy() investigate_log("has been destroyed.", INVESTIGATE_SUPERMATTER) SSair.atmos_machinery -= src QDEL_NULL(radio) @@ -167,7 +171,7 @@ GLOBAL_DATUM(main_supermatter_engine, /obj/machinery/power/supermatter_shard) QDEL_NULL(soundloop) return ..() -/obj/machinery/power/supermatter_shard/examine(mob/user) +/obj/machinery/power/supermatter_crystal/examine(mob/user) ..() if(!ishuman(user)) return @@ -180,12 +184,12 @@ GLOBAL_DATUM(main_supermatter_engine, /obj/machinery/power/supermatter_shard) to_chat(H, "You get headaches just from looking at it.") return -/obj/machinery/power/supermatter_shard/get_spans() +/obj/machinery/power/supermatter_crystal/get_spans() return list(SPAN_ROBOT) #define CRITICAL_TEMPERATURE 10000 -/obj/machinery/power/supermatter_shard/proc/get_status() +/obj/machinery/power/supermatter_crystal/proc/get_status() var/turf/T = get_turf(src) if(!T) return SUPERMATTER_ERROR @@ -212,7 +216,7 @@ GLOBAL_DATUM(main_supermatter_engine, /obj/machinery/power/supermatter_shard) return SUPERMATTER_NORMAL return SUPERMATTER_INACTIVE -/obj/machinery/power/supermatter_shard/proc/alarm() +/obj/machinery/power/supermatter_crystal/proc/alarm() switch(get_status()) if(SUPERMATTER_DELAMINATING) playsound(src, 'sound/misc/bloblarm.ogg', 100) @@ -223,13 +227,51 @@ GLOBAL_DATUM(main_supermatter_engine, /obj/machinery/power/supermatter_shard) if(SUPERMATTER_WARNING) playsound(src, 'sound/machines/terminal_alert.ogg', 75) -/obj/machinery/power/supermatter_shard/proc/get_integrity() +/obj/machinery/power/supermatter_crystal/proc/get_integrity() var/integrity = damage / explosion_point integrity = round(100 - integrity * 100, 0.01) integrity = integrity < 0 ? 0 : integrity return integrity -/obj/machinery/power/supermatter_shard/proc/explode() +/obj/machinery/power/supermatter_crystal/proc/countdown() + if(final_countdown) // We're already doing it go away + return + final_countdown = TRUE + + var/image/causality_field = image(icon, null, "causality_field") + add_overlay(causality_field, TRUE) + + var/speaking = "[emergency_alert] The supermatter has reached critical integrity failure. Emergency causality destabilization field has been activated." + radio.talk_into(src, speaking, common_channel, get_spans(), get_default_language()) + for(var/i in SUPERMATTER_COUNTDOWN_TIME to 0 step -10) + if(damage < explosion_point) // Cutting it a bit close there engineers + radio.talk_into(src, "[safe_alert] Failsafe has been disengaged.", common_channel, get_spans(), get_default_language()) + cut_overlay(causality_field, TRUE) + final_countdown = FALSE + return + else if((i % 50) != 0 && i > 50) // A message once every 5 seconds until the final 5 seconds which count down individualy + sleep(10) + continue + else if(i > 50) + speaking = "[i/10] seconds remain before causality stabilization." + else + speaking = "[i/10]..." + radio.talk_into(src, speaking, common_channel, get_spans(), get_default_language()) + sleep(10) + + explode() + +/obj/machinery/power/supermatter_crystal/proc/explode() + for(var/mob in GLOB.alive_mob_list) + var/mob/living/L = mob + if(istype(L) && L.z == z) + if(ishuman(mob)) + //Hilariously enough, running into a closet should make you get hit the hardest. + var/mob/living/carbon/human/H = mob + H.hallucination += max(50, min(300, DETONATION_HALLUCINATION * sqrt(1 / (get_dist(mob, src) + 1)) ) ) + var/rads = DETONATION_RADS * sqrt( 1 / (get_dist(L, src) + 1) ) + L.rad_act(rads) + var/turf/T = get_turf(src) for(var/mob/M in GLOB.player_list) if(M.z == z) @@ -251,7 +293,7 @@ GLOBAL_DATUM(main_supermatter_engine, /obj/machinery/power/supermatter_shard) E.energy = power qdel(src) -/obj/machinery/power/supermatter_shard/process_atmos() +/obj/machinery/power/supermatter_crystal/process_atmos() var/turf/T = loc if(isnull(T)) // We have a null turf...something is wrong, stop processing this entity. @@ -282,7 +324,7 @@ GLOBAL_DATUM(main_supermatter_engine, /obj/machinery/power/supermatter_shard) else if(takes_damage) //causing damage - damage = max(damage + (max(removed.temperature - ((T0C + HEAT_PENALTY_THRESHOLD)*dynamic_heat_resistance), 0) * mole_heat_penalty / 150 ) * DAMAGE_INCREASE_MULTIPLIER, 0) + damage = max(damage + (max(CLAMP(removed.total_moles() / 200, 0.5, 1) * removed.temperature - ((T0C + HEAT_PENALTY_THRESHOLD)*dynamic_heat_resistance), 0) * mole_heat_penalty / 150 ) * DAMAGE_INCREASE_MULTIPLIER, 0) damage = max(damage + (max(power - POWER_PENALTY_THRESHOLD, 0)/500) * DAMAGE_INCREASE_MULTIPLIER, 0) damage = max(damage + (max(combined_gas - MOLE_PENALTY_THRESHOLD, 0)/80) * DAMAGE_INCREASE_MULTIPLIER, 0) @@ -427,21 +469,11 @@ GLOBAL_DATUM(main_supermatter_engine, /obj/machinery/power/supermatter_shard) radio.talk_into(src, "Warning: Critical coolant mass reached.", engineering_channel, get_spans(), get_default_language()) if(damage > explosion_point) - for(var/mob in GLOB.alive_mob_list) - var/mob/living/L = mob - if(istype(L) && L.z == z) - if(ishuman(mob)) - //Hilariously enough, running into a closet should make you get hit the hardest. - var/mob/living/carbon/human/H = mob - H.hallucination += max(50, min(300, DETONATION_HALLUCINATION * sqrt(1 / (get_dist(mob, src) + 1)) ) ) - var/rads = DETONATION_RADS * sqrt( 1 / (get_dist(L, src) + 1) ) - L.rad_act(rads) - - explode() + countdown() return 1 -/obj/machinery/power/supermatter_shard/bullet_act(obj/item/projectile/Proj) +/obj/machinery/power/supermatter_crystal/bullet_act(obj/item/projectile/Proj) var/turf/L = loc if(!istype(L)) return FALSE @@ -457,7 +489,7 @@ GLOBAL_DATUM(main_supermatter_engine, /obj/machinery/power/supermatter_shard) damage += Proj.damage * config_bullet_energy return FALSE -/obj/machinery/power/supermatter_shard/singularity_act() +/obj/machinery/power/supermatter_crystal/singularity_act() var/gain = 100 investigate_log("Supermatter shard consumed by singularity.", INVESTIGATE_SINGULO) message_admins("Singularity has consumed a supermatter shard and can now become stage six.") @@ -469,7 +501,7 @@ GLOBAL_DATUM(main_supermatter_engine, /obj/machinery/power/supermatter_shard) qdel(src) return gain -/obj/machinery/power/supermatter_shard/blob_act(obj/structure/blob/B) +/obj/machinery/power/supermatter_crystal/blob_act(obj/structure/blob/B) if(B && !isspaceturf(loc)) //does nothing in space playsound(get_turf(src), 'sound/effects/supermatter.ogg', 50, 1) damage += B.obj_integrity * 0.5 //take damage equal to 50% of remaining blob health before it tried to eat us @@ -482,20 +514,20 @@ GLOBAL_DATUM(main_supermatter_engine, /obj/machinery/power/supermatter_shard) "You hear a loud crack as you are washed with a wave of heat.") Consume(B) -/obj/machinery/power/supermatter_shard/attack_tk(mob/user) +/obj/machinery/power/supermatter_crystal/attack_tk(mob/user) if(iscarbon(user)) var/mob/living/carbon/C = user to_chat(C, "That was a really dumb idea.") var/obj/item/bodypart/head/rip_u = C.get_bodypart(BODY_ZONE_HEAD) rip_u.dismember(BURN) //nice try jedi -/obj/machinery/power/supermatter_shard/attack_paw(mob/user) +/obj/machinery/power/supermatter_crystal/attack_paw(mob/user) dust_mob(user, cause = "monkey attack") -/obj/machinery/power/supermatter_shard/attack_alien(mob/user) +/obj/machinery/power/supermatter_crystal/attack_alien(mob/user) dust_mob(user, cause = "alien attack") -/obj/machinery/power/supermatter_shard/attack_animal(mob/living/simple_animal/S) +/obj/machinery/power/supermatter_crystal/attack_animal(mob/living/simple_animal/S) var/murder if(!S.melee_damage_upper && !S.melee_damage_lower) murder = S.friendly @@ -506,20 +538,20 @@ GLOBAL_DATUM(main_supermatter_engine, /obj/machinery/power/supermatter_shard) "You unwisely touch [src], and your vision glows brightly as your body crumbles to dust. Oops.", \ "simple animal attack") -/obj/machinery/power/supermatter_shard/attack_robot(mob/user) +/obj/machinery/power/supermatter_crystal/attack_robot(mob/user) if(Adjacent(user)) dust_mob(user, cause = "cyborg attack") -/obj/machinery/power/supermatter_shard/attack_ai(mob/user) +/obj/machinery/power/supermatter_crystal/attack_ai(mob/user) return -/obj/machinery/power/supermatter_shard/attack_hand(mob/living/user) +/obj/machinery/power/supermatter_crystal/attack_hand(mob/living/user) . = ..() if(.) return dust_mob(user, cause = "hand") -/obj/machinery/power/supermatter_shard/proc/dust_mob(mob/living/nom, vis_msg, mob_msg, cause) +/obj/machinery/power/supermatter_crystal/proc/dust_mob(mob/living/nom, vis_msg, mob_msg, cause) if(nom.incorporeal_move || nom.status_flags & GODMODE) return if(!vis_msg) @@ -533,7 +565,7 @@ GLOBAL_DATUM(main_supermatter_engine, /obj/machinery/power/supermatter_shard) playsound(get_turf(src), 'sound/effects/supermatter.ogg', 50, 1) Consume(nom) -/obj/machinery/power/supermatter_shard/attackby(obj/item/W, mob/living/user, params) +/obj/machinery/power/supermatter_crystal/attackby(obj/item/W, mob/living/user, params) if(!istype(W) || (W.flags_1 & ABSTRACT_1) || !istype(user)) return if (istype(W, /obj/item/melee/roastingstick)) @@ -554,12 +586,12 @@ GLOBAL_DATUM(main_supermatter_engine, /obj/machinery/power/supermatter_shard) radiation_pulse(src, 150, 4) -/obj/machinery/power/supermatter_shard/wrench_act(mob/user, obj/item/tool) +/obj/machinery/power/supermatter_crystal/wrench_act(mob/user, obj/item/tool) if (moveable) default_unfasten_wrench(user, tool, time = 20) return TRUE -/obj/machinery/power/supermatter_shard/CollidedWith(atom/movable/AM) +/obj/machinery/power/supermatter_crystal/CollidedWith(atom/movable/AM) if(isliving(AM)) AM.visible_message("\The [AM] slams into \the [src] inducing a resonance... [AM.p_their()] body starts to glow and catch flame before flashing into ash.",\ "You slam into \the [src] as your ears are filled with unearthly ringing. Your last thought is \"Oh, fuck.\"",\ @@ -574,7 +606,7 @@ GLOBAL_DATUM(main_supermatter_engine, /obj/machinery/power/supermatter_shard) Consume(AM) -/obj/machinery/power/supermatter_shard/proc/Consume(atom/movable/AM) +/obj/machinery/power/supermatter_crystal/proc/Consume(atom/movable/AM) if(isliving(AM)) var/mob/living/user = AM if(user.status_flags & GODMODE) @@ -602,30 +634,30 @@ GLOBAL_DATUM(main_supermatter_engine, /obj/machinery/power/supermatter_shard) else L.show_message("You hear an unearthly ringing and notice your skin is covered in fresh radiation burns.", 2) -/obj/machinery/power/supermatter_shard/engine +/obj/machinery/power/supermatter_crystal/engine + is_main_engine = TRUE + +/obj/machinery/power/supermatter_crystal/shard + name = "supermatter shard" + desc = "A strangely translucent and iridescent crystal that looks like it used to be part of a larger structure." + base_icon_state = "darkmatter_shard" + icon_state = "darkmatter_shard" + anchored = FALSE + gasefficency = 0.125 + explosion_power = 12 + moveable = TRUE + +/obj/machinery/power/supermatter_crystal/shard/engine is_main_engine = TRUE // When you wanna make a supermatter shard for the dramatic effect, but // don't want it exploding suddenly -/obj/machinery/power/supermatter_shard/hugbox +/obj/machinery/power/supermatter_crystal/shard/hugbox takes_damage = FALSE produces_gas = FALSE moveable = FALSE -/obj/machinery/power/supermatter_shard/crystal - name = "supermatter crystal" - desc = "A strangely translucent and iridescent crystal." - base_icon_state = "darkmatter" - icon_state = "darkmatter" - anchored = TRUE - gasefficency = 0.15 - explosion_power = 35 - moveable = FALSE - -/obj/machinery/power/supermatter_shard/crystal/engine - is_main_engine = TRUE - -/obj/machinery/power/supermatter_shard/proc/supermatter_pull(turf/center, pull_range = 10) +/obj/machinery/power/supermatter_crystal/proc/supermatter_pull(turf/center, pull_range = 10) playsound(src.loc, 'sound/weapons/marauder.ogg', 100, 1, extrarange = 7) for(var/atom/P in orange(pull_range,center)) if(ismovableatom(P)) @@ -639,7 +671,7 @@ GLOBAL_DATUM(main_supermatter_engine, /obj/machinery/power/supermatter_shard) step_towards(pulled_object,center) step_towards(pulled_object,center) -/obj/machinery/power/supermatter_shard/proc/supermatter_anomaly_gen(turf/anomalycenter, type = FLUX_ANOMALY, anomalyrange = 5) +/obj/machinery/power/supermatter_crystal/proc/supermatter_anomaly_gen(turf/anomalycenter, type = FLUX_ANOMALY, anomalyrange = 5) var/turf/L = pick(orange(anomalyrange, anomalycenter)) if(L) switch(type) @@ -651,7 +683,7 @@ GLOBAL_DATUM(main_supermatter_engine, /obj/machinery/power/supermatter_shard) if(PYRO_ANOMALY) new /obj/effect/anomaly/pyro(L, 200) -/obj/machinery/power/supermatter_shard/proc/supermatter_zap(atom/zapstart, range = 3, power) +/obj/machinery/power/supermatter_crystal/proc/supermatter_zap(atom/zapstart, range = 3, power) . = zapstart.dir if(power < 1000) return diff --git a/code/modules/power/switch.dm b/code/modules/power/switch.dm deleted file mode 100644 index 1dca58eb6f..0000000000 --- a/code/modules/power/switch.dm +++ /dev/null @@ -1,84 +0,0 @@ -//This is a power switch. When turned on it looks at the cables around the tile that it's on and notes which cables are trying to connect to it. -//After it knows this it creates the number of cables from the center to each of the cables attempting to conenct. These cables cannot be removed -//with wirecutters. When the switch is turned off it removes all the cables on the tile it's on. -//The switch uses a 5s delay to prevent powernet change spamming. -/* -/obj/structure/powerswitch - name = "power switch" - desc = "A switch that controls power." - icon = 'icons/obj/power.dmi' - icon_state = "switch-dbl-up" - var/icon_state_on = "switch-dbl-down" - var/icon_state_off = "switch-dbl-up" - density = FALSE - anchored = TRUE - var/on = FALSE //up is off, down is on - var/busy = FALSE //set to 1 when you start pulling - -/obj/structure/powerswitch/simple - icon_state = "switch-up" - icon_state_on = "switch-down" - icon_state_off = "switch-up" - - -/obj/structure/powerswitch/examine(mob/user) - ..() - if(on) - to_chat(user, "The switch is in the on position") - else - to_chat(user, "The switch is in the off position") - -/obj/structure/powerswitch/attack_ai(mob/user) - to_chat(user, "\red You're an AI. This is a manual switch. It's not going to work.") - return - -/obj/structure/powerswitch/attack_hand(mob/user) - - if(busy) - to_chat(user, "\red This switch is already being toggled.") - return - - ..() - - busy = TRUE - for(var/mob/O in viewers(user)) - O.show_message(text("\red [user] started pulling the [src]."), 1) - - if(do_after(user, 50)) - set_state(!on) - for(var/mob/O in viewers(user)) - O.show_message(text("\red [user] flipped the [src] into the [on ? "on": "off"] position."), 1) - busy = FALSE - -/obj/structure/powerswitch/proc/set_state(var/state) - on = state - if(on) - icon_state = icon_state_on - var/list/connection_dirs = list() - for(var/direction in list(1,2,4,8,5,6,9,10)) - for(var/obj/structure/cable/C in get_step(src,direction)) - if(C.d1 == turn(direction, 180) || C.d2 == turn(direction, 180)) - connection_dirs += direction - break - - for(var/direction in connection_dirs) - var/obj/structure/cable/C = new/obj/structure/cable(src.loc) - C.d1 = 0 - C.d2 = direction - C.icon_state = "[C.d1]-[C.d2]" - C.power_switch = src - - var/datum/powernet/PN = new() - PN.number = powernets.len + 1 - powernets += PN - C.netnum = PN.number - PN.cables += C - - C.mergeConnectedNetworks(C.d2) - C.mergeConnectedNetworksOnTurf() - - else - icon_state = icon_state_off - for(var/obj/structure/cable/C in src.loc) - qdel(C) -*/ \ No newline at end of file diff --git a/code/modules/procedural_mapping/mapGenerator.dm b/code/modules/procedural_mapping/mapGenerator.dm index 95eded309c..4c9e1dddea 100644 --- a/code/modules/procedural_mapping/mapGenerator.dm +++ b/code/modules/procedural_mapping/mapGenerator.dm @@ -2,11 +2,11 @@ //All based on clusterMin and clusterMax as guides //Individual defines -#define CLUSTER_CHECK_NONE 0 //No checks are done, cluster as much as possible -#define CLUSTER_CHECK_DIFFERENT_TURFS 2 //Don't let turfs of DIFFERENT types cluster -#define CLUSTER_CHECK_DIFFERENT_ATOMS 4 //Don't let atoms of DIFFERENT types cluster -#define CLUSTER_CHECK_SAME_TURFS 8 //Don't let turfs of the SAME type cluster -#define CLUSTER_CHECK_SAME_ATOMS 16 //Don't let atoms of the SAME type cluster +#define CLUSTER_CHECK_NONE 0 //No checks are done, cluster as much as possible +#define CLUSTER_CHECK_DIFFERENT_TURFS (1<<1) //Don't let turfs of DIFFERENT types cluster +#define CLUSTER_CHECK_DIFFERENT_ATOMS (1<<2) //Don't let atoms of DIFFERENT types cluster +#define CLUSTER_CHECK_SAME_TURFS (1<<3) //Don't let turfs of the SAME type cluster +#define CLUSTER_CHECK_SAME_ATOMS (1<<4) //Don't let atoms of the SAME type cluster //Combined defines #define CLUSTER_CHECK_SAMES 24 //Don't let any of the same type cluster @@ -197,4 +197,3 @@ to_chat(src, "Generating Region") N.generate() to_chat(src, "Generated Region") - diff --git a/code/modules/projectiles/guns/energy/kinetic_accelerator.dm b/code/modules/projectiles/guns/energy/kinetic_accelerator.dm index 63d3736eba..3896293f78 100644 --- a/code/modules/projectiles/guns/energy/kinetic_accelerator.dm +++ b/code/modules/projectiles/guns/energy/kinetic_accelerator.dm @@ -244,11 +244,10 @@ ..() /obj/item/borg/upgrade/modkit/action(mob/living/silicon/robot/R) - if(..()) - return - - for(var/obj/item/gun/energy/kinetic_accelerator/cyborg/H in R.module.modules) - return install(H, usr) + . = ..() + if (.) + for(var/obj/item/gun/energy/kinetic_accelerator/cyborg/H in R.module.modules) + return install(H, usr) /obj/item/borg/upgrade/modkit/proc/install(obj/item/gun/energy/kinetic_accelerator/KA, mob/user) . = TRUE @@ -281,10 +280,18 @@ to_chat(user, "You don't have room([KA.get_remaining_mod_capacity()]% remaining, [cost]% needed) to install this modkit. Use a crowbar to remove existing modkits.") . = FALSE +/obj/item/borg/upgrade/modkit/deactivate(mob/living/silicon/robot/R, user = usr) + . = ..() + if (.) + for(var/obj/item/gun/energy/kinetic_accelerator/cyborg/KA in R.module.modules) + uninstall(KA) + /obj/item/borg/upgrade/modkit/proc/uninstall(obj/item/gun/energy/kinetic_accelerator/KA) forceMove(get_turf(KA)) KA.modkits -= src + + /obj/item/borg/upgrade/modkit/proc/modify_projectile(obj/item/projectile/kinetic/K) //use this one for effects you want to trigger before any damage is done at all and before damage is decreased by pressure diff --git a/code/modules/reagents/chemistry/holder.dm b/code/modules/reagents/chemistry/holder.dm index 5fcb554c7d..afa73fcd4a 100644 --- a/code/modules/reagents/chemistry/holder.dm +++ b/code/modules/reagents/chemistry/holder.dm @@ -72,7 +72,7 @@ cached_reagents = null if(my_atom && my_atom.reagents == src) my_atom.reagents = null - + my_atom = null // Used in attack logs for reagents in pills and such /datum/reagents/proc/log_list() diff --git a/code/modules/reagents/chemistry/machinery/chem_master.dm b/code/modules/reagents/chemistry/machinery/chem_master.dm index f915bc497f..f3abe40ca5 100644 --- a/code/modules/reagents/chemistry/machinery/chem_master.dm +++ b/code/modules/reagents/chemistry/machinery/chem_master.dm @@ -144,9 +144,9 @@ data["isPillBottleLoaded"] = bottle ? 1 : 0 if(bottle) + GET_COMPONENT_FROM(STRB, /datum/component/storage, bottle) data["pillBotContent"] = bottle.contents.len - data["pillBotMaxContent"] = bottle.storage_slots - + data["pillBotMaxContent"] = STRB.max_items var/beakerContents[0] if(beaker) @@ -160,7 +160,6 @@ bufferContents.Add(list(list("name" = N.name, "id" = N.id, "volume" = N.volume))) // ^ data["bufferContents"] = bufferContents - return data /obj/machinery/chem_master/ui_act(action, params) @@ -222,12 +221,18 @@ if(!name || !reagents.total_volume || !src || QDELETED(src) || !usr.canUseTopic(src, !issilicon(usr))) return var/obj/item/reagent_containers/pill/P + var/target_loc = drop_location() + var/drop_threshold = INFINITY + if(bottle) + GET_COMPONENT_FROM(STRB, /datum/component/storage, bottle) + if(STRB) + drop_threshold = STRB.max_items - bottle.contents.len for(var/i = 0; i < amount; i++) - if(bottle && bottle.contents.len < bottle.storage_slots) - P = new/obj/item/reagent_containers/pill(bottle) + if(i < drop_threshold) + P = new(target_loc) else - P = new/obj/item/reagent_containers/pill(drop_location()) + P = new(drop_location()) P.name = trim("[name] pill") adjust_item_drop_location(P) reagents.trans_to(P,vol_each) @@ -303,7 +308,7 @@ reagents.trans_to(P, vol_part) . = TRUE //CITADEL ADD Hypospray Vials - if("createvial") + if("createVial") var/many = params["many"] if(reagents.total_volume == 0) return @@ -314,21 +319,21 @@ amount_full = round(reagents.total_volume / 30) vol_part = reagents.total_volume % 30 var/name = stripped_input(usr, "Name:","Name your hypovial!", (reagents.total_volume ? reagents.get_master_reagent_name() : " "), MAX_NAME_LEN) - if(!name || !reagents.total_volume || !src || QDELETED(src) || !usr.canUseTopic(src, BE_CLOSE)) + if(!name || !reagents.total_volume || !src || QDELETED(src) || !usr.canUseTopic(src, !issilicon(usr))) return - var/obj/item/reagent_containers/glass/bottle/vial/small/V + var/obj/item/reagent_containers/glass/bottle/vial/small/P for(var/i = 0; i < amount_full; i++) - V = new/obj/item/reagent_containers/glass/bottle/vial/small(drop_location()) - V.name = trim("[name] hypovial") - adjust_item_drop_location(V) - reagents.trans_to(V, 30) + P = new/obj/item/reagent_containers/glass/bottle/vial/small(drop_location()) + P.name = trim("[name] hypovial") + adjust_item_drop_location(P) + reagents.trans_to(P, 30) if(vol_part) - V = new/obj/item/reagent_containers/glass/bottle/vial/small(drop_location()) - V.name = trim("[name] hypovial") - adjust_item_drop_location(V) - reagents.trans_to(V, vol_part) + P = new/obj/item/reagent_containers/glass/bottle/vial/small(drop_location()) + P.name = trim("[name] hypovial") + adjust_item_drop_location(P) + reagents.trans_to(P, vol_part) . = TRUE //END CITADEL ADDITIONS if("analyze") diff --git a/code/modules/reagents/chemistry/machinery/reagentgrinder.dm b/code/modules/reagents/chemistry/machinery/reagentgrinder.dm index 3cdaaa0f5f..a4d9829aa6 100644 --- a/code/modules/reagents/chemistry/machinery/reagentgrinder.dm +++ b/code/modules/reagents/chemistry/machinery/reagentgrinder.dm @@ -101,16 +101,14 @@ //Fill machine with a bag! if(istype(I, /obj/item/storage/bag)) - var/obj/item/storage/bag/B = I - for (var/obj/item/reagent_containers/food/snacks/grown/G in B.contents) - B.remove_from_storage(G, src) - holdingitems[G] = TRUE - if(length(holdingitems) >= limit) //Sanity checking so the blender doesn't overfill + var/list/inserted = list() + if(I.SendSignal(COMSIG_TRY_STORAGE_TAKE_TYPE, /obj/item/reagent_containers/food/snacks/grown, src, limit - length(holdingitems), null, null, user, inserted)) + for(var/i in inserted) + holdingitems[i] = TRUE + if(!I.contents.len) + to_chat(user, "You empty [I] into [src].") + else to_chat(user, "You fill [src] to the brim.") - break - - if(!I.contents.len) - to_chat(user, "You empty [I] into [src].") updateUsrDialog() return TRUE diff --git a/code/modules/reagents/chemistry/reagents.dm b/code/modules/reagents/chemistry/reagents.dm index 3fe5d47479..7369fd6042 100644 --- a/code/modules/reagents/chemistry/reagents.dm +++ b/code/modules/reagents/chemistry/reagents.dm @@ -1,7 +1,3 @@ -#define SOLID 1 -#define LIQUID 2 -#define GAS 3 - #define REM REAGENTS_EFFECT_MULTIPLIER //Various reagents diff --git a/code/modules/reagents/chemistry/reagents/food_reagents.dm b/code/modules/reagents/chemistry/reagents/food_reagents.dm index 4c475fd4c4..b9b0fd4136 100644 --- a/code/modules/reagents/chemistry/reagents/food_reagents.dm +++ b/code/modules/reagents/chemistry/reagents/food_reagents.dm @@ -615,6 +615,7 @@ to_chat(M, "Your eyes sting!") M.blind_eyes(2) + /datum/reagent/consumable/nutriment/stabilized name = "Stabilized Nutriment" id = "stabilizednutriment" @@ -627,7 +628,7 @@ if(M.nutrition > NUTRITION_LEVEL_FULL - 25) M.nutrition -= 3*nutriment_factor ..() - + ////Lavaland Flora Reagents//// diff --git a/code/modules/reagents/chemistry/reagents/other_reagents.dm b/code/modules/reagents/chemistry/reagents/other_reagents.dm index 9eb81e918f..3881311490 100644 --- a/code/modules/reagents/chemistry/reagents/other_reagents.dm +++ b/code/modules/reagents/chemistry/reagents/other_reagents.dm @@ -587,7 +587,7 @@ ..() if(!istype(H)) return - if(!H.dna || !H.dna.species || !(H.dna.species.species_traits & SPECIES_ORGANIC)) + if(!H.dna || !H.dna.species || !(MOB_ORGANIC in H.mob_biotypes)) return if(isjellyperson(H)) @@ -1472,7 +1472,7 @@ /datum/reagent/carpet/reaction_turf(turf/T, reac_volume) if(isplatingturf(T) || istype(T, /turf/open/floor/plasteel)) var/turf/open/floor/F = T - F.ChangeTurf(/turf/open/floor/carpet) + F.PlaceOnTop(/turf/open/floor/carpet) ..() return @@ -1817,12 +1817,6 @@ L.remove_trait(TRAIT_PACIFISM, id) ..() -/datum/reagent/pax/borg - name = "synth-pax" - id = "synthpax" - description = "A colorless liquid that suppresses violence on the subjects. Cheaper to synthetize, but wears out faster than normal Pax." - metabolization_rate = 1.5 * REAGENTS_METABOLISM - /datum/reagent/bz_metabolites name = "BZ metabolites" id = "bz_metabolites" @@ -1845,3 +1839,40 @@ if(changeling) changeling.chem_charges = max(changeling.chem_charges-2, 0) return ..() + +/datum/reagent/pax/peaceborg + name = "synth-pax" + id = "synthpax" + description = "A colorless liquid that suppresses violence on the subjects. Cheaper to synthetize, but wears out faster than normal Pax." + metabolization_rate = 1.5 * REAGENTS_METABOLISM + +/datum/reagent/peaceborg/confuse + name = "Dizzying Solution" + id = "dizzysolution" + description = "Makes the target off balance and dizzy" + metabolization_rate = 1.5 * REAGENTS_METABOLISM + taste_description = "dizziness" + +/datum/reagent/peaceborg/confuse/on_mob_life(mob/living/M) + if(M.confused < 6) + M.confused = CLAMP(M.confused + 3, 0, 5) + if(M.dizziness < 6) + M.dizziness = CLAMP(M.dizziness + 3, 0, 5) + if(prob(20)) + to_chat(M, "You feel confused and disorientated.") + ..() + +/datum/reagent/peaceborg/tire + name = "Tiring Solution" + id = "tiresolution" + description = "An extremely weak stamina-toxin that tires out the target. Completely harmless." + metabolization_rate = 1.5 * REAGENTS_METABOLISM + taste_description = "tiredness" + +/datum/reagent/peaceborg/tire/on_mob_life(mob/living/M) + var/healthcomp = (100 - M.health) //DOES NOT ACCOUNT FOR ADMINBUS THINGS THAT MAKE YOU HAVE MORE THAN 200/210 HEALTH, OR SOMETHING OTHER THAN A HUMAN PROCESSING THIS. + if(M.getStaminaLoss() < (45 - healthcomp)) //At 50 health you would have 200 - 150 health meaning 50 compensation. 60 - 50 = 10, so would only do 10-19 stamina.) + M.adjustStaminaLoss(10) + if(prob(30)) + to_chat(M, "You should sit down and take a rest...") + ..() diff --git a/code/modules/reagents/chemistry/reagents/toxin_reagents.dm b/code/modules/reagents/chemistry/reagents/toxin_reagents.dm index 2746f311f8..0972f32ad7 100644 --- a/code/modules/reagents/chemistry/reagents/toxin_reagents.dm +++ b/code/modules/reagents/chemistry/reagents/toxin_reagents.dm @@ -231,12 +231,10 @@ toxpwr = 1 /datum/reagent/toxin/pestkiller/reaction_mob(mob/living/M, method=TOUCH, reac_volume) - if(method == VAPOR) - if(iscarbon(M)) - var/mob/living/carbon/C = M - if(!C.wear_mask) // If not wearing a mask - var/damage = min(round(0.4*reac_volume, 0.1),10) - C.adjustToxLoss(damage) + ..() + if(MOB_BUG in M.mob_biotypes) + var/damage = min(round(0.4*reac_volume, 0.1),10) + M.adjustToxLoss(damage) /datum/reagent/toxin/spore name = "Spore Toxin" @@ -847,39 +845,6 @@ . = 1 ..() -/datum/reagent/toxin/peaceborg/confuse - name = "Dizzying Solution" - id = "dizzysolution" - description = "Makes the target off balance and dizzy" - toxpwr = 0 - metabolization_rate = 1.5 * REAGENTS_METABOLISM - taste_description = "dizziness" - -/datum/reagent/toxin/peaceborg/confuse/on_mob_life(mob/living/M) - if(M.confused < 6) - M.confused = CLAMP(M.confused + 3, 0, 5) - if(M.dizziness < 6) - M.dizziness = CLAMP(M.dizziness + 3, 0, 5) - if(prob(20)) - to_chat(M, "You feel confused and disorientated.") - ..() - -/datum/reagent/toxin/peaceborg/tire - name = "Tiring Solution" - id = "tiresolution" - description = "An extremely weak stamina-toxin that tires out the target. Completely harmless." - toxpwr = 0 - metabolization_rate = 1.5 * REAGENTS_METABOLISM - taste_description = "tiredness" - -/datum/reagent/toxin/peaceborg/tire/on_mob_life(mob/living/M) - var/healthcomp = (100 - M.health) //DOES NOT ACCOUNT FOR ADMINBUS THINGS THAT MAKE YOU HAVE MORE THAN 200/210 HEALTH, OR SOMETHING OTHER THAN A HUMAN PROCESSING THIS. - if(M.getStaminaLoss() < (45 - healthcomp)) //At 50 health you would have 200 - 150 health meaning 50 compensation. 60 - 50 = 10, so would only do 10-19 stamina.) - M.adjustStaminaLoss(10) - if(prob(30)) - to_chat(M, "You should sit down and take a rest...") - ..() - /datum/reagent/toxin/delayed name = "Toxin Microcapsules" id = "delayed_toxin" diff --git a/code/modules/reagents/reagent_containers/borghydro.dm b/code/modules/reagents/reagent_containers/borghydro.dm index b4116a2915..ef41c7951e 100644 --- a/code/modules/reagents/reagent_containers/borghydro.dm +++ b/code/modules/reagents/reagent_containers/borghydro.dm @@ -67,6 +67,21 @@ Borg Hypospray modes[reagent] = modes.len + 1 +/obj/item/reagent_containers/borghypo/proc/del_reagent(reagent) + reagent_ids -= reagent + var/datum/reagents/RG + var/datum/reagents/TRG + for(var/i in 1 to reagent_ids.len) + TRG = reagent_list[i] + if (TRG.has_reagent(reagent)) + RG = TRG + break + if (RG) + reagent_list -= RG + RG.del_reagent(reagent) + + modes[reagent] = modes.len - 1 + /obj/item/reagent_containers/borghypo/proc/regenerate_reagents() if(iscyborg(src.loc)) var/mob/living/silicon/robot/R = src.loc diff --git a/code/modules/recycling/conveyor2.dm b/code/modules/recycling/conveyor2.dm index 5f3470725d..41fbc5092d 100644 --- a/code/modules/recycling/conveyor2.dm +++ b/code/modules/recycling/conveyor2.dm @@ -5,12 +5,12 @@ GLOBAL_LIST_EMPTY(conveyors_by_id) /obj/machinery/conveyor icon = 'icons/obj/recycling.dmi' - icon_state = "conveyor0" + icon_state = "conveyor_map" name = "conveyor belt" desc = "A conveyor belt." anchored = TRUE layer = BELOW_OPEN_DOOR_LAYER - var/operating = FALSE // 1 if running forward, -1 if backwards, 0 if off + var/operating = 0 // 1 if running forward, -1 if backwards, 0 if off var/operable = 1 // true if can operate (no broken segments in this belt run) var/forwards // this is the default (forward) direction, set by the map dir var/backwards // hopefully self-explanatory @@ -18,13 +18,22 @@ GLOBAL_LIST_EMPTY(conveyors_by_id) var/list/affecting // the list of all items that will be moved this ptick var/id = "" // the control ID - must match controller ID - var/verted = 1 // set to -1 to have the conveyour belt be inverted, so you can use the other corner icons + var/verted = 1 // Inverts the direction the conveyor belt moves. speed_process = TRUE /obj/machinery/conveyor/centcom_auto id = "round_end_belt" +/obj/machinery/conveyor/inverted //Directions inverted so you can use different corner peices. + icon_state = "conveyor_map_inverted" + verted = -1 + +/obj/machinery/conveyor/inverted/Initialize(mapload) + . = ..() + if(mapload && !(dir in GLOB.diagonals)) + log_game("### MAPPING ERROR: [src] at [COORD(src)] spawned without using a diagonal dir. Please replace with a normal version.") + // Auto conveyour is always on unless unpowered /obj/machinery/conveyor/auto/Initialize(mapload, newdir) @@ -214,7 +223,8 @@ GLOBAL_LIST_EMPTY(conveyors_by_id) var/position = 0 // 0 off, -1 reverse, 1 forward var/last_pos = -1 // last direction setting var/operated = 1 // true if just operated - var/convdir = 0 // 0 is two way switch, 1 and -1 means one way + var/oneway = FALSE // if the switch only operates the conveyor belts in a single direction. + var/invert_icon = FALSE // If the level points the opposite direction when it's turned on. var/id = "" // must match conveyor IDs to control them @@ -247,9 +257,15 @@ GLOBAL_LIST_EMPTY(conveyors_by_id) /obj/machinery/conveyor_switch/update_icon() if(position<0) - icon_state = "switch-rev" + if(invert_icon) + icon_state = "switch-fwd" + else + icon_state = "switch-rev" else if(position>0) - icon_state = "switch-fwd" + if(invert_icon) + icon_state = "switch-rev" + else + icon_state = "switch-fwd" else icon_state = "switch-off" @@ -271,8 +287,8 @@ GLOBAL_LIST_EMPTY(conveyors_by_id) /obj/machinery/conveyor_switch/interact(mob/user) add_fingerprint(user) if(position == 0) - if(convdir) //is it a oneway switch - position = convdir + if(oneway) //is it a oneway switch + position = oneway else if(last_pos < 0) position = 1 @@ -289,6 +305,7 @@ GLOBAL_LIST_EMPTY(conveyors_by_id) // find any switches with same id as this one, and set their positions to match us for(var/obj/machinery/conveyor_switch/S in GLOB.conveyors_by_id[id]) + S.invert_icon = invert_icon S.position = position S.update_icon() CHECK_TICK @@ -302,8 +319,14 @@ GLOBAL_LIST_EMPTY(conveyors_by_id) qdel(src) /obj/machinery/conveyor_switch/oneway - convdir = 1 //Set to 1 or -1 depending on which way you want the convayor to go. (In other words keep at 1 and set the proper dir on the belts.) + icon_state = "conveyor_switch_oneway" desc = "A conveyor control switch. It appears to only go in one direction." + oneway = TRUE + +/obj/machinery/conveyor_switch/oneway/Initialize() + . = ..() + if((dir == NORTH) || (dir == WEST)) + invert_icon = TRUE // // CONVEYOR CONSTRUCTION STARTS HERE diff --git a/code/modules/recycling/disposal/bin.dm b/code/modules/recycling/disposal/bin.dm index 529d883916..6defa464b9 100644 --- a/code/modules/recycling/disposal/bin.dm +++ b/code/modules/recycling/disposal/bin.dm @@ -246,13 +246,16 @@ return src //How disposal handles getting a storage dump from a storage object -/obj/machinery/disposal/storage_contents_dump_act(obj/item/storage/src_object, mob/user) +/obj/machinery/disposal/storage_contents_dump_act(datum/component/storage/src_object, mob/user) + . = ..() + if(.) + return for(var/obj/item/I in src_object) - if(user.s_active != src_object) + if(user.active_storage != src_object) if(I.on_found(user)) return src_object.remove_from_storage(I, src) - return 1 + return TRUE // Disposal bin // Holds items for disposal into pipe system @@ -268,11 +271,12 @@ // attack by item places it in to disposal /obj/machinery/disposal/bin/attackby(obj/item/I, mob/user, params) - if(istype(I, /obj/item/storage/bag/trash)) + if(istype(I, /obj/item/storage/bag/trash)) //Not doing component overrides because this is a specific type. var/obj/item/storage/bag/trash/T = I + GET_COMPONENT_FROM(STR, /datum/component/storage, T) to_chat(user, "You empty the bag.") for(var/obj/item/O in T.contents) - T.remove_from_storage(O,src) + STR.remove_from_storage(O,src) T.update_icon() update_icon() else @@ -281,7 +285,7 @@ // handle machine interaction /obj/machinery/disposal/bin/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) + datum/tgui/master_ui = null, datum/ui_state/state = GLOB.notcontained_state) if(stat & BROKEN) return ui = SStgui.try_update_ui(user, src, ui_key, ui, force_open) diff --git a/code/modules/research/message_server.dm b/code/modules/research/message_server.dm deleted file mode 100644 index d42e43ec9a..0000000000 --- a/code/modules/research/message_server.dm +++ /dev/null @@ -1,140 +0,0 @@ -GLOBAL_LIST_INIT(message_servers, list()) - -/datum/data_pda_msg - var/recipient = "Unspecified" //name of the person - var/sender = "Unspecified" //name of the sender - var/message = "Blank" //transferred message - var/icon/photo //Attached photo - -/datum/data_pda_msg/New(var/param_rec = "",var/param_sender = "",var/param_message = "",var/param_photo=null) - - if(param_rec) - recipient = param_rec - if(param_sender) - sender = param_sender - if(param_message) - message = param_message - if(param_photo) - photo = param_photo - -/datum/data_pda_msg/proc/get_photo_ref() - if(photo) - return "(Photo)" - return "" - -/datum/data_pda_msg/Topic(href,href_list) - ..() - if(href_list["photo"]) - var/mob/M = usr - M << browse_rsc(photo, "pda_photo.png") - M << browse("PDA Photo" \ - + "" \ - + "" \ - + "", "window=book;size=192x192") - onclose(M, "PDA Photo") - -/datum/data_rc_msg - var/rec_dpt = "Unspecified" //name of the person - var/send_dpt = "Unspecified" //name of the sender - var/message = "Blank" //transferred message - var/stamp = "Unstamped" - var/id_auth = "Unauthenticated" - var/priority = "Normal" - -/datum/data_rc_msg/New(var/param_rec = "",var/param_sender = "",var/param_message = "",var/param_stamp = "",var/param_id_auth = "",var/param_priority) - if(param_rec) - rec_dpt = param_rec - if(param_sender) - send_dpt = param_sender - if(param_message) - message = param_message - if(param_stamp) - stamp = param_stamp - if(param_id_auth) - id_auth = param_id_auth - if(param_priority) - switch(param_priority) - if(1) - priority = "Normal" - if(2) - priority = "High" - if(3) - priority = "Extreme" - else - priority = "Undetermined" - -/obj/machinery/message_server - icon = 'icons/obj/machines/research.dmi' - icon_state = "server" - name = "Messaging Server" - desc = "A machine that attempts to gather the secret knowledge of the universe." - density = TRUE - anchored = TRUE - use_power = IDLE_POWER_USE - idle_power_usage = 10 - active_power_usage = 100 - - var/list/datum/data_pda_msg/pda_msgs = list() - var/list/datum/data_rc_msg/rc_msgs = list() - var/active = 1 - var/decryptkey = "password" - -/obj/machinery/message_server/Initialize() - GLOB.message_servers += src - decryptkey = GenerateKey() - send_pda_message("System Administrator", "system", "This is an automated message. The messaging system is functioning correctly.") - . = ..() - -/obj/machinery/message_server/Destroy() - GLOB.message_servers -= src - return ..() - -/obj/machinery/message_server/proc/GenerateKey() - //Feel free to move to Helpers. - var/newKey - newKey += pick("the", "if", "of", "as", "in", "a", "you", "from", "to", "an", "too", "little", "snow", "dead", "drunk", "rosebud", "duck", "al", "le") - newKey += pick("diamond", "beer", "mushroom", "assistant", "clown", "captain", "twinkie", "security", "nuke", "small", "big", "escape", "yellow", "gloves", "monkey", "engine", "nuclear", "ai") - newKey += pick("1", "2", "3", "4", "5", "6", "7", "8", "9", "0") - return newKey - -/obj/machinery/message_server/process() - if(active && (stat & (BROKEN|NOPOWER))) - active = 0 - return - update_icon() - return - -/obj/machinery/message_server/proc/send_pda_message(recipient = "",sender = "",message = "",photo=null) - . = new/datum/data_pda_msg(recipient,sender,message,photo) - pda_msgs += . - -/obj/machinery/message_server/proc/send_rc_message(recipient = "",sender = "",message = "",stamp = "", id_auth = "", priority = 1) - rc_msgs += new/datum/data_rc_msg(recipient,sender,message,stamp,id_auth) - -/obj/machinery/message_server/attack_hand(mob/user) - to_chat(user, "You toggle PDA message passing from [active ? "On" : "Off"] to [active ? "Off" : "On"]") - active = !active - update_icon() - - return - -/obj/machinery/message_server/update_icon() - if((stat & (BROKEN|NOPOWER))) - icon_state = "server-nopower" - else if (!active) - icon_state = "server-off" - else - icon_state = "server-on" - - return - -/obj/machinery/blackbox_recorder - icon = 'icons/obj/stationobjs.dmi' - icon_state = "blackbox" - name = "Blackbox Recorder" - density = TRUE - anchored = TRUE - use_power = IDLE_POWER_USE - idle_power_usage = 10 - active_power_usage = 100 - armor = list(melee = 25, bullet = 10, laser = 10, energy = 0, bomb = 0, bio = 0, rad = 0, fire = 50, acid = 70) diff --git a/code/modules/research/stock_parts.dm b/code/modules/research/stock_parts.dm index 459c1a9955..96e7656fbc 100644 --- a/code/modules/research/stock_parts.dm +++ b/code/modules/research/stock_parts.dm @@ -9,58 +9,18 @@ If you create T5+ please take a pass at gene_modder.dm [L40]. Max_values MUST fi lefthand_file = 'icons/mob/inhands/misc/devices_lefthand.dmi' righthand_file = 'icons/mob/inhands/misc/devices_righthand.dmi' w_class = WEIGHT_CLASS_HUGE - storage_slots = 50 - use_to_pickup = 1 - allow_quick_gather = 1 - allow_quick_empty = 1 - collection_mode = 1 - display_contents_with_number = 1 - max_w_class = WEIGHT_CLASS_NORMAL - max_combined_w_class = 100 - - can_hold = list( - /obj/item/reagent_containers/glass/beaker, - /obj/item/device/assembly/igniter, - /obj/item/stock_parts, - /obj/item/stack/ore/bluespace_crystal) - - var/works_from_distance = 0 + component_type = /datum/component/storage/concrete/rped + var/works_from_distance = FALSE var/pshoom_or_beepboopblorpzingshadashwoosh = 'sound/items/rped.ogg' var/alt_sound = null /obj/item/storage/part_replacer/afterattack(obj/machinery/T, mob/living/carbon/human/user, flag, params) - if(flag) - return - else if(works_from_distance) - if(istype(T)) - if(T.component_parts) - T.exchange_parts(user, src) - user.Beam(T,icon_state="rped_upgrade",time=5) - return - -/obj/item/storage/part_replacer/bluespace - name = "bluespace rapid part exchange device" - desc = "A version of the RPED that allows for replacement of parts and scanning from a distance, along with higher capacity for parts." - icon_state = "BS_RPED" - w_class = WEIGHT_CLASS_NORMAL - storage_slots = 400 - max_w_class = WEIGHT_CLASS_NORMAL - max_combined_w_class = 800 - works_from_distance = 1 - pshoom_or_beepboopblorpzingshadashwoosh = 'sound/items/pshoom.ogg' - alt_sound = 'sound/items/pshoom_2.ogg' - -/obj/item/storage/part_replacer/bluespace/dump_content_at(atom/dest_object, mob/user) - if(Adjacent(user)) - var/atom/dumping_location = dest_object.get_dumping_location() - if(get_dist(user, dumping_location) < 8) - if(dumping_location.storage_contents_dump_act(src, user)) - play_rped_sound() - user.Beam(dumping_location,icon_state="rped_upgrade",time=5) - return 1 - to_chat(user, "The [src.name] buzzes.") - playsound(src, 'sound/machines/buzz-sigh.ogg', 50, 0) - return 0 + if(!istype(T) || !T.component_parts) + return ..() + if(works_from_distance || user.Adjacent(T)) + T.exchange_parts(user, src) + if(works_from_distance) + user.Beam(T, icon_state = "rped_upgrade", time = 5) /obj/item/storage/part_replacer/proc/play_rped_sound() //Plays the sound for RPED exhanging or installing parts. @@ -69,6 +29,16 @@ If you create T5+ please take a pass at gene_modder.dm [L40]. Max_values MUST fi else playsound(src, pshoom_or_beepboopblorpzingshadashwoosh, 40, 1) +/obj/item/storage/part_replacer/bluespace + name = "bluespace rapid part exchange device" + desc = "A version of the RPED that allows for replacement of parts and scanning from a distance, along with higher capacity for parts." + icon_state = "BS_RPED" + w_class = WEIGHT_CLASS_NORMAL + works_from_distance = TRUE + pshoom_or_beepboopblorpzingshadashwoosh = 'sound/items/pshoom.ogg' + alt_sound = 'sound/items/pshoom_2.ogg' + component_type = /datum/component/storage/concrete/bluespace/rped + /obj/item/storage/part_replacer/cyborg name = "rapid part exchange device" desc = "Special mechanical module made to store, sort, and apply standard machine parts." @@ -78,8 +48,9 @@ If you create T5+ please take a pass at gene_modder.dm [L40]. Max_values MUST fi righthand_file = 'icons/mob/inhands/misc/devices_righthand.dmi' //Sorts stock parts inside an RPED by their rating. -/proc/cmp_rped_sort(obj/item/A, obj/item/B) - return A.get_part_rating() - B.get_part_rating() +//Only use /obj/item/stock_parts/ with this sort proc! +/proc/cmp_rped_sort(obj/item/stock_parts/A, obj/item/stock_parts/B) + return B.rating - A.rating /obj/item/stock_parts name = "stock part" @@ -95,6 +66,7 @@ If you create T5+ please take a pass at gene_modder.dm [L40]. Max_values MUST fi /obj/item/stock_parts/get_part_rating() return rating + //Rating 1 /obj/item/stock_parts/capacitor diff --git a/code/modules/research/xenobiology/crossbreeding/reproductive.dm b/code/modules/research/xenobiology/crossbreeding/reproductive.dm index 17e33a9c41..878e17c1e7 100644 --- a/code/modules/research/xenobiology/crossbreeding/reproductive.dm +++ b/code/modules/research/xenobiology/crossbreeding/reproductive.dm @@ -18,22 +18,16 @@ Reproductive extracts: to_chat(user, "[src] is still digesting!") return if(istype(O, /obj/item/storage/bag/bio)) - var/obj/item/storage/P = O - var/obj/item/reagent_containers/food/snacks/monkeycube/M - for(var/obj/item/X in P.contents) - M = X - if(M && istype(M)) - break - if(M && istype(M)) - P.remove_from_storage(M, get_turf(src)) - attackby(M,user) + var/list/inserted = list() + O.SendSignal(COMSIG_TRY_STORAGE_TAKE_TYPE, /obj/item/reagent_containers/food/snacks/monkeycube, src, 1, null, null, user, inserted) + if(inserted.len) + var/obj/item/reagent_containers/food/snacks/monkeycube/M = inserted[1] + if(istype(M)) + eat_cube(M, user) else to_chat(user, "There are no monkey cubes in the bio bag!") if(istype(O,/obj/item/reagent_containers/food/snacks/monkeycube)) - qdel(O) - cubes_eaten++ - to_chat(user, "You feed [O] to [src], and it pulses gently.") - playsound(src, 'sound/items/eatfood.ogg', 20, 1) + eat_cube(O, user) if(cubes_eaten >= 3) var/cores = rand(1,4) visible_message("[src] briefly swells to a massive size, and expels [cores] extract[cores > 1 ? "s":""]!") @@ -43,6 +37,12 @@ Reproductive extracts: new extract_type(get_turf(loc)) cubes_eaten = 0 +/obj/item/slimecross/reproductive/proc/eat_cube(obj/item/reagent_containers/food/snacks/monkeycube, mob/user) + qdel(monkeycube) + cubes_eaten++ + to_chat(user, "You feed [monkeycube] to [src], and it pulses gently.") + playsound(src, 'sound/items/eatfood.ogg', 20, 1) + /obj/item/slimecross/reproductive/grey extract_type = /obj/item/slime_extract/grey colour = "grey" diff --git a/code/modules/research/xenobiology/xenobio_camera.dm b/code/modules/research/xenobiology/xenobio_camera.dm index 19f553f2b6..3b71906dd4 100644 --- a/code/modules/research/xenobiology/xenobio_camera.dm +++ b/code/modules/research/xenobiology/xenobio_camera.dm @@ -22,14 +22,16 @@ 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 = new - var/datum/action/innate/slime_pick_up/slime_up_action = new - var/datum/action/innate/feed_slime/feed_slime_action = new - var/datum/action/innate/monkey_recycle/monkey_recycle_action = new - var/datum/action/innate/slime_scan/scan_action = new - var/datum/action/innate/feed_potion/potion_action = new + 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/list/stored_slimes = list() + var/datum/component/redirect/listener + + var/list/stored_slimes var/obj/item/slimepotion/slime/current_potion var/max_slimes = 5 var/monkeys = 0 @@ -39,6 +41,26 @@ light_color = LIGHT_COLOR_PINK +/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 + stored_slimes = list() + listener = AddComponent(/datum/component/redirect, COMSIG_ATOM_CONTENTS_DEL, CALLBACK(src, .proc/on_contents_del)) + +/obj/machinery/computer/camera_advanced/xenobio/Destroy() + stored_slimes = null + QDEL_NULL(current_potion) + for(var/i in contents) + var/mob/living/simple_animal/slime/S = i + if(istype(S)) + S.forceMove(drop_location()) + return ..() + /obj/machinery/computer/camera_advanced/xenobio/CreateEye() eyeobj = new /mob/camera/aiEye/remote/xenobio(get_turf(src)) eyeobj.origin = src @@ -64,7 +86,7 @@ feed_slime_action.Grant(user) actions += feed_slime_action - if(monkey_recycle_action && (upgradetier & XENOBIO_UPGRADE_MONKEYS)) //CIT CHANGE - makes remote monkey recycling require XENOBIO_UPGRADE_MONKEYS + 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 @@ -79,6 +101,12 @@ potion_action.Grant(user) actions += potion_action +/obj/machinery/computer/camera_advanced/xenobio/proc/on_contents_del(atom/deleted) + if(current_potion == deleted) + current_potion = null + if(deleted in stored_slimes) + stored_slimes -= deleted + /obj/machinery/computer/camera_advanced/xenobio/attackby(obj/item/O, mob/user, params) if(istype(O, /obj/item/reagent_containers/food/snacks/monkeycube) && (upgradetier & XENOBIO_UPGRADE_MONKEYS)) //CIT CHANGE - makes monkey-related actions require XENOBIO_UPGRADE_MONKEYS monkeys++ diff --git a/code/modules/shuttle/assault_pod.dm b/code/modules/shuttle/assault_pod.dm index f2b1bd5e08..5b5de35595 100644 --- a/code/modules/shuttle/assault_pod.dm +++ b/code/modules/shuttle/assault_pod.dm @@ -7,7 +7,7 @@ height = 7 /obj/docking_port/mobile/assault_pod/request() - if(z == initial(src.z)) //No launching pods that have already launched + if(!(z in SSmapping.levels_by_trait(ZTRAIT_STATION))) //No launching pods that have already launched return ..() diff --git a/code/modules/shuttle/docking.dm b/code/modules/shuttle/docking.dm index df41f1f9e6..c0052845c7 100644 --- a/code/modules/shuttle/docking.dm +++ b/code/modules/shuttle/docking.dm @@ -14,25 +14,11 @@ var/obj/docking_port/stationary/old_dock = get_docked() - // The turf that gets placed under where the shuttle moved from - var/underlying_turf_type = SHUTTLE_DEFAULT_TURF_TYPE - - // The baseturf that the gets assigned to the turf_type above - var/underlying_baseturf_type = SHUTTLE_DEFAULT_BASETURF_TYPE - // The area that gets placed under where the shuttle moved from var/underlying_area_type = SHUTTLE_DEFAULT_UNDERLYING_AREA - - // The baseturf cache is a typecache of what counts as a baseturf to be left behind - var/list/baseturf_cache if(old_dock) //Dock overwrites - underlying_turf_type = old_dock.turf_type - underlying_baseturf_type = old_dock.baseturf_type underlying_area_type = old_dock.area_type - baseturf_cache = old_dock.baseturf_cache - else - baseturf_cache = typecacheof(underlying_baseturf_type) /************************************************************************************************************** Both lists are associative with a turf:bitflag structure. (new_turfs bitflag space unused currently) @@ -70,7 +56,7 @@ remove_ripples() - . = preflight_check(old_turfs, new_turfs, areas_to_move, rotation, underlying_turf_type, baseturf_cache) + . = preflight_check(old_turfs, new_turfs, areas_to_move, rotation) if(.) return @@ -97,7 +83,7 @@ CHECK_TICK - cleanup_runway(new_dock, old_turfs, new_turfs, areas_to_move, moved_atoms, rotation, movement_direction, underlying_old_area, underlying_turf_type, underlying_baseturf_type) + cleanup_runway(new_dock, old_turfs, new_turfs, areas_to_move, moved_atoms, rotation, movement_direction, underlying_old_area) CHECK_TICK @@ -118,8 +104,6 @@ list/new_turfs, list/areas_to_move, rotation, - underlying_turf_type, - baseturf_cache, ) for(var/i in 1 to old_turfs.len) @@ -142,8 +126,8 @@ continue move_mode = moving_atom.beforeShuttleMove(newT, rotation, move_mode, src) //atoms - move_mode = oldT.fromShuttleMove(newT, underlying_turf_type, baseturf_cache, move_mode) //turfs - move_mode = newT.toShuttleMove(oldT, move_mode , src) //turfs + move_mode = oldT.fromShuttleMove(newT, move_mode) //turfs + move_mode = newT.toShuttleMove(oldT, move_mode, src) //turfs if(move_mode & MOVE_AREA) areas_to_move[old_area] = TRUE @@ -188,8 +172,6 @@ rotation, movement_direction, area/underlying_old_area, - underlying_turf_type, - underlying_baseturf_type, ) underlying_old_area.afterShuttleMove() @@ -210,7 +192,7 @@ continue var/turf/oldT = old_turfs[i] var/turf/newT = new_turfs[i] - newT.afterShuttleMove(oldT, underlying_turf_type, underlying_baseturf_type, rotation) //turfs + newT.afterShuttleMove(oldT, rotation) //turfs for(var/i in 1 to moved_atoms.len) CHECK_TICK diff --git a/code/modules/shuttle/emergency.dm b/code/modules/shuttle/emergency.dm index 33c51cf0db..1f262b285c 100644 --- a/code/modules/shuttle/emergency.dm +++ b/code/modules/shuttle/emergency.dm @@ -561,7 +561,7 @@ SSshuttle.emergency = current_emergency SSshuttle.backup_shuttle = src -#undef TIMELEFT +#undef TIME_LEFT #undef ENGINES_START_TIME #undef ENGINES_STARTED #undef IS_DOCKED diff --git a/code/modules/shuttle/manipulator.dm b/code/modules/shuttle/manipulator.dm index 299d9e1eaa..1d8732cda9 100644 --- a/code/modules/shuttle/manipulator.dm +++ b/code/modules/shuttle/manipulator.dm @@ -271,8 +271,7 @@ // The shuttle template we loaded isn't "timid" which means // it's already registered with the shuttles subsystem. // This is a bad thing. - var/m = "Template [S] is non-timid! Unloading." - WARNING(m) + stack_trace("Template [S] is non-timid! Unloading.") M.jumpToNullSpace() return else diff --git a/code/modules/shuttle/on_move.dm b/code/modules/shuttle/on_move.dm index d0ae11046d..bce22d05cf 100644 --- a/code/modules/shuttle/on_move.dm +++ b/code/modules/shuttle/on_move.dm @@ -6,15 +6,9 @@ All ShuttleMove procs go here // Called on every turf in the shuttle region, returns a bitflag for allowed movements of that turf // returns the new move_mode (based on the old) -/turf/proc/fromShuttleMove(turf/newT, turf_type, list/baseturf_cache, move_mode) - if(!(move_mode & MOVE_AREA)) +/turf/proc/fromShuttleMove(turf/newT, move_mode) + if(!(move_mode & MOVE_AREA) || !isshuttleturf(src)) return move_mode - if(istype(src, turf_type)) - if(length(baseturfs)) - if(baseturf_cache[baseturfs[1]]) - return move_mode - else if(baseturf_cache[baseturfs]) - return move_mode return move_mode | MOVE_TURF | MOVE_CONTENTS @@ -54,7 +48,12 @@ All ShuttleMove procs go here if(newT == src) // In case of in place shuttle rotation shenanigans. return //Destination turf changes - newT.CopyOnTop(src, 1, 0) // We only want a surface copy + //Baseturfs is definitely a list or this proc wouldnt be called + var/shuttle_boundary = baseturfs.Find(/turf/baseturf_skipover/shuttle) + if(!shuttle_boundary) + CRASH("A turf queued to move via shuttle somehow had no skipover in baseturfs. [src]([type]):[loc]") + var/depth = baseturfs.len - shuttle_boundary + 1 + newT.CopyOnTop(src, 1, depth) //Air stuff newT.blocks_air = TRUE newT.air_update_turf(TRUE) @@ -67,10 +66,12 @@ All ShuttleMove procs go here return TRUE // Called on the new turf after everything has been moved -/turf/proc/afterShuttleMove(turf/oldT, turf_type, baseturf_type, rotation) +/turf/proc/afterShuttleMove(turf/oldT, rotation) //Dealing with the turf we left behind oldT.TransferComponents(src) - oldT.ChangeTurf(turf_type, baseturf_type, CHANGETURF_IGNORE_AIR) // TODO: make this oldT.ScrapeAway() which requires templating all shuttles + var/shuttle_boundary = baseturfs.Find(/turf/baseturf_skipover/shuttle) + if(shuttle_boundary) + oldT.ScrapeAway(baseturfs.len - shuttle_boundary + 1) if(rotation) shuttleRotate(rotation) //see shuttle_rotate.dm diff --git a/code/modules/shuttle/shuttle.dm b/code/modules/shuttle/shuttle.dm index 99b79f6653..77dac0745b 100644 --- a/code/modules/shuttle/shuttle.dm +++ b/code/modules/shuttle/shuttle.dm @@ -7,7 +7,6 @@ /obj/docking_port invisibility = INVISIBILITY_ABSTRACT icon = 'icons/obj/device.dmi' - //icon = 'icons/dirsquare.dmi' icon_state = "pinonfar" resistance_flags = INDESTRUCTIBLE | LAVA_PROOF | FIRE_PROOF | UNACIDABLE | ACID_PROOF @@ -22,8 +21,6 @@ var/dheight = 0 //position relative to covered area, parallel to dir var/area_type - var/turf_type - var/baseturf_type var/hidden = FALSE //are we invisible to shuttle navigation computers? //these objects are indestructible @@ -146,25 +143,17 @@ var/y0 = bounds[2] var/x1 = bounds[3] var/y1 = bounds[4] - if(x0 <= x1 && !ISINRANGE(T.x, x0, x1)) + if(!ISINRANGE(T.x, min(x0, x1), max(x0, x1))) return FALSE - else if(!ISINRANGE(T.x, x1, x0)) - return FALSE - if(y0 <= y1 && !ISINRANGE(T.y, y0, y1)) - return FALSE - else if(!ISINRANGE(T.y, y1, y0)) + if(!ISINRANGE(T.y, min(y0, y1), max(y0, y1))) return FALSE return TRUE /obj/docking_port/stationary name = "dock" - turf_type = SHUTTLE_DEFAULT_TURF_TYPE - baseturf_type = SHUTTLE_DEFAULT_BASETURF_TYPE area_type = SHUTTLE_DEFAULT_UNDERLYING_AREA - var/list/baseturf_cache - var/last_dock_time var/datum/map_template/shuttle/roundstart_template @@ -177,7 +166,6 @@ id = "[SSshuttle.stationary.len]" if(name == "dock") name = "dock[SSshuttle.stationary.len]" - baseturf_cache = typecacheof(baseturf_type) if(mapload) for(var/turf/T in return_turfs()) @@ -214,7 +202,6 @@ /obj/docking_port/stationary/transit name = "In Transit" - turf_type = /turf/open/space/transit var/list/turf/assigned_turfs = list() var/area/shuttle/transit/assigned_area var/obj/docking_port/mobile/owner @@ -226,8 +213,9 @@ /obj/docking_port/stationary/transit/proc/dezone() for(var/i in 1 to assigned_turfs.len) var/turf/T = assigned_turfs[i] - if(T.type == turf_type) - T.ChangeTurf(SHUTTLE_DEFAULT_TURF_TYPE, SHUTTLE_DEFAULT_BASETURF_TYPE) + if(istype(T, /turf/open/space/transit)) + T.ChangeTurf(/turf/open/space) + T.assemble_baseturfs(initial(T.baseturfs)) T.flags_1 |= UNUSED_TRANSIT_TURF_1 /obj/docking_port/stationary/transit/Destroy(force=FALSE) @@ -437,18 +425,11 @@ // Not in a fancy way, it just ceases. var/obj/docking_port/stationary/current_dock = get_docked() - var/turf_type = SHUTTLE_DEFAULT_TURF_TYPE - var/baseturf_type = SHUTTLE_DEFAULT_BASETURF_TYPE var/underlying_area_type = SHUTTLE_DEFAULT_UNDERLYING_AREA // If the shuttle is docked to a stationary port, restore its normal // "empty" area and turf - if(current_dock) - if(current_dock.turf_type) - turf_type = current_dock.turf_type - if(current_dock.baseturf_type) - baseturf_type = current_dock.baseturf_type - if(current_dock.area_type) - underlying_area_type = current_dock.area_type + if(current_dock && current_dock.area_type) + underlying_area_type = current_dock.area_type var/list/old_turfs = return_ordered_turfs(x, y, z, dir) var/area/underlying_area = locate(underlying_area_type) in GLOB.sortedAreas @@ -462,7 +443,14 @@ var/area/old_area = oldT.loc underlying_area.contents += oldT oldT.change_area(old_area, underlying_area) - oldT.empty(turf_type, baseturf_type) + oldT.empty(null) + + // Here we locate the bottomost shuttle boundary and remove all turfs above it + var/list/baseturf_cache = oldT.baseturfs + for(var/k in 1 to length(baseturf_cache)) + if(ispath(baseturf_cache[k], /turf/baseturf_skipover/shuttle)) + oldT.ScrapeAway(baseturf_cache.len - k + 1) + break qdel(src, force=TRUE) diff --git a/code/modules/surgery/organs/autoimplanter.dm b/code/modules/surgery/organs/autoimplanter.dm deleted file mode 100644 index 2caae96184..0000000000 --- a/code/modules/surgery/organs/autoimplanter.dm +++ /dev/null @@ -1,64 +0,0 @@ -#define INFINITE -1 - -/obj/item/device/autoimplanter - name = "autoimplanter" - desc = "A device that automatically injects a cyber-implant into the user without the hassle of extensive surgery. It has a slot to insert implants and a screwdriver slot for removing accidentally added implants." - icon_state = "autoimplanter" - item_state = "walkietalkie"//left as this so as to intentionally not have inhands - w_class = WEIGHT_CLASS_SMALL - var/obj/item/organ/storedorgan - var/organ_type = /obj/item/organ/cyberimp - var/uses = INFINITE - -/obj/item/device/autoimplanter/New() - ..() - if(storedorgan) - storedorgan.loc = src - -/obj/item/device/autoimplanter/attack_self(mob/user)//when the object it used... - if(!uses) - to_chat(user, "[src] has already been used. The tools are dull and won't reactivate.") - return - else if(!storedorgan) - to_chat(user, "[src] currently has no implant stored.") - return - storedorgan.Insert(user)//insert stored organ into the user - user.visible_message("[user] presses a button on [src], and you hear a short mechanical noise.", "You feel a sharp sting as [src] plunges into your body.") - playsound(get_turf(user), 'sound/weapons/circsawhit.ogg', 50, 1) - storedorgan = null - if(uses != INFINITE) - uses-- - if(!uses) - desc = "[initial(desc)] Looks like it's been used up." - -/obj/item/device/autoimplanter/attackby(obj/item/I, mob/user, params) - if(istype(I, organ_type)) - if(storedorgan) - to_chat(user, "[src] already has an implant stored.") - return - else if(!uses) - to_chat(user, "[src] has already been used up.") - return - if(!user.transferItemToLoc(I, src)) - return - storedorgan = I - to_chat(user, "You insert the [I] into [src].") - else if(istype(I, /obj/item/screwdriver)) - if(!storedorgan) - to_chat(user, "There's no implant in [src] for you to remove.") - else - var/turf/open/floorloc = get_turf(user) - floorloc.contents += contents - to_chat(user, "You remove the [storedorgan] from [src].") - playsound(get_turf(user), I.usesound, 50, 1) - storedorgan = null - if(uses != INFINITE) - uses-- - if(!uses) - desc = "[initial(desc)] Looks like it's been used up." - -/obj/item/device/autoimplanter/cmo - name = "medical HUD autoimplanter" - desc = "A single use autoimplanter that contains a medical heads-up display augment. A screwdriver can be used to remove it, but implants can't be placed back in." - storedorgan = new/obj/item/organ/cyberimp/eyes/hud/medical() - uses = 1 diff --git a/code/modules/surgery/organs/liver.dm b/code/modules/surgery/organs/liver.dm index 3cb1a7e764..e8cbb80203 100755 --- a/code/modules/surgery/organs/liver.dm +++ b/code/modules/surgery/organs/liver.dm @@ -1,6 +1,6 @@ #define LIVER_DEFAULT_HEALTH 100 //amount of damage required for liver failure #define LIVER_DEFAULT_TOX_TOLERANCE 3 //amount of toxins the liver can filter out -#define LIVER_DEFAULT_TOX_LETHALITY 0.5 //lower values lower how harmful toxins are to the liver +#define LIVER_DEFAULT_TOX_LETHALITY 0.01 //lower values lower how harmful toxins are to the liver /obj/item/organ/liver name = "liver" @@ -25,22 +25,17 @@ //slowly heal liver damage damage = max(0, damage - 0.1) - if(filterToxins) + if(filterToxins && !owner.has_trait(TRAIT_TOXINLOVER)) //handle liver toxin filtration - var/toxamount var/static/list/toxinstypecache = typecacheof(/datum/reagent/toxin) for(var/I in C.reagents.reagent_list) var/datum/reagent/pickedreagent = I if(is_type_in_typecache(pickedreagent, toxinstypecache)) - toxamount += C.reagents.get_reagent_amount(initial(pickedreagent.id)) - if(toxamount <= toxTolerance && toxamount > 0) - for(var/I in C.reagents.reagent_list) - var/datum/reagent/pickedreagent = I - if(is_type_in_typecache(pickedreagent, toxinstypecache)) + var/thisamount = C.reagents.get_reagent_amount(initial(pickedreagent.id)) + if (thisamount <= toxTolerance && thisamount) C.reagents.remove_reagent(initial(pickedreagent.id), 1) - else if(toxamount > toxTolerance) - damage += toxamount*toxLethality - + else + damage += (thisamount*toxLethality) //metabolize reagents C.reagents.metabolize(C, can_overdose=TRUE) @@ -80,7 +75,7 @@ alcohol_tolerance = 0.001 maxHealth = 200 //double the health of a normal liver toxTolerance = 15 //can shrug off up to 15u of toxins - toxLethality = 0.3 //20% less damage than a normal liver + toxLethality = 0.008 //20% less damage than a normal liver /obj/item/organ/liver/cybernetic/emp_act(severity) switch(severity) diff --git a/code/modules/surgery/organs/lungs.dm b/code/modules/surgery/organs/lungs.dm index aaed5757d1..ce5fafcd9f 100644 --- a/code/modules/surgery/organs/lungs.dm +++ b/code/modules/surgery/organs/lungs.dm @@ -1,13 +1,3 @@ -#define HUMAN_MAX_OXYLOSS 3 -#define HUMAN_CRIT_MAX_OXYLOSS (SSmobs.wait/30) -#define HEAT_GAS_DAMAGE_LEVEL_1 2 -#define HEAT_GAS_DAMAGE_LEVEL_2 4 -#define HEAT_GAS_DAMAGE_LEVEL_3 8 - -#define COLD_GAS_DAMAGE_LEVEL_1 0.5 -#define COLD_GAS_DAMAGE_LEVEL_2 1.5 -#define COLD_GAS_DAMAGE_LEVEL_3 3 - /obj/item/organ/lungs name = "lungs" icon_state = "lungs" @@ -369,13 +359,3 @@ cold_level_1_threshold = 200 cold_level_2_threshold = 140 cold_level_3_threshold = 100 - -#undef HUMAN_MAX_OXYLOSS -#undef HUMAN_CRIT_MAX_OXYLOSS -#undef HEAT_GAS_DAMAGE_LEVEL_1 -#undef HEAT_GAS_DAMAGE_LEVEL_2 -#undef HEAT_GAS_DAMAGE_LEVEL_3 - -#undef COLD_GAS_DAMAGE_LEVEL_1 -#undef COLD_GAS_DAMAGE_LEVEL_2 -#undef COLD_GAS_DAMAGE_LEVEL_3 diff --git a/code/modules/telesci/telepad.dm b/code/modules/telesci/telepad.dm deleted file mode 100644 index d712b773d3..0000000000 --- a/code/modules/telesci/telepad.dm +++ /dev/null @@ -1,170 +0,0 @@ -///SCI TELEPAD/// -/obj/machinery/telepad - name = "telepad" - desc = "A bluespace telepad used for teleporting objects to and from a location." - icon = 'icons/obj/telescience.dmi' - icon_state = "pad-idle" - anchored = 1 - use_power = 1 - idle_power_usage = 200 - active_power_usage = 5000 - var/efficiency - -/obj/machinery/telepad/Initialize() - . = ..() - var/obj/item/circuitboard/machine/B = new /obj/item/circuitboard/machine/telesci_pad(null) - B.apply_default_parts(src) - -/obj/item/circuitboard/machine/telesci_pad - name = "Telepad (Machine Board)" - build_path = /obj/machinery/telepad - req_components = list( - /obj/item/ore/bluespace_crystal = 2, - /obj/item/stock_parts/capacitor = 1, - /obj/item/stack/cable_coil = 1, - /obj/item/stock_parts/console_screen = 1) - def_components = list(/obj/item/ore/bluespace_crystal = /obj/item/ore/bluespace_crystal/artificial) - -/obj/machinery/telepad/RefreshParts() - var/E - for(var/obj/item/stock_parts/capacitor/C in component_parts) - E += C.rating - efficiency = E - -/obj/machinery/telepad/attackby(obj/item/I, mob/user, params) - if(default_deconstruction_screwdriver(user, "pad-idle-o", "pad-idle", I)) - return - - if(panel_open) - if(istype(I, /obj/item/device/multitool)) - var/obj/item/device/multitool/M = I - M.buffer = src - to_chat(user, "You save the data in the [I.name]'s buffer.") - return 1 - - if(exchange_parts(user, I)) - return - - if(default_deconstruction_crowbar(I)) - return - - return ..() - - -//CARGO TELEPAD// -/obj/machinery/telepad_cargo - name = "cargo telepad" - desc = "A telepad used by the Rapid Crate Sender." - icon = 'icons/obj/telescience.dmi' - icon_state = "pad-idle" - anchored = 1 - use_power = 1 - idle_power_usage = 20 - active_power_usage = 500 - var/stage = 0 -/obj/machinery/telepad_cargo/attackby(obj/item/W, mob/user, params) - if(istype(W, /obj/item/wrench)) - anchored = 0 - playsound(src, 'sound/items/Ratchet.ogg', 50, 1) - if(anchored) - anchored = 0 - to_chat(user, "\The [src] can now be moved.") - else if(!anchored) - anchored = 1 - to_chat(user, "\The [src] is now secured.") - else if(istype(W, /obj/item/screwdriver)) - if(stage == 0) - playsound(src, W.usesound, 50, 1) - to_chat(user, "You unscrew the telepad's tracking beacon.") - stage = 1 - else if(stage == 1) - playsound(src, W.usesound, 50, 1) - to_chat(user, "You screw in the telepad's tracking beacon.") - stage = 0 - else if(istype(W, /obj/item/weldingtool) && stage == 1) - var/obj/item/weldingtool/WT = W - if(WT.remove_fuel(0,user)) - playsound(src.loc, 'sound/items/Welder2.ogg', 100, 1) - to_chat(user, "You start disassembling [src]...") - if(do_after(user,20*WT.toolspeed, target = src)) - if(!WT.isOn()) - return - to_chat(user, "You disassemble [src].") - new /obj/item/stack/sheet/metal(get_turf(src)) - new /obj/item/stack/sheet/glass(get_turf(src)) - qdel(src) - else - return ..() - -///TELEPAD CALLER/// -/obj/item/device/telepad_beacon - name = "telepad beacon" - desc = "Use to warp in a cargo telepad." - icon = 'icons/obj/radio.dmi' - icon_state = "beacon" - item_state = "beacon" - -/obj/item/device/telepad_beacon/attack_self(mob/user) - if(user) - to_chat(user, "Locked In") - new /obj/machinery/telepad_cargo(user.loc) - playsound(src, 'sound/effects/pop.ogg', 100, 1, 1) - qdel(src) - return - -///HANDHELD TELEPAD USER/// -/obj/item/rcs - name = "rapid-crate-sender (RCS)" - desc = "Use this to send crates and closets to cargo telepads." - icon = 'icons/obj/telescience.dmi' - icon_state = "rcs" - flags_1 = CONDUCT_1 - force = 10 - throwforce = 10 - throw_speed = 2 - throw_range = 5 - var/rcharges = 10 - var/obj/machinery/pad = null - var/last_charge = 30 - var/mode = 0 - var/rand_x = 0 - var/rand_y = 0 - var/emagged = 0 - var/teleporting = 0 - -/obj/item/rcs/New() - ..() - START_PROCESSING(SSobj, src) - -/obj/item/rcs/examine(mob/user) - ..() - to_chat(user, "There are [rcharges] charge\s left.") - -/obj/item/rcs/Destroy() - STOP_PROCESSING(SSobj, src) - return ..() -/obj/item/rcs/process() - if(rcharges > 10) - rcharges = 10 - if(last_charge == 0) - rcharges++ - last_charge = 30 - else - last_charge-- - -/obj/item/rcs/attack_self(mob/user) - if(emagged) - if(mode == 0) - mode = 1 - playsound(src.loc, 'sound/effects/pop.ogg', 50, 0) - to_chat(user, "The telepad locator has become uncalibrated.") - else - mode = 0 - playsound(src.loc, 'sound/effects/pop.ogg', 50, 0) - to_chat(user, "You calibrate the telepad locator.") - -/obj/item/rcs/emag_act(mob/user) - if(!emagged) - emagged = TRUE - do_sparks(5, TRUE, src) - to_chat(user, "You emag the RCS. Click on it to toggle between modes.") diff --git a/code/modules/telesci/telesci_computer.dm b/code/modules/telesci/telesci_computer.dm deleted file mode 100644 index 72f17fbf55..0000000000 --- a/code/modules/telesci/telesci_computer.dm +++ /dev/null @@ -1,363 +0,0 @@ -/obj/machinery/computer/telescience - name = "\improper Telepad Control Console" - desc = "Used to teleport objects to and from the telescience telepad." - icon_screen = "teleport" - icon_keyboard = "teleport_key" - circuit = /obj/item/circuitboard/computer/telesci_console - var/sending = 1 - var/obj/machinery/telepad/telepad = null - var/temp_msg = "Telescience control console initialized.
Welcome." - - // VARIABLES // - var/teles_left // How many teleports left until it becomes uncalibrated - var/datum/projectile_data/last_tele_data = null - var/z_co = 1 - var/power_off - var/rotation_off - //var/angle_off - var/last_target - - var/rotation = 0 - var/angle = 45 - var/power = 5 - - // Based on the power used - var/teleport_cooldown = 0 // every index requires a bluespace crystal - var/list/power_options = list(5, 10, 20, 25, 30, 40, 50, 80, 100) - var/teleporting = 0 - var/starting_crystals = 3 - var/max_crystals = 4 - var/list/crystals = list() - var/obj/item/device/gps/inserted_gps - -/obj/machinery/computer/telescience/Initialize() - recalibrate() - . = ..() - -/obj/machinery/computer/telescience/Destroy() - eject() - if(inserted_gps) - inserted_gps.loc = loc - inserted_gps = null - return ..() - -/obj/machinery/computer/telescience/examine(mob/user) - ..() - to_chat(user, "There are [crystals.len ? crystals.len : "no"] bluespace crystal\s in the crystal slots.") - -/obj/machinery/computer/telescience/Initialize(mapload) - . = ..() - if(mapload) - for(var/i = 1; i <= starting_crystals; i++) - crystals += new /obj/item/ore/bluespace_crystal/artificial(null) // starting crystals - -/obj/machinery/computer/telescience/attack_paw(mob/user) - to_chat(user, "You are too primitive to use this computer!") - return - -/obj/machinery/computer/telescience/attackby(obj/item/W, mob/user, params) - if(istype(W, /obj/item/ore/bluespace_crystal)) - if(crystals.len >= max_crystals) - to_chat(user, "There are not enough crystal slots.") - return - if(!user.drop_item()) - return - crystals += W - W.loc = null - user.visible_message("[user] inserts [W] into \the [src]'s crystal slot.", "You insert [W] into \the [src]'s crystal slot.") - updateDialog() - else if(istype(W, /obj/item/device/gps)) - if(!inserted_gps) - if(!user.transferItemToLoc(W, src)) - return - inserted_gps = W - user.visible_message("[user] inserts [W] into \the [src]'s GPS device slot.", "You insert [W] into \the [src]'s GPS device slot.") - else if(istype(W, /obj/item/device/multitool)) - var/obj/item/device/multitool/M = W - if(M.buffer && istype(M.buffer, /obj/machinery/telepad)) - telepad = M.buffer - M.buffer = null - to_chat(user, "You upload the data from the [W.name]'s buffer.") - else - return ..() - -/obj/machinery/computer/telescience/attack_ai(mob/user) - src.attack_hand(user) - -/obj/machinery/computer/telescience/attack_hand(mob/user) - if(..()) - return - interact(user) - -/obj/machinery/computer/telescience/interact(mob/user) - var/t - if(!telepad) - in_use = 0 //Yeah so if you deconstruct teleporter while its in the process of shooting it wont disable the console - t += "
No telepad located.
Please add telepad data.

" - else - if(inserted_gps) - t += "Eject GPS" - t += "Set GPS memory" - else - t += "Eject GPS" - t += "Set GPS memory" - t += "
[temp_msg]

" - t += "Set Bearing" - t += "
[rotation]°
" - t += "Set Elevation" - t += "
[angle]°
" - t += "Set Power" - t += "
" - - for(var/i = 1; i <= power_options.len; i++) - if(crystals.len + telepad.efficiency < i) - t += "[power_options[i]]" - continue - if(power == power_options[i]) - t += "[power_options[i]]" - continue - t += "[power_options[i]]" - t += "
" - - t += "Set Sector" - t += "
[z_co ? z_co : "NULL"]
" - - t += "
Send" - t += " Receive" - t += "
Recalibrate Crystals Eject Crystals" - - // Information about the last teleport - t += "
" - if(!last_tele_data) - t += "No teleport data found." - else - t += "Source Location: ([last_tele_data.src_x], [last_tele_data.src_y])
" - //t += "Distance: [round(last_tele_data.distance, 0.1)]m
" - t += "Time: [round(last_tele_data.time, 0.1)] secs
" - t += "
" - - var/datum/browser/popup = new(user, "telesci", name, 300, 500) - popup.set_content(t) - popup.open() - -/obj/machinery/computer/telescience/proc/sparks() - if(telepad) - do_sparks(5, TRUE, get_turf(telepad)) - -/obj/machinery/computer/telescience/proc/telefail() - sparks() - visible_message("The telepad weakly fizzles.") - -/obj/machinery/computer/telescience/proc/doteleport(mob/user) - - if(teleport_cooldown > world.time) - temp_msg = "Telepad is recharging power.
Please wait [round((teleport_cooldown - world.time) / 10)] seconds." - return - - if(teleporting) - temp_msg = "Telepad is in use.
Please wait." - return - - if(telepad) - - var/truePower = Clamp(power + power_off, 1, 1000) - var/trueRotation = rotation + rotation_off - var/trueAngle = Clamp(angle, 1, 90) - - var/datum/projectile_data/proj_data = projectile_trajectory(telepad.x, telepad.y, trueRotation, trueAngle, truePower) - last_tele_data = proj_data - - var/trueX = Clamp(round(proj_data.dest_x, 1), 1, world.maxx) - var/trueY = Clamp(round(proj_data.dest_y, 1), 1, world.maxy) - var/spawn_time = round(proj_data.time) * 10 - - var/turf/target = locate(trueX, trueY, z_co) - last_target = target - var/area/A = get_area(target) - flick("pad-beam", telepad) - - if(spawn_time > 15) // 1.5 seconds - playsound(telepad.loc, 'sound/weapons/flash.ogg', 25, 1) - // Wait depending on the time the projectile took to get there - teleporting = 1 - temp_msg = "Powering up bluespace crystals.
Please wait." - - - spawn(round(proj_data.time) * 10) // in seconds - if(!telepad) - return - if(telepad.stat & NOPOWER) - return - teleporting = 0 - teleport_cooldown = world.time + (power * 2) - teles_left -= 1 - - // use a lot of power - use_power(power * 10) - - do_sparks(5, TRUE, get_turf(telepad)) - - temp_msg = "Teleport successful.
" - if(teles_left < 10) - temp_msg += "
Calibration required soon." - else - temp_msg += "Data printed below." - - do_sparks(5, TRUE, get_turf(target)) - - var/turf/source = target - var/turf/dest = get_turf(telepad) - var/log_msg = "" - log_msg += ": [key_name(user)] has teleported " - - if(sending) - source = dest - dest = target - - flick("pad-beam", telepad) - playsound(telepad.loc, 'sound/weapons/emitter2.ogg', 25, 1, extrarange = 3, falloff = 5) - for(var/atom/movable/ROI in source) - // if is anchored, don't let through - if(ROI.anchored) - if(isliving(ROI)) - var/mob/living/L = ROI - if(L.buckled) - // TP people on office chairs - if(L.buckled.anchored) - continue - - log_msg += "[key_name(L)] (on a chair), " - else - continue - else if(!isobserver(ROI)) - continue - if(ismob(ROI)) - var/mob/T = ROI - log_msg += "[key_name(T)], " - else - log_msg += "[ROI.name]" - if (istype(ROI, /obj/structure/closet)) - var/obj/structure/closet/C = ROI - log_msg += " (" - for(var/atom/movable/Q as mob|obj in C) - if(ismob(Q)) - log_msg += "[key_name(Q)], " - else - log_msg += "[Q.name], " - if (dd_hassuffix(log_msg, "(")) - log_msg += "empty)" - else - log_msg = dd_limittext(log_msg, length(log_msg) - 2) - log_msg += ")" - log_msg += ", " - do_teleport(ROI, dest) - - if (dd_hassuffix(log_msg, ", ")) - log_msg = dd_limittext(log_msg, length(log_msg) - 2) - else - log_msg += "nothing" - log_msg += " [sending ? "to" : "from"] [trueX], [trueY], [z_co] ([A ? A.name : "null area"])" - investigate_log(log_msg, "telesci") - updateDialog() - -/obj/machinery/computer/telescience/proc/teleport(mob/user) - if(rotation == null || angle == null || z_co == null) - temp_msg = "ERROR!
Set a angle, rotation and sector." - return - if(power <= 0) - telefail() - temp_msg = "ERROR!
No power selected!" - return - if(angle < 1 || angle > 90) - telefail() - temp_msg = "ERROR!
Elevation is less than 1 or greater than 90." - return - if(z_co == ZLEVEL_CENTCOM || z_co < 1 || z_co > ZLEVEL_SPACEMAX) - telefail() - temp_msg = "ERROR! Sector is outside known time and space!" - return - if(teles_left > 0) - doteleport(user) - else - telefail() - temp_msg = "ERROR!
Calibration required." - return - return - -/obj/machinery/computer/telescience/proc/eject() - for(var/obj/item/I in crystals) - I.loc = src.loc - crystals -= I - power = 0 - -/obj/machinery/computer/telescience/Topic(href, href_list) - if(..()) - return - if(!telepad) - updateDialog() - return - if(telepad.panel_open) - temp_msg = "Telepad undergoing physical maintenance operations." - - if(href_list["setrotation"]) - var/new_rot = input("Please input desired bearing in degrees.", name, rotation) as num - if(..()) // Check after we input a value, as they could've moved after they entered something - return - rotation = Clamp(new_rot, -900, 900) - rotation = round(rotation, 0.01) - - if(href_list["setangle"]) - var/new_angle = input("Please input desired elevation in degrees.", name, angle) as num - if(..()) - return - angle = Clamp(round(new_angle, 0.1), 1, 9999) - - if(href_list["setpower"]) - var/index = href_list["setpower"] - index = text2num(index) - if(index != null && power_options[index]) - if(crystals.len + telepad.efficiency >= index) - power = power_options[index] - - if(href_list["setz"]) - var/new_z = input("Please input desired sector.", name, z_co) as num - if(..()) - return - z_co = Clamp(round(new_z), 1, 10) - - if(href_list["ejectGPS"]) - if(inserted_gps) - inserted_gps.loc = loc - inserted_gps = null - - if(href_list["setMemory"]) - if(last_target && inserted_gps) - inserted_gps.locked_location = last_target - temp_msg = "Location saved." - else - temp_msg = "ERROR!
No data was stored." - - if(href_list["send"]) - sending = 1 - teleport(usr) - - if(href_list["receive"]) - sending = 0 - teleport(usr) - - if(href_list["recal"]) - recalibrate() - sparks() - temp_msg = "NOTICE:
Calibration successful." - - if(href_list["eject"]) - eject() - temp_msg = "NOTICE:
Bluespace crystals ejected." - - updateDialog() - -/obj/machinery/computer/telescience/proc/recalibrate() - teles_left = rand(30, 40) - //angle_off = rand(-25, 25) - power_off = rand(-4, 0) - rotation_off = rand(-10, 10) diff --git a/code/modules/vending/snack.dm b/code/modules/vending/snack.dm index 55e1424d96..8fcd189a4f 100644 --- a/code/modules/vending/snack.dm +++ b/code/modules/vending/snack.dm @@ -44,7 +44,7 @@ if(iscompartmentfull(user)) break if(!S.junkiness) - T.remove_from_storage(S, src) + T.SendSignal(COMSIG_TRY_STORAGE_TAKE, S, src, TRUE) food_load(S) loaded++ else