[MIRROR] Using a soulstone on a construct shell no longer destroys it and the shade if no option is taken. Plus code improvement (#7928)

* Using a soulstone on a construct shell no longer destroys it and the shade if no option is taken. Plus code improvement

* Fixed the merge conflicts.

Co-authored-by: Ghom <42542238+Ghommie@users.noreply.github.com>
Co-authored-by: GoldenAlpharex <jerego1234@hotmail.com>
This commit is contained in:
SkyratBot
2021-09-03 20:31:43 -04:00
committed by GitHub
co-authored by Ghom GoldenAlpharex
parent fa9916dd20
commit 98ee0b19e5
5 changed files with 89 additions and 113 deletions
+15 -13
View File
@@ -212,19 +212,21 @@
if(dash_toggled && !proximity)
jaunt.Teleport(user, target)
return
if(proximity)
if(ishuman(target))
var/mob/living/carbon/human/H = target
if(H.stat != CONSCIOUS)
var/obj/item/soulstone/SS = new /obj/item/soulstone(src)
SS.attack(H, user)
if(!LAZYLEN(SS.contents))
qdel(SS)
if(istype(target, /obj/structure/constructshell) && contents.len)
var/obj/item/soulstone/SS = contents[1]
if(istype(SS))
SS.transfer_soul("CONSTRUCT",target,user)
qdel(SS)
if(!proximity)
return
if(ishuman(target))
var/mob/living/carbon/human/human_target = target
if(human_target.stat != CONSCIOUS)
var/obj/item/soulstone/stone = new /obj/item/soulstone(src)
stone.attack(human_target, user)
if(!LAZYLEN(stone.contents))
qdel(stone)
if(istype(target, /obj/structure/constructshell) && contents.len)
var/obj/item/soulstone/stone = contents[1]
if(!istype(stone))
stone.forceMove(drop_location())
else if(!stone.transfer_to_construct(target, user) && !(locate(/mob/living/simple_animal/shade) in stone))
qdel(stone)
/datum/action/innate/dash/cult
name = "Rend the Veil"
+2 -2
View File
@@ -325,7 +325,7 @@ structure_check() searches for nearby cultist structures required for the invoca
if(iscyborg(sacrificial))
var/construct_class = show_radial_menu(first_invoker, sacrificial, GLOB.construct_radial_images, require_near = TRUE, tooltips = TRUE)
if(QDELETED(sacrificial))
if(QDELETED(sacrificial) || !construct_class)
return FALSE
sacrificial.grab_ghost()
make_new_construct_from_class(construct_class, THEME_CULT, sacrificial, first_invoker, TRUE, get_turf(src))
@@ -336,7 +336,7 @@ structure_check() searches for nearby cultist structures required for the invoca
var/obj/item/soulstone/stone = new /obj/item/soulstone(get_turf(src))
if(sacrificial.mind && !sacrificial.suiciding)
stone.invisibility = INVISIBILITY_MAXIMUM //so it's not picked up during transfer_soul()
stone.transfer_soul("FORCE", sacrificial, usr)
stone.capture_soul(sacrificial, first_invoker, TRUE)
stone.invisibility = 0
//SKYRAT EDIT BEGIN -- SOULSTONE_CHANGES
if(sacrificial)
@@ -139,7 +139,7 @@
hot_potato(user)
return
log_combat(user, M, "captured [M.name]'s soul", src)
transfer_soul("VICTIM", M, user)
capture_soul(M, user)
///////////////////Options for using captured souls///////////////////////////////////////
@@ -234,94 +234,72 @@
if(SS.theme == THEME_HOLY && IS_CULTIST(user))
SS.hot_potato(user)
return
SS.transfer_soul("CONSTRUCT",src,user)
SS.was_used()
SS.transfer_to_construct(src, user)
else
return ..()
////////////////////////////Proc for moving soul in and out off stone//////////////////////////////////////
/// Procs for moving soul in and out off stone
/// transfer the mind of a carbon mob (which is then dusted) into a shade mob inside src. If forced, sacrifical and stat checks are skipped.
/obj/item/soulstone/proc/capture_soul(mob/living/carbon/victim, mob/user, forced = FALSE)
if(!iscarbon(victim)) //TODO: Add sacrifice stoning for non-organics, just because you have no body doesnt mean you dont have a soul
return FALSE
if(!forced)
var/datum/antagonist/cult/C = user?.mind?.has_antag_datum(/datum/antagonist/cult,TRUE)
if(C?.cult_team.is_sacrifice_target(victim.mind))
to_chat(user, span_cult("<b>\"This soul is mine.</b></span> <span class='cultlarge'>SACRIFICE THEM!\""))
return FALSE
if(contents.len)
return FALSE
if(!forced && (grab_sleeping ? victim.stat == CONSCIOUS : victim.stat != DEAD))
to_chat(user, "[span_userdanger("Capture failed!")]: Kill or maim the victim first!")
return FALSE
if(victim.client)
// victim.unequip_everything() /// SKYRAT EDIT REMOVAL BEGIN - SOULSTONE_CHANGES
init_shade(victim, user)
return TRUE
else
to_chat(user, "[span_userdanger("Capture failed!")]: The soul has already fled its mortal frame. You attempt to bring it back...")
return getCultGhost(victim,user)
/obj/item/soulstone/proc/transfer_soul(choice as text, target, mob/user)
switch(choice)
if("FORCE")
if(!iscarbon(target)) //TODO: Add sacrifice stoning for non-organics, just because you have no body doesnt mean you dont have a soul
return FALSE
if(contents.len)
return FALSE
var/mob/living/carbon/T = target
if(T.client != null)
/* SKYRAT EDIT REMOVAL BEGIN - SOULSTONE_CHANGES
for(var/obj/item/W in T)
T.dropItemToGround(W)
*/
//SKYRAT EDIT REMOVAL END
init_shade(T, user)
return TRUE
else
to_chat(user, "[span_userdanger("Capture failed!")]: The soul has already fled its mortal frame. You attempt to bring it back...")
return getCultGhost(T,user)
///captures a shade that was previously released from a soulstone.
/obj/item/soulstone/proc/capture_shade(mob/living/simple_animal/shade/shade, mob/user)
if(contents.len)
to_chat(user, "[span_userdanger("Capture failed!")]: [src] is full! Free an existing soul to make room.")
return FALSE
shade.AddComponent(/datum/component/soulstoned, src)
if(theme == THEME_HOLY)
icon_state = "purified_soulstone2"
shade.mind?.remove_antag_datum(/datum/antagonist/cult)
if(theme == THEME_WIZARD)
icon_state = "mystic_soulstone2"
if(theme == THEME_CULT)
icon_state = "soulstone2"
name = "soulstone: Shade of [shade.real_name]"
to_chat(shade, span_notice("Your soul has been captured by [src]. Its arcane energies are reknitting your ethereal form."))
if(user != shade)
to_chat(user, "[span_info("<b>Capture successful!</b>:")] [shade.real_name]'s soul has been captured and stored within [src].")
return TRUE
if("VICTIM")
var/mob/living/carbon/human/T = target
var/datum/antagonist/cult/C = user.mind.has_antag_datum(/datum/antagonist/cult,TRUE)
if(C?.cult_team.is_sacrifice_target(T.mind))
to_chat(user, span_cult("<b>\"This soul is mine.</b></span> <span class='cultlarge'>SACRIFICE THEM!\""))
return FALSE
if(contents.len)
to_chat(user, "[span_userdanger("Capture failed!")]: [src] is full! Free an existing soul to make room.")
else
if((grab_sleeping && T.stat != CONSCIOUS) || (!grab_sleeping && T.stat == DEAD))
if(T.client == null)
to_chat(user, "[span_userdanger("Capture failed!")]: The soul has already fled its mortal frame. You attempt to bring it back...")
getCultGhost(T,user)
else
/* SKYRAT EDIT REMOVAL BEGIN - SOULSTONE_CHANGES
for(var/obj/item/W in T)
T.dropItemToGround(W)
*/
//SKYRAT EDIT REMOVAL END
init_shade(T, user, message_user = 1)
qdel(T)
else
to_chat(user, "[span_userdanger("Capture failed!")]: Kill or maim the victim first!")
///transfer the mind of the shade to a construct mob selected by the user, then deletes both the shade and src.
/obj/item/soulstone/proc/transfer_to_construct(obj/structure/constructshell/shell, mob/user)
var/mob/living/simple_animal/shade/shade = locate() in src
if(!shade)
to_chat(user, "[span_userdanger("Creation failed!")]: [src] is empty! Go kill someone!")
return FALSE
var/construct_class = show_radial_menu(user, src, GLOB.construct_radial_images, custom_check = CALLBACK(src, .proc/check_menu, user, shell), require_near = TRUE, tooltips = TRUE)
if(!shell || !construct_class)
return FALSE
make_new_construct_from_class(construct_class, theme, shade, user, FALSE, shell.loc)
shade.mind?.remove_antag_datum(/datum/antagonist/cult)
qdel(shell)
qdel(src)
return TRUE
if("SHADE")
var/mob/living/simple_animal/shade/T = target
if(contents.len)
to_chat(user, "[span_userdanger("Capture failed!")]: [src] is full! Free an existing soul to make room.")
else
T.AddComponent(/datum/component/soulstoned, src)
if(theme == THEME_HOLY)
icon_state = "purified_soulstone2"
T.mind?.remove_antag_datum(/datum/antagonist/cult)
if(theme == THEME_WIZARD)
icon_state = "mystic_soulstone2"
if(theme == THEME_CULT)
icon_state = "soulstone2"
name = "soulstone: Shade of [T.real_name]"
to_chat(T, span_notice("Your soul has been captured by [src]. Its arcane energies are reknitting your ethereal form."))
if(user != T)
to_chat(user, "[span_info("<b>Capture successful!</b>:")] [T.real_name]'s soul has been captured and stored within [src].")
if("CONSTRUCT")
var/obj/structure/constructshell/T = target
var/mob/living/simple_animal/shade/A = locate() in src
if(A)
var/construct_class = show_radial_menu(user, src, GLOB.construct_radial_images, custom_check = CALLBACK(src, .proc/check_menu, user), require_near = TRUE, tooltips = TRUE)
if(!T || !T.loc)
return
make_new_construct_from_class(construct_class, theme, A, user, FALSE, T.loc)
A.mind?.remove_antag_datum(/datum/antagonist/cult)
qdel(T)
qdel(src)
else
to_chat(user, "[span_userdanger("Creation failed!")]: [src] is empty! Go kill someone!")
/obj/item/soulstone/proc/check_menu(mob/user)
/obj/item/soulstone/proc/check_menu(mob/user, obj/structure/constructshell/shell)
if(!istype(user))
return FALSE
if(user.incapacitated() || !user.Adjacent(src))
if(user.incapacitated() || !user.is_holding(src) || !user.CanReach(shell, src))
return FALSE
return TRUE
@@ -447,27 +425,23 @@
to_chat(user, "[span_info("<b>Capture successful!</b>:")] [dusted_victim.real_name]'s soul has been ripped from [dusted_victim.p_their()] body and stored within [src].")
/obj/item/soulstone/proc/getCultGhost(mob/living/carbon/human/T, mob/user)
/obj/item/soulstone/proc/getCultGhost(mob/living/carbon/victim, mob/user)
var/mob/dead/observer/chosen_ghost
chosen_ghost = T.get_ghost(TRUE,TRUE) //Try to grab original owner's ghost first
chosen_ghost = victim.get_ghost(TRUE,TRUE) //Try to grab original owner's ghost first
if(!chosen_ghost || !chosen_ghost.client) //Failing that, we grab a ghosts
var/list/consenting_candidates = pollGhostCandidates("Would you like to play as a Shade?", "Cultist", ROLE_CULTIST, 50, POLL_IGNORE_SHADE)
if(consenting_candidates.len)
chosen_ghost = pick(consenting_candidates)
if(!T)
if(!victim || user.incapacitated() || !user.is_holding(src) || !user.CanReach(victim, src))
return FALSE
if(!chosen_ghost || !chosen_ghost.client)
to_chat(user, span_danger("There were no spirits willing to become a shade."))
return FALSE
if(contents.len) //If they used the soulstone on someone else in the meantime
return FALSE
/* SKYRAT EDIT REMOVAL BEGIN - SOULSTONE_CHANGES
for(var/obj/item/W in T)
T.dropItemToGround(W)
*/
//SKYRAT EDIT REMOVAL END
init_shade(T, user , shade_controller = chosen_ghost)
//qdel(T) SKYRAT REMOVAL -- SOULSTONE_CHANGES
// victim.unequip_everything() /// SKYRAT REMOVAL - SOULSTONE_CHANGES
init_shade(victim, user, shade_controller = chosen_ghost)
// qdel(victim) /// SKYRAT REMOVAL - SOULSTONE_CHANGES
return TRUE
@@ -65,9 +65,9 @@
else if(src != user)
return ..()
/mob/living/simple_animal/shade/attackby(obj/item/O, mob/user, params) //Marker -Agouri
if(istype(O, /obj/item/soulstone))
var/obj/item/soulstone/SS = O
SS.transfer_soul("SHADE", src, user)
/mob/living/simple_animal/shade/attackby(obj/item/item, mob/user, params) //Marker -Agouri
if(istype(item, /obj/item/soulstone))
var/obj/item/soulstone/stone = item
stone.capture_shade(src, user)
else
. = ..()
@@ -263,10 +263,10 @@
desc = "To play with this revolver requires wagering your very soul."
/obj/item/gun/ballistic/revolver/russian/soul/shoot_self(mob/living/user)
..()
var/obj/item/soulstone/anybody/revolver/SS = new /obj/item/soulstone/anybody/revolver(get_turf(src))
if(!SS.transfer_soul("FORCE", user)) //Something went wrong
qdel(SS)
. = ..()
var/obj/item/soulstone/anybody/revolver/stone = new /obj/item/soulstone/anybody/revolver(get_turf(src))
if(!stone.capture_soul(user, forced = TRUE)) //Something went wrong
qdel(stone)
return
user.visible_message(span_danger("[user.name]'s soul is captured by \the [src]!"), span_userdanger("You've lost the gamble! Your soul is forfeit!"))