Merge branch 'master' of https://github.com/Citadel-Station-13/Citadel-Station-13 into upstream-merge-33463

This commit is contained in:
LetterJay
2018-01-01 04:36:29 -06:00
1006 changed files with 18001 additions and 28778 deletions
+1 -1
View File
@@ -18,7 +18,7 @@
return list("reason"="invalid login data", "desc"="Error: Could not check ban status, Please try again. Error message: Your computer provided an invalid Computer ID.)")
var/admin = 0
var/ckey = ckey(key)
if((ckey in GLOB.admin_datums) || (ckey in GLOB.deadmins))
if(GLOB.admin_datums[ckey] || GLOB.deadmins[ckey])
admin = 1
//Whitelist
+29 -25
View File
@@ -705,56 +705,60 @@
/datum/admins/proc/output_all_devil_info()
var/devil_number = 0
for(var/D in SSticker.mode.devils)
for(var/datum/mind/D in SSticker.mode.devils)
devil_number++
to_chat(usr, "Devil #[devil_number]:<br><br>" + SSticker.mode.printdevilinfo(D))
var/datum/antagonist/devil/devil = D.has_antag_datum(/datum/antagonist/devil)
to_chat(usr, "Devil #[devil_number]:<br><br>" + devil.printdevilinfo())
if(!devil_number)
to_chat(usr, "<b>No Devils located</b>" )
/datum/admins/proc/output_devil_info(mob/living/M)
if(is_devil(M))
to_chat(usr, SSticker.mode.printdevilinfo(M))
var/datum/antagonist/devil/devil = M.mind.has_antag_datum(/datum/antagonist/devil)
to_chat(usr, devil.printdevilinfo())
else
to_chat(usr, "<b>[M] is not a devil.")
/datum/admins/proc/manage_free_slots()
if(!check_rights())
return
var/dat = "<html><head><title>Manage Free Slots</title></head><body>"
var/datum/browser/browser = new(usr, "jobmanagement", "Manage Free Slots", 520)
var/list/dat = list()
var/count = 0
if(!SSticker.HasRoundStarted())
alert(usr, "You cannot manage jobs before the round starts!")
if(!SSjob.initialized)
alert(usr, "You cannot manage jobs before the job subsystem is initialized!")
return
for(var/datum/job/job in SSjob.occupations)
dat += "<table>"
for(var/j in SSjob.occupations)
var/datum/job/job = j
count++
var/J_title = html_encode(job.title)
var/J_opPos = html_encode(job.total_positions - (job.total_positions - job.current_positions))
var/J_totPos = html_encode(job.total_positions)
if(job.total_positions < 0)
dat += "[J_title]: [J_opPos] (unlimited)"
else
dat += "[J_title]: [J_opPos]/[J_totPos]"
dat += "<tr><td>[J_title]:</td> <td>[J_opPos]/[job.total_positions < 0 ? " (unlimited)" : J_totPos]"
if(job.title == "AI" || job.title == "Cyborg")
dat += " (Cannot Late Join)<br>"
dat += " (Cannot Late Join)</td>"
continue
if(job.total_positions >= 0)
dat += " <A href='?src=[REF(src)];[HrefToken()];addjobslot=[job.title]'>Add</A> | "
if(job.total_positions > job.current_positions)
dat += "<A href='?src=[REF(src)];[HrefToken()];removejobslot=[job.title]'>Remove</A> | "
else
dat += "Remove | "
dat += "<A href='?src=[REF(src)];[HrefToken()];unlimitjobslot=[job.title]'>Unlimit</A>"
else
dat += " <A href='?src=[REF(src)];[HrefToken()];limitjobslot=[job.title]'>Limit</A>"
dat += "<br>"
dat += "</td>"
dat += "<td>"
if(job.total_positions >= 0)
dat += "<A href='?src=[REF(src)];[HrefToken()];addjobslot=[job.title]'>Add</A> | "
if(job.total_positions > job.current_positions)
dat += "<A href='?src=[REF(src)];[HrefToken()];removejobslot=[job.title]'>Remove</A> | "
else
dat += "Remove | "
dat += "<A href='?src=[REF(src)];[HrefToken()];unlimitjobslot=[job.title]'>Unlimit</A></td>"
else
dat += "<A href='?src=[REF(src)];[HrefToken()];limitjobslot=[job.title]'>Limit</A></td>"
dat += "</body>"
var/winheight = 100 + (count * 20)
winheight = min(winheight, 690)
usr << browse(dat, "window=players;size=375x[winheight]")
browser.height = min(100 + count * 20, 650)
browser.set_content(dat.Join())
browser.open()
/datum/admins/proc/create_or_modify_area()
set category = "Debug"
+2
View File
@@ -11,6 +11,8 @@
return
switch(subject)
if("notes, memos, watchlist")
if(!check_rights(R_ADMIN))
return
browse_messages()
else
var/F = file("[GLOB.log_directory]/[subject].html")
+41 -33
View File
@@ -3,7 +3,7 @@ GLOBAL_PROTECT(admin_ranks)
/datum/admin_rank
var/name = "NoRank"
var/rights = 0
var/rights = R_DEFAULT
var/list/adds
var/list/subs
@@ -56,11 +56,13 @@ GLOBAL_PROTECT(admin_ranks)
if("varedit")
flag = R_VAREDIT
if("everything","host","all")
flag = 65535
flag = ALL
if("sound","sounds")
flag = R_SOUNDS
if("spawn","create")
flag = R_SPAWN
if("autologin", "autoadmin")
flag = R_AUTOLOGIN
if("@","prev")
flag = previous_rights
if("rejuv","rejuvinate")
@@ -171,21 +173,19 @@ GLOBAL_PROTECT(admin_ranks)
#endif
/proc/load_admins(target = null)
if(IsAdminAdvancedProcCall())
to_chat(usr, "<span class='admin prefix'>Admin Reload blocked: Advanced ProcCall detected.</span>")
return
/proc/load_admins()
//clear the datums references
if(!target)
GLOB.admin_datums.Cut()
for(var/client/C in GLOB.admins)
C.remove_admin_verbs()
C.holder = null
GLOB.admins.Cut()
load_admin_ranks()
//Clear profile access
for(var/A in world.GetConfig("admin"))
world.SetConfig("APP/admin", A, null)
GLOB.admin_datums.Cut()
for(var/client/C in GLOB.admins)
C.remove_admin_verbs()
C.holder = null
GLOB.admins.Cut()
GLOB.deadmins.Cut()
load_admin_ranks()
//Clear profile access
for(var/A in world.GetConfig("admin"))
world.SetConfig("APP/admin", A, null)
var/list/rank_names = list()
for(var/datum/admin_rank/R in GLOB.admin_ranks)
@@ -208,13 +208,11 @@ GLOBAL_PROTECT(admin_ranks)
var/ckey = ckey(entry[1])
var/rank = ckeyEx(entry[2])
if(!ckey || !rank || (target && ckey != target))
if(!ckey || !rank)
continue
var/datum/admins/D = new(rank_names[rank], ckey) //create the admin datum and store it for later use
if(!D)
continue //will occur if an invalid rank is provided
D.associate(GLOB.directory[ckey]) //find the client for a ckey if they are connected and associate them with the new admin datum
new /datum/admins(rank_names[rank], ckey)
else
if(!SSdbcore.Connect())
log_world("Failed to connect to database in load_admins(). Reverting to legacy system.")
@@ -229,19 +227,12 @@ GLOBAL_PROTECT(admin_ranks)
while(query_load_admins.NextRow())
var/ckey = ckey(query_load_admins.item[1])
var/rank = ckeyEx(query_load_admins.item[2])
if(target && ckey != target)
continue
if(rank_names[rank] == null)
WARNING("Admin rank ([rank]) does not exist.")
continue
var/datum/admins/D = new(rank_names[rank], ckey) //create the admin datum and store it for later use
if(!D)
continue //will occur if an invalid rank is provided
if(D.rank.rights & R_DEBUG) //grant profile access
world.SetConfig("APP/admin", ckey, "role=admin")
D.associate(GLOB.directory[ckey]) //find the client for a ckey if they are connected and associate them with the new admin datum
new /datum/admins(rank_names[rank], ckey)
#ifdef TESTING
var/msg = "Admins Built:\n"
@@ -298,6 +289,8 @@ GLOBAL_PROTECT(admin_ranks)
return
var/datum/admins/D = GLOB.admin_datums[adm_ckey]
if (!D)
D = GLOB.deadmins[adm_ckey]
switch(task)
if("remove")
@@ -309,6 +302,7 @@ GLOBAL_PROTECT(admin_ranks)
log_admin("[key_name(usr)] attempted to remove [adm_ckey] from the admins list without sufficient rights.")
return
GLOB.admin_datums -= adm_ckey
GLOB.deadmins -= adm_ckey
D.disassociate()
updateranktodb(adm_ckey, "player")
@@ -350,11 +344,9 @@ GLOBAL_PROTECT(admin_ranks)
if(D) //they were previously an admin
D.disassociate() //existing admin needs to be disassociated
D.rank = R //set the admin_rank as our rank
D.associate()
else
D = new(R,adm_ckey) //new admin
var/client/C = GLOB.directory[adm_ckey] //find the client with the specified ckey (if they are logged in)
D.associate(C) //link up with the client and add verbs
D = new(R, adm_ckey, TRUE) //new admin
updateranktodb(adm_ckey, new_rank)
message_admins("[key_name_admin(usr)] edited the admin rank of [adm_ckey] to [new_rank]")
@@ -387,6 +379,22 @@ GLOBAL_PROTECT(admin_ranks)
message_admins("[key_name(usr)] added keyword [keyword] to permission of [adm_ckey]")
log_admin("[key_name(usr)] added keyword [keyword] to permission of [adm_ckey]")
log_admin_permission_modification(adm_ckey, D.rank.rights)
if("activate") //forcefully readmin
if(!D || !D.deadmined)
return
D.activate()
message_admins("[key_name_admin(usr)] forcefully readmined [adm_ckey]")
log_admin("[key_name(usr)] forcefully readmined [adm_ckey]")
if("deactivate") //forcefully deadmin
if(!D || D.deadmined)
return
message_admins("[key_name_admin(usr)] forcefully deadmined [adm_ckey]")
log_admin("[key_name(usr)] forcefully deadmined [adm_ckey]")
D.deactivate() //after logs so the deadmined admin can see the message.
edit_admin_permissions()
+13 -11
View File
@@ -638,12 +638,7 @@ GLOBAL_LIST_INIT(admin_verbs_hideable, list(
if(has_antag_hud())
toggle_antag_hud()
holder.disassociate()
qdel(holder)
GLOB.deadmins += ckey
GLOB.admin_datums -= ckey
verbs += /client/proc/readmin
holder.deactivate()
to_chat(src, "<span class='interface'>You are now a normal player.</span>")
log_admin("[src] deadmined themself.")
@@ -655,13 +650,20 @@ GLOBAL_LIST_INIT(admin_verbs_hideable, list(
set category = "Admin"
set desc = "Regain your admin powers."
load_admins(ckey)
var/datum/admins/A = GLOB.deadmins[ckey]
if(!holder) // Something went wrong...
return
if(!A)
A = GLOB.admin_datums[ckey]
if (!A)
var/msg = " is trying to readmin but they have no deadmin entry"
message_admins("[key_name_admin(src)][msg]")
log_admin_private("[key_name(src)][msg]")
return
GLOB.deadmins -= ckey
verbs -= /client/proc/readmin
A.associate(src)
if (!holder)
return //This can happen if an admin attempts to vv themself into somebody elses's deadmin datum by getting ref via brute force
to_chat(src, "<span class='interface'>You are now an admin.</span>")
message_admins("[src] re-adminned themselves.")
+20 -1
View File
@@ -47,7 +47,9 @@
target = AH.initiator_ckey
else
return "Ticket #[id] not found!"
return IrcPm(target, all_params.Join(" "), sender)
var/res = IrcPm(target, all_params.Join(" "), sender)
if(res != "Message Successful")
return res
/datum/server_tools_command/namecheck
name = "namecheck"
@@ -82,6 +84,23 @@ GLOBAL_LIST(round_end_notifiees)
GLOB.round_end_notifiees[sender] = TRUE
return "I will notify [sender] when the round ends."
/datum/server_tools_command/sdql
name = "sdql"
help_text = "Runs an SDQL query"
admin_only = TRUE
/datum/server_tools_command/sdql/Run(sender, params)
if(GLOB.AdminProcCaller)
return "Unable to run query, another admin proc call is in progress. Try again later."
GLOB.AdminProcCaller = "CHAT_[sender]" //_ won't show up in ckeys so it'll never match with a real admin
var/list/results = world.SDQL2_query(params, GLOB.AdminProcCaller, GLOB.AdminProcCaller)
GLOB.AdminProcCaller = null
if(!results)
return "Query produced no output"
var/list/text_res = results.Copy(1, 3)
var/list/refs = results.len > 3 ? results.Copy(4) : null
. = "[text_res.Join("\n")][refs ? "\nRefs: [refs.Join(" ")]" : ""]"
/datum/server_tools_command/reload_admins
name = "reload_admins"
help_text = "Forces the server to reload admins."
+16 -10
View File
@@ -95,7 +95,7 @@
var/obj/docking_port/stationary/SM = S
if(SM.id == "emergency_home")
var/new_dir = turn(SM.dir, 180)
SM.loc = get_ranged_target_turf(SM, new_dir, rand(3,15))
SM.forceMove(get_ranged_target_turf(SM, new_dir, rand(3,15)))
break
qdel(src)
@@ -110,26 +110,32 @@
anchored = TRUE
/obj/effect/shuttle_build/New()
SSshuttle.emergency.dock(SSshuttle.getDock("emergency_home"))
SSshuttle.emergency.initiate_docking(SSshuttle.getDock("emergency_home"))
qdel(src)
//Arena
/obj/effect/forcefield/arena_shuttle
name = "portal"
var/list/warp_points = list()
var/list/warp_points
/obj/effect/forcefield/arena_shuttle/Initialize()
. = ..()
warp_points = get_area_turfs(/area/shuttle/escape)
for(var/thing in warp_points)
CHECK_TICK
var/turf/T = thing
if(istype(T.loc, /area/shuttle/escape/backup))
warp_points -= T
continue
for(var/atom/movable/TAM in T)
if(TAM.density && TAM.anchored)
warp_points -= T
break
/obj/effect/forcefield/arena_shuttle/CollidedWith(atom/movable/AM)
if(!isliving(AM))
return
if(!warp_points.len)
warp_points = get_area_turfs(/area/shuttle/escape)
for(var/turf/T in warp_points)
for(var/atom/movable/TAM in T)
if(TAM.density && TAM.anchored)
warp_points -= T
break
var/mob/living/L = AM
if(L.pulling && istype(L.pulling, /obj/item/bodypart/head))
+66 -25
View File
@@ -7,6 +7,8 @@ GLOBAL_PROTECT(href_token)
/datum/admins
var/datum/admin_rank/rank
var/target
var/name = "nobody's admin datum (no rank)" //Makes for better runtimes
var/client/owner = null
var/fakekey = null
@@ -19,9 +21,12 @@ GLOBAL_PROTECT(href_token)
var/datum/newscaster/wanted_message/admincaster_wanted_message = new /datum/newscaster/wanted_message
var/datum/newscaster/feed_channel/admincaster_feed_channel = new /datum/newscaster/feed_channel
var/admin_signature
var/href_token
/datum/admins/New(datum/admin_rank/R, ckey)
var/deadmined
/datum/admins/New(datum/admin_rank/R, ckey, force_active = FALSE)
if(!ckey)
QDEL_IN(src, 0)
throw EXCEPTION("Admin datum created without a ckey")
@@ -30,34 +35,36 @@ GLOBAL_PROTECT(href_token)
QDEL_IN(src, 0)
throw EXCEPTION("Admin datum created without a rank")
return
target = ckey
name = "[ckey]'s admin datum ([R])"
rank = R
admin_signature = "Nanotrasen Officer #[rand(0,9)][rand(0,9)][rand(0,9)]"
href_token = GenerateToken()
GLOB.admin_datums[ckey] = src
if(R.rights & R_DEBUG) //grant profile access
world.SetConfig("APP/admin", ckey, "role=admin")
//only admins with +ADMIN start admined
if (force_active || (R.rights & R_AUTOLOGIN))
activate()
else
deactivate()
/proc/GenerateToken()
. = ""
for(var/I in 1 to 32)
. += "[rand(10)]"
/proc/RawHrefToken(forceGlobal = FALSE)
var/tok = GLOB.href_token
if(!forceGlobal && usr)
var/client/C = usr.client
if(!C)
CRASH("No client for HrefToken()!")
var/datum/admins/holder = C.holder
if(holder)
tok = holder.href_token
return tok
/datum/admins/proc/activate()
GLOB.deadmins -= target
GLOB.admin_datums[target] = src
deadmined = FALSE
if (GLOB.directory[target])
associate(GLOB.directory[target]) //find the client for a ckey if they are connected and associate them with us
/proc/HrefToken(forceGlobal = FALSE)
return "admin_token=[RawHrefToken(forceGlobal)]"
/proc/HrefTokenFormField(forceGlobal = FALSE)
return "<input type='hidden' name='admin_token' value='[RawHrefToken(forceGlobal)]'>"
/datum/admins/proc/deactivate()
GLOB.deadmins[target] = src
GLOB.admin_datums -= target
deadmined = TRUE
var/client/C
if ((C = owner) || (C = GLOB.directory[target]))
disassociate()
C.verbs += /client/proc/readmin
/datum/admins/proc/associate(client/C)
if(IsAdminAdvancedProcCall())
@@ -65,10 +72,18 @@ GLOBAL_PROTECT(href_token)
message_admins("[key_name_admin(usr)][msg]")
log_admin_private("[key_name(usr)][msg]")
return
if(istype(C))
if(C.ckey != target)
var/msg = " has attempted to associate with [target]'s admin datum"
message_admins("[key_name_admin(C)][msg]")
log_admin_private("[key_name(C)][msg]")
return
if (deadmined)
activate()
owner = C
owner.holder = src
owner.add_admin_verbs() //TODO
owner.add_admin_verbs() //TODO <--- todo what? the proc clearly exists and works since its the backbone to our entire admin system
owner.verbs -= /client/proc/readmin
GLOB.admins |= C
@@ -79,6 +94,12 @@ GLOBAL_PROTECT(href_token)
owner.holder = null
owner = null
/datum/admins/proc/check_for_rights(rights_required)
if(rights_required && !(rights_required & rank.rights))
return 0
return 1
/datum/admins/proc/check_if_greater_rights_than_holder(datum/admins/other)
if(!other)
return 1 //they have no rights
@@ -128,8 +149,28 @@ you will have to do something like if(client.rights & R_ADMIN) yourself.
//This proc checks whether subject has at least ONE of the rights specified in rights_required.
/proc/check_rights_for(client/subject, rights_required)
if(subject && subject.holder && subject.holder.rank)
if(rights_required && !(rights_required & subject.holder.rank.rights))
return 0
return 1
if(subject && subject.holder)
return subject.holder.check_for_rights(rights_required)
return 0
/proc/GenerateToken()
. = ""
for(var/I in 1 to 32)
. += "[rand(10)]"
/proc/RawHrefToken(forceGlobal = FALSE)
var/tok = GLOB.href_token
if(!forceGlobal && usr)
var/client/C = usr.client
if(!C)
CRASH("No client for HrefToken()!")
var/datum/admins/holder = C.holder
if(holder)
tok = holder.href_token
return tok
/proc/HrefToken(forceGlobal = FALSE)
return "admin_token=[RawHrefToken(forceGlobal)]"
/proc/HrefTokenFormField(forceGlobal = FALSE)
return "<input type='hidden' name='admin_token' value='[RawHrefToken(forceGlobal)]'>"
@@ -10,7 +10,7 @@
if(!check_rights(R_PERMISSIONS))
return
var/output = {"<!DOCTYPE html>
var/list/output = list({"<!DOCTYPE html>
<html>
<head>
<title>Permissions Panel</title>
@@ -25,18 +25,26 @@
<th style='width:375px;'>PERMISSIONS</th>
<th style='width:100%;'>VERB-OVERRIDES</th>
</tr>
"}
"})
for(var/adm_ckey in GLOB.admin_datums)
for(var/adm_ckey in GLOB.admin_datums+GLOB.deadmins)
var/datum/admins/D = GLOB.admin_datums[adm_ckey]
if(!D)
continue
D = GLOB.deadmins[adm_ckey]
if (!D)
continue
var/rights = rights2text(D.rank.rights," ")
if(!rights) rights = "*none*"
if(!rights)
rights = "*none*"
var/deadminlink = ""
if (D.deadmined)
deadminlink = " <a class='small' href='?src=[REF(src)];[HrefToken()];editrights=activate;ckey=[adm_ckey]'>\[RA\]</a>"
else
deadminlink = " <a class='small' href='?src=[REF(src)];[HrefToken()];editrights=deactivate;ckey=[adm_ckey]'>\[DA\]</a>"
output += "<tr>"
output += "<td style='text-align:right;'>[adm_ckey] <a class='small' href='?src=[REF(src)];[HrefToken()];editrights=remove;ckey=[adm_ckey]'>\[-\]</a></td>"
output += "<td style='text-align:right;'>[adm_ckey] [deadminlink]<a class='small' href='?src=[REF(src)];[HrefToken()];editrights=remove;ckey=[adm_ckey]'>\[-\]</a></td>"
output += "<td><a href='?src=[REF(src)];[HrefToken()];editrights=rank;ckey=[adm_ckey]'>[D.rank.name]</a></td>"
output += "<td><a class='small' href='?src=[REF(src)];[HrefToken()];editrights=permissions;ckey=[adm_ckey]'>[rights]</a></td>"
output += "<td><a class='small' href='?src=[REF(src)];[HrefToken()];editrights=permissions;ckey=[adm_ckey]'>[rights2text(0," ",D.rank.adds,D.rank.subs)]</a></td>"
@@ -48,7 +56,7 @@
</body>
</html>"}
usr << browse(output,"window=editrights;size=900x650")
usr << browse(jointext(output, ""),"window=editrights;size=900x650")
/datum/admins/proc/log_admin_rank_modification(adm_ckey, new_rank)
if(CONFIG_GET(flag/admin_legacy_system))
+4 -3
View File
@@ -384,9 +384,10 @@
dat += "<BR><span class='userdanger'>[other_players] players in invalid state or the statistics code is bugged!</span>"
dat += "<BR>"
if(SSticker.mode.syndicates.len)
var/list/nukeops = get_antagonists(/datum/antagonist/nukeop)
if(nukeops.len)
dat += "<br><table cellspacing=5><tr><td><B>Syndicates</B></td><td></td></tr>"
for(var/datum/mind/N in SSticker.mode.syndicates)
for(var/datum/mind/N in nukeops)
var/mob/M = N.current
if(M)
dat += "<tr><td><a href='?_src_=holder;[HrefToken()];adminplayeropts=[REF(M)]'>[M.real_name]</a>[M.client ? "" : " <i>(No Client)</i>"][M.stat == DEAD ? " <b><font color=red>(DEAD)</font></b>" : ""]</td>"
@@ -523,7 +524,7 @@
if(SSticker.mode.brother_teams.len > 0)
dat += "<br><table cellspacing=5><tr><td><B>Brothers</B></td><td></td><td></td></tr>"
for(var/datum/objective_team/brother_team/team in SSticker.mode.brother_teams)
for(var/datum/team/brother_team/team in SSticker.mode.brother_teams)
for(var/datum/mind/brother in team.members)
var/mob/M = brother.current
if(M)
+2 -2
View File
@@ -92,7 +92,7 @@
var/new_volume = input(user, "Choose a volume.", "Sound Emitter", sound_volume) as null|num
if(isnull(new_volume))
return
new_volume = Clamp(new_volume, 0, 100)
new_volume = CLAMP(new_volume, 0, 100)
sound_volume = new_volume
to_chat(user, "<span class='notice'>Volume set to [sound_volume]%.</span>")
if(href_list["edit_mode"])
@@ -115,7 +115,7 @@
var/new_radius = input(user, "Choose a radius.", "Sound Emitter", sound_volume) as null|num
if(isnull(new_radius))
return
new_radius = Clamp(new_radius, 0, 127)
new_radius = CLAMP(new_radius, 0, 127)
play_radius = new_radius
to_chat(user, "<span class='notice'>Audible radius set to [play_radius].</span>")
if(href_list["play"])
+1 -1
View File
@@ -220,7 +220,7 @@
var/nsd = CONFIG_GET(number/note_stale_days)
var/nfd = CONFIG_GET(number/note_fresh_days)
if (agegate && type == "note" && isnum(nsd) && isnum(nfd) && nsd > nfd)
var/alpha = Clamp(100 - (age - nfd) * (85 / (nsd - nfd)), 15, 100)
var/alpha = CLAMP(100 - (age - nfd) * (85 / (nsd - nfd)), 15, 100)
if (alpha < 100)
if (alpha <= 15)
if (skipped)
+115 -4
View File
@@ -58,6 +58,8 @@
toggle_exempt_status(C)
else if(href_list["makeAntag"])
if(!check_rights(R_ADMIN))
return
if (!SSticker.mode)
to_chat(usr, "<span class='danger'>Not until the round starts!</span>")
return
@@ -201,7 +203,8 @@
return
else if(href_list["dbbanaddtype"])
if(!check_rights(R_BAN))
return
var/bantype = text2num(href_list["dbbanaddtype"])
var/banckey = href_list["dbbanaddckey"]
var/banip = href_list["dbbanaddip"]
@@ -599,6 +602,8 @@
return
else if(href_list["jobban2"])
if(!check_rights(R_BAN))
return
var/mob/M = locate(href_list["jobban2"])
if(!ismob(M))
to_chat(usr, "This can only be used on instances of type /mob.")
@@ -1029,6 +1034,8 @@
return 0 //we didn't do anything!
else if(href_list["boot2"])
if(!check_rights(R_ADMIN))
return
var/mob/M = locate(href_list["boot2"])
if (ismob(M))
if(!check_if_greater_rights_than(M.client))
@@ -1041,72 +1048,110 @@
qdel(M.client)
else if(href_list["addmessage"])
if(!check_rights(R_ADMIN))
return
var/target_ckey = href_list["addmessage"]
create_message("message", target_ckey, secret = 0)
else if(href_list["addnote"])
if(!check_rights(R_ADMIN))
return
var/target_ckey = href_list["addnote"]
create_message("note", target_ckey)
else if(href_list["addwatch"])
if(!check_rights(R_ADMIN))
return
var/target_ckey = href_list["addwatch"]
create_message("watchlist entry", target_ckey, secret = 1)
else if(href_list["addmemo"])
if(!check_rights(R_ADMIN))
return
create_message("memo", secret = 0, browse = 1)
else if(href_list["addmessageempty"])
if(!check_rights(R_ADMIN))
return
create_message("message", secret = 0)
else if(href_list["addnoteempty"])
if(!check_rights(R_ADMIN))
return
create_message("note")
else if(href_list["addwatchempty"])
if(!check_rights(R_ADMIN))
return
create_message("watchlist entry", secret = 1)
else if(href_list["deletemessage"])
if(!check_rights(R_ADMIN))
return
var/message_id = href_list["deletemessage"]
delete_message(message_id)
else if(href_list["deletemessageempty"])
if(!check_rights(R_ADMIN))
return
var/message_id = href_list["deletemessageempty"]
delete_message(message_id, browse = 1)
else if(href_list["editmessage"])
if(!check_rights(R_ADMIN))
return
var/message_id = href_list["editmessage"]
edit_message(message_id)
else if(href_list["editmessageempty"])
if(!check_rights(R_ADMIN))
return
var/message_id = href_list["editmessageempty"]
edit_message(message_id, browse = 1)
else if(href_list["secretmessage"])
if(!check_rights(R_ADMIN))
return
var/message_id = href_list["secretmessage"]
toggle_message_secrecy(message_id)
else if(href_list["searchmessages"])
if(!check_rights(R_ADMIN))
return
var/target = href_list["searchmessages"]
browse_messages(index = target)
else if(href_list["nonalpha"])
if(!check_rights(R_ADMIN))
return
var/target = href_list["nonalpha"]
target = text2num(target)
browse_messages(index = target)
else if(href_list["showmessages"])
if(!check_rights(R_ADMIN))
return
var/target = href_list["showmessages"]
browse_messages(index = target)
else if(href_list["showmemo"])
if(!check_rights(R_ADMIN))
return
browse_messages("memo")
else if(href_list["showwatch"])
if(!check_rights(R_ADMIN))
return
browse_messages("watchlist entry")
else if(href_list["showwatchfilter"])
if(!check_rights(R_ADMIN))
return
browse_messages("watchlist entry", filter = 1)
else if(href_list["showmessageckey"])
if(!check_rights(R_ADMIN))
return
var/target = href_list["showmessageckey"]
var/agegate = TRUE
if (href_list["showall"])
@@ -1118,6 +1163,8 @@
browse_messages(target_ckey = target, linkless = 1)
else if(href_list["messageedits"])
if(!check_rights(R_ADMIN))
return
var/message_id = sanitizeSQL("[href_list["messageedits"]]")
var/datum/DBQuery/query_get_message_edits = SSdbcore.NewQuery("SELECT edits FROM [format_table_name("messages")] WHERE id = '[message_id]'")
if(!query_get_message_edits.warn_execute())
@@ -1307,7 +1354,7 @@
if(alert(usr, "Send [key_name(M)] to Prison?", "Message", "Yes", "No") != "Yes")
return
M.loc = pick(GLOB.prisonwarp)
M.forceMove(pick(GLOB.prisonwarp))
to_chat(M, "<span class='adminnotice'>You have been sent to Prison!</span>")
log_admin("[key_name(usr)] has sent [key_name(M)] to Prison!")
@@ -1543,7 +1590,7 @@
C.admin_ghost()
var/mob/dead/observer/A = C.mob
A.ManualFollow(AM)
else if(href_list["admingetmovable"])
if(!check_rights(R_ADMIN))
return
@@ -1568,9 +1615,13 @@
C.jumptocoord(x,y,z)
else if(href_list["adminchecklaws"])
if(!check_rights(R_ADMIN))
return
output_ai_laws()
else if(href_list["admincheckdevilinfo"])
if(!check_rights(R_ADMIN))
return
var/mob/M = locate(href_list["admincheckdevilinfo"])
output_devil_info(M)
@@ -1892,7 +1943,7 @@
return
var/list/offset = splittext(href_list["offset"],",")
var/number = Clamp(text2num(href_list["object_count"]), 1, 100)
var/number = CLAMP(text2num(href_list["object_count"]), 1, 100)
var/X = offset.len > 0 ? text2num(offset[1]) : 0
var/Y = offset.len > 1 ? text2num(offset[2]) : 0
var/Z = offset.len > 2 ? text2num(offset[3]) : 0
@@ -1979,20 +2030,28 @@
Secrets_topic(href_list["secrets"],href_list)
else if(href_list["ac_view_wanted"]) //Admin newscaster Topic() stuff be here
if(!check_rights(R_ADMIN))
return
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"])
if(!check_rights(R_ADMIN))
return
src.admincaster_feed_channel.channel_name = stripped_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,lentext(src.admincaster_feed_channel.channel_name)+1)
src.access_news_network()
else if(href_list["ac_set_channel_lock"])
if(!check_rights(R_ADMIN))
return
src.admincaster_feed_channel.locked = !src.admincaster_feed_channel.locked
src.access_news_network()
else if(href_list["ac_submit_new_channel"])
if(!check_rights(R_ADMIN))
return
var/check = 0
for(var/datum/newscaster/feed_channel/FC in GLOB.news_network.network_channels)
if(FC.channel_name == src.admincaster_feed_channel.channel_name)
@@ -2010,6 +2069,8 @@
src.access_news_network()
else if(href_list["ac_set_channel_receiving"])
if(!check_rights(R_ADMIN))
return
var/list/available_channels = list()
for(var/datum/newscaster/feed_channel/F in GLOB.news_network.network_channels)
available_channels += F.channel_name
@@ -2017,12 +2078,16 @@
src.access_news_network()
else if(href_list["ac_set_new_message"])
if(!check_rights(R_ADMIN))
return
src.admincaster_feed_message.body = adminscrub(input(usr, "Write your Feed story.", "Network Channel Handler", ""))
while (findtext(src.admincaster_feed_message.returnBody(-1)," ") == 1)
src.admincaster_feed_message.body = copytext(src.admincaster_feed_message.returnBody(-1),2,lentext(src.admincaster_feed_message.returnBody(-1))+1)
src.access_news_network()
else if(href_list["ac_submit_new_message"])
if(!check_rights(R_ADMIN))
return
if(src.admincaster_feed_message.returnBody(-1) =="" || src.admincaster_feed_message.returnBody(-1) =="\[REDACTED\]" || src.admincaster_feed_channel.channel_name == "" )
src.admincaster_screen = 6
else
@@ -2037,22 +2102,32 @@
src.access_news_network()
else if(href_list["ac_create_channel"])
if(!check_rights(R_ADMIN))
return
src.admincaster_screen=2
src.access_news_network()
else if(href_list["ac_create_feed_story"])
if(!check_rights(R_ADMIN))
return
src.admincaster_screen=3
src.access_news_network()
else if(href_list["ac_menu_censor_story"])
if(!check_rights(R_ADMIN))
return
src.admincaster_screen=10
src.access_news_network()
else if(href_list["ac_menu_censor_channel"])
if(!check_rights(R_ADMIN))
return
src.admincaster_screen=11
src.access_news_network()
else if(href_list["ac_menu_wanted"])
if(!check_rights(R_ADMIN))
return
var/already_wanted = 0
if(GLOB.news_network.wanted_issue.active)
already_wanted = 1
@@ -2064,18 +2139,24 @@
src.access_news_network()
else if(href_list["ac_set_wanted_name"])
if(!check_rights(R_ADMIN))
return
src.admincaster_wanted_message.criminal = adminscrub(input(usr, "Provide the name of the Wanted person.", "Network Security Handler", ""))
while(findtext(src.admincaster_wanted_message.criminal," ") == 1)
src.admincaster_wanted_message.criminal = copytext(admincaster_wanted_message.criminal,2,lentext(admincaster_wanted_message.criminal)+1)
src.access_news_network()
else if(href_list["ac_set_wanted_desc"])
if(!check_rights(R_ADMIN))
return
src.admincaster_wanted_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_wanted_message.body," ") == 1)
src.admincaster_wanted_message.body = copytext(src.admincaster_wanted_message.body,2,lentext(src.admincaster_wanted_message.body)+1)
src.access_news_network()
else if(href_list["ac_submit_wanted"])
if(!check_rights(R_ADMIN))
return
var/input_param = text2num(href_list["ac_submit_wanted"])
if(src.admincaster_wanted_message.criminal == "" || src.admincaster_wanted_message.body == "")
src.admincaster_screen = 16
@@ -2092,6 +2173,8 @@
src.access_news_network()
else if(href_list["ac_cancel_wanted"])
if(!check_rights(R_ADMIN))
return
var/choice = alert("Please confirm Wanted Issue removal.","Network Security Handler","Confirm","Cancel")
if(choice=="Confirm")
GLOB.news_network.deleteWanted()
@@ -2099,36 +2182,50 @@
src.access_news_network()
else if(href_list["ac_censor_channel_author"])
if(!check_rights(R_ADMIN))
return
var/datum/newscaster/feed_channel/FC = locate(href_list["ac_censor_channel_author"])
FC.toggleCensorAuthor()
src.access_news_network()
else if(href_list["ac_censor_channel_story_author"])
if(!check_rights(R_ADMIN))
return
var/datum/newscaster/feed_message/MSG = locate(href_list["ac_censor_channel_story_author"])
MSG.toggleCensorAuthor()
src.access_news_network()
else if(href_list["ac_censor_channel_story_body"])
if(!check_rights(R_ADMIN))
return
var/datum/newscaster/feed_message/MSG = locate(href_list["ac_censor_channel_story_body"])
MSG.toggleCensorBody()
src.access_news_network()
else if(href_list["ac_pick_d_notice"])
if(!check_rights(R_ADMIN))
return
var/datum/newscaster/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"])
if(!check_rights(R_ADMIN))
return
var/datum/newscaster/feed_channel/FC = locate(href_list["ac_toggle_d_notice"])
FC.toggleCensorDclass()
src.access_news_network()
else if(href_list["ac_view"])
if(!check_rights(R_ADMIN))
return
src.admincaster_screen=1
src.access_news_network()
else if(href_list["ac_setScreen"]) //Brings us to the main menu and resets all fields~
if(!check_rights(R_ADMIN))
return
src.admincaster_screen = text2num(href_list["ac_setScreen"])
if (src.admincaster_screen == 0)
if(src.admincaster_feed_channel)
@@ -2140,25 +2237,35 @@
src.access_news_network()
else if(href_list["ac_show_channel"])
if(!check_rights(R_ADMIN))
return
var/datum/newscaster/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"])
if(!check_rights(R_ADMIN))
return
var/datum/newscaster/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"])
if(!check_rights(R_ADMIN))
return
src.access_news_network()
else if(href_list["ac_set_signature"])
if(!check_rights(R_ADMIN))
return
src.admin_signature = adminscrub(input(usr, "Provide your desired signature.", "Network Identity Handler", ""))
src.access_news_network()
else if(href_list["ac_del_comment"])
if(!check_rights(R_ADMIN))
return
var/datum/newscaster/feed_comment/FC = locate(href_list["ac_del_comment"])
var/datum/newscaster/feed_message/FM = locate(href_list["ac_del_comment_msg"])
FM.comments -= FC
@@ -2166,6 +2273,8 @@
src.access_news_network()
else if(href_list["ac_lock_comment"])
if(!check_rights(R_ADMIN))
return
var/datum/newscaster/feed_message/FM = locate(href_list["ac_lock_comment"])
FM.locked ^= 1
src.access_news_network()
@@ -2262,6 +2371,8 @@
error_viewer.show_to(owner, null, href_list["viewruntime_linear"])
else if(href_list["showrelatedacc"])
if(!check_rights(R_ADMIN))
return
var/client/C = locate(href_list["client"]) in GLOB.clients
var/thing_to_check
if(href_list["showrelatedacc"] == "cid")
+12 -6
View File
@@ -24,10 +24,14 @@
message_admins("<span class='danger'>ERROR: Non-admin [key_name(usr, usr.client)] attempted to execute a SDQL query!</span>")
log_admin("Non-admin [usr.ckey]([usr]) attempted to execute a SDQL query!")
return FALSE
var/list/results = world.SDQL2_query(query_text, key_name_admin(usr), "[usr.ckey]([usr])")
for(var/I in 1 to 3)
to_chat(usr, results[I])
/world/proc/SDQL2_query(query_text, log_entry1, log_entry2)
var/query_log = "executed SDQL query: \"[query_text]\"."
message_admins("[key_name_admin(usr)] [query_log]")
query_log = "[usr.ckey]([usr]) [query_log]"
message_admins("[log_entry1] [query_log]")
query_log = "[log_entry2] [query_log]"
log_game(query_log)
NOTICE(query_log)
var/objs_all = 0
@@ -49,6 +53,7 @@
if(!querys || querys.len < 1)
return
var/list/refs = list()
for(var/list/query_tree in querys)
var/list/from_objs = list()
var/list/select_types = list()
@@ -100,6 +105,7 @@
var/text = ""
for(var/datum/t in objs)
text += SDQL_gen_vv_href(t)
refs[REF(t)] = TRUE
CHECK_TICK
usr << browse(text, "window=SDQL-result")
@@ -112,9 +118,9 @@
var/end_time = REALTIMEOFDAY
end_time -= start_time
to_chat(usr, "<span class='admin'>SDQL query results: [query_text]</span>")
to_chat(usr, "<span class='admin'>SDQL query completed: [objs_all] objects selected by path, and [objs_eligible] objects executed on after WHERE filtering if applicable.</span>")
to_chat(usr, "<span class='admin'>SDQL query took [DisplayTimeText(end_time)] to complete.</span>")
return list("<span class='admin'>SDQL query results: [query_text]</span>",\
"<span class='admin'>SDQL query completed: [objs_all] objects selected by path, and [objs_eligible] objects executed on after WHERE filtering if applicable.</span>",\
"<span class='admin'>SDQL query took [DisplayTimeText(end_time)] to complete.</span>") + refs
/proc/SDQL_qdel_datum(datum/d)
qdel(d)
@@ -429,7 +435,7 @@
else if(expression[start + 1] == "\[" && islist(v))
var/list/L = v
var/index = SDQL_expression(source, expression[start + 2])
if(isnum(index) && (!IsInteger(index) || L.len < index))
if(isnum(index) && (!ISINTEGER(index) || L.len < index))
to_chat(usr, "<span class='danger'>Invalid list index: [index]</span>")
return null
return L[index]
+2 -2
View File
@@ -34,7 +34,7 @@
log_admin("[key_name(usr)] jumped to [T.x],[T.y],[T.z] in [T.loc]")
message_admins("[key_name_admin(usr)] jumped to [T.x],[T.y],[T.z] in [T.loc]")
usr.loc = T
usr.forceMove(T)
SSblackbox.record_feedback("tally", "admin_verb", 1, "Jump To Turf") //If you are copy-pasting this, ensure the 2nd parameter is unique to the new proc!
return
@@ -137,7 +137,7 @@
admin_ticket_log(M, msg)
if(M)
M.forceMove(get_turf(usr))
usr.loc = M.loc
usr.forceMove(M.loc)
SSblackbox.record_feedback("tally", "admin_verb", 1, "Get Key") //If you are copy-pasting this, ensure the 2nd parameter is unique to the new proc!
/client/proc/sendmob(mob/M in sortmobs())
+5 -3
View File
@@ -110,7 +110,9 @@ GLOBAL_PROTECT(LastAdminCalledProc)
/proc/WrapAdminProcCall(target, procname, list/arguments)
var/current_caller = GLOB.AdminProcCaller
var/ckey = usr.client.ckey
var/ckey = usr ? usr.client.ckey : GLOB.AdminProcCaller
if(!ckey)
CRASH("WrapAdminProcCall with no ckey: [target] [procname] [english_list(arguments)]")
if(current_caller && current_caller != ckey)
to_chat(usr, "<span class='adminnotice'>Another set of admin called procs are still running, your proc will be run after theirs finish.</span>")
UNTIL(!GLOB.AdminProcCaller)
@@ -733,11 +735,11 @@ GLOBAL_PROTECT(LastAdminCalledProc)
if(Rad.anchored)
if(!Rad.loaded_tank)
var/obj/item/tank/internals/plasma/Plasma = new/obj/item/tank/internals/plasma(Rad)
ASSERT_GAS(/datum/gas/plasma, Plasma.air_contents)
Plasma.air_contents.assert_gas(/datum/gas/plasma)
Plasma.air_contents.gases[/datum/gas/plasma][MOLES] = 70
Rad.drainratio = 0
Rad.loaded_tank = Plasma
Plasma.loc = Rad
Plasma.forceMove(Rad)
if(!Rad.active)
Rad.toggle_power()
+10 -3
View File
@@ -213,7 +213,9 @@ GLOBAL_PROTECT(VVpixelmovement)
.["class"] = null
return
.["type"] = type
.["value"] = new type()
var/atom/newguy = new type()
newguy.var_edited = TRUE
.["value"] = newguy
if (VV_NEW_DATUM)
var/type = pick_closest_path(FALSE, get_fancy_list_of_datum_types())
@@ -221,7 +223,9 @@ GLOBAL_PROTECT(VVpixelmovement)
.["class"] = null
return
.["type"] = type
.["value"] = new type()
var/datum/newguy = new type()
newguy.var_edited = TRUE
.["value"] = newguy
if (VV_NEW_TYPE)
var/type = current_value
@@ -237,7 +241,10 @@ GLOBAL_PROTECT(VVpixelmovement)
.["class"] = null
return
.["type"] = type
.["value"] = new type()
var/datum/newguy = new type()
if(istype(newguy))
newguy.var_edited = TRUE
.["value"] = newguy
if (VV_NEW_LIST)
+13 -13
View File
@@ -238,26 +238,17 @@
if(agentcount < 3)
return 0
var/nuke_code = random_nukecode()
var/obj/machinery/nuclearbomb/nuke = locate("syndienuke") in GLOB.nuke_list
if(nuke)
nuke.r_code = nuke_code
//Let's find the spawn locations
var/leader_chosen = FALSE
var/spawnpos = 1 //Decides where they'll spawn. 1=leader.
var/datum/team/nuclear/nuke_team
for(var/mob/c in chosen)
if(spawnpos > GLOB.nukeop_start.len)
spawnpos = 1 //Ran out of spawns. Let's loop back to the first non-leader position
var/mob/living/carbon/human/new_character=makeBody(c)
if(!leader_chosen)
leader_chosen = TRUE
new_character.mind.make_Nuke(pick(GLOB.nukeop_leader_start), nuke_code, TRUE)
var/datum/antagonist/nukeop/N = new_character.mind.add_antag_datum(/datum/antagonist/nukeop/leader)
nuke_team = N.nuke_team
else
new_character.mind.make_Nuke(GLOB.nukeop_start[spawnpos], nuke_code)
spawnpos++
new_character.mind.add_antag_datum(/datum/antagonist/nukeop,nuke_team)
return 1
else
return 0
@@ -317,12 +308,15 @@
//Assign antag status and the mission
SSticker.mode.traitors += Commando.mind
Commando.mind.special_role = "deathsquad"
var/datum/objective/missionobj = new
missionobj.owner = Commando.mind
missionobj.explanation_text = mission
missionobj.completed = 1
Commando.mind.objectives += missionobj
Commando.mind.add_antag_datum(/datum/antagonist/auto_custom)
//Greet the commando
to_chat(Commando, "<B><font size=3 color=red>You are the [numagents==1?"Deathsquad Officer":"Death Commando"].</font></B>")
var/missiondesc = "Your squad is being sent on a mission to [station_name()] by Nanotrasen's Security Division."
@@ -369,12 +363,15 @@
//Assign antag status and the mission
SSticker.mode.traitors += newmob.mind
newmob.mind.special_role = "official"
var/datum/objective/missionobj = new
missionobj.owner = newmob.mind
missionobj.explanation_text = mission
missionobj.completed = 1
newmob.mind.objectives += missionobj
newmob.mind.add_antag_datum(/datum/antagonist/auto_custom)
if(CONFIG_GET(flag/enforce_human_authority))
newmob.set_species(/datum/species/human)
@@ -474,12 +471,15 @@
//Assign antag status and the mission
SSticker.mode.traitors += ERTOperative.mind
ERTOperative.mind.special_role = "ERT"
var/datum/objective/missionobj = new
missionobj.owner = ERTOperative.mind
missionobj.explanation_text = mission
missionobj.completed = 1
ERTOperative.mind.objectives += missionobj
ERTOperative.mind.add_antag_datum(/datum/antagonist/auto_custom)
//Greet the commando
to_chat(ERTOperative, "<B><font size=3 color=red>You are [numagents==1?"the Emergency Response Team Commander":"an Emergency Response Officer"].</font></B>")
var/missiondesc = "Your squad is being sent on a Code [alert] mission to [station_name()] by Nanotrasen's Security Division."
+3
View File
@@ -28,6 +28,7 @@ GLOBAL_VAR_INIT(highlander, FALSE)
/mob/living/carbon/human/proc/make_scottish()
SSticker.mode.traitors += mind
mind.special_role = "highlander"
dna.species.species_traits |= NOGUNS //nice try jackass
var/datum/objective/steal/steal_objective = new
@@ -40,6 +41,8 @@ GLOBAL_VAR_INIT(highlander, FALSE)
hijack_objective.owner = mind
mind.objectives += hijack_objective
mind.add_antag_datum(/datum/antagonist/auto_custom)
mind.announce_objectives()
for(var/obj/item/I in get_equipped_items())
+1 -1
View File
@@ -12,7 +12,7 @@
var/vol = input(usr, "What volume would you like the sound to play at?",, 100) as null|num
if(!vol)
return
vol = Clamp(vol, 1, 100)
vol = CLAMP(vol, 1, 100)
var/sound/admin_sound = new()
admin_sound.file = S
+11 -4
View File
@@ -386,7 +386,8 @@ Traitors and the like can also be revived with the previous role mostly intact.
A.equip_wizard()
if("Syndicate")
new_character.forceMove(pick(GLOB.nukeop_start))
call(/datum/game_mode/proc/equip_syndicate)(new_character)
var/datum/antagonist/nukeop/N = new_character.mind.has_antag_datum(/datum/antagonist/nukeop,TRUE)
N.equip_op()
if("Space Ninja")
var/list/ninja_spawn = list()
for(var/obj/effect/landmark/carpspawn/L in GLOB.landmarks_list)
@@ -471,7 +472,7 @@ Traitors and the like can also be revived with the previous role mostly intact.
if(!holder)
to_chat(src, "Only administrators may use this command.")
return
var/input = input(usr, "Please enter anything you want. Anything. Serious.", "What?", "") as message|null
var/input = input(usr, "Enter a Command Report. Ensure it makes sense IC.", "What?", "") as message|null
if(!input)
return
@@ -522,7 +523,7 @@ Traitors and the like can also be revived with the previous role mostly intact.
SSblackbox.record_feedback("tally", "admin_verb", 1, "Delete") //If you are copy-pasting this, ensure the 2nd parameter is unique to the new proc!
if(isturf(D))
var/turf/T = D
T.ChangeTurf(T.baseturf)
T.ScrapeAway()
else
qdel(D)
@@ -1206,7 +1207,7 @@ GLOBAL_LIST_EMPTY(custom_outfits) //Admin created outfits
if(!holder)
return
var/list/punishment_list = list(ADMIN_PUNISHMENT_LIGHTNING, ADMIN_PUNISHMENT_BRAINDAMAGE, ADMIN_PUNISHMENT_GIB, ADMIN_PUNISHMENT_BSA, ADMIN_PUNISHMENT_FIREBALL)
var/list/punishment_list = list(ADMIN_PUNISHMENT_LIGHTNING, ADMIN_PUNISHMENT_BRAINDAMAGE, ADMIN_PUNISHMENT_GIB, ADMIN_PUNISHMENT_BSA, ADMIN_PUNISHMENT_FIREBALL, ADMIN_PUNISHMENT_ROD)
var/punishment = input("Choose a punishment", "DIVINE SMITING") as null|anything in punishment_list
@@ -1228,6 +1229,12 @@ GLOBAL_LIST_EMPTY(custom_outfits) //Admin created outfits
bluespace_artillery(target)
if(ADMIN_PUNISHMENT_FIREBALL)
new /obj/effect/temp_visual/target(get_turf(target))
if(ADMIN_PUNISHMENT_ROD)
var/turf/T = get_turf(target)
var/startside = pick(GLOB.cardinals)
var/turf/startT = spaceDebrisStartLoc(startside, T.z)
var/turf/endT = spaceDebrisFinishLoc(startside, T.z)
new /obj/effect/immovablerod(startT, endT,target)
var/msg = "[key_name_admin(usr)] punished [key_name_admin(target)] with [punishment]."
message_admins(msg)
+1 -1
View File
@@ -30,7 +30,7 @@
holder.update_icon()
/obj/item/device/assembly/flash/proc/clown_check(mob/living/carbon/human/user)
if(user.disabilities & CLUMSY && prob(50))
if(user.has_disability(DISABILITY_CLUMSY) && prob(50))
flash_carbon(user, user, 15, 0)
return 0
return 1
+2 -2
View File
@@ -88,10 +88,10 @@
return 0
if(a_left)
a_left.holder = null
a_left.loc = T
a_left.forceMove(T)
if(a_right)
a_right.holder = null
a_right.loc = T
a_right.forceMove(T)
qdel(src)
else
..()
+4 -4
View File
@@ -20,7 +20,7 @@
if(!armed)
if(ishuman(usr))
var/mob/living/carbon/human/user = usr
if((user.getBrainLoss() >= 60) || user.disabilities & CLUMSY && prob(50))
if((user.has_disability(DISABILITY_DUMB) || user.has_disability(DISABILITY_CLUMSY)) && prob(50))
to_chat(user, "<span class='warning'>Your hand slips, setting off the trigger!</span>")
pulse(0)
update_icon()
@@ -76,7 +76,7 @@
if(!armed)
to_chat(user, "<span class='notice'>You arm [src].</span>")
else
if(((user.getBrainLoss() >= 60) || user.disabilities & CLUMSY) && prob(50))
if((user.has_disability(DISABILITY_DUMB) || user.has_disability(DISABILITY_CLUMSY)) && prob(50))
var/which_hand = "l_hand"
if(!(user.active_hand_index % 2))
which_hand = "r_hand"
@@ -92,7 +92,7 @@
/obj/item/device/assembly/mousetrap/attack_hand(mob/living/carbon/human/user)
if(armed)
if(((user.getBrainLoss() >= 60) || user.disabilities & CLUMSY) && prob(50))
if((user.has_disability(DISABILITY_DUMB) || user.has_disability(DISABILITY_CLUMSY)) && prob(50))
var/which_hand = "l_hand"
if(!(user.active_hand_index % 2))
which_hand = "r_hand"
@@ -139,4 +139,4 @@
/obj/item/device/assembly/mousetrap/armed
icon_state = "mousetraparmed"
armed = TRUE
armed = 1
+38 -41
View File
@@ -1,42 +1,39 @@
/obj/item/assembly/shock_kit
name = "electrohelmet assembly"
desc = "This appears to be made from both an electropack and a helmet."
icon = 'icons/obj/assemblies.dmi'
icon_state = "shock_kit"
var/obj/item/clothing/head/helmet/part1 = null
var/obj/item/device/electropack/part2 = null
w_class = WEIGHT_CLASS_HUGE
/obj/item/assembly/shock_kit
name = "electrohelmet assembly"
desc = "This appears to be made from both an electropack and a helmet."
icon = 'icons/obj/assemblies.dmi'
icon_state = "shock_kit"
var/obj/item/clothing/head/helmet/part1 = null
var/obj/item/device/electropack/part2 = null
w_class = WEIGHT_CLASS_HUGE
flags_1 = CONDUCT_1
/obj/item/assembly/shock_kit/Destroy()
qdel(part1)
qdel(part2)
return ..()
/obj/item/assembly/shock_kit/attackby(obj/item/W, mob/user, params)
if(istype(W, /obj/item/wrench))
var/turf/T = loc
if(ismob(T))
T = T.loc
part1.loc = T
part2.loc = T
part1.master = null
part2.master = null
part1 = null
part2 = null
qdel(src)
return
add_fingerprint(user)
return
/obj/item/assembly/shock_kit/attack_self(mob/user)
part1.attack_self(user)
part2.attack_self(user)
add_fingerprint(user)
return
/obj/item/assembly/shock_kit/receive_signal()
if(istype(loc, /obj/structure/chair/e_chair))
var/obj/structure/chair/e_chair/C = loc
C.shock()
return
/obj/item/assembly/shock_kit/Destroy()
qdel(part1)
qdel(part2)
return ..()
/obj/item/assembly/shock_kit/attackby(obj/item/W, mob/user, params)
if(istype(W, /obj/item/wrench))
part1.forceMove(drop_location())
part2.forceMove(drop_location())
part1.master = null
part2.master = null
part1 = null
part2 = null
qdel(src)
return
add_fingerprint(user)
return
/obj/item/assembly/shock_kit/attack_self(mob/user)
part1.attack_self(user)
part2.attack_self(user)
add_fingerprint(user)
return
/obj/item/assembly/shock_kit/receive_signal()
if(istype(loc, /obj/structure/chair/e_chair))
var/obj/structure/chair/e_chair/C = loc
C.shock()
return
@@ -168,7 +168,7 @@
else
chance_of_deletion = 100
if(prob(chance_of_deletion))
T.ChangeTurf(T.baseturf)
T.ScrapeAway()
else
T.to_be_destroyed = FALSE
T.max_fire_temperature_sustained = 0
@@ -37,14 +37,24 @@ GLOBAL_LIST_INIT(gaslist_cache, init_gaslist_cache())
reaction_results = new
//listmos procs
//use the macros in performance intensive areas. for their definitions, refer to code/__DEFINES/atmospherics.dm
// The following procs used to live here: thermal_energy(), assert_gas() and add_gas(). They have been moved into defines in code/__DEFINES/atmospherics.dm
//assert_gas(gas_id) - used to guarantee that the gas list for this id exists in gas_mixture.gases.
//Must be used before adding to a gas. May be used before reading from a gas.
/datum/gas_mixture/proc/assert_gas(gas_id)
ASSERT_GAS(gas_id, src)
//assert_gases(args) - shorthand for calling ASSERT_GAS() once for each gas type.
/datum/gas_mixture/proc/assert_gases()
for(var/id in args)
ASSERT_GAS(id, src)
//add_gas(gas_id) - similar to assert_gas(), but does not check for an existing
//gas list for this id. This can clobber existing gases.
//Used instead of assert_gas() when you know the gas does not exist. Faster than assert_gas().
/datum/gas_mixture/proc/add_gas(gas_id)
ADD_GAS(gas_id, gases)
//add_gases(args) - shorthand for calling add_gas() once for each gas_type.
/datum/gas_mixture/proc/add_gases()
var/cached_gases = gases
@@ -101,6 +111,9 @@ GLOBAL_LIST_INIT(gaslist_cache, init_gaslist_cache())
/datum/gas_mixture/proc/return_volume() //liters
return max(0, volume)
/datum/gas_mixture/proc/thermal_energy() //joules
return THERMAL_ENERGY(src) //see code/__DEFINES/atmospherics.dm; use the define in performance critical areas
/datum/gas_mixture/proc/archive()
//Update archived versions of variables
//Returns: 1 in all cases
@@ -399,7 +412,7 @@ GLOBAL_LIST_INIT(gaslist_cache, init_gaslist_cache())
return ""
/datum/gas_mixture/react(turf/open/dump_location)
. = 0
. = NO_REACTION
reaction_results = new
@@ -423,6 +436,22 @@ GLOBAL_LIST_INIT(gaslist_cache, init_gaslist_cache())
continue reaction_loop
//at this point, all minimum requirements for the reaction are satisfied.
/* currently no reactions have maximum requirements, so we can leave the checks commented out for a slight performance boost
PLEASE DO NOT REMOVE THIS CODE. the commenting is here only for a performance increase.
enabling these checks should be as easy as possible and the fact that they are disabled should be as clear as possible
var/list/max_reqs = reaction.max_requirements.Copy()
if((max_reqs["TEMP"] && temp > max_reqs["TEMP"]) \
|| (max_reqs["ENER"] && ener > max_reqs["ENER"]))
continue
max_reqs -= "TEMP"
max_reqs -= "ENER"
for(var/id in max_reqs)
if(cached_gases[id] && cached_gases[id][MOLES] > max_reqs[id])
continue reaction_loop
//at this point, all requirements for the reaction are satisfied. we can now react()
*/
. |= reaction.react(src, dump_location)
if (. & STOP_REACTIONS)
break
@@ -184,7 +184,7 @@
//fusion: a terrible idea that was fun but broken. Now reworked to be less broken and more interesting.
/datum/gas_reaction/fusion
exclude = FALSE
exclude = TRUE
priority = 2
name = "Plasmic Fusion"
id = "fusion"
+14 -15
View File
@@ -452,11 +452,7 @@
for(var/device_id in A.air_scrub_names)
send_signal(device_id, list(
"power" = 1,
"co2_scrub" = 1,
"tox_scrub" = 0,
"n2o_scrub" = 0,
"rare_scrub"= 0,
"water_vapor_scrub"= 0,
"set_filters" = list(/datum/gas/carbon_dioxide),
"scrubbing" = 1,
"widenet" = 0,
))
@@ -470,11 +466,18 @@
for(var/device_id in A.air_scrub_names)
send_signal(device_id, list(
"power" = 1,
"co2_scrub" = 1,
"tox_scrub" = 1,
"n2o_scrub" = 1,
"rare_scrub"= 1,
"water_vapor_scrub"= 1,
"set_filters" = list(
/datum/gas/carbon_dioxide,
/datum/gas/plasma,
/datum/gas/water_vapor,
/datum/gas/hypernoblium,
/datum/gas/nitrous_oxide,
/datum/gas/nitryl,
/datum/gas/tritium,
/datum/gas/bz,
/datum/gas/stimulum,
/datum/gas/pluoxium
),
"scrubbing" = 1,
"widenet" = 1,
))
@@ -501,11 +504,7 @@
for(var/device_id in A.air_scrub_names)
send_signal(device_id, list(
"power" = 1,
"co2_scrub" = 1,
"tox_scrub" = 0,
"n2o_scrub" = 0,
"rare_scrub"= 0,
"water_vapor_scrub"= 0,
"set_filters" = list(/datum/gas/carbon_dioxide),
"scrubbing" = 1,
"widenet" = 0,
))
@@ -185,13 +185,13 @@ Acts like a normal vent, but has an input AND output.
pump_direction = 1
if("set_input_pressure" in signal.data)
input_pressure_min = Clamp(text2num(signal.data["set_input_pressure"]),0,ONE_ATMOSPHERE*50)
input_pressure_min = CLAMP(text2num(signal.data["set_input_pressure"]),0,ONE_ATMOSPHERE*50)
if("set_output_pressure" in signal.data)
output_pressure_max = Clamp(text2num(signal.data["set_output_pressure"]),0,ONE_ATMOSPHERE*50)
output_pressure_max = CLAMP(text2num(signal.data["set_output_pressure"]),0,ONE_ATMOSPHERE*50)
if("set_external_pressure" in signal.data)
external_pressure_bound = Clamp(text2num(signal.data["set_external_pressure"]),0,ONE_ATMOSPHERE*50)
external_pressure_bound = CLAMP(text2num(signal.data["set_external_pressure"]),0,ONE_ATMOSPHERE*50)
if("status" in signal.data)
spawn(2)
@@ -127,7 +127,7 @@ Passive gate is similar to the regular pump except:
pressure = text2num(pressure)
. = TRUE
if(.)
target_pressure = Clamp(pressure, 0, MAX_OUTPUT_PRESSURE)
target_pressure = CLAMP(pressure, 0, MAX_OUTPUT_PRESSURE)
investigate_log("was set to [target_pressure] kPa by [key_name(usr)]", INVESTIGATE_ATMOS)
update_icon()
@@ -149,7 +149,7 @@ Passive gate is similar to the regular pump except:
on = !on
if("set_output_pressure" in signal.data)
target_pressure = Clamp(text2num(signal.data["set_output_pressure"]),0,ONE_ATMOSPHERE*50)
target_pressure = CLAMP(text2num(signal.data["set_output_pressure"]),0,ONE_ATMOSPHERE*50)
if(on != old_on)
investigate_log("was turned [on ? "on" : "off"] by a remote signal", INVESTIGATE_ATMOS)
@@ -133,9 +133,8 @@ Thus, the two variables affect pump operation are set in New():
pressure = text2num(pressure)
. = TRUE
if(.)
target_pressure = Clamp(pressure, 0, MAX_OUTPUT_PRESSURE)
investigate_log("Pump, [src.name], was set to [target_pressure] kPa by [key_name(usr)] at [x], [y], [z], [A]", INVESTIGATE_ATMOS)
message_admins("Pump, [src.name], was set to [target_pressure] kPa by [ADMIN_LOOKUPFLW(usr)] at [ADMIN_COORDJMP(T)], [A]")
target_pressure = CLAMP(pressure, 0, MAX_OUTPUT_PRESSURE)
investigate_log("was set to [target_pressure] kPa by [key_name(usr)]", INVESTIGATE_ATMOS)
update_icon()
/obj/machinery/atmospherics/components/binary/pump/atmosinit()
@@ -156,7 +155,7 @@ Thus, the two variables affect pump operation are set in New():
on = !on
if("set_output_pressure" in signal.data)
target_pressure = Clamp(text2num(signal.data["set_output_pressure"]),0,ONE_ATMOSPHERE*50)
target_pressure = CLAMP(text2num(signal.data["set_output_pressure"]),0,ONE_ATMOSPHERE*50)
if(on != old_on)
investigate_log("was turned [on ? "on" : "off"] by a remote signal", INVESTIGATE_ATMOS)
@@ -133,9 +133,8 @@ Thus, the two variables affect pump operation are set in New():
rate = text2num(rate)
. = TRUE
if(.)
transfer_rate = Clamp(rate, 0, MAX_TRANSFER_RATE)
investigate_log("Volume Pump, [src.name], was set to [transfer_rate] L/s by [key_name(usr)] at [x], [y], [z], [A]", INVESTIGATE_ATMOS)
message_admins("Volume Pump, [src.name], was set to [transfer_rate] L/s by [ADMIN_LOOKUPFLW(usr)] at [ADMIN_COORDJMP(T)], [A]")
transfer_rate = CLAMP(rate, 0, MAX_TRANSFER_RATE)
investigate_log("was set to [transfer_rate] L/s by [key_name(usr)]", INVESTIGATE_ATMOS)
update_icon()
/obj/machinery/atmospherics/components/binary/volume_pump/receive_signal(datum/signal/signal)
@@ -152,7 +151,7 @@ Thus, the two variables affect pump operation are set in New():
if("set_transfer_rate" in signal.data)
var/datum/gas_mixture/air1 = AIR1
transfer_rate = Clamp(text2num(signal.data["set_transfer_rate"]),0,air1.volume)
transfer_rate = CLAMP(text2num(signal.data["set_transfer_rate"]),0,air1.volume)
if(on != old_on)
investigate_log("was turned [on ? "on" : "off"] by a remote signal", INVESTIGATE_ATMOS)
@@ -103,7 +103,7 @@
var/datum/gas_mixture/filtered_out = new
filtered_out.temperature = removed.temperature
ASSERT_GAS(filter_type, filtered_out)
filtered_out.add_gas(filter_type)
filtered_out.gases[filter_type][MOLES] = removed.gases[filter_type][MOLES]
removed.gases[filter_type][MOLES] = 0
@@ -162,7 +162,7 @@
pressure = text2num(pressure)
. = TRUE
if(.)
target_pressure = Clamp(pressure, 0, MAX_OUTPUT_PRESSURE)
target_pressure = CLAMP(pressure, 0, MAX_OUTPUT_PRESSURE)
investigate_log("was set to [target_pressure] kPa by [key_name(usr)]", INVESTIGATE_ATMOS)
if("filter")
filter_type = null
@@ -152,7 +152,7 @@
pressure = text2num(pressure)
. = TRUE
if(.)
target_pressure = Clamp(pressure, 0, MAX_OUTPUT_PRESSURE)
target_pressure = CLAMP(pressure, 0, MAX_OUTPUT_PRESSURE)
investigate_log("was set to [target_pressure] kPa by [key_name(usr)]", INVESTIGATE_ATMOS)
if("node1")
var/value = text2num(params["concentration"])
@@ -131,7 +131,7 @@
if("set_volume_rate" in signal.data)
var/number = text2num(signal.data["set_volume_rate"])
var/datum/gas_mixture/air_contents = AIR1
volume_rate = Clamp(number, 0, air_contents.volume)
volume_rate = CLAMP(number, 0, air_contents.volume)
if("status" in signal.data)
spawn(2)
@@ -180,7 +180,7 @@
rate = text2num(rate)
. = TRUE
if(.)
volume_rate = Clamp(rate, 0, MAX_TRANSFER_RATE)
volume_rate = CLAMP(rate, 0, MAX_TRANSFER_RATE)
investigate_log("was set to [volume_rate] L/s by [key_name(usr)]", INVESTIGATE_ATMOS)
update_icon()
broadcast_status()
@@ -17,7 +17,7 @@
air_contents.volume = volume
air_contents.temperature = T20C
if(gas_type)
ASSERT_GAS(gas_type, air_contents)
air_contents.assert_gas(gas_type)
air_contents.gases[gas_type][MOLES] = AIR_CONTENTS
name = "[name] ([air_contents.gases[gas_type][GAS_META][META_GAS_NAME]])"
@@ -153,7 +153,7 @@
target = text2num(target)
. = TRUE
if(.)
target_temperature = Clamp(target, min_temperature, max_temperature)
target_temperature = CLAMP(target, min_temperature, max_temperature)
investigate_log("was set to [target_temperature] K by [key_name(usr)]", INVESTIGATE_ATMOS)
update_icon()
@@ -244,10 +244,10 @@
pump_direction = text2num(signal.data["direction"])
if("set_internal_pressure" in signal.data)
internal_pressure_bound = Clamp(text2num(signal.data["set_internal_pressure"]),0,ONE_ATMOSPHERE*50)
internal_pressure_bound = CLAMP(text2num(signal.data["set_internal_pressure"]),0,ONE_ATMOSPHERE*50)
if("set_external_pressure" in signal.data)
external_pressure_bound = Clamp(text2num(signal.data["set_external_pressure"]),0,ONE_ATMOSPHERE*50)
external_pressure_bound = CLAMP(text2num(signal.data["set_external_pressure"]),0,ONE_ATMOSPHERE*50)
if("reset_external_pressure" in signal.data)
external_pressure_bound = ONE_ATMOSPHERE
@@ -256,10 +256,10 @@
internal_pressure_bound = 0
if("adjust_internal_pressure" in signal.data)
internal_pressure_bound = Clamp(internal_pressure_bound + text2num(signal.data["adjust_internal_pressure"]),0,ONE_ATMOSPHERE*50)
internal_pressure_bound = CLAMP(internal_pressure_bound + text2num(signal.data["adjust_internal_pressure"]),0,ONE_ATMOSPHERE*50)
if("adjust_external_pressure" in signal.data)
external_pressure_bound = Clamp(external_pressure_bound + text2num(signal.data["adjust_external_pressure"]),0,ONE_ATMOSPHERE*50)
external_pressure_bound = CLAMP(external_pressure_bound + text2num(signal.data["adjust_external_pressure"]),0,ONE_ATMOSPHERE*50)
if("init" in signal.data)
name = signal.data["init"]
@@ -179,7 +179,7 @@
filtered_out.temperature = removed.temperature
for(var/gas in filter_types & removed_gases)
ADD_GAS(gas, filtered_gases)
filtered_out.add_gas(gas)
filtered_gases[gas][MOLES] = removed_gases[gas][MOLES]
removed_gases[gas][MOLES] = 0
@@ -242,6 +242,11 @@
if("toggle_filter" in signal.data)
filter_types ^= gas_id2path(signal.data["toggle_filter"])
if("set_filters" in signal.data)
filter_types = list()
for(var/gas in signal.data["set_filters"])
filter_types += gas_id2path(gas)
if("init" in signal.data)
name = signal.data["init"]
return
@@ -132,7 +132,7 @@
if(!isopenturf(O))
return FALSE
var/datum/gas_mixture/merger = new
ASSERT_GAS(spawn_id, merger)
merger.assert_gas(spawn_id)
merger.gases[spawn_id][MOLES] = (spawn_mol)
merger.temperature = spawn_temp
O.assume_air(merger)
@@ -121,7 +121,7 @@
if(initialize_directions & dir)
return ..()
if((NORTH|EAST) & dir)
user.ventcrawl_layer = Clamp(user.ventcrawl_layer + 1, PIPING_LAYER_MIN, PIPING_LAYER_MAX)
user.ventcrawl_layer = CLAMP(user.ventcrawl_layer + 1, PIPING_LAYER_MIN, PIPING_LAYER_MAX)
if((SOUTH|WEST) & dir)
user.ventcrawl_layer = Clamp(user.ventcrawl_layer - 1, PIPING_LAYER_MIN, PIPING_LAYER_MAX)
user.ventcrawl_layer = CLAMP(user.ventcrawl_layer - 1, PIPING_LAYER_MIN, PIPING_LAYER_MAX)
to_chat(user, "You align yourself with the [user.ventcrawl_layer]\th output.")
@@ -196,7 +196,7 @@
/obj/machinery/portable_atmospherics/canister/proc/create_gas()
if(gas_type)
ADD_GAS(gas_type, air_contents.gases)
air_contents.add_gas(gas_type)
if(starter_temp)
air_contents.temperature = starter_temp
air_contents.gases[gas_type][MOLES] = (maximum_pressure * filled) * air_contents.volume / (R_IDEAL_GAS_EQUATION * air_contents.temperature)
@@ -411,7 +411,7 @@
pressure = text2num(pressure)
. = TRUE
if(.)
release_pressure = Clamp(round(pressure), can_min_release_pressure, can_max_release_pressure)
release_pressure = CLAMP(round(pressure), can_min_release_pressure, can_max_release_pressure)
investigate_log("was set to [release_pressure] kPa by [key_name(usr)].", INVESTIGATE_ATMOS)
if("valve")
var/logmsg
@@ -455,7 +455,7 @@
var/N = text2num(user_input)
if(!N)
return
timer_set = Clamp(N,minimum_timer_set,maximum_timer_set)
timer_set = CLAMP(N,minimum_timer_set,maximum_timer_set)
log_admin("[key_name(usr)] has activated a prototype valve timer")
. = TRUE
if("toggle_timer")
@@ -131,11 +131,11 @@
pressure = text2num(pressure)
. = TRUE
if(.)
pump.target_pressure = Clamp(round(pressure), PUMP_MIN_PRESSURE, PUMP_MAX_PRESSURE)
pump.target_pressure = CLAMP(round(pressure), PUMP_MIN_PRESSURE, PUMP_MAX_PRESSURE)
investigate_log("was set to [pump.target_pressure] kPa by [key_name(usr)].", INVESTIGATE_ATMOS)
if("eject")
if(holding)
holding.loc = get_turf(src)
holding.forceMove(drop_location())
holding = null
. = TRUE
update_icon()
@@ -45,7 +45,7 @@
filtered.temperature = filtering.temperature
for(var/gas in filtering.gases & scrubbing)
ADD_GAS(gas, filtered.gases)
filtered.add_gas(gas)
filtered.gases[gas][MOLES] = filtering.gases[gas][MOLES] // Shuffle the "bad" gasses to the filtered mixture.
filtering.gases[gas][MOLES] = 0
filtering.garbage_collect() // Now that the gasses are set to 0, clean up the mixture.
@@ -96,7 +96,7 @@
. = TRUE
if("eject")
if(holding)
holding.loc = get_turf(src)
holding.forceMove(drop_location())
holding = null
. = TRUE
if("toggle_filter")
@@ -26,6 +26,7 @@
flags_2 = SLOWS_WHILE_IN_HAND_2
var/team = WHITE_TEAM
var/reset_cooldown = 0
var/anyonecanpickup = TRUE
var/obj/effect/ctf/flag_reset/reset
var/reset_path = /obj/effect/ctf/flag_reset
@@ -48,7 +49,7 @@
STOP_PROCESSING(SSobj, src)
/obj/item/twohanded/ctf/attack_hand(mob/living/user)
if(!is_ctf_target(user))
if(!is_ctf_target(user) && !anyonecanpickup)
to_chat(user, "Non players shouldn't be moving the flag!")
return
if(team in user.faction)
+8 -8
View File
@@ -199,9 +199,9 @@ GLOBAL_DATUM(the_gateway, /obj/machinery/gateway/centerstation)
active = 1
update_icon()
/obj/machinery/gateway/centeraway/proc/check_exile_implant(mob/living/carbon/C)
for(var/obj/item/implant/exile/E in C.implants)//Checking that there is an exile implant
to_chat(C, "\black The station gate has detected your exile implant and is blocking your entry.")
/obj/machinery/gateway/centeraway/proc/check_exile_implant(mob/living/L)
for(var/obj/item/implant/exile/E in L.implants)//Checking that there is an exile implant
to_chat(L, "\black The station gate has detected your exile implant and is blocking your entry.")
return TRUE
return FALSE
@@ -212,17 +212,17 @@ GLOBAL_DATUM(the_gateway, /obj/machinery/gateway/centerstation)
return
if(!stationgate || QDELETED(stationgate))
return
if(istype(AM, /mob/living/carbon))
if(isliving(AM))
if(check_exile_implant(AM))
return
else
for(var/mob/living/carbon/C in AM.contents)
if(check_exile_implant(C))
for(var/mob/living/L in AM.contents)
if(check_exile_implant(L))
say("Rejecting [AM]: Exile implant detected in contained lifeform.")
return
if(AM.has_buckled_mobs())
for(var/mob/living/carbon/C in AM.buckled_mobs)
if(check_exile_implant(C))
for(var/mob/living/L in AM.buckled_mobs)
if(check_exile_implant(L))
say("Rejecting [AM]: Exile implant detected in close proximity lifeform.")
return
AM.forceMove(get_step(stationgate.loc, SOUTH))
@@ -207,7 +207,7 @@
//Swarm of creatures
for(var/direction in GLOB.alldirs)
var/turf/T = get_turf(src)
new /mob/living/simple_animal/hostile/creature(get_step(T,direction))
new /mob/living/simple_animal/hostile/netherworld(get_step(T,direction))
if(4)
//Destroy Equipment
for (var/obj/item/I in user)
@@ -115,9 +115,11 @@
to_chat(user, "The Wish Granter punishes you for your wickedness, claiming your soul and warping your body to match the darkness in your heart.")
SSticker.mode.traitors += user.mind
user.mind.special_role = "traitor"
var/datum/objective/hijack/hijack = new
hijack.owner = user.mind
user.mind.objectives += hijack
user.mind.add_antag_datum(/datum/antagonist/auto_custom)
to_chat(user, "<B>Your inhibitions are swept away, the bonds of loyalty broken, you are free to murder as you please!</B>")
user.mind.announce_objectives()
user.set_species(/datum/species/shadow)
+3 -3
View File
@@ -86,7 +86,7 @@ Credit dupes that require a lot of manual work shouldn't be removed, unless they
/datum/export/process()
..()
cost *= GLOB.E**(k_elasticity * (1/30))
cost *= NUM_E**(k_elasticity * (1/30))
if(cost > init_cost)
cost = init_cost
@@ -94,7 +94,7 @@ Credit dupes that require a lot of manual work shouldn't be removed, unless they
/datum/export/proc/get_cost(obj/O, contr = 0, emag = 0)
var/amount = get_amount(O, contr, emag)
if(k_elasticity!=0)
return round((cost/k_elasticity) * (1 - GLOB.E**(-1 * k_elasticity * amount))) //anti-derivative of the marginal cost function
return round((cost/k_elasticity) * (1 - NUM_E**(-1 * k_elasticity * amount))) //anti-derivative of the marginal cost function
else
return round(cost * amount) //alternative form derived from L'Hopital to avoid division by 0
@@ -131,7 +131,7 @@ Credit dupes that require a lot of manual work shouldn't be removed, unless they
else
total_amount += amount
cost *= GLOB.E**(-1*k_elasticity*amount) //marginal cost modifier
cost *= NUM_E**(-1*k_elasticity*amount) //marginal cost modifier
SSblackbox.record_feedback("nested tally", "export_sold_cost", 1, list("[O.type]", "[the_cost]"))
// Total printout for the cargo console.
+3
View File
@@ -68,3 +68,6 @@
var/datum/chatOutput/chatOutput
var/list/credits //lazy list of all credit object bound to this client
var/datum/player_details/player_details //these persist between logins/logouts during the same round.
+29 -9
View File
@@ -75,7 +75,8 @@
//Logs all hrefs, except chat pings
if(!(href_list["_src_"] == "chat" && href_list["proc"] == "ping" && LAZYLEN(href_list) == 2))
WRITE_FILE(GLOB.world_href_log, "<small>[time_stamp(show_ds = TRUE)] [src] (usr:[usr])</small> || [hsrc ? "[hsrc] " : ""][href]<br>")
WRITE_FILE(GLOB.world_href_log, "<small>[time_stamp(show_ds = TRUE)] [src] (usr:[usr]\[[COORD(usr)]\])</small> || [hsrc ? "[hsrc] " : ""][href]<br>")
// Admin PM
if(href_list["priv_msg"])
cmd_admin_pm(href_list["priv_msg"],null)
@@ -152,7 +153,7 @@ GLOBAL_LIST(external_rsc_urls)
#if (PRELOAD_RSC == 0)
var/static/next_external_rsc = 0
if(external_rsc_urls && external_rsc_urls.len)
next_external_rsc = Wrap(next_external_rsc+1, 1, external_rsc_urls.len+1)
next_external_rsc = WRAP(next_external_rsc+1, 1, external_rsc_urls.len+1)
preload_rsc = external_rsc_urls[next_external_rsc]
#endif
@@ -160,7 +161,7 @@ GLOBAL_LIST(external_rsc_urls)
GLOB.directory[ckey] = src
GLOB.ahelp_tickets.ClientLogin(src)
var/connecting_admin = FALSE //because de-admined admins connecting should be treated like admins.
//Admin Authorisation
var/localhost_addresses = list("127.0.0.1", "::1")
if(address && (address in localhost_addresses))
@@ -184,6 +185,11 @@ GLOBAL_LIST(external_rsc_urls)
if(holder)
GLOB.admins |= src
holder.owner = src
connecting_admin = TRUE
else if(GLOB.deadmins[ckey])
verbs += /client/proc/readmin
connecting_admin = TRUE
//preferences datum - also holds some persistent data for the client (because we may as well keep these datums to a minimum)
prefs = GLOB.preferences_datums[ckey]
@@ -222,13 +228,20 @@ GLOBAL_LIST(external_rsc_urls)
message_admins("<font color='red'><B>Notice: </B><font color='blue'>[key_name_admin(src)] has the same [matches] as [key_name_admin(C)] (no longer logged in). </font>")
log_access("Notice: [key_name(src)] has the same [matches] as [key_name(C)] (no longer logged in).")
if(GLOB.player_details[ckey])
player_details = GLOB.player_details[ckey]
else
player_details = new
GLOB.player_details[ckey] = player_details
. = ..() //calls mob.Login()
chatOutput.start() // Starts the chat
if(alert_mob_dupe_login)
set waitfor = FALSE
alert(mob, "You have logged in already with another key this round, please log out of this one NOW or risk being banned!")
spawn()
alert(mob, "You have logged in already with another key this round, please log out of this one NOW or risk being banned!")
connection_time = world.time
connection_realtime = world.realtime
@@ -242,7 +255,7 @@ GLOBAL_LIST(external_rsc_urls)
to_chat(src, "Your version: [byond_version]")
to_chat(src, "Required version: [cev] or later")
to_chat(src, "Visit http://www.byond.com/download/ to get the latest version of byond.")
if (holder)
if (connecting_admin)
to_chat(src, "Because you are an admin, you are being allowed to walk past this limitation, But it is still STRONGLY suggested you upgrade")
else
qdel(src)
@@ -262,7 +275,7 @@ GLOBAL_LIST(external_rsc_urls)
to_chat(src, "Required version to remove this message: [cwv] or later")
to_chat(src, "Visit http://www.byond.com/download/ to get the latest version of byond.")
if (connection == "web" && !holder)
if (connection == "web" && !connecting_admin)
if (!CONFIG_GET(flag/allow_webclient))
to_chat(src, "Web client is disabled")
qdel(src)
@@ -427,7 +440,7 @@ GLOBAL_LIST(external_rsc_urls)
if (src.holder && src.holder.rank)
admin_rank = src.holder.rank.name
else
if (check_randomizer(connectiontopic))
if (!GLOB.deadmins[ckey] && check_randomizer(connectiontopic))
return
var/sql_ip = sanitizeSQL(address)
var/sql_computerid = sanitizeSQL(computer_id)
@@ -437,7 +450,7 @@ GLOBAL_LIST(external_rsc_urls)
if(!query_client_in_db.Execute())
return
if(!query_client_in_db.NextRow())
if (CONFIG_GET(flag/panic_bunker) && !holder && !(ckey in GLOB.deadmins))
if (CONFIG_GET(flag/panic_bunker) && !holder && !GLOB.deadmins[ckey])
log_access("Failed Login: [key] - New account attempting to connect during panic bunker")
message_admins("<span class='adminnotice'>Failed Login: [key] - New account attempting to connect during panic bunker</span>")
to_chat(src, "Sorry but the server is currently not accepting connections from never before seen players.")
@@ -668,6 +681,13 @@ GLOBAL_LIST(external_rsc_urls)
return TRUE
. = ..()
/client/proc/rescale_view(change, min, max)
var/viewscale = getviewsize(view)
var/x = viewscale[1]
var/y = viewscale[2]
x = CLAMP(x+change, min, max)
y = CLAMP(y+change, min,max)
change_view("[x]x[y]")
/client/proc/change_view(new_size)
if (isnull(new_size))
+2
View File
@@ -0,0 +1,2 @@
/datum/player_details
var/list/player_actions = list()
+2 -2
View File
@@ -1596,12 +1596,12 @@ GLOBAL_LIST_EMPTY(preferences_datums)
toggles ^= MIDROUND_ANTAG
if("parallaxup")
parallax = Wrap(parallax + 1, PARALLAX_INSANE, PARALLAX_DISABLE + 1)
parallax = WRAP(parallax + 1, PARALLAX_INSANE, PARALLAX_DISABLE + 1)
if (parent && parent.mob && parent.mob.hud_used)
parent.mob.hud_used.update_parallax_pref(parent.mob)
if("parallaxdown")
parallax = Wrap(parallax - 1, PARALLAX_INSANE, PARALLAX_DISABLE + 1)
parallax = WRAP(parallax - 1, PARALLAX_INSANE, PARALLAX_DISABLE + 1)
if (parent && parent.mob && parent.mob.hud_used)
parent.mob.hud_used.update_parallax_pref(parent.mob)
+1
View File
@@ -206,6 +206,7 @@
sensor_mode = SENSOR_OFF //Hey who's this guy on the Syndicate Shuttle??
random_sensor = FALSE
resistance_flags = NONE
can_adjust = FALSE
armor = list(melee = 10, bullet = 10, laser = 10, energy = 0, bomb = 0, bio = 0, rad = 0, fire = 50, acid = 50)
var/datum/action/item_action/chameleon/change/chameleon_action
+3 -3
View File
@@ -11,7 +11,7 @@
materials = list(MAT_GLASS = 250)
var/vision_flags = 0
var/darkness_view = 2//Base human is 2
var/invis_view = SEE_INVISIBLE_LIVING
var/invis_view = SEE_INVISIBLE_LIVING //admin only for now
var/invis_override = 0 //Override to allow glasses to set higher than normal see_invis
var/lighting_alpha
var/list/icon/current = list() //the current hud icons
@@ -41,7 +41,7 @@
/obj/item/clothing/glasses/proc/thermal_overload()
if(ishuman(src.loc))
var/mob/living/carbon/human/H = src.loc
if(!(H.disabilities & BLIND))
if(!(H.has_disability(DISABILITY_BLIND)))
if(H.glasses == src)
to_chat(H, "<span class='danger'>[src] overloads and blinds you!</span>")
H.flash_act(visual = 1)
@@ -261,7 +261,7 @@
icon_state = "thermal"
item_state = "glasses"
vision_flags = SEE_MOBS
invis_view = 2
lighting_alpha = LIGHTING_PLANE_ALPHA_MOSTLY_VISIBLE
flash_protect = 0
glass_colour_type = /datum/client_colour/glass_colour/red
+1 -1
View File
@@ -174,7 +174,7 @@
icon_state = "thermal"
hud_type = DATA_HUD_SECURITY_ADVANCED
vision_flags = SEE_MOBS
invis_view = 2
lighting_alpha = LIGHTING_PLANE_ALPHA_MOSTLY_VISIBLE
glass_colour_type = /datum/client_colour/glass_colour/red
/obj/item/clothing/glasses/hud/toggle/thermal/attack_self(mob/user)
+10 -8
View File
@@ -192,7 +192,7 @@
item_state = "wgloves"
item_color = "mime"
/obj/item/clothing/gloves/color/random/New()
/obj/item/clothing/gloves/color/random/Initialize()
..()
var/list/gloves = list(
/obj/item/clothing/gloves/color/orange = 1,
@@ -202,12 +202,14 @@
/obj/item/clothing/gloves/color/green = 1,
/obj/item/clothing/gloves/color/grey = 1,
/obj/item/clothing/gloves/color/light_brown = 1,
/obj/item/clothing/gloves/color/brown = 1)
/obj/item/clothing/gloves/color/brown = 1,
/obj/item/clothing/gloves/color/white = 1,
/obj/item/clothing/gloves/color/rainbow = 1)
var/obj/item/clothing/gloves/color/selected = pick(gloves)
name = initial(selected.name)
desc = initial(selected.desc)
icon_state = initial(selected.icon_state)
item_state = initial(selected.item_state)
item_color = initial(selected.item_color)
if(ishuman(loc))
var/mob/living/carbon/human/H = loc
H.equip_to_slot_or_del(new selected(H), slot_gloves)
else
new selected(loc)
return INITIALIZE_HINT_QDEL
+1 -1
View File
@@ -283,7 +283,7 @@
for(var/obj/item/device/flashlight/seclite/S in src)
to_chat(user, "<span class='notice'>You unscrew the seclite from [src].</span>")
F = null
S.loc = get_turf(user)
S.forceMove(user.drop_location())
update_helmlight(user)
S.update_brightness(user)
update_icon()
@@ -98,7 +98,7 @@
I.flags_1 &= ~NODROP_1
if(camera)
camera.remove_target_ui()
camera.loc = user
camera.forceMove(user)
teleport_now.UpdateButtonIcon()
/obj/item/clothing/suit/space/chronos/proc/chronowalk(atom/location)
@@ -278,19 +278,19 @@
if(loc == user)
forceMove(get_turf(user))
if(user.client && user.client.eye != src)
src.loc = get_turf(user)
src.forceMove(user.drop_location())
user.reset_perspective(src)
user.set_machine(src)
var/atom/step = get_step(src, direction)
if(step)
if((step.x <= TRANSITIONEDGE) || (step.x >= (world.maxx - TRANSITIONEDGE - 1)) || (step.y <= TRANSITIONEDGE) || (step.y >= (world.maxy - TRANSITIONEDGE - 1)))
if(!src.Move(step))
src.loc = step
src.forceMove(step)
else
src.loc = step
src.forceMove(step)
if((x == holder.x) && (y == holder.y) && (z == holder.z))
remove_target_ui()
loc = user
forceMove(user)
else if(!target_ui)
create_target_ui()
phase_time = world.time + phase_time_length
+10 -10
View File
@@ -164,7 +164,7 @@
assembled = TRUE
boost_chargerate *= cap
boost_drain -= manip
powersetting_high = Clamp(laser, 0, 3)
powersetting_high = CLAMP(laser, 0, 3)
emp_disable_threshold = bin*1.25
stabilizer_decay_amount = scan*3.5
airbrake_decay_amount = manip*8
@@ -194,15 +194,15 @@
/obj/item/device/flightpack/proc/adjust_momentum(amountx, amounty, reduce_amount_total = 0)
if(reduce_amount_total != 0)
if(momentum_x > 0)
momentum_x = Clamp(momentum_x - reduce_amount_total, 0, momentum_max)
momentum_x = CLAMP(momentum_x - reduce_amount_total, 0, momentum_max)
else if(momentum_x < 0)
momentum_x = Clamp(momentum_x + reduce_amount_total, -momentum_max, 0)
momentum_x = CLAMP(momentum_x + reduce_amount_total, -momentum_max, 0)
if(momentum_y > 0)
momentum_y = Clamp(momentum_y - reduce_amount_total, 0, momentum_max)
momentum_y = CLAMP(momentum_y - reduce_amount_total, 0, momentum_max)
else if(momentum_y < 0)
momentum_y = Clamp(momentum_y + reduce_amount_total, -momentum_max, 0)
momentum_x = Clamp(momentum_x + amountx, -momentum_max, momentum_max)
momentum_y = Clamp(momentum_y + amounty, -momentum_max, momentum_max)
momentum_y = CLAMP(momentum_y + reduce_amount_total, -momentum_max, 0)
momentum_x = CLAMP(momentum_x + amountx, -momentum_max, momentum_max)
momentum_y = CLAMP(momentum_y + amounty, -momentum_max, momentum_max)
calculate_momentum_speed()
/obj/item/device/flightpack/intercept_user_move(dir, mob, newLoc, oldLoc)
@@ -314,7 +314,7 @@
/obj/item/device/flightpack/proc/handle_damage()
if(emp_damage)
emp_damage = Clamp(emp_damage-emp_heal_amount, 0, emp_disable_threshold * 10)
emp_damage = CLAMP(emp_damage-emp_heal_amount, 0, emp_disable_threshold * 10)
if(emp_damage >= emp_disable_threshold)
emp_disabled = TRUE
if(emp_disabled && (emp_damage <= 0.5))
@@ -347,11 +347,11 @@
/obj/item/device/flightpack/proc/handle_boost()
if(boost)
boost_charge = Clamp(boost_charge-boost_drain, 0, boost_maxcharge)
boost_charge = CLAMP(boost_charge-boost_drain, 0, boost_maxcharge)
if(boost_charge < 1)
deactivate_booster()
if(boost_charge < boost_maxcharge)
boost_charge = Clamp(boost_charge+boost_chargerate, 0, boost_maxcharge)
boost_charge = CLAMP(boost_charge+boost_chargerate, 0, boost_maxcharge)
/obj/item/device/flightpack/proc/cycle_power()
powersetting < powersetting_high? (powersetting++) : (powersetting = 1)
+2 -2
View File
@@ -136,7 +136,7 @@
return
jetpack.turn_off()
jetpack.loc = get_turf(src)
jetpack.forceMove(drop_location())
jetpack = null
to_chat(user, "<span class='notice'>You successfully remove the jetpack from [src].</span>")
@@ -654,7 +654,7 @@
/obj/item/clothing/suit/space/hardsuit/shielded/process()
if(world.time > recharge_cooldown && current_charges < max_charges)
current_charges = Clamp((current_charges + recharge_rate), 0, max_charges)
current_charges = CLAMP((current_charges + recharge_rate), 0, max_charges)
playsound(loc, 'sound/magic/charge.ogg', 50, 1)
if(current_charges == max_charges)
playsound(loc, 'sound/machines/ding.ogg', 50, 1)
+4 -4
View File
@@ -15,11 +15,11 @@
if(U.pockets) // storage items conflict
return FALSE
pockets.loc = U
pockets.forceMove(U)
U.pockets = pockets
U.attached_accessory = src
loc = U
forceMove(U)
layer = FLOAT_LAYER
plane = FLOAT_PLANE
if(minimize_when_attached)
@@ -39,7 +39,7 @@
/obj/item/clothing/accessory/proc/detach(obj/item/clothing/under/U, user)
if(pockets && pockets == U.pockets)
pockets.loc = src
pockets.forceMove(src)
U.pockets = null
for(var/armor_type in armor)
@@ -135,7 +135,7 @@
"<span class='notice'>You pin \the [src] on [M]'s chest.</span>")
if(input)
SSblackbox.record_feedback("associative", "commendation", 1, list("commender" = "[user.real_name]", "commendee" = "[M.real_name]", "medal" = "[src]", "reason" = input))
GLOB.commendations += "[user.real_name] awarded <b>[M.real_name]</b> the <font color='blue'>[name]</font>! \n- [input]"
GLOB.commendations += "[user.real_name] awarded <b>[M.real_name]</b> the <span class='medaltext'>[name]</span>! \n- [input]"
commended = TRUE
log_game("<b>[key_name(M)]</b> was given the following commendation by <b>[key_name(user)]</b>: [input]")
message_admins("<b>[key_name(M)]</b> was given the following commendation by <b>[key_name(user)]</b>: [input]")
+8 -6
View File
@@ -4,13 +4,15 @@
/obj/item/clothing/under/color/random
icon_state = "random_jumpsuit"
/obj/item/clothing/under/color/random/New()
/obj/item/clothing/under/color/random/Initialize()
..()
var/obj/item/clothing/under/color/C = pick(subtypesof(/obj/item/clothing/under/color) - /obj/item/clothing/under/color/random)
name = initial(C.name)
icon_state = initial(C.icon_state)
item_state = initial(C.item_state)
item_color = initial(C.item_color)
var/obj/item/clothing/under/color/C = pick(subtypesof(/obj/item/clothing/under/color) - /obj/item/clothing/under/color/random - /obj/item/clothing/under/color/grey/glorf - /obj/item/clothing/under/color/black/ghost)
if(ishuman(loc))
var/mob/living/carbon/human/H = loc
H.equip_to_slot_or_del(new C(H), slot_w_uniform) //or else you end up with naked assistants running around everywhere...
else
new C(loc)
return INITIALIZE_HINT_QDEL
/obj/item/clothing/under/color/black
name = "black jumpsuit"
@@ -274,6 +274,7 @@
icon_state = "burial"
item_state = "burial"
item_color = "burial"
has_sensor = NO_SENSORS
/obj/item/clothing/under/skirt/black
name = "black skirt"
+1 -1
View File
@@ -98,7 +98,7 @@
else
if(istype(I, /obj/item/reagent_containers))
var/obj/item/reagent_containers/RC = I
if(RC.container_type & OPENCONTAINER_1)
if(RC.is_drainable())
for(var/datum/reagent/A in RC.reagents.reagent_list)
.[A.type] += A.volume
.[I.type] += 1
@@ -13,7 +13,7 @@
icon = 'icons/obj/toy.dmi'
icon_state = "rag"
flags_1 = NOBLUDGEON_1
container_type = OPENCONTAINER_1
container_type = OPENCONTAINER
amount_per_transfer_from_this = 5
possible_transfer_amounts = list()
volume = 5
+3 -3
View File
@@ -29,8 +29,8 @@
/datum/round_event_control/New()
if(config && !wizardevent) // Magic is unaffected by configs
earliest_start = Ceiling(earliest_start * CONFIG_GET(number/events_min_time_mul))
min_players = Ceiling(min_players * CONFIG_GET(number/events_min_players_mul))
earliest_start = CEILING(earliest_start * CONFIG_GET(number/events_min_time_mul), 1)
min_players = CEILING(min_players * CONFIG_GET(number/events_min_players_mul), 1)
/datum/round_event_control/wizard
wizardevent = 1
@@ -60,7 +60,7 @@
triggering = TRUE
if (alertadmins)
message_admins("Random Event triggering in 10 seconds: [name] ([typepath]) (<a href='?src=[REF(src)];cancel=1'>CANCEL</a>)")
message_admins("Random Event triggering in 10 seconds: [name] (<a href='?src=[REF(src)];cancel=1'>CANCEL</a>)")
sleep(100)
var/gamemode = SSticker.mode.config_tag
var/players_amt = get_active_player_count(alive_check = TRUE, afk_check = TRUE, human_check = TRUE)
+2 -2
View File
@@ -67,12 +67,12 @@
kill()
return
if(IsMultiple(activeFor, 4))
if(ISMULTIPLE(activeFor, 4))
var/obj/machinery/vending/rebel = pick(vendingMachines)
vendingMachines.Remove(rebel)
infectedMachines.Add(rebel)
rebel.shut_up = 0
rebel.shoot_inventory = 1
if(IsMultiple(activeFor, 8))
if(ISMULTIPLE(activeFor, 8))
originMachine.speak(pick(rampant_speeches))
+53 -13
View File
@@ -10,22 +10,30 @@
var/virus_type
var/max_severity = 3
/datum/round_event/disease_outbreak/announce(fake)
/datum/round_event/disease_outbreak/announce()
priority_announce("Confirmed outbreak of level 7 viral biohazard aboard [station_name()]. All personnel must contain the outbreak.", "Biohazard Alert", 'sound/ai/outbreak7.ogg')
/datum/round_event/disease_outbreak/setup()
announceWhen = rand(15, 30)
/datum/round_event/disease_outbreak/start()
if(!virus_type)
var/advanced_virus = FALSE
max_severity = 3 + max(FLOOR((world.time - control.earliest_start)/6000, 1),0) //3 symptoms at 20 minutes, plus 1 per 10 minutes
if(prob(20 + (10 * max_severity)))
advanced_virus = TRUE
if(!virus_type && !advanced_virus)
virus_type = pick(/datum/disease/dnaspread, /datum/disease/advance/flu, /datum/disease/advance/cold, /datum/disease/brainrot, /datum/disease/magnitis)
for(var/mob/living/carbon/human/H in shuffle(GLOB.alive_mob_list))
var/turf/T = get_turf(H)
if(!T)
continue
if(!(T.z in GLOB.station_z_levels))
if(T.z != ZLEVEL_STATION_PRIMARY)
continue
if(!H.client)
continue
@@ -41,16 +49,48 @@
continue
var/datum/disease/D
if(virus_type == /datum/disease/dnaspread) //Dnaspread needs strain_data set to work.
if(!H.dna || (H.disabilities & BLIND)) //A blindness disease would be the worst.
continue
D = new virus_type()
var/datum/disease/dnaspread/DS = D
DS.strain_data["name"] = H.real_name
DS.strain_data["UI"] = H.dna.uni_identity
DS.strain_data["SE"] = H.dna.struc_enzymes
if(!advanced_virus)
if(virus_type == /datum/disease/dnaspread) //Dnaspread needs strain_data set to work.
if(!H.dna || (H.has_disability(DISABILITY_BLIND))) //A blindness disease would be the worst.
continue
D = new virus_type()
var/datum/disease/dnaspread/DS = D
DS.strain_data["name"] = H.real_name
DS.strain_data["UI"] = H.dna.uni_identity
DS.strain_data["SE"] = H.dna.struc_enzymes
else
D = new virus_type()
else
D = new virus_type()
D = make_virus(max_severity, max_severity)
D.carrier = TRUE
H.AddDisease(D)
break
if(advanced_virus)
var/datum/disease/advance/A = D
var/list/name_symptoms = list() //for feedback
for(var/datum/symptom/S in A.symptoms)
name_symptoms += S.name
message_admins("An event has triggered a random advanced virus outbreak on [key_name_admin(H)]! It has these symptoms: [english_list(name_symptoms)]")
log_game("An event has triggered a random advanced virus outbreak on [key_name(H)]! It has these symptoms: [english_list(name_symptoms)]")
break
/datum/round_event/disease_outbreak/proc/make_virus(max_symptoms, max_level)
if(max_symptoms > SYMPTOM_LIMIT)
max_symptoms = SYMPTOM_LIMIT
var/datum/disease/advance/A = new(FALSE, null)
A.symptoms = list()
var/list/datum/symptom/possible_symptoms = list()
for(var/symptom in subtypesof(/datum/symptom))
var/datum/symptom/S = symptom
if(initial(S.level) > max_level)
continue
if(initial(S.level) <= 0) //unobtainable symptoms
continue
possible_symptoms += S
for(var/i in 1 to max_symptoms)
var/datum/symptom/chosen_symptom = pick_n_take(possible_symptoms)
if(chosen_symptom)
var/datum/symptom/S = new chosen_symptom
A.symptoms += S
A.Refresh() //just in case someone already made and named the same disease
return A
+7
View File
@@ -45,19 +45,26 @@
to_chat(L, "<span class='warning'><B>You didn't get a date! They're all having fun without you! you'll show them though...</B></span>")
var/datum/objective/martyr/normiesgetout = new
normiesgetout.owner = L.mind
L.mind.special_role = "heartbreaker"
SSticker.mode.traitors |= L.mind
L.mind.objectives += normiesgetout
L.mind.add_antag_datum(/datum/antagonist/auto_custom)
/proc/forge_valentines_objective(mob/living/lover,mob/living/date)
SSticker.mode.traitors |= lover.mind
lover.mind.special_role = "valentine"
var/datum/objective/protect/protect_objective = new /datum/objective/protect
protect_objective.owner = lover.mind
protect_objective.target = date.mind
protect_objective.explanation_text = "Protect [date.real_name], your date."
lover.mind.objectives += protect_objective
lover.mind.add_antag_datum(/datum/antagonist/auto_custom)
to_chat(lover, "<span class='warning'><B>You're on a date with [date]! Protect them at all costs. This takes priority over all other loyalties.</B></span>")
+10 -47
View File
@@ -1,44 +1,3 @@
/datum/round_event_control/treevenge
name = "Treevenge (Christmas)"
holidayID = CHRISTMAS
typepath = /datum/round_event/treevenge
max_occurrences = 1
weight = 20
/datum/round_event/treevenge/start()
for(var/obj/structure/flora/tree/pine/xmas in world)
var/mob/living/simple_animal/hostile/tree/evil_tree = new /mob/living/simple_animal/hostile/tree(xmas.loc)
evil_tree.icon_state = xmas.icon_state
evil_tree.icon_living = evil_tree.icon_state
evil_tree.icon_dead = evil_tree.icon_state
evil_tree.icon_gib = evil_tree.icon_state
qdel(xmas) //b-but I don't want to delete xmas...
//this is an example of a possible round-start event
/datum/round_event_control/presents
name = "Presents under Trees (Christmas)"
holidayID = CHRISTMAS
typepath = /datum/round_event/presents
weight = -1 //forces it to be called, regardless of weight
max_occurrences = 1
earliest_start = 0
/datum/round_event/presents/start()
for(var/obj/structure/flora/tree/pine/xmas in world)
if(!(xmas.z in GLOB.station_z_levels))
continue
for(var/turf/open/floor/T in orange(1,xmas))
for(var/i=1,i<=rand(1,5),i++)
new /obj/item/a_gift(T)
for(var/mob/living/simple_animal/pet/dog/corgi/Ian/Ian in GLOB.mob_living_list)
Ian.place_on_head(new /obj/item/clothing/head/helmet/space/santahat(Ian))
for(var/obj/machinery/computer/security/telescreen/entertainment/Monitor in GLOB.machines)
Monitor.icon_state = "entertainment_xmas"
/datum/round_event/presents/announce(fake)
priority_announce("Ho Ho Ho, Merry Xmas!", "Unknown Transmission")
/obj/item/toy/xmas_cracker
name = "xmas cracker"
icon = 'icons/obj/christmas.dmi'
@@ -82,23 +41,27 @@
/obj/effect/landmark/xmastree
name = "christmas tree spawner"
var/tree = /obj/structure/flora/tree/pine/xmas
var/festive_tree = /obj/structure/flora/tree/pine/xmas
var/christmas_tree = /obj/structure/flora/tree/pine/xmas/presents
/obj/effect/landmark/xmastree/Initialize(mapload)
..()
if(FESTIVE_SEASON in SSevents.holidays)
new tree(get_turf(src))
if((CHRISTMAS in SSevents.holidays) && christmas_tree)
new christmas_tree(get_turf(src))
else if((FESTIVE_SEASON in SSevents.holidays) && festive_tree)
new festive_tree(get_turf(src))
return INITIALIZE_HINT_QDEL
/obj/effect/landmark/xmastree/rdrod
name = "festivus pole spawner"
tree = /obj/structure/festivus
festive_tree = /obj/structure/festivus
christmas_tree = null
/datum/round_event_control/santa
name = "Santa is coming to town! (Christmas)"
holidayID = CHRISTMAS
typepath = /datum/round_event/santa
weight = 150
weight = 20
max_occurrences = 1
earliest_start = 20000
@@ -109,7 +72,7 @@
priority_announce("Santa is coming to town!", "Unknown Transmission")
/datum/round_event/santa/start()
var/list/candidates = pollGhostCandidates("Santa is coming to town! Do you want to be santa?", poll_time=150)
var/list/candidates = pollGhostCandidates("Santa is coming to town! Do you want to be Santa?", poll_time=150)
if(LAZYLEN(candidates))
var/mob/dead/observer/Z = pick(candidates)
santa = new /mob/living/carbon/human(pick(GLOB.blobstart))
+37 -4
View File
@@ -12,6 +12,16 @@ In my current plan for it, 'solid' will be defined as anything with density == 1
typepath = /datum/round_event/immovable_rod
min_players = 15
max_occurrences = 5
var/atom/special_target
/datum/round_event_control/immovable_rod/admin_setup()
if(!check_rights(R_FUN))
return
var/aimed = alert("Aimed at current location?","Sniperod", "Yes", "No")
if(aimed == "Yes")
special_target = get_turf(usr)
/datum/round_event/immovable_rod
announceWhen = 5
@@ -20,10 +30,11 @@ In my current plan for it, 'solid' will be defined as anything with density == 1
priority_announce("What the fuck was that?!", "General Alert")
/datum/round_event/immovable_rod/start()
var/datum/round_event_control/immovable_rod/C = control
var/startside = pick(GLOB.cardinals)
var/turf/startT = spaceDebrisStartLoc(startside, ZLEVEL_STATION_PRIMARY)
var/turf/endT = spaceDebrisFinishLoc(startside, ZLEVEL_STATION_PRIMARY)
new /obj/effect/immovablerod(startT, endT)
new /obj/effect/immovablerod(startT, endT, C.special_target)
/obj/effect/immovablerod
name = "immovable rod"
@@ -36,18 +47,28 @@ In my current plan for it, 'solid' will be defined as anything with density == 1
var/z_original = 0
var/destination
var/notify = TRUE
var/atom/special_target
/obj/effect/immovablerod/New(atom/start, atom/end)
/obj/effect/immovablerod/New(atom/start, atom/end, aimed_at)
..()
SSaugury.register_doom(src, 2000)
z_original = z
destination = end
special_target = aimed_at
if(notify)
notify_ghosts("\A [src] is inbound!",
enter_link="<a href=?src=[REF(src)];orbit=1>(Click to orbit)</a>",
source=src, action=NOTIFY_ORBIT)
GLOB.poi_list += src
if(end && end.z==z_original)
var/special_target_valid = FALSE
if(special_target)
var/turf/T = get_turf(special_target)
if(T.z == z_original)
special_target_valid = TRUE
if(special_target_valid)
walk_towards(src, special_target, 1)
else if(end && end.z==z_original)
walk_towards(src, destination, 1)
/obj/effect/immovablerod/Topic(href, href_list)
@@ -60,11 +81,20 @@ In my current plan for it, 'solid' will be defined as anything with density == 1
GLOB.poi_list -= src
. = ..()
/obj/effect/immovablerod/Move()
/obj/effect/immovablerod/Moved()
if((z != z_original) || (loc == destination))
qdel(src)
if(special_target && loc == get_turf(special_target))
complete_trajectory()
return ..()
/obj/effect/immovablerod/proc/complete_trajectory()
//We hit what we wanted to hit, time to go
special_target = null
destination = get_edge_target_turf(src, dir)
walk(src,0)
walk_towards(src, destination, 1)
/obj/effect/immovablerod/ex_act(severity, target)
return 0
@@ -83,6 +113,9 @@ In my current plan for it, 'solid' will be defined as anything with density == 1
x = clong.x
y = clong.y
if(special_target && clong == special_target)
complete_trajectory()
if(isturf(clong) || isobj(clong))
if(clong.density)
clong.ex_act(EXPLODE_HEAVY)
+1 -1
View File
@@ -49,7 +49,7 @@
priority_announce("Meteors have been detected on collision course with the station.", "Meteor Alert", 'sound/ai/meteors.ogg')
/datum/round_event/meteor_wave/tick()
if(IsMultiple(activeFor, 3))
if(ISMULTIPLE(activeFor, 3))
spawn_meteors(5, wave_type) //meteor list types defined in gamemode/meteor/meteors.dm
/datum/round_event_control/meteor_wave/threatening
+1
View File
@@ -35,6 +35,7 @@
player_mind.assigned_role = "Nightmare"
player_mind.special_role = "Nightmare"
SSticker.mode.traitors += player_mind
player_mind.add_antag_datum(/datum/antagonist/auto_custom)
S.set_species(/datum/species/shadow/nightmare)
playsound(S, 'sound/magic/ethereal_exit.ogg', 50, 1, -1)
message_admins("[key_name_admin(S)] has been made into a Nightmare by an event.")
+1 -19
View File
@@ -27,31 +27,13 @@
A.copy_to(operative)
operative.dna.update_dna_identity()
operative.equipOutfit(/datum/outfit/syndicate/full)
var/datum/mind/Mind = new /datum/mind(selected.key)
Mind.assigned_role = "Lone Operative"
Mind.special_role = "Lone Operative"
SSticker.mode.traitors |= Mind
Mind.active = 1
var/obj/machinery/nuclearbomb/selfdestruct/nuke = locate() in GLOB.machines
if(nuke)
var/nuke_code
if(!nuke.r_code || nuke.r_code == "ADMIN")
nuke_code = random_nukecode()
nuke.r_code = nuke_code
else
nuke_code = nuke.r_code
Mind.store_memory("<B>Station Self-Destruct Device Code</B>: [nuke_code]", 0, 0)
to_chat(Mind.current, "The nuclear authorization code is: <B>[nuke_code]</B>")
var/datum/objective/nuclear/O = new()
O.owner = Mind
Mind.objectives += O
Mind.transfer_to(operative)
Mind.add_antag_datum(/datum/antagonist/nukeop/lone)
message_admins("[key_name_admin(operative)] has been made into lone operative by an event.")
log_game("[key_name(operative)] was spawned as a lone operative by an event.")
+1 -1
View File
@@ -206,7 +206,7 @@
if(engines_cooling)
return "[.] - Engines cooling."
/obj/docking_port/mobile/pirate/dock(obj/docking_port/stationary/new_dock, movement_direction, force=FALSE)
/obj/docking_port/mobile/pirate/initiate_docking(obj/docking_port/stationary/new_dock, movement_direction, force=FALSE)
. = ..()
if(. == DOCKING_SUCCESS && new_dock.z != ZLEVEL_TRANSIT)
engines_cooling = TRUE
+3 -3
View File
@@ -64,7 +64,7 @@
T = safepick(get_area_turfs(pick(station_areas)))
hostiles_spawn += T
next_boss_spawn = startWhen + Ceiling(2 * number_of_hostiles / number_of_bosses)
next_boss_spawn = startWhen + CEILING(2 * number_of_hostiles / number_of_bosses, 1)
/datum/round_event/portal_storm/announce(fake)
set waitfor = 0
@@ -117,14 +117,14 @@
/datum/round_event/portal_storm/proc/spawn_hostile()
if(!hostile_types || !hostile_types.len)
return 0
return IsMultiple(activeFor, 2)
return ISMULTIPLE(activeFor, 2)
/datum/round_event/portal_storm/proc/spawn_boss()
if(!boss_types || !boss_types.len)
return 0
if(activeFor == next_boss_spawn)
next_boss_spawn += Ceiling(number_of_hostiles / number_of_bosses)
next_boss_spawn += CEILING(number_of_hostiles / number_of_bosses, 1)
return 1
/datum/round_event/portal_storm/proc/time_to_end()
@@ -44,6 +44,7 @@
citizens += H
SSticker.mode.traitors += M
M.special_role = "separatist"
M.add_antag_datum(/datum/antagonist/auto_custom)
H.log_message("<font color='red'>Was made into a separatist, long live [nation]!</font>", INDIVIDUAL_ATTACK_LOG)
to_chat(H, "<B>You are a separatist! [nation] forever! Protect the sovereignty of your newfound land with your comrades in arms!</B>")
if(citizens.len)
+1
View File
@@ -67,6 +67,7 @@
O.completed = 1 //YES!
O.owner = new_holder.mind
new_holder.mind.objectives += O
new_holder.mind.add_antag_datum(/datum/antagonist/auto_custom)
new_holder.log_message("<font color='green'>Won with greentext!!!</font>", INDIVIDUAL_ATTACK_LOG)
color_altered_mobs -= new_holder
resistance_flags |= ON_FIRE
+1 -1
View File
@@ -12,7 +12,7 @@
for(var/speciestype in subtypesof(/datum/species))
var/datum/species/S = new speciestype()
if(!S.dangerous_existence)
if(!S.dangerous_existence && !S.blacklisted)
all_species += speciestype
var/datum/species/new_species = pick(all_species)
+13
View File
@@ -72,6 +72,9 @@
freeze_projectile(A)
else
return FALSE
into_the_negative_zone(A)
return TRUE
/datum/proximity_monitor/advanced/timestop/proc/unfreeze_all()
@@ -106,6 +109,7 @@
return ..()
/datum/proximity_monitor/advanced/timestop/proc/unfreeze_projectile(obj/item/projectile/P)
escape_the_negative_zone(P)
frozen_projectiles -= P
P.paused = FALSE
@@ -123,9 +127,18 @@
H.LoseTarget()
/datum/proximity_monitor/advanced/timestop/proc/unfreeze_mob(mob/living/L)
escape_the_negative_zone(L)
L.AdjustStun(-20, 1, 1)
L.anchored = frozen_mobs[L]
frozen_mobs -= L
if(ishostile(L))
var/mob/living/simple_animal/hostile/H = L
H.toggle_ai(initial(H.AIStatus))
//you don't look quite right, is something the matter?
/datum/proximity_monitor/advanced/timestop/proc/into_the_negative_zone(atom/A)
A.add_atom_colour(list(-1,0,0,0, 0,-1,0,0, 0,0,-1,0, 0,0,0,1, 1,1,1,0), TEMPORARY_COLOUR_PRIORITY)
//let's put some colour back into your cheeks
/datum/proximity_monitor/advanced/timestop/proc/escape_the_negative_zone(atom/A)
A.remove_atom_colour(TEMPORARY_COLOUR_PRIORITY)
+3
View File
@@ -80,6 +80,7 @@ GLOBAL_LIST_INIT(hallucinations_major, list(
/obj/effect/hallucination
invisibility = INVISIBILITY_OBSERVER
anchored = TRUE
var/mob/living/carbon/target = null
/obj/effect/hallucination/simple
@@ -713,6 +714,8 @@ GLOBAL_LIST_INIT(hallucinations_major, list(
for(var/obj/machinery/door/airlock/A in range(7, target))
if(count>door_number && door_number>0)
break
if(!A.density)
continue
count++
I = image(A.overlays_file, get_turf(A), "lights_bolts",layer=A.layer+0.1)
doors += I
+32 -30
View File
@@ -8,7 +8,7 @@
icon_state = null
lefthand_file = 'icons/mob/inhands/misc/food_lefthand.dmi'
righthand_file = 'icons/mob/inhands/misc/food_righthand.dmi'
container_type = OPENCONTAINER_1
container_type = OPENCONTAINER
var/gulp_size = 5 //This is now officially broken ... need to think of a nice way to fix it.
possible_transfer_amounts = list(5,10,15,20,25,30,50)
volume = 50
@@ -30,7 +30,7 @@
if(!canconsume(M, user))
return 0
if (!is_open_container())
if (!is_drainable())
to_chat(user, "<span class='warning'>[src]'s lid hasn't been opened!</span>")
return 0
@@ -44,7 +44,7 @@
if(!reagents || !reagents.total_volume)
return // The drink might be empty after the delay, such as by spam-feeding
M.visible_message("<span class='danger'>[user] feeds the contents of [src] to [M].</span>", "<span class='userdanger'>[user] feeds the contents of [src] to [M].</span>")
add_logs(user, M, "fed", reagentlist(src))
add_logs(user, M, "fed", reagents.log_list())
var/fraction = min(gulp_size/reagents.total_volume, 1)
checkLiked(fraction, M)
@@ -56,31 +56,16 @@
/obj/item/reagent_containers/food/drinks/afterattack(obj/target, mob/user , proximity)
if(!proximity)
return
if(istype(target, /obj/structure/reagent_dispensers)) //A dispenser. Transfer FROM it TO us.
if (!is_open_container())
to_chat(user, "<span class='warning'>[target]'s tab isn't open!</span>")
return
if(!target.reagents.total_volume)
to_chat(user, "<span class='warning'>[target] is empty.</span>")
return
if(reagents.total_volume >= reagents.maximum_volume)
to_chat(user, "<span class='warning'>[src] is full.</span>")
return
var/trans = target.reagents.trans_to(src, amount_per_transfer_from_this)
to_chat(user, "<span class='notice'>You fill [src] with [trans] units of the contents of [target].</span>")
else if(target.is_open_container()) //Something like a glass. Player probably wants to transfer TO it.
if(target.is_refillable()) //Something like a glass. Player probably wants to transfer TO it.
if(!reagents.total_volume)
to_chat(user, "<span class='warning'>[src] is empty.</span>")
return
if(target.reagents.total_volume >= target.reagents.maximum_volume)
if(target.reagents.holder_full())
to_chat(user, "<span class='warning'>[target] is full.</span>")
return
var/refill = reagents.get_master_reagent_id()
var/trans = src.reagents.trans_to(target, amount_per_transfer_from_this)
to_chat(user, "<span class='notice'>You transfer [trans] units of the solution to [target].</span>")
@@ -90,13 +75,29 @@
bro.cell.use(30)
addtimer(CALLBACK(reagents, /datum/reagents.proc/add_reagent, refill, trans), 600)
else if(target.is_drainable()) //A dispenser. Transfer FROM it TO us.
if (!is_refillable())
to_chat(user, "<span class='warning'>[src]'s tab isn't open!</span>")
return
if(!target.reagents.total_volume)
to_chat(user, "<span class='warning'>[target] is empty.</span>")
return
if(reagents.holder_full())
to_chat(user, "<span class='warning'>[src] is full.</span>")
return
var/trans = target.reagents.trans_to(src, amount_per_transfer_from_this)
to_chat(user, "<span class='notice'>You fill [src] with [trans] units of the contents of [target].</span>")
else
/obj/item/reagent_containers/food/drinks/attackby(obj/item/I, mob/user, params)
if(I.is_hot())
var/added_heat = (I.is_hot() / 100) //ishot returns a temperature
if(reagents)
reagents.chem_temp += added_heat
to_chat(user, "<span class='notice'>You heat [src] with [I].</span>")
reagents.handle_reactions()
var/hotness = I.is_hot()
if(hotness && reagents)
reagents.expose_temperature(hotness)
to_chat(user, "<span class='notice'>You heat [name] with [I]!</span>")
..()
/obj/item/reagent_containers/food/drinks/throw_impact(atom/target, mob/thrower)
@@ -142,7 +143,7 @@
possible_transfer_amounts = list()
volume = 5
flags_1 = CONDUCT_1
container_type = OPENCONTAINER_1
container_type = OPENCONTAINER
spillable = TRUE
resistance_flags = FIRE_PROOF
isGlass = FALSE
@@ -393,6 +394,7 @@
container_type = NONE
spillable = FALSE
isGlass = FALSE
grind_results = list("aluminum" = 10)
/obj/item/reagent_containers/food/drinks/soda_cans/attack(mob/M, mob/user)
if(M == user && !src.reagents.total_volume && user.a_intent == INTENT_HARM && user.zone_selected == "head")
@@ -405,9 +407,9 @@
/obj/item/reagent_containers/food/drinks/soda_cans/attack_self(mob/user)
if(!is_open_container())
if(!is_drainable())
to_chat(user, "You pull back the tab of \the [src] with a satisfying pop.") //Ahhhhhhhh
container_type = OPENCONTAINER_1
container_type = OPENCONTAINER
playsound(src, "can_open", 50, 1)
spillable = TRUE
return
+1 -1
View File
@@ -4,7 +4,7 @@
/obj/item/reagent_containers/food
possible_transfer_amounts = list()
volume = 50 //Sets the default container amount for all food items.
container_type = INJECTABLE_1
container_type = INJECTABLE
resistance_flags = FLAMMABLE
var/foodtype = NONE
var/last_check_time
@@ -10,7 +10,7 @@
desc = "Just your average condiment container."
icon = 'icons/obj/food/containers.dmi'
icon_state = "emptycondiment"
container_type = OPENCONTAINER_1
container_type = OPENCONTAINER
possible_transfer_amounts = list(1, 5, 10, 15, 20, 25, 30, 50)
volume = 50
//Possible_states has the reagent id as key and a list of, in order, the icon_state, the name and the desc as values. Used in the on_reagent_change(changetype) to change names, descs and sprites.
@@ -45,7 +45,7 @@
if(!reagents || !reagents.total_volume)
return // The condiment might be empty after the delay.
user.visible_message("<span class='warning'>[user] feeds [M] from [src].</span>")
add_logs(user, M, "fed", reagentlist(src))
add_logs(user, M, "fed", reagents.log_list())
var/fraction = min(10/reagents.total_volume, 1)
reagents.reaction(M, INGEST, fraction)
@@ -70,7 +70,7 @@
to_chat(user, "<span class='notice'>You fill [src] with [trans] units of the contents of [target].</span>")
//Something like a glass or a food item. Player probably wants to transfer TO it.
else if(target.is_open_container() || istype(target, /obj/item/reagent_containers/food/snacks))
else if(target.is_drainable() || istype(target, /obj/item/reagent_containers/food/snacks))
if(!reagents.total_volume)
to_chat(user, "<span class='warning'>[src] is empty!</span>")
return
@@ -291,7 +291,7 @@
desc = "A simple bowl, used for soups and salads."
icon = 'icons/obj/food/soupsalad.dmi'
icon_state = "bowl"
container_type = OPENCONTAINER_1
container_type = OPENCONTAINER
materials = list(MAT_GLASS = 500)
w_class = WEIGHT_CLASS_NORMAL
+2 -1
View File
@@ -6,6 +6,7 @@
lefthand_file = 'icons/mob/inhands/misc/food_lefthand.dmi'
righthand_file = 'icons/mob/inhands/misc/food_righthand.dmi'
unique_rename = 1
grind_results = list() //To let them be ground up to transfer their reagents
var/bitesize = 2
var/bitecount = 0
var/trash = null
@@ -93,7 +94,7 @@
if(!do_mob(user, M))
return
add_logs(user, M, "fed", reagentlist(src))
add_logs(user, M, "fed", reagents.log_list())
M.visible_message("<span class='danger'>[user] forces [M] to eat [src].</span>", \
"<span class='userdanger'>[user] forces [M] to eat [src].</span>")
@@ -20,6 +20,7 @@
filling_color = "#F0E68C"
tastes = list("egg" = 1)
foodtype = MEAT
grind_results = list("eggyolk" = 5)
/obj/item/reagent_containers/food/snacks/egg/throw_impact(atom/hit_atom)
if(!..()) //was it caught by a mob?
@@ -28,6 +28,7 @@
filling_color = "#FF1493"
tastes = list("watermelon" = 1)
foodtype = FRUIT
juice_results = list("watermelonjuice" = 5)
/obj/item/reagent_containers/food/snacks/candy_corn
name = "candy corn"
@@ -29,7 +29,7 @@ God bless America.
anchored = TRUE
use_power = IDLE_POWER_USE
idle_power_usage = 5
container_type = OPENCONTAINER_1
container_type = OPENCONTAINER
var/obj/item/reagent_containers/food/snacks/deepfryholder/frying //What's being fried RIGHT NOW?
var/cook_time = 0
var/oil_use = 0.05 //How much cooking oil is used per tick
@@ -15,7 +15,7 @@
var/portion = 10
var/selected_drink
var/list/stored_food = list()
container_type = OPENCONTAINER_1
container_type = OPENCONTAINER
var/obj/item/reagent_containers/mixer
/obj/machinery/food_cart/Initialize()
@@ -100,7 +100,7 @@
stored_food[sanitize(S.name)]++
else
stored_food[sanitize(S.name)] = 1
else if(O.is_open_container())
else if(O.is_drainable())
return
else
. = ..()
@@ -123,7 +123,7 @@
break
if(href_list["portion"])
portion = Clamp(input("How much drink do you want to dispense per glass?") as num, 0, 50)
portion = CLAMP(input("How much drink do you want to dispense per glass?") as num, 0, 50)
if(href_list["pour"] || href_list["m_pour"])
if(glasses-- <= 0)
@@ -14,7 +14,7 @@
anchored = FALSE
use_power = NO_POWER_USE
layer = BELOW_OBJ_LAYER
container_type = OPENCONTAINER_1
container_type = OPENCONTAINER
max_integrity = 300
var/list/product_types = list()
var/dispense_flavour = ICECREAM_VANILLA
@@ -112,7 +112,7 @@
else
to_chat(user, "<span class='notice'>[O] already has ice cream in it.</span>")
return 1
else if(O.is_open_container())
else if(O.is_drainable())
return
else
return ..()
@@ -81,7 +81,7 @@
src.icon_state = "mw"
src.broken = 0 // Fix it!
src.dirty = 0 // just to be sure
src.container_type = OPENCONTAINER_1
src.container_type = OPENCONTAINER
return 0 //to use some fuel
else
to_chat(user, "<span class='warning'>It's broken!</span>")
@@ -98,7 +98,7 @@
src.dirty = 0 // It's clean!
src.broken = 0 // just to be sure
src.icon_state = "mw"
src.container_type = OPENCONTAINER_1
src.container_type = OPENCONTAINER
src.updateUsrDialog()
return 1 // Disables the after-attack so we don't spray the floor/user.
else
@@ -119,7 +119,7 @@
src.dirty = 0 // It's clean!
src.broken = 0 // just to be sure
src.icon_state = "mw"
src.container_type = OPENCONTAINER_1
src.container_type = OPENCONTAINER
else if(src.dirty==100) // The microwave is all dirty so can't be used!
to_chat(user, "<span class='warning'>It's dirty!</span>")
@@ -277,9 +277,9 @@
operating = FALSE // Turn it off again aferwards
icon_state = "mw"
updateUsrDialog()
soundloop.stop()
/obj/machinery/microwave/proc/stop()
soundloop.stop()
abort()
/obj/machinery/microwave/proc/dispose()
@@ -293,7 +293,6 @@
icon_state = "mwbloody1" // Make it look dirty!!
/obj/machinery/microwave/proc/muck_finish()
playsound(src.loc, 'sound/machines/ding.ogg', 50, 1)
visible_message("<span class='warning'>The microwave gets covered in muck!</span>")
dirty = 100 // Make it dirty so it can't be used util cleaned
icon_state = "mwbloody" // Make it look dirty too
@@ -303,6 +302,7 @@
if(prob(50))
new /obj/item/reagent_containers/food/snacks/badrecipe(src)
qdel(S)
soundloop.stop()
/obj/machinery/microwave/proc/broke()
var/datum/effect_system/spark_spread/s = new
@@ -314,6 +314,7 @@
flags_1 = null //So you can't add condiments
operating = FALSE // Turn it off again aferwards
updateUsrDialog()
soundloop.stop()
/obj/machinery/microwave/Topic(href, href_list)
if(..() || panel_open)
+1 -1
View File
@@ -124,7 +124,7 @@
return
else
bomb_timer = input(user, "Set the [bomb] timer from [BOMB_TIMER_MIN] to [BOMB_TIMER_MAX].", bomb, bomb_timer) as num
bomb_timer = Clamp(Ceiling(bomb_timer / 2), BOMB_TIMER_MIN, BOMB_TIMER_MAX)
bomb_timer = CLAMP(CEILING(bomb_timer / 2, 1), BOMB_TIMER_MIN, BOMB_TIMER_MAX)
bomb_defused = FALSE
var/message = "[ADMIN_LOOKUPFLW(user)] has trapped a [src] with [bomb] set to [bomb_timer * 2] seconds."
+1 -1
View File
@@ -187,7 +187,7 @@
ASSERT(H)
usr.visible_message("\The [usr] plays \the [card.name].")
H.loc = get_step(usr,usr.dir)
H.forceMove(get_step(usr,usr.dir))
src.update_icon()
+1 -1
View File
@@ -132,7 +132,7 @@ GLOBAL_DATUM_INIT(iconCache, /savefile, new("data/iconCache.sav")) //Cache of ic
/datum/chatOutput/proc/setMusicVolume(volume = "")
if(volume)
adminMusicVolume = Clamp(text2num(volume), 0, 100)
adminMusicVolume = CLAMP(text2num(volume), 0, 100)
//Sends client connection details to the chat to handle and save
/datum/chatOutput/proc/sendClientData()
@@ -13,7 +13,7 @@ body {
background: #fff;
font-family: Verdana, sans-serif;
font-size: 9pt;
line-height: 1.4;
line-height: 1.2;
overflow-x: hidden;
overflow-y: scroll;
word-wrap: break-word;
@@ -38,6 +38,19 @@ img.icon {
vertical-align: bottom;
}
.r:before { /* "repeated" badge class for combined messages */
content: 'x';
}
.r {
display: inline;
padding: .2em .6em .3em;
font-size: 75%;
font-weight: 700;
line-height: 1;
color: #f00;
}
a {color: #0000ff;}
a.visited {color: #ff00ff;}
a:visited {color: #ff00ff;}
@@ -377,6 +390,7 @@ h1.alert, h2.alert {color: #000000;}
.memo {color: #638500; text-align: center;}
.memoedit {text-align: center; font-size: 16px;}
.abductor {color: #800080; font-style: italic;}
.mind_control {color: #A00D6F; font-size: 3; font-weight: bold; font-style: italic;}
.slime {color: #00CED1;}
.drone {color: #848482;}
.monkey {color: #975032;}
@@ -36,9 +36,12 @@
<div class="sub" id="subOptions">
<a href="#" class="subCell decreaseFont topCell" id="decreaseFont"><span>Decrease font size</span> <i class="icon-font">-</i></a>
<a href="#" class="subCell increaseFont" id="increaseFont"><span>Increase font size</span> <i class="icon-font">+</i></a>
<a href="#" class="subCell decreaseLineHeight" id="decreaseLineHeight"><span>Decrease line height</span> <i class="icon-text-height">-</i></a>
<a href="#" class="subCell increaseLineHeight" id="increaseLineHeight"><span>Increase line height</span> <i class="icon-text-height">+</i></a>
<a href="#" class="subCell togglePing" id="togglePing"><span>Toggle ping display</span> <i class="icon-circle"></i></a>
<a href="#" class="subCell highlightTerm" id="highlightTerm"><span>Highlight string</span> <i class="icon-tag"></i></a>
<a href="#" class="subCell saveLog" id="saveLog"><span>Save chat log</span> <i class="icon-save"></i></a>
<a href="#" class="subCell toggleCombine" id="toggleCombine"><span>Toggle line combining</span> <i class="icon-filter"></i></a>
<a href="#" class="subCell clearMessages" id="clearMessages"><span>Clear all messages</span> <i class="icon-eraser"></i></a>
</div>
<div class="sub" id="subAudio">
@@ -22,7 +22,7 @@ window.onerror = function(msg, url, line, col, error) {
//Globals
window.status = 'Output';
var $messages, $subOptions, $subAudio, $selectedSub, $contextMenu, $filterMessages;
var $messages, $subOptions, $subAudio, $selectedSub, $contextMenu, $filterMessages, $last_message;
var opts = {
//General
'messageCount': 0, //A count...of messages...
@@ -68,6 +68,8 @@ var opts = {
'defaultMusicVolume': 25,
'messageCombining': true,
};
function clamp(val, min, max) {
@@ -294,27 +296,54 @@ function output(message, flag) {
opts.messageCount--; //I guess the count should only ever equal the limit
}
//Actually append the message
var entry = document.createElement('div');
entry.className = 'entry';
if (filteredOut) {
entry.className += ' hidden';
entry.setAttribute('data-filter', filteredOut);
var handled = false;
var trimmed_message = message.trim()
var lastmessages = $messages.children('div.entry:last-child');
if (opts.messageCombining && lastmessages.length && $last_message)
{
if($last_message == trimmed_message)
{
if(lastmessages.children('span.r').length)
{
var current_value = parseInt(lastmessages.children('span.r').text())
lastmessages.children('span.r').text(current_value+1)
}
else
{
lastmessages.append($('<span/>', { 'class': 'r', 'text': 2}));
}
if(parseInt(lastmessages.css("font-size")) < 24) //Completely arbitrary max size
lastmessages.css("font-size","+=2")
opts.messageCount--;
handled = true;
}
}
if(!handled)
{
//Actually append the message
var entry = document.createElement('div');
entry.className = 'entry';
if (filteredOut) {
entry.className += ' hidden';
entry.setAttribute('data-filter', filteredOut);
}
$last_message = trimmed_message;
entry.innerHTML = trimmed_message;
$messages[0].appendChild(entry);
$(entry).find("img.icon").error(iconError);
//Actually do the snap
//Stuff we can do after the message shows can go here, in the interests of responsiveness
if (opts.highlightTerms && opts.highlightTerms.length > 0) {
highlightTerms(entry);
}
}
entry.innerHTML = message.trim();
$messages[0].appendChild(entry);
$(entry).find("img.icon").error(iconError);
//Actually do the snap
if (!filteredOut && atBottom) {
$('body,html').scrollTop($messages.outerHeight());
}
//Stuff we can do after the message shows can go here, in the interests of responsiveness
if (opts.highlightTerms && opts.highlightTerms.length > 0) {
highlightTerms(entry);
}
}
function internalOutput(message, flag)
@@ -564,16 +593,22 @@ $(function() {
******************************************/
var savedConfig = {
'sfontSize': getCookie('fontsize'),
'slineHeight': getCookie('lineheight'),
'spingDisabled': getCookie('pingdisabled'),
'shighlightTerms': getCookie('highlightterms'),
'shighlightColor': getCookie('highlightcolor'),
'smusicVolume': getCookie('musicVolume'),
'smessagecombining': getCookie('messagecombining'),
};
if (savedConfig.sfontSize) {
$messages.css('font-size', savedConfig.sfontSize);
internalOutput('<span class="internal boldnshit">Loaded font size setting of: '+savedConfig.sfontSize+'</span>', 'internal');
}
if (savedConfig.slineHeight) {
$("body").css('line-height', savedConfig.slineHeight);
internalOutput('<span class="internal boldnshit">Loaded line height setting of: '+savedConfig.slineHeight+'</span>', 'internal');
}
if (savedConfig.spingDisabled) {
if (savedConfig.spingDisabled == 'true') {
opts.pingDisabled = true;
@@ -606,9 +641,19 @@ $(function() {
opts.updatedVolume = newVolume;
sendVolumeUpdate();
internalOutput('<span class="internal boldnshit">Loaded music volume of: '+savedConfig.smusicVolume+'</span>', 'internal');
} else {
}
else{
$('#adminMusic').prop('volume', opts.defaultMusicVolume / 100);
}
if (savedConfig.smessagecombining) {
if (savedConfig.smessagecombining == 'false') {
opts.messageCombining = false;
} else {
opts.messageCombining = true;
}
}
(function() {
var dataCookie = getCookie('connData');
@@ -805,6 +850,28 @@ $(function() {
internalOutput('<span class="internal boldnshit">Font size set to '+fontSize+'</span>', 'internal');
});
$('#decreaseLineHeight').click(function(e) {
var Heightline = parseFloat($("body").css('line-height'));
var Sizefont = parseFloat($("body").css('font-size'));
var lineheightvar = Heightline / Sizefont
lineheightvar -= 0.1;
lineheightvar = lineheightvar.toFixed(1)
$("body").css({'line-height': lineheightvar});
setCookie('lineheight', lineheightvar, 365);
internalOutput('<span class="internal boldnshit">Line height set to '+lineheightvar+'</span>', 'internal');
});
$('#increaseLineHeight').click(function(e) {
var Heightline = parseFloat($("body").css('line-height'));
var Sizefont = parseFloat($("body").css('font-size'));
var lineheightvar = Heightline / Sizefont
lineheightvar += 0.1;
lineheightvar = lineheightvar.toFixed(1)
$("body").css({'line-height': lineheightvar});
setCookie('lineheight', lineheightvar, 365);
internalOutput('<span class="internal boldnshit">Line height set to '+lineheightvar+'</span>', 'internal');
});
$('#togglePing').click(function(e) {
if (opts.pingDisabled) {
$('#ping').slideDown('fast');
@@ -922,6 +989,11 @@ $(function() {
}
});
$('#toggleCombine').click(function(e) {
opts.messageCombining = !opts.messageCombining;
setCookie('messagecombining', (opts.messageCombining ? 'true' : 'false'), 365);
});
$('img.icon').error(iconError);

Some files were not shown because too many files have changed in this diff Show More