Spectral blade now shows orbs, not ghosts (#24124)

* Implements

* yeah I meant to do this

* this should probably be safer

* alpha

* Add some contingencies

* Update code/modules/mining/lavaland/loot/tendril_loot.dm

Co-authored-by: Henri215 <77684085+Henri215@users.noreply.github.com>

---------

Co-authored-by: Henri215 <77684085+Henri215@users.noreply.github.com>
This commit is contained in:
Luc
2024-03-01 15:07:19 -05:00
committed by GitHub
parent 1937ac2db7
commit 06f89243f3
2 changed files with 69 additions and 18 deletions
@@ -39,19 +39,25 @@
attack_verb = list("attacked", "slashed", "stabbed", "sliced", "torn", "ripped", "diced", "rended")
flags_2 = RANDOM_BLOCKER_2
var/summon_cooldown = 0
var/list/mob/dead/observer/spirits
/// List of wisps we have active, for cleanup purposes in case a ghost gets randomly deleted.
var/list/obj/effect/wisp/ghost/orbs
/// List of ghosts currently orbiting us.
var/list/mob/dead/observer/ghosts
/obj/item/melee/ghost_sword/New()
..()
spirits = list()
ghosts = list()
orbs = list()
register_signals(src)
RegisterSignal(src, COMSIG_MOVABLE_MOVED, PROC_REF(on_move))
GLOB.poi_list |= src
/obj/item/melee/ghost_sword/Destroy()
for(var/mob/dead/observer/G in spirits)
for(var/mob/dead/observer/G in ghosts)
remove_ghost(G)
spirits.Cut()
// if there are any orbs left (possibly detached from ghosts) ensure they don't stick around
for(var/spirit as anything in orbs)
qdel(spirit)
remove_signals(src)
UnregisterSignal(src, COMSIG_MOVABLE_MOVED)
GLOB.poi_list -= src
@@ -59,8 +65,8 @@
/obj/item/melee/ghost_sword/examine()
. = ..()
if(length(spirits))
. += "It appears to pulse with the power of [length(spirits)] vengeful spirits!"
if(length(orbs))
. += "It appears to pulse with the power of [length(orbs)] vengeful spirit\s!"
else
. += "It glows weakly."
@@ -83,7 +89,7 @@
/obj/item/melee/ghost_sword/proc/add_ghost(atom/movable/orbited, atom/orbiter)
SIGNAL_HANDLER // COMSIG_ATOM_ORBIT_BEGIN
var/mob/dead/observer/ghost = orbiter
if(!istype(ghost) || !isobserver(orbiter) || (ghost in spirits))
if(!istype(ghost) || !isobserver(orbiter) || (ghost in ghosts))
return
if(!ismob(loc))
@@ -91,23 +97,34 @@
// they'll get added to spirits (and turned visible) when the sword enters a mob's hand then
return
register_signals(ghost) // Pull in any ghosts that may be orbiting other ghosts TODO THIS MIGHT BE THE FUCKIN PROBLEM
register_signals(ghost) // Pull in any ghosts that may be orbiting other ghosts
spirits |= ghost
ghost.invisibility = 0
var/obj/effect/wisp/ghost/orb = new(src)
orb.color = ghost.get_runechat_color()
orb.alpha = 128
orb.orbit(src, clockwise = FALSE)
ghosts[ghost] = orb
orbs.Add(orb)
// if a ghost gets deleted, the orb cleans itself up
// which then passes the torch to us to clean ourselves up
RegisterSignal(orb, COMSIG_PARENT_QDELETING, PROC_REF(on_orb_qdel))
/obj/item/melee/ghost_sword/proc/remove_ghost(atom/movable/orbited, atom/orbiter)
SIGNAL_HANDLER // COMSIG_ATOM_ORBIT_STOP
var/mob/dead/observer/ghost = orbiter
if(!istype(ghost) || !isobserver(ghost) || !(ghost in spirits))
if(!istype(ghost) || !(ghost in ghosts))
return
remove_signals(ghost)
spirits -= ghost
ghost.invisibility = initial(ghost.invisibility)
var/obj/effect/wisp/ghost/attached_orb = ghosts[ghost]
attached_orb.stop_orbit()
qdel(attached_orb)
ghosts -= ghost
/obj/item/melee/ghost_sword/proc/remove_signals(atom/A)
UnregisterSignal(A, COMSIG_ATOM_ORBIT_STOP)
@@ -126,7 +143,7 @@
if(ismob(old_loc))
remove_signals(old_loc)
for(var/mob/dead/observer/orbiter in spirits)
for(var/mob/dead/observer/orbiter in ghosts)
remove_ghost(src, orbiter)
if(ismob(loc))
@@ -135,20 +152,48 @@
for(var/mob/dead/observer/orbiter in get_orbiters_up_hierarchy(recursive = TRUE))
add_ghost(src, orbiter)
// clean up wisps
/obj/item/melee/ghost_sword/proc/on_orb_qdel(obj/effect/wisp/ghost/orb)
SIGNAL_HANDLER // COMSIG_PARENT_QDELETING
orbs -= orb
for(var/ghost in ghosts)
if(ghosts[ghost] == orb)
ghosts -= ghost
break
/obj/item/melee/ghost_sword/attack(mob/living/target, mob/living/carbon/human/user)
force = 0
var/ghost_counter = length(spirits)
var/ghost_counter = length(orbs)
force = clamp((ghost_counter * 4), 0, 75)
user.visible_message("<span class='danger'>[user] strikes with the force of [ghost_counter] vengeful spirits!</span>")
user.visible_message("<span class='danger'>[user] strikes with the force of [ghost_counter] vengeful spirit\s!</span>")
..()
/obj/item/melee/ghost_sword/hit_reaction(mob/living/carbon/human/owner, atom/movable/hitby, attack_text = "the attack", final_block_chance = 0, damage = 0, attack_type = MELEE_ATTACK)
var/ghost_counter = length(spirits)
var/ghost_counter = length(orbs)
final_block_chance += clamp((ghost_counter * 5), 0, 75)
owner.visible_message("<span class='danger'>[owner] is protected by a ring of [ghost_counter] ghosts!</span>")
owner.visible_message("<span class='danger'>[owner] is protected by a ring of [ghost_counter] ghost\s!</span>")
return ..()
/obj/effect/wisp/ghost
name = "mischievous wisp"
desc = "A wisp that seems to want to get up to shenanigans. It often seems disappointed, for some reason."
light_range = 0
mouse_opacity = MOUSE_OPACITY_TRANSPARENT
/obj/effect/wisp/ghost/Initialize(mapload, mob/dead/observer/ghost)
. = ..()
RegisterSignal(ghost, COMSIG_PARENT_QDELETING, PROC_REF(on_ghost_qdel))
/obj/effect/wisp/ghost/proc/on_ghost_qdel(mob/dead/observer/ghost)
SIGNAL_HANDLER // COMSIG_PARENT_QDELETING
stop_orbit()
// we only live as long as our attached ghost
qdel(src)
// Blood
/obj/item/dragons_blood
@@ -35,6 +35,8 @@ GLOBAL_VAR_INIT(observer_default_invisibility, INVISIBILITY_OBSERVER)
///toggle for ghost gas analyzer
var/gas_analyzer = FALSE
var/datum/orbit_menu/orbit_menu
/// The "color" their runechat would have had
var/alive_runechat_color = "#FFFFFF"
/mob/dead/observer/New(mob/body=null, flags=1)
set_invisibility(GLOB.observer_default_invisibility)
@@ -59,6 +61,7 @@ GLOBAL_VAR_INIT(observer_default_invisibility, INVISIBILITY_OBSERVER)
if(ismob(body))
T = get_turf(body) //Where is the body located?
attack_log_old = body.attack_log_old //preserve our attack logs by copying them to our ghost
alive_runechat_color = body.get_runechat_color()
var/mutable_appearance/MA = copy_appearance(body)
if(body.mind && body.mind.name)
@@ -846,3 +849,6 @@ This is the proc mobs get to turn into a ghost. Forked from ghostize due to comp
return allow_roundstart_observers
return FALSE
/mob/dead/observer/get_runechat_color()
return alive_runechat_color