/obj/effect/proc_holder/spell/lichdom name = "Bind Soul" desc = "A dark necromantic pact that can forever bind your soul to an item of your choosing. So long as both your body and the item remain intact and on the same plane you can revive from death, though the time between reincarnations grows steadily with use." school = "necromancy" base_cooldown = 10 clothes_req = FALSE centcom_cancast = FALSE invocation = "NECREM IMORTIUM!" invocation_type = "shout" level_max = 0 //cannot be improved cooldown_min = 10 var/marked_item_uid var/mob/living/current_body var/resurrections = 0 var/existence_stops_round_end = FALSE action_icon_state = "skeleton" /obj/effect/proc_holder/spell/lichdom/create_new_targeting() return new /datum/spell_targeting/self /obj/effect/proc_holder/spell/lichdom/Destroy() for(var/datum/mind/M in SSticker.mode.wizards) //Make sure no other bones are about for(var/obj/effect/proc_holder/spell/S in M.spell_list) if(istype(S,/obj/effect/proc_holder/spell/lichdom) && S != src) return ..() if(existence_stops_round_end) GLOB.configuration.gamemode.disable_certain_round_early_end = FALSE return ..() /obj/effect/proc_holder/spell/lichdom/cast(list/targets, mob/user = usr) for(var/mob/M in targets) if(stat_allowed) attempt_revive(M) else if(!marked_item_uid) attempt_mark_item(M) /obj/effect/proc_holder/spell/lichdom/proc/attempt_revive(mob/user) // Can only cast when unconscious/dead if(user.stat == CONSCIOUS) to_chat(user, "You aren't dead enough to revive!") cooldown_handler.revert_cast() return // Body was destroyed if(QDELETED(current_body)) to_chat(user, "Your body is gone!") return // Phylactery was destroyed var/obj/item/marked_item = locateUID(marked_item_uid) if(QDELETED(marked_item)) to_chat(user, "Your phylactery is gone!") return // Wrong z-level var/turf/body_turf = get_turf(current_body) var/turf/item_turf = get_turf(marked_item) if(body_turf.z != item_turf.z) to_chat(user, "Your phylactery is out of range!") return if(isobserver(user)) var/mob/dead/observer/O = user O.reenter_corpse() // Clean up the old body if(!QDELETED(current_body)) if(iscarbon(current_body)) var/mob/living/carbon/C = current_body for(var/obj/item/W in C) C.unEquip(W) // Give a hint as to where the body is var/wheres_wizdo = dir2text(get_dir(body_turf, item_turf)) if(wheres_wizdo) current_body.visible_message("Suddenly [current_body.name]'s corpse falls to pieces! You see a strange energy rise from the remains, and speed off towards the [wheres_wizdo]!") body_turf.Beam(item_turf, icon_state = "lichbeam", icon = 'icons/effects/effects.dmi', time = 10 + 10 * resurrections, maxdistance = INFINITY) UnregisterSignal(current_body, list(COMSIG_PARENT_QDELETING, COMSIG_MOVABLE_Z_CHANGED)) current_body.dust() var/stun_time = (1 + resurrections++) * 20 SECONDS var/mob/living/carbon/human/lich = new /mob/living/carbon/human(item_turf) lich.set_species(/datum/species/skeleton/lich) lich.real_name = user.mind.name lich.Weaken(stun_time) user.mind.transfer_to(lich) equip_lich(lich) RegisterSignal(lich, list(COMSIG_PARENT_QDELETING, COMSIG_MOVABLE_Z_CHANGED), PROC_REF(check_revivability_handler)) current_body = lich cooldown_handler.recharge_duration += 1 MINUTES to_chat(lich, "Your bones clatter and shudder as they're pulled back into this world!") /obj/effect/proc_holder/spell/lichdom/proc/attempt_mark_item(mob/user) var/obj/item/target = user.get_active_hand() if(!target) to_chat(user, "You must hold an item you wish to make your phylactery!") return if(target.flags & (ABSTRACT|NODROP)) to_chat(user, "[target] cannot be used as your phylactery!") return if(!do_after(user, 5 SECONDS, target = target)) to_chat(user, "Your soul snaps back to your body as you drop [target]!") return name = "RISE!" desc = "Rise from the dead! You will reform at the location of your phylactery and your old body will crumble away." stat_allowed = UNCONSCIOUS cooldown_handler.recharge_duration = 3 MINUTES cooldown_handler.revert_cast() if(action && action.button) action.name = action.button.name = name action.desc = action.button.desc = desc target.name = "ensouled [target.name]" target.desc += "
A terrible aura surrounds this item, its very existence is offensive to life itself..." target.color = "#003300" marked_item_uid = target.UID() current_body = user.mind.current if(ishuman(user)) var/mob/living/carbon/human/H = user H.set_species(/datum/species/skeleton/lich) H.unEquip(H.wear_suit) H.unEquip(H.head) H.unEquip(H.shoes) H.unEquip(H.head) equip_lich(H) RegisterSignal(target, list(COMSIG_PARENT_QDELETING, COMSIG_MOVABLE_Z_CHANGED), PROC_REF(check_revivability_handler)) RegisterSignal(current_body, list(COMSIG_PARENT_QDELETING, COMSIG_MOVABLE_Z_CHANGED), PROC_REF(check_revivability_handler)) to_chat(user, "With a hideous feeling of emptiness you watch in horrified fascination as skin sloughs off bone! Blood boils, nerves disintegrate, eyes boil in their sockets! As your organs crumble to dust in your fleshless chest you come to terms with your choice. You're a lich!") existence_stops_round_end = TRUE GLOB.configuration.gamemode.disable_certain_round_early_end = TRUE /obj/effect/proc_holder/spell/lichdom/proc/is_revive_possible() var/obj/item/marked_item = locateUID(marked_item_uid) if(QDELETED(marked_item)) return FALSE if(QDELETED(current_body)) return FALSE var/turf/body_turf = get_turf(current_body) var/turf/item_turf = get_turf(marked_item) if(body_turf.z != item_turf.z) return FALSE return TRUE /obj/effect/proc_holder/spell/lichdom/proc/check_revivability_handler() SIGNAL_HANDLER // There are other liches about, so round may still continue for(var/datum/mind/M in SSticker.mode.wizards) for(var/obj/effect/proc_holder/spell/lichdom/S in M.spell_list) if(S == src) continue // Other lich can still revive if(S.is_revive_possible()) return // Other lich is still alive if(!QDELETED(S.current_body) && S.current_body.stat != DEAD) return GLOB.configuration.gamemode.disable_certain_round_early_end = is_revive_possible() /obj/effect/proc_holder/spell/lichdom/proc/equip_lich(mob/living/carbon/human/H) H.equip_to_slot_or_del(new /obj/item/clothing/suit/wizrobe/black(H), SLOT_HUD_OUTER_SUIT) H.equip_to_slot_or_del(new /obj/item/clothing/head/wizard/black(H), SLOT_HUD_HEAD) H.equip_to_slot_or_del(new /obj/item/clothing/shoes/sandal(H), SLOT_HUD_SHOES) H.equip_to_slot_or_del(new /obj/item/clothing/under/color/black(H), SLOT_HUD_JUMPSUIT)