mirror of
https://github.com/Bubberstation/Bubberstation.git
synced 2026-08-24 13:38:41 +01:00
Mirrors can trap dormant revenants (#95942)
## About The Pull Request If glimmering residue (revenant ectoplasm) is scattered in the vicinity of a mirror, the revenant will be trapped inside it instead. -When mirrors are cursed in this way, the reflections are shifty and distorted, like the revenant's reflection when it's alive. -In this state, the revenant may only communicate via telepathy with people reflected in the mirror (it's more like "standing close to it", but that's probably ok). -If the mirror is broken, the revenant will reform. If it's catatonic, a new candidate will be pulled, much like with ectoplasm reforming. -If the mirror is destroyed in another way, the revenant will be destroyed as well. -There is a 1/500 chance that a mirror will be haunted roundstart ## Why It's Good For The Game You can now torment the revenant by eternally trapping it if it really pissed you off ## Changelog 🆑 add: you can now trap dormant revenants in mirrors add: haunted mirrors may very rarely appear roundstart /🆑 --------- Co-authored-by: l0 <--> Co-authored-by: SmArtKar <44720187+SmArtKar@users.noreply.github.com>
This commit is contained in:
co-authored by
l0 <-->
SmArtKar
parent
259a28b98b
commit
7cf1670987
@@ -62,6 +62,8 @@
|
||||
var/draining = FALSE
|
||||
/// Have we already given this revenant abilities?
|
||||
var/generated_objectives_and_spells = FALSE
|
||||
/// ckey of the player who controlled this mob when it was killed
|
||||
var/old_ckey = ""
|
||||
|
||||
/// Lazylist of drained mobs to ensure that we don't steal a soul from someone twice
|
||||
var/list/drained_mobs = null
|
||||
@@ -343,10 +345,7 @@
|
||||
|
||||
visible_message(span_danger("[src]'s body breaks apart into a fine pile of blue dust."))
|
||||
|
||||
var/obj/item/ectoplasm/revenant/goop = new(get_turf(src)) // the ectoplasm will handle moving us out of dormancy
|
||||
goop.old_ckey = client.ckey
|
||||
goop.revenant = src
|
||||
forceMove(goop)
|
||||
new /obj/item/ectoplasm/revenant(get_turf(src), src) // the ectoplasm will handle moving us out of dormancy
|
||||
|
||||
/mob/living/basic/revenant/proc/on_move(datum/source, atom/entering_loc)
|
||||
SIGNAL_HANDLER
|
||||
@@ -519,4 +518,30 @@
|
||||
if(!HAS_TRAIT(src, TRAIT_REVENANT_REVEALED) && !istype(reflecting_in, /obj/structure/mirror/magic))
|
||||
apply_wibbly_filters(reflection)
|
||||
|
||||
/mob/living/basic/revenant/proc/get_new_user()
|
||||
message_admins("A poll for the reforming revenant was created.")
|
||||
var/mob/chosen_one = SSpolling.poll_ghosts_for_target("Do you want to be [span_notice(name)] (reforming)?", check_jobban = ROLE_REVENANT, role = ROLE_REVENANT, poll_time = 5 SECONDS, checked_target = src, alert_pic = src, role_name_text = "reforming revenant", chat_text_border_icon = src)
|
||||
if(!chosen_one)
|
||||
message_admins("No candidates were found for the new revenant.")
|
||||
visible_message(span_revenwarning("A blue dust appears from thin air and settles down."))
|
||||
new /obj/item/ectoplasm/revenant(get_turf(src)) // inert
|
||||
qdel(src)
|
||||
return
|
||||
|
||||
PossessByPlayer(chosen_one.key)
|
||||
message_admins("[chosen_one.key] has been made into the reformed revenant via poll.")
|
||||
qdel(chosen_one)
|
||||
|
||||
/mob/living/basic/revenant/proc/reform(cause)
|
||||
if(QDELETED(src))
|
||||
return FALSE
|
||||
|
||||
death_reset()
|
||||
if(isnull(client))
|
||||
INVOKE_ASYNC(src, PROC_REF(get_new_user))
|
||||
return TRUE
|
||||
|
||||
message_admins("[client.ckey] has been remade into a revenant.")
|
||||
log_message("was remade as a revenant.", LOG_GAME)
|
||||
return TRUE
|
||||
#undef REVENANT_STUNNED_TRAIT
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
#define REVENANT_DEFILE_MIN_DAMAGE 30
|
||||
#define REVENANT_DEFILE_MAX_DAMAGE 50
|
||||
|
||||
//Transmit: the revemant's only direct way to communicate. Sends a single message silently to a single mob
|
||||
//Transmit: the revenant's only direct way to communicate. Sends a single message silently to a single mob
|
||||
/datum/action/cooldown/spell/list_target/telepathy/revenant
|
||||
name = "Revenant Transmit"
|
||||
background_icon_state = "bg_revenant"
|
||||
@@ -12,6 +12,14 @@
|
||||
|
||||
antimagic_flags = MAGIC_RESISTANCE_HOLY|MAGIC_RESISTANCE_MIND
|
||||
|
||||
/datum/action/cooldown/spell/list_target/telepathy/revenant/get_list_targets(atom/center, target_radius = 7)
|
||||
if(!istype(center, /mob/living/basic/revenant))
|
||||
return ..()
|
||||
var/mob/living/basic/revenant/revenant = center
|
||||
if(!revenant.dormant)
|
||||
return ..()
|
||||
return ..(get_turf(revenant), 2)
|
||||
|
||||
/datum/action/cooldown/spell/aoe/revenant
|
||||
background_icon_state = "bg_revenant"
|
||||
overlay_icon_state = "bg_revenant_border"
|
||||
|
||||
@@ -5,31 +5,36 @@
|
||||
icon = 'icons/effects/effects.dmi'
|
||||
icon_state = "revenantEctoplasm"
|
||||
w_class = WEIGHT_CLASS_SMALL
|
||||
/// Are we currently reforming?
|
||||
var/reforming = TRUE
|
||||
/// Are we inert (aka distorted such that we can't reform)?
|
||||
// Can the revenant reform?
|
||||
var/inert = FALSE
|
||||
/// The key of the revenant that we started the reform as
|
||||
var/old_ckey
|
||||
/// The revenant we're currently storing
|
||||
var/mob/living/basic/revenant/revenant
|
||||
|
||||
/obj/item/ectoplasm/revenant/Initialize(mapload)
|
||||
/obj/item/ectoplasm/revenant/Initialize(mapload, revenant)
|
||||
. = ..()
|
||||
addtimer(CALLBACK(src, PROC_REF(try_reform)), 1 MINUTES)
|
||||
inert = !revenant
|
||||
if(revenant)
|
||||
AddComponent(/datum/component/revenant_prison, revenant = revenant)
|
||||
addtimer(CALLBACK(src, PROC_REF(reform)), 1 MINUTES)
|
||||
|
||||
/obj/item/ectoplasm/revenant/Destroy()
|
||||
if(!QDELETED(revenant))
|
||||
qdel(revenant)
|
||||
return ..()
|
||||
|
||||
/obj/item/ectoplasm/revenant/proc/check_for_mirrors(turf/location, radius)
|
||||
PRIVATE_PROC(TRUE)
|
||||
for(var/obj/structure/mirror/mirror in view(radius, location))
|
||||
if(mirror.cursable && !mirror.GetComponent(/datum/component/revenant_prison))
|
||||
return mirror
|
||||
return null
|
||||
|
||||
/obj/item/ectoplasm/revenant/attack_self(mob/user)
|
||||
if(!reforming || inert)
|
||||
if(inert)
|
||||
return ..()
|
||||
user.visible_message(
|
||||
span_notice("[user] scatters [src] in all directions."),
|
||||
span_notice("You scatter [src] across the area. The particles slowly fade away."),
|
||||
span_notice("You scatter [src] across the area."),
|
||||
)
|
||||
var/obj/structure/mirror/nearby_mirror = check_for_mirrors(drop_location(), 5)
|
||||
if(nearby_mirror)
|
||||
transfer_to_mirror(nearby_mirror)
|
||||
user.dropItemToGround(src)
|
||||
qdel(src)
|
||||
|
||||
@@ -37,14 +42,25 @@
|
||||
. = ..()
|
||||
if(inert)
|
||||
return
|
||||
visible_message(span_notice("[src] breaks into particles upon impact, which fade away to nothingness."))
|
||||
var/obj/structure/mirror/nearby_mirror = check_for_mirrors(get_turf(hit_atom), 3)
|
||||
if(!nearby_mirror)
|
||||
visible_message(span_notice("[src] breaks into particles upon impact, which fade away to nothingness."))
|
||||
else
|
||||
transfer_to_mirror(nearby_mirror)
|
||||
qdel(src)
|
||||
|
||||
/obj/item/ectoplasm/revenant/proc/transfer_to_mirror(obj/structure/mirror/nearby_mirror)
|
||||
PRIVATE_PROC(TRUE)
|
||||
nearby_mirror.TakeComponent(GetComponent(/datum/component/revenant_prison))
|
||||
nearby_mirror.visible_message(span_revenwarning("A dismal moan echoes as particles of [src] fall onto [nearby_mirror]!"))
|
||||
log_game("A revenant was trapped inside [nearby_mirror]")
|
||||
message_admins("A revenant was trapped inside [nearby_mirror] [ADMIN_JMP(nearby_mirror)]")
|
||||
|
||||
/obj/item/ectoplasm/revenant/examine(mob/user)
|
||||
. = ..()
|
||||
if(inert)
|
||||
. += span_revennotice("It seems inert.")
|
||||
else if(reforming)
|
||||
else
|
||||
. += span_revenwarning("It is shifting and distorted. It would be wise to destroy this.")
|
||||
|
||||
/obj/item/ectoplasm/revenant/suicide_act(mob/living/user)
|
||||
@@ -52,45 +68,13 @@
|
||||
qdel(src)
|
||||
return OXYLOSS
|
||||
|
||||
/obj/item/ectoplasm/revenant/proc/try_reform()
|
||||
if(reforming)
|
||||
reforming = FALSE
|
||||
reform()
|
||||
else
|
||||
inert = TRUE
|
||||
visible_message(span_warning("[src] settles down and seems lifeless."))
|
||||
|
||||
/// Actually moves the revenant out of ourself
|
||||
/obj/item/ectoplasm/revenant/proc/reform()
|
||||
if(QDELETED(src) || QDELETED(revenant) || inert)
|
||||
if(QDELETED(src) || inert)
|
||||
return
|
||||
if(!GetComponent(/datum/component/revenant_prison))
|
||||
return
|
||||
|
||||
message_admins("Revenant ectoplasm was left undestroyed for 1 minute and is reforming into a new revenant.")
|
||||
forceMove(drop_location()) //In case it's in a backpack or someone's hand
|
||||
|
||||
var/user_name = old_ckey
|
||||
if(isnull(revenant.client))
|
||||
var/mob/potential_user = get_new_user()
|
||||
revenant.PossessByPlayer(potential_user.key)
|
||||
user_name = potential_user.ckey
|
||||
qdel(potential_user)
|
||||
|
||||
message_admins("[user_name] has been [old_ckey == user_name ? "re":""]made into a revenant by reforming ectoplasm.")
|
||||
revenant.log_message("was [old_ckey == user_name ? "re":""]made as a revenant by reforming ectoplasm.", LOG_GAME)
|
||||
SEND_SIGNAL(src, COMSIG_REVENANT_RELEASE, cause = "ectoplasm reforming")
|
||||
visible_message(span_revenboldnotice("[src] suddenly rises into the air before fading away."))
|
||||
|
||||
revenant.death_reset()
|
||||
revenant = null
|
||||
qdel(src)
|
||||
|
||||
/// Handles giving the revenant a new client to control it
|
||||
/obj/item/ectoplasm/revenant/proc/get_new_user()
|
||||
message_admins("The new revenant's old client either could not be found or is in a new, living mob - grabbing a random candidate instead...")
|
||||
var/mob/chosen_one = SSpolling.poll_ghosts_for_target("Do you want to be [span_notice(revenant.name)] (reforming)?", check_jobban = ROLE_REVENANT, role = ROLE_REVENANT, poll_time = 5 SECONDS, checked_target = revenant, alert_pic = revenant, role_name_text = "reforming revenant", chat_text_border_icon = revenant)
|
||||
if(isnull(chosen_one))
|
||||
message_admins("No candidates were found for the new revenant.")
|
||||
inert = TRUE
|
||||
visible_message(span_revenwarning("[src] settles down and seems lifeless."))
|
||||
qdel(revenant)
|
||||
return null
|
||||
return chosen_one
|
||||
|
||||
Reference in New Issue
Block a user