diff --git a/code/__DEFINES/sight.dm b/code/__DEFINES/sight.dm index ab70cb9895b..ae5f4e48352 100644 --- a/code/__DEFINES/sight.dm +++ b/code/__DEFINES/sight.dm @@ -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" + diff --git a/code/__HELPERS/mobs.dm b/code/__HELPERS/mobs.dm index aa161690ceb..df98ab953fa 100644 --- a/code/__HELPERS/mobs.dm +++ b/code/__HELPERS/mobs.dm @@ -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 diff --git a/code/__HELPERS/spatial_info.dm b/code/__HELPERS/spatial_info.dm index 033d5a60b79..5a0d5c3f002 100644 --- a/code/__HELPERS/spatial_info.dm +++ b/code/__HELPERS/spatial_info.dm @@ -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 diff --git a/code/_onclick/click.dm b/code/_onclick/click.dm index 667611f1075..98c5c4d94a7 100644 --- a/code/_onclick/click.dm +++ b/code/_onclick/click.dm @@ -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)) diff --git a/code/_onclick/hud/parallax/parallax.dm b/code/_onclick/hud/parallax/parallax.dm index 8d4e68c911d..506226b41ea 100755 --- a/code/_onclick/hud/parallax/parallax.dm +++ b/code/_onclick/hud/parallax/parallax.dm @@ -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 diff --git a/code/datums/elements/undertile.dm b/code/datums/elements/undertile.dm index e1fdef4d413..ecc621a57e4 100644 --- a/code/datums/elements/undertile.dm +++ b/code/datums/elements/undertile.dm @@ -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 diff --git a/code/game/atoms.dm b/code/game/atoms.dm index aafeb699ea7..e590fb66019 100644 --- a/code/game/atoms.dm +++ b/code/game/atoms.dm @@ -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 diff --git a/code/game/machinery/gigabeacon.dm b/code/game/machinery/gigabeacon.dm index b1e3b2f7cda..2154abffc11 100644 --- a/code/game/machinery/gigabeacon.dm +++ b/code/game/machinery/gigabeacon.dm @@ -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) diff --git a/code/game/machinery/porta_turret/portable_turret.dm b/code/game/machinery/porta_turret/portable_turret.dm index cacecb6a684..cf4e4d1e7e7 100644 --- a/code/game/machinery/porta_turret/portable_turret.dm +++ b/code/game/machinery/porta_turret/portable_turret.dm @@ -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) diff --git a/code/game/machinery/porta_turret/portable_turret_cover.dm b/code/game/machinery/porta_turret/portable_turret_cover.dm index 86b1df20e7f..a4582875574 100644 --- a/code/game/machinery/porta_turret/portable_turret_cover.dm +++ b/code/game/machinery/porta_turret/portable_turret_cover.dm @@ -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 diff --git a/code/game/machinery/shieldgen.dm b/code/game/machinery/shieldgen.dm index f1cbc110a3e..ad6adae767c 100644 --- a/code/game/machinery/shieldgen.dm +++ b/code/game/machinery/shieldgen.dm @@ -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" diff --git a/code/game/objects/effects/countdown.dm b/code/game/objects/effects/countdown.dm index f820397c0d9..1c7377bd50a 100644 --- a/code/game/objects/effects/countdown.dm +++ b/code/game/objects/effects/countdown.dm @@ -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() diff --git a/code/game/objects/effects/spawners/random/maintenance.dm b/code/game/objects/effects/spawners/random/maintenance.dm index 5481123bbff..242613e403d 100644 --- a/code/game/objects/effects/spawners/random/maintenance.dm +++ b/code/game/objects/effects/spawners/random/maintenance.dm @@ -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() diff --git a/code/game/objects/items/robot/robot_parts.dm b/code/game/objects/items/robot/robot_parts.dm index c42145ff2a7..3f698c5c08f 100644 --- a/code/game/objects/items/robot/robot_parts.dm +++ b/code/game/objects/items/robot/robot_parts.dm @@ -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 diff --git a/code/game/objects/structures/construction_console/construction_console.dm b/code/game/objects/structures/construction_console/construction_console.dm index 5cf4a9bfd85..d33c91f7c07 100644 --- a/code/game/objects/structures/construction_console/construction_console.dm +++ b/code/game/objects/structures/construction_console/construction_console.dm @@ -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 diff --git a/code/modules/admin/admin_verbs.dm b/code/modules/admin/admin_verbs.dm index 15297383a7b..3635c108cfd 100644 --- a/code/modules/admin/admin_verbs.dm +++ b/code/modules/admin/admin_verbs.dm @@ -395,16 +395,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("Invisimin on. You are now as invisible as a ghost."), 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("Invisimin on. You are now as invisible as a ghost."), confidential = TRUE) /client/proc/check_antagonists() set name = "Check Antagonists" @@ -550,7 +550,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 @@ -564,7 +564,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) diff --git a/code/modules/antagonists/abductor/machinery/camera.dm b/code/modules/antagonists/abductor/machinery/camera.dm index 685ae2d12db..36618e62269 100644 --- a/code/modules/antagonists/abductor/machinery/camera.dm +++ b/code/modules/antagonists/abductor/machinery/camera.dm @@ -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) diff --git a/code/modules/antagonists/blob/overmind.dm b/code/modules/antagonists/blob/overmind.dm index d87574c092d..e56426a89ad 100644 --- a/code/modules/antagonists/blob/overmind.dm +++ b/code/modules/antagonists/blob/overmind.dm @@ -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) diff --git a/code/modules/antagonists/changeling/powers/tiny_prick.dm b/code/modules/antagonists/changeling/powers/tiny_prick.dm index 83dc308022c..eb6ccccd8b5 100644 --- a/code/modules/antagonists/changeling/powers/tiny_prick.dm +++ b/code/modules/antagonists/changeling/powers/tiny_prick.dm @@ -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) diff --git a/code/modules/antagonists/cult/cult_structures.dm b/code/modules/antagonists/cult/cult_structures.dm index 0dd0d941aad..8ba039564da 100644 --- a/code/modules/antagonists/cult/cult_structures.dm +++ b/code/modules/antagonists/cult/cult_structures.dm @@ -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)) diff --git a/code/modules/antagonists/cult/runes.dm b/code/modules/antagonists/cult/runes.dm index d343e331fad..1359a391043 100644 --- a/code/modules/antagonists/cult/runes.dm +++ b/code/modules/antagonists/cult/runes.dm @@ -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) diff --git a/code/modules/antagonists/heretic/transmutation_rune.dm b/code/modules/antagonists/heretic/transmutation_rune.dm index cd49feb3f17..f625e809432 100644 --- a/code/modules/antagonists/heretic/transmutation_rune.dm +++ b/code/modules/antagonists/heretic/transmutation_rune.dm @@ -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 - diff --git a/code/modules/assembly/infrared.dm b/code/modules/assembly/infrared.dm index 3fc1de43b3c..a7a641bb884 100644 --- a/code/modules/assembly/infrared.dm +++ b/code/modules/assembly/infrared.dm @@ -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 diff --git a/code/modules/awaymissions/away_props.dm b/code/modules/awaymissions/away_props.dm index 920287dd51e..f6d1a830a91 100644 --- a/code/modules/awaymissions/away_props.dm +++ b/code/modules/awaymissions/away_props.dm @@ -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 diff --git a/code/modules/awaymissions/super_secret_room.dm b/code/modules/awaymissions/super_secret_room.dm index 78d0b78150c..556a9fd63ad 100644 --- a/code/modules/awaymissions/super_secret_room.dm +++ b/code/modules/awaymissions/super_secret_room.dm @@ -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() diff --git a/code/modules/library/bibles.dm b/code/modules/library/bibles.dm index 8a10a058341..48621abfd1a 100644 --- a/code/modules/library/bibles.dm +++ b/code/modules/library/bibles.dm @@ -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) diff --git a/code/modules/mining/lavaland/megafauna_loot.dm b/code/modules/mining/lavaland/megafauna_loot.dm index 20cbec1444b..64414f10501 100644 --- a/code/modules/mining/lavaland/megafauna_loot.dm +++ b/code/modules/mining/lavaland/megafauna_loot.dm @@ -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 diff --git a/code/modules/mining/lavaland/tendril_loot.dm b/code/modules/mining/lavaland/tendril_loot.dm index a6684a221ae..07079516fc1 100644 --- a/code/modules/mining/lavaland/tendril_loot.dm +++ b/code/modules/mining/lavaland/tendril_loot.dm @@ -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.")) diff --git a/code/modules/mob/dead/observer/observer.dm b/code/modules/mob/dead/observer/observer.dm index 8033d465a90..307e0f60261 100644 --- a/code/modules/mob/dead/observer/observer.dm +++ b/code/modules/mob/dead/observer/observer.dm @@ -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) diff --git a/code/modules/mob/living/basic/lavaland/bileworm/bileworm_actions.dm b/code/modules/mob/living/basic/lavaland/bileworm/bileworm_actions.dm index b6f7468697a..9c5e2697f63 100644 --- a/code/modules/mob/living/basic/lavaland/bileworm/bileworm_actions.dm +++ b/code/modules/mob/living/basic/lavaland/bileworm/bileworm_actions.dm @@ -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 diff --git a/code/modules/mob/living/basic/space_fauna/revenant/_revenant.dm b/code/modules/mob/living/basic/space_fauna/revenant/_revenant.dm index 526d268df03..856b5820b98 100644 --- a/code/modules/mob/living/basic/space_fauna/revenant/_revenant.dm +++ b/code/modules/mob/living/basic/space_fauna/revenant/_revenant.dm @@ -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) diff --git a/code/modules/mob/living/basic/space_fauna/revenant/revenant_effects.dm b/code/modules/mob/living/basic/space_fauna/revenant/revenant_effects.dm index 0eeec231973..b7bc6e34dcf 100644 --- a/code/modules/mob/living/basic/space_fauna/revenant/revenant_effects.dm +++ b/code/modules/mob/living/basic/space_fauna/revenant/revenant_effects.dm @@ -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 ..() diff --git a/code/modules/mob/living/carbon/alien/special/alien_embryo.dm b/code/modules/mob/living/carbon/alien/special/alien_embryo.dm index 5a6746ec6fa..3f3809c89b2 100644 --- a/code/modules/mob/living/carbon/alien/special/alien_embryo.dm +++ b/code/modules/mob/living/carbon/alien/special/alien_embryo.dm @@ -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!")) diff --git a/code/modules/mob/living/living.dm b/code/modules/mob/living/living.dm index c409b84c4e2..d29c24021ff 100644 --- a/code/modules/mob/living/living.dm +++ b/code/modules/mob/living/living.dm @@ -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 diff --git a/code/modules/mob/living/silicon/ai/freelook/eye.dm b/code/modules/mob/living/silicon/ai/freelook/eye.dm index 6204ecdea60..416bbb19912 100644 --- a/code/modules/mob/living/silicon/ai/freelook/eye.dm +++ b/code/modules/mob/living/silicon/ai/freelook/eye.dm @@ -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" diff --git a/code/modules/mob/mob_defines.dm b/code/modules/mob/mob_defines.dm index c5aac5f526e..6808728a833 100644 --- a/code/modules/mob/mob_defines.dm +++ b/code/modules/mob/mob_defines.dm @@ -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 diff --git a/code/modules/mob/transform_procs.dm b/code/modules/mob/transform_procs.dm index 290177f5baf..1caf5e9f1ea 100644 --- a/code/modules/mob/transform_procs.dm +++ b/code/modules/mob/transform_procs.dm @@ -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) diff --git a/code/modules/point/point.dm b/code/modules/point/point.dm index 3a3d97e2565..6e61b1154d5 100644 --- a/code/modules/point/point.dm +++ b/code/modules/point/point.dm @@ -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 diff --git a/code/modules/shuttle/shuttle.dm b/code/modules/shuttle/shuttle.dm index e11e6bf9156..1f9348ffa4b 100644 --- a/code/modules/shuttle/shuttle.dm +++ b/code/modules/shuttle/shuttle.dm @@ -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) diff --git a/code/modules/vehicles/mecha/combat/durand.dm b/code/modules/vehicles/mecha/combat/durand.dm index 4ac13b8dd64..f1c7bac4f81 100644 --- a/code/modules/vehicles/mecha/combat/durand.dm +++ b/code/modules/vehicles/mecha/combat/durand.dm @@ -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