From d421a56cc446a9f7a2b028de89bc48df0ad78223 Mon Sep 17 00:00:00 2001 From: Kashargul <144968721+Kashargul@users.noreply.github.com> Date: Sun, 22 Dec 2024 22:34:54 +0100 Subject: [PATCH] More area flag option fixes (#16740) * some mor fixes on the block flags * . * fix aghosting * . * add privacy switch * . * ignore bellied * . * . * fix it up --- code/__defines/visualnet.dm | 1 + code/game/area/areas.dm | 2 + code/game/machinery/computer/timeclock_vr.dm | 1 - code/modules/admin/admin_verbs.dm | 12 +++-- code/modules/mob/dead/observer/chunk.dm | 23 +++++++++ code/modules/mob/dead/observer/ghostnet.dm | 51 ++++++++++++++++++-- code/modules/mob/dead/observer/observer.dm | 20 +++++--- code/modules/mob/freelook/visualnet.dm | 4 -- code/modules/power/privacy_switch.dm | 41 ++++++++++++++++ vorestation.dme | 2 + 10 files changed, 137 insertions(+), 20 deletions(-) create mode 100644 code/__defines/visualnet.dm create mode 100644 code/modules/power/privacy_switch.dm diff --git a/code/__defines/visualnet.dm b/code/__defines/visualnet.dm new file mode 100644 index 0000000000..4b503bee2d --- /dev/null +++ b/code/__defines/visualnet.dm @@ -0,0 +1 @@ +#define CHUNK_SIZE 16 diff --git a/code/game/area/areas.dm b/code/game/area/areas.dm index 3af919882b..8d5616955b 100644 --- a/code/game/area/areas.dm +++ b/code/game/area/areas.dm @@ -562,6 +562,8 @@ GLOBAL_DATUM(spoiler_obfuscation_image, /image) return if(!isliving(ourmob)) return + if(ourmob.client?.holder) + return if(isanimal(ourmob)) var/mob/living/simple_mob/shadekin/SK = ourmob if(SK.ability_flags & AB_PHASE_SHIFTED) diff --git a/code/game/machinery/computer/timeclock_vr.dm b/code/game/machinery/computer/timeclock_vr.dm index a517bcbf7c..6f63c4c946 100644 --- a/code/game/machinery/computer/timeclock_vr.dm +++ b/code/game/machinery/computer/timeclock_vr.dm @@ -88,7 +88,6 @@ data["job_datum"] = null data["allow_change_job"] = null data["job_choices"] = null - data["on_cooldown"] = null if(card) data["card"] = "[card]" data["assignment"] = card.assignment diff --git a/code/modules/admin/admin_verbs.dm b/code/modules/admin/admin_verbs.dm index 6e860e317c..abf4005f4b 100644 --- a/code/modules/admin/admin_verbs.dm +++ b/code/modules/admin/admin_verbs.dm @@ -67,13 +67,11 @@ var/mob/observer/dead/ghost if(build_mode) togglebuildmode(body) - ghost = body.ghostize(1) - ghost.admin_ghosted = 1 + ghost = body.ghostize(1, TRUE) if(build_mode == "Yes") togglebuildmode(ghost) else - ghost = body.ghostize(1) - ghost.admin_ghosted = 1 + ghost = body.ghostize(1, TRUE) init_verbs() if(body) body.teleop = ghost @@ -359,6 +357,9 @@ message_admins("[src] re-admined themself.", 1) to_chat(src, span_filter_system(span_interface("You now have the keys to control the planet, or at least a small space station"))) remove_verb(src, /client/proc/readmin_self) + if(isobserver(mob)) + var/mob/observer/dead/our_mob = mob + our_mob.visualnet?.addVisibility(our_mob, src) /client/proc/deadmin_self() set name = "De-admin self" @@ -371,6 +372,9 @@ deadmin() to_chat(src, span_filter_system(span_interface("You are now a normal player."))) add_verb(src, /client/proc/readmin_self) + if(isobserver(mob)) + var/mob/observer/dead/our_mob = mob + our_mob.visualnet?.removeVisibility(our_mob, src) feedback_add_details("admin_verb","DAS") //If you are copy-pasting this, ensure the 2nd parameter is unique to the new proc! /client/proc/toggle_log_hrefs() diff --git a/code/modules/mob/dead/observer/chunk.dm b/code/modules/mob/dead/observer/chunk.dm index 0de1b2af73..5efe8fcd5b 100644 --- a/code/modules/mob/dead/observer/chunk.dm +++ b/code/modules/mob/dead/observer/chunk.dm @@ -6,6 +6,27 @@ /datum/chunk/ghost var/list/hidden_areas = list() +/datum/chunk/ghost/add(mob/observer/dead/ghost, add_images = TRUE) + if(add_images) + var/client/client = ghost.client + if(client) + client.images += obscured + ghost.visibleChunks += src + visible++ + seenby += ghost + if(changed && !updating) + update() + +/datum/chunk/ghost/remove(mob/observer/dead/ghost, remove_images = TRUE) + if(remove_images) + var/client/client = ghost.client + if(client) + client.images -= obscured + ghost.visibleChunks -= src + seenby -= ghost + if(visible > 0) + visible-- + /datum/chunk/ghost/acquireVisibleTurfs(var/list/invisible) for(var/area/A in hidden_areas) @@ -85,6 +106,8 @@ if(!m) seenby -= m continue + if(!m.checkStatic()) + continue var/client/client = m.client if(client) client.images += t.obfuscations[obfuscation.type] diff --git a/code/modules/mob/dead/observer/ghostnet.dm b/code/modules/mob/dead/observer/ghostnet.dm index cce2677262..b9e6952d19 100644 --- a/code/modules/mob/dead/observer/ghostnet.dm +++ b/code/modules/mob/dead/observer/ghostnet.dm @@ -5,20 +5,65 @@ /datum/visualnet/ghost chunk_type = /datum/chunk/ghost -// Removes a area from a chunk. +/datum/visualnet/ghost/proc/addVisibility(list/moved_eyes, client/C) + if(!islist(moved_eyes)) + moved_eyes = moved_eyes ? list(moved_eyes) : list() + var/list/chunks_pre_seen = list() + + for(var/mob/observer/dead/ghost as anything in moved_eyes) + if(C) + chunks_pre_seen |= ghost.visibleChunks + + if(C) + for(var/datum/chunk/ghost/c as anything in chunks_pre_seen) + for(var/mob/observer/dead/ghost as anything in moved_eyes) + c.remove(ghost) + +/datum/visualnet/ghost/proc/removeVisibility(list/moved_eyes, client/C) + if(!islist(moved_eyes)) + moved_eyes = moved_eyes ? list(moved_eyes) : list() + + var/list/chunks_post_seen = list() + + for(var/mob/observer/dead/ghost as anything in moved_eyes) + // 0xf = 15 + var/static_range = ghost.static_visibility_range + var/x1 = max(0, ghost.x - static_range) & ~(CHUNK_SIZE - 1) + var/y1 = max(0, ghost.y - static_range) & ~(CHUNK_SIZE - 1) + var/x2 = min(world.maxx, ghost.x + static_range) & ~(CHUNK_SIZE - 1) + var/y2 = min(world.maxy, ghost.y + static_range) & ~(CHUNK_SIZE - 1) + + var/list/visibleChunks = list() + + for(var/x = x1; x <= x2; x += CHUNK_SIZE) + for(var/y = y1; y <= y2; y += CHUNK_SIZE) + visibleChunks |= getChunk(x, y, ghost.z) + + var/list/add = visibleChunks - ghost.visibleChunks + + for(var/datum/chunk/ghost/c as anything in add) + c.add(ghost, FALSE) + + if(C) + chunks_post_seen |= ghost.visibleChunks + + if(C) + + for(var/datum/chunk/c as anything in chunks_post_seen) + C.images += c.obscured + +// Removes a area from a chunk. /datum/visualnet/ghost/proc/removeArea(area/A) if(!A.flag_check(AREA_BLOCK_GHOST_SIGHT)) majorChunkChange(A, 0) // Add a area to a chunk. - /datum/visualnet/ghost/proc/addArea(area/A) if(A.flag_check(AREA_BLOCK_GHOST_SIGHT)) majorChunkChange(A, 1) // Used for ghost visible areas. Since portable areas can be in ANY chunk. - /datum/visualnet/ghost/proc/updateArea(area/A) if(A.flag_check(AREA_BLOCK_GHOST_SIGHT)) majorChunkChange(A, 1) diff --git a/code/modules/mob/dead/observer/observer.dm b/code/modules/mob/dead/observer/observer.dm index 83bfa07de9..5bf40b9dd4 100644 --- a/code/modules/mob/dead/observer/observer.dm +++ b/code/modules/mob/dead/observer/observer.dm @@ -14,8 +14,7 @@ blinded = 0 anchored = TRUE // don't get pushed around var/list/visibleChunks = list() - var/datum/visualnet/visualnet - var/use_static = TRUE + var/datum/visualnet/ghost/visualnet var/static_visibility_range = 16 var/can_reenter_corpse @@ -92,13 +91,14 @@ var/last_revive_notification = null // world.time of last notification, used to avoid spamming players from defibs or cloners. var/cleanup_timer // Refernece to a timer that will delete this mob if no client returns -/mob/observer/dead/New(mob/body) +/mob/observer/dead/New(mob/body, aghost = FALSE) appearance = body invisibility = INVISIBILITY_OBSERVER layer = BELOW_MOB_LAYER plane = PLANE_GHOSTS alpha = 127 + admin_ghosted = aghost sight |= SEE_TURFS | SEE_MOBS | SEE_OBJS | SEE_SELF see_invisible = SEE_INVISIBLE_OBSERVER @@ -146,10 +146,14 @@ ..() visualnet = ghostnet +/mob/observer/dead/proc/checkStatic() + return !(check_rights(R_ADMIN|R_FUN|R_EVENT|R_SERVER, 0, src) || (client && client.buildmode) || isbelly(loc)) + /mob/observer/dead/Moved(atom/old_loc, direction, forced) . = ..() - use_static = !(check_rights(R_ADMIN|R_FUN|R_EVENT|R_SERVER, 0, src) || (client && client.buildmode)) - if(visualnet && use_static) + if(isbelly(loc) && !isbelly(old_loc)) + visualnet.addVisibility() + if(visualnet && checkStatic()) visualnet.visibility(src, client) /mob/observer/dead/Topic(href, href_list) @@ -220,14 +224,14 @@ Works together with spawning an observer, noted above. forceMove(O.loc) //RS Port #658 End -/mob/proc/ghostize(var/can_reenter_corpse = 1) +/mob/proc/ghostize(var/can_reenter_corpse = 1, var/aghost = FALSE) if(key) if(ishuman(src)) var/mob/living/carbon/human/H = src if(H.vr_holder && !can_reenter_corpse) H.exit_vr() return 0 - var/mob/observer/dead/ghost = new(src) //Transfer safety to observer spawning proc. + var/mob/observer/dead/ghost = new(src, aghost) //Transfer safety to observer spawning proc. ghost.can_reenter_corpse = can_reenter_corpse ghost.timeofdeath = src.timeofdeath //BS12 EDIT ghost.key = key @@ -463,7 +467,7 @@ This is the proc mobs get to turn into a ghost. Forked from ghostize due to comp //RS Port #658 Start var/area/A = get_area(destination) - if(A?.flag_check(AREA_BLOCK_GHOSTS) && !isbelly(destination)) + if(A?.flag_check(AREA_BLOCK_GHOSTS) && !isbelly(destination) && !admin_ghosted) to_chat(src,span_warning("Sorry, that area does not allow ghosts.")) if(following) stop_following() diff --git a/code/modules/mob/freelook/visualnet.dm b/code/modules/mob/freelook/visualnet.dm index 2af7ffacd6..d153701cdd 100644 --- a/code/modules/mob/freelook/visualnet.dm +++ b/code/modules/mob/freelook/visualnet.dm @@ -2,8 +2,6 @@ // // The datum containing all the chunks. -#define CHUNK_SIZE 16 - /datum/visualnet // The chunks of the map, mapping the areas that an object can see. var/list/chunks = list() @@ -159,5 +157,3 @@ var/datum/chunk/chunk = cameranet.getCameraChunk(x, y, z) usr.client.debug_variables(chunk) */ - -#undef CHUNK_SIZE diff --git a/code/modules/power/privacy_switch.dm b/code/modules/power/privacy_switch.dm new file mode 100644 index 0000000000..c18a6a295c --- /dev/null +++ b/code/modules/power/privacy_switch.dm @@ -0,0 +1,41 @@ +/obj/structure/privacyswitch + name = "privacy switch" + desc = "A special switch to increase the room's privavy. (Blocks ghosts from seeing the area)" + icon = 'icons/obj/power_vr.dmi' + icon_state = "light0" + var/nextUse = 0 + +/obj/structure/privacyswitch/Initialize() + var/area/A = get_area(src) + if(A?.flag_check(AREA_BLOCK_GHOST_SIGHT)) + icon_state = "light1" + . = ..() + +/obj/structure/privacyswitch/attack_ai(mob/user) + attack_hand() + return + +/obj/structure/privacyswitch/attack_hand(mob/user) + if(nextUse - world.time > 0) + to_chat(user, span_warning("The area can not be altered so soon again!")) + return + var/area/A = get_area(src) + if(!A) + return + + if(tgui_alert(user, "Do you want to toggle ghost vision for this area [A.flag_check(AREA_BLOCK_GHOST_SIGHT) ? "on" : "off"]?", "Toggle ghost vision?", list("Yes", "No")) != "Yes") + return + + if(A.flag_check(AREA_BLOCK_GHOST_SIGHT)) + A.flags ^= AREA_BLOCK_GHOST_SIGHT + icon_state = "light0" + ghostnet.removeArea(A) + to_chat(user, span_notice("The area is no longer protected from ghost vison.")) + log_and_message_admins("toggled ghost vision in [A] on.", user) + else + A.flags ^= AREA_BLOCK_GHOST_SIGHT + icon_state = "light1" + ghostnet.addArea(A) + to_chat(user, span_notice("The area is now protected from ghost vison.")) + log_and_message_admins("toggled ghost vision in [A] off.", user) + nextUse = world.time + 5 MINUTES diff --git a/vorestation.dme b/vorestation.dme index 696c098f4b..b3f0b69b81 100644 --- a/vorestation.dme +++ b/vorestation.dme @@ -154,6 +154,7 @@ #include "code\__defines\unit_tests.dm" #include "code\__defines\update_icons.dm" #include "code\__defines\verb_manager.dm" +#include "code\__defines\visualnet.dm" #include "code\__defines\vore.dm" #include "code\__defines\vote.dm" #include "code\__defines\vv.dm" @@ -3749,6 +3750,7 @@ #include "code\modules\power\port_gen_vr.dm" #include "code\modules\power\power.dm" #include "code\modules\power\powernet.dm" +#include "code\modules\power\privacy_switch.dm" #include "code\modules\power\smes.dm" #include "code\modules\power\smes_construction.dm" #include "code\modules\power\smes_vr.dm"