diff --git a/code/_onclick/hud/blob_overmind.dm b/code/_onclick/hud/blob_overmind.dm
index 6fe3a781642..1e8f99814df 100644
--- a/code/_onclick/hud/blob_overmind.dm
+++ b/code/_onclick/hud/blob_overmind.dm
@@ -126,7 +126,7 @@
/obj/screen/blob/Split
icon_state = "ui_split"
name = "Split consciousness (100)"
- desc = "Creates another Blob Overmind at the nearest node. One use only.
Offsprings are be unable to use this ability."
+ desc = "Creates another Blob Overmind at the targeted node. One use only.
Offspring are unable to use this ability."
/obj/screen/blob/Split/Click()
if(isovermind(usr))
diff --git a/code/controllers/subsystem/tickets/tickets.dm b/code/controllers/subsystem/tickets/tickets.dm
index dc8b8488d39..1b1735b34c1 100644
--- a/code/controllers/subsystem/tickets/tickets.dm
+++ b/code/controllers/subsystem/tickets/tickets.dm
@@ -337,8 +337,8 @@ UI STUFF
return TRUE
//Sends a message to the designated staff
-/datum/controller/subsystem/tickets/proc/message_staff(var/msg)
- message_adminTicket(msg)
+/datum/controller/subsystem/tickets/proc/message_staff(var/msg, var/alt = FALSE)
+ message_adminTicket(msg, alt)
/datum/controller/subsystem/tickets/Topic(href, href_list)
@@ -406,5 +406,8 @@ UI STUFF
/datum/controller/subsystem/tickets/proc/takeTicket(var/index)
if(assignStaffToTicket(usr.client, index))
- message_staff("[usr.client] / ([usr]) has taken [ticket_name] number [index]")
+ if(span_class == "mentorhelp")
+ message_staff("[usr.client] / ([usr]) has taken [ticket_name] number [index]")
+ else
+ message_staff("[usr.client] / ([usr]) has taken [ticket_name] number [index]", TRUE)
to_chat_safe(returnClient(index), "Your [ticket_name] is being handled by [usr.client].")
diff --git a/code/datums/spell.dm b/code/datums/spell.dm
index 3d00394d278..d8c7b26554c 100644
--- a/code/datums/spell.dm
+++ b/code/datums/spell.dm
@@ -62,6 +62,7 @@ var/list/spells = typesof(/obj/effect/proc_holder/spell) //needed for the badmin
var/charge_type = "recharge" //can be recharge or charges, see charge_max and charge_counter descriptions; can also be based on the holder's vars now, use "holder_var" for that
var/charge_max = 100 //recharge time in deciseconds if charge_type = "recharge" or starting charges if charge_type = "charges"
+ var/starts_charged = TRUE //Does this spell start ready to go?
var/charge_counter = 0 //can only cast spells if it equals recharge, ++ each decisecond if charge_type = "recharge" or -- each cast if charge_type = "charges"
var/still_recharging_msg = "The spell is still recharging."
@@ -195,9 +196,11 @@ var/list/spells = typesof(/obj/effect/proc_holder/spell) //needed for the badmin
/obj/effect/proc_holder/spell/New()
..()
action = new(src)
-
still_recharging_msg = "[name] is still recharging."
- charge_counter = charge_max
+ if(starts_charged)
+ charge_counter = charge_max
+ else
+ start_recharge()
/obj/effect/proc_holder/spell/Destroy()
QDEL_NULL(action)
@@ -214,9 +217,14 @@ var/list/spells = typesof(/obj/effect/proc_holder/spell) //needed for the badmin
/obj/effect/proc_holder/spell/proc/start_recharge()
if(action)
action.UpdateButtonIcon()
- while(charge_counter < charge_max)
- sleep(1)
- charge_counter++
+ START_PROCESSING(SSfastprocess, src)
+
+/obj/effect/proc_holder/spell/process()
+ charge_counter += 2
+ if(charge_counter < charge_max)
+ return
+ STOP_PROCESSING(SSfastprocess, src)
+ charge_counter = charge_max
if(action)
action.UpdateButtonIcon()
diff --git a/code/game/atoms.dm b/code/game/atoms.dm
index f49cf05197a..889f32b3aee 100644
--- a/code/game/atoms.dm
+++ b/code/game/atoms.dm
@@ -337,6 +337,9 @@
if(AM && isturf(AM.loc))
step(AM, turn(AM.dir, 180))
+/atom/proc/get_spooked()
+ return
+
/atom/proc/add_hiddenprint(mob/living/M as mob)
if(isnull(M)) return
if(isnull(M.key)) return
@@ -655,7 +658,7 @@ var/list/blood_splatter_icons = list()
if(V.type == type)
V.reagents.add_reagent(vomit_reagent, 5)
return
-
+
var/obj/effect/decal/cleanable/vomit/this = new type(src)
// Make toxins vomit look different
diff --git a/code/game/gamemodes/blob/blobs/core.dm b/code/game/gamemodes/blob/blobs/core.dm
index 0482a8e19ae..91c6df639e5 100644
--- a/code/game/gamemodes/blob/blobs/core.dm
+++ b/code/game/gamemodes/blob/blobs/core.dm
@@ -105,7 +105,11 @@
spawn()
if(!new_overmind)
- candidates = pollCandidates("Do you want to play as a blob?", ROLE_BLOB, 1)
+ if(is_offspring)
+ candidates = pollCandidates("Do you want to play as a blob offspring?", ROLE_BLOB, 1)
+ else
+ candidates = pollCandidates("Do you want to play as a blob?", ROLE_BLOB, 1)
+
if(candidates.len)
C = pick(candidates)
else
@@ -123,7 +127,6 @@
if(is_offspring)
B.is_offspring = TRUE
-
/obj/structure/blob/core/proc/lateblobtimer()
addtimer(CALLBACK(src, .proc/lateblobcheck), 50)
diff --git a/code/game/gamemodes/blob/powers.dm b/code/game/gamemodes/blob/powers.dm
index 5eb15759d99..2743277edb7 100644
--- a/code/game/gamemodes/blob/powers.dm
+++ b/code/game/gamemodes/blob/powers.dm
@@ -350,31 +350,32 @@
BS.Goto(pick(surrounding_turfs), BS.move_to_delay)
return
-
/mob/camera/blob/verb/split_consciousness()
set category = "Blob"
set name = "Split consciousness (100) (One use)"
set desc = "Expend resources to attempt to produce another sentient overmind."
+ var/turf/T = get_turf(src)
+ if(!T)
+ return
if(split_used)
to_chat(src, "You have already produced an offspring.")
return
if(is_offspring)
to_chat(src, "You cannot split as an offspring of another Blob.")
return
- if(!blob_nodes || !blob_nodes.len)
- to_chat(src, "A node is required to birth your offspring...")
- return
- var/obj/structure/blob/node/N = locate(/obj/structure/blob) in blob_nodes
- if(!N)
- to_chat(src, "A node is required to birth your offspring...")
- return
+ var/obj/structure/blob/N = (locate(/obj/structure/blob) in T)
+ if(!N)
+ to_chat(src, "A node is required to birth your offspring.")
+ return
+ if(!istype(N, /obj/structure/blob/node))
+ to_chat(src, "A node is required to birth your offspring.")
+ return
if(!can_buy(100))
return
split_used = TRUE
-
new /obj/structure/blob/core/ (get_turf(N), 200, null, blob_core.point_rate, "offspring")
qdel(N)
@@ -382,7 +383,6 @@
var/datum/game_mode/blob/BL = SSticker.mode
BL.blobwincount += initial(BL.blobwincount)
-
/mob/camera/blob/verb/blob_broadcast()
set category = "Blob"
set name = "Blob Broadcast"
diff --git a/code/game/gamemodes/changeling/evolution_menu.dm b/code/game/gamemodes/changeling/evolution_menu.dm
index e8d266d2dd5..b6a0213f82f 100644
--- a/code/game/gamemodes/changeling/evolution_menu.dm
+++ b/code/game/gamemodes/changeling/evolution_menu.dm
@@ -18,7 +18,6 @@ var/list/sting_paths
var/dat = create_menu(changeling)
usr << browse(dat, "window=powers;size=600x700")//900x480
-
/datum/action/changeling/evolution_menu/proc/create_menu(var/datum/changeling/changeling)
var/dat
dat +="
Changeling Evolution Menu"
@@ -298,12 +297,10 @@ var/list/sting_paths
/////
/datum/changeling/proc/purchasePower(var/mob/living/carbon/user, var/sting_name)
-
var/datum/action/changeling/thepower = null
+ var/list/all_powers = init_subtypes(/datum/action/changeling)
- if(!sting_paths)
- sting_paths = init_subtypes(/datum/action/changeling)
- for(var/datum/action/changeling/cling_sting in sting_paths)
+ for(var/datum/action/changeling/cling_sting in all_powers)
if(cling_sting.name == sting_name)
thepower = cling_sting
@@ -344,21 +341,19 @@ var/list/sting_paths
to_chat(user, "We have removed our evolutions from this form, and are now ready to readapt.")
user.remove_changeling_powers(1)
canrespec = 0
- user.make_changeling()
+ user.make_changeling(FALSE)
return 1
else
to_chat(user, "You lack the power to readapt your evolutions!")
return 0
-/mob/proc/make_changeling()
+/mob/proc/make_changeling(var/get_free_powers = TRUE)
if(!mind)
return
if(!ishuman(src))
return
if(!mind.changeling)
mind.changeling = new /datum/changeling(gender)
- if(!sting_paths)
- sting_paths = init_subtypes(/datum/action/changeling)
if(mind.changeling.purchasedpowers)
remove_changeling_powers(1)
@@ -367,13 +362,23 @@ var/list/sting_paths
for(var/language in languages)
mind.changeling.absorbed_languages |= language
- // purchase free powers.
- for(var/datum/action/changeling/path in sting_paths)
- //var/datum/action/changeling/S = new path()
- if(!path.dna_cost)
- if(!mind.changeling.has_sting(path))
- mind.changeling.purchasedpowers += path
- path.on_purchase(src)
+ if(get_free_powers)
+ var/list/all_powers = init_subtypes(/datum/action/changeling)
+ for(var/datum/action/changeling/path in all_powers) // purchase free powers.
+ if(!path.dna_cost)
+ if(!mind.changeling.has_sting(path))
+ mind.changeling.purchasedpowers += path
+ path.on_purchase(src)
+ else //for respec
+ var/datum/action/changeling/hivemind_upload/S1 = new
+ if(!mind.changeling.has_sting(S1))
+ mind.changeling.purchasedpowers+=S1
+ S1.Grant(src)
+
+ var/datum/action/changeling/hivemind_download/S2 = new
+ if(!mind.changeling.has_sting(S2))
+ mind.changeling.purchasedpowers+=S2
+ S2.Grant(src)
var/mob/living/carbon/C = src //only carbons have dna now, so we have to typecaste
mind.changeling.absorbed_dna |= C.dna.Clone()
diff --git a/code/game/machinery/adv_med.dm b/code/game/machinery/adv_med.dm
index 679af70526e..b7e24014f1e 100644
--- a/code/game/machinery/adv_med.dm
+++ b/code/game/machinery/adv_med.dm
@@ -459,8 +459,8 @@
organData["germ_level"] = I.germ_level
organData["damage"] = I.damage
organData["maxHealth"] = I.max_damage
- organData["bruised"] = I.min_broken_damage
- organData["broken"] = I.min_bruised_damage
+ organData["bruised"] = I.min_bruised_damage
+ organData["broken"] = I.min_broken_damage
organData["robotic"] = I.is_robotic()
organData["dead"] = (I.status & ORGAN_DEAD)
diff --git a/code/game/machinery/cryopod.dm b/code/game/machinery/cryopod.dm
index 0ab3d01ddf1..17965c12f4c 100644
--- a/code/game/machinery/cryopod.dm
+++ b/code/game/machinery/cryopod.dm
@@ -231,9 +231,9 @@
/obj/item/reagent_containers/hypospray/CMO,
/obj/item/clothing/accessory/medal/gold/captain,
/obj/item/clothing/gloves/color/black/krav_maga/sec,
- /obj/item/storage/internal,
/obj/item/spacepod_key,
- /obj/item/nullrod
+ /obj/item/nullrod,
+ /obj/item/key
)
// These items will NOT be preserved
var/list/do_not_preserve_items = list (
diff --git a/code/game/machinery/status_display.dm b/code/game/machinery/status_display.dm
index 05545e6a3d1..642676c6eff 100644
--- a/code/game/machinery/status_display.dm
+++ b/code/game/machinery/status_display.dm
@@ -78,6 +78,9 @@
set_picture("ai_bsod")
..(severity)
+/obj/machinery/status_display/get_spooked()
+ spookymode = TRUE
+
// set what is displayed
/obj/machinery/status_display/proc/update()
if(friendc && !ignore_friendc)
@@ -227,6 +230,9 @@
set_picture("ai_bsod")
..(severity)
+/obj/machinery/ai_status_display/get_spooked()
+ spookymode = TRUE
+
/obj/machinery/ai_status_display/proc/update()
if(mode==0) //Blank
overlays.Cut()
diff --git a/code/game/machinery/vending.dm b/code/game/machinery/vending.dm
index dc4b9124d77..4e8074581bf 100644
--- a/code/game/machinery/vending.dm
+++ b/code/game/machinery/vending.dm
@@ -738,7 +738,7 @@
break
if(!throw_item)
return
- throw_item.throw_at(target, 16, 3, src)
+ throw_item.throw_at(target, 16, 3)
visible_message("[src] launches [throw_item.name] at [target.name]!")
/obj/machinery/vending/onTransitZ()
diff --git a/code/game/objects/items/robot/robot_upgrades.dm b/code/game/objects/items/robot/robot_upgrades.dm
index 0b9f6c3aca9..a13bce6fb61 100644
--- a/code/game/objects/items/robot/robot_upgrades.dm
+++ b/code/game/objects/items/robot/robot_upgrades.dm
@@ -31,31 +31,9 @@
if(..())
return
- R.notify_ai(2)
+ R.reset_module()
- R.uneq_all()
- R.sight_mode = null
- R.hands.icon_state = "nomod"
- R.icon_state = "robot"
- R.module.remove_subsystems_and_actions(R)
- QDEL_NULL(R.module)
-
- R.camera.network.Remove(list("Engineering", "Medical", "Mining Outpost"))
- R.rename_character(R.real_name, R.get_default_name("Default"))
- R.languages = list()
- R.speech_synthesizer_langs = list()
-
- R.update_icons()
- R.update_headlamp()
-
- R.speed = 0 // Remove upgrades.
- R.ionpulse = 0
- R.magpulse = 0
- R.add_language("Robot Talk", 1)
-
- R.status_flags |= CANPUSH
-
- return 1
+ return TRUE
/obj/item/borg/upgrade/rename
name = "cyborg reclassification board"
diff --git a/code/game/objects/items/weapons/handcuffs.dm b/code/game/objects/items/weapons/handcuffs.dm
index 6fa0c875333..28e73f29317 100644
--- a/code/game/objects/items/weapons/handcuffs.dm
+++ b/code/game/objects/items/weapons/handcuffs.dm
@@ -24,6 +24,10 @@
if(!istype(C))
return
+ if(flags & NODROP)
+ to_chat(user, "[src] is stuck to your hand!")
+ return
+
if((CLUMSY in user.mutations) && prob(50) && (!ignoresClumsy))
to_chat(user, "Uh... how do those things work?!")
apply_cuffs(user, user)
diff --git a/code/game/turfs/turf.dm b/code/game/turfs/turf.dm
index 5e214e87d80..993cb458777 100644
--- a/code/game/turfs/turf.dm
+++ b/code/game/turfs/turf.dm
@@ -299,6 +299,10 @@
/turf/proc/Bless()
flags |= NOJAUNT
+/turf/get_spooked()
+ for(var/atom/movable/AM in contents)
+ AM.get_spooked()
+
/turf/proc/burn_down()
return
diff --git a/code/modules/admin/admin.dm b/code/modules/admin/admin.dm
index 2a981e8b9c4..1a9f38b1486 100644
--- a/code/modules/admin/admin.dm
+++ b/code/modules/admin/admin.dm
@@ -21,8 +21,11 @@ var/global/nologevent = 0
to_chat(C, msg)
-/proc/message_adminTicket(var/msg)
- msg = "ADMIN TICKET: [msg]"
+/proc/message_adminTicket(var/msg, var/alt = FALSE)
+ if(alt)
+ msg = "ADMIN TICKET: [msg]"
+ else
+ msg = "ADMIN TICKET: [msg]"
for(var/client/C in GLOB.admins)
if(R_ADMIN & C.holder.rights)
if(C.prefs && !(C.prefs.toggles & CHAT_NO_TICKETLOGS))
diff --git a/code/modules/clothing/masks/breath.dm b/code/modules/clothing/masks/breath.dm
index 55c305cf449..401e3dd949a 100644
--- a/code/modules/clothing/masks/breath.dm
+++ b/code/modules/clothing/masks/breath.dm
@@ -10,14 +10,15 @@
permeability_coefficient = 0.50
actions_types = list(/datum/action/item_action/adjust)
burn_state = FIRE_PROOF
- species_fit = list("Vox", "Unathi", "Tajaran", "Vulpkanin", "Grey" )
+ species_fit = list("Vox", "Unathi", "Tajaran", "Vulpkanin", "Grey", "Plasmaman" )
sprite_sheets = list(
"Vox" = 'icons/mob/species/vox/mask.dmi',
"Unathi" = 'icons/mob/species/unathi/mask.dmi',
"Tajaran" = 'icons/mob/species/tajaran/mask.dmi',
"Vulpkanin" = 'icons/mob/species/vulpkanin/mask.dmi',
"Grey" = 'icons/mob/species/grey/mask.dmi',
- "Drask" = 'icons/mob/species/drask/mask.dmi'
+ "Drask" = 'icons/mob/species/drask/mask.dmi',
+ "Plasmaman" = 'icons/mob/species/plasmaman/mask.dmi'
)
/obj/item/clothing/mask/breath/attack_self(var/mob/user)
diff --git a/code/modules/clothing/masks/gasmask.dm b/code/modules/clothing/masks/gasmask.dm
index 757af55d4a3..5393fe9f18f 100644
--- a/code/modules/clothing/masks/gasmask.dm
+++ b/code/modules/clothing/masks/gasmask.dm
@@ -10,14 +10,15 @@
gas_transfer_coefficient = 0.01
permeability_coefficient = 0.01
burn_state = FIRE_PROOF
- species_fit = list("Vox", "Unathi", "Tajaran", "Vulpkanin", "Grey")
+ species_fit = list("Vox", "Unathi", "Tajaran", "Vulpkanin", "Grey", "Plasmaman" )
sprite_sheets = list(
"Vox" = 'icons/mob/species/vox/mask.dmi',
"Unathi" = 'icons/mob/species/unathi/mask.dmi',
"Tajaran" = 'icons/mob/species/tajaran/mask.dmi',
"Vulpkanin" = 'icons/mob/species/vulpkanin/mask.dmi',
"Drask" = 'icons/mob/species/drask/mask.dmi',
- "Grey" = 'icons/mob/species/grey/mask.dmi'
+ "Grey" = 'icons/mob/species/grey/mask.dmi',
+ "Plasmaman" = 'icons/mob/species/plasmaman/mask.dmi'
)
// **** Welding gas mask ****
diff --git a/code/modules/mob/dead/observer/spells.dm b/code/modules/mob/dead/observer/spells.dm
index 620c1854e73..916ff9aa9b8 100644
--- a/code/modules/mob/dead/observer/spells.dm
+++ b/code/modules/mob/dead/observer/spells.dm
@@ -1,6 +1,4 @@
-
-
-var/global/list/boo_phrases=list(
+GLOBAL_LIST_INIT(boo_phrases, list(
"You feel a chill run down your spine.",
"You think you see a figure in your peripheral vision.",
"What was that?",
@@ -9,16 +7,17 @@ var/global/list/boo_phrases=list(
"Something doesn't feel right...",
"You feel a presence in the room.",
"It feels like someone's standing behind you.",
-)
+))
/obj/effect/proc_holder/spell/aoe_turf/boo
name = "Boo!"
desc = "Fuck with the living."
- ghost = 1
+ ghost = TRUE
school = "transmutation"
charge_max = 600
+ starts_charged = FALSE
clothes_req = 0
stat_allowed = 1
invocation = ""
@@ -27,26 +26,4 @@ var/global/list/boo_phrases=list(
/obj/effect/proc_holder/spell/aoe_turf/boo/cast(list/targets, mob/user = usr)
for(var/turf/T in targets)
- for(var/atom/A in T.contents)
-
- // Bug humans
- if(ishuman(A))
- var/mob/living/carbon/human/H = A
- if(H && H.client)
- to_chat(H, "[pick(boo_phrases)]")
-
- // Flicker unblessed lights in range
- if(istype(A,/obj/machinery/light))
- var/obj/machinery/light/L = A
- if(L)
- L.flicker()
-
- // OH GOD BLUE APC (single animation cycle)
- if(istype(A, /obj/machinery/power/apc))
- A:spookify()
-
- if(istype(A, /obj/machinery/status_display))
- A:spookymode=1
-
- if(istype(A, /obj/machinery/ai_status_display))
- A:spookymode=1
\ No newline at end of file
+ T.get_spooked()
diff --git a/code/modules/mob/living/carbon/human/human.dm b/code/modules/mob/living/carbon/human/human.dm
index e497fd04814..2cd524f8a15 100644
--- a/code/modules/mob/living/carbon/human/human.dm
+++ b/code/modules/mob/living/carbon/human/human.dm
@@ -2003,6 +2003,9 @@ Eyes need to have significantly high darksight to shine unless the mob has the X
genemutcheck(src, block, null, MUTCHK_FORCED)
dna.UpdateSE()
+/mob/living/carbon/human/get_spooked()
+ to_chat(src, "[pick(GLOB.boo_phrases)]")
+
/mob/living/carbon/human/extinguish_light()
// Parent function handles stuff the human may be holding
..()
diff --git a/code/modules/mob/living/carbon/human/inventory.dm b/code/modules/mob/living/carbon/human/inventory.dm
index e68f5652b01..47dd5622379 100644
--- a/code/modules/mob/living/carbon/human/inventory.dm
+++ b/code/modules/mob/living/carbon/human/inventory.dm
@@ -44,9 +44,9 @@
return has_organ("chest")
if(slot_wear_id)
// the only relevant check for this is the uniform check
- return 1
+ return TRUE
if(slot_wear_pda)
- return 1
+ return TRUE
if(slot_l_ear)
return has_organ("head")
if(slot_r_ear)
@@ -70,9 +70,9 @@
if(slot_s_store)
return has_organ("chest")
if(slot_in_backpack)
- return 1
+ return TRUE
if(slot_tie)
- return 1
+ return TRUE
// The actual dropping happens at the mob level - checks to prevent drops should
// come here
@@ -421,56 +421,34 @@
/mob/living/carbon/human/can_equip(obj/item/I, slot, disable_warning = 0)
switch(dna.species.handle_can_equip(I, slot, disable_warning, src))
- if(1) return 1
- if(2) return 0 //if it returns 2, it wants no normal handling
-
+ if(1) return TRUE
+ if(2) return FALSE //if it returns 2, it wants no normal handling
+ if(!has_organ_for_slot(slot))
+ return FALSE
+
if(istype(I, /obj/item/clothing/under) || istype(I, /obj/item/clothing/suit))
if(FAT in mutations)
//testing("[M] TOO FAT TO WEAR [src]!")
if(!(I.flags_size & ONESIZEFITSALL))
if(!disable_warning)
to_chat(src, "You're too fat to wear the [I].")
- return 0
+ return FALSE
switch(slot)
if(slot_l_hand)
- if(l_hand)
- return 0
- return !incapacitated()
+ return !l_hand && !incapacitated()
if(slot_r_hand)
- if(r_hand)
- return 0
- return !incapacitated()
+ return !r_hand && !incapacitated()
if(slot_wear_mask)
- if(wear_mask)
- return 0
- if(!(I.slot_flags & SLOT_MASK))
- return 0
- return 1
+ return !wear_mask && (I.slot_flags & SLOT_MASK)
if(slot_back)
- if(back)
- return 0
- if(!(I.slot_flags & SLOT_BACK))
- return 0
- return 1
+ return !back && (I.slot_flags & SLOT_BACK)
if(slot_wear_suit)
- if(wear_suit)
- return 0
- if(!(I.slot_flags & SLOT_OCLOTHING))
- return 0
- return 1
+ return !wear_suit && (I.slot_flags & SLOT_OCLOTHING)
if(slot_gloves)
- if(gloves)
- return 0
- if(!(I.slot_flags & SLOT_GLOVES))
- return 0
- return 1
+ return !gloves && (I.slot_flags & SLOT_GLOVES)
if(slot_shoes)
- if(shoes)
- return 0
- if(!(I.slot_flags & SLOT_FEET))
- return 0
- return 1
+ return !shoes && (I.slot_flags & SLOT_FEET)
if(slot_belt)
if(belt)
return 0
@@ -482,39 +460,15 @@
return
return 1
if(slot_glasses)
- if(glasses)
- return 0
- if(!(I.slot_flags & SLOT_EYES))
- return 0
- return 1
+ return !glasses && (I.slot_flags & SLOT_EYES)
if(slot_head)
- if(head)
- return 0
- if(!(I.slot_flags & SLOT_HEAD))
- return 0
- return 1
+ return !head && (I.slot_flags & SLOT_HEAD)
if(slot_l_ear)
- if(l_ear)
- return 0
- if(!(I.slot_flags & SLOT_EARS))
- return 0
- if((I.slot_flags & SLOT_TWOEARS) && r_ear )
- return 0
- return 1
+ return !l_ear && (I.slot_flags & SLOT_EARS) && !((I.slot_flags & SLOT_TWOEARS) && r_ear)
if(slot_r_ear)
- if(r_ear)
- return 0
- if(!(I.slot_flags & SLOT_EARS))
- return 0
- if((I.slot_flags & SLOT_TWOEARS) && l_ear)
- return 0
- return 1
+ return !r_ear && (I.slot_flags & SLOT_EARS) && !((I.slot_flags & SLOT_TWOEARS) && l_ear)
if(slot_w_uniform)
- if(w_uniform)
- return 0
- if(!(I.slot_flags & SLOT_ICLOTHING))
- return 0
- return 1
+ return !w_uniform && (I.slot_flags & SLOT_ICLOTHING)
if(slot_wear_id)
if(wear_id)
return 0
@@ -583,17 +537,9 @@
return 1
return 0
if(slot_handcuffed)
- if(handcuffed)
- return 0
- if(!istype(I, /obj/item/restraints/handcuffs))
- return 0
- return 1
+ return !handcuffed && istype(I, /obj/item/restraints/handcuffs)
if(slot_legcuffed)
- if(legcuffed)
- return 0
- if(!istype(I, /obj/item/restraints/legcuffs))
- return 0
- return 1
+ return !legcuffed && istype(I, /obj/item/restraints/legcuffs)
if(slot_in_backpack)
if(back && istype(back, /obj/item/storage/backpack))
var/obj/item/storage/backpack/B = back
diff --git a/code/modules/mob/living/carbon/human/species/monkey.dm b/code/modules/mob/living/carbon/human/species/monkey.dm
index cac42a29cd2..7eedf2520a3 100644
--- a/code/modules/mob/living/carbon/human/species/monkey.dm
+++ b/code/modules/mob/living/carbon/human/species/monkey.dm
@@ -59,6 +59,8 @@
genemutcheck(H, MONKEYBLOCK, null, MUTCHK_FORCED)
/datum/species/monkey/handle_can_equip(obj/item/I, slot, disable_warning = 0, mob/living/carbon/human/user)
+ if(!user.has_organ_for_slot(slot))
+ return 2
switch(slot)
if(slot_l_hand)
if(user.l_hand)
diff --git a/code/modules/mob/living/login.dm b/code/modules/mob/living/login.dm
index d8e27df91fe..580996e54d9 100644
--- a/code/modules/mob/living/login.dm
+++ b/code/modules/mob/living/login.dm
@@ -18,6 +18,14 @@
if(ranged_ability)
ranged_ability.add_ranged_ability(src, "You currently have [ranged_ability] active!")
+ //for when action buttons are lost and need to be regained, such as when the mind enters a new mob
+ var/datum/changeling/changeling = usr.mind.changeling
+ if(changeling)
+ for(var/power in changeling.purchasedpowers)
+ var/datum/action/changeling/S = power
+ if(istype(S) && S.needs_button)
+ S.Grant(src)
+
//Should update regardless of if we can ventcrawl, since we can end up in pipes in other ways.
update_pipe_vision()
diff --git a/code/modules/mob/living/silicon/robot/robot.dm b/code/modules/mob/living/silicon/robot/robot.dm
index 7521270346e..100dd1ffbba 100644
--- a/code/modules/mob/living/silicon/robot/robot.dm
+++ b/code/modules/mob/living/silicon/robot/robot.dm
@@ -289,7 +289,7 @@ var/list/robot_verbs_default = list(
if(islist(force_modules) && force_modules.len)
modules = force_modules.Copy()
if(security_level == (SEC_LEVEL_GAMMA || SEC_LEVEL_EPSILON) || crisis)
- to_chat(src, "Crisis mode active. Combat module available.")
+ to_chat(src, "Crisis mode active. The combat module is now available.")
modules += "Combat"
if(mmi != null && mmi.alien)
modules = list("Hunter")
@@ -417,6 +417,31 @@ var/list/robot_verbs_default = list(
radio.config(module.channels)
notify_ai(2)
+/mob/living/silicon/robot/proc/reset_module()
+ notify_ai(2)
+
+ uneq_all()
+ sight_mode = null
+ hands.icon_state = "nomod"
+ icon_state = "robot"
+ module.remove_subsystems_and_actions(src)
+ QDEL_NULL(module)
+
+ camera.network.Remove(list("Engineering", "Medical", "Mining Outpost"))
+ rename_character(real_name, get_default_name("Default"))
+ languages = list()
+ speech_synthesizer_langs = list()
+
+ update_icons()
+ update_headlamp()
+
+ speed = 0 // Remove upgrades.
+ ionpulse = FALSE
+ magpulse = FALSE
+ add_language("Robot Talk", 1)
+
+ status_flags |= CANPUSH
+
//for borg hotkeys, here module refers to borg inv slot, not core module
/mob/living/silicon/robot/verb/cmd_toggle_module(module as num)
set name = "Toggle Module"
diff --git a/code/modules/mob/living/simple_animal/friendly/mouse.dm b/code/modules/mob/living/simple_animal/friendly/mouse.dm
index 3b9b2d720ca..4faa821701c 100644
--- a/code/modules/mob/living/simple_animal/friendly/mouse.dm
+++ b/code/modules/mob/living/simple_animal/friendly/mouse.dm
@@ -57,7 +57,7 @@
/mob/living/simple_animal/mouse/Life()
..()
- if(prob(0.5))
+ if(prob(0.5) && !ckey)
stat = UNCONSCIOUS
icon_state = "mouse_[mouse_color]_sleep"
wander = 0
@@ -220,4 +220,4 @@
response_harm = "stamps on"
gold_core_spawnable = CHEM_MOB_SPAWN_INVALID
can_collar = 0
- butcher_results = list(/obj/item/stack/sheet/metal = 1)
\ No newline at end of file
+ butcher_results = list(/obj/item/stack/sheet/metal = 1)
diff --git a/code/modules/power/apc.dm b/code/modules/power/apc.dm
index a3186b115a4..4b88ba41ef8 100644
--- a/code/modules/power/apc.dm
+++ b/code/modules/power/apc.dm
@@ -49,7 +49,6 @@
use_power = NO_POWER_USE
req_access = list(access_engine_equip)
siemens_strength = 1
- var/spooky=0
var/area/area
var/areastring = null
var/obj/item/stock_parts/cell/cell
@@ -248,9 +247,9 @@
// update the APC icon to show the three base states
// also add overlays for indicator lights
-/obj/machinery/power/apc/update_icon()
+/obj/machinery/power/apc/update_icon(force_update = FALSE)
- if(!status_overlays)
+ if(!status_overlays || force_update)
status_overlays = 1
status_overlays_lock = new
status_overlays_charging = new
@@ -291,10 +290,10 @@
var/update = check_updates() //returns 0 if no need to update icons.
// 1 if we need to update the icon_state
// 2 if we need to update the overlays
- if(!update)
+ if(!update && !force_update)
return
- if(update & 1) // Updating the icon state
+ if(force_update || update & 1) // Updating the icon state
if(update_state & UPSTATE_ALLGOOD)
icon_state = "apc0"
else if(update_state & (UPSTATE_OPENED1|UPSTATE_OPENED2))
@@ -322,7 +321,7 @@
- if(update & 2)
+ if(force_update || update & 2)
if(overlays.len)
overlays.len = 0
@@ -412,14 +411,17 @@
update_icon()
updating_icon = 0
-/obj/machinery/power/apc/proc/spookify()
- if(spooky) return // Fuck you we're already spooky
- spooky=1
- update_icon()
- spawn(10)
- spooky=0
- update_icon()
-
+/obj/machinery/power/apc/get_spooked(second_pass = FALSE)
+ if(opened || wiresexposed)
+ return
+ if(stat & (NOPOWER | BROKEN))
+ return
+ if(!second_pass) //The first time, we just cut overlays
+ addtimer(CALLBACK(src, .get_spooked, TRUE), 1)
+ cut_overlays()
+ else
+ flick("apcemag", src) //Second time we cause the APC to update its icon, then add a timer to update icon later
+ addtimer(CALLBACK(src, .proc/update_icon, TRUE), 10)
//attack with an item - open/close cover, insert cell, or (un)lock interface
/obj/machinery/power/apc/attackby(obj/item/W, mob/living/user, params)
diff --git a/code/modules/power/lighting.dm b/code/modules/power/lighting.dm
index a0bee89e0be..b186e862f01 100644
--- a/code/modules/power/lighting.dm
+++ b/code/modules/power/lighting.dm
@@ -232,6 +232,9 @@
on = FALSE
return
+/obj/machinery/light/get_spooked()
+ flicker()
+
// update the icon_state and luminosity of the light depending on its state
/obj/machinery/light/proc/update(var/trigger = TRUE)
switch(status)
diff --git a/code/modules/security_levels/security levels.dm b/code/modules/security_levels/security levels.dm
index 050326891fb..3b1e56e0c2d 100644
--- a/code/modules/security_levels/security levels.dm
+++ b/code/modules/security_levels/security levels.dm
@@ -31,6 +31,15 @@
// Mark down this time to prevent shuttle cheese
SSshuttle.emergency_sec_level_time = world.time
+ // Reset gamma borgs if the new security level is lower than Gamma.
+ if(level < SEC_LEVEL_GAMMA)
+ for(var/M in GLOB.silicon_mob_list)
+ if(isrobot(M))
+ var/mob/living/silicon/robot/R = M
+ if(istype(R.module, /obj/item/robot_module/combat) && !R.crisis)
+ R.reset_module()
+ to_chat(R, "Crisis mode deactivated. The combat module is no longer available and your module has been reset.")
+
switch(level)
if(SEC_LEVEL_GREEN)
security_announcement_down.Announce("All threats to the station have passed. All weapons need to be holstered and privacy laws are once again fully enforced.","Attention! Security level lowered to green.")
@@ -176,15 +185,3 @@
return SEC_LEVEL_EPSILON
if("delta")
return SEC_LEVEL_DELTA
-
-
-/*DEBUG
-/mob/verb/set_thing0()
- set_security_level(0)
-/mob/verb/set_thing1()
- set_security_level(1)
-/mob/verb/set_thing2()
- set_security_level(2)
-/mob/verb/set_thing3()
- set_security_level(3)
-*/
diff --git a/html/changelogs/AutoChangeLog-pr-11444.yml b/html/changelogs/AutoChangeLog-pr-11444.yml
new file mode 100644
index 00000000000..08ad07a902d
--- /dev/null
+++ b/html/changelogs/AutoChangeLog-pr-11444.yml
@@ -0,0 +1,4 @@
+author: "Kyep"
+delete-after: True
+changes:
+ - bugfix: "unanchored vending machines will no longer generate a runtime error when throwing products at people."
diff --git a/html/changelogs/AutoChangeLog-pr-11465.yml b/html/changelogs/AutoChangeLog-pr-11465.yml
new file mode 100644
index 00000000000..a38d2a20e15
--- /dev/null
+++ b/html/changelogs/AutoChangeLog-pr-11465.yml
@@ -0,0 +1,4 @@
+author: "farie82"
+delete-after: True
+changes:
+ - bugfix: "Can't use cuffs now while you have antidrop"
diff --git a/html/changelogs/AutoChangeLog-pr-11518.yml b/html/changelogs/AutoChangeLog-pr-11518.yml
new file mode 100644
index 00000000000..0ad85e1e84a
--- /dev/null
+++ b/html/changelogs/AutoChangeLog-pr-11518.yml
@@ -0,0 +1,4 @@
+author: "farie82"
+delete-after: True
+changes:
+ - bugfix: "can_equip now checks if you have the limbs required to equip something"
diff --git a/html/changelogs/AutoChangeLog-pr-11520.yml b/html/changelogs/AutoChangeLog-pr-11520.yml
new file mode 100644
index 00000000000..ffc477deba7
--- /dev/null
+++ b/html/changelogs/AutoChangeLog-pr-11520.yml
@@ -0,0 +1,5 @@
+author: "Citinited"
+delete-after: True
+changes:
+ - bugfix: "Boo affects APCs again"
+ - bugfix: "Boo no longer fully charges when you enter your corpse"
diff --git a/html/changelogs/AutoChangeLog-pr-11521.yml b/html/changelogs/AutoChangeLog-pr-11521.yml
new file mode 100644
index 00000000000..48a73a71cac
--- /dev/null
+++ b/html/changelogs/AutoChangeLog-pr-11521.yml
@@ -0,0 +1,5 @@
+author: "Arkatos"
+delete-after: True
+changes:
+ - tweak: "Blob split consciousness ability now requires you to directly target a node you want to turn into another sentient overmind instead of selecting a nearest one"
+ - spellcheck: "Fixed and improved some descriptions regarding Blob offspring"
diff --git a/html/changelogs/AutoChangeLog-pr-11536.yml b/html/changelogs/AutoChangeLog-pr-11536.yml
new file mode 100644
index 00000000000..0fba2aa34e5
--- /dev/null
+++ b/html/changelogs/AutoChangeLog-pr-11536.yml
@@ -0,0 +1,5 @@
+author: "dovydas12345"
+delete-after: True
+changes:
+ - bugfix: "Fixes cryopod removing ambulance, secway keys"
+ - bugfix: "Fixes cryopod recovering the invisible headpocket item"
diff --git a/html/changelogs/AutoChangeLog-pr-11553.yml b/html/changelogs/AutoChangeLog-pr-11553.yml
new file mode 100644
index 00000000000..9954dccfd28
--- /dev/null
+++ b/html/changelogs/AutoChangeLog-pr-11553.yml
@@ -0,0 +1,4 @@
+author: "Ty-Omaha"
+delete-after: True
+changes:
+ - tweak: "Changed admin take ticket color from neon green to Asay pink"
diff --git a/html/changelogs/AutoChangeLog-pr-11567.yml b/html/changelogs/AutoChangeLog-pr-11567.yml
new file mode 100644
index 00000000000..8e0769768f9
--- /dev/null
+++ b/html/changelogs/AutoChangeLog-pr-11567.yml
@@ -0,0 +1,4 @@
+author: "Couls"
+delete-after: True
+changes:
+ - bugfix: "t-t-t-typo!"
diff --git a/html/changelogs/AutoChangeLog-pr-11573.yml b/html/changelogs/AutoChangeLog-pr-11573.yml
new file mode 100644
index 00000000000..bb4c67a6cc3
--- /dev/null
+++ b/html/changelogs/AutoChangeLog-pr-11573.yml
@@ -0,0 +1,4 @@
+author: "Shadeykins"
+delete-after: True
+changes:
+ - bugfix: "Fixes rogue pixels on breath masks/gas masks for Plasmamen."
diff --git a/html/changelogs/AutoChangeLog-pr-11574.yml b/html/changelogs/AutoChangeLog-pr-11574.yml
new file mode 100644
index 00000000000..0acc59e9621
--- /dev/null
+++ b/html/changelogs/AutoChangeLog-pr-11574.yml
@@ -0,0 +1,4 @@
+author: "Christasmurf"
+delete-after: True
+changes:
+ - bugfix: "Fixes a random pixel on the leather shoes"
diff --git a/html/changelogs/AutoChangeLog-pr-11582.yml b/html/changelogs/AutoChangeLog-pr-11582.yml
new file mode 100644
index 00000000000..455dfcea14e
--- /dev/null
+++ b/html/changelogs/AutoChangeLog-pr-11582.yml
@@ -0,0 +1,4 @@
+author: "uc_guy"
+delete-after: True
+changes:
+ - bugfix: "Fixed \"Venus Human Traps\" being invisible."
diff --git a/html/changelogs/AutoChangeLog-pr-11585.yml b/html/changelogs/AutoChangeLog-pr-11585.yml
new file mode 100644
index 00000000000..053b6deb819
--- /dev/null
+++ b/html/changelogs/AutoChangeLog-pr-11585.yml
@@ -0,0 +1,5 @@
+author: "Arkatos"
+delete-after: True
+changes:
+ - bugfix: "Changelings should now correctly receive their action buttons"
+ - bugfix: "Changelings now do not steal action buttons from other changelings"
diff --git a/icons/mob/animal.dmi b/icons/mob/animal.dmi
index 241af99e460..26cc4faf2ee 100644
Binary files a/icons/mob/animal.dmi and b/icons/mob/animal.dmi differ
diff --git a/icons/mob/feet.dmi b/icons/mob/feet.dmi
index 7fa7b78561d..db20e9a2a79 100644
Binary files a/icons/mob/feet.dmi and b/icons/mob/feet.dmi differ
diff --git a/icons/mob/species/plasmaman/mask.dmi b/icons/mob/species/plasmaman/mask.dmi
new file mode 100644
index 00000000000..1acdc5e581f
Binary files /dev/null and b/icons/mob/species/plasmaman/mask.dmi differ