Files
nevimer 00ccf0c6b5 Merge remote-tracking branch 'tgstation/master' into upstream-feb12-2026
# Conflicts:
#	.github/CODEOWNERS
#	.github/workflows/compile_changelogs.yml
#	.github/workflows/stale.yml
#	SQL/database_changelog.md
#	_maps/map_files/CatwalkStation/CatwalkStation_2023.dmm
#	code/__DEFINES/atom_hud.dm
#	code/__DEFINES/inventory.dm
#	code/__DEFINES/mobs.dm
#	code/__DEFINES/species_clothing_paths.dm
#	code/__DEFINES/subsystems.dm
#	code/__DEFINES/surgery.dm
#	code/__HELPERS/global_lists.dm
#	code/_globalvars/lists/maintenance_loot.dm
#	code/_globalvars/traits/_traits.dm
#	code/controllers/subsystem/minor_mapping.dm
#	code/controllers/subsystem/processing/quirks.dm
#	code/controllers/subsystem/shuttle.dm
#	code/datums/components/palette.dm
#	code/datums/components/surgery_initiator.dm
#	code/datums/diseases/advance/advance.dm
#	code/datums/hud.dm
#	code/datums/mood.dm
#	code/datums/mutations/chameleon.dm
#	code/datums/quirks/negative_quirks/nyctophobia.dm
#	code/datums/status_effects/debuffs/debuffs.dm
#	code/datums/status_effects/debuffs/drunk.dm
#	code/datums/status_effects/debuffs/slime/slime_leech.dm
#	code/datums/weather/weather.dm
#	code/game/data_huds.dm
#	code/game/objects/items.dm
#	code/game/objects/items/devices/scanners/health_analyzer.dm
#	code/game/objects/items/frog_statue.dm
#	code/game/objects/items/rcd/RLD.dm
#	code/game/objects/items/robot/items/hypo.dm
#	code/game/objects/items/stacks/medical.dm
#	code/game/objects/items/stacks/wrap.dm
#	code/game/objects/items/storage/garment.dm
#	code/game/objects/items/tools/medical/defib.dm
#	code/game/objects/items/weaponry.dm
#	code/game/objects/items/weaponry/melee/misc.dm
#	code/game/objects/structures/crates_lockers/closets/secure/security.dm
#	code/game/objects/structures/curtains.dm
#	code/game/objects/structures/dresser.dm
#	code/game/objects/structures/girders.dm
#	code/game/objects/structures/maintenance.dm
#	code/game/objects/structures/mirror.dm
#	code/modules/admin/greyscale_modify_menu.dm
#	code/modules/admin/verbs/light_debug.dm
#	code/modules/antagonists/ashwalker/ashwalker.dm
#	code/modules/antagonists/heretic/knowledge/starting_lore.dm
#	code/modules/antagonists/ninja/ninjaDrainAct.dm
#	code/modules/art/paintings.dm
#	code/modules/client/preferences.dm
#	code/modules/client/verbs/ooc.dm
#	code/modules/clothing/head/wig.dm
#	code/modules/events/disease_outbreak.dm
#	code/modules/holodeck/holo_effect.dm
#	code/modules/jobs/job_types/head_of_security.dm
#	code/modules/jobs/job_types/security_officer.dm
#	code/modules/library/skill_learning/generic_skillchips/point.dm
#	code/modules/mining/lavaland/ash_flora.dm
#	code/modules/mining/lavaland/mining_loot/megafauna/ash_drake.dm
#	code/modules/mob/dead/new_player/new_player.dm
#	code/modules/mob/living/basic/guardian/guardian.dm
#	code/modules/mob/living/basic/space_fauna/space_dragon/space_dragon.dm
#	code/modules/mob/living/carbon/carbon.dm
#	code/modules/mob/living/carbon/human/human.dm
#	code/modules/mob/living/carbon/human/human_defines.dm
#	code/modules/mob/living/carbon/life.dm
#	code/modules/mob/living/living.dm
#	code/modules/mob/living/living_defines.dm
#	code/modules/mob/mob.dm
#	code/modules/mob_spawn/ghost_roles/mining_roles.dm
#	code/modules/mod/mod_control.dm
#	code/modules/mod/modules/modules_general.dm
#	code/modules/modular_computers/computers/item/computer_ui.dm
#	code/modules/paperwork/paper.dm
#	code/modules/paperwork/paperbin.dm
#	code/modules/power/lighting/light.dm
#	code/modules/projectiles/guns/energy/kinetic_accelerator.dm
#	code/modules/projectiles/projectile.dm
#	code/modules/reagents/chemistry/reagents/drinks/alcohol_reagents.dm
#	code/modules/reagents/chemistry/reagents/food_reagents.dm
#	code/modules/reagents/chemistry/reagents/other_reagents.dm
#	code/modules/reagents/chemistry/reagents/pyrotechnic_reagents.dm
#	code/modules/research/xenobiology/crossbreeding/_clothing.dm
#	code/modules/research/xenobiology/crossbreeding/prismatic.dm
#	code/modules/surgery/advanced/brainwashing.dm
#	code/modules/surgery/advanced/lobotomy.dm
#	code/modules/surgery/amputation.dm
#	code/modules/surgery/blood_filter.dm
#	code/modules/surgery/bodyparts/_bodyparts.dm
#	code/modules/surgery/brain_surgery.dm
#	code/modules/surgery/cavity_implant.dm
#	code/modules/surgery/coronary_bypass.dm
#	code/modules/surgery/gastrectomy.dm
#	code/modules/surgery/healing.dm
#	code/modules/surgery/limb_augmentation.dm
#	code/modules/surgery/organ_manipulation.dm
#	code/modules/surgery/revival.dm
#	code/modules/surgery/sleeper_protocol.dm
#	code/modules/surgery/surgery_helpers.dm
#	code/modules/surgery/surgery_step.dm
#	code/modules/unit_tests/_unit_tests.dm
#	code/modules/unit_tests/designs.dm
#	code/modules/unit_tests/icon_state_worn.dm
#	code/modules/unit_tests/screenshots/screenshot_antag_icons_cultist.png
#	code/modules/unit_tests/screenshots/screenshot_antag_icons_headrevolutionary.png
#	code/modules/unit_tests/screenshots/screenshot_antag_icons_provocateur.png
#	code/modules/unit_tests/screenshots/screenshot_husk_body.png
#	code/modules/unit_tests/screenshots/screenshot_husk_body_missing_limbs.png
#	icons/map_icons/clothing/head/_head.dmi
#	icons/map_icons/clothing/shoes.dmi
#	icons/map_icons/items/_item.dmi
#	icons/mob/huds/hud.dmi
#	icons/mob/inhands/64x64_lefthand.dmi
#	icons/mob/inhands/64x64_righthand.dmi
#	icons/obj/machines/computer.dmi
#	tgui/packages/tgui/interfaces/OperatingComputer.jsx
#	tgui/packages/tgui/interfaces/PreferencesMenu/CharacterPreferences/MainPage.tsx
#	tgui/packages/tgui/interfaces/PreferencesMenu/types.ts
#	tgui/packages/tgui/interfaces/SurgeryInitiator.tsx
#	tools/icon_cutter/check.py
2026-02-12 23:50:09 -05:00

228 lines
8.2 KiB
Plaintext

#define MEATSPIKE_IRONROD_REQUIREMENT 4
/obj/structure/kitchenspike_frame//SKYRAT EDIT - ICON OVERRIDDEN BY AESTHETICS - SEE MODULE
name = "meatspike frame"
icon = 'icons/obj/service/kitchen.dmi'
icon_state = "spikeframe"
desc = "The frame of a meat spike."
density = TRUE
anchored = FALSE
max_integrity = 200
custom_materials = list(/datum/material/iron = SHEET_MATERIAL_AMOUNT * 5)
/obj/structure/kitchenspike_frame/Initialize(mapload)
. = ..()
register_context()
/obj/structure/kitchenspike_frame/examine(mob/user)
. = ..()
. += "It can be <b>welded</b> apart."
. += "You could attach <b>[MEATSPIKE_IRONROD_REQUIREMENT]</b> iron rods to it to create a <b>Meat Spike</b>."
/obj/structure/kitchenspike_frame/add_context(atom/source, list/context, obj/item/held_item, mob/living/user)
if(isnull(held_item))
return NONE
var/message = ""
if(held_item.tool_behaviour == TOOL_WELDER)
message = "Deconstruct"
else if(held_item.tool_behaviour == TOOL_WRENCH)
message = "Bolt Down Frame"
if(!message)
return NONE
context[SCREENTIP_CONTEXT_LMB] = message
return CONTEXTUAL_SCREENTIP_SET
/obj/structure/kitchenspike_frame/welder_act(mob/living/user, obj/item/tool)
if(!tool.tool_start_check(user, amount = 0, heat_required = HIGH_TEMPERATURE_REQUIRED))
return FALSE
to_chat(user, span_notice("You begin cutting \the [src] apart..."))
if(!tool.use_tool(src, user, 5 SECONDS, volume = 50))
return TRUE
visible_message(span_notice("[user] slices apart \the [src]."),
span_notice("You cut \the [src] apart with \the [tool]."),
span_hear("You hear welding."))
new /obj/item/stack/sheet/iron(loc, MEATSPIKE_IRONROD_REQUIREMENT)
qdel(src)
return TRUE
/obj/structure/kitchenspike_frame/wrench_act(mob/living/user, obj/item/tool)
default_unfasten_wrench(user, tool)
return TRUE
/obj/structure/kitchenspike_frame/attackby(obj/item/attacking_item, mob/user, list/modifiers, list/attack_modifiers)
add_fingerprint(user)
if(!istype(attacking_item, /obj/item/stack/rods))
return ..()
var/obj/item/stack/rods/used_rods = attacking_item
if(used_rods.get_amount() >= MEATSPIKE_IRONROD_REQUIREMENT)
used_rods.use(MEATSPIKE_IRONROD_REQUIREMENT)
balloon_alert(user, "meatspike built")
var/obj/structure/new_meatspike = new /obj/structure/kitchenspike(loc)
transfer_fingerprints_to(new_meatspike)
qdel(src)
return
balloon_alert(user, "[MEATSPIKE_IRONROD_REQUIREMENT] rods needed!")
/obj/structure/kitchenspike_frame/examine(mob/user)
. = ..()
. += "It can be <b>welded</b> apart."
. += "You could attach <b>[MEATSPIKE_IRONROD_REQUIREMENT]</b> iron rods to it to create a <b>Meat Spike</b>."
/obj/structure/kitchenspike_frame/add_context(atom/source, list/context, obj/item/held_item, mob/living/user)
if(isnull(held_item))
return NONE
var/message = ""
if(held_item.tool_behaviour == TOOL_WELDER)
message = "Deconstruct"
else if(held_item.tool_behaviour == TOOL_WRENCH)
message = "Bolt Down Frame"
if(!message)
return NONE
context[SCREENTIP_CONTEXT_LMB] = message
return CONTEXTUAL_SCREENTIP_SET
/obj/structure/kitchenspike_frame/welder_act(mob/living/user, obj/item/tool)
if(!tool.tool_start_check(user, amount = 0))
return FALSE
to_chat(user, span_notice("You begin cutting \the [src] apart..."))
if(!tool.use_tool(src, user, 5 SECONDS, volume = 50))
return TRUE
visible_message(span_notice("[user] slices apart \the [src]."),
span_notice("You cut \the [src] apart with \the [tool]."),
span_hear("You hear welding."))
new /obj/item/stack/sheet/iron(loc, MEATSPIKE_IRONROD_REQUIREMENT)
qdel(src)
return TRUE
/obj/structure/kitchenspike_frame/wrench_act(mob/living/user, obj/item/tool)
default_unfasten_wrench(user, tool)
return TRUE
/obj/structure/kitchenspike_frame/attackby(obj/item/attacking_item, mob/user, params)
add_fingerprint(user)
if(!istype(attacking_item, /obj/item/stack/rods))
return ..()
var/obj/item/stack/rods/used_rods = attacking_item
if(used_rods.get_amount() >= MEATSPIKE_IRONROD_REQUIREMENT)
used_rods.use(MEATSPIKE_IRONROD_REQUIREMENT)
balloon_alert(user, "meatspike built")
var/obj/structure/new_meatspike = new /obj/structure/kitchenspike(loc)
transfer_fingerprints_to(new_meatspike)
qdel(src)
return
balloon_alert(user, "[MEATSPIKE_IRONROD_REQUIREMENT] rods needed!")
/obj/structure/kitchenspike//SKYRAT EDIT - ICON OVERRIDDEN BY AESTHETICS - SEE MODULE
name = "meat spike"
icon = 'icons/obj/service/kitchen.dmi'
icon_state = "spike"
desc = "A spike for collecting meat from animals."
density = TRUE
anchored = TRUE
buckle_lying = 180
buckle_dir = SOUTH
can_buckle = TRUE
max_integrity = 250
custom_materials = list(/datum/material/iron = SHEET_MATERIAL_AMOUNT * 7)
buckle_delay = 10 SECONDS
/obj/structure/kitchenspike/Initialize(mapload)
. = ..()
register_context()
ADD_TRAIT(src, TRAIT_DANGEROUS_BUCKLE, INNATE_TRAIT)
/obj/structure/kitchenspike/examine(mob/user)
. = ..()
. += "<b>Drag a mob</b> onto it to hook it in place."
. += "A <b>crowbar</b> could remove those spikes."
/obj/structure/kitchenspike/add_context(atom/source, list/context, obj/item/held_item, mob/living/user)
if(isnull(held_item))
return NONE
if(held_item.tool_behaviour == TOOL_CROWBAR)
context[SCREENTIP_CONTEXT_LMB] = "Remove Spikes"
return CONTEXTUAL_SCREENTIP_SET
return NONE
/obj/structure/kitchenspike/attack_paw(mob/user, list/modifiers)
return attack_hand(user, modifiers)
/obj/structure/kitchenspike/crowbar_act(mob/living/user, obj/item/tool)
if(has_buckled_mobs())
to_chat(user, span_warning("You can't do that while something's on the spike!"))
return TRUE
if(tool.use_tool(src, user, 2 SECONDS, volume = 100))
to_chat(user, span_notice("You pry the spikes out of the frame."))
deconstruct(TRUE)
return TRUE
return FALSE
/obj/structure/kitchenspike/user_buckle_mob(mob/living/target, mob/user, check_loc = TRUE)
if(!iscarbon(target) && !isanimal_or_basicmob(target))
return
if(target != user || target.loc == loc)
return ..()
if(!do_after(user, 10 SECONDS, target))
return
if(!is_user_buckle_possible(target, user, check_loc))
return FALSE
return ..()
/obj/structure/kitchenspike/post_buckle_mob(mob/living/target)
playsound(src.loc, 'sound/effects/splat.ogg', 25, TRUE)
target.emote("scream")
target.add_splatter_floor()
target.adjust_brute_loss(30)
target.add_offsets(type, x_add = -1)
target.set_lying_angle(buckle_lying)
ADD_TRAIT(target, TRAIT_MOVE_UPSIDE_DOWN, REF(src))
// So you can butcher people too
target.AddComponentFrom(REF(src), /datum/component/free_operation)
/obj/structure/kitchenspike/user_unbuckle_mob(mob/living/buckled_mob, mob/user)
if(buckled_mob != user)
buckled_mob.visible_message(span_notice("[user] tries to pull [buckled_mob] free of [src]!"),\
span_notice("[user] is trying to pull you off [src], opening up fresh wounds!"),\
span_hear("You hear a squishy wet noise."))
if(!do_after(user, 30 SECONDS, target = src))
if(buckled_mob?.buckled)
buckled_mob.visible_message(span_notice("[user] fails to free [buckled_mob]!"),\
span_notice("[user] fails to pull you off of [src]."))
return
else
buckled_mob.visible_message(span_warning("[buckled_mob] struggles to break free from [src]!"),\
span_notice("You struggle to break free from [src], exacerbating your wounds! (Stay still for two minutes.)"),\
span_hear("You hear a wet squishing noise.."))
buckled_mob.adjust_brute_loss(30)
if(!do_after(buckled_mob, 2 MINUTES, target = src, hidden = TRUE))
if(buckled_mob?.buckled)
to_chat(buckled_mob, span_warning("You fail to free yourself!"))
return
return ..()
/obj/structure/kitchenspike/post_unbuckle_mob(mob/living/buckled_mob)
buckled_mob.adjust_brute_loss(30)
INVOKE_ASYNC(buckled_mob, TYPE_PROC_REF(/mob, emote), "scream")
buckled_mob.AdjustParalyzed(20)
buckled_mob.remove_offsets(type)
REMOVE_TRAIT(buckled_mob, TRAIT_MOVE_UPSIDE_DOWN, REF(src))
buckled_mob.RemoveComponentSource(REF(src), /datum/component/free_operation)
/obj/structure/kitchenspike/atom_deconstruct(disassembled = TRUE)
if(disassembled)
var/obj/structure/meatspike_frame = new /obj/structure/kitchenspike_frame(src.loc)
transfer_fingerprints_to(meatspike_frame)
else
new /obj/item/stack/sheet/iron(src.loc, 4)
new /obj/item/stack/rods(loc, MEATSPIKE_IRONROD_REQUIREMENT)
#undef MEATSPIKE_IRONROD_REQUIREMENT