Merge pull request #15317 from LetterN/what-should-i-name-this-branch

TGUI hardsync & stuff
This commit is contained in:
silicons
2022-01-25 00:06:59 -08:00
committed by GitHub
592 changed files with 24650 additions and 10686 deletions
+74 -43
View File
@@ -46,11 +46,23 @@ GLOBAL_VAR_INIT(embedpocalypse, FALSE) // if true, all items will be able to emb
max_integrity = 200
obj_flags = NONE
///Item flags for the item
var/item_flags = NONE
var/hitsound = null
var/usesound = null
var/throwhitsound = null
///Sound played when you hit something with the item
var/hitsound
///Played when the item is used, for example tools
var/usesound
///Used when yate into a mob
var/mob_throw_hit_sound
///Sound used when equipping the item into a valid slot
var/equip_sound
///Sound uses when picking the item up (into your hands)
var/pickup_sound
///Sound uses when dropping the item, or when its thrown.
var/drop_sound
///Whether or not we use stealthy audio levels for this item's attack sounds
var/stealthy_audio = FALSE
/// Weight class for how much storage capacity it uses and how big it physically is meaning storages can't hold it if their maximum weight class isn't as high as it.
var/w_class = WEIGHT_CLASS_NORMAL
@@ -129,7 +141,8 @@ GLOBAL_VAR_INIT(embedpocalypse, FALSE) // if true, all items will be able to emb
var/datum/dog_fashion/dog_fashion = null
//Tooltip vars
var/force_string //string form of an item's force. Edit this var only to set a custom force string
///string form of an item's force. Edit this var only to set a custom force string
var/force_string
var/last_force_string_check = 0
var/trigger_guard = TRIGGER_GUARD_NONE
@@ -388,7 +401,7 @@ GLOBAL_VAR_INIT(embedpocalypse, FALSE) // if true, all items will be able to emb
if(!allow_attack_hand_drop(user) || !user.temporarilyRemoveItemFromInventory(src))
return
remove_outline()
. = FALSE
pickup(user)
add_fingerprint(user)
if(!user.put_in_active_hand(src, FALSE, FALSE))
@@ -461,9 +474,8 @@ GLOBAL_VAR_INIT(embedpocalypse, FALSE) // if true, all items will be able to emb
item_flags &= ~(IN_INVENTORY)
item_flags &= ~(IN_STORAGE)
SEND_SIGNAL(src, COMSIG_ITEM_DROPPED,user)
remove_outline()
// if(!silent)
// playsound(src, drop_sound, DROP_SOUND_VOLUME, ignore_walls = FALSE)
if(!silent)
playsound(src, drop_sound, DROP_SOUND_VOLUME, ignore_walls = FALSE)
user?.update_equipment_speed_mods()
// called just as an item is picked up (loc is not yet changed)
@@ -710,8 +722,8 @@ GLOBAL_VAR_INIT(embedpocalypse, FALSE) // if true, all items will be able to emb
if(isliving(hit_atom)) //Living mobs handle hit sounds differently.
var/volume = get_volume_by_throwforce_and_or_w_class()
if (throwforce > 0)
if (throwhitsound)
playsound(hit_atom, throwhitsound, volume, TRUE, -1)
if (mob_throw_hit_sound)
playsound(hit_atom, mob_throw_hit_sound, volume, TRUE, -1)
else if(hitsound)
playsound(hit_atom, hitsound, volume, TRUE, -1)
else
@@ -719,8 +731,8 @@ GLOBAL_VAR_INIT(embedpocalypse, FALSE) // if true, all items will be able to emb
else
playsound(hit_atom, 'sound/weapons/throwtap.ogg', 1, volume, -1)
// else
// playsound(src, drop_sound, YEET_SOUND_VOLUME, ignore_walls = FALSE)
else if (drop_sound)
playsound(src, drop_sound, YEET_SOUND_VOLUME, ignore_walls = FALSE)
return hit_atom.hitby(src, 0, itempush, throwingdatum=throwingdatum)
/obj/item/throw_at(atom/target, range, speed, mob/thrower, spin=1, diagonals_first = 0, datum/callback/callback, force, messy_throw = TRUE)
@@ -894,47 +906,55 @@ GLOBAL_VAR_INIT(embedpocalypse, FALSE) // if true, all items will be able to emb
openToolTip(user,src,params,title = name,content = "[desc]<br><b>Force:</b> [force_string]",theme = "")
/obj/item/MouseEntered(location, control, params)
. = ..()
SEND_SIGNAL(src, COMSIG_ITEM_MOUSE_ENTER, location, control, params)
if((item_flags & IN_INVENTORY || item_flags & IN_STORAGE) && usr?.client.prefs.enable_tips && !QDELETED(src))
var/timedelay = max(usr.client.prefs.tip_delay * 0.01, 0.01) // I heard multiplying is faster, also runtimes from very low/negative numbers
usr.client.tip_timer = addtimer(CALLBACK(src, .proc/openTip, location, control, params, usr), timedelay, TIMER_STOPPABLE)//timer takes delay in deciseconds, but the pref is in milliseconds. dividing by 100 converts it.
var/mob/living/L = usr
if(istype(L) && (L.incapacitated() || (current_equipped_slot in L.check_obscured_slots()) || !L.canUnEquip(src)))
apply_outline(_size = 3)
else
apply_outline()
if(get(src, /mob) == usr && !QDELETED(src))
var/mob/living/L = usr
if(usr.client.prefs.enable_tips)
var/timedelay = usr.client.prefs.tip_delay/100
usr.client.tip_timer = addtimer(CALLBACK(src, .proc/openTip, location, control, params, usr), timedelay, TIMER_STOPPABLE)//timer takes delay in deciseconds, but the pref is in milliseconds. dividing by 100 converts it.
if(usr.client.prefs.outline_enabled)
if(istype(L) && L.incapacitated())
apply_outline(COLOR_RED_GRAY) //if they're dead or handcuffed, let's show the outline as red to indicate that they can't interact with that right now
else
apply_outline(usr.client.prefs.outline_color) //if the player's alive and well we send the command with no color set, so it uses the theme's color
/obj/item/MouseDrop(atom/over, src_location, over_location, src_control, over_control, params)
. = ..()
remove_outline()
remove_filter("hover_outline") //get rid of the hover effect in case the mouse exit isn't called if someone drags and drops an item and somthing goes wrong
/obj/item/MouseExited(location,control,params)
/obj/item/MouseExited(location, control, params)
SEND_SIGNAL(src, COMSIG_ITEM_MOUSE_EXIT, location, control, params)
deltimer(usr.client.tip_timer) //delete any in-progress timer if the mouse is moved off the item before it finishes
closeToolTip(usr)
remove_outline()
remove_filter("hover_outline")
/obj/item/proc/apply_outline(colour = null, _size=1)
if(!(item_flags & IN_INVENTORY || item_flags & IN_STORAGE) || QDELETED(src) || isobserver(usr))
/obj/item/proc/apply_outline(outline_color = null)
if(get(src, /mob) != usr || QDELETED(src) || isobserver(usr)) //cancel if the item isn't in an inventory, is being deleted, or if the person hovering is a ghost (so that people spectating you don't randomly make your items glow)
return
if(usr.client)
if(!usr.client.prefs.outline_enabled)
return
if(!colour)
if(usr.client)
colour = usr.client.prefs.outline_color
if(!colour)
colour = COLOR_BLUE_GRAY
else
colour = COLOR_BLUE_GRAY
if(outline_filter)
filters -= outline_filter
outline_filter = filter(type="outline", size=_size, color=colour)
filters += outline_filter
var/theme = lowertext(usr.client.prefs.UI_style)
if(!outline_color) //if we weren't provided with a color, take the theme's color
switch(theme) //yeah it kinda has to be this way
if("midnight")
outline_color = COLOR_THEME_MIDNIGHT
if("plasmafire")
outline_color = COLOR_THEME_PLASMAFIRE
if("retro")
outline_color = COLOR_THEME_RETRO //just as garish as the rest of this theme
if("slimecore")
outline_color = COLOR_THEME_SLIMECORE
if("operative")
outline_color = COLOR_THEME_OPERATIVE
if("clockwork")
outline_color = COLOR_THEME_CLOCKWORK //if you want free gbp go fix the fact that clockwork's tooltip css is glass'
if("glass")
outline_color = COLOR_THEME_GLASS
else //this should never happen, hopefully
outline_color = COLOR_WHITE
if(color)
outline_color = COLOR_WHITE //if the item is recolored then the outline will be too, let's make the outline white so it becomes the same color instead of some ugly mix of the theme and the tint
/obj/item/proc/remove_outline()
if(outline_filter)
filters -= outline_filter
outline_filter = null
add_filter("hover_outline", 1, list("type" = "outline", "size" = 1, "color" = outline_color))
// Called when a mob tries to use the item as a tool.
// Handles most checks.
@@ -1216,3 +1236,14 @@ GLOBAL_VAR_INIT(embedpocalypse, FALSE) // if true, all items will be able to emb
pain_stam_pct = (!isnull(embedding["pain_stam_pct"]) ? embedding["pain_stam_pct"] : EMBEDDED_PAIN_STAM_PCT),\
embed_chance_turf_mod = (!isnull(embedding["embed_chance_turf_mod"]) ? embedding["embed_chance_turf_mod"] : EMBED_CHANCE_TURF_MOD))
return TRUE
/**
* Updates all action buttons associated with this item
*
* Arguments:
* * status_only - Update only current availability status of the buttons to show if they are ready or not to use
* * force - Force buttons update even if the given button icon state has not changed
*/
/obj/item/proc/update_action_buttons(status_only = FALSE, force = FALSE)
for(var/datum/action/current_action as anything in actions)
current_action.UpdateButtonIcon(status_only, force)
@@ -19,6 +19,7 @@
w_class = WEIGHT_CLASS_SMALL
slot_flags = ITEM_SLOT_BELT
rad_flags = RAD_NO_CONTAMINATE
item_flags = NOBLUDGEON
custom_materials = list(/datum/material/iron = 150, /datum/material/glass = 150)
var/grace = RAD_GRACE_PERIOD
@@ -35,17 +36,15 @@
. = ..()
START_PROCESSING(SSobj, src)
soundloop = new(list(src), FALSE)
soundloop = new(src, FALSE)
/obj/item/geiger_counter/Destroy()
STOP_PROCESSING(SSobj, src)
QDEL_NULL(soundloop)
return ..()
/obj/item/geiger_counter/process()
update_icon()
update_sound()
/obj/item/geiger_counter/process(delta_time)
if(!scanning)
current_tick_amount = 0
return
@@ -64,49 +63,55 @@
current_tick_amount = 0
update_appearance()
update_sound()
/obj/item/geiger_counter/examine(mob/user)
. = ..()
if(!scanning)
return
. += "<span class='info'>Alt-click it to clear stored radiation levels.</span>"
. += span_info("Alt-click it to clear stored radiation levels.")
if(obj_flags & EMAGGED)
. += "<span class='warning'>The display seems to be incomprehensible.</span>"
. += span_warning("The display seems to be incomprehensible.")
return
switch(radiation_count)
if(-INFINITY to RAD_LEVEL_NORMAL)
. += "<span class='notice'>Ambient radiation level count reports that all is well.</span>"
. += span_notice("Ambient radiation level count reports that all is well.")
if(RAD_LEVEL_NORMAL + 1 to RAD_LEVEL_MODERATE)
. += "<span class='disarm'>Ambient radiation levels slightly above average.</span>"
. += span_alert("Ambient radiation levels slightly above average.")
if(RAD_LEVEL_MODERATE + 1 to RAD_LEVEL_HIGH)
. += "<span class='warning'>Ambient radiation levels above average.</span>"
. += span_warning("Ambient radiation levels above average.")
if(RAD_LEVEL_HIGH + 1 to RAD_LEVEL_VERY_HIGH)
. += "<span class='danger'>Ambient radiation levels highly above average.</span>"
. += span_danger("Ambient radiation levels highly above average.")
if(RAD_LEVEL_VERY_HIGH + 1 to RAD_LEVEL_CRITICAL)
. += "<span class='suicide'>Ambient radiation levels nearing critical level.</span>"
. += span_suicide("Ambient radiation levels nearing critical level.")
if(RAD_LEVEL_CRITICAL + 1 to INFINITY)
. += "<span class='boldannounce'>Ambient radiation levels above critical level!</span>"
. += span_boldannounce("Ambient radiation levels above critical level!")
. += "<span class='notice'>The last radiation amount detected was [last_tick_amount]</span>"
. += span_notice("The last radiation amount detected was [last_tick_amount]")
/obj/item/geiger_counter/update_icon_state()
if(!scanning)
icon_state = "geiger_off"
else if(obj_flags & EMAGGED)
return ..()
if(obj_flags & EMAGGED)
icon_state = "geiger_on_emag"
else
switch(radiation_count)
if(-INFINITY to RAD_LEVEL_NORMAL)
icon_state = "geiger_on_1"
if(RAD_LEVEL_NORMAL + 1 to RAD_LEVEL_MODERATE)
icon_state = "geiger_on_2"
if(RAD_LEVEL_MODERATE + 1 to RAD_LEVEL_HIGH)
icon_state = "geiger_on_3"
if(RAD_LEVEL_HIGH + 1 to RAD_LEVEL_VERY_HIGH)
icon_state = "geiger_on_4"
if(RAD_LEVEL_VERY_HIGH + 1 to RAD_LEVEL_CRITICAL)
icon_state = "geiger_on_4"
if(RAD_LEVEL_CRITICAL + 1 to INFINITY)
icon_state = "geiger_on_5"
return ..()
switch(radiation_count)
if(-INFINITY to RAD_LEVEL_NORMAL)
icon_state = "geiger_on_1"
if(RAD_LEVEL_NORMAL + 1 to RAD_LEVEL_MODERATE)
icon_state = "geiger_on_2"
if(RAD_LEVEL_MODERATE + 1 to RAD_LEVEL_HIGH)
icon_state = "geiger_on_3"
if(RAD_LEVEL_HIGH + 1 to RAD_LEVEL_VERY_HIGH)
icon_state = "geiger_on_4"
if(RAD_LEVEL_VERY_HIGH + 1 to RAD_LEVEL_CRITICAL)
icon_state = "geiger_on_4"
if(RAD_LEVEL_CRITICAL + 1 to INFINITY)
icon_state = "geiger_on_5"
return ..()
/obj/item/geiger_counter/proc/update_sound()
var/datum/looping_sound/geiger/loop = soundloop
@@ -124,21 +129,21 @@
if(amount <= RAD_BACKGROUND_RADIATION || !scanning)
return
current_tick_amount += amount
update_icon()
update_appearance()
/obj/item/geiger_counter/attack_self(mob/user)
scanning = !scanning
update_icon()
to_chat(user, "<span class='notice'>[icon2html(src, user)] You switch [scanning ? "on" : "off"] [src].</span>")
update_appearance()
to_chat(user, span_notice("[icon2html(src, user)] You switch [scanning ? "on" : "off"] [src]."))
/obj/item/geiger_counter/afterattack(atom/target, mob/user)
/obj/item/geiger_counter/afterattack(atom/target, mob/living/user)
. = ..()
if(user.a_intent == INTENT_HELP)
if(!(obj_flags & EMAGGED))
user.visible_message("<span class='notice'>[user] scans [target] with [src].</span>", "<span class='notice'>You scan [target]'s radiation levels with [src]...</span>")
user.visible_message(span_notice("[user] scans [target] with [src]."), span_notice("You scan [target]'s radiation levels with [src]..."))
addtimer(CALLBACK(src, .proc/scan, target, user), 20, TIMER_UNIQUE) // Let's not have spamming GetAllContents
else
user.visible_message("<span class='notice'>[user] scans [target] with [src].</span>", "<span class='danger'>You project [src]'s stored radiation into [target]!</span>")
user.visible_message(span_notice("[user] scans [target] with [src]."), span_danger("You project [src]'s stored radiation into [target]!"))
target.rad_act(radiation_count)
radiation_count = 0
return TRUE
@@ -156,57 +161,61 @@
if(isliving(A))
var/mob/living/M = A
if(!M.radiation)
to_chat(user, "<span class='notice'>[icon2html(src, user)] Radiation levels within normal boundaries.</span>")
to_chat(user, span_notice("[icon2html(src, user)] Radiation levels within normal boundaries."))
else
to_chat(user, "<span class='boldannounce'>[icon2html(src, user)] Subject is irradiated. Radiation levels: [M.radiation] rad.</span>")
to_chat(user, span_boldannounce("[icon2html(src, user)] Subject is irradiated. Radiation levels: [M.radiation]."))
if(rad_strength)
to_chat(user, "<span class='boldannounce'>[icon2html(src, user)] Target contains radioactive contamination. Radioactive strength: [rad_strength]</span>")
to_chat(user, span_boldannounce("[icon2html(src, user)] Target contains radioactive contamination. Radioactive strength: [rad_strength]"))
else
to_chat(user, "<span class='notice'>[icon2html(src, user)] Target is free of radioactive contamination.</span>")
to_chat(user, span_notice("[icon2html(src, user)] Target is free of radioactive contamination."))
/obj/item/geiger_counter/attackby(obj/item/I, mob/user, params)
if(I.tool_behaviour == TOOL_SCREWDRIVER && (obj_flags & EMAGGED))
if(scanning)
to_chat(user, "<span class='warning'>Turn off [src] before you perform this action!</span>")
return 0
user.visible_message("<span class='notice'>[user] unscrews [src]'s maintenance panel and begins fiddling with its innards...</span>", "<span class='notice'>You begin resetting [src]...</span>")
to_chat(user, span_warning("Turn off [src] before you perform this action!"))
return FALSE
user.visible_message(span_notice("[user] unscrews [src]'s maintenance panel and begins fiddling with its innards..."), span_notice("You begin resetting [src]..."))
if(!I.use_tool(src, user, 40, volume=50))
return 0
user.visible_message("<span class='notice'>[user] refastens [src]'s maintenance panel!</span>", "<span class='notice'>You reset [src] to its factory settings!</span>")
return FALSE
user.visible_message(span_notice("[user] refastens [src]'s maintenance panel!"), span_notice("You reset [src] to its factory settings!"))
obj_flags &= ~EMAGGED
radiation_count = 0
update_icon()
return 1
update_appearance()
return TRUE
else
return ..()
/obj/item/geiger_counter/AltClick(mob/living/user)
. = ..()
if(!istype(user) || !user.canUseTopic(src, BE_CLOSE))
return
return ..()
if(!scanning)
to_chat(usr, "<span class='warning'>[src] must be on to reset its radiation level!</span>")
return TRUE
to_chat(usr, span_warning("[src] must be on to reset its radiation level!"))
return
radiation_count = 0
to_chat(usr, "<span class='notice'>You flush [src]'s radiation counts, resetting it to normal.</span>")
update_icon()
return TRUE
to_chat(usr, span_notice("You flush [src]'s radiation counts, resetting it to normal."))
update_appearance()
/obj/item/geiger_counter/emag_act(mob/user)
. = ..()
if(obj_flags & EMAGGED)
return
if(scanning)
to_chat(user, "<span class='warning'>Turn off [src] before you perform this action!</span>")
to_chat(user, span_warning("Turn off [src] before you perform this action!"))
return
to_chat(user, "<span class='warning'>You override [src]'s radiation storing protocols. It will now generate small doses of radiation, and stored rads are now projected into creatures you scan.</span>")
to_chat(user, span_warning("You override [src]'s radiation storing protocols. It will now generate small doses of radiation, and stored rads are now projected into creatures you scan."))
obj_flags |= EMAGGED
return TRUE
/obj/item/geiger_counter/cyborg
var/mob/listeningTo
/obj/item/geiger_counter/cyborg/cyborg_unequip(mob/user)
if(!scanning)
return
scanning = FALSE
update_appearance()
/obj/item/geiger_counter/cyborg/equipped(mob/user)
. = ..()
if(listeningTo == user)
@@ -217,6 +226,7 @@
listeningTo = user
/obj/item/geiger_counter/cyborg/proc/redirect_rad_act(datum/source, amount)
SIGNAL_HANDLER
rad_act(amount)
/obj/item/geiger_counter/cyborg/dropped(mob/user)
@@ -24,8 +24,8 @@
/obj/item/reverse_bear_trap/Initialize()
. = ..()
soundloop = new(list(src))
soundloop2 = new(list(src))
soundloop = new(src)
soundloop2 = new(src)
/obj/item/reverse_bear_trap/Destroy()
QDEL_NULL(soundloop)
@@ -33,16 +33,16 @@
STOP_PROCESSING(SSprocessing, src)
return ..()
/obj/item/reverse_bear_trap/process()
/obj/item/reverse_bear_trap/process(delta_time)
if(!ticking)
return
time_left--
time_left -= delta_time
soundloop2.mid_length = max(0.5, time_left - 5) //beepbeepbeepbeepbeep
if(!time_left || !isliving(loc))
if(time_left <= 0 || !isliving(loc))
playsound(src, 'sound/machines/microwave/microwave-end.ogg', 100, FALSE)
soundloop.stop()
soundloop2.stop()
to_chat(loc, "<span class='userdanger'>*ding*</span>")
to_chat(loc, span_userdanger("*ding*"))
addtimer(CALLBACK(src, .proc/snap), 2)
/obj/item/reverse_bear_trap/on_attack_hand(mob/user, act_intent = user.a_intent, unarmed_attack_flags)
@@ -116,13 +116,22 @@
/obj/item/reverse_bear_trap/proc/reset()
ticking = FALSE
update_appearance(UPDATE_OVERLAYS)
REMOVE_TRAIT(src, TRAIT_NODROP, REVERSE_BEAR_TRAP_TRAIT)
soundloop.stop()
soundloop2.stop()
STOP_PROCESSING(SSprocessing, src)
/obj/item/reverse_bear_trap/update_overlays()
. = ..()
if(ticking != TRUE)
return
/// note: this timer overlay increments one frame every second (to simulate a clock ticking). If you want to instead have it do a full cycle in a minute, set the 'delay' of each frame of the icon overlay to 75 rather than 10, and the worn overlay to twice that.
// . += "rbt_ticking"
/obj/item/reverse_bear_trap/proc/arm() //hulen
ticking = TRUE
update_appearance(UPDATE_OVERLAYS)
escape_chance = initial(escape_chance) //we keep these vars until re-arm, for tracking purposes
time_left = initial(time_left)
ADD_TRAIT(src, TRAIT_NODROP, REVERSE_BEAR_TRAP_TRAIT)
@@ -20,4 +20,7 @@
imp_type = /obj/item/implant/uplink/precharged
/obj/item/implant/uplink/precharged
starting_tc = 10
starting_tc = TELECRYSTALS_PRELOADED_IMPLANT
/obj/item/implant/uplink/starting
starting_tc = TELECRYSTALS_DEFAULT - UPLINK_IMPLANT_TELECRYSTAL_COST
+3 -1
View File
@@ -52,6 +52,8 @@
var/author_ckey
var/icon_generated = FALSE
var/icon/generated_icon
///boolean that blocks persistence from saving it. enabled from printing copies, because we do not want to save copies.
var/no_save = FALSE
// Painting overlay offset when framed
var/framed_offset_x = 11
@@ -370,7 +372,7 @@
update_icon()
/obj/structure/sign/painting/proc/save_persistent()
if(!persistence_id || !current_canvas)
if(!persistence_id || !current_canvas || current_canvas.no_save)
return
if(sanitize_filename(persistence_id) != persistence_id)
stack_trace("Invalid persistence_id - [persistence_id]")
@@ -25,7 +25,7 @@
/obj/machinery/manned_turret/Destroy()
target = null
target_turf = null
..()
return ..()
//BUCKLE HOOKS
+81 -43
View File
@@ -1,3 +1,5 @@
#define MAX_NOTICES 5
/obj/structure/noticeboard
name = "notice board"
desc = "A board for pinning important notices upon."
@@ -7,8 +9,25 @@
density = FALSE
anchored = TRUE
max_integrity = 150
/// Current number of a pinned notices
var/notices = 0
/obj/structure/noticeboard/directional/north
dir = SOUTH
pixel_y = 32
/obj/structure/noticeboard/directional/south
dir = NORTH
pixel_y = -32
/obj/structure/noticeboard/directional/east
dir = WEST
pixel_x = 32
/obj/structure/noticeboard/directional/west
dir = EAST
pixel_x = -32
/obj/structure/noticeboard/Initialize(mapload)
. = ..()
@@ -16,7 +35,7 @@
return
for(var/obj/item/I in loc)
if(notices > 4)
if(notices >= MAX_NOTICES)
break
if(istype(I, /obj/item/paper))
I.forceMove(src)
@@ -27,67 +46,84 @@
/obj/structure/noticeboard/attackby(obj/item/O, mob/user, params)
if(istype(O, /obj/item/paper) || istype(O, /obj/item/photo))
if(!allowed(user))
to_chat(user, "<span class='info'>You are not authorized to add notices</span>")
to_chat(user, span_warning("You are not authorized to add notices!"))
return
if(notices < 5)
if(notices < MAX_NOTICES)
if(!user.transferItemToLoc(O, src))
return
notices++
icon_state = "nboard0[notices]"
to_chat(user, "<span class='notice'>You pin the [O] to the noticeboard.</span>")
to_chat(user, span_notice("You pin the [O] to the noticeboard."))
else
to_chat(user, "<span class='notice'>The notice board is full</span>")
to_chat(user, span_warning("The notice board is full!"))
else
return ..()
/obj/structure/noticeboard/interact(mob/user)
ui_interact(user)
/obj/structure/noticeboard/ui_state(mob/user)
return GLOB.physical_state
/obj/structure/noticeboard/ui_interact(mob/user)
/obj/structure/noticeboard/ui_interact(mob/user, datum/tgui/ui)
ui = SStgui.try_update_ui(user, src, ui)
if(!ui)
ui = new(user, src, "NoticeBoard", name)
ui.open()
/obj/structure/noticeboard/ui_data(mob/user)
var/list/data = list()
data["allowed"] = allowed(user)
data["items"] = list()
for(var/obj/item/content in contents)
var/list/content_data = list(
name = content.name,
ref = REF(content)
)
data["items"] += list(content_data)
return data
/obj/structure/noticeboard/ui_act(action, params)
. = ..()
var/auth = allowed(user)
var/dat = "<B>[name]</B><BR>"
for(var/obj/item/P in src)
if(istype(P, /obj/item/paper))
dat += "<A href='?src=[REF(src)];read=[REF(P)]'>[P.name]</A> [auth ? "<A href='?src=[REF(src)];write=[REF(P)]'>Write</A> <A href='?src=[REF(src)];remove=[REF(P)]'>Remove</A>" : ""]<BR>"
else
dat += "<A href='?src=[REF(src)];read=[REF(P)]'>[P.name]</A> [auth ? "<A href='?src=[REF(src)];remove=[REF(P)]'>Remove</A>" : ""]<BR>"
user << browse("<HEAD><TITLE>Notices</TITLE></HEAD>[dat]","window=noticeboard")
onclose(user, "noticeboard")
if(.)
return
/obj/structure/noticeboard/Topic(href, href_list)
..()
usr.set_machine(src)
if(href_list["remove"])
if((usr.stat || usr.restrained())) //For when a player is handcuffed while they have the notice window open
return
var/obj/item/I = locate(href_list["remove"]) in contents
if(istype(I) && I.loc == src)
I.forceMove(usr.loc)
usr.put_in_hands(I)
notices--
icon_state = "nboard0[notices]"
var/obj/item/item = locate(params["ref"]) in contents
if(!istype(item) || item.loc != src)
return
if(href_list["write"])
if((usr.stat || usr.restrained())) //For when a player is handcuffed while they have the notice window open
return
var/obj/item/P = locate(href_list["write"]) in contents
if(istype(P) && P.loc == src)
var/obj/item/I = usr.is_holding_item_of_type(/obj/item/pen)
if(I)
add_fingerprint(usr)
P.attackby(I, usr)
var/mob/user = usr
switch(action)
if("examine")
if(istype(item, /obj/item/paper))
item.ui_interact(user)
else
to_chat(usr, "<span class='notice'>You'll need something to write with!</span>")
user.examinate(item)
return TRUE
if("remove")
if(!allowed(user))
return
remove_item(item, user)
return TRUE
if(href_list["read"])
var/obj/item/I = locate(href_list["read"]) in contents
if(istype(I) && I.loc == src)
usr.examinate(I)
/**
* Removes an item from the notice board
*
* Arguments:
* * item - The item that is to be removed
* * user - The mob that is trying to get the item removed, if there is one
*/
/obj/structure/noticeboard/proc/remove_item(obj/item/item, mob/user)
item.forceMove(drop_location())
if(user)
user.put_in_hands(item)
balloon_alert(user, "removed from board")
notices--
icon_state = "nboard0[notices]"
/obj/structure/noticeboard/deconstruct(disassembled = TRUE)
if(!(flags_1 & NODECONSTRUCT_1))
new /obj/item/stack/sheet/metal (loc, 1)
for(var/obj/item/content in contents)
remove_item(content)
qdel(src)
// Notice boards for the heads of staff (plus the qm)
@@ -131,3 +167,5 @@
name = "Staff Notice Board"
desc = "Important notices from the heads of staff."
req_access = list(ACCESS_HEADS)
#undef MAX_NOTICES
+1 -1
View File
@@ -257,7 +257,7 @@
/obj/machinery/shower/Initialize()
. = ..()
soundloop = new(list(src), FALSE)
soundloop = new(src, FALSE)
/obj/machinery/shower/Destroy()
QDEL_NULL(soundloop)