mirror of
https://github.com/ParadiseSS13/Paradise.git
synced 2026-08-23 12:07:27 +01:00
[PORT] Adds TG "busy" cogbar animation for players (#27932)
* looks like it works * move to PREFTOGGLE_3 and add sneaky do_after * linter * param doc and some cleanup * autodoc and comment signal * fix wrong type in link_processing * fix wrong var in preferences * cover do_mob and do_after_once * fix toggles total * replace indent with space * offset and helpers procs * fix conditional statement * Apply suggestions from code review Co-authored-by: Luc <89928798+lewcc@users.noreply.github.com> Signed-off-by: Mira <42539014+MiraHell@users.noreply.github.com> * Update code/__HELPERS/mob_helpers.dm Co-authored-by: Luc <89928798+lewcc@users.noreply.github.com> Signed-off-by: Mira <42539014+MiraHell@users.noreply.github.com> * use SECONDS * Update code/game/objects/items/weapons/weaponry.dm Co-authored-by: Burzah <116982774+Burzah@users.noreply.github.com> Signed-off-by: Mira <42539014+MiraHell@users.noreply.github.com> --------- Signed-off-by: Mira <42539014+MiraHell@users.noreply.github.com> Co-authored-by: Luc <89928798+lewcc@users.noreply.github.com> Co-authored-by: Burzah <116982774+Burzah@users.noreply.github.com>
This commit is contained in:
@@ -112,6 +112,7 @@
|
||||
#define EMISSIVE_RENDER_TARGET "*EMISSIVE_PLANE"
|
||||
|
||||
#define POINT_PLANE 14
|
||||
#define COGBAR_PLANE 14
|
||||
|
||||
#define LIGHTING_PLANE 15
|
||||
#define LIGHTING_LAYER 15
|
||||
|
||||
@@ -82,11 +82,11 @@
|
||||
|
||||
|
||||
// toggles_3 variables. These MUST be prefixed with PREFTOGGLE_3
|
||||
#define TOGGLES_3_TOTAL 1023 // If you add or remove a preference toggle above, make sure you update this define with the total value of the toggles combined.
|
||||
#define PREFTOGGLE_3_COGBAR_ANIMATIONS (1<<0) // 1
|
||||
|
||||
// When you add a toggle here, inform AA on merge so the column can be zeroed out. This needs to exist to avoid the compiler freaking out
|
||||
// Also update the above value to the actual total
|
||||
#define TOGGLES_3_DEFAULT (1)
|
||||
#define TOGGLES_3_TOTAL 1 // If you add or remove a preference toggle above, make sure you update this define with the total value of the toggles combined.
|
||||
|
||||
#define TOGGLES_3_DEFAULT (PREFTOGGLE_3_COGBAR_ANIMATIONS)
|
||||
|
||||
// Sanity checks
|
||||
// I should really convert these to a JSON list at some point hnnnnnng
|
||||
|
||||
@@ -50,15 +50,16 @@
|
||||
#define INIT_ORDER_PROFILER 101
|
||||
#define INIT_ORDER_QUEUE 100 // Load this quickly so people cant queue skip
|
||||
#define INIT_ORDER_TITLE 99 // Load this quickly so people dont see a blank lobby screen
|
||||
#define INIT_ORDER_GARBAGE 24
|
||||
#define INIT_ORDER_DBCORE 23
|
||||
#define INIT_ORDER_REDIS 22 // Make sure we dont miss any events
|
||||
#define INIT_ORDER_BLACKBOX 21
|
||||
#define INIT_ORDER_CLEANUP 20
|
||||
#define INIT_ORDER_INPUT 19
|
||||
#define INIT_ORDER_SOUNDS 18
|
||||
#define INIT_ORDER_INSTRUMENTS 17
|
||||
#define INIT_ORDER_RESEARCH 16 // SoonTM
|
||||
#define INIT_ORDER_GARBAGE 25
|
||||
#define INIT_ORDER_DBCORE 24
|
||||
#define INIT_ORDER_REDIS 23 // Make sure we dont miss any events
|
||||
#define INIT_ORDER_BLACKBOX 22
|
||||
#define INIT_ORDER_CLEANUP 21
|
||||
#define INIT_ORDER_INPUT 20
|
||||
#define INIT_ORDER_SOUNDS 19
|
||||
#define INIT_ORDER_INSTRUMENTS 18
|
||||
#define INIT_ORDER_RESEARCH 17 // SoonTM
|
||||
#define INIT_ORDER_VIS 16
|
||||
#define INIT_ORDER_STATION 15 //This is high priority because it manipulates a lot of the subsystems that will initialize after it.
|
||||
#define INIT_ORDER_EVENTS 14
|
||||
#define INIT_ORDER_JOBS 13
|
||||
@@ -100,6 +101,7 @@
|
||||
#define FIRE_PRIORITY_TICKETS 10
|
||||
#define FIRE_PRIORITY_RESEARCH 10 // SoonTM
|
||||
#define FIRE_PRIORITY_AMBIENCE 10
|
||||
#define FIRE_PRIORITY_VIS 10
|
||||
#define FIRE_PRIORITY_GARBAGE 15
|
||||
#define FIRE_PRIORITY_AIR 20
|
||||
#define FIRE_PRIORITY_NPC 20
|
||||
|
||||
@@ -529,6 +529,25 @@ GLOBAL_LIST_EMPTY(bicon_cache)
|
||||
var/icon/I = getFlatIcon(thing)
|
||||
return icon2asset(I, target)
|
||||
|
||||
/// Returns a list containing the width and height of an icon file
|
||||
/proc/get_icon_dimensions(icon_path)
|
||||
if(isnull(GLOB.icon_dimensions[icon_path]))
|
||||
var/icon/my_icon = icon(icon_path)
|
||||
GLOB.icon_dimensions[icon_path] = list("width" = my_icon.Width(), "height" = my_icon.Height())
|
||||
return GLOB.icon_dimensions[icon_path]
|
||||
|
||||
/// Returns an x and y value require to reverse the transformations made to center an oversized icon
|
||||
/atom/proc/get_oversized_icon_offsets()
|
||||
if(pixel_x == 0 && pixel_y == 0)
|
||||
return list("x" = 0, "y" = 0)
|
||||
var/list/icon_dimensions = get_icon_dimensions(icon)
|
||||
var/icon_width = icon_dimensions["width"]
|
||||
var/icon_height = icon_dimensions["height"]
|
||||
return list(
|
||||
"x" = icon_width > world.icon_size && pixel_x != 0 ? (icon_width - world.icon_size) * 0.5 : 0,
|
||||
"y" = icon_height > world.icon_size && pixel_y != 0 ? (icon_height - world.icon_size) * 0.5 : 0,
|
||||
)
|
||||
|
||||
/// Slimifies an icon by painting a color onto the icon, then changing the alpha.
|
||||
/icon/proc/slimify(color = "#FFFFFF", alpha = "FF")
|
||||
GrayScale()
|
||||
|
||||
@@ -330,7 +330,7 @@
|
||||
|
||||
msg_admin_attack("[key_name_admin(user)] vs [target_info]: [what_done]", loglevel)
|
||||
|
||||
/proc/do_mob(mob/user, mob/target, time = 30, progress = 1, list/extra_checks = list(), only_use_extra_checks = FALSE, requires_upright = TRUE)
|
||||
/proc/do_mob(mob/user, mob/target, time = 30, progress = 1, list/extra_checks = list(), only_use_extra_checks = FALSE, requires_upright = TRUE, hidden = FALSE)
|
||||
if(!user || !target)
|
||||
return 0
|
||||
var/user_loc = user.loc
|
||||
@@ -343,9 +343,13 @@
|
||||
|
||||
var/holding = user.get_active_hand()
|
||||
var/datum/progressbar/progbar
|
||||
var/datum/cogbar/cog
|
||||
if(progress)
|
||||
progbar = new(user, time, target)
|
||||
|
||||
if(!hidden && time >= 1 SECONDS)
|
||||
cog = new(user)
|
||||
|
||||
var/endtime = world.time+time
|
||||
var/starttime = world.time
|
||||
. = 1
|
||||
@@ -376,6 +380,7 @@
|
||||
break
|
||||
if(progress)
|
||||
qdel(progbar)
|
||||
cog?.remove()
|
||||
|
||||
/* Use this proc when you want to have code under it execute after a delay, and ensure certain conditions are met during that delay...
|
||||
* Such as the user not being interrupted via getting stunned or by moving off the tile they're currently on.
|
||||
@@ -387,8 +392,9 @@
|
||||
*
|
||||
* This will create progress bar that lasts for 5 seconds. If the user doesn't move or otherwise do something that would cause the checks to fail in those 5 seconds, do_stuff() would execute.
|
||||
* The Proc returns TRUE upon success (the progress bar reached the end), or FALSE upon failure (the user moved or some other check failed)
|
||||
* param {boolean} hidden - By default, any action 1 second or longer shows a cog over the user while it is in progress. If hidden is set to TRUE, the cog will not be shown.
|
||||
*/
|
||||
/proc/do_after(mob/user, delay, needhand = 1, atom/target = null, progress = 1, allow_moving = 0, must_be_held = 0, list/extra_checks = list(), use_default_checks = TRUE, allow_moving_target = FALSE)
|
||||
/proc/do_after(mob/user, delay, needhand = 1, atom/target = null, progress = 1, allow_moving = 0, must_be_held = 0, list/extra_checks = list(), use_default_checks = TRUE, allow_moving_target = FALSE, hidden = FALSE)
|
||||
if(!user)
|
||||
return FALSE
|
||||
var/atom/Tloc = null
|
||||
@@ -408,9 +414,13 @@
|
||||
holdingnull = FALSE //Users hand started holding something, check to see if it's still holding that
|
||||
|
||||
var/datum/progressbar/progbar
|
||||
var/datum/cogbar/cog
|
||||
if(progress)
|
||||
progbar = new(user, delay, target)
|
||||
|
||||
if(!hidden && delay >= 1 SECONDS)
|
||||
cog = new(user)
|
||||
|
||||
var/endtime = world.time + delay
|
||||
var/starttime = world.time
|
||||
. = TRUE
|
||||
@@ -457,6 +467,7 @@
|
||||
break
|
||||
if(progress)
|
||||
qdel(progbar)
|
||||
cog?.remove()
|
||||
|
||||
// Upon any of the callbacks in the list returning TRUE, the proc will return TRUE.
|
||||
/proc/check_for_true_callbacks(list/extra_checks)
|
||||
@@ -467,7 +478,7 @@
|
||||
|
||||
#define DOAFTERONCE_MAGIC "Magic~~"
|
||||
GLOBAL_LIST_EMPTY(do_after_once_tracker)
|
||||
/proc/do_after_once(mob/user, delay, needhand = 1, atom/target = null, progress = 1, allow_moving, must_be_held, attempt_cancel_message = "Attempt cancelled.", special_identifier)
|
||||
/proc/do_after_once(mob/user, delay, needhand = 1, atom/target = null, progress = 1, allow_moving, must_be_held, attempt_cancel_message = "Attempt cancelled.", special_identifier, hidden = FALSE)
|
||||
if(!user || !target)
|
||||
return
|
||||
|
||||
@@ -477,7 +488,7 @@ GLOBAL_LIST_EMPTY(do_after_once_tracker)
|
||||
to_chat(user, "<span class='warning'>[attempt_cancel_message]</span>")
|
||||
return FALSE
|
||||
GLOB.do_after_once_tracker[cache_key] = TRUE
|
||||
. = do_after(user, delay, needhand, target, progress, allow_moving, must_be_held, extra_checks = list(CALLBACK(GLOBAL_PROC, GLOBAL_PROC_REF(do_after_once_checks), cache_key)))
|
||||
. = do_after(user, delay, needhand, target, progress, allow_moving, must_be_held, extra_checks = list(CALLBACK(GLOBAL_PROC, GLOBAL_PROC_REF(do_after_once_checks), cache_key, hidden)))
|
||||
GLOB.do_after_once_tracker[cache_key] = FALSE
|
||||
|
||||
/proc/do_after_once_checks(cache_key)
|
||||
|
||||
@@ -0,0 +1,2 @@
|
||||
/// Cache of the width and height of icon files, to avoid repeating the same expensive operation
|
||||
GLOBAL_LIST_EMPTY(icon_dimensions)
|
||||
@@ -61,6 +61,16 @@
|
||||
if(istype(mymob) && mymob.client && mymob.client.prefs)
|
||||
alpha = (mymob.client.prefs.toggles2 & PREFTOGGLE_2_THOUGHT_BUBBLE) ? 255 : 0
|
||||
|
||||
/atom/movable/screen/plane_master/cogbar
|
||||
name = "cogbar plane master"
|
||||
plane = COGBAR_PLANE
|
||||
appearance_flags = PLANE_MASTER //should use client color
|
||||
blend_mode = BLEND_OVERLAY
|
||||
|
||||
/atom/movable/screen/plane_master/cogbar/backdrop(mob/mymob)
|
||||
if(istype(mymob) && mymob.client?.prefs)
|
||||
alpha = (mymob.client.prefs.toggles3 & PREFTOGGLE_3_COGBAR_ANIMATIONS) ? 255 : 0
|
||||
|
||||
/**
|
||||
* Things placed on this mask the lighting plane. Doesn't render directly.
|
||||
*
|
||||
|
||||
@@ -0,0 +1,130 @@
|
||||
/**
|
||||
* # SSvis_overlays
|
||||
*
|
||||
* This subsystem handles visual overlays for objects in the game world.
|
||||
*
|
||||
* It manages the creation, caching, and removal of visual overlays, allowing for dynamic visual effects
|
||||
* associated with various atoms. Overlays can be reused if they are not unique, and they are automatically
|
||||
* cleaned up if they go unused for a specified duration.
|
||||
*/
|
||||
SUBSYSTEM_DEF(vis_overlays)
|
||||
name = "Vis contents overlays"
|
||||
wait = 1 MINUTES
|
||||
priority = FIRE_PRIORITY_VIS
|
||||
init_order = INIT_ORDER_VIS
|
||||
|
||||
/// Cache for visual overlays
|
||||
var/list/vis_overlay_cache
|
||||
/// List of currently processed overlays during a run
|
||||
var/list/currentrun
|
||||
|
||||
/datum/controller/subsystem/vis_overlays/Initialize()
|
||||
vis_overlay_cache = list()
|
||||
|
||||
/datum/controller/subsystem/vis_overlays/fire(resumed = FALSE)
|
||||
if(!resumed)
|
||||
currentrun = vis_overlay_cache.Copy()
|
||||
var/list/current_run = currentrun
|
||||
|
||||
while(length(current_run))
|
||||
var/key = current_run[current_run.len]
|
||||
var/obj/effect/overlay/vis/overlay = current_run[key]
|
||||
current_run.len--
|
||||
if(!overlay.unused && !length(overlay.vis_locs))
|
||||
overlay.unused = world.time
|
||||
else if(overlay.unused && overlay.unused + overlay.cache_expiration < world.time)
|
||||
vis_overlay_cache -= key
|
||||
qdel(overlay)
|
||||
if(MC_TICK_CHECK)
|
||||
return
|
||||
|
||||
/**
|
||||
* Adds a visual overlay to a given atom.
|
||||
*
|
||||
* This procedure creates and adds a visual overlay to the specified object. It can either create a unique
|
||||
* overlay or reuse an existing one based on the provided parameters.
|
||||
*
|
||||
* Arguments:
|
||||
* * thing - The atom to which the overlay will be added. The "thing" var can be anything with vis_contents which includes images
|
||||
* * icon - The icon to display for the overlay.
|
||||
* * iconstate - The state of the icon.
|
||||
* * layer - The layer on which the overlay will be rendered.
|
||||
* * plane - The plane for the overlay.
|
||||
* * dir - The direction the overlay faces.
|
||||
* * alpha - The transparency level of the overlay (default is 255).
|
||||
* * add_appearance_flags - Additional flags for overlay appearance (default is NONE).
|
||||
* * unique - A boolean indicating if the overlay should be unique (default is FALSE).
|
||||
*
|
||||
* Returns the overlay that was added.
|
||||
*/
|
||||
/datum/controller/subsystem/vis_overlays/proc/add_vis_overlay(atom/movable/thing, icon, iconstate, layer, plane, dir, alpha = 255, add_appearance_flags = NONE, unique = FALSE)
|
||||
var/obj/effect/overlay/vis/overlay
|
||||
if(!unique)
|
||||
. = "[icon]|[iconstate]|[layer]|[plane]|[dir]|[alpha]|[add_appearance_flags]"
|
||||
overlay = vis_overlay_cache[.]
|
||||
if(!overlay)
|
||||
overlay = _create_new_vis_overlay(icon, iconstate, layer, plane, dir, alpha, add_appearance_flags)
|
||||
vis_overlay_cache[.] = overlay
|
||||
else
|
||||
overlay.unused = 0
|
||||
else
|
||||
overlay = _create_new_vis_overlay(icon, iconstate, layer, plane, dir, alpha, add_appearance_flags)
|
||||
overlay.cache_expiration = -1
|
||||
var/cache_id = "[text_ref(overlay)]@{[world.time]}"
|
||||
vis_overlay_cache[cache_id] = overlay
|
||||
. = overlay
|
||||
thing.vis_contents += overlay
|
||||
|
||||
if(!isatom(thing)) // Automatic rotation is not supported on non atoms
|
||||
return overlay
|
||||
|
||||
if(!thing.managed_vis_overlays)
|
||||
thing.managed_vis_overlays = list(overlay)
|
||||
else
|
||||
thing.managed_vis_overlays += overlay
|
||||
return overlay
|
||||
|
||||
/**
|
||||
* Creates a new visual overlay with the specified parameters.
|
||||
*
|
||||
* This procedure initializes a new visual overlay object with the given attributes.
|
||||
*
|
||||
* Arguments:
|
||||
* * icon - The icon to display for the overlay.
|
||||
* * iconstate - The state of the icon.
|
||||
* * layer - The layer on which the overlay will be rendered.
|
||||
* * plane - The plane for the overlay.
|
||||
* * dir - The direction the overlay faces.
|
||||
* * alpha - The transparency level of the overlay.
|
||||
* * add_appearance_flags - Additional flags for overlay appearance.
|
||||
*
|
||||
* Returns the newly created overlay.
|
||||
*/
|
||||
/datum/controller/subsystem/vis_overlays/proc/_create_new_vis_overlay(icon, iconstate, layer, plane, dir, alpha, add_appearance_flags)
|
||||
var/obj/effect/overlay/vis/overlay = new
|
||||
overlay.icon = icon
|
||||
overlay.icon_state = iconstate
|
||||
overlay.layer = layer
|
||||
overlay.plane = plane
|
||||
overlay.dir = dir
|
||||
overlay.alpha = alpha
|
||||
overlay.appearance_flags |= add_appearance_flags
|
||||
return overlay
|
||||
|
||||
/**
|
||||
* Removes specified visual overlays from an atom.
|
||||
*
|
||||
* This procedure removes the given overlays from the atom's visual contents and also updates the
|
||||
* managed overlays list if applicable.
|
||||
*
|
||||
* Arguments:
|
||||
* * thing - The atom from which the overlays will be removed.
|
||||
* * overlays - A list of overlays to remove.
|
||||
*/
|
||||
/datum/controller/subsystem/vis_overlays/proc/remove_vis_overlay(atom/movable/thing, list/overlays)
|
||||
thing.vis_contents -= overlays
|
||||
if(!isatom(thing))
|
||||
return
|
||||
thing.managed_vis_overlays -= overlays
|
||||
if(!length(thing.managed_vis_overlays))
|
||||
thing.managed_vis_overlays = null
|
||||
@@ -0,0 +1,119 @@
|
||||
#define COGBAR_ANIMATION_TIME (0.5 SECONDS)
|
||||
|
||||
/**
|
||||
* # Cogbar
|
||||
* Represents that the user is busy doing something.
|
||||
*
|
||||
* The cogbar is a visual representation in the game that indicates to other players
|
||||
* that a user is currently busy with an action. This class handles the creation,
|
||||
* display, and removal of the cog animation.
|
||||
*/
|
||||
/datum/cogbar
|
||||
/// Who's doing the thing
|
||||
var/mob/user
|
||||
/// The user client
|
||||
var/client/user_client
|
||||
/// The visible element to other players
|
||||
var/obj/effect/overlay/vis/cog
|
||||
/// The blank image that overlaps the cog - hides it from the source user
|
||||
var/image/blank
|
||||
/// The offset of the icon
|
||||
var/offset_y
|
||||
|
||||
// Class constructor
|
||||
/**
|
||||
* Initializes a new instance of the cogbar for the specified user.
|
||||
*
|
||||
* This constructor sets up the user and user client properties, adds the cog overlay
|
||||
* to the user, and registers a signal to handle user deletion.
|
||||
*
|
||||
* @param user - The user for whom the cogbar is created.
|
||||
*/
|
||||
/datum/cogbar/New(mob/user)
|
||||
src.user = user
|
||||
src.user_client = user.client
|
||||
|
||||
var/list/icon_offsets = user.get_oversized_icon_offsets()
|
||||
offset_y = icon_offsets["y"]
|
||||
|
||||
add_cog_to_user()
|
||||
|
||||
RegisterSignal(user, COMSIG_PARENT_QDELETING, PROC_REF(on_user_delete))
|
||||
|
||||
// Destructor
|
||||
/**
|
||||
* Cleans up the cogbar instance, removing overlays and images associated with the user.
|
||||
*
|
||||
* This method ensures that all visual elements are properly removed when the cogbar instance is destroyed
|
||||
*/
|
||||
/datum/cogbar/Destroy()
|
||||
if(user)
|
||||
SSvis_overlays.remove_vis_overlay(user, user.managed_vis_overlays)
|
||||
user_client?.images -= blank
|
||||
|
||||
user = null
|
||||
user_client = null
|
||||
cog = null
|
||||
QDEL_NULL(blank)
|
||||
|
||||
return ..()
|
||||
|
||||
/// Adds the cog to the user, visible by other players
|
||||
/**
|
||||
* Adds the cog overlay to the user, making it visible to other players.
|
||||
*
|
||||
* This function creates the cog overlay with appropriate properties and
|
||||
* initiates the animation to fade it in. Additionally, a blank image is
|
||||
* added to the user's client to hide the cog from the user's own perspective.
|
||||
*/
|
||||
/datum/cogbar/proc/add_cog_to_user()
|
||||
cog = SSvis_overlays.add_vis_overlay(user,
|
||||
icon = 'icons/effects/progressbar.dmi',
|
||||
iconstate = "cog",
|
||||
plane = COGBAR_PLANE,
|
||||
add_appearance_flags = APPEARANCE_UI_IGNORE_ALPHA,
|
||||
unique = TRUE,
|
||||
alpha = 0,
|
||||
)
|
||||
|
||||
cog.pixel_y = world.icon_size + offset_y
|
||||
animate(cog, alpha = 255, time = COGBAR_ANIMATION_TIME)
|
||||
|
||||
if(isnull(user_client))
|
||||
return
|
||||
|
||||
blank = image('icons/blanks/32x32.dmi', cog, "nothing")
|
||||
blank.plane = HUD_PLANE
|
||||
blank.appearance_flags = APPEARANCE_UI_IGNORE_ALPHA
|
||||
blank.override = TRUE
|
||||
|
||||
user_client.images += blank
|
||||
|
||||
/// Removes the cog from the user
|
||||
/**
|
||||
* Initiates the removal process for the cog overlay.
|
||||
*
|
||||
* This function fades out the cog overlay and schedules the cogbar instance
|
||||
* for deletion after the animation completes.
|
||||
*/
|
||||
/datum/cogbar/proc/remove()
|
||||
if(isnull(cog))
|
||||
qdel(src)
|
||||
return
|
||||
|
||||
animate(cog, alpha = 0, time = COGBAR_ANIMATION_TIME)
|
||||
|
||||
QDEL_IN(src, COGBAR_ANIMATION_TIME)
|
||||
|
||||
/// When the user is deleted, remove the cog
|
||||
/**
|
||||
* Handles the cleanup when the associated user is deleted.
|
||||
*
|
||||
* This function is triggered by a signal and ensures that the cogbar instance is properly destroyed
|
||||
*/
|
||||
/datum/cogbar/proc/on_user_delete(datum/source)
|
||||
SIGNAL_HANDLER // COMSIG_PARENT_QDELETING
|
||||
|
||||
qdel(src)
|
||||
|
||||
#undef COGBAR_ANIMATION_TIME
|
||||
@@ -14,7 +14,7 @@
|
||||
EXCEPTION("Invalid target given")
|
||||
if(goal_number)
|
||||
goal = goal_number
|
||||
bar = image('icons/effects/progessbar.dmi', target, "prog_bar_0", ABOVE_HUD_LAYER)
|
||||
bar = image('icons/effects/progressbar.dmi', target, "prog_bar_0", ABOVE_HUD_LAYER)
|
||||
bar.alpha = 0
|
||||
bar.plane = ABOVE_HUD_PLANE
|
||||
bar.appearance_flags = APPEARANCE_UI_IGNORE_ALPHA
|
||||
|
||||
@@ -42,6 +42,9 @@
|
||||
/// Value used to increment ex_act() if reactionary_explosions is on
|
||||
var/explosion_block = 0
|
||||
|
||||
///vis overlays managed by SSvis_overlays to automaticaly turn them like other overlays.
|
||||
var/list/managed_vis_overlays
|
||||
|
||||
// Detective Work, used for the duplicate data points kept in the scanners
|
||||
var/list/original_atom
|
||||
/// List of fibers that this atom has
|
||||
|
||||
@@ -865,7 +865,7 @@
|
||||
user.playsound_local(user, "sparks", 50, FALSE, use_reverb = FALSE)
|
||||
adjust_uses(-1, user)
|
||||
robot_target.audible_message("<span class='italics'>You hear a loud electrical buzzing sound coming from [robot_target]!</span>")
|
||||
if(!do_mob(user, robot_target, 10 SECONDS))
|
||||
if(!do_mob(user, robot_target, 10 SECONDS, hidden = TRUE))
|
||||
is_active = FALSE
|
||||
return
|
||||
is_active = FALSE
|
||||
|
||||
@@ -229,7 +229,7 @@
|
||||
if(!occupant)
|
||||
return
|
||||
to_chat(occupant, "<span class='warning'>You start trying to break free!</span>")
|
||||
if(!do_after_once(occupant, 20 SECONDS, FALSE, src))
|
||||
if(!do_after_once(occupant, 20 SECONDS, FALSE, src, hidden = TRUE))
|
||||
return
|
||||
var/list/possible_results = list(
|
||||
CALLBACK(src, PROC_REF(electrocute_abductee)) = 1,
|
||||
|
||||
@@ -68,3 +68,12 @@
|
||||
layer = FLOAT_LAYER
|
||||
vis_flags = VIS_INHERIT_ID
|
||||
appearance_flags = KEEP_TOGETHER | LONG_GLIDE | PIXEL_SCALE
|
||||
|
||||
/obj/effect/overlay/vis
|
||||
mouse_opacity = MOUSE_OPACITY_TRANSPARENT
|
||||
anchored = TRUE
|
||||
vis_flags = VIS_INHERIT_DIR
|
||||
///When detected to be unused it gets set to world.time, after a while it gets removed
|
||||
var/unused = 0
|
||||
///overlays which go unused for this amount of time get cleaned up
|
||||
var/cache_expiration = 2 MINUTES
|
||||
|
||||
@@ -392,7 +392,7 @@
|
||||
to_chat(user, "<span class='danger'>The mind batterer has been burnt out!</span>")
|
||||
times_used--
|
||||
return
|
||||
if(!do_after_once(user, 2 SECONDS, target = src, allow_moving = TRUE, attempt_cancel_message = "You think it's best to save this for later."))
|
||||
if(!do_after_once(user, 2 SECONDS, target = src, allow_moving = TRUE, attempt_cancel_message = "You think it's best to save this for later.", hidden = TRUE))
|
||||
times_used--
|
||||
return
|
||||
to_chat(user, "<span class='notice'>You trigger [src]. It has [max_uses-times_used] charges left.</span>")
|
||||
|
||||
@@ -12,7 +12,7 @@
|
||||
user.visible_message("<span class='warning'>[user] attempts to [break_cuffs ? "break" : "remove"] [src]!</span>", "<span class='notice'>You attempt to [break_cuffs ? "break" : "remove"] [src]...</span>")
|
||||
to_chat(user, "<span class='notice'>(This will take around [DisplayTimeText(effective_breakout_time)] and you need to stand still.)</span>")
|
||||
|
||||
if(!do_after(user, effective_breakout_time, FALSE, user))
|
||||
if(!do_after(user, effective_breakout_time, FALSE, user, hidden = TRUE))
|
||||
user.remove_status_effect(STATUS_EFFECT_REMOVE_CUFFS)
|
||||
to_chat(user, "<span class='warning'>You fail to [break_cuffs ? "break" : "remove"] [src]!</span>")
|
||||
return
|
||||
|
||||
@@ -224,7 +224,7 @@
|
||||
L.update_inv_l_hand()
|
||||
spinning = TRUE
|
||||
for(var/i in 1 to max_spins)
|
||||
if(!do_mob(L, L, 1 SECONDS, only_use_extra_checks = TRUE, extra_checks = list(CALLBACK(src, PROC_REF(can_spin_check), L))))
|
||||
if(!do_mob(L, L, 1 SECONDS, only_use_extra_checks = TRUE, extra_checks = list(CALLBACK(src, PROC_REF(can_spin_check), L)), hidden = TRUE))
|
||||
reset_values(L)
|
||||
break
|
||||
throw_range += range_increment
|
||||
|
||||
@@ -258,7 +258,7 @@
|
||||
return ..()
|
||||
to_chat(user, "<span class='warning'>You begin gathering strength...</span>")
|
||||
playsound(get_turf(src), 'sound/magic/lightning_chargeup.ogg', 65, 1)
|
||||
if(do_after(user, 90, target = user))
|
||||
if(do_after(user, 9 SECONDS, target = user, hidden = TRUE))
|
||||
to_chat(user, "<span class='userdanger'>You gather power! Time for a home run!</span>")
|
||||
homerun_ready = 1
|
||||
..()
|
||||
|
||||
@@ -154,7 +154,7 @@
|
||||
"<span class='notice'>You struggle to break free from [src], exacerbating your wounds! (Stay still for two minutes.)</span>",\
|
||||
"<span class='italics'>You hear a wet squishing noise..</span>")
|
||||
M.adjustBruteLoss(30)
|
||||
if(!do_after(M, 2 MINUTES, target = src))
|
||||
if(!do_after(M, 2 MINUTES, target = src, hidden = TRUE))
|
||||
if(M && M.buckled)
|
||||
to_chat(M, "<span class='warning'>You fail to free yourself!</span>")
|
||||
return
|
||||
|
||||
@@ -101,7 +101,7 @@ GLOBAL_LIST_EMPTY(safes)
|
||||
if(!drill_timer)
|
||||
return
|
||||
cut_overlay(progress_bar)
|
||||
progress_bar = image('icons/effects/progessbar.dmi', src, "prog_bar_[round((((world.time - drill_start_time) / time_to_drill) * 100), 5)]", HUD_LAYER)
|
||||
progress_bar = image('icons/effects/progressbar.dmi', src, "prog_bar_[round((((world.time - drill_start_time) / time_to_drill) * 100), 5)]", HUD_LAYER)
|
||||
add_overlay(progress_bar)
|
||||
if(prob(DRILL_SPARK_CHANCE))
|
||||
drill.spark_system.start()
|
||||
|
||||
@@ -33,7 +33,7 @@
|
||||
M.visible_message("<span class='warning'>[M.name] struggles to break free from the gelatinous resin!</span>",\
|
||||
"<span class='notice'>You struggle to break free from the gelatinous resin... (Stay still for two minutes.)</span>",\
|
||||
"<span class='italics'>You hear squelching...</span>")
|
||||
if(!do_after(M, 120 SECONDS, target = src))
|
||||
if(!do_after(M, 120 SECONDS, target = src, hidden = TRUE))
|
||||
if(M && M.buckled)
|
||||
to_chat(M, "<span class='warning'>You fail to escape \the [src]!</span>")
|
||||
return
|
||||
|
||||
@@ -27,7 +27,7 @@
|
||||
is_operating = FALSE
|
||||
return FALSE
|
||||
user.visible_message("<span class='danger'>[user] begins vomiting an arachnid!</span>")
|
||||
if(do_after(user, 4 SECONDS, FALSE, target = user)) // Takes 4 seconds to spawn a spider
|
||||
if(do_after(user, 4 SECONDS, FALSE, target = user, hidden = TRUE)) // Takes 4 seconds to spawn a spider
|
||||
spider_counter++
|
||||
user.visible_message("<span class='danger'>[user] vomits up an arachnid!</span>")
|
||||
var/mob/living/simple_animal/hostile/poison/giant_spider/hunter/infestation_spider/S = new(user.loc)
|
||||
|
||||
@@ -134,7 +134,7 @@
|
||||
"<span class='sinister'>We begin our harvest on [H].</span>",
|
||||
"<span class='notice'>You hear the hum of electricity.</span>"
|
||||
)
|
||||
if(!do_mob(owner.current, H, time = 2 SECONDS))
|
||||
if(!do_mob(owner.current, H, time = 2 SECONDS, hidden = TRUE))
|
||||
send_swarm_message("Our connection was incomplete.")
|
||||
harvesting = null
|
||||
return
|
||||
|
||||
@@ -201,7 +201,7 @@
|
||||
to_chat(user, "<span class='notice'>Your override attempt fails before it can even begin.</span>")
|
||||
qdel(src)
|
||||
return
|
||||
if(!do_mob(user, borg, conversion_time))
|
||||
if(!do_mob(user, borg, conversion_time, hidden = TRUE))
|
||||
to_chat(user, "<span class='notice'>Your concentration breaks.</span>")
|
||||
qdel(src)
|
||||
return
|
||||
|
||||
@@ -253,7 +253,7 @@
|
||||
|
||||
M.visible_message("<span class='notice'>[M] starts entering a cryptic series of characters on [U].</span>",\
|
||||
"<span class='notice'>You start entering an extraction signal to your handlers on [U]...</span>")
|
||||
if(do_after(M, EXTRACTION_PHASE_PREPARE, target = M))
|
||||
if(do_after(M, EXTRACTION_PHASE_PREPARE, target = M, hidden = TRUE))
|
||||
if(!U.Adjacent(M) || extraction_deadline > world.time)
|
||||
return
|
||||
var/obj/effect/contractor_flare/F = new(get_turf(M))
|
||||
|
||||
@@ -113,7 +113,7 @@ RESTRICT_TYPE(/datum/antagonist/vampire)
|
||||
H.LAssailant = null
|
||||
else
|
||||
H.LAssailant = owner
|
||||
while(do_mob(owner.current, H, suck_rate))
|
||||
while(do_mob(owner.current, H, suck_rate, hidden = TRUE))
|
||||
owner.current.do_attack_animation(H, ATTACK_EFFECT_BITE)
|
||||
if(unique_suck_id in drained_humans)
|
||||
if(drained_humans[unique_suck_id] >= BLOOD_DRAIN_LIMIT)
|
||||
|
||||
@@ -28,7 +28,7 @@
|
||||
var/mob/living/target = targets[1]
|
||||
user.visible_message("<span class='warning'>[user] bites [target]'s neck!</span>", "<span class='warning'>You bite [target]'s neck and begin the flow of power.</span>")
|
||||
to_chat(target, "<span class='warning'>You feel the tendrils of evil invade your mind.</span>")
|
||||
if(do_mob(user, target, 15 SECONDS))
|
||||
if(do_mob(user, target, 15 SECONDS, hidden = TRUE))
|
||||
if(can_enthrall(user, target))
|
||||
handle_enthrall(user, target)
|
||||
var/datum/spell_handler/vampire/V = custom_handler
|
||||
|
||||
@@ -140,7 +140,7 @@
|
||||
if(!making_anchor && !anchor) // first cast, setup the anchor
|
||||
var/turf/anchor_turf = get_turf(user)
|
||||
making_anchor = TRUE
|
||||
if(do_mob(user, user, 5 SECONDS, only_use_extra_checks = TRUE)) // no checks, cant fail
|
||||
if(do_mob(user, user, 5 SECONDS, only_use_extra_checks = TRUE, hidden = TRUE)) // no checks, cant fail
|
||||
make_anchor(user, anchor_turf)
|
||||
making_anchor = FALSE
|
||||
return
|
||||
|
||||
@@ -1011,6 +1011,12 @@
|
||||
var/atom/movable/screen/plane_master/point/PM = locate(/atom/movable/screen/plane_master/point) in parent.screen
|
||||
PM.backdrop(parent.mob)
|
||||
|
||||
if("cogbar")
|
||||
toggles3 ^= PREFTOGGLE_3_COGBAR_ANIMATIONS
|
||||
if(length(parent?.screen))
|
||||
var/atom/movable/screen/plane_master/cogbar/PM = locate(/atom/movable/screen/plane_master/cogbar) in parent.screen
|
||||
PM.backdrop(parent.mob)
|
||||
|
||||
if("be_special")
|
||||
var/r = href_list["role"]
|
||||
if(r in GLOB.special_roles)
|
||||
|
||||
@@ -481,6 +481,7 @@ GLOBAL_LIST_INIT(special_role_times, list(
|
||||
dat += "<b>Set screentip mode:</b> <a href='byond://?_src_=prefs;preference=screentip_mode'>[(screentip_mode == 0) ? "Disabled" : "[screentip_mode]px"]</a><br>"
|
||||
dat += "<b>Screentip color:</b> <span style='border: 1px solid #161616; background-color: [screentip_color];'> </span> <a href='byond://?_src_=prefs;preference=screentip_color'><b>Change</b></a><br>"
|
||||
dat += "<b>Thought Bubble when pointing:</b> <a href='byond://?_src_=prefs;preference=thought_bubble'>[(toggles2 & PREFTOGGLE_2_THOUGHT_BUBBLE) ? "Yes" : "No"]</a><br>"
|
||||
dat += "<b>Cogbar indicators:</b> <a href='byond://?_src_=prefs;preference=cogbar'>[(toggles3 & PREFTOGGLE_3_COGBAR_ANIMATIONS) ? "Yes" : "No"]</a><br>"
|
||||
dat += "<b>Custom UI settings:</b><br>"
|
||||
dat += " - <b>Alpha (transparency):</b> <a href='byond://?_src_=prefs;preference=UIalpha'><b>[UI_style_alpha]</b></a><br>"
|
||||
dat += " - <b>Color:</b> <a href='byond://?_src_=prefs;preference=UIcolor'><b>[UI_style_color]</b></a> <span style='border: 1px solid #161616; background-color: [UI_style_color];'> </span><br>"
|
||||
|
||||
@@ -882,7 +882,7 @@
|
||||
user.visible_message("<span class='warning'>[user] attempts to [break_restraints ? "break" : "remove"] [src]!</span>", "<span class='notice'>You attempt to [break_restraints ? "break" : "remove"] [src]...</span>")
|
||||
to_chat(user, "<span class='notice'>(This will take around [DisplayTimeText(effective_breakout_time)] and you need to stand still.)</span>")
|
||||
|
||||
if(!do_after(user, effective_breakout_time, FALSE, user))
|
||||
if(!do_after(user, effective_breakout_time, FALSE, user, hidden = TRUE))
|
||||
user.remove_status_effect(STATUS_EFFECT_REMOVE_CUFFS)
|
||||
to_chat(user, "<span class='warning'>You fail to [break_restraints ? "break" : "remove"] [src]!</span>")
|
||||
return
|
||||
|
||||
@@ -68,7 +68,7 @@
|
||||
add_attack_logs(A, D, "Put into a chokehold with martial-art [src]", ATKLOG_ALL)
|
||||
chokehold_active = TRUE
|
||||
var/damage_multiplier = 1 + D.getStaminaLoss() / 100 //The chokehold is more effective the more tired the target is.
|
||||
while(do_mob(A, D, 2 SECONDS) && chokehold_active)
|
||||
while(do_mob(A, D, 2 SECONDS, hidden = TRUE) && chokehold_active)
|
||||
D.apply_damage(10 * damage_multiplier, OXY)
|
||||
D.LoseBreath(3 SECONDS)
|
||||
if(D.getOxyLoss() >= 50 || D.health <= 20)
|
||||
|
||||
@@ -865,7 +865,7 @@ GLOBAL_LIST_INIT(ventcrawl_machinery, list(/obj/machinery/atmospherics/unary/ven
|
||||
|
||||
visible_message("<span class='warning'>[src] attempts to unbuckle [p_themselves()]!</span>",
|
||||
"<span class='notice'>You attempt to unbuckle yourself... (This will take around [breakout_time / 10] seconds and you need to stay still.)</span>")
|
||||
if(!do_after(src, breakout_time, FALSE, src, allow_moving = TRUE, extra_checks = list(CALLBACK(src, PROC_REF(buckle_check))), allow_moving_target = TRUE))
|
||||
if(!do_after(src, breakout_time, FALSE, src, allow_moving = TRUE, extra_checks = list(CALLBACK(src, PROC_REF(buckle_check))), allow_moving_target = TRUE, hidden = TRUE))
|
||||
if(src && buckled)
|
||||
to_chat(src, "<span class='warning'>You fail to unbuckle yourself!</span>")
|
||||
else
|
||||
@@ -931,7 +931,7 @@ GLOBAL_LIST_INIT(ventcrawl_machinery, list(/obj/machinery/atmospherics/unary/ven
|
||||
apply_status_effect(STATUS_EFFECT_REMOVE_MUZZLE)
|
||||
visible_message("<span class='warning'>[src] gnaws on [I], trying to remove it!</span>")
|
||||
to_chat(src, "<span class='notice'>You attempt to remove [I]... (This will take around [time/10] seconds and you need to stand still.)</span>")
|
||||
if(do_after(src, time, FALSE, src, extra_checks = list(CALLBACK(src, PROC_REF(muzzle_check)))))
|
||||
if(do_after(src, time, FALSE, src, extra_checks = list(CALLBACK(src, PROC_REF(muzzle_check))), hidden = TRUE))
|
||||
visible_message("<span class='warning'>[src] removes [I]!</span>")
|
||||
to_chat(src, "<span class='notice'>You get rid of [I]!</span>")
|
||||
if(I.security_lock)
|
||||
|
||||
@@ -91,7 +91,7 @@ STATUS EFFECTS
|
||||
|
||||
if(stat == DEAD && !work_when_dead)
|
||||
return
|
||||
if(!instant && !do_mob(src, src, 1 SECONDS, extra_checks = list(CALLBACK(src, TYPE_PROC_REF(/mob/living, cannot_stand))), only_use_extra_checks = TRUE))
|
||||
if(!instant && !do_mob(src, src, 1 SECONDS, extra_checks = list(CALLBACK(src, TYPE_PROC_REF(/mob/living, cannot_stand))), only_use_extra_checks = TRUE, hidden = TRUE))
|
||||
return
|
||||
if(resting || body_position == STANDING_UP || HAS_TRAIT(src, TRAIT_FLOORED))
|
||||
return
|
||||
|
||||
@@ -48,7 +48,7 @@
|
||||
/mob/living/simple_animal/hostile/headslug/AltClickOn(mob/living/carbon/carbon_target)
|
||||
if(egg_layed || !istype(carbon_target) || !Adjacent(carbon_target) || ismachineperson(carbon_target))
|
||||
return ..()
|
||||
if(carbon_target.stat != DEAD && !do_mob(src, carbon_target, 5 SECONDS))
|
||||
if(carbon_target.stat != DEAD && !do_mob(src, carbon_target, 5 SECONDS, hidden = TRUE))
|
||||
return
|
||||
if(HAS_TRAIT(carbon_target, TRAIT_XENO_HOST))
|
||||
to_chat(src, "<span class='userdanger'>A foreign presence repels us from this body. Perhaps we should try to infest another?</span>")
|
||||
|
||||
@@ -524,7 +524,7 @@
|
||||
else
|
||||
to_chat(src, "<span class='notice'>You are now trying to get up.</span>")
|
||||
|
||||
if(!do_mob(src, src, 1 SECONDS, extra_checks = list(CALLBACK(src, TYPE_PROC_REF(/mob/living, cannot_stand))), only_use_extra_checks = TRUE))
|
||||
if(!do_mob(src, src, 1 SECONDS, extra_checks = list(CALLBACK(src, TYPE_PROC_REF(/mob/living, cannot_stand))), only_use_extra_checks = TRUE, hidden = TRUE))
|
||||
return
|
||||
|
||||
if(resting)
|
||||
|
||||
Binary file not shown.
|
After Width: | Height: | Size: 216 B |
Binary file not shown.
|
Before Width: | Height: | Size: 559 B |
Binary file not shown.
|
After Width: | Height: | Size: 833 B |
@@ -227,6 +227,7 @@
|
||||
#include "code\_globalvars\lists\dye_registry.dm"
|
||||
#include "code\_globalvars\lists\flavor_misc.dm"
|
||||
#include "code\_globalvars\lists\fortunes.dm"
|
||||
#include "code\_globalvars\lists\icons.dm"
|
||||
#include "code\_globalvars\lists\keybindings_lists.dm"
|
||||
#include "code\_globalvars\lists\maint_loot_tables.dm"
|
||||
#include "code\_globalvars\lists\misc_lists.dm"
|
||||
@@ -352,6 +353,7 @@
|
||||
#include "code\controllers\subsystem\SStime_track.dm"
|
||||
#include "code\controllers\subsystem\SStimer.dm"
|
||||
#include "code\controllers\subsystem\SSverb_manager.dm"
|
||||
#include "code\controllers\subsystem\SSvis_overlays.dm"
|
||||
#include "code\controllers\subsystem\SSvote.dm"
|
||||
#include "code\controllers\subsystem\SSweather.dm"
|
||||
#include "code\controllers\subsystem\movement\movement_types.dm"
|
||||
@@ -398,6 +400,7 @@
|
||||
#include "code\datums\chat_payload.dm"
|
||||
#include "code\datums\chatmessage.dm"
|
||||
#include "code\datums\click_intercept.dm"
|
||||
#include "code\datums\cogbar.dm"
|
||||
#include "code\datums\custom_user_item.dm"
|
||||
#include "code\datums\datacore.dm"
|
||||
#include "code\datums\datum.dm"
|
||||
|
||||
Reference in New Issue
Block a user