diff --git a/__DEFINES/role_datums_defines.dm b/__DEFINES/role_datums_defines.dm index 50d37a15198..af54b09b028 100644 --- a/__DEFINES/role_datums_defines.dm +++ b/__DEFINES/role_datums_defines.dm @@ -146,6 +146,8 @@ #define RITUALABORT_TOOLS "moved talisman" #define RITUALABORT_REMOVED "victim removed" #define RITUALABORT_CONVERT "convert success" +#define RITUALABORT_REFUSED "convert refused" +#define RITUALABORT_NOCHOICE "convert nochoice" #define RITUALABORT_SACRIFICE "convert failure" #define RITUALABORT_FULL "no room" #define RITUALABORT_CONCEAL "conceal" @@ -178,6 +180,7 @@ #define CONVERSION_REFUSE -1 #define CONVERSION_NOCHOICE 0 #define CONVERSION_ACCEPT 1 +#define CONVERSION_BANNED 2 #define CONVERTIBLE_ALWAYS 1 #define CONVERTIBLE_CHOICE 2 @@ -186,6 +189,9 @@ #define CONVERTIBLE_ALREADY 5 #define CONVERTIBLE_IMPLANT 6 +#define DECONVERSION_ACCEPT 1 +#define DECONVERSION_REFUSE 2 + //////////////////////////////////////////////////////////////////////////////// // -- Objectives flags diff --git a/code/__HELPERS/unsorted.dm b/code/__HELPERS/unsorted.dm index a3aa6ff4b1a..2a7ce466418 100644 --- a/code/__HELPERS/unsorted.dm +++ b/code/__HELPERS/unsorted.dm @@ -1240,6 +1240,8 @@ var/global/list/common_tools = list( if((ishuman(M) || isslime(M)) && M.lying) if(locate(/obj/machinery/optable,M.loc) || locate(/obj/structure/bed/roller/surgery, M.loc)) return 1 + if(iscultist(U) && locate(/obj/structure/cult/altar, M.loc)) + return 1 if(locate(/obj/structure/bed/roller, M.loc) && prob(75)) return 1 var/obj/structure/table/T = locate(/obj/structure/table/, M.loc) diff --git a/code/_onclick/hud/fullscreen.dm b/code/_onclick/hud/fullscreen.dm index 9b7ac8bfe9a..cfba04052bf 100644 --- a/code/_onclick/hud/fullscreen.dm +++ b/code/_onclick/hud/fullscreen.dm @@ -149,6 +149,16 @@ layer = HALLUCINATION_LAYER alpha = 0 +/obj/abstract/screen/fullscreen/confusion_border + icon_state = "conversionoverlay" + layer = HALLUCINATION_LAYER + alpha = 0 + +/obj/abstract/screen/fullscreen/deafmute_border + icon_state = "conversionoverlay" + layer = HALLUCINATION_LAYER + alpha = 0 + /obj/abstract/screen/fullscreen/conversion_red icon = 'icons/mob/screen1.dmi' screen_loc = "WEST,SOUTH to EAST,NORTH" diff --git a/code/datums/gamemode/factions/bloodcult/bloodcult.dm b/code/datums/gamemode/factions/bloodcult/bloodcult.dm index 885247c3fa4..de901338c5a 100644 --- a/code/datums/gamemode/factions/bloodcult/bloodcult.dm +++ b/code/datums/gamemode/factions/bloodcult/bloodcult.dm @@ -62,6 +62,8 @@ var/global/global_anchor_bloodstone // Keeps track of what stone becomes the anc var/list/cult_reminders = list() + var/list/bindings = list() + /datum/faction/bloodcult/check_win() return cult_win @@ -188,10 +190,9 @@ var/global/global_anchor_bloodstone // Keeps track of what stone becomes the anc new_obj = new /datum/objective/bloodcult_sacrifice for(var/datum/role/cultist/C in members) var/mob/M = C.antag.current - for(var/obj/item/weapon/implant/loyalty/I in M) - I.forceMove(get_turf(M)) - I.implanted = 0 - M.visible_message("\The [I] pops out of \the [M]'s head.") + if (iscarbon(M)) + var/mob/living/carbon/CARB = M + CARB.implant_pop() if (CULT_ACT_III) var/datum/objective/bloodcult_sacrifice/O = locate() in objective_holder.objectives minor_victory = TRUE // At any rate, we achieve a minor win. @@ -253,6 +254,50 @@ var/global/global_anchor_bloodstone // Keeps track of what stone becomes the anc if (O.IsFulfilled()) stage(CULT_ACT_IV) +/mob/living/carbon/proc/implant_pop() + for(var/obj/item/weapon/implant/loyalty/I in src) + if (I.implanted) + to_chat(src, "Your blood pushes back against the loyalty implant, it will visibly pop out within seconds!") + spawn(10 SECONDS) + I.forceMove(get_turf(src)) + I.implanted = 0 + visible_message("\The [I] pops out of \the [src]'s head.") + +/mob/living/carbon/proc/boxify(var/delete_body = TRUE, var/new_anim = TRUE, var/box_state = "cult")//now its own proc so admins may atomProcCall it if they so desire. + var/turf/T = get_turf(src) + for(var/mob/living/M in dview(world.view, T, INVISIBILITY_MAXIMUM)) + if (M.client) + M.playsound_local(T, 'sound/effects/convert_failure.ogg', 75, 0, -4) + if (new_anim) + var/obj/effect/cult_ritual/conversion/anim = new(T) + anim.icon_state = "" + flick("rune_convert_failure",anim) + anim.Die() + var/obj/item/weapon/storage/cult/coffer = new(T) + coffer.icon_state = box_state + var/obj/item/weapon/reagent_containers/food/drinks/cult/cup = new(coffer) + if (istype(src,/mob/living/carbon/human) && dna) + take_blood(cup, cup.volume)//Up to 60u + cup.on_reagent_change()//so we get the reagentsfillings overlay + new/obj/item/weapon/skull(coffer) + if (isslime(src)) + cup.reagents.add_reagent(SLIMEJELLY, 50) + if (isalien(src))//w/e + cup.reagents.add_reagent(RADIUM, 50) + + for(var/obj/item/weapon/implant/loyalty/I in src) + I.implanted = 0 + + for(var/obj/item/I in src) + u_equip(I) + if(I) + I.forceMove(T) + I.reset_plane_and_layer() + I.dropped(src) + I.forceMove(coffer) + if (delete_body) + qdel(src) + /datum/faction/bloodcult/proc/add_bloody_floor(var/turf/T) if (!istype(T)) return @@ -388,13 +433,11 @@ var/global/global_anchor_bloodstone // Keeps track of what stone becomes the anc if(ishuman(Grab.affecting)) var/mob/living/carbon/human/H = Grab.affecting if(!(H.species.anatomy_flags & NO_BLOOD)) - for(var/datum/organ/external/org in H.organs) - if(org.status & ORGAN_BLEEDING) - var/blood_volume = round(H.vessel.get_reagent_amount(BLOOD)) - var/blood_gathered = min(amount_needed-amount_gathered,blood_volume) - data[BLOODCOST_TARGET_GRAB] = H - data[BLOODCOST_AMOUNT_GRAB] = blood_gathered - amount_gathered += blood_gathered + var/blood_volume = round(H.vessel.get_reagent_amount(BLOOD)) + var/blood_gathered = min(amount_needed-amount_gathered,blood_volume) + data[BLOODCOST_TARGET_GRAB] = H + data[BLOODCOST_AMOUNT_GRAB] = blood_gathered + amount_gathered += blood_gathered if(ismonkey(Grab.affecting) || isalien(Grab.affecting))//Unlike humans, monkeys take oxy damage when blood is taken from them. var/mob/living/carbon/C = Grab.affecting if(!C.isDead()) diff --git a/code/datums/gamemode/factions/bloodcult/bloodcult_buildings.dm b/code/datums/gamemode/factions/bloodcult/bloodcult_buildings.dm index 4b21b80dc52..061c90586f4 100644 --- a/code/datums/gamemode/factions/bloodcult/bloodcult_buildings.dm +++ b/code/datums/gamemode/factions/bloodcult/bloodcult_buildings.dm @@ -557,10 +557,22 @@ var/extra = "" if (H && istype(H)) if (H.isInCrit()) - extra = " - CRITICAL" + extra = " - CRITICAL" else if (H.isDead()) extra = " - DEAD" dat += "
  • [M.name]
  • - [origin_text][extra]" + for(var/obj/item/weapon/handcuffs/cult/cuffs in cult.bindings) + if (iscarbon(cuffs.loc)) + var/mob/living/carbon/C = cuffs.loc + if (C.handcuffed == cuffs && cuffs.gaoler && cuffs.gaoler.antag) + var/datum/mind/gaoler = cuffs.gaoler.antag + var/extra = "" + if (C && istype(C)) + if (C.isInCrit()) + extra = " - CRITICAL" + else if (C.isDead()) + extra = " - DEAD" + dat += "
  • [C.real_name]
  • - Prisoner of [gaoler.name][extra]" dat += {""} user << browse("Cult Roster[dat]", "window=cultroster;size=500x300") onclose(user, "cultroster") diff --git a/code/datums/gamemode/factions/bloodcult/bloodcult_effects.dm b/code/datums/gamemode/factions/bloodcult/bloodcult_effects.dm index 86d12e89aca..4d2a3aee478 100644 --- a/code/datums/gamemode/factions/bloodcult/bloodcult_effects.dm +++ b/code/datums/gamemode/factions/bloodcult/bloodcult_effects.dm @@ -154,17 +154,37 @@ qdel(src) return if (user) - user.forceMove(src) - rider = user - if (ismob(rider)) - var/mob/M = rider - M.see_invisible = SEE_INVISIBLE_CULTJAUNT - M.see_invisible_override = SEE_INVISIBLE_CULTJAUNT - M.apply_vision_overrides() - M.flags |= INVULNERABLE + var/muted = FALSE + if (user.anchored) + to_chat(user, "The blood jaunt fails to grasp you as you are currently anchored.") + if (iscarbon(user)) + var/mob/living/carbon/C = user + if (C.occult_muted()) + muted = TRUE + to_chat(C, "The holy energies upon your body repel the blood jaunt.") + if (!muted && !user.anchored) + user.forceMove(src) + rider = user + if (ismob(rider)) + var/mob/M = rider + M.see_invisible = SEE_INVISIBLE_CULTJAUNT + M.see_invisible_override = SEE_INVISIBLE_CULTJAUNT + M.apply_vision_overrides() + M.flags |= INVULNERABLE if (packup) for (var/atom/movable/AM in packup) - if (!AM.anchored) + if (AM.anchored) + if (ismob(AM)) + var/mob/M = AM + to_chat(M, "The blood jaunt fails to grasp you as you are currently anchored.") + continue + var/muted = FALSE + if (iscarbon(AM)) + var/mob/living/carbon/C = AM + if (C.occult_muted()) + muted = TRUE + to_chat(C, "The holy energies upon your body repel the blood jaunt.") + if (!AM.anchored && !muted) AM.forceMove(src) packed.Add(AM) if (ismob(AM)) @@ -362,6 +382,11 @@ M.see_invisible = SEE_INVISIBLE_LIVING M.see_invisible_override = 0 M.apply_vision_overrides() + if (iscarbon(rider)) + var/mob/living/carbon/C = rider + if (istype(C.handcuffed,/obj/item/weapon/handcuffs/cult)) + C.pain_shock_stage = max(C.pain_shock_stage, 100) + to_chat(C,"Traveling through the veil seems to have a recharging effect on the ghastly bindings as they begin to hurt you anew.") rider = null if (packed.len > 0) for(var/atom/movable/AM in packed) @@ -372,6 +397,11 @@ M.see_invisible = SEE_INVISIBLE_LIVING M.see_invisible_override = 0 M.apply_vision_overrides() + if (iscarbon(AM)) + var/mob/living/carbon/C = AM + if (istype(C.handcuffed,/obj/item/weapon/handcuffs/cult)) + C.pain_shock_stage = max(C.pain_shock_stage, 100) + to_chat(C,"Traveling through the veil seems to have a recharging effect on the ghastly bindings as they begin to hurt you anew.") packed = list() if (landing_animation) @@ -418,7 +448,10 @@ var/bloodstone_backup = 0 2;/mob/living/simple_animal/hostile/creature/cult, 1;/mob/living/simple_animal/hostile/faithless/cult, ) - new mobtype(get_turf(src)) + var/mob/living/simple_animal/hostile/backup = new mobtype(get_turf(src)) + var/new_target = backup.FindTarget() + backup.GiveTarget(new_target) + backup.MoveToTarget()//no time to dilly dally qdel(src) ///////////////////////////////////////STUN INDICATOR//////////////////////////////////////////////// diff --git a/code/datums/gamemode/factions/bloodcult/bloodcult_items.dm b/code/datums/gamemode/factions/bloodcult/bloodcult_items.dm index 3aec6dac61c..a6124179e8b 100644 --- a/code/datums/gamemode/factions/bloodcult/bloodcult_items.dm +++ b/code/datums/gamemode/factions/bloodcult/bloodcult_items.dm @@ -1397,6 +1397,64 @@ var/list/arcane_tomes = list() name = "gamer goblet" desc = "A plastic cup in the shape of a skull. Typically full of Geometer-Fuel." +///////////////////////////////////////CULT CUFFS//////////////////////////////////////////////// +/obj/item/weapon/handcuffs/cult + name = "ghastly bindings" + desc = "" + icon = 'icons/obj/cult.dmi' + icon_state = "cultcuff" + restraint_resist_time = 60 SECONDS + mech_flags = MECH_SCAN_FAIL + origin_tech = null + var/datum/role/cultist/gaoler + +/obj/item/weapon/handcuffs/cult/New() + ..() + + var/datum/faction/bloodcult/cult = find_active_faction_by_type(/datum/faction/bloodcult) + if (!cult) + cult = ticker.mode.CreateFaction(/datum/faction/bloodcult, null, 1) + cult.OnPostSetup() + + cult.bindings += src + +/obj/item/weapon/handcuffs/cult/Destroy() + ..() + + var/datum/faction/bloodcult/cult = find_active_faction_by_type(/datum/faction/bloodcult) + if (!cult) + cult = ticker.mode.CreateFaction(/datum/faction/bloodcult, null, 1) + cult.OnPostSetup() + + cult.bindings -= src + +/obj/item/weapon/handcuffs/cult/examine(var/mob/user) + ..() + if (!isliving(loc))//shouldn't happen unless they get admin spawned + to_chat(user, "The tentacles flailing out of this egg-like object seem like they're trying to grasp at their surroundings.") + else + var/mob/living/carbon/C = loc + if (C.handcuffed == src) + to_chat(user, "These restrict your arms and inflict tremendous pain upon both your body and psyche. But given some time you should be able to break them.") + else + to_chat(user, "\The [C] seems to be in pain as these restrict their arms.") + +/obj/item/weapon/handcuffs/cult/on_restraint_removal(var/mob/living/carbon/C) + C.pain_shock_stage = max(C.pain_shock_stage-50, 0) + spawn(1) + var/turf/T = get_turf(src) + playsound(T, 'sound/effects/hit_on_shattered_glass.ogg', 70, 1) + anim(target = T, a_icon = 'icons/obj/cult.dmi', flick_anim = "cuffbreak") + if (gaoler && gaoler.antag && gaoler.antag.current) + to_chat(gaoler.antag.current, "Bindings you placed upon someone have been shattered") + qdel(src) + +/obj/item/weapon/handcuffs/cult/on_restraint_apply(var/mob/living/carbon/C) + C.pain_shock_stage = max(C.pain_shock_stage, 100) + to_chat(C, "[pick("It hurts so much!", "You really need some painkillers.", "Dear god, the pain!")]") + + + ///////////////////////////////////////BLOOD TESSERACT//////////////////////////////////////////////// /obj/item/weapon/blood_tesseract diff --git a/code/datums/gamemode/factions/bloodcult/bloodcult_runes.dm b/code/datums/gamemode/factions/bloodcult/bloodcult_runes.dm index 61c9db69405..1ef2a875352 100644 --- a/code/datums/gamemode/factions/bloodcult/bloodcult_runes.dm +++ b/code/datums/gamemode/factions/bloodcult/bloodcult_runes.dm @@ -285,7 +285,7 @@ if(iscarbon(user)) var/mob/living/carbon/C = user - if (C.muted()) + if (C.occult_muted()) to_chat(user, "You find yourself unable to focus your mind on the arcane words of the rune.") return @@ -418,7 +418,7 @@ if(iscarbon(user)) var/mob/living/carbon/C = user - if (C.muted()) + if (C.occult_muted()) to_chat(user, "You find yourself unable to focus your mind on the arcane words of the rune.") return diff --git a/code/datums/gamemode/factions/bloodcult/bloodcult_runespells.dm b/code/datums/gamemode/factions/bloodcult/bloodcult_runespells.dm index 23e2ff51d73..45c00ef17f5 100644 --- a/code/datums/gamemode/factions/bloodcult/bloodcult_runespells.dm +++ b/code/datums/gamemode/factions/bloodcult/bloodcult_runespells.dm @@ -155,9 +155,15 @@ if (RITUALABORT_CONVERT) if (activator) to_chat(activator, "The conversion ritual successfully brought a new member to the cult. Inform them of the current situation so they can take action.") + if (RITUALABORT_REFUSED) + if (activator) + to_chat(activator, "The conversion ritual ended with the target being restrained by some eldritch contraption. Deal with them how you see fit so their life may serve our plans.") + if (RITUALABORT_NOCHOICE) + if (activator) + to_chat(activator, "The target never manifested any clear reaction to the ritual. As such they were automatically restrained.") if (RITUALABORT_SACRIFICE) if (activator) - to_chat(activator, "Whether because of their defiance, or Nar-Sie's thirst for their blood, the ritual ends leaving behind nothing but a creepy chest.") + to_chat(activator, "The ritual ends leaving behind nothing but a creepy chest, filled with your lost soul's belongings.") if (RITUALABORT_CONCEAL) if (activator) to_chat(activator, "The ritual is disrupted by the rune's sudden phasing out.") @@ -270,6 +276,7 @@ to_chat(activator, "Perform more conversions.") if(CULT_ACT_II) to_chat(activator, "Perform the Sacrifice.") + qdel(src) return if(istype(spell_holder,/obj/effect/rune)) if((rune_flags & RUNE_STAND) && (activator.loc != spell_holder.loc)) @@ -806,8 +813,8 @@ talisman_absorb = RUNE_CAN_ATTUNE page = "The cult needs many followers to properly thrive, but the teachings of Nar-Sie are extensive, and most cultists learned them over the course of many years. \ You won't always have that sort of time however, this is what the Conversion ritual is for. By making an unbeliever appear before Nar-Sie, their eyes will open \ - in a matter of seconds, that is, if their mind can handle it. Those either too weak, or of an impenetrable mind will be purged, and devoured by Nar-Sie. \ - In this case, their remains will be converted into a container where to retrieve their belongings, along with a portion of their blood. \ + in a matter of seconds, that is, if their mind can handle it. Those either too weak, or of an impenetrable mind will be restrained by ghastly bindings. \ + In this case, it is up to you to deal with them. You may kill them, keep them prisonner, or release them, the latter being ill-advised. \ Also, know that you can quicken the ritual by wearing formal cult attire, and that the vessel will remain incapacitated for the duration of the ritual." var/remaining = 100 var/mob/living/carbon/victim = null @@ -867,6 +874,8 @@ qdel(src) return + var/mob/convertee = victim//trying to fix logs showing the victim as *null* + update_progbar() if (activator.client) activator.client.images |= progbar @@ -884,26 +893,27 @@ victim.update_fullscreen_alpha("conversionborder", 255, 5) conversion = new(T) flick("rune_convert_start",conversion) - playsound(R, 'sound/effects/convert_start.ogg', 75, 0, -4) + for(var/mob/living/M in dview(world.view, T, INVISIBILITY_MAXIMUM)) + if (M.client) + M.playsound_local(T, 'sound/effects/convert_start.ogg', 75, 0, -4) for(var/obj/item/device/gps/secure/SPS in get_contents_in_object(victim)) SPS.OnMobDeath(victim)//Think carefully before converting a sec officer if (victim.mind) if (victim.mind.assigned_role in impede_medium) - to_chat(victim, "Your sense of duty impedes down the ritual.") - to_chat(activator, "Their will is strong, the ritual will take longer.") + to_chat(victim, "Your devotion to Nanotrasen slows down the ritual.") + to_chat(activator, "Their devotion to Nanotrasen is strong, the ritual will take longer.") if (victim.mind.assigned_role in impede_hard) - to_chat(victim, "Your devotion to higher causes impedes the ritual.") - to_chat(activator, "Their willpower is amazing, the ritual will be exhausting.") - - for(var/obj/item/weapon/implant/loyalty/I in victim) - if(I.implanted) - to_chat(victim, "Your loyalty implants drastically slows down the ritual's progression.") - to_chat(activator, "Their mind seems to reject the ritual by reflex. The ritual will take much longer.") - break - + var/higher_cause = "Space Jesus" + switch(victim.mind.assigned_role) + if ("Captain") + higher_cause = "Nanotrasen" + if ("Chaplain") + higher_cause = "[victim.mind.faith ? "[victim.mind.faith.deity_name]" : "Space Jesus"]" + to_chat(victim, "Your devotion to [higher_cause] slows down the ritual.") + to_chat(activator, "Their devotion to [higher_cause] is amazing, the ritual will be lengthy.") spawn() while (remaining > 0) @@ -913,7 +923,9 @@ if (victim.loc != T)//Removed() should take care of it, but just in case victim.clear_fullscreen("conversionred", 10) victim.clear_fullscreen("conversionborder", 10) - playsound(R, 'sound/effects/convert_abort.ogg', 50, 0, -4) + for(var/mob/living/M in dview(world.view, T, INVISIBILITY_MAXIMUM)) + if (M.client) + M.playsound_local(T, 'sound/effects/convert_abort.ogg', 50, 0, -4) conversion.icon_state = "" flick("rune_convert_abort",conversion) abort(RITUALABORT_REMOVED) @@ -925,14 +937,18 @@ if (cancelling <= 0) victim.clear_fullscreen("conversionred", 10) victim.clear_fullscreen("conversionborder", 10) - playsound(R, 'sound/effects/convert_abort.ogg', 50, 0, -4) + for(var/mob/living/M in dview(world.view, T, INVISIBILITY_MAXIMUM)) + if (M.client) + M.playsound_local(T, 'sound/effects/convert_abort.ogg', 50, 0, -4) conversion.icon_state = "" flick("rune_convert_abort",conversion) abort(RITUALABORT_GONE) return else - playsound(R, 'sound/effects/convert_process.ogg', 10, 0, -4) + for(var/mob/living/M in dview(world.view, T, INVISIBILITY_MAXIMUM)) + if (M.client) + M.playsound_local(T, 'sound/effects/convert_process.ogg', 10, 0, -4) //then progress through the ritual victim.Silent(5) victim.Knockdown(5) @@ -942,13 +958,9 @@ var/progress = 10//10 seconds to reach second phase for a naked cultist progress += activator.get_cult_power()//down to 1-2 seconds when wearing cult gear var/delay = 0 - for(var/obj/item/weapon/implant/loyalty/I in victim) - if(I.implanted) - delay = 1 - progress = progress/4 - break if (victim.mind) if (victim.mind.assigned_role in impede_medium) + delay = 1 progress = progress/2 if (victim.mind.assigned_role in impede_hard) @@ -965,13 +977,13 @@ var/threshold = min(100,round((100-remaining), 10)) if (flavor_text < 3) if (flavor_text == 0 && threshold > 10)//it's ugly but gotta account for the possibility of several messages appearing at once - to_chat(victim, "Your blood pulses.") + to_chat(victim, "WE ARE THE BLOOD PUMPING THROUGH THE FABRIC OF SPACE") flavor_text++ if (flavor_text == 1 && threshold > 40) - to_chat(victim, "Your head throbs.") + to_chat(victim, "THE GEOMETER CALLS FOR YET ANOTHER FEAST") flavor_text++ if (flavor_text == 2 && threshold > 70) - to_chat(victim, "The world goes red.") + to_chat(victim, "FRIEND OR FOE, YOU TOO SHALL JOIN THE FESTIVITIES") flavor_text++ sleep(10) @@ -986,39 +998,63 @@ if (isalien(victim)) victim.Paralyse(15) - if (victim.client && victim.mind.assigned_role != "Chaplain")//Chaplains can never be converted - acceptance = get_role_desire_str(victim.client.prefs.roles[CULTIST]) + if (victim.client) + if(victim.mind.assigned_role == "Chaplain") + acceptance = "Chaplain" + else + acceptance = get_role_desire_str(victim.client.prefs.roles[CULTIST]) + + for(var/obj/item/weapon/implant/loyalty/I in victim) + if(I.implanted) + acceptance = "Implanted" if (jobban_isbanned(victim, CULTIST) || isantagbanned(victim)) acceptance = "Banned" //Players with cult enabled in their preferences will always get converted. //Others get a choice, unless they're cult-banned or have their preferences set to Never (or disconnected), in which case they always die. + var/conversion_delay = 100 switch (acceptance) if ("Always","Yes") conversion.icon_state = "rune_convert_good" - to_chat(activator, "\The [victim] effortlessly opens himself to the teachings of Nar-Sie. They will undoubtedly become one of us when the ritual concludes.") - to_chat(victim, "Your begin hearing strange words, straight into your mind. Somehow you think you can understand their meaning. A sense of dread and fascination comes over you.") + to_chat(activator, "The ritual immediately stabilizes, \the [victim] appears eager help prepare the festivities.") + to_chat(victim, "YOU HAVE BEEN WAITING FOR US. OUR CULT WELCOMES YOU") success = CONVERSION_ACCEPT - if ("No","???") - to_chat(activator, "The ritual arrives in its final phase. How it ends depends now of \the [victim].") - spawn() - if (alert(victim, "You feel the gaze of an alien entity, it speaks into your mind. It has much to share with you, but time is of the essence. Will you open your mind to it? Or will you become its sustenance? Decide now!","You have 10 seconds","Join the Cult","Be Devoured") == "Join the Cult") - conversion.icon_state = "rune_convert_good" - success = CONVERSION_ACCEPT - to_chat(victim, "As you let the strange words into your mind, you find yourself suddenly understanding their meaning. A sense of dread and fascination comes over you.") - else - conversion.icon_state = "rune_convert_bad" - to_chat(victim, "You won't let it have its way with you! Better die now as a human, than serve them.") - success = CONVERSION_REFUSE - - if ("Never","Banned") + conversion_delay = 50 + if ("No","???","Never") + if (victim.client) + to_chat(activator, "The ritual arrives in its final phase. How it ends depends now of \the [victim]. You do not have to remain adjacent for the remainder of the ritual.") + spawn() + if (alert(victim, "The Cult of Nar-Sie has much in store for you, but what specifically?","You have 10 seconds to decide","Join the Cult","Become Prisoner") == "Join the Cult") + conversion.icon_state = "rune_convert_good" + success = CONVERSION_ACCEPT + to_chat(victim, "THAT IS GOOD. COME CLOSER. THERE IS MUCH TO TEACH YOU") + else + to_chat(victim, "THAT IS ALSO GOOD, FOR YOU WILL ENTERTAIN US") + success = CONVERSION_REFUSE + else//converting a braindead carbon will always lead to them being captured + to_chat(activator, "\The [victim] doesn't really seem to have all their wits about them. Letting the ritual conclude will let you restrain them.") + if ("Implanted") + if (victim.client) + to_chat(activator, "A loyalty implant interferes with the ritual. They will not be able to accept the conversion.") + to_chat(victim, "Your loyalty implant prevents you from hearing any more of what they have to say.") + success = CONVERSION_REFUSE + else//converting a braindead carbon will always lead to them being captured + to_chat(activator, "\The [victim] doesn't really seem to have all their wits about them. Letting the ritual conclude will let you restrain them.") + if ("Chaplain")//Chaplains can never be converted + if (victim.client) + to_chat(activator, "Chaplains won't ever let themselves be converted. They will be restrained.") + to_chat(victim, "Your devotion to [victim.mind.faith ? "[victim.mind.faith.deity_name]" : "Space Jesus"] shields you from Nar-Sie's temptations.") + success = CONVERSION_REFUSE + else//converting a braindead carbon will always lead to them being captured + to_chat(activator, "\The [victim] doesn't really seem to have all their wits about them. Letting the ritual conclude will let you restrain them.") + if ("Banned") conversion.icon_state = "rune_convert_bad" - to_chat(activator, "\The [victim]'s mind appears to be completely impervious to the Geometer of Blood's words of power. If they won't become one of us, they won't need their body any longer.") - to_chat(victim, "A sense of dread comes over you, as you feel under the gaze of a cosmic being. You cannot hear its voice, but you can feel its thirst...for your blood!") - success = CONVERSION_REFUSE + to_chat(activator, "Given how unstable the ritual is becoming, \The [victim] will surely be consumed entirely by it. They weren't meant to become one of us.") + to_chat(victim, "Except your past actions have displeased us. You will be our snack before the feast begins. \[You are banned from this role\]") + success = CONVERSION_BANNED //since we're no longer checking for the cultist's adjacency, let's finish this ritual without a loop - sleep(100) + sleep(conversion_delay) if (destroying_self || !spell_holder || !activator || !victim) return @@ -1026,7 +1062,9 @@ if (victim.loc != T)//Removed() should take care of it, but just in case victim.clear_fullscreen("conversionred", 10) victim.clear_fullscreen("conversionborder", 10) - playsound(R, 'sound/effects/convert_abort.ogg', 50, 0, -4) + for(var/mob/living/M in dview(world.view, T, INVISIBILITY_MAXIMUM)) + if (M.client) + M.playsound_local(T, 'sound/effects/convert_abort.ogg', 50, 0, -4) conversion.icon_state = "" flick("rune_convert_abort",conversion) abort(RITUALABORT_REMOVED) @@ -1052,24 +1090,28 @@ conversion.plane = OBJ_PLANE victim.clear_fullscreen("conversionred", 10) victim.clear_fullscreen("conversionborder", 10) - playsound(R, 'sound/effects/convert_success.ogg', 75, 0, -4) + for(var/mob/living/M in dview(world.view, T, INVISIBILITY_MAXIMUM)) + if (M.client) + M.playsound_local(T, 'sound/effects/convert_success.ogg', 75, 0, -4) //new cultists get purged of the debuffs victim.SetKnockdown(0) victim.SetStunned(0) victim.SetSilent(0) if (isalien(victim)) victim.SetParalysis(0) - //and their loyalty implants are removed, so they can't mislead security - for(var/obj/item/weapon/implant/loyalty/I in victim) - I.forceMove(T) - I.implanted = 0 - spell_holder.visible_message("\The [I] pops out of \the [victim]'s head.") - convert(victim, converter) + //let's also remove cult cuffs if they have them + if (istype(victim.handcuffed,/obj/item/weapon/handcuffs/cult)) + victim.drop_from_inventory(victim.handcuffed) + //and their loyalty implants are removed, so they can't mislead security, not that the conversion should even go through + victim.implant_pop() + for(var/obj/item/weapon/implant/holy/H in victim) + to_chat(victim, "The ritual's energies have completely fried the holy implant that was lodged in your skull.") + qdel(H) + convert(convertee, converter) conversion.icon_state = "" flick("rune_convert_success",conversion) - abort(RITUALABORT_CONVERT) - message_admins("BLOODCULT: [key_name(victim)] has been converted by [key_name(converter)].") - log_admin("BLOODCULT: [key_name(victim)] has been converted by [key_name(converter)].") + message_admins("BLOODCULT: [key_name(convertee)] has been converted by [key_name(converter)].") + log_admin("BLOODCULT: [key_name(convertee)] has been converted by [key_name(converter)].") if (issilicon(victim)) var/mob/living/silicon/S = victim S.laws = new /datum/ai_laws/cultimov @@ -1084,53 +1126,53 @@ gondola.icon_state_lying = "[gondola.icon_state_standing]_lying" gondola.icon_state_dead = "gondola_skull" gondola.icon_state = gondola.icon_state_standing + abort(RITUALABORT_CONVERT) return - if (CONVERSION_NOCHOICE) - to_chat(victim, "As you stood there, unable to make a choice for yourself, the Geometer of Blood ran out of patience and chose for you.") - if (CONVERSION_REFUSE) - to_chat(victim, "Your mind was impervious to the teachings of Nar-Sie. Being of no use for the cult, your body was be devoured when the ritual ended. Your blood and equipment now belong to the cult.") - switch(acceptance) - if ("Never") - to_chat(victim, "The conversion automatically failed due to your cult preferences being set to Never. By setting them to No, you may instead choose whether to accept or refuse a conversion.") - if ("Banned") - to_chat(victim, "The conversion automatically failed due to your account being banned from the cultist role.") + if (CONVERSION_NOCHOICE, CONVERSION_REFUSE) + conversion.icon_state = "" + flick("rune_convert_refused",conversion) + for(var/mob/living/M in dview(world.view, T, INVISIBILITY_MAXIMUM)) + if (M.client) + M.playsound_local(T, 'sound/effects/convert_abort.ogg', 75, 0, -4) - cult.send_flavour_text_refuse(victim, converter) - message_admins("BLOODCULT: [key_name(victim)] refused conversion by [key_name(converter)], and died.") - log_admin("BLOODCULT: [key_name(victim)] refused conversion by [key_name(converter)], and died.") - to_chat(converter, "\The [victim] was pulled through the veil, their body was devoured by Nar-Sie and their possession stored inside this coffer.") + victim.Silent(8) + victim.Knockdown(7) + victim.Stun(6) + victim.Jitter(5) + if (isalien(victim)) + victim.Paralyse(8) - playsound(R, 'sound/effects/convert_failure.ogg', 75, 0, -4) - conversion.icon_state = "" - flick("rune_convert_failure",conversion) + var/obj/item/weapon/handcuffs/cult/restraints = new(victim) + victim.handcuffed = restraints + restraints.on_restraint_apply(victim)//a jolt of pain to slow them down + restraints.gaoler = converter.mind.GetRole(CULTIST) + victim.update_inv_handcuffed() //update handcuff overlays - //sacrificed victims have all their stuff stored in a coffer that also contains their skull and a cup of their blood, should they have either - var/obj/item/weapon/storage/cult/coffer = new(T) - var/obj/item/weapon/reagent_containers/food/drinks/cult/cup = new(coffer) - if (istype(victim,/mob/living/carbon/human) && victim.dna) - victim.take_blood(cup, cup.volume)//Up to 60u - cup.on_reagent_change()//so we get the reagentsfillings overlay - new/obj/item/weapon/skull(coffer) - to_chat(converter, "Inside you may also find a cup filled with a portion of the blood left in their body, along with their skull to potentially use in a resurrection ritual.") - if (isslime(victim)) - cup.reagents.add_reagent(SLIMEJELLY, 50) - to_chat(converter, "Inside you may also find a cup filled with a slimy substance.") - if (isalien(victim))//w/e - cup.reagents.add_reagent(RADIUM, 50) - to_chat(converter, "Inside you may also find a cup filled with a green radioactive liquid.") + if (success == CONVERSION_NOCHOICE) + if (convertee.mind)//no need to generate logs when capturing mindless monkeys + to_chat(victim, "Because you didn't give your answer in time, you were automatically made prisoner.") + message_admins("BLOODCULT: [key_name(convertee)] has timed-out during conversion by [key_name(converter)].") + log_admin("BLOODCULT: [key_name(convertee)] has timed-out during conversion by [key_name(converter)].") - for(var/obj/item/weapon/implant/loyalty/I in victim) - I.implanted = 0 - for(var/obj/item/I in victim) - victim.u_equip(I) - if(I) - I.forceMove(victim.loc) - I.reset_plane_and_layer() - I.dropped(victim) - I.forceMove(coffer) + abort(RITUALABORT_NOCHOICE) + else + message_admins("BLOODCULT: [key_name(convertee)] has refused conversion by [key_name(converter)].") + log_admin("BLOODCULT: [key_name(convertee)] has refused conversion by [key_name(converter)].") - qdel(victim) - abort(RITUALABORT_SACRIFICE) + abort(RITUALABORT_REFUSED) + + if (CONVERSION_BANNED) + + //cult.send_flavour_text_refuse(convertee, converter) Disabling those for now, I'll rewrite them at a later date + + message_admins("BLOODCULT: [key_name(convertee)] died because they were converted by [key_name(converter)] while cult-banned.") + log_admin("BLOODCULT: [key_name(convertee)] died because they were converted by [key_name(converter)] while cult-banned.") + conversion.icon_state = "" + flick("rune_convert_failure",conversion) + + //sacrificed victims have all their stuff stored in a coffer that also contains their skull and a cup of their blood, should they have either + victim.boxify(TRUE, FALSE, "cult") + abort(RITUALABORT_SACRIFICE) /datum/rune_spell/blood_cult/conversion/proc/convert(var/mob/M, var/mob/converter) var/datum/role/cultist/newCultist = new @@ -1141,12 +1183,14 @@ cult.HandleRecruitedRole(newCultist) newCultist.OnPostSetup() newCultist.Greet(GREET_CONVERTED) - cult.send_flavour_text_accept(victim, converter) + //cult.send_flavour_text_accept(victim, converter) Disabling those for now, I'll rewrite them at a later date newCultist.conversion["converted"] = activator /datum/rune_spell/blood_cult/conversion/Removed(var/mob/M) if (victim == M) - playsound(spell_holder, 'sound/effects/convert_abort.ogg', 50, 0, -4) + for(var/mob/living/L in dview(world.view, spell_holder.loc, INVISIBILITY_MAXIMUM)) + if (L.client) + L.playsound_local(spell_holder.loc, 'sound/effects/convert_abort.ogg', 50, 0, -4) conversion.icon_state = "" flick("rune_convert_abort",conversion) abort(RITUALABORT_REMOVED) @@ -1378,7 +1422,7 @@ var/list/blind_victims = list() shadow(C,T)//shadow trail moving from the spell_holder to the victim anim(target = C, a_icon = 'icons/effects/effects.dmi', flick_anim = "rune_blind", lay = NARSIE_GLOW, plane = LIGHTING_PLANE) if (!(C in blind_victims)) - C.overlay_fullscreen("blindborder", /obj/abstract/screen/fullscreen/conversion_border)//victims DO still get blinded for a second + C.overlay_fullscreen("blindborder", /obj/abstract/screen/fullscreen/confusion_border)//victims DO still get blinded for a second C.overlay_fullscreen("blindblack", /obj/abstract/screen/fullscreen/black)//which will allow us to subtly reveal the surprise C.update_fullscreen_alpha("blindblack", 255, 5) else @@ -1424,7 +1468,7 @@ var/list/blind_victims = list() my_hallucinated_stuff.Add(blind_victims[C]) C.client.images.Remove(blind_victims[C])//removing the images from client.images after adding them to my_hallucinated_stuff blind_victims[C] = my_hallucinated_stuff//allows us to seamlessly refresh their duration. - C.client.images.Add(blind_victims[C]) + C.client.images.Add(my_hallucinated_stuff) var/hallenght = my_hallucinated_stuff.len spawn(duration-5) if (C in blind_victims) @@ -1443,6 +1487,8 @@ var/list/blind_victims = list() C.client.images.Remove(my_hallucinated_stuff)//removing images caused by every blind rune used consecutively on that mob sleep(15) C.clear_fullscreen("blindwhite", animate = 0) + while (blind_victims.len > 0)//if the ritual atom stops existing while people are still confused, weird shit can occurs such as people remaining blinded forever. + sleep(10 SECONDS) qdel(src) //RUNE VIII @@ -1469,7 +1515,7 @@ var/list/blind_victims = list() for(var/mob/living/M in range(effect_range,get_turf(spell_holder))) if (iscultist(M)) continue - M.overlay_fullscreen("deafborder", /obj/abstract/screen/fullscreen/conversion_border)//victims DO still get blinded for a second + M.overlay_fullscreen("deafborder", /obj/abstract/screen/fullscreen/deafmute_border)//victims see a red overlay fade in-out for a second M.update_fullscreen_alpha("deafborder", 100, 5) M.Deafen(deaf_duration) M.Mute(mute_duration) @@ -1967,6 +2013,10 @@ var/list/blind_victims = list() if (pay_blood()) for(var/mob/living/L in range(effect_range,get_turf(spell_holder))) + if (iscarbon(L)) + var/mob/living/carbon/C = L + if (C.occult_muted()) + continue if(L.stat != DEAD && iscultist(L)) playsound(L, 'sound/effects/fervor.ogg', 50, 0, -2) anim(target = L, a_icon = 'icons/effects/effects.dmi', flick_anim = "rune_fervor", lay = NARSIE_GLOW, plane = LIGHTING_PLANE, direction = L.dir) @@ -2041,11 +2091,19 @@ var/list/blind_victims = list() rejoin = alert(activator, "Will you pull them toward you, or pull yourself toward them?","Blood Magnetism","Summon Cultist","Rejoin Cultist") == "Rejoin Cultist" var/list/possible_targets = list() - var/datum/faction/bloodcult = find_active_faction_by_member(activator.mind.GetRole(CULTIST)) + var/list/prisoners = list() + var/datum/faction/bloodcult/bloodcult = find_active_faction_by_member(activator.mind.GetRole(CULTIST)) for(var/datum/role/cultist/C in bloodcult.members) var/datum/mind/M = C.antag possible_targets.Add(M.current) + //Prisoners are valid Blood Magnetism targets! + for(var/obj/item/weapon/handcuffs/cult/cuffs in bloodcult.bindings) + if (iscarbon(cuffs.loc)) + var/mob/living/carbon/C = cuffs.loc + if (C.handcuffed == cuffs) + prisoners.Add(C) + var/list/annotated_targets = list() var/list/visible_mobs = viewers(activator) var/i = 1 @@ -2060,6 +2118,10 @@ var/list/blind_victims = list() annotated_targets["\Roman[i]-[M.real_name][status]"] = M i++ + for(var/mob/M in prisoners) + annotated_targets["\Roman[i]-[M.real_name] (Prisoner)"] = M + i++ + var/choice = input(activator, "Choose who you wish to [rejoin ? "rejoin" : "summon"]", "Blood Magnetism") as null|anything in annotated_targets if (!choice) qdel(src) @@ -2170,7 +2232,7 @@ var/list/blind_victims = list() flick("cult_jaunt_land",landing_animation) else if(target.locked_to || !isturf(target.loc)) - to_chat(target, "You feel that some force wants to pull you through the veil, but cannot proceed while buckled or inside something.") + to_chat(target, "You feel that some force wants to pull you through the veil, but cannot proceed while you are buckled or inside something.") for(var/mob/living/L in contributors) to_chat(activator, "The ritual failed, the target seems to be anchored to where they are.") else diff --git a/code/datums/gamemode/factions/bloodcult/bloodcult_spells.dm b/code/datums/gamemode/factions/bloodcult/bloodcult_spells.dm index 214852d8b92..0eedce31da4 100644 --- a/code/datums/gamemode/factions/bloodcult/bloodcult_spells.dm +++ b/code/datums/gamemode/factions/bloodcult/bloodcult_spells.dm @@ -76,7 +76,7 @@ var/list/uristrune_cache = list() cast_delay = 5 var/mob/living/carbon/C = user - var/muted = C.muted() + var/muted = C.occult_muted() if (muted) to_chat(user,"You find yourself unable to focus your mind on the words of Nar-Sie.") return muted @@ -264,6 +264,9 @@ var/list/uristrune_cache = list() /spell/cult/blood_dagger/cast(var/list/targets, var/mob/living/carbon/user) ..() + if (user.occult_muted()) + to_chat(user, "You try grasping your blood but you can't quite will it into the shape of a dagger.") + return 0 var/mob/living/carbon/human/H = user var/list/data = use_available_blood(user, 5) if (data[BLOODCOST_RESULT] == BLOODCOST_FAILURE) @@ -325,6 +328,9 @@ var/list/arcane_pockets = list() /spell/cult/arcane_dimension/cast(var/list/targets, var/mob/living/carbon/user) ..() + if (user.occult_muted()) + to_chat(user, "You can't seem to remember how to access your arcane dimension right now.") + return 0 if (stored_tome) stored_tome.forceMove(get_turf(user)) if (user.get_inactive_hand() && user.get_active_hand())//full hands diff --git a/code/datums/gamemode/role/cultist.dm b/code/datums/gamemode/role/cultist.dm index 474eb30a119..f2f38669bbc 100644 --- a/code/datums/gamemode/role/cultist.dm +++ b/code/datums/gamemode/role/cultist.dm @@ -11,6 +11,7 @@ var/holywarning_cooldown = 0 var/list/conversion = list() var/second_chance = 1 + var/datum/deconversion_ritual/deconversion = null /datum/role/cultist/New(var/datum/mind/M, var/datum/faction/fac=null, var/new_id) ..() @@ -35,32 +36,45 @@ /datum/role/cultist/RemoveFromRole(var/datum/mind/M) antag.current.remove_language(LANGUAGE_CULT) + remove_cult_hud() for(var/spell/cult/spell_to_remove in antag.current.spell_list) antag.current.remove_spell(spell_to_remove) if (src in blood_communion) blood_communion.Remove(src) + if (conversion.len > 0) + var/conv = pick(conversion) + switch (conv) + if ("converted") + to_chat(antag.current, "Your memories of the cult gradually fade away. You remember getting converted by [conversion[conv]], but nothing else.") + if ("resurrected") + to_chat(antag.current, "Your memories of the cult gradually fade away. You remember getting resurrected by [conversion[conv]], but nothing else.") + if ("soulstone") + to_chat(antag.current, "Your memories of the cult gradually fade away. You remember having your soul captured by [conversion[conv]], but nothing else.") + if ("altar") + to_chat(antag.current, "Your memories of the cult gradually fade away. You do not remember anything, not even who you were prior.") + if ("sacrifice") + to_chat(antag.current, "Your memories of the cult gradually fade away. You do not remember anything other than having had your body sacrificed at some point.") + else + to_chat(antag.current, "Your memories of the cult gradually fade away. You do not remember anything.") + else + to_chat(antag.current, "Your memories of the cult gradually fade away. You do not remember anything.") ..() + if (faction) + faction.members -= src + update_faction_icons() /datum/role/cultist/PostMindTransfer(var/mob/living/new_character) . = ..() if (issilicon(new_character)) - antag.decult() + to_chat(new_character, "As the silicon directives override your free will, your connection to the cult is shattered. You are to follow your new master's commands and help them in their goal.") + Drop() + return update_cult_hud() antag.current.add_language(LANGUAGE_CULT) if((ishuman(antag.current) || ismonkey(antag.current) || isalien(antag.current)) && !(locate(/spell/cult) in antag.current.spell_list)) antag.current.add_spell(new /spell/cult/trace_rune/blood_cult, "cult_spell_ready", /obj/abstract/screen/movable/spell_master/bloodcult) antag.current.add_spell(new /spell/cult/erase_rune, "cult_spell_ready", /obj/abstract/screen/movable/spell_master/bloodcult) -/datum/mind/proc/decult() - antag_roles -= CULTIST - current.remove_language(LANGUAGE_CULT) - for(var/spell/cult/spell_to_remove in current.spell_list) - current.remove_spell(spell_to_remove) - var/datum/role/cultist/C = GetRole(CULTIST) - if (C in blood_communion) - blood_communion.Remove(C) - update_faction_icons() - /datum/role/cultist/process() ..() if (holywarning_cooldown > 0) @@ -156,6 +170,7 @@ if (OH.objectives.len > 0) var/datum/objective/O = OH.objectives[OH.objectives.len] //Gets the latest objective. to_chat(antag.current,"[O.name]: [O.explanation_text]") + /datum/role/cultist/update_antag_hud() update_cult_hud() @@ -222,10 +237,21 @@ M.healths2, ) -/mob/living/carbon/proc/muted() +/datum/role/cultist/proc/remove_cult_hud() + var/mob/M = antag?.current + if(M && M.client && M.hud_used) + qdel(M.hud_used.cult_Act_display) + qdel(M.hud_used.cult_tattoo_display) + +/mob/living/carbon/proc/occult_muted() if (checkTattoo(TATTOO_HOLY)) return 0 - return (iscultist(src) && reagents && reagents.has_reagent(HOLYWATER)) + if (reagents && reagents.has_reagent(HOLYWATER)) + return 1 + for(var/obj/item/weapon/implant/holy/I in src) + if (I.implanted) + return 1 + return 0 /datum/role/cultist/AdminPanelEntry(var/show_logo = FALSE,var/datum/admins/A) var/dat = ..() diff --git a/code/datums/religions.dm b/code/datums/religions.dm index fb38be0577f..ea75203d121 100755 --- a/code/datums/religions.dm +++ b/code/datums/religions.dm @@ -1069,6 +1069,9 @@ preferred_incense = /obj/item/weapon/storage/fancy/incensebox/moonflowers bookstyle = "Tome" +/datum/religion/cult/equip_chaplain(var/mob/living/carbon/human/H) + H.add_language(LANGUAGE_CULT) + /datum/religion/cult/convertCeremony(var/mob/living/preacher, var/mob/living/subject) var/obj/effect/decal/cleanable/crayon/rune = locate(/obj/effect/decal/cleanable/crayon/, subject.loc) if (!rune) @@ -1502,7 +1505,7 @@ /datum/religion/anprim name = "Primitivism" deity_name = "Grug" - bible_name = "Industrial Society and Its Future" + bible_name = "Industrial Society and Its Future" bible_type = /obj/item/weapon/storage/bible/booze male_adept = "Primitive" female_adept = "Primitive" diff --git a/code/datums/supplypacks.dm b/code/datums/supplypacks.dm index 982ad03db83..6057e46122a 100755 --- a/code/datums/supplypacks.dm +++ b/code/datums/supplypacks.dm @@ -437,6 +437,17 @@ var/list/all_supply_groups = list("Supplies","Clothing","Security","Hospitality" containername = "airbag crate" group = "Supplies" +/datum/supply_packs/religious//you can only order default-looking bibles for now + name = "Religious Paraphernelia" + contains = list(/obj/item/weapon/reagent_containers/food/drinks/bottle/holywater, + /obj/item/weapon/storage/bible, + /obj/item/weapon/storage/fancy/incensebox/harebells, + /obj/item/weapon/thurible) + cost = 100 + containertype = /obj/structure/closet/crate/basic + containername = "religious stuff crate" + group = "Supplies" + //////CLOTHING////// /datum/supply_packs/costume @@ -1074,6 +1085,15 @@ var/list/all_supply_groups = list("Supplies","Clothing","Security","Hospitality" access = list(access_armory) group = "Security" +/datum/supply_packs/holy + name = "Holy implants" + contains = list (/obj/item/weapon/storage/lockbox/holy) + cost = 60 + containertype = /obj/structure/closet/crate/secure/basic + containername = "holy implant crate" + access = list(access_armory) + group = "Security" + /datum/supply_packs/ballistic name = "Ballistic gear" contains = list(/obj/item/clothing/suit/armor/bulletproof, diff --git a/code/game/objects/items/soulstone.dm b/code/game/objects/items/soulstone.dm index 0266e03a194..eb5ac205c9b 100644 --- a/code/game/objects/items/soulstone.dm +++ b/code/game/objects/items/soulstone.dm @@ -20,6 +20,7 @@ slot_flags = SLOT_BELT mech_flags = MECH_SCAN_FAIL origin_tech = Tc_BLUESPACE + "=4;" + Tc_MATERIALS + "=4" + sharpness_flags = SHARP_TIP | SHARP_BLADE var/mob/living/simple_animal/shade/shade = null @@ -122,16 +123,23 @@ to_chat(user, "Capture successful!: [target.real_name]'s has been captured and stored within the soul stone.") //Is our user a cultist? Then you're a cultist too now! - if (iscultist(user) && !iscultist(target)) - var/datum/role/cultist/newCultist = new - newCultist.AssignToRole(target.mind,1) - var/datum/faction/bloodcult/cult = find_active_faction_by_type(/datum/faction/bloodcult) - if (!cult) - cult = ticker.mode.CreateFaction(/datum/faction/bloodcult, null, 1) - cult.HandleRecruitedRole(newCultist) - newCultist.OnPostSetup() - newCultist.Greet(GREET_SOULSTONE) - newCultist.conversion["soulstone"] = user + if (iscultist(user)) + if(!iscultist(target)) + var/datum/role/cultist/newCultist = new + newCultist.AssignToRole(target.mind,1) + var/datum/faction/bloodcult/cult = find_active_faction_by_type(/datum/faction/bloodcult) + if (!cult) + cult = ticker.mode.CreateFaction(/datum/faction/bloodcult, null, 1) + cult.HandleRecruitedRole(newCultist) + newCultist.OnPostSetup() + newCultist.Greet(GREET_SOULSTONE) + newCultist.conversion["soulstone"] = user + else + if (iscultist(target)) + var/datum/role/cultist = target.mind.GetRole(CULTIST) + to_chat(target, "Your new master is NOT a cultist, you are henceforth disconnected from the rest of the cult. You are to follow your new master's commands and help them in their goal.") + cultist.Drop() + target.add_language(LANGUAGE_CULT)//re-adding cult languages, as all shades can speak it /obj/item/soulstone/proc/eject_shade(var/mob/user) if (!shade) @@ -163,6 +171,7 @@ icon_state = "soulstone" item_state = "shard-soulstone" inhand_states = list("left_hand" = 'icons/mob/in-hand/left/shards.dmi', "right_hand" = 'icons/mob/in-hand/right/shards.dmi') + sharpness_flags = 0 /obj/item/soulstone/gem/throw_impact(var/atom/hit_atom, var/speed, var/mob/user) ..() @@ -356,32 +365,7 @@ var/turf/T = get_turf(body) if (gem)//if we're using a gem, let's store everything in a neat coffer along with some of the victim's blood - var/obj/effect/cult_ritual/conversion/anim = new(T) - anim.icon_state = "" - playsound(T, 'sound/effects/convert_failure.ogg', 75, 0, -4) - flick("rune_convert_failure",anim) - anim.Die() - var/obj/item/weapon/storage/cult/coffer = new(T) - var/obj/item/weapon/reagent_containers/food/drinks/cult/cup = new(coffer) - if (istype(body,/mob/living/carbon/human) && body.dna) - body.take_blood(cup, cup.volume)//Up to 60u - cup.on_reagent_change()//so we get the reagentsfillings overlay - new/obj/item/weapon/skull(coffer) - if (isslime(body)) - cup.reagents.add_reagent(SLIMEJELLY, 50) - if (isalien(body))//w/e - cup.reagents.add_reagent(RADIUM, 50) - - for(var/obj/item/weapon/implant/loyalty/I in body) - I.implanted = 0 - - for(var/obj/item/I in body) - body.u_equip(I) - if(I) - I.forceMove(body.loc) - I.reset_plane_and_layer() - I.dropped(body) - I.forceMove(coffer) + body.boxify(FALSE, TRUE, "cult") else//otherwise just drop it on the ground for(var/obj/item/W in body) @@ -477,21 +461,25 @@ if (!suicide) //Is our user a cultist? Then you're a cultist too now! if (iscultist(user)) - var/datum/role/cultist/newCultist = new - newCultist.AssignToRole(shadeMob.mind,1) - var/datum/faction/bloodcult/cult = find_active_faction_by_type(/datum/faction/bloodcult) - if (!cult) - cult = ticker.mode.CreateFaction(/datum/faction/bloodcult, null, 1) - cult.HandleRecruitedRole(newCultist) - newCultist.OnPostSetup() - newCultist.Greet(GREET_SOULSTONE) - newCultist.conversion["soulstone"] = user + if (!iscultist(shadeMob)) + var/datum/role/cultist/newCultist = new + newCultist.AssignToRole(shadeMob.mind,1) + var/datum/faction/bloodcult/cult = find_active_faction_by_type(/datum/faction/bloodcult) + if (!cult) + cult = ticker.mode.CreateFaction(/datum/faction/bloodcult, null, 1) + cult.HandleRecruitedRole(newCultist) + newCultist.OnPostSetup() + newCultist.Greet(GREET_SOULSTONE) + newCultist.conversion["soulstone"] = user else if (iscultist(shadeMob)) - to_chat(shadeMob, "Your master is NOT a cultist, but you are. You are still to follow their commands and help them in their goal.") - to_chat(shadeMob, "Your loyalty to Nar-Sie temporarily wanes, but the God takes his toll on your treacherous mind. You only remember of who converted you.") - shadeMob.mind.decult() + var/datum/role/cultist = shadeMob.mind.GetRole(CULTIST) + to_chat(shadeMob, "Your new master is NOT a cultist, you are henceforth disconnected from the rest of the cult. You are to follow your new master's commands and help them in their goal.") + cultist.Drop() + shadeMob.add_language(LANGUAGE_CULT)//re-adding cult languages, as all shades can speak it + + //Pretty particles var/turf/T1 = get_turf(target) diff --git a/code/game/objects/items/weapons/implants/implant.dm b/code/game/objects/items/weapons/implants/implant.dm index 516b91d0129..8430c6e2789 100644 --- a/code/game/objects/items/weapons/implants/implant.dm +++ b/code/game/objects/items/weapons/implants/implant.dm @@ -61,8 +61,8 @@ var/phrase = "supercalifragilisticexpialidocious" icon_state = "implant_evil" - get_data() - var/dat = {" +/obj/item/weapon/implant/explosive/get_data() + var/dat = {" Implant Specifications:
    Name: Robust Corp RX-78 Intimidation Class Implant
    Life: Activates upon codephrase or detected death.
    @@ -72,7 +72,7 @@ Function: Contains a compact, electrically detonated explosive that detonates upon receiving a specially encoded signal or upon host death.
    Special Features: Explodes
    Integrity: Implant will occasionally be degraded by the body's immune system and thus will occasionally malfunction."} - return dat + return dat /obj/item/weapon/implant/explosive/Hear(var/datum/speech/speech, var/rendered_speech="") hear(speech.message) @@ -163,8 +163,8 @@ desc = "Injects things." allow_reagents = 1 - get_data() - var/dat = {" +/obj/item/weapon/implant/chem/get_data() + var/dat = {" Implant Specifications:
    Name: Robust Corp MJ-420 Prisoner Management Implant
    Life: Deactivates upon death but remains within the body.
    @@ -179,7 +179,7 @@ the implant releases the chemicals directly into the blood stream.
    Can only be loaded while still in its original case.
    Integrity: Implant will last so long as the subject is alive. However, if the subject suffers from malnutrition,
    the implant may become unstable and either pre-maturely inject the subject or simply break."} - return dat + return dat /obj/item/weapon/implant/chem/New() ..() @@ -226,10 +226,10 @@ the implant may become unstable and either pre-maturely inject the subject or si /obj/item/weapon/implant/loyalty name = "loyalty implant" - desc = "Makes you loyal or such." + desc = "Induces constant thoughts of loyalty to Nanotrasen." - get_data() - var/dat = {" +/obj/item/weapon/implant/loyalty/get_data() + var/dat = {" Implant Specifications:
    Name: Nanotrasen Employee Management Implant
    Life: Ten years.
    @@ -237,9 +237,9 @@ the implant may become unstable and either pre-maturely inject the subject or si
    Implant Details:
    Function: Contains a small pod of nanobots that manipulate the host's mental functions.
    -Special Features: Will prevent and cure most forms of brainwashing.
    +Special Features: Will prevent and cure light forms of brainwashing.
    Integrity: Implant will last so long as the nanobots are inside the bloodstream."} - return dat + return dat /obj/item/weapon/implant/loyalty/implanted(mob/M) @@ -251,9 +251,14 @@ the implant may become unstable and either pre-maturely inject the subject or si if(I.imp_in == H) H.visible_message("[H] seems to resist the implant!", "You feel a strange sensation in your head that quickly dissipates.") return 0 - if(isrevhead(H) || (iscultist(H) && veil_thickness >= CULT_ACT_II)) + if(isrevhead(H)) H.visible_message("[H] seems to resist the implant!", "You feel the corporate tendrils of Nanotrasen try to invade your mind!") return 0 + if(iscultist(H) && veil_thickness >= CULT_ACT_I) + to_chat(H, "You feel the corporate tendrils of Nanotrasen trying to invade your mind!") + spawn (1)//waiting for the implant to have its loc moved inside the body + H.implant_pop() + return 1 if(isrevnothead(H)) var/datum/role/R = H.mind.GetRole(REV) R.Drop() @@ -268,8 +273,8 @@ the implant may become unstable and either pre-maturely inject the subject or si desc = "Greytide Station wide" icon_state = "implant_evil" - get_data() - var/dat = {" +/obj/item/weapon/implant/traitor/get_data() + var/dat = {" Implant Specifications:
    Name: Greytide Mind-Slave Implant
    Life: ???
    @@ -279,7 +284,7 @@ the implant may become unstable and either pre-maturely inject the subject or si Function: Contains a small pod of nanobots that manipulate the host's mental functions.
    Special Features: Glory to the Greytide!
    Integrity: Implant will last so long as the nanobots are inside the bloodstream."} - return dat + return dat /obj/item/weapon/implant/traitor/implanted(mob/M, mob/user) if(!iscarbon(M)) @@ -337,8 +342,8 @@ the implant may become unstable and either pre-maturely inject the subject or si desc = "Removes all stuns and knockdowns." var/uses - get_data() - var/dat = {" +/obj/item/weapon/implant/adrenalin/get_data() + var/dat = {" Implant Specifications:
    Name: Cybersun Industries Adrenalin Implant
    Life: Five days.
    @@ -348,7 +353,7 @@ the implant may become unstable and either pre-maturely inject the subject or si Function: Contains nanobots to stimulate body to mass-produce Adrenalin.
    Special Features: Will prevent and cure most forms of brainwashing.
    Integrity: Implant can only be used three times before the nanobots are depleted."} - return dat + return dat /obj/item/weapon/implant/adrenalin/trigger(emote, mob/source as mob) if (src.uses < 1) @@ -375,8 +380,8 @@ the implant may become unstable and either pre-maturely inject the subject or si desc = "An alarm which monitors host vital signs and transmits a radio message upon death." var/mobname = "Will Robinson" - get_data() - var/dat = {" +/obj/item/weapon/implant/death_alarm/get_data() + var/dat = {" Implant Specifications:
    Name: Nanotrasen \"Profit Margin\" Class Employee Lifesign Sensor
    Life: Activates upon death.
    @@ -386,7 +391,7 @@ the implant may become unstable and either pre-maturely inject the subject or si Function: Contains a compact radio signaler that triggers when the host's lifesigns cease.
    Special Features: Alerts crew to crewmember death.
    Integrity: Implant will occasionally be degraded by the body's immune system and thus will occasionally malfunction."} - return dat + return dat /obj/item/weapon/implant/death_alarm/process() if (!implanted || timestopped) @@ -462,8 +467,8 @@ the implant may become unstable and either pre-maturely inject the subject or si var/activation_emote = "sigh" var/obj/item/scanned = null - get_data() - var/dat = {" +/obj/item/weapon/implant/compressed/get_data() + var/dat = {" Implant Specifications:
    Name: Nanotrasen \"Profit Margin\" Class Employee Lifesign Sensor
    Life: Activates upon death.
    @@ -473,7 +478,7 @@ the implant may become unstable and either pre-maturely inject the subject or si Function: Contains a compact radio signaler that triggers when the host's lifesigns cease.
    Special Features: Alerts crew to crewmember death.
    Integrity: Implant will occasionally be degraded by the body's immune system and thus will occasionally malfunction."} - return dat + return dat /obj/item/weapon/implant/compressed/trigger(emote, mob/source as mob) if (src.scanned == null) @@ -514,7 +519,9 @@ the implant may become unstable and either pre-maturely inject the subject or si desc = "A bean-shaped implant with a single embossed word - PAX - on it." var/imp_alive = 0 var/imp_msg_debounce = 0 - var/imp_data = {" + +/obj/item/weapon/implant/peace/get_data() + var/dat = {" Implant Specifications:
    Name: Pax Implant
    Manufacturer: Ouroboros Medical
    @@ -522,6 +529,7 @@ the implant may become unstable and either pre-maturely inject the subject or si Important Notes: Effect accomplished by paralyzing parts of the brain. This effect is neutralized by 15u or greater of Methylin.
    Life: Sustained as long as it remains within a host. Survives on the host's nutrition. Dies upon removal.
    "} + return dat /obj/item/weapon/implant/peace/meltdown() visible_message("\The [src] releases a dying hiss as it denatures!") @@ -569,5 +577,34 @@ the implant may become unstable and either pre-maturely inject the subject or si else return 0 -/obj/item/weapon/implant/peace/get_data() - return imp_data + +/obj/item/weapon/implant/holy + name = "holy implant" + desc = "Subjects its user to the chants of a thousand chaplains." + +/obj/item/weapon/implant/holy/get_data() + var/dat = {" +Implant Specifications:
    +Name: Holy Dogmatic Interference Implant
    +Life: Anywhere from ten days to ten years depending on the strain placed upon the implant by the subject.
    +Important Notes: This device was commissioned by Nanotrasen after it proved able to distract occult practitioners, making them unable to practice their dark arts.
    +
    +Implant Details:
    +Function: Submits its subject to the chants of a thousand chaplains.
    +Special Features: Prevents cultists from using their runes and talismans, or from being the target of some of their peers' rituals.
    +Integrity: Implant anchors itself inside the subject's bones to prevent blood pressure induced ejections."} + return dat + +/obj/item/weapon/implant/holy/implanted(mob/M) + if(!iscarbon(M)) + return 0 + var/mob/living/carbon/H = M + H << sound('sound/ambience/ambicha1.ogg') + H << sound('sound/ambience/ambicha2.ogg') + H << sound('sound/ambience/ambicha3.ogg') + H << sound('sound/ambience/ambicha4.ogg') + if(iscultist(H)) + to_chat(H, "You feel uneasy as you suddenly start hearing a cacophony of religious chants. You find yourself unable to perform any ritual.") + else + to_chat(H, "You hear the soothing millennia-old Gregorian chants of the clergy.") + return 1 diff --git a/code/game/objects/items/weapons/implants/implantcase.dm b/code/game/objects/items/weapons/implants/implantcase.dm index ad04895a843..27063dfb989 100644 --- a/code/game/objects/items/weapons/implants/implantcase.dm +++ b/code/game/objects/items/weapons/implants/implantcase.dm @@ -1,6 +1,7 @@ /obj/item/weapon/implantcase name = "Glass Case" desc = "A case containing an implant." + icon = 'icons/obj/items.dmi' icon_state = "implantcase-0" item_state = "implantcase" throw_speed = 1 @@ -9,11 +10,10 @@ var/obj/item/weapon/implant/imp = null /obj/item/weapon/implantcase/proc/update() - if (src.imp) - src.icon_state = text("implantcase-[]", src.imp._color) + if (imp) + icon_state = text("implantcase-[]", imp._color) else - src.icon_state = "implantcase-0" - return + icon_state = "implantcase-0" /obj/item/weapon/implantcase/attackby(obj/item/I as obj, mob/user as mob) ..() @@ -22,98 +22,98 @@ else if (istype(I, /obj/item/weapon/implanter)) var/obj/item/weapon/implanter/the_implanter = I if (the_implanter.imp) - if (src.imp || the_implanter.imp.implanted) + if (imp || the_implanter.imp.implanted) return the_implanter.imp.forceMove(src) - src.imp = the_implanter.imp + imp = the_implanter.imp the_implanter.imp = null - src.update() + update() the_implanter.update() - else if (src.imp) - src.imp.forceMove(I) - the_implanter.imp = src.imp - src.imp = null + else if (imp) + imp.forceMove(I) + the_implanter.imp = imp + imp = null - src.update() + update() the_implanter.update() /obj/item/weapon/implantcase/on_syringe_injection(var/mob/user, var/obj/item/weapon/reagent_containers/syringe/tool) - if(!src.imp || !src.imp.allow_reagents) + if(!imp || !imp.allow_reagents) return INJECTION_RESULT_FAIL - if(src.imp.reagents.total_volume >= src.imp.reagents.maximum_volume) + if(imp.reagents.total_volume >= imp.reagents.maximum_volume) to_chat(user, "[src] is full.") return INJECTION_RESULT_FAIL var/tx_amount = min(tool.amount_per_transfer_from_this, tool.reagents.total_volume) - tx_amount = tool.reagents.trans_to(src.imp, tx_amount, log_transfer = TRUE, whodunnit = user) + tx_amount = tool.reagents.trans_to(imp, tx_amount, log_transfer = TRUE, whodunnit = user) to_chat(user, "You inject [tx_amount] units of the solution. \The [tool] now contains [tool.reagents.total_volume] units.") return INJECTION_RESULT_SUCCESS_BUT_SKIP_REAGENT_TRANSFER /obj/item/weapon/implantcase/tracking name = "Glass Case- 'Tracking'" desc = "A case containing a tracking implant." - icon = 'icons/obj/items.dmi' icon_state = "implantcase-b" /obj/item/weapon/implantcase/tracking/New() - src.imp = new /obj/item/weapon/implant/tracking( src ) - ..() - return + imp = new /obj/item/weapon/implant/tracking(src) + ..() /obj/item/weapon/implantcase/explosive name = "Glass Case- 'Explosive'" desc = "A case containing an explosive implant." - icon = 'icons/obj/items.dmi' icon_state = "implantcase-r" /obj/item/weapon/implantcase/explosive/New() - src.imp = new /obj/item/weapon/implant/explosive( src ) - ..() - return + imp = new /obj/item/weapon/implant/explosive(src) + ..() /obj/item/weapon/implantcase/chem name = "Glass Case- 'Chem'" desc = "A case containing a chemical implant." - icon = 'icons/obj/items.dmi' icon_state = "implantcase-b" /obj/item/weapon/implantcase/chem/New() - src.imp = new /obj/item/weapon/implant/chem( src ) + imp = new /obj/item/weapon/implant/chem(src) ..() - return /obj/item/weapon/implantcase/loyalty name = "Glass Case- 'Loyalty'" desc = "A case containing a loyalty implant." - icon = 'icons/obj/items.dmi' icon_state = "implantcase-r" /obj/item/weapon/implantcase/loyalty/New() - src.imp = new /obj/item/weapon/implant/loyalty( src ) + imp = new /obj/item/weapon/implant/loyalty(src) ..() - return /obj/item/weapon/implantcase/death_alarm name = "Glass Case- 'Death Alarm'" desc = "A case containing a death alarm implant." - icon = 'icons/obj/items.dmi' icon_state = "implantcase-b" /obj/item/weapon/implantcase/death_alarm/New() - src.imp = new /obj/item/weapon/implant/death_alarm( src ) + imp = new /obj/item/weapon/implant/death_alarm(src) ..() - return /obj/item/weapon/implantcase/peace name = "glass case- 'Pax'" desc = "A case containing a peace-inducing implant." - icon = 'icons/obj/items.dmi' icon_state = "implantcase-b" /obj/item/weapon/implantcase/peace/New() - src.imp = new /obj/item/weapon/implant/peace(src) + imp = new /obj/item/weapon/implant/peace(src) + ..() + + +/obj/item/weapon/implantcase/holy + name = "Glass Case- 'Holy'" + desc = "A case containing a holy implant." + icon_state = "implantcase-o" + + +/obj/item/weapon/implantcase/holy/New() + imp = new /obj/item/weapon/implant/holy(src) ..() diff --git a/code/game/objects/items/weapons/implants/implanter.dm b/code/game/objects/items/weapons/implants/implanter.dm index 27677203a26..465657e8233 100644 --- a/code/game/objects/items/weapons/implants/implanter.dm +++ b/code/game/objects/items/weapons/implants/implanter.dm @@ -77,6 +77,10 @@ desc = "An implanter containing a pax implant" imp_type = /obj/item/weapon/implant/peace +/obj/item/weapon/implanter/holy + name = "implanter-holy" + imp_type = /obj/item/weapon/implant/holy + /obj/item/weapon/implanter/compressed name = "implanter (C)" icon_state = "cimplanter1" diff --git a/code/game/objects/items/weapons/null_rod.dm b/code/game/objects/items/weapons/null_rod.dm index c013b26467a..a1fa35ec9f7 100644 --- a/code/game/objects/items/weapons/null_rod.dm +++ b/code/game/objects/items/weapons/null_rod.dm @@ -20,7 +20,7 @@ user.visible_message("[user] is impaling \himself with \the [src]! It looks like \he's trying to commit suicide.") return (SUICIDE_ACT_BRUTELOSS|SUICIDE_ACT_FIRELOSS) -/obj/item/weapon/nullrod/attack(mob/M as mob, mob/living/user as mob) //Paste from old-code to decult with a null rod. +/obj/item/weapon/nullrod/attack(mob/M as mob, mob/living/user as mob) M.attack_log += text("\[[time_stamp()]\] Has been attacked with [src.name] by [user.name] ([user.ckey])") user.attack_log += text("\[[time_stamp()]\] Used the [src.name] to attack [M.name] ([M.ckey])") @@ -128,7 +128,7 @@ M.drop_item(src, force_drop = TRUE) M.put_in_active_hand(holy_weapon) qdel(src) - + /obj/item/weapon/nullrod/sword name = "holy avenger" desc = "DEUS VULT!" diff --git a/code/game/objects/items/weapons/storage/bible.dm b/code/game/objects/items/weapons/storage/bible.dm index 10a534e5a21..8bcbf0a81a0 100644 --- a/code/game/objects/items/weapons/storage/bible.dm +++ b/code/game/objects/items/weapons/storage/bible.dm @@ -68,6 +68,39 @@ var/datum/role/vampire/V = isvampire(user) + //they have holy water in them? deconversion mode activate! anyone can do it. + if (M.reagents?.has_reagent(HOLYWATER) && user.a_intent == I_HELP) + if (M.stat == DEAD) + to_chat(user,"You cannot deconvert the dead!") + return 1 + if (M.health < 20) + to_chat(user,"\The [M] is too weak to handle the deconversion ritual, patch them up a bit first.") + return 1 + if(iscultist(M)) + var/datum/role/cultist/cultist = M.mind.GetRole(CULTIST) + if (cultist.deconversion) + to_chat(user,"There is already a deconversion attempt undergoing!") + return 1 + else + playsound(src, "punch", 25, 1, -1) + if (istype(my_rel, /datum/religion/cult)) + user.visible_message("[user] [pick(attack_verb)] [M]'s head with \the [src] and they begin to radiate with light.", + "You bless [M]'s head with \the [src]. In the name of this [my_rel.deity_name] fanfiction headcanon, Nar-Sie forsake this body and soul!") + else + user.visible_message("[user] [pick(attack_verb)] [M]'s head with \the [src] and they begin to radiate with light.", + "You bless [M]'s head with \the [src]. In the name of [my_rel.deity_name], Nar-Sie forsake this body and soul!") + new /datum/deconversion_ritual(user, M, src) + return 1 + else + playsound(src, "punch", 25, 1, -1) + if (istype(my_rel, /datum/religion/cult)) + user.visible_message("[user] [pick(attack_verb)] [M]'s head with \the [src].", + "You bless [M]'s head with \the [src]. In the name of this [my_rel.deity_name] fanfiction headcanon, Nar-Sie forsake this body and soul!") + else + user.visible_message("[user] [pick(attack_verb)] [M]'s head with \the [src].", + "You bless [M]'s head with \the [src]. In the name of [my_rel.deity_name], Nar-Sie forsake this body and soul!") + user.visible_message("...but nothing unusal happens.") + return 1 if (!my_rel.leadsThisReligion(user)) //The user is not the leader of this religon. BLASPHEMY ! //Using the Bible as a member of the occult will get you smithed, aka holy cleansing fire. You'd have to be stupid to remotely consider it if(V) //Vampire trying to use it @@ -213,3 +246,98 @@ else owner.mind.faith.convertAct(owner, subject, B) // usr = preacher ; target = subject return TRUE + +/datum/deconversion_ritual + var/datum/role/cultist/cultist = null + var/cult_chaplain = FALSE + var/last_cultist = FALSE + var/success = DECONVERSION_ACCEPT + +/datum/deconversion_ritual/New(var/mob/living/deconverter, var/mob/living/deconvertee, var/obj/item/weapon/storage/bible/bible) + ..() + if (!bible||!bible.my_rel||!deconverter||!deconvertee||!iscultist(deconvertee)) + qdel(src) + return + var/mob/target + deconvertee.overlays += image('icons/effects/effects.dmi',src,"deconversion") + playsound(deconvertee, 'sound/effects/deconversion_start.ogg', 50, 0, -4) + cultist = deconvertee.mind.GetRole(CULTIST) + cultist.deconversion = src + + deconvertee.eye_blurry = max(deconvertee.eye_blurry, 10) + deconvertee.Dizzy(30) + deconvertee.stuttering = max(deconvertee.stuttering, 10) + deconvertee.Jitter(30) + deconvertee.Knockdown(10) + + if (istype(bible.my_rel, /datum/religion/cult)) + cult_chaplain = TRUE + var/datum/faction/bloodcult/cult = find_active_faction_by_type(/datum/faction/bloodcult) + var/living_cultists = 0 + for(var/datum/role/cultist/C in cult.members) + if (C.antag && C.antag.current && C.antag.current.stat != DEAD) + living_cultists++ + if (living_cultists <= 1) + last_cultist = TRUE + + spawn() + spawn() + if (alert(deconvertee, "You are being compelled by the powers of [bible.my_rel.deity_name][cult_chaplain ? " (wait what?)" : ""] to give up on serving the Cult of Nar-Sie[cult_chaplain ? " (huh!?)" : ""]","You have 10 seconds to decide","[!cult_chaplain ? "Abandon the Cult" : "I am so confused right now, ok I guess?"]","[!cult_chaplain ? "Resist!" : "This is obviously a trick! Resist!"]") == "[!cult_chaplain ? "Abandon the Cult" : "I am so confused right now, ok I guess?"]") + success = DECONVERSION_ACCEPT + if (!target && !last_cultist)//no threats if nobody remains to carry them out. + to_chat(deconvertee, "[cult_chaplain ? "WERE YOU DECEIVED THAT EASILY? SO BE IT THEN." : "THERE WILL BE A PRICE."]") + else + success = DECONVERSION_REFUSE + if (!target) + to_chat(deconvertee, "You block the sweet promises of forgiveness from your mind.") + sleep(100) + if (!deconvertee || !iscultist(deconvertee)) + qdel(src) + return + deconvertee.take_overall_damage(10)//it's a painful process no matter what. + var/turf/T = get_turf(deconvertee) + anim(target = deconvertee, a_icon = 'icons/effects/effects.dmi', flick_anim = "cult_jaunt_land", lay = SNOW_OVERLAY_LAYER, plane = EFFECTS_PLANE) + var/mob/living/simple_animal/hostile/shade/redshade_A = new(T) + var/mob/living/simple_animal/hostile/shade/redshade_B = new(T) + if (!bible.my_rel.leadsThisReligion(deconverter))//the shades are a bit stronger if it's not an actual chaplain doing the deconversion, or they're not using a bible of their religion. + redshade_A.buff() + redshade_B.buff() + var/list/adjacent_turfs = list() + for (var/turf/U in orange(1,T)) + adjacent_turfs += U + switch(success) + if (DECONVERSION_ACCEPT) + playsound(deconvertee, 'sound/effects/deconversion_complete.ogg', 50, 0, -4) + to_chat(deconvertee,) + deconvertee.visible_message("You see [deconvertee]'s eyes become clear. Through the blessing of [cult_chaplain ? "some fanfic headcanon version of [bible.my_rel.deity_name]" : "[bible.my_rel.deity_name]"] they have renounced Nar-Sie.","You were forgiven by [bible.my_rel.deity_name][cult_chaplain ? " (YEAH RIGHT...)" : ""]. You no longer share the cult's goals.") + deconvertee.visible_message("A pair of shades manifests from the occult energies that left them and start attacking them.") + cultist.Drop() + var/list/speak = list("...you shall give back the blood we gave you [deconvertee]...","...one does not simply turn their back on our gift...","...if you won't dedicate your heart to Nar-Sie, you don't need it anymore...") + redshade_A.speak = speak + redshade_B.speak = speak + target = deconvertee + if (DECONVERSION_REFUSE) + playsound(deconvertee, 'sound/effects/deconversion_failed.ogg', 50, 0, -4) + to_chat(deconvertee,"You manage to block out the exorcism.") + deconvertee.visible_message("The ritual was resisted, a pair of shades manifest and start attacking all nearby.","The energies you mustered take their toll on your body, and manifest into a couple or red shades that start attacking whoever tried to deconvert you.") + var/list/speak = list("...how dare you try and harass [deconvertee]...","...this is a blatant disregard of the freedom of religion...","...[deconvertee] has pledged their blood to Nar-Sie and we demand that you respect their choice...") + if (cult_chaplain) + speak = list("...cut it out with the weird fanfictions [deconverter]...","...that is why we don't want you among us...","...go back to do word research where no one can hear about you [deconverter]...") + redshade_A.speak = speak + redshade_B.speak = speak + target = deconverter + spawn(1) + redshade_A.forceMove(get_turf(pick(adjacent_turfs))) + redshade_B.forceMove(get_turf(pick(adjacent_turfs))) + redshade_A.GiveTarget(target) + redshade_B.GiveTarget(target) + redshade_A.MoveToTarget() + redshade_B.MoveToTarget() + deconvertee.overlays -= image('icons/effects/effects.dmi',src,"deconversion") + qdel(src) + +/datum/deconversion_ritual/Destroy() + if (cultist) + cultist.deconversion = null + cultist = null + ..() diff --git a/code/game/objects/items/weapons/storage/lockbox.dm b/code/game/objects/items/weapons/storage/lockbox.dm index 29dde71f009..1c02cfbf18b 100644 --- a/code/game/objects/items/weapons/storage/lockbox.dm +++ b/code/game/objects/items/weapons/storage/lockbox.dm @@ -221,6 +221,17 @@ new /obj/item/weapon/reagent_containers/syringe(src) new /obj/item/weapon/implanter(src) +/obj/item/weapon/storage/lockbox/holy + name = "lockbox (holy implants)" + req_one_access = list(access_security) + +/obj/item/weapon/storage/lockbox/holy/New() + ..() + new /obj/item/weapon/implantcase/holy(src) + new /obj/item/weapon/implantcase/holy(src) + new /obj/item/weapon/implantcase/holy(src) + new /obj/item/weapon/implanter/holy(src) + /obj/item/weapon/storage/lockbox/clusterbang name = "lockbox (clusterbang)" desc = "You have a bad feeling about opening this." diff --git a/code/game/turfs/simulated/walls.dm b/code/game/turfs/simulated/walls.dm index 4ca44666447..8347c626d05 100644 --- a/code/game/turfs/simulated/walls.dm +++ b/code/game/turfs/simulated/walls.dm @@ -140,6 +140,10 @@ if (iscultist(user) && !(locate(/obj/effect/cult_shortcut) in src)) var/datum/cult_tattoo/CT = user.checkTattoo(TATTOO_SHORTCUT) if (CT) + var/mob/living/carbon/C = user + if (C.occult_muted()) + to_chat(user, "The holy aura preying upon your body prevents you from correctly drawing the sigil.") + return var/data = use_available_blood(user, CT.blood_cost) if (data[BLOODCOST_RESULT] != BLOODCOST_FAILURE) if(do_after(user, src, 30)) diff --git a/code/modules/flufftext/Dreaming.dm b/code/modules/flufftext/Dreaming.dm index 1ac4711f925..79840c571e0 100644 --- a/code/modules/flufftext/Dreaming.dm +++ b/code/modules/flufftext/Dreaming.dm @@ -18,7 +18,7 @@ mob/living/carbon/proc/dream() "a ship full of spiders","valids","hardcore","your mom","lewd","explosions","broken bones","clowns everywhere","features","a crash","a skrell","a unathi","a tajaran", "a vox","a plasmaman","a skellington","a diona","the derelict","the end of the world","the thunderdome","a ship full of dead clowns","a chicken with godlike powers", "a red bus that drives through space","an alien artifact","the mechanic","a newspaper","an insectoid","a slime","a slime person","a mushroom person", - "the Cult of Nar-Sie","the Wizard Federation","an impossibly gigantic lamprey floating through space, bending reality as it goes", + "the Cult of Nar-Sie","the Wizard Federation","an impossibly gigantic lamprey floating through space, bending reality as it goes","a sword that talks", ) spawn(0) for(var/i = rand(1,4),i > 0, i--) diff --git a/code/modules/mob/living/carbon/human/life/handle_shock.dm b/code/modules/mob/living/carbon/human/life/handle_shock.dm index d37e4d459ff..1653fe52ec1 100644 --- a/code/modules/mob/living/carbon/human/life/handle_shock.dm +++ b/code/modules/mob/living/carbon/human/life/handle_shock.dm @@ -4,55 +4,64 @@ ..() if(status_flags & GODMODE || !feels_pain()) return 0 + var/pain_goes_up = TRUE if(health < config.health_threshold_softcrit) //Going under the crit threshold makes you immediately collapse pain_shock_stage = max(pain_shock_stage, 61) - - if(pain_level >= BASE_CARBON_PAIN_RESIST) + else if(pain_level >= BASE_CARBON_PAIN_RESIST)//Remaining over the pain threshold causes shock to increase over time pain_shock_stage += 1 - else if(health < config.health_threshold_softcrit) - pain_shock_stage = max(pain_shock_stage, 61) else - pain_shock_stage = clamp(pain_shock_stage - 1, 0, 160) - return + pain_shock_stage = clamp(pain_shock_stage - 1, 0, 160)//While staying under will decrease it over time + pain_goes_up = FALSE - if(pain_shock_stage == 10) - to_chat(src, "[pick("It hurts so much!", "You really need some painkillers.", "Dear god, the pain!")]") + if (pain_goes_up || istype(handcuffed,/obj/item/weapon/handcuffs/cult))//cult cuffs cause you to suffer from pain symptoms even as the pain slowly goes down + if(pain_shock_stage == 10) + to_chat(src, "[pick("It hurts so much!", "You really need some painkillers.", "Dear god, the pain!")]") - if(pain_shock_stage >= 30) - if(pain_shock_stage == 30) - if(!isUnconscious()) - visible_message("[src] is having trouble keeping their eyes open.") - eye_blurry = max(2, eye_blurry) - stuttering = max(stuttering, 5) + if(pain_shock_stage >= 30) + if(pain_shock_stage == 30) + if(!isUnconscious()) + visible_message("[src] is having trouble keeping their eyes open.","You're having trouble keeping your eyes open.") + eye_blurry = max(2, eye_blurry) + stuttering = max(stuttering, 5) - if(pain_shock_stage == 40) - to_chat(src, "[pick("The pain is excruciating!", "Please, just end the pain!", "Your whole body is going numb!")]") - - if(pain_shock_stage >= 60) - if(pain_shock_stage == 60) - if(!isUnconscious()) - visible_message("[src]'s body becomes limp.") - if(prob(2)) + if(pain_shock_stage == 40) to_chat(src, "[pick("The pain is excruciating!", "Please, just end the pain!", "Your whole body is going numb!")]") + + if(pain_shock_stage >= 60) + if(pain_shock_stage == 60) + if(!isUnconscious()) + visible_message("[src]'s body becomes limp.","Your body becomes limp.") + if(prob(2)) + to_chat(src, "[pick("The pain is excruciating!", "Please, just end the pain!", "Your whole body is going numb!")]") + Knockdown(20) + + if(pain_shock_stage >= 80 && pain_shock_stage < 150) + if(prob(5)) + to_chat(src, "[pick("The pain is excruciating!", "Please, just end the pain!", "Your whole body is going numb!")]") + Knockdown(20) + + if(pain_shock_stage >= 120 && pain_shock_stage < 150) + if(prob(2)) + to_chat(src, "[pick("You black out!", "You feel like you could die any moment now.", "You're about to lose consciousness.")]") + Paralyse(5) + + if(pain_shock_stage == 150) + if(!isUnconscious()) + visible_message("[src] can no longer stand, collapsing!","You can no longer stand, you collapse!") Knockdown(20) - if(pain_shock_stage >= 80 && pain_shock_stage < 150) - if(prob(5)) - to_chat(src, "[pick("The pain is excruciating!", "Please, just end the pain!", "Your whole body is going numb!")]") - Knockdown(20) - - if(pain_shock_stage >= 120 && pain_shock_stage < 150) - if(prob(2)) - to_chat(src, "[pick("You black out!", "You feel like you could die any moment now.", "You're about to lose consciousness.")]") - Paralyse(5) - - if(pain_shock_stage == 150) + if(pain_shock_stage >= 150) + if((life_tick % 8) == 0) + if(prob(80)) + Knockdown(9) + else//pain goes down + //treshold messages if(!isUnconscious()) - visible_message("[src] can no longer stand, collapsing!") - Knockdown(20) - - if(pain_shock_stage >= 150) - if((life_tick % 8) == 0) - if(prob(80)) - Knockdown(9) + if(pain_shock_stage == 29) + to_chat(src,"The pain becomes manageable.") + if(pain_shock_stage == 49)//movement stops being slowed down + to_chat(src,"The pain stops hindering your movement.") + if(pain_shock_stage >= 50) + if(prob(2)) + to_chat(src, "[pick("The pain slowly resorbs.", "You slowly begin to feel better.", "You begin to feel stuff other than pain again.")]") diff --git a/code/modules/mob/living/carbon/shock.dm b/code/modules/mob/living/carbon/shock.dm index 88526d72c42..3dbc522820f 100644 --- a/code/modules/mob/living/carbon/shock.dm +++ b/code/modules/mob/living/carbon/shock.dm @@ -19,7 +19,7 @@ for(var/datum/reagent/R in reagents.reagent_list) pain_level -= R.pain_resistance - if(src.slurring) //I'm not sure why this is here. + if(src.slurring) //We're drunk, dulls the pain a bit pain_level -= 20 // broken or ripped off organs will add quite a bit of pain diff --git a/code/modules/mob/living/simple_animal/hostile/shade.dm b/code/modules/mob/living/simple_animal/hostile/shade.dm new file mode 100644 index 00000000000..3a21b8fe3e9 --- /dev/null +++ b/code/modules/mob/living/simple_animal/hostile/shade.dm @@ -0,0 +1,94 @@ +/mob/living/simple_animal/hostile/shade + name = "red shade" + real_name = "red shade" + desc = "A vengeful spirit" + icon = 'icons/mob/mob.dmi' + icon_state = "red shade" + icon_living = "red shade" + icon_dead = "shade_dead" + maxHealth = 20 + health = 20 + speak_chance = 33 + turns_per_move = 5 + speak = list("...blood...","...destroy...","...others...") + speak_emote = list("hisses") + emote_hear = list("wails","screeches") + response_help = "puts their hand through" + response_disarm = "flails at" + response_harm = "punches" + melee_damage_lower = 5 + melee_damage_upper = 5 + attacktext = "torments" + attack_sound = 'sound/hallucinations/growl1.ogg' + minbodytemp = 0 + maxbodytemp = 4000 + min_oxy = 0 + max_co2 = 0 + max_tox = 0 + speed = 1 + faction = "cult" + status_flags = CANPUSH + supernatural = TRUE + flying = TRUE + meat_type = /obj/item/weapon/ectoplasm + mob_property_flags = MOB_SUPERNATURAL + alpha = 180 + +/mob/living/simple_animal/hostile/shade/New() + ..() + add_language(LANGUAGE_CULT) + add_language(LANGUAGE_GALACTIC_COMMON) + default_language = all_languages[LANGUAGE_CULT] + +/mob/living/simple_animal/hostile/shade/death(var/gibbed = FALSE) + var/turf/T = get_turf(src) + if (T) + playsound(T, get_sfx("soulstone"), 50,1) + new /obj/item/weapon/ectoplasm (T) + qdel (src) + +/mob/living/simple_animal/hostile/shade/say(var/message) + . = ..(message, "C") + +/mob/living/simple_animal/hostile/shade/proc/buff() + //same damage and health as regular shades + melee_damage_lower = 8 + melee_damage_upper = 8 + maxHealth = 50 + health = 50 + alpha = 255 + +/mob/living/simple_animal/hostile/shade/gib(var/animation = 0, var/meat = 1) + death(TRUE) + monkeyizing = TRUE + canmove = FALSE + icon = null + invisibility = 101 + + dead_mob_list -= src + + qdel(src) + +/mob/living/simple_animal/hostile/shade/Process_Spacemove(var/check_drift = 0) + return 1 + +/mob/living/simple_animal/hostile/shade/FindTarget() + . = ..() + if(.) + emote("me",,"wails at [.]!") + +/mob/living/simple_animal/hostile/faithless/cult/CanAttack(var/atom/the_target) + if(ismob(the_target)) + var/mob/M = the_target + if(isanycultist(M)) + return 0 + return ..(the_target) + +/mob/living/simple_animal/hostile/shade/cultify() + return + +/mob/living/simple_animal/hostile/shade/attackby(var/obj/item/O, var/mob/user) + if(istype(O, /obj/item/soulstone)) + to_chat(user,"The red shade doesn't seem to have an actual soul to capture.") + return + return ..() diff --git a/code/modules/organs/blood.dm b/code/modules/organs/blood.dm index fcc39b26c75..cf1ecd4d788 100644 --- a/code/modules/organs/blood.dm +++ b/code/modules/organs/blood.dm @@ -78,6 +78,11 @@ var/const/BLOOD_VOLUME_SURVIVE = 122 B.volume += 0.1 // regenerate blood VERY slowly if(M_REGEN in mutations) B.volume += 0.4 //A big chunky boost. If you have nutriment and iron you can regenerate 4.1 blood per tick + if (iscultist(src) && (mind.GetRole(CULTIST) in blood_communion))//cultists that take on the blood communion tattoo get a slight blood regen bonus + if(M_REGEN in mutations) + B.volume += 0.6 + else + B.volume += 0.3 if (reagents.has_reagent(NUTRIMENT)) //Getting food speeds it up if(M_REGEN in mutations) B.volume += 1.2 diff --git a/code/modules/reagents/Chemistry-Reagents.dm b/code/modules/reagents/Chemistry-Reagents.dm index 4a5803b425f..fc2c2e6f7a1 100644 --- a/code/modules/reagents/Chemistry-Reagents.dm +++ b/code/modules/reagents/Chemistry-Reagents.dm @@ -82,7 +82,10 @@ chance = chance * 100 - if(prob(chance) && !block) + if(self.id == HOLYWATER && istype(self.holder.my_atom, /obj/item/weapon/reagent_containers/food/drinks/bottle/holywater)) + if(M.reagents) + M.reagents.add_reagent(self.id, min(5,self.volume/2)) //holy water flasks only splash 5u at a time. But for deconversion purposes they will always be ingested. + else if(prob(chance) && !block) if(M.reagents) M.reagents.add_reagent(self.id, self.volume/2) //Hardcoded, transfer half of volume diff --git a/code/modules/surgery/encased.dm b/code/modules/surgery/encased.dm index e657e1decb3..fc5c38909ea 100644 --- a/code/modules/surgery/encased.dm +++ b/code/modules/surgery/encased.dm @@ -20,7 +20,8 @@ /datum/surgery_step/open_encased/saw allowed_tools = list( /obj/item/weapon/circular_saw = 100, - /obj/item/weapon/kitchen/utensil/knife/large/butch = 75, \ + /obj/item/weapon/melee/blood_dagger = 80, + /obj/item/weapon/kitchen/utensil/knife/large/butch = 75, /obj/item/weapon/hatchet = 75, ) diff --git a/code/modules/surgery/generic.dm b/code/modules/surgery/generic.dm index 97bbb716151..56d81196163 100644 --- a/code/modules/surgery/generic.dm +++ b/code/modules/surgery/generic.dm @@ -140,6 +140,7 @@ /datum/surgery_step/generic/cut_open allowed_tools = list( /obj/item/weapon/scalpel = 100, + /obj/item/weapon/melee/blood_dagger = 90, /obj/item/weapon/kitchen/utensil/knife/large = 75, /obj/item/weapon/shard = 50, ) @@ -187,6 +188,7 @@ allowed_tools = list( /obj/item/weapon/hemostat = 100, /obj/item/stack/cable_coil = 75, + /obj/item/weapon/talisman = 70, /obj/item/device/assembly/mousetrap = 20, ) diff --git a/code/modules/surgery/implant.dm b/code/modules/surgery/implant.dm index 1cbcd8ba2cd..ec9ed42dae7 100644 --- a/code/modules/surgery/implant.dm +++ b/code/modules/surgery/implant.dm @@ -171,6 +171,7 @@ allowed_tools = list( /obj/item/weapon/hemostat = 100, /obj/item/weapon/wirecutters = 75, + /obj/item/weapon/talisman = 70, /obj/item/weapon/kitchen/utensil/fork = 20, ) diff --git a/icons/effects/64x64.dmi b/icons/effects/64x64.dmi index 8e3106a89f5..68491ecf934 100644 Binary files a/icons/effects/64x64.dmi and b/icons/effects/64x64.dmi differ diff --git a/icons/effects/effects.dmi b/icons/effects/effects.dmi index f72549e9ee8..2069e364fb0 100644 Binary files a/icons/effects/effects.dmi and b/icons/effects/effects.dmi differ diff --git a/icons/mob/in-hand/left/drinkingglass.dmi b/icons/mob/in-hand/left/drinkingglass.dmi index 0dc19e05e47..b50b74c2aaa 100644 Binary files a/icons/mob/in-hand/left/drinkingglass.dmi and b/icons/mob/in-hand/left/drinkingglass.dmi differ diff --git a/icons/mob/in-hand/right/drinkingglass.dmi b/icons/mob/in-hand/right/drinkingglass.dmi index 81579741af1..b316d548de0 100644 Binary files a/icons/mob/in-hand/right/drinkingglass.dmi and b/icons/mob/in-hand/right/drinkingglass.dmi differ diff --git a/icons/mob/mob.dmi b/icons/mob/mob.dmi index 27868d8e544..9acee1e20be 100644 Binary files a/icons/mob/mob.dmi and b/icons/mob/mob.dmi differ diff --git a/icons/obj/cuffs.dmi b/icons/obj/cuffs.dmi index 0946ef6d0cc..7e6cb165318 100644 Binary files a/icons/obj/cuffs.dmi and b/icons/obj/cuffs.dmi differ diff --git a/icons/obj/cult.dmi b/icons/obj/cult.dmi index a7c52c7747f..22b53247aa8 100644 Binary files a/icons/obj/cult.dmi and b/icons/obj/cult.dmi differ diff --git a/icons/obj/items.dmi b/icons/obj/items.dmi index 49029729923..f6502845739 100644 Binary files a/icons/obj/items.dmi and b/icons/obj/items.dmi differ diff --git a/sound/effects/deconversion_complete.ogg b/sound/effects/deconversion_complete.ogg new file mode 100644 index 00000000000..3008a354e88 Binary files /dev/null and b/sound/effects/deconversion_complete.ogg differ diff --git a/sound/effects/deconversion_failed.ogg b/sound/effects/deconversion_failed.ogg new file mode 100644 index 00000000000..747229cb9d4 Binary files /dev/null and b/sound/effects/deconversion_failed.ogg differ diff --git a/sound/effects/deconversion_start.ogg b/sound/effects/deconversion_start.ogg new file mode 100644 index 00000000000..60e7c1898ed Binary files /dev/null and b/sound/effects/deconversion_start.ogg differ diff --git a/vgstation13.dme b/vgstation13.dme index 64963862d70..81c019aab7a 100644 --- a/vgstation13.dme +++ b/vgstation13.dme @@ -2005,6 +2005,7 @@ #include "code\modules\mob\living\simple_animal\hostile\pitbull.dm" #include "code\modules\mob\living\simple_animal\hostile\rattlemebones.dm" #include "code\modules\mob\living\simple_animal\hostile\scp_173.dm" +#include "code\modules\mob\living\simple_animal\hostile\shade.dm" #include "code\modules\mob\living\simple_animal\hostile\skeletonjack.dm" #include "code\modules\mob\living\simple_animal\hostile\slime.dm" #include "code\modules\mob\living\simple_animal\hostile\tree.dm"