mirror of
https://github.com/Bubberstation/Bubberstation.git
synced 2025-12-10 17:52:36 +00:00
[MIRROR] Invisibility refactor [MDB IGNORE] (#24405)
* Invisibility refactor (#78908) This adds a tracker for sources of invisibility and a priority system. I needed this for another thing so I'm doing this first since it touches a lot of code. As for the bugs fixed in the changelog, it's only what I noticed while going through everything and there's likely a few more things fixed with this. This should be testmerged for a while, I'll bring this out of draft when it feels safe. 🆑 admin: Invisimin can now be used on mobs that are already invisible, whether through temporary or permanent effects. fix: Monkeyize/Humanize mob transformations no longer permanently reveal invisible mobs if they had effects making them invisible otherwise. fix: Objects with the undertile element that have been made invisible through other means are no longer revealed by being uncovered. /🆑 * Invisibility refactor --------- Co-authored-by: Emmett Gaines <ninjanomnom@gmail.com>
This commit is contained in:
@@ -1,3 +1,5 @@
|
||||
#define INVISIBILITY_NONE 0
|
||||
|
||||
#define SEE_INVISIBLE_MINIMUM 5
|
||||
|
||||
#define INVISIBILITY_LIGHTING 20
|
||||
@@ -57,3 +59,19 @@
|
||||
/// Bitfield of sight flags that show THINGS but no lighting
|
||||
/// Since lighting is an underlay on turfs, this is everything but that
|
||||
#define SEE_AVOID_TURF_BLACKNESS (SEE_MOBS|SEE_OBJS)
|
||||
|
||||
//------------------------
|
||||
// INVISIBILITY PRIORITIES
|
||||
|
||||
#define INVISIBILITY_PRIORITY_ADMIN 100
|
||||
#define INVISIBILITY_PRIORITY_BASIC_ANTI_INVISIBILITY 1
|
||||
#define INVISIBILITY_PRIORITY_NONE 0
|
||||
|
||||
//------------------------
|
||||
// INVISIBILITY SOURCE IDS
|
||||
// Though don't feel the need to add one here if you have a simple effect that
|
||||
// gets added and/or removed in only one place near eachother in the code.
|
||||
|
||||
#define INVISIBILITY_SOURCE_INVISIMIN "invisimin"
|
||||
#define INVISIBILITY_SOURCE_STEALTHMODE "stealthmode"
|
||||
|
||||
|
||||
@@ -779,7 +779,7 @@ GLOBAL_DATUM_INIT(dview_mob, /mob/dview, new)
|
||||
|
||||
/mob/dview
|
||||
name = "INTERNAL DVIEW MOB"
|
||||
invisibility = 101
|
||||
invisibility = INVISIBILITY_ABSTRACT
|
||||
density = FALSE
|
||||
move_resist = INFINITY
|
||||
var/ready_to_die = FALSE
|
||||
|
||||
@@ -18,7 +18,7 @@
|
||||
icon_state = null
|
||||
density = FALSE
|
||||
move_resist = INFINITY
|
||||
invisibility = 0
|
||||
invisibility = INVISIBILITY_NONE
|
||||
mouse_opacity = MOUSE_OPACITY_TRANSPARENT
|
||||
logging = null
|
||||
held_items = null //all of these are list objects that should not exist for something like us
|
||||
|
||||
@@ -260,7 +260,7 @@
|
||||
if(2 to INFINITY)
|
||||
var/obj/dummy = new(get_turf(here))
|
||||
dummy.pass_flags |= PASSTABLE
|
||||
dummy.invisibility = INVISIBILITY_ABSTRACT
|
||||
dummy.SetInvisibility(INVISIBILITY_ABSTRACT)
|
||||
for(var/i in 1 to reach) //Limit it to that many tries
|
||||
var/turf/T = get_step(dummy, get_dir(dummy, there))
|
||||
if(dummy.CanReach(there))
|
||||
|
||||
@@ -360,7 +360,7 @@ INITIALIZE_IMMEDIATE(/atom/movable/screen/parallax_layer)
|
||||
var/turf/posobj = get_turf(boss?.eye)
|
||||
if(!posobj)
|
||||
return
|
||||
invisibility = is_station_level(posobj.z) ? 0 : INVISIBILITY_ABSTRACT
|
||||
SetInvisibility(is_station_level(posobj.z) ? INVISIBILITY_NONE : INVISIBILITY_ABSTRACT, id=type)
|
||||
|
||||
/atom/movable/screen/parallax_layer/planet/update_o()
|
||||
return //Shit won't move
|
||||
|
||||
@@ -31,12 +31,14 @@
|
||||
src.use_alpha = use_alpha
|
||||
src.use_anchor = use_anchor
|
||||
|
||||
|
||||
///called when a tile has been covered or uncovered
|
||||
/datum/element/undertile/proc/hide(atom/movable/source, underfloor_accessibility)
|
||||
SIGNAL_HANDLER
|
||||
|
||||
source.invisibility = underfloor_accessibility < UNDERFLOOR_VISIBLE ? invisibility_level : 0
|
||||
if(underfloor_accessibility < UNDERFLOOR_VISIBLE)
|
||||
source.SetInvisibility(invisibility_level, id=type)
|
||||
else
|
||||
source.RemoveInvisibility(type)
|
||||
|
||||
var/turf/T = get_turf(source)
|
||||
|
||||
@@ -73,11 +75,10 @@
|
||||
if(use_anchor)
|
||||
source.set_anchored(FALSE)
|
||||
|
||||
|
||||
/datum/element/undertile/Detach(atom/movable/source, visibility_trait, invisibility_level = INVISIBILITY_MAXIMUM)
|
||||
. = ..()
|
||||
|
||||
hide(source, UNDERFLOOR_INTERACTABLE)
|
||||
|
||||
source.RemoveInvisibility(type)
|
||||
|
||||
#undef ALPHA_UNDERTILE
|
||||
|
||||
@@ -187,6 +187,9 @@
|
||||
/// How this atom should react to having its astar blocking checked
|
||||
var/can_astar_pass = CANASTARPASS_DENSITY
|
||||
|
||||
VAR_PRIVATE/list/invisibility_sources
|
||||
VAR_PRIVATE/current_invisibility_priority = -INFINITY
|
||||
|
||||
/**
|
||||
* Called when an atom is created in byond (built in engine proc)
|
||||
*
|
||||
@@ -2195,3 +2198,71 @@
|
||||
segment = -segment
|
||||
SEND_SIGNAL(src, COMSIG_ATOM_SPIN_ANIMATION, speed, loops, segments, segment)
|
||||
do_spin_animation(speed, loops, segments, segment, parallel)
|
||||
|
||||
#define INVISIBILITY_VALUE 1
|
||||
#define INVISIBILITY_PRIORITY 2
|
||||
|
||||
/atom/proc/RecalculateInvisibility()
|
||||
PRIVATE_PROC(TRUE)
|
||||
|
||||
if(!invisibility_sources)
|
||||
current_invisibility_priority = -INFINITY
|
||||
invisibility = initial(invisibility)
|
||||
return
|
||||
|
||||
var/highest_priority
|
||||
var/list/highest_priority_invisibility_data
|
||||
for(var/entry in invisibility_sources)
|
||||
var/list/priority_data
|
||||
if(islist(entry))
|
||||
priority_data = entry
|
||||
else
|
||||
priority_data = invisibility_sources[entry]
|
||||
|
||||
var/priority = priority_data[INVISIBILITY_PRIORITY]
|
||||
if(highest_priority > priority) // In the case of equal priorities, we use the last thing in the list so that more recent changes apply first
|
||||
continue
|
||||
|
||||
highest_priority = priority
|
||||
highest_priority_invisibility_data = priority_data
|
||||
|
||||
current_invisibility_priority = highest_priority
|
||||
invisibility = highest_priority_invisibility_data[INVISIBILITY_VALUE]
|
||||
|
||||
/**
|
||||
* Sets invisibility according to priority.
|
||||
* If you want to be able to undo the value you set back to what it would be otherwise,
|
||||
* you should provide an id here and remove it using RemoveInvisibility(id)
|
||||
*/
|
||||
/atom/proc/SetInvisibility(desired_value, id, priority=0)
|
||||
if(!invisibility_sources)
|
||||
invisibility_sources = list()
|
||||
|
||||
if(id)
|
||||
invisibility_sources[id] = list(desired_value, priority)
|
||||
else
|
||||
invisibility_sources += list(list(desired_value, priority))
|
||||
|
||||
if(current_invisibility_priority > priority)
|
||||
return
|
||||
|
||||
RecalculateInvisibility()
|
||||
|
||||
/// Removes the specified invisibility source from the tracker
|
||||
/atom/proc/RemoveInvisibility(source_id)
|
||||
if(!invisibility_sources)
|
||||
return
|
||||
|
||||
var/list/priority_data = invisibility_sources[source_id]
|
||||
invisibility_sources -= source_id
|
||||
|
||||
if(length(invisibility_sources) == 0)
|
||||
invisibility_sources = null
|
||||
|
||||
if(current_invisibility_priority > priority_data[INVISIBILITY_PRIORITY])
|
||||
return
|
||||
|
||||
RecalculateInvisibility()
|
||||
|
||||
#undef INVISIBILITY_VALUE
|
||||
#undef INVISIBILITY_PRIORITY
|
||||
|
||||
@@ -13,7 +13,7 @@
|
||||
. = ..()
|
||||
var/turf/T = loc
|
||||
Beacon = new(T)
|
||||
Beacon.invisibility = INVISIBILITY_MAXIMUM
|
||||
Beacon.SetInvisibility(INVISIBILITY_MAXIMUM)
|
||||
|
||||
AddElement(/datum/element/undertile, TRAIT_T_RAY_VISIBLE)
|
||||
|
||||
@@ -25,6 +25,6 @@
|
||||
if(QDELETED(Beacon)) //Don't move it out of nullspace BACK INTO THE GAME for the love of god
|
||||
var/turf/T = loc
|
||||
Beacon = new(T)
|
||||
Beacon.invisibility = INVISIBILITY_MAXIMUM
|
||||
Beacon.SetInvisibility(INVISIBILITY_MAXIMUM)
|
||||
else if (Beacon.loc != loc)
|
||||
Beacon.forceMove(loc)
|
||||
|
||||
@@ -326,7 +326,7 @@ DEFINE_BITFIELD(turret_flags, list(
|
||||
//This code handles moving the turret around. After all, it's a portable turret!
|
||||
if(!anchored && !isinspace())
|
||||
set_anchored(TRUE)
|
||||
invisibility = INVISIBILITY_MAXIMUM
|
||||
SetInvisibility(INVISIBILITY_MAXIMUM, id=type)
|
||||
update_appearance()
|
||||
to_chat(user, span_notice("You secure the exterior bolts on the turret."))
|
||||
if(has_cover)
|
||||
@@ -336,7 +336,7 @@ DEFINE_BITFIELD(turret_flags, list(
|
||||
set_anchored(FALSE)
|
||||
to_chat(user, span_notice("You unsecure the exterior bolts on the turret."))
|
||||
power_change()
|
||||
invisibility = 0
|
||||
RemoveInvisibility(type)
|
||||
qdel(cover) //deletes the cover, and the turret instance itself becomes its own cover.
|
||||
|
||||
else if(I.GetID())
|
||||
@@ -407,7 +407,7 @@ DEFINE_BITFIELD(turret_flags, list(
|
||||
. = ..()
|
||||
if(.)
|
||||
power_change()
|
||||
invisibility = 0
|
||||
RemoveInvisibility(type)
|
||||
spark_system.start() //creates some sparks because they look cool
|
||||
qdel(cover) //deletes the cover - no need on keeping it there!
|
||||
|
||||
@@ -514,7 +514,7 @@ DEFINE_BITFIELD(turret_flags, list(
|
||||
return
|
||||
if(machine_stat & BROKEN)
|
||||
return
|
||||
invisibility = 0
|
||||
RemoveInvisibility(type)
|
||||
raising = 1
|
||||
if(cover)
|
||||
flick("popup", cover)
|
||||
@@ -539,7 +539,7 @@ DEFINE_BITFIELD(turret_flags, list(
|
||||
if(cover)
|
||||
cover.icon_state = "turretCover"
|
||||
raised = 0
|
||||
invisibility = 2
|
||||
SetInvisibility(2, id=type)
|
||||
update_appearance()
|
||||
|
||||
/obj/machinery/porta_turret/proc/assess_perp(mob/living/carbon/human/perp)
|
||||
|
||||
@@ -16,7 +16,7 @@
|
||||
/obj/machinery/porta_turret_cover/Destroy()
|
||||
if(parent_turret)
|
||||
parent_turret.cover = null
|
||||
parent_turret.invisibility = 0
|
||||
parent_turret.RemoveInvisibility(type)
|
||||
parent_turret = null
|
||||
return ..()
|
||||
|
||||
@@ -43,12 +43,12 @@
|
||||
if(!parent_turret.anchored)
|
||||
parent_turret.set_anchored(TRUE)
|
||||
to_chat(user, span_notice("You secure the exterior bolts on the turret."))
|
||||
parent_turret.invisibility = 0
|
||||
parent_turret.RemoveInvisibility(type)
|
||||
parent_turret.update_appearance()
|
||||
else
|
||||
parent_turret.set_anchored(FALSE)
|
||||
to_chat(user, span_notice("You unsecure the exterior bolts on the turret."))
|
||||
parent_turret.invisibility = INVISIBILITY_MAXIMUM
|
||||
parent_turret.SetInvisibility(INVISIBILITY_MAXIMUM, id=type)
|
||||
parent_turret.update_appearance()
|
||||
qdel(src)
|
||||
return
|
||||
|
||||
@@ -130,9 +130,10 @@
|
||||
/obj/structure/emergency_shield/cult/barrier/proc/Toggle()
|
||||
set_density(!density)
|
||||
air_update_turf(TRUE, !density)
|
||||
invisibility = initial(invisibility)
|
||||
if(!density)
|
||||
invisibility = INVISIBILITY_OBSERVER
|
||||
SetInvisibility(INVISIBILITY_OBSERVER, id=type)
|
||||
else
|
||||
RemoveInvisibility(type)
|
||||
|
||||
/obj/machinery/shieldgen
|
||||
name = "anti-breach shielding projector"
|
||||
|
||||
@@ -157,7 +157,7 @@
|
||||
return round(time_left)
|
||||
|
||||
/obj/effect/countdown/arena
|
||||
invisibility = 0
|
||||
invisibility = INVISIBILITY_NONE
|
||||
name = "arena countdown"
|
||||
|
||||
/obj/effect/countdown/arena/get_value()
|
||||
|
||||
@@ -13,7 +13,7 @@
|
||||
return ..()
|
||||
|
||||
/obj/effect/spawner/random/maintenance/proc/hide()
|
||||
invisibility = INVISIBILITY_OBSERVER
|
||||
SetInvisibility(INVISIBILITY_OBSERVER)
|
||||
alpha = 100
|
||||
|
||||
/obj/effect/spawner/random/maintenance/proc/get_effective_lootcount()
|
||||
|
||||
@@ -292,7 +292,7 @@
|
||||
O.laws = M.laws
|
||||
M.laws.associate(O)
|
||||
|
||||
O.invisibility = 0
|
||||
O.SetInvisibility(INVISIBILITY_NONE)
|
||||
//Transfer debug settings to new mob
|
||||
O.custom_name = created_name
|
||||
O.locked = panel_locked
|
||||
|
||||
@@ -80,12 +80,12 @@
|
||||
/obj/machinery/computer/camera_advanced/base_construction/GrantActions(mob/living/user)
|
||||
..()
|
||||
//When the eye is in use, make it visible to players so they know when someone is building.
|
||||
eyeobj.invisibility = 0
|
||||
SetInvisibility(INVISIBILITY_NONE, id=type)
|
||||
|
||||
/obj/machinery/computer/camera_advanced/base_construction/remove_eye_control(mob/living/user)
|
||||
..()
|
||||
//Hide the eye when not in use.
|
||||
eyeobj.invisibility = INVISIBILITY_MAXIMUM
|
||||
//Set back to default invisibility when not in use.
|
||||
RemoveInvisibility(type)
|
||||
|
||||
/**
|
||||
* A mob used by [/obj/machinery/computer/camera_advanced/base_construction] for building in specific areas.
|
||||
@@ -101,6 +101,7 @@
|
||||
move_on_shuttle = TRUE
|
||||
icon = 'icons/obj/mining.dmi'
|
||||
icon_state = "construction_drone"
|
||||
invisibility = INVISIBILITY_MAXIMUM
|
||||
///Reference to the camera console controlling this drone
|
||||
var/obj/machinery/computer/camera_advanced/base_construction/linked_console
|
||||
|
||||
|
||||
@@ -391,16 +391,16 @@ GLOBAL_PROTECT(admin_verbs_poll)
|
||||
set name = "Invisimin"
|
||||
set category = "Admin.Game"
|
||||
set desc = "Toggles ghost-like invisibility (Don't abuse this)"
|
||||
if(holder && mob)
|
||||
if(initial(mob.invisibility) == INVISIBILITY_OBSERVER)
|
||||
to_chat(mob, span_boldannounce("Invisimin toggle failed. You are already an invisible mob like a ghost."), confidential = TRUE)
|
||||
return
|
||||
if(mob.invisibility == INVISIBILITY_OBSERVER)
|
||||
mob.invisibility = initial(mob.invisibility)
|
||||
to_chat(mob, span_boldannounce("Invisimin off. Invisibility reset."), confidential = TRUE)
|
||||
else
|
||||
mob.invisibility = INVISIBILITY_OBSERVER
|
||||
to_chat(mob, span_adminnotice("<b>Invisimin on. You are now as invisible as a ghost.</b>"), confidential = TRUE)
|
||||
if(isnull(holder) || isnull(mob))
|
||||
return
|
||||
if(mob.invisimin)
|
||||
mob.invisimin = FALSE
|
||||
mob.RemoveInvisibility(INVISIBILITY_SOURCE_INVISIMIN)
|
||||
to_chat(mob, span_boldannounce("Invisimin off. Invisibility reset."), confidential = TRUE)
|
||||
else
|
||||
mob.invisimin = TRUE
|
||||
mob.SetInvisibility(INVISIBILITY_OBSERVER, INVISIBILITY_SOURCE_INVISIMIN, INVISIBILITY_PRIORITY_ADMIN)
|
||||
to_chat(mob, span_adminnotice("<b>Invisimin on. You are now as invisible as a ghost.</b>"), confidential = TRUE)
|
||||
|
||||
/client/proc/check_antagonists()
|
||||
set name = "Check Antagonists"
|
||||
@@ -546,7 +546,7 @@ GLOBAL_PROTECT(admin_verbs_poll)
|
||||
holder.fakekey = new_key
|
||||
createStealthKey()
|
||||
if(isobserver(mob))
|
||||
mob.invisibility = INVISIBILITY_MAXIMUM //JUST IN CASE
|
||||
mob.SetInvisibility(INVISIBILITY_ABSTRACT, INVISIBILITY_SOURCE_STEALTHMODE, INVISIBILITY_PRIORITY_ADMIN)
|
||||
mob.alpha = 0 //JUUUUST IN CASE
|
||||
mob.name = " "
|
||||
mob.mouse_opacity = MOUSE_OPACITY_TRANSPARENT
|
||||
@@ -560,7 +560,7 @@ GLOBAL_PROTECT(admin_verbs_poll)
|
||||
/client/proc/disable_stealth_mode()
|
||||
holder.fakekey = null
|
||||
if(isobserver(mob))
|
||||
mob.invisibility = initial(mob.invisibility)
|
||||
mob.RemoveInvisibility(INVISIBILITY_SOURCE_STEALTHMODE)
|
||||
mob.alpha = initial(mob.alpha)
|
||||
if(mob.mind)
|
||||
if(mob.mind.ghostname)
|
||||
|
||||
@@ -25,7 +25,7 @@
|
||||
eyeobj.visible_icon = TRUE
|
||||
eyeobj.icon = 'icons/mob/silicon/cameramob.dmi'
|
||||
eyeobj.icon_state = "abductor_camera"
|
||||
eyeobj.invisibility = INVISIBILITY_OBSERVER
|
||||
eyeobj.SetInvisibility(INVISIBILITY_OBSERVER)
|
||||
|
||||
/obj/machinery/computer/camera_advanced/abductor/GrantActions(mob/living/carbon/user)
|
||||
if(!abduct_created)
|
||||
|
||||
@@ -220,7 +220,7 @@ GLOBAL_LIST_EMPTY(blob_nodes)
|
||||
check_area.icon = 'icons/mob/nonhuman-player/blob.dmi'
|
||||
check_area.icon_state = "blob_shield"
|
||||
check_area.layer = BELOW_MOB_LAYER
|
||||
check_area.invisibility = 0
|
||||
check_area.SetInvisibility(INVISIBILITY_NONE)
|
||||
check_area.blend_mode = 0
|
||||
|
||||
var/datum/antagonist/blob/B = mind.has_antag_datum(/datum/antagonist/blob)
|
||||
|
||||
@@ -21,7 +21,7 @@
|
||||
changeling.chosen_sting = src
|
||||
|
||||
changeling.lingstingdisplay.icon_state = button_icon_state
|
||||
changeling.lingstingdisplay.invisibility = 0
|
||||
changeling.lingstingdisplay.SetInvisibility(0, id=type)
|
||||
|
||||
/datum/action/changeling/sting/proc/unset_sting(mob/user)
|
||||
to_chat(user, span_warning("We retract our sting, we can't sting anyone for now."))
|
||||
@@ -29,7 +29,7 @@
|
||||
changeling.chosen_sting = null
|
||||
|
||||
changeling.lingstingdisplay.icon_state = null
|
||||
changeling.lingstingdisplay.invisibility = INVISIBILITY_ABSTRACT
|
||||
changeling.lingstingdisplay.RemoveInvisibility(type)
|
||||
|
||||
/mob/living/carbon/proc/unset_sting()
|
||||
if(mind)
|
||||
|
||||
@@ -63,7 +63,7 @@
|
||||
/obj/structure/destructible/cult/proc/conceal()
|
||||
set_density(FALSE)
|
||||
visible_message(span_danger("[src] fades away."))
|
||||
invisibility = INVISIBILITY_OBSERVER
|
||||
SetInvisibility(INVISIBILITY_OBSERVER, id=type)
|
||||
alpha = 100
|
||||
set_light_power(0)
|
||||
set_light_range(0)
|
||||
@@ -74,7 +74,7 @@
|
||||
*/
|
||||
/obj/structure/destructible/cult/proc/reveal()
|
||||
set_density(initial(density))
|
||||
invisibility = 0
|
||||
RemoveInvisibility(type)
|
||||
visible_message(span_danger("[src] suddenly appears!"))
|
||||
alpha = initial(alpha)
|
||||
set_light_range(initial(light_range))
|
||||
|
||||
@@ -118,11 +118,11 @@ Runes can either be invoked by one's self or with many different cultists. Each
|
||||
|
||||
/obj/effect/rune/proc/conceal() //for talisman of revealing/hiding
|
||||
visible_message(span_danger("[src] fades away."))
|
||||
invisibility = INVISIBILITY_OBSERVER
|
||||
SetInvisibility(INVISIBILITY_OBSERVER, id=type)
|
||||
alpha = 100 //To help ghosts distinguish hidden runes
|
||||
|
||||
/obj/effect/rune/proc/reveal() //for talisman of revealing/hiding
|
||||
invisibility = 0
|
||||
RemoveInvisibility(type)
|
||||
visible_message(span_danger("[src] suddenly appears!"))
|
||||
alpha = initial(alpha)
|
||||
|
||||
|
||||
@@ -171,7 +171,7 @@
|
||||
// Some rituals may remove atoms from the selected_atoms list, and not consume them.
|
||||
var/list/initial_selected_atoms = selected_atoms.Copy()
|
||||
for(var/atom/to_disappear as anything in selected_atoms)
|
||||
to_disappear.invisibility = INVISIBILITY_ABSTRACT
|
||||
to_disappear.SetInvisibility(INVISIBILITY_ABSTRACT, id=type)
|
||||
|
||||
// All the components have been invisibled, time to actually do the ritual. Call on_finished_recipe
|
||||
// (Note: on_finished_recipe may sleep in the case of some rituals like summons, which expect ghost candidates.)
|
||||
@@ -185,7 +185,7 @@
|
||||
for(var/atom/to_appear as anything in initial_selected_atoms)
|
||||
if(QDELETED(to_appear))
|
||||
continue
|
||||
to_appear.invisibility = initial(to_appear.invisibility)
|
||||
to_appear.RemoveInvisibility(type)
|
||||
|
||||
// And finally, give some user feedback
|
||||
// No feedback is given on failure here -
|
||||
|
||||
@@ -113,7 +113,8 @@
|
||||
beams += I
|
||||
I.master = src
|
||||
I.setDir(_dir)
|
||||
I.invisibility = visible? 0 : INVISIBILITY_ABSTRACT
|
||||
if(!visible)
|
||||
I.SetInvisibility(INVISIBILITY_ABSTRACT)
|
||||
T = _T
|
||||
_T = get_step(_T, _dir)
|
||||
CHECK_TICK
|
||||
|
||||
@@ -80,7 +80,10 @@
|
||||
if(!istype(T))
|
||||
return
|
||||
//Simple way to keep plane conflicts away, could probably be upgraded to something less nuclear with 513
|
||||
T.invisibility = open ? 0 : INVISIBILITY_MAXIMUM
|
||||
if(!open)
|
||||
T.SetInvisibility(INVISIBILITY_MAXIMUM, id=type)
|
||||
else
|
||||
T.RemoveInvisibility(type)
|
||||
|
||||
/obj/structure/pitgrate/proc/toggle()
|
||||
open = !open
|
||||
|
||||
@@ -28,7 +28,7 @@
|
||||
if(0)
|
||||
SpeakPeace(list("Welcome to the error handling room.","Something's goofed up bad to send you here.","You should probably tell an admin what you were doing, or make a bug report."))
|
||||
for(var/obj/structure/signpost/salvation/sign in orange(7))
|
||||
sign.invisibility = 0
|
||||
sign.SetInvisibility(INVISIBILITY_NONE)
|
||||
var/datum/effect_system/fluid_spread/smoke/smoke = new
|
||||
smoke.set_up(1, holder = src, location = sign.loc)
|
||||
smoke.start()
|
||||
|
||||
@@ -289,7 +289,7 @@ GLOBAL_LIST_INIT(bibleitemstates, list(
|
||||
make_new_altar(bible_smacked, user)
|
||||
return
|
||||
for(var/obj/effect/rune/nearby_runes in range(2, user))
|
||||
nearby_runes.invisibility = 0
|
||||
nearby_runes.SetInvisibility(INVISIBILITY_NONE, id=type, priority=INVISIBILITY_PRIORITY_BASIC_ANTI_INVISIBILITY)
|
||||
bible_smacked.balloon_alert(user, "floor smacked!")
|
||||
|
||||
if(user.mind?.holy_role)
|
||||
|
||||
@@ -651,7 +651,7 @@
|
||||
|
||||
/obj/item/melee/ghost_sword/Destroy()
|
||||
for(var/mob/dead/observer/G in spirits)
|
||||
G.invisibility = GLOB.observer_default_invisibility
|
||||
G.RemoveInvisibility(type)
|
||||
spirits.Cut()
|
||||
STOP_PROCESSING(SSobj, src)
|
||||
. = ..()
|
||||
@@ -690,10 +690,10 @@
|
||||
continue
|
||||
var/mob/dead/observer/G = i
|
||||
ghost_counter++
|
||||
G.invisibility = 0
|
||||
G.SetInvisibility(INVISIBILITY_NONE, id=type, priority=INVISIBILITY_PRIORITY_BASIC_ANTI_INVISIBILITY)
|
||||
current_spirits |= G
|
||||
for(var/mob/dead/observer/G in spirits - current_spirits)
|
||||
G.invisibility = GLOB.observer_default_invisibility
|
||||
G.RemoveInvisibility(type)
|
||||
spirits = current_spirits
|
||||
return ghost_counter
|
||||
|
||||
|
||||
@@ -1052,7 +1052,7 @@
|
||||
|
||||
/obj/item/cursed_katana/proc/cloak(mob/living/target, mob/user)
|
||||
user.alpha = 150
|
||||
user.invisibility = INVISIBILITY_OBSERVER // so hostile mobs cant see us or target us
|
||||
user.SetInvisibility(INVISIBILITY_OBSERVER, id=type) // so hostile mobs cant see us or target us
|
||||
user.add_sight(SEE_SELF) // so we can see us
|
||||
user.visible_message(span_warning("[user] vanishes into thin air!"),
|
||||
span_notice("You enter the dark cloak."))
|
||||
@@ -1066,7 +1066,7 @@
|
||||
|
||||
/obj/item/cursed_katana/proc/uncloak(mob/user)
|
||||
user.alpha = 255
|
||||
user.invisibility = 0
|
||||
user.RemoveInvisibility(type)
|
||||
user.clear_sight(SEE_SELF)
|
||||
user.visible_message(span_warning("[user] appears from thin air!"),
|
||||
span_notice("You exit the dark cloak."))
|
||||
|
||||
@@ -1010,7 +1010,7 @@ This is the proc mobs get to turn into a ghost. Forked from ghostize due to comp
|
||||
|
||||
|
||||
/mob/dead/observer/proc/set_invisibility(value)
|
||||
invisibility = value
|
||||
SetInvisibility(value, id=type)
|
||||
set_light_on(!value ? TRUE : FALSE)
|
||||
|
||||
|
||||
|
||||
@@ -20,14 +20,14 @@
|
||||
playsound(burrower, 'sound/effects/break_stone.ogg', 50, TRUE)
|
||||
new /obj/effect/temp_visual/mook_dust(get_turf(burrower))
|
||||
burrower.status_flags |= GODMODE
|
||||
burrower.invisibility = INVISIBILITY_MAXIMUM
|
||||
burrower.SetInvisibility(INVISIBILITY_MAXIMUM, id=type)
|
||||
burrower.forceMove(unburrow_turf)
|
||||
//not that it's gonna die with godmode but still
|
||||
SLEEP_CHECK_DEATH(rand(0.7 SECONDS, 1.2 SECONDS), burrower)
|
||||
playsound(burrower, 'sound/effects/break_stone.ogg', 50, TRUE)
|
||||
new /obj/effect/temp_visual/mook_dust(unburrow_turf)
|
||||
burrower.status_flags &= ~GODMODE
|
||||
burrower.invisibility = 0
|
||||
burrower.RemoveInvisibility(type)
|
||||
|
||||
/datum/action/cooldown/mob_cooldown/resurface/proc/get_unburrow_turf(mob/living/burrower, atom/target)
|
||||
//we want the worm to try guaranteeing a hit on a living target if it thinks it can
|
||||
@@ -105,14 +105,14 @@
|
||||
playsound(devourer, 'sound/effects/break_stone.ogg', 50, TRUE)
|
||||
new /obj/effect/temp_visual/mook_dust(get_turf(devourer))
|
||||
devourer.status_flags |= GODMODE
|
||||
devourer.invisibility = INVISIBILITY_MAXIMUM
|
||||
devourer.SetInvisibility(INVISIBILITY_MAXIMUM, id=type)
|
||||
devourer.forceMove(devour_turf)
|
||||
//not that it's gonna die with godmode but still
|
||||
SLEEP_CHECK_DEATH(rand(0.7 SECONDS, 1.2 SECONDS), devourer)
|
||||
playsound(devourer, 'sound/effects/break_stone.ogg', 50, TRUE)
|
||||
new /obj/effect/temp_visual/mook_dust(devour_turf)
|
||||
devourer.status_flags &= ~GODMODE
|
||||
devourer.invisibility = 0
|
||||
devourer.RemoveInvisibility(type)
|
||||
if(!(target in devour_turf))
|
||||
to_chat(devourer, span_warning("Someone stole your dinner!"))
|
||||
return
|
||||
|
||||
@@ -302,7 +302,7 @@
|
||||
span_revendanger("NO! No... it's too late, you can feel your essence [pick("breaking apart", "drifting away")]..."),
|
||||
)
|
||||
|
||||
invisibility = 0
|
||||
SetInvisibility(INVISIBILITY_NONE, id=type)
|
||||
icon_state = "revenant_draining"
|
||||
playsound(src, 'sound/effects/screech.ogg', 100, TRUE)
|
||||
|
||||
@@ -428,7 +428,7 @@
|
||||
draining = FALSE
|
||||
dormant = FALSE
|
||||
incorporeal_move = INCORPOREAL_MOVE_JAUNT
|
||||
invisibility = INVISIBILITY_REVENANT
|
||||
RemoveInvisibility(type)
|
||||
alpha = 255
|
||||
|
||||
/mob/living/basic/revenant/proc/change_essence_amount(essence_to_change_by, silent = FALSE, source = null)
|
||||
|
||||
@@ -16,7 +16,7 @@
|
||||
owner.orbiting?.end_orbit(src)
|
||||
|
||||
ADD_TRAIT(owner, TRAIT_REVENANT_REVEALED, TRAIT_STATUS_EFFECT(id))
|
||||
owner.invisibility = 0
|
||||
owner.SetInvisibility(INVISIBILITY_NONE, id=type, priority=INVISIBILITY_PRIORITY_BASIC_ANTI_INVISIBILITY)
|
||||
owner.incorporeal_move = FALSE
|
||||
owner.update_appearance(UPDATE_ICON)
|
||||
owner.update_mob_action_buttons()
|
||||
@@ -25,7 +25,7 @@
|
||||
REMOVE_TRAIT(owner, TRAIT_REVENANT_REVEALED, TRAIT_STATUS_EFFECT(id))
|
||||
|
||||
owner.incorporeal_move = INCORPOREAL_MOVE_JAUNT
|
||||
owner.invisibility = INVISIBILITY_REVENANT
|
||||
owner.RemoveInvisibility(type)
|
||||
owner.update_appearance(UPDATE_ICON)
|
||||
owner.update_mob_action_buttons()
|
||||
return ..()
|
||||
|
||||
@@ -112,7 +112,7 @@
|
||||
new_xeno.key = ghost.key
|
||||
SEND_SOUND(new_xeno, sound('sound/voice/hiss5.ogg',0,0,0,100)) //To get the player's attention
|
||||
new_xeno.add_traits(list(TRAIT_HANDS_BLOCKED, TRAIT_IMMOBILIZED, TRAIT_NO_TRANSFORM), type) //so we don't move during the bursting animation
|
||||
new_xeno.invisibility = INVISIBILITY_MAXIMUM
|
||||
new_xeno.SetInvisibility(INVISIBILITY_MAXIMUM, id=type)
|
||||
|
||||
sleep(0.6 SECONDS)
|
||||
|
||||
@@ -122,7 +122,7 @@
|
||||
|
||||
if(!isnull(new_xeno))
|
||||
new_xeno.remove_traits(list(TRAIT_HANDS_BLOCKED, TRAIT_IMMOBILIZED, TRAIT_NO_TRANSFORM), type)
|
||||
new_xeno.invisibility = 0
|
||||
new_xeno.RemoveInvisibility(type)
|
||||
|
||||
if(gib_on_success)
|
||||
new_xeno.visible_message(span_danger("[new_xeno] bursts out of [owner] in a shower of gore!"), span_userdanger("You exit [owner], your previous host."), span_hear("You hear organic matter ripping and tearing!"))
|
||||
|
||||
@@ -1399,7 +1399,7 @@
|
||||
add_traits(list(TRAIT_IMMOBILIZED, TRAIT_HANDS_BLOCKED, TRAIT_NO_TRANSFORM), MAGIC_TRAIT)
|
||||
icon = null
|
||||
cut_overlays()
|
||||
invisibility = INVISIBILITY_ABSTRACT
|
||||
SetInvisibility(INVISIBILITY_ABSTRACT)
|
||||
|
||||
var/list/item_contents = list()
|
||||
|
||||
@@ -1449,7 +1449,7 @@
|
||||
if(issilicon(new_mob))
|
||||
var/mob/living/silicon/robot/created_robot = new_mob
|
||||
new_mob.gender = gender
|
||||
new_mob.invisibility = 0
|
||||
new_mob.SetInvisibility(INVISIBILITY_NONE)
|
||||
new_mob.job = JOB_CYBORG
|
||||
created_robot.lawupdate = FALSE
|
||||
created_robot.connected_ai = null
|
||||
|
||||
@@ -218,7 +218,10 @@
|
||||
if(!eyeobj)
|
||||
return
|
||||
eyeobj.mouse_opacity = state ? MOUSE_OPACITY_ICON : initial(eyeobj.mouse_opacity)
|
||||
eyeobj.invisibility = state ? INVISIBILITY_OBSERVER : initial(eyeobj.invisibility)
|
||||
if(state)
|
||||
eyeobj.SetInvisibility(INVISIBILITY_OBSERVER, id=type)
|
||||
else
|
||||
eyeobj.RemoveInvisibility(type)
|
||||
|
||||
/mob/living/silicon/ai/verb/toggle_acceleration()
|
||||
set category = "AI Commands"
|
||||
|
||||
@@ -214,3 +214,6 @@
|
||||
var/active_thinking_indicator
|
||||
/// User is thinking in character. Used to revert to thinking state after stop_typing
|
||||
var/thinking_IC = FALSE
|
||||
|
||||
/// Whether invisimin is enabled on this mob
|
||||
var/invisimin = FALSE
|
||||
|
||||
@@ -20,9 +20,11 @@
|
||||
Paralyze(TRANSFORMATION_DURATION, ignore_canstun = TRUE)
|
||||
icon = null
|
||||
cut_overlays()
|
||||
invisibility = INVISIBILITY_MAXIMUM
|
||||
|
||||
new /obj/effect/temp_visual/monkeyify(loc)
|
||||
var/obj/effect = new /obj/effect/temp_visual/monkeyify(loc)
|
||||
effect.SetInvisibility(invisibility)
|
||||
SetInvisibility(INVISIBILITY_MAXIMUM, id=type)
|
||||
|
||||
transformation_timer = addtimer(CALLBACK(src, PROC_REF(finish_monkeyize)), TRANSFORMATION_DURATION, TIMER_UNIQUE)
|
||||
|
||||
/mob/living/carbon/proc/finish_monkeyize()
|
||||
@@ -30,7 +32,7 @@
|
||||
to_chat(src, span_boldnotice("You are now a monkey."))
|
||||
REMOVE_TRAIT(src, TRAIT_NO_TRANSFORM, TEMPORARY_TRANSFORMATION_TRAIT)
|
||||
icon = initial(icon)
|
||||
invisibility = 0
|
||||
RemoveInvisibility(type)
|
||||
set_species(/datum/species/monkey)
|
||||
name = "monkey"
|
||||
set_name()
|
||||
@@ -57,9 +59,11 @@
|
||||
Paralyze(TRANSFORMATION_DURATION, ignore_canstun = TRUE)
|
||||
icon = null
|
||||
cut_overlays()
|
||||
invisibility = INVISIBILITY_MAXIMUM
|
||||
|
||||
new /obj/effect/temp_visual/monkeyify/humanify(loc)
|
||||
var/obj/effect = new /obj/effect/temp_visual/monkeyify/humanify(loc)
|
||||
effect.SetInvisibility(invisibility)
|
||||
SetInvisibility(INVISIBILITY_MAXIMUM, id=type)
|
||||
|
||||
transformation_timer = addtimer(CALLBACK(src, PROC_REF(finish_humanize), species), TRANSFORMATION_DURATION, TIMER_UNIQUE)
|
||||
|
||||
/mob/living/carbon/proc/finish_humanize(species = /datum/species/human)
|
||||
@@ -67,7 +71,7 @@
|
||||
to_chat(src, span_boldnotice("You are now a human."))
|
||||
REMOVE_TRAIT(src, TRAIT_NO_TRANSFORM, TEMPORARY_TRANSFORMATION_TRAIT)
|
||||
icon = initial(icon)
|
||||
invisibility = 0
|
||||
RemoveInvisibility(type)
|
||||
set_species(species)
|
||||
SEND_SIGNAL(src, COMSIG_MONKEY_HUMANIZE)
|
||||
return src
|
||||
@@ -117,7 +121,7 @@
|
||||
dropItemToGround(W)
|
||||
regenerate_icons()
|
||||
icon = null
|
||||
invisibility = INVISIBILITY_MAXIMUM
|
||||
SetInvisibility(INVISIBILITY_MAXIMUM)
|
||||
return ..()
|
||||
|
||||
/mob/living/carbon/human/AIize(client/preference_source, transfer_after = TRUE)
|
||||
@@ -135,7 +139,7 @@
|
||||
var/mob/living/silicon/robot/new_borg = new /mob/living/silicon/robot(loc)
|
||||
|
||||
new_borg.gender = gender
|
||||
new_borg.invisibility = 0
|
||||
new_borg.SetInvisibility(INVISIBILITY_NONE)
|
||||
|
||||
if(client)
|
||||
new_borg.updatename(client)
|
||||
@@ -176,7 +180,7 @@
|
||||
dropItemToGround(W)
|
||||
regenerate_icons()
|
||||
icon = null
|
||||
invisibility = INVISIBILITY_MAXIMUM
|
||||
SetInvisibility(INVISIBILITY_MAXIMUM)
|
||||
|
||||
REMOVE_TRAIT(src, TRAIT_NO_TRANSFORM, TEMPORARY_TRANSFORMATION_TRAIT)
|
||||
return ..()
|
||||
@@ -201,7 +205,7 @@
|
||||
dropItemToGround(W)
|
||||
regenerate_icons()
|
||||
icon = null
|
||||
invisibility = INVISIBILITY_MAXIMUM
|
||||
SetInvisibility(INVISIBILITY_MAXIMUM)
|
||||
for(var/t in bodyparts)
|
||||
qdel(t)
|
||||
|
||||
@@ -231,7 +235,7 @@
|
||||
dropItemToGround(W)
|
||||
regenerate_icons()
|
||||
icon = null
|
||||
invisibility = INVISIBILITY_MAXIMUM
|
||||
SetInvisibility(INVISIBILITY_MAXIMUM)
|
||||
for(var/t in bodyparts)
|
||||
qdel(t)
|
||||
|
||||
@@ -270,7 +274,7 @@
|
||||
dropItemToGround(W)
|
||||
regenerate_icons()
|
||||
icon = null
|
||||
invisibility = INVISIBILITY_MAXIMUM
|
||||
SetInvisibility(INVISIBILITY_MAXIMUM)
|
||||
for(var/t in bodyparts) //this really should not be necessary
|
||||
qdel(t)
|
||||
|
||||
@@ -297,7 +301,7 @@
|
||||
|
||||
regenerate_icons()
|
||||
icon = null
|
||||
invisibility = INVISIBILITY_MAXIMUM
|
||||
SetInvisibility(INVISIBILITY_MAXIMUM)
|
||||
var/mob/living/basic/gorilla/new_gorilla = new (get_turf(src))
|
||||
new_gorilla.set_combat_mode(TRUE)
|
||||
if(mind)
|
||||
@@ -328,7 +332,7 @@
|
||||
|
||||
regenerate_icons()
|
||||
icon = null
|
||||
invisibility = INVISIBILITY_MAXIMUM
|
||||
SetInvisibility(INVISIBILITY_MAXIMUM)
|
||||
|
||||
for(var/t in bodyparts)
|
||||
qdel(t)
|
||||
|
||||
@@ -77,7 +77,7 @@
|
||||
abstract_move(get_turf(src))
|
||||
pixel_x = old_loc.pixel_x
|
||||
pixel_y = old_loc.pixel_y
|
||||
invisibility = set_invis
|
||||
SetInvisibility(set_invis)
|
||||
|
||||
#undef POINT_TIME
|
||||
|
||||
|
||||
@@ -149,7 +149,7 @@
|
||||
#ifdef DOCKING_PORT_HIGHLIGHT
|
||||
//Debug proc used to highlight bounding area
|
||||
/obj/docking_port/proc/highlight(_color = "#f00")
|
||||
invisibility = 0
|
||||
SetInvisibility(INVISIBILITY_NONE)
|
||||
SET_PLANE_IMPLICIT(src, GHOST_PLANE)
|
||||
var/list/L = return_coords()
|
||||
var/turf/T0 = locate(L[1],L[2],z)
|
||||
|
||||
@@ -233,7 +233,7 @@ own integrity back to max. Shield is automatically dropped if we run out of powe
|
||||
set_light_on(chassis.defense_mode)
|
||||
|
||||
if(chassis.defense_mode)
|
||||
invisibility = 0
|
||||
SetInvisibility(INVISIBILITY_NONE, id=type)
|
||||
flick("shield_raise", src)
|
||||
playsound(src, 'sound/mecha/mech_shield_raise.ogg', 50, FALSE)
|
||||
icon_state = "shield"
|
||||
@@ -256,7 +256,7 @@ own integrity back to max. Shield is automatically dropped if we run out of powe
|
||||
*/
|
||||
/obj/durand_shield/proc/make_invisible()
|
||||
if(!chassis.defense_mode)
|
||||
invisibility = INVISIBILITY_MAXIMUM
|
||||
RemoveInvisibility(type)
|
||||
|
||||
/obj/durand_shield/proc/resetdir(datum/source, olddir, newdir)
|
||||
SIGNAL_HANDLER
|
||||
|
||||
Reference in New Issue
Block a user