diff --git a/code/__DEFINES/DNA.dm b/code/__DEFINES/DNA.dm
index 7be3533d47..60fb49f780 100644
--- a/code/__DEFINES/DNA.dm
+++ b/code/__DEFINES/DNA.dm
@@ -105,6 +105,7 @@
#define MATRIXED 22 //if icon is color matrix'd
#define SKINTONE 23 //uses skin tones
#define HORNCOLOR 24
+#define WINGCOLOR 25
//organ slots
#define ORGAN_SLOT_BRAIN "brain"
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/items/grenades/plastic.dm b/code/game/objects/items/grenades/plastic.dm
index 709fedbe5a..1956a1f317 100644
--- a/code/game/objects/items/grenades/plastic.dm
+++ b/code/game/objects/items/grenades/plastic.dm
@@ -174,6 +174,7 @@
gender = PLURAL
var/open_panel = 0
can_attach_mob = TRUE
+ full_damage_on_mobs = TRUE
/obj/item/grenade/plastic/c4/New()
wires = new /datum/wires/explosive/c4(src)
diff --git a/code/modules/client/preferences.dm b/code/modules/client/preferences.dm
index c6166ca970..47c3293c35 100644
--- a/code/modules/client/preferences.dm
+++ b/code/modules/client/preferences.dm
@@ -86,6 +86,7 @@ GLOBAL_LIST_EMPTY(preferences_datums)
var/skin_tone = "caucasian1" //Skin color
var/eye_color = "000" //Eye color
var/horn_color = "85615a" //Horn color
+ var/wing_color = "fff" //Wing color
var/datum/species/pref_species = new /datum/species/human() //Mutant race
var/list/features = list("mcolor" = "FFF",
"tail_lizard" = "Smooth",
@@ -591,6 +592,8 @@ GLOBAL_LIST_EMPTY(preferences_datums)
dat += "
Decorative wings
"
dat += "[features["deco_wings"]]"
+ dat += " Change
"
+
if("insect_wings" in pref_species.default_features)
if(!mutant_category)
dat += APPEARANCE_CATEGORY_COLUMN
@@ -598,6 +601,7 @@ GLOBAL_LIST_EMPTY(preferences_datums)
dat += "Insect wings
"
dat += "[features["insect_wings"]]"
+ dat += " Change
"
mutant_category++
if(mutant_category >= MAX_MUTANT_ROWS)
dat += ""
@@ -1689,7 +1693,10 @@ GLOBAL_LIST_EMPTY(preferences_datums)
if("horns_color")
var/new_horn_color = input(user, "Choose your character's horn colour:", "Character Preference","#"+horn_color) as color|null
if(new_horn_color)
- horn_color = sanitize_hexcolor(new_horn_color)
+ if (new_horn_color == "#000000")
+ horn_color = "#85615A"
+ else
+ horn_color = sanitize_hexcolor(new_horn_color)
if("wings")
var/new_wings
@@ -1697,6 +1704,14 @@ GLOBAL_LIST_EMPTY(preferences_datums)
if(new_wings)
features["wings"] = new_wings
+ if("wings_color")
+ var/new_wing_color = input(user, "Choose your character's wing colour:", "Character Preference","#"+wing_color) as color|null
+ if(new_wing_color)
+ if (new_wing_color == "#000000")
+ wing_color = "#FFFFFF"
+ else
+ wing_color = sanitize_hexcolor(new_wing_color)
+
if("frills")
var/new_frills
new_frills = input(user, "Choose your character's frills:", "Character Preference") as null|anything in GLOB.frills_list
@@ -1730,13 +1745,13 @@ GLOBAL_LIST_EMPTY(preferences_datums)
new_insect_wings = input(user, "Choose your character's wings:", "Character Preference") as null|anything in GLOB.insect_wings_list
if(new_insect_wings)
features["insect_wings"] = new_insect_wings
-
+
if("deco_wings")
var/new_deco_wings
new_deco_wings = input(user, "Choose your character's wings:", "Character Preference") as null|anything in GLOB.deco_wings_list
if(new_deco_wings)
features["deco_wings"] = new_deco_wings
-
+
if("insect_fluffs")
var/new_insect_fluff
new_insect_fluff = input(user, "Choose your character's wings:", "Character Preference") as null|anything in GLOB.insect_fluffs_list
@@ -2262,6 +2277,7 @@ GLOBAL_LIST_EMPTY(preferences_datums)
character.hair_color = hair_color
character.facial_hair_color = facial_hair_color
character.horn_color = horn_color
+ character.wing_color = wing_color
character.skin_tone = skin_tone
character.hair_style = hair_style
diff --git a/code/modules/client/preferences_savefile.dm b/code/modules/client/preferences_savefile.dm
index 94c1158885..01a46a44a0 100644
--- a/code/modules/client/preferences_savefile.dm
+++ b/code/modules/client/preferences_savefile.dm
@@ -317,6 +317,12 @@ SAVEFILE UPDATING/VERSIONING - 'Simplified', or rather, more coder-friendly ~Car
if(!S["features["mcolor"]"] || S["features["mcolor"]"] == "#000")
WRITE_FILE(S["features["mcolor"]"] , "#FFF")
+ if(!S["features["horn_color"]"] || S["features["horn_color"]"] == "#000")
+ WRITE_FILE(S["features["horn_color"]"] , "#85615a")
+
+ if(!S["features["wing_color"]"] || S["features["wing_color"]"] == "#000")
+ WRITE_FILE(S["features["wing_color"]"] , "#FFF")
+
//Character
S["real_name"] >> real_name
S["nameless"] >> nameless
@@ -338,6 +344,7 @@ SAVEFILE UPDATING/VERSIONING - 'Simplified', or rather, more coder-friendly ~Car
S["socks"] >> socks
S["socks_color"] >> socks_color
S["horn_color"] >> horn_color
+ S["wing_color"] >> wing_color
S["backbag"] >> backbag
S["jumpsuit_style"] >> jumpsuit_style
S["uplink_loc"] >> uplink_spawn_loc
@@ -449,6 +456,12 @@ SAVEFILE UPDATING/VERSIONING - 'Simplified', or rather, more coder-friendly ~Car
if(!features["mcolor"] || features["mcolor"] == "#000")
features["mcolor"] = pick("FFFFFF","7F7F7F", "7FFF7F", "7F7FFF", "FF7F7F", "7FFFFF", "FF7FFF", "FFFF7F")
+ if(!features["horn_color"] || features["horn_color"] == "#000")
+ features["horn_color"] = "85615a"
+
+ if(!features["wing_color"] || features["wing_color"] == "#000")
+ features["wing_color"] = "FFFFFF"
+
nameless = sanitize_integer(nameless, 0, 1, initial(nameless))
be_random_name = sanitize_integer(be_random_name, 0, 1, initial(be_random_name))
be_random_body = sanitize_integer(be_random_body, 0, 1, initial(be_random_body))
@@ -471,6 +484,7 @@ SAVEFILE UPDATING/VERSIONING - 'Simplified', or rather, more coder-friendly ~Car
eye_color = sanitize_hexcolor(eye_color, 3, 0)
skin_tone = sanitize_inlist(skin_tone, GLOB.skin_tones)
horn_color = sanitize_hexcolor(horn_color, 3, FALSE)
+ wing_color = sanitize_hexcolor(wing_color, 3, FALSE, "#FFFFFF")
backbag = sanitize_inlist(backbag, GLOB.backbaglist, initial(backbag))
jumpsuit_style = sanitize_inlist(jumpsuit_style, GLOB.jumpsuitlist, initial(jumpsuit_style))
uplink_spawn_loc = sanitize_inlist(uplink_spawn_loc, GLOB.uplink_spawn_loc_list, initial(uplink_spawn_loc))
@@ -485,7 +499,7 @@ SAVEFILE UPDATING/VERSIONING - 'Simplified', or rather, more coder-friendly ~Car
features["body_markings"] = sanitize_inlist(features["body_markings"], GLOB.body_markings_list)
features["feature_lizard_legs"] = sanitize_inlist(features["legs"], GLOB.legs_list)
features["insect_wings"] = sanitize_inlist(features["insect_wings"], GLOB.insect_wings_list)
- features["deco_wings"] = sanitize_inlist(features["deco_wings"], GLOB.deco_wings_list)
+ features["deco_wings"] = sanitize_inlist(features["deco_wings"], GLOB.deco_wings_list, "None")
features["insect_fluff"] = sanitize_inlist(features["insect_fluff"], GLOB.insect_fluffs_list)
joblessrole = sanitize_integer(joblessrole, 1, 3, initial(joblessrole))
@@ -540,6 +554,7 @@ SAVEFILE UPDATING/VERSIONING - 'Simplified', or rather, more coder-friendly ~Car
WRITE_FILE(S["socks"] , socks)
WRITE_FILE(S["socks_color"] , socks_color)
WRITE_FILE(S["horn_color"] , horn_color)
+ WRITE_FILE(S["wing_color"] , wing_color)
WRITE_FILE(S["backbag"] , backbag)
WRITE_FILE(S["jumpsuit_style"] , jumpsuit_style)
WRITE_FILE(S["uplink_loc"] , uplink_spawn_loc)
diff --git a/code/modules/crafting/recipes.dm b/code/modules/crafting/recipes.dm
index 5d0ef609c8..2987b52338 100644
--- a/code/modules/crafting/recipes.dm
+++ b/code/modules/crafting/recipes.dm
@@ -8,5 +8,4 @@
var/chem_catalysts[] = list() //like tools but for reagents
var/category = CAT_NONE //where it shows up in the crafting UI
var/subcategory = CAT_NONE
- var/always_availible = TRUE //Set to FALSE if it needs to be learned first.
-
+ var/always_availible = TRUE //Set to FALSE if it needs to be learned first.
\ No newline at end of file
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/flufftext/Hallucination.dm b/code/modules/flufftext/Hallucination.dm
index 88f72d27c3..bac2e0bb65 100644
--- a/code/modules/flufftext/Hallucination.dm
+++ b/code/modules/flufftext/Hallucination.dm
@@ -771,7 +771,7 @@ GLOBAL_LIST_INIT(hallucination_list, list(
..()
var/turf/source = random_far_turf()
if(!sound_type)
- sound_type = pick("airlock","airlock pry","console","explosion","far explosion","mech","glass","alarm","beepsky","mech","wall decon","door hack")
+ sound_type = pick("airlock","airlock pry","console","flash","explosion","far explosion","mech","glass","alarm","beepsky","mech","wall decon","door hack")
feedback_details += "Type: [sound_type]"
//Strange audio
switch(sound_type)
@@ -788,6 +788,8 @@ GLOBAL_LIST_INIT(hallucination_list, list(
target.playsound_local(source,'sound/effects/explosion1.ogg', 50, 1)
else
target.playsound_local(source, 'sound/effects/explosion2.ogg', 50, 1)
+ if("flash")
+ target.playsound_local(source, 'sound/weapons/flash.ogg', 50, 1)
if("far explosion")
target.playsound_local(source, 'sound/effects/explosionfar.ogg', 50, 1)
if("glass")
@@ -1291,4 +1293,4 @@ GLOBAL_LIST_INIT(hallucination_list, list(
H.hal_target = target
H.preparePixelProjectile(target, start)
H.fire()
- qdel(src)
\ No newline at end of file
+ qdel(src)
diff --git a/code/modules/mining/equipment/explorer_gear.dm b/code/modules/mining/equipment/explorer_gear.dm
index 23ec02976d..7bf59e9ba7 100644
--- a/code/modules/mining/equipment/explorer_gear.dm
+++ b/code/modules/mining/equipment/explorer_gear.dm
@@ -129,7 +129,7 @@
/obj/item/clothing/suit/hooded/explorer/seva
name = "SEVA Suit"
- desc = "A fire-proof suit for exploring hot environments."
+ desc = "A fire-proof suit for exploring hot environments. Its design and material make it easier for a Goliath to keep their grip on the wearer."
icon_state = "seva"
item_state = "seva"
w_class = WEIGHT_CLASS_BULKY
@@ -141,7 +141,7 @@
/obj/item/clothing/head/hooded/explorer/seva
name = "SEVA Hood"
- desc = "A fire-proof hood for exploring hot environments."
+ desc = "A fire-proof hood for exploring hot environments. Its design and material make it easier for a Goliath to keep their grip on the wearer."
icon_state = "seva"
item_state = "seva"
max_heat_protection_temperature = FIRE_IMMUNITY_MAX_TEMP_PROTECT
@@ -159,7 +159,7 @@
/obj/item/clothing/suit/hooded/explorer/exo
name = "Exo-suit"
- desc = "A robust suit for exploring dangerous environments."
+ desc = "A robust suit for fighting dangerous animals. Its design and material make it harder for a Goliath to keep their grip on the wearer."
icon_state = "exo"
item_state = "exo"
w_class = WEIGHT_CLASS_BULKY
@@ -170,7 +170,7 @@
/obj/item/clothing/head/hooded/explorer/exo
name = "Exo-hood"
- desc = "A robust helmet for exploring dangerous environments."
+ desc = "A robust helmet for fighting dangerous animals. Its design and material make it harder for a Goliath to keep their grip on the wearer."
icon_state = "exo"
item_state = "exo"
armor = list("melee" = 65, "bullet" = 5, "laser" = 5, "energy" = 5, "bomb" = 60, "bio" = 25, "rad" = 10, "fire" = 0, "acid" = 0)
diff --git a/code/modules/mob/dead/new_player/preferences_setup.dm b/code/modules/mob/dead/new_player/preferences_setup.dm
index 994d082585..d54b8256a9 100644
--- a/code/modules/mob/dead/new_player/preferences_setup.dm
+++ b/code/modules/mob/dead/new_player/preferences_setup.dm
@@ -17,6 +17,8 @@
hair_color = random_short_color()
facial_hair_color = hair_color
eye_color = random_eye_color()
+ horn_color = "85615a"
+ wing_color = "fff"
if(!pref_species)
var/rando_race = pick(GLOB.roundstart_races)
pref_species = new rando_race()
diff --git a/code/modules/mob/dead/new_player/sprite_accessories/wings.dm b/code/modules/mob/dead/new_player/sprite_accessories/wings.dm
index 554b7edfdb..6c42177c3c 100644
--- a/code/modules/mob/dead/new_player/sprite_accessories/wings.dm
+++ b/code/modules/mob/dead/new_player/sprite_accessories/wings.dm
@@ -30,6 +30,7 @@
// Decorative wings
/datum/sprite_accessory/deco_wings
icon = 'icons/mob/wings.dmi'
+ color_src = WINGCOLOR
/datum/sprite_accessory/deco_wings/plain
name = "Plain"
@@ -104,6 +105,22 @@
center = TRUE
dimension_y = 34
+/datum/sprite_accessory/deco_wings/bee
+ name = "Bee"
+ icon_state = "bee"
+
+/datum/sprite_accessory/deco_wings/fairy
+ name = "Fairy"
+ icon_state = "fairy"
+
+/datum/sprite_accessory/deco_wings/bat
+ name = "Bat"
+ icon_state = "bat"
+
+/datum/sprite_accessory/deco_wings/feathery
+ name = "Feathery"
+ icon_state = "feathery"
+
/datum/sprite_accessory/deco_wings/none
name = "None"
icon_state = "none"
@@ -113,7 +130,7 @@
/datum/sprite_accessory/insect_wings
icon = 'icons/mob/wings.dmi'
- color_src = null
+ color_src = WINGCOLOR
/datum/sprite_accessory/insect_wings/none
name = "None"
@@ -183,35 +200,10 @@
name = "Snow"
icon_state = "snow"
-/datum/sprite_accessory/insect_wings/colored
- name = "Colored (Hair)"
- icon_state = "snowplain"
- color_src = HAIR
-
-/datum/sprite_accessory/insect_fluff/colored1
- name = "Colored (Primary)"
- icon_state = "snowplain"
- color_src = MUTCOLORS
-
-/datum/sprite_accessory/insect_fluff/colored2
- name = "Colored (Secondary)"
- icon_state = "snowplain"
- color_src = MUTCOLORS2
-
-/datum/sprite_accessory/insect_fluff/colored3
- name = "Colored (Tertiary)"
- icon_state = "snowplain"
- color_src = MUTCOLORS3
-
/datum/sprite_accessory/insect_wings/bee
name = "Bee"
icon_state = "bee"
-/datum/sprite_accessory/insect_wings/bee_color
- name = "Bee (Hair colored)"
- icon_state = "bee"
- color_src = HAIR
-
/datum/sprite_accessory/insect_wings/fairy
name = "Fairy"
icon_state = "fairy"
diff --git a/code/modules/mob/living/carbon/human/human_defines.dm b/code/modules/mob/living/carbon/human/human_defines.dm
index e32d073500..657c32ba01 100644
--- a/code/modules/mob/living/carbon/human/human_defines.dm
+++ b/code/modules/mob/living/carbon/human/human_defines.dm
@@ -19,6 +19,8 @@
var/horn_color = "85615a" //specific horn colors, because why not?
+ var/wing_color = "fff" //wings too
+
var/skin_tone = "caucasian1" //Skin tone
var/lip_style = null //no lipstick by default- arguably misleading, as it could be used for general makeup
diff --git a/code/modules/mob/living/carbon/human/species.dm b/code/modules/mob/living/carbon/human/species.dm
index 1f843483ee..a59d9e914b 100644
--- a/code/modules/mob/living/carbon/human/species.dm
+++ b/code/modules/mob/living/carbon/human/species.dm
@@ -37,6 +37,7 @@ GLOBAL_LIST_EMPTY(roundstart_race_names)
var/hair_alpha = 255 // the alpha used by the hair. 255 is completely solid, 0 is transparent.
var/horn_color //specific horn colors, because why not?
+ var/wing_color
var/use_skintones = 0 // does it use skintones or not? (spoiler alert this is only used by humans)
var/exotic_blood = "" // If your race wants to bleed something other than bog standard blood, change this to reagent id.
@@ -869,6 +870,8 @@ GLOBAL_LIST_EMPTY(roundstart_race_names)
accessory_overlay.color = "#[H.eye_color]"
if(HORNCOLOR)
accessory_overlay.color = "#[H.horn_color]"
+ if(WINGCOLOR)
+ accessory_overlay.color = "#[H.wing_color]"
else
accessory_overlay.color = forced_colour
else
@@ -946,6 +949,8 @@ GLOBAL_LIST_EMPTY(roundstart_race_names)
if(HORNCOLOR)
extra_accessory_overlay.color = "#[H.horn_color]"
+ if(WINGCOLOR)
+ extra_accessory_overlay.color = "#[H.wing_color]"
if(OFFSET_MUTPARTS in H.dna.species.offset_features)
extra_accessory_overlay.pixel_x += H.dna.species.offset_features[OFFSET_MUTPARTS][1]
@@ -985,6 +990,8 @@ GLOBAL_LIST_EMPTY(roundstart_race_names)
extra2_accessory_overlay.color = "#[H.hair_color]"
if(HORNCOLOR)
extra2_accessory_overlay.color = "#[H.horn_color]"
+ if(WINGCOLOR)
+ extra2_accessory_overlay.color = "#[H.wing_color]"
if(OFFSET_MUTPARTS in H.dna.species.offset_features)
extra2_accessory_overlay.pixel_x += H.dna.species.offset_features[OFFSET_MUTPARTS][1]
diff --git a/code/modules/mob/living/carbon/human/species_types/bugmen.dm b/code/modules/mob/living/carbon/human/species_types/bugmen.dm
index 94dba550b6..b4e55b60a5 100644
--- a/code/modules/mob/living/carbon/human/species_types/bugmen.dm
+++ b/code/modules/mob/living/carbon/human/species_types/bugmen.dm
@@ -3,7 +3,7 @@
id = "insect"
say_mod = "flutters"
default_color = "00FF00"
- species_traits = list(LIPS,NOEYES,HAIR,FACEHAIR,MUTCOLORS,HORNCOLOR)
+ species_traits = list(LIPS,NOEYES,HAIR,FACEHAIR,MUTCOLORS,HORNCOLOR,WINGCOLOR)
inherent_biotypes = list(MOB_ORGANIC, MOB_HUMANOID, MOB_BUG)
mutant_bodyparts = list("mam_ears", "mam_snout", "mam_tail", "taur", "insect_wings", "mam_snouts", "insect_fluff","horns")
default_features = list("mcolor" = "FFF","mcolor2" = "FFF","mcolor3" = "FFF", "mam_tail" = "None", "mam_ears" = "None",
diff --git a/code/modules/mob/living/carbon/human/species_types/felinid.dm b/code/modules/mob/living/carbon/human/species_types/felinid.dm
index 1ee697d66c..ec58a3be9c 100644
--- a/code/modules/mob/living/carbon/human/species_types/felinid.dm
+++ b/code/modules/mob/living/carbon/human/species_types/felinid.dm
@@ -4,8 +4,8 @@
id = "felinid"
limbs_id = "human"
- mutant_bodyparts = list("mam_ears", "mam_tail")
- default_features = list("mcolor" = "FFF", "mam_tail" = "Cat", "mam_ears" = "Cat", "wings" = "None")
+ mutant_bodyparts = list("mam_ears", "mam_tail", "deco_wings")
+ default_features = list("mcolor" = "FFF", "mam_tail" = "Cat", "mam_ears" = "Cat", "wings" = "None", "deco_wings" = "None")
mutantears = /obj/item/organ/ears/cat
mutanttail = /obj/item/organ/tail/cat
diff --git a/code/modules/mob/living/carbon/human/species_types/furrypeople.dm b/code/modules/mob/living/carbon/human/species_types/furrypeople.dm
index 07e594d20b..0390d4accc 100644
--- a/code/modules/mob/living/carbon/human/species_types/furrypeople.dm
+++ b/code/modules/mob/living/carbon/human/species_types/furrypeople.dm
@@ -3,7 +3,7 @@
id = "mammal"
default_color = "4B4B4B"
should_draw_citadel = TRUE
- species_traits = list(MUTCOLORS,EYECOLOR,LIPS,HAIR,HORNCOLOR)
+ species_traits = list(MUTCOLORS,EYECOLOR,LIPS,HAIR,HORNCOLOR,WINGCOLOR)
inherent_biotypes = list(MOB_ORGANIC, MOB_HUMANOID)
mutant_bodyparts = list("mam_tail", "mam_ears", "mam_body_markings", "mam_snouts", "deco_wings", "taur", "horns", "legs")
default_features = list("mcolor" = "FFF","mcolor2" = "FFF","mcolor3" = "FFF", "mam_snouts" = "Husky", "mam_tail" = "Husky", "mam_ears" = "Husky", "deco_wings" = "None",
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 96b43795a2..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)
- mutant_bodyparts = list("ears", "tail_human", "wings", "taur") // CITADEL EDIT gives humans snowflake parts
- default_features = list("mcolor" = "FFF", "mcolor2" = "FFF","mcolor3" = "FFF","tail_human" = "None", "ears" = "None", "wings" = "None", "taur" = "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/carbon/human/species_types/jellypeople.dm b/code/modules/mob/living/carbon/human/species_types/jellypeople.dm
index 03cd514300..8e98569644 100644
--- a/code/modules/mob/living/carbon/human/species_types/jellypeople.dm
+++ b/code/modules/mob/living/carbon/human/species_types/jellypeople.dm
@@ -4,10 +4,10 @@
id = "jelly"
default_color = "00FF90"
say_mod = "chirps"
- species_traits = list(MUTCOLORS,EYECOLOR,HAIR,FACEHAIR,NOBLOOD)
+ species_traits = list(MUTCOLORS,EYECOLOR,HAIR,FACEHAIR,NOBLOOD,WINGCOLOR)
mutantlungs = /obj/item/organ/lungs/slime
- mutant_bodyparts = list("mam_tail", "mam_ears", "mam_snouts", "taur") //CIT CHANGE
- default_features = list("mcolor" = "FFF", "mam_tail" = "None", "mam_ears" = "None", "mam_snouts" = "None", "taur" = "None") //CIT CHANGE
+ mutant_bodyparts = list("mam_tail", "mam_ears", "mam_snouts", "taur", "deco_wings") //CIT CHANGE
+ default_features = list("mcolor" = "FFF", "mam_tail" = "None", "mam_ears" = "None", "mam_snouts" = "None", "taur" = "None", "deco_wings" = "None") //CIT CHANGE
inherent_traits = list(TRAIT_TOXINLOVER)
meat = /obj/item/reagent_containers/food/snacks/meat/slab/human/mutant/slime
exotic_blood = "slimejelly"
diff --git a/code/modules/mob/living/carbon/human/species_types/lizardpeople.dm b/code/modules/mob/living/carbon/human/species_types/lizardpeople.dm
index 4dbfd23df8..a719f2eda0 100644
--- a/code/modules/mob/living/carbon/human/species_types/lizardpeople.dm
+++ b/code/modules/mob/living/carbon/human/species_types/lizardpeople.dm
@@ -4,16 +4,16 @@
id = "lizard"
say_mod = "hisses"
default_color = "00FF00"
- species_traits = list(MUTCOLORS,EYECOLOR,HAIR,FACEHAIR,LIPS,HORNCOLOR)
+ species_traits = list(MUTCOLORS,EYECOLOR,HAIR,FACEHAIR,LIPS,HORNCOLOR,WINGCOLOR)
inherent_biotypes = list(MOB_ORGANIC, MOB_HUMANOID, MOB_REPTILE)
- mutant_bodyparts = list("tail_lizard", "snout", "spines", "horns", "frills", "body_markings", "legs", "taur")
+ mutant_bodyparts = list("tail_lizard", "snout", "spines", "horns", "frills", "body_markings", "legs", "taur", "deco_wings")
mutanttongue = /obj/item/organ/tongue/lizard
mutanttail = /obj/item/organ/tail/lizard
coldmod = 1.5
heatmod = 0.67
default_features = list("mcolor" = "0F0", "mcolor2" = "0F0", "mcolor3" = "0F0", "tail_lizard" = "Smooth", "snout" = "Round",
"horns" = "None", "frills" = "None", "spines" = "None", "body_markings" = "None",
- "legs" = "Digitigrade", "taur" = "None")
+ "legs" = "Digitigrade", "taur" = "None", "deco_wings" = "None")
attack_verb = "slash"
attack_sound = 'sound/weapons/slash.ogg'
miss_sound = 'sound/weapons/slashmiss.ogg'
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/mob/living/simple_animal/guardian/types/support.dm b/code/modules/mob/living/simple_animal/guardian/types/support.dm
index 8bf1874d84..d31809e9aa 100644
--- a/code/modules/mob/living/simple_animal/guardian/types/support.dm
+++ b/code/modules/mob/living/simple_animal/guardian/types/support.dm
@@ -30,7 +30,7 @@
C.adjustBruteLoss(-5)
C.adjustFireLoss(-5)
C.adjustOxyLoss(-5)
- C.adjustToxLoss(-5)
+ C.adjustToxLoss(-5, forced = TRUE)
var/obj/effect/temp_visual/heal/H = new /obj/effect/temp_visual/heal(get_turf(C))
if(namedatum)
H.color = namedatum.colour
diff --git a/code/modules/projectiles/ammunition/energy/laser.dm b/code/modules/projectiles/ammunition/energy/laser.dm
index 638711e8d4..0940144721 100644
--- a/code/modules/projectiles/ammunition/energy/laser.dm
+++ b/code/modules/projectiles/ammunition/energy/laser.dm
@@ -71,9 +71,3 @@
projectile_type = /obj/item/projectile/beam/mindflayer
select_name = "MINDFUCK"
fire_sound = 'sound/weapons/laser.ogg'
-
-/obj/item/ammo_casing/energy/laser/weak
- projectile_type = /obj/item/projectile/beam/weak/minigun
- e_cost = 10
- fire_sound = 'sound/weapons/gatling.ogg'
- click_cooldown_override = 1
diff --git a/code/modules/projectiles/guns/energy/minigun.dm b/code/modules/projectiles/guns/energy/minigun.dm
deleted file mode 100644
index d903cda47c..0000000000
--- a/code/modules/projectiles/guns/energy/minigun.dm
+++ /dev/null
@@ -1,149 +0,0 @@
-//The ammo/gun is stored in a back slot item
-/obj/item/minigunpack2
- name = " Laser Gatling Pack"
- desc = "A massive battery pack with an attached laser gatling gun!"
- icon = 'icons/obj/guns/minigun.dmi'
- icon_state = "holstered"
- item_state = "backpack"
- lefthand_file = 'icons/mob/inhands/equipment/backpack_lefthand.dmi'
- righthand_file = 'icons/mob/inhands/equipment/backpack_righthand.dmi'
- slot_flags = ITEM_SLOT_BACK
- w_class = WEIGHT_CLASS_HUGE
- var/obj/item/gun/energy/minigun/gun
- var/armed = 0 //whether the gun is attached, 0 is attached, 1 is the gun is wielded.
- var/overheat = 0
- var/overheat_max = 60
- var/heat_diffusion = 5
-
-/obj/item/minigunpack2/Initialize()
- . = ..()
- gun = new(src)
- START_PROCESSING(SSobj, src)
-
-/obj/item/minigunpack2/Destroy()
- STOP_PROCESSING(SSobj, src)
- return ..()
-
-/obj/item/minigunpack2/process()
- overheat = max(0, overheat - heat_diffusion)
-
-//ATTACK HAND IGNORING PARENT RETURN VALUE
-/obj/item/minigunpack2/attack_hand(var/mob/living/carbon/user)
- if(src.loc == user)
- if(!armed)
- if(user.get_item_by_slot(SLOT_BACK) == src)
- armed = 1
- if(!user.put_in_hands(gun))
- armed = 0
- to_chat(user, "You need a free hand to hold the gun!")
- return
- update_icon()
- user.update_inv_back()
- else
- to_chat(user, "You are already holding the gun!")
- else
- ..()
-
-/obj/item/minigunpack2/attackby(obj/item/W, mob/user, params)
- if(W == gun) //Don't need armed check, because if you have the gun assume its armed.
- user.dropItemToGround(gun, TRUE)
- else
- ..()
-
-/obj/item/minigunpack2/dropped(mob/user)
- if(armed)
- user.dropItemToGround(gun, TRUE)
-
-/obj/item/minigunpack2/MouseDrop(atom/over_object)
- . = ..()
- if(armed)
- return
- if(iscarbon(usr))
- var/mob/M = usr
-
- if(!over_object)
- return
-
- if(!M.incapacitated())
-
- if(istype(over_object, /obj/screen/inventory/hand))
- var/obj/screen/inventory/hand/H = over_object
- M.putItemFromInventoryInHandIfPossible(src, H.held_index)
-
-
-/obj/item/minigunpack2/update_icon()
- if(armed)
- icon_state = "notholstered"
- else
- icon_state = "holstered"
-
-/obj/item/minigunpack2/proc/attach_gun(var/mob/user)
- if(!gun)
- gun = new(src)
- gun.forceMove(src)
- armed = 0
- if(user)
- to_chat(user, "You attach the [gun.name] to the [name].")
- else
- src.visible_message("The [gun.name] snaps back onto the [name]!")
- update_icon()
- user.update_inv_back()
-
-
-/obj/item/gun/energy/minigun
- name = "laser gatling gun"
- desc = "An advanced laser cannon with an incredible rate of fire. Requires a bulky backpack power source to use."
- icon = 'icons/obj/guns/minigun.dmi'
- icon_state = "minigun_spin"
- item_state = "minigun"
- flags_1 = CONDUCT_1
- force = 15
- recoil = 2
- slowdown = 1
- slot_flags = null
- w_class = WEIGHT_CLASS_HUGE
- materials = list()
- ammo_type = list(/obj/item/ammo_casing/energy/laser/weak)
- burst_size = 2
- automatic = 1
- can_charge = 0
- selfcharge = EGUN_SELFCHARGE
- charge_tick = 2
- charge_delay = 5
- weapon_weight = WEAPON_HEAVY
- item_flags = NEEDS_PERMIT | SLOWS_WHILE_IN_HAND
- var/obj/item/minigunpack2/ammo_pack
-
-/obj/item/gun/energy/minigun/Initialize()
- if(istype(loc, /obj/item/minigunpack2)) //We should spawn inside an ammo pack so let's use that one.
- ammo_pack = loc
- else
- return INITIALIZE_HINT_QDEL //No pack, no gun
-
- return ..()
-
-/obj/item/gun/energy/minigun/attack_self(mob/living/user)
- return
-
-/obj/item/gun/energy/minigun/dropped(mob/user)
- if(ammo_pack)
- ammo_pack.attach_gun(user)
- else
- qdel(src)
-
-/obj/item/gun/energy/minigun/process_fire(atom/target, mob/living/user, message = TRUE, params = null, zone_override = "", bonus_spread = 0)
- if(ammo_pack)
- if(ammo_pack.overheat < ammo_pack.overheat_max)
- ammo_pack.overheat += burst_size
- ..()
- else
- to_chat(user, "The gun's heat sensor locked the trigger to prevent lens damage.")
-
-/obj/item/gun/energy/minigun/afterattack(atom/target, mob/living/user, flag, params)
- if(!ammo_pack || ammo_pack.loc != user)
- to_chat(user, "You need the backpack power source to fire the gun!")
- . = ..()
-
-/obj/item/gun/energy/minigun/dropped(mob/living/user)
- ammo_pack.attach_gun(user)
-
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/beams.dm b/code/modules/projectiles/projectile/beams.dm
index d8154b367d..e43eb5a3bc 100644
--- a/code/modules/projectiles/projectile/beams.dm
+++ b/code/modules/projectiles/projectile/beams.dm
@@ -39,14 +39,6 @@
/obj/item/projectile/beam/weak
damage = 15
-/obj/item/projectile/beam/weak/minigun
- damage = 12.5
- armour_penetration = 40
-
-/obj/item/projectile/beam/weak/minigun/Initialize()
- .=..()
- speed = pick(0.7,0.75,0.8,0.85,0.9,0.95,1,1.05,1.1,1.15)
-
/obj/item/projectile/beam/weak/penetrator
armour_penetration = 50
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/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/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-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-9524.yml b/html/changelogs/AutoChangeLog-pr-9524.yml
new file mode 100644
index 0000000000..df1ff4959a
--- /dev/null
+++ b/html/changelogs/AutoChangeLog-pr-9524.yml
@@ -0,0 +1,7 @@
+author: "Linzolle"
+delete-after: True
+changes:
+ - rscadd: "Decorative and insect wings can now be coloured individually, similar to horns."
+ - bugfix: "people getting assigned wings if their savefile is old."
+ - rscdel: "wings that take the hair colour. Unnecessary if you can just set the colour."
+ - tweak: "Cannot make horns pure black. Trying to do so will set it to a default value."
diff --git a/html/changelogs/AutoChangeLog-pr-9525.yml b/html/changelogs/AutoChangeLog-pr-9525.yml
new file mode 100644
index 0000000000..a77b9e28b2
--- /dev/null
+++ b/html/changelogs/AutoChangeLog-pr-9525.yml
@@ -0,0 +1,4 @@
+author: "Linzolle"
+delete-after: True
+changes:
+ - bugfix: "decorative angel wings being invisible"
diff --git a/html/changelogs/AutoChangeLog-pr-9536.yml b/html/changelogs/AutoChangeLog-pr-9536.yml
new file mode 100644
index 0000000000..ffac8e8f6f
--- /dev/null
+++ b/html/changelogs/AutoChangeLog-pr-9536.yml
@@ -0,0 +1,4 @@
+author: "r4d6"
+delete-after: True
+changes:
+ - tweak: "Change the SEVA suit & Exo-suit's descriptions"
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-9540.yml b/html/changelogs/AutoChangeLog-pr-9540.yml
new file mode 100644
index 0000000000..8dd4e46bc6
--- /dev/null
+++ b/html/changelogs/AutoChangeLog-pr-9540.yml
@@ -0,0 +1,4 @@
+author: "YakumoChen"
+delete-after: True
+changes:
+ - rscdel: "Reverted laser miniguns."
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/icons/mob/wings.dmi b/icons/mob/wings.dmi
index 58f4cb735c..105da7d865 100644
Binary files a/icons/mob/wings.dmi and b/icons/mob/wings.dmi differ
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/sound/weapons/gatling.ogg b/sound/weapons/gatling.ogg
deleted file mode 100644
index 0f8045560d..0000000000
Binary files a/sound/weapons/gatling.ogg and /dev/null differ
diff --git a/tgstation.dme b/tgstation.dme
index 7dfecc28d4..0a0adc78e4 100755
--- a/tgstation.dme
+++ b/tgstation.dme
@@ -2492,7 +2492,6 @@
#include "code\modules\projectiles\guns\energy\kinetic_accelerator.dm"
#include "code\modules\projectiles\guns\energy\laser.dm"
#include "code\modules\projectiles\guns\energy\megabuster.dm"
-#include "code\modules\projectiles\guns\energy\minigun.dm"
#include "code\modules\projectiles\guns\energy\mounted.dm"
#include "code\modules\projectiles\guns\energy\plasma_cit.dm"
#include "code\modules\projectiles\guns\energy\pulse.dm"
@@ -2789,6 +2788,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"
@@ -2808,7 +2808,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"
@@ -3121,7 +3120,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"