Skip to content

Cult 2020 (actually let's just call it Cult 4) Rework Part #3: Conversion rework, Deconversion, & Holy Implants #28613

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
6 changes: 6 additions & 0 deletions __DEFINES/role_datums_defines.dm
Original file line number Diff line number Diff line change
Expand Up @@ -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"
Expand Down Expand Up @@ -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
Expand All @@ -186,6 +189,9 @@
#define CONVERTIBLE_ALREADY 5
#define CONVERTIBLE_IMPLANT 6

#define DECONVERSION_ACCEPT 1
#define DECONVERSION_REFUSE 2

////////////////////////////////////////////////////////////////////////////////

// -- Objectives flags
Expand Down
2 changes: 2 additions & 0 deletions code/__HELPERS/unsorted.dm
Original file line number Diff line number Diff line change
Expand Up @@ -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)
Expand Down
10 changes: 10 additions & 0 deletions code/_onclick/hud/fullscreen.dm
Original file line number Diff line number Diff line change
Expand Up @@ -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"
Expand Down
65 changes: 54 additions & 11 deletions code/datums/gamemode/factions/bloodcult/bloodcult.dm
Original file line number Diff line number Diff line change
Expand Up @@ -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

Expand Down Expand Up @@ -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("<span class='warning'>\The [I] pops out of \the [M]'s head.</span>")
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.
Expand Down Expand Up @@ -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, "<span class='sinister'>Your blood pushes back against the loyalty implant, it will visibly pop out within seconds!</span>")
spawn(10 SECONDS)
I.forceMove(get_turf(src))
I.implanted = 0
visible_message("<span class='warning'>\The [I] pops out of \the [src]'s head.</span>")

/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
Expand Down Expand Up @@ -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())
Expand Down
14 changes: 13 additions & 1 deletion code/datums/gamemode/factions/bloodcult/bloodcult_buildings.dm
Original file line number Diff line number Diff line change
Expand Up @@ -557,10 +557,22 @@
var/extra = ""
if (H && istype(H))
if (H.isInCrit())
extra = " - <span style='color:#FF0000'>CRITICAL</span>"
extra = " - <span style='color:#FFFF00'>CRITICAL</span>"
else if (H.isDead())
extra = " - <span style='color:#FF0000'>DEAD</span>"
dat += "<li><b>[M.name]</b></li> - [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 = " - <span style='color:#FFFF00'>CRITICAL</span>"
else if (C.isDead())
extra = " - <span style='color:#FF0000'>DEAD</span>"
dat += "<li><span style='color:#FFFF00'><b>[C.real_name]</b></span></li> - Prisoner of [gaoler.name][extra]"
dat += {"</ul></body>"}
user << browse("<TITLE>Cult Roster</TITLE>[dat]", "window=cultroster;size=500x300")
onclose(user, "cultroster")
Expand Down
53 changes: 43 additions & 10 deletions code/datums/gamemode/factions/bloodcult/bloodcult_effects.dm
Original file line number Diff line number Diff line change
Expand Up @@ -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, "<span class='warning'>The blood jaunt fails to grasp you as you are currently anchored.</span>")
if (iscarbon(user))
var/mob/living/carbon/C = user
if (C.occult_muted())
muted = TRUE
to_chat(C, "<span class='warning'>The holy energies upon your body repel the blood jaunt.</span>")
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, "<span class='warning'>The blood jaunt fails to grasp you as you are currently anchored.</span>")
continue
var/muted = FALSE
if (iscarbon(AM))
var/mob/living/carbon/C = AM
if (C.occult_muted())
muted = TRUE
to_chat(C, "<span class='warning'>The holy energies upon your body repel the blood jaunt.</span>")
if (!AM.anchored && !muted)
AM.forceMove(src)
packed.Add(AM)
if (ismob(AM))
Expand Down Expand Up @@ -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,"<span class='danger'>Traveling through the veil seems to have a recharging effect on the ghastly bindings as they begin to hurt you anew.</span>")
rider = null
if (packed.len > 0)
for(var/atom/movable/AM in packed)
Expand All @@ -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,"<span class='danger'>Traveling through the veil seems to have a recharging effect on the ghastly bindings as they begin to hurt you anew.</span>")
packed = list()

if (landing_animation)
Expand Down Expand Up @@ -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////////////////////////////////////////////////
Expand Down
58 changes: 58 additions & 0 deletions code/datums/gamemode/factions/bloodcult/bloodcult_items.dm
Original file line number Diff line number Diff line change
Expand Up @@ -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, "<span class='info'>The tentacles flailing out of this egg-like object seem like they're trying to grasp at their surroundings.</span>")
else
var/mob/living/carbon/C = loc
if (C.handcuffed == src)
to_chat(user, "<span class='info'>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.</span>")
else
to_chat(user, "<span class='info'>\The [C] seems to be in pain as these restrict their arms.</span>")

/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, "<span class='sinister'>Bindings you placed upon someone have been shattered</span>")
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, "<span class='danger'>[pick("It hurts so much!", "You really need some painkillers.", "Dear god, the pain!")]</span>")



///////////////////////////////////////BLOOD TESSERACT////////////////////////////////////////////////

/obj/item/weapon/blood_tesseract
Expand Down
4 changes: 2 additions & 2 deletions code/datums/gamemode/factions/bloodcult/bloodcult_runes.dm
Original file line number Diff line number Diff line change
Expand Up @@ -285,7 +285,7 @@

if(iscarbon(user))
var/mob/living/carbon/C = user
if (C.muted())
if (C.occult_muted())
to_chat(user, "<span class='danger'>You find yourself unable to focus your mind on the arcane words of the rune.</span>")
return

Expand Down Expand Up @@ -418,7 +418,7 @@

if(iscarbon(user))
var/mob/living/carbon/C = user
if (C.muted())
if (C.occult_muted())
to_chat(user, "<span class='danger'>You find yourself unable to focus your mind on the arcane words of the rune.</span>")
return

Expand Down
Loading