diff --git a/code/__DEFINES/dcs/signals/signals_global.dm b/code/__DEFINES/dcs/signals/signals_global.dm index bafb53f1ffd..f0938ea68ee 100644 --- a/code/__DEFINES/dcs/signals/signals_global.dm +++ b/code/__DEFINES/dcs/signals/signals_global.dm @@ -51,6 +51,8 @@ #define LINKED_UP (1<<0) /// an obj/item is created! (obj/item/created_item) #define COMSIG_GLOB_NEW_ITEM "!new_item" +/// an obj/machinery is created! (obj/machinery/created_machine) +#define COMSIG_GLOB_NEW_MACHINE "!new_machine" /// a client (re)connected, after all /client/New() checks have passed : (client/connected_client) #define COMSIG_GLOB_CLIENT_CONNECT "!client_connect" /// a weather event of some kind occured diff --git a/code/__DEFINES/dcs/signals/signals_object.dm b/code/__DEFINES/dcs/signals/signals_object.dm index 36c28708959..3f0edab3f75 100644 --- a/code/__DEFINES/dcs/signals/signals_object.dm +++ b/code/__DEFINES/dcs/signals/signals_object.dm @@ -416,3 +416,6 @@ /// from /obj/item/detective_scanner/scan(): (mob/user, list/extra_data) #define COMSIG_DETECTIVE_SCANNED "det_scanned" + +/// from /obj/machinery/mineral/ore_redemption/pickup_item when it successfully picks something up +#define COMSIG_ORM_COLLECTED_ORE "orm_collected_ore" diff --git a/code/__DEFINES/dcs/signals/signals_traitor.dm b/code/__DEFINES/dcs/signals/signals_traitor.dm index 666ff575837..66aebd7ae95 100644 --- a/code/__DEFINES/dcs/signals/signals_traitor.dm +++ b/code/__DEFINES/dcs/signals/signals_traitor.dm @@ -21,6 +21,9 @@ #define COMPONENT_FORCE_PLACEMENT (1<<0) #define COMPONENT_FORCE_FAIL_PLACEMENT (1<<1) +/// Called when a machine a traitor has booby trapped triggers its payload +#define COMSIG_TRAITOR_MACHINE_TRAP_TRIGGERED "traitor_machine_trap_triggered" + /// Called when a device a traitor has planted effects someone's mood. Pass the mind of the viewer. #define COMSIG_DEMORALISING_EVENT "traitor_demoralise_event" /// Called when you finish drawing some graffiti so we can register more signals on it. Pass the graffiti effect. diff --git a/code/__DEFINES/do_afters.dm b/code/__DEFINES/do_afters.dm index 693c0dba6f5..f46710643d0 100644 --- a/code/__DEFINES/do_afters.dm +++ b/code/__DEFINES/do_afters.dm @@ -5,3 +5,4 @@ #define DOAFTER_SOURCE_CLIMBING_LADDER "doafter_climbingladder" #define DOAFTER_SOURCE_SPIDER "doafter_spider" #define DOAFTER_SOURCE_HEAL_TOUCH "doafter_heal_touch" +#define DOAFTER_SOURCE_PLANTING_DEVICE "doafter_planting_device" diff --git a/code/datums/components/interaction_booby_trap.dm b/code/datums/components/interaction_booby_trap.dm new file mode 100644 index 00000000000..03892f3e93b --- /dev/null +++ b/code/datums/components/interaction_booby_trap.dm @@ -0,0 +1,102 @@ +/** + * Attached to an atom, creates an explosion when it is interacted with + */ +/datum/component/interaction_booby_trap + /// Explosion radius of light damage + var/explosion_light_range + /// Explosion radius of heavy damage + var/explosion_heavy_range + /// Sound to play when triggered + var/triggered_sound + /// Time to wait between being triggered and blowing up + var/trigger_delay + /// Looping sound to clue people in that something is up + var/datum/looping_sound/active_sound_loop + /// Using this tool on the atom will defuse the explosive + var/defuse_tool + /// List of additional signals which should make this explode + var/list/additional_triggers + /// Callback to run when we're going to explode + var/datum/callback/on_triggered_callback + /// Callback to run when we've been defused + var/datum/callback/on_defused_callback + /// Time until we explode + var/explode_timer + +/datum/component/interaction_booby_trap/Initialize( + explosion_light_range = 3, + explosion_heavy_range = 1, // So we destroy some machine components + triggered_sound = 'sound/machines/triple_beep.ogg', + trigger_delay = 0.5 SECONDS, + sound_loop_type = /datum/looping_sound/trapped_machine_beep, + defuse_tool = TOOL_SCREWDRIVER, + additional_triggers = list(), + datum/callback/on_triggered_callback = null, + datum/callback/on_defused_callback = null, +) + if(!isatom(parent)) + return COMPONENT_INCOMPATIBLE + + src.explosion_light_range = explosion_light_range + src.explosion_heavy_range = explosion_heavy_range + src.triggered_sound = triggered_sound + src.trigger_delay = trigger_delay + src.defuse_tool = defuse_tool + src.additional_triggers = additional_triggers + src.on_triggered_callback = on_triggered_callback + src.on_defused_callback = on_defused_callback + if (sound_loop_type) + active_sound_loop = new sound_loop_type(parent) + active_sound_loop.start() + + RegisterSignal(parent, COMSIG_ATOM_ATTACK_HAND, PROC_REF(on_touched)) + RegisterSignal(parent, COMSIG_PARENT_EXAMINE_MORE, PROC_REF(on_examine)) + if (defuse_tool) + RegisterSignal(parent, COMSIG_ATOM_TOOL_ACT(defuse_tool), PROC_REF(on_defused)) + if (length(additional_triggers)) + RegisterSignals(parent, additional_triggers, PROC_REF(trigger_explosive)) + +/datum/component/interaction_booby_trap/Destroy(force, silent) + UnregisterSignal(parent, list(COMSIG_ATOM_ATTACK_HAND, COMSIG_ATOM_TOOL_ACT(defuse_tool), COMSIG_PARENT_EXAMINE_MORE) + additional_triggers) + QDEL_NULL(active_sound_loop) + QDEL_NULL(on_triggered_callback) + QDEL_NULL(on_defused_callback) + return ..() + +/// Called when someone touches the parent atom with their hands, we want to blow up +/datum/component/interaction_booby_trap/proc/on_touched(atom/source) + SIGNAL_HANDLER + trigger_explosive(source) + return COMPONENT_CANCEL_ATTACK_CHAIN + +/// Start a countdown until destruction +/datum/component/interaction_booby_trap/proc/trigger_explosive(atom/source) + SIGNAL_HANDLER + if (explode_timer) + return + explode_timer = addtimer(CALLBACK(src, PROC_REF(explode), source), 0.5 SECONDS) + source.balloon_alert_to_viewers("beep") + playsound(parent, triggered_sound, 50, FALSE) + return + +/// Blow up the parent atom and delete ourselves +/datum/component/interaction_booby_trap/proc/explode(atom/source) + on_triggered_callback?.Invoke(source) + var/turf/origin_turf = get_turf(source) + new /obj/effect/temp_visual/explosion/fast(origin_turf) + EX_ACT(source, EXPLODE_HEAVY, source) + explosion(origin = origin_turf, light_impact_range = explosion_light_range, heavy_impact_range = explosion_heavy_range, explosion_cause = src) + qdel(src) + +/// Defuse the bomb and delete ourselves +/datum/component/interaction_booby_trap/proc/on_defused(atom/source, mob/user, obj/item/tool) + SIGNAL_HANDLER + on_defused_callback?.Invoke(source, user, tool) + qdel(src) + return COMPONENT_BLOCK_TOOL_ATTACK + +/// Give people a little hint +/datum/component/interaction_booby_trap/proc/on_examine(atom/source, mob/examiner, list/examine_list) + SIGNAL_HANDLER + var/defuse_hint = (defuse_tool) ? "Perhaps [tool_behaviour_name(defuse_tool)] could help..." : "" + examine_list += span_warning("There's a light flashing red inside the maintenance panel. [defuse_hint]") diff --git a/code/datums/looping_sounds/item_sounds.dm b/code/datums/looping_sounds/item_sounds.dm index 9a7028aab6e..93de93ec94b 100644 --- a/code/datums/looping_sounds/item_sounds.dm +++ b/code/datums/looping_sounds/item_sounds.dm @@ -18,3 +18,11 @@ mid_sounds = list('sound/items/taperecorder/taperecorder_hiss_mid.ogg' = 1) start_sound = list('sound/items/taperecorder/taperecorder_hiss_start.ogg' = 1) volume = 10 + +/datum/looping_sound/trapped_machine_beep + mid_sounds = list('sound/machines/beep.ogg' = 1) + mid_length = 10 SECONDS + mid_length_vary = 5 SECONDS + falloff_exponent = 10 + falloff_distance = 1 + volume = 5 diff --git a/code/game/machinery/_machinery.dm b/code/game/machinery/_machinery.dm index 8fc4f302304..677717356b1 100644 --- a/code/game/machinery/_machinery.dm +++ b/code/game/machinery/_machinery.dm @@ -183,6 +183,7 @@ if(HAS_TRAIT(SSstation, STATION_TRAIT_BOTS_GLITCHED)) randomize_language_if_on_station() + SEND_GLOBAL_SIGNAL(COMSIG_GLOB_NEW_MACHINE, src) return INITIALIZE_HINT_LATELOAD @@ -1200,3 +1201,7 @@ if(isliving(user)) last_used_time = world.time last_user_mobtype = user.type + +/// Called if this machine is supposed to be a sabotage machine objective. +/obj/machinery/proc/add_as_sabotage_target() + return diff --git a/code/modules/antagonists/traitor/objectives/destroy_machinery.dm b/code/modules/antagonists/traitor/objectives/destroy_machinery.dm deleted file mode 100644 index 29cc7e42856..00000000000 --- a/code/modules/antagonists/traitor/objectives/destroy_machinery.dm +++ /dev/null @@ -1,76 +0,0 @@ -/datum/traitor_objective_category/destroy_machinery - name = "Destroy Protolathe" - objectives = list( - /datum/traitor_objective/destroy_machinery = 1, - /datum/traitor_objective/destroy_machinery/high_risk = 1 - ) - -/datum/traitor_objective/destroy_machinery - name = "Destroy the %MACHINE%" - description = "Destroy the %MACHINE% to cause disarray and disrupt the operations of the %JOB%'s department." - - progression_reward = list(2 MINUTES, 8 MINUTES) - telecrystal_reward = list(0, 1) - - progression_minimum = 0 MINUTES - progression_maximum = 10 MINUTES - - /// The maximum amount of this type of objective a traitor can have. - var/maximum_allowed = 2 - /// The possible target machinery and the jobs tied to each one. - var/list/applicable_jobs = list( - JOB_RESEARCH_DIRECTOR = /obj/machinery/rnd/production/protolathe/department/science, - JOB_CHIEF_MEDICAL_OFFICER = /obj/machinery/rnd/production/techfab/department/medical, - JOB_CHIEF_ENGINEER = /obj/machinery/rnd/production/protolathe/department/engineering, - JOB_HEAD_OF_PERSONNEL = /obj/machinery/rnd/production/techfab/department/service, - JOB_SHAFT_MINER = /obj/machinery/mineral/ore_redemption, - JOB_QUARTERMASTER = /obj/machinery/rnd/production/techfab/department/cargo, - ) - /// Whether this can bypass the maximum_allowed value or not - var/allow_more_than_max = FALSE - /// The chosen job. Used to check for duplicates - var/chosen_job - -/datum/traitor_objective/destroy_machinery/high_risk - progression_reward = list(5 MINUTES, 10 MINUTES) - telecrystal_reward = list(3, 4) - - progression_minimum = 15 MINUTES - progression_maximum = 30 MINUTES - allow_more_than_max = TRUE - applicable_jobs = list( - JOB_STATION_ENGINEER = /obj/machinery/telecomms/hub, - JOB_SCIENTIST = /obj/machinery/rnd/server, - ) - -/datum/traitor_objective/destroy_machinery/can_generate_objective(datum/mind/generating_for, list/possible_duplicates) - if(length(possible_duplicates) >= maximum_allowed && !allow_more_than_max) - return FALSE - return TRUE - -/datum/traitor_objective/destroy_machinery/generate_objective(datum/mind/generating_for, list/possible_duplicates) - for(var/datum/traitor_objective/destroy_machinery/objective as anything in possible_duplicates) - applicable_jobs -= objective.chosen_job - if(!length(applicable_jobs)) - return FALSE - var/list/obj/machinery/possible_machines = list() - while(length(possible_machines) <= 0 && length(applicable_jobs) > 0) - var/target_head = pick(applicable_jobs) - var/obj/machinery/machine_to_find = applicable_jobs[target_head] - applicable_jobs -= target_head - - chosen_job = target_head - for(var/obj/machinery/machine as anything in GLOB.machines) - if(istype(machine, machine_to_find) && is_station_level(machine.z)) - possible_machines += machine - - if(!length(possible_machines)) - return FALSE - - for(var/obj/machinery/machine as anything in possible_machines) - AddComponent(/datum/component/traitor_objective_register, machine, succeed_signals = list(COMSIG_PARENT_QDELETING)) - - replace_in_name("%JOB%", lowertext(chosen_job)) - replace_in_name("%MACHINE%", possible_machines[1].name) - return TRUE - diff --git a/code/modules/antagonists/traitor/objectives/sabotage_machinery.dm b/code/modules/antagonists/traitor/objectives/sabotage_machinery.dm new file mode 100644 index 00000000000..b5e26c725ad --- /dev/null +++ b/code/modules/antagonists/traitor/objectives/sabotage_machinery.dm @@ -0,0 +1,242 @@ +/// Datum which manages references to things we are instructed to destroy +GLOBAL_DATUM_INIT(objective_machine_handler, /datum/objective_target_machine_handler, new()) + +/// Marks a machine as a possible traitor sabotage target +/proc/add_sabotage_machine(source, typepath) + LAZYADD(GLOB.objective_machine_handler.machine_instances_by_path[typepath], source) + return typepath + +/// Traitor objective to destroy a machine the crew cares about +/datum/traitor_objective_category/sabotage_machinery + name = "Sabotage Worksite" + objectives = list( + /datum/traitor_objective/sabotage_machinery/trap = 1, + /datum/traitor_objective/sabotage_machinery/destroy = 1, + ) + +/datum/traitor_objective/sabotage_machinery + name = "Sabotage the %MACHINE%" + description = "Abstract objective holder which shouldn't appear in your uplink." + abstract_type = /datum/traitor_objective/sabotage_machinery + + /// The maximum amount of this type of objective a traitor can have, set to 0 for no limit. + var/maximum_allowed = 0 + /// The possible target machinery and the jobs tied to each one. + var/list/applicable_jobs = list() + /// The chosen job. Used to check for duplicates + var/chosen_job + +/datum/traitor_objective/sabotage_machinery/can_generate_objective(datum/mind/generating_for, list/possible_duplicates) + if(!maximum_allowed) + return TRUE + if(length(possible_duplicates) >= maximum_allowed) + return FALSE + return TRUE + +/datum/traitor_objective/sabotage_machinery/generate_objective(datum/mind/generating_for, list/possible_duplicates) + var/list/possible_jobs = applicable_jobs.Copy() + for(var/datum/traitor_objective/sabotage_machinery/objective as anything in possible_duplicates) + possible_jobs -= objective.chosen_job + for(var/available_job in possible_jobs) + var/job_machine_path = possible_jobs[available_job] + if (!length(GLOB.objective_machine_handler.machine_instances_by_path[job_machine_path])) + possible_jobs -= available_job + if(!length(possible_jobs)) + return FALSE + + chosen_job = pick(possible_jobs) + var/list/obj/machinery/possible_machines = GLOB.objective_machine_handler.machine_instances_by_path[possible_jobs[chosen_job]] + for(var/obj/machinery/machine as anything in possible_machines) + prepare_machine(machine) + + replace_in_name("%JOB%", lowertext(chosen_job)) + replace_in_name("%MACHINE%", possible_machines[1].name) + return TRUE + +/// Marks a given machine as our target +/datum/traitor_objective/sabotage_machinery/proc/prepare_machine(obj/machinery/machine) + AddComponent(/datum/component/traitor_objective_register, machine, succeed_signals = list(COMSIG_PARENT_QDELETING)) + +// Destroy machines which are in annoying locations, are annoying when destroyed, and aren't directly interacted with +/datum/traitor_objective/sabotage_machinery/destroy + name = "Destroy the %MACHINE%" + description = "Destroy the %MACHINE% to cause disarray and disrupt the operations of the %JOB%'s department." + + progression_reward = list(5 MINUTES, 10 MINUTES) + telecrystal_reward = list(3, 4) + + progression_minimum = 15 MINUTES + progression_maximum = 30 MINUTES + + applicable_jobs = list( + JOB_STATION_ENGINEER = /obj/machinery/telecomms/hub, + JOB_SCIENTIST = /obj/machinery/rnd/server, + ) + +// Rig machines which are in public locations to explode when interacted with +/datum/traitor_objective/sabotage_machinery/trap + name = "Sabotage the %MACHINE%" + description = "Destroy the %MACHINE% to cause disarray and disrupt the operations of the %JOB%'s department. If you can get another crew member to destroy the machine using the provided booby trap, you will be rewarded with an additional %PROGRESSION% reputation and %TC% telecrystals." + + progression_reward = list(2 MINUTES, 4 MINUTES) + telecrystal_reward = 0 // Only from completing the bonus objective + + progression_minimum = 0 MINUTES + progression_maximum = 10 MINUTES + + maximum_allowed = 2 + applicable_jobs = list( + JOB_CHIEF_ENGINEER = /obj/machinery/rnd/production/protolathe/department/engineering, + JOB_CHIEF_MEDICAL_OFFICER = /obj/machinery/rnd/production/techfab/department/medical, + JOB_HEAD_OF_PERSONNEL = /obj/machinery/rnd/production/techfab/department/service, + JOB_QUARTERMASTER = /obj/machinery/rnd/production/techfab/department/cargo, + JOB_RESEARCH_DIRECTOR = /obj/machinery/rnd/production/protolathe/department/science, + JOB_SHAFT_MINER = /obj/machinery/mineral/ore_redemption, + ) + + /// Bonus reward to grant if you booby trap successfully + var/bonus_tc = 2 + /// Bonus progression to grant if you booby trap successfully + var/bonus_progression = 5 MINUTES + /// The trap device we give out + var/obj/item/traitor_machine_trapper/tool + +/datum/traitor_objective/sabotage_machinery/trap/generate_objective(datum/mind/generating_for, list/possible_duplicates) + . = ..() + if (!.) + return FALSE + + replace_in_name("%TC%", bonus_tc) + replace_in_name("%PROGRESSION%", DISPLAY_PROGRESSION(bonus_progression)) + return TRUE + +/datum/traitor_objective/sabotage_machinery/trap/prepare_machine(obj/machinery/machine) + RegisterSignal(machine, COMSIG_TRAITOR_MACHINE_TRAP_TRIGGERED, PROC_REF(sabotage_success)) + return ..() + +/// Called when you successfully proc the booby trap, gives a bonus reward +/datum/traitor_objective/sabotage_machinery/trap/proc/sabotage_success(obj/machinery/machine) + progression_reward += bonus_progression + telecrystal_reward += bonus_tc + succeed_objective() + +/datum/traitor_objective/sabotage_machinery/trap/generate_ui_buttons(mob/user) + var/list/buttons = list() + if(!tool) + buttons += add_ui_button("", "Pressing this will materialize an explosive trap in your hand, which you can conceal within the target machine", "wifi", "summon_gear") + return buttons + +/datum/traitor_objective/sabotage_machinery/trap/ui_perform_action(mob/living/user, action) + . = ..() + switch(action) + if("summon_gear") + if(tool) + return + tool = new(user.drop_location()) + user.put_in_hands(tool) + tool.balloon_alert(user, "a booby trap materializes in your hand") + tool.target_machine_path = applicable_jobs[chosen_job] + +/// Item which you use on a machine to cause it to explode next time someone interacts with it +/obj/item/traitor_machine_trapper + name = "suspicious device" + desc = "It looks dangerous." + icon = 'icons/obj/weapons/items_and_weapons.dmi' + icon_state = "boobytrap" + + /// Light explosion range, to hurt the person using the machine + var/explosion_range = 3 + /// The type of object on which this can be planted on. + var/obj/machinery/target_machine_path + /// The time it takes to deploy the bomb. + var/deploy_time = 10 SECONDS + +/obj/item/traitor_machine_trapper/examine(mob/user) + . = ..() + if(!user.mind?.has_antag_datum(/datum/antagonist/traitor)) + return + if(target_machine_path) + . += span_notice("This device must be placed by clicking on a [initial(target_machine_path.name)] with it. It can be removed with a screwdriver.") + . += span_notice("Remember, you may leave behind fingerprints on the device. Wear gloves when handling it to be safe!") + +/obj/item/traitor_machine_trapper/afterattack(atom/movable/target, mob/user, proximity_flag, click_parameters) + . = ..() + if(!user.Adjacent(target)) + return + if(!istype(target, target_machine_path)) + balloon_alert(user, "invalid target!") + return + . |= AFTERATTACK_PROCESSED_ITEM + balloon_alert(user, "planting device...") + if(!do_after(user, delay = deploy_time, target = src, interaction_key = DOAFTER_SOURCE_PLANTING_DEVICE)) + return + target.AddComponent(\ + /datum/component/interaction_booby_trap,\ + additional_triggers = list(COMSIG_ORM_COLLECTED_ORE),\ + on_triggered_callback = CALLBACK(src, PROC_REF(on_triggered)),\ + on_defused_callback = CALLBACK(src, PROC_REF(on_defused)),\ + ) + RegisterSignal(target, COMSIG_PARENT_QDELETING, GLOBAL_PROC_REF(qdel), src) + moveToNullspace() + +/// Called when applied trap is triggered, mark success +/obj/item/traitor_machine_trapper/proc/on_triggered(atom/machine) + SEND_SIGNAL(machine, COMSIG_TRAITOR_MACHINE_TRAP_TRIGGERED) + qdel(src) + +/// Called when applied trap has been defused, retrieve this item from nullspace +/obj/item/traitor_machine_trapper/proc/on_defused(atom/machine, mob/defuser, obj/item/tool) + UnregisterSignal(machine, COMSIG_PARENT_QDELETING) + playsound(machine, 'sound/effects/structure_stress/pop3.ogg', 100, vary = TRUE) + forceMove(get_turf(machine)) + visible_message(span_warning("A [src] falls out from the [machine]!")) + +/// Datum which manages references to things we are instructed to destroy +/datum/objective_target_machine_handler + /// Existing instances of machines organised by typepath + var/list/machine_instances_by_path = list() + +/datum/objective_target_machine_handler/New() + . = ..() + RegisterSignal(SSdcs, COMSIG_GLOB_NEW_MACHINE, PROC_REF(on_machine_created)) + RegisterSignal(SSatoms, COMSIG_SUBSYSTEM_POST_INITIALIZE, PROC_REF(finalise_valid_targets)) + +/// Adds a newly created machine to our list of machines, if we need it +/datum/objective_target_machine_handler/proc/on_machine_created(datum/source, obj/machinery/new_machine) + SIGNAL_HANDLER + new_machine.add_as_sabotage_target() + +/// Confirm that everything added to the list is a valid target, then prevent new targets from being added +/datum/objective_target_machine_handler/proc/finalise_valid_targets() + SIGNAL_HANDLER + for (var/machine_type in machine_instances_by_path) + for (var/obj/machinery/machine as anything in machine_instances_by_path[machine_type]) + var/turf/place = get_turf(machine) + if(!place || !is_station_level(place.z)) + machine_instances_by_path[machine_type] -= machine + continue + RegisterSignal(machine, COMSIG_PARENT_QDELETING, PROC_REF(machine_destroyed)) + UnregisterSignal(SSdcs, COMSIG_GLOB_NEW_MACHINE) + +/datum/objective_target_machine_handler/proc/machine_destroyed(atom/machine) + SIGNAL_HANDLER + // Sadly can't do a direct typepath association because of some map helper subtypes + for (var/machine_type in machine_instances_by_path) + machine_instances_by_path[machine_type] -= machine + +// Mark valid machines as targets, add a new entry here if you add a new potential target + +/obj/machinery/telecomms/hub/add_as_sabotage_target() + return add_sabotage_machine(src, /obj/machinery/telecomms/hub) // Not always our specific type because of map helper subtypes + +/obj/machinery/rnd/server/add_as_sabotage_target() + return add_sabotage_machine(src, type) + +/obj/machinery/rnd/production/protolathe/department/add_as_sabotage_target() + return add_sabotage_machine(src, type) + +/obj/machinery/rnd/production/techfab/department/add_as_sabotage_target() + return add_sabotage_machine(src, type) + +/obj/machinery/mineral/ore_redemption/add_as_sabotage_target() + return add_sabotage_machine(src, type) diff --git a/code/modules/mining/machine_redemption.dm b/code/modules/mining/machine_redemption.dm index c8b14a20310..f37092fcfc8 100644 --- a/code/modules/mining/machine_redemption.dm +++ b/code/modules/mining/machine_redemption.dm @@ -48,34 +48,36 @@ . += span_notice("Alt-click to rotate the input and output direction.") /// Turns ore into its refined type, and sends it to its material container -/obj/machinery/mineral/ore_redemption/proc/smelt_ore(obj/item/stack/ore/O) - if(QDELETED(O)) +/obj/machinery/mineral/ore_redemption/proc/smelt_ore(obj/item/stack/ore/gathered_ore) + if(QDELETED(gathered_ore)) return var/datum/component/material_container/mat_container = materials.mat_container if (!mat_container) return - if(O.refined_type == null) + if(gathered_ore.refined_type == null) return - if(O?.refined_type) - points += O.points * point_upgrade * O.amount + if(gathered_ore?.refined_type) + points += gathered_ore.points * point_upgrade * gathered_ore.amount - var/material_amount = mat_container.get_item_material_amount(O, BREAKDOWN_FLAGS_ORM) + var/material_amount = mat_container.get_item_material_amount(gathered_ore, BREAKDOWN_FLAGS_ORM) if(!material_amount) - qdel(O) //no materials, incinerate it + qdel(gathered_ore) //no materials, incinerate it - else if(!mat_container.has_space(material_amount * O.amount)) //if there is no space, eject it - unload_mineral(O) + else if(!mat_container.has_space(material_amount * gathered_ore.amount)) //if there is no space, eject it + unload_mineral(gathered_ore) else - var/list/stack_mats = O.get_material_composition(BREAKDOWN_FLAGS_ORM) + var/list/stack_mats = gathered_ore.get_material_composition(BREAKDOWN_FLAGS_ORM) var/mats = stack_mats & mat_container.materials - var/amount = O.amount - mat_container.insert_item(O, ore_multiplier, breakdown_flags=BREAKDOWN_FLAGS_ORM) //insert it + var/amount = gathered_ore.amount + mat_container.insert_item(gathered_ore, ore_multiplier, breakdown_flags=BREAKDOWN_FLAGS_ORM) //insert it materials.silo_log(src, "smelted", amount, "someone", mats) - qdel(O) + qdel(gathered_ore) + + SEND_SIGNAL(src, COMSIG_ORM_COLLECTED_ORE) /// Returns the amount of a specific alloy design, based on the accessible materials /obj/machinery/mineral/ore_redemption/proc/can_smelt_alloy(datum/design/D) diff --git a/icons/obj/weapons/items_and_weapons.dmi b/icons/obj/weapons/items_and_weapons.dmi index 584ae5f7d19..2ae955091f6 100644 Binary files a/icons/obj/weapons/items_and_weapons.dmi and b/icons/obj/weapons/items_and_weapons.dmi differ diff --git a/tgstation.dme b/tgstation.dme index b8715c03bcb..81616728c1e 100644 --- a/tgstation.dme +++ b/tgstation.dme @@ -976,6 +976,7 @@ #include "code\datums\components\holderloving.dm" #include "code\datums\components\igniter.dm" #include "code\datums\components\infective.dm" +#include "code\datums\components\interaction_booby_trap.dm" #include "code\datums\components\irradiated.dm" #include "code\datums\components\itembound.dm" #include "code\datums\components\itempicky.dm" @@ -2686,12 +2687,12 @@ #include "code\modules\antagonists\traitor\objectives\demoralise_poster.dm" #include "code\modules\antagonists\traitor\objectives\destroy_heirloom.dm" #include "code\modules\antagonists\traitor\objectives\destroy_item.dm" -#include "code\modules\antagonists\traitor\objectives\destroy_machinery.dm" #include "code\modules\antagonists\traitor\objectives\eyesnatching.dm" #include "code\modules\antagonists\traitor\objectives\hack_comm_console.dm" #include "code\modules\antagonists\traitor\objectives\kidnapping.dm" #include "code\modules\antagonists\traitor\objectives\kill_pet.dm" #include "code\modules\antagonists\traitor\objectives\locate_weakpoint.dm" +#include "code\modules\antagonists\traitor\objectives\sabotage_machinery.dm" #include "code\modules\antagonists\traitor\objectives\sleeper_protocol.dm" #include "code\modules\antagonists\traitor\objectives\steal.dm" #include "code\modules\antagonists\traitor\objectives\final_objective\battlecruiser.dm"