Merge branch 'master' of https://github.com/tgstation/tgstation into upstream-23-10-2025

This commit is contained in:
Roxy
2025-10-23 17:38:23 -04:00
453 changed files with 20635 additions and 15897 deletions
+20 -3
View File
@@ -421,16 +421,29 @@ CIGARETTE PACKETS ARE IN FANCY.DM
damtype = BURN
force = 4
if(reagents && reagents.has_reagent(/datum/reagent/drug/methamphetamine))
if(reagents?.has_reagent(/datum/reagent/flash_powder))
if(!isliving(loc))
loc.visible_message(span_hear("\The [src] burns up!"))
qdel(src)
return
var/mob/living/user = loc
loc.visible_message(span_hear("[user]'s [name] burns up as [p_they(user)] fall to the ground!"), span_danger("The solution violently explodes!"))
user.flash_act(INFINITY, visual = TRUE, length = 5 SECONDS)
user.playsound_local(get_turf(user), SFX_EXPLOSION, 50, TRUE)
user.cause_hallucination(/datum/hallucination/death, "trick trick [name]")
qdel(src)
return
if(reagents?.has_reagent(/datum/reagent/drug/methamphetamine))
reagents.flags |= NO_REACT
if(reagents.get_reagent_amount(/datum/reagent/toxin/plasma)) // the plasma explodes when exposed to fire
if(reagents?.get_reagent_amount(/datum/reagent/toxin/plasma)) // the plasma explodes when exposed to fire
var/datum/effect_system/reagents_explosion/e = new()
e.set_up(round(reagents.get_reagent_amount(/datum/reagent/toxin/plasma) / 2.5, 1), get_turf(src), 0, 0)
e.start(src)
qdel(src)
return
if(reagents.get_reagent_amount(/datum/reagent/fuel)) // the fuel explodes, too, but much less violently
if(reagents?.get_reagent_amount(/datum/reagent/fuel)) // the fuel explodes, too, but much less violently
var/datum/effect_system/reagents_explosion/e = new()
e.set_up(round(reagents.get_reagent_amount(/datum/reagent/fuel) / 5, 1), get_turf(src), 0, 0)
e.start(src)
@@ -709,6 +722,10 @@ CIGARETTE PACKETS ARE IN FANCY.DM
lung_harm = 2
list_reagents = list (/datum/reagent/drug/nicotine = 20, /datum/reagent/medicine/regen_jelly = 15, /datum/reagent/drug/krokodil = 4)
/obj/item/cigarette/flash_powder
desc = /obj/item/cigarette/space_cigarette::desc
list_reagents = list (/datum/reagent/drug/nicotine = 9, /datum/reagent/flash_powder = 5)
// Rollies.
/obj/item/cigarette/rollie
+10
View File
@@ -14,6 +14,8 @@
name = "control wand"
desc = "A remote for controlling a set of airlocks."
w_class = WEIGHT_CLASS_TINY
drop_sound = 'sound/items/door_remote/door_remote_drop1.ogg'
pickup_sound = 'sound/items/door_remote/door_remote_pick_up1.ogg'
var/department = "civilian"
var/mode = WAND_OPEN
@@ -34,6 +36,10 @@
/area/station/ai_monitored/turret_protected/ai_upload, // their doors with our several dozen access helpers
)
COOLDOWN_DECLARE(shock_cooldown)
/// sound played when mode is switched
var/mode_switch_sound = SFX_REMOTE_MODE_SWITCH
/// sound played when an action is done
var/action_sound = SFX_REMOTE_ACTION
/obj/item/door_remote/Initialize(mapload)
. = ..()
@@ -80,6 +86,8 @@
mode = WAND_OPEN
update_icon_state()
balloon_alert(user, "mode: [ops[mode]]")
if(mode_switch_sound)
playsound(src, mode_switch_sound, 50, TRUE)
/obj/item/door_remote/interact_with_atom(atom/interacting_with, mob/living/user, list/modifiers)
if(!istype(interacting_with, /obj/machinery/door) && !isturf(interacting_with))
@@ -159,6 +167,8 @@
/obj/item/door_remote/ranged_interact_with_atom(atom/interacting_with, mob/living/user, list/modifiers)
var/obj/machinery/door/door
if(action_sound)
playsound(src, action_sound, 50, TRUE)
if (istype(interacting_with, /obj/machinery/door))
door = interacting_with
+1
View File
@@ -215,6 +215,7 @@
drawtype = pick(all_drawables)
AddElement(/datum/element/venue_price, FOOD_PRICE_EXOTIC)
AddElement(/datum/element/tool_renaming)
if(can_change_colour)
AddComponent(/datum/component/palette, AVAILABLE_SPRAYCAN_SPACE, paint_color)
+1 -12
View File
@@ -6,6 +6,7 @@
inhand_icon_state = "beacon"
lefthand_file = 'icons/mob/inhands/items/devices_lefthand.dmi'
righthand_file = 'icons/mob/inhands/items/devices_righthand.dmi'
obj_flags = UNIQUE_RENAME
var/enabled = TRUE
var/renamed = FALSE
@@ -46,15 +47,3 @@
/obj/item/beacon/attack_hand_secondary(mob/user, list/modifiers)
attack_self(user)
return SECONDARY_ATTACK_CANCEL_ATTACK_CHAIN
/obj/item/beacon/attackby(obj/item/W, mob/user)
if(IS_WRITING_UTENSIL(W)) // needed for things that use custom names like the locator
var/new_name = tgui_input_text(user, "What would you like the name to be?", "Beacon", max_length = MAX_NAME_LEN)
if(!user.can_perform_action(src))
return
if(new_name)
name = new_name
renamed = TRUE
return
else
return ..()
@@ -323,15 +323,63 @@
icon_state = "lightreplacer_high"
max_uses = 50
#define BLIGHTREPLACER_SPOT_COOLDOWN (BLIGHTREPLACER_SPOT_LIFE + 1 SECONDS)
#define BLIGHTREPLACER_SPOT_RANGE 7
#define BLIGHTREPLACER_SPOT_LIFE (5 SECONDS)
/obj/item/lightreplacer/blue
name = "bluespace light replacer"
desc = "A modified light replacer that zaps lights into place. Refill with broken or working lightbulbs, or sheets of glass."
icon_state = "lightreplacer_blue"
bluespace_toggle = TRUE
actions_types = list(/datum/action/item_action/lightreplacer_scan)
action_slots = ALL
COOLDOWN_DECLARE(lightreplacer_spot_cooldown)
/obj/item/lightreplacer/blue/emag_act()
return FALSE // balancing against longrange explosions
/obj/item/lightreplacer/blue/ui_action_click(mob/user, actiontype)
if(!COOLDOWN_FINISHED(src, lightreplacer_spot_cooldown))
balloon_alert(user, "on cooldown!")
return
COOLDOWN_START(src, lightreplacer_spot_cooldown, BLIGHTREPLACER_SPOT_COOLDOWN)
lightreplacer_scan()
/// Scans the area in search of fixtures with broken bulbs in the BLIGHTREPLACER_SPOT_RANGE range, and also marks them with the blue_firefly effect.
/obj/item/lightreplacer/blue/proc/lightreplacer_scan()
var/turf/source_turf = get_turf(src)
for(var/obj/machinery/light/broken_light in dview(BLIGHTREPLACER_SPOT_RANGE, source_turf))
if(broken_light.status == LIGHT_OK)
continue
var/obj/effect/temp_visual/blue_firefly/firefly = new(get_turf(broken_light))
animate(firefly, alpha = 0, time = BLIGHTREPLACER_SPOT_LIFE, easing = CIRCULAR_EASING | EASE_IN)
/datum/action/item_action/lightreplacer_scan
name = "Scan for broken lamps"
desc = "Scans the surrounding area for fixtures with broken light bulbs and marks them."
/obj/effect/temp_visual/blue_firefly
name = "bluespace firefly"
icon = 'icons/effects/effects.dmi'
icon_state = "bluespace_firefly"
light_power = 1
light_range = 2
light_color = LIGHT_COLOR_DARK_BLUE
duration = BLIGHTREPLACER_SPOT_LIFE
/obj/effect/temp_visual/blue_firefly/Initialize(mapload)
. = ..()
update_appearance(UPDATE_OVERLAYS)
/obj/effect/temp_visual/blue_firefly/update_overlays()
. = ..()
. += emissive_appearance(icon, icon_state, src, alpha = src.alpha)
#undef BLIGHTREPLACER_SPOT_COOLDOWN
#undef BLIGHTREPLACER_SPOT_RANGE
#undef BLIGHTREPLACER_SPOT_LIFE
#undef GLASS_SHEET_USES
#undef LIGHTBULB_COST
#undef BULB_SHARDS_REQUIRED
@@ -28,24 +28,27 @@
icon_state = "intercom_prison"
icon_off = "intercom_prison-p"
/obj/item/radio/intercom/prison/Initialize(mapload, ndir, building)
/obj/item/radio/intercom/prison/Initialize(mapload)
. = ..()
wires?.cut(WIRE_TX)
/obj/item/radio/intercom/Initialize(mapload, ndir, building)
/obj/item/radio/intercom/Initialize(mapload)
. = ..()
var/area/current_area = get_area(src)
if(!current_area)
return
RegisterSignal(current_area, COMSIG_AREA_POWER_CHANGE, PROC_REF(AreaPowerCheck))
if(mapload)
find_and_hang_on_wall()
GLOB.intercoms_list += src
/obj/item/radio/intercom/find_and_hang_on_wall()
if(!unscrewed)
find_and_hang_on_wall(directional = TRUE, \
custom_drop_callback = CALLBACK(src, PROC_REF(knock_down)))
return ..()
/obj/item/radio/intercom/Destroy()
. = ..()
GLOB.intercoms_list -= src
return ..()
/obj/item/radio/intercom/examine(mob/user)
. = ..()
@@ -87,7 +90,7 @@
if(tool.use_tool(src, user, 80))
user.visible_message(span_notice("[user] unsecures [src]!"), span_notice("You detach [src] from the wall."))
playsound(src, 'sound/items/deconstruct.ogg', 50, TRUE)
knock_down()
deconstruct(TRUE)
/**
* Override attack_tk_grab instead of attack_tk because we actually want attack_tk's
@@ -187,9 +190,8 @@
/**
* Called by the wall mount component and reused during the tool deconstruction proc.
*/
/obj/item/radio/intercom/proc/knock_down()
/obj/item/radio/intercom/atom_deconstruct(disassembled)
new/obj/item/wallframe/intercom(get_turf(src))
qdel(src)
//Created through the autolathe or through deconstructing intercoms. Can be applied to wall to make a new intercom on it!
/obj/item/wallframe/intercom
@@ -209,7 +211,7 @@ MAPPING_DIRECTIONAL_HELPERS(/obj/item/radio/intercom, 27)
anonymize = TRUE
freqlock = RADIO_FREQENCY_EMAGGABLE_LOCK
/obj/item/radio/intercom/chapel/Initialize(mapload, ndir, building)
/obj/item/radio/intercom/chapel/Initialize(mapload)
. = ..()
set_frequency(1481)
set_broadcasting(TRUE)
@@ -109,8 +109,8 @@
update_appearance()
/obj/item/taperecorder/fire_act(exposed_temperature, exposed_volume)
mytape.unspool() //Fires unspool the tape, which makes sense if you don't think about it
..()
mytape?.unspool() //Fires unspool the tape, which makes sense if you don't think about it
return ..()
//ATTACK HAND IGNORING PARENT RETURN VALUE
/obj/item/taperecorder/attack_hand(mob/user, list/modifiers)
+1 -1
View File
@@ -355,7 +355,7 @@
if(4)
//Destroy Equipment
selected_turf.visible_message(span_userdanger("Everything [user] is holding and wearing disappears!"))
var/list/belongings = user.get_all_gear()
var/list/belongings = user.get_all_gear(NONE) //don't delete prosthetics or abstract items.
QDEL_LIST(belongings)
if(5)
//Monkeying
+2 -2
View File
@@ -358,7 +358,7 @@
/obj/item/extinguisher/click_alt(mob/user)
if(!user.is_holding(src))
to_chat(user, span_notice("You must be holding the [src] in your hands do this!"))
to_chat(user, span_notice("You must be holding [src] in your hands to do this!"))
return CLICK_ACTION_BLOCKING
EmptyExtinguisher(user)
return CLICK_ACTION_SUCCESS
@@ -367,7 +367,7 @@
if(loc == user && reagents.total_volume)
reagents.expose(user.loc, TOUCH)
reagents.clear_reagents()
user.visible_message(span_notice("[user] empties out \the [src] onto the floor using the release valve."), span_info("You quietly empty out \the [src] using its release valve."))
user.visible_message(span_notice("[user] empties out [src] onto the floor using the release valve."), span_info("You quietly empty out [src] using its release valve."))
//firebot assembly
/obj/item/extinguisher/attackby(obj/O, mob/user, list/modifiers, list/attack_modifiers)
+1 -1
View File
@@ -22,7 +22,7 @@
/obj/item/food/bread/make_processable()
if (slice_type)
AddElement(/datum/element/processable, TOOL_KNIFE, slice_type, yield, 3 SECONDS, table_required = TRUE, screentip_verb = "Slice")
AddElement(/datum/element/processable, TOOL_KNIFE, slice_type, yield, 3 SECONDS, table_required = TRUE, screentip_verb = "Slice", sound_to_play = SFX_KNIFE_SLICE)
AddElement(/datum/element/processable, TOOL_SAW, slice_type, yield, 4 SECONDS, table_required = TRUE, screentip_verb = "Slice")
// Abstract parent object for sliced bread items. Should not be made obtainable in game.
+1 -1
View File
@@ -21,7 +21,7 @@
/obj/item/food/cake/make_processable()
if (slice_type)
AddElement(/datum/element/processable, TOOL_KNIFE, slice_type, yield, 3 SECONDS, table_required = TRUE, screentip_verb = "Slice")
AddElement(/datum/element/processable, TOOL_KNIFE, slice_type, yield, 3 SECONDS, table_required = TRUE, screentip_verb = "Slice", sound_to_play = SFX_KNIFE_SLICE)
/obj/item/food/cakeslice
icon = 'icons/obj/food/piecake.dmi'
+2 -2
View File
@@ -59,7 +59,7 @@
AddComponent(/datum/component/food_storage)
/obj/item/food/cheese/wheel/make_processable()
AddElement(/datum/element/processable, TOOL_KNIFE, /obj/item/food/cheese/wedge, 5, 3 SECONDS, table_required = TRUE, screentip_verb = "Slice")
AddElement(/datum/element/processable, TOOL_KNIFE, /obj/item/food/cheese/wedge, 5, 3 SECONDS, table_required = TRUE, screentip_verb = "Slice", sound_to_play = SFX_KNIFE_SLICE)
/obj/item/food/cheese/wheel/make_bakeable()
AddComponent(/datum/component/bakeable, /obj/item/food/baked_cheese, rand(20 SECONDS, 25 SECONDS), TRUE, TRUE)
@@ -131,7 +131,7 @@
crafting_complexity = FOOD_COMPLEXITY_3
/obj/item/food/cheese/firm_cheese/make_processable()
AddElement(/datum/element/processable, TOOL_KNIFE, /obj/item/food/cheese/firm_cheese_slice, 3, 3 SECONDS, screentip_verb = "Slice")
AddElement(/datum/element/processable, TOOL_KNIFE, /obj/item/food/cheese/firm_cheese_slice, 3, 3 SECONDS, screentip_verb = "Slice", sound_to_play = SFX_KNIFE_SLICE)
/obj/item/food/cheese/firm_cheese_slice
name = "firm cheese slice"
+5 -5
View File
@@ -15,7 +15,7 @@
// Dough + rolling pin = flat dough
/obj/item/food/dough/make_processable()
AddElement(/datum/element/processable, TOOL_ROLLINGPIN, /obj/item/food/flatdough, 1, 3 SECONDS, table_required = TRUE, screentip_verb = "Flatten")
AddElement(/datum/element/processable, TOOL_ROLLINGPIN, /obj/item/food/flatdough, 1, 3 SECONDS, table_required = TRUE, screentip_verb = "Flatten", sound_to_play = SFX_ROLLING_PIN_ROLLING)
/obj/item/food/flatdough
name = "flat dough"
@@ -32,7 +32,7 @@
// sliceable into 3xdoughslices
/obj/item/food/flatdough/make_processable()
AddElement(/datum/element/processable, TOOL_KNIFE, /obj/item/food/doughslice, 3, 3 SECONDS, table_required = TRUE, screentip_verb = "Slice")
AddElement(/datum/element/processable, TOOL_KNIFE, /obj/item/food/doughslice, 3, 3 SECONDS, table_required = TRUE, screentip_verb = "Slice", sound_to_play = SFX_KNIFE_SLICE)
/obj/item/food/pizzabread
name = "pizza bread"
@@ -63,7 +63,7 @@
AddComponent(/datum/component/bakeable, /obj/item/food/bun, rand(20 SECONDS, 25 SECONDS), TRUE, TRUE)
/obj/item/food/doughslice/make_processable()
AddElement(/datum/element/processable, TOOL_KNIFE, /obj/item/food/bait/doughball, 5, 3 SECONDS, screentip_verb = "Slice")
AddElement(/datum/element/processable, TOOL_KNIFE, /obj/item/food/bait/doughball, 5, 3 SECONDS, screentip_verb = "Slice", sound_to_play = SFX_KNIFE_SLICE)
/obj/item/food/bun
name = "bun"
@@ -94,7 +94,7 @@
AddComponent(/datum/component/bakeable, /obj/item/food/cake/plain, rand(70 SECONDS, 90 SECONDS), TRUE, TRUE)
/obj/item/food/cakebatter/make_processable()
AddElement(/datum/element/processable, TOOL_ROLLINGPIN, /obj/item/food/piedough, 1, 3 SECONDS, table_required = TRUE, screentip_verb = "Flatten")
AddElement(/datum/element/processable, TOOL_ROLLINGPIN, /obj/item/food/piedough, 1, 3 SECONDS, table_required = TRUE, screentip_verb = "Flatten", sound_to_play = SFX_ROLLING_PIN_ROLLING)
/obj/item/food/piedough
name = "pie dough"
@@ -110,7 +110,7 @@
AddComponent(/datum/component/bakeable, /obj/item/food/pie/plain, rand(30 SECONDS, 45 SECONDS), TRUE, TRUE)
/obj/item/food/piedough/make_processable()
AddElement(/datum/element/processable, TOOL_KNIFE, /obj/item/food/rawpastrybase, 6, 3 SECONDS, table_required = TRUE, screentip_verb = "Slice")
AddElement(/datum/element/processable, TOOL_KNIFE, /obj/item/food/rawpastrybase, 6, 3 SECONDS, table_required = TRUE, screentip_verb = "Slice", sound_to_play = SFX_KNIFE_SLICE)
/obj/item/food/rawpastrybase
name = "raw pastry base"
+4 -4
View File
@@ -73,7 +73,7 @@
custom_materials = list(/datum/material/meat = MEATSLAB_MATERIAL_AMOUNT)
/obj/item/food/headcheese/make_processable()
AddElement(/datum/element/processable, TOOL_KNIFE, /obj/item/food/headcheese_slice, 5, 3 SECONDS, table_required = TRUE, screentip_verb = "Slice")
AddElement(/datum/element/processable, TOOL_KNIFE, /obj/item/food/headcheese_slice, 5, 3 SECONDS, table_required = TRUE, screentip_verb = "Slice", sound_to_play = SFX_KNIFE_SLICE)
/obj/item/food/headcheese_slice
name = "headcheese slice"
@@ -451,7 +451,7 @@
AddComponent(/datum/component/bakeable, bread_type, rand(15 SECONDS, 25 SECONDS), TRUE, TRUE)
/obj/item/food/rootdough/make_processable()
AddElement(/datum/element/processable, TOOL_ROLLINGPIN, flat_type, 1, 3 SECONDS, table_required = TRUE, screentip_verb = "Flatten")
AddElement(/datum/element/processable, TOOL_ROLLINGPIN, flat_type, 1, 3 SECONDS, table_required = TRUE, screentip_verb = "Flatten", sound_to_play = SFX_ROLLING_PIN_ROLLING)
/obj/item/food/rootdough/egg
desc = "A root based dough, made with nuts, tubers and eggs. Used in a wide range of Tiziran cooking."
@@ -472,7 +472,7 @@
var/grill_type = /obj/item/food/root_flatbread
/obj/item/food/flatrootdough/make_processable()
AddElement(/datum/element/processable, TOOL_KNIFE, process_type, 3, 3 SECONDS, table_required = TRUE, screentip_verb = "Slice")
AddElement(/datum/element/processable, TOOL_KNIFE, process_type, 3, 3 SECONDS, table_required = TRUE, screentip_verb = "Slice", sound_to_play = SFX_KNIFE_SLICE)
/obj/item/food/flatrootdough/make_grillable()
AddComponent(/datum/component/grillable, grill_type, rand(15 SECONDS, 25 SECONDS), TRUE, TRUE)
@@ -499,7 +499,7 @@
foodtypes = parent_type::foodtypes | MEAT
/obj/item/food/rootdoughslice/make_processable()
AddElement(/datum/element/processable, TOOL_KNIFE, /obj/item/food/spaghetti/nizaya, 1, 3 SECONDS, table_required = TRUE, screentip_verb = "Slice")
AddElement(/datum/element/processable, TOOL_KNIFE, /obj/item/food/spaghetti/nizaya, 1, 3 SECONDS, table_required = TRUE, screentip_verb = "Slice", sound_to_play = SFX_KNIFE_SLICE)
/obj/item/food/rootdoughslice/make_bakeable()
AddComponent(/datum/component/bakeable, /obj/item/food/rootroll, rand(15 SECONDS, 25 SECONDS), TRUE, TRUE)
+4 -4
View File
@@ -359,7 +359,7 @@
// sliceable into 4xtempehslices
/obj/item/food/tempeh/make_processable()
AddElement(/datum/element/processable, TOOL_KNIFE, /obj/item/food/tempehslice, 4, 5 SECONDS, table_required = TRUE, screentip_verb = "Slice")
AddElement(/datum/element/processable, TOOL_KNIFE, /obj/item/food/tempehslice, 4, 5 SECONDS, table_required = TRUE, screentip_verb = "Slice", sound_to_play = SFX_KNIFE_SLICE)
//add an icon for slices
/obj/item/food/tempehslice
@@ -466,7 +466,7 @@
AddComponent(/datum/component/grillable, meatball_type, rand(30 SECONDS, 40 SECONDS), TRUE)
/obj/item/food/raw_meatball/make_processable()
AddElement(/datum/element/processable, TOOL_ROLLINGPIN, patty_type, 1, table_required = TRUE, screentip_verb = "Flatten")
AddElement(/datum/element/processable, TOOL_ROLLINGPIN, patty_type, 1, table_required = TRUE, screentip_verb = "Flatten", sound_to_play = SFX_ROLLING_PIN_ROLLING)
/obj/item/food/raw_meatball/human
name = "strange raw meatball"
@@ -638,8 +638,8 @@
custom_materials = list(/datum/material/meat = MEATSLAB_MATERIAL_AMOUNT)
/obj/item/food/sausage/make_processable()
AddElement(/datum/element/processable, TOOL_KNIFE, /obj/item/food/salami, 6, 3 SECONDS, table_required = TRUE, screentip_verb = "Slice")
AddElement(/datum/element/processable, TOOL_KNIFE, /obj/item/food/sausage/american, 1, 3 SECONDS, table_required = TRUE, screentip_verb = "Slice")
AddElement(/datum/element/processable, TOOL_KNIFE, /obj/item/food/salami, 6, 3 SECONDS, table_required = TRUE, screentip_verb = "Slice", sound_to_play = SFX_KNIFE_SLICE)
AddElement(/datum/element/processable, TOOL_KNIFE, /obj/item/food/sausage/american, 1, 3 SECONDS, table_required = TRUE, screentip_verb = "Slice", sound_to_play = SFX_KNIFE_SLICE)
/obj/item/food/sausage/american
name = "american sausage"
+9 -9
View File
@@ -52,7 +52,7 @@
AddComponent(/datum/component/grillable, /obj/item/food/meat/steak/plain, rand(30 SECONDS, 90 SECONDS), TRUE, TRUE) //Add medium rare later maybe?
/obj/item/food/meat/slab/make_processable()
AddElement(/datum/element/processable, TOOL_KNIFE, /obj/item/food/meat/rawcutlet/plain, MEATSLAB_PROCESSED_AMOUNT, 3 SECONDS, table_required = TRUE, screentip_verb = "Cut")
AddElement(/datum/element/processable, TOOL_KNIFE, /obj/item/food/meat/rawcutlet/plain, MEATSLAB_PROCESSED_AMOUNT, 3 SECONDS, table_required = TRUE, screentip_verb = "Cut", sound_to_play = SFX_KNIFE_SLICE)
///////////////////////////////////// HUMAN MEATS //////////////////////////////////////////////////////
@@ -66,7 +66,7 @@
AddComponent(/datum/component/grillable, /obj/item/food/meat/steak/plain/human, rand(30 SECONDS, 90 SECONDS), TRUE, TRUE) //Add medium rare later maybe?
/obj/item/food/meat/slab/human/make_processable()
AddElement(/datum/element/processable, TOOL_KNIFE, /obj/item/food/meat/rawcutlet/plain/human, 3, 3 SECONDS, table_required = TRUE, screentip_verb = "Cut")
AddElement(/datum/element/processable, TOOL_KNIFE, /obj/item/food/meat/rawcutlet/plain/human, 3, 3 SECONDS, table_required = TRUE, screentip_verb = "Cut", sound_to_play = SFX_KNIFE_SLICE)
/obj/item/food/meat/slab/human/mutant
abstract_type = /obj/item/food/meat/slab/human/mutant
@@ -262,7 +262,7 @@
AddComponent(/datum/component/grillable, /obj/item/food/meat/steak/killertomato, rand(70 SECONDS, 85 SECONDS), TRUE, TRUE)
/obj/item/food/meat/slab/killertomato/make_processable()
AddElement(/datum/element/processable, TOOL_KNIFE, /obj/item/food/meat/rawcutlet/killertomato, 3, 3 SECONDS, table_required = TRUE, screentip_verb = "Cut")
AddElement(/datum/element/processable, TOOL_KNIFE, /obj/item/food/meat/rawcutlet/killertomato, 3, 3 SECONDS, table_required = TRUE, screentip_verb = "Cut", sound_to_play = SFX_KNIFE_SLICE)
/obj/item/food/meat/slab/bear
name = "bear meat"
@@ -278,7 +278,7 @@
foodtypes = RAW | MEAT
/obj/item/food/meat/slab/bear/make_processable()
AddElement(/datum/element/processable, TOOL_KNIFE, /obj/item/food/meat/rawcutlet/bear, 3, 3 SECONDS, table_required = TRUE, screentip_verb = "Cut")
AddElement(/datum/element/processable, TOOL_KNIFE, /obj/item/food/meat/rawcutlet/bear, 3, 3 SECONDS, table_required = TRUE, screentip_verb = "Cut", sound_to_play = SFX_KNIFE_SLICE)
/obj/item/food/meat/slab/bear/make_grillable()
AddComponent(/datum/component/grillable, /obj/item/food/meat/steak/bear, rand(40 SECONDS, 70 SECONDS), TRUE, TRUE)
@@ -301,7 +301,7 @@
blood_decal_type = /obj/effect/decal/cleanable/blood/xeno
/obj/item/food/meat/slab/xeno/make_processable()
AddElement(/datum/element/processable, TOOL_KNIFE, /obj/item/food/meat/rawcutlet/xeno, 3, 3 SECONDS, table_required = TRUE, screentip_verb = "Cut")
AddElement(/datum/element/processable, TOOL_KNIFE, /obj/item/food/meat/rawcutlet/xeno, 3, 3 SECONDS, table_required = TRUE, screentip_verb = "Cut", sound_to_play = SFX_KNIFE_SLICE)
/obj/item/food/meat/slab/xeno/make_grillable()
AddComponent(/datum/component/grillable, /obj/item/food/meat/steak/xeno, rand(40 SECONDS, 70 SECONDS), TRUE, TRUE)
@@ -320,7 +320,7 @@
blood_decal_type = /obj/effect/decal/cleanable/insectguts
/obj/item/food/meat/slab/spider/make_processable()
AddElement(/datum/element/processable, TOOL_KNIFE, /obj/item/food/meat/rawcutlet/spider, 3, 3 SECONDS, table_required = TRUE, screentip_verb = "Cut")
AddElement(/datum/element/processable, TOOL_KNIFE, /obj/item/food/meat/rawcutlet/spider, 3, 3 SECONDS, table_required = TRUE, screentip_verb = "Cut", sound_to_play = SFX_KNIFE_SLICE)
/obj/item/food/meat/slab/spider/make_grillable()
AddComponent(/datum/component/grillable, /obj/item/food/meat/steak/spider, rand(40 SECONDS, 70 SECONDS), TRUE, TRUE)
@@ -403,7 +403,7 @@
foodtypes = RAW | MEAT | GORE
/obj/item/food/meat/slab/gondola/make_processable()
AddElement(/datum/element/processable, TOOL_KNIFE, /obj/item/food/meat/rawcutlet/gondola, 3, 3 SECONDS, table_required = TRUE, screentip_verb = "Cut")
AddElement(/datum/element/processable, TOOL_KNIFE, /obj/item/food/meat/rawcutlet/gondola, 3, 3 SECONDS, table_required = TRUE, screentip_verb = "Cut", sound_to_play = SFX_KNIFE_SLICE)
/obj/item/food/meat/slab/gondola/make_grillable()
AddComponent(/datum/component/grillable, /obj/item/food/meat/steak/gondola, rand(30 SECONDS, 90 SECONDS), TRUE, TRUE) //Add medium rare later maybe?
@@ -420,7 +420,7 @@
/obj/item/food/meat/slab/penguin/make_processable()
. = ..()
AddElement(/datum/element/processable, TOOL_KNIFE, /obj/item/food/meat/rawcutlet/penguin, 3, 3 SECONDS, table_required = TRUE, screentip_verb = "Cut")
AddElement(/datum/element/processable, TOOL_KNIFE, /obj/item/food/meat/rawcutlet/penguin, 3, 3 SECONDS, table_required = TRUE, screentip_verb = "Cut", sound_to_play = SFX_KNIFE_SLICE)
/obj/item/food/meat/slab/penguin/make_grillable()
AddComponent(/datum/component/grillable, /obj/item/food/meat/steak/penguin, rand(30 SECONDS, 90 SECONDS), TRUE, TRUE) //Add medium rare later maybe?
@@ -463,7 +463,7 @@
starting_reagent_purity = 1
/obj/item/food/meat/slab/chicken/make_processable()
AddElement(/datum/element/processable, TOOL_KNIFE, /obj/item/food/meat/rawcutlet/chicken, 3, 3 SECONDS, table_required = TRUE, screentip_verb = "Cut")
AddElement(/datum/element/processable, TOOL_KNIFE, /obj/item/food/meat/rawcutlet/chicken, 3, 3 SECONDS, table_required = TRUE, screentip_verb = "Cut", sound_to_play = SFX_KNIFE_SLICE)
/obj/item/food/meat/slab/chicken/make_grillable()
AddComponent(/datum/component/grillable, /obj/item/food/meat/steak/chicken, rand(30 SECONDS, 90 SECONDS), TRUE, TRUE) //Add medium rare later maybe? (no this is chicken)
+1 -1
View File
@@ -405,7 +405,7 @@
can_stick = FALSE
/obj/item/food/butter/make_processable()
AddElement(/datum/element/processable, TOOL_KNIFE, /obj/item/food/butterslice, 3, 3 SECONDS, table_required = TRUE, screentip_verb = "Slice")
AddElement(/datum/element/processable, TOOL_KNIFE, /obj/item/food/butterslice, 3, 3 SECONDS, table_required = TRUE, screentip_verb = "Slice", sound_to_play = SFX_KNIFE_SLICE)
/obj/item/food/butterslice
name = "butter slice"
+1 -1
View File
@@ -194,7 +194,7 @@
crafting_complexity = FOOD_COMPLEXITY_5
/obj/item/food/green_lasagne/make_processable()
AddElement(/datum/element/processable, TOOL_KNIFE, /obj/item/food/green_lasagne_slice, 6, 3 SECONDS, table_required = TRUE, screentip_verb = "Slice")
AddElement(/datum/element/processable, TOOL_KNIFE, /obj/item/food/green_lasagne_slice, 6, 3 SECONDS, table_required = TRUE, screentip_verb = "Slice", sound_to_play = SFX_KNIFE_SLICE)
/obj/item/food/green_lasagne_slice
name = "green lasagne al forno slice"
+2 -2
View File
@@ -470,7 +470,7 @@
crafting_complexity = FOOD_COMPLEXITY_2
/obj/item/food/brownie_sheet/make_processable()
AddElement(/datum/element/processable, TOOL_KNIFE, /obj/item/food/brownie, 4, 3 SECONDS, table_required = TRUE, screentip_verb = "Slice")
AddElement(/datum/element/processable, TOOL_KNIFE, /obj/item/food/brownie, 4, 3 SECONDS, table_required = TRUE, screentip_verb = "Slice", sound_to_play = SFX_KNIFE_SLICE)
/obj/item/food/brownie
name = "brownie"
@@ -519,7 +519,7 @@
crafting_complexity = FOOD_COMPLEXITY_3
/obj/item/food/peanut_butter_brownie_sheet/make_processable()
AddElement(/datum/element/processable, TOOL_KNIFE, /obj/item/food/peanut_butter_brownie, 4, 3 SECONDS, table_required = TRUE, screentip_verb = "Slice")
AddElement(/datum/element/processable, TOOL_KNIFE, /obj/item/food/peanut_butter_brownie, 4, 3 SECONDS, table_required = TRUE, screentip_verb = "Slice", sound_to_play = SFX_KNIFE_SLICE)
/obj/item/food/peanut_butter_brownie
name = "peanut butter brownie"
+1 -1
View File
@@ -16,7 +16,7 @@
/obj/item/food/pie/make_processable()
if (slice_type)
AddElement(/datum/element/processable, TOOL_KNIFE, slice_type, yield, table_required = TRUE, screentip_verb = "Slice")
AddElement(/datum/element/processable, TOOL_KNIFE, slice_type, yield, table_required = TRUE, screentip_verb = "Slice", sound_to_play = SFX_KNIFE_SLICE)
/obj/item/food/pieslice
name = "pie slice"
+1 -1
View File
@@ -134,7 +134,7 @@
crafting_complexity = FOOD_COMPLEXITY_2
/obj/item/food/pizzaslice/make_processable()
AddElement(/datum/element/processable, TOOL_ROLLINGPIN, /obj/item/stack/sheet/pizza, 1, 1 SECONDS, table_required = TRUE, screentip_verb = "Flatten")
AddElement(/datum/element/processable, TOOL_ROLLINGPIN, /obj/item/stack/sheet/pizza, 1, 1 SECONDS, table_required = TRUE, screentip_verb = "Flatten", sound_to_play = SFX_ROLLING_PIN_ROLLING)
/obj/item/food/pizza/margherita
name = "pizza margherita"
@@ -13,6 +13,7 @@
throw_range = 5
w_class = WEIGHT_CLASS_TINY
custom_materials = list(/datum/material/glass= SMALL_MATERIAL_AMOUNT * 5)
obj_flags = UNIQUE_RENAME | RENAME_NO_DESC
///the implant within the case
var/obj/item/implant/imp = null
///Type of implant this will spawn as imp upon being spawned
@@ -36,18 +37,7 @@
return ..()
/obj/item/implantcase/attackby(obj/item/used_item, mob/living/user, list/modifiers, list/attack_modifiers)
if(IS_WRITING_UTENSIL(used_item))
if(!user.can_write(used_item))
return
var/new_name = tgui_input_text(user, "What would you like the label to be?", name, max_length = MAX_NAME_LEN)
if((user.get_active_held_item() != used_item) || !user.can_perform_action(src))
return
if(new_name)
playsound(src, SFX_WRITING_PEN, 50, TRUE, SHORT_RANGE_SOUND_EXTRARANGE, SOUND_FALLOFF_EXPONENT + 3, ignore_walls = FALSE)
name = "implant case - '[new_name]'"
else
name = "implant case"
else if(istype(used_item, /obj/item/implanter))
if(istype(used_item, /obj/item/implanter))
var/obj/item/implanter/used_implanter = used_item
if(used_implanter.imp && !imp)
//implanter to case implant transfer
@@ -68,6 +58,8 @@
else
return ..()
/obj/item/implantcase/nameformat(input, user)
return "implant case[input? " - '[input]'" : null]"
///An implant case that spawns with a tracking implant, as well as an appropriate name and description.
/obj/item/implantcase/tracking
+4 -16
View File
@@ -12,6 +12,7 @@
throw_speed = 3
throw_range = 5
w_class = WEIGHT_CLASS_SMALL
obj_flags = UNIQUE_RENAME | RENAME_NO_DESC
custom_materials = list(/datum/material/iron=SMALL_MATERIAL_AMOUNT * 6, /datum/material/glass=SMALL_MATERIAL_AMOUNT *2)
///The implant in our implanter
var/obj/item/implant/imp = null
@@ -44,24 +45,11 @@
else
to_chat(user, span_warning("[src] fails to implant [target]."))
/obj/item/implanter/attackby(obj/item/I, mob/living/user, list/modifiers, list/attack_modifiers)
if(IS_WRITING_UTENSIL(I))
return ..()
if(!user.can_write(I))
return
var/new_name = tgui_input_text(user, "What would you like the label to be?", name, max_length = MAX_NAME_LEN)
if(user.get_active_held_item() != I)
return
if(!user.can_perform_action(src))
return
if(new_name)
name = "implanter ([new_name])"
else
name = "implanter"
/obj/item/implanter/Initialize(mapload)
. = ..()
if(!imp && imp_type)
imp = new imp_type(src)
update_appearance()
/obj/item/implanter/nameformat(input, user)
return "implanter[input? " ([input])" : null]"
@@ -12,6 +12,8 @@
throw_speed = 2
throw_range = 4
item_flags = NO_PIXEL_RANDOM_DROP
drop_sound = SFX_POTTED_PLANT_DROP
pickup_sound = SFX_POTTED_PLANT_PICKUP
/// Can this plant be trimmed by someone with TRAIT_BONSAI
var/trimmable = TRUE
+15
View File
@@ -38,6 +38,9 @@
sharpness = SHARP_POINTY
var/datum/reagent/forkload //used to eat omelette
custom_price = PAYCHECK_LOWER
sound_vary = TRUE
pickup_sound = SFX_CUTLERY_PICKUP
drop_sound = SFX_CUTLERY_DROP
/datum/armor/kitchen_fork
fire = 50
@@ -77,6 +80,8 @@
throwforce = 0
custom_materials = list(/datum/material/plastic = SMALL_MATERIAL_AMOUNT * 0.8)
custom_price = PAYCHECK_LOWER * 1
pickup_sound = null
drop_sound = null
/obj/item/kitchen/fork/plastic/Initialize(mapload)
. = ..()
@@ -100,6 +105,8 @@
attack_verb_simple = list("prod", "whiff", "scratch", "poke")
sharpness = SHARP_EDGED
custom_price = PAYCHECK_LOWER * 2
pickup_sound = null
drop_sound = null
/obj/item/knife/plastic/Initialize(mapload)
. = ..()
@@ -167,6 +174,9 @@
attack_verb_simple = list("bash", "batter", "bludgeon", "thrash", "whack")
custom_price = PAYCHECK_CREW * 1.5
tool_behaviour = TOOL_ROLLINGPIN
sound_vary = TRUE
pickup_sound = SFX_ROLLING_PIN_PICKUP
drop_sound = SFX_ROLLING_PIN_DROP
/obj/item/kitchen/rollingpin/illegal
name = "metal rolling pin"
@@ -202,6 +212,9 @@
custom_price = PAYCHECK_LOWER * 2
tool_behaviour = TOOL_MINING
toolspeed = 25 // Literally 25 times worse than the base pickaxe
sound_vary = TRUE
pickup_sound = SFX_CUTLERY_PICKUP
drop_sound = SFX_CUTLERY_DROP
var/spoon_sip_size = 5
@@ -316,6 +329,8 @@
custom_materials = list(/datum/material/plastic = SMALL_MATERIAL_AMOUNT * 1.2)
toolspeed = 75 // The plastic spoon takes 5 minutes to dig through a single mineral turf... It's one, continuous, breakable, do_after...
custom_price = PAYCHECK_LOWER * 1
pickup_sound = null
drop_sound = null
/datum/armor/kitchen_spoon
fire = 50
+4
View File
@@ -27,6 +27,10 @@
tool_behaviour = TOOL_KNIFE
var/list/alt_continuous = list("stabs", "pierces", "shanks")
var/list/alt_simple = list("stab", "pierce", "shank")
sound_vary = TRUE
operating_sound = SFX_KNIFE_SLICE
pickup_sound = SFX_KNIFE_PICKUP
drop_sound = SFX_KNIFE_DROP
/datum/armor/item_knife
fire = 50
+1 -1
View File
@@ -327,7 +327,7 @@
desc = "In lieu of fuel, performative spirit can be used to light cigarettes."
icon_state = "mlighter" //These ones don't show a flame.
light_color = LIGHT_COLOR_HALOGEN
heat_while_on = 0 //I swear it's a real lighter dude you just can't see the flame dude I promise
heat_while_on = TCMB //I swear it's a real lighter dude you just can't see the flame dude I promise
overlay_state = "mime"
grind_results = list(/datum/reagent/iron = 1, /datum/reagent/toxin/mutetoxin = 5, /datum/reagent/consumable/nothing = 10)
light_range = 0
+8 -59
View File
@@ -30,7 +30,7 @@
/// How much stamina damage we deal on a successful hit against a living, non-cyborg mob.
var/stamina_damage = 55
/// How much armor does our baton ignore? This operates as armour penetration, but only applies to the stun attack.
var/stun_armour_penetration = 15
var/stun_armour_penetration = 15 // pens very light / cosmetic armor
/// What armor does our stun attack check before delivering the attack?
var/armour_type_against_stun = MELEE
/// Chance of causing force_say() when stunning a human mob
@@ -96,7 +96,7 @@
readout += "\nThe effects of each strike can be mitigated by utilizing [span_warning("[armour_type_against_stun]")] armor."
readout += "\nIt has a stun armor-piercing capability of [span_warning("[get_stun_penetration_value()]%")]."
readout += "\nIt has a stun armor-piercing capability of [span_warning("[stun_armour_penetration]%")]."
return readout.Join("\n")
/// Checks if we can actually USE the baton. Impure
@@ -229,8 +229,7 @@
var/mob/living/carbon/human/human_target = target
if(prob(force_say_chance))
human_target.force_say()
var/effective_armour_penetration = get_stun_penetration_value()
var/armour_block = target.run_armor_check(null, armour_type_against_stun, null, null, effective_armour_penetration)
var/armour_block = target.run_armor_check(null, armour_type_against_stun, null, null, stun_armour_penetration)
target.apply_damage(stamina_damage, STAMINA, blocked = armour_block)
if(!trait_check)
target.Knockdown((isnull(stun_override) ? knockdown_time : stun_override))
@@ -304,10 +303,6 @@
log_combat(user, user, "accidentally stun attacked [user.p_them()]self due to their clumsiness", src)
user.do_attack_animation(user)
/// Handles the penetration value of our baton, called during baton_effect()
/obj/item/melee/baton/proc/get_stun_penetration_value()
return stun_armour_penetration
/obj/item/conversion_kit
name = "conversion kit"
desc = "A strange box containing wood working tools and an instruction paper to turn stun batons into something else."
@@ -410,19 +405,18 @@
name = "bronze-capped telescopic baton"
desc = "A compact yet robust personal defense weapon. Can be concealed when folded. This one is ranked BRONZE, and thus has mediocre penetrative power."
icon_state = "telebaton_bronze"
stun_armour_penetration = 20
/obj/item/melee/baton/telescopic/silver
name = "silver-capped telescopic baton"
desc = "A compact yet robust personal defense weapon. Can be concealed when folded. This one is ranked SILVER, and thus has decent penetrative power."
icon_state = "telebaton_silver"
stun_armour_penetration = 40
stun_armour_penetration = 30 // strong enough to pen sec armor
/obj/item/melee/baton/telescopic/gold
name = "gold-capped telescopic baton"
desc = "A compact yet robust personal defense weapon. Can be concealed when folded. This one is ranked GOLD, and thus has exceptional penetrative power."
icon_state = "telebaton_gold"
stun_armour_penetration = 60
stun_armour_penetration = 50 // strong enough to pen syndicate modsuits
/obj/item/melee/baton/telescopic/contractor_baton
name = "contractor baton"
@@ -440,7 +434,7 @@
cooldown = 2.5 SECONDS
force_say_chance = 80 //very high force say chance because it's funny
stamina_damage = 85
stun_armour_penetration = 40
stun_armour_penetration = 30 // strong enough to pen sec armor
clumsy_knockdown_time = 24 SECONDS
affect_cyborg = TRUE
wait_desc = "still charging!"
@@ -476,8 +470,6 @@
force_say_chance = 50
stamina_damage = 60
armour_type_against_stun = ENERGY
// This value is added to our stun armour penetration when called by get_stun_penetration_value(). For giving some batons extra OOMPH.
var/additional_stun_armour_penetration = 0
knockdown_time = 5 SECONDS
clumsy_knockdown_time = 15 SECONDS
cooldown = 2.5 SECONDS
@@ -509,8 +501,6 @@
var/convertible = TRUE //if it can be converted with a conversion kit
///Whether or not our inhand changes when active.
var/active_changes_inhand = TRUE
///Whether or not our baton visibly changes the inhand sprite based on inserted cell
var/tip_changes_color = TRUE
///When set, inhand_icon_state defaults to this instead of base_icon_state
var/base_inhand_state = null
@@ -581,10 +571,7 @@
if(active)
icon_state = "[base_icon_state]_active"
if(active_changes_inhand)
if(tip_changes_color)
inhand_icon_state = "[base_inhand]_active_[get_baton_tip_color()]"
else
inhand_icon_state = "[base_inhand]_active"
inhand_icon_state = "[base_inhand]_active"
return ..()
if(!cell)
icon_state = "[base_icon_state]_nocell"
@@ -646,35 +633,7 @@
/// Toggles the stun baton's light
/obj/item/melee/baton/security/proc/toggle_light()
set_light_color(get_baton_tip_color(TRUE))
set_light_on(!light_on)
return
/// Change our baton's top color based on the contained cell.
/obj/item/melee/baton/security/proc/get_baton_tip_color(set_light = FALSE)
var/tip_type_to_set
var/tip_light_to_set
if(cell)
var/chargepower = cell.maxcharge
var/zap_value = clamp(chargepower/STANDARD_CELL_CHARGE, 0, 100)
switch(zap_value)
if(-INFINITY to 10)
tip_type_to_set = "orange"
tip_light_to_set = LIGHT_COLOR_ORANGE
if(11 to 20)
tip_type_to_set = "red"
tip_light_to_set = LIGHT_COLOR_INTENSE_RED
if(21 to 30)
tip_type_to_set = "green"
tip_light_to_set = LIGHT_COLOR_GREEN
if(31 to INFINITY)
tip_type_to_set = "blue"
tip_light_to_set = LIGHT_COLOR_BLUE
else
tip_type_to_set = "orange"
return set_light ? tip_light_to_set : tip_type_to_set
/obj/item/melee/baton/security/proc/turn_on(mob/user)
active = TRUE
@@ -734,13 +693,6 @@
stun_override = 0 //Avoids knocking people down prematurely.
return ..()
/obj/item/melee/baton/security/get_stun_penetration_value()
if(cell)
var/chargepower = cell.maxcharge
var/zap_pen = clamp(chargepower/STANDARD_CELL_CHARGE, 0, 100)
return zap_pen + additional_stun_armour_penetration
return stun_armour_penetration + additional_stun_armour_penetration
/*
* After a target is hit, we apply some status effects.
* After a period of time, we then check to see what stun duration we give.
@@ -831,7 +783,6 @@
stun_armour_penetration = 40
throw_stun_chance = 60
convertible = FALSE
tip_changes_color = FALSE
obj_flags = UNIQUE_RENAME
unique_reskin = list(
@@ -866,7 +817,6 @@
slot_flags = ITEM_SLOT_BACK
convertible = FALSE
active_changes_inhand = FALSE
tip_changes_color = FALSE
var/obj/item/assembly/igniter/sparkler
///Determines whether or not we can improve the cattleprod into a new type. Prevents turning the cattleprod subtypes into different subtypes, or wasting materials on making it....another version of itself.
var/can_upgrade = TRUE
@@ -932,7 +882,6 @@
throw_stun_chance = 99 //Have you prayed today?
convertible = FALSE
active_changes_inhand = FALSE
tip_changes_color = FALSE
custom_materials = list(/datum/material/iron = SHEET_MATERIAL_AMOUNT * 5, /datum/material/glass = SHEET_MATERIAL_AMOUNT*2, /datum/material/silver = SHEET_MATERIAL_AMOUNT*5, /datum/material/gold = SHEET_MATERIAL_AMOUNT)
/obj/item/melee/baton/security/boomerang/Initialize(mapload)
@@ -1013,7 +962,7 @@
knockdown_time = 0.25 SECONDS
demolition_mod = 1.5
stamina_damage = 30 // 4 hit stamcrit
stun_armour_penetration = 30 // bronze-silver telescopic
stun_armour_penetration = 25 // bronze-silver telescopic
force = 16 // 7 hit crit
exposed_wound_bonus = 5
+12 -15
View File
@@ -5,6 +5,7 @@
name = "blank picket sign"
desc = "It's blank."
force = 5
obj_flags = UNIQUE_RENAME | RENAME_NO_DESC
w_class = WEIGHT_CLASS_BULKY
attack_verb_continuous = list("bashes", "smacks")
attack_verb_simple = list("bash", "smack")
@@ -20,21 +21,14 @@
resistance_flags = NONE
actions_types = list(/datum/action/item_action/nano_picket_sign)
/obj/item/picket_sign/proc/retext(mob/user, obj/item/writing_instrument)
if(!user.can_write(writing_instrument))
return
var/txt = tgui_input_text(user, "What would you like to write on the sign?", "Sign Label", max_length = 30)
if(txt && user.can_perform_action(src))
playsound(src, SFX_WRITING_PEN, 50, TRUE, SHORT_RANGE_SOUND_EXTRARANGE, SOUND_FALLOFF_EXPONENT + 3, ignore_walls = FALSE)
label = txt
name = "[label] sign"
desc = "It reads: [label]"
/obj/item/picket_sign/nameformat(input, user)
playsound(src, SFX_WRITING_PEN, 50, TRUE, SHORT_RANGE_SOUND_EXTRARANGE, SOUND_FALLOFF_EXPONENT + 3, ignore_walls = FALSE)
label = input
AddComponent(/datum/component/rename, name, "It reads: [input]")
return "[input] sign"
/obj/item/picket_sign/attackby(obj/item/W, mob/user, list/modifiers, list/attack_modifiers)
if(IS_WRITING_UTENSIL(W))
retext(user, W)
else
return ..()
/obj/item/picket_sign/rename_reset()
label = initial(label)
/obj/item/picket_sign/attack_self(mob/living/carbon/human/user)
if(!COOLDOWN_FINISHED(src, picket_sign_cooldown))
@@ -66,7 +60,10 @@
if(!istype(target, /obj/item/picket_sign))
return FALSE
var/obj/item/picket_sign/sign = target
sign.retext(owner)
var/input = tgui_input_text(owner, "What would you like to write on the sign?", "Sign Label", max_length = 30)
if(input && owner.can_perform_action(sign))
sign.label = input
sign.AddComponent(/datum/component/rename, "[input] sign", "It reads: [input]")
return TRUE
/datum/crafting_recipe/picket_sign
+1
View File
@@ -42,6 +42,7 @@ GLOBAL_LIST_INIT(rod_recipes, list ( \
pickup_sound = 'sound/items/handling/materials/iron_rod_pick_up.ogg'
drop_sound = 'sound/items/handling/materials/metal_drop.ogg'
sound_vary = TRUE
usable_for_construction = TRUE
/datum/embedding/rods
embed_chance = 50
@@ -605,7 +605,8 @@ GLOBAL_LIST_INIT(durathread_recipes, list ( \
. = ..()
. += GLOB.durathread_recipes
/obj/item/stack/sheet/durathread/on_item_crafted(mob/builder, atom/created)
/obj/item/stack/sheet/durathread/used_in_craft(atom/created, datum/crafting_recipe/recipe)
. = ..()
created.set_armor_rating(CONSUME, max(50, created.get_armor_rating(CONSUME)))
/obj/item/stack/sheet/cotton
+7 -11
View File
@@ -455,24 +455,24 @@
var/turf/covered_turf = builder.drop_location()
if(!isturf(covered_turf))
return
var/turf/created_turf = covered_turf.place_on_top(recipe.result_type, flags = CHANGETURF_INHERIT_AIR)
created = covered_turf.place_on_top(recipe.result_type, flags = CHANGETURF_INHERIT_AIR)
builder.balloon_alert(builder, "placed [ispath(recipe.result_type, /turf/open) ? "floor" : "wall"]")
if((recipe.crafting_flags & CRAFT_APPLIES_MATS) && LAZYLEN(mats_per_unit))
created_turf.set_custom_materials(mats_per_unit, recipe.req_amount / recipe.res_amount)
created.set_custom_materials(mats_per_unit, recipe.req_amount / recipe.res_amount)
else
created = new recipe.result_type(builder.drop_location())
builder.balloon_alert(builder, "built item")
if(created)
// split the material and use it for the craft
var/obj/item/stack/used_stack = split_stack(recipe.req_amount * multiplier)
if(ismovable(created))
created.setDir(builder.dir)
SEND_SIGNAL(created, COMSIG_ATOM_CONSTRUCTED, builder)
on_item_crafted(builder, created)
created.on_craft_completion(list(used_stack), null, builder)
qdel(used_stack) //you've outlived your purpose
builder.mind.adjust_experience(/datum/skill/construction, 5) //SKYRAT EDIT: Construction Skill
// Use up the material
use(recipe.req_amount * multiplier)
builder.investigate_log("crafted [recipe.title]", INVESTIGATE_CRAFTING)
// Apply mat datums
@@ -500,10 +500,6 @@
return TRUE
/// Run special logic on created items after they've been successfully crafted.
/obj/item/stack/proc/on_item_crafted(mob/builder, atom/created)
return
/obj/item/stack/vv_edit_var(vname, vval)
if(vname == NAMEOF(src, amount))
add(clamp(vval, 1-amount, max_amount - amount)) //there must always be one.
+9
View File
@@ -220,3 +220,12 @@
/obj/item/sticker/syndicate/trap
name = "bear trap sticker"
icon_state = "trap"
/obj/item/sticker/purity_seal
name = "purity seal"
icon_state = "purity_seal_1"
desc = "Looking closer, you realize it's actually a mass produced sticker. You suppose it's the holiness that counts."
/obj/item/sticker/purity_seal/purity_seal_2
icon_state = "purity_seal_2"
+3
View File
@@ -357,6 +357,9 @@
custom_materials = list(/datum/material/iron=SHEET_MATERIAL_AMOUNT*1.5)
custom_price = PAYCHECK_CREW * 0.6
storage_type = /datum/storage/bag/tray
sound_vary = TRUE
pickup_sound = SFX_TRAY_PICKUP
drop_sound = SFX_TRAY_DROP
/obj/item/storage/bag/tray/attack(mob/living/M, mob/living/user)
. = ..()
@@ -294,3 +294,14 @@
/obj/item/storage/box/heretic_box/PopulateContents()
for(var/i in 1 to rand(1,4))
new /obj/item/toy/reality_pierce(src)
/obj/item/storage/box/purity_seal_box
name = "box of purity seals"
desc = "A box containing several blessed purity seals."
/obj/item/storage/box/purity_seal_box/PopulateContents()
for(var/i in 1 to 4)
new /obj/item/sticker/purity_seal(src)
new /obj/item/sticker/purity_seal/purity_seal_2(src)
+8 -1
View File
@@ -85,10 +85,17 @@
icon_state = "secure"
base_icon_state = "secure"
inhand_icon_state = "sec-case"
var/stored_lock_code
/obj/item/storage/briefcase/secure/Initialize(mapload)
. = ..()
AddComponent(/datum/component/lockable_storage)
AddComponent(/datum/component/lockable_storage, stored_lock_code)
RegisterSignal(src, COMSIG_LOCKABLE_STORAGE_SET_CODE, PROC_REF(update_lock_code))
/obj/item/storage/briefcase/secure/proc/update_lock_code(obj/item/storage/briefcase/secure/briefacase, new_code)
SIGNAL_HANDLER
stored_lock_code = new_code
/// Base container used for gimmick disks.
/obj/item/storage/briefcase/secure/digital_storage
+3
View File
@@ -465,6 +465,9 @@
spawn_coupon = FALSE
open_status = FANCY_CONTAINER_OPEN
/obj/item/storage/fancy/cigarettes/flash_powder
spawn_type = /obj/item/cigarette/flash_powder
/obj/item/storage/fancy/rollingpapers
name = "rolling paper pack"
desc = "A pack of Nanotrasen brand rolling papers."
@@ -39,6 +39,10 @@
name = "quartermasters's garment bag"
desc = "A bag for storing extra clothes and shoes. This one belongs to the quartermaster."
/obj/item/storage/bag/garment/paramedic
name = "EMT's garment bag"
desc = "A bag for storing extra clothes and shoes. This one belongs to the emergency medical team."
/obj/item/storage/bag/garment/captain/PopulateContents()
new /obj/item/clothing/under/rank/captain(src)
new /obj/item/clothing/under/rank/captain/skirt(src)
@@ -248,3 +252,10 @@
new /obj/item/clothing/suit/jacket/tailcoat/quartermaster(src)
new /obj/item/clothing/neck/tie/bunnytie/cargo(src)
/obj/item/storage/bag/garment/paramedic/PopulateContents()
new /obj/item/clothing/under/rank/medical/paramedic(src)
new /obj/item/clothing/under/rank/medical/paramedic/skirt(src)
new /obj/item/clothing/gloves/latex/nitrile(src)
new /obj/item/clothing/shoes/workboots/black(src)
new /obj/item/clothing/glasses/hud/health(src)
+25 -51
View File
@@ -12,7 +12,7 @@
*/
/obj/item/locator
name = "bluespace locator"
desc = "Used to track portable teleportation beacons and targets with embedded tracking implants."
desc = "A handheld device that locks onto the unique bluespace resonance of tracking implants, providing real-time directional and positional data."
icon = 'icons/obj/devices/tracker.dmi'
icon_state = "locator"
var/temp = null
@@ -34,61 +34,35 @@
/obj/item/locator/ui_data(mob/user)
var/list/data = list()
data["trackingrange"] = tracking_range;
// Get our current turf location.
var/turf/sr = get_turf(src)
var/turf/current_turf = get_turf(src) // Get our current turf location.
if(!current_turf)
return data
if (sr)
// Check every teleport beacon.
var/list/tele_beacons = list()
for(var/obj/item/beacon/W in GLOB.teleportbeacons)
var/list/track_implants = list()
for(var/obj/item/implant/tracking/tracking_implant in GLOB.tracked_implants)
if(!tracking_implant.imp_in || !isliving(tracking_implant.imp_in))
continue
// Get the tracking beacon's turf location.
var/turf/tr = get_turf(W)
// Make sure it's on a turf and that its Z-level matches the tracker's Z-level
if (tr && tr.z == sr.z)
// Get the distance between the beacon's turf and our turf
var/distance = max(abs(tr.x - sr.x), abs(tr.y - sr.y))
// If the target is too far away, skip over this beacon.
if(distance > tracking_range)
continue
var/beacon_name
if(W.renamed)
beacon_name = W.name
else
var/area/A = get_area(W)
beacon_name = A.name
var/D = dir2text(get_dir(sr, tr))
tele_beacons += list(list(name = beacon_name, direction = D, distance = distance))
data["telebeacons"] = tele_beacons
var/list/track_implants = list()
for (var/obj/item/implant/beacon/tracking_beacon in GLOB.tracked_implants)
if (!tracking_beacon.imp_in || !isliving(tracking_beacon.loc))
continue
else
var/mob/living/living_mob = tracking_beacon.loc
if (living_mob.stat == DEAD)
if (living_mob.timeofdeath + tracking_beacon.lifespan_postmortem < world.time)
continue
var/turf/tr = get_turf(tracking_beacon)
var/distance = max(abs(tr.x - sr.x), abs(tr.y - sr.y))
if(distance > tracking_range)
var/mob/living/tracked_mob = tracking_implant.imp_in
if(tracked_mob.stat == DEAD)
if(tracked_mob.timeofdeath + tracking_implant.lifespan_postmortem < world.time)
continue
var/D = dir2text(get_dir(sr, tr))
track_implants += list(list(name = tracking_beacon.imp_in.name, direction = D, distance = distance))
data["trackimplants"] = track_implants
var/turf/implant_turf = get_turf(tracking_implant)
if(!implant_turf || implant_turf.z != current_turf.z)
continue
var/distance = max(abs(implant_turf.x - current_turf.x), abs(implant_turf.y - current_turf.y)) // get Chebyshev distance
if(distance > tracking_range)
continue
var/implant_direction = dir2text(get_dir(current_turf, implant_turf))
track_implants += list(list(name = tracking_implant.imp_in.name, direction = implant_direction, distance = distance))
data["trackimplants"] = track_implants
return data
#define PORTAL_LOCATION_DANGEROUS "portal_location_dangerous"
@@ -431,7 +405,7 @@
var/bagholdingcheck = FALSE
if(iscarbon(user))
var/mob/living/carbon/teleporting_guy = user
if(locate(/obj/item/storage/backpack/holding) in teleporting_guy.get_all_gear())
if(locate(/obj/item/storage/backpack/holding) in teleporting_guy.get_all_gear(INCLUDE_PROSTHETICS|INCLUDE_ABSTRACT|INCLUDE_ACCESSORIES))
bagholdingcheck = TRUE
if(isclosedturf(destination))
+6
View File
@@ -326,6 +326,12 @@
"TOOL" = "replaced with the tool used",
)
/obj/item/crowbar/power/paramedic/silent
name = "modified jaws of recovery"
desc = "Modified version for jaws of life, made to act like jaws of recovery. This one doesn't announce doors you're prying open and lets you pry any door, acting like regular jaws of life"
limit_jaws_access = FALSE
radio_alert = FALSE
/obj/item/crowbar/cyborg
name = "hydraulic crowbar"
desc = "A hydraulic prying tool, simple but powerful."
+2 -1
View File
@@ -43,7 +43,7 @@
span_hear("You hear clicking."))
var/floor_to_wall = get_dir(user, on_wall)
var/obj/hanging_object = new result_path(get_turf(user), floor_to_wall, TRUE)
var/obj/hanging_object = new result_path(get_turf(user))
hanging_object.setDir(floor_to_wall)
if(pixel_shift)
switch(floor_to_wall)
@@ -55,6 +55,7 @@
hanging_object.pixel_x = pixel_shift
if(WEST)
hanging_object.pixel_x = -pixel_shift
hanging_object.find_and_hang_on_wall()
after_attach(hanging_object)
//BUBBER EDIT START - For lewd_portals, you can place multiple with the same frame.
if(multi_use > 1)