diff --git a/code/__DEFINES/layers.dm b/code/__DEFINES/layers.dm
index 8891c06f75..5e903997e4 100644
--- a/code/__DEFINES/layers.dm
+++ b/code/__DEFINES/layers.dm
@@ -39,6 +39,7 @@
#define DOOR_HELPER_LAYER 2.71 //keep this above OPEN_DOOR_LAYER
#define PROJECTILE_HIT_THRESHHOLD_LAYER 2.75 //projectiles won't hit objects at or below this layer if possible
#define TABLE_LAYER 2.8
+#define TRAY_LAYER 2.85
#define BELOW_OBJ_LAYER 2.9
#define LOW_ITEM_LAYER 2.95
//#define OBJ_LAYER 3 //For easy recordkeeping; this is a byond define
diff --git a/code/__DEFINES/movespeed_modification.dm b/code/__DEFINES/movespeed_modification.dm
index 4336ad28f7..12a3c331ec 100644
--- a/code/__DEFINES/movespeed_modification.dm
+++ b/code/__DEFINES/movespeed_modification.dm
@@ -33,4 +33,6 @@
#define MOVESPEED_ID_SANITY "MOOD_SANITY"
#define MOVESPEED_ID_PRONE_DRAGGING "PRONE_DRAG"
-#define MOVESPEED_ID_HUMAN_CARRYING "HUMAN_CARRY"
\ No newline at end of file
+#define MOVESPEED_ID_HUMAN_CARRYING "HUMAN_CARRY"
+
+#define MOVESPEED_ID_TASED_STATUS "TASED"
\ No newline at end of file
diff --git a/code/__DEFINES/robots.dm b/code/__DEFINES/robots.dm
index 0820d63247..a05e6f6160 100644
--- a/code/__DEFINES/robots.dm
+++ b/code/__DEFINES/robots.dm
@@ -50,3 +50,7 @@
#define ASSEMBLY_THIRD_STEP 2
#define ASSEMBLY_FOURTH_STEP 3
#define ASSEMBLY_FIFTH_STEP 4
+
+
+//Checks to determine borg availability depending on the server's config. These are defines in the interest of reducing copypasta
+#define BORG_SEC_AVAILABLE (!CONFIG_GET(flag/disable_secborg) && GLOB.security_level >= CONFIG_GET(number/minimum_secborg_alert))
\ No newline at end of file
diff --git a/code/__DEFINES/status_effects.dm b/code/__DEFINES/status_effects.dm
index 3cd64af8c7..332d36f2f4 100644
--- a/code/__DEFINES/status_effects.dm
+++ b/code/__DEFINES/status_effects.dm
@@ -44,6 +44,8 @@
#define STATUS_EFFECT_SLEEPING /datum/status_effect/incapacitating/sleeping //the affected is asleep
+#define STATUS_EFFECT_TASED /datum/status_effect/electrode //the affected has been tased, preventing fine muscle control
+
#define STATUS_EFFECT_PACIFY /datum/status_effect/pacify //the affected is pacified, preventing direct hostile actions
#define STATUS_EFFECT_BELLIGERENT /datum/status_effect/belligerent //forces the affected to walk, doing damage if they try to run
diff --git a/code/__HELPERS/mobs.dm b/code/__HELPERS/mobs.dm
index 39d58ec15a..19d126f08f 100644
--- a/code/__HELPERS/mobs.dm
+++ b/code/__HELPERS/mobs.dm
@@ -400,6 +400,12 @@ GLOBAL_LIST_EMPTY(species_list)
. = 0
break
+ if(isliving(user))
+ var/mob/living/L = user
+ if(L.recoveringstam)
+ . = 0
+ break
+
if(!QDELETED(Tloc) && (QDELETED(target) || Tloc != target.loc))
if((Uloc != Tloc || Tloc != user) && !drifting)
. = 0
diff --git a/code/controllers/configuration/entries/game_options.dm b/code/controllers/configuration/entries/game_options.dm
index cfd57b4850..cf0caebb61 100644
--- a/code/controllers/configuration/entries/game_options.dm
+++ b/code/controllers/configuration/entries/game_options.dm
@@ -70,6 +70,9 @@
/datum/config_entry/flag/disable_peaceborg
+/datum/config_entry/number/minimum_secborg_alert //Minimum alert level for secborgs to be chosen.
+ config_entry_value = 3
+
/datum/config_entry/number/traitor_scaling_coeff //how much does the amount of players get divided by to determine traitors
config_entry_value = 6
min_val = 1
diff --git a/code/datums/components/storage/concrete/pockets.dm b/code/datums/components/storage/concrete/pockets.dm
index 84be4fdca4..fe5e1e5217 100644
--- a/code/datums/components/storage/concrete/pockets.dm
+++ b/code/datums/components/storage/concrete/pockets.dm
@@ -56,7 +56,7 @@
/obj/item/scalpel, /obj/item/reagent_containers/syringe, /obj/item/dnainjector,
/obj/item/reagent_containers/hypospray/medipen, /obj/item/reagent_containers/dropper,
/obj/item/implanter, /obj/item/screwdriver, /obj/item/weldingtool/mini,
- /obj/item/firing_pin
+ /obj/item/firing_pin, /obj/item/gun/ballistic/automatic/pistol/mag
))
/datum/component/storage/concrete/pockets/shoes/clown/Initialize()
diff --git a/code/datums/status_effects/debuffs.dm b/code/datums/status_effects/debuffs.dm
index da59c79ac5..186c988595 100644
--- a/code/datums/status_effects/debuffs.dm
+++ b/code/datums/status_effects/debuffs.dm
@@ -80,6 +80,36 @@
desc = "You've fallen asleep. Wait a bit and you should wake up. Unless you don't, considering how helpless you are."
icon_state = "asleep"
+//TASER
+/datum/status_effect/electrode
+ id = "tased"
+ blocks_combatmode = TRUE
+ status_type = STATUS_EFFECT_REPLACE
+ alert_type = null
+
+/datum/status_effect/electrode/on_creation(mob/living/new_owner, set_duration)
+ if(isnum(set_duration))
+ duration = set_duration
+ . = ..()
+ if(iscarbon(owner))
+ var/mob/living/carbon/C = owner
+ if(C.combatmode)
+ C.toggle_combat_mode(TRUE)
+ C.add_movespeed_modifier(MOVESPEED_ID_TASED_STATUS, TRUE, override = TRUE, multiplicative_slowdown = 8)
+
+/datum/status_effect/electrode/on_remove()
+ if(iscarbon(owner))
+ var/mob/living/carbon/C = owner
+ C.remove_movespeed_modifier(MOVESPEED_ID_TASED_STATUS)
+ . = ..()
+
+/datum/status_effect/electrode/tick()
+ if(owner)
+ owner.adjustStaminaLoss(5) //if you really want to try to stamcrit someone with a taser alone, you can, but it'll take time and good timing.
+
+/datum/status_effect/electrode/nextmove_modifier() //why is this a proc. its no big deal since this doesnt get called often at all but literally w h y
+ return 2
+
//OTHER DEBUFFS
/datum/status_effect/his_wrath //does minor damage over time unless holding His Grace
id = "his_wrath"
diff --git a/code/datums/status_effects/status_effect.dm b/code/datums/status_effects/status_effect.dm
index c8bcd831e2..bc1cfba112 100644
--- a/code/datums/status_effects/status_effect.dm
+++ b/code/datums/status_effects/status_effect.dm
@@ -11,6 +11,7 @@
var/on_remove_on_mob_delete = FALSE //if we call on_remove() when the mob is deleted
var/examine_text //If defined, this text will appear when the mob is examined - to use he, she etc. use "SUBJECTPRONOUN" and replace it in the examines themselves
var/alert_type = /obj/screen/alert/status_effect //the alert thrown by the status effect, contains name and description
+ var/blocks_combatmode //Does this status effect prevent the user from toggling combat mode?
var/obj/screen/alert/status_effect/linked_alert = null //the alert itself, if it exists
/datum/status_effect/New(list/arguments)
diff --git a/code/game/machinery/computer/medical.dm b/code/game/machinery/computer/medical.dm
index d4fe3e27a2..c912586ea3 100644
--- a/code/game/machinery/computer/medical.dm
+++ b/code/game/machinery/computer/medical.dm
@@ -575,7 +575,7 @@
if(user)
if(message)
if(authenticated)
- if(user.canUseTopic(src, BE_CLOSE))
+ if(user.canUseTopic(src, !issilicon(user)))
if(!record1 || record1 == active1)
if(!record2 || record2 == active2)
return 1
diff --git a/code/game/machinery/computer/security.dm b/code/game/machinery/computer/security.dm
index 1823e34100..efb1039b8b 100644
--- a/code/game/machinery/computer/security.dm
+++ b/code/game/machinery/computer/security.dm
@@ -801,7 +801,7 @@ What a mess.*/
/obj/machinery/computer/secure_data/proc/canUseSecurityRecordsConsole(mob/user, message1 = 0, record1, record2)
if(user)
if(authenticated)
- if(user.canUseTopic(src, BE_CLOSE))
+ if(user.canUseTopic(src, !issilicon(user)))
if(!trim(message1))
return 0
if(!record1 || record1 == active1)
diff --git a/code/game/machinery/computer/teleporter.dm b/code/game/machinery/computer/teleporter.dm
index 0e6a059c7b..f4f20aecc9 100644
--- a/code/game/machinery/computer/teleporter.dm
+++ b/code/game/machinery/computer/teleporter.dm
@@ -139,7 +139,7 @@
L[avoid_assoc_duplicate_keys(M.real_name, areaindex)] = M
var/desc = input("Please select a location to lock in.", "Locking Computer") as null|anything in L
- if(!user.canUseTopic(src, BE_CLOSE, NO_DEXTERY)) //check if we are still around
+ if(!user.canUseTopic(src, !issilicon(user), NO_DEXTERY)) //check if we are still around
return
target = L[desc]
if(imp_t)
@@ -167,7 +167,7 @@
to_chat(user, "No active connected stations located.")
return
var/desc = input("Please select a station to lock in.", "Locking Computer") as null|anything in L
- if(!user.canUseTopic(src, BE_CLOSE, NO_DEXTERY)) //again, check if we are still around
+ if(!user.canUseTopic(src, !issilicon(user), NO_DEXTERY)) //again, check if we are still around
return
var/obj/machinery/teleport/station/target_station = L[desc]
if(!target_station || !target_station.teleporter_hub)
diff --git a/code/game/machinery/porta_turret/portable_turret.dm b/code/game/machinery/porta_turret/portable_turret.dm
index b0a75c99dc..165170cf0f 100644
--- a/code/game/machinery/porta_turret/portable_turret.dm
+++ b/code/game/machinery/porta_turret/portable_turret.dm
@@ -40,6 +40,8 @@
var/stun_projectile = null //stun mode projectile type
var/stun_projectile_sound
+ var/nonlethal_projectile //projectile to use in stun mode when the target is resting, if any
+ var/nonlethal_projectile_sound
var/lethal_projectile = null //lethal mode projectile type
var/lethal_projectile_sound
@@ -535,13 +537,22 @@
T = closer
break
+ var/mob/living/carbon/C
+ if(iscarbon(target))
+ C = target
+
update_icon()
var/obj/item/projectile/A
//any emagged turrets drains 2x power and uses a different projectile?
if(mode == TURRET_STUN)
- use_power(reqpower)
- A = new stun_projectile(T)
- playsound(loc, stun_projectile_sound, 75, 1)
+ if(nonlethal_projectile && C && C.resting)
+ use_power(reqpower*0.5)
+ A = new nonlethal_projectile(T)
+ playsound(loc, nonlethal_projectile_sound, 75, 1)
+ else
+ use_power(reqpower)
+ A = new stun_projectile(T)
+ playsound(loc, stun_projectile_sound, 75, 1)
else
use_power(reqpower * 2)
A = new lethal_projectile(T)
@@ -653,6 +664,8 @@
base_icon_state = "standard"
stun_projectile = /obj/item/projectile/energy/electrode
stun_projectile_sound = 'sound/weapons/taser.ogg'
+ nonlethal_projectile = /obj/item/projectile/beam/disabler
+ nonlethal_projectile_sound = 'sound/weapons/taser2.ogg'
lethal_projectile = /obj/item/projectile/beam/laser
lethal_projectile_sound = 'sound/weapons/laser.ogg'
desc = "An energy blaster auto-turret."
@@ -662,6 +675,8 @@
base_icon_state = "standard"
stun_projectile = /obj/item/projectile/energy/electrode
stun_projectile_sound = 'sound/weapons/taser.ogg'
+ nonlethal_projectile = /obj/item/projectile/beam/disabler
+ nonlethal_projectile_sound = 'sound/weapons/taser2.ogg'
lethal_projectile = /obj/item/projectile/beam/laser/heavylaser
lethal_projectile_sound = 'sound/weapons/lasercannonfire.ogg'
desc = "An energy blaster auto-turret."
@@ -681,6 +696,8 @@
/obj/machinery/porta_turret/ai
faction = list("silicon")
+ nonlethal_projectile = /obj/item/projectile/beam/disabler
+ nonlethal_projectile_sound = 'sound/weapons/taser2.ogg'
/obj/machinery/porta_turret/ai/assess_perp(mob/living/carbon/human/perp)
return 10 //AI turrets shoot at everything not in their faction
diff --git a/code/game/objects/structures.dm b/code/game/objects/structures.dm
index 5f21862c17..7526807eeb 100644
--- a/code/game/objects/structures.dm
+++ b/code/game/objects/structures.dm
@@ -8,6 +8,7 @@
var/climbable = FALSE
var/mob/living/structureclimber
var/broken = 0 //similar to machinery's stat BROKEN
+ layer = BELOW_OBJ_LAYER
/obj/structure/Initialize()
if (!armor)
diff --git a/code/game/objects/structures/crates_lockers/closets.dm b/code/game/objects/structures/crates_lockers/closets.dm
index edcb4a6181..8b0d410a72 100644
--- a/code/game/objects/structures/crates_lockers/closets.dm
+++ b/code/game/objects/structures/crates_lockers/closets.dm
@@ -4,7 +4,6 @@
icon = 'icons/obj/closet.dmi'
icon_state = "generic"
density = TRUE
- layer = BELOW_OBJ_LAYER
var/icon_door = null
var/icon_door_override = FALSE //override to have open overlay use icon different to its base's
var/secure = FALSE //secure locker or not, also used if overriding a non-secure locker with a secure door overlay to add fancy lights
diff --git a/code/game/objects/structures/girders.dm b/code/game/objects/structures/girders.dm
index cd87075258..31bf9318ce 100644
--- a/code/game/objects/structures/girders.dm
+++ b/code/game/objects/structures/girders.dm
@@ -4,7 +4,6 @@
desc = "A large structural assembly made out of metal; It requires a layer of metal before it can be considered a wall."
anchored = TRUE
density = TRUE
- layer = BELOW_OBJ_LAYER
var/state = GIRDER_NORMAL
var/girderpasschance = 20 // percentage chance that a projectile passes through the girder.
var/can_displace = TRUE //If the girder can be moved around by wrenching it
diff --git a/code/game/objects/structures/mineral_doors.dm b/code/game/objects/structures/mineral_doors.dm
index 13ca421daa..5733ea123c 100644
--- a/code/game/objects/structures/mineral_doors.dm
+++ b/code/game/objects/structures/mineral_doors.dm
@@ -6,6 +6,7 @@
density = TRUE
anchored = TRUE
opacity = TRUE
+ layer = CLOSED_DOOR_LAYER
icon = 'icons/obj/doors/mineral_doors.dmi'
icon_state = "metal"
@@ -90,6 +91,7 @@
flick("[initial_state]opening",src)
sleep(10)
density = FALSE
+ layer = OPEN_DOOR_LAYER
state = 1
air_update_turf(1)
update_icon()
@@ -111,6 +113,7 @@
density = TRUE
set_opacity(TRUE)
state = 0
+ layer = initial(layer)
air_update_turf(1)
update_icon()
isSwitchingStates = 0
diff --git a/code/game/objects/structures/morgue.dm b/code/game/objects/structures/morgue.dm
index 98a26faae2..e7be30520e 100644
--- a/code/game/objects/structures/morgue.dm
+++ b/code/game/objects/structures/morgue.dm
@@ -307,7 +307,7 @@ GLOBAL_LIST_EMPTY(crematoriums)
/obj/structure/tray
icon = 'icons/obj/stationobjs.dmi'
density = TRUE
- layer = BELOW_OBJ_LAYER
+ layer = TRAY_LAYER
var/obj/structure/bodycontainer/connected = null
anchored = TRUE
pass_flags = LETPASSTHROW
diff --git a/code/game/objects/structures/reflector.dm b/code/game/objects/structures/reflector.dm
index 889cdab388..419502e2b0 100644
--- a/code/game/objects/structures/reflector.dm
+++ b/code/game/objects/structures/reflector.dm
@@ -5,7 +5,6 @@
desc = "A base for reflector assemblies."
anchored = FALSE
density = FALSE
- layer = BELOW_OBJ_LAYER
var/deflector_icon_state
var/image/deflector_overlay
var/finished = FALSE
diff --git a/code/game/objects/structures/transit_tubes/transit_tube_pod.dm b/code/game/objects/structures/transit_tubes/transit_tube_pod.dm
index ee46538be1..392c802ed8 100644
--- a/code/game/objects/structures/transit_tubes/transit_tube_pod.dm
+++ b/code/game/objects/structures/transit_tubes/transit_tube_pod.dm
@@ -4,7 +4,6 @@
animate_movement = FORWARD_STEPS
anchored = TRUE
density = TRUE
- layer = BELOW_OBJ_LAYER
var/moving = 0
var/datum/gas_mixture/air_contents = new()
diff --git a/code/modules/antagonists/clockcult/clock_structures/traps/steam_vent.dm b/code/modules/antagonists/clockcult/clock_structures/traps/steam_vent.dm
index 8d65574987..6aede1592e 100644
--- a/code/modules/antagonists/clockcult/clock_structures/traps/steam_vent.dm
+++ b/code/modules/antagonists/clockcult/clock_structures/traps/steam_vent.dm
@@ -7,7 +7,6 @@
break_message = "The vent snaps and collapses!"
max_integrity = 100
density = FALSE
- layer = BELOW_OBJ_LAYER
/obj/structure/destructible/clockwork/trap/steam_vent/activate()
opacity = !opacity
diff --git a/code/modules/antagonists/clockcult/clock_structures/wall_gear.dm b/code/modules/antagonists/clockcult/clock_structures/wall_gear.dm
index fb8397eed7..32b1b61dd1 100644
--- a/code/modules/antagonists/clockcult/clock_structures/wall_gear.dm
+++ b/code/modules/antagonists/clockcult/clock_structures/wall_gear.dm
@@ -5,7 +5,6 @@
unanchored_icon = "wall_gear"
climbable = TRUE
max_integrity = 100
- layer = BELOW_OBJ_LAYER
construction_value = 3
desc = "A massive brass gear. You could probably secure or unsecure it with a wrench, or just climb over it."
break_message = "The gear breaks apart into shards of alloy!"
diff --git a/code/modules/events/meteor_wave.dm b/code/modules/events/meteor_wave.dm
index c575c97901..604e203cd6 100644
--- a/code/modules/events/meteor_wave.dm
+++ b/code/modules/events/meteor_wave.dm
@@ -32,8 +32,6 @@
determine_wave_type()
/datum/round_event/meteor_wave/proc/determine_wave_type()
- if(SSevents.holidays && SSevents.holidays[HALLOWEEN])
- wave_name = "halloween"
if(!wave_name)
wave_name = pickweight(list(
"normal" = 50,
@@ -45,7 +43,10 @@
if("threatening")
wave_type = GLOB.meteors_threatening
if("catastrophic")
- wave_type = GLOB.meteors_catastrophic
+ if(SSevents.holidays && SSevents.holidays[HALLOWEEN])
+ wave_type = GLOB.meteorsSPOOKY
+ else
+ wave_type = GLOB.meteors_catastrophic
if("meaty")
wave_type = GLOB.meteorsB
if("space dust")
diff --git a/code/modules/mob/living/carbon/human/species_types/humans.dm b/code/modules/mob/living/carbon/human/species_types/humans.dm
index 0df2fca368..3332465c78 100644
--- a/code/modules/mob/living/carbon/human/species_types/humans.dm
+++ b/code/modules/mob/living/carbon/human/species_types/humans.dm
@@ -1,41 +1,42 @@
-/datum/species/human
- name = "Human"
- id = "human"
- default_color = "FFFFFF"
- species_traits = list(EYECOLOR,HAIR,FACEHAIR,LIPS,MUTCOLORS_PARTSONLY,WINGCOLOR)
- mutant_bodyparts = list("ears", "tail_human", "wings", "taur", "deco_wings") // CITADEL EDIT gives humans snowflake parts
- default_features = list("mcolor" = "FFF", "mcolor2" = "FFF","mcolor3" = "FFF","tail_human" = "None", "ears" = "None", "wings" = "None", "taur" = "None", "deco_wings" = "None")
- use_skintones = 1
- skinned_type = /obj/item/stack/sheet/animalhide/human
- disliked_food = GROSS | RAW
- liked_food = JUNKFOOD | FRIED
-
-/datum/species/human/qualifies_for_rank(rank, list/features)
- return TRUE //Pure humans are always allowed in all roles.
-
-/datum/species/human/spec_death(gibbed, mob/living/carbon/human/H)
- if(H)
- stop_wagging_tail(H)
-
-/datum/species/human/spec_stun(mob/living/carbon/human/H,amount)
- if(H)
- stop_wagging_tail(H)
- . = ..()
-
-/datum/species/human/can_wag_tail(mob/living/carbon/human/H)
- return ("tail_human" in mutant_bodyparts) || ("waggingtail_human" in mutant_bodyparts)
-
-/datum/species/human/is_wagging_tail(mob/living/carbon/human/H)
- return ("waggingtail_human" in mutant_bodyparts)
-
-/datum/species/human/start_wagging_tail(mob/living/carbon/human/H)
- if("tail_human" in mutant_bodyparts)
- mutant_bodyparts -= "tail_human"
- mutant_bodyparts |= "waggingtail_human"
- H.update_body()
-
-/datum/species/human/stop_wagging_tail(mob/living/carbon/human/H)
- if("waggingtail_human" in mutant_bodyparts)
- mutant_bodyparts -= "waggingtail_human"
- mutant_bodyparts |= "tail_human"
- H.update_body()
+/datum/species/human
+ name = "Human"
+ id = "human"
+ default_color = "FFFFFF"
+
+ species_traits = list(EYECOLOR,HAIR,FACEHAIR,LIPS,MUTCOLORS_PARTSONLY,WINGCOLOR)
+ mutant_bodyparts = list("ears", "tail_human", "wings", "taur", "deco_wings") // CITADEL EDIT gives humans snowflake parts
+ default_features = list("mcolor" = "FFF", "mcolor2" = "FFF","mcolor3" = "FFF","tail_human" = "None", "ears" = "None", "wings" = "None", "taur" = "None", "deco_wings" = "None")
+ use_skintones = 1
+ skinned_type = /obj/item/stack/sheet/animalhide/human
+ disliked_food = GROSS | RAW
+ liked_food = JUNKFOOD | FRIED
+
+/datum/species/human/qualifies_for_rank(rank, list/features)
+ return TRUE //Pure humans are always allowed in all roles.
+
+/datum/species/human/spec_death(gibbed, mob/living/carbon/human/H)
+ if(H)
+ stop_wagging_tail(H)
+
+/datum/species/human/spec_stun(mob/living/carbon/human/H,amount)
+ if(H)
+ stop_wagging_tail(H)
+ . = ..()
+
+/datum/species/human/can_wag_tail(mob/living/carbon/human/H)
+ return ("tail_human" in mutant_bodyparts) || ("waggingtail_human" in mutant_bodyparts)
+
+/datum/species/human/is_wagging_tail(mob/living/carbon/human/H)
+ return ("waggingtail_human" in mutant_bodyparts)
+
+/datum/species/human/start_wagging_tail(mob/living/carbon/human/H)
+ if("tail_human" in mutant_bodyparts)
+ mutant_bodyparts -= "tail_human"
+ mutant_bodyparts |= "waggingtail_human"
+ H.update_body()
+
+/datum/species/human/stop_wagging_tail(mob/living/carbon/human/H)
+ if("waggingtail_human" in mutant_bodyparts)
+ mutant_bodyparts -= "waggingtail_human"
+ mutant_bodyparts |= "tail_human"
+ H.update_body()
diff --git a/code/modules/mob/living/damage_procs.dm b/code/modules/mob/living/damage_procs.dm
index 563ab7cfb6..fbb6074ba2 100644
--- a/code/modules/mob/living/damage_procs.dm
+++ b/code/modules/mob/living/damage_procs.dm
@@ -79,7 +79,7 @@
-/mob/living/proc/apply_effect(effect = 0,effecttype = EFFECT_STUN, blocked = FALSE)
+/mob/living/proc/apply_effect(effect = 0,effecttype = EFFECT_STUN, blocked = FALSE, knockdown_stamoverride, knockdown_stammax)
var/hit_percent = (100-blocked)/100
if(!effect || (hit_percent <= 0))
return 0
@@ -87,7 +87,7 @@
if(EFFECT_STUN)
Stun(effect * hit_percent)
if(EFFECT_KNOCKDOWN)
- Knockdown(effect * hit_percent)
+ Knockdown(effect * hit_percent, override_stamdmg = knockdown_stammax ? CLAMP(knockdown_stamoverride, 0, knockdown_stammax-getStaminaLoss()) : knockdown_stamoverride)
if(EFFECT_UNCONSCIOUS)
Unconscious(effect * hit_percent)
if(EFFECT_IRRADIATE)
@@ -107,13 +107,13 @@
return 1
-/mob/living/proc/apply_effects(stun = 0, knockdown = 0, unconscious = 0, irradiate = 0, slur = 0, stutter = 0, eyeblur = 0, drowsy = 0, blocked = FALSE, stamina = 0, jitter = 0)
+/mob/living/proc/apply_effects(stun = 0, knockdown = 0, unconscious = 0, irradiate = 0, slur = 0, stutter = 0, eyeblur = 0, drowsy = 0, blocked = FALSE, stamina = 0, jitter = 0, kd_stamoverride, kd_stammax)
if(blocked >= 100)
return 0
if(stun)
apply_effect(stun, EFFECT_STUN, blocked)
if(knockdown)
- apply_effect(knockdown, EFFECT_KNOCKDOWN, blocked)
+ apply_effect(knockdown, EFFECT_KNOCKDOWN, blocked, kd_stamoverride, kd_stammax)
if(unconscious)
apply_effect(unconscious, EFFECT_UNCONSCIOUS, blocked)
if(irradiate)
diff --git a/code/modules/mob/living/silicon/robot/robot.dm b/code/modules/mob/living/silicon/robot/robot.dm
index 6c58921abc..2b2cc4c0b5 100644
--- a/code/modules/mob/living/silicon/robot/robot.dm
+++ b/code/modules/mob/living/silicon/robot/robot.dm
@@ -226,6 +226,9 @@
to_chat(src,"ERROR: Module installer reply timeout. Please check internal connections.")
return
+ if(!CONFIG_GET(flag/disable_secborg) && GLOB.security_level < CONFIG_GET(number/minimum_secborg_alert))
+ to_chat(src, "NOTICE: Due to local station regulations, the security cyborg module and its variants are only available during [num2seclevel(CONFIG_GET(number/minimum_secborg_alert))] alert and greater.")
+
var/list/modulelist = list("Standard" = /obj/item/robot_module/standard, \
"Engineering" = /obj/item/robot_module/engineering, \
"Medical" = /obj/item/robot_module/medical, \
@@ -234,7 +237,7 @@
"Service" = /obj/item/robot_module/butler)
if(!CONFIG_GET(flag/disable_peaceborg))
modulelist["Peacekeeper"] = /obj/item/robot_module/peacekeeper
- if(!CONFIG_GET(flag/disable_secborg))
+ if(BORG_SEC_AVAILABLE)
modulelist["Security"] = /obj/item/robot_module/security
modulelist += get_cit_modules() //Citadel change - adds Citadel's borg modules.
diff --git a/code/modules/projectiles/guns/energy/stun.dm b/code/modules/projectiles/guns/energy/stun.dm
index 44c7894467..c5d4c36813 100644
--- a/code/modules/projectiles/guns/energy/stun.dm
+++ b/code/modules/projectiles/guns/energy/stun.dm
@@ -20,7 +20,7 @@
name = "hybrid taser"
desc = "A dual-mode taser designed to fire both short-range high-power electrodes and long-range disabler beams."
icon_state = "advtaser"
- ammo_type = list(/obj/item/ammo_casing/energy/electrode, /obj/item/ammo_casing/energy/disabler)
+ ammo_type = list(/obj/item/ammo_casing/energy/disabler, /obj/item/ammo_casing/energy/electrode)
ammo_x_offset = 2
/obj/item/gun/energy/e_gun/advtaser/cyborg
diff --git a/code/modules/projectiles/projectile.dm b/code/modules/projectiles/projectile.dm
index efae090707..dace31c2f7 100644
--- a/code/modules/projectiles/projectile.dm
+++ b/code/modules/projectiles/projectile.dm
@@ -88,6 +88,8 @@
//Effects
var/stun = 0
var/knockdown = 0
+ var/knockdown_stamoverride
+ var/knockdown_stam_max
var/unconscious = 0
var/irradiate = 0
var/stutter = 0
@@ -202,7 +204,7 @@
else
L.log_message("has been shot by [firer] with [src]", LOG_ATTACK, color="orange")
- return L.apply_effects(stun, knockdown, unconscious, irradiate, slur, stutter, eyeblur, drowsy, blocked, stamina, jitter)
+ return L.apply_effects(stun, knockdown, unconscious, irradiate, slur, stutter, eyeblur, drowsy, blocked, stamina, jitter, knockdown_stamoverride, knockdown_stam_max)
/obj/item/projectile/proc/vol_by_damage()
if(src.damage)
diff --git a/code/modules/projectiles/projectile/energy/stun.dm b/code/modules/projectiles/projectile/energy/stun.dm
index 895a165f49..d7c8b8b082 100644
--- a/code/modules/projectiles/projectile/energy/stun.dm
+++ b/code/modules/projectiles/projectile/energy/stun.dm
@@ -3,7 +3,9 @@
icon_state = "spark"
color = "#FFFF00"
nodamage = 1
- knockdown = 100
+ knockdown = 60
+ knockdown_stamoverride = 36
+ knockdown_stam_max = 50
stutter = 5
jitter = 20
hitsound = 'sound/weapons/taserhit.ogg'
@@ -11,6 +13,7 @@
tracer_type = /obj/effect/projectile/tracer/stun
muzzle_type = /obj/effect/projectile/muzzle/stun
impact_type = /obj/effect/projectile/impact/stun
+ var/tase_duration = 50
/obj/item/projectile/energy/electrode/on_hit(atom/target, blocked = FALSE)
. = ..()
@@ -23,6 +26,7 @@
if(C.dna && C.dna.check_mutation(HULK))
C.say(pick(";RAAAAAAAARGH!", ";HNNNNNNNNNGGGGGGH!", ";GWAAAAAAAARRRHHH!", "NNNNNNNNGGGGGGGGHH!", ";AAAAAAARRRGH!" ), forced = "hulk")
else if((C.status_flags & CANKNOCKDOWN) && !HAS_TRAIT(C, TRAIT_STUNIMMUNE))
+ C.apply_status_effect(STATUS_EFFECT_TASED, tase_duration)
addtimer(CALLBACK(C, /mob/living/carbon.proc/do_jitter_animation, jitter), 5)
/obj/item/projectile/energy/electrode/on_range() //to ensure the bolt sparks when it reaches the end of its range if it didn't hit a target yet
diff --git a/code/modules/research/designs/medical_designs.dm b/code/modules/research/designs/medical_designs.dm
index d8b00ddd61..e70362553c 100644
--- a/code/modules/research/designs/medical_designs.dm
+++ b/code/modules/research/designs/medical_designs.dm
@@ -766,13 +766,49 @@
surgery = /datum/surgery/advanced/viral_bonding
research_icon_state = "surgery_chest"
-/datum/design/surgery/reconstruction
- name = "Reconstruction"
- desc = "A surgical procedure that gradually repairs damage done to a body without the assistance of chemicals. Unlike classic medicine, it is effective on corpses."
- id = "surgery_reconstruction"
- surgery = /datum/surgery/advanced/reconstruction
+/datum/design/surgery/healing
+ name = "Tend Wounds"
+ desc = "An upgraded version of the original surgery."
+ id = "surgery_healing_base" //holder because travis cries otherwise. Not used in techweb unlocks.
research_icon_state = "surgery_chest"
+/datum/design/surgery/healing/brute_upgrade
+ name = "Tend Wounds (Brute) Upgrade"
+ surgery = /datum/surgery/healing/brute/upgraded
+ id = "surgery_heal_brute_upgrade"
+
+/datum/design/surgery/healing/brute_upgrade_2
+ name = "Tend Wounds (Brute) Upgrade"
+ surgery = /datum/surgery/healing/brute/upgraded/femto
+ id = "surgery_heal_brute_upgrade_femto"
+
+/datum/design/surgery/healing/burn_upgrade
+ name = "Tend Wounds (Burn) Upgrade"
+ surgery = /datum/surgery/healing/burn/upgraded
+ id = "surgery_heal_burn_upgrade"
+
+/datum/design/surgery/healing/burn_upgrade_2
+ name = "Tend Wounds (Burn) Upgrade"
+ surgery = /datum/surgery/healing/brute/upgraded/femto
+ id = "surgery_heal_burn_upgrade_femto"
+
+/datum/design/surgery/healing/combo
+ name = "Tend Wounds (Mixture)"
+ desc = "A surgical procedure that repairs both bruises and burns. Repair efficiency is not as high as the individual surgeries but it is faster."
+ surgery = /datum/surgery/healing/combo
+ id = "surgery_heal_combo"
+
+/datum/design/surgery/healing/combo_upgrade
+ name = "Tend Wounds (Mixture) Upgrade"
+ surgery = /datum/surgery/healing/combo/upgraded
+ id = "surgery_heal_combo_upgrade"
+
+/datum/design/surgery/healing/combo_upgrade_2
+ name = "Tend Wounds (Mixture) Upgrade"
+ desc = "A surgical procedure that repairs both bruises and burns faster than their individual counterparts. It is more effective than both the individual surgeries."
+ surgery = /datum/surgery/healing/combo/upgraded/femto
+ id = "surgery_heal_combo_upgrade_femto"
+
/datum/design/surgery/surgery_toxinhealing
name = "Body Rejuvenation"
desc = "A surgical procedure that helps deal with oxygen deprecation, and treat toxic damaged. Works on corpses and alive alike without chemicals."
diff --git a/code/modules/research/techweb/all_nodes.dm b/code/modules/research/techweb/all_nodes.dm
index 0c9d4ca98b..5b3a21dd5c 100644
--- a/code/modules/research/techweb/all_nodes.dm
+++ b/code/modules/research/techweb/all_nodes.dm
@@ -110,12 +110,21 @@
export_price = 5000
/////////////////////////Advanced Surgery/////////////////////////
+/datum/techweb_node/imp_wt_surgery
+ id = "imp_wt_surgery"
+ display_name = "Improved Wound-Tending Surgery"
+ description = "Who would have known being more gentle with a hemostat decreases patient pain?"
+ prereq_ids = list("biotech")
+ design_ids = list("surgery_heal_brute_upgrade","surgery_heal_burn_upgrade")
+ research_costs = list(TECHWEB_POINT_TYPE_GENERIC = 1000)
+ export_price = 1000
+
/datum/techweb_node/adv_surgery
id = "adv_surgery"
display_name = "Advanced Surgery"
description = "When simple medicine doesn't cut it."
- prereq_ids = list("adv_biotech")
- design_ids = list("surgery_lobotomy", "surgery_reconstruction", "surgery_toxinhealing", "organbox", "surgery_adv_dissection")
+ prereq_ids = list("imp_wt_surgery")
+ design_ids = list("surgery_revival", "surgery_lobotomy", "surgery_heal_brute_upgrade_femto","surgery_heal_burn_upgrade_femto", "surgery_heal_combo", "surgery_toxinhealing", "organbox", "surgery_adv_dissection")
research_costs = list(TECHWEB_POINT_TYPE_GENERIC = 2500)
export_price = 5000
@@ -124,7 +133,7 @@
display_name = "Experimental Surgery"
description = "When evolution isn't fast enough."
prereq_ids = list("adv_surgery")
- design_ids = list("surgery_revival","surgery_pacify","surgery_vein_thread","surgery_muscled_veins","surgery_nerve_splice","surgery_nerve_ground","surgery_ligament_hook","surgery_ligament_reinforcement","surgery_viral_bond", "surgery_exp_dissection")
+ design_ids = list("surgery_pacify","surgery_vein_thread","surgery_muscled_veins","surgery_nerve_splice","surgery_nerve_ground","surgery_ligament_hook","surgery_ligament_reinforcement","surgery_viral_bond", "surgery_exp_dissection", "surgery_heal_combo_upgrade")
research_costs = list(TECHWEB_POINT_TYPE_GENERIC = 5000)
export_price = 5000
@@ -133,7 +142,7 @@
display_name = "Alien Surgery"
description = "Abductors did nothing wrong."
prereq_ids = list("exp_surgery", "alientech")
- design_ids = list("surgery_brainwashing","surgery_zombie", "surgery_ext_dissection")
+ design_ids = list("surgery_brainwashing","surgery_zombie", "surgery_ext_dissection", "surgery_heal_combo_upgrade_femto")
research_costs = list(TECHWEB_POINT_TYPE_GENERIC = 10000)
export_price = 5000
diff --git a/code/modules/surgery/advanced/reconstruction.dm b/code/modules/surgery/advanced/reconstruction.dm
deleted file mode 100644
index 9e2fd79d96..0000000000
--- a/code/modules/surgery/advanced/reconstruction.dm
+++ /dev/null
@@ -1,35 +0,0 @@
-/datum/surgery/advanced/reconstruction
- name = "Reconstruction"
- desc = "A surgical procedure that gradually repairs damage done to a body without the assistance of chemicals. Unlike classic medicine, it is effective on corpses."
- steps = list(/datum/surgery_step/incise,
- /datum/surgery_step/incise,
- /datum/surgery_step/retract_skin,
- /datum/surgery_step/incise,
- /datum/surgery_step/clamp_bleeders,
- /datum/surgery_step/incise,
- /datum/surgery_step/retract_skin,
- /datum/surgery_step/reconstruct,
- /datum/surgery_step/close)
-
- target_mobtypes = list(/mob/living/carbon/human, /mob/living/carbon/monkey)
- possible_locs = list(BODY_ZONE_CHEST)
- requires_bodypart_type = 0
-
-/datum/surgery_step/reconstruct
- name = "repair body"
- implements = list(TOOL_HEMOSTAT = 100, TOOL_SCREWDRIVER = 35, /obj/item/pen = 15)
- repeatable = TRUE
- time = 25
-
-/datum/surgery_step/reconstruct/preop(mob/user, mob/living/carbon/target, target_zone, obj/item/tool, datum/surgery/surgery)
- user.visible_message("[user] starts knitting some of [target]'s flesh back together.", "You start knitting some of [target]'s flesh back together.")
-
-/datum/surgery_step/reconstruct/success(mob/user, mob/living/carbon/target, target_zone, obj/item/tool, datum/surgery/surgery)
- user.visible_message("[user] fixes some of [target]'s wounds.", "You succeed in fixing some of [target]'s wounds.")
- target.heal_bodypart_damage(10,10)
- return TRUE
-
-/datum/surgery_step/reconstruct/failure(mob/user, mob/living/carbon/target, target_zone, obj/item/tool, datum/surgery/surgery)
- user.visible_message("[user] screws up!", "You screwed up!")
- target.take_bodypart_damage(5,0)
- return FALSE
\ No newline at end of file
diff --git a/code/modules/surgery/coronary_bypass.dm b/code/modules/surgery/coronary_bypass.dm
index c620b83d1f..71a48ae68c 100644
--- a/code/modules/surgery/coronary_bypass.dm
+++ b/code/modules/surgery/coronary_bypass.dm
@@ -48,7 +48,7 @@
//grafts a coronary bypass onto the individual's heart, success chance is 90% base again
/datum/surgery_step/coronary_bypass
name = "graft coronary bypass"
- implements = list(/obj/item/hemostat = 90, TOOL_WIRECUTTER = 35, /obj/item/stack/packageWrap = 15, /obj/item/stack/cable_coil = 5)
+ implements = list(TOOL_HEMOSTAT = 90, TOOL_WIRECUTTER = 35, /obj/item/stack/packageWrap = 15, /obj/item/stack/cable_coil = 5)
time = 90
/datum/surgery_step/coronary_bypass/preop(mob/user, mob/living/carbon/target, target_zone, obj/item/tool, datum/surgery/surgery)
diff --git a/code/modules/surgery/healing.dm b/code/modules/surgery/healing.dm
new file mode 100644
index 0000000000..d20d1d822a
--- /dev/null
+++ b/code/modules/surgery/healing.dm
@@ -0,0 +1,215 @@
+/datum/surgery/healing
+ steps = list(/datum/surgery_step/incise,
+ /datum/surgery_step/retract_skin,
+ /datum/surgery_step/incise,
+ /datum/surgery_step/clamp_bleeders,
+ /datum/surgery_step/heal,
+ /datum/surgery_step/close)
+
+ target_mobtypes = list(/mob/living/carbon/human, /mob/living/carbon/monkey)
+ possible_locs = list(BODY_ZONE_CHEST)
+ requires_bodypart_type = FALSE
+ replaced_by = /datum/surgery
+ ignore_clothes = TRUE
+ var/healing_step_type
+ var/antispam = FALSE
+
+/datum/surgery/healing/New(surgery_target, surgery_location, surgery_bodypart)
+ ..()
+ if(healing_step_type)
+ steps = list(/datum/surgery_step/incise/nobleed,
+ healing_step_type, //hehe cheeky
+ /datum/surgery_step/close)
+
+/datum/surgery_step/heal
+ name = "repair body"
+ implements = list(TOOL_HEMOSTAT = 100, TOOL_SCREWDRIVER = 65, /obj/item/pen = 55)
+ repeatable = TRUE
+ time = 25
+ var/brutehealing = 0
+ var/burnhealing = 0
+ var/missinghpbonus = 0 //heals an extra point of damager per X missing damage of type (burn damage for burn healing, brute for brute). Smaller Number = More Healing!
+
+/datum/surgery_step/heal/preop(mob/user, mob/living/carbon/target, target_zone, obj/item/tool, datum/surgery/surgery)
+ var/woundtype
+ if(brutehealing && burnhealing)
+ woundtype = "wounds"
+ else if(brutehealing)
+ woundtype = "bruises"
+ else //why are you trying to 0,0...?
+ woundtype = "burns"
+ if(istype(surgery,/datum/surgery/healing))
+ var/datum/surgery/healing/the_surgery = surgery
+ if(!the_surgery.antispam)
+ display_results(user, target, "You attempt to patch some of [target]'s [woundtype].",
+ "[user] attempts to patch some of [target]'s [woundtype].",
+ "[user] attempts to patch some of [target]'s [woundtype].")
+
+/datum/surgery_step/heal/initiate(mob/user, mob/living/carbon/target, target_zone, obj/item/tool, datum/surgery/surgery, try_to_fail = FALSE)
+ if(..())
+ while((brutehealing && target.getBruteLoss()) || (burnhealing && target.getFireLoss()))
+ if(!..())
+ break
+
+/datum/surgery_step/heal/success(mob/user, mob/living/carbon/target, target_zone, obj/item/tool, datum/surgery/surgery)
+ var/umsg = "You succeed in fixing some of [target]'s wounds" //no period, add initial space to "addons"
+ var/tmsg = "[user] fixes some of [target]'s wounds" //see above
+ var/urhealedamt_brute = brutehealing
+ var/urhealedamt_burn = burnhealing
+ if(missinghpbonus)
+ if(target.stat != DEAD)
+ urhealedamt_brute += round((target.getBruteLoss()/ missinghpbonus),0.1)
+ urhealedamt_burn += round((target.getFireLoss()/ missinghpbonus),0.1)
+ else //less healing bonus for the dead since they're expected to have lots of damage to begin with (to make TW into defib not TOO simple)
+ urhealedamt_brute += round((target.getBruteLoss()/ (missinghpbonus*5)),0.1)
+ urhealedamt_burn += round((target.getFireLoss()/ (missinghpbonus*5)),0.1)
+ if(!get_location_accessible(target, target_zone))
+ urhealedamt_brute *= 0.55
+ urhealedamt_burn *= 0.55
+ umsg += " as best as you can while they have clothing on"
+ tmsg += " as best as they can while [target] has clothing on"
+ target.heal_bodypart_damage(urhealedamt_brute,urhealedamt_burn)
+ display_results(user, target, "[umsg].",
+ "[tmsg].",
+ "[tmsg].")
+ if(istype(surgery, /datum/surgery/healing))
+ var/datum/surgery/healing/the_surgery = surgery
+ the_surgery.antispam = TRUE
+ return TRUE
+
+/datum/surgery_step/heal/failure(mob/user, mob/living/carbon/target, target_zone, obj/item/tool, datum/surgery/surgery)
+ display_results(user, target, "You screwed up!",
+ "[user] screws up!",
+ "[user] fixes some of [target]'s wounds.", TRUE)
+ var/urdamageamt_burn = brutehealing * 0.8
+ var/urdamageamt_brute = burnhealing * 0.8
+ if(missinghpbonus)
+ urdamageamt_brute += round((target.getBruteLoss()/ (missinghpbonus*2)),0.1)
+ urdamageamt_burn += round((target.getFireLoss()/ (missinghpbonus*2)),0.1)
+
+ target.take_bodypart_damage(urdamageamt_brute, urdamageamt_burn)
+ return FALSE
+
+/***************************BRUTE***************************/
+/datum/surgery/healing/brute
+ name = "Tend Wounds (Bruises)"
+
+/datum/surgery/healing/brute/basic
+ name = "Tend Wounds (Bruises, Basic)"
+ replaced_by = /datum/surgery/healing/brute/upgraded
+ healing_step_type = /datum/surgery_step/heal/brute/basic
+ desc = "A surgical procedure that provides basic treatment for a patient's brute traumas. Heals slightly more when the patient is severely injured."
+
+/datum/surgery/healing/brute/upgraded
+ name = "Tend Wounds (Bruises, Adv.)"
+ replaced_by = /datum/surgery/healing/brute/upgraded/femto
+ requires_tech = TRUE
+ healing_step_type = /datum/surgery_step/heal/brute/upgraded
+ desc = "A surgical procedure that provides advanced treatment for a patient's brute traumas. Heals more when the patient is severely injured."
+
+/datum/surgery/healing/brute/upgraded/femto
+ name = "Tend Wounds (Bruises, Exp.)"
+ replaced_by = /datum/surgery/healing/combo/upgraded/femto
+ requires_tech = TRUE
+ healing_step_type = /datum/surgery_step/heal/brute/upgraded/femto
+ desc = "A surgical procedure that provides experimental treatment for a patient's brute traumas. Heals considerably more when the patient is severely injured."
+
+/********************BRUTE STEPS********************/
+/datum/surgery_step/heal/brute/basic
+ name = "tend bruises"
+ brutehealing = 5
+ missinghpbonus = 15
+
+/datum/surgery_step/heal/brute/upgraded
+ brutehealing = 5
+ missinghpbonus = 10
+
+/datum/surgery_step/heal/brute/upgraded/femto
+ brutehealing = 5
+ missinghpbonus = 5
+
+/***************************BURN***************************/
+/datum/surgery/healing/burn
+ name = "Tend Wounds (Burn)"
+
+/datum/surgery/healing/burn/basic
+ name = "Tend Wounds (Burn, Basic)"
+ replaced_by = /datum/surgery/healing/burn/upgraded
+ healing_step_type = /datum/surgery_step/heal/burn/basic
+ desc = "A surgical procedure that provides basic treatment for a patient's burns. Heals slightly more when the patient is severely injured."
+
+/datum/surgery/healing/burn/upgraded
+ name = "Tend Wounds (Burn, Adv.)"
+ replaced_by = /datum/surgery/healing/burn/upgraded/femto
+ requires_tech = TRUE
+ healing_step_type = /datum/surgery_step/heal/burn/upgraded
+ desc = "A surgical procedure that provides advanced treatment for a patient's burns. Heals more when the patient is severely injured."
+
+/datum/surgery/healing/burn/upgraded/femto
+ name = "Tend Wounds (Burn, Exp.)"
+ replaced_by = /datum/surgery/healing/combo/upgraded/femto
+ requires_tech = TRUE
+ healing_step_type = /datum/surgery_step/heal/burn/upgraded/femto
+ desc = "A surgical procedure that provides experimental treatment for a patient's burns. Heals considerably more when the patient is severely injured."
+
+/********************BURN STEPS********************/
+/datum/surgery_step/heal/burn/basic
+ name = "tend burn wounds"
+ burnhealing = 5
+ missinghpbonus = 15
+
+/datum/surgery_step/heal/burn/upgraded
+ burnhealing = 5
+ missinghpbonus = 10
+
+/datum/surgery_step/heal/burn/upgraded/femto
+ burnhealing = 5
+ missinghpbonus = 5
+
+/***************************COMBO***************************/
+/datum/surgery/healing/combo
+
+
+/datum/surgery/healing/combo
+ name = "Tend Wounds (Mixture, Basic)"
+ replaced_by = /datum/surgery/healing/combo/upgraded
+ requires_tech = TRUE
+ healing_step_type = /datum/surgery_step/heal/combo
+ desc = "A surgical procedure that provides basic treatment for a patient's burns and brute traumas. Heals slightly more when the patient is severely injured."
+
+/datum/surgery/healing/combo/upgraded
+ name = "Tend Wounds (Mixture, Adv.)"
+ replaced_by = /datum/surgery/healing/combo/upgraded/femto
+ healing_step_type = /datum/surgery_step/heal/combo/upgraded
+ desc = "A surgical procedure that provides advanced treatment for a patient's burns and brute traumas. Heals more when the patient is severely injured."
+
+
+/datum/surgery/healing/combo/upgraded/femto //no real reason to type it like this except consistency, don't worry you're not missing anything
+ name = "Tend Wounds (Mixture, Exp.)"
+ replaced_by = null
+ healing_step_type = /datum/surgery_step/heal/combo/upgraded/femto
+ desc = "A surgical procedure that provides experimental treatment for a patient's burns and brute traumas. Heals considerably more when the patient is severely injured."
+
+/********************COMBO STEPS********************/
+/datum/surgery_step/heal/combo
+ name = "tend physical wounds"
+ brutehealing = 3
+ burnhealing = 3
+ missinghpbonus = 15
+ time = 10
+
+/datum/surgery_step/heal/combo/upgraded
+ brutehealing = 3
+ burnhealing = 3
+ missinghpbonus = 10
+
+/datum/surgery_step/heal/combo/upgraded/femto
+ brutehealing = 1
+ burnhealing = 1
+ missinghpbonus = 2.5
+
+/datum/surgery_step/heal/combo/upgraded/femto/failure(mob/user, mob/living/carbon/target, target_zone, obj/item/tool, datum/surgery/surgery)
+ display_results(user, target, "You screwed up!",
+ "[user] screws up!",
+ "[user] fixes some of [target]'s wounds.", TRUE)
+ target.take_bodypart_damage(5,5)
\ No newline at end of file
diff --git a/code/modules/surgery/lobectomy.dm b/code/modules/surgery/lobectomy.dm
index 7d8b8a53e8..297be175a0 100644
--- a/code/modules/surgery/lobectomy.dm
+++ b/code/modules/surgery/lobectomy.dm
@@ -15,7 +15,7 @@
//lobectomy, removes the most damaged lung lobe with a 95% base success chance
/datum/surgery_step/lobectomy
name = "excise damaged lung node"
- implements = list(/obj/item/scalpel = 95, /obj/item/melee/transforming/energy/sword = 65, /obj/item/kitchen/knife = 45,
+ implements = list(TOOL_SCALPEL = 95, /obj/item/melee/transforming/energy/sword = 65, /obj/item/kitchen/knife = 45,
/obj/item/shard = 35)
time = 42
diff --git a/code/modules/surgery/organic_steps.dm b/code/modules/surgery/organic_steps.dm
index 459a540f26..392244fb4b 100644
--- a/code/modules/surgery/organic_steps.dm
+++ b/code/modules/surgery/organic_steps.dm
@@ -24,6 +24,16 @@
H.bleed_rate += 3
return TRUE
+/datum/surgery_step/incise/nobleed //silly friendly!
+
+/datum/surgery_step/incise/nobleed/preop(mob/user, mob/living/carbon/target, target_zone, obj/item/tool, datum/surgery/surgery)
+ display_results(user, target, "You begin to carefully make an incision in [target]'s [parse_zone(target_zone)]...",
+ "[user] begins to carefully make an incision in [target]'s [parse_zone(target_zone)].",
+ "[user] begins to carefully make an incision in [target]'s [parse_zone(target_zone)].")
+
+/datum/surgery_step/incise/nobleed/success(mob/user, mob/living/carbon/target, target_zone, obj/item/tool, datum/surgery/surgery)
+ return TRUE
+
//clamp bleeders
/datum/surgery_step/clamp_bleeders
name = "clamp bleeders"
diff --git a/code/modules/surgery/surgery.dm b/code/modules/surgery/surgery.dm
index 5504d56310..1d660df794 100644
--- a/code/modules/surgery/surgery.dm
+++ b/code/modules/surgery/surgery.dm
@@ -60,7 +60,7 @@
var/obj/item/surgical_processor/SP = locate() in R.module.modules
if(SP)
if (replaced_by in SP.advanced_surgeries)
- return FALSE
+ return .
if(type in SP.advanced_surgeries)
return TRUE
@@ -69,7 +69,7 @@
var/obj/structure/table/optable/table = locate(/obj/structure/table/optable, T)
if(table)
if(!table.computer)
- return FALSE
+ return .
if(table.computer.stat & (NOPOWER|BROKEN))
return .
if(replaced_by in table.computer.advanced_surgeries)
diff --git a/config/game_options.txt b/config/game_options.txt
index 2e346ce0ac..02d620eb31 100644
--- a/config/game_options.txt
+++ b/config/game_options.txt
@@ -267,6 +267,10 @@ ALLOW_AI_MULTICAM
## Uncomment to prevent the security cyborg module from being chosen
#DISABLE_SECBORG
+## Determines the minimum alert level for the security cyborg model to be chosen
+## 0: Green, 1:Blue, 2:Amber, 3:Red, 4:Delta
+MINIMUM_SECBORG_ALERT 3
+
## Peacekeeper Borg ###
## Uncomment to prevent the peacekeeper cyborg module from being chosen
#DISABLE_PEACEBORG
diff --git a/html/changelogs/AutoChangeLog-pr-9466.yml b/html/changelogs/AutoChangeLog-pr-9466.yml
new file mode 100644
index 0000000000..473ec04eec
--- /dev/null
+++ b/html/changelogs/AutoChangeLog-pr-9466.yml
@@ -0,0 +1,5 @@
+author: "Bhijn"
+delete-after: True
+changes:
+ - tweak: "Security borgs and K9s are now only available during red alert or higher."
+ - server: "Headmins or other folks with access to the server's config can choose the minimum alert level for secborgs to be chosen via the MINIMUM_SECBORG_ALERT config option. See the default game_options.txt for more info."
diff --git a/html/changelogs/AutoChangeLog-pr-9503.yml b/html/changelogs/AutoChangeLog-pr-9503.yml
new file mode 100644
index 0000000000..7b79ad7185
--- /dev/null
+++ b/html/changelogs/AutoChangeLog-pr-9503.yml
@@ -0,0 +1,6 @@
+author: "deathride58"
+delete-after: True
+changes:
+ - balance: "The taser's electrode has been reworked. Instead of being a strong knockdown that deals a heavy amount of stamloss, it now causes a weak knockdown, applies a debilitating status effect for 5 seconds, and deals 35 stamloss on hit up to a maximum 50 total stamloss."
+ - balance: "Roundstart turrets now have a nonlethal projectile that gets used when they're set to stun and the target is resting"
+ - tweak: "Hybrid tasers now have disablers set as their default mode."
diff --git a/html/changelogs/AutoChangeLog-pr-9515.yml b/html/changelogs/AutoChangeLog-pr-9515.yml
new file mode 100644
index 0000000000..ece9a57449
--- /dev/null
+++ b/html/changelogs/AutoChangeLog-pr-9515.yml
@@ -0,0 +1,7 @@
+author: "Ghommie (original PR by Skoglol)"
+delete-after: True
+changes:
+ - tweak: "Moved machine and computer frames below objects, parts are now always on top."
+ - tweak: "Moved structures (chairs, closets, windows, cult altars etc etc) below objects."
+ - tweak: "Moves mineral doors to airlock layers"
+ - tweak: "morgue/crematorium trays' layers shouldn't overlap bodybags' anymore."
diff --git a/html/changelogs/AutoChangeLog-pr-9520.yml b/html/changelogs/AutoChangeLog-pr-9520.yml
new file mode 100644
index 0000000000..20188b7137
--- /dev/null
+++ b/html/changelogs/AutoChangeLog-pr-9520.yml
@@ -0,0 +1,4 @@
+author: "r4d6"
+delete-after: True
+changes:
+ - rscadd: "Added Decorative Wings for Humans, Felinids, Slimepersons and Lizardpeoples."
diff --git a/html/changelogs/AutoChangeLog-pr-9522.yml b/html/changelogs/AutoChangeLog-pr-9522.yml
new file mode 100644
index 0000000000..e4c51bf1e0
--- /dev/null
+++ b/html/changelogs/AutoChangeLog-pr-9522.yml
@@ -0,0 +1,6 @@
+author: "Linzolle"
+delete-after: True
+changes:
+ - rscadd: "Tend Wounds surgery. Heal in the field, with better healing the more damage the patient has."
+ - rscdel: "Reconstruction replaced by Tend Wounds"
+ - balance: "made Revival more accessible, more viable alternative to cloning."
diff --git a/html/changelogs/AutoChangeLog-pr-9523.yml b/html/changelogs/AutoChangeLog-pr-9523.yml
new file mode 100644
index 0000000000..da6864ace8
--- /dev/null
+++ b/html/changelogs/AutoChangeLog-pr-9523.yml
@@ -0,0 +1,4 @@
+author: "Linzolle"
+delete-after: True
+changes:
+ - bugfix: "advanced surgery tools can't perform lobectomy or coronary bypass"
diff --git a/html/changelogs/AutoChangeLog-pr-9537.yml b/html/changelogs/AutoChangeLog-pr-9537.yml
new file mode 100644
index 0000000000..24318d4364
--- /dev/null
+++ b/html/changelogs/AutoChangeLog-pr-9537.yml
@@ -0,0 +1,4 @@
+author: "Hatterhat"
+delete-after: True
+changes:
+ - rscadd: "Magnetic pistols now fit in boot pockets - jackboots, workboots, etc."
diff --git a/html/changelogs/AutoChangeLog-pr-9545.yml b/html/changelogs/AutoChangeLog-pr-9545.yml
new file mode 100644
index 0000000000..970e463f41
--- /dev/null
+++ b/html/changelogs/AutoChangeLog-pr-9545.yml
@@ -0,0 +1,4 @@
+author: "Ghommie (original PR by Barhandar"
+delete-after: True
+changes:
+ - bugfix: "Pumpkin meteors on Halloween now replace catastrophic meteor waves, instead of ALL OF THEM."
diff --git a/html/changelogs/AutoChangeLog-pr-9547.yml b/html/changelogs/AutoChangeLog-pr-9547.yml
new file mode 100644
index 0000000000..7e0abca8f4
--- /dev/null
+++ b/html/changelogs/AutoChangeLog-pr-9547.yml
@@ -0,0 +1,4 @@
+author: "Ghommie"
+delete-after: True
+changes:
+ - bugfix: "Silicons can now operate teleporter, medical and security records console from a distance again."
diff --git a/modular_citadel/code/modules/clothing/glasses/phantomthief.dm b/modular_citadel/code/modules/clothing/glasses/phantomthief.dm
index 49eb089afa..1b13ba5dc8 100644
--- a/modular_citadel/code/modules/clothing/glasses/phantomthief.dm
+++ b/modular_citadel/code/modules/clothing/glasses/phantomthief.dm
@@ -35,6 +35,8 @@
. = ..()
if(!istype(user))
return
+ if(slot != SLOT_GLASSES)
+ return
if(!combattoggle_redir)
combattoggle_redir = user.AddComponent(/datum/component/redirect, list(COMSIG_COMBAT_TOGGLED = CALLBACK(src, .proc/injectadrenaline)))
diff --git a/modular_citadel/code/modules/mob/living/carbon/carbon.dm b/modular_citadel/code/modules/mob/living/carbon/carbon.dm
index 43931db689..02b98bdbf2 100644
--- a/modular_citadel/code/modules/mob/living/carbon/carbon.dm
+++ b/modular_citadel/code/modules/mob/living/carbon/carbon.dm
@@ -18,9 +18,13 @@
return FALSE
return .
-/mob/living/carbon/proc/toggle_combat_mode()
+/mob/living/carbon/proc/toggle_combat_mode(forced)
if(recoveringstam)
return TRUE
+ if(!forced)
+ for(var/datum/status_effect/S in status_effects)
+ if(S.blocks_combatmode)
+ return TRUE
combatmode = !combatmode
if(voremode)
toggle_vore_mode()
diff --git a/modular_citadel/code/modules/mob/living/living.dm b/modular_citadel/code/modules/mob/living/living.dm
index ac79ea7f25..ed33041d58 100644
--- a/modular_citadel/code/modules/mob/living/living.dm
+++ b/modular_citadel/code/modules/mob/living/living.dm
@@ -116,7 +116,7 @@
to_chat(src, "You're too exhausted to keep going...")
resting = TRUE
if(combatmode)
- toggle_combat_mode()
+ toggle_combat_mode(TRUE)
recoveringstam = TRUE
filters += CIT_FILTER_STAMINACRIT
update_canmove()
diff --git a/modular_citadel/code/modules/mob/living/silicon/robot/robot_modules.dm b/modular_citadel/code/modules/mob/living/silicon/robot/robot_modules.dm
index b16ac1d586..c063d8b9ef 100644
--- a/modular_citadel/code/modules/mob/living/silicon/robot/robot_modules.dm
+++ b/modular_citadel/code/modules/mob/living/silicon/robot/robot_modules.dm
@@ -13,7 +13,7 @@
/mob/living/silicon/robot/proc/get_cit_modules()
var/list/modulelist = list()
modulelist["MediHound"] = /obj/item/robot_module/medihound
- if(!CONFIG_GET(flag/disable_secborg))
+ if(BORG_SEC_AVAILABLE)
modulelist["Security K-9"] = /obj/item/robot_module/k9
modulelist["Scrub Puppy"] = /obj/item/robot_module/scrubpup
modulelist["Borgi"] = /obj/item/robot_module/borgi
diff --git a/modular_citadel/code/modules/projectiles/projectile/energy.dm b/modular_citadel/code/modules/projectiles/projectile/energy.dm
deleted file mode 100644
index a32f23f0fc..0000000000
--- a/modular_citadel/code/modules/projectiles/projectile/energy.dm
+++ /dev/null
@@ -1,2 +0,0 @@
-/obj/item/projectile/energy/electrode
- stamina = 36
diff --git a/tgstation.dme b/tgstation.dme
index bd7a22d503..ad1531b5be 100755
--- a/tgstation.dme
+++ b/tgstation.dme
@@ -2784,6 +2784,7 @@
#include "code\modules\surgery\experimental_dissection.dm"
#include "code\modules\surgery\eye_surgery.dm"
#include "code\modules\surgery\graft_synthtissue.dm"
+#include "code\modules\surgery\healing.dm"
#include "code\modules\surgery\helpers.dm"
#include "code\modules\surgery\implant_removal.dm"
#include "code\modules\surgery\limb_augmentation.dm"
@@ -2803,7 +2804,6 @@
#include "code\modules\surgery\advanced\lobotomy.dm"
#include "code\modules\surgery\advanced\necrotic_revival.dm"
#include "code\modules\surgery\advanced\pacification.dm"
-#include "code\modules\surgery\advanced\reconstruction.dm"
#include "code\modules\surgery\advanced\revival.dm"
#include "code\modules\surgery\advanced\toxichealing.dm"
#include "code\modules\surgery\advanced\viral_bonding.dm"
@@ -3116,7 +3116,6 @@
#include "modular_citadel\code\modules\projectiles\guns\ballistic\spinfusor.dm"
#include "modular_citadel\code\modules\projectiles\guns\energy\energy_gun.dm"
#include "modular_citadel\code\modules\projectiles\guns\energy\laser.dm"
-#include "modular_citadel\code\modules\projectiles\projectile\energy.dm"
#include "modular_citadel\code\modules\projectiles\projectiles\reusable.dm"
#include "modular_citadel\code\modules\reagents\chemistry\reagents\astrogen.dm"
#include "modular_citadel\code\modules\reagents\chemistry\reagents\eigentstasium.dm"