diff --git a/code/__DEFINES/dcs/signals/atom/mob/signals_mind.dm b/code/__DEFINES/dcs/signals/atom/mob/signals_mind.dm new file mode 100644 index 0000000000..2cca5fe18c --- /dev/null +++ b/code/__DEFINES/dcs/signals/atom/mob/signals_mind.dm @@ -0,0 +1,2 @@ +///from mind/transfer_to. Sent after the mind has been transferred to a different body: (mob/previous_body) +#define COMSIG_MIND_TRANSFERRED "mind_transferred" diff --git a/code/__DEFINES/dcs/signals/atom/mob/signals_mob.dm b/code/__DEFINES/dcs/signals/atom/mob/signals_mob.dm index 0271cd6334..dd995ba864 100644 --- a/code/__DEFINES/dcs/signals/atom/mob/signals_mob.dm +++ b/code/__DEFINES/dcs/signals/atom/mob/signals_mob.dm @@ -72,9 +72,13 @@ #define COMSIG_MOB_PRE_CLICK "mob_pre_click" #define COMPONENT_INTERRUPT_CLICK (1<<0) -///from base of /mob/Login(): () +/// From base of /mob/Login(), called when a client logs into this mob: () +/// Not to be confused with [COMSIG_MOB_LOGGED_IN] #define COMSIG_MOB_LOGIN "mob_login" -///from base of /mob/Logout(): () +/// From base of /mob/Login(), called after a client logs into this mob: () +/// Not to be confused with [COMSIG_MOB_LOGIN] +#define COMSIG_MOB_LOGGED_IN "mob_logged_in" +/// From base of /mob/Logout(): () #define COMSIG_MOB_LOGOUT "mob_logout" //from /mob/proc/on_deafness_gain() diff --git a/code/__DEFINES/dcs/signals/signals_client.dm b/code/__DEFINES/dcs/signals/signals_client.dm index 6733e07035..e7e74771fc 100644 --- a/code/__DEFINES/dcs/signals/signals_client.dm +++ b/code/__DEFINES/dcs/signals/signals_client.dm @@ -19,8 +19,8 @@ /// Called after one or more verbs are added: (list of verbs added) #define COMSIG_CLIENT_VERB_REMOVED "client_verb_removed" -/// Called after a client logs into a mob: (mob) -#define COMSIG_CLIENT_MOB_LOGIN "client_mob_changed" +/// Called from /mob/Login() after a client logs into a mob: (mob) +#define COMSIG_CLIENT_MOB_LOGGED_IN "client_mob_logged_in" /// Called when something is added to a client's screen : /client/proc/add_to_screen(screen_add) #define COMSIG_CLIENT_SCREEN_ADD "client_screen_add" diff --git a/code/__DEFINES/dcs/signals/signals_global.dm b/code/__DEFINES/dcs/signals/signals_global.dm index 89904c5a1b..825f427695 100644 --- a/code/__DEFINES/dcs/signals/signals_global.dm +++ b/code/__DEFINES/dcs/signals/signals_global.dm @@ -34,9 +34,11 @@ #define COMSIG_GLOB_REMOVE_VOTE_BUTTON "!remove_vote_button" -#define COMSIG_GLOB_CLIENT_LOGIN "!client_login" +/// Called from /client/New() when a client logs in to the game: (client) +#define COMSIG_GLOB_CLIENT_LOGGED_IN "!client_logged_in" -#define COMSIG_GLOB_MOB_LOGIN "!mob_login" +/// Called from /mob/Login() when a client logs into a mob: (mob) +#define COMSIG_GLOB_MOB_LOGGED_IN "!mob_logged_in" ///from /datum/controller/subsystem/ticker/PostSetup #define COMSIG_GLOB_POST_SETUP "!post_setup" diff --git a/code/__DEFINES/sounds.dm b/code/__DEFINES/sounds.dm index 6c5d2879f3..13a4468427 100644 --- a/code/__DEFINES/sounds.dm +++ b/code/__DEFINES/sounds.dm @@ -61,6 +61,9 @@ #define SOUND_ENVIRONMENT_DIZZY 24 #define SOUND_ENVIRONMENT_PSYCHOTIC 25 +#define SOUND_ECHO_REVERB_ON list(0, 0, 0, 0, 0, 0.0, 0, 0.25, 1.5, 1.0, 0, 1.0, 0, 0.0, 0.0, 0.0, 1.0, 0) +#define SOUND_ECHO_REVERB_OFF list(0, 0, -10000, -10000, 0, 0.0, 0, 0.25, 1.5, 1.0, 0, 1.0, 0, 0.0, 0.0, 0.0, 1.0, 0) //-10000 to Room & RoomHF makes enviromental reverb effectively inaudible + #define AMBIENCE_SHIP 'sound/ambience/shipambience.ogg' #define AMBIENCE_JUNGLE 'sound/ambience/ambienceLV624.ogg' #define AMBIENCE_RIVER 'sound/ambience/ambienceriver.ogg' diff --git a/code/_onclick/hud/screen_objects.dm b/code/_onclick/hud/screen_objects.dm index d114aff6b7..18587c0545 100644 --- a/code/_onclick/hud/screen_objects.dm +++ b/code/_onclick/hud/screen_objects.dm @@ -59,9 +59,11 @@ /atom/movable/screen/action_button/attack_ghost(mob/dead/observer/user) return -/atom/movable/screen/action_button/clicked(mob/user) +/atom/movable/screen/action_button/clicked(mob/user, list/mods) if(!user || !source_action) return TRUE + if(source_action.owner != user) + return TRUE if(source_action.can_use_action()) source_action.action_activate() @@ -97,7 +99,7 @@ icon_state = "hide" var/hidden = 0 -/atom/movable/screen/action_button/hide_toggle/clicked(mob/user, mods) +/atom/movable/screen/action_button/hide_toggle/clicked(mob/user, list/mods) user.hud_used.action_buttons_hidden = !user.hud_used.action_buttons_hidden hidden = user.hud_used.action_buttons_hidden if(hidden) @@ -107,7 +109,7 @@ name = "Hide Buttons" icon_state = "hide" user.update_action_buttons() - return 1 + return TRUE /atom/movable/screen/action_button/ghost/minimap/get_button_screen_loc(button_number) return "SOUTH:6,CENTER+1:24" @@ -214,7 +216,7 @@ /atom/movable/screen/zone_sel/robot icon = 'icons/mob/hud/screen1_robot.dmi' -/atom/movable/screen/clicked(mob/user) +/atom/movable/screen/clicked(mob/user, list/mods) if(!user) return TRUE diff --git a/code/controllers/subsystem/minimap.dm b/code/controllers/subsystem/minimap.dm index 1c2a6d3e24..a26d024b17 100644 --- a/code/controllers/subsystem/minimap.dm +++ b/code/controllers/subsystem/minimap.dm @@ -717,6 +717,7 @@ SUBSYSTEM_DEF(minimaps) user.client.register_map_obj(map_holder.map) ui = new(user, src, "TacticalMap") ui.open() + RegisterSignal(user.mind, COMSIG_MIND_TRANSFERRED, PROC_REF(on_mind_transferred)) /datum/tacmap/drawing/tgui_interact(mob/user, datum/tgui/ui) var/mob/living/carbon/xenomorph/xeno = user @@ -755,6 +756,7 @@ SUBSYSTEM_DEF(minimaps) tacmap_ready_time = SSminimaps.next_fire + 2 SECONDS addtimer(CALLBACK(src, PROC_REF(on_tacmap_fire), faction), SSminimaps.next_fire - world.time + 1 SECONDS) user.client.register_map_obj(map_holder.map) + RegisterSignal(user.mind, COMSIG_MIND_TRANSFERRED, PROC_REF(on_mind_transferred)) ui = new(user, src, "TacticalMap") ui.open() @@ -835,6 +837,9 @@ SUBSYSTEM_DEF(minimaps) return data +/datum/tacmap/ui_close(mob/user) + UnregisterSignal(user.mind, COMSIG_MIND_TRANSFERRED) + /datum/tacmap/drawing/ui_close(mob/user) . = ..() action_queue_change = 0 @@ -950,6 +955,11 @@ SUBSYSTEM_DEF(minimaps) return UI_INTERACTIVE +// This gets removed when the player changes bodies (i.e. xeno evolution), so re-register it when that happens. +/datum/tacmap/proc/on_mind_transferred(datum/mind/source, mob/previous_body) + SIGNAL_HANDLER + source.current.client.register_map_obj(map_holder.map) + /datum/tacmap_holder var/map_ref var/atom/movable/screen/minimap/map diff --git a/code/controllers/subsystem/ticker.dm b/code/controllers/subsystem/ticker.dm index cfe66421c9..d3cb19c40e 100644 --- a/code/controllers/subsystem/ticker.dm +++ b/code/controllers/subsystem/ticker.dm @@ -180,7 +180,7 @@ SUBSYSTEM_DEF(ticker) CHECK_TICK mode.announce() if(mode.taskbar_icon) - RegisterSignal(SSdcs, COMSIG_GLOB_CLIENT_LOGIN, PROC_REF(handle_mode_icon)) + RegisterSignal(SSdcs, COMSIG_GLOB_CLIENT_LOGGED_IN, PROC_REF(handle_mode_icon)) set_clients_taskbar_icon(mode.taskbar_icon) if(GLOB.perf_flags & PERF_TOGGLE_LAZYSS) diff --git a/code/controllers/subsystem/vote.dm b/code/controllers/subsystem/vote.dm index a56e10636a..34350613ce 100644 --- a/code/controllers/subsystem/vote.dm +++ b/code/controllers/subsystem/vote.dm @@ -59,7 +59,7 @@ SUBSYSTEM_DEF(vote) voting.Cut() remove_action_buttons() - UnregisterSignal(SSdcs, COMSIG_GLOB_CLIENT_LOGIN) + UnregisterSignal(SSdcs, COMSIG_GLOB_CLIENT_LOGGED_IN) for(var/c in GLOB.player_list) update_static_data(c) @@ -370,7 +370,7 @@ SUBSYSTEM_DEF(vote) if(send_clients_vote) C.mob.vote() - RegisterSignal(SSdcs, COMSIG_GLOB_CLIENT_LOGIN, PROC_REF(handle_client_joining)) + RegisterSignal(SSdcs, COMSIG_GLOB_CLIENT_LOGGED_IN, PROC_REF(handle_client_joining)) SStgui.update_uis(src) return TRUE return FALSE diff --git a/code/datums/action.dm b/code/datums/action.dm index 0510a43415..3a597ad262 100644 --- a/code/datums/action.dm +++ b/code/datums/action.dm @@ -11,9 +11,9 @@ var/cost = 0 // By default an action has no cost -> will be utilized by skill actions/xeno actions var/action_flags = 0 // Check out __game.dm for flags /// Whether the action is hidden from its owner - /// Useful for when you want to preserve action state while preventing - /// a mob from using said action - var/hidden = FALSE + var/hidden = FALSE //Preserve action state while preventing mob from using action + ///Hide the action from the owner without preventing them from using it (incase of keybind listen_signal) + var/player_hidden = FALSE var/unique = TRUE /// A signal on the mob that will cause the action to activate var/listen_signal @@ -227,7 +227,7 @@ var/atom/movable/screen/action_button/B = A.button if(reload_screen) client.add_to_screen(B) - if(A.hidden) + if(A.hidden || A.player_hidden) B.screen_loc = null continue button_number++ diff --git a/code/datums/components/overlay_lighting.dm b/code/datums/components/overlay_lighting.dm index e14066ffb7..225149ecb4 100644 --- a/code/datums/components/overlay_lighting.dm +++ b/code/datums/components/overlay_lighting.dm @@ -199,7 +199,7 @@ get_new_turfs() -///Adds the luminosity and source for the afected movable atoms to keep track of their visibility. +///Adds the luminosity and source for the affected movable atoms to keep track of their visibility. /datum/component/overlay_lighting/proc/add_dynamic_lumi() LAZYSET(current_holder.affected_movable_lights, src, lumcount_range + 1) current_holder.underlays += visible_mask @@ -207,7 +207,7 @@ if(directional) current_holder.underlays += cone -///Removes the luminosity and source for the afected movable atoms to keep track of their visibility. +///Removes the luminosity and source for the affected movable atoms to keep track of their visibility. /datum/component/overlay_lighting/proc/remove_dynamic_lumi() LAZYREMOVE(current_holder.affected_movable_lights, src) current_holder.underlays -= visible_mask @@ -267,6 +267,9 @@ ///Used to determine the new valid current_holder from the parent's loc. /datum/component/overlay_lighting/proc/check_holder() var/atom/movable/movable_parent = GET_PARENT + if(QDELETED(movable_parent)) + set_holder(null) + return if(isturf(movable_parent.loc)) set_holder(movable_parent) return @@ -275,13 +278,21 @@ set_holder(null) return if(isturf(inside.loc)) - set_holder(inside) + // storage items block light, also don't be moving into a qdeleted item + if(QDELETED(inside) || istype(inside, /obj/item/storage)) + set_holder(null) + else + set_holder(inside) return set_holder(null) ///Called when the current_holder is qdeleted, to remove the light effect. /datum/component/overlay_lighting/proc/on_holder_qdel(atom/movable/source, force) + SIGNAL_HANDLER + if(QDELETED(current_holder)) + set_holder(null) + return UnregisterSignal(current_holder, list(COMSIG_PARENT_QDELETING, COMSIG_MOVABLE_MOVED)) if(directional) UnregisterSignal(current_holder, COMSIG_ATOM_DIR_CHANGE) @@ -290,6 +301,7 @@ ///Called when current_holder changes loc. /datum/component/overlay_lighting/proc/on_holder_moved(atom/movable/source, OldLoc, Dir, Forced) + SIGNAL_HANDLER if(!(overlay_lighting_flags & LIGHTING_ON)) return make_luminosity_update() @@ -450,8 +462,7 @@ . = lum_power lum_power = new_lum_power var/difference = . - lum_power - for(var/t in affected_turfs) - var/turf/lit_turf = t + for(var/turf/lit_turf as anything in affected_turfs) lit_turf.dynamic_lumcount -= difference ///Here we append the behavior associated to changing lum_power. diff --git a/code/datums/mind.dm b/code/datums/mind.dm index fe59699fb9..ae6304dbcd 100644 --- a/code/datums/mind.dm +++ b/code/datums/mind.dm @@ -32,11 +32,11 @@ msg_admin_niche("[key]/[ckey] has tried to transfer to deleted [new_character].") return - SEND_SIGNAL(current.client, COMSIG_CLIENT_MIND_TRANSFER, new_character) - + var/mob/old_current = current if(current) current.mind = null //remove ourself from our old body's mind variable nanomanager.user_transferred(current, new_character) // transfer active NanoUI instances to new user + SStgui.on_transfer(current, new_character) // and active TGUI instances if(key) if(new_character.key != key) @@ -66,6 +66,7 @@ continue player_entity = setup_player_entity(ckey) + SEND_SIGNAL(src, COMSIG_MIND_TRANSFERRED, old_current) SEND_SIGNAL(new_character, COMSIG_MOB_NEW_MIND, current.client) new_character.refresh_huds(current) //inherit the HUDs from the old body diff --git a/code/datums/soundOutput.dm b/code/datums/soundOutput.dm index 85548d6c90..0fddd9b503 100644 --- a/code/datums/soundOutput.dm +++ b/code/datums/soundOutput.dm @@ -4,13 +4,25 @@ var/list/soundscape_playlist = list() //Updated on changing areas var/ambience = null //The file currently being played as ambience var/status_flags = 0 //For things like ear deafness, psychodelic effects, and other things that change how all sounds behave - var/list/echo -/datum/soundOutput/New(client/C) - if(!C) + + /// Currently applied environmental reverb. + VAR_PROTECTED/owner_environment = SOUND_ENVIRONMENT_NONE + +/datum/soundOutput/New(client/client) + if(!client) qdel(src) return - owner = C - . = ..() + owner = client + RegisterSignal(owner.mob, COMSIG_MOVABLE_MOVED, PROC_REF(on_mob_moved)) + RegisterSignal(owner.mob, COMSIG_MOB_LOGOUT, PROC_REF(on_mob_logout)) + RegisterSignal(owner, COMSIG_CLIENT_MOB_LOGGED_IN, PROC_REF(on_client_mob_logged_in)) + return ..() + +/datum/soundOutput/Destroy() + UnregisterSignal(owner.mob, list(COMSIG_MOVABLE_MOVED, COMSIG_MOB_LOGOUT)) + UnregisterSignal(owner, COMSIG_CLIENT_MOB_LOGGED_IN) + owner = null + return ..() /datum/soundOutput/proc/process_sound(datum/sound_template/T) var/sound/S = sound(T.file, T.repeat, T.wait) @@ -24,7 +36,6 @@ S.offset = T.offset S.pitch = T.pitch S.status = T.status - S.echo = T.echo if(T.x && T.y && T.z) var/turf/owner_turf = get_turf(owner.mob) if(owner_turf) @@ -40,16 +51,12 @@ S.x = T.x - owner_turf.x S.y = 0 S.z = T.y - owner_turf.y - var/area/A = owner_turf.loc - S.environment = A.sound_environment S.y += T.y_s_offset S.x += T.x_s_offset + S.echo = SOUND_ECHO_REVERB_ON //enable environment reverb for positional sounds if(owner.mob.ear_deaf > 0) S.status |= SOUND_MUTE - if(owner.mob.sound_environment_override != SOUND_ENVIRONMENT_NONE) - S.environment = owner.mob.sound_environment_override - sound_to(owner,S) /datum/soundOutput/proc/update_ambience(area/target_area, ambience_override, force_update = FALSE) @@ -86,7 +93,6 @@ S.status = status_flags if(target_area) - S.environment = target_area.sound_environment var/muffle if(target_area.ceiling_muffle) switch(target_area.ceiling) @@ -130,6 +136,51 @@ S.status = SOUND_UPDATE sound_to(owner, S) +/// Pulls mob's area's sound_environment and applies if necessary and not overridden. +/datum/soundOutput/proc/update_area_environment() + var/area/owner_area = get_area(owner.mob) + var/new_environment = owner_area.sound_environment + + if(owner.mob.sound_environment_override != SOUND_ENVIRONMENT_NONE) //override in effect, can't apply + return + + set_owner_environment(new_environment) + +/// Pulls mob's sound_environment_override and applies if necessary. +/datum/soundOutput/proc/update_mob_environment_override() + var/new_environment_override = owner.mob.sound_environment_override + + if(new_environment_override == SOUND_ENVIRONMENT_NONE) //revert to area environment + update_area_environment() + return + + set_owner_environment(new_environment_override) + +/// Pushes new_environment to owner and updates owner_environment var. +/datum/soundOutput/proc/set_owner_environment(new_environment = SOUND_ENVIRONMENT_NONE) + if(new_environment ~= src.owner_environment) //no need to change + return + + var/sound/sound = sound() + sound.environment = new_environment + sound_to(owner, sound) + + src.owner_environment = new_environment + +/datum/soundOutput/proc/on_mob_moved(datum/source, atom/oldloc, direction, Forced) + SIGNAL_HANDLER //COMSIG_MOVABLE_MOVED + update_area_environment() + +/datum/soundOutput/proc/on_mob_logout(datum/source) + SIGNAL_HANDLER //COMSIG_MOB_LOGOUT + UnregisterSignal(owner.mob, list(COMSIG_MOVABLE_MOVED, COMSIG_MOB_LOGOUT)) + +/datum/soundOutput/proc/on_client_mob_logged_in(datum/source, mob/new_mob) + SIGNAL_HANDLER //COMSIG_CLIENT_MOB_LOGGED_IN + RegisterSignal(owner.mob, COMSIG_MOVABLE_MOVED, PROC_REF(on_mob_moved)) + RegisterSignal(owner.mob, COMSIG_MOB_LOGOUT, PROC_REF(on_mob_logout)) + update_mob_environment_override() + /client/proc/adjust_volume_prefs(volume_key, prompt = "", channel_update = 0) volume_preferences[volume_key] = (tgui_input_number(src, prompt, "Volume", volume_preferences[volume_key]*100)) / 100 if(volume_preferences[volume_key] > 1) diff --git a/code/game/objects/items/devices/radio/headset.dm b/code/game/objects/items/devices/radio/headset.dm index e6daba29ae..f00ba138ef 100644 --- a/code/game/objects/items/devices/radio/headset.dm +++ b/code/game/objects/items/devices/radio/headset.dm @@ -244,7 +244,7 @@ ), PROC_REF(turn_on)) wearer = user RegisterSignal(user, COMSIG_MOB_STAT_SET_ALIVE, PROC_REF(update_minimap_icon)) - RegisterSignal(user, COMSIG_MOB_LOGIN, PROC_REF(add_hud_tracker)) + RegisterSignal(user, COMSIG_MOB_LOGGED_IN, PROC_REF(add_hud_tracker)) RegisterSignal(user, COMSIG_MOB_DEATH, PROC_REF(update_minimap_icon)) RegisterSignal(user, COMSIG_HUMAN_SET_UNDEFIBBABLE, PROC_REF(update_minimap_icon)) if(headset_hud_on) @@ -261,7 +261,7 @@ UnregisterSignal(user, list( COMSIG_LIVING_REJUVENATED, COMSIG_HUMAN_REVIVED, - COMSIG_MOB_LOGIN, + COMSIG_MOB_LOGGED_IN, COMSIG_MOB_DEATH, COMSIG_HUMAN_SET_UNDEFIBBABLE, COMSIG_MOB_STAT_SET_ALIVE diff --git a/code/game/sound.dm b/code/game/sound.dm index f2574975a7..6bee74ba01 100644 --- a/code/game/sound.dm +++ b/code/game/sound.dm @@ -1,3 +1,5 @@ +/sound + echo = SOUND_ECHO_REVERB_OFF //disable enviroment reverb by default, soundOutput re-enables for positional sounds /datum/sound_template //Basically a sound datum, but only serves as a way to carry info to soundOutput //copied sound datum vars @@ -23,8 +25,6 @@ var/falloff = 1 ///Changes the environmental reverb for all 3D sounds until another environment is specified. The default value (-1) specifies no change in environment. A numeric value from 0 to 25 specifies a set of reverb presets for the environment. var/environment = -1 - ///If set to an 18-element list, this value customizes reverbration settings for this sound only. - var/list/echo //custom vars ///The category of this sound for client volume purposes: VOLUME_SFX (Sound effects), VOLUME_AMB (Ambience and Soundscapes) and VOLUME_ADM (Admin sounds and some other stuff) @@ -59,16 +59,40 @@ * * channel - use this only when you want to force the sound to play on a specific channel * * status - combined bit flags: SOUND_MUTE, SOUND_PAUSED, SOUND_STREAM, SOUND_UPDATE * * falloff - max range till sound volume starts dropping as distance increases - * * echo - customizes reverbration settings for this sound * * y_s_offset - vertical sound position offset * * x_s_offset - horizontal sound position offset * * Returns selected channel on success, FALSE on failure */ -/proc/playsound(atom/source, sound/soundin, vol = 100, vary = FALSE, sound_range, vol_cat = VOLUME_SFX, channel = 0, status, falloff = 1, list/echo, y_s_offset, x_s_offset) +/proc/playsound(atom/source, sound/soundin, vol = 100, vary = FALSE, sound_range, vol_cat = VOLUME_SFX, channel = 0, status, falloff = 1, y_s_offset, x_s_offset) if(isarea(source)) error("[source] is an area and is trying to make the sound: [soundin]") return FALSE + var/datum/sound_template/S = new() + + var/sound/SD = soundin + if(istype(SD)) + S.file = SD.file + S.wait = SD.wait + S.repeat = SD.repeat + else + S.file = get_sfx(soundin) + S.channel = channel ? channel : get_free_channel() + S.status = status + S.falloff = falloff + S.volume = vol + S.volume_cat = vol_cat + S.y_s_offset = y_s_offset + S.x_s_offset = x_s_offset + if(vary != FALSE) + if(vary > 1) + S.frequency = vary + else + S.frequency = GET_RANDOM_FREQ // Same frequency for everybody + + if(!sound_range) + sound_range = floor(0.25*vol) //if no specific range, the max range is equal to a quarter of the volume. + S.range = sound_range var/turf/turf_source = get_turf(source) if(!turf_source?.z) @@ -100,7 +124,6 @@ template.frequency = GET_RANDOM_FREQ // Same frequency for everybody template.status = status template.falloff = falloff - template.echo = echo template.volume_cat = vol_cat template.range = sound_range || floor(0.25 * vol) //if no specific range, the max range is equal to a quarter of the volume. @@ -147,13 +170,12 @@ * * vol_cat - the category of this sound for client volume purposes: VOLUME_SFX (Sound effects), VOLUME_AMB (Ambience and Soundscapes), VOLUME_ADM (Admin sounds) * * channel - use this only when you want to force the sound to play on a specific channel * * status - combined bit flags: SOUND_MUTE, SOUND_PAUSED, SOUND_STREAM, SOUND_UPDATE - * * echo - customizes reverbration settings for this sound * * y_s_offset - vertical sound position offset * * x_s_offset - horizontal sound position offset * * Returns FALSE on failure */ -/proc/playsound_client(client/C, sound/soundin, atom/origin, vol = 100, random_freq, vol_cat = VOLUME_SFX, channel = 0, status, list/echo, y_s_offset, x_s_offset) +/proc/playsound_client(client/C, sound/soundin, atom/origin, vol = 100, random_freq, vol_cat = VOLUME_SFX, channel = 0, status, y_s_offset, x_s_offset) if(!istype(C) || !C.soundOutput) return FALSE var/datum/sound_template/template = new() @@ -179,7 +201,6 @@ if(random_freq) template.frequency = GET_RANDOM_FREQ template.status = status - template.echo = echo template.volume_cat = vol_cat var/turf/turf_origin = get_turf(origin) @@ -206,7 +227,7 @@ * * Returns FALSE on failure */ -/proc/playsound_area(area/A, sound/soundin, vol = 100, channel = 0, status, vol_cat = VOLUME_SFX, list/echo, y_s_offset, x_s_offset) +/proc/playsound_area(area/A, sound/soundin, vol = 100, channel = 0, status, vol_cat = VOLUME_SFX, y_s_offset, x_s_offset) if(!isarea(A)) return FALSE @@ -259,13 +280,12 @@ * * soundin - sound datum ( sound() ), sound file ('mysound.ogg'), or string to get a SFX ("male_warcry") * * volume - the initial volume of the sound, 0 is no sound at all, 75 is loud queen screech. * * vol_cat - the category of this sound for client volume purposes: VOLUME_SFX (Sound effects), VOLUME_AMB (Ambience and Soundscapes), VOLUME_ADM (Admin sounds) - * * echo - customizes reverbration settings for this sound * * y_s_offset - vertical sound position offset * * x_s_offset - horizontal sound position offset * * Returns selected channel on success, FALSE on failure */ -/proc/playsound_z(list/z, sound/soundin, volume = 100, vol_cat = VOLUME_SFX, echo, y_s_offset, x_s_offset) +/proc/playsound_z(list/z, sound/soundin, volume = 100, vol_cat = VOLUME_SFX, y_s_offset, x_s_offset) var/datum/sound_template/template = new() if(istype(soundin)) @@ -286,7 +306,6 @@ template.channel = SOUND_CHANNEL_Z template.volume = volume - template.echo = echo template.volume_cat = vol_cat template.x_s_offset = x_s_offset diff --git a/code/modules/client/client_procs.dm b/code/modules/client/client_procs.dm index d69833ec5c..8456b92463 100644 --- a/code/modules/client/client_procs.dm +++ b/code/modules/client/client_procs.dm @@ -464,7 +464,7 @@ GLOBAL_LIST_INIT(whitelisted_client_procs, list( view = world_view_size - SEND_GLOBAL_SIGNAL(COMSIG_GLOB_CLIENT_LOGIN, src) + SEND_GLOBAL_SIGNAL(COMSIG_GLOB_CLIENT_LOGGED_IN, src) ////////////// //DISCONNECT// @@ -820,3 +820,32 @@ GLOBAL_LIST_INIT(whitelisted_client_procs, list( xeno_prefix = "XX" if(!xeno_postfix || xeno_name_ban) xeno_postfix = "" + +/client/verb/action_hide_menu() + set name = "Show/Hide Actions" + set category = "IC" + + var/mob/user = usr + + var/list/actions_list = list() + for(var/datum/action/action as anything in user.actions) + var/action_name = action.name + if(action.player_hidden) + action_name += " (Hidden)" + actions_list[action_name] += action + + if(!LAZYLEN(actions_list)) + to_chat(user, SPAN_WARNING("You have no actions available.")) + return + + var/selected_action_name = tgui_input_list(user, "Show or hide selected action", "Show/Hide Actions", actions_list, 30 SECONDS) + if(!selected_action_name) + to_chat(user, SPAN_WARNING("You did not select an action.")) + return + + var/datum/action/selected_action = actions_list[selected_action_name] + selected_action.player_hidden = !selected_action.player_hidden + user.update_action_buttons() + + if(!selected_action.player_hidden && selected_action.hidden) //Inform the player that even if they are unhiding it, itll still not be visible + to_chat(user, SPAN_NOTICE("[selected_action] is forcefully hidden, bypassing player unhiding.")) diff --git a/code/modules/defenses/sentry_computer.dm b/code/modules/defenses/sentry_computer.dm index bb6f55d72b..7cb4f7bb84 100644 --- a/code/modules/defenses/sentry_computer.dm +++ b/code/modules/defenses/sentry_computer.dm @@ -48,41 +48,18 @@ // Stuff needed to render the map /// asset name for the game map - var/map_name - - /// camera screen which renders the world - var/atom/movable/screen/map_view/cam_screen - - /// camera screen which shows a blank error - var/atom/movable/screen/background/cam_background - - var/list/cam_plane_masters + var/camera_map_name /obj/item/device/sentry_computer/Initialize(mapload) . = ..() if(cell_type) cell = new cell_type() cell.charge = cell.maxcharge - // set up cameras - map_name = "sentry_computer_[REF(src)]_map" - cam_screen = new - cam_screen.name = "screen" - cam_screen.assigned_map = map_name - cam_screen.del_on_map_removal = FALSE - cam_screen.screen_loc = "[map_name]:1,1" - cam_background = new - cam_background.assigned_map = map_name - cam_background.del_on_map_removal = FALSE - - cam_plane_masters = list() - for(var/plane in subtypesof(/atom/movable/screen/plane_master) - /atom/movable/screen/plane_master/blackness) - var/atom/movable/screen/plane_master/instance = new plane() - instance.assigned_map = map_name - instance.del_on_map_removal = FALSE - if(instance.blend_mode_override) - instance.blend_mode = instance.blend_mode_override - instance.screen_loc = "[map_name]:CENTER" - cam_plane_masters += instance + + RegisterSignal(src, COMSIG_CAMERA_MAPNAME_ASSIGNED, PROC_REF(camera_mapname_update)) + + AddComponent(/datum/component/camera_manager) + SEND_SIGNAL(src, COMSIG_CAMERA_CLEAR) faction_group = FACTION_LIST_MARINE transceiver.forceMove(src) @@ -94,16 +71,20 @@ /obj/item/device/sentry_computer/Destroy() . = ..() + UnregisterSignal(src, COMSIG_CAMERA_MAPNAME_ASSIGNED) QDEL_NULL(cell) - QDEL_NULL(cam_background) - QDEL_NULL(cam_screen) QDEL_NULL(transceiver) QDEL_NULL(voice) last_camera_turf = null current = null registered_tools = null + for(var/obj/structure/machinery/defenses/sentry/sentrygun as anything in paired_sentry) + unpair_sentry(sentrygun) paired_sentry = null +/obj/item/device/sentry_computer/proc/camera_mapname_update(source, value) + camera_map_name = value + /obj/item/device/sentry_computer/Move(NewLoc, direct) ..() if(table_setup || open || on) @@ -232,7 +213,7 @@ for(var/key_id in tool.encryption_keys) var/datum/weakref/ref = tool.encryption_keys[key_id] var/obj/item/device/sentry_computer/key_object = ref.resolve() - key_object.registered_tools -= id + key_object?.registered_tools -= id tool.encryption_keys = list() to_chat(user, SPAN_NOTICE("Existing encryption keys cleared.")) to_chat(usr, SPAN_NOTICE("You begin encryption key to \the [tool].")) @@ -321,7 +302,7 @@ if(current == target) current = null - update_active_camera() + SEND_SIGNAL(src, COMSIG_CAMERA_CLEAR) /obj/item/device/sentry_computer/ui_status(mob/user, datum/ui_state/state) . = ..() @@ -332,19 +313,16 @@ /obj/item/device/sentry_computer/ui_close(mob/user) - - // Unregister map objects - user.client.clear_map(map_name) + SEND_SIGNAL(src, COMSIG_CAMERA_UNREGISTER_UI, user) /obj/item/device/sentry_computer/ui_static_data(mob/user) . = list() .["sentry_static"] = list() - .["mapRef"] = map_name + .["mapRef"] = camera_map_name var/index = 1 - for(var/sentry in paired_sentry) + for(var/obj/structure/machinery/defenses/sentry/sentrygun as anything in paired_sentry) var/list/sentry_holder = list() - var/obj/structure/machinery/defenses/sentry/sentrygun = sentry sentry_holder["selection_menu"] = list() sentry_holder["index"] = index sentry_holder["name"] = sentrygun.name @@ -396,13 +374,8 @@ /obj/item/device/sentry_computer/tgui_interact(mob/user, datum/tgui/ui) ui = SStgui.try_update_ui(user, src, ui) - update_active_camera() if (!ui) - // Register map objects - user.client.register_map_obj(cam_background) - user.client.register_map_obj(cam_screen) - for(var/plane in cam_plane_masters) - user.client.register_map_obj(plane) + SEND_SIGNAL(src, COMSIG_CAMERA_REGISTER_UI, user) ui = new(user, src, "SentryGunUI", name) ui.open() @@ -426,7 +399,17 @@ if("set-camera") current = sentry playsound(src, get_sfx("terminal_button"), 25, FALSE) - update_active_camera() + var/obj/structure/machinery/defenses/sentry/defense = sentry + if (defense.has_camera) + defense.set_watched_turfs() + var/list/turf/visible_turfs = defense.watching_turfs + var/list/bbox = get_bbox_of_atoms(visible_turfs) + var/center_x = (bbox[3] + bbox[1]) * 0.5 + var/center_y = (bbox[4] + bbox[2]) * 0.5 + var/size_x = bbox[3] - bbox[1] + 1 + var/size_y = bbox[4] - bbox[2] + 1 + SEND_SIGNAL(src, COMSIG_CAMERA_SET_AREA, center_x, center_y, defense.loc.z, size_x, size_y) + return TRUE if("ping") playsound(sentry, 'sound/machines/twobeep.ogg', 50, 1) @@ -439,54 +422,8 @@ if("clear-camera") current = null playsound(src, get_sfx("terminal_button"), 25, FALSE) - update_active_camera() + SEND_SIGNAL(src, COMSIG_CAMERA_CLEAR) return TRUE if("ui-interact") playsound(src, get_sfx("terminal_button"), 25, FALSE) return FALSE - -/** - * Set the displayed camera to the static not-connected. - */ -/obj/item/device/sentry_computer/proc/show_camera_static() - cam_screen.vis_contents.Cut() - last_camera_turf = null - cam_background.icon_state = "scanline2" - cam_background.fill_rect(1, 1, 15, 15) - -/** - * Update camera settings and redraw camera on the current variable. - */ -/obj/item/device/sentry_computer/proc/update_active_camera() - // Show static if can't use the camera - if(isnull(current) || !current.has_camera || current.placed != 1) - show_camera_static() - return - - // Is this camera located in or attached to a living thing, Vehicle or helmet? If so, assume the camera's loc is the living (or non) thing. - var/cam_location = current - if(isliving(current.loc) || isVehicle(current.loc)) - cam_location = current.loc - else if(istype(current.loc, /obj/item/clothing/head/helmet/marine)) - var/obj/item/clothing/head/helmet/marine/helmet = current.loc - cam_location = helmet.loc - // If we're not forcing an update for some reason and the cameras are in the same location, - // we don't need to update anything. - // Most security cameras will end here as they're not moving. - if(last_camera_turf == get_turf(cam_location)) - return - - // Cameras that get here are moving, and are likely attached to some moving atom such as cyborgs. - last_camera_turf = get_turf(cam_location) - - current.set_watched_turfs() - var/list/turf/visible_turfs = current.watching_turfs - - var/list/bbox = get_bbox_of_atoms(visible_turfs) - var/size_x = bbox[3] - bbox[1] + 1 - var/size_y = bbox[4] - bbox[2] + 1 - cam_screen.icon = null - cam_screen.icon_state = "clear" - cam_screen.vis_contents = visible_turfs - cam_background.icon_state = "clear" - cam_background.fill_rect(1, 1, size_x, size_y) diff --git a/code/modules/escape_menu/escape_menu.dm b/code/modules/escape_menu/escape_menu.dm index c31234678b..b61bbd5b3f 100644 --- a/code/modules/escape_menu/escape_menu.dm +++ b/code/modules/escape_menu/escape_menu.dm @@ -49,7 +49,7 @@ GLOBAL_LIST_EMPTY(escape_menus) show_page() RegisterSignal(client, COMSIG_PARENT_QDELETING, PROC_REF(on_client_qdel)) - RegisterSignal(client, COMSIG_CLIENT_MOB_LOGIN, PROC_REF(on_client_mob_login)) + RegisterSignal(client, COMSIG_CLIENT_MOB_LOGGED_IN, PROC_REF(on_client_mob_login)) if (!isnull(ckey)) GLOB.escape_menus[ckey] = src diff --git a/code/modules/mob/dead/observer/observer.dm b/code/modules/mob/dead/observer/observer.dm index 409c88388f..cf225caadc 100644 --- a/code/modules/mob/dead/observer/observer.dm +++ b/code/modules/mob/dead/observer/observer.dm @@ -32,6 +32,7 @@ plane = GHOST_PLANE layer = ABOVE_FLY_LAYER stat = DEAD + mob_flags = KNOWS_TECHNOLOGY var/adminlarva = FALSE var/ghostvision = TRUE var/can_reenter_corpse @@ -189,37 +190,38 @@ clean_observe_target() /// When the observer target gets a screen, our observer gets a screen minus some game screens we don't want the observer to touch -/mob/dead/observer/proc/observe_target_screen_add(observe_target_mob_client, add_to_screen) +/mob/dead/observer/proc/observe_target_screen_add(observe_target_mob_client, screen_add) SIGNAL_HANDLER - if(!client) - return - - if(istype(add_to_screen, /atom/movable/screen/action_button)) - return - - if(istype(add_to_screen, /atom/movable/screen/fullscreen)) - return + var/static/list/excluded_types = typecacheof(list( + /atom/movable/screen/fullscreen, + /atom/movable/screen/click_catcher, + /atom/movable/screen/escape_menu, + /atom/movable/screen/buildmode, + /obj/effect/detector_blip, + )) - if(istype(add_to_screen, /atom/movable/screen/click_catcher)) + if(!client) return - if(istype(add_to_screen, /atom/movable/screen/escape_menu)) - return + // `screen_add` can sometimes be a list, so it's safest to just handle everything as one. + var/list/stuff_to_add = (islist(screen_add) ? screen_add : list(screen_add)) - if(istype(add_to_screen, /obj/effect/detector_blip)) - return + for(var/item in stuff_to_add) + // Ignore anything that's in `excluded_types`. + if(is_type_in_typecache(item, excluded_types)) + continue - client.add_to_screen(add_to_screen) + client.add_to_screen(screen_add) /// When the observer target loses a screen, our observer loses it as well -/mob/dead/observer/proc/observe_target_screen_remove(observe_target_mob_client, remove_from_screen) +/mob/dead/observer/proc/observe_target_screen_remove(observe_target_mob_client, screen_remove) SIGNAL_HANDLER if(!client) return - client.remove_from_screen(remove_from_screen) + client.remove_from_screen(screen_remove) /// When the observe target ghosts our observer disconnect from their screen updates /mob/dead/observer/proc/observe_target_ghosting(mob/observer_target_mob) @@ -236,8 +238,9 @@ if(observe_target_client != new_client) observe_target_client = new_client - RegisterSignal(observe_target_client, COMSIG_CLIENT_SCREEN_ADD, PROC_REF(observe_target_screen_add)) - RegisterSignal(observe_target_client, COMSIG_CLIENT_SCREEN_REMOVE, PROC_REF(observe_target_screen_remove)) + // Override the signal from any previous targets. + RegisterSignal(observe_target_client, COMSIG_CLIENT_SCREEN_ADD, PROC_REF(observe_target_screen_add), TRUE) + RegisterSignal(observe_target_client, COMSIG_CLIENT_SCREEN_REMOVE, PROC_REF(observe_target_screen_remove), TRUE) /// When the observe target logs in our observer connect to the new client /mob/dead/observer/proc/observe_target_login(mob/living/new_character) @@ -246,8 +249,9 @@ if(observe_target_client != new_character.client) observe_target_client = new_character.client - RegisterSignal(observe_target_client, COMSIG_CLIENT_SCREEN_ADD, PROC_REF(observe_target_screen_add)) - RegisterSignal(observe_target_client, COMSIG_CLIENT_SCREEN_REMOVE, PROC_REF(observe_target_screen_remove)) + // Override the signal from any previous targets. + RegisterSignal(observe_target_client, COMSIG_CLIENT_SCREEN_ADD, PROC_REF(observe_target_screen_add), TRUE) + RegisterSignal(observe_target_client, COMSIG_CLIENT_SCREEN_REMOVE, PROC_REF(observe_target_screen_remove), TRUE) ///makes the ghost see the target hud and sets the eye at the target. /mob/dead/observer/proc/do_observe(atom/movable/target) @@ -257,52 +261,28 @@ ManualFollow(target) reset_perspective() - if(!ishuman(target) || !client.prefs?.auto_observe) + if(!iscarbon(target) || !client.prefs?.auto_observe) return - var/mob/living/carbon/human/human_target = target - - client.eye = human_target - - if(!human_target.hud_used) + var/mob/living/carbon/carbon_target = target + if(!carbon_target.hud_used) return client.clear_screen() - LAZYINITLIST(human_target.observers) - human_target.observers |= src - human_target.hud_used.show_hud(human_target.hud_used.hud_version, src) - - var/list/target_contents = human_target.get_contents() - - //Handles any currently open storage containers the target is looking in when we observe - for(var/obj/item/storage/checked_storage in target_contents) - if(!(human_target in checked_storage.content_watchers)) - continue - - client.add_to_screen(checked_storage.closer) - client.add_to_screen(checked_storage.contents) + client.eye = carbon_target + observe_target_mob = carbon_target - if(checked_storage.storage_slots) - client.add_to_screen(checked_storage.boxes) - else - client.add_to_screen(checked_storage.storage_start) - client.add_to_screen(checked_storage.storage_continue) - client.add_to_screen(checked_storage.storage_end) + carbon_target.auto_observed(src) - break - - observe_target_mob = human_target + RegisterSignal(src, COMSIG_MOVABLE_MOVED, PROC_REF(observer_move_react)) RegisterSignal(observe_target_mob, COMSIG_PARENT_QDELETING, PROC_REF(clean_observe_target)) RegisterSignal(observe_target_mob, COMSIG_MOB_GHOSTIZE, PROC_REF(observe_target_ghosting)) RegisterSignal(observe_target_mob, COMSIG_MOB_NEW_MIND, PROC_REF(observe_target_new_mind)) RegisterSignal(observe_target_mob, COMSIG_MOB_LOGIN, PROC_REF(observe_target_login)) - RegisterSignal(src, COMSIG_MOVABLE_MOVED, PROC_REF(observer_move_react)) - - if(human_target.client) - observe_target_client = human_target.client + if(observe_target_mob.client) + observe_target_client = observe_target_mob.client RegisterSignal(observe_target_client, COMSIG_CLIENT_SCREEN_ADD, PROC_REF(observe_target_screen_add)) RegisterSignal(observe_target_client, COMSIG_CLIENT_SCREEN_REMOVE, PROC_REF(observe_target_screen_remove)) - return /mob/dead/observer/reset_perspective(atom/A) if(observe_target_mob) @@ -620,7 +600,6 @@ This is the proc mobs get to turn into a ghost. Forked from ghostize due to comp return mind.transfer_to(mind.original, TRUE) - SStgui.on_transfer(src, mind.current) qdel(src) return TRUE @@ -758,12 +737,7 @@ This is the proc mobs get to turn into a ghost. Forked from ghostize due to comp if(!tx || !ty || !tz) return following = null - spawn(0) - // To stop the ghost flickering. - x = tx - y = ty - z = tz - sleep(15) + forceMove(locate(tx, ty, tz)) /mob/dead/observer/verb/dead_teleport_mob() //Moves the ghost instead of just changing the ghosts's eye -Nodrak set category = "Ghost" diff --git a/code/modules/mob/living/carbon/carbon.dm b/code/modules/mob/living/carbon/carbon.dm index b63ce0174a..4ea2f35aa6 100644 --- a/code/modules/mob/living/carbon/carbon.dm +++ b/code/modules/mob/living/carbon/carbon.dm @@ -416,6 +416,29 @@
"} show_browser(user, dat, name, "mob[name]") +/** + * Called by [/mob/dead/observer/proc/do_observe] when a carbon mob is observed by a ghost with [/datum/preferences/var/auto_observe] enabled. + * + * Any HUD changes past this point are handled by [/mob/dead/observer/proc/observe_target_screen_add] + * and [/mob/dead/observer/proc/observe_target_screen_remove]. + * + * Override on subtype mobs if they have any extra HUD elements/behaviour. + */ +/mob/living/carbon/proc/auto_observed(mob/dead/observer/observer) + SHOULD_CALL_PARENT(TRUE) + + LAZYINITLIST(observers) + observers |= observer + hud_used.show_hud(hud_used.hud_version, observer) + + // Add the player's action buttons (not the actions themselves) to the observer's screen. + for(var/datum/action/action as anything in actions) + // Skip any hidden ones (of course). + if(action.hidden || action.player_hidden) + continue + + observer.client.add_to_screen(action.button) + //generates realistic-ish pulse output based on preset levels /mob/living/carbon/proc/get_pulse(method) //method 0 is for hands, 1 is for machines, more accurate var/temp = 0 //see setup.dm:694 diff --git a/code/modules/mob/living/carbon/human/human.dm b/code/modules/mob/living/carbon/human/human.dm index dfa646ef80..350bcec3e8 100644 --- a/code/modules/mob/living/carbon/human/human.dm +++ b/code/modules/mob/living/carbon/human/human.dm @@ -313,6 +313,29 @@
"} show_browser(user, dat, name, "mob[name]") +/** + * Handles any storage containers that the human is looking inside when auto-observed. + */ +/mob/living/carbon/human/auto_observed(mob/dead/observer/observer) + . = ..() + + // If `src` doesn't have an inventory open. + if(!s_active) + return + + // Add the storage interface to `observer`'s screen. + observer.client.add_to_screen(s_active.closer) + observer.client.add_to_screen(s_active.contents) + + // If the storage has a set number of item slots. + if(s_active.storage_slots) + observer.client.add_to_screen(s_active.boxes) + // If the storage instead has a maximum combined item 'weight'. + else + observer.client.add_to_screen(s_active.storage_start) + observer.client.add_to_screen(s_active.storage_continue) + observer.client.add_to_screen(s_active.storage_end) + // called when something steps onto a human // this handles mulebots and vehicles /mob/living/carbon/human/Crossed(atom/movable/AM) diff --git a/code/modules/mob/living/carbon/xenomorph/Xenomorph.dm b/code/modules/mob/living/carbon/xenomorph/Xenomorph.dm index a89e2d0444..f27616508d 100644 --- a/code/modules/mob/living/carbon/xenomorph/Xenomorph.dm +++ b/code/modules/mob/living/carbon/xenomorph/Xenomorph.dm @@ -797,6 +797,11 @@ var/datum/mob_hud/MH = huds[MOB_HUD_XENO_INFECTION] MH.add_hud_to(src, src) +// Transfer any observing players over to the xeno's new body (`target`) on evolve/de-evolve. +/mob/living/carbon/xenomorph/transfer_observers_to(atom/target) + for(var/mob/dead/observer/observer as anything in observers) + observer.clean_observe_target() + observer.do_observe(target) /mob/living/carbon/xenomorph/check_improved_pointing() //xeno leaders get a big arrow and less cooldown diff --git a/code/modules/mob/living/init_signals.dm b/code/modules/mob/living/init_signals.dm index a2b92007d9..825fa4dcc9 100644 --- a/code/modules/mob/living/init_signals.dm +++ b/code/modules/mob/living/init_signals.dm @@ -26,6 +26,7 @@ if(stat < UNCONSCIOUS) set_stat(UNCONSCIOUS) sound_environment_override = SOUND_ENVIRONMENT_PSYCHOTIC + client?.soundOutput?.update_mob_environment_override() /// Called when [TRAIT_KNOCKEDOUT] is removed from the mob. /mob/living/proc/on_knockedout_trait_loss(datum/source) @@ -33,6 +34,7 @@ if(stat <= UNCONSCIOUS) update_stat() sound_environment_override = SOUND_ENVIRONMENT_NONE + client?.soundOutput?.update_mob_environment_override() /// Called when [TRAIT_IMMOBILIZED] is added to the mob. /mob/living/proc/on_immobilized_trait_gain(datum/source) diff --git a/code/modules/mob/living/living.dm b/code/modules/mob/living/living.dm index 64c8513108..72fd380e58 100644 --- a/code/modules/mob/living/living.dm +++ b/code/modules/mob/living/living.dm @@ -485,12 +485,10 @@ if(CONSCIOUS) if(stat >= UNCONSCIOUS) ADD_TRAIT(src, TRAIT_IMMOBILIZED, TRAIT_KNOCKEDOUT) - sound_environment_override = SOUND_ENVIRONMENT_PSYCHOTIC add_traits(list(/*TRAIT_HANDS_BLOCKED, */ TRAIT_INCAPACITATED, TRAIT_FLOORED), STAT_TRAIT) if(UNCONSCIOUS) if(stat >= UNCONSCIOUS) ADD_TRAIT(src, TRAIT_IMMOBILIZED, TRAIT_KNOCKEDOUT) //adding trait sources should come before removing to avoid unnecessary updates - sound_environment_override = SOUND_ENVIRONMENT_PSYCHOTIC if(DEAD) SEND_SIGNAL(src, COMSIG_MOB_STAT_SET_ALIVE) // remove_from_dead_mob_list() @@ -500,12 +498,10 @@ if(CONSCIOUS) if(. >= UNCONSCIOUS) REMOVE_TRAIT(src, TRAIT_IMMOBILIZED, TRAIT_KNOCKEDOUT) - sound_environment_override = SOUND_ENVIRONMENT_NONE remove_traits(list(/*TRAIT_HANDS_BLOCKED, */ TRAIT_INCAPACITATED, TRAIT_FLOORED, /*TRAIT_CRITICAL_CONDITION*/), STAT_TRAIT) if(UNCONSCIOUS) if(. >= UNCONSCIOUS) REMOVE_TRAIT(src, TRAIT_IMMOBILIZED, TRAIT_KNOCKEDOUT) - sound_environment_override = SOUND_ENVIRONMENT_NONE if(DEAD) SEND_SIGNAL(src, COMSIG_MOB_STAT_SET_DEAD) // REMOVE_TRAIT(src, TRAIT_CRITICAL_CONDITION, STAT_TRAIT) diff --git a/code/modules/mob/login.dm b/code/modules/mob/login.dm index 775e69dc0b..38157a0673 100644 --- a/code/modules/mob/login.dm +++ b/code/modules/mob/login.dm @@ -18,6 +18,8 @@ update_Login_details() + SEND_SIGNAL(src, COMSIG_MOB_LOGIN) + client.images = null client.screen = null //remove hud items just in case if(!hud_used) @@ -58,6 +60,6 @@ client.init_verbs() - SEND_GLOBAL_SIGNAL(COMSIG_GLOB_MOB_LOGIN, src) - SEND_SIGNAL(client, COMSIG_CLIENT_MOB_LOGIN, src) - SEND_SIGNAL(src, COMSIG_MOB_LOGIN) + SEND_GLOBAL_SIGNAL(COMSIG_GLOB_MOB_LOGGED_IN, src) + SEND_SIGNAL(client, COMSIG_CLIENT_MOB_LOGGED_IN, src) + SEND_SIGNAL(src, COMSIG_MOB_LOGGED_IN) diff --git a/code/modules/mob/mob_defines.dm b/code/modules/mob/mob_defines.dm index f0e5bc48a8..e2f40506b2 100644 --- a/code/modules/mob/mob_defines.dm +++ b/code/modules/mob/mob_defines.dm @@ -28,7 +28,8 @@ I'll make some notes on where certain variable defines should probably go. Changing this around would probably require a good look-over the pre-existing code. */ - var/list/observers //The list of people observing this mob. + /// The list of people observing this mob. + var/list/mob/dead/observer/observers var/zone_selected = "chest" var/use_me = 1 //Allows all mobs to use the me verb by default, will have to manually specify they cannot @@ -433,4 +434,3 @@ return src.regenerate_icons() - diff --git a/code/modules/mob/mob_helpers.dm b/code/modules/mob/mob_helpers.dm index 7bda746325..2664c14a8a 100644 --- a/code/modules/mob/mob_helpers.dm +++ b/code/modules/mob/mob_helpers.dm @@ -584,7 +584,7 @@ var/global/list/limb_types_by_name = list( alert_overlay.layer = FLOAT_LAYER alert_overlay.plane = FLOAT_PLANE - + alert_overlay.underlays.Cut() screen_alert.overlays += alert_overlay /mob/proc/reset_lighting_alpha() diff --git a/code/modules/vehicles/van/van.dm b/code/modules/vehicles/van/van.dm index 0b99d682c0..3dcc603445 100644 --- a/code/modules/vehicles/van/van.dm +++ b/code/modules/vehicles/van/van.dm @@ -82,7 +82,7 @@ icon_state = null - RegisterSignal(SSdcs, COMSIG_GLOB_MOB_LOGIN, PROC_REF(add_default_image)) + RegisterSignal(SSdcs, COMSIG_GLOB_MOB_LOGGED_IN, PROC_REF(add_default_image)) for(var/I in GLOB.player_list) add_default_image(SSdcs, I) @@ -124,7 +124,7 @@ mobs_under += L RegisterSignal(L, COMSIG_PARENT_QDELETING, PROC_REF(remove_under_van)) - RegisterSignal(L, COMSIG_MOB_LOGIN, PROC_REF(add_client)) + RegisterSignal(L, COMSIG_MOB_LOGGED_IN, PROC_REF(add_client)) RegisterSignal(L, COMSIG_MOVABLE_MOVED, PROC_REF(check_under_van)) if(L.client) @@ -140,7 +140,7 @@ UnregisterSignal(L, list( COMSIG_PARENT_QDELETING, - COMSIG_MOB_LOGIN, + COMSIG_MOB_LOGGED_IN, COMSIG_MOVABLE_MOVED, )) diff --git a/colonialmarines.dme b/colonialmarines.dme index 37c2468767..73716cf47f 100644 --- a/colonialmarines.dme +++ b/colonialmarines.dme @@ -136,6 +136,7 @@ #include "code\__DEFINES\dcs\signals\atom\signals_obj.dm" #include "code\__DEFINES\dcs\signals\atom\signals_projectile.dm" #include "code\__DEFINES\dcs\signals\atom\signals_turf.dm" +#include "code\__DEFINES\dcs\signals\atom\mob\signals_mind.dm" #include "code\__DEFINES\dcs\signals\atom\mob\signals_mob.dm" #include "code\__DEFINES\dcs\signals\atom\mob\living\signals_human.dm" #include "code\__DEFINES\dcs\signals\atom\mob\living\signals_living.dm" diff --git a/strings/metatips.txt b/strings/metatips.txt index 17ffd607a7..e0ede9c626 100644 --- a/strings/metatips.txt +++ b/strings/metatips.txt @@ -12,6 +12,7 @@ As a mentor, you can become the imaginary friend of a new player to teach them! You shouldn't ignore what your allies are up to. Sometimes they can be organizing a flank on the radio, sometimes they can be walking up behind you with a buck-loaded shotgun. Either way, it pays to be alert to what they're doing, as much to as what the enemies are. The Wiki (https://cm-ss13.com/wiki) is a very useful repository of information about the game, such as weapons, equipment, xenomorph castes and their strains. It may not be fully up to date much of the time, but the basics are usually accurate. As an observer, you may see how much remaining hijack time is left in the status panel. +As an observer, you can quickly follow someone by ctrl-clicking on their sprite. You can always AdminHelp with the F1 key to question a member of staff regarding rules or game bugs. As ghost you are given extra tools for spectating the round: you can jump and follow specific players, get notifications about CAS and OB strikes, can see all health bars, and such. You can press ESC key to bring up the game pause menu. It allows you change settings, AdminHelp and MentorHelp, and even access the Web Maps of game by clicking at top right.