diff --git a/_maps/map_files/generic/CentCom.dmm b/_maps/map_files/generic/CentCom.dmm
index 4bd268ca2547e..2844ad94387b8 100644
--- a/_maps/map_files/generic/CentCom.dmm
+++ b/_maps/map_files/generic/CentCom.dmm
@@ -4439,6 +4439,11 @@
/area/abductor_ship)
"alj" = (
/obj/structure/closet/abductor,
+/obj/item/reagent_containers/glass/bottle/chloralhydrate,
+/obj/item/reagent_containers/glass/bottle/chloralhydrate,
+/obj/item/reagent_containers/glass/bottle/morphine,
+/obj/item/reagent_containers/glass/bottle/morphine,
+/obj/item/reagent_containers/glass/bottle/morphine,
/turf/open/floor/plating/abductor,
/area/abductor_ship)
"alk" = (
diff --git a/code/__DEFINES/wounds.dm b/code/__DEFINES/wounds.dm
index cda67caaab80f..8028ef989bc08 100644
--- a/code/__DEFINES/wounds.dm
+++ b/code/__DEFINES/wounds.dm
@@ -4,7 +4,7 @@
/// an attack must do this much damage after armor in order to roll for being a wound (incremental pressure damage need not apply)
#define WOUND_MINIMUM_DAMAGE 5
/// an attack must do this much damage after armor in order to be eliigible to dismember a suitably mushed bodypart
-#define DISMEMBER_MINIMUM_DAMAGE 10
+#define DISMEMBER_MINIMUM_DAMAGE 20
/// any damage dealt over this is ignored for damage rolls unless the target has the frail quirk (35^1.4=145)
#define WOUND_MAX_CONSIDERED_DAMAGE 35
diff --git a/code/datums/components/uplink.dm b/code/datums/components/uplink.dm
index d97ddde00a011..e231084cfec93 100644
--- a/code/datums/components/uplink.dm
+++ b/code/datums/components/uplink.dm
@@ -241,10 +241,9 @@ GLOBAL_LIST_EMPTY(uplinks)
if (!user || user.incapacitated())
return
if(U.hijack_only)
- if(!(usr.mind.special_role == ROLE_OPERATIVE) || !(usr.mind.special_role == "nukie mid") || !(usr.mind.special_role == "Lone Operative"))//nukies get items that regular traitors only get with hijack. If a hijack-only item is not for nukies, then exclude it via the gamemode list.
- if(!(locate(/datum/objective/hijack) in usr.mind.get_all_objectives()) || !(locate(/datum/objective/martyr) in usr.mind.get_all_objectives()))
- to_chat(usr, "InteQ выдает этот чрезвычайно опасный предмет только агентам, получившим особо сложное задание.")
- return
+ if(!(usr.mind.special_role == ROLE_OPERATIVE) || !(usr.mind.special_role == "nukie mid") || !(usr.mind.special_role == "Lone Operative") || !(locate(/datum/objective/hijack) in usr.mind.get_all_objectives()) || !(locate(/datum/objective/martyr) in usr.mind.get_all_objectives()))//nukies get items that regular traitors only get with hijack. If a hijack-only item is not for nukies, then exclude it via the gamemode list.
+ to_chat(usr, "InteQ выдает этот чрезвычайно опасный предмет только агентам, получившим особо сложное задание.")
+ return
if(telecrystals < U.cost || U.limited_stock == 0)
return
diff --git a/code/datums/diseases/advance/symptoms/flesh_eating.dm b/code/datums/diseases/advance/symptoms/flesh_eating.dm
index b5b55c1e14ae4..39203e922d428 100644
--- a/code/datums/diseases/advance/symptoms/flesh_eating.dm
+++ b/code/datums/diseases/advance/symptoms/flesh_eating.dm
@@ -85,7 +85,6 @@ Bonus
*/
/datum/symptom/flesh_death
-
name = "Autophagocytosis Necrosis"
desc = "The virus rapidly consumes infected cells, leading to heavy and widespread damage."
stealth = -2
diff --git a/code/modules/mob/living/carbon/human/species_types/zombies.dm b/code/modules/mob/living/carbon/human/species_types/zombies.dm
index 0dc08eeedbcc5..e5d91736845aa 100644
--- a/code/modules/mob/living/carbon/human/species_types/zombies.dm
+++ b/code/modules/mob/living/carbon/human/species_types/zombies.dm
@@ -33,13 +33,15 @@
name = "Infectious Zombie"
id = "memezombies"
limbs_id = SPECIES_ZOMBIE
- inherent_traits = list(TRAIT_RESISTCOLD,TRAIT_RESISTHIGHPRESSURE,TRAIT_RESISTLOWPRESSURE,TRAIT_RADIMMUNE,TRAIT_EASYDISMEMBER,TRAIT_LIMBATTACHMENT,TRAIT_NOBREATH,TRAIT_NODEATH,TRAIT_NOSOFTCRIT, TRAIT_FAKEDEATH)
+ inherent_traits = list(TRAIT_RESISTCOLD,TRAIT_RESISTHIGHPRESSURE,TRAIT_RESISTLOWPRESSURE,TRAIT_RADIMMUNE,TRAIT_EASYDISMEMBER,TRAIT_LIMBATTACHMENT,TRAIT_NOBREATH,TRAIT_NODEATH,TRAIT_NOSOFTCRIT,TRAIT_FAKEDEATH)
mutanthands = /obj/item/zombie_hand
armor = 20 // 120 damage to KO a zombie, which kills it
speedmod = 1.6 // they're very slow
+ burnmod = 0.75
+ brutemod = 0.75
mutanteyes = /obj/item/organ/eyes/night_vision/zombie
blacklisted_quirks = list(/datum/quirk/nonviolent)
- var/heal_rate = 1
+ var/heal_rate = 5
var/regen_cooldown = 0
/datum/species/zombie/infectious/check_roundstart_eligible()
diff --git a/code/modules/reagents/reagent_containers/bottle.dm b/code/modules/reagents/reagent_containers/bottle.dm
index d53d729630627..697884025cf2e 100644
--- a/code/modules/reagents/reagent_containers/bottle.dm
+++ b/code/modules/reagents/reagent_containers/bottle.dm
@@ -254,7 +254,7 @@
// Viro bottles
/obj/item/reagent_containers/glass/bottle/romerol
- name = "romerol bottle"
+ name = "Romerol Bottle"
desc = "A small bottle of Romerol. The REAL zombie powder."
list_reagents = list(/datum/reagent/romerol = 30)
diff --git a/code/modules/zombie/organs.dm b/code/modules/zombie/organs.dm
index a755b1c127770..37aaad554d85a 100644
--- a/code/modules/zombie/organs.dm
+++ b/code/modules/zombie/organs.dm
@@ -1,5 +1,5 @@
/obj/item/organ/zombie_infection
- name = "festering ooze"
+ name = "Festering Ooze"
desc = "A black web of pus and viscera."
zone = BODY_ZONE_HEAD
slot = ORGAN_SLOT_ZOMBIE
@@ -23,57 +23,61 @@
GLOB.zombie_infection_list -= src
. = ..()
-/obj/item/organ/zombie_infection/Insert(var/mob/living/carbon/M, special = 0, drop_if_replaced = TRUE)
+/obj/item/organ/zombie_infection/Insert(mob/living/carbon/organ_mob, special, drop_if_replaced)
. = ..()
- // BLUEMOON ADD START - роботы вообще не могут быть зомби
- if(owner.mob_biotypes & MOB_ROBOTIC)
- qdel(src)
- return
- // BLUEMOON ADD END
+
START_PROCESSING(SSobj, src)
-/obj/item/organ/zombie_infection/Remove(special = FALSE)
- if(owner)
- if(iszombie(owner) && old_species)
- owner.set_species(old_species)
- if(timer_id)
- deltimer(timer_id)
+/obj/item/organ/zombie_infection/Remove(mob/living/carbon/M, special = FALSE)
+ . = ..()
+ STOP_PROCESSING(SSobj, src)
+ if(iszombie(M) && old_species && !special)
+ M.set_species(old_species)
+ if(timer_id)
+ deltimer(timer_id)
+
+/obj/item/organ/zombie_infection/Insert(mob/living/carbon/organ_owner, special)
+ . = ..()
+ RegisterSignal(organ_owner, COMSIG_LIVING_DEATH, PROC_REF(organ_owner_died))
+
+/obj/item/organ/zombie_infection/Remove(mob/living/carbon/organ_owner, special)
. = ..()
- STOP_PROCESSING(SSobj, src) //Required to be done after the parent call to avoid conflicts with organ decay.
+ UnregisterSignal(organ_owner, COMSIG_LIVING_DEATH)
+
+/obj/item/organ/zombie_infection/proc/organ_owner_died(mob/living/carbon/source, gibbed)
+ SIGNAL_HANDLER
+ if(iszombie(source))
+ qdel(src) // Congrats you somehow died so hard you stopped being a zombie
/obj/item/organ/zombie_infection/on_find(mob/living/finder)
- to_chat(finder, "Inside the head is a disgusting black \
+ to_chat(finder, span_warning("Inside the head is a disgusting black \
web of pus and viscera, bound tightly around the brain like some \
- biological harness.")
+ biological harness."))
-/obj/item/organ/zombie_infection/process()
+/obj/item/organ/zombie_infection/process(seconds_per_tick, times_fired)
if(!owner)
return
if(!(src in owner.internal_organs))
- INVOKE_ASYNC(src,.proc/Remove,owner)
+ Remove(owner)
if(owner.mob_biotypes & MOB_MINERAL)//does not process in inorganic things
return
if (causes_damage && !iszombie(owner) && owner.stat != DEAD)
- owner.adjustToxLoss(1)
- if (prob(10))
- to_chat(owner, "You feel sick...")
- if(timer_id)
- return
- if(owner.suiciding)
+ owner.adjustToxLoss(0.5 * seconds_per_tick)
+ if (SPT_PROB(5, seconds_per_tick))
+ to_chat(owner, span_danger("You feel sick..."))
+ if(timer_id || !owner.getorgan(/obj/item/organ/brain))
return
if(owner.stat != DEAD && !converts_living)
return
- if(!owner.getorgan(/obj/item/organ/brain))
- return
if(!iszombie(owner))
- to_chat(owner, "You can feel your heart stopping, but something isn't right... \
- life has not abandoned your broken form. You can only feel a deep and immutable hunger that \
- not even death can stop, you will rise again!")
+ to_chat(owner, "Кажется, ваше сердце остановилось... однако что-то здесь не так! \
+ Жизнь не желает покидать вашу оболочку... что-то поддерживает вашу жизнь и это что-то вызывает у вас непреодолимый голод. \
+ Ничего, даже смерть, не сможет убить вас!")
var/revive_time = rand(revive_time_min, revive_time_max)
var/flags = TIMER_STOPPABLE
- timer_id = addtimer(CALLBACK(src, .proc/zombify), revive_time, flags)
+ timer_id = addtimer(CALLBACK(src, PROC_REF(zombify), owner), revive_time, flags)
-/obj/item/organ/zombie_infection/proc/zombify()
+/obj/item/organ/zombie_infection/proc/zombify(mob/living/carbon/target)
timer_id = null
if(!converts_living && owner.stat != DEAD)
@@ -81,9 +85,9 @@
if(!iszombie(owner))
old_species = owner.dna.species.type
- owner.set_species(/datum/species/zombie/infectious)
+ target.set_species(/datum/species/zombie/infectious)
- var/stand_up = (owner.stat == DEAD) || (owner.stat == UNCONSCIOUS)
+ var/stand_up = (target.stat == DEAD) || (target.stat == UNCONSCIOUS)
//Fully heal the zombie's damage the first time they rise
owner.setToxLoss(0, 0)
@@ -93,13 +97,13 @@
if(!owner.revive())
return
- owner.grab_ghost()
- owner.visible_message("[owner] suddenly convulses, as [owner.ru_who()][stand_up ? " stagger to [owner.ru_ego()] feet and" : ""] gain a ravenous hunger in [owner.ru_ego()] eyes!", "You HUNGER!")
- playsound(owner.loc, 'sound/hallucinations/far_noise.ogg', 50, 1)
- owner.do_jitter_animation(living_transformation_time)
- owner.Stun(living_transformation_time)
- to_chat(owner, "You are now a zombie! You claw and bite, turning your fellow crewmembers into friends that help spread the plague.")
- to_chat(owner, "You are a zombie. Please act like one. Letting the crew remove the tumor inside your brain is a dick move to whoever infected you. Please do not do it.")
+ owner.visible_message("[owner] suddenly convulses, as [owner.p_they()][stand_up ? " stagger to [owner.p_their()] feet and" : ""] gain a ravenous hunger in [owner.p_their()] eyes!", "You HUNGER!")
+
+ to_chat(target, span_alien("You HUNGER!"))
+ to_chat(target, span_alertalien("You are now a zombie! Do not seek to be cured, do not help any non-zombies in any way, do not harm your zombie brethren and spread the disease by killing others. You are a creature of hunger and violence."))
+ playsound(target, 'sound/hallucinations/far_noise.ogg', 50, 1)
+ target.do_jitter_animation(living_transformation_time)
+ target.Stun(living_transformation_time)
/obj/item/organ/zombie_infection/nodamage
causes_damage = FALSE
diff --git a/modular_bluemoon/shower_trait/shower_trait.dm b/modular_bluemoon/shower_trait/shower_trait.dm
index d8ee0986368a1..a60344df7f28e 100644
--- a/modular_bluemoon/shower_trait/shower_trait.dm
+++ b/modular_bluemoon/shower_trait/shower_trait.dm
@@ -16,8 +16,8 @@
mood_quirk = TRUE
var/cleanse_level = CLEAN //уровень чистоты персонажа
- var/warning_level = 0 // предупреждения для игрока в чат. Обнуляются при достижении чистоты в 100 и меньше
var/doing_shower = FALSE // оповещение, что персонаж вошёл в душ и игроку нужно подождать, пока он не станет чистым
+ var/warning_level = 0 // предупреждения для игрока в чат. Обнуляются при достижении чистоты в 100 и меньше
/datum/quirk/bluemoon_shower_need/on_spawn()
. = ..()
@@ -42,7 +42,7 @@
if(DIRTY to VERY_DIRTY)
SEND_SIGNAL(quirk_holder, COMSIG_ADD_MOOD_EVENT, "need_shower", /datum/mood_event/need_shower/dirty)
if(warning_level < 2)
- to_chat(quirk_holder, span_warning("Мне нужно сходить в душ."))
+ to_chat(quirk_holder, span_phobia("Мне нужно сходить в душ."))
warning_level = 2
if(VERY_DIRTY to INFINITY)
SEND_SIGNAL(quirk_holder, COMSIG_ADD_MOOD_EVENT, "need_shower", /datum/mood_event/need_shower/very_dirty)
@@ -60,17 +60,20 @@
SIGNAL_HANDLER
var/cleaning_efficiency = 10 // 3.5~ минуты с 1000
+ if(cleanse_level <= 10) // снижение нагрузки, чтобы стояние куклы под душем с этим квирком не генерило постоянно все проверки внизу
+ return
+
if(!check_for_clothing())
to_chat(quirk_holder, span_warning("Нужно снять одежду, не подходящую для душа! Бюстгалтер и трусы допустимы."))
return
var/area/A = get_area(quirk_holder)
- if(A in typesof(/area/security/prison, /area/commons/toilet, /area/command/heads_quarters/captain, /area/commons/dorms, /area/command/blueshielquarters, /area/service/chapel/main/monastery, /area/mine/laborcamp))
+ if(A.type in typesof(/area/security/prison, /area/commons/toilet, /area/command/heads_quarters/captain, /area/commons/dorms, /area/command/blueshielquarters, /area/service/chapel/main/monastery, /area/mine/laborcamp))
if(!doing_shower && warning_level != 0)
- to_chat(quirk_holder, span_notice("Теперь постоять под душем и помыться..."))
+ to_chat(quirk_holder, span_notice("Теперь только подождать... Есть время разгрузить голову и расслабиться."))
doing_shower = TRUE
cleaning_efficiency = 20 // 1.7~ минут с 1000
- else
+ else // За поставленный в неподходящей зоне душ и мытьё там штраф
if(!doing_shower && warning_level != 0)
to_chat(quirk_holder, span_warning("Я смогу помыться, но это место плохо подходит для душевой и это будет в два раза дольше. Дормиторий, уборные, личные каюты подходят куда лучше..."))
doing_shower = TRUE
@@ -83,26 +86,27 @@
if(holder.w_shirt) // мыться в футболках нельзя
if(!(holder.w_shirt.type in typesof(/obj/item/clothing/underwear/shirt/bra, /obj/item/clothing/underwear/shirt/top))) // мыться в лифчике можно
- return FALSE
+ return
if(holder.back) // мыться с рюкзаком нельзя
- return FALSE
+ return
if(holder.gloves) // мыться в перчатках нельзя
if(!(holder.gloves.type in typesof(/obj/item/clothing/accessory/ring))) // с кольцами можно
- return FALSE
+ return
if(holder.w_uniform) // мыться в униформе нельзя
if(holder.w_uniform.body_parts_covered & CHEST) // можно, если униформа закрывает грудь
- return FALSE
+ return
if(holder.wear_suit) // мыться в костюме нельзя
- return FALSE
+ return
if(!get_location_accessible(holder, BODY_ZONE_HEAD)) // мыться в шапочке нельзя
- return FALSE
+ return
+
if(!get_location_accessible(holder, BODY_ZONE_PRECISE_L_FOOT)) // мыться в обуви нельзя
- return FALSE
+ return
return TRUE // в наушниках, очках, галстуках, части нижнего белья можно мыться
@@ -120,7 +124,7 @@
mood_change = -2
/datum/mood_event/need_shower/very_dirty
- description = span_phobia("Мне ОЧЕНЬ нужно сходить в душ!\n")
+ description = span_boldwarning("Мне ОЧЕНЬ нужно сходить в душ!\n")
mood_change = -4
/*
@@ -147,7 +151,7 @@
return
var/matrix/M = matrix()
M.Scale(0.6)
- overlay = image('modular_bluemoon/shower_trait/steam.dmi', "steam_single", pixel_y = 12, layer = -FIRE_LAYER)
+ overlay = image('modular_bluemoon/shower_trait/stink.dmi', "steam_single", pixel_y = 12, layer = -FIRE_LAYER)
overlay.transform = M
owner.add_overlay(overlay)
@@ -155,3 +159,11 @@
owner.cut_overlay(overlay)
overlay = null
return ..()
+
+#undef STATUS_EFFECT_STINK
+
+#undef CLEAN
+#undef FINE_CLEAN
+#undef FIRST_WARNING
+#undef DIRTY
+#undef VERY_DIRTY
diff --git a/modular_bluemoon/shower_trait/stink.dmi b/modular_bluemoon/shower_trait/stink.dmi
new file mode 100644
index 0000000000000..16bbc8d8804b6
Binary files /dev/null and b/modular_bluemoon/shower_trait/stink.dmi differ