mirror of
https://github.com/ParadiseSS13/Paradise.git
synced 2026-07-16 01:23:41 +01:00
Merge remote-tracking branch 'upstream/master' into rnd-tgui-rebase
This commit is contained in:
+46
-255
@@ -6,7 +6,7 @@ GLOBAL_VAR_INIT(nologevent, 0)
|
||||
msg = "<span class=\"admin\"><span class=\"prefix\">ADMIN LOG:</span> <span class=\"message\">[msg]</span></span>"
|
||||
for(var/client/C in GLOB.admins)
|
||||
if(R_ADMIN & C.holder.rights)
|
||||
if(C.prefs && !(C.prefs.toggles & CHAT_NO_ADMINLOGS))
|
||||
if(C.prefs && !(C.prefs.toggles & PREFTOGGLE_CHAT_NO_ADMINLOGS))
|
||||
to_chat(C, msg)
|
||||
|
||||
/proc/msg_admin_attack(var/text, var/loglevel)
|
||||
@@ -20,22 +20,39 @@ GLOBAL_VAR_INIT(nologevent, 0)
|
||||
if(C.prefs.atklog <= loglevel)
|
||||
to_chat(C, msg)
|
||||
|
||||
|
||||
/proc/message_adminTicket(var/msg, var/alt = FALSE)
|
||||
if(alt)
|
||||
msg = "<span class=admin_channel>ADMIN TICKET: [msg]</span>"
|
||||
else
|
||||
msg = "<span class=adminticket><span class='prefix'>ADMIN TICKET:</span> [msg]</span>"
|
||||
/**
|
||||
* Sends a message to the staff able to see admin tickets
|
||||
* Arguments:
|
||||
* msg - The message being send
|
||||
* important - If the message is important. If TRUE it will ignore the CHAT_NO_TICKETLOGS preferences,
|
||||
send a sound and flash the window. Defaults to FALSE
|
||||
*/
|
||||
/proc/message_adminTicket(msg, important = FALSE)
|
||||
for(var/client/C in GLOB.admins)
|
||||
if(R_ADMIN & C.holder.rights)
|
||||
if(C.prefs && !(C.prefs.toggles & CHAT_NO_TICKETLOGS))
|
||||
if(important || (C.prefs && !(C.prefs.toggles & PREFTOGGLE_CHAT_NO_TICKETLOGS)))
|
||||
to_chat(C, msg)
|
||||
if(important)
|
||||
if(C.prefs?.sound & SOUND_ADMINHELP)
|
||||
SEND_SOUND(C, 'sound/effects/adminhelp.ogg')
|
||||
window_flash(C)
|
||||
|
||||
/proc/message_mentorTicket(var/msg)
|
||||
/**
|
||||
* Sends a message to the staff able to see mentor tickets
|
||||
* Arguments:
|
||||
* msg - The message being send
|
||||
* important - If the message is important. If TRUE it will ignore the CHAT_NO_TICKETLOGS preferences,
|
||||
send a sound and flash the window. Defaults to FALSE
|
||||
*/
|
||||
/proc/message_mentorTicket(msg, important = FALSE)
|
||||
for(var/client/C in GLOB.admins)
|
||||
if(check_rights(R_ADMIN | R_MENTOR | R_MOD, 0, C.mob))
|
||||
if(C.prefs && !(C.prefs.toggles & CHAT_NO_MENTORTICKETLOGS))
|
||||
if(important || (C.prefs && !(C.prefs.toggles & PREFTOGGLE_CHAT_NO_TICKETLOGS)))
|
||||
to_chat(C, msg)
|
||||
if(important)
|
||||
if(C.prefs?.sound & SOUND_MENTORHELP)
|
||||
SEND_SOUND(C, 'sound/effects/adminhelp.ogg')
|
||||
window_flash(C)
|
||||
|
||||
/proc/admin_ban_mobsearch(var/mob/M, var/ckey_to_find, var/mob/admin_to_notify)
|
||||
if(!M || !M.ckey)
|
||||
@@ -291,251 +308,6 @@ GLOBAL_VAR_INIT(nologevent, 0)
|
||||
if(key)
|
||||
vpn_whitelist_panel(key)
|
||||
|
||||
/datum/admins/proc/access_news_network() //MARKER
|
||||
set category = "Event"
|
||||
set name = "Access Newscaster Network"
|
||||
set desc = "Allows you to view, add and edit news feeds."
|
||||
|
||||
if(!check_rights(R_EVENT))
|
||||
return
|
||||
|
||||
if(!istype(src,/datum/admins))
|
||||
src = usr.client.holder
|
||||
|
||||
var/dat
|
||||
dat = text("<HEAD><TITLE>Admin Newscaster</TITLE></HEAD><H3>Admin Newscaster Unit</H3>")
|
||||
|
||||
switch(admincaster_screen)
|
||||
if(0)
|
||||
dat += {"Welcome to the admin newscaster.<BR> Here you can add, edit and censor every newspiece on the network.
|
||||
<BR>Feed channels and stories entered through here will be uneditable and handled as official news by the rest of the units.
|
||||
<BR>Note that this panel allows full freedom over the news network, there are no constrictions except the few basic ones. Don't break things!</FONT>
|
||||
"}
|
||||
if(GLOB.news_network.wanted_issue)
|
||||
dat+= "<HR><A href='?src=[UID()];ac_view_wanted=1'>Read Wanted Issue</A>"
|
||||
|
||||
dat+= {"<HR><BR><A href='?src=[UID()];ac_create_channel=1'>Create Feed Channel</A>
|
||||
<BR><A href='?src=[UID()];ac_view=1'>View Feed Channels</A>
|
||||
<BR><A href='?src=[UID()];ac_create_feed_story=1'>Submit new Feed story</A>
|
||||
<BR><BR><A href='?src=[usr.UID()];mach_close=newscaster_main'>Exit</A>
|
||||
"}
|
||||
|
||||
var/wanted_already = 0
|
||||
if(GLOB.news_network.wanted_issue)
|
||||
wanted_already = 1
|
||||
|
||||
dat+={"<HR><B>Feed Security functions:</B><BR>
|
||||
<BR><A href='?src=[UID()];ac_menu_wanted=1'>[(wanted_already) ? ("Manage") : ("Publish")] \"Wanted\" Issue</A>
|
||||
<BR><A href='?src=[UID()];ac_menu_censor_story=1'>Censor Feed Stories</A>
|
||||
<BR><A href='?src=[UID()];ac_menu_censor_channel=1'>Mark Feed Channel with Nanotrasen D-Notice (disables and locks the channel.</A>
|
||||
<BR><HR><A href='?src=[UID()];ac_set_signature=1'>The newscaster recognises you as:<BR> <FONT COLOR='green'>[src.admincaster_signature]</FONT></A>
|
||||
"}
|
||||
if(1)
|
||||
dat+= "Station Feed Channels<HR>"
|
||||
if( isemptylist(GLOB.news_network.network_channels) )
|
||||
dat+="<I>No active channels found...</I>"
|
||||
else
|
||||
for(var/datum/feed_channel/CHANNEL in GLOB.news_network.network_channels)
|
||||
if(CHANNEL.is_admin_channel)
|
||||
dat+="<B><FONT style='BACKGROUND-COLOR: LightGreen'><A href='?src=[UID()];ac_show_channel=\ref[CHANNEL]'>[CHANNEL.channel_name]</A></FONT></B><BR>"
|
||||
else
|
||||
dat+="<B><A href='?src=[UID()];ac_show_channel=\ref[CHANNEL]'>[CHANNEL.channel_name]</A> [(CHANNEL.censored) ? ("<FONT COLOR='red'>***</FONT>") : ""]<BR></B>"
|
||||
dat+={"<BR><HR><A href='?src=[UID()];ac_refresh=1'>Refresh</A>
|
||||
<BR><A href='?src=[UID()];ac_setScreen=[0]'>Back</A>
|
||||
"}
|
||||
|
||||
if(2)
|
||||
dat+={"
|
||||
Creating new Feed Channel...
|
||||
<HR><B><A href='?src=[UID()];ac_set_channel_name=1'>Channel Name</A>:</B> [src.admincaster_feed_channel.channel_name]<BR>
|
||||
<B><A href='?src=[UID()];ac_set_signature=1'>Channel Author</A>:</B> <FONT COLOR='green'>[src.admincaster_signature]</FONT><BR>
|
||||
<B><A href='?src=[UID()];ac_set_channel_lock=1'>Will Accept Public Feeds</A>:</B> [(src.admincaster_feed_channel.locked) ? ("NO") : ("YES")]<BR><BR>
|
||||
<BR><A href='?src=[UID()];ac_submit_new_channel=1'>Submit</A><BR><BR><A href='?src=[UID()];ac_setScreen=[0]'>Cancel</A><BR>
|
||||
"}
|
||||
if(3)
|
||||
dat+={"
|
||||
Creating new Feed Message...
|
||||
<HR><B><A href='?src=[UID()];ac_set_channel_receiving=1'>Receiving Channel</A>:</B> [src.admincaster_feed_channel.channel_name]<BR>
|
||||
<B>Message Author:</B> <FONT COLOR='green'>[src.admincaster_signature]</FONT><BR>
|
||||
<B><A href='?src=[UID()];ac_set_new_message=1'>Message Body</A>:</B> [src.admincaster_feed_message.body] <BR>
|
||||
<BR><A href='?src=[UID()];ac_submit_new_message=1'>Submit</A><BR><BR><A href='?src=[UID()];ac_setScreen=[0]'>Cancel</A><BR>
|
||||
"}
|
||||
if(4)
|
||||
dat+={"
|
||||
Feed story successfully submitted to [src.admincaster_feed_channel.channel_name].<BR><BR>
|
||||
<BR><A href='?src=[UID()];ac_setScreen=[0]'>Return</A><BR>
|
||||
"}
|
||||
if(5)
|
||||
dat+={"
|
||||
Feed Channel [src.admincaster_feed_channel.channel_name] created successfully.<BR><BR>
|
||||
<BR><A href='?src=[UID()];ac_setScreen=[0]'>Return</A><BR>
|
||||
"}
|
||||
if(6)
|
||||
dat+="<B><FONT COLOR='maroon'>ERROR: Could not submit Feed story to Network.</B></FONT><HR><BR>"
|
||||
if(src.admincaster_feed_channel.channel_name=="")
|
||||
dat+="<FONT COLOR='maroon'>Invalid receiving channel name.</FONT><BR>"
|
||||
if(src.admincaster_feed_message.body == "" || src.admincaster_feed_message.body == "\[REDACTED\]")
|
||||
dat+="<FONT COLOR='maroon'>Invalid message body.</FONT><BR>"
|
||||
dat+="<BR><A href='?src=[UID()];ac_setScreen=[3]'>Return</A><BR>"
|
||||
if(7)
|
||||
dat+="<B><FONT COLOR='maroon'>ERROR: Could not submit Feed Channel to Network.</B></FONT><HR><BR>"
|
||||
if(src.admincaster_feed_channel.channel_name =="" || src.admincaster_feed_channel.channel_name == "\[REDACTED\]")
|
||||
dat+="<FONT COLOR='maroon'>Invalid channel name.</FONT><BR>"
|
||||
var/check = 0
|
||||
for(var/datum/feed_channel/FC in GLOB.news_network.network_channels)
|
||||
if(FC.channel_name == src.admincaster_feed_channel.channel_name)
|
||||
check = 1
|
||||
break
|
||||
if(check)
|
||||
dat+="<FONT COLOR='maroon'>Channel name already in use.</FONT><BR>"
|
||||
dat+="<BR><A href='?src=[UID()];ac_setScreen=[2]'>Return</A><BR>"
|
||||
if(9)
|
||||
dat+="<B>[src.admincaster_feed_channel.channel_name]: </B><FONT SIZE=1>\[created by: <FONT COLOR='maroon'>[src.admincaster_feed_channel.author]</FONT>\]</FONT><HR>"
|
||||
if(src.admincaster_feed_channel.censored)
|
||||
dat+={"
|
||||
<FONT COLOR='red'><B>ATTENTION: </B></FONT>This channel has been deemed as threatening to the welfare of the station, and marked with a Nanotrasen D-Notice.<BR>
|
||||
No further feed story additions are allowed while the D-Notice is in effect.</FONT><BR><BR>
|
||||
"}
|
||||
else
|
||||
if( isemptylist(src.admincaster_feed_channel.messages) )
|
||||
dat+="<I>No feed messages found in channel...</I><BR>"
|
||||
else
|
||||
var/i = 0
|
||||
for(var/datum/feed_message/MESSAGE in src.admincaster_feed_channel.messages)
|
||||
i++
|
||||
dat+="-[MESSAGE.body] <BR>"
|
||||
if(MESSAGE.img)
|
||||
usr << browse_rsc(MESSAGE.img, "tmp_photo[i].png")
|
||||
dat+="<img src='tmp_photo[i].png' width = '180'><BR><BR>"
|
||||
dat+="<FONT SIZE=1>\[Story by <FONT COLOR='maroon'>[MESSAGE.author]</FONT>\]</FONT><BR>"
|
||||
dat+={"
|
||||
<BR><HR><A href='?src=[UID()];ac_refresh=1'>Refresh</A>
|
||||
<BR><A href='?src=[UID()];ac_setScreen=[1]'>Back</A>
|
||||
"}
|
||||
if(10)
|
||||
dat+={"
|
||||
<B>Nanotrasen Feed Censorship Tool</B><BR>
|
||||
<FONT SIZE=1>NOTE: Due to the nature of news Feeds, total deletion of a Feed Story is not possible.<BR>
|
||||
Keep in mind that users attempting to view a censored feed will instead see the \[REDACTED\] tag above it.</FONT>
|
||||
<HR>Select Feed channel to get Stories from:<BR>
|
||||
"}
|
||||
if(isemptylist(GLOB.news_network.network_channels))
|
||||
dat+="<I>No feed channels found active...</I><BR>"
|
||||
else
|
||||
for(var/datum/feed_channel/CHANNEL in GLOB.news_network.network_channels)
|
||||
dat+="<A href='?src=[UID()];ac_pick_censor_channel=\ref[CHANNEL]'>[CHANNEL.channel_name]</A> [(CHANNEL.censored) ? ("<FONT COLOR='red'>***</FONT>") : ""]<BR>"
|
||||
dat+="<BR><A href='?src=[UID()];ac_setScreen=[0]'>Cancel</A>"
|
||||
if(11)
|
||||
dat+={"
|
||||
<B>Nanotrasen D-Notice Handler</B><HR>
|
||||
<FONT SIZE=1>A D-Notice is to be bestowed upon the channel if the handling Authority deems it as harmful for the station's
|
||||
morale, integrity or disciplinary behaviour. A D-Notice will render a channel unable to be updated by anyone, without deleting any feed
|
||||
stories it might contain at the time. You can lift a D-Notice if you have the required access at any time.</FONT><HR>
|
||||
"}
|
||||
if(isemptylist(GLOB.news_network.network_channels))
|
||||
dat+="<I>No feed channels found active...</I><BR>"
|
||||
else
|
||||
for(var/datum/feed_channel/CHANNEL in GLOB.news_network.network_channels)
|
||||
dat+="<A href='?src=[UID()];ac_pick_d_notice=\ref[CHANNEL]'>[CHANNEL.channel_name]</A> [(CHANNEL.censored) ? ("<FONT COLOR='red'>***</FONT>") : ""]<BR>"
|
||||
|
||||
dat+="<BR><A href='?src=[UID()];ac_setScreen=[0]'>Back</A>"
|
||||
if(12)
|
||||
dat+={"
|
||||
<B>[src.admincaster_feed_channel.channel_name]: </B><FONT SIZE=1>\[ created by: <FONT COLOR='maroon'>[src.admincaster_feed_channel.author]</FONT> \]</FONT><BR>
|
||||
<FONT SIZE=2><A href='?src=[UID()];ac_censor_channel_author=\ref[src.admincaster_feed_channel]'>[(src.admincaster_feed_channel.author=="\[REDACTED\]") ? ("Undo Author censorship") : ("Censor channel Author")]</A></FONT><HR>
|
||||
"}
|
||||
if( isemptylist(src.admincaster_feed_channel.messages) )
|
||||
dat+="<I>No feed messages found in channel...</I><BR>"
|
||||
else
|
||||
for(var/datum/feed_message/MESSAGE in src.admincaster_feed_channel.messages)
|
||||
dat+={"
|
||||
-[MESSAGE.body] <BR><FONT SIZE=1>\[Story by <FONT COLOR='maroon'>[MESSAGE.author]</FONT>\]</FONT><BR>
|
||||
<FONT SIZE=2><A href='?src=[UID()];ac_censor_channel_story_body=\ref[MESSAGE]'>[(MESSAGE.body == "\[REDACTED\]") ? ("Undo story censorship") : ("Censor story")]</A> - <A href='?src=[UID()];ac_censor_channel_story_author=\ref[MESSAGE]'>[(MESSAGE.author == "\[REDACTED\]") ? ("Undo Author Censorship") : ("Censor message Author")]</A></FONT><BR>
|
||||
"}
|
||||
dat+="<BR><A href='?src=[UID()];ac_setScreen=[10]'>Back</A>"
|
||||
if(13)
|
||||
dat+={"
|
||||
<B>[src.admincaster_feed_channel.channel_name]: </B><FONT SIZE=1>\[ created by: <FONT COLOR='maroon'>[src.admincaster_feed_channel.author]</FONT> \]</FONT><BR>
|
||||
Channel messages listed below. If you deem them dangerous to the station, you can <A href='?src=[UID()];ac_toggle_d_notice=\ref[src.admincaster_feed_channel]'>Bestow a D-Notice upon the channel</A>.<HR>
|
||||
"}
|
||||
if(src.admincaster_feed_channel.censored)
|
||||
dat+={"
|
||||
<FONT COLOR='red'><B>ATTENTION: </B></FONT>This channel has been deemed as threatening to the welfare of the station, and marked with a Nanotrasen D-Notice.<BR>
|
||||
No further feed story additions are allowed while the D-Notice is in effect.</FONT><BR><BR>
|
||||
"}
|
||||
else
|
||||
if( isemptylist(src.admincaster_feed_channel.messages) )
|
||||
dat+="<I>No feed messages found in channel...</I><BR>"
|
||||
else
|
||||
for(var/datum/feed_message/MESSAGE in src.admincaster_feed_channel.messages)
|
||||
dat+="-[MESSAGE.body] <BR><FONT SIZE=1>\[Story by <FONT COLOR='maroon'>[MESSAGE.author]</FONT>\]</FONT><BR>"
|
||||
|
||||
dat+="<BR><A href='?src=[UID()];ac_setScreen=[11]'>Back</A>"
|
||||
if(14)
|
||||
dat+="<B>Wanted Issue Handler:</B>"
|
||||
var/wanted_already = 0
|
||||
var/end_param = 1
|
||||
if(GLOB.news_network.wanted_issue)
|
||||
wanted_already = 1
|
||||
end_param = 2
|
||||
if(wanted_already)
|
||||
dat+="<FONT SIZE=2><BR><I>A wanted issue is already in Feed Circulation. You can edit or cancel it below.</FONT></I>"
|
||||
dat+={"
|
||||
<HR>
|
||||
<A href='?src=[UID()];ac_set_wanted_name=1'>Criminal Name</A>: [src.admincaster_feed_message.author] <BR>
|
||||
<A href='?src=[UID()];ac_set_wanted_desc=1'>Description</A>: [src.admincaster_feed_message.body] <BR>
|
||||
"}
|
||||
if(wanted_already)
|
||||
dat+="<B>Wanted Issue created by:</B><FONT COLOR='green'> [GLOB.news_network.wanted_issue.backup_author]</FONT><BR>"
|
||||
else
|
||||
dat+="<B>Wanted Issue will be created under prosecutor:</B><FONT COLOR='green'> [src.admincaster_signature]</FONT><BR>"
|
||||
dat+="<BR><A href='?src=[UID()];ac_submit_wanted=[end_param]'>[(wanted_already) ? ("Edit Issue") : ("Submit")]</A>"
|
||||
if(wanted_already)
|
||||
dat+="<BR><A href='?src=[UID()];ac_cancel_wanted=1'>Take down Issue</A>"
|
||||
dat+="<BR><A href='?src=[UID()];ac_setScreen=[0]'>Cancel</A>"
|
||||
if(15)
|
||||
dat+={"
|
||||
<FONT COLOR='green'>Wanted issue for [src.admincaster_feed_message.author] is now in Network Circulation.</FONT><BR><BR>
|
||||
<BR><A href='?src=[UID()];ac_setScreen=[0]'>Return</A><BR>
|
||||
"}
|
||||
if(16)
|
||||
dat+="<B><FONT COLOR='maroon'>ERROR: Wanted Issue rejected by Network.</B></FONT><HR><BR>"
|
||||
if(src.admincaster_feed_message.author =="" || src.admincaster_feed_message.author == "\[REDACTED\]")
|
||||
dat+="<FONT COLOR='maroon'>Invalid name for person wanted.</FONT><BR>"
|
||||
if(src.admincaster_feed_message.body == "" || src.admincaster_feed_message.body == "\[REDACTED\]")
|
||||
dat+="<FONT COLOR='maroon'>Invalid description.</FONT><BR>"
|
||||
dat+="<BR><A href='?src=[UID()];ac_setScreen=[0]'>Return</A><BR>"
|
||||
if(17)
|
||||
dat+={"
|
||||
<B>Wanted Issue successfully deleted from Circulation</B><BR>
|
||||
<BR><A href='?src=[UID()];ac_setScreen=[0]'>Return</A><BR>
|
||||
"}
|
||||
if(18)
|
||||
dat+={"
|
||||
<B><FONT COLOR ='maroon'>-- STATIONWIDE WANTED ISSUE --</B></FONT><BR><FONT SIZE=2>\[Submitted by: <FONT COLOR='green'>[GLOB.news_network.wanted_issue.backup_author]</FONT>\]</FONT><HR>
|
||||
<B>Criminal</B>: [GLOB.news_network.wanted_issue.author]<BR>
|
||||
<B>Description</B>: [GLOB.news_network.wanted_issue.body]<BR>
|
||||
<B>Photo:</B>:
|
||||
"}
|
||||
if(GLOB.news_network.wanted_issue.img)
|
||||
usr << browse_rsc(GLOB.news_network.wanted_issue.img, "tmp_photow.png")
|
||||
dat+="<BR><img src='tmp_photow.png' width = '180'>"
|
||||
else
|
||||
dat+="None"
|
||||
dat+="<BR><A href='?src=[UID()];ac_setScreen=[0]'>Back</A><BR>"
|
||||
if(19)
|
||||
dat+={"
|
||||
<FONT COLOR='green'>Wanted issue for [src.admincaster_feed_message.author] successfully edited.</FONT><BR><BR>
|
||||
<BR><A href='?src=[UID()];ac_setScreen=[0]'>Return</A><BR>
|
||||
"}
|
||||
else
|
||||
dat+="I'm sorry to break your immersion. This shit's bugged. Report this bug to Agouri, polyxenitopalidou@gmail.com"
|
||||
|
||||
// to_chat(world, "Channelname: [src.admincaster_feed_channel.channel_name] [src.admincaster_feed_channel.author]")
|
||||
// to_chat(world, "Msg: [src.admincaster_feed_message.author] [src.admincaster_feed_message.body]")
|
||||
usr << browse(dat, "window=admincaster_main;size=400x600")
|
||||
onclose(usr, "admincaster_main")
|
||||
|
||||
/datum/admins/proc/Jobbans()
|
||||
if(!check_rights(R_BAN))
|
||||
return
|
||||
@@ -594,6 +366,25 @@ GLOBAL_VAR_INIT(nologevent, 0)
|
||||
feedback_add_details("admin_verb","R") //If you are copy-pasting this, ensure the 2nd parameter is unique to the new proc!
|
||||
world.Reboot("Initiated by [usr.client.holder.fakekey ? "Admin" : usr.key].", "end_error", "admin reboot - by [usr.key] [usr.client.holder.fakekey ? "(stealth)" : ""]", delay)
|
||||
|
||||
/datum/admins/proc/end_round()
|
||||
set category = "Server"
|
||||
set name = "End Round"
|
||||
set desc = "Instantly ends the round and brings up the scoreboard, like shadowlings or wizards dying."
|
||||
if(!check_rights(R_SERVER))
|
||||
return
|
||||
var/input = sanitize(copytext(input(usr, "What text should players see announcing the round end? Input nothing to cancel.", "Specify Announcement Text", "Shift Has Ended!"), 1, MAX_MESSAGE_LEN))
|
||||
|
||||
if(!input)
|
||||
return
|
||||
if(SSticker.force_ending)
|
||||
return
|
||||
message_admins("[key_name_admin(usr)] has admin ended the round with message: '[input]'")
|
||||
log_admin("[key_name(usr)] has admin ended the round with message: '[input]'")
|
||||
SSticker.force_ending = TRUE
|
||||
to_chat(world, "<span class='warning'><big><b>[input]</b></big></span>")
|
||||
feedback_add_details("admin_verb", "END") //If you are copy-pasting this, ensure the 2nd parameter is unique to the new proc!
|
||||
feedback_set_details("round_end_result", "Admin ended")
|
||||
|
||||
/datum/admins/proc/announce()
|
||||
set category = "Admin"
|
||||
set name = "Announce"
|
||||
|
||||
@@ -98,7 +98,6 @@ GLOBAL_LIST_INIT(admin_verbs_event, list(
|
||||
/client/proc/toggle_ert_calling,
|
||||
/client/proc/show_tip,
|
||||
/client/proc/cmd_admin_change_custom_event,
|
||||
/datum/admins/proc/access_news_network, /*allows access of newscasters*/
|
||||
/client/proc/cmd_admin_subtle_message, /*send an message to somebody as a 'voice in their head'*/
|
||||
/client/proc/cmd_admin_direct_narrate, /*send text directly to a player with no padding. Useful for narratives and fluff-text*/
|
||||
/client/proc/cmd_admin_world_narrate, /*sends text to all players with no padding*/
|
||||
@@ -123,6 +122,7 @@ GLOBAL_LIST_INIT(admin_verbs_server, list(
|
||||
/client/proc/Set_Holiday,
|
||||
/datum/admins/proc/startnow,
|
||||
/datum/admins/proc/restart,
|
||||
/datum/admins/proc/end_round,
|
||||
/datum/admins/proc/delay,
|
||||
/datum/admins/proc/toggleaban,
|
||||
/datum/admins/proc/toggleenter, /*toggles whether people can join the current game*/
|
||||
@@ -888,9 +888,9 @@ GLOBAL_LIST_INIT(admin_verbs_ticket, list(
|
||||
if(!check_rights(R_ADMIN))
|
||||
return
|
||||
|
||||
prefs.toggles ^= CHAT_NO_ADMINLOGS
|
||||
prefs.toggles ^= PREFTOGGLE_CHAT_NO_ADMINLOGS
|
||||
prefs.save_preferences(src)
|
||||
if(prefs.toggles & CHAT_NO_ADMINLOGS)
|
||||
if(prefs.toggles & PREFTOGGLE_CHAT_NO_ADMINLOGS)
|
||||
to_chat(usr, "You now won't get admin log messages.")
|
||||
else
|
||||
to_chat(usr, "You now will get admin log messages.")
|
||||
@@ -902,9 +902,9 @@ GLOBAL_LIST_INIT(admin_verbs_ticket, list(
|
||||
if(!check_rights(R_MENTOR|R_ADMIN))
|
||||
return
|
||||
|
||||
prefs.toggles ^= CHAT_NO_MENTORTICKETLOGS
|
||||
prefs.toggles ^= PREFTOGGLE_CHAT_NO_MENTORTICKETLOGS
|
||||
prefs.save_preferences(src)
|
||||
if(prefs.toggles & CHAT_NO_MENTORTICKETLOGS)
|
||||
if(prefs.toggles & PREFTOGGLE_CHAT_NO_MENTORTICKETLOGS)
|
||||
to_chat(usr, "You now won't get mentor ticket messages.")
|
||||
else
|
||||
to_chat(usr, "You now will get mentor ticket messages.")
|
||||
@@ -916,9 +916,9 @@ GLOBAL_LIST_INIT(admin_verbs_ticket, list(
|
||||
if(!check_rights(R_ADMIN))
|
||||
return
|
||||
|
||||
prefs.toggles ^= CHAT_NO_TICKETLOGS
|
||||
prefs.toggles ^= PREFTOGGLE_CHAT_NO_TICKETLOGS
|
||||
prefs.save_preferences(src)
|
||||
if(prefs.toggles & CHAT_NO_TICKETLOGS)
|
||||
if(prefs.toggles & PREFTOGGLE_CHAT_NO_TICKETLOGS)
|
||||
to_chat(usr, "You now won't get admin ticket messages.")
|
||||
else
|
||||
to_chat(usr, "You now will get admin ticket messages.")
|
||||
@@ -941,9 +941,9 @@ GLOBAL_LIST_INIT(admin_verbs_ticket, list(
|
||||
if(!check_rights(R_DEBUG))
|
||||
return
|
||||
|
||||
prefs.toggles ^= CHAT_DEBUGLOGS
|
||||
prefs.toggles ^= PREFTOGGLE_CHAT_DEBUGLOGS
|
||||
prefs.save_preferences(src)
|
||||
if(prefs.toggles & CHAT_DEBUGLOGS)
|
||||
if(prefs.toggles & PREFTOGGLE_CHAT_DEBUGLOGS)
|
||||
to_chat(usr, "You now will get debug log messages")
|
||||
else
|
||||
to_chat(usr, "You now won't get debug log messages")
|
||||
|
||||
+13
-225
@@ -26,17 +26,16 @@
|
||||
message_admins("[key_name_admin(usr)] rejected [key_name_admin(C.mob)]'s admin help")
|
||||
log_admin("[key_name(usr)] rejected [key_name(C.mob)]'s admin help")
|
||||
|
||||
if(href_list["openadminticket"])
|
||||
if(!check_rights(R_ADMIN))
|
||||
return
|
||||
var/ticketID = text2num(href_list["openadminticket"])
|
||||
SStickets.showDetailUI(usr, ticketID)
|
||||
|
||||
if(href_list["openmentorticket"])
|
||||
if(!check_rights(R_MENTOR|R_MOD|R_ADMIN))
|
||||
return
|
||||
var/ticketID = text2num(href_list["openmentorticket"])
|
||||
SSmentor_tickets.showDetailUI(usr, ticketID)
|
||||
if(href_list["openticket"])
|
||||
var/ticketID = text2num(href_list["openticket"])
|
||||
if(!href_list["is_mhelp"])
|
||||
if(!check_rights(R_ADMIN))
|
||||
return
|
||||
SStickets.showDetailUI(usr, ticketID)
|
||||
else
|
||||
if(!check_rights(R_MENTOR|R_MOD|R_ADMIN))
|
||||
return
|
||||
SSmentor_tickets.showDetailUI(usr, ticketID)
|
||||
|
||||
if(href_list["stickyban"])
|
||||
stickyban(href_list["stickyban"],href_list)
|
||||
@@ -1669,6 +1668,9 @@
|
||||
SStickets.resolveTicket(index)
|
||||
|
||||
else if(href_list["autorespond"])
|
||||
if(href_list["is_mhelp"])
|
||||
to_chat(usr, "<span class='warning'>Auto responses are not available for mentor helps.</span>")
|
||||
return
|
||||
var/index = text2num(href_list["autorespond"])
|
||||
if(!check_rights(R_ADMIN|R_MOD))
|
||||
return
|
||||
@@ -3214,220 +3216,6 @@
|
||||
J.spawn_positions = -1
|
||||
message_admins("[key_name_admin(usr)] has removed the cap on security officers.")
|
||||
|
||||
else if(href_list["ac_view_wanted"]) //Admin newscaster Topic() stuff be here
|
||||
src.admincaster_screen = 18 //The ac_ prefix before the hrefs stands for AdminCaster.
|
||||
src.access_news_network()
|
||||
|
||||
else if(href_list["ac_set_channel_name"])
|
||||
src.admincaster_feed_channel.channel_name = strip_html_simple(input(usr, "Provide a Feed Channel Name", "Network Channel Handler", ""))
|
||||
while(findtext(src.admincaster_feed_channel.channel_name," ") == 1)
|
||||
src.admincaster_feed_channel.channel_name = copytext(src.admincaster_feed_channel.channel_name,2,length(src.admincaster_feed_channel.channel_name)+1)
|
||||
src.access_news_network()
|
||||
|
||||
else if(href_list["ac_set_channel_lock"])
|
||||
src.admincaster_feed_channel.locked = !src.admincaster_feed_channel.locked
|
||||
src.access_news_network()
|
||||
|
||||
else if(href_list["ac_submit_new_channel"])
|
||||
var/check = 0
|
||||
for(var/datum/feed_channel/FC in GLOB.news_network.network_channels)
|
||||
if(FC.channel_name == src.admincaster_feed_channel.channel_name)
|
||||
check = 1
|
||||
break
|
||||
if(src.admincaster_feed_channel.channel_name == "" || src.admincaster_feed_channel.channel_name == "\[REDACTED\]" || check )
|
||||
src.admincaster_screen=7
|
||||
else
|
||||
var/choice = alert("Please confirm Feed channel creation","Network Channel Handler","Confirm","Cancel")
|
||||
if(choice=="Confirm")
|
||||
var/datum/feed_channel/newChannel = new /datum/feed_channel
|
||||
newChannel.channel_name = src.admincaster_feed_channel.channel_name
|
||||
newChannel.author = src.admincaster_signature
|
||||
newChannel.locked = src.admincaster_feed_channel.locked
|
||||
newChannel.is_admin_channel = 1
|
||||
feedback_inc("newscaster_channels",1)
|
||||
GLOB.news_network.network_channels += newChannel //Adding channel to the global network
|
||||
log_admin("[key_name_admin(usr)] created command feed channel: [src.admincaster_feed_channel.channel_name]!")
|
||||
src.admincaster_screen=5
|
||||
src.access_news_network()
|
||||
|
||||
else if(href_list["ac_set_channel_receiving"])
|
||||
var/list/available_channels = list()
|
||||
for(var/datum/feed_channel/F in GLOB.news_network.network_channels)
|
||||
available_channels += F.channel_name
|
||||
src.admincaster_feed_channel.channel_name = adminscrub(input(usr, "Choose receiving Feed Channel", "Network Channel Handler") in available_channels )
|
||||
src.access_news_network()
|
||||
|
||||
else if(href_list["ac_set_new_message"])
|
||||
src.admincaster_feed_message.body = adminscrub(input(usr, "Write your Feed story", "Network Channel Handler", ""))
|
||||
while(findtext(src.admincaster_feed_message.body," ") == 1)
|
||||
src.admincaster_feed_message.body = copytext(src.admincaster_feed_message.body,2,length(src.admincaster_feed_message.body)+1)
|
||||
src.access_news_network()
|
||||
|
||||
else if(href_list["ac_submit_new_message"])
|
||||
if(src.admincaster_feed_message.body =="" || src.admincaster_feed_message.body =="\[REDACTED\]" || src.admincaster_feed_channel.channel_name == "" )
|
||||
src.admincaster_screen = 6
|
||||
else
|
||||
var/datum/feed_message/newMsg = new /datum/feed_message
|
||||
newMsg.author = src.admincaster_signature
|
||||
newMsg.body = src.admincaster_feed_message.body
|
||||
newMsg.is_admin_message = 1
|
||||
feedback_inc("newscaster_stories",1)
|
||||
for(var/datum/feed_channel/FC in GLOB.news_network.network_channels)
|
||||
if(FC.channel_name == src.admincaster_feed_channel.channel_name)
|
||||
FC.messages += newMsg //Adding message to the network's appropriate feed_channel
|
||||
break
|
||||
src.admincaster_screen=4
|
||||
|
||||
for(var/obj/machinery/newscaster/NEWSCASTER in GLOB.allNewscasters)
|
||||
NEWSCASTER.newsAlert(src.admincaster_feed_channel.channel_name)
|
||||
|
||||
log_admin("[key_name_admin(usr)] submitted a feed story to channel: [src.admincaster_feed_channel.channel_name]!")
|
||||
src.access_news_network()
|
||||
|
||||
else if(href_list["ac_create_channel"])
|
||||
src.admincaster_screen=2
|
||||
src.access_news_network()
|
||||
|
||||
else if(href_list["ac_create_feed_story"])
|
||||
src.admincaster_screen=3
|
||||
src.access_news_network()
|
||||
|
||||
else if(href_list["ac_menu_censor_story"])
|
||||
src.admincaster_screen=10
|
||||
src.access_news_network()
|
||||
|
||||
else if(href_list["ac_menu_censor_channel"])
|
||||
src.admincaster_screen=11
|
||||
src.access_news_network()
|
||||
|
||||
else if(href_list["ac_menu_wanted"])
|
||||
var/already_wanted = 0
|
||||
if(GLOB.news_network.wanted_issue)
|
||||
already_wanted = 1
|
||||
|
||||
if(already_wanted)
|
||||
src.admincaster_feed_message.author = GLOB.news_network.wanted_issue.author
|
||||
src.admincaster_feed_message.body = GLOB.news_network.wanted_issue.body
|
||||
src.admincaster_screen = 14
|
||||
src.access_news_network()
|
||||
|
||||
else if(href_list["ac_set_wanted_name"])
|
||||
src.admincaster_feed_message.author = adminscrub(input(usr, "Provide the name of the Wanted person", "Network Security Handler", ""))
|
||||
while(findtext(src.admincaster_feed_message.author," ") == 1)
|
||||
src.admincaster_feed_message.author = copytext(admincaster_feed_message.author,2,length(admincaster_feed_message.author)+1)
|
||||
src.access_news_network()
|
||||
|
||||
else if(href_list["ac_set_wanted_desc"])
|
||||
src.admincaster_feed_message.body = adminscrub(input(usr, "Provide the a description of the Wanted person and any other details you deem important", "Network Security Handler", ""))
|
||||
while(findtext(src.admincaster_feed_message.body," ") == 1)
|
||||
src.admincaster_feed_message.body = copytext(src.admincaster_feed_message.body,2,length(src.admincaster_feed_message.body)+1)
|
||||
src.access_news_network()
|
||||
|
||||
else if(href_list["ac_submit_wanted"])
|
||||
var/input_param = text2num(href_list["ac_submit_wanted"])
|
||||
if(src.admincaster_feed_message.author == "" || src.admincaster_feed_message.body == "")
|
||||
src.admincaster_screen = 16
|
||||
else
|
||||
var/choice = alert("Please confirm Wanted Issue [(input_param==1) ? ("creation.") : ("edit.")]","Network Security Handler","Confirm","Cancel")
|
||||
if(choice=="Confirm")
|
||||
if(input_param==1) //If input_param == 1 we're submitting a new wanted issue. At 2 we're just editing an existing one. See the else below
|
||||
var/datum/feed_message/WANTED = new /datum/feed_message
|
||||
WANTED.author = src.admincaster_feed_message.author //Wanted name
|
||||
WANTED.body = src.admincaster_feed_message.body //Wanted desc
|
||||
WANTED.backup_author = src.admincaster_signature //Submitted by
|
||||
WANTED.is_admin_message = 1
|
||||
GLOB.news_network.wanted_issue = WANTED
|
||||
for(var/obj/machinery/newscaster/NEWSCASTER in GLOB.allNewscasters)
|
||||
NEWSCASTER.newsAlert()
|
||||
NEWSCASTER.update_icon()
|
||||
src.admincaster_screen = 15
|
||||
else
|
||||
GLOB.news_network.wanted_issue.author = src.admincaster_feed_message.author
|
||||
GLOB.news_network.wanted_issue.body = src.admincaster_feed_message.body
|
||||
GLOB.news_network.wanted_issue.backup_author = src.admincaster_feed_message.backup_author
|
||||
src.admincaster_screen = 19
|
||||
log_admin("[key_name_admin(usr)] issued a Station-wide Wanted Notification for [src.admincaster_feed_message.author]!")
|
||||
src.access_news_network()
|
||||
|
||||
else if(href_list["ac_cancel_wanted"])
|
||||
var/choice = alert("Please confirm Wanted Issue removal","Network Security Handler","Confirm","Cancel")
|
||||
if(choice=="Confirm")
|
||||
GLOB.news_network.wanted_issue = null
|
||||
for(var/obj/machinery/newscaster/NEWSCASTER in GLOB.allNewscasters)
|
||||
NEWSCASTER.update_icon()
|
||||
src.admincaster_screen=17
|
||||
src.access_news_network()
|
||||
|
||||
else if(href_list["ac_censor_channel_author"])
|
||||
var/datum/feed_channel/FC = locate(href_list["ac_censor_channel_author"])
|
||||
if(FC.author != "<b>\[REDACTED\]</b>")
|
||||
FC.backup_author = FC.author
|
||||
FC.author = "<b>\[REDACTED\]</b>"
|
||||
else
|
||||
FC.author = FC.backup_author
|
||||
src.access_news_network()
|
||||
|
||||
else if(href_list["ac_censor_channel_story_author"])
|
||||
var/datum/feed_message/MSG = locate(href_list["ac_censor_channel_story_author"])
|
||||
if(MSG.author != "<b>\[REDACTED\]</b>")
|
||||
MSG.backup_author = MSG.author
|
||||
MSG.author = "<b>\[REDACTED\]</b>"
|
||||
else
|
||||
MSG.author = MSG.backup_author
|
||||
src.access_news_network()
|
||||
|
||||
else if(href_list["ac_censor_channel_story_body"])
|
||||
var/datum/feed_message/MSG = locate(href_list["ac_censor_channel_story_body"])
|
||||
if(MSG.body != "<b>\[REDACTED\]</b>")
|
||||
MSG.backup_body = MSG.body
|
||||
MSG.body = "<b>\[REDACTED\]</b>"
|
||||
else
|
||||
MSG.body = MSG.backup_body
|
||||
src.access_news_network()
|
||||
|
||||
else if(href_list["ac_pick_d_notice"])
|
||||
var/datum/feed_channel/FC = locate(href_list["ac_pick_d_notice"])
|
||||
src.admincaster_feed_channel = FC
|
||||
src.admincaster_screen=13
|
||||
src.access_news_network()
|
||||
|
||||
else if(href_list["ac_toggle_d_notice"])
|
||||
var/datum/feed_channel/FC = locate(href_list["ac_toggle_d_notice"])
|
||||
FC.censored = !FC.censored
|
||||
src.access_news_network()
|
||||
|
||||
else if(href_list["ac_view"])
|
||||
src.admincaster_screen=1
|
||||
src.access_news_network()
|
||||
|
||||
else if(href_list["ac_setScreen"]) //Brings us to the main menu and resets all fields~
|
||||
src.admincaster_screen = text2num(href_list["ac_setScreen"])
|
||||
if(src.admincaster_screen == 0)
|
||||
if(src.admincaster_feed_channel)
|
||||
src.admincaster_feed_channel = new /datum/feed_channel
|
||||
if(src.admincaster_feed_message)
|
||||
src.admincaster_feed_message = new /datum/feed_message
|
||||
src.access_news_network()
|
||||
|
||||
else if(href_list["ac_show_channel"])
|
||||
var/datum/feed_channel/FC = locate(href_list["ac_show_channel"])
|
||||
src.admincaster_feed_channel = FC
|
||||
src.admincaster_screen = 9
|
||||
src.access_news_network()
|
||||
|
||||
else if(href_list["ac_pick_censor_channel"])
|
||||
var/datum/feed_channel/FC = locate(href_list["ac_pick_censor_channel"])
|
||||
src.admincaster_feed_channel = FC
|
||||
src.admincaster_screen = 12
|
||||
src.access_news_network()
|
||||
|
||||
else if(href_list["ac_refresh"])
|
||||
src.access_news_network()
|
||||
|
||||
else if(href_list["ac_set_signature"])
|
||||
src.admincaster_signature = adminscrub(input(usr, "Provide your desired signature", "Network Identity Handler", ""))
|
||||
src.access_news_network()
|
||||
|
||||
if(href_list["secretsmenu"])
|
||||
switch(href_list["secretsmenu"])
|
||||
if("tab")
|
||||
|
||||
@@ -29,64 +29,12 @@ GLOBAL_LIST_INIT(adminhelp_ignored_words, list("unknown","the","a","an","of","mo
|
||||
|
||||
msg = sanitize_simple(copytext(msg,1,MAX_MESSAGE_LEN))
|
||||
if(!msg) return
|
||||
var/original_msg = msg
|
||||
if(selected_type == "Mentorhelp")
|
||||
SSmentor_tickets.newHelpRequest(src, msg)
|
||||
else
|
||||
SStickets.newHelpRequest(src, msg)
|
||||
|
||||
//explode the input msg into a list
|
||||
var/list/msglist = splittext(msg, " ")
|
||||
|
||||
//generate keywords lookup
|
||||
var/list/surnames = list()
|
||||
var/list/forenames = list()
|
||||
var/list/ckeys = list()
|
||||
for(var/mob/M in GLOB.mob_list)
|
||||
var/list/indexing = list(M.real_name, M.name)
|
||||
if(M.mind) indexing += M.mind.name
|
||||
|
||||
for(var/string in indexing)
|
||||
var/list/L = splittext(string, " ")
|
||||
var/surname_found = 0
|
||||
//surnames
|
||||
for(var/i=L.len, i>=1, i--)
|
||||
var/word = ckey(L[i])
|
||||
if(word)
|
||||
surnames[word] = M
|
||||
surname_found = i
|
||||
break
|
||||
//forenames
|
||||
for(var/i=1, i<surname_found, i++)
|
||||
var/word = ckey(L[i])
|
||||
if(word)
|
||||
forenames[word] = M
|
||||
//ckeys
|
||||
ckeys[M.ckey] = M
|
||||
|
||||
var/ai_found = 0
|
||||
msg = ""
|
||||
var/list/mobs_found = list()
|
||||
for(var/original_word in msglist)
|
||||
var/word = ckey(original_word)
|
||||
if(word)
|
||||
if(!(word in GLOB.adminhelp_ignored_words))
|
||||
if(word == "ai")
|
||||
ai_found = 1
|
||||
else
|
||||
var/mob/found = ckeys[word]
|
||||
if(!found)
|
||||
found = surnames[word]
|
||||
if(!found)
|
||||
found = forenames[word]
|
||||
if(found)
|
||||
if(!(found in mobs_found))
|
||||
mobs_found += found
|
||||
if(!ai_found && isAI(found))
|
||||
ai_found = 1
|
||||
msg += "<b><span class='adminnotice'>[original_word] </span></b> "
|
||||
continue
|
||||
msg += "[original_word] "
|
||||
|
||||
if(!mob) return //this doesn't happen
|
||||
|
||||
//send this msg to all admins
|
||||
//See how many staff are on
|
||||
var/admin_number_afk = 0
|
||||
var/list/mentorholders = list()
|
||||
var/list/modholders = list()
|
||||
@@ -103,65 +51,19 @@ GLOBAL_LIST_INIT(adminhelp_ignored_words, list("unknown","the","a","an","of","mo
|
||||
if(check_rights(R_MENTOR, 0, X.mob))
|
||||
mentorholders += X
|
||||
continue
|
||||
var/ticketNum // Holder for the ticket number
|
||||
var/prunedmsg ="[src]: [msg]" // Message without links
|
||||
var/datum/ticket/T
|
||||
var/isMhelp = selected_type == "Mentorhelp"
|
||||
var/span
|
||||
if(isMhelp)
|
||||
span = "<span class='mentorhelp'>"
|
||||
if(SSmentor_tickets.checkForOpenTicket(src)) // If user already has an open ticket
|
||||
T = SSmentor_tickets.checkForOpenTicket(src)
|
||||
else
|
||||
ticketNum = SSmentor_tickets.getTicketCounter() // ticketNum is the ticket ready to be assigned.
|
||||
else //Ahelp
|
||||
span = "<span class='adminhelp'>"
|
||||
if(SStickets.checkForOpenTicket(src)) // If user already has an open ticket
|
||||
T = SStickets.checkForOpenTicket(src) // Make T equal to the ticket they have open
|
||||
else
|
||||
ticketNum = SStickets.getTicketCounter() // ticketNum is the ticket ready to be assigned.
|
||||
|
||||
if(T)
|
||||
ticketNum = T.ticketNum // ticketNum is the number of their ticket.
|
||||
T.addResponse(src, msg)
|
||||
|
||||
var/finalised_msg = "[span][selected_type]: </span><span class='boldnotice'>[key_name(src, TRUE, selected_type)] "
|
||||
finalised_msg += "([ADMIN_QUE(mob,"?")]) ([ADMIN_PP(mob,"PP")]) ([ADMIN_VV(mob,"VV")]) ([ADMIN_TP(mob,"TP")]) ([ADMIN_SM(mob,"SM")]) "
|
||||
finalised_msg += "([admin_jump_link(mob)]) (<A HREF='?_src_=holder;[isMhelp ? "openmentorticket" : "openadminticket"]=[ticketNum]'>TICKET</A>) "
|
||||
finalised_msg += "[ai_found ? "(<A HREF='?_src_=holder;adminchecklaws=[mob.UID()]'>CL</A>)" : ""] (<A HREF='?_src_=holder;take_question=[ticketNum][isMhelp ? ";is_mhelp=1" : ""]'>TAKE</A>) "
|
||||
finalised_msg += "(<A HREF='?_src_=holder;resolve=[ticketNum][isMhelp ? ";is_mhelp=1" : ""]'>RESOLVE</A>) [isMhelp ? "" : "<A HREF='?_src_=holder;autorespond=[ticketNum]'>(AUTO)</A>"] "
|
||||
finalised_msg += "<a href='?_src_=holder;convert_ticket=[ticketNum][isMhelp ? ";is_mhelp=1" : ""]'>(CONVERT)</a> :</span> [span][msg]</span>"
|
||||
|
||||
if(isMhelp)
|
||||
//Open a new adminticket and inform the user.
|
||||
SSmentor_tickets.newTicket(src, prunedmsg, finalised_msg)
|
||||
for(var/client/X in mentorholders + modholders + adminholders)
|
||||
if(X.prefs.sound & SOUND_MENTORHELP)
|
||||
SEND_SOUND(X, 'sound/effects/adminhelp.ogg')
|
||||
to_chat(X, finalised_msg)
|
||||
else //Ahelp
|
||||
//Open a new adminticket and inform the user.
|
||||
SStickets.newTicket(src, prunedmsg, finalised_msg)
|
||||
for(var/client/X in modholders + adminholders)
|
||||
if(X.prefs.sound & SOUND_ADMINHELP)
|
||||
SEND_SOUND(X, 'sound/effects/adminhelp.ogg')
|
||||
window_flash(X)
|
||||
to_chat(X, finalised_msg)
|
||||
|
||||
|
||||
|
||||
//show it to the person adminhelping too
|
||||
to_chat(src, "<span class='boldnotice'>[selected_type]</b>: [original_msg]</span>")
|
||||
to_chat(src, "<span class='boldnotice'>[selected_type]</b>: [msg]</span>")
|
||||
|
||||
var/admin_number_present = adminholders.len - admin_number_afk
|
||||
log_admin("[selected_type]: [key_name(src)]: [original_msg] - heard by [admin_number_present] non-AFK admins.")
|
||||
log_admin("[selected_type]: [key_name(src)]: [msg] - heard by [admin_number_present] non-AFK admins.")
|
||||
if(admin_number_present <= 0)
|
||||
if(!admin_number_afk)
|
||||
send2adminirc("[selected_type] from [key_name(src)]: [original_msg] - !!No admins online!!")
|
||||
send2adminirc("[selected_type] from [key_name(src)]: [msg] - !!No admins online!!")
|
||||
else
|
||||
send2adminirc("[selected_type] from [key_name(src)]: [original_msg] - !!All admins AFK ([admin_number_afk])!!")
|
||||
send2adminirc("[selected_type] from [key_name(src)]: [msg] - !!All admins AFK ([admin_number_afk])!!")
|
||||
else
|
||||
send2adminirc("[selected_type] from [key_name(src)]: [original_msg]")
|
||||
send2adminirc("[selected_type] from [key_name(src)]: [msg]")
|
||||
feedback_add_details("admin_verb","AH") //If you are copy-pasting this, ensure the 2nd parameter is unique to the new proc!
|
||||
return
|
||||
|
||||
|
||||
@@ -2,18 +2,18 @@
|
||||
set category = "Admin"
|
||||
set name = "Dsay" //Gave this shit a shorter name so you only have to time out "dsay" rather than "dead say" to use it --NeoFite
|
||||
set hidden = 1
|
||||
|
||||
|
||||
if(!check_rights(R_ADMIN|R_MOD))
|
||||
return
|
||||
|
||||
|
||||
if(!src.mob)
|
||||
return
|
||||
|
||||
|
||||
if(prefs.muted & MUTE_DEADCHAT)
|
||||
to_chat(src, "<span class='warning'>You cannot send DSAY messages (muted).</span>")
|
||||
return
|
||||
|
||||
if(!(prefs.toggles & CHAT_DEAD))
|
||||
if(!(prefs.toggles & PREFTOGGLE_CHAT_DEAD))
|
||||
to_chat(src, "<span class='warning'>You have deadchat muted.</span>")
|
||||
return
|
||||
|
||||
|
||||
@@ -90,6 +90,7 @@
|
||||
This facility is sealed shut by order of Commander Marquez. Do not enter.<br>
|
||||
Terror spiders live here. We believe they are a weapon developed by the syndicate.<br>
|
||||
Any surviving personnel are to evacuate immediately via the gateway.<br>
|
||||
Any arriving response team is advised to use the ID Upgrade Machine to obtain local access.<br>
|
||||
"}
|
||||
|
||||
/obj/item/paper/terrorspiders2
|
||||
@@ -134,10 +135,10 @@
|
||||
name = "paper - 'Prescription for Jones, David'"
|
||||
info = {"PRESCRIPTION FOR: David Jones<br>
|
||||
RANK: Miner<br>
|
||||
FOR: Haloperidol<br>
|
||||
REASON FOR TREATMENT: Hallucinations, Paranoia<br>
|
||||
CAUSE: Hallucinations caused by encounter with toxic spit of spider in the caves. Paranoia caused by disappearing staff and suspicions of syndicate infiltration.<br>
|
||||
TREATMENT PLAN: Take as needed. See Dr. Phloxi in one week if symptoms persist. <br>
|
||||
FOR: Charcoal<br>
|
||||
REASON FOR TREATMENT: Toxins in bloodstream<br>
|
||||
CAUSE: Bitten by a black terror spider.<br>
|
||||
TREATMENT PLAN: Take hourly. See Dr. Phloxi if symptoms persist more than three hours.<br>
|
||||
"}
|
||||
|
||||
/obj/item/paper/terrorspiders5
|
||||
@@ -149,7 +150,7 @@
|
||||
<p>Green<br>Will lay eggs on dead bodies, breeding more spiders.</p>
|
||||
<p>Black<br>Even a single bite is enough to kill a humanoid, given time.</p>
|
||||
<p>White<br>Injects a parasitic agent. Deemed to pose too great an infection risk to study.</p>
|
||||
<p>Purple<br>Only seen guarding the nest of the Queen to the south. Appear to be territorial, and very dangerous.</p>
|
||||
<p>Purple<br>Seen guarding key areas and important spiders. Appear to be territorial, and very dangerous.</p>
|
||||
<p>Prince<br>Held in containment 2. Appears to be a sort of super-warrior. Fast, strong, and thickly armored.</p>
|
||||
<p>Mother<br>Carries hordes of spiderlings on its back. Held in containment 1. </p>
|
||||
<p>Queen<br>Unable to contain. Present south of Cargo before contact was lost. Presumed ruler of the local hive.</p>
|
||||
|
||||
@@ -398,14 +398,14 @@
|
||||
check_ip_intel()
|
||||
send_resources()
|
||||
|
||||
if(prefs.toggles & UI_DARKMODE) // activates dark mode if its flagged. -AA07
|
||||
if(prefs.toggles & PREFTOGGLE_UI_DARKMODE) // activates dark mode if its flagged. -AA07
|
||||
activate_darkmode()
|
||||
else
|
||||
// activate_darkmode() calls the CL update button proc, so we dont want it double called
|
||||
SSchangelog.UpdatePlayerChangelogButton(src)
|
||||
|
||||
|
||||
if(prefs.toggles & DISABLE_KARMA) // activates if karma is disabled
|
||||
if(prefs.toggles & PREFTOGGLE_DISABLE_KARMA) // activates if karma is disabled
|
||||
if(establish_db_connection())
|
||||
to_chat(src,"<span class='notice'>You have disabled karma gains.") // reminds those who have it disabled
|
||||
else
|
||||
|
||||
@@ -83,20 +83,14 @@ GLOBAL_LIST_INIT(special_role_times, list( //minimum age (in days) for accounts
|
||||
var/ooccolor = "#b82e00"
|
||||
var/list/be_special = list() //Special role selection
|
||||
var/UI_style = "Midnight"
|
||||
var/nanoui_fancy = TRUE
|
||||
var/toggles = TOGGLES_DEFAULT
|
||||
var/toggles2 = TOGGLES_2_DEFAULT // Created because 1 column has a bitflag limit of 24 (BYOND limitation not MySQL)
|
||||
var/sound = SOUND_DEFAULT
|
||||
var/show_ghostitem_attack = TRUE
|
||||
var/UI_style_color = "#ffffff"
|
||||
var/UI_style_alpha = 255
|
||||
var/windowflashing = TRUE
|
||||
var/clientfps = 0
|
||||
var/atklog = ATKLOG_ALL
|
||||
var/fuid // forum userid
|
||||
var/afk_watch = FALSE // If the player wants to be kept track of by the AFK system
|
||||
|
||||
//ghostly preferences
|
||||
var/ghost_anonsay = 0
|
||||
|
||||
//character preferences
|
||||
var/real_name //our character's name
|
||||
@@ -190,9 +184,6 @@ GLOBAL_LIST_INIT(special_role_times, list( //minimum age (in days) for accounts
|
||||
var/slot_name = ""
|
||||
var/saved = FALSE // Indicates whether the character comes from the database or not
|
||||
|
||||
// Whether or not to use randomized character slots
|
||||
var/randomslot = 0
|
||||
|
||||
// jukebox volume
|
||||
var/volume = 100
|
||||
|
||||
@@ -447,24 +438,24 @@ GLOBAL_LIST_INIT(special_role_times, list( //minimum age (in days) for accounts
|
||||
dat += "<h2>General Settings</h2>"
|
||||
if(user.client.holder)
|
||||
dat += "<b>Adminhelp sound:</b> <a href='?_src_=prefs;preference=hear_adminhelps'><b>[(sound & SOUND_ADMINHELP)?"On":"Off"]</b></a><br>"
|
||||
dat += "<b>AFK Cryoing:</b> <a href='?_src_=prefs;preference=afk_watch'>[(afk_watch) ? "Yes" : "No"]</a><br>"
|
||||
dat += "<b>Ambient Occlusion:</b> <a href='?_src_=prefs;preference=ambientocclusion'><b>[toggles & AMBIENT_OCCLUSION ? "Enabled" : "Disabled"]</b></a><br>"
|
||||
dat += "<b>Attack Animations:</b> <a href='?_src_=prefs;preference=ghost_att_anim'>[(show_ghostitem_attack) ? "Yes" : "No"]</a><br>"
|
||||
dat += "<b>AFK Cryoing:</b> <a href='?_src_=prefs;preference=afk_watch'>[(toggles2 & PREFTOGGLE_2_AFKWATCH) ? "Yes" : "No"]</a><br>"
|
||||
dat += "<b>Ambient Occlusion:</b> <a href='?_src_=prefs;preference=ambientocclusion'><b>[toggles & PREFTOGGLE_AMBIENT_OCCLUSION ? "Enabled" : "Disabled"]</b></a><br>"
|
||||
dat += "<b>Attack Animations:</b> <a href='?_src_=prefs;preference=ghost_att_anim'>[(toggles2 & PREFTOGGLE_2_ITEMATTACK) ? "Yes" : "No"]</a><br>"
|
||||
if(unlock_content)
|
||||
dat += "<b>BYOND Membership Publicity:</b> <a href='?_src_=prefs;preference=publicity'><b>[(toggles & MEMBER_PUBLIC) ? "Public" : "Hidden"]</b></a><br>"
|
||||
dat += "<b>BYOND Membership Publicity:</b> <a href='?_src_=prefs;preference=publicity'><b>[(toggles & PREFTOGGLE_MEMBER_PUBLIC) ? "Public" : "Hidden"]</b></a><br>"
|
||||
dat += "<b>Custom UI settings:</b><br>"
|
||||
dat += " - <b>Alpha (transparency):</b> <a href='?_src_=prefs;preference=UIalpha'><b>[UI_style_alpha]</b></a><br>"
|
||||
dat += " - <b>Color:</b> <a href='?_src_=prefs;preference=UIcolor'><b>[UI_style_color]</b></a> <span style='border: 1px solid #161616; background-color: [UI_style_color];'> </span><br>"
|
||||
dat += " - <b>UI Style:</b> <a href='?_src_=prefs;preference=ui'><b>[UI_style]</b></a><br>"
|
||||
dat += "<b>Deadchat Anonymity:</b> <a href='?_src_=prefs;preference=ghost_anonsay'><b>[ghost_anonsay ? "Anonymous" : "Not Anonymous"]</b></a><br>"
|
||||
dat += "<b>Deadchat Anonymity:</b> <a href='?_src_=prefs;preference=ghost_anonsay'><b>[toggles2 & PREFTOGGLE_2_ANONDCHAT ? "Anonymous" : "Not Anonymous"]</b></a><br>"
|
||||
if(user.client.donator_level > 0)
|
||||
dat += "<b>Donator Publicity:</b> <a href='?_src_=prefs;preference=donor_public'><b>[(toggles & DONATOR_PUBLIC) ? "Public" : "Hidden"]</b></a><br>"
|
||||
dat += "<b>Fancy NanoUI:</b> <a href='?_src_=prefs;preference=nanoui'>[(nanoui_fancy) ? "Yes" : "No"]</a><br>"
|
||||
dat += "<b>Donator Publicity:</b> <a href='?_src_=prefs;preference=donor_public'><b>[(toggles & PREFTOGGLE_DONATOR_PUBLIC) ? "Public" : "Hidden"]</b></a><br>"
|
||||
dat += "<b>Fancy NanoUI:</b> <a href='?_src_=prefs;preference=nanoui'>[(toggles2 & PREFTOGGLE_2_FANCYUI) ? "Yes" : "No"]</a><br>"
|
||||
dat += "<b>FPS:</b> <a href='?_src_=prefs;preference=clientfps;task=input'>[clientfps]</a><br>"
|
||||
dat += "<b>Ghost Ears:</b> <a href='?_src_=prefs;preference=ghost_ears'><b>[(toggles & CHAT_GHOSTEARS) ? "All Speech" : "Nearest Creatures"]</b></a><br>"
|
||||
dat += "<b>Ghost Radio:</b> <a href='?_src_=prefs;preference=ghost_radio'><b>[(toggles & CHAT_GHOSTRADIO) ? "All Chatter" : "Nearest Speakers"]</b></a><br>"
|
||||
dat += "<b>Ghost Sight:</b> <a href='?_src_=prefs;preference=ghost_sight'><b>[(toggles & CHAT_GHOSTSIGHT) ? "All Emotes" : "Nearest Creatures"]</b></a><br>"
|
||||
dat += "<b>Ghost PDA:</b> <a href='?_src_=prefs;preference=ghost_pda'><b>[(toggles & CHAT_GHOSTPDA) ? "All PDA Messages" : "No PDA Messages"]</b></a><br>"
|
||||
dat += "<b>Ghost Ears:</b> <a href='?_src_=prefs;preference=ghost_ears'><b>[(toggles & PREFTOGGLE_CHAT_GHOSTEARS) ? "All Speech" : "Nearest Creatures"]</b></a><br>"
|
||||
dat += "<b>Ghost Radio:</b> <a href='?_src_=prefs;preference=ghost_radio'><b>[(toggles & PREFTOGGLE_CHAT_GHOSTRADIO) ? "All Chatter" : "Nearest Speakers"]</b></a><br>"
|
||||
dat += "<b>Ghost Sight:</b> <a href='?_src_=prefs;preference=ghost_sight'><b>[(toggles & PREFTOGGLE_CHAT_GHOSTSIGHT) ? "All Emotes" : "Nearest Creatures"]</b></a><br>"
|
||||
dat += "<b>Ghost PDA:</b> <a href='?_src_=prefs;preference=ghost_pda'><b>[(toggles & PREFTOGGLE_CHAT_GHOSTPDA) ? "All PDA Messages" : "No PDA Messages"]</b></a><br>"
|
||||
if(check_rights(R_ADMIN,0))
|
||||
dat += "<b>OOC Color:</b> <span style='border: 1px solid #161616; background-color: [ooccolor ? ooccolor : GLOB.normal_ooc_colour];'> </span> <a href='?_src_=prefs;preference=ooccolor;task=input'><b>Change</b></a><br>"
|
||||
if(config.allow_Metadata)
|
||||
@@ -484,8 +475,8 @@ GLOBAL_LIST_INIT(special_role_times, list( //minimum age (in days) for accounts
|
||||
dat += "</a><br>"
|
||||
dat += "<b>Play Admin MIDIs:</b> <a href='?_src_=prefs;preference=hear_midis'><b>[(sound & SOUND_MIDI) ? "Yes" : "No"]</b></a><br>"
|
||||
dat += "<b>Play Lobby Music:</b> <a href='?_src_=prefs;preference=lobby_music'><b>[(sound & SOUND_LOBBY) ? "Yes" : "No"]</b></a><br>"
|
||||
dat += "<b>Randomized Character Slot:</b> <a href='?_src_=prefs;preference=randomslot'><b>[randomslot ? "Yes" : "No"]</b></a><br>"
|
||||
dat += "<b>Window Flashing:</b> <a href='?_src_=prefs;preference=winflash'>[(windowflashing) ? "Yes" : "No"]</a><br>"
|
||||
dat += "<b>Randomized Character Slot:</b> <a href='?_src_=prefs;preference=randomslot'><b>[toggles2 & PREFTOGGLE_2_RANDOMSLOT ? "Yes" : "No"]</b></a><br>"
|
||||
dat += "<b>Window Flashing:</b> <a href='?_src_=prefs;preference=winflash'>[(toggles2 & PREFTOGGLE_2_WINDOWFLASHING) ? "Yes" : "No"]</a><br>"
|
||||
// RIGHT SIDE OF THE PAGE
|
||||
dat += "</td><td width='300px' height='300px' valign='top'>"
|
||||
dat += "<h2>Special Role Settings</h2>"
|
||||
@@ -1952,11 +1943,11 @@ GLOBAL_LIST_INIT(special_role_times, list( //minimum age (in days) for accounts
|
||||
switch(href_list["preference"])
|
||||
if("publicity")
|
||||
if(unlock_content)
|
||||
toggles ^= MEMBER_PUBLIC
|
||||
toggles ^= PREFTOGGLE_MEMBER_PUBLIC
|
||||
|
||||
if("donor_public")
|
||||
if(user.client.donator_level > 0)
|
||||
toggles ^= DONATOR_PUBLIC
|
||||
toggles ^= PREFTOGGLE_DONATOR_PUBLIC
|
||||
|
||||
if("gender")
|
||||
if(!S.has_gender)
|
||||
@@ -1997,21 +1988,21 @@ GLOBAL_LIST_INIT(special_role_times, list( //minimum age (in days) for accounts
|
||||
H.remake_hud()
|
||||
|
||||
if("nanoui")
|
||||
nanoui_fancy = !nanoui_fancy
|
||||
toggles2 ^= PREFTOGGLE_2_FANCYUI
|
||||
|
||||
if("ghost_att_anim")
|
||||
show_ghostitem_attack = !show_ghostitem_attack
|
||||
toggles2 ^= PREFTOGGLE_2_ITEMATTACK
|
||||
|
||||
if("winflash")
|
||||
windowflashing = !windowflashing
|
||||
toggles2 ^= PREFTOGGLE_2_WINDOWFLASHING
|
||||
|
||||
if("afk_watch")
|
||||
if(!afk_watch)
|
||||
if(!(toggles2 & PREFTOGGLE_2_AFKWATCH))
|
||||
to_chat(user, "<span class='info'>You will now get put into cryo dorms after [config.auto_cryo_afk] minutes. \
|
||||
Then after [config.auto_despawn_afk] minutes you will be fully despawned. You will receive a visual and auditory warning before you will be put into cryodorms.</span>")
|
||||
else
|
||||
to_chat(user, "<span class='info'>Automatic cryoing turned off.</span>")
|
||||
afk_watch = !afk_watch
|
||||
toggles2 ^= PREFTOGGLE_2_AFKWATCH
|
||||
|
||||
if("UIcolor")
|
||||
var/UI_style_color_new = input(user, "Choose your UI color, dark colors are not recommended!", UI_style_color) as color|null
|
||||
@@ -2040,7 +2031,7 @@ GLOBAL_LIST_INIT(special_role_times, list( //minimum age (in days) for accounts
|
||||
be_random_name = !be_random_name
|
||||
|
||||
if("randomslot")
|
||||
randomslot = !randomslot
|
||||
toggles2 ^= PREFTOGGLE_2_RANDOMSLOT
|
||||
if(isnewplayer(usr))
|
||||
var/mob/new_player/N = usr
|
||||
N.new_player_panel_proc()
|
||||
@@ -2056,22 +2047,22 @@ GLOBAL_LIST_INIT(special_role_times, list( //minimum age (in days) for accounts
|
||||
user.stop_sound_channel(CHANNEL_LOBBYMUSIC)
|
||||
|
||||
if("ghost_ears")
|
||||
toggles ^= CHAT_GHOSTEARS
|
||||
toggles ^= PREFTOGGLE_CHAT_GHOSTEARS
|
||||
|
||||
if("ghost_sight")
|
||||
toggles ^= CHAT_GHOSTSIGHT
|
||||
toggles ^= PREFTOGGLE_CHAT_GHOSTSIGHT
|
||||
|
||||
if("ghost_radio")
|
||||
toggles ^= CHAT_GHOSTRADIO
|
||||
toggles ^= PREFTOGGLE_CHAT_GHOSTRADIO
|
||||
|
||||
if("ghost_radio")
|
||||
toggles ^= CHAT_GHOSTRADIO
|
||||
toggles ^= PREFTOGGLE_CHAT_GHOSTRADIO
|
||||
|
||||
if("ghost_pda")
|
||||
toggles ^= CHAT_GHOSTPDA
|
||||
toggles ^= PREFTOGGLE_CHAT_GHOSTPDA
|
||||
|
||||
if("ghost_anonsay")
|
||||
ghost_anonsay = !ghost_anonsay
|
||||
toggles2 ^= PREFTOGGLE_2_ANONDCHAT
|
||||
|
||||
if("save")
|
||||
save_preferences(user)
|
||||
@@ -2110,12 +2101,12 @@ GLOBAL_LIST_INIT(special_role_times, list( //minimum age (in days) for accounts
|
||||
|
||||
|
||||
if("ambientocclusion")
|
||||
toggles ^= AMBIENT_OCCLUSION
|
||||
toggles ^= PREFTOGGLE_AMBIENT_OCCLUSION
|
||||
if(parent && parent.screen && parent.screen.len)
|
||||
var/obj/screen/plane_master/game_world/PM = locate(/obj/screen/plane_master/game_world) in parent.screen
|
||||
PM.filters -= FILTER_AMBIENT_OCCLUSION
|
||||
if(toggles & AMBIENT_OCCLUSION)
|
||||
PM.filters += FILTER_AMBIENT_OCCLUSION
|
||||
PM.remove_filter(AMBIENT_OCCLUSION_FILTER_KEY)
|
||||
if(toggles & PREFTOGGLE_AMBIENT_OCCLUSION)
|
||||
PM.add_filter(AMBIENT_OCCLUSION_FILTER_KEY, FILTER_AMBIENT_OCCLUSION)
|
||||
|
||||
if("parallax")
|
||||
var/parallax_styles = list(
|
||||
|
||||
@@ -8,19 +8,14 @@
|
||||
be_role,
|
||||
default_slot,
|
||||
toggles,
|
||||
toggles_2,
|
||||
sound,
|
||||
randomslot,
|
||||
volume,
|
||||
nanoui_fancy,
|
||||
show_ghostitem_attack,
|
||||
lastchangelog,
|
||||
windowflashing,
|
||||
ghost_anonsay,
|
||||
exp,
|
||||
clientfps,
|
||||
atklog,
|
||||
fuid,
|
||||
afk_watch,
|
||||
parallax
|
||||
FROM [format_table_name("player")]
|
||||
WHERE ckey='[C.ckey]'"}
|
||||
@@ -42,41 +37,31 @@
|
||||
be_special = params2list(query.item[5])
|
||||
default_slot = text2num(query.item[6])
|
||||
toggles = text2num(query.item[7])
|
||||
sound = text2num(query.item[8])
|
||||
randomslot = text2num(query.item[9])
|
||||
toggles2 = text2num(query.item[8])
|
||||
sound = text2num(query.item[9])
|
||||
volume = text2num(query.item[10])
|
||||
nanoui_fancy = text2num(query.item[11])
|
||||
show_ghostitem_attack = text2num(query.item[12])
|
||||
lastchangelog = query.item[13]
|
||||
windowflashing = text2num(query.item[14])
|
||||
ghost_anonsay = text2num(query.item[15])
|
||||
exp = query.item[16]
|
||||
clientfps = text2num(query.item[17])
|
||||
atklog = text2num(query.item[18])
|
||||
fuid = text2num(query.item[19])
|
||||
afk_watch = text2num(query.item[20])
|
||||
parallax = text2num(query.item[21])
|
||||
lastchangelog = query.item[11]
|
||||
exp = query.item[12]
|
||||
clientfps = text2num(query.item[13])
|
||||
atklog = text2num(query.item[14])
|
||||
fuid = text2num(query.item[15])
|
||||
parallax = text2num(query.item[16])
|
||||
|
||||
//Sanitize
|
||||
ooccolor = sanitize_hexcolor(ooccolor, initial(ooccolor))
|
||||
UI_style = sanitize_inlist(UI_style, list("White", "Midnight"), initial(UI_style))
|
||||
default_slot = sanitize_integer(default_slot, 1, max_save_slots, initial(default_slot))
|
||||
toggles = sanitize_integer(toggles, 0, TOGGLES_TOTAL, initial(toggles))
|
||||
toggles2 = sanitize_integer(toggles2, 0, TOGGLES_2_TOTAL, initial(toggles2))
|
||||
sound = sanitize_integer(sound, 0, 65535, initial(sound))
|
||||
UI_style_color = sanitize_hexcolor(UI_style_color, initial(UI_style_color))
|
||||
UI_style_alpha = sanitize_integer(UI_style_alpha, 0, 255, initial(UI_style_alpha))
|
||||
randomslot = sanitize_integer(randomslot, 0, 1, initial(randomslot))
|
||||
volume = sanitize_integer(volume, 0, 100, initial(volume))
|
||||
nanoui_fancy = sanitize_integer(nanoui_fancy, 0, 1, initial(nanoui_fancy))
|
||||
show_ghostitem_attack = sanitize_integer(show_ghostitem_attack, 0, 1, initial(show_ghostitem_attack))
|
||||
lastchangelog = sanitize_text(lastchangelog, initial(lastchangelog))
|
||||
windowflashing = sanitize_integer(windowflashing, 0, 1, initial(windowflashing))
|
||||
ghost_anonsay = sanitize_integer(ghost_anonsay, 0, 1, initial(ghost_anonsay))
|
||||
exp = sanitize_text(exp, initial(exp))
|
||||
clientfps = sanitize_integer(clientfps, 0, 1000, initial(clientfps))
|
||||
atklog = sanitize_integer(atklog, 0, 100, initial(atklog))
|
||||
fuid = sanitize_integer(fuid, 0, 10000000, initial(fuid))
|
||||
afk_watch = sanitize_integer(afk_watch, 0, 1, initial(afk_watch))
|
||||
parallax = sanitize_integer(parallax, 0, 16, initial(parallax))
|
||||
return 1
|
||||
|
||||
@@ -97,18 +82,13 @@
|
||||
be_role='[sanitizeSQL(list2params(be_special))]',
|
||||
default_slot='[default_slot]',
|
||||
toggles='[num2text(toggles, CEILING(log(10, (TOGGLES_TOTAL)), 1))]',
|
||||
toggles_2='[num2text(toggles2, CEILING(log(10, (TOGGLES_2_TOTAL)), 1))]',
|
||||
atklog='[atklog]',
|
||||
sound='[sound]',
|
||||
randomslot='[randomslot]',
|
||||
volume='[volume]',
|
||||
nanoui_fancy='[nanoui_fancy]',
|
||||
show_ghostitem_attack='[show_ghostitem_attack]',
|
||||
lastchangelog='[lastchangelog]',
|
||||
windowflashing='[windowflashing]',
|
||||
ghost_anonsay='[ghost_anonsay]',
|
||||
clientfps='[clientfps]',
|
||||
atklog='[atklog]',
|
||||
afk_watch='[afk_watch]',
|
||||
parallax='[parallax]'
|
||||
WHERE ckey='[C.ckey]'"}
|
||||
)
|
||||
|
||||
@@ -3,8 +3,8 @@
|
||||
set name = "Show/Hide GhostEars"
|
||||
set category = "Preferences"
|
||||
set desc = ".Toggle Between seeing all mob speech, and only speech of nearby mobs"
|
||||
prefs.toggles ^= CHAT_GHOSTEARS
|
||||
to_chat(src, "As a ghost, you will now [(prefs.toggles & CHAT_GHOSTEARS) ? "see all speech in the world" : "only see speech from nearby mobs"].")
|
||||
prefs.toggles ^= PREFTOGGLE_CHAT_GHOSTEARS
|
||||
to_chat(src, "As a ghost, you will now [(prefs.toggles & PREFTOGGLE_CHAT_GHOSTEARS) ? "see all speech in the world" : "only see speech from nearby mobs"].")
|
||||
prefs.save_preferences(src)
|
||||
feedback_add_details("admin_verb","TGE") //If you are copy-pasting this, ensure the 2nd parameter is unique to the new proc!
|
||||
|
||||
@@ -12,8 +12,8 @@
|
||||
set name = "Show/Hide GhostSight"
|
||||
set category = "Preferences"
|
||||
set desc = ".Toggle Between seeing all mob emotes, and only emotes of nearby mobs"
|
||||
prefs.toggles ^= CHAT_GHOSTSIGHT
|
||||
to_chat(src, "As a ghost, you will now [(prefs.toggles & CHAT_GHOSTSIGHT) ? "see all emotes in the world" : "only see emotes from nearby mobs"].")
|
||||
prefs.toggles ^= PREFTOGGLE_CHAT_GHOSTSIGHT
|
||||
to_chat(src, "As a ghost, you will now [(prefs.toggles & PREFTOGGLE_CHAT_GHOSTSIGHT) ? "see all emotes in the world" : "only see emotes from nearby mobs"].")
|
||||
prefs.save_preferences(src)
|
||||
feedback_add_details("admin_verb","TGS") //If you are copy-pasting this, ensure the 2nd parameter is unique to the new proc!
|
||||
|
||||
@@ -21,8 +21,8 @@
|
||||
set name = "Enable/Disable GhostRadio"
|
||||
set category = "Preferences"
|
||||
set desc = ".Toggle between hearing all radio chatter, or only from nearby speakers"
|
||||
prefs.toggles ^= CHAT_GHOSTRADIO
|
||||
to_chat(src, "As a ghost, you will now [(prefs.toggles & CHAT_GHOSTRADIO) ? "hear all radio chat in the world" : "only hear from nearby speakers"].")
|
||||
prefs.toggles ^= PREFTOGGLE_CHAT_GHOSTRADIO
|
||||
to_chat(src, "As a ghost, you will now [(prefs.toggles & PREFTOGGLE_CHAT_GHOSTRADIO) ? "hear all radio chat in the world" : "only hear from nearby speakers"].")
|
||||
prefs.save_preferences(src)
|
||||
feedback_add_details("admin_verb","TGR")
|
||||
|
||||
@@ -32,9 +32,9 @@
|
||||
set desc = "Toggle seeing radiochatter from radios and speakers"
|
||||
if(!check_rights(R_ADMIN))
|
||||
return
|
||||
prefs.toggles ^= CHAT_RADIO
|
||||
prefs.toggles ^= PREFTOGGLE_CHAT_RADIO
|
||||
prefs.save_preferences(src)
|
||||
to_chat(usr, "You will [(prefs.toggles & CHAT_RADIO) ? "now" : "no longer"] see radio chatter from radios or speakers")
|
||||
to_chat(usr, "You will [(prefs.toggles & PREFTOGGLE_CHAT_RADIO) ? "now" : "no longer"] see radio chatter from radios or speakers")
|
||||
feedback_add_details("admin_verb","THR") //If you are copy-pasting this, ensure the 2nd parameter is unique to the new proc!
|
||||
|
||||
/client/verb/toggle_ai_voice_annoucements()
|
||||
@@ -72,13 +72,13 @@
|
||||
set name = "Show/Hide Deadchat"
|
||||
set category = "Preferences"
|
||||
set desc ="Toggles seeing deadchat"
|
||||
prefs.toggles ^= CHAT_DEAD
|
||||
prefs.toggles ^= PREFTOGGLE_CHAT_DEAD
|
||||
prefs.save_preferences(src)
|
||||
|
||||
if(src.holder)
|
||||
to_chat(src, "You will [(prefs.toggles & CHAT_DEAD) ? "now" : "no longer"] see deadchat.")
|
||||
to_chat(src, "You will [(prefs.toggles & PREFTOGGLE_CHAT_DEAD) ? "now" : "no longer"] see deadchat.")
|
||||
else
|
||||
to_chat(src, "As a ghost, you will [(prefs.toggles & CHAT_DEAD) ? "now" : "no longer"] see deadchat.")
|
||||
to_chat(src, "As a ghost, you will [(prefs.toggles & PREFTOGGLE_CHAT_DEAD) ? "now" : "no longer"] see deadchat.")
|
||||
|
||||
feedback_add_details("admin_verb","TDV") //If you are copy-pasting this, ensure the 2nd parameter is unique to the new proc!
|
||||
|
||||
@@ -86,27 +86,27 @@
|
||||
set name = "Show/Hide Prayers"
|
||||
set category = "Preferences"
|
||||
set desc = "Toggles seeing prayers"
|
||||
prefs.toggles ^= CHAT_PRAYER
|
||||
prefs.toggles ^= PREFTOGGLE_CHAT_PRAYER
|
||||
prefs.save_preferences(src)
|
||||
to_chat(src, "You will [(prefs.toggles & CHAT_PRAYER) ? "now" : "no longer"] see prayerchat.")
|
||||
to_chat(src, "You will [(prefs.toggles & PREFTOGGLE_CHAT_PRAYER) ? "now" : "no longer"] see prayerchat.")
|
||||
feedback_add_details("admin_verb","TP") //If you are copy-pasting this, ensure the 2nd parameter is unique to the new proc!
|
||||
|
||||
/client/verb/togglescoreboard()
|
||||
set name = "Hide/Display End Round Scoreboard"
|
||||
set category = "Preferences"
|
||||
set desc = "Toggles displaying end of round scoreboard"
|
||||
prefs.toggles ^= DISABLE_SCOREBOARD
|
||||
prefs.toggles ^= PREFTOGGLE_DISABLE_SCOREBOARD
|
||||
prefs.save_preferences(src)
|
||||
to_chat(src, "You will [(prefs.toggles & DISABLE_SCOREBOARD) ? "no longer" : "now"] see the end of round scoreboard.")
|
||||
to_chat(src, "You will [(prefs.toggles & PREFTOGGLE_DISABLE_SCOREBOARD) ? "no longer" : "now"] see the end of round scoreboard.")
|
||||
feedback_add_details("admin_verb","TScoreboard") //If you are copy-pasting this, ensure the 2nd parameter is unique to the new proc!
|
||||
|
||||
/client/verb/togglekarmareminder()
|
||||
set name = "Hide/Display End Round Karma Reminder"
|
||||
set category = "Preferences"
|
||||
set desc = "Toggles displaying end of round karma reminder"
|
||||
prefs.toggles ^= DISABLE_KARMA_REMINDER
|
||||
prefs.toggles ^= PREFTOGGLE_DISABLE_KARMA_REMINDER
|
||||
prefs.save_preferences(src)
|
||||
to_chat(src, "You will [(prefs.toggles & DISABLE_KARMA_REMINDER) ? "no longer" : "now"] see the end of round karma reminder.")
|
||||
to_chat(src, "You will [(prefs.toggles & PREFTOGGLE_DISABLE_KARMA_REMINDER) ? "no longer" : "now"] see the end of round karma reminder.")
|
||||
feedback_add_details("admin_verb","TKarmabugger") //If you are copy-pasting this, ensure the 2nd parameter is unique to the new proc!
|
||||
|
||||
/client/verb/toggletitlemusic()
|
||||
@@ -143,9 +143,9 @@
|
||||
set name = "Show/Hide OOC"
|
||||
set category = "Preferences"
|
||||
set desc = "Toggles seeing OutOfCharacter chat"
|
||||
prefs.toggles ^= CHAT_OOC
|
||||
prefs.toggles ^= PREFTOGGLE_CHAT_OOC
|
||||
prefs.save_preferences(src)
|
||||
to_chat(src, "You will [(prefs.toggles & CHAT_OOC) ? "now" : "no longer"] see messages on the OOC channel.")
|
||||
to_chat(src, "You will [(prefs.toggles & PREFTOGGLE_CHAT_OOC) ? "now" : "no longer"] see messages on the OOC channel.")
|
||||
feedback_add_details("admin_verb","TOOC") //If you are copy-pasting this, ensure the 2nd parameter is unique to the new proc!
|
||||
|
||||
|
||||
@@ -153,9 +153,9 @@
|
||||
set name = "Show/Hide LOOC"
|
||||
set category = "Preferences"
|
||||
set desc = "Toggles seeing Local OutOfCharacter chat"
|
||||
prefs.toggles ^= CHAT_LOOC
|
||||
prefs.toggles ^= PREFTOGGLE_CHAT_LOOC
|
||||
prefs.save_preferences(src)
|
||||
to_chat(src, "You will [(prefs.toggles & CHAT_LOOC) ? "now" : "no longer"] see messages on the LOOC channel.")
|
||||
to_chat(src, "You will [(prefs.toggles & PREFTOGGLE_CHAT_LOOC) ? "now" : "no longer"] see messages on the LOOC channel.")
|
||||
feedback_add_details("admin_verb","TLOOC") //If you are copy-pasting this, ensure the 2nd parameter is unique to the new proc!
|
||||
|
||||
|
||||
@@ -236,9 +236,9 @@
|
||||
set name = "Toggle Darkmode"
|
||||
set category = "Preferences"
|
||||
set desc = "Toggles UI style between dark and light"
|
||||
prefs.toggles ^= UI_DARKMODE
|
||||
prefs.toggles ^= PREFTOGGLE_UI_DARKMODE
|
||||
prefs.save_preferences(src)
|
||||
if(prefs.toggles & UI_DARKMODE)
|
||||
if(prefs.toggles & PREFTOGGLE_UI_DARKMODE)
|
||||
activate_darkmode()
|
||||
else
|
||||
deactivate_darkmode()
|
||||
@@ -248,9 +248,9 @@
|
||||
set name = "Toggle Karma Gains"
|
||||
set category = "Special Verbs"
|
||||
set desc = "This button will allow you to stop other people giving you karma."
|
||||
prefs.toggles ^= DISABLE_KARMA
|
||||
prefs.toggles ^= PREFTOGGLE_DISABLE_KARMA
|
||||
prefs.save_preferences(src)
|
||||
if(prefs.toggles & DISABLE_KARMA)
|
||||
if(prefs.toggles & PREFTOGGLE_DISABLE_KARMA)
|
||||
to_chat(usr, "<span class='notice'>You have disabled karma gains.")
|
||||
else
|
||||
to_chat(usr, "<span class='notice'>You have enabled karma gains.")
|
||||
@@ -259,9 +259,9 @@
|
||||
set name = "Toggle Text Popup Limiter"
|
||||
set category = "Preferences"
|
||||
set desc = "Will let you limit the text input popups to one at a time."
|
||||
prefs.toggles ^= TYPING_ONCE
|
||||
prefs.toggles ^= PREFTOGGLE_TYPING_ONCE
|
||||
prefs.save_preferences(src)
|
||||
if(prefs.toggles & TYPING_ONCE)
|
||||
if(prefs.toggles & PREFTOGGLE_TYPING_ONCE)
|
||||
to_chat(usr, "<span class='notice'>You have enabled text popup limiting.")
|
||||
else
|
||||
to_chat(usr, "<span class='notice'>You have disabled text popup limiting.")
|
||||
@@ -271,9 +271,9 @@
|
||||
set name = "Toggle Numpad targetting"
|
||||
set category = "Preferences"
|
||||
set desc = "This button will allow you to enable or disable Numpad Targetting"
|
||||
prefs.toggles ^= NUMPAD_TARGET
|
||||
prefs.toggles ^= PREFTOGGLE_NUMPAD_TARGET
|
||||
prefs.save_preferences(src)
|
||||
if (prefs.toggles & NUMPAD_TARGET)
|
||||
if (prefs.toggles & PREFTOGGLE_NUMPAD_TARGET)
|
||||
to_chat(usr, "<span class='notice'>You have enabled Numpad Targetting.")
|
||||
else
|
||||
to_chat(usr, "<span class='notice'>You have disabled Numpad Targetting.")
|
||||
@@ -283,9 +283,9 @@
|
||||
set name = "Toggle QWERTY/AZERTY"
|
||||
set category = "Preferences"
|
||||
set desc = "This button will switch you between QWERTY and AZERTY control sets"
|
||||
prefs.toggles ^= AZERTY
|
||||
prefs.toggles ^= PREFTOGGLE_AZERTY
|
||||
prefs.save_preferences(src)
|
||||
if (prefs.toggles & AZERTY)
|
||||
if (prefs.toggles & PREFTOGGLE_AZERTY)
|
||||
to_chat(usr, "<span class='notice'>You are now in AZERTY mode.")
|
||||
else
|
||||
to_chat(usr, "<span class='notice'>You are now in QWERTY mode.")
|
||||
@@ -294,8 +294,8 @@
|
||||
set name = "Show/Hide GhostPDA"
|
||||
set category = "Preferences"
|
||||
set desc = ".Toggle seeing PDA messages as an observer."
|
||||
prefs.toggles ^= CHAT_GHOSTPDA
|
||||
to_chat(src, "As a ghost, you will now [(prefs.toggles & CHAT_GHOSTPDA) ? "see all PDA messages" : "no longer see PDA messages"].")
|
||||
prefs.toggles ^= PREFTOGGLE_CHAT_GHOSTPDA
|
||||
to_chat(src, "As a ghost, you will now [(prefs.toggles & PREFTOGGLE_CHAT_GHOSTPDA) ? "see all PDA messages" : "no longer see PDA messages"].")
|
||||
prefs.save_preferences(src)
|
||||
feedback_add_details("admin_verb","TGP") //If you are copy-pasting this, ensure the 2nd parameter is unique to the new proc!
|
||||
|
||||
|
||||
@@ -12,7 +12,6 @@
|
||||
armor = list("melee" = 30, "bullet" = 30, "laser" = 30, "energy" = 10, "bomb" = 25, "bio" = 0, "rad" = 0, "fire" = 50, "acid" = 50)
|
||||
sprite_sheets = list(
|
||||
"Vox" = 'icons/mob/species/vox/suit.dmi',
|
||||
"Grey" = 'icons/mob/species/grey/suit.dmi'
|
||||
)
|
||||
w_class = WEIGHT_CLASS_NORMAL
|
||||
|
||||
@@ -41,6 +40,9 @@
|
||||
/obj/item/clothing/suit/armor/vest/security
|
||||
name = "security armor"
|
||||
desc = "An armored vest that protects against some damage. This one has a clip for a holobadge."
|
||||
sprite_sheets = list(
|
||||
"Grey" = 'icons/mob/species/grey/suit.dmi'
|
||||
)
|
||||
icon_state = "armor"
|
||||
item_state = "armor"
|
||||
var/obj/item/clothing/accessory/holobadge/attached_badge
|
||||
@@ -51,7 +53,6 @@
|
||||
add_fingerprint(user)
|
||||
W.forceMove(src)
|
||||
attached_badge = W
|
||||
|
||||
var/datum/action/A = new /datum/action/item_action/remove_badge(src)
|
||||
A.Grant(user)
|
||||
icon_state = "armorsec"
|
||||
|
||||
@@ -71,23 +71,26 @@ GLOBAL_VAR_INIT(setup_economy, 0)
|
||||
var/datum/feed_channel/newChannel = new /datum/feed_channel
|
||||
newChannel.channel_name = "Public Station Announcements"
|
||||
newChannel.author = "Automated Announcement Listing"
|
||||
newChannel.locked = 1
|
||||
newChannel.is_admin_channel = 1
|
||||
GLOB.news_network.network_channels += newChannel
|
||||
newChannel.icon = "bullhorn"
|
||||
newChannel.frozen = TRUE
|
||||
newChannel.admin_locked = TRUE
|
||||
GLOB.news_network.channels += newChannel
|
||||
|
||||
newChannel = new /datum/feed_channel
|
||||
newChannel.channel_name = "Nyx Daily"
|
||||
newChannel.author = "CentComm Minister of Information"
|
||||
newChannel.locked = 1
|
||||
newChannel.is_admin_channel = 1
|
||||
GLOB.news_network.network_channels += newChannel
|
||||
newChannel.icon = "meteor"
|
||||
newChannel.frozen = TRUE
|
||||
newChannel.admin_locked = TRUE
|
||||
GLOB.news_network.channels += newChannel
|
||||
|
||||
newChannel = new /datum/feed_channel
|
||||
newChannel.channel_name = "The Gibson Gazette"
|
||||
newChannel.author = "Editor Mike Hammers"
|
||||
newChannel.locked = 1
|
||||
newChannel.is_admin_channel = 1
|
||||
GLOB.news_network.network_channels += newChannel
|
||||
newChannel.icon = "star"
|
||||
newChannel.frozen = TRUE
|
||||
newChannel.admin_locked = TRUE
|
||||
GLOB.news_network.channels += newChannel
|
||||
|
||||
for(var/loc_type in subtypesof(/datum/trade_destination))
|
||||
var/datum/trade_destination/D = new loc_type
|
||||
|
||||
@@ -58,7 +58,7 @@
|
||||
//copy-pasted from the admin verbs to submit new newscaster messages
|
||||
var/datum/feed_message/newMsg = new /datum/feed_message
|
||||
newMsg.author = "Nyx Daily"
|
||||
newMsg.is_admin_message = 1
|
||||
newMsg.admin_locked = TRUE
|
||||
|
||||
//see if our location has custom event info for this event
|
||||
newMsg.body = affected_dest.get_custom_eventstring()
|
||||
@@ -94,12 +94,10 @@
|
||||
if(FESTIVAL)
|
||||
newMsg.body = "A [pick("festival","week long celebration","day of revelry","planet-wide holiday")] has been declared on [affected_dest.name] by [pick("Governor","Commissioner","General","Commandant","Administrator")] [random_name(pick(MALE,FEMALE))] to celebrate [pick("the birth of their [pick("son","daughter")]","coming of age of their [pick("son","daughter")]","the pacification of rogue military cell","the apprehension of a violent criminal who had been terrorising the planet")]. Massive stocks of food and meat have been bought driving up prices across the planet."
|
||||
|
||||
for(var/datum/feed_channel/FC in GLOB.news_network.network_channels)
|
||||
if(FC.channel_name == "Nyx Daily")
|
||||
FC.messages += newMsg
|
||||
break
|
||||
for(var/obj/machinery/newscaster/NEWSCASTER in GLOB.allNewscasters)
|
||||
NEWSCASTER.newsAlert("Nyx Daily")
|
||||
GLOB.news_network.get_channel_by_name("Nyx Daily")?.add_message(newMsg)
|
||||
for(var/nc in GLOB.allNewscasters)
|
||||
var/obj/machinery/newscaster/NC = nc
|
||||
NC.alert_news("Nyx Daily")
|
||||
|
||||
/datum/event/economic_event/end()
|
||||
for(var/good_type in dearer_goods)
|
||||
|
||||
@@ -14,7 +14,7 @@
|
||||
//copy-pasted from the admin verbs to submit new newscaster messages
|
||||
var/datum/feed_message/newMsg = new /datum/feed_message
|
||||
newMsg.author = "Nyx Daily"
|
||||
newMsg.is_admin_message = 1
|
||||
newMsg.admin_locked = TRUE
|
||||
|
||||
//see if our location has custom event info for this event
|
||||
newMsg.body = affected_dest.get_custom_eventstring()
|
||||
@@ -126,12 +126,10 @@
|
||||
Nyx Daily is offering discount tickets for two to see [random_name(pick(MALE,FEMALE))] live in return for eyewitness reports and up to the minute coverage."
|
||||
|
||||
|
||||
for(var/datum/feed_channel/FC in GLOB.news_network.network_channels)
|
||||
if(FC.channel_name == "Nyx Daily")
|
||||
FC.messages += newMsg
|
||||
break
|
||||
for(var/obj/machinery/newscaster/NEWSCASTER in GLOB.allNewscasters)
|
||||
NEWSCASTER.newsAlert("Nyx Daily")
|
||||
GLOB.news_network.get_channel_by_name("Nyx Daily")?.add_message(newMsg)
|
||||
for(var/nc in GLOB.allNewscasters)
|
||||
var/obj/machinery/newscaster/NC = nc
|
||||
NC.alert_news("Nyx Daily")
|
||||
|
||||
/datum/event/trivial_news
|
||||
endWhen = 10
|
||||
@@ -145,9 +143,7 @@
|
||||
newMsg.body = pick(file2list("config/news/trivial.txt"))
|
||||
newMsg.body = replacetext(newMsg.body,"{{AFFECTED}}",affected_dest.name)
|
||||
|
||||
for(var/datum/feed_channel/FC in GLOB.news_network.network_channels)
|
||||
if(FC.channel_name == "The Gibson Gazette")
|
||||
FC.messages += newMsg
|
||||
break
|
||||
for(var/obj/machinery/newscaster/NEWSCASTER in GLOB.allNewscasters)
|
||||
NEWSCASTER.newsAlert("The Gibson Gazette")
|
||||
GLOB.news_network.get_channel_by_name("The Gibson Gazette")?.add_message(newMsg)
|
||||
for(var/nc in GLOB.allNewscasters)
|
||||
var/obj/machinery/newscaster/NC = nc
|
||||
NC.alert_news("The Gibson Gazette")
|
||||
|
||||
@@ -3,7 +3,7 @@
|
||||
var/highpop_trigger = 80
|
||||
var/spawncount = 2
|
||||
var/list/playercount
|
||||
var/successSpawn = 0 //So we don't make a command report if nothing gets spawned.
|
||||
var/successSpawn = FALSE //So we don't make a command report if nothing gets spawned.
|
||||
|
||||
/datum/event/alien_infestation/setup()
|
||||
announceWhen = rand(announceWhen, announceWhen + 50)
|
||||
@@ -11,21 +11,18 @@
|
||||
/datum/event/alien_infestation/announce()
|
||||
if(successSpawn)
|
||||
GLOB.event_announcement.Announce("Unidentified lifesigns detected coming aboard [station_name()]. Secure any exterior access, including ducting and ventilation.", "Lifesign Alert", new_sound = 'sound/AI/aliens.ogg')
|
||||
else
|
||||
log_and_message_admins("Warning: Could not spawn any mobs for event Alien Infestation")
|
||||
|
||||
/datum/event/alien_infestation/start()
|
||||
var/list/vents = list()
|
||||
var/list/vents = get_valid_vent_spawns(exclude_mobs_nearby = TRUE, exclude_visible_by_mobs = TRUE)
|
||||
playercount = length(GLOB.clients)//grab playercount when event starts not when game starts
|
||||
if(playercount >= highpop_trigger) //spawn with 4 if highpop
|
||||
spawncount = 4
|
||||
for(var/obj/machinery/atmospherics/unary/vent_pump/temp_vent in SSair.atmos_machinery)
|
||||
if(is_station_level(temp_vent.loc.z) && !temp_vent.welded)
|
||||
if(temp_vent.parent.other_atmosmch.len > 50) //Stops Aliens getting stuck in small networks. See: Security, Virology
|
||||
vents += temp_vent
|
||||
|
||||
spawn()
|
||||
var/list/candidates = SSghost_spawns.poll_candidates("Do you want to play as an alien?", ROLE_ALIEN, TRUE, source = /mob/living/carbon/alien/larva)
|
||||
|
||||
while(spawncount > 0 && vents.len && candidates.len)
|
||||
while(spawncount && length(vents) && length(candidates))
|
||||
var/obj/vent = pick_n_take(vents)
|
||||
var/mob/C = pick_n_take(candidates)
|
||||
if(C)
|
||||
@@ -37,4 +34,4 @@
|
||||
SSticker.mode.xenos += new_xeno.mind
|
||||
|
||||
spawncount--
|
||||
successSpawn = 1
|
||||
successSpawn = TRUE
|
||||
|
||||
@@ -0,0 +1,52 @@
|
||||
/datum/event/anomaly/anomaly_atmos
|
||||
startWhen = 30
|
||||
announceWhen = 3
|
||||
endWhen = 100
|
||||
|
||||
/datum/event/anomaly/anomaly_atmos/announce()
|
||||
GLOB.event_announcement.Announce("Transformative gas anomaly detected on long range scanners. Expected location: [impact_area.name].", "Anomaly Alert")
|
||||
|
||||
/datum/event/anomaly/anomaly_atmos/start()
|
||||
var/turf/T = pick(get_area_turfs(impact_area))
|
||||
if(T)
|
||||
newAnomaly = new /obj/effect/anomaly/atmos(T.loc)
|
||||
|
||||
|
||||
/datum/event/anomaly/anomaly_atmos/tick()
|
||||
if(!newAnomaly)
|
||||
kill()
|
||||
return
|
||||
if(ISMULTIPLE(activeFor, 5))
|
||||
newAnomaly.anomalyEffect()
|
||||
|
||||
/datum/event/anomaly/anomaly_atmos/end()
|
||||
if(!newAnomaly || !newAnomaly.loc) //no anomaly or it is in nullspace
|
||||
return
|
||||
var/obj/effect/anomaly/atmos/A = newAnomaly
|
||||
var/gas_type = A.gas_type
|
||||
var/area/t_area = get_area(A)
|
||||
for(var/turf/T in t_area)
|
||||
if(istype(T, /turf/simulated)) //should not occur on unsimulated turfs without admemery
|
||||
var/turf/simulated/S = T
|
||||
fill_with_gas(gas_type, S)
|
||||
explosion(get_turf(newAnomaly), -1, 0, 2) // a small boom so people know something happened.
|
||||
..()
|
||||
|
||||
/**
|
||||
* Replaces all oxygen and nitrogen on the simulated turf S with the gas type specified in gas, taking N2, N20, CO2 and agent B
|
||||
*/
|
||||
/datum/event/anomaly/anomaly_atmos/proc/fill_with_gas(gas, turf/simulated/S)
|
||||
if(!S.air)//no air to transform
|
||||
return
|
||||
var/amount_to_add = S.air.oxygen + S.air.nitrogen
|
||||
S.air.oxygen = 0
|
||||
S.air.nitrogen = 0
|
||||
switch(gas)
|
||||
if(GAS_N2)
|
||||
S.air.nitrogen += amount_to_add
|
||||
if(GAS_N2O)
|
||||
S.air.sleeping_agent += amount_to_add
|
||||
if(GAS_CO2)
|
||||
S.air.carbon_dioxide += amount_to_add
|
||||
S.update_visuals()
|
||||
S.air_update_turf()
|
||||
@@ -1,9 +1,13 @@
|
||||
/datum/event/blob
|
||||
announceWhen = 180
|
||||
endWhen = 240
|
||||
var/successSpawn = FALSE //So we don't make a command report if nothing gets spawned.
|
||||
|
||||
/datum/event/blob/announce()
|
||||
GLOB.event_announcement.Announce("Confirmed outbreak of level 5 biohazard aboard [station_name()]. All personnel must contain the outbreak.", "Biohazard Alert", 'sound/AI/outbreak5.ogg')
|
||||
if(successSpawn)
|
||||
GLOB.event_announcement.Announce("Confirmed outbreak of level 5 biohazard aboard [station_name()]. All personnel must contain the outbreak.", "Biohazard Alert", 'sound/AI/outbreak5.ogg')
|
||||
else
|
||||
log_and_message_admins("Warning: Could not spawn any mobs for event Blob")
|
||||
|
||||
/datum/event/blob/start()
|
||||
processing = FALSE //so it won't fire again in next tick
|
||||
@@ -16,12 +20,9 @@
|
||||
if(!length(candidates))
|
||||
return kill()
|
||||
|
||||
var/list/vents = list()
|
||||
for(var/obj/machinery/atmospherics/unary/vent_pump/temp_vent in GLOB.all_vent_pumps)
|
||||
if(is_station_level(temp_vent.loc.z) && !temp_vent.welded)
|
||||
if(length(temp_vent.parent.other_atmosmch) > 50)
|
||||
vents += temp_vent
|
||||
|
||||
var/list/vents = get_valid_vent_spawns(exclude_mobs_nearby = TRUE, exclude_visible_by_mobs = TRUE)
|
||||
if(!length(vents))
|
||||
return
|
||||
var/obj/vent = pick(vents)
|
||||
var/mob/living/simple_animal/mouse/blobinfected/B = new(vent.loc)
|
||||
var/mob/M = pick(candidates)
|
||||
@@ -30,4 +31,5 @@
|
||||
|
||||
to_chat(B, "<span class='userdanger'>You are now a mouse, infected with blob spores. Find somewhere isolated... before you burst and become the blob! Use ventcrawl (alt-click on vents) to move around.</span>")
|
||||
notify_ghosts("Infected Mouse has appeared in [get_area(B)].", source = B)
|
||||
successSpawn = TRUE
|
||||
processing = TRUE // Let it naturally end, if it runs successfully
|
||||
|
||||
@@ -170,19 +170,20 @@ GLOBAL_LIST_EMPTY(event_last_fired)
|
||||
new /datum/event_meta(EVENT_LEVEL_MODERATE, "Brand Intelligence", /datum/event/brand_intelligence, 50, list(ASSIGNMENT_ENGINEER = 25), TRUE),
|
||||
new /datum/event_meta(EVENT_LEVEL_MODERATE, "Space Dust", /datum/event/dust, 50, list(ASSIGNMENT_ENGINEER = 50)),
|
||||
new /datum/event_meta(EVENT_LEVEL_MODERATE, "Dimensional Tear", /datum/event/tear, 0, list(ASSIGNMENT_SECURITY = 35)),
|
||||
new /datum/event_meta(EVENT_LEVEL_MODERATE, "Honknomoly", /datum/event/tear/honk, 0),
|
||||
new /datum/event_meta(EVENT_LEVEL_MODERATE, "Honknomoly", /datum/event/tear/honk, 0),
|
||||
new /datum/event_meta(EVENT_LEVEL_MODERATE, "Vent Clog", /datum/event/vent_clog, 250),
|
||||
new /datum/event_meta(EVENT_LEVEL_MODERATE, "Wormholes", /datum/event/wormholes, 150),
|
||||
new /datum/event_meta(EVENT_LEVEL_MODERATE, "Pyro Anomaly", /datum/event/anomaly/anomaly_pyro, 75, list(ASSIGNMENT_ENGINEER = 60)),
|
||||
new /datum/event_meta(EVENT_LEVEL_MODERATE, "Pyro Anomaly", /datum/event/anomaly/anomaly_pyro, 75, list(ASSIGNMENT_ENGINEER = 60)),
|
||||
new /datum/event_meta(EVENT_LEVEL_MODERATE, "Atmos Anomaly", /datum/event/anomaly/anomaly_atmos, 75, list(ASSIGNMENT_ENGINEER = 60)),
|
||||
new /datum/event_meta(EVENT_LEVEL_MODERATE, "Vortex Anomaly", /datum/event/anomaly/anomaly_vortex, 75, list(ASSIGNMENT_ENGINEER = 25)),
|
||||
new /datum/event_meta(EVENT_LEVEL_MODERATE, "Bluespace Anomaly", /datum/event/anomaly/anomaly_bluespace, 75, list(ASSIGNMENT_ENGINEER = 25)),
|
||||
new /datum/event_meta(EVENT_LEVEL_MODERATE, "Flux Anomaly", /datum/event/anomaly/anomaly_flux, 75, list(ASSIGNMENT_ENGINEER = 50)),
|
||||
new /datum/event_meta(EVENT_LEVEL_MODERATE, "Gravitational Anomaly", /datum/event/anomaly/anomaly_grav, 200),
|
||||
new /datum/event_meta(EVENT_LEVEL_MODERATE, "Revenant", /datum/event/revenant, 150),
|
||||
new /datum/event_meta(EVENT_LEVEL_MODERATE, "Swarmer Spawn", /datum/event/spawn_swarmer, 150, is_one_shot = TRUE),
|
||||
new /datum/event_meta(EVENT_LEVEL_MODERATE, "Morph Spawn", /datum/event/spawn_morph, 40, is_one_shot = TRUE),
|
||||
new /datum/event_meta(EVENT_LEVEL_MODERATE, "Morph Spawn", /datum/event/spawn_morph, 40, list(ASSIGNMENT_SECURITY = 10), is_one_shot = TRUE),
|
||||
new /datum/event_meta(EVENT_LEVEL_MODERATE, "Disease Outbreak", /datum/event/disease_outbreak, 0, list(ASSIGNMENT_MEDICAL = 150), TRUE),
|
||||
new /datum/event_meta(EVENT_LEVEL_MODERATE, "Headcrabs", /datum/event/headcrabs, 0, list(ASSIGNMENT_SECURITY = 20))
|
||||
new /datum/event_meta(EVENT_LEVEL_MODERATE, "Headcrabs", /datum/event/headcrabs, 0, list(ASSIGNMENT_SECURITY = 20))
|
||||
)
|
||||
|
||||
/datum/event_container/major
|
||||
|
||||
@@ -15,16 +15,13 @@
|
||||
/datum/event/money_lotto/announce()
|
||||
var/datum/feed_message/newMsg = new /datum/feed_message
|
||||
newMsg.author = "Nanotrasen Editor"
|
||||
newMsg.is_admin_message = 1
|
||||
newMsg.admin_locked = TRUE
|
||||
|
||||
newMsg.body = "Nyx Daily wishes to congratulate <b>[winner_name]</b> for recieving the Nyx Stellar Slam Lottery, and receiving the out of this world sum of [winner_sum] credits!"
|
||||
if(!deposit_success)
|
||||
newMsg.body += "<br>Unfortunately, we were unable to verify the account details provided, so we were unable to transfer the money. Send a cheque containing the sum of $500 to ND 'Stellar Slam' office on the Nyx gateway containing updated details, and your winnings'll be re-sent within the month."
|
||||
|
||||
for(var/datum/feed_channel/FC in GLOB.news_network.network_channels)
|
||||
if(FC.channel_name == "Nyx Daily")
|
||||
FC.messages += newMsg
|
||||
break
|
||||
|
||||
for(var/obj/machinery/newscaster/NEWSCASTER in GLOB.allNewscasters)
|
||||
NEWSCASTER.newsAlert("Nyx Daily")
|
||||
GLOB.news_network.get_channel_by_name("Nyx Daily")?.add_message(newMsg)
|
||||
for(var/nc in GLOB.allNewscasters)
|
||||
var/obj/machinery/newscaster/NC = nc
|
||||
NC.alert_news("Nyx Daily")
|
||||
|
||||
@@ -3,6 +3,7 @@ GLOBAL_VAR_INIT(sent_spiders_to_station, 0)
|
||||
/datum/event/spider_infestation
|
||||
announceWhen = 400
|
||||
var/spawncount = 1
|
||||
var/successSpawn = FALSE //So we don't make a command report if nothing gets spawned.
|
||||
|
||||
/datum/event/spider_infestation/setup()
|
||||
announceWhen = rand(announceWhen, announceWhen + 50)
|
||||
@@ -10,20 +11,17 @@ GLOBAL_VAR_INIT(sent_spiders_to_station, 0)
|
||||
GLOB.sent_spiders_to_station = 1
|
||||
|
||||
/datum/event/spider_infestation/announce()
|
||||
GLOB.event_announcement.Announce("Unidentified lifesigns detected coming aboard [station_name()]. Secure any exterior access, including ducting and ventilation.", "Lifesign Alert", new_sound = 'sound/AI/aliens.ogg')
|
||||
if(successSpawn)
|
||||
GLOB.event_announcement.Announce("Unidentified lifesigns detected coming aboard [station_name()]. Secure any exterior access, including ducting and ventilation.", "Lifesign Alert", new_sound = 'sound/AI/aliens.ogg')
|
||||
else
|
||||
log_and_message_admins("Warning: Could not spawn any mobs for event Spider Infestation")
|
||||
|
||||
/datum/event/spider_infestation/start()
|
||||
|
||||
var/list/vents = list()
|
||||
for(var/obj/machinery/atmospherics/unary/vent_pump/temp_vent in SSair.atmos_machinery)
|
||||
if(is_station_level(temp_vent.loc.z) && !temp_vent.welded)
|
||||
if(temp_vent.parent.other_atmosmch.len > 50)
|
||||
vents += temp_vent
|
||||
|
||||
while((spawncount >= 1) && vents.len)
|
||||
var/obj/vent = pick(vents)
|
||||
var/list/vents = get_valid_vent_spawns(exclude_mobs_nearby = TRUE, exclude_visible_by_mobs = TRUE)
|
||||
while(spawncount && length(vents))
|
||||
var/obj/vent = pick_n_take(vents)
|
||||
var/obj/structure/spider/spiderling/S = new(vent.loc)
|
||||
if(prob(66))
|
||||
S.grow_as = /mob/living/simple_animal/hostile/poison/giant_spider/nurse
|
||||
vents -= vent
|
||||
spawncount--
|
||||
successSpawn = TRUE
|
||||
|
||||
@@ -3,25 +3,20 @@
|
||||
/datum/event/spider_terror
|
||||
announceWhen = 240
|
||||
var/spawncount = 1
|
||||
var/successSpawn = FALSE //So we don't make a command report if nothing gets spawned.
|
||||
|
||||
/datum/event/spider_terror/setup()
|
||||
announceWhen = rand(announceWhen, announceWhen + 30)
|
||||
spawncount = 1
|
||||
|
||||
/datum/event/spider_terror/announce()
|
||||
GLOB.command_announcement.Announce("Confirmed outbreak of level 3 biohazard aboard [station_name()]. All personnel must contain the outbreak.", "Biohazard Alert", 'sound/effects/siren-spooky.ogg')
|
||||
if(successSpawn)
|
||||
GLOB.command_announcement.Announce("Confirmed outbreak of level 3 biohazard aboard [station_name()]. All personnel must contain the outbreak.", "Biohazard Alert", 'sound/effects/siren-spooky.ogg')
|
||||
else
|
||||
log_and_message_admins("Warning: Could not spawn any mobs for event Terror Spiders")
|
||||
|
||||
/datum/event/spider_terror/start()
|
||||
|
||||
var/list/vents = list()
|
||||
for(var/obj/machinery/atmospherics/unary/vent_pump/temp_vent in GLOB.all_vent_pumps)
|
||||
if(is_station_level(temp_vent.loc.z) && !temp_vent.welded)
|
||||
if(!temp_vent.parent)
|
||||
// Issue happening more often with vents. Log and continue. Delete once solved
|
||||
log_debug("spider_terror/start(), vent has no parent: [temp_vent], qdeled: [QDELETED(temp_vent)], loc: [temp_vent.loc]")
|
||||
continue
|
||||
if(temp_vent.parent.other_atmosmch.len > 50)
|
||||
vents += temp_vent
|
||||
var/list/vents = get_valid_vent_spawns(exclude_mobs_nearby = TRUE, exclude_visible_by_mobs = TRUE)
|
||||
var/spider_type
|
||||
var/infestation_type
|
||||
if((length(GLOB.clients)) < TS_HIGHPOP_TRIGGER)
|
||||
@@ -49,27 +44,11 @@
|
||||
// Strongest, only used during highpop.
|
||||
spider_type = /mob/living/simple_animal/hostile/poison/terror_spider/queen
|
||||
spawncount = 1
|
||||
while(spawncount >= 1 && vents.len)
|
||||
var/obj/machinery/atmospherics/unary/vent_pump/vent = pick(vents)
|
||||
|
||||
if(vent.welded)
|
||||
vents -= vent
|
||||
continue
|
||||
|
||||
// If the vent we picked has any living mob nearby, just remove it from the list, loop again, and pick something else.
|
||||
|
||||
var/turf/T = get_turf(vent)
|
||||
var/hostiles_present = FALSE
|
||||
for(var/mob/living/L in viewers(T))
|
||||
if(L.stat != DEAD)
|
||||
hostiles_present = TRUE
|
||||
break
|
||||
|
||||
vents -= vent
|
||||
if(!hostiles_present)
|
||||
new spider_type(vent.loc)
|
||||
spawncount--
|
||||
|
||||
while(spawncount && length(vents))
|
||||
var/obj/vent = pick_n_take(vents)
|
||||
new spider_type(vent.loc)
|
||||
spawncount--
|
||||
successSpawn = TRUE
|
||||
|
||||
#undef TS_HIGHPOP_TRIGGER
|
||||
|
||||
|
||||
@@ -226,7 +226,7 @@
|
||||
desc = "Made in Space Switzerland."
|
||||
icon_state = "hot_coco"
|
||||
item_state = "coffee"
|
||||
list_reagents = list("chocolate" = 30)
|
||||
list_reagents = list("hot_coco" = 15, "chocolate" = 6, "water" = 9)
|
||||
resistance_flags = FREEZE_PROOF
|
||||
|
||||
/obj/item/reagent_containers/food/drinks/weightloss
|
||||
|
||||
@@ -370,6 +370,7 @@
|
||||
var/extra_reagent = null
|
||||
filling_color = "#D2691E"
|
||||
var/randomized_sprinkles = 1
|
||||
var/donut_sprite_type = "regular"
|
||||
tastes = list("donut" = 1)
|
||||
|
||||
/obj/item/reagent_containers/food/snacks/donut/New()
|
||||
@@ -378,6 +379,7 @@
|
||||
icon_state = "donut2"
|
||||
name = "frosted donut"
|
||||
reagents.add_reagent("sprinkles", 2)
|
||||
donut_sprite_type = "frosted"
|
||||
filling_color = "#FF69B4"
|
||||
|
||||
/obj/item/reagent_containers/food/snacks/donut/sprinkles
|
||||
@@ -385,6 +387,7 @@
|
||||
icon_state = "donut2"
|
||||
list_reagents = list("nutriment" = 3, "sugar" = 2, "sprinkles" = 2)
|
||||
filling_color = "#FF69B4"
|
||||
donut_sprite_type = "frosted"
|
||||
randomized_sprinkles = 0
|
||||
|
||||
/obj/item/reagent_containers/food/snacks/donut/chaos
|
||||
@@ -408,6 +411,7 @@
|
||||
desc = "You jelly?"
|
||||
icon_state = "jdonut1"
|
||||
extra_reagent = "berryjuice"
|
||||
donut_sprite_type = "jelly"
|
||||
tastes = list("jelly" = 1, "donut" = 3)
|
||||
|
||||
/obj/item/reagent_containers/food/snacks/donut/jelly/New()
|
||||
@@ -417,6 +421,7 @@
|
||||
if(prob(30))
|
||||
icon_state = "jdonut2"
|
||||
name = "frosted jelly Donut"
|
||||
donut_sprite_type = "frostedjelly"
|
||||
reagents.add_reagent("sprinkles", 2)
|
||||
filling_color = "#FF69B4"
|
||||
|
||||
|
||||
@@ -65,6 +65,7 @@
|
||||
name = "sweet & sour chicken balls"
|
||||
desc = "Is this chicken cooked? The odds are better than wok paper scissors."
|
||||
icon_state = "chickenball"
|
||||
item_state = "chinese3"
|
||||
junkiness = 25
|
||||
list_reagents = list("nutriment" = 2, "msg" = 4, "sugar" = 2)
|
||||
tastes = list("chicken" = 1, "sweetness" = 1)
|
||||
@@ -89,6 +90,7 @@
|
||||
name = "fried rice"
|
||||
desc = "A timeless classic."
|
||||
icon_state = "chinese4"
|
||||
item_state = "chinese2"
|
||||
junkiness = 20
|
||||
list_reagents = list("nutriment" = 1, "rice" = 3, "msg" = 4, "sugar" = 2)
|
||||
tastes = list("rice" = 1)
|
||||
|
||||
@@ -323,7 +323,7 @@
|
||||
else
|
||||
I = image(icon = myseed.growing_icon, icon_state = myseed.icon_harvest)
|
||||
else
|
||||
var/t_growthstate = min(round((age / myseed.maturation) * myseed.growthstages), myseed.growthstages)
|
||||
var/t_growthstate = clamp(round((age / myseed.maturation) * myseed.growthstages), 1, myseed.growthstages)
|
||||
I = image(icon = myseed.growing_icon, icon_state = "[myseed.icon_grow][t_growthstate]")
|
||||
I.layer = OBJ_LAYER + 0.01
|
||||
overlays += I
|
||||
|
||||
@@ -85,7 +85,7 @@ GLOBAL_LIST_EMPTY(karma_spenders)
|
||||
log_game("Illegal karma spending attempt detected from [key] to [M.key]. Using the same IP!")
|
||||
to_chat(src, "<span class='warning'>You can't spend karma on someone connected from the same IP.</span>")
|
||||
return FALSE
|
||||
if(M.get_preference(DISABLE_KARMA))
|
||||
if(M.get_preference(PREFTOGGLE_DISABLE_KARMA))
|
||||
to_chat(src, "<span class='warning'>That player has turned off incoming karma.")
|
||||
return FALSE
|
||||
return TRUE
|
||||
|
||||
@@ -5,7 +5,7 @@
|
||||
if(!user.keys_held["Ctrl"])
|
||||
var/movement_dir = NONE
|
||||
var/list/movement = SSinput.movement_keys
|
||||
if(user.prefs.toggles & AZERTY)
|
||||
if(user.prefs.toggles & PREFTOGGLE_AZERTY)
|
||||
movement = SSinput.alt_movement_keys
|
||||
for(var/_key in user.keys_held)
|
||||
movement_dir = movement_dir | movement[_key]
|
||||
|
||||
@@ -44,7 +44,7 @@
|
||||
current_key_address = ((current_key_address + 1) % HELD_KEY_BUFFER_LENGTH)
|
||||
|
||||
var/movement = SSinput.movement_keys[_key]
|
||||
if (prefs.toggles & AZERTY) movement = SSinput.alt_movement_keys[_key]
|
||||
if (prefs.toggles & PREFTOGGLE_AZERTY) movement = SSinput.alt_movement_keys[_key]
|
||||
if(!(next_move_dir_sub & movement) && !keys_held["Ctrl"])
|
||||
next_move_dir_add |= movement
|
||||
|
||||
@@ -85,7 +85,7 @@
|
||||
keys_held[i] = null
|
||||
break
|
||||
var/movement = SSinput.movement_keys[_key]
|
||||
if (prefs.toggles & AZERTY) movement = SSinput.alt_movement_keys[_key]
|
||||
if (prefs.toggles & PREFTOGGLE_AZERTY) movement = SSinput.alt_movement_keys[_key]
|
||||
if(!(next_move_dir_add & movement))
|
||||
next_move_dir_sub |= movement
|
||||
|
||||
|
||||
@@ -3,7 +3,7 @@
|
||||
// Or we can have NPC's send actual keypresses and detect that by seeing no client
|
||||
|
||||
/mob/key_down(_key, client/user)
|
||||
if(user.prefs.toggles & AZERTY)
|
||||
if(user.prefs.toggles & PREFTOGGLE_AZERTY)
|
||||
switch(_key)
|
||||
if("Delete")
|
||||
if(!pulling)
|
||||
@@ -70,7 +70,7 @@
|
||||
toggle_move_intent()
|
||||
return
|
||||
//Bodypart selections
|
||||
if(client.prefs.toggles & NUMPAD_TARGET)
|
||||
if(client.prefs.toggles & PREFTOGGLE_NUMPAD_TARGET)
|
||||
switch(_key)
|
||||
if("Numpad8")
|
||||
user.body_toggle_head()
|
||||
@@ -107,7 +107,7 @@
|
||||
if("Numpad4")
|
||||
a_intent_change("harm")
|
||||
return
|
||||
if(client.keys_held["Ctrl"] && client.prefs.toggles & AZERTY)
|
||||
if(client.keys_held["Ctrl"] && client.prefs.toggles & PREFTOGGLE_AZERTY)
|
||||
switch(SSinput.alt_movement_keys[_key])
|
||||
if(NORTH)
|
||||
northface()
|
||||
|
||||
@@ -10,9 +10,9 @@
|
||||
cycle_modules()
|
||||
return
|
||||
if("Q")
|
||||
if(!(client.prefs.toggles & AZERTY))
|
||||
if(!(client.prefs.toggles & PREFTOGGLE_AZERTY))
|
||||
on_drop_hotkey_press() // User is in QWERTY hotkey mode.
|
||||
if("A")
|
||||
if(client.prefs.toggles & AZERTY)
|
||||
if(client.prefs.toggles & PREFTOGGLE_AZERTY)
|
||||
on_drop_hotkey_press()
|
||||
return ..()
|
||||
|
||||
@@ -11,6 +11,7 @@
|
||||
throw_range = 5
|
||||
origin_tech = "bluespace=2"
|
||||
slot_flags = SLOT_BELT
|
||||
var/emagged = FALSE
|
||||
|
||||
/obj/item/wormhole_jaunter/attack_self(mob/user)
|
||||
user.visible_message("<span class='notice'>[user.name] activates the [name]!</span>")
|
||||
@@ -43,6 +44,7 @@
|
||||
return
|
||||
var/chosen_beacon = pick(L)
|
||||
var/obj/effect/portal/jaunt_tunnel/J = new(get_turf(src), get_turf(chosen_beacon), src, 100)
|
||||
J.emagged = emagged
|
||||
if(adjacent)
|
||||
try_move_adjacent(J)
|
||||
else
|
||||
@@ -57,12 +59,26 @@
|
||||
else
|
||||
to_chat(user, "[src] is not attached to your belt, preventing it from saving you from the chasm. RIP.</span>")
|
||||
|
||||
/obj/item/wormhole_jaunter/emag_act(mob/user)
|
||||
if(!emagged)
|
||||
emagged = TRUE
|
||||
to_chat(user, "<span class='notice'>You emag [src].</span>")
|
||||
var/turf/T = get_turf(src)
|
||||
do_sparks(5, 0, T)
|
||||
playsound(T, "sparks", 50, 1)
|
||||
|
||||
/obj/effect/portal/jaunt_tunnel
|
||||
name = "jaunt tunnel"
|
||||
icon = 'icons/effects/effects.dmi'
|
||||
icon_state = "bhole3"
|
||||
desc = "A stable hole in the universe made by a wormhole jaunter. Turbulent doesn't even begin to describe how rough passage through one of these is, but at least it will always get you somewhere near a beacon."
|
||||
failchance = 0
|
||||
var/emagged = FALSE
|
||||
|
||||
/obj/effect/portal/jaunt_tunnel/can_teleport(atom/movable/M)
|
||||
if(!emagged && ismegafauna(M))
|
||||
return FALSE
|
||||
return ..()
|
||||
|
||||
/obj/effect/portal/jaunt_tunnel/teleport(atom/movable/M)
|
||||
. = ..()
|
||||
|
||||
@@ -120,13 +120,18 @@
|
||||
return
|
||||
|
||||
var/mob/living/carbon/human/H = user
|
||||
var/random = rand(1,2)
|
||||
var/random = rand(1,3)
|
||||
|
||||
switch(random)
|
||||
if(1)
|
||||
to_chat(user, "<span class='danger'>Your flesh begins to melt! Miraculously, you seem fine otherwise.</span>")
|
||||
H.set_species(/datum/species/skeleton)
|
||||
if(2)
|
||||
to_chat(user, "<span class='danger'>Power courses through you! You can now shift your form at will.")
|
||||
if(user.mind)
|
||||
var/obj/effect/proc_holder/spell/targeted/shapeshift/dragon/D = new
|
||||
user.mind.AddSpell(D)
|
||||
if(3)
|
||||
to_chat(user, "<span class='danger'>You feel like you could walk straight through lava now.</span>")
|
||||
H.weather_immunities |= "lava"
|
||||
|
||||
|
||||
@@ -393,7 +393,8 @@
|
||||
activation_method = "touch"
|
||||
cooldown_add = 50
|
||||
activation_sound = 'sound/magic/timeparadox2.ogg'
|
||||
var/list/banned_items_typecache = list(/obj/item/storage, /obj/item/implant, /obj/item/implanter, /obj/item/disk/nuclear, /obj/item/projectile, /obj/item/spellbook)
|
||||
var/list/banned_items_typecache = list(/obj/item/storage, /obj/item/implant, /obj/item/implanter, /obj/item/disk/nuclear,
|
||||
/obj/item/projectile, /obj/item/spellbook, /obj/item/clothing/mask/facehugger)
|
||||
|
||||
/obj/machinery/anomalous_crystal/refresher/New()
|
||||
..()
|
||||
|
||||
@@ -254,7 +254,7 @@
|
||||
new /obj/item/extinguisher/mini(drop_location)
|
||||
new /obj/item/twohanded/kinetic_crusher(drop_location)
|
||||
if("Mining Conscription Kit")
|
||||
new /obj/item/storage/backpack/duffel/mining_conscript/full(drop_location)
|
||||
new /obj/item/storage/backpack/duffel/mining_conscript(drop_location)
|
||||
|
||||
qdel(voucher)
|
||||
|
||||
@@ -343,27 +343,6 @@
|
||||
. = ..()
|
||||
. += "There's [points] points on the card."
|
||||
|
||||
/**********************Conscription Kit**********************/
|
||||
|
||||
/obj/item/card/id/mining_access_card
|
||||
name = "mining access card"
|
||||
desc = "A small card, that when used on any ID, will add mining access."
|
||||
icon_state = "data"
|
||||
|
||||
/obj/item/card/id/mining_access_card/afterattack(atom/movable/AM, mob/user, proximity)
|
||||
. = ..()
|
||||
if(istype(AM, /obj/item/card/id) && proximity)
|
||||
var/obj/item/card/id/I = AM
|
||||
I.access |= list(ACCESS_MINING, ACCESS_MINING_STATION, ACCESS_MINERAL_STOREROOM, ACCESS_CARGO)
|
||||
to_chat(user, "You upgrade [I] with mining access.")
|
||||
qdel(src)
|
||||
|
||||
/obj/item/storage/backpack/duffel/mining_conscript/full
|
||||
name = "mining conscription kit"
|
||||
desc = "A kit containing everything a crewmember needs to support a shaft miner in the field."
|
||||
|
||||
/obj/item/storage/backpack/duffel/mining_conscript/full/New()
|
||||
..()
|
||||
new /obj/item/card/id/mining_access_card(src)
|
||||
|
||||
#undef EQUIPMENT
|
||||
|
||||
|
||||
@@ -576,7 +576,7 @@ This is the proc mobs get to turn into a ghost. Forked from ghostize due to comp
|
||||
|
||||
var/dat
|
||||
dat += "<h4>Crew Manifest</h4>"
|
||||
dat += GLOB.data_core.get_manifest()
|
||||
dat += GLOB.data_core.get_manifest(OOC = TRUE)
|
||||
|
||||
src << browse(dat, "window=manifest;size=370x420;can_close=1")
|
||||
|
||||
@@ -647,8 +647,8 @@ This is the proc mobs get to turn into a ghost. Forked from ghostize due to comp
|
||||
set name = "Toggle Anonymous Dead-chat"
|
||||
set category = "Ghost"
|
||||
set desc = "Toggles showing your key in dead chat."
|
||||
client.prefs.ghost_anonsay = !client.prefs.ghost_anonsay
|
||||
to_chat(src, "As a ghost, your key will [(client.prefs.ghost_anonsay) ? "no longer" : "now"] be shown when you speak in dead chat.</span>")
|
||||
client.prefs.toggles2 ^= PREFTOGGLE_2_ANONDCHAT
|
||||
to_chat(src, "As a ghost, your key will [(client.prefs.toggles2 & PREFTOGGLE_2_ANONDCHAT) ? "no longer" : "now"] be shown when you speak in dead chat.</span>")
|
||||
client.prefs.save_preferences(src)
|
||||
|
||||
/mob/dead/observer/verb/toggle_ghostsee()
|
||||
|
||||
@@ -72,7 +72,7 @@
|
||||
if(findtext(message, " snores.")) //Because we have so many sleeping people.
|
||||
break
|
||||
|
||||
if(isobserver(M) && M.get_preference(CHAT_GHOSTSIGHT) && !(M in viewers(src, null)) && client) // The client check makes sure people with ghost sight don't get spammed by simple mobs emoting.
|
||||
if(isobserver(M) && M.get_preference(PREFTOGGLE_CHAT_GHOSTSIGHT) && !(M in viewers(src, null)) && client) // The client check makes sure people with ghost sight don't get spammed by simple mobs emoting.
|
||||
M.show_message(message)
|
||||
|
||||
// Type 1 (Visual) emotes are sent to anyone in view of the item
|
||||
@@ -111,7 +111,7 @@
|
||||
to_chat(src, "<span class='warning'>You cannot send deadchat emotes (muted).</span>")
|
||||
return
|
||||
|
||||
if(!(client.prefs.toggles & CHAT_DEAD))
|
||||
if(!(client.prefs.toggles & PREFTOGGLE_CHAT_DEAD))
|
||||
to_chat(src, "<span class='warning'>You have deadchat muted.</span>")
|
||||
return
|
||||
|
||||
@@ -138,8 +138,8 @@
|
||||
if(isnewplayer(M))
|
||||
continue
|
||||
|
||||
if(check_rights(R_ADMIN|R_MOD, 0, M) && M.get_preference(CHAT_DEAD)) // Show the emote to admins/mods
|
||||
if(check_rights(R_ADMIN|R_MOD, 0, M) && M.get_preference(PREFTOGGLE_CHAT_DEAD)) // Show the emote to admins/mods
|
||||
to_chat(M, message)
|
||||
|
||||
else if(M.stat == DEAD && M.get_preference(CHAT_DEAD)) // Show the emote to regular ghosts with deadchat toggled on
|
||||
else if(M.stat == DEAD && M.get_preference(PREFTOGGLE_CHAT_DEAD)) // Show the emote to regular ghosts with deadchat toggled on
|
||||
M.show_message(message, 2)
|
||||
|
||||
@@ -51,7 +51,7 @@
|
||||
if(!client)
|
||||
return 0
|
||||
|
||||
if(isobserver(src) && client.prefs.toggles & CHAT_GHOSTEARS)
|
||||
if(isobserver(src) && client.prefs.toggles & PREFTOGGLE_CHAT_GHOSTEARS)
|
||||
if(speaker && !speaker.client && !(speaker in view(src)))
|
||||
//Does the speaker have a client? It's either random stuff that observers won't care about (Experiment 97B says, 'EHEHEHEHEHEHEHE')
|
||||
//Or someone snoring. So we make it where they won't hear it.
|
||||
@@ -90,7 +90,7 @@
|
||||
if(speaker_name != speaker.real_name && speaker.real_name)
|
||||
speaker_name = "[speaker.real_name] ([speaker_name])"
|
||||
track = "([ghost_follow_link(speaker, ghost=src)]) "
|
||||
if(client.prefs.toggles & CHAT_GHOSTEARS && (speaker in view(src)))
|
||||
if(client.prefs.toggles & PREFTOGGLE_CHAT_GHOSTEARS && (speaker in view(src)))
|
||||
message = "<b>[message]</b>"
|
||||
|
||||
if(!can_hear())
|
||||
|
||||
@@ -23,6 +23,9 @@
|
||||
// Needed to fix a rather insane bug when a posibrain/robotic brain commits suicide
|
||||
var/dead_icon = "mmi_dead"
|
||||
|
||||
/// Time at which the ghost belonging to the mind in the mmi can be pinged again to be borged
|
||||
var/next_possible_ghost_ping
|
||||
|
||||
/obj/item/mmi/attackby(var/obj/item/O as obj, var/mob/user as mob, params)
|
||||
if(istype(O, /obj/item/organ/internal/brain/crystal))
|
||||
to_chat(user, "<span class='warning'> This brain is too malformed to be able to use with the [src].</span>")
|
||||
|
||||
@@ -986,7 +986,7 @@
|
||||
if(isnewplayer(M))
|
||||
continue
|
||||
|
||||
if(isobserver(M) && M.get_preference(CHAT_GHOSTSIGHT) && !(M in viewers(src, null)) && client) // The client check makes sure people with ghost sight don't get spammed by simple mobs emoting.
|
||||
if(isobserver(M) && M.get_preference(PREFTOGGLE_CHAT_GHOSTSIGHT) && !(M in viewers(src, null)) && client) // The client check makes sure people with ghost sight don't get spammed by simple mobs emoting.
|
||||
M.show_message(message)
|
||||
|
||||
switch(m_type)
|
||||
|
||||
@@ -218,37 +218,38 @@
|
||||
////////////////
|
||||
// MOVE SPEED //
|
||||
////////////////
|
||||
#define ADD_SLOWDOWN(__value) if(!ignoreslow || __value < 0) . += __value
|
||||
|
||||
/datum/species/proc/movement_delay(mob/living/carbon/human/H)
|
||||
. = 0 //We start at 0.
|
||||
var/flight = 0 //Check for flight and flying items
|
||||
var/ignoreslow = 0
|
||||
var/gravity = 0
|
||||
|
||||
if(H.flying)
|
||||
flight = 1
|
||||
|
||||
if((H.status_flags & IGNORESLOWDOWN) || (RUN in H.mutations))
|
||||
ignoreslow = 1
|
||||
if(H.status_flags & IGNORE_SPEED_CHANGES)
|
||||
return .
|
||||
|
||||
if(has_gravity(H))
|
||||
gravity = 1
|
||||
if(H.status_flags & GOTTAGOFAST)
|
||||
. -= 1
|
||||
|
||||
if(!ignoreslow && gravity)
|
||||
if(speed_mod)
|
||||
. = speed_mod
|
||||
var/ignoreslow = FALSE
|
||||
if((H.status_flags & IGNORESLOWDOWN) || (RUN in H.mutations))
|
||||
ignoreslow = TRUE
|
||||
|
||||
var/flight = H.flying //Check for flight and flying items
|
||||
|
||||
ADD_SLOWDOWN(speed_mod)
|
||||
|
||||
if(H.wear_suit)
|
||||
. += H.wear_suit.slowdown
|
||||
if(!H.buckled)
|
||||
if(H.shoes)
|
||||
. += H.shoes.slowdown
|
||||
ADD_SLOWDOWN(H.wear_suit.slowdown)
|
||||
if(!H.buckled && H.shoes)
|
||||
ADD_SLOWDOWN(H.shoes.slowdown)
|
||||
if(H.back)
|
||||
. += H.back.slowdown
|
||||
ADD_SLOWDOWN(H.back.slowdown)
|
||||
if(H.l_hand && (H.l_hand.flags & HANDSLOW))
|
||||
. += H.l_hand.slowdown
|
||||
ADD_SLOWDOWN(H.l_hand.slowdown)
|
||||
if(H.r_hand && (H.r_hand.flags & HANDSLOW))
|
||||
. += H.r_hand.slowdown
|
||||
ADD_SLOWDOWN(H.r_hand.slowdown)
|
||||
|
||||
if(ignoreslow)
|
||||
return . // Only malusses after here
|
||||
|
||||
var/health_deficiency = max(H.maxHealth - H.health, H.staminaloss)
|
||||
var/hungry = (500 - H.nutrition)/5 // So overeat would be 100 and default level would be 80
|
||||
@@ -270,10 +271,10 @@
|
||||
if(H.bodytemperature < BODYTEMP_COLD_DAMAGE_LIMIT)
|
||||
. += (BODYTEMP_COLD_DAMAGE_LIMIT - H.bodytemperature) / COLD_SLOWDOWN_FACTOR
|
||||
|
||||
if(H.status_flags & GOTTAGOFAST)
|
||||
. -= 1
|
||||
return .
|
||||
|
||||
#undef ADD_SLOWDOWN
|
||||
|
||||
/datum/species/proc/on_species_gain(mob/living/carbon/human/H) //Handles anything not already covered by basic species assignment.
|
||||
for(var/slot_id in no_equip)
|
||||
var/obj/item/thing = H.get_item_by_slot(slot_id)
|
||||
|
||||
@@ -251,7 +251,7 @@ GLOBAL_LIST_EMPTY(channel_to_radio_key)
|
||||
continue
|
||||
|
||||
if(isobserver(M))
|
||||
if(M.get_preference(CHAT_GHOSTEARS) && client) // The client check is so that ghosts don't have to listen to mice.
|
||||
if(M.get_preference(PREFTOGGLE_CHAT_GHOSTEARS) && client) // The client check is so that ghosts don't have to listen to mice.
|
||||
listening |= M
|
||||
continue
|
||||
|
||||
@@ -311,7 +311,7 @@ GLOBAL_LIST_EMPTY(channel_to_radio_key)
|
||||
if(isnewplayer(M))
|
||||
continue
|
||||
|
||||
if(isobserver(M) && M.get_preference(CHAT_GHOSTSIGHT) && !(M in viewers(src, null)) && client) // The client check makes sure people with ghost sight don't get spammed by simple mobs emoting.
|
||||
if(isobserver(M) && M.get_preference(PREFTOGGLE_CHAT_GHOSTSIGHT) && !(M in viewers(src, null)) && client) // The client check makes sure people with ghost sight don't get spammed by simple mobs emoting.
|
||||
M.show_message(message)
|
||||
|
||||
switch(type)
|
||||
@@ -418,7 +418,7 @@ GLOBAL_LIST_EMPTY(channel_to_radio_key)
|
||||
continue
|
||||
|
||||
if(isobserver(M))
|
||||
if(M.get_preference(CHAT_GHOSTEARS)) // The client check is so that ghosts don't have to listen to mice.
|
||||
if(M.get_preference(PREFTOGGLE_CHAT_GHOSTEARS)) // The client check is so that ghosts don't have to listen to mice.
|
||||
listening |= M
|
||||
continue
|
||||
|
||||
|
||||
@@ -47,6 +47,13 @@
|
||||
if(C.can_inject(null, FALSE, inject_target, FALSE))
|
||||
C.reagents.add_reagent("spidertoxin", venom_per_bite)
|
||||
|
||||
/mob/living/simple_animal/hostile/poison/giant_spider/get_spacemove_backup()
|
||||
. = ..()
|
||||
// If we don't find any normal thing to use, attempt to use any nearby spider structure instead.
|
||||
if(!.)
|
||||
for(var/obj/structure/spider/S in range(1, get_turf(src)))
|
||||
return S
|
||||
|
||||
//nursemaids - these create webs and eggs
|
||||
/mob/living/simple_animal/hostile/poison/giant_spider/nurse
|
||||
desc = "Furry and black, it makes you shudder to look at it. This one has brilliant green eyes."
|
||||
|
||||
@@ -391,6 +391,13 @@ GLOBAL_LIST_EMPTY(ts_spiderling_list)
|
||||
return TRUE
|
||||
|
||||
|
||||
/mob/living/simple_animal/hostile/poison/terror_spider/get_spacemove_backup()
|
||||
. = ..()
|
||||
// If we don't find any normal thing to use, attempt to use any nearby spider structure instead.
|
||||
if(!.)
|
||||
for(var/obj/structure/spider/S in range(1, get_turf(src)))
|
||||
return S
|
||||
|
||||
/mob/living/simple_animal/hostile/poison/terror_spider/Stat()
|
||||
..()
|
||||
// Determines what shows in the "Status" tab for player-controlled spiders. Used to help players understand spider health regeneration mechanics.
|
||||
|
||||
@@ -10,10 +10,10 @@
|
||||
|
||||
/mob/living/update_blurry_effects()
|
||||
if(eyes_blurred())
|
||||
overlay_fullscreen("blurry", /obj/screen/fullscreen/blurry)
|
||||
add_eyeblur()
|
||||
return 1
|
||||
else
|
||||
clear_fullscreen("blurry")
|
||||
remove_eyeblur()
|
||||
return 0
|
||||
|
||||
/mob/living/update_druggy_effects()
|
||||
@@ -133,3 +133,19 @@
|
||||
updatehealth("var edit")
|
||||
if("resize")
|
||||
update_transform()
|
||||
|
||||
/mob/proc/add_eyeblur()
|
||||
if(client?.screen)
|
||||
var/obj/screen/plane_master/game_world/GW = locate(/obj/screen/plane_master/game_world) in client.screen
|
||||
var/obj/screen/plane_master/floor/F = locate(/obj/screen/plane_master/floor) in client.screen
|
||||
GW.add_filter(EYE_BLUR_FILTER_KEY, FILTER_EYE_BLUR)
|
||||
F.add_filter(EYE_BLUR_FILTER_KEY, FILTER_EYE_BLUR)
|
||||
animate(GW.filters[GW.filters.len], size = 3, time = 5)
|
||||
animate(F.filters[F.filters.len], size = 3, time = 5)
|
||||
|
||||
/mob/proc/remove_eyeblur()
|
||||
if(client?.screen)
|
||||
var/obj/screen/plane_master/game_world/GW = locate(/obj/screen/plane_master/game_world) in client.screen
|
||||
var/obj/screen/plane_master/floor/F = locate(/obj/screen/plane_master/floor) in client.screen
|
||||
GW.remove_filter(EYE_BLUR_FILTER_KEY)
|
||||
F.remove_filter(EYE_BLUR_FILTER_KEY)
|
||||
|
||||
+6
-13
@@ -1133,21 +1133,14 @@ GLOBAL_LIST_INIT(slot_equipment_priority, list( \
|
||||
return
|
||||
|
||||
//find a viable mouse candidate
|
||||
var/mob/living/simple_animal/mouse/host
|
||||
var/obj/machinery/atmospherics/unary/vent_pump/vent_found
|
||||
var/list/found_vents = list()
|
||||
for(var/obj/machinery/atmospherics/unary/vent_pump/v in SSair.atmos_machinery)
|
||||
if(!v.welded && v.z == src.z)
|
||||
found_vents.Add(v)
|
||||
if(found_vents.len)
|
||||
vent_found = pick(found_vents)
|
||||
host = new /mob/living/simple_animal/mouse(vent_found.loc)
|
||||
else
|
||||
to_chat(src, "<span class='warning'>Unable to find any unwelded vents to spawn mice at.</span>")
|
||||
|
||||
if(host)
|
||||
var/list/found_vents = get_valid_vent_spawns(min_network_size = 0, station_levels_only = FALSE, z_level = z)
|
||||
if(length(found_vents))
|
||||
var/obj/vent_found = pick(found_vents)
|
||||
var/mob/living/simple_animal/mouse/host = new(vent_found.loc)
|
||||
host.ckey = src.ckey
|
||||
to_chat(host, "<span class='info'>You are now a mouse. Try to avoid interaction with players, and do not give hints away that you are more than a simple rodent.</span>")
|
||||
else
|
||||
to_chat(src, "<span class='warning'>Unable to find any unwelded vents to spawn mice at.</span>")
|
||||
|
||||
/mob/proc/assess_threat() //For sec bot threat assessment
|
||||
return 5
|
||||
|
||||
@@ -459,7 +459,7 @@ GLOBAL_LIST_INIT(intents, list(INTENT_HELP,INTENT_DISARM,INTENT_GRAB,INTENT_HARM
|
||||
name = realname
|
||||
|
||||
for(var/mob/M in GLOB.player_list)
|
||||
if(M.client && ((!isnewplayer(M) && M.stat == DEAD) || check_rights(R_ADMIN|R_MOD,0,M)) && M.get_preference(CHAT_DEAD))
|
||||
if(M.client && ((!isnewplayer(M) && M.stat == DEAD) || check_rights(R_ADMIN|R_MOD,0,M)) && M.get_preference(PREFTOGGLE_CHAT_DEAD))
|
||||
var/follow
|
||||
var/lname
|
||||
if(subject)
|
||||
@@ -471,9 +471,9 @@ GLOBAL_LIST_INIT(intents, list(INTENT_HELP,INTENT_DISARM,INTENT_GRAB,INTENT_HARM
|
||||
if(istype(subject, /mob/dead/observer))
|
||||
DM = subject
|
||||
if(check_rights(R_ADMIN|R_MOD,0,M)) // What admins see
|
||||
lname = "[keyname][(DM && DM.client && DM.client.prefs.ghost_anonsay) ? "*" : (DM ? "" : "^")] ([name])"
|
||||
lname = "[keyname][(DM && DM.client && DM.client.prefs.toggles2 & PREFTOGGLE_2_ANONDCHAT) ? "*" : (DM ? "" : "^")] ([name])"
|
||||
else
|
||||
if(DM && DM.client && DM.client.prefs.ghost_anonsay) // If the person is actually observer they have the option to be anonymous
|
||||
if(DM && DM.client && DM.client.prefs.toggles2 & PREFTOGGLE_2_ANONDCHAT) // If the person is actually observer they have the option to be anonymous
|
||||
lname = "Ghost of [name]"
|
||||
else if(DM) // Non-anons
|
||||
lname = "[keyname] ([name])"
|
||||
|
||||
@@ -60,7 +60,7 @@
|
||||
|
||||
/mob/new_player/proc/new_player_panel_proc()
|
||||
var/real_name = client.prefs.real_name
|
||||
if(client.prefs.randomslot)
|
||||
if(client.prefs.toggles2 & PREFTOGGLE_2_RANDOMSLOT)
|
||||
real_name = "Random Character Slot"
|
||||
var/output = "<center><p><a href='byond://?src=[UID()];show_preferences=1'>Setup Character</A><br /><i>[real_name]</i></p>"
|
||||
|
||||
@@ -250,7 +250,7 @@
|
||||
to_chat(usr, "<span class='notice'>There is an administrative lock on entering the game!</span>")
|
||||
return
|
||||
|
||||
if(client.prefs.randomslot)
|
||||
if(client.prefs.toggles2 & PREFTOGGLE_2_RANDOMSLOT)
|
||||
client.prefs.load_random_character_slot(client)
|
||||
|
||||
if(client.prefs.species in GLOB.whitelisted_species)
|
||||
|
||||
@@ -55,7 +55,7 @@
|
||||
to_chat(src, "<span class='warning'>You cannot talk in deadchat (muted).</span>")
|
||||
return
|
||||
|
||||
if(!(client.prefs.toggles & CHAT_DEAD))
|
||||
if(!(client.prefs.toggles & PREFTOGGLE_CHAT_DEAD))
|
||||
to_chat(src, "<span class='danger'>You have deadchat muted.</span>")
|
||||
return
|
||||
|
||||
|
||||
@@ -21,7 +21,7 @@ GLOBAL_LIST_EMPTY(typing_indicator)
|
||||
return
|
||||
|
||||
if(client)
|
||||
if((client.prefs.toggles & SHOW_TYPING) || stat != CONSCIOUS || is_muzzled())
|
||||
if((client.prefs.toggles & PREFTOGGLE_SHOW_TYPING) || stat != CONSCIOUS || is_muzzled())
|
||||
overlays -= GLOB.typing_indicator[bubble_icon]
|
||||
else
|
||||
if(state)
|
||||
@@ -61,7 +61,7 @@ GLOBAL_LIST_EMPTY(typing_indicator)
|
||||
|
||||
/mob/proc/handle_typing_indicator()
|
||||
if(client)
|
||||
if(!(client.prefs.toggles & SHOW_TYPING) && !hud_typing)
|
||||
if(!(client.prefs.toggles & PREFTOGGLE_SHOW_TYPING) && !hud_typing)
|
||||
var/temp = winget(client, "input", "text")
|
||||
|
||||
if(temp != last_typed)
|
||||
@@ -83,12 +83,12 @@ GLOBAL_LIST_EMPTY(typing_indicator)
|
||||
set name = "Show/Hide Typing Indicator"
|
||||
set category = "Preferences"
|
||||
set desc = "Toggles showing an indicator when you are typing emote or say message."
|
||||
prefs.toggles ^= SHOW_TYPING
|
||||
prefs.toggles ^= PREFTOGGLE_SHOW_TYPING
|
||||
prefs.save_preferences(src)
|
||||
to_chat(src, "You will [(prefs.toggles & SHOW_TYPING) ? "no longer" : "now"] display a typing indicator.")
|
||||
to_chat(src, "You will [(prefs.toggles & PREFTOGGLE_SHOW_TYPING) ? "no longer" : "now"] display a typing indicator.")
|
||||
|
||||
// Clear out any existing typing indicator.
|
||||
if(prefs.toggles & SHOW_TYPING)
|
||||
if(prefs.toggles & PREFTOGGLE_SHOW_TYPING)
|
||||
if(istype(mob)) mob.set_typing_indicator(0)
|
||||
|
||||
feedback_add_details("admin_verb","TID") //If you are copy-pasting this, ensure the 2nd parameter is unique to the new proc!
|
||||
|
||||
@@ -186,7 +186,7 @@ nanoui is used to open and update nano browser uis
|
||||
"mapZLevel" = map_z_level,
|
||||
"user" = list(
|
||||
"name" = user.name,
|
||||
"fancy" = user.client.prefs.nanoui_fancy
|
||||
"fancy" = user.client.prefs.toggles2 & PREFTOGGLE_2_FANCYUI
|
||||
),
|
||||
"window" = list(
|
||||
"width" = width,
|
||||
@@ -418,7 +418,7 @@ nanoui is used to open and update nano browser uis
|
||||
|
||||
// Preset the can_rezie and titlebar values on uis if the user has fancy uis set
|
||||
// Prevents the ui from flickering when opened
|
||||
if(user.client.prefs.nanoui_fancy)
|
||||
if(user.client.prefs.toggles2 & PREFTOGGLE_2_FANCYUI)
|
||||
set_window_options("focus=0;can_close=1;can_minimize=1;can_maximize=0;can_resize=0;titlebar=0;")
|
||||
|
||||
user << browse(get_html(), "window=[window_id];[window_size][window_options]")
|
||||
|
||||
@@ -0,0 +1,186 @@
|
||||
/**
|
||||
* # Feed Network
|
||||
*
|
||||
* Singleton that contains all informations related to newscasters (channels, stories).
|
||||
*/
|
||||
/datum/feed_network
|
||||
/// Contains all of the feed channels created during the round.
|
||||
var/list/datum/feed_channel/channels = list()
|
||||
/// Contains all of the feed stories created during the round.
|
||||
var/list/datum/feed_message/stories = list()
|
||||
/// The current wanted issue.
|
||||
var/datum/feed_message/wanted_issue
|
||||
|
||||
/**
|
||||
* Returns the [/datum/feed_channel] with the given name, or null if not found.
|
||||
*
|
||||
* Arguments:
|
||||
* * name - The name
|
||||
*/
|
||||
/datum/feed_network/proc/get_channel_by_name(name)
|
||||
RETURN_TYPE(/datum/feed_channel)
|
||||
for(var/fc in channels)
|
||||
var/datum/feed_channel/FC = fc
|
||||
if(FC.channel_name == name)
|
||||
return FC
|
||||
|
||||
/**
|
||||
* Returns the [/datum/feed_channel] with the given author, or null if not found.
|
||||
*
|
||||
* Arguments:
|
||||
* * author - The author
|
||||
*/
|
||||
/datum/feed_network/proc/get_channel_by_author(author)
|
||||
RETURN_TYPE(/datum/feed_channel)
|
||||
for(var/fc in channels)
|
||||
var/datum/feed_channel/FC = fc
|
||||
if(FC.author == author)
|
||||
return FC
|
||||
|
||||
/**
|
||||
* Returns the [/datum/feed_channel] at the given index, or null if not found.
|
||||
*
|
||||
* Arguments:
|
||||
* * idx - The index
|
||||
*/
|
||||
/datum/feed_network/proc/get_channel_by_idx(idx)
|
||||
RETURN_TYPE(/datum/feed_channel)
|
||||
if(!ISINDEXSAFE(channels, idx))
|
||||
return
|
||||
return channels[idx]
|
||||
|
||||
|
||||
/**
|
||||
* # Feed Message
|
||||
*
|
||||
* Describes a single feed story. Always owned by a [/datum/feed_channel].
|
||||
*/
|
||||
/datum/feed_message
|
||||
/// The author of the story.
|
||||
var/author = ""
|
||||
/// The title of the story.
|
||||
var/title = ""
|
||||
/// The textual contents of the story.
|
||||
var/body = ""
|
||||
/// The story's icon.
|
||||
var/icon/img = null
|
||||
/// Flags that dictate the story should be censored.
|
||||
var/censor_flags = 0
|
||||
/// Whether the story is admin-locked.
|
||||
var/admin_locked = FALSE
|
||||
/// The number of views the story has.
|
||||
var/view_count = 0
|
||||
/// The world.time at which the story was published.
|
||||
var/publish_time = 0
|
||||
|
||||
/datum/feed_message/New()
|
||||
publish_time = world.time
|
||||
|
||||
/**
|
||||
* Clears the story's information.
|
||||
*
|
||||
* Does not delete it from the owning channel.
|
||||
*/
|
||||
/datum/feed_message/proc/clear()
|
||||
author = ""
|
||||
title = ""
|
||||
body = ""
|
||||
img = null
|
||||
censor_flags = 0
|
||||
admin_locked = 0
|
||||
view_count = 0
|
||||
publish_time = 0
|
||||
|
||||
/**
|
||||
* # Feed Channel
|
||||
*
|
||||
* Describes a single feed channel. Owns a list of [/datum/feed_message].
|
||||
*/
|
||||
/datum/feed_channel
|
||||
/// The name of the channel.
|
||||
var/channel_name = ""
|
||||
/// The author of the channel.
|
||||
var/author = ""
|
||||
/// The description of the channel.
|
||||
var/description = ""
|
||||
/// The channel's icon.
|
||||
var/icon = "newspaper"
|
||||
/// The fallback author name to display if the channel is censored.
|
||||
var/backup_author = ""
|
||||
/// Lazy list. Contains all [/datum/feed_message] pertaining to the channel.
|
||||
var/list/datum/feed_message/messages
|
||||
/// Whether the channel is public or not.
|
||||
var/is_public = FALSE
|
||||
/// Whether the channel is frozen or not.
|
||||
var/frozen = FALSE
|
||||
/// Whether the channel is censored or not.
|
||||
var/censored = FALSE
|
||||
/// Whether the channel is admin-locked.
|
||||
var/admin_locked = FALSE
|
||||
|
||||
/datum/feed_channel/Destroy()
|
||||
for(var/m in messages)
|
||||
GLOB.news_network.stories -= m
|
||||
|
||||
/**
|
||||
* Returns whether the given user can publish new stories to this channel.
|
||||
*
|
||||
* Arguments:
|
||||
* * user - The user
|
||||
* * scanned_user - The user's identifying information on the newscaster
|
||||
*/
|
||||
/datum/feed_channel/proc/can_publish(mob/user, scanned_user = "Unknown")
|
||||
return (!frozen && (is_public || (author == scanned_user))) || user?.can_admin_interact()
|
||||
|
||||
/**
|
||||
* Returns whether the given user can edit or delete this channel.
|
||||
*
|
||||
* Arguments:
|
||||
* * user - The user
|
||||
* * scanned_user - The user's identifying information on the newscaster
|
||||
*/
|
||||
/datum/feed_channel/proc/can_modify(mob/user, scanned_user = "Unknown")
|
||||
return (!frozen && author == scanned_user) || user?.can_admin_interact()
|
||||
|
||||
/**
|
||||
* Clears the channel's information.
|
||||
*
|
||||
* Discards all owned stories.
|
||||
*/
|
||||
/datum/feed_channel/proc/clear()
|
||||
channel_name = ""
|
||||
author = ""
|
||||
backup_author = ""
|
||||
messages = list()
|
||||
is_public = FALSE
|
||||
frozen = FALSE
|
||||
censored = FALSE
|
||||
admin_locked = FALSE
|
||||
|
||||
/**
|
||||
* Adds a new [story][/datum/feed_message] to the channel and network singleton.
|
||||
*
|
||||
* Arguments:
|
||||
* * M - The story to add.
|
||||
*/
|
||||
/datum/feed_channel/proc/add_message(datum/feed_message/M)
|
||||
ASSERT(istype(M))
|
||||
|
||||
if(!length(M.title))
|
||||
M.title = "[channel_name] Story #[length(messages) + 1]"
|
||||
LAZYADD(messages, M)
|
||||
GLOB.news_network.stories += M
|
||||
// Update all newscaster TGUIs
|
||||
for(var/nc in GLOB.allNewscasters)
|
||||
SStgui.update_uis(nc)
|
||||
|
||||
/**
|
||||
* Returns the text to be said by newscasters when announcing new news from a channel.
|
||||
*
|
||||
* Arguments:
|
||||
* * title - Optional. The headline to announce along with the channel's name. Typically the newest story's title.
|
||||
*/
|
||||
/datum/feed_channel/proc/get_announce_text(title)
|
||||
if(length(title))
|
||||
return "Breaking news from [channel_name]: [title]"
|
||||
return "Breaking news from [channel_name]"
|
||||
@@ -0,0 +1,19 @@
|
||||
// Globals
|
||||
/// The feed network singleton. Contains all channels (which contain all stories).
|
||||
GLOBAL_DATUM_INIT(news_network, /datum/feed_network, new)
|
||||
/// Global list that contains all existing newscasters in the world.
|
||||
GLOBAL_LIST_EMPTY(allNewscasters)
|
||||
|
||||
// Screen indexes
|
||||
/// Headlines screen index.
|
||||
#define NEWSCASTER_HEADLINES 0
|
||||
/// Available Jobs screen index.
|
||||
#define NEWSCASTER_JOBS 1
|
||||
/// View Channel screen index.
|
||||
#define NEWSCASTER_CHANNEL 2
|
||||
|
||||
// Censor flags
|
||||
/// Censor author name.
|
||||
#define CENSOR_AUTHOR (1 << 0)
|
||||
/// Censor story title, body and image.
|
||||
#define CENSOR_STORY (1 << 1)
|
||||
@@ -0,0 +1,718 @@
|
||||
#define CHANNEL_NAME_MAX_LENGTH 50
|
||||
#define CHANNEL_DESC_MAX_LENGTH 128
|
||||
#define STORY_NAME_MAX_LENGTH 128
|
||||
#define STORY_BODY_MAX_LENGTH 1024
|
||||
#define WANTED_NOTICE_NAME_MAX_LENGTH 128
|
||||
#define WANTED_NOTICE_DESC_MAX_LENGTH 512
|
||||
#define STORIES_PER_LOAD 9999 // TODO during QP...
|
||||
|
||||
/**
|
||||
* # Newscaster
|
||||
*
|
||||
* For all of the crew's news need. Includes reading, submitting and printing stories.
|
||||
*
|
||||
* Includes a security variant which can be used to issue wanted notices, censor channels and stories.
|
||||
* Allows full access when aghosting.
|
||||
*/
|
||||
/obj/machinery/newscaster
|
||||
name = "newscaster"
|
||||
desc = "A standard Nanotrasen-licensed newsfeed handler for use in commercial space stations. All the news you absolutely have no use for, in one place!"
|
||||
icon = 'icons/obj/terminals.dmi'
|
||||
icon_state = "newscaster_normal"
|
||||
max_integrity = 200
|
||||
integrity_failure = 50
|
||||
light_range = 0
|
||||
anchored = TRUE
|
||||
/// The current screen index in the UI.
|
||||
var/screen = NEWSCASTER_HEADLINES
|
||||
/// The amount of newspapers the newscaster can print.
|
||||
var/paper_remaining = 15
|
||||
/// Whether the newscaster can be used to make wanted issues or not.
|
||||
var/is_security = FALSE
|
||||
/// Whether the newscaster has new stories or not.
|
||||
var/alert = FALSE
|
||||
/// The newcaster's index among all newscasters (GLOB.allNewscasters).
|
||||
var/unit_number = 0
|
||||
/// The name of the mob currently using the newscaster.
|
||||
var/scanned_user = "Unknown"
|
||||
/// The currently attached photo.
|
||||
var/obj/item/photo/photo = null
|
||||
/// The currently viewed channel.
|
||||
var/datum/feed_channel/viewing_channel = null
|
||||
/// Whether the unit is silent or not.
|
||||
var/is_silent = FALSE
|
||||
/// The current temporary notice.
|
||||
var/temp_notice
|
||||
/// Whether the newscaster is currently printing a newspaper or not.
|
||||
var/is_printing = FALSE
|
||||
/// Static list of jobs that shouldn't be advertised if a position is available.
|
||||
var/static/list/jobblacklist
|
||||
/// Static, lazy list containing a user's last view time per channel.
|
||||
var/static/last_views
|
||||
|
||||
/obj/machinery/newscaster/security_unit
|
||||
name = "security newscaster"
|
||||
is_security = TRUE
|
||||
|
||||
/obj/machinery/newscaster/New()
|
||||
GLOB.allNewscasters += src
|
||||
unit_number = length(GLOB.allNewscasters)
|
||||
update_icon() //for any custom ones on the map...
|
||||
if(!last_views)
|
||||
last_views = list()
|
||||
armor = list(melee = 50, bullet = 0, laser = 0, energy = 0, bomb = 0, bio = 0, rad = 0, fire = 50, acid = 30)
|
||||
..()
|
||||
|
||||
/obj/machinery/newscaster/Initialize(mapload)
|
||||
. = ..()
|
||||
if(!jobblacklist)
|
||||
jobblacklist = list(
|
||||
/datum/job/ai,
|
||||
/datum/job/cyborg,
|
||||
/datum/job/captain,
|
||||
/datum/job/judge,
|
||||
/datum/job/blueshield,
|
||||
/datum/job/nanotrasenrep,
|
||||
/datum/job/pilot,
|
||||
/datum/job/brigdoc,
|
||||
/datum/job/mechanic,
|
||||
/datum/job/barber,
|
||||
/datum/job/chaplain,
|
||||
/datum/job/ntnavyofficer,
|
||||
/datum/job/ntspecops,
|
||||
/datum/job/civilian,
|
||||
/datum/job/syndicateofficer
|
||||
)
|
||||
|
||||
/obj/machinery/newscaster/Destroy()
|
||||
GLOB.allNewscasters -= src
|
||||
viewing_channel = null
|
||||
QDEL_NULL(photo)
|
||||
return ..()
|
||||
|
||||
/obj/machinery/newscaster/update_icon()
|
||||
cut_overlays()
|
||||
if(inoperable())
|
||||
icon_state = "newscaster_off"
|
||||
else
|
||||
if(!GLOB.news_network.wanted_issue) //wanted icon state, there can be no overlays on it as it's a priority message
|
||||
icon_state = "newscaster_normal"
|
||||
if(alert) //new message alert overlay
|
||||
add_overlay("newscaster_alert")
|
||||
var/hp_percent = obj_integrity * 100 / max_integrity
|
||||
switch(hp_percent)
|
||||
if(75 to INFINITY)
|
||||
return
|
||||
if(50 to 75)
|
||||
add_overlay("crack1")
|
||||
if(25 to 50)
|
||||
add_overlay("crack2")
|
||||
else
|
||||
add_overlay("crack3")
|
||||
|
||||
/obj/machinery/newscaster/power_change()
|
||||
..()
|
||||
update_icon()
|
||||
|
||||
/obj/machinery/newscaster/take_damage(damage_amount, damage_type = BRUTE, damage_flag = 0, sound_effect = TRUE, attack_dir)
|
||||
. = ..()
|
||||
update_icon()
|
||||
|
||||
/obj/machinery/newscaster/wrench_act(mob/user, obj/item/I)
|
||||
. = TRUE
|
||||
if(!I.tool_use_check(user, 0))
|
||||
return
|
||||
to_chat(user, "<span class='notice'>Now [anchored ? "un" : ""]securing [name]</span>")
|
||||
if(!I.use_tool(src, user, 60, volume = I.tool_volume))
|
||||
return
|
||||
playsound(loc, 'sound/items/deconstruct.ogg', 50, TRUE)
|
||||
if(stat & BROKEN)
|
||||
to_chat(user, "<span class='warning'>The broken remains of [src] fall on the ground.</span>")
|
||||
new /obj/item/stack/sheet/metal(loc, 5)
|
||||
new /obj/item/shard(loc)
|
||||
new /obj/item/shard(loc)
|
||||
else
|
||||
to_chat(user, "<span class='notice'>You [anchored ? "un" : ""]secure [name].</span>")
|
||||
new /obj/item/mounted/frame/newscaster_frame(loc)
|
||||
qdel(src)
|
||||
|
||||
/obj/machinery/newscaster/welder_act(mob/user, obj/item/I)
|
||||
. = TRUE
|
||||
if(!I.tool_use_check(user, 0))
|
||||
return
|
||||
default_welder_repair(user, I)
|
||||
|
||||
/obj/machinery/newscaster/play_attack_sound(damage, damage_type = BRUTE, damage_flag = 0)
|
||||
switch(damage_type)
|
||||
if(BRUTE)
|
||||
if(stat & BROKEN)
|
||||
playsound(loc, 'sound/effects/hit_on_shattered_glass.ogg', 100, TRUE)
|
||||
else
|
||||
playsound(loc, 'sound/effects/glasshit.ogg', 90, TRUE)
|
||||
if(BURN)
|
||||
playsound(loc, 'sound/items/welder.ogg', 100, TRUE)
|
||||
|
||||
/obj/machinery/newscaster/deconstruct(disassembled = TRUE)
|
||||
if(!(flags & NODECONSTRUCT))
|
||||
new /obj/item/stack/sheet/metal(loc, 2)
|
||||
new /obj/item/shard(loc)
|
||||
new /obj/item/shard(loc)
|
||||
qdel(src)
|
||||
|
||||
/obj/machinery/newscaster/obj_break()
|
||||
if(!(stat & BROKEN) && !(flags & NODECONSTRUCT))
|
||||
stat |= BROKEN
|
||||
playsound(loc, 'sound/effects/glassbr3.ogg', 100, TRUE)
|
||||
update_icon()
|
||||
|
||||
/obj/machinery/newscaster/attack_ghost(mob/user)
|
||||
tgui_interact(user)
|
||||
|
||||
/obj/machinery/newscaster/attack_hand(mob/user)
|
||||
if(..())
|
||||
return
|
||||
tgui_interact(user)
|
||||
|
||||
/obj/machinery/newscaster/tgui_interact(mob/user, ui_key = "main", datum/tgui/ui = null, force_open = TRUE, datum/tgui/master_ui = null, datum/tgui_state/state = GLOB.tgui_default_state)
|
||||
if(can_scan(user))
|
||||
scanned_user = get_scanned_user(user)["name"]
|
||||
ui = SStgui.try_update_ui(user, src, ui_key, ui, force_open)
|
||||
if(!ui)
|
||||
ui = new(user, src, ui_key, "Newscaster", name, 800, 600)
|
||||
ui.open()
|
||||
ui.set_autoupdate(FALSE)
|
||||
|
||||
/obj/machinery/newscaster/tgui_data(mob/user)
|
||||
var/list/data = list()
|
||||
data["unit_number"] = unit_number
|
||||
data["is_security"] = is_security
|
||||
data["is_admin"] = user.can_admin_interact()
|
||||
data["is_silent"] = is_silent
|
||||
data["is_printing"] = is_printing
|
||||
data["screen"] = screen
|
||||
data["modal"] = tgui_modal_data(src)
|
||||
if(data["modal"] && !isnull(data["modal"]["args"]["is_admin"]))
|
||||
data["modal"]["args"]["is_admin"] = user.can_admin_interact()
|
||||
data["temp"] = temp_notice
|
||||
|
||||
// Wanted notice
|
||||
if(GLOB.news_network.wanted_issue)
|
||||
data["wanted"] = get_message_data(GLOB.news_network.wanted_issue, user)[1]
|
||||
data["world_time"] = world.time
|
||||
|
||||
var/user_name = get_scanned_user(user)["name"]
|
||||
switch(screen)
|
||||
if(NEWSCASTER_HEADLINES, NEWSCASTER_CHANNEL)
|
||||
// Get the list of stories to pick from - either all or from a specific channel depending on the screen
|
||||
var/list/message_list = GLOB.news_network.stories
|
||||
if(screen == NEWSCASTER_CHANNEL)
|
||||
if(!viewing_channel) // Uh oh, channel doesn't exist! Redirect to Headlines
|
||||
screen = NEWSCASTER_HEADLINES
|
||||
return tgui_data(user)
|
||||
message_list = viewing_channel.messages
|
||||
data["channel_idx"] = GLOB.news_network.channels.Find(viewing_channel)
|
||||
data["channel_can_manage"] = viewing_channel.can_modify(usr, user_name)
|
||||
// Append the data
|
||||
var/list/stories = list()
|
||||
data["stories"] = stories
|
||||
for(var/i in 1 to min(STORIES_PER_LOAD, length(message_list)))
|
||||
stories += get_message_data(message_list[i], user)
|
||||
// View and unread data
|
||||
var/now = world.time
|
||||
data["world_time"] = now
|
||||
if(user_name)
|
||||
// Increase views
|
||||
for(var/m in stories)
|
||||
if(now >= m["publish_time"])
|
||||
var/datum/feed_message/FM = locateUID(m["uid"])
|
||||
if(FM && !(FM.censor_flags & CENSOR_STORY))
|
||||
FM.view_count++
|
||||
m["view_count"] = FM.view_count
|
||||
// Update the last viewed times for the user
|
||||
LAZYINITLIST(last_views[user_name])
|
||||
for(var/c in GLOB.news_network.channels)
|
||||
var/datum/feed_channel/C = c
|
||||
if(screen == NEWSCASTER_CHANNEL && C != viewing_channel)
|
||||
continue
|
||||
last_views[user_name][C.UID()] = now
|
||||
if(NEWSCASTER_JOBS)
|
||||
var/list/jobs = list()
|
||||
data["jobs"] = jobs
|
||||
for(var/cat in list("security", "engineering", "medical", "science", "service", "supply"))
|
||||
jobs[cat] = list()
|
||||
|
||||
for(var/datum/job/job in SSjobs.occupations)
|
||||
if(job.type in jobblacklist)
|
||||
continue
|
||||
if(job.is_position_available())
|
||||
var/list/opening_data = list("title" = job.title)
|
||||
// Is the job a command job?
|
||||
if(job.title in GLOB.command_positions)
|
||||
opening_data["is_command"] = TRUE
|
||||
// Add the job opening to the corresponding categories
|
||||
// Ugly!
|
||||
opening_data = list(opening_data)
|
||||
if(job.is_security)
|
||||
jobs["security"] += opening_data
|
||||
if(job.is_engineering)
|
||||
jobs["engineering"] += opening_data
|
||||
if(job.is_medical)
|
||||
jobs["medical"] += opening_data
|
||||
if(job.is_science)
|
||||
jobs["science"] += opening_data
|
||||
if(job.is_service)
|
||||
jobs["service"] += opening_data
|
||||
if(job.is_supply)
|
||||
jobs["supply"] += opening_data
|
||||
|
||||
// Append temp photo
|
||||
if(photo && data["modal"] && (data["modal"]["id"] in list("create_story", "wanted_notice")))
|
||||
data["photo"] = list(
|
||||
name = photo.name,
|
||||
uid = photo.UID(),
|
||||
)
|
||||
user << browse_rsc(photo.img, "inserted_photo_[photo.UID()].png")
|
||||
else
|
||||
data["photo"] = null
|
||||
|
||||
// Append channels
|
||||
var/list/channels = list()
|
||||
data["channels"] = channels
|
||||
for(var/c in GLOB.news_network.channels)
|
||||
var/datum/feed_channel/C = c
|
||||
var/list/channel = list(
|
||||
uid = C.UID(),
|
||||
name = C.channel_name,
|
||||
author = C.author,
|
||||
description = C.description,
|
||||
icon = C.icon,
|
||||
public = C.is_public,
|
||||
frozen = C.frozen,
|
||||
censored = C.censored,
|
||||
admin = C.admin_locked,
|
||||
unread = 0,
|
||||
)
|
||||
// Add the number of unseen stories if authed
|
||||
if(user_name)
|
||||
var/last_view_time = (last_views[user_name] && last_views[user_name][C.UID()]) || 0
|
||||
for(var/m in C.messages)
|
||||
var/datum/feed_message/M = m
|
||||
if(last_view_time < M.publish_time)
|
||||
channel["unread"]++
|
||||
channels += list(channel)
|
||||
|
||||
return data
|
||||
|
||||
/**
|
||||
* Returns a [/datum/feed_message] in a format that can be used as TGUI data.
|
||||
*
|
||||
* Arguments:
|
||||
* * FM - The story to send
|
||||
* * M - Optional. The user to send the story's photo to if it exists
|
||||
*/
|
||||
/obj/machinery/newscaster/proc/get_message_data(datum/feed_message/FM, mob/M)
|
||||
if(!(FM.censor_flags & CENSOR_STORY) && M && FM.img)
|
||||
M << browse_rsc(FM.img, "story_photo_[FM.UID()].png")
|
||||
return list(list(
|
||||
uid = FM.UID(),
|
||||
author = (FM.censor_flags & CENSOR_AUTHOR) ? "" : FM.author,
|
||||
title = (FM.censor_flags & CENSOR_STORY) ? "" : FM.title,
|
||||
body = (FM.censor_flags & CENSOR_STORY) ? "" : FM.body,
|
||||
admin_locked = FM.admin_locked,
|
||||
censor_flags = FM.censor_flags,
|
||||
view_count = FM.view_count,
|
||||
publish_time = FM.publish_time,
|
||||
publish_time_proper = station_time_timestamp(time = FM.publish_time),
|
||||
has_photo = !isnull(FM.img),
|
||||
))
|
||||
|
||||
/obj/machinery/newscaster/tgui_act(action, list/params)
|
||||
if(..())
|
||||
return
|
||||
|
||||
. = TRUE
|
||||
if(tgui_act_modal(action, params))
|
||||
return
|
||||
|
||||
switch(action)
|
||||
if("cleartemp")
|
||||
temp_notice = null
|
||||
if("jobs")
|
||||
screen = NEWSCASTER_JOBS
|
||||
if("headlines")
|
||||
if(screen == NEWSCASTER_HEADLINES)
|
||||
return FALSE
|
||||
screen = NEWSCASTER_HEADLINES
|
||||
if("channel")
|
||||
var/datum/feed_channel/FC = locateUID(params["uid"])
|
||||
if(!istype(FC))
|
||||
return
|
||||
if(screen == NEWSCASTER_CHANNEL && viewing_channel == FC)
|
||||
return FALSE
|
||||
screen = NEWSCASTER_CHANNEL
|
||||
viewing_channel = FC
|
||||
if("attach_photo")
|
||||
var/list/open_modal = tgui_modal_data(src)
|
||||
if(photo || !open_modal || !(open_modal["id"] in list("create_story", "wanted_notice")))
|
||||
return
|
||||
if(ishuman(usr))
|
||||
var/obj/item/photo/P = usr.get_active_hand()
|
||||
if(istype(P) && usr.unEquip(P))
|
||||
photo = P
|
||||
P.forceMove(src)
|
||||
usr.visible_message("<span class='notice'>[usr] inserts [P] into [src]'s photo slot.</span>",\
|
||||
"<span class='notice'>You insert [P] into [src]'s photo slot.</span>")
|
||||
playsound(loc, 'sound/machines/terminal_insert_disc.ogg', 30, TRUE)
|
||||
else if(issilicon(usr))
|
||||
var/mob/living/silicon/M = usr
|
||||
var/datum/picture/selection = M.aiCamera?.selectpicture()
|
||||
if(!selection)
|
||||
return
|
||||
var/obj/item/photo/P = new
|
||||
P.construct(selection)
|
||||
P.forceMove(src)
|
||||
photo = P
|
||||
visible_message("<span class='notice'>[src]'s photo slot quietly whirs as it prints [P] inside it.</span>")
|
||||
playsound(loc, 'sound/goonstation/machines/printer_thermal.ogg', 15, TRUE)
|
||||
if("eject_photo")
|
||||
eject_photo(usr)
|
||||
return FALSE // Updating handled in that proc
|
||||
if("censor_channel")
|
||||
if(is_security && !get_scanned_user(usr)["security"])
|
||||
set_temp("You do not have permission to perform this action. Please ensure your ID has appropiate access.", "danger")
|
||||
return
|
||||
var/datum/feed_channel/FC = locateUID(params["uid"])
|
||||
if(!istype(FC))
|
||||
return
|
||||
if(FC.admin_locked && !usr.can_admin_interact())
|
||||
set_temp("This channel has been locked by CentComm and thus cannot be (un)censored.", "danger")
|
||||
return
|
||||
FC.censored = !FC.censored
|
||||
if("censor_author", "censor_story")
|
||||
if(is_security && !get_scanned_user(usr)["security"])
|
||||
set_temp("You do not have permission to perform this action. Please ensure your ID has appropiate access.", "danger")
|
||||
return
|
||||
var/datum/feed_message/FM = locateUID(params["uid"])
|
||||
if(!istype(FM))
|
||||
return
|
||||
if(FM.admin_locked && !usr.can_admin_interact())
|
||||
set_temp("This story has been locked by CentComm and thus cannot be censored in any way.", "danger")
|
||||
return
|
||||
if(action == "censor_author")
|
||||
FM.censor_flags = (FM.censor_flags & CENSOR_AUTHOR) ? (FM.censor_flags & ~CENSOR_AUTHOR) : (FM.censor_flags|CENSOR_AUTHOR)
|
||||
else if(action == "censor_story")
|
||||
FM.censor_flags = (FM.censor_flags & CENSOR_STORY) ? (FM.censor_flags & ~CENSOR_STORY) : (FM.censor_flags|CENSOR_STORY)
|
||||
else
|
||||
return FALSE
|
||||
if("clear_wanted_notice")
|
||||
if(is_security && !get_scanned_user(usr)["security"])
|
||||
set_temp("You do not have permission to perform this action. Please ensure your ID has appropiate access.", "danger")
|
||||
return
|
||||
var/datum/feed_message/WN = GLOB.news_network.wanted_issue
|
||||
if(!WN)
|
||||
return
|
||||
if(WN.admin_locked && !usr.can_admin_interact())
|
||||
set_temp("This wanted notice has been locked by CentComm and thus cannot be altered.", "danger")
|
||||
return
|
||||
GLOB.news_network.wanted_issue = null
|
||||
set_temp("Wanted notice cleared.", update_now = TRUE)
|
||||
return FALSE
|
||||
if("toggle_mute")
|
||||
is_silent = !is_silent
|
||||
if("print_newspaper")
|
||||
if(is_printing)
|
||||
return
|
||||
if(paper_remaining <= 0)
|
||||
set_temp("There is no more paper available.", "danger")
|
||||
return
|
||||
print_newspaper()
|
||||
else
|
||||
return FALSE
|
||||
|
||||
add_fingerprint(usr)
|
||||
|
||||
/**
|
||||
* Called in tgui_act() to process modal actions
|
||||
*
|
||||
* Arguments:
|
||||
* * action - The action passed by tgui
|
||||
* * params - The params passed by tgui
|
||||
*/
|
||||
/obj/machinery/newscaster/proc/tgui_act_modal(action, list/params)
|
||||
. = TRUE
|
||||
var/id = params["id"]
|
||||
var/list/arguments = istext(params["arguments"]) ? json_decode(params["arguments"]) : params["arguments"]
|
||||
switch(tgui_modal_act(src, action, params))
|
||||
if(TGUI_MODAL_OPEN)
|
||||
switch(id)
|
||||
if("create_channel", "manage_channel")
|
||||
// If trying to manage the channel, make sure the user is allowed to!
|
||||
if(id == "manage_channel")
|
||||
var/datum/feed_channel/FC = locateUID(arguments["uid"])
|
||||
if(!istype(FC) || !FC.can_modify(usr, get_scanned_user(usr)["name"]))
|
||||
return
|
||||
tgui_modal_message(src, id, "", arguments = list(
|
||||
uid = arguments["uid"], // Only when managing a channel
|
||||
scanned_user = scanned_user,
|
||||
is_admin = usr.can_admin_interact(),
|
||||
))
|
||||
if("create_story", "wanted_notice") // Other modals
|
||||
if(id == "wanted_notice" && !(is_security || usr.can_admin_interact()))
|
||||
return
|
||||
tgui_modal_message(src, id, "", arguments = list(
|
||||
scanned_user = scanned_user,
|
||||
is_admin = usr.can_admin_interact(),
|
||||
))
|
||||
else
|
||||
return FALSE
|
||||
if(TGUI_MODAL_ANSWER)
|
||||
switch(id)
|
||||
if("create_channel", "manage_channel")
|
||||
var/author = trim(arguments["author"])
|
||||
var/name = trim(arguments["name"])
|
||||
if(!length(author) || !length(name))
|
||||
return
|
||||
var/description = trim(arguments["description"])
|
||||
var/icon = arguments["icon"]
|
||||
var/public = text2num(arguments["public"])
|
||||
var/admin_locked = text2num(arguments["admin_locked"])
|
||||
//
|
||||
var/datum/feed_channel/FC = null
|
||||
if(id == "create_channel") // Channel creation
|
||||
if(GLOB.news_network.get_channel_by_name(name))
|
||||
set_temp("A channel with this name already exists.", "danger")
|
||||
return
|
||||
if(GLOB.news_network.get_channel_by_author(author))
|
||||
set_temp("A channel with this author name already exists.", "danger")
|
||||
return
|
||||
FC = new
|
||||
GLOB.news_network.channels += FC
|
||||
feedback_inc("newscaster_channels", 1)
|
||||
// Redirect
|
||||
screen = NEWSCASTER_CHANNEL
|
||||
viewing_channel = FC
|
||||
else if (id == "manage_channel") // Channel management
|
||||
FC = locateUID(arguments["uid"])
|
||||
if(!FC || !FC.can_modify(usr, get_scanned_user(usr)["name"]))
|
||||
return
|
||||
// Add/update the information
|
||||
FC.channel_name = copytext(name, 1, CHANNEL_NAME_MAX_LENGTH)
|
||||
FC.description = copytext(description, 1, CHANNEL_DESC_MAX_LENGTH)
|
||||
FC.icon = usr.can_admin_interact() ? icon : "newspaper"
|
||||
FC.author = usr.can_admin_interact() ? author : scanned_user
|
||||
FC.is_public = public
|
||||
FC.admin_locked = usr.can_admin_interact() && admin_locked
|
||||
set_temp("Channel [FC.channel_name] created.", "good")
|
||||
if("create_story")
|
||||
var/author = trim(arguments["author"])
|
||||
var/channel = trim(arguments["channel"])
|
||||
var/title = trim(arguments["title"])
|
||||
var/body = trim(arguments["body"])
|
||||
var/admin_locked = text2num(arguments["admin_locked"])
|
||||
if(!length(author) || !length(title) || !length(body))
|
||||
return
|
||||
// Find the named channel the user is trying to publish a story to
|
||||
var/user_name = get_scanned_user(usr)["name"]
|
||||
var/datum/feed_channel/FC = GLOB.news_network.get_channel_by_name(channel)
|
||||
if(!FC || !FC.can_publish(usr, user_name))
|
||||
return
|
||||
var/datum/feed_message/FM = new
|
||||
FM.author = usr.can_admin_interact() ? author : scanned_user
|
||||
FM.title = copytext(title, 1, STORY_NAME_MAX_LENGTH)
|
||||
FM.body = copytext(body, 1, STORY_BODY_MAX_LENGTH)
|
||||
FM.img = photo?.img
|
||||
FM.admin_locked = usr.can_admin_interact() && admin_locked
|
||||
// Register it
|
||||
FC.add_message(FM)
|
||||
feedback_inc("newscaster_stories", 1)
|
||||
var/announcement = FC.get_announce_text(title)
|
||||
// Announce it
|
||||
for(var/nc in GLOB.allNewscasters)
|
||||
var/obj/machinery/newscaster/NC = nc
|
||||
NC.alert_news(announcement)
|
||||
// Redirect and eject photo
|
||||
LAZYINITLIST(last_views[user_name])
|
||||
last_views[user_name][FC.UID()] = world.time
|
||||
screen = NEWSCASTER_CHANNEL
|
||||
viewing_channel = FC
|
||||
eject_photo(usr)
|
||||
set_temp("Story published to channel [FC.channel_name].", "good")
|
||||
if("wanted_notice")
|
||||
if(id == "wanted_notice" && !(is_security || usr.can_admin_interact()))
|
||||
return
|
||||
var/author = trim(arguments["author"])
|
||||
var/name = trim(arguments["name"])
|
||||
var/description = trim(arguments["description"])
|
||||
var/admin_locked = text2num(arguments["admin_locked"])
|
||||
if(!length(author) || !length(name) || !length(description))
|
||||
return
|
||||
var/datum/feed_message/WN = GLOB.news_network.wanted_issue
|
||||
if(WN)
|
||||
if(WN.admin_locked && !usr.can_admin_interact())
|
||||
set_temp("This wanted notice has been locked by CentComm and thus cannot be altered.", "danger")
|
||||
return
|
||||
else
|
||||
WN = new
|
||||
GLOB.news_network.wanted_issue = WN
|
||||
WN.author = usr.can_admin_interact() ? author : scanned_user
|
||||
WN.title = "WANTED: [copytext(name, 1, WANTED_NOTICE_NAME_MAX_LENGTH)]"
|
||||
WN.body = copytext(description, 1, WANTED_NOTICE_DESC_MAX_LENGTH)
|
||||
WN.img = photo?.img
|
||||
WN.admin_locked = usr.can_admin_interact() && admin_locked
|
||||
WN.publish_time = world.time
|
||||
// Announce it and eject photo
|
||||
for(var/nc in GLOB.allNewscasters)
|
||||
var/obj/machinery/newscaster/NC = nc
|
||||
NC.alert_news(wanted_notice = TRUE)
|
||||
eject_photo(usr)
|
||||
set_temp("Wanted notice distributed.", "good")
|
||||
else
|
||||
return FALSE
|
||||
else
|
||||
return FALSE
|
||||
|
||||
/**
|
||||
* Ejects the photo currently held by the machine if there is one.
|
||||
*
|
||||
* Arguments:
|
||||
* * user - The user to try to give the photo to.
|
||||
*/
|
||||
/obj/machinery/newscaster/proc/eject_photo(mob/user)
|
||||
if(!photo)
|
||||
return
|
||||
var/obj/item/photo/P = photo
|
||||
photo = null
|
||||
P.forceMove(loc)
|
||||
if(ishuman(user) && user.put_in_active_hand(P))
|
||||
visible_message("<span class='notice'>[src] ejects [P] from its photo slot into [user]'s hand.")
|
||||
else
|
||||
visible_message("<span class='notice'>[src] ejects [P] from its photo slot.")
|
||||
playsound(loc, 'sound/machines/terminal_insert_disc.ogg', 30, TRUE)
|
||||
SStgui.update_uis(src)
|
||||
|
||||
/**
|
||||
* Sets a temporary message to display to the user
|
||||
*
|
||||
* Arguments:
|
||||
* * text - Text to display, null/empty to clear the message from the UI
|
||||
* * style - The style of the message: (color name), info, success, warning, danger
|
||||
*/
|
||||
/obj/machinery/newscaster/proc/set_temp(text = "", style = "info", update_now = FALSE)
|
||||
temp_notice = list(text = text, style = style)
|
||||
if(update_now)
|
||||
SStgui.update_uis(src)
|
||||
|
||||
/**
|
||||
* Tries to obtain a mob's name and security access based on their ID.
|
||||
*
|
||||
* Arguments:
|
||||
* * user - The user
|
||||
*/
|
||||
/obj/machinery/newscaster/proc/get_scanned_user(mob/user)
|
||||
. = list(name = "Unknown", security = user.can_admin_interact())
|
||||
if(ishuman(user))
|
||||
var/mob/living/carbon/human/M = user
|
||||
// No ID, no luck
|
||||
if(!M.wear_id)
|
||||
return
|
||||
// Try to get the ID
|
||||
var/obj/item/card/id/ID
|
||||
if(istype(M.wear_id, /obj/item/pda))
|
||||
var/obj/item/pda/P = M.wear_id
|
||||
ID = P.id
|
||||
else if(istype(M.wear_id, /obj/item/card/id))
|
||||
ID = M.wear_id
|
||||
if(istype(ID))
|
||||
return list(name = "[ID.registered_name] ([ID.assignment])", security = has_access(list(), list(ACCESS_SECURITY), ID.access))
|
||||
else if(issilicon(user))
|
||||
var/mob/living/silicon/ai_user = user
|
||||
return list(name = "[ai_user.name] ([ai_user.job])", security = TRUE)
|
||||
|
||||
/**
|
||||
* Returns whether the machine's [/obj/machinery/newscaster/var/scanned_user] should update on interact.
|
||||
*
|
||||
* Arguments:
|
||||
* * user - The user to check
|
||||
*/
|
||||
/obj/machinery/newscaster/proc/can_scan(mob/user)
|
||||
if(ishuman(user) || issilicon(user))
|
||||
return TRUE
|
||||
return FALSE
|
||||
|
||||
/**
|
||||
* Tries to print a newspaper with all of the content so far.
|
||||
*/
|
||||
/obj/machinery/newscaster/proc/print_newspaper()
|
||||
if(paper_remaining <= 0 || is_printing)
|
||||
return
|
||||
paper_remaining--
|
||||
feedback_inc("newscaster_newspapers_printed", 1)
|
||||
// Print it
|
||||
is_printing = TRUE
|
||||
playsound(loc, 'sound/goonstation/machines/printer_dotmatrix.ogg', 50, TRUE)
|
||||
visible_message("<span class='notice'>[src] whirs as it prints a newspaper.</span>")
|
||||
addtimer(CALLBACK(src, .proc/print_newspaper_finish), 5 SECONDS)
|
||||
|
||||
/**
|
||||
* Called when the timer following a call to [/obj/machinery/newscaster/proc/print_newspaper] finishes.
|
||||
*/
|
||||
/obj/machinery/newscaster/proc/print_newspaper_finish()
|
||||
is_printing = FALSE
|
||||
SStgui.update_uis(src)
|
||||
// Create the newspaper
|
||||
var/obj/item/newspaper/NP = new
|
||||
NP.forceMove(loc)
|
||||
// Populate the newspaper
|
||||
NP.important_message = GLOB.news_network.wanted_issue
|
||||
for(var/fc in GLOB.news_network.channels)
|
||||
var/datum/feed_channel/FC = fc
|
||||
NP.news_content += FC
|
||||
|
||||
/**
|
||||
* Makes the newscaster say a message and change its icon state for a while.
|
||||
*
|
||||
* Arguments:
|
||||
* * announcement - The message to say
|
||||
* * wanted_notice - Whether the alert is a wanted notice notification (overrides announcement)
|
||||
*/
|
||||
/obj/machinery/newscaster/proc/alert_news(announcement, wanted_notice = FALSE)
|
||||
if(wanted_notice)
|
||||
atom_say("Attention! Wanted issue distributed!")
|
||||
playsound(loc, 'sound/machines/warning-buzzer.ogg', 75, TRUE)
|
||||
else if(length(announcement))
|
||||
atom_say("[announcement]!")
|
||||
if(!is_silent)
|
||||
playsound(loc, 'sound/machines/twobeep.ogg', 75, TRUE)
|
||||
else
|
||||
return
|
||||
alert = TRUE
|
||||
addtimer(CALLBACK(src, .proc/alert_timer_finish), 30 SECONDS)
|
||||
update_icon()
|
||||
|
||||
/**
|
||||
* Called when the timer following a call to [/obj/machinery/newscaster/proc/alert_news] finishes.
|
||||
*/
|
||||
/obj/machinery/newscaster/proc/alert_timer_finish()
|
||||
alert = FALSE
|
||||
update_icon()
|
||||
|
||||
/**
|
||||
* Ejects the currently loaded photo if there is one.
|
||||
*/
|
||||
/obj/machinery/newscaster/verb/eject_photo_verb()
|
||||
set name = "Eject Photo"
|
||||
set category = "Object"
|
||||
set src in oview(1)
|
||||
|
||||
if(usr.incapacitated())
|
||||
return
|
||||
|
||||
eject_photo(usr)
|
||||
|
||||
#undef CHANNEL_NAME_MAX_LENGTH
|
||||
#undef CHANNEL_DESC_MAX_LENGTH
|
||||
#undef STORY_NAME_MAX_LENGTH
|
||||
#undef STORY_BODY_MAX_LENGTH
|
||||
#undef WANTED_NOTICE_NAME_MAX_LENGTH
|
||||
#undef WANTED_NOTICE_DESC_MAX_LENGTH
|
||||
#undef STORIES_PER_LOAD
|
||||
@@ -0,0 +1,166 @@
|
||||
#define SCREEN_COVER 0
|
||||
#define SCREEN_PAGE_INNER 1
|
||||
#define SCREEN_PAGE_LAST 2
|
||||
|
||||
/**
|
||||
* # Newspaper
|
||||
*
|
||||
* A newspaper displaying the stories of all channels contained within.
|
||||
*/
|
||||
/obj/item/newspaper
|
||||
name = "newspaper"
|
||||
desc = "An issue of The Griffon, the newspaper circulating aboard Nanotrasen Space Stations."
|
||||
icon = 'icons/obj/bureaucracy.dmi'
|
||||
icon_state = "newspaper"
|
||||
w_class = WEIGHT_CLASS_SMALL
|
||||
attack_verb = list("bapped")
|
||||
/// The current screen to display.
|
||||
var/screen = 0
|
||||
/// The number of pages.
|
||||
var/pages = 0
|
||||
/// The currently selected page.
|
||||
var/curr_page = 0
|
||||
/// The channels to display as content.
|
||||
var/list/datum/feed_channel/news_content
|
||||
/// The security notice to display optionally.
|
||||
var/datum/feed_message/important_message = null
|
||||
/// The contents of a scribble made through pen, if any.
|
||||
var/scribble = ""
|
||||
/// The page of said scribble.
|
||||
var/scribble_page = null
|
||||
|
||||
/obj/item/newspaper/Initialize(mapload)
|
||||
. = ..()
|
||||
if(!news_content)
|
||||
news_content = list()
|
||||
|
||||
/obj/item/newspaper/attack_self(mob/user)
|
||||
if(ishuman(user))
|
||||
var/mob/living/carbon/human/human_user = user
|
||||
var/dat
|
||||
pages = 0
|
||||
switch(screen)
|
||||
if(SCREEN_COVER) //Cover
|
||||
dat += "<div align='center'><b><font size=6>The Griffon</font></b></div>"
|
||||
dat += "<div align='center'><font size=2>Nanotrasen-standard newspaper, for use on Nanotrasen Space Facilities</font></div><hr>"
|
||||
if(!length(news_content))
|
||||
if(important_message)
|
||||
dat += "Contents:<br><ul><b><font color='red'>**</font>Important Security Announcement<font color='red'>**</font></b> <font size=2>\[page [pages+2]\]</font><br></ul>"
|
||||
else
|
||||
dat += "<i>Other than the title, the rest of the newspaper is unprinted...</i>"
|
||||
else
|
||||
dat += "Contents:<br><ul>"
|
||||
for(var/datum/feed_channel/NP in news_content)
|
||||
pages++
|
||||
if(important_message)
|
||||
dat += "<b><font color='red'>**</font>Important Security Announcement<font color='red'>**</font></b> <font size=2>\[page [pages+2]\]</font><br>"
|
||||
var/temp_page=0
|
||||
for(var/datum/feed_channel/NP in news_content)
|
||||
temp_page++
|
||||
dat += "<b>[NP.channel_name]</b> <font size=2>\[page [temp_page+1]\]</font><br>"
|
||||
dat += "</ul>"
|
||||
if(scribble_page==curr_page)
|
||||
dat += "<br><i>There is a small scribble near the end of this page... It reads: \"[scribble]\"</i>"
|
||||
dat+= "<hr><div style='float:right;'><a href='?src=[UID()];next_page=1'>Next Page</a></div> <div style='float:left;'><a href='?src=[human_user.UID()];mach_close=newspaper_main'>Done reading</a></div>"
|
||||
if(SCREEN_PAGE_INNER) // X channel pages inbetween.
|
||||
for(var/datum/feed_channel/NP in news_content)
|
||||
pages++ //Let's get it right again.
|
||||
var/datum/feed_channel/C = news_content[curr_page]
|
||||
dat += "<font size=4><b>[C.channel_name]</b></font><font size=1> \[created by: <font color='maroon'>[C.author]</font>\]</font><br><br>"
|
||||
if(C.censored)
|
||||
dat += "This channel was deemed dangerous to the general welfare of the station and therefore marked with a <b><font color='red'>D-Notice</b></font>. Its contents were not transferred to the newspaper at the time of printing."
|
||||
else
|
||||
if(!length(C.messages))
|
||||
dat += "No Feed stories stem from this channel..."
|
||||
else
|
||||
dat += "<ul>"
|
||||
var/i = 0
|
||||
for(var/datum/feed_message/MESSAGE in C.messages)
|
||||
var/title = (MESSAGE.censor_flags & CENSOR_STORY) ? "\[REDACTED\]" : MESSAGE.title
|
||||
var/body = (MESSAGE.censor_flags & CENSOR_STORY) ? "\[REDACTED\]" : MESSAGE.body
|
||||
i++
|
||||
dat += "<b>[title]</b> <br>"
|
||||
dat += "[body] <br>"
|
||||
if(MESSAGE.img)
|
||||
user << browse_rsc(MESSAGE.img, "tmp_photo[i].png")
|
||||
dat += "<img src='tmp_photo[i].png' width = '180'><br>"
|
||||
dat += "<font size=1>\[Story by <font color='maroon'>[MESSAGE.author]</font>\]</font><br><br>"
|
||||
dat += "</ul>"
|
||||
if(scribble_page==curr_page)
|
||||
dat += "<br><i>There is a small scribble near the end of this page... It reads: \"[scribble]\"</i>"
|
||||
dat+= "<br><hr><div style='float:left;'><a href='?src=[UID()];prev_page=1'>Previous Page</a></div> <div style='float:right;'><a href='?src=[UID()];next_page=1'>Next Page</a></div>"
|
||||
if(SCREEN_PAGE_LAST) //Last page
|
||||
for(var/datum/feed_channel/NP in news_content)
|
||||
pages++
|
||||
if(important_message!=null)
|
||||
dat += "<div style='float:center;'><font size=4><b>Wanted Issue:</b></font size></div><br><br>"
|
||||
dat += "<b>Criminal name</b>: <font color='maroon'>[important_message.author]</font><br>"
|
||||
dat += "<b>Description</b>: [important_message.body]<br>"
|
||||
dat += "<b>Photo:</b>: "
|
||||
if(important_message.img)
|
||||
user << browse_rsc(important_message.img, "tmp_photow.png")
|
||||
dat += "<br><img src='tmp_photow.png' width = '180'>"
|
||||
else
|
||||
dat += "None"
|
||||
else
|
||||
dat += "<i>Apart from some uninteresting Classified ads, there's nothing on this page...</i>"
|
||||
if(scribble_page==curr_page)
|
||||
dat += "<br><i>There is a small scribble near the end of this page... It reads: \"[scribble]\"</i>"
|
||||
dat+= "<hr><div style='float:left;'><a href='?src=[UID()];prev_page=1'>Previous Page</a></div>"
|
||||
else
|
||||
dat += "i'm sorry to break your immersion. This shit's bugged. Report this bug to Agouri, polyxenitopalidou@gmail.com"
|
||||
|
||||
dat += "<br><hr><div align='center'>[curr_page+1]</div>"
|
||||
human_user << browse(dat, "window=newspaper_main;size=300x400")
|
||||
onclose(human_user, "newspaper_main")
|
||||
else
|
||||
to_chat(user, "<span class='warning'>The paper is full of unintelligible symbols!</span>")
|
||||
|
||||
/obj/item/newspaper/Topic(href, href_list)
|
||||
if(..())
|
||||
return
|
||||
var/mob/living/M = usr
|
||||
if(!Adjacent(M))
|
||||
return
|
||||
M.set_machine(src)
|
||||
if(href_list["next_page"])
|
||||
if(curr_page == pages + 1)
|
||||
return //Don't need that at all, but anyway.
|
||||
else if(curr_page == pages) //We're at the middle, get to the end
|
||||
screen = SCREEN_PAGE_LAST
|
||||
else if(curr_page == 0) //We're at the start, get to the middle
|
||||
screen = SCREEN_PAGE_INNER
|
||||
curr_page++
|
||||
playsound(loc, "pageturn", 50, TRUE)
|
||||
else if(href_list["prev_page"])
|
||||
if(curr_page == 0)
|
||||
return
|
||||
else if(curr_page == 1)
|
||||
screen = SCREEN_COVER
|
||||
else if(curr_page == pages + 1) //we're at the end, let's go back to the middle.
|
||||
screen = SCREEN_PAGE_INNER
|
||||
curr_page--
|
||||
playsound(loc, "pageturn", 50, TRUE)
|
||||
if(loc == M)
|
||||
attack_self(M)
|
||||
|
||||
/obj/item/newspaper/attackby(obj/item/W, mob/user, params)
|
||||
if(istype(W, /obj/item/pen))
|
||||
if(scribble_page == curr_page)
|
||||
to_chat(user, "<span class='notice'>There's already a scribble in this page... You wouldn't want to make things too cluttered, would you?</span>")
|
||||
else
|
||||
var/s = strip_html(input(user, "Write something", "Newspaper", ""))
|
||||
s = sanitize(copytext(s, 1, MAX_MESSAGE_LEN))
|
||||
if(!s || !Adjacent(user))
|
||||
return
|
||||
scribble_page = curr_page
|
||||
scribble = s
|
||||
user.visible_message("<span class='notice'>[user] scribbles something on [src].</span>",\
|
||||
"<span class='notice'>You scribble on page number [curr_page] of [src].</span>")
|
||||
attack_self(user)
|
||||
return
|
||||
return ..()
|
||||
|
||||
#undef SCREEN_COVER
|
||||
#undef SCREEN_PAGE_INNER
|
||||
#undef SCREEN_PAGE_LAST
|
||||
@@ -177,7 +177,7 @@
|
||||
|
||||
// Show it to ghosts
|
||||
for(var/mob/M in GLOB.dead_mob_list)
|
||||
if(isobserver(M) && M.client && (M.client.prefs.toggles & CHAT_GHOSTPDA))
|
||||
if(isobserver(M) && M.client && (M.client.prefs.toggles & PREFTOGGLE_CHAT_GHOSTPDA))
|
||||
var/ghost_message = "<span class='name'>[pda.owner]</span> ([ghost_follow_link(pda, ghost=M)]) <span class='game say'>PDA Message</span> --> <span class='name'>[P.owner]</span> ([ghost_follow_link(P, ghost=M)]): <span class='message'>[t]</span>"
|
||||
to_chat(M, "[ghost_message]")
|
||||
|
||||
|
||||
@@ -144,7 +144,7 @@ field_generator power level display
|
||||
..()
|
||||
|
||||
/obj/machinery/field/generator/bullet_act(obj/item/projectile/Proj)
|
||||
if(Proj.flag != "bullet")
|
||||
if(Proj.flag != "bullet" && !Proj.nodamage)
|
||||
power = min(power + Proj.damage, field_generator_max_power)
|
||||
check_power_level()
|
||||
return 0
|
||||
|
||||
@@ -313,6 +313,8 @@
|
||||
return attack_hand(user)
|
||||
|
||||
/obj/machinery/power/supermatter_shard/attack_hand(mob/user as mob)
|
||||
if(isAI(user))
|
||||
return
|
||||
user.visible_message("<span class=\"warning\">\The [user] reaches out and touches \the [src], inducing a resonance... [user.p_their(TRUE)] body starts to glow and bursts into flames before flashing into ash.</span>",\
|
||||
"<span class=\"danger\">You reach out and touch \the [src]. Everything starts burning and all you can hear is ringing. Your last thought is \"That was not a wise decision.\"</span>",\
|
||||
"<span class=\"warning\">You hear an uneartly ringing, then what sounds like a shrilling kettle as you are washed with a wave of heat.</span>")
|
||||
|
||||
@@ -187,7 +187,8 @@
|
||||
/obj/item/ammo_casing/energy/wormhole
|
||||
projectile_type = /obj/item/projectile/beam/wormhole
|
||||
muzzle_flash_color = "#33CCFF"
|
||||
e_cost = 0
|
||||
delay = 10
|
||||
e_cost = 100
|
||||
fire_sound = 'sound/weapons/pulse3.ogg'
|
||||
var/obj/item/gun/energy/wormhole_projector/gun = null
|
||||
select_name = "blue"
|
||||
|
||||
@@ -200,6 +200,8 @@
|
||||
item_state = null
|
||||
icon_state = "wormhole_projector1"
|
||||
origin_tech = "combat=4;bluespace=6;plasmatech=4;engineering=4"
|
||||
charge_delay = 5
|
||||
selfcharge = TRUE
|
||||
var/obj/effect/portal/blue
|
||||
var/obj/effect/portal/orange
|
||||
|
||||
|
||||
@@ -85,6 +85,7 @@
|
||||
icon_state = "omnilaser"
|
||||
hitsound = 'sound/weapons/tap.ogg'
|
||||
nodamage = 1
|
||||
damage = 0
|
||||
damage_type = STAMINA
|
||||
flag = "laser"
|
||||
var/suit_types = list(/obj/item/clothing/suit/redtag, /obj/item/clothing/suit/bluetag)
|
||||
|
||||
@@ -85,6 +85,7 @@
|
||||
damage = 12.5
|
||||
tile_dropoff = 0.75
|
||||
tile_dropoff_s = 1.25
|
||||
armour_penetration = -30
|
||||
|
||||
/obj/item/projectile/bullet/pellet/rubber
|
||||
name = "rubber pellet"
|
||||
|
||||
@@ -628,7 +628,7 @@
|
||||
reagent_state = LIQUID
|
||||
color = "#B4B400"
|
||||
metabolization_rate = 0.2
|
||||
nutriment_factor = 2
|
||||
nutriment_factor = 2.5 * REAGENTS_METABOLISM
|
||||
taste_description = "broth"
|
||||
|
||||
/datum/reagent/consumable/cheese
|
||||
|
||||
@@ -121,7 +121,14 @@
|
||||
|
||||
/datum/reagent/medicine/cryoxadone/on_mob_life(mob/living/M)
|
||||
var/update_flags = STATUS_UPDATE_NONE
|
||||
if(M.bodytemperature < TCRYO)
|
||||
var/external_temp
|
||||
if(istype(M.loc, /obj/machinery/atmospherics/unary/cryo_cell))
|
||||
var/obj/machinery/atmospherics/unary/cryo_cell/C = M.loc
|
||||
external_temp = C.temperature_archived
|
||||
else
|
||||
var/turf/T = get_turf(M)
|
||||
external_temp = T.temperature
|
||||
if(external_temp < TCRYO)
|
||||
update_flags |= M.adjustCloneLoss(-4, FALSE)
|
||||
update_flags |= M.adjustOxyLoss(-10, FALSE)
|
||||
update_flags |= M.adjustToxLoss(-3, FALSE)
|
||||
|
||||
@@ -50,15 +50,20 @@
|
||||
user.changeNext_move(CLICK_CD_RANGE*2)
|
||||
user.newtonian_move(get_dir(A, user))
|
||||
|
||||
if(reagents.reagent_list.len == 1 && reagents.has_reagent("cleaner")) // Only show space cleaner logs if it's burning people from being too hot or cold
|
||||
if(reagents.chem_temp < 300 && reagents.chem_temp > 280) // 280 is the cold threshold for slimes, 300 the hot threshold for drask
|
||||
var/attack_log_type = ATKLOG_ALMOSTALL
|
||||
|
||||
if(reagents.chem_temp > 300 || reagents.chem_temp < 280) //harmful temperature
|
||||
attack_log_type = ATKLOG_MOST
|
||||
|
||||
if(reagents.reagent_list.len == 1 && reagents.has_reagent("cleaner")) // Only create space cleaner logs if it's burning people from being too hot or cold
|
||||
if(attack_log_type == ATKLOG_ALMOSTALL)
|
||||
return
|
||||
|
||||
var/attack_log_type = ATKLOG_MOST
|
||||
//commonly used for griefing or just very annoying and dangerous
|
||||
if(reagents.has_reagent("sacid") || reagents.has_reagent("facid") || reagents.has_reagent("lube"))
|
||||
attack_log_type = ATKLOG_FEW
|
||||
|
||||
add_attack_logs(user, A, "Used a potentially harmful spray bottle. Contents: [contents_log] - Temperature: [reagents.chem_temp]K", attack_log_type)
|
||||
add_attack_logs(user, A, "Used a spray bottle. Contents: [contents_log] - Temperature: [reagents.chem_temp]K", attack_log_type)
|
||||
return
|
||||
|
||||
|
||||
|
||||
@@ -267,7 +267,7 @@
|
||||
timer = world.time
|
||||
GLOB.priority_announcement.Announce("The Emergency Shuttle has left the station. Estimate [timeLeft(600)] minutes until the shuttle docks at Central Command.")
|
||||
for(var/mob/M in GLOB.player_list)
|
||||
if(!isnewplayer(M) && !M.client.karma_spent && !(M.client.ckey in GLOB.karma_spenders) && !M.get_preference(DISABLE_KARMA_REMINDER))
|
||||
if(!isnewplayer(M) && !M.client.karma_spent && !(M.client.ckey in GLOB.karma_spenders) && !M.get_preference(PREFTOGGLE_DISABLE_KARMA_REMINDER))
|
||||
to_chat(M, "<i>You have not yet spent your karma for the round; was there a player worthy of receiving your reward? Look under Special Verbs tab, Award Karma.</i>")
|
||||
|
||||
if(SHUTTLE_ESCAPE)
|
||||
|
||||
@@ -930,7 +930,7 @@
|
||||
desc = "Used to control the Golem Ship."
|
||||
circuit = /obj/item/circuitboard/shuttle/golem_ship
|
||||
shuttleId = "freegolem"
|
||||
possible_destinations = "freegolem_lavaland;freegolem_z5;freegolem_z6"
|
||||
possible_destinations = "freegolem_lavaland;freegolem_space;freegolem_ussp"
|
||||
|
||||
/obj/machinery/computer/shuttle/golem_ship/attack_hand(mob/user)
|
||||
if(!isgolem(user) && !isobserver(user))
|
||||
|
||||
@@ -20,6 +20,10 @@
|
||||
/datum/tgui_module/power_monitor/tgui_data(mob/user)
|
||||
var/list/data = list()
|
||||
|
||||
// Sanity check
|
||||
if(QDELETED(powermonitor))
|
||||
powermonitor = null
|
||||
|
||||
data["powermonitor"] = powermonitor
|
||||
if(select_monitor)
|
||||
data["select_monitor"] = TRUE
|
||||
|
||||
@@ -106,7 +106,7 @@
|
||||
window_options += "size=[width]x[height];"
|
||||
|
||||
// Remove titlebar and resize handles for a fancy window
|
||||
if(user.client.prefs.nanoui_fancy)
|
||||
if(user.client.prefs.toggles2 & PREFTOGGLE_2_FANCYUI)
|
||||
window_options += "titlebar=0;can_resize=0;"
|
||||
else
|
||||
window_options += "titlebar=1;can_resize=1;"
|
||||
@@ -196,7 +196,7 @@
|
||||
"title" = title,
|
||||
"status" = status,
|
||||
"interface" = interface,
|
||||
"fancy" = user.client.prefs.nanoui_fancy,
|
||||
"fancy" = user.client.prefs.toggles2 & PREFTOGGLE_2_FANCYUI,
|
||||
"observer" = isobserver(user),
|
||||
"window" = window_id,
|
||||
"map" = (GLOB.using_map && GLOB.using_map.name) ? GLOB.using_map.name : "Unknown",
|
||||
@@ -252,8 +252,7 @@
|
||||
src_object.tgui_shared_states[key] = value
|
||||
SStgui.update_uis(src_object)
|
||||
if("tgui:setFancy")
|
||||
var/value = text2num(params["value"])
|
||||
user.client.prefs.nanoui_fancy = value
|
||||
user.client.prefs.toggles2 ^= PREFTOGGLE_2_FANCYUI
|
||||
if("tgui:log")
|
||||
// Force window to show frills on fatal errors
|
||||
if(params["fatal"])
|
||||
|
||||
Reference in New Issue
Block a user