Merge conflict solved(?)

This commit is contained in:
Luca
2020-06-14 01:50:07 +10:00
2297 changed files with 218601 additions and 293365 deletions
File diff suppressed because it is too large Load Diff
+4 -4
View File
@@ -25,13 +25,13 @@ world/IsBanned(key, address, computer_id, type, check_ipintel = TRUE)
if (C && ckey == C.ckey && computer_id == C.computer_id && address == C.address)
return //don't recheck connected clients.
if((ckey in admin_datums) || (ckey in GLOB.deadmins))
var/datum/admins/A = admin_datums[ckey]
if((ckey in GLOB.admin_datums) || (ckey in GLOB.deadmins))
var/datum/admins/A = GLOB.admin_datums[ckey]
if(A && (A.rights & R_ADMIN))
admin = 1
//Guest Checking
if(!guests_allowed && IsGuestKey(key))
if(!GLOB.guests_allowed && IsGuestKey(key))
log_adminwarn("Failed Login: [key] [computer_id] [address] - Guests not allowed")
// message_admins("<span class='notice'>Failed Login: [key] - Guests not allowed</span>")
return list("reason"="guest", "desc"="\nReason: Guests not allowed. Please sign in with a BYOND account.")
@@ -82,7 +82,7 @@ world/IsBanned(key, address, computer_id, type, check_ipintel = TRUE)
if(computer_id)
cidquery = " OR computerid = '[computer_id]' "
var/DBQuery/query = dbcon.NewQuery("SELECT ckey, ip, computerid, a_ckey, reason, expiration_time, duration, bantime, bantype FROM [format_table_name("ban")] WHERE (ckey = '[ckeytext]' [ipquery] [cidquery]) AND (bantype = 'PERMABAN' OR bantype = 'ADMIN_PERMABAN' OR ((bantype = 'TEMPBAN' OR bantype = 'ADMIN_TEMPBAN') AND expiration_time > Now())) AND isnull(unbanned)")
var/DBQuery/query = GLOB.dbcon.NewQuery("SELECT ckey, ip, computerid, a_ckey, reason, expiration_time, duration, bantime, bantype FROM [format_table_name("ban")] WHERE (ckey = '[ckeytext]' [ipquery] [cidquery]) AND (bantype = 'PERMABAN' OR bantype = 'ADMIN_PERMABAN' OR ((bantype = 'TEMPBAN' OR bantype = 'ADMIN_TEMPBAN') AND expiration_time > Now())) AND isnull(unbanned)")
query.Execute()
+232 -232
View File
@@ -1,232 +1,232 @@
var/CMinutes = null
var/savefile/Banlist
/proc/CheckBan(var/ckey, var/id, var/address)
if(!Banlist) // if Banlist cannot be located for some reason
LoadBans() // try to load the bans
if(!Banlist) // uh oh, can't find bans!
return 0 // ABORT ABORT ABORT
. = list()
var/appeal
if(config && config.banappeals)
appeal = "\nFor more information on your ban, or to appeal, head to <a href='[config.banappeals]'>[config.banappeals]</a>"
Banlist.cd = "/base"
if( "[ckey][id]" in Banlist.dir )
Banlist.cd = "[ckey][id]"
if(Banlist["temp"])
if(!GetExp(Banlist["minutes"]))
ClearTempbans()
return 0
else
.["desc"] = "\nReason: [Banlist["reason"]]\nExpires: [GetExp(Banlist["minutes"])]\nBy: [Banlist["bannedby"]][appeal]"
else
Banlist.cd = "/base/[ckey][id]"
.["desc"] = "\nReason: [Banlist["reason"]]\nExpires: <B>PERMENANT</B>\nBy: [Banlist["bannedby"]][appeal]"
.["reason"] = "ckey/id"
return .
else
for(var/A in Banlist.dir)
Banlist.cd = "/base/[A]"
var/matches
if( ckey == Banlist["key"] )
matches += "ckey"
if( id == Banlist["id"] )
if(matches)
matches += "/"
matches += "id"
if( address == Banlist["ip"] )
if(matches)
matches += "/"
matches += "ip"
if(matches)
if(Banlist["temp"])
if(!GetExp(Banlist["minutes"]))
ClearTempbans()
return 0
else
.["desc"] = "\nReason: [Banlist["reason"]]\nExpires: [GetExp(Banlist["minutes"])]\nBy: [Banlist["bannedby"]][appeal]"
else
.["desc"] = "\nReason: [Banlist["reason"]]\nExpires: <B>PERMENANT</B>\nBy: [Banlist["bannedby"]][appeal]"
.["reason"] = matches
return .
return 0
/proc/UpdateTime() //No idea why i made this a proc.
CMinutes = (world.realtime / 10) / 60
return 1
/hook/startup/proc/loadBans()
return LoadBans()
/proc/LoadBans()
Banlist = new("data/banlist.bdb")
log_admin("Loading Banlist")
if(!length(Banlist.dir)) log_admin("Banlist is empty.")
if(!Banlist.dir.Find("base"))
log_admin("Banlist missing base dir.")
Banlist.dir.Add("base")
Banlist.cd = "/base"
else if(Banlist.dir.Find("base"))
Banlist.cd = "/base"
ClearTempbans()
return 1
/proc/ClearTempbans()
UpdateTime()
Banlist.cd = "/base"
for(var/A in Banlist.dir)
Banlist.cd = "/base/[A]"
if(!Banlist["key"] || !Banlist["id"])
RemoveBan(A)
log_admin("Invalid Ban.")
message_admins("Invalid Ban.")
continue
if(!Banlist["temp"]) continue
if(CMinutes >= Banlist["minutes"]) RemoveBan(A)
return 1
/proc/AddBan(ckey, computerid, reason, bannedby, temp, minutes, address)
var/bantimestamp
if(temp)
UpdateTime()
bantimestamp = CMinutes + minutes
Banlist.cd = "/base"
if( Banlist.dir.Find("[ckey][computerid]") )
to_chat(usr, "<span class='danger'>Ban already exists.</span>")
return 0
else
Banlist.dir.Add("[ckey][computerid]")
Banlist.cd = "/base/[ckey][computerid]"
Banlist["key"] << ckey
Banlist["id"] << computerid
Banlist["ip"] << address
Banlist["reason"] << reason
Banlist["bannedby"] << bannedby
Banlist["temp"] << temp
if(temp)
Banlist["minutes"] << bantimestamp
if(!temp)
add_note(ckey, "Permanently banned - [reason]", null, bannedby, 0)
else
add_note(ckey, "Banned for [minutes] minutes - [reason]", null, bannedby, 0)
return 1
/proc/RemoveBan(foldername)
var/key
var/id
Banlist.cd = "/base/[foldername]"
Banlist["key"] >> key
Banlist["id"] >> id
Banlist.cd = "/base"
if(!Banlist.dir.Remove(foldername)) return 0
if(!usr)
log_admin("Ban Expired: [key]")
message_admins("Ban Expired: [key]")
else
ban_unban_log_save("[key_name_admin(usr)] unbanned [key]")
log_admin("[key_name_admin(usr)] unbanned [key]")
message_admins("[key_name_admin(usr)] unbanned: [key]")
feedback_inc("ban_unban",1)
usr.client.holder.DB_ban_unban( ckey(key), BANTYPE_ANY_FULLBAN)
for(var/A in Banlist.dir)
Banlist.cd = "/base/[A]"
if(key == Banlist["key"] /*|| id == Banlist["id"]*/)
Banlist.cd = "/base"
Banlist.dir.Remove(A)
continue
return 1
/proc/GetExp(minutes as num)
UpdateTime()
var/exp = minutes - CMinutes
if(exp <= 0)
return 0
else
var/timeleftstring
if(exp >= 1440) //1440 = 1 day in minutes
timeleftstring = "[round(exp / 1440, 0.1)] Days"
else if(exp >= 60) //60 = 1 hour in minutes
timeleftstring = "[round(exp / 60, 0.1)] Hours"
else
timeleftstring = "[exp] Minutes"
return timeleftstring
/datum/admins/proc/unbanpanel()
var/count = 0
var/dat
Banlist.cd = "/base"
for(var/A in Banlist.dir)
count++
Banlist.cd = "/base/[A]"
var/ref = UID()
var/key = Banlist["key"]
var/id = Banlist["id"]
var/ip = Banlist["ip"]
var/reason = Banlist["reason"]
var/by = Banlist["bannedby"]
var/expiry
if(Banlist["temp"])
expiry = GetExp(Banlist["minutes"])
if(!expiry) expiry = "Removal Pending"
else expiry = "Permaban"
dat += text("<tr><td><A href='?src=[ref];unbanf=[key][id]'>(U)</A><A href='?src=[ref];unbane=[key][id]'>(E)</A> Key: <B>[key]</B></td><td>ComputerID: <B>[id]</B></td><td>IP: <B>[ip]</B></td><td> [expiry]</td><td>(By: [by])</td><td>(Reason: [reason])</td></tr>")
dat += "</table>"
dat = "<HR><B>Bans:</B> <FONT COLOR=blue>(U) = Unban , (E) = Edit Ban</FONT> - <FONT COLOR=green>([count] Bans)</FONT><HR><table border=1 rules=all frame=void cellspacing=0 cellpadding=3 >[dat]"
usr << browse(dat, "window=unbanp;size=875x400")
//////////////////////////////////// DEBUG ////////////////////////////////////
/proc/CreateBans()
UpdateTime()
var/i
var/last
for(i=0, i<1001, i++)
var/a = pick(1,0)
var/b = pick(1,0)
if(b)
Banlist.cd = "/base"
Banlist.dir.Add("trash[i]trashid[i]")
Banlist.cd = "/base/trash[i]trashid[i]"
Banlist["key"] << "trash[i]"
else
Banlist.cd = "/base"
Banlist.dir.Add("[last]trashid[i]")
Banlist.cd = "/base/[last]trashid[i]"
Banlist["key"] << last
Banlist["id"] << "trashid[i]"
Banlist["reason"] << "Trashban[i]."
Banlist["temp"] << a
Banlist["minutes"] << CMinutes + rand(1,2000)
Banlist["bannedby"] << "trashmin"
last = "trash[i]"
Banlist.cd = "/base"
/proc/ClearAllBans()
Banlist.cd = "/base"
for(var/A in Banlist.dir)
RemoveBan(A)
GLOBAL_VAR(CMinutes)
GLOBAL_DATUM(banlist_savefile, /savefile)
GLOBAL_PROTECT(banlist_savefile) // Obvious reasons
/proc/CheckBan(var/ckey, var/id, var/address)
if(!GLOB.banlist_savefile) // if banlist_savefile cannot be located for some reason
LoadBans() // try to load the bans
if(!GLOB.banlist_savefile) // uh oh, can't find bans!
return 0 // ABORT ABORT ABORT
. = list()
var/appeal
if(config && config.banappeals)
appeal = "\nFor more information on your ban, or to appeal, head to <a href='[config.banappeals]'>[config.banappeals]</a>"
GLOB.banlist_savefile.cd = "/base"
if( "[ckey][id]" in GLOB.banlist_savefile.dir )
GLOB.banlist_savefile.cd = "[ckey][id]"
if(GLOB.banlist_savefile["temp"])
if(!GetExp(GLOB.banlist_savefile["minutes"]))
ClearTempbans()
return 0
else
.["desc"] = "\nReason: [GLOB.banlist_savefile["reason"]]\nExpires: [GetExp(GLOB.banlist_savefile["minutes"])]\nBy: [GLOB.banlist_savefile["bannedby"]][appeal]"
else
GLOB.banlist_savefile.cd = "/base/[ckey][id]"
.["desc"] = "\nReason: [GLOB.banlist_savefile["reason"]]\nExpires: <B>PERMENANT</B>\nBy: [GLOB.banlist_savefile["bannedby"]][appeal]"
.["reason"] = "ckey/id"
return .
else
for(var/A in GLOB.banlist_savefile.dir)
GLOB.banlist_savefile.cd = "/base/[A]"
var/matches
if( ckey == GLOB.banlist_savefile["key"] )
matches += "ckey"
if( id == GLOB.banlist_savefile["id"] )
if(matches)
matches += "/"
matches += "id"
if( address == GLOB.banlist_savefile["ip"] )
if(matches)
matches += "/"
matches += "ip"
if(matches)
if(GLOB.banlist_savefile["temp"])
if(!GetExp(GLOB.banlist_savefile["minutes"]))
ClearTempbans()
return 0
else
.["desc"] = "\nReason: [GLOB.banlist_savefile["reason"]]\nExpires: [GetExp(GLOB.banlist_savefile["minutes"])]\nBy: [GLOB.banlist_savefile["bannedby"]][appeal]"
else
.["desc"] = "\nReason: [GLOB.banlist_savefile["reason"]]\nExpires: <B>PERMENANT</B>\nBy: [GLOB.banlist_savefile["bannedby"]][appeal]"
.["reason"] = matches
return .
return 0
/proc/UpdateTime() //No idea why i made this a proc.
GLOB.CMinutes = (world.realtime / 10) / 60
return 1
/hook/startup/proc/loadBans()
return LoadBans()
/proc/LoadBans()
GLOB.banlist_savefile = new("data/banlist.bdb")
log_admin("Loading Banlist")
if(!length(GLOB.banlist_savefile.dir)) log_admin("Banlist is empty.")
if(!GLOB.banlist_savefile.dir.Find("base"))
log_admin("Banlist missing base dir.")
GLOB.banlist_savefile.dir.Add("base")
GLOB.banlist_savefile.cd = "/base"
else if(GLOB.banlist_savefile.dir.Find("base"))
GLOB.banlist_savefile.cd = "/base"
ClearTempbans()
return 1
/proc/ClearTempbans()
UpdateTime()
GLOB.banlist_savefile.cd = "/base"
for(var/A in GLOB.banlist_savefile.dir)
GLOB.banlist_savefile.cd = "/base/[A]"
if(!GLOB.banlist_savefile["key"] || !GLOB.banlist_savefile["id"])
RemoveBan(A)
log_admin("Invalid Ban.")
message_admins("Invalid Ban.")
continue
if(!GLOB.banlist_savefile["temp"]) continue
if(GLOB.CMinutes >= GLOB.banlist_savefile["minutes"]) RemoveBan(A)
return 1
/proc/AddBan(ckey, computerid, reason, bannedby, temp, minutes, address)
var/bantimestamp
if(temp)
UpdateTime()
bantimestamp = GLOB.CMinutes + minutes
GLOB.banlist_savefile.cd = "/base"
if( GLOB.banlist_savefile.dir.Find("[ckey][computerid]") )
to_chat(usr, "<span class='danger'>Ban already exists.</span>")
return 0
else
GLOB.banlist_savefile.dir.Add("[ckey][computerid]")
GLOB.banlist_savefile.cd = "/base/[ckey][computerid]"
GLOB.banlist_savefile["key"] << ckey
GLOB.banlist_savefile["id"] << computerid
GLOB.banlist_savefile["ip"] << address
GLOB.banlist_savefile["reason"] << reason
GLOB.banlist_savefile["bannedby"] << bannedby
GLOB.banlist_savefile["temp"] << temp
if(temp)
GLOB.banlist_savefile["minutes"] << bantimestamp
if(!temp)
add_note(ckey, "Permanently banned - [reason]", null, bannedby, 0)
else
add_note(ckey, "Banned for [minutes] minutes - [reason]", null, bannedby, 0)
return 1
/proc/RemoveBan(foldername)
var/key
var/id
GLOB.banlist_savefile.cd = "/base/[foldername]"
GLOB.banlist_savefile["key"] >> key
GLOB.banlist_savefile["id"] >> id
GLOB.banlist_savefile.cd = "/base"
if(!GLOB.banlist_savefile.dir.Remove(foldername)) return 0
if(!usr)
log_admin("Ban Expired: [key]")
message_admins("Ban Expired: [key]")
else
ban_unban_log_save("[key_name_admin(usr)] unbanned [key]")
log_admin("[key_name_admin(usr)] unbanned [key]")
message_admins("[key_name_admin(usr)] unbanned: [key]")
feedback_inc("ban_unban",1)
usr.client.holder.DB_ban_unban( ckey(key), BANTYPE_ANY_FULLBAN)
for(var/A in GLOB.banlist_savefile.dir)
GLOB.banlist_savefile.cd = "/base/[A]"
if(key == GLOB.banlist_savefile["key"] /*|| id == GLOB.banlist_savefile["id"]*/)
GLOB.banlist_savefile.cd = "/base"
GLOB.banlist_savefile.dir.Remove(A)
continue
return 1
/proc/GetExp(minutes as num)
UpdateTime()
var/exp = minutes - GLOB.CMinutes
if(exp <= 0)
return 0
else
var/timeleftstring
if(exp >= 1440) //1440 = 1 day in minutes
timeleftstring = "[round(exp / 1440, 0.1)] Days"
else if(exp >= 60) //60 = 1 hour in minutes
timeleftstring = "[round(exp / 60, 0.1)] Hours"
else
timeleftstring = "[exp] Minutes"
return timeleftstring
/datum/admins/proc/unbanpanel()
var/count = 0
var/dat
GLOB.banlist_savefile.cd = "/base"
for(var/A in GLOB.banlist_savefile.dir)
count++
GLOB.banlist_savefile.cd = "/base/[A]"
var/ref = UID()
var/key = GLOB.banlist_savefile["key"]
var/id = GLOB.banlist_savefile["id"]
var/ip = GLOB.banlist_savefile["ip"]
var/reason = GLOB.banlist_savefile["reason"]
var/by = GLOB.banlist_savefile["bannedby"]
var/expiry
if(GLOB.banlist_savefile["temp"])
expiry = GetExp(GLOB.banlist_savefile["minutes"])
if(!expiry) expiry = "Removal Pending"
else expiry = "Permaban"
dat += text("<tr><td><A href='?src=[ref];unbanf=[key][id]'>(U)</A><A href='?src=[ref];unbane=[key][id]'>(E)</A> Key: <B>[key]</B></td><td>ComputerID: <B>[id]</B></td><td>IP: <B>[ip]</B></td><td> [expiry]</td><td>(By: [by])</td><td>(Reason: [reason])</td></tr>")
dat += "</table>"
dat = "<HR><B>Bans:</B> <FONT COLOR=blue>(U) = Unban , (E) = Edit Ban</FONT> - <FONT COLOR=green>([count] Bans)</FONT><HR><table border=1 rules=all frame=void cellspacing=0 cellpadding=3 >[dat]"
usr << browse(dat, "window=unbanp;size=875x400")
//////////////////////////////////// DEBUG ////////////////////////////////////
/proc/CreateBans()
UpdateTime()
var/i
var/last
for(i=0, i<1001, i++)
var/a = pick(1,0)
var/b = pick(1,0)
if(b)
GLOB.banlist_savefile.cd = "/base"
GLOB.banlist_savefile.dir.Add("trash[i]trashid[i]")
GLOB.banlist_savefile.cd = "/base/trash[i]trashid[i]"
GLOB.banlist_savefile["key"] << "trash[i]"
else
GLOB.banlist_savefile.cd = "/base"
GLOB.banlist_savefile.dir.Add("[last]trashid[i]")
GLOB.banlist_savefile.cd = "/base/[last]trashid[i]"
GLOB.banlist_savefile["key"] << last
GLOB.banlist_savefile["id"] << "trashid[i]"
GLOB.banlist_savefile["reason"] << "Trashban[i]."
GLOB.banlist_savefile["temp"] << a
GLOB.banlist_savefile["minutes"] << GLOB.CMinutes + rand(1,2000)
GLOB.banlist_savefile["bannedby"] << "trashmin"
last = "trash[i]"
GLOB.banlist_savefile.cd = "/base"
/proc/ClearAllBans()
GLOB.banlist_savefile.cd = "/base"
for(var/A in GLOB.banlist_savefile.dir)
RemoveBan(A)
+89 -89
View File
@@ -1,89 +1,89 @@
//By Carnwennan
//fetches an external list and processes it into a list of ip addresses.
//It then stores the processed list into a savefile for later use
#define TORFILE "data/ToR_ban.bdb"
#define TOR_UPDATE_INTERVAL 216000 //~6 hours
/proc/ToRban_isbanned(var/ip_address)
var/savefile/F = new(TORFILE)
if(F)
if( ip_address in F.dir )
return 1
return 0
/proc/ToRban_autoupdate()
var/savefile/F = new(TORFILE)
if(F)
var/last_update
F["last_update"] >> last_update
if((last_update + TOR_UPDATE_INTERVAL) < world.realtime) //we haven't updated for a while
ToRban_update()
return
/proc/ToRban_update()
spawn(0)
log_world("Downloading updated ToR data...")
var/http[] = world.Export("http://exitlist.torproject.org/exit-addresses")
var/list/rawlist = file2list(http["CONTENT"])
if(rawlist.len)
fdel(TORFILE)
var/savefile/F = new(TORFILE)
for( var/line in rawlist )
if(!line) continue
if( copytext(line,1,12) == "ExitAddress" )
var/cleaned = copytext(line,13,length(line)-19)
if(!cleaned) continue
F[cleaned] << 1
to_chat(F["last_update"], world.realtime)
log_world("ToR data updated!")
if(usr)
to_chat(usr, "ToRban updated.")
return 1
log_world("ToR data update aborted: no data.")
return 0
/client/proc/ToRban(task in list("update","toggle","show","remove","remove all","find"))
set name = "ToRban"
set category = "Server"
if(!holder) return
switch(task)
if("update")
ToRban_update()
if("toggle")
if(config)
if(config.ToRban)
config.ToRban = 0
message_admins("<font color='red'>ToR banning disabled.</font>")
else
config.ToRban = 1
message_admins("<font colot='green'>ToR banning enabled.</font>")
if("show")
var/savefile/F = new(TORFILE)
var/dat
if( length(F.dir) )
for( var/i=1, i<=length(F.dir), i++ )
dat += "<tr><td>#[i]</td><td> [F.dir[i]]</td></tr>"
dat = "<table width='100%'>[dat]</table>"
else
dat = "No addresses in list."
src << browse(dat,"window=ToRban_show")
if("remove")
var/savefile/F = new(TORFILE)
var/choice = input(src,"Please select an IP address to remove from the ToR banlist:","Remove ToR ban",null) as null|anything in F.dir
if(choice)
F.dir.Remove(choice)
to_chat(src, "<b>Address removed</b>")
if("remove all")
to_chat(src, "<b>[TORFILE] was [fdel(TORFILE)?"":"not "]removed.</b>")
if("find")
var/input = input(src,"Please input an IP address to search for:","Find ToR ban",null) as null|text
if(input)
if(ToRban_isbanned(input))
to_chat(src, "<font color='green'><b>Address is a known ToR address</b></font>")
else
to_chat(src, "<font color='red'><b>Address is not a known ToR address</b></font>")
return
#undef TORFILE
#undef TOR_UPDATE_INTERVAL
//By Carnwennan
//fetches an external list and processes it into a list of ip addresses.
//It then stores the processed list into a savefile for later use
#define TORFILE "data/ToR_ban.bdb"
#define TOR_UPDATE_INTERVAL 216000 //~6 hours
/proc/ToRban_isbanned(var/ip_address)
var/savefile/F = new(TORFILE)
if(F)
if( ip_address in F.dir )
return 1
return 0
/proc/ToRban_autoupdate()
var/savefile/F = new(TORFILE)
if(F)
var/last_update
F["last_update"] >> last_update
if((last_update + TOR_UPDATE_INTERVAL) < world.realtime) //we haven't updated for a while
ToRban_update()
return
/proc/ToRban_update()
spawn(0)
log_world("Downloading updated ToR data...")
var/http[] = world.Export("http://exitlist.torproject.org/exit-addresses")
var/list/rawlist = file2list(http["CONTENT"])
if(rawlist.len)
fdel(TORFILE)
var/savefile/F = new(TORFILE)
for( var/line in rawlist )
if(!line) continue
if( copytext(line,1,12) == "ExitAddress" )
var/cleaned = copytext(line,13,length(line)-19)
if(!cleaned) continue
F[cleaned] << 1
to_chat(F["last_update"], world.realtime)
log_world("ToR data updated!")
if(usr)
to_chat(usr, "ToRban updated.")
return 1
log_world("ToR data update aborted: no data.")
return 0
/client/proc/ToRban(task in list("update","toggle","show","remove","remove all","find"))
set name = "ToRban"
set category = "Server"
if(!holder) return
switch(task)
if("update")
ToRban_update()
if("toggle")
if(config)
if(config.ToRban)
config.ToRban = 0
message_admins("<font color='red'>ToR banning disabled.</font>")
else
config.ToRban = 1
message_admins("<font colot='green'>ToR banning enabled.</font>")
if("show")
var/savefile/F = new(TORFILE)
var/dat
if( length(F.dir) )
for( var/i=1, i<=length(F.dir), i++ )
dat += "<tr><td>#[i]</td><td> [F.dir[i]]</td></tr>"
dat = "<table width='100%'>[dat]</table>"
else
dat = "No addresses in list."
src << browse(dat,"window=ToRban_show")
if("remove")
var/savefile/F = new(TORFILE)
var/choice = input(src,"Please select an IP address to remove from the ToR banlist:","Remove ToR ban",null) as null|anything in F.dir
if(choice)
F.dir.Remove(choice)
to_chat(src, "<b>Address removed</b>")
if("remove all")
to_chat(src, "<b>[TORFILE] was [fdel(TORFILE)?"":"not "]removed.</b>")
if("find")
var/input = input(src,"Please input an IP address to search for:","Find ToR ban",null) as null|text
if(input)
if(ToRban_isbanned(input))
to_chat(src, "<font color='green'><b>Address is a known ToR address</b></font>")
else
to_chat(src, "<font color='red'><b>Address is not a known ToR address</b></font>")
return
#undef TORFILE
#undef TOR_UPDATE_INTERVAL
+1094 -1092
View File
File diff suppressed because it is too large Load Diff
+3 -3
View File
@@ -23,18 +23,18 @@
if(!message) return
var/F = investigate_subject2file(subject)
if(!F) return
investigate_log_subjects |= subject
GLOB.investigate_log_subjects |= subject
F << "<small>[time_stamp()] \ref[src] ([x],[y],[z])</small> || [src] [message]<br>"
/proc/log_investigate(message, subject)
if(!message) return
var/F = investigate_subject2file(subject)
if(!F) return
investigate_log_subjects |= subject
GLOB.investigate_log_subjects |= subject
F << "<small>[time_stamp()] || [message]<br>"
//ADMINVERBS
/client/proc/investigate_show( subject in investigate_log_subjects )
/client/proc/investigate_show( subject in GLOB.investigate_log_subjects )
set name = "Investigate"
set category = "Admin"
if(!holder) return
+10 -10
View File
@@ -3,7 +3,7 @@
set category = "Server"
if(!check_rights(R_SERVER))
return
if(!dbcon.IsConnected())
if(!GLOB.dbcon.IsConnected())
to_chat(src, "<span class='danger'>Failed to establish database connection.</span>")
return
var/memotask = input(usr,"Choose task.","Memo") in list("Show","Write","Edit","Remove")
@@ -16,13 +16,13 @@
return
if(!task)
return
if(!dbcon.IsConnected())
if(!GLOB.dbcon.IsConnected())
to_chat(src, "<span class='danger'>Failed to establish database connection.</span>")
return
var/sql_ckey = sanitizeSQL(src.ckey)
switch(task)
if("Write")
var/DBQuery/query_memocheck = dbcon.NewQuery("SELECT ckey FROM [format_table_name("memo")] WHERE ckey = '[sql_ckey]'")
var/DBQuery/query_memocheck = GLOB.dbcon.NewQuery("SELECT ckey FROM [format_table_name("memo")] WHERE ckey = '[sql_ckey]'")
if(!query_memocheck.Execute())
var/err = query_memocheck.ErrorMsg()
log_game("SQL ERROR obtaining ckey from memo table. Error : \[[err]\]\n")
@@ -35,7 +35,7 @@
return
memotext = sanitizeSQL(memotext)
var/timestamp = SQLtime()
var/DBQuery/query_memoadd = dbcon.NewQuery("INSERT INTO [format_table_name("memo")] (ckey, memotext, timestamp) VALUES ('[sql_ckey]', '[memotext]', '[timestamp]')")
var/DBQuery/query_memoadd = GLOB.dbcon.NewQuery("INSERT INTO [format_table_name("memo")] (ckey, memotext, timestamp) VALUES ('[sql_ckey]', '[memotext]', '[timestamp]')")
if(!query_memoadd.Execute())
var/err = query_memoadd.ErrorMsg()
log_game("SQL ERROR adding new memo. Error : \[[err]\]\n")
@@ -43,7 +43,7 @@
log_admin("[key_name(src)] has set a memo: [memotext]")
message_admins("[key_name_admin(src)] has set a memo:<br>[memotext]")
if("Edit")
var/DBQuery/query_memolist = dbcon.NewQuery("SELECT ckey FROM [format_table_name("memo")]")
var/DBQuery/query_memolist = GLOB.dbcon.NewQuery("SELECT ckey FROM [format_table_name("memo")]")
if(!query_memolist.Execute())
var/err = query_memolist.ErrorMsg()
log_game("SQL ERROR obtaining ckey from memo table. Error : \[[err]\]\n")
@@ -59,7 +59,7 @@
if(!target_ckey)
return
var/target_sql_ckey = sanitizeSQL(target_ckey)
var/DBQuery/query_memofind = dbcon.NewQuery("SELECT memotext FROM [format_table_name("memo")] WHERE ckey = '[target_sql_ckey]'")
var/DBQuery/query_memofind = GLOB.dbcon.NewQuery("SELECT memotext FROM [format_table_name("memo")] WHERE ckey = '[target_sql_ckey]'")
if(!query_memofind.Execute())
var/err = query_memofind.ErrorMsg()
log_game("SQL ERROR obtaining memotext from memo table. Error : \[[err]\]\n")
@@ -72,7 +72,7 @@
new_memo = sanitizeSQL(new_memo)
var/edit_text = "Edited by [sql_ckey] on [SQLtime()] from<br>[old_memo]<br>to<br>[new_memo]<hr>"
edit_text = sanitizeSQL(edit_text)
var/DBQuery/update_query = dbcon.NewQuery("UPDATE [format_table_name("memo")] SET memotext = '[new_memo]', last_editor = '[sql_ckey]', edits = CONCAT(IFNULL(edits,''),'[edit_text]') WHERE ckey = '[target_sql_ckey]'")
var/DBQuery/update_query = GLOB.dbcon.NewQuery("UPDATE [format_table_name("memo")] SET memotext = '[new_memo]', last_editor = '[sql_ckey]', edits = CONCAT(IFNULL(edits,''),'[edit_text]') WHERE ckey = '[target_sql_ckey]'")
if(!update_query.Execute())
var/err = update_query.ErrorMsg()
log_game("SQL ERROR editing memo. Error : \[[err]\]\n")
@@ -84,7 +84,7 @@
log_admin("[key_name(src)] has edited [target_sql_ckey]'s memo from \"[old_memo]\" to \"[new_memo]\"")
message_admins("[key_name_admin(src)] has edited [target_sql_ckey]'s memo from \"[old_memo]\" to \"[new_memo]\"")
if("Show")
var/DBQuery/query_memoshow = dbcon.NewQuery("SELECT ckey, memotext, timestamp, last_editor FROM [format_table_name("memo")]")
var/DBQuery/query_memoshow = GLOB.dbcon.NewQuery("SELECT ckey, memotext, timestamp, last_editor FROM [format_table_name("memo")]")
if(!query_memoshow.Execute())
var/err = query_memoshow.ErrorMsg()
log_game("SQL ERROR obtaining ckey, memotext, timestamp, last_editor from memo table. Error : \[[err]\]\n")
@@ -104,7 +104,7 @@
else if(!silent)
to_chat(src, "No memos found in database.")
if("Remove")
var/DBQuery/query_memodellist = dbcon.NewQuery("SELECT ckey FROM [format_table_name("memo")]")
var/DBQuery/query_memodellist = GLOB.dbcon.NewQuery("SELECT ckey FROM [format_table_name("memo")]")
if(!query_memodellist.Execute())
var/err = query_memodellist.ErrorMsg()
log_game("SQL ERROR obtaining ckey from memo table. Error : \[[err]\]\n")
@@ -120,7 +120,7 @@
if(!target_ckey)
return
var/target_sql_ckey = sanitizeSQL(target_ckey)
var/DBQuery/query_memodel = dbcon.NewQuery("DELETE FROM [format_table_name("memo")] WHERE ckey = '[target_sql_ckey]'")
var/DBQuery/query_memodel = GLOB.dbcon.NewQuery("DELETE FROM [format_table_name("memo")] WHERE ckey = '[target_sql_ckey]'")
if(!query_memodel.Execute())
var/err = query_memodel.ErrorMsg()
log_game("SQL ERROR removing memo. Error : \[[err]\]\n")
+172 -160
View File
@@ -1,160 +1,172 @@
var/list/admin_ranks = list() //list of all ranks with associated rights
//load our rank - > rights associations
/proc/load_admin_ranks()
admin_ranks.Cut()
var/previous_rights = 0
//load text from file
var/list/Lines = file2list("config/admin_ranks.txt")
//process each line seperately
for(var/line in Lines)
if(!length(line)) continue
if(copytext(line,1,2) == "#") continue
var/list/List = splittext(line,"+")
if(!List.len) continue
var/rank = ckeyEx(List[1])
switch(rank)
if(null,"") continue
if("Removed") continue //Reserved
var/rights = 0
for(var/i=2, i<=List.len, i++)
switch(ckey(List[i]))
if("@","prev") rights |= previous_rights
if("buildmode","build") rights |= R_BUILDMODE
if("admin") rights |= R_ADMIN
if("ban") rights |= R_BAN
if("event") rights |= R_EVENT
if("server") rights |= R_SERVER
if("debug") rights |= R_DEBUG
if("permissions","rights") rights |= R_PERMISSIONS
if("possess") rights |= R_POSSESS
if("stealth") rights |= R_STEALTH
if("rejuv","rejuvinate") rights |= R_REJUVINATE
if("varedit") rights |= R_VAREDIT
if("everything","host","all") rights |= R_HOST
if("sound","sounds") rights |= R_SOUNDS
if("spawn","create") rights |= R_SPAWN
if("mod") rights |= R_MOD
if("mentor") rights |= R_MENTOR
if("proccall") rights |= R_PROCCALL
admin_ranks[rank] = rights
previous_rights = rights
#ifdef TESTING
var/msg = "Permission Sets Built:\n"
for(var/rank in admin_ranks)
msg += "\t[rank] - [admin_ranks[rank]]\n"
testing(msg)
#endif
/hook/startup/proc/loadAdmins()
load_admins()
return 1
/proc/load_admins()
//clear the datums references
admin_datums.Cut()
for(var/client/C in GLOB.admins)
C.remove_admin_verbs()
C.holder = null
GLOB.admins.Cut()
if(config.admin_legacy_system)
load_admin_ranks()
//load text from file
var/list/Lines = file2list("config/admins.txt")
//process each line seperately
for(var/line in Lines)
if(!length(line)) continue
if(copytext(line,1,2) == "#") continue
//Split the line at every "-"
var/list/List = splittext(line, "-")
if(!List.len) continue
//ckey is before the first "-"
var/ckey = ckey(List[1])
if(!ckey) continue
//rank follows the first "-"
var/rank = ""
if(List.len >= 2)
rank = ckeyEx(List[2])
//load permissions associated with this rank
var/rights = admin_ranks[rank]
//create the admin datum and store it for later use
var/datum/admins/D = new /datum/admins(rank, rights, ckey)
//find the client for a ckey if they are connected and associate them with the new admin datum
D.associate(GLOB.directory[ckey])
else
//The current admin system uses SQL
establish_db_connection()
if(!dbcon.IsConnected())
log_world("Failed to connect to database in load_admins(). Reverting to legacy system.")
config.admin_legacy_system = 1
load_admins()
return
var/DBQuery/query = dbcon.NewQuery("SELECT ckey, rank, level, flags FROM [format_table_name("admin")]")
query.Execute()
while(query.NextRow())
var/ckey = query.item[1]
var/rank = query.item[2]
if(rank == "Removed") continue //This person was de-adminned. They are only in the admin list for archive purposes.
var/rights = query.item[4]
if(istext(rights)) rights = text2num(rights)
var/datum/admins/D = new /datum/admins(rank, rights, ckey)
//find the client for a ckey if they are connected and associate them with the new admin datum
D.associate(GLOB.directory[ckey])
if(!admin_datums)
log_world("The database query in load_admins() resulted in no admins being added to the list. Reverting to legacy system.")
config.admin_legacy_system = 1
load_admins()
return
#ifdef TESTING
var/msg = "Admins Built:\n"
for(var/ckey in admin_datums)
var/rank
var/datum/admins/D = admin_datums[ckey]
if(D) rank = D.rank
msg += "\t[ckey] - [rank]\n"
testing(msg)
#endif
#ifdef TESTING
/client/verb/changerank(newrank in admin_ranks)
if(holder)
holder.rank = newrank
holder.rights = admin_ranks[newrank]
else
holder = new /datum/admins(newrank,admin_ranks[newrank],ckey)
remove_admin_verbs()
holder.associate(src)
/client/verb/changerights(newrights as num)
if(holder)
holder.rights = newrights
else
holder = new /datum/admins("testing",newrights,ckey)
remove_admin_verbs()
holder.associate(src)
#endif
GLOBAL_LIST_EMPTY(admin_ranks) //list of all ranks with associated rights
GLOBAL_PROTECT(admin_ranks) // this shit is being protected for obvious reasons
//load our rank - > rights associations
/proc/load_admin_ranks()
GLOB.admin_ranks.Cut()
var/previous_rights = 0
//load text from file
var/list/Lines = file2list("config/admin_ranks.txt")
//process each line seperately
for(var/line in Lines)
if(!length(line)) continue
if(copytext(line,1,2) == "#") continue
var/list/List = splittext(line,"+")
if(!List.len) continue
var/rank = ckeyEx(List[1])
switch(rank)
if(null,"") continue
if("Removed") continue //Reserved
var/rights = 0
for(var/i=2, i<=List.len, i++)
switch(ckey(List[i]))
if("@","prev") rights |= previous_rights
if("buildmode","build") rights |= R_BUILDMODE
if("admin") rights |= R_ADMIN
if("ban") rights |= R_BAN
if("event") rights |= R_EVENT
if("server") rights |= R_SERVER
if("debug") rights |= R_DEBUG
if("permissions","rights") rights |= R_PERMISSIONS
if("possess") rights |= R_POSSESS
if("stealth") rights |= R_STEALTH
if("rejuv","rejuvinate") rights |= R_REJUVINATE
if("varedit") rights |= R_VAREDIT
if("everything","host","all") rights |= R_HOST
if("sound","sounds") rights |= R_SOUNDS
if("spawn","create") rights |= R_SPAWN
if("mod") rights |= R_MOD
if("mentor") rights |= R_MENTOR
if("proccall") rights |= R_PROCCALL
if("viewruntimes") rights |= R_VIEWRUNTIMES
GLOB.admin_ranks[rank] = rights
previous_rights = rights
#ifdef TESTING
var/msg = "Permission Sets Built:\n"
for(var/rank in GLOB.admin_ranks)
msg += "\t[rank] - [GLOB.admin_ranks[rank]]\n"
testing(msg)
#endif
/hook/startup/proc/loadAdmins()
load_admins()
return 1
/proc/load_admins()
//clear the datums references
GLOB.admin_datums.Cut()
for(var/client/C in GLOB.admins)
C.remove_admin_verbs()
C.holder = null
GLOB.admins.Cut()
// Remove all profiler access
for(var/A in world.GetConfig("admin"))
world.SetConfig("APP/admin", A, null)
if(config.admin_legacy_system)
load_admin_ranks()
//load text from file
var/list/Lines = file2list("config/admins.txt")
//process each line seperately
for(var/line in Lines)
if(!length(line)) continue
if(copytext(line,1,2) == "#") continue
//Split the line at every "-"
var/list/List = splittext(line, "-")
if(!List.len) continue
//ckey is before the first "-"
var/ckey = ckey(List[1])
if(!ckey) continue
//rank follows the first "-"
var/rank = ""
if(List.len >= 2)
rank = ckeyEx(List[2])
//load permissions associated with this rank
var/rights = GLOB.admin_ranks[rank]
//create the admin datum and store it for later use
var/datum/admins/D = new /datum/admins(rank, rights, ckey)
if(D.rights & R_DEBUG || D.rights & R_VIEWRUNTIMES) // Grants profiler access to anyone with R_DEBUG or R_VIEWRUNTIMES
world.SetConfig("APP/admin", ckey, "role=admin")
//find the client for a ckey if they are connected and associate them with the new admin datum
D.associate(GLOB.directory[ckey])
else
//The current admin system uses SQL
establish_db_connection()
if(!GLOB.dbcon.IsConnected())
log_world("Failed to connect to database in load_admins(). Reverting to legacy system.")
config.admin_legacy_system = 1
load_admins()
return
var/DBQuery/query = GLOB.dbcon.NewQuery("SELECT ckey, rank, level, flags FROM [format_table_name("admin")]")
query.Execute()
while(query.NextRow())
var/ckey = query.item[1]
var/rank = query.item[2]
if(rank == "Removed") continue //This person was de-adminned. They are only in the admin list for archive purposes.
var/rights = query.item[4]
if(istext(rights)) rights = text2num(rights)
var/datum/admins/D = new /datum/admins(rank, rights, ckey)
if(D.rights & R_DEBUG || D.rights & R_VIEWRUNTIMES) // Grants profiler access to anyone with R_DEBUG or R_VIEWRUNTIMES
world.SetConfig("APP/admin", ckey, "role=admin")
//find the client for a ckey if they are connected and associate them with the new admin datum
D.associate(GLOB.directory[ckey])
if(!GLOB.admin_datums)
log_world("The database query in load_admins() resulted in no admins being added to the list. Reverting to legacy system.")
config.admin_legacy_system = 1
load_admins()
return
#ifdef TESTING
var/msg = "Admins Built:\n"
for(var/ckey in GLOB.admin_datums)
var/rank
var/datum/admins/D = GLOB.admin_datums[ckey]
if(D) rank = D.rank
msg += "\t[ckey] - [rank]\n"
testing(msg)
#endif
#ifdef TESTING
/client/verb/changerank(newrank in GLOB.admin_ranks)
if(holder)
holder.rank = newrank
holder.rights = GLOB.admin_ranks[newrank]
else
holder = new /datum/admins(newrank,GLOB.admin_ranks[newrank],ckey)
remove_admin_verbs()
holder.associate(src)
/client/verb/changerights(newrights as num)
if(holder)
holder.rights = newrights
else
holder = new /datum/admins("testing",newrights,ckey)
remove_admin_verbs()
holder.associate(src)
#endif
File diff suppressed because it is too large Load Diff
+18 -18
View File
@@ -1,22 +1,22 @@
//ban people from using custom names and appearances. that'll show 'em.
var/appearanceban_runonce //Updates legacy bans with new info
var/appearance_keylist[0] //to store the keys
GLOBAL_VAR(appearanceban_runonce) //Updates legacy bans with new info
GLOBAL_LIST_EMPTY(appearance_keylist) //to store the keys
/proc/appearance_fullban(mob/M, reason)
if(!M || !M.key) return
appearance_keylist.Add(text("[M.ckey] ## [reason]"))
GLOB.appearance_keylist.Add(text("[M.ckey] ## [reason]"))
appearance_savebanfile()
/proc/appearance_client_fullban(ckey)
if(!ckey) return
appearance_keylist.Add(text("[ckey]"))
GLOB.appearance_keylist.Add(text("[ckey]"))
appearance_savebanfile()
//returns a reason if M is banned, returns 0 otherwise
/proc/appearance_isbanned(mob/M)
if(M)
for(var/s in appearance_keylist)
for(var/s in GLOB.appearance_keylist)
if(findtext(s, "[M.ckey]") == 1)
var/startpos = findtext(s, "## ") + 3
if(startpos && startpos < length(s))
@@ -43,12 +43,12 @@ DEBUG
/proc/appearance_loadbanfile()
if(config.ban_legacy_system)
var/savefile/S=new("data/appearance_full.ban")
S["keys[0]"] >> appearance_keylist
S["keys[0]"] >> GLOB.appearance_keylist
log_admin("Loading appearance_rank")
S["runonce"] >> appearanceban_runonce
S["runonce"] >> GLOB.appearanceban_runonce
if(!length(appearance_keylist))
appearance_keylist=list()
if(!length(GLOB.appearance_keylist))
GLOB.appearance_keylist=list()
log_admin("appearance_keylist was empty")
else
if(!establish_db_connection())
@@ -58,17 +58,17 @@ DEBUG
return
//appearance bans
var/DBQuery/query = dbcon.NewQuery("SELECT ckey FROM [format_table_name("ban")] WHERE bantype = 'APPEARANCE_BAN' AND NOT unbanned = 1")
var/DBQuery/query = GLOB.dbcon.NewQuery("SELECT ckey FROM [format_table_name("ban")] WHERE bantype = 'APPEARANCE_BAN' AND NOT unbanned = 1")
query.Execute()
while(query.NextRow())
var/ckey = query.item[1]
appearance_keylist.Add("[ckey]")
GLOB.appearance_keylist.Add("[ckey]")
/proc/appearance_savebanfile()
var/savefile/S=new("data/appearance_full.ban")
to_chat(S["keys[0]"], appearance_keylist)
to_chat(S["keys[0]"], GLOB.appearance_keylist)
/proc/appearance_unban(mob/M)
appearance_remove("[M.ckey]")
@@ -76,18 +76,18 @@ DEBUG
/proc/appearance_updatelegacybans()
if(!appearanceban_runonce)
if(!GLOB.appearanceban_runonce)
log_admin("Updating appearancefile!")
// Updates bans.. Or fixes them. Either way.
for(var/T in appearance_keylist)
for(var/T in GLOB.appearance_keylist)
if(!T) continue
appearanceban_runonce++ //don't run this update again
GLOB.appearanceban_runonce++ //don't run this update again
/proc/appearance_remove(X)
for(var/i = 1; i <= length(appearance_keylist); i++)
if( findtext(appearance_keylist[i], "[X]") )
appearance_keylist.Remove(appearance_keylist[i])
for(var/i = 1; i <= length(GLOB.appearance_keylist); i++)
if( findtext(GLOB.appearance_keylist[i], "[X]") )
GLOB.appearance_keylist.Remove(GLOB.appearance_keylist[i])
appearance_savebanfile()
return 1
return 0
+179 -179
View File
@@ -1,179 +1,179 @@
var/jobban_runonce // Updates legacy bans with new info
var/jobban_keylist[0] // Linear list of jobban strings, kept around for the legacy system
var/jobban_assoclist[0] // Associative list, for efficiency
// Matches string-based jobbans into ckey, rank, and reason groups
var/regex/jobban_regex = regex("(\[\\S]+) - (\[^#]+\[^# ])(?: ## (.+))?")
/proc/jobban_assoc_insert(ckey, rank, reason)
if(!ckey || !rank)
return
if(!jobban_assoclist[ckey])
jobban_assoclist[ckey] = list()
jobban_assoclist[ckey][rank] = reason || "Reason Unspecified"
/proc/jobban_fullban(mob/M, rank, reason)
if(!M || !M.key)
return
jobban_keylist.Add(text("[M.ckey] - [rank] ## [reason]"))
jobban_assoc_insert(M.ckey, rank, reason)
if(config.ban_legacy_system)
jobban_savebanfile()
/proc/jobban_client_fullban(ckey, rank)
if(!ckey || !rank)
return
jobban_keylist.Add(text("[ckey] - [rank]"))
jobban_assoc_insert(ckey, rank)
if(config.ban_legacy_system)
jobban_savebanfile()
//returns a reason if M is banned from rank, returns 0 otherwise
/proc/jobban_isbanned(mob/M, rank)
if(!M || !rank)
return 0
if(config.guest_jobban && guest_jobbans(rank))
if(IsGuestKey(M.key))
return "Guest Job-ban"
if(jobban_assoclist[M.ckey])
return jobban_assoclist[M.ckey][rank]
else
return 0
/*
DEBUG
/mob/verb/list_all_jobbans()
set name = "list all jobbans"
for(var/s in jobban_keylist)
to_chat(world, s)
/mob/verb/reload_jobbans()
set name = "reload jobbans"
jobban_loadbanfile()
*/
/hook/startup/proc/loadJobBans()
jobban_loadbanfile()
return 1
/proc/jobban_loadbanfile()
if(config.ban_legacy_system)
var/savefile/S=new("data/job_full.ban")
S["keys[0]"] >> jobban_keylist
log_admin("Loading jobban_rank")
S["runonce"] >> jobban_runonce
if(!length(jobban_keylist))
jobban_keylist=list()
log_admin("jobban_keylist was empty")
for(var/s in jobban_keylist)
if(jobban_regex.Find(s))
jobban_assoc_insert(jobban_regex.group[1], jobban_regex.group[2], jobban_regex.group[3])
else
log_runtime(EXCEPTION("Skipping malformed job ban: [s]"))
else
if(!establish_db_connection())
log_world("Database connection failed. Reverting to the legacy ban system.")
config.ban_legacy_system = 1
jobban_loadbanfile()
return
//Job permabans
var/DBQuery/permabans = dbcon.NewQuery("SELECT ckey, job FROM [format_table_name("ban")] WHERE bantype = 'JOB_PERMABAN' AND isnull(unbanned)")
permabans.Execute()
// Job tempbans
var/DBQuery/tempbans = dbcon.NewQuery("SELECT ckey, job FROM [format_table_name("ban")] WHERE bantype = 'JOB_TEMPBAN' AND isnull(unbanned) AND expiration_time > Now()")
tempbans.Execute()
while(TRUE)
var/ckey
var/job
if(permabans.NextRow())
ckey = permabans.item[1]
job = permabans.item[2]
else if(tempbans.NextRow())
ckey = tempbans.item[1]
job = tempbans.item[2]
else
break
jobban_keylist.Add("[ckey] - [job]")
jobban_assoc_insert(ckey, job)
/proc/jobban_savebanfile()
var/savefile/S=new("data/job_full.ban")
S["keys[0]"] << jobban_keylist
/proc/jobban_unban(mob/M, rank)
jobban_remove("[M.ckey] - [rank]")
/proc/jobban_unban_client(ckey, rank)
jobban_remove("[ckey] - [rank]")
/proc/ban_unban_log_save(var/formatted_log)
text2file(formatted_log,"data/ban_unban_log.txt")
/proc/jobban_remove(X)
for(var/i = 1; i <= length(jobban_keylist); i++)
if( findtext(jobban_keylist[i], "[X]") )
// This need to be here, instead of jobban_unban, due to direct calls to jobban_remove
if(jobban_regex.Find(X))
var/ckey = jobban_regex.group[1]
var/rank = jobban_regex.group[2]
if(jobban_assoclist[ckey] && jobban_assoclist[ckey][rank])
jobban_assoclist[ckey] -= rank
else
log_runtime(EXCEPTION("Attempted to remove non-existent job ban: [X]"))
else
log_runtime(EXCEPTION("Failed to remove malformed job ban from associative list: [X]"))
jobban_keylist.Remove(jobban_keylist[i])
if(config.ban_legacy_system)
jobban_savebanfile()
return 1
return 0
/mob/verb/displayjobbans()
set category = "OOC"
set name = "Display Current Jobbans"
set desc = "Displays all of your current jobbans."
if(!client || !ckey)
return
if(config.ban_legacy_system)
//using the legacy .txt ban system
to_chat(src, "The server is using the legacy ban system. Ask an administrator for help!")
else
//using the SQL ban system
var/is_actually_banned = FALSE
var/DBQuery/select_query = dbcon.NewQuery("SELECT bantime, bantype, reason, job, duration, expiration_time, a_ckey FROM [format_table_name("ban")] WHERE ckey like '[ckey]' AND ((bantype like 'JOB_TEMPBAN' AND expiration_time > Now()) OR (bantype like 'JOB_PERMABAN')) AND isnull(unbanned) ORDER BY bantime DESC LIMIT 100")
select_query.Execute()
while(select_query.NextRow())
var/bantime = select_query.item[1]
var/bantype = select_query.item[2]
var/reason = select_query.item[3]
var/job = select_query.item[4]
var/duration = select_query.item[5]
var/expiration = select_query.item[6]
var/ackey = select_query.item[7]
if(bantype == "JOB_PERMABAN")
to_chat(src, "<span class='warning'>[bantype]: [job] - REASON: [reason], by [ackey]; [bantime]</span>")
else if(bantype == "JOB_TEMPBAN")
to_chat(src, "<span class='warning'>[bantype]: [job] - REASON: [reason], by [ackey]; [bantime]; [duration]; expires [expiration]</span>")
is_actually_banned = TRUE
if(is_actually_banned)
if(config.banappeals)
to_chat(src, "<span class='warning'>You can appeal the bans at: [config.banappeals]</span>")
else
to_chat(src, "<span class='warning'>You have no active jobbans!</span>")
GLOBAL_VAR(jobban_runonce) // Updates legacy bans with new info
GLOBAL_LIST_INIT(jobban_keylist, new()) // Linear list of jobban strings, kept around for the legacy system
GLOBAL_LIST_INIT(jobban_assoclist, new()) // Associative list, for efficiency
// Matches string-based jobbans into ckey, rank, and reason groups
GLOBAL_DATUM_INIT(jobban_regex, /regex, regex("(\[\\S]+) - (\[^#]+\[^# ])(?: ## (.+))?"))
/proc/jobban_assoc_insert(ckey, rank, reason)
if(!ckey || !rank)
return
if(!GLOB.jobban_assoclist[ckey])
GLOB.jobban_assoclist[ckey] = list()
GLOB.jobban_assoclist[ckey][rank] = reason || "Reason Unspecified"
/proc/jobban_fullban(mob/M, rank, reason)
if(!M || !M.key)
return
GLOB.jobban_keylist.Add(text("[M.ckey] - [rank] ## [reason]"))
jobban_assoc_insert(M.ckey, rank, reason)
if(config.ban_legacy_system)
jobban_savebanfile()
/proc/jobban_client_fullban(ckey, rank)
if(!ckey || !rank)
return
GLOB.jobban_keylist.Add(text("[ckey] - [rank]"))
jobban_assoc_insert(ckey, rank)
if(config.ban_legacy_system)
jobban_savebanfile()
//returns a reason if M is banned from rank, returns 0 otherwise
/proc/jobban_isbanned(mob/M, rank)
if(!M || !rank)
return 0
if(config.guest_jobban && guest_jobbans(rank))
if(IsGuestKey(M.key))
return "Guest Job-ban"
if(GLOB.jobban_assoclist[M.ckey])
return GLOB.jobban_assoclist[M.ckey][rank]
else
return 0
/*
DEBUG
/mob/verb/list_all_jobbans()
set name = "list all jobbans"
for(var/s in jobban_keylist)
to_chat(world, s)
/mob/verb/reload_jobbans()
set name = "reload jobbans"
jobban_loadbanfile()
*/
/hook/startup/proc/loadJobBans()
jobban_loadbanfile()
return 1
/proc/jobban_loadbanfile()
if(config.ban_legacy_system)
var/savefile/S=new("data/job_full.ban")
S["keys[0]"] >> GLOB.jobban_keylist
log_admin("Loading jobban_rank")
S["runonce"] >> GLOB.jobban_runonce
if(!length(GLOB.jobban_keylist))
GLOB.jobban_keylist=list()
log_admin("jobban_keylist was empty")
for(var/s in GLOB.jobban_keylist)
if(GLOB.jobban_regex.Find(s))
jobban_assoc_insert(GLOB.jobban_regex.group[1], GLOB.jobban_regex.group[2], GLOB.jobban_regex.group[3])
else
log_runtime(EXCEPTION("Skipping malformed job ban: [s]"))
else
if(!establish_db_connection())
log_world("Database connection failed. Reverting to the legacy ban system.")
config.ban_legacy_system = 1
jobban_loadbanfile()
return
//Job permabans
var/DBQuery/permabans = GLOB.dbcon.NewQuery("SELECT ckey, job FROM [format_table_name("ban")] WHERE bantype = 'JOB_PERMABAN' AND isnull(unbanned)")
permabans.Execute()
// Job tempbans
var/DBQuery/tempbans = GLOB.dbcon.NewQuery("SELECT ckey, job FROM [format_table_name("ban")] WHERE bantype = 'JOB_TEMPBAN' AND isnull(unbanned) AND expiration_time > Now()")
tempbans.Execute()
while(TRUE)
var/ckey
var/job
if(permabans.NextRow())
ckey = permabans.item[1]
job = permabans.item[2]
else if(tempbans.NextRow())
ckey = tempbans.item[1]
job = tempbans.item[2]
else
break
GLOB.jobban_keylist.Add("[ckey] - [job]")
jobban_assoc_insert(ckey, job)
/proc/jobban_savebanfile()
var/savefile/S=new("data/job_full.ban")
S["keys[0]"] << GLOB.jobban_keylist
/proc/jobban_unban(mob/M, rank)
jobban_remove("[M.ckey] - [rank]")
/proc/jobban_unban_client(ckey, rank)
jobban_remove("[ckey] - [rank]")
/proc/ban_unban_log_save(var/formatted_log)
text2file(formatted_log,"data/ban_unban_log.txt")
/proc/jobban_remove(X)
for(var/i = 1; i <= length(GLOB.jobban_keylist); i++)
if( findtext(GLOB.jobban_keylist[i], "[X]") )
// This need to be here, instead of jobban_unban, due to direct calls to jobban_remove
if(GLOB.jobban_regex.Find(X))
var/ckey = GLOB.jobban_regex.group[1]
var/rank = GLOB.jobban_regex.group[2]
if(GLOB.jobban_assoclist[ckey] && GLOB.jobban_assoclist[ckey][rank])
GLOB.jobban_assoclist[ckey] -= rank
else
log_runtime(EXCEPTION("Attempted to remove non-existent job ban: [X]"))
else
log_runtime(EXCEPTION("Failed to remove malformed job ban from associative list: [X]"))
GLOB.jobban_keylist.Remove(GLOB.jobban_keylist[i])
if(config.ban_legacy_system)
jobban_savebanfile()
return 1
return 0
/mob/verb/displayjobbans()
set category = "OOC"
set name = "Display Current Jobbans"
set desc = "Displays all of your current jobbans."
if(!client || !ckey)
return
if(config.ban_legacy_system)
//using the legacy .txt ban system
to_chat(src, "The server is using the legacy ban system. Ask an administrator for help!")
else
//using the SQL ban system
var/is_actually_banned = FALSE
var/DBQuery/select_query = GLOB.dbcon.NewQuery("SELECT bantime, bantype, reason, job, duration, expiration_time, a_ckey FROM [format_table_name("ban")] WHERE ckey like '[ckey]' AND ((bantype like 'JOB_TEMPBAN' AND expiration_time > Now()) OR (bantype like 'JOB_PERMABAN')) AND isnull(unbanned) ORDER BY bantime DESC LIMIT 100")
select_query.Execute()
while(select_query.NextRow())
var/bantime = select_query.item[1]
var/bantype = select_query.item[2]
var/reason = select_query.item[3]
var/job = select_query.item[4]
var/duration = select_query.item[5]
var/expiration = select_query.item[6]
var/ackey = select_query.item[7]
if(bantype == "JOB_PERMABAN")
to_chat(src, "<span class='warning'>[bantype]: [job] - REASON: [reason], by [ackey]; [bantime]</span>")
else if(bantype == "JOB_TEMPBAN")
to_chat(src, "<span class='warning'>[bantype]: [job] - REASON: [reason], by [ackey]; [bantime]; [duration]; expires [expiration]</span>")
is_actually_banned = TRUE
if(is_actually_banned)
if(config.banappeals)
to_chat(src, "<span class='warning'>You can appeal the bans at: [config.banappeals]</span>")
else
to_chat(src, "<span class='warning'>You have no active jobbans!</span>")
+9 -9
View File
@@ -1,9 +1,9 @@
/var/create_mob_html = null
/datum/admins/proc/create_mob(var/mob/user)
if(!create_mob_html)
var/mobjs = null
mobjs = jointext(typesof(/mob), ";")
create_mob_html = file2text('html/create_object.html')
create_mob_html = replacetext(create_mob_html, "null /* object types */", "\"[mobjs]\"")
user << browse(replacetext(create_mob_html, "/* ref src */", UID()), "window=create_mob;size=425x475")
GLOBAL_VAR(create_mob_html)
/datum/admins/proc/create_mob(var/mob/user)
if(!GLOB.create_mob_html)
var/mobjs = null
mobjs = jointext(typesof(/mob), ";")
GLOB.create_mob_html = file2text('html/create_object.html')
GLOB.create_mob_html = replacetext(GLOB.create_mob_html, "null /* object types */", "\"[mobjs]\"")
user << browse(replacetext(GLOB.create_mob_html, "/* ref src */", UID()), "window=create_mob;size=425x475")
+23 -23
View File
@@ -1,23 +1,23 @@
var/create_object_html = null
var/list/create_object_forms = list(/obj, /obj/structure, /obj/machinery, /obj/effect, /obj/item, /obj/mecha, /obj/item/clothing, /obj/item/stack, /obj/item/reagent_containers, /obj/item/gun)
/datum/admins/proc/create_object(var/mob/user)
if(!create_object_html)
var/objectjs = null
objectjs = jointext(typesof(/obj), ";")
create_object_html = file2text('html/create_object.html')
create_object_html = replacetext(create_object_html, "null /* object types */", "\"[objectjs]\"")
user << browse(replacetext(create_object_html, "/* ref src */", UID()), "window=create_object;size=425x475")
/datum/admins/proc/quick_create_object(var/mob/user)
var/path = input("Select the path of the object you wish to create.", "Path", /obj) in create_object_forms
var/html_form = create_object_forms[path]
if(!html_form)
var/objectjs = jointext(typesof(path), ";")
html_form = file2text('html/create_object.html')
html_form = replacetext(html_form, "null /* object types */", "\"[objectjs]\"")
create_object_forms[path] = html_form
user << browse(replacetext(html_form, "/* ref src */", UID()), "window=qco[path];size=425x475")
GLOBAL_VAR(create_object_html)
GLOBAL_LIST_INIT(create_object_forms, list(/obj, /obj/structure, /obj/machinery, /obj/effect, /obj/item, /obj/mecha, /obj/item/clothing, /obj/item/stack, /obj/item/reagent_containers, /obj/item/gun))
/datum/admins/proc/create_object(var/mob/user)
if(!GLOB.create_object_html)
var/objectjs = null
objectjs = jointext(typesof(/obj), ";")
GLOB.create_object_html = file2text('html/create_object.html')
GLOB.create_object_html = replacetext(GLOB.create_object_html, "null /* object types */", "\"[objectjs]\"")
user << browse(replacetext(GLOB.create_object_html, "/* ref src */", UID()), "window=create_object;size=425x475")
/datum/admins/proc/quick_create_object(var/mob/user)
var/path = input("Select the path of the object you wish to create.", "Path", /obj) in GLOB.create_object_forms
var/html_form = GLOB.create_object_forms[path]
if(!html_form)
var/objectjs = jointext(typesof(path), ";")
html_form = file2text('html/create_object.html')
html_form = replacetext(html_form, "null /* object types */", "\"[objectjs]\"")
GLOB.create_object_forms[path] = html_form
user << browse(replacetext(html_form, "/* ref src */", UID()), "window=qco[path];size=425x475")
+13 -13
View File
@@ -1,15 +1,15 @@
/client/proc/create_poll()
set name = "Create Server Poll"
set category = "Server"
if(!check_rights(R_SERVER))
if(!check_rights(R_SERVER))
return
if(!dbcon.IsConnected())
if(!GLOB.dbcon.IsConnected())
to_chat(src, "<span class='danger'>Failed to establish database connection.</span>")
return
create_poll_window()
/client/proc/create_poll_window(var/errormessage = "")
if(!check_rights(R_SERVER))
if(!check_rights(R_SERVER))
return
var/output={"<!DOCTYPE html>
<html>
@@ -75,7 +75,7 @@ function onload() {
<form name='createpoll' action='byond://' method='post' style='padding-left:30px;padding-right:30px;padding-top:10px'>
<input type='hidden' name='createpollnumoptions' id='createpollnumoptions' value='0'>
<table><tr><td style='width:50%' style="vertical-align:top"><div id='polloptions'><div id='polloptionsinner'>
</div>
<input type='button' onclick='add_option()' value="Add Option"></input>
<input type='button' onclick='del_option()' value="Delete Option"></input>
@@ -99,7 +99,7 @@ function onload() {
src << browse(output, "window=createplayerpoll;size=950x500")
/client/proc/create_poll_function(href_list)
if(!check_rights(R_SERVER))
if(!check_rights(R_SERVER))
return
var/polltype = href_list["createpoll"]
if(polltype != POLLTYPE_OPTION && polltype != POLLTYPE_TEXT && polltype != POLLTYPE_RATING && polltype != POLLTYPE_MULTI)
@@ -122,15 +122,15 @@ function onload() {
create_poll_window("<font color='red'>Question cannot be blank.</font>")
return
question = sanitizeSQL(question)
var/starttime
var/endtime
var/DBQuery/query = dbcon.NewQuery("SELECT Now() AS starttime, ADDDATE(Now(), INTERVAL [poll_len] DAY) AS endtime")
var/DBQuery/query = GLOB.dbcon.NewQuery("SELECT Now() AS starttime, ADDDATE(Now(), INTERVAL [poll_len] DAY) AS endtime")
query.Execute()
while(query.NextRow())
starttime = query.item[1]
endtime = query.item[2]
var/pollquery = "INSERT INTO [format_table_name("poll_question")] (polltype, starttime, endtime, question, adminonly, multiplechoiceoptions, createdby_ckey, createdby_ip) VALUES ('[polltype]', '[starttime]', '[endtime]', '[question]', '[adminonly]', '[choice_amount]', '[sql_ckey]', '[address]')"
var/idquery = "SELECT id FROM [format_table_name("poll_question")] WHERE question = '[question]' AND starttime = '[starttime]' AND endtime = '[endtime]' AND createdby_ckey = '[sql_ckey]' AND createdby_ip = '[address]'"
var/list/option_queries = list()
@@ -175,15 +175,15 @@ function onload() {
if(descmax)
descmax = sanitizeSQL(descmax)
option_queries += "INSERT INTO [format_table_name("poll_option")] (pollid, text, percentagecalc, minval, maxval, descmin, descmid, descmax) VALUES ('{POLLID}', '[option]', '[percentagecalc]', '[minval]', '[maxval]', '[descmin]', '[descmid]', '[descmax]')"
query = dbcon.NewQuery(pollquery)
query = GLOB.dbcon.NewQuery(pollquery)
if(!query.Execute())
var/err = query.ErrorMsg()
create_poll_window("<font color='red'>An SQL error has occured while creating your poll</font>")
log_game("SQL ERROR adding new poll question to table. Error : \[[err]\]\n")
return
var/pollid = 0
query = dbcon.NewQuery(idquery)
query = GLOB.dbcon.NewQuery(idquery)
if(!query.Execute())
var/err = query.ErrorMsg()
create_poll_window("<font color='red'>An SQL error has occured while creating your poll</font>")
@@ -192,11 +192,11 @@ function onload() {
if(query.NextRow())
pollid = text2num(query.item[1])
for(var/querytext in option_queries)
query = dbcon.NewQuery(replacetext(idquery, "{POLLID}", pollid))
query = GLOB.dbcon.NewQuery(replacetext(idquery, "{POLLID}", pollid))
if(!query.Execute())
var/err = query.ErrorMsg()
create_poll_window("<font color='red'>An SQL error has occured while creating your poll</font>")
log_game("SQL ERROR obtaining id from poll_question table. Error : \[[err]\]\n")
return
create_poll_window("<font color='#008800'>Your poll has been successfully created</font>")
return pollid
return pollid
+9 -9
View File
@@ -1,9 +1,9 @@
/var/create_turf_html = null
/datum/admins/proc/create_turf(var/mob/user)
if(!create_turf_html)
var/turfjs = null
turfjs = jointext(typesof(/turf), ";")
create_turf_html = file2text('html/create_object.html')
create_turf_html = replacetext(create_turf_html, "null /* object types */", "\"[turfjs]\"")
user << browse(replacetext(create_turf_html, "/* ref src */", UID()), "window=create_turf;size=425x475")
GLOBAL_VAR(create_turf_html)
/datum/admins/proc/create_turf(var/mob/user)
if(!GLOB.create_turf_html)
var/turfjs = null
turfjs = jointext(typesof(/turf), ";")
GLOB.create_turf_html = file2text('html/create_object.html')
GLOB.create_turf_html = replacetext(GLOB.create_turf_html, "null /* object types */", "\"[turfjs]\"")
user << browse(replacetext(GLOB.create_turf_html, "/* ref src */", UID()), "window=create_turf;size=425x475")
+109 -108
View File
@@ -1,108 +1,109 @@
var/list/admin_datums = list()
/datum/admins
var/rank = "Temporary Admin"
var/client/owner = null
var/rights = 0
var/fakekey = null
var/big_brother = 0
var/datum/marked_datum
var/admincaster_screen = 0 //See newscaster.dm under machinery for a full description
var/datum/feed_message/admincaster_feed_message = new /datum/feed_message //These two will act as holders.
var/datum/feed_channel/admincaster_feed_channel = new /datum/feed_channel
var/admincaster_signature //What you'll sign the newsfeeds as
/datum/admins/New(initial_rank = "Temporary Admin", initial_rights = 0, ckey)
if(!ckey)
error("Admin datum created without a ckey argument. Datum has been deleted")
qdel(src)
return
admincaster_signature = "Nanotrasen Officer #[rand(0,9)][rand(0,9)][rand(0,9)]"
rank = initial_rank
rights = initial_rights
admin_datums[ckey] = src
/datum/admins/Destroy()
..()
return QDEL_HINT_HARDDEL_NOW
/datum/admins/proc/associate(client/C)
if(istype(C))
owner = C
owner.holder = src
owner.on_holder_add()
owner.add_admin_verbs() //TODO
owner.verbs -= /client/proc/readmin
GLOB.admins |= C
/datum/admins/proc/disassociate()
if(owner)
GLOB.admins -= owner
owner.remove_admin_verbs()
owner.holder = null
owner = null
/*
checks if usr is an admin with at least ONE of the flags in rights_required. (Note, they don't need all the flags)
if rights_required == 0, then it simply checks if they are an admin.
if it doesn't return 1 and show_msg=1 it will prints a message explaining why the check has failed
generally it would be used like so:
proc/admin_proc()
if(!check_rights(R_ADMIN)) return
to_chat(world, "you have enough rights!")
NOTE: it checks usr! not src! So if you're checking somebody's rank in a proc which they did not call
you will have to do something like if(client.holder.rights & R_ADMIN) yourself.
*/
/proc/check_rights(rights_required, show_msg=1, var/mob/user = usr)
if(user && user.client)
if(rights_required)
if(user.client.holder)
if(rights_required & user.client.holder.rights)
return 1
else
if(show_msg)
to_chat(user, "<font color='red'>Error: You do not have sufficient rights to do that. You require one of the following flags:[rights2text(rights_required," ")].</font>")
else
if(user.client.holder)
return 1
else
if(show_msg)
to_chat(user, "<font color='red'>Error: You are not an admin.</font>")
return 0
//probably a bit iffy - will hopefully figure out a better solution
/proc/check_if_greater_rights_than(client/other)
if(usr && usr.client)
if(usr.client.holder)
if(!other || !other.holder)
return 1
if(usr.client.holder.rights != other.holder.rights)
if( (usr.client.holder.rights & other.holder.rights) == other.holder.rights )
return 1 //we have all the rights they have and more
to_chat(usr, "<font color='red'>Error: Cannot proceed. They have more or equal rights to us.</font>")
return 0
/client/proc/deadmin()
admin_datums -= ckey
if(holder)
holder.disassociate()
qdel(holder)
return 1
//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)
if(rights_required && !(rights_required & subject.holder.rights))
return 0
return 1
return 0
/datum/admins/vv_edit_var(var_name, var_value)
return FALSE // no admin abuse
/datum/admins/can_vv_delete()
return FALSE // don't break shit either
GLOBAL_LIST_EMPTY(admin_datums)
GLOBAL_PROTECT(admin_datums) // This is protected because we dont want people making their own admin ranks, for obvious reasons
/datum/admins
var/rank = "Temporary Admin"
var/client/owner = null
var/rights = 0
var/fakekey = null
var/big_brother = 0
var/datum/marked_datum
var/admincaster_screen = 0 //See newscaster.dm under machinery for a full description
var/datum/feed_message/admincaster_feed_message = new /datum/feed_message //These two will act as holders.
var/datum/feed_channel/admincaster_feed_channel = new /datum/feed_channel
var/admincaster_signature //What you'll sign the newsfeeds as
/datum/admins/New(initial_rank = "Temporary Admin", initial_rights = 0, ckey)
if(!ckey)
error("Admin datum created without a ckey argument. Datum has been deleted")
qdel(src)
return
admincaster_signature = "Nanotrasen Officer #[rand(0,9)][rand(0,9)][rand(0,9)]"
rank = initial_rank
rights = initial_rights
GLOB.admin_datums[ckey] = src
/datum/admins/Destroy()
..()
return QDEL_HINT_HARDDEL_NOW
/datum/admins/proc/associate(client/C)
if(istype(C))
owner = C
owner.holder = src
owner.on_holder_add()
owner.add_admin_verbs() //TODO
owner.verbs -= /client/proc/readmin
GLOB.admins |= C
/datum/admins/proc/disassociate()
if(owner)
GLOB.admins -= owner
owner.remove_admin_verbs()
owner.holder = null
owner = null
/*
checks if usr is an admin with at least ONE of the flags in rights_required. (Note, they don't need all the flags)
if rights_required == 0, then it simply checks if they are an admin.
if it doesn't return 1 and show_msg=1 it will prints a message explaining why the check has failed
generally it would be used like so:
proc/admin_proc()
if(!check_rights(R_ADMIN)) return
to_chat(world, "you have enough rights!")
NOTE: it checks usr! not src! So if you're checking somebody's rank in a proc which they did not call
you will have to do something like if(client.holder.rights & R_ADMIN) yourself.
*/
/proc/check_rights(rights_required, show_msg=1, var/mob/user = usr)
if(user && user.client)
if(rights_required)
if(user.client.holder)
if(rights_required & user.client.holder.rights)
return 1
else
if(show_msg)
to_chat(user, "<font color='red'>Error: You do not have sufficient rights to do that. You require one of the following flags:[rights2text(rights_required," ")].</font>")
else
if(user.client.holder)
return 1
else
if(show_msg)
to_chat(user, "<font color='red'>Error: You are not an admin.</font>")
return 0
//probably a bit iffy - will hopefully figure out a better solution
/proc/check_if_greater_rights_than(client/other)
if(usr && usr.client)
if(usr.client.holder)
if(!other || !other.holder)
return 1
if(usr.client.holder.rights != other.holder.rights)
if( (usr.client.holder.rights & other.holder.rights) == other.holder.rights )
return 1 //we have all the rights they have and more
to_chat(usr, "<font color='red'>Error: Cannot proceed. They have more or equal rights to us.</font>")
return 0
/client/proc/deadmin()
GLOB.admin_datums -= ckey
if(holder)
holder.disassociate()
qdel(holder)
return 1
//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)
if(rights_required && !(rights_required & subject.holder.rights))
return 0
return 1
return 0
/datum/admins/vv_edit_var(var_name, var_value)
return FALSE // no admin abuse
/datum/admins/can_vv_delete()
return FALSE // don't break shit either
+10 -10
View File
@@ -34,9 +34,9 @@
cachedintel.cache = TRUE
return cachedintel
if(dbcon.IsConnected())
if(GLOB.dbcon.IsConnected())
var/rating_bad = config.ipintel_rating_bad
var/DBQuery/query_get_ip_intel = dbcon.NewQuery({"
var/DBQuery/query_get_ip_intel = GLOB.dbcon.NewQuery({"
SELECT date, intel, TIMESTAMPDIFF(MINUTE,date,NOW())
FROM [format_table_name("ipintel")]
WHERE
@@ -67,8 +67,8 @@
res.intel = ip_intel_query(ip)
if(updatecache && res.intel >= 0)
SSipintel.cache[ip] = res
if(dbcon.IsConnected())
var/DBQuery/query_add_ip_intel = dbcon.NewQuery("INSERT INTO [format_table_name("ipintel")] (ip, intel) VALUES (INET_ATON('[ip]'), [res.intel]) ON DUPLICATE KEY UPDATE intel = VALUES(intel), date = NOW()")
if(GLOB.dbcon.IsConnected())
var/DBQuery/query_add_ip_intel = GLOB.dbcon.NewQuery("INSERT INTO [format_table_name("ipintel")] (ip, intel) VALUES (INET_ATON('[ip]'), [res.intel]) ON DUPLICATE KEY UPDATE intel = VALUES(intel), date = NOW()")
query_add_ip_intel.Execute()
qdel(query_add_ip_intel)
@@ -139,7 +139,7 @@
return FALSE
if(!config.ipintel_whitelist)
return FALSE
if(!dbcon.IsConnected())
if(!GLOB.dbcon.IsConnected())
return FALSE
if(!ipintel_badip_check(t_ip))
return FALSE
@@ -160,7 +160,7 @@
rating_bad = sanitizeSQL(rating_bad)
valid_hours = sanitizeSQL(valid_hours)
var/check_sql = {"SELECT * FROM [format_table_name("ipintel")] WHERE ip = INET_ATON('[target_ip]') AND intel >= [rating_bad] AND (date + INTERVAL [valid_hours] HOUR) > NOW()"}
var/DBQuery/query_get_ip_intel = dbcon.NewQuery(check_sql)
var/DBQuery/query_get_ip_intel = GLOB.dbcon.NewQuery(check_sql)
if(!query_get_ip_intel.Execute())
log_debug("ipintel_badip_check reports failed query execution")
qdel(query_get_ip_intel)
@@ -175,7 +175,7 @@
if(!config.ipintel_whitelist)
return FALSE
var/target_sql_ckey = ckey(target_ckey)
var/DBQuery/query_whitelist_check = dbcon.NewQuery("SELECT * FROM [format_table_name("vpn_whitelist")] WHERE ckey = '[target_sql_ckey]'")
var/DBQuery/query_whitelist_check = GLOB.dbcon.NewQuery("SELECT * FROM [format_table_name("vpn_whitelist")] WHERE ckey = '[target_sql_ckey]'")
if(!query_whitelist_check.Execute())
var/err = query_whitelist_check.ErrorMsg()
log_debug("SQL ERROR on proc/vpn_whitelist_check for ckey '[target_sql_ckey]'. Error : \[[err]\]\n")
@@ -190,7 +190,7 @@
if(!reason_string)
return FALSE
reason_string = sanitizeSQL(reason_string)
var/DBQuery/query_whitelist_add = dbcon.NewQuery("INSERT INTO [format_table_name("vpn_whitelist")] (ckey,reason) VALUES ('[target_sql_ckey]','[reason_string]')")
var/DBQuery/query_whitelist_add = GLOB.dbcon.NewQuery("INSERT INTO [format_table_name("vpn_whitelist")] (ckey,reason) VALUES ('[target_sql_ckey]','[reason_string]')")
if(!query_whitelist_add.Execute())
var/err = query_whitelist_add.ErrorMsg()
log_debug("SQL ERROR on proc/vpn_whitelist_add for ckey '[target_sql_ckey]'. Error : \[[err]\]\n")
@@ -199,7 +199,7 @@
/proc/vpn_whitelist_remove(target_ckey)
var/target_sql_ckey = ckey(target_ckey)
var/DBQuery/query_whitelist_remove = dbcon.NewQuery("DELETE FROM [format_table_name("vpn_whitelist")] WHERE ckey = '[target_sql_ckey]'")
var/DBQuery/query_whitelist_remove = GLOB.dbcon.NewQuery("DELETE FROM [format_table_name("vpn_whitelist")] WHERE ckey = '[target_sql_ckey]'")
if(!query_whitelist_remove.Execute())
var/err = query_whitelist_remove.ErrorMsg()
log_debug("SQL ERROR on proc/vpn_whitelist_remove for ckey '[target_sql_ckey]'. Error : \[[err]\]\n")
@@ -225,4 +225,4 @@
if(vpn_whitelist_add(target_ckey))
to_chat(usr, "[target_ckey] was added to the VPN whitelist.")
else
to_chat(usr, "VPN whitelist unchanged.")
to_chat(usr, "VPN whitelist unchanged.")
@@ -1,167 +1,170 @@
/client/proc/edit_admin_permissions()
set category = "Admin"
set name = "Permissions Panel"
set desc = "Edit admin permissions"
if(!check_rights(R_PERMISSIONS))
return
usr.client.holder.edit_admin_permissions()
/datum/admins/proc/edit_admin_permissions()
if(!check_rights(R_PERMISSIONS))
return
var/output = {"<!DOCTYPE html>
<html>
<head>
<title>Permissions Panel</title>
<script type='text/javascript' src="search.js"></script>
<link rel='stylesheet' type='text/css' href="panels.css">
</head>
<body onload='selectTextField();updateSearch();'>
<div id='main'><table id='searchable' cellspacing='0'>
<tr class='title'>
<th style='width:125px;text-align:right;'>CKEY <a class='small' href='?src=[UID()];editrights=add'>\[+\]</a></th>
<th style='width:125px;'>RANK</th><th style='width:100%;'>PERMISSIONS</th>
</tr>
"}
for(var/adm_ckey in admin_datums)
var/datum/admins/D = admin_datums[adm_ckey]
if(!D) continue
var/rank = D.rank ? D.rank : "*none*"
var/rights = rights2text(D.rights," ")
if(!rights) rights = "*none*"
output += {"<tr>
<td style='text-align:right;'>[adm_ckey] <a class='small' href='?src=[UID()];editrights=remove;ckey=[adm_ckey]'>\[-\]</a></td>
<td><a href='?src=[UID()];editrights=rank;ckey=[adm_ckey]'>[rank]</a></td>
<td><a class='small' href='?src=[UID()];editrights=permissions;ckey=[adm_ckey]'>[rights]</a></font></td>
</tr>"}
/*output += "<tr>"
output += "<td style='text-align:right;'>[adm_ckey] <a class='small' href='?src=[UID()];editrights=remove;ckey=[adm_ckey]'>\[-\]</a></td>"
output += "<td><a href='?src=[UID()];editrights=rank;ckey=[adm_ckey]'>[rank]</a></td>"
output += "<td><a class='small' href='?src=[UID()];editrights=permissions;ckey=[adm_ckey]'>[rights]</a></font></td>"
output += "</tr>"*/
output += {"
</table></div>
<div id='top'><b>Search:</b> <input type='text' id='filter' value='' style='width:70%;' onkeyup='updateSearch();'></div>
</body>
</html>"}
usr << browse(output,"window=editrights;size=600x500")
/datum/admins/proc/log_admin_rank_modification(var/adm_ckey, var/new_rank)
if(config.admin_legacy_system) return
if(!usr.client)
return
if(!check_rights(R_PERMISSIONS))
return
establish_db_connection()
if(!dbcon.IsConnected())
to_chat(usr, "<span class='warning'>Failed to establish database connection</span>")
return
if(!adm_ckey || !new_rank)
return
adm_ckey = ckey(adm_ckey)
if(!adm_ckey)
return
if(!istext(adm_ckey) || !istext(new_rank))
return
var/DBQuery/select_query = dbcon.NewQuery("SELECT id FROM [format_table_name("admin")] WHERE ckey = '[adm_ckey]'")
select_query.Execute()
var/new_admin = 1
var/admin_id
while(select_query.NextRow())
new_admin = 0
admin_id = text2num(select_query.item[1])
if(new_admin)
var/DBQuery/insert_query = dbcon.NewQuery("INSERT INTO [format_table_name("admin")] (`id`, `ckey`, `rank`, `level`, `flags`) VALUES (null, '[adm_ckey]', '[new_rank]', -1, 0)")
insert_query.Execute()
var/DBQuery/log_query = dbcon.NewQuery("INSERT INTO `test`.[format_table_name("admin_log")] (`id` ,`datetime` ,`adminckey` ,`adminip` ,`log` ) VALUES (NULL , NOW( ) , '[usr.ckey]', '[usr.client.address]', 'Added new admin [adm_ckey] to rank [new_rank]');")
log_query.Execute()
to_chat(usr, "<span class='notice'>New admin added.</span>")
else
if(!isnull(admin_id) && isnum(admin_id))
var/DBQuery/insert_query = dbcon.NewQuery("UPDATE [format_table_name("admin")] SET rank = '[new_rank]' WHERE id = [admin_id]")
insert_query.Execute()
var/DBQuery/log_query = dbcon.NewQuery("INSERT INTO `test`.[format_table_name("admin_log")] (`id` ,`datetime` ,`adminckey` ,`adminip` ,`log` ) VALUES (NULL , NOW( ) , '[usr.ckey]', '[usr.client.address]', 'Edited the rank of [adm_ckey] to [new_rank]');")
log_query.Execute()
to_chat(usr, "<span class='notice'>Admin rank changed.</span>")
/datum/admins/proc/log_admin_permission_modification(var/adm_ckey, var/new_permission)
if(config.admin_legacy_system)
return
if(!usr.client)
return
if(!check_rights(R_PERMISSIONS))
return
establish_db_connection()
if(!dbcon.IsConnected())
to_chat(usr, "<span class='warning'>Failed to establish database connection</span>")
return
if(!adm_ckey || !new_permission)
return
adm_ckey = ckey(adm_ckey)
if(!adm_ckey)
return
if(istext(new_permission))
new_permission = text2num(new_permission)
if(!istext(adm_ckey) || !isnum(new_permission))
return
var/DBQuery/select_query = dbcon.NewQuery("SELECT id, flags FROM [format_table_name("admin")] WHERE ckey = '[adm_ckey]'")
select_query.Execute()
var/admin_id
var/admin_rights
while(select_query.NextRow())
admin_id = text2num(select_query.item[1])
admin_rights = text2num(select_query.item[2])
if(!admin_id)
return
if(admin_rights & new_permission) //This admin already has this permission, so we are removing it.
var/DBQuery/insert_query = dbcon.NewQuery("UPDATE [format_table_name("admin")] SET flags = [admin_rights & ~new_permission] WHERE id = [admin_id]")
insert_query.Execute()
var/DBQuery/log_query = dbcon.NewQuery("INSERT INTO `test`.[format_table_name("admin_log")] (`id` ,`datetime` ,`adminckey` ,`adminip` ,`log` ) VALUES (NULL , NOW( ) , '[usr.ckey]', '[usr.client.address]', 'Removed permission [rights2text(new_permission)] (flag = [new_permission]) to admin [adm_ckey]');")
log_query.Execute()
to_chat(usr, "<span class='notice'>Permission removed.</span>")
else //This admin doesn't have this permission, so we are adding it.
var/DBQuery/insert_query = dbcon.NewQuery("UPDATE [format_table_name("admin")] SET flags = '[admin_rights | new_permission]' WHERE id = [admin_id]")
insert_query.Execute()
var/DBQuery/log_query = dbcon.NewQuery("INSERT INTO `test`.[format_table_name("admin_log")] (`id` ,`datetime` ,`adminckey` ,`adminip` ,`log` ) VALUES (NULL , NOW( ) , '[usr.ckey]', '[usr.client.address]', 'Added permission [rights2text(new_permission)] (flag = [new_permission]) to admin [adm_ckey]')")
log_query.Execute()
to_chat(usr, "<span class='notice'>Permission added.</span>")
/datum/admins/proc/updateranktodb(ckey,newrank)
establish_db_connection()
if(!dbcon.IsConnected())
return
if(!check_rights(R_PERMISSIONS))
return
var/sql_ckey = sanitizeSQL(ckey)
var/sql_admin_rank = sanitizeSQL(newrank)
var/DBQuery/query_update = dbcon.NewQuery("UPDATE [format_table_name("player")] SET lastadminrank = '[sql_admin_rank]' WHERE ckey = '[sql_ckey]'")
query_update.Execute()
/client/proc/edit_admin_permissions()
set category = "Admin"
set name = "Permissions Panel"
set desc = "Edit admin permissions"
if(!check_rights(R_PERMISSIONS))
return
usr.client.holder.edit_admin_permissions()
/datum/admins/proc/edit_admin_permissions()
if(!check_rights(R_PERMISSIONS))
return
var/output = {"<!DOCTYPE html>
<html>
<head>
<title>Permissions Panel</title>
<script type='text/javascript' src="search.js"></script>
<link rel='stylesheet' type='text/css' href="panels.css">
</head>
<body onload='selectTextField();updateSearch();'>
<div id='main'><table id='searchable' cellspacing='0'>
<tr class='title'>
<th style='width:125px;text-align:right;'>CKEY <a class='small' href='?src=[UID()];editrights=add'>\[+\]</a></th>
<th style='width:125px;'>RANK</th><th style='width:100%;'>PERMISSIONS</th>
</tr>
"}
for(var/adm_ckey in GLOB.admin_datums)
var/datum/admins/D = GLOB.admin_datums[adm_ckey]
if(!D) continue
var/rank = D.rank ? D.rank : "*none*"
var/rights = rights2text(D.rights," ")
if(!rights) rights = "*none*"
output += {"<tr>
<td style='text-align:right;'>[adm_ckey] <a class='small' href='?src=[UID()];editrights=remove;ckey=[adm_ckey]'>\[-\]</a></td>
<td><a href='?src=[UID()];editrights=rank;ckey=[adm_ckey]'>[rank]</a></td>
<td><a class='small' href='?src=[UID()];editrights=permissions;ckey=[adm_ckey]'>[rights]</a></font></td>
</tr>"}
/*output += "<tr>"
output += "<td style='text-align:right;'>[adm_ckey] <a class='small' href='?src=[UID()];editrights=remove;ckey=[adm_ckey]'>\[-\]</a></td>"
output += "<td><a href='?src=[UID()];editrights=rank;ckey=[adm_ckey]'>[rank]</a></td>"
output += "<td><a class='small' href='?src=[UID()];editrights=permissions;ckey=[adm_ckey]'>[rights]</a></font></td>"
output += "</tr>"*/
output += {"
</table></div>
<div id='top'><b>Search:</b> <input type='text' id='filter' value='' style='width:70%;' onkeyup='updateSearch();'></div>
</body>
</html>"}
usr << browse(output,"window=editrights;size=600x500")
/datum/admins/proc/log_admin_rank_modification(var/adm_ckey, var/new_rank)
if(config.admin_legacy_system) return
if(!usr.client)
return
if(!check_rights(R_PERMISSIONS))
return
establish_db_connection()
if(!GLOB.dbcon.IsConnected())
to_chat(usr, "<span class='warning'>Failed to establish database connection</span>")
return
if(!adm_ckey || !new_rank)
return
adm_ckey = ckey(adm_ckey)
if(!adm_ckey)
return
if(!istext(adm_ckey) || !istext(new_rank))
return
var/DBQuery/select_query = GLOB.dbcon.NewQuery("SELECT id FROM [format_table_name("admin")] WHERE ckey = '[adm_ckey]'")
select_query.Execute()
var/new_admin = 1
var/admin_id
while(select_query.NextRow())
new_admin = 0
admin_id = text2num(select_query.item[1])
flag_account_for_forum_sync(adm_ckey)
if(new_admin)
var/DBQuery/insert_query = GLOB.dbcon.NewQuery("INSERT INTO [format_table_name("admin")] (`id`, `ckey`, `rank`, `level`, `flags`) VALUES (null, '[adm_ckey]', '[new_rank]', -1, 0)")
insert_query.Execute()
var/DBQuery/log_query = GLOB.dbcon.NewQuery("INSERT INTO [format_table_name("admin_log")] (`datetime` ,`adminckey` ,`adminip` ,`log` ) VALUES (Now() , '[usr.ckey]', '[usr.client.address]', 'Added new admin [adm_ckey] to rank [new_rank]');")
log_query.Execute()
to_chat(usr, "<span class='notice'>New admin added.</span>")
else
if(!isnull(admin_id) && isnum(admin_id))
var/DBQuery/insert_query = GLOB.dbcon.NewQuery("UPDATE [format_table_name("admin")] SET rank = '[new_rank]' WHERE id = [admin_id]")
insert_query.Execute()
var/DBQuery/log_query = GLOB.dbcon.NewQuery("INSERT INTO [format_table_name("admin_log")] (`datetime` ,`adminckey` ,`adminip` ,`log` ) VALUES (Now() , '[usr.ckey]', '[usr.client.address]', 'Edited the rank of [adm_ckey] to [new_rank]');")
log_query.Execute()
to_chat(usr, "<span class='notice'>Admin rank changed.</span>")
/datum/admins/proc/log_admin_permission_modification(var/adm_ckey, var/new_permission)
if(config.admin_legacy_system)
return
if(!usr.client)
return
if(!check_rights(R_PERMISSIONS))
return
establish_db_connection()
if(!GLOB.dbcon.IsConnected())
to_chat(usr, "<span class='warning'>Failed to establish database connection</span>")
return
if(!adm_ckey || !new_permission)
return
adm_ckey = ckey(adm_ckey)
if(!adm_ckey)
return
if(istext(new_permission))
new_permission = text2num(new_permission)
if(!istext(adm_ckey) || !isnum(new_permission))
return
var/DBQuery/select_query = GLOB.dbcon.NewQuery("SELECT id, flags FROM [format_table_name("admin")] WHERE ckey = '[adm_ckey]'")
select_query.Execute()
var/admin_id
var/admin_rights
while(select_query.NextRow())
admin_id = text2num(select_query.item[1])
admin_rights = text2num(select_query.item[2])
if(!admin_id)
return
flag_account_for_forum_sync(adm_ckey)
if(admin_rights & new_permission) //This admin already has this permission, so we are removing it.
var/DBQuery/insert_query = GLOB.dbcon.NewQuery("UPDATE [format_table_name("admin")] SET flags = [admin_rights & ~new_permission] WHERE id = [admin_id]")
insert_query.Execute()
var/DBQuery/log_query = GLOB.dbcon.NewQuery("INSERT INTO [format_table_name("admin_log")] (`datetime` ,`adminckey` ,`adminip` ,`log` ) VALUES (Now() , '[usr.ckey]', '[usr.client.address]', 'Removed permission [rights2text(new_permission)] (flag = [new_permission]) to admin [adm_ckey]');")
log_query.Execute()
to_chat(usr, "<span class='notice'>Permission removed.</span>")
else //This admin doesn't have this permission, so we are adding it.
var/DBQuery/insert_query = GLOB.dbcon.NewQuery("UPDATE [format_table_name("admin")] SET flags = '[admin_rights | new_permission]' WHERE id = [admin_id]")
insert_query.Execute()
var/DBQuery/log_query = GLOB.dbcon.NewQuery("INSERT INTO [format_table_name("admin_log")] (`datetime` ,`adminckey` ,`adminip` ,`log` ) VALUES (Now() , '[usr.ckey]', '[usr.client.address]', 'Added permission [rights2text(new_permission)] (flag = [new_permission]) to admin [adm_ckey]')")
log_query.Execute()
to_chat(usr, "<span class='notice'>Permission added.</span>")
/datum/admins/proc/updateranktodb(ckey,newrank)
establish_db_connection()
if(!GLOB.dbcon.IsConnected())
return
if(!check_rights(R_PERMISSIONS))
return
var/sql_ckey = sanitizeSQL(ckey)
var/sql_admin_rank = sanitizeSQL(newrank)
var/DBQuery/query_update = GLOB.dbcon.NewQuery("UPDATE [format_table_name("player")] SET lastadminrank = '[sql_admin_rank]' WHERE ckey = '[sql_ckey]'")
query_update.Execute()
flag_account_for_forum_sync(sql_ckey)
+14 -9
View File
@@ -2,6 +2,10 @@
/datum/admins/proc/player_panel_new()//The new one
if(!usr.client.holder)
return
// This stops the panel from being invoked by mentors who press F7.
if(!check_rights(R_ADMIN))
message_admins("[key_name_admin(usr)] attempted to invoke player panel without admin rights. If this is a mentor, its a chance they accidentally hit F7. If this is NOT a mentor, there is a high chance an exploit is being used")
return
var/dat = "<html><head><title>Admin Player Panel</title></head>"
//javascript, the part that does most of the work~
@@ -392,11 +396,12 @@
var/logout_status
logout_status = M.client ? "" : " <i>(logged out)</i>"
var/dname = M.real_name
var/area/A = get_area(M)
if(!dname)
dname = M
return {"<tr><td><a href='?src=[UID()];adminplayeropts=[M.UID()]'>[dname]</a><b>[caption]</b>[logout_status][M.stat == 2 ? " <b><font color=red>(DEAD)</font></b>" : ""]</td>
<td><A href='?src=[usr.UID()];priv_msg=[M.client ? M.client.UID() : null]'>PM</A></td>[close ? "</tr>" : ""]"}
return {"<tr><td><a href='?src=[UID()];adminplayeropts=[M.UID()]'>[dname]</a><b>[caption]</b>[logout_status][istype(A, /area/security/permabrig) ? "<b><font color=red> (PERMA) </b></font>" : ""][M.stat == 2 ? " <b><font color=red>(DEAD)</font></b>" : ""]</td>
<td><A href='?src=[usr.UID()];priv_msg=[M.client ? M.client.UID() : null]'>PM</A> [ADMIN_FLW(M, "FLW")] </td>[close ? "</tr>" : ""]"}
/datum/admins/proc/check_antagonists()
if(!check_rights(R_ADMIN)) return
@@ -465,7 +470,7 @@
if(GAMEMODE_IS_BLOB)
var/datum/game_mode/blob/mode = SSticker.mode
dat += "<br><table cellspacing=5><tr><td><B>Blob</B></td><td></td><td></td></tr>"
dat += "<tr><td><i>Progress: [blobs.len]/[mode.blobwincount]</i></td></tr>"
dat += "<tr><td><i>Progress: [GLOB.blobs.len]/[mode.blobwincount]</i></td></tr>"
for(var/datum/mind/blob in mode.infected_crew)
var/mob/M = blob.current
@@ -475,7 +480,7 @@
else
dat += "<tr><td><i>Blob not found!</i></td></tr>"
dat += "</table>"
if(SSticker.mode.blob_overminds.len)
dat += check_role_table("Blob Overminds", SSticker.mode.blob_overminds)
@@ -492,7 +497,7 @@
dat += check_role_table("Ninjas", ticker.mode.ninjas)*/
if(SSticker.mode.cult.len)
dat += check_role_table("Cultists", SSticker.mode.cult, 0)
dat += check_role_table("Cultists", SSticker.mode.cult)
dat += "<br> use <a href='?src=[UID()];cult_mindspeak=[UID()]'>Cult Mindspeak</a>"
if(GAMEMODE_IS_CULT)
var/datum/game_mode/cult/cult_round = SSticker.mode
@@ -541,9 +546,9 @@
if(SSticker.mode.eventmiscs.len)
dat += check_role_table("Event Roles", SSticker.mode.eventmiscs)
if(ts_spiderlist.len)
if(GLOB.ts_spiderlist.len)
var/list/spider_minds = list()
for(var/mob/living/simple_animal/hostile/poison/terror_spider/S in ts_spiderlist)
for(var/mob/living/simple_animal/hostile/poison/terror_spider/S in GLOB.ts_spiderlist)
if(S.ckey)
spider_minds += S.mind
if(spider_minds.len)
@@ -551,10 +556,10 @@
var/count_eggs = 0
var/count_spiderlings = 0
for(var/obj/structure/spider/eggcluster/terror_eggcluster/E in ts_egg_list)
for(var/obj/structure/spider/eggcluster/terror_eggcluster/E in GLOB.ts_egg_list)
if(is_station_level(E.z))
count_eggs += E.spiderling_number
for(var/obj/structure/spider/spiderling/terror_spiderling/L in ts_spiderling_list)
for(var/obj/structure/spider/spiderling/terror_spiderling/L in GLOB.ts_spiderling_list)
if(!L.stillborn && is_station_level(L.z))
count_spiderlings += 1
dat += "<table cellspacing=5><TR><TD>Growing TS on-station: [count_eggs] egg[count_eggs != 1 ? "s" : ""], [count_spiderlings] spiderling[count_spiderlings != 1 ? "s" : ""]. </TD></TR></TABLE>"
+4 -4
View File
@@ -27,8 +27,8 @@
<B>Bombs</b><br>
[check_rights(R_SERVER, 0) ? "&nbsp;&nbsp;<A href='?src=[UID()];secretsfun=togglebombcap'>Toggle bomb cap</A><br>" : "<br>"]
<B>Lists</b><br>
<A href='?src=[UID()];secretsadmin=list_signalers'>Show last [length(lastsignalers)] signalers</A>&nbsp;&nbsp;
<A href='?src=[UID()];secretsadmin=list_lawchanges'>Show last [length(lawchanges)] law changes</A><BR>
<A href='?src=[UID()];secretsadmin=list_signalers'>Show last [length(GLOB.lastsignalers)] signalers</A>&nbsp;&nbsp;
<A href='?src=[UID()];secretsadmin=list_lawchanges'>Show last [length(GLOB.lawchanges)] law changes</A><BR>
<A href='?src=[UID()];secretsadmin=DNA'>List DNA (Blood)</A>&nbsp;&nbsp;
<A href='?src=[UID()];secretsadmin=fingerprints'>List Fingerprints</A><BR>
<B>Power</b><br>
@@ -49,7 +49,7 @@
<B>Security Level Elevated</B><BR>
<BR>
<A href='?src=[UID()];secretscoder=maint_access_engiebrig'>Change all maintenance doors to engie/brig access only</A><BR>
<A href='?src=[UID()];secretscoder=maint_access_brig'>Change all maintenance doors to brig access only</A><BR>
<A href='?src=[UID()];secretscoder=maint_ACCESS_BRIG'>Change all maintenance doors to brig access only</A><BR>
<A href='?src=[UID()];secretscoder=infinite_sec'>Remove cap on security officers</A>&nbsp;&nbsp;
<BR>
<B>Coder Secrets</B><BR>
@@ -105,7 +105,7 @@
<A href='?src=[UID()];secretsfun=monkey'>Turn all humans into monkeys</A><BR>
<A href='?src=[UID()];secretsfun=fakeguns'>Make all items look like guns</A><BR>
<A href='?src=[UID()];secretsfun=prisonwarp'>Warp all Players to Prison</A><BR>
<A href='?src=[UID()];secretsfun=retardify'>Make all players retarded</A><BR>
<A href='?src=[UID()];secretsfun=stupify'>Make all players stupid</A><BR>
<b>Misc</b><br>
<A href='?src=[UID()];secretsfun=sec_classic1'>Remove firesuits, grilles, and pods</A>&nbsp;&nbsp;
<A href='?src=[UID()];secretsfun=tripleAI'>Triple AI mode (needs to be used in the lobby)</A><BR>
+40 -26
View File
@@ -1,25 +1,33 @@
/proc/add_note(target_ckey, notetext, timestamp, adminckey, logged = 1, server, checkrights = 1)
if(checkrights && !check_rights(R_ADMIN|R_MOD))
return
if(!dbcon.IsConnected())
if(!GLOB.dbcon.IsConnected())
to_chat(usr, "<span class='danger'>Failed to establish database connection.</span>")
return
if(!target_ckey)
var/new_ckey = ckey(clean_input("Who would you like to add a note for?","Enter a ckey",null))
if(!new_ckey)
return
new_ckey = ckey(new_ckey)
var/DBQuery/query_find_ckey = dbcon.NewQuery("SELECT ckey FROM [format_table_name("player")] WHERE ckey = '[new_ckey]'")
if(!query_find_ckey.Execute())
var/err = query_find_ckey.ErrorMsg()
log_game("SQL ERROR obtaining ckey from player table. Error : \[[err]\]\n")
return
if(!query_find_ckey.NextRow())
to_chat(usr, "<span class='redtext'>[new_ckey] has not been seen before, you can only add notes to known players.</span>")
return
else
target_ckey = new_ckey
var/target_sql_ckey = ckey(target_ckey)
target_ckey = ckey(new_ckey)
else
target_ckey = ckey(target_ckey)
var/DBQuery/query_find_ckey = GLOB.dbcon.NewQuery("SELECT ckey, exp FROM [format_table_name("player")] WHERE ckey = '[target_ckey]'")
if(!query_find_ckey.Execute())
var/err = query_find_ckey.ErrorMsg()
log_game("SQL ERROR obtaining ckey from player table. Error : \[[err]\]\n")
return
if(!query_find_ckey.NextRow())
to_chat(usr, "<span class='redtext'>[target_ckey] has not been seen before, you can only add notes to known players.</span>")
return
var/exp_data = query_find_ckey.item[2]
var/crew_number = 0
if(exp_data)
var/list/play_records = params2list(exp_data)
crew_number = play_records[EXP_TYPE_CREW]
if(!notetext)
notetext = input(usr,"Write your note","Add Note") as message|null
if(!notetext)
@@ -38,7 +46,7 @@
if(config && config.server_name)
server = config.server_name
server = sanitizeSQL(server)
var/DBQuery/query_noteadd = dbcon.NewQuery("INSERT INTO [format_table_name("notes")] (ckey, timestamp, notetext, adminckey, server) VALUES ('[target_sql_ckey]', '[timestamp]', '[notetext]', '[admin_sql_ckey]', '[server]')")
var/DBQuery/query_noteadd = GLOB.dbcon.NewQuery("INSERT INTO [format_table_name("notes")] (ckey, timestamp, notetext, adminckey, server, crew_playtime) VALUES ('[target_ckey]', '[timestamp]', '[notetext]', '[admin_sql_ckey]', '[server]', '[crew_number]')")
if(!query_noteadd.Execute())
var/err = query_noteadd.ErrorMsg()
log_game("SQL ERROR adding new note to table. Error : \[[err]\]\n")
@@ -54,13 +62,13 @@
var/ckey
var/notetext
var/adminckey
if(!dbcon.IsConnected())
if(!GLOB.dbcon.IsConnected())
to_chat(usr, "<span class='danger'>Failed to establish database connection.</span>")
return
if(!note_id)
return
note_id = text2num(note_id)
var/DBQuery/query_find_note_del = dbcon.NewQuery("SELECT ckey, notetext, adminckey FROM [format_table_name("notes")] WHERE id = [note_id]")
var/DBQuery/query_find_note_del = GLOB.dbcon.NewQuery("SELECT ckey, notetext, adminckey FROM [format_table_name("notes")] WHERE id = [note_id]")
if(!query_find_note_del.Execute())
var/err = query_find_note_del.ErrorMsg()
log_game("SQL ERROR obtaining ckey, notetext, adminckey from player table. Error : \[[err]\]\n")
@@ -69,7 +77,7 @@
ckey = query_find_note_del.item[1]
notetext = query_find_note_del.item[2]
adminckey = query_find_note_del.item[3]
var/DBQuery/query_del_note = dbcon.NewQuery("DELETE FROM [format_table_name("notes")] WHERE id = [note_id]")
var/DBQuery/query_del_note = GLOB.dbcon.NewQuery("DELETE FROM [format_table_name("notes")] WHERE id = [note_id]")
if(!query_del_note.Execute())
var/err = query_del_note.ErrorMsg()
log_game("SQL ERROR removing note from table. Error : \[[err]\]\n")
@@ -81,7 +89,7 @@
/proc/edit_note(note_id)
if(!check_rights(R_ADMIN|R_MOD))
return
if(!dbcon.IsConnected())
if(!GLOB.dbcon.IsConnected())
to_chat(usr, "<span class='danger'>Failed to establish database connection.</span>")
return
if(!note_id)
@@ -89,7 +97,7 @@
note_id = text2num(note_id)
var/target_ckey
var/sql_ckey = usr.ckey
var/DBQuery/query_find_note_edit = dbcon.NewQuery("SELECT ckey, notetext, adminckey FROM [format_table_name("notes")] WHERE id = [note_id]")
var/DBQuery/query_find_note_edit = GLOB.dbcon.NewQuery("SELECT ckey, notetext, adminckey FROM [format_table_name("notes")] WHERE id = [note_id]")
if(!query_find_note_edit.Execute())
var/err = query_find_note_edit.ErrorMsg()
log_game("SQL ERROR obtaining notetext from notes table. Error : \[[err]\]\n")
@@ -104,7 +112,7 @@
new_note = sanitizeSQL(new_note)
var/edit_text = "Edited by [sql_ckey] on [SQLtime()] from \"[old_note]\" to \"[new_note]\"<hr>"
edit_text = sanitizeSQL(edit_text)
var/DBQuery/query_update_note = dbcon.NewQuery("UPDATE [format_table_name("notes")] SET notetext = '[new_note]', last_editor = '[sql_ckey]', edits = CONCAT(IFNULL(edits,''),'[edit_text]') WHERE id = [note_id]")
var/DBQuery/query_update_note = GLOB.dbcon.NewQuery("UPDATE [format_table_name("notes")] SET notetext = '[new_note]', last_editor = '[sql_ckey]', edits = CONCAT(IFNULL(edits,''),'[edit_text]') WHERE id = [note_id]")
if(!query_update_note.Execute())
var/err = query_update_note.ErrorMsg()
log_game("SQL ERROR editing note. Error : \[[err]\]\n")
@@ -131,10 +139,10 @@
output = navbar
if(target_ckey)
var/target_sql_ckey = ckey(target_ckey)
var/DBQuery/query_get_notes = dbcon.NewQuery("SELECT id, timestamp, notetext, adminckey, last_editor, server FROM [format_table_name("notes")] WHERE ckey = '[target_sql_ckey]' ORDER BY timestamp")
var/DBQuery/query_get_notes = GLOB.dbcon.NewQuery("SELECT id, timestamp, notetext, adminckey, last_editor, server, crew_playtime FROM [format_table_name("notes")] WHERE ckey = '[target_sql_ckey]' ORDER BY timestamp")
if(!query_get_notes.Execute())
var/err = query_get_notes.ErrorMsg()
log_game("SQL ERROR obtaining ckey, notetext, adminckey, last_editor, server from notes table. Error : \[[err]\]\n")
log_game("SQL ERROR obtaining ckey, notetext, adminckey, last_editor, server, crew_playtime from notes table. Error : \[[err]\]\n")
return
output += "<h2><center>Notes of [target_ckey]</center></h2>"
if(!linkless)
@@ -147,7 +155,13 @@
var/adminckey = query_get_notes.item[4]
var/last_editor = query_get_notes.item[5]
var/server = query_get_notes.item[6]
output += "<b>[timestamp] | [server] | [adminckey]</b>"
var/mins = text2num(query_get_notes.item[7])
output += "<b>[timestamp] | [server] | [adminckey]"
if(mins)
var/playstring = get_exp_format(mins)
output += " | [playstring] as Crew"
output += "</b>"
if(!linkless)
output += " <a href='?_src_=holder;removenote=[id]'>\[Remove Note\]</a> <a href='?_src_=holder;editnote=[id]'>\[Edit Note\]</a>"
if(last_editor)
@@ -167,7 +181,7 @@
search = "^\[^\[:alpha:\]\]"
else
search = "^[index]"
var/DBQuery/query_list_notes = dbcon.NewQuery("SELECT DISTINCT ckey FROM [format_table_name("notes")] WHERE ckey REGEXP '[search]' ORDER BY ckey")
var/DBQuery/query_list_notes = GLOB.dbcon.NewQuery("SELECT DISTINCT ckey FROM [format_table_name("notes")] WHERE ckey REGEXP '[search]' ORDER BY ckey")
if(!query_list_notes.Execute())
var/err = query_list_notes.ErrorMsg()
log_game("SQL ERROR obtaining ckey from notes table. Error : \[[err]\]\n")
@@ -182,10 +196,10 @@
/proc/show_player_info_irc(var/key as text)
var/target_sql_ckey = ckey(key)
var/DBQuery/query_get_notes = dbcon.NewQuery("SELECT timestamp, notetext, adminckey, server FROM [format_table_name("notes")] WHERE ckey = '[target_sql_ckey]' ORDER BY timestamp")
var/DBQuery/query_get_notes = GLOB.dbcon.NewQuery("SELECT timestamp, notetext, adminckey, server, crew_playtime FROM [format_table_name("notes")] WHERE ckey = '[target_sql_ckey]' ORDER BY timestamp")
if(!query_get_notes.Execute())
var/err = query_get_notes.ErrorMsg()
log_game("SQL ERROR obtaining timestamp, notetext, adminckey, server from notes table. Error : \[[err]\]\n")
log_game("SQL ERROR obtaining timestamp, notetext, adminckey, server, crew_playtime from notes table. Error : \[[err]\]\n")
return
var/output = " Info on [key]%0D%0A"
while(query_get_notes.NextRow())
+3500 -3480
View File
File diff suppressed because it is too large Load Diff
+36 -36
View File
@@ -1,36 +1,36 @@
/proc/getbrokeninhands()
set name = "Broken Sprite List"
set category = "Debug"
var/text
for(var/A in typesof(/obj/item))
var/obj/item/O = new A( locate(1,1,1) )
if(!O) continue
var/icon/IL = new(O.lefthand_file)
var/list/Lstates = IL.IconStates()
var/icon/IR = new(O.righthand_file)
var/list/Rstates = IR.IconStates()
var/icon/J = new(O.icon)
var/list/istates = J.IconStates()
if(!Lstates.Find(O.icon_state) && !Lstates.Find(O.item_state))
if(O.icon_state)
text += "[O.type] is missing left hand icon called \"[O.icon_state]\".\n"
if(!Rstates.Find(O.icon_state) && !Rstates.Find(O.item_state))
if(O.icon_state)
text += "[O.type] is missing right hand icon called \"[O.icon_state]\".\n"
if(O.icon_state)
if(!istates.Find(O.icon_state))
text += "[O.type] is missing normal icon called \"[O.icon_state]\" in \"[O.icon]\".\n"
//if(O.item_state)
// if(!istates.Find(O.item_state))
// text += "[O.type] MISSING NORMAL ICON CALLED\n\"[O.item_state]\" IN \"[O.icon]\"\n"
//text+="\n"
qdel(O)
if(text)
var/F = file("broken_hand_icons.txt")
fdel(F)
to_chat(F, text)
to_chat(world, "Completed and written to [F]")
/proc/getbrokeninhands()
set name = "Broken Sprite List"
set category = "Debug"
var/text
for(var/A in typesof(/obj/item))
var/obj/item/O = new A( locate(1,1,1) )
if(!O) continue
var/icon/IL = new(O.lefthand_file)
var/list/Lstates = IL.IconStates()
var/icon/IR = new(O.righthand_file)
var/list/Rstates = IR.IconStates()
var/icon/J = new(O.icon)
var/list/istates = J.IconStates()
if(!Lstates.Find(O.icon_state) && !Lstates.Find(O.item_state))
if(O.icon_state)
text += "[O.type] is missing left hand icon called \"[O.icon_state]\".\n"
if(!Rstates.Find(O.icon_state) && !Rstates.Find(O.item_state))
if(O.icon_state)
text += "[O.type] is missing right hand icon called \"[O.icon_state]\".\n"
if(O.icon_state)
if(!istates.Find(O.icon_state))
text += "[O.type] is missing normal icon called \"[O.icon_state]\" in \"[O.icon]\".\n"
//if(O.item_state)
// if(!istates.Find(O.item_state))
// text += "[O.type] MISSING NORMAL ICON CALLED\n\"[O.item_state]\" IN \"[O.icon]\"\n"
//text+="\n"
qdel(O)
if(text)
var/F = file("broken_hand_icons.txt")
fdel(F)
to_chat(F, text)
to_chat(world, "Completed and written to [F]")
+187 -187
View File
@@ -1,187 +1,187 @@
//This is a list of words which are ignored by the parser when comparing message contents for names. MUST BE IN LOWER CASE!
var/list/adminhelp_ignored_words = list("unknown","the","a","an","of","monkey","alien","as")
/client/verb/adminhelp()
set category = "Admin"
set name = "Adminhelp"
//handle muting and automuting
if(prefs.muted & MUTE_ADMINHELP)
to_chat(src, "<font color='red'>Error: Admin-PM: You cannot send adminhelps (Muted).</font>")
return
adminhelped = 1 //Determines if they get the message to reply by clicking the name.
var/msg
var/list/type = list("Mentorhelp","Adminhelp")
var/selected_type = input("Pick a category.", "Admin Help", null, null) as null|anything in type
if(selected_type)
msg = clean_input("Please enter your message.", "Admin Help", null)
//clean the input msg
if(!msg)
return
if(handle_spam_prevention(msg, MUTE_ADMINHELP, OOC_COOLDOWN))
return
msg = sanitize_simple(copytext(msg,1,MAX_MESSAGE_LEN))
if(!msg) return
var/original_msg = msg
//explode the input msg into a list
var/list/msglist = splittext(msg, " ")
//generate keywords lookup
var/list/surnames = list()
var/list/forenames = list()
var/list/ckeys = list()
for(var/mob/M in GLOB.mob_list)
var/list/indexing = list(M.real_name, M.name)
if(M.mind) indexing += M.mind.name
for(var/string in indexing)
var/list/L = splittext(string, " ")
var/surname_found = 0
//surnames
for(var/i=L.len, i>=1, i--)
var/word = ckey(L[i])
if(word)
surnames[word] = M
surname_found = i
break
//forenames
for(var/i=1, i<surname_found, i++)
var/word = ckey(L[i])
if(word)
forenames[word] = M
//ckeys
ckeys[M.ckey] = M
var/ai_found = 0
msg = ""
var/list/mobs_found = list()
for(var/original_word in msglist)
var/word = ckey(original_word)
if(word)
if(!(word in adminhelp_ignored_words))
if(word == "ai")
ai_found = 1
else
var/mob/found = ckeys[word]
if(!found)
found = surnames[word]
if(!found)
found = forenames[word]
if(found)
if(!(found in mobs_found))
mobs_found += found
if(!ai_found && isAI(found))
ai_found = 1
msg += "<b><font color='black'>[original_word] </font></b> "
continue
msg += "[original_word] "
if(!mob) return //this doesn't happen
//send this msg to all admins
var/admin_number_afk = 0
var/list/mentorholders = list()
var/list/modholders = list()
var/list/adminholders = list()
for(var/client/X in GLOB.admins)
if(check_rights(R_ADMIN, 0, X.mob))
if(X.is_afk())
admin_number_afk++
adminholders += X
continue
if(check_rights(R_MOD, 0, X.mob))
modholders += X
continue
if(check_rights(R_MENTOR, 0, X.mob))
mentorholders += X
continue
var/ticketNum // Holder for the ticket number
var/prunedmsg ="[src]: [msg]" // Message without links
var/datum/ticket/T
var/isMhelp = selected_type == "Mentorhelp"
var/span
if(isMhelp)
span = "<span class='mentorhelp'>"
if(SSmentor_tickets.checkForOpenTicket(src)) // If user already has an open ticket
T = SSmentor_tickets.checkForOpenTicket(src)
else
ticketNum = SSmentor_tickets.getTicketCounter() // ticketNum is the ticket ready to be assigned.
else //Ahelp
span = "<span class='adminhelp'>"
if(SStickets.checkForOpenTicket(src)) // If user already has an open ticket
T = SStickets.checkForOpenTicket(src) // Make T equal to the ticket they have open
else
ticketNum = SStickets.getTicketCounter() // ticketNum is the ticket ready to be assigned.
if(T)
ticketNum = T.ticketNum // ticketNum is the number of their ticket.
T.addResponse(src, msg)
msg = "[span][selected_type]: </span><span class='boldnotice'>[key_name(src, TRUE, selected_type)] ([ADMIN_QUE(mob,"?")]) ([ADMIN_PP(mob,"PP")]) ([ADMIN_VV(mob,"VV")]) ([ADMIN_TP(mob,"TP")]) ([ADMIN_SM(mob,"SM")]) ([admin_jump_link(mob)]) (<A HREF='?_src_=holder;[isMhelp ? "openmentorticket" : "openadminticket"]=[ticketNum]'>TICKET</A>) [ai_found ? "(<A HREF='?_src_=holder;adminchecklaws=[mob.UID()]'>CL</A>)" : ""] (<A HREF='?_src_=holder;take_question=[ticketNum][isMhelp ? ";is_mhelp=1" : ""]'>TAKE</A>) (<A HREF='?_src_=holder;resolve=[ticketNum][isMhelp ? ";is_mhelp=1" : ""]'>RESOLVE</A>) [isMhelp ? "" : "<A HREF='?_src_=holder;autorespond=[ticketNum]'>(AUTO)</A>"] :</span> [span][msg]</span>"
if(isMhelp)
//Open a new adminticket and inform the user.
SSmentor_tickets.newTicket(src, prunedmsg, msg)
for(var/client/X in mentorholders + modholders + adminholders)
if(X.prefs.sound & SOUND_MENTORHELP)
X << 'sound/effects/adminhelp.ogg'
to_chat(X, msg)
else //Ahelp
//Open a new adminticket and inform the user.
SStickets.newTicket(src, prunedmsg, msg)
for(var/client/X in modholders + adminholders)
if(X.prefs.sound & SOUND_ADMINHELP)
X << 'sound/effects/adminhelp.ogg'
window_flash(X)
to_chat(X, msg)
//show it to the person adminhelping too
to_chat(src, "<span class='boldnotice'>[selected_type]</b>: [original_msg]</span>")
var/admin_number_present = adminholders.len - admin_number_afk
log_admin("[selected_type]: [key_name(src)]: [original_msg] - heard by [admin_number_present] non-AFK admins.")
if(admin_number_present <= 0)
if(!admin_number_afk)
send2adminirc("[selected_type] from [key_name(src)]: [original_msg] - !!No admins online!!")
else
send2adminirc("[selected_type] from [key_name(src)]: [original_msg] - !!All admins AFK ([admin_number_afk])!!")
else
send2adminirc("[selected_type] from [key_name(src)]: [original_msg]")
feedback_add_details("admin_verb","AH") //If you are copy-pasting this, ensure the 2nd parameter is unique to the new proc!
return
/proc/send2irc_adminless_only(source, msg, requiredflags = R_BAN)
var/admin_number_total = 0 //Total number of admins
var/admin_number_afk = 0 //Holds the number of admins who are afk
var/admin_number_ignored = 0 //Holds the number of admins without +BAN (so admins who are not really admins)
var/admin_number_decrease = 0 //Holds the number of admins with are afk, ignored or both
for(var/client/X in GLOB.admins)
admin_number_total++;
var/invalid = 0
if(requiredflags != 0 && !check_rights_for(X, requiredflags))
admin_number_ignored++
invalid = 1
if(X.is_afk())
admin_number_afk++
invalid = 1
if(X.holder.fakekey)
admin_number_ignored++
invalid = 1
if(invalid)
admin_number_decrease++
var/admin_number_present = admin_number_total - admin_number_decrease //Number of admins who are neither afk nor invalid
if(admin_number_present <= 0)
if(!admin_number_afk && !admin_number_ignored)
send2irc(source, "[msg] - No admins online")
else
send2irc(source, "[msg] - All admins AFK ([admin_number_afk]/[admin_number_total]) or skipped ([admin_number_ignored]/[admin_number_total])")
return admin_number_present
//This is a list of words which are ignored by the parser when comparing message contents for names. MUST BE IN LOWER CASE!
GLOBAL_LIST_INIT(adminhelp_ignored_words, list("unknown","the","a","an","of","monkey","alien","as"))
/client/verb/adminhelp()
set category = "Admin"
set name = "Adminhelp"
//handle muting and automuting
if(prefs.muted & MUTE_ADMINHELP)
to_chat(src, "<font color='red'>Error: Admin-PM: You cannot send adminhelps (Muted).</font>")
return
adminhelped = 1 //Determines if they get the message to reply by clicking the name.
var/msg
var/list/type = list("Mentorhelp","Adminhelp")
var/selected_type = input("Pick a category.", "Admin Help", null, null) as null|anything in type
if(selected_type)
msg = clean_input("Please enter your message.", "Admin Help", null)
//clean the input msg
if(!msg)
return
if(handle_spam_prevention(msg, MUTE_ADMINHELP, OOC_COOLDOWN))
return
msg = sanitize_simple(copytext(msg,1,MAX_MESSAGE_LEN))
if(!msg) return
var/original_msg = msg
//explode the input msg into a list
var/list/msglist = splittext(msg, " ")
//generate keywords lookup
var/list/surnames = list()
var/list/forenames = list()
var/list/ckeys = list()
for(var/mob/M in GLOB.mob_list)
var/list/indexing = list(M.real_name, M.name)
if(M.mind) indexing += M.mind.name
for(var/string in indexing)
var/list/L = splittext(string, " ")
var/surname_found = 0
//surnames
for(var/i=L.len, i>=1, i--)
var/word = ckey(L[i])
if(word)
surnames[word] = M
surname_found = i
break
//forenames
for(var/i=1, i<surname_found, i++)
var/word = ckey(L[i])
if(word)
forenames[word] = M
//ckeys
ckeys[M.ckey] = M
var/ai_found = 0
msg = ""
var/list/mobs_found = list()
for(var/original_word in msglist)
var/word = ckey(original_word)
if(word)
if(!(word in GLOB.adminhelp_ignored_words))
if(word == "ai")
ai_found = 1
else
var/mob/found = ckeys[word]
if(!found)
found = surnames[word]
if(!found)
found = forenames[word]
if(found)
if(!(found in mobs_found))
mobs_found += found
if(!ai_found && isAI(found))
ai_found = 1
msg += "<b><font color='black'>[original_word] </font></b> "
continue
msg += "[original_word] "
if(!mob) return //this doesn't happen
//send this msg to all admins
var/admin_number_afk = 0
var/list/mentorholders = list()
var/list/modholders = list()
var/list/adminholders = list()
for(var/client/X in GLOB.admins)
if(check_rights(R_ADMIN, 0, X.mob))
if(X.is_afk())
admin_number_afk++
adminholders += X
continue
if(check_rights(R_MOD, 0, X.mob))
modholders += X
continue
if(check_rights(R_MENTOR, 0, X.mob))
mentorholders += X
continue
var/ticketNum // Holder for the ticket number
var/prunedmsg ="[src]: [msg]" // Message without links
var/datum/ticket/T
var/isMhelp = selected_type == "Mentorhelp"
var/span
if(isMhelp)
span = "<span class='mentorhelp'>"
if(SSmentor_tickets.checkForOpenTicket(src)) // If user already has an open ticket
T = SSmentor_tickets.checkForOpenTicket(src)
else
ticketNum = SSmentor_tickets.getTicketCounter() // ticketNum is the ticket ready to be assigned.
else //Ahelp
span = "<span class='adminhelp'>"
if(SStickets.checkForOpenTicket(src)) // If user already has an open ticket
T = SStickets.checkForOpenTicket(src) // Make T equal to the ticket they have open
else
ticketNum = SStickets.getTicketCounter() // ticketNum is the ticket ready to be assigned.
if(T)
ticketNum = T.ticketNum // ticketNum is the number of their ticket.
T.addResponse(src, msg)
msg = "[span][selected_type]: </span><span class='boldnotice'>[key_name(src, TRUE, selected_type)] ([ADMIN_QUE(mob,"?")]) ([ADMIN_PP(mob,"PP")]) ([ADMIN_VV(mob,"VV")]) ([ADMIN_TP(mob,"TP")]) ([ADMIN_SM(mob,"SM")]) ([admin_jump_link(mob)]) (<A HREF='?_src_=holder;[isMhelp ? "openmentorticket" : "openadminticket"]=[ticketNum]'>TICKET</A>) [ai_found ? "(<A HREF='?_src_=holder;adminchecklaws=[mob.UID()]'>CL</A>)" : ""] (<A HREF='?_src_=holder;take_question=[ticketNum][isMhelp ? ";is_mhelp=1" : ""]'>TAKE</A>) (<A HREF='?_src_=holder;resolve=[ticketNum][isMhelp ? ";is_mhelp=1" : ""]'>RESOLVE</A>) [isMhelp ? "" : "<A HREF='?_src_=holder;autorespond=[ticketNum]'>(AUTO)</A>"] :</span> [span][msg]</span>"
if(isMhelp)
//Open a new adminticket and inform the user.
SSmentor_tickets.newTicket(src, prunedmsg, msg)
for(var/client/X in mentorholders + modholders + adminholders)
if(X.prefs.sound & SOUND_MENTORHELP)
X << 'sound/effects/adminhelp.ogg'
to_chat(X, msg)
else //Ahelp
//Open a new adminticket and inform the user.
SStickets.newTicket(src, prunedmsg, msg)
for(var/client/X in modholders + adminholders)
if(X.prefs.sound & SOUND_ADMINHELP)
X << 'sound/effects/adminhelp.ogg'
window_flash(X)
to_chat(X, msg)
//show it to the person adminhelping too
to_chat(src, "<span class='boldnotice'>[selected_type]</b>: [original_msg]</span>")
var/admin_number_present = adminholders.len - admin_number_afk
log_admin("[selected_type]: [key_name(src)]: [original_msg] - heard by [admin_number_present] non-AFK admins.")
if(admin_number_present <= 0)
if(!admin_number_afk)
send2adminirc("[selected_type] from [key_name(src)]: [original_msg] - !!No admins online!!")
else
send2adminirc("[selected_type] from [key_name(src)]: [original_msg] - !!All admins AFK ([admin_number_afk])!!")
else
send2adminirc("[selected_type] from [key_name(src)]: [original_msg]")
feedback_add_details("admin_verb","AH") //If you are copy-pasting this, ensure the 2nd parameter is unique to the new proc!
return
/proc/send2irc_adminless_only(source, msg, requiredflags = R_BAN)
var/admin_number_total = 0 //Total number of admins
var/admin_number_afk = 0 //Holds the number of admins who are afk
var/admin_number_ignored = 0 //Holds the number of admins without +BAN (so admins who are not really admins)
var/admin_number_decrease = 0 //Holds the number of admins with are afk, ignored or both
for(var/client/X in GLOB.admins)
admin_number_total++;
var/invalid = 0
if(requiredflags != 0 && !check_rights_for(X, requiredflags))
admin_number_ignored++
invalid = 1
if(X.is_afk())
admin_number_afk++
invalid = 1
if(X.holder.fakekey)
admin_number_ignored++
invalid = 1
if(invalid)
admin_number_decrease++
var/admin_number_present = admin_number_total - admin_number_decrease //Number of admins who are neither afk nor invalid
if(admin_number_present <= 0)
if(!admin_number_afk && !admin_number_ignored)
send2irc(source, "[msg] - No admins online")
else
send2irc(source, "[msg] - All admins AFK ([admin_number_afk]/[admin_number_total]) or skipped ([admin_number_ignored]/[admin_number_total])")
return admin_number_present
+161 -161
View File
@@ -1,161 +1,161 @@
/client/proc/Jump(area/A in return_sorted_areas())
set name = "Jump to Area"
set desc = "Area to jump to"
set category = "Admin"
if(!check_rights(R_ADMIN))
return
if(!A)
return
var/list/turfs = list()
for(var/turf/T in A)
if(T.density)
continue
if(locate(/obj/structure/grille, T)) // Quick check to not spawn in windows
continue
turfs.Add(T)
var/turf/T = pick_n_take(turfs)
if(!T)
to_chat(src, "Nowhere to jump to!")
return
admin_forcemove(usr, T)
log_admin("[key_name(usr)] jumped to [A]")
if(!isobserver(usr))
message_admins("[key_name_admin(usr)] jumped to [A]")
feedback_add_details("admin_verb","JA") //If you are copy-pasting this, ensure the 2nd parameter is unique to the new proc!
/client/proc/jumptoturf(var/turf/T in world)
set name = "Jump to Turf"
set category = null
if(!check_rights(R_ADMIN))
return
log_admin("[key_name(usr)] jumped to [T.x], [T.y], [T.z] in [T.loc]")
if(!isobserver(usr))
message_admins("[key_name_admin(usr)] jumped to [T.x], [T.y], [T.z] in [T.loc]", 1)
admin_forcemove(usr, T)
feedback_add_details("admin_verb","JT") //If you are copy-pasting this, ensure the 2nd parameter is unique to the new proc!
return
/client/proc/jumptomob(var/mob/M in GLOB.mob_list)
set category = "Admin"
set name = "Jump to Mob"
if(!check_rights(R_ADMIN))
return
log_admin("[key_name(usr)] jumped to [key_name(M)]")
if(!isobserver(usr))
message_admins("[key_name_admin(usr)] jumped to [key_name_admin(M)]", 1)
if(src.mob)
var/mob/A = src.mob
var/turf/T = get_turf(M)
if(T && isturf(T))
feedback_add_details("admin_verb","JM") //If you are copy-pasting this, ensure the 2nd parameter is unique to the new proc!
admin_forcemove(A, M.loc)
else
to_chat(A, "This mob is not located in the game world.")
/client/proc/jumptocoord(tx as num, ty as num, tz as num)
set category = "Admin"
set name = "Jump to Coordinate"
if(!check_rights(R_ADMIN))
return
var/turf/T = locate(tx, ty, tz)
if(T)
admin_forcemove(usr, T)
if(isobserver(usr))
var/mob/dead/observer/O = usr
O.ManualFollow(T)
feedback_add_details("admin_verb","JC") //If you are copy-pasting this, ensure the 2nd parameter is unique to the new proc!
if(!isobserver(usr))
message_admins("[key_name_admin(usr)] jumped to coordinates [tx], [ty], [tz]")
/client/proc/jumptokey()
set category = "Admin"
set name = "Jump to Key"
if(!check_rights(R_ADMIN))
return
var/list/keys = list()
for(var/mob/M in GLOB.player_list)
keys += M.client
var/selection = input("Please, select a player!", "Admin Jumping", null, null) as null|anything in sortKey(keys)
if(!selection)
to_chat(src, "No keys found.")
return
var/mob/M = selection:mob
log_admin("[key_name(usr)] jumped to [key_name(M)]")
if(!isobserver(usr))
message_admins("[key_name_admin(usr)] jumped to [key_name_admin(M)]", 1)
admin_forcemove(usr, M.loc)
feedback_add_details("admin_verb","JK") //If you are copy-pasting this, ensure the 2nd parameter is unique to the new proc!
/client/proc/Getmob(var/mob/M in GLOB.mob_list)
set category = "Admin"
set name = "Get Mob"
set desc = "Mob to teleport"
if(!check_rights(R_ADMIN))
return
log_admin("[key_name(usr)] teleported [key_name(M)]")
message_admins("[key_name_admin(usr)] teleported [key_name_admin(M)]", 1)
admin_forcemove(M, get_turf(usr))
feedback_add_details("admin_verb","GM") //If you are copy-pasting this, ensure the 2nd parameter is unique to the new proc!
/client/proc/Getkey()
set category = "Admin"
set name = "Get Key"
set desc = "Key to teleport"
if(!check_rights(R_ADMIN))
return
var/list/keys = list()
for(var/mob/M in GLOB.player_list)
keys += M.client
var/selection = input("Please, select a player!", "Admin Jumping", null, null) as null|anything in sortKey(keys)
if(!selection)
return
var/mob/M = selection:mob
if(!M)
return
log_admin("[key_name(usr)] teleported [key_name(M)]")
message_admins("[key_name_admin(usr)] teleported [key_name(M)]", 1)
if(M)
admin_forcemove(M, get_turf(usr))
admin_forcemove(usr, M.loc)
feedback_add_details("admin_verb","GK") //If you are copy-pasting this, ensure the 2nd parameter is unique to the new proc!
/client/proc/sendmob(var/mob/M in GLOB.mob_list)
set category = "Admin"
set name = "Send Mob"
if(!check_rights(R_ADMIN))
return
var/area/A = input(usr, "Pick an area.", "Pick an area") in return_sorted_areas()
if(A)
admin_forcemove(M, pick(get_area_turfs(A)))
feedback_add_details("admin_verb","SMOB") //If you are copy-pasting this, ensure the 2nd parameter is unique to the new proc!
log_admin("[key_name(usr)] teleported [key_name(M)] to [A]")
message_admins("[key_name_admin(usr)] teleported [key_name_admin(M)] to [A]", 1)
/proc/admin_forcemove(mob/mover, atom/newloc)
mover.forceMove(newloc)
mover.on_forcemove(newloc)
/mob/proc/on_forcemove(atom/newloc)
return
/client/proc/Jump(area/A in return_sorted_areas())
set name = "Jump to Area"
set desc = "Area to jump to"
set category = "Admin"
if(!check_rights(R_ADMIN))
return
if(!A)
return
var/list/turfs = list()
for(var/turf/T in A)
if(T.density)
continue
if(locate(/obj/structure/grille, T)) // Quick check to not spawn in windows
continue
turfs.Add(T)
var/turf/T = pick_n_take(turfs)
if(!T)
to_chat(src, "Nowhere to jump to!")
return
admin_forcemove(usr, T)
log_admin("[key_name(usr)] jumped to [A]")
if(!isobserver(usr))
message_admins("[key_name_admin(usr)] jumped to [A]")
feedback_add_details("admin_verb","JA") //If you are copy-pasting this, ensure the 2nd parameter is unique to the new proc!
/client/proc/jumptoturf(var/turf/T in world)
set name = "Jump to Turf"
set category = null
if(!check_rights(R_ADMIN))
return
log_admin("[key_name(usr)] jumped to [T.x], [T.y], [T.z] in [T.loc]")
if(!isobserver(usr))
message_admins("[key_name_admin(usr)] jumped to [T.x], [T.y], [T.z] in [T.loc]", 1)
admin_forcemove(usr, T)
feedback_add_details("admin_verb","JT") //If you are copy-pasting this, ensure the 2nd parameter is unique to the new proc!
return
/client/proc/jumptomob(var/mob/M in GLOB.mob_list)
set category = "Admin"
set name = "Jump to Mob"
if(!check_rights(R_ADMIN))
return
log_admin("[key_name(usr)] jumped to [key_name(M)]")
if(!isobserver(usr))
message_admins("[key_name_admin(usr)] jumped to [key_name_admin(M)]", 1)
if(src.mob)
var/mob/A = src.mob
var/turf/T = get_turf(M)
if(T && isturf(T))
feedback_add_details("admin_verb","JM") //If you are copy-pasting this, ensure the 2nd parameter is unique to the new proc!
admin_forcemove(A, M.loc)
else
to_chat(A, "This mob is not located in the game world.")
/client/proc/jumptocoord(tx as num, ty as num, tz as num)
set category = "Admin"
set name = "Jump to Coordinate"
if(!check_rights(R_ADMIN))
return
var/turf/T = locate(tx, ty, tz)
if(T)
admin_forcemove(usr, T)
if(isobserver(usr))
var/mob/dead/observer/O = usr
O.ManualFollow(T)
feedback_add_details("admin_verb","JC") //If you are copy-pasting this, ensure the 2nd parameter is unique to the new proc!
if(!isobserver(usr))
message_admins("[key_name_admin(usr)] jumped to coordinates [tx], [ty], [tz]")
/client/proc/jumptokey()
set category = "Admin"
set name = "Jump to Key"
if(!check_rights(R_ADMIN))
return
var/list/keys = list()
for(var/mob/M in GLOB.player_list)
keys += M.client
var/selection = input("Please, select a player!", "Admin Jumping", null, null) as null|anything in sortKey(keys)
if(!selection)
to_chat(src, "No keys found.")
return
var/mob/M = selection:mob
log_admin("[key_name(usr)] jumped to [key_name(M)]")
if(!isobserver(usr))
message_admins("[key_name_admin(usr)] jumped to [key_name_admin(M)]", 1)
admin_forcemove(usr, M.loc)
feedback_add_details("admin_verb","JK") //If you are copy-pasting this, ensure the 2nd parameter is unique to the new proc!
/client/proc/Getmob(var/mob/M in GLOB.mob_list)
set category = "Admin"
set name = "Get Mob"
set desc = "Mob to teleport"
if(!check_rights(R_ADMIN))
return
log_admin("[key_name(usr)] teleported [key_name(M)]")
message_admins("[key_name_admin(usr)] teleported [key_name_admin(M)]", 1)
admin_forcemove(M, get_turf(usr))
feedback_add_details("admin_verb","GM") //If you are copy-pasting this, ensure the 2nd parameter is unique to the new proc!
/client/proc/Getkey()
set category = "Admin"
set name = "Get Key"
set desc = "Key to teleport"
if(!check_rights(R_ADMIN))
return
var/list/keys = list()
for(var/mob/M in GLOB.player_list)
keys += M.client
var/selection = input("Please, select a player!", "Admin Jumping", null, null) as null|anything in sortKey(keys)
if(!selection)
return
var/mob/M = selection:mob
if(!M)
return
log_admin("[key_name(usr)] teleported [key_name(M)]")
message_admins("[key_name_admin(usr)] teleported [key_name(M)]", 1)
if(M)
admin_forcemove(M, get_turf(usr))
admin_forcemove(usr, M.loc)
feedback_add_details("admin_verb","GK") //If you are copy-pasting this, ensure the 2nd parameter is unique to the new proc!
/client/proc/sendmob(var/mob/M in GLOB.mob_list)
set category = "Admin"
set name = "Send Mob"
if(!check_rights(R_ADMIN))
return
var/area/A = input(usr, "Pick an area.", "Pick an area") in return_sorted_areas()
if(A)
admin_forcemove(M, pick(get_area_turfs(A)))
feedback_add_details("admin_verb","SMOB") //If you are copy-pasting this, ensure the 2nd parameter is unique to the new proc!
log_admin("[key_name(usr)] teleported [key_name(M)] to [A]")
message_admins("[key_name_admin(usr)] teleported [key_name_admin(M)] to [A]", 1)
/proc/admin_forcemove(mob/mover, atom/newloc)
mover.forceMove(newloc)
mover.on_forcemove(newloc)
/mob/proc/on_forcemove(atom/newloc)
return
+1 -1
View File
@@ -261,7 +261,7 @@
/datum/pm_tracker
var/current_title = ""
var/open = FALSE
var/list/pms = list()
var/list/datum/pm_convo/pms = list()
var/show_archived = FALSE
var/window_id = "pms_window"
+82 -82
View File
@@ -1,82 +1,82 @@
/client/proc/cmd_admin_say(msg as text)
set category = "Admin"
set name = "Asay" //Gave this shit a shorter name so you only have to time out "asay" rather than "admin say" to use it --NeoFite
set hidden = 1
if(!check_rights(R_ADMIN)) return
msg = sanitize(copytext(msg, 1, MAX_MESSAGE_LEN))
if(!msg) return
log_adminsay(msg, src)
if(check_rights(R_ADMIN,0))
for(var/client/C in GLOB.admins)
if(R_ADMIN & C.holder.rights)
msg = "<span class='emoji_enabled'>[msg]</span>"
to_chat(C, "<span class='admin_channel'>ADMIN: <span class='name'>[key_name(usr, 1)]</span> ([admin_jump_link(mob)]): <span class='message'>[msg]</span></span>")
feedback_add_details("admin_verb","M") //If you are copy-pasting this, ensure the 2nd parameter is unique to the new proc!
/client/proc/get_admin_say()
var/msg = input(src, null, "asay \"text\"") as text|null
cmd_admin_say(msg)
/client/proc/cmd_mentor_say(msg as text)
set category = "Admin"
set name = "Msay"
set hidden = 1
if(!check_rights(R_ADMIN|R_MOD|R_MENTOR))
return
msg = sanitize(copytext(msg, 1, MAX_MESSAGE_LEN))
log_mentorsay(msg, src)
if(!msg)
return
for(var/client/C in GLOB.admins)
if(check_rights(R_ADMIN|R_MOD|R_MENTOR, 0, C.mob))
var/display_name = key
if(holder.fakekey)
if(C.holder && C.holder.rights & R_ADMIN)
display_name = "[holder.fakekey]/([key])"
else
display_name = holder.fakekey
msg = "<span class='emoji_enabled'>[msg]</span>"
to_chat(C, "<span class='[check_rights(R_ADMIN, 0) ? "mentor_channel_admin" : "mentor_channel"]'>MENTOR: <span class='name'>[display_name]</span> ([admin_jump_link(mob)]): <span class='message'>[msg]</span></span>")
feedback_add_details("admin_verb","MS") //If you are copy-pasting this, ensure the 2nd parameter is unique to the new proc!
/client/proc/toggle_mentor_chat()
set category = "Server"
set name = "Toggle Mentor Chat"
set desc = "Toggle whether mentors have access to the msay command"
if(!check_rights(R_ADMIN))
return
var/enabling
var/msay = /client/proc/cmd_mentor_say
if(msay in admin_verbs_mentor)
enabling = FALSE
admin_verbs_mentor -= msay
else
enabling = TRUE
admin_verbs_mentor += msay
for(var/client/C in GLOB.admins)
if(check_rights(R_ADMIN|R_MOD, 0, C.mob))
continue
if(!check_rights(R_MENTOR, 0, C.mob))
continue
if(enabling)
C.verbs += msay
to_chat(C, "<b>Mentor chat has been enabled.</b> Use 'msay' to speak in it.")
else
C.verbs -= msay
to_chat(C, "<b>Mentor chat has been disabled.</b>")
admin_log_and_message_admins("toggled mentor chat [enabling ? "on" : "off"].")
feedback_add_details("admin_verb", "TMC")
/client/proc/cmd_admin_say(msg as text)
set category = "Admin"
set name = "Asay" //Gave this shit a shorter name so you only have to time out "asay" rather than "admin say" to use it --NeoFite
set hidden = 1
if(!check_rights(R_ADMIN)) return
msg = sanitize(copytext(msg, 1, MAX_MESSAGE_LEN))
if(!msg) return
log_adminsay(msg, src)
if(check_rights(R_ADMIN,0))
for(var/client/C in GLOB.admins)
if(R_ADMIN & C.holder.rights)
msg = "<span class='emoji_enabled'>[msg]</span>"
to_chat(C, "<span class='admin_channel'>ADMIN: <span class='name'>[key_name(usr, 1)]</span> ([admin_jump_link(mob)]): <span class='message'>[msg]</span></span>")
feedback_add_details("admin_verb","M") //If you are copy-pasting this, ensure the 2nd parameter is unique to the new proc!
/client/proc/get_admin_say()
var/msg = input(src, null, "asay \"text\"") as text|null
cmd_admin_say(msg)
/client/proc/cmd_mentor_say(msg as text)
set category = "Admin"
set name = "Msay"
set hidden = 1
if(!check_rights(R_ADMIN|R_MOD|R_MENTOR))
return
msg = sanitize(copytext(msg, 1, MAX_MESSAGE_LEN))
log_mentorsay(msg, src)
if(!msg)
return
for(var/client/C in GLOB.admins)
if(check_rights(R_ADMIN|R_MOD|R_MENTOR, 0, C.mob))
var/display_name = key
if(holder.fakekey)
if(C.holder && C.holder.rights & R_ADMIN)
display_name = "[holder.fakekey]/([key])"
else
display_name = holder.fakekey
msg = "<span class='emoji_enabled'>[msg]</span>"
to_chat(C, "<span class='[check_rights(R_ADMIN, 0) ? "mentor_channel_admin" : "mentor_channel"]'>MENTOR: <span class='name'>[display_name]</span> ([admin_jump_link(mob)]): <span class='message'>[msg]</span></span>")
feedback_add_details("admin_verb","MS") //If you are copy-pasting this, ensure the 2nd parameter is unique to the new proc!
/client/proc/toggle_mentor_chat()
set category = "Server"
set name = "Toggle Mentor Chat"
set desc = "Toggle whether mentors have access to the msay command"
if(!check_rights(R_ADMIN))
return
var/enabling
var/msay = /client/proc/cmd_mentor_say
if(msay in GLOB.admin_verbs_mentor)
enabling = FALSE
GLOB.admin_verbs_mentor -= msay
else
enabling = TRUE
GLOB.admin_verbs_mentor += msay
for(var/client/C in GLOB.admins)
if(check_rights(R_ADMIN|R_MOD, 0, C.mob))
continue
if(!check_rights(R_MENTOR, 0, C.mob))
continue
if(enabling)
C.verbs += msay
to_chat(C, "<b>Mentor chat has been enabled.</b> Use 'msay' to speak in it.")
else
C.verbs -= msay
to_chat(C, "<b>Mentor chat has been disabled.</b>")
admin_log_and_message_admins("toggled mentor chat [enabling ? "on" : "off"].")
feedback_add_details("admin_verb", "TMC")
+1 -1
View File
@@ -6,7 +6,7 @@
<br>Additionally make an attempt to introduce new players to the server
<HR>"}
if(dbcon.IsConnected())
if(GLOB.dbcon.IsConnected())
for(var/client/C in GLOB.clients)
dat += "<p>[C.ckey] (Player Age: <font color = 'red'>[C.player_age]</font>) - <b>[C.computer_id]</b> / <b>[C.address]</b><br>"
if(C.related_accounts_cid.len)
+63 -63
View File
@@ -1,63 +1,63 @@
/client/proc/atmosscan()
set category = "Mapping"
set name = "Check Piping"
set background = 1
if(!src.holder)
to_chat(src, "Only administrators may use this command.")
return
feedback_add_details("admin_verb","CP") //If you are copy-pasting this, ensure the 2nd parameter is unique to the new proc!
if(alert("WARNING: This command should not be run on a live server. Do you want to continue?", "Check Piping", "No", "Yes") == "No")
return
to_chat(usr, "Checking for disconnected pipes...")
//all plumbing - yes, some things might get stated twice, doesn't matter.
for(var/obj/machinery/atmospherics/plumbing in world)
if(plumbing.nodealert)
to_chat(usr, "Unconnected [plumbing.name] located at [plumbing.x],[plumbing.y],[plumbing.z] ([get_area(plumbing.loc)])")
//Manifolds
for(var/obj/machinery/atmospherics/pipe/manifold/pipe in world)
if(!pipe.node1 || !pipe.node2 || !pipe.node3)
to_chat(usr, "Unconnected [pipe.name] located at [pipe.x],[pipe.y],[pipe.z] ([get_area(pipe.loc)])")
//Pipes
for(var/obj/machinery/atmospherics/pipe/simple/pipe in world)
if(!pipe.node1 || !pipe.node2)
to_chat(usr, "Unconnected [pipe.name] located at [pipe.x],[pipe.y],[pipe.z] ([get_area(pipe.loc)])")
to_chat(usr, "Checking for overlapping pipes...")
for(var/turf/T in world)
for(var/dir in cardinal)
var/list/check = list(0, 0, 0)
var/done = 0
for(var/obj/machinery/atmospherics/pipe in T)
if(dir & pipe.initialize_directions)
for(var/ct in pipe.connect_types)
check[ct]++
if(check[ct] > 1)
to_chat(usr, "Overlapping pipe ([pipe.name]) located at [T.x],[T.y],[T.z] ([get_area(T)])")
done = 1
break
if(done)
break
to_chat(usr, "Done")
/client/proc/powerdebug()
set category = "Mapping"
set name = "Check Power"
if(!src.holder)
to_chat(src, "Only administrators may use this command.")
return
feedback_add_details("admin_verb","CPOW") //If you are copy-pasting this, ensure the 2nd parameter is unique to the new proc!
for(var/datum/powernet/PN in SSmachines.powernets)
if(!PN.nodes || !PN.nodes.len)
if(PN.cables && (PN.cables.len > 1))
var/obj/structure/cable/C = PN.cables[1]
to_chat(usr, "Powernet with no nodes! (number [PN.number]) - example cable at [C.x], [C.y], [C.z] in area [get_area(C.loc)]")
if(!PN.cables || (PN.cables.len < 10))
if(PN.cables && (PN.cables.len > 1))
var/obj/structure/cable/C = PN.cables[1]
to_chat(usr, "Powernet with fewer than 10 cables! (number [PN.number]) - example cable at [C.x], [C.y], [C.z] in area [get_area(C.loc)]")
/client/proc/atmosscan()
set category = "Mapping"
set name = "Check Piping"
set background = 1
if(!src.holder)
to_chat(src, "Only administrators may use this command.")
return
feedback_add_details("admin_verb","CP") //If you are copy-pasting this, ensure the 2nd parameter is unique to the new proc!
if(alert("WARNING: This command should not be run on a live server. Do you want to continue?", "Check Piping", "No", "Yes") == "No")
return
to_chat(usr, "Checking for disconnected pipes...")
//all plumbing - yes, some things might get stated twice, doesn't matter.
for(var/obj/machinery/atmospherics/plumbing in world)
if(plumbing.nodealert)
to_chat(usr, "Unconnected [plumbing.name] located at [plumbing.x],[plumbing.y],[plumbing.z] ([get_area(plumbing.loc)])")
//Manifolds
for(var/obj/machinery/atmospherics/pipe/manifold/pipe in world)
if(!pipe.node1 || !pipe.node2 || !pipe.node3)
to_chat(usr, "Unconnected [pipe.name] located at [pipe.x],[pipe.y],[pipe.z] ([get_area(pipe.loc)])")
//Pipes
for(var/obj/machinery/atmospherics/pipe/simple/pipe in world)
if(!pipe.node1 || !pipe.node2)
to_chat(usr, "Unconnected [pipe.name] located at [pipe.x],[pipe.y],[pipe.z] ([get_area(pipe.loc)])")
to_chat(usr, "Checking for overlapping pipes...")
for(var/turf/T in world)
for(var/dir in GLOB.cardinal)
var/list/check = list(0, 0, 0)
var/done = 0
for(var/obj/machinery/atmospherics/pipe in T)
if(dir & pipe.initialize_directions)
for(var/ct in pipe.connect_types)
check[ct]++
if(check[ct] > 1)
to_chat(usr, "Overlapping pipe ([pipe.name]) located at [T.x],[T.y],[T.z] ([get_area(T)])")
done = 1
break
if(done)
break
to_chat(usr, "Done")
/client/proc/powerdebug()
set category = "Mapping"
set name = "Check Power"
if(!src.holder)
to_chat(src, "Only administrators may use this command.")
return
feedback_add_details("admin_verb","CPOW") //If you are copy-pasting this, ensure the 2nd parameter is unique to the new proc!
for(var/datum/powernet/PN in SSmachines.powernets)
if(!PN.nodes || !PN.nodes.len)
if(PN.cables && (PN.cables.len > 1))
var/obj/structure/cable/C = PN.cables[1]
to_chat(usr, "Powernet with no nodes! (number [PN.number]) - example cable at [C.x], [C.y], [C.z] in area [get_area(C.loc)]")
if(!PN.cables || (PN.cables.len < 10))
if(PN.cables && (PN.cables.len > 1))
var/obj/structure/cable/C = PN.cables[1]
to_chat(usr, "Powernet with fewer than 10 cables! (number [PN.number]) - example cable at [C.x], [C.y], [C.z] in area [get_area(C.loc)]")
+1 -1
View File
@@ -14,4 +14,4 @@
override = input(src, "mode = ?","Enter Parameter", null) as anything in list("nuclear emergency", "fake", "no override")
if(0)
override = input(src, "mode = ?","Enter Parameter", null) as anything in list("blob", "nuclear emergency", "AI malfunction", "no override")
SSticker.station_explosion_cinematic(parameter, override)
SSticker.station_explosion_cinematic(parameter, override)
+6 -6
View File
@@ -7,9 +7,9 @@
to_chat(src, "Only administrators may use this command.")
return
var/input = input(usr, "Enter the description of the custom event. Be descriptive. To cancel the event, make this blank or hit cancel.", "Custom Event", custom_event_msg) as message|null
var/input = input(usr, "Enter the description of the custom event. Be descriptive. To cancel the event, make this blank or hit cancel.", "Custom Event", GLOB.custom_event_msg) as message|null
if(!input || input == "")
custom_event_msg = null
GLOB.custom_event_msg = null
log_admin("[key_name(usr)] has cleared the custom event text.")
message_admins("[key_name_admin(usr)] has cleared the custom event text.")
return
@@ -17,11 +17,11 @@
log_admin("[key_name(usr)] has changed the custom event text.")
message_admins("[key_name_admin(usr)] has changed the custom event text.")
custom_event_msg = input
GLOB.custom_event_msg = input
to_chat(world, "<h1 class='alert'>Custom Event</h1>")
to_chat(world, "<h2 class='alert'>A custom event is starting. OOC Info:</h2>")
to_chat(world, "<span class='alert'>[html_encode(custom_event_msg)]</span>")
to_chat(world, "<span class='alert'>[html_encode(GLOB.custom_event_msg)]</span>")
to_chat(world, "<br>")
// normal verb for players to view info
@@ -29,12 +29,12 @@
set category = "OOC"
set name = "Custom Event Info"
if(!custom_event_msg || custom_event_msg == "")
if(!GLOB.custom_event_msg || GLOB.custom_event_msg == "")
to_chat(src, "There currently is no known custom event taking place.")
to_chat(src, "Keep in mind: it is possible that an admin has not properly set this.")
return
to_chat(src, "<h1 class='alert'>Custom Event</h1>")
to_chat(src, "<h2 class='alert'>A custom event is taking place. OOC Info:</h2>")
to_chat(src, "<span class='alert'>[html_encode(custom_event_msg)]</span>")
to_chat(src, "<span class='alert'>[html_encode(GLOB.custom_event_msg)]</span>")
to_chat(src, "<br>")
+49 -49
View File
@@ -1,49 +1,49 @@
/client/proc/dsay(msg as text)
set category = "Admin"
set name = "Dsay" //Gave this shit a shorter name so you only have to time out "dsay" rather than "dead say" to use it --NeoFite
set hidden = 1
if(!check_rights(R_ADMIN|R_MOD))
return
if(!src.mob)
return
if(prefs.muted & MUTE_DEADCHAT)
to_chat(src, "<span class='warning'>You cannot send DSAY messages (muted).</span>")
return
if(!(prefs.toggles & CHAT_DEAD))
to_chat(src, "<span class='warning'>You have deadchat muted.</span>")
return
if(handle_spam_prevention(msg,MUTE_DEADCHAT))
return
var/stafftype = null
if(check_rights(R_MENTOR, 0))
stafftype = "MENTOR"
if(check_rights(R_MOD, 0))
stafftype = "MOD"
if(check_rights(R_ADMIN, 0))
stafftype = "ADMIN"
msg = sanitize(copytext(msg, 1, MAX_MESSAGE_LEN))
log_admin("[key_name(src)] : [msg]")
if(!msg)
return
var/prefix = "[stafftype] ([src.key])"
if(holder.fakekey)
prefix = "Administrator"
say_dead_direct("<span class='name'>[prefix]</span> says, <span class='message'>\"[msg]\"</span>")
feedback_add_details("admin_verb","D") //If you are copy-pasting this, ensure the 2nd parameter is unique to the new proc!
/client/proc/get_dead_say()
var/msg = input(src, null, "dsay \"text\"") as text
dsay(msg)
/client/proc/dsay(msg as text)
set category = "Admin"
set name = "Dsay" //Gave this shit a shorter name so you only have to time out "dsay" rather than "dead say" to use it --NeoFite
set hidden = 1
if(!check_rights(R_ADMIN|R_MOD))
return
if(!src.mob)
return
if(prefs.muted & MUTE_DEADCHAT)
to_chat(src, "<span class='warning'>You cannot send DSAY messages (muted).</span>")
return
if(!(prefs.toggles & CHAT_DEAD))
to_chat(src, "<span class='warning'>You have deadchat muted.</span>")
return
if(handle_spam_prevention(msg,MUTE_DEADCHAT))
return
var/stafftype = null
if(check_rights(R_MENTOR, 0))
stafftype = "MENTOR"
if(check_rights(R_MOD, 0))
stafftype = "MOD"
if(check_rights(R_ADMIN, 0))
stafftype = "ADMIN"
msg = sanitize(copytext(msg, 1, MAX_MESSAGE_LEN))
log_admin("[key_name(src)] : [msg]")
if(!msg)
return
var/prefix = "[stafftype] ([src.key])"
if(holder.fakekey)
prefix = "Administrator"
say_dead_direct("<span class='name'>[prefix]</span> says, <span class='message'>\"[msg]\"</span>")
feedback_add_details("admin_verb","D") //If you are copy-pasting this, ensure the 2nd parameter is unique to the new proc!
/client/proc/get_dead_say()
var/msg = input(src, null, "dsay \"text\"") as text
dsay(msg)
File diff suppressed because it is too large Load Diff
+178 -178
View File
@@ -1,178 +1,178 @@
/client/proc/air_status(turf/target as turf)
set category = "Debug"
set name = "Display Air Status"
if(!check_rights(R_DEBUG))
return
if(!isturf(target))
return
var/datum/gas_mixture/GM = target.return_air()
var/burning = 0
if(istype(target, /turf/simulated))
var/turf/simulated/T = target
if(T.active_hotspot)
burning = 1
to_chat(usr, "<span class='notice'>@[target.x],[target.y]: O:[GM.oxygen] T:[GM.toxins] N:[GM.nitrogen] C:[GM.carbon_dioxide] w [GM.temperature] Kelvin, [GM.return_pressure()] kPa [(burning)?("<span class='warning'>BURNING</span>"):(null)]</span>")
for(var/datum/gas/trace_gas in GM.trace_gases)
to_chat(usr, "[trace_gas.type]: [trace_gas.moles]")
message_admins("[key_name_admin(usr)] has checked the air status of [T]")
log_admin("[key_name(usr)] has checked the air status of [T]")
feedback_add_details("admin_verb","DAST") //If you are copy-pasting this, ensure the 2nd parameter is unique to the new proc!
/client/proc/fix_next_move()
set category = "Debug"
set name = "Unfreeze Everyone"
if(!check_rights(R_DEBUG))
return
message_admins("[key_name_admin(usr)] has unfrozen everyone")
log_admin("[key_name(usr)] has unfrozen everyone")
var/largest_move_time = 0
var/largest_click_time = 0
var/mob/largest_move_mob = null
var/mob/largest_click_mob = null
for(var/mob/M in world)
if(!M.client)
continue
if(M.next_move >= largest_move_time)
largest_move_mob = M
if(M.next_move > world.time)
largest_move_time = M.next_move - world.time
else
largest_move_time = 1
if(M.next_click >= largest_click_time)
largest_click_mob = M
if(M.next_click > world.time)
largest_click_time = M.next_click - world.time
else
largest_click_time = 0
log_admin("DEBUG: [key_name(M)] next_move = [M.next_move] next_click = [M.next_click] world.time = [world.time]")
M.next_move = 1
M.next_click = 0
message_admins("[key_name_admin(largest_move_mob)] had the largest move delay with [largest_move_time] frames / [largest_move_time/10] seconds!", 1)
message_admins("[key_name_admin(largest_click_mob)] had the largest click delay with [largest_click_time] frames / [largest_click_time/10] seconds!", 1)
message_admins("world.time = [world.time]", 1)
feedback_add_details("admin_verb","UFE") //If you are copy-pasting this, ensure the 2nd parameter is unique to the new proc!
return
/client/proc/radio_report()
set category = "Debug"
set name = "Radio report"
if(!check_rights(R_DEBUG))
return
var/filters = list(
"1" = "RADIO_TO_AIRALARM",
"2" = "RADIO_FROM_AIRALARM",
"3" = "RADIO_CHAT",
"4" = "RADIO_ATMOSIA",
"5" = "RADIO_NAVBEACONS",
"6" = "RADIO_AIRLOCK",
"7" = "RADIO_SECBOT",
"8" = "RADIO_MULEBOT",
"_default" = "NO_FILTER"
)
var/output = "<b>Radio Report</b><hr>"
for(var/fq in SSradio.frequencies)
output += "<b>Freq: [fq]</b><br>"
var/list/datum/radio_frequency/fqs = SSradio.frequencies[fq]
if(!fqs)
output += "&nbsp;&nbsp;<b>ERROR</b><br>"
continue
for(var/filter in fqs.devices)
var/list/f = fqs.devices[filter]
if(!f)
output += "&nbsp;&nbsp;[filters[filter]]: ERROR<br>"
continue
output += "&nbsp;&nbsp;[filters[filter]]: [f.len]<br>"
for(var/device in f)
if(isobj(device))
output += "&nbsp;&nbsp;&nbsp;&nbsp;[device] ([device:x],[device:y],[device:z] in area [get_area(device:loc)])<br>"
else
output += "&nbsp;&nbsp;&nbsp;&nbsp;[device]<br>"
usr << browse(output,"window=radioreport")
message_admins("[key_name_admin(usr)] has generated a radio report")
log_admin("[key_name(usr)] has generated a radio report")
feedback_add_details("admin_verb","RR") //If you are copy-pasting this, ensure the 2nd parameter is unique to the new proc!
/client/proc/reload_admins()
set name = "Reload Admins"
set category = "Debug"
if(!check_rights(R_SERVER))
return
message_admins("[key_name_admin(usr)] has manually reloaded admins")
log_admin("[key_name(usr)] has manually reloaded admins")
load_admins()
feedback_add_details("admin_verb","RLDA") //If you are copy-pasting this, ensure the 2nd parameter is unique to the new proc!
/client/proc/print_jobban_old()
set name = "Print Jobban Log"
set desc = "This spams all the active jobban entries for the current round to standard output."
set category = "Debug"
if(!check_rights(R_DEBUG))
return
to_chat(usr, "<b>Jobbans active in this round.</b>")
for(var/t in jobban_keylist)
to_chat(usr, "[t]")
message_admins("[key_name_admin(usr)] has printed the jobban log")
log_admin("[key_name(usr)] has printed the jobban log")
/client/proc/print_jobban_old_filter()
set name = "Search Jobban Log"
set desc = "This searches all the active jobban entries for the current round and outputs the results to standard output."
set category = "Debug"
if(!check_rights(R_DEBUG))
return
var/filter = clean_input("Contains what?","Filter")
if(!filter)
return
to_chat(usr, "<b>Jobbans active in this round.</b>")
for(var/t in jobban_keylist)
if(findtext(t, filter))
to_chat(usr, "[t]")
message_admins("[key_name_admin(usr)] has searched the jobban log for [filter]")
log_admin("[key_name(usr)] has searched the jobban log for [filter]")
/client/proc/vv_by_ref()
set name = "VV by Ref"
set desc = "Give this a ref string, and you will see its corresponding VV panel if it exists"
set category = "Debug"
// It's gated by "Debug Verbs", so might as well gate it to the debug permission
if(!check_rights(R_DEBUG))
return
var/refstring = clean_input("Which reference?","Ref")
if(!refstring)
return
var/datum/D = locate(refstring)
if(!D)
to_chat(usr, "<span class='warning'>That ref string does not correspond to any datum.</span>")
return
debug_variables(D)
/client/proc/air_status(turf/target as turf)
set category = "Debug"
set name = "Display Air Status"
if(!check_rights(R_DEBUG))
return
if(!isturf(target))
return
var/datum/gas_mixture/GM = target.return_air()
var/burning = 0
if(istype(target, /turf/simulated))
var/turf/simulated/T = target
if(T.active_hotspot)
burning = 1
to_chat(usr, "<span class='notice'>@[target.x],[target.y]: O:[GM.oxygen] T:[GM.toxins] N:[GM.nitrogen] C:[GM.carbon_dioxide] w [GM.temperature] Kelvin, [GM.return_pressure()] kPa [(burning)?("<span class='warning'>BURNING</span>"):(null)]</span>")
for(var/datum/gas/trace_gas in GM.trace_gases)
to_chat(usr, "[trace_gas.type]: [trace_gas.moles]")
message_admins("[key_name_admin(usr)] has checked the air status of [target]")
log_admin("[key_name(usr)] has checked the air status of [target]")
feedback_add_details("admin_verb","DAST") //If you are copy-pasting this, ensure the 2nd parameter is unique to the new proc!
/client/proc/fix_next_move()
set category = "Debug"
set name = "Unfreeze Everyone"
if(!check_rights(R_DEBUG))
return
message_admins("[key_name_admin(usr)] has unfrozen everyone")
log_admin("[key_name(usr)] has unfrozen everyone")
var/largest_move_time = 0
var/largest_click_time = 0
var/mob/largest_move_mob = null
var/mob/largest_click_mob = null
for(var/mob/M in world)
if(!M.client)
continue
if(M.next_move >= largest_move_time)
largest_move_mob = M
if(M.next_move > world.time)
largest_move_time = M.next_move - world.time
else
largest_move_time = 1
if(M.next_click >= largest_click_time)
largest_click_mob = M
if(M.next_click > world.time)
largest_click_time = M.next_click - world.time
else
largest_click_time = 0
log_admin("DEBUG: [key_name(M)] next_move = [M.next_move] next_click = [M.next_click] world.time = [world.time]")
M.next_move = 1
M.next_click = 0
message_admins("[key_name_admin(largest_move_mob)] had the largest move delay with [largest_move_time] frames / [largest_move_time/10] seconds!", 1)
message_admins("[key_name_admin(largest_click_mob)] had the largest click delay with [largest_click_time] frames / [largest_click_time/10] seconds!", 1)
message_admins("world.time = [world.time]", 1)
feedback_add_details("admin_verb","UFE") //If you are copy-pasting this, ensure the 2nd parameter is unique to the new proc!
return
/client/proc/radio_report()
set category = "Debug"
set name = "Radio report"
if(!check_rights(R_DEBUG))
return
var/filters = list(
"1" = "RADIO_TO_AIRALARM",
"2" = "RADIO_FROM_AIRALARM",
"3" = "RADIO_CHAT",
"4" = "RADIO_ATMOSIA",
"5" = "RADIO_NAVBEACONS",
"6" = "RADIO_AIRLOCK",
"7" = "RADIO_SECBOT",
"8" = "RADIO_MULEBOT",
"_default" = "NO_FILTER"
)
var/output = "<b>Radio Report</b><hr>"
for(var/fq in SSradio.frequencies)
output += "<b>Freq: [fq]</b><br>"
var/datum/radio_frequency/fqs = SSradio.frequencies[fq]
if(!fqs)
output += "&nbsp;&nbsp;<b>ERROR</b><br>"
continue
for(var/filter in fqs.devices)
var/list/f = fqs.devices[filter]
if(!f)
output += "&nbsp;&nbsp;[filters[filter]]: ERROR<br>"
continue
output += "&nbsp;&nbsp;[filters[filter]]: [f.len]<br>"
for(var/device in f)
if(isobj(device))
output += "&nbsp;&nbsp;&nbsp;&nbsp;[device] ([device:x],[device:y],[device:z] in area [get_area(device:loc)])<br>"
else
output += "&nbsp;&nbsp;&nbsp;&nbsp;[device]<br>"
usr << browse(output,"window=radioreport")
message_admins("[key_name_admin(usr)] has generated a radio report")
log_admin("[key_name(usr)] has generated a radio report")
feedback_add_details("admin_verb","RR") //If you are copy-pasting this, ensure the 2nd parameter is unique to the new proc!
/client/proc/reload_admins()
set name = "Reload Admins"
set category = "Debug"
if(!check_rights(R_SERVER))
return
message_admins("[key_name_admin(usr)] has manually reloaded admins")
log_admin("[key_name(usr)] has manually reloaded admins")
load_admins()
feedback_add_details("admin_verb","RLDA") //If you are copy-pasting this, ensure the 2nd parameter is unique to the new proc!
/client/proc/print_jobban_old()
set name = "Print Jobban Log"
set desc = "This spams all the active jobban entries for the current round to standard output."
set category = "Debug"
if(!check_rights(R_DEBUG))
return
to_chat(usr, "<b>Jobbans active in this round.</b>")
for(var/t in GLOB.jobban_keylist)
to_chat(usr, "[t]")
message_admins("[key_name_admin(usr)] has printed the jobban log")
log_admin("[key_name(usr)] has printed the jobban log")
/client/proc/print_jobban_old_filter()
set name = "Search Jobban Log"
set desc = "This searches all the active jobban entries for the current round and outputs the results to standard output."
set category = "Debug"
if(!check_rights(R_DEBUG))
return
var/filter = clean_input("Contains what?","Filter")
if(!filter)
return
to_chat(usr, "<b>Jobbans active in this round.</b>")
for(var/t in GLOB.jobban_keylist)
if(findtext(t, filter))
to_chat(usr, "[t]")
message_admins("[key_name_admin(usr)] has searched the jobban log for [filter]")
log_admin("[key_name(usr)] has searched the jobban log for [filter]")
/client/proc/vv_by_ref()
set name = "VV by Ref"
set desc = "Give this a ref string, and you will see its corresponding VV panel if it exists"
set category = "Debug"
// It's gated by "Debug Verbs", so might as well gate it to the debug permission
if(!check_rights(R_DEBUG))
return
var/refstring = clean_input("Which reference?","Ref")
if(!refstring)
return
var/datum/D = locate(refstring)
if(!D)
to_chat(usr, "<span class='warning'>That ref string does not correspond to any datum.</span>")
return
debug_variables(D)
+1 -1
View File
@@ -19,4 +19,4 @@
if(alert("Do you want to inform the world about the result?",,"Yes", "No") == "Yes")
to_chat(world, "<h2 style=\"color:#A50400\">Gods rolled [dice], result is [result]</h2>")
message_admins("[key_name_admin(src)] rolled dice [dice], result is [result]", 1)
message_admins("[key_name_admin(src)] rolled dice [dice], result is [result]", 1)
+67 -89
View File
@@ -5,121 +5,99 @@
//////Allows admin's to right click on any mob/mech and freeze them in place.///
////////////////////////////////////////////////////////////////////////////////
////////////////////////////////////////////////////////////////////////////////
var/global/list/frozen_mob_list = list()
/client/proc/freeze(var/mob/living/M as mob in GLOB.mob_list)
GLOBAL_LIST_EMPTY(frozen_atom_list) // A list of admin-frozen atoms.
/client/proc/freeze(atom/movable/M)
set name = "Freeze"
set category = null
if(!check_rights(R_ADMIN))
return
if(!istype(M))
return
M.admin_Freeze(src)
if(M in frozen_mob_list)
M.admin_unFreeze(src)
else
M.admin_Freeze(src)
/// Created here as a base proc. Override as needed for any type of object or mob you want able to be frozen.
/atom/movable/proc/admin_Freeze(client/admin)
to_chat(admin, "<span class='warning'>Freeze is not able to be called on this type of object.</span")
return
///mob freeze procs
/mob/living/var/frozen = null //used for preventing attacks on admin-frozen mobs
/mob/living/var/admin_prev_sleeping = 0 //used for keeping track of previous sleeping value with admin freeze
/mob/living
/// Used for preventing attacks on admin-frozen mobs.
var/frozen = null
/// Used for keeping track of previous sleeping value with admin freeze.
var/admin_prev_sleeping = 0
/mob/living/proc/admin_Freeze(client/admin, skip_overlays = FALSE)
if(istype(admin))
to_chat(src, "<b><font color= red>You have been frozen by [admin]</b></font>")
message_admins("<span class='notice'>[key_name_admin(admin)]</span> froze [key_name_admin(src)]")
log_admin("[key_name(admin)] froze [key_name(src)]")
/mob/living/admin_Freeze(client/admin, skip_overlays = FALSE, mech = null)
if(!istype(admin))
return
var/obj/effect/overlay/adminoverlay/AO = new
if(skip_overlays)
overlays += AO
if(!(src in GLOB.frozen_atom_list))
GLOB.frozen_atom_list += src
anchored = TRUE
canmove = FALSE
admin_prev_sleeping = sleeping
AdjustSleeping(20000)
frozen = AO
if(!(src in frozen_mob_list))
frozen_mob_list += src
var/obj/effect/overlay/adminoverlay/AO = new
if(skip_overlays)
overlays += AO
/mob/living/proc/admin_unFreeze(client/admin, skip_overlays = FALSE)
if(istype(admin))
to_chat(src, "<b><font color= red>You have been unfrozen by [admin]</b></font>")
message_admins("<span class='notice'>[key_name_admin(admin)] unfroze [key_name_admin(src)]</span>")
log_admin("[key_name(admin)] unfroze [key_name(src)]")
anchored = TRUE
canmove = FALSE
admin_prev_sleeping = sleeping
AdjustSleeping(20000)
frozen = AO
if(skip_overlays)
overlays -= frozen
else
GLOB.frozen_atom_list -= src
anchored = FALSE
canmove = TRUE
frozen = null
SetSleeping(admin_prev_sleeping)
admin_prev_sleeping = null
if(src in frozen_mob_list)
frozen_mob_list -= src
if(skip_overlays)
overlays -= frozen
anchored = FALSE
canmove = TRUE
frozen = null
SetSleeping(admin_prev_sleeping)
admin_prev_sleeping = null
to_chat(src, "<b><font color= red>You have been [frozen ? "frozen" : "unfrozen"] by [admin]</b></font>")
message_admins("<span class='notice'>[key_name_admin(admin)] [frozen ? "froze" : "unfroze"] [key_name_admin(src)] [mech ? "in a [mech]" : ""]</span>")
log_admin("[key_name(admin)] [frozen ? "froze" : "unfroze"] [key_name(src)] [mech ? "in a [mech]" : ""]")
update_icons()
return frozen
/mob/living/simple_animal/slime/admin_Freeze(admin)
..(admin)
adjustHealth(1000) //arbitrary large value
/mob/living/simple_animal/slime/admin_unFreeze(admin)
..(admin)
revive()
if(..()) // The result of the parent call here will be the value of the mob's `frozen` variable after they get (un)frozen.
adjustHealth(1000) //arbitrary large value
else
revive()
/mob/living/simple_animal/var/admin_prev_health = null
/mob/living/simple_animal/admin_Freeze(admin)
..(admin)
admin_prev_health = health
health = 0
/mob/living/simple_animal/admin_unFreeze(admin)
..(admin)
revive()
overlays.Cut()
if(..()) // The result of the parent call here will be the value of the mob's `frozen` variable after they get (un)frozen.
admin_prev_health = health
health = 0
else
revive()
overlays.Cut()
//////////////////////////Freeze Mech
/client/proc/freezemecha(var/obj/mecha/O as obj in GLOB.mechas_list)
set name = "Freeze Mech"
set category = null
if(!check_rights(R_ADMIN))
return
var/obj/mecha/M = O
if(!istype(M,/obj/mecha))
to_chat(src, "<span class='danger'>This can only be used on mechs!</span>")
return
/obj/mecha/admin_Freeze(client/admin)
var/obj/effect/overlay/adminoverlay/freeze_overlay = new
if(!frozen)
GLOB.frozen_atom_list += src
frozen = TRUE
overlays += freeze_overlay
else
if(usr)
if(usr.client)
if(usr.client.holder)
var/adminomaly = new/obj/effect/overlay/adminoverlay
if(M.can_move == 1)
M.can_move = 0
M.overlays += adminomaly
if(M.occupant)
to_chat(M.occupant, "<b><font color= red>You have been frozen by <a href='?priv_msg=[usr.client.UID()]'>[key]</a></b></font>")
message_admins("<span class='notice'>[key_name_admin(usr)] froze [key_name(M.occupant)] in a [M.name]</span>")
log_admin("[key_name(usr)] froze [key_name(M.occupant)] in a [M.name]")
else
message_admins("<span class='notice'>[key_name_admin(usr)] froze an empty [M.name]</span>")
log_admin("[key_name(usr)] froze an empty [M.name]")
else if(M.can_move == 0)
M.can_move = 1
M.overlays -= adminomaly
if(M.occupant)
to_chat(M.occupant, "<b><font color= red>You have been unfrozen by <a href='?priv_msg=[usr.client.UID()]'>[key]</a></b></font>")
message_admins("<span class='notice'>[key_name_admin(usr)] unfroze [key_name(M.occupant)] in a [M.name]</span>")
log_admin("[key_name(usr)] unfroze [key_name(M.occupant)] in a [M.name]")
else
message_admins("<span class='notice'>[key_name_admin(usr)] unfroze an empty [M.name]</span>")
log_admin("[key_name(usr)] unfroze an empty [M.name]")
GLOB.frozen_atom_list -= src
frozen = FALSE
overlays -= freeze_overlay
if(occupant)
occupant.admin_Freeze(admin, mech = name) // We also want to freeze the driver of the mech.
else
message_admins("<span class='notice'>[key_name_admin(admin)] [frozen ? "froze" : "unfroze"] an empty [name]</span>")
log_admin("[key_name(admin)] [frozen ? "froze" : "unfroze"] an empty [name]")
+1 -1
View File
@@ -38,4 +38,4 @@
else
return
to_chat(src, "Attempting to send [path], this may take a fair few minutes if the file is very large.")
return
return
+1 -1
View File
@@ -27,7 +27,7 @@
if(!themission)
alert("No mission specified. Aborting.")
return
var/admin_outfits = subtypesof(/datum/outfit/admin)
var/admin_outfits = subtypesof(/datum/outfit/admin) + list(/datum/outfit/naked)
var/outfit_list = list()
for(var/type in admin_outfits)
var/datum/outfit/admin/O = type
+8 -8
View File
@@ -1,7 +1,7 @@
//HONKsquad
var/const/honksquad_possible = 6 //if more Commandos are needed in the future
var/global/sent_honksquad = 0
#define HONKSQUAD_POSSIBLE 6 //if more Commandos are needed in the future
GLOBAL_VAR_INIT(sent_honksquad, 0)
/client/proc/honksquad()
if(!SSticker)
@@ -10,7 +10,7 @@ var/global/sent_honksquad = 0
if(world.time < 6000)
to_chat(usr, "<font color='red'>There are [(6000-world.time)/10] seconds remaining before it may be called.</font>")
return
if(sent_honksquad == 1)
if(GLOB.sent_honksquad == 1)
to_chat(usr, "<font color='red'>Clown Planet has already dispatched a HONKsquad.</font>")
return
if(alert("Do you want to send in the HONKsquad? Once enabled, this is irreversible.",,"Yes","No")!="Yes")
@@ -24,14 +24,14 @@ var/global/sent_honksquad = 0
if(alert("Error, no mission set. Do you want to exit the setup process?",,"Yes","No")=="Yes")
return
if(sent_honksquad)
if(GLOB.sent_honksquad)
to_chat(usr, "Looks like someone beat you to it. HONK.")
return
sent_honksquad = 1
GLOB.sent_honksquad = 1
var/honksquad_number = honksquad_possible //for selecting a leader
var/honksquad_number = HONKSQUAD_POSSIBLE //for selecting a leader
var/honk_leader_selected = 0 //when the leader is chosen. The last person spawned.
@@ -42,7 +42,7 @@ var/global/sent_honksquad = 0
if(!G.client.holder && !G.client.is_afk()) //Whoever called/has the proc won't be added to the list.
if(!(G.mind && G.mind.current && G.mind.current.stat != DEAD))
candidates += G.key
for(var/i=honksquad_possible,(i>0&&candidates.len),i--)//Decrease with every commando selected.
for(var/i=HONKSQUAD_POSSIBLE,(i>0&&candidates.len),i--)//Decrease with every commando selected.
var/candidate = input("Pick characters to spawn as the HONKsquad. This will go on until there either no more ghosts to pick from or the slots are full.", "Active Players") as null|anything in candidates //It will auto-pick a person when there is only one candidate.
candidates -= candidate //Subtract from candidates.
commandos += candidate//Add their ghost to commandos.
@@ -132,7 +132,7 @@ var/global/sent_honksquad = 0
var/obj/item/card/id/W = new(src)
W.name = "[real_name]'s ID Card"
W.icon_state = "centcom_old"
W.access = list(access_clown)//They get full station access.
W.access = list(ACCESS_CLOWN)//They get full station access.
W.assignment = "HONKsquad"
W.registered_name = real_name
equip_to_slot_or_del(W, slot_wear_id)
@@ -1,7 +1,7 @@
// Syndicate Infiltration Team (SIT)
// A little like Syndicate Strike Team (SST) but geared towards stealthy team missions rather than murderbone.
var/global/sent_syndicate_infiltration_team = 0
GLOBAL_VAR_INIT(sent_syndicate_infiltration_team, 0)
/client/proc/syndicate_infiltration_team()
set category = "Event"
@@ -35,7 +35,7 @@ var/global/sent_syndicate_infiltration_team = 0
var/tctext = input(src, "How much TC do you want to give each team member? Suggested: 20-30. They cannot trade TC.") as num
var/tcamount = text2num(tctext)
tcamount = between(0, tcamount, 1000)
if(sent_syndicate_infiltration_team == 1)
if(GLOB.sent_syndicate_infiltration_team == 1)
if(alert("A Syndicate Infiltration Team has already been sent. Sure you want to send another?",,"Yes","No")=="No")
return
@@ -61,7 +61,7 @@ var/global/sent_syndicate_infiltration_team = 0
to_chat(src, "Nobody volunteered.")
return 0
sent_syndicate_infiltration_team = 1
GLOB.sent_syndicate_infiltration_team = 1
var/list/sit_spawns = list()
var/list/sit_spawns_leader = list()
@@ -90,7 +90,7 @@ var/global/sent_syndicate_infiltration_team = 0
to_chat(new_syndicate_infiltrator, "<span class='danger'>You are a [!syndicate_leader_selected?"Infiltrator":"<B>Lead Infiltrator</B>"] in the service of the Syndicate. \nYour current mission is: <B>[input]</B></span>")
to_chat(new_syndicate_infiltrator, "<span class='notice'>You are equipped with an uplink implant to help you achieve your objectives. ((activate it via button in top left of screen))</span>")
new_syndicate_infiltrator.faction += "syndicate"
data_core.manifest_inject(new_syndicate_infiltrator)
GLOB.data_core.manifest_inject(new_syndicate_infiltrator)
if(syndicate_leader_selected)
var/obj/effect/landmark/warpto = pick(sit_spawns_leader)
new_syndicate_infiltrator.loc = warpto.loc
@@ -104,7 +104,7 @@ var/global/sent_syndicate_infiltration_team = 0
new_syndicate_infiltrator.mind.store_memory("<B>Mission:</B> [input] ")
new_syndicate_infiltrator.mind.store_memory("<B>Team Leader:</B> [team_leader] ")
new_syndicate_infiltrator.mind.store_memory("<B>Starting Equipment:</B> <BR>- Syndicate Headset ((.h for your radio))<BR>- Chameleon Jumpsuit ((right click to Change Color))<BR> - Agent ID card ((disguise as another job))<BR> - Uplink Implant ((top left of screen)) <BR> - Dust Implant ((destroys your body on death)) <BR> - Combat Gloves ((insulated, disguised as black gloves)) <BR> - Anything bought with your uplink implant")
var/datum/atom_hud/antag/opshud = huds[ANTAG_HUD_OPS]
var/datum/atom_hud/antag/opshud = GLOB.huds[ANTAG_HUD_OPS]
opshud.join_hud(new_syndicate_infiltrator.mind.current)
set_antag_hud(new_syndicate_infiltrator.mind.current, "hudoperative")
new_syndicate_infiltrator.regenerate_icons()
@@ -177,10 +177,10 @@ var/global/sent_syndicate_infiltration_team = 0
W.icon_state = "commander"
else
W.icon_state = "id"
W.access = list(access_maint_tunnels,access_external_airlocks)
W.access = list(ACCESS_MAINT_TUNNELS,ACCESS_EXTERNAL_AIRLOCKS)
W.assignment = "Civilian"
W.access += get_access("Civilian")
W.access += list(access_medical, access_engine, access_cargo, access_research)
W.access += list(ACCESS_MEDICAL, ACCESS_ENGINE, ACCESS_CARGO, ACCESS_RESEARCH)
if(flag_mgmt)
W.assignment = "Syndicate Management Consultant"
W.access += get_syndicate_access("Syndicate Commando")
+11
View File
@@ -0,0 +1,11 @@
GLOBAL_LIST_INIT(open_logging_views, list())
/client/proc/cmd_admin_open_logging_view()
set category = "Admin"
set name = "Open Logging View"
set desc = "Opens the detailed logging viewer"
if(!GLOB.open_logging_views[usr.client.ckey])
GLOB.open_logging_views[usr.client.ckey] = new /datum/log_viewer()
var/datum/log_viewer/LV = GLOB.open_logging_views[usr.client.ckey]
LV.show_ui(usr)
@@ -6,10 +6,10 @@
return
var/datum/map_template/template
var/map = input(usr, "Choose a Map Template to place at your CURRENT LOCATION","Place Map Template") as null|anything in map_templates
var/map = input(usr, "Choose a Map Template to place at your CURRENT LOCATION","Place Map Template") as null|anything in GLOB.map_templates
if(!map)
return
template = map_templates[map]
template = GLOB.map_templates[map]
var/turf/T = get_turf(mob)
if(!T)
@@ -48,7 +48,7 @@
var/datum/map_template/M = new(map=map, rename="[map]")
if(M.preload_size(map))
to_chat(usr, "Map template '[map]' ready to place ([M.width]x[M.height])")
map_templates[M.name] = M
GLOB.map_templates[M.name] = M
message_admins("<span class='adminnotice'>[key_name_admin(usr)] has uploaded a map template ([map]). Took [stop_watch(timer)]s.</span>")
else
to_chat(usr, "Map template '[map]' failed to load properly")
+185 -185
View File
@@ -1,185 +1,185 @@
//- Are all the floors with or without air, as they should be? (regular or airless)
//- Does the area have an APC?
//- Does the area have an Air Alarm?
//- Does the area have a Request Console?
//- Does the area have lights?
//- Does the area have a light switch?
//- Does the area have enough intercoms?
//- Does the area have enough security cameras? (Use the 'Camera Range Display' verb under Debug)
//- Is the area connected to the scrubbers air loop?
//- Is the area connected to the vent air loop? (vent pumps)
//- Is everything wired properly?
//- Does the area have a fire alarm and firedoors?
//- Do all pod doors work properly?
//- Are accesses set properly on doors, pod buttons, etc.
//- Are all items placed properly? (not below vents, scrubbers, tables)
//- Does the disposal system work properly from all the disposal units in this room and all the units, the pipes of which pass through this room?
//- Check for any misplaced or stacked piece of pipe (air and disposal)
//- Check for any misplaced or stacked piece of wire
//- Identify how hard it is to break into the area and where the weak points are
//- Check if the area has too much empty space. If so, make it smaller and replace the rest with maintenance tunnels.
var/camera_range_display_status = 0
var/intercom_range_display_status = 0
/obj/effect/debugging/camera_range
icon = 'icons/480x480.dmi'
icon_state = "25percent"
New()
src.pixel_x = -224
src.pixel_y = -224
/obj/effect/debugging/mapfix_marker
name = "map fix marker"
icon = 'icons/mob/screen_gen.dmi'
icon_state = "mapfixmarker"
desc = "I am a mappers mistake."
/obj/effect/debugging/marker
icon = 'icons/turf/areas.dmi'
icon_state = "yellow"
/obj/effect/debugging/marker/Move()
return 0
/client/proc/camera_view()
set category = "Mapping"
set name = "Camera Range Display"
if(!check_rights(R_DEBUG))
return
if(camera_range_display_status)
camera_range_display_status = 0
else
camera_range_display_status = 1
for(var/obj/effect/debugging/camera_range/C in world)
qdel(C)
if(camera_range_display_status)
for(var/obj/machinery/camera/C in cameranet.cameras)
new/obj/effect/debugging/camera_range(C.loc)
feedback_add_details("admin_verb","mCRD") //If you are copy-pasting this, ensure the 2nd parameter is unique to the new proc!
/client/proc/sec_camera_report()
set category = "Mapping"
set name = "Camera Report"
if(!check_rights(R_DEBUG))
return
var/list/obj/machinery/camera/CL = list()
for(var/obj/machinery/camera/C in cameranet.cameras)
CL += C
var/output = {"<B>CAMERA ANOMALIES REPORT</B><HR>
<B>The following anomalies have been detected. The ones in red need immediate attention: Some of those in black may be intentional.</B><BR><ul>"}
for(var/obj/machinery/camera/C1 in CL)
for(var/obj/machinery/camera/C2 in CL)
if(C1 != C2)
if(C1.c_tag == C2.c_tag)
output += "<li><font color='red'>c_tag match for sec. cameras at \[[C1.x], [C1.y], [C1.z]\] ([C1.loc.loc]) and \[[C2.x], [C2.y], [C2.z]\] ([C2.loc.loc]) - c_tag is [C1.c_tag]</font></li>"
if(C1.loc == C2.loc && C1.dir == C2.dir && C1.pixel_x == C2.pixel_x && C1.pixel_y == C2.pixel_y)
output += "<li><font color='red'>FULLY overlapping sec. cameras at \[[C1.x], [C1.y], [C1.z]\] ([C1.loc.loc]) Networks: [C1.network] and [C2.network]</font></li>"
if(C1.loc == C2.loc)
output += "<li>overlapping sec. cameras at \[[C1.x], [C1.y], [C1.z]\] ([C1.loc.loc]) Networks: [C1.network] and [C2.network]</font></li>"
var/turf/T = get_step(C1,turn(C1.dir,180))
if(!T || !isturf(T) || !T.density )
if(!(locate(/obj/structure/grille,T)))
var/window_check = 0
for(var/obj/structure/window/W in T)
if(W.dir == turn(C1.dir,180) || W.fulltile)
window_check = 1
break
if(!window_check)
output += "<li><font color='red'>Camera not connected to wall at \[[C1.x], [C1.y], [C1.z]\] ([C1.loc.loc]) Network: [C1.network]</color></li>"
output += "</ul>"
usr << browse(output,"window=airreport;size=1000x500")
feedback_add_details("admin_verb","mCRP") //If you are copy-pasting this, ensure the 2nd parameter is unique to the new proc!
/client/proc/intercom_view()
set category = "Mapping"
set name = "Intercom Range Display"
if(!check_rights(R_DEBUG))
return
if(intercom_range_display_status)
intercom_range_display_status = 0
else
intercom_range_display_status = 1
for(var/obj/effect/debugging/marker/M in world)
qdel(M)
if(intercom_range_display_status)
for(var/obj/item/radio/intercom/I in world)
for(var/turf/T in orange(7,I))
var/obj/effect/debugging/marker/F = new/obj/effect/debugging/marker(T)
if(!(F in view(7,I.loc)))
qdel(F)
feedback_add_details("admin_verb","mIRD") //If you are copy-pasting this, ensure the 2nd parameter is unique to the new proc!
/client/proc/count_objects_on_z_level()
set category = "Mapping"
set name = "Count Objects On Level"
if(!check_rights(R_DEBUG))
return
var/level = clean_input("Which z-level?","Level?")
if(!level) return
var/num_level = text2num(level)
if(!num_level) return
if(!isnum(num_level)) return
var/type_text = clean_input("Which type path?","Path?")
if(!type_text) return
var/type_path = text2path(type_text)
if(!type_path) return
var/count = 0
var/list/atom/atom_list = list()
for(var/atom/A in world)
if(istype(A,type_path))
var/atom/B = A
while(!(isturf(B.loc)))
if(B && B.loc)
B = B.loc
else
break
if(B)
if(B.z == num_level)
count++
atom_list += A
to_chat(world, "There are [count] objects of type [type_path] on z-level [num_level].")
feedback_add_details("admin_verb","mOBJZ") //If you are copy-pasting this, ensure the 2nd parameter is unique to the new proc!
/client/proc/count_objects_all()
set category = "Mapping"
set name = "Count Objects All"
if(!check_rights(R_DEBUG))
return
var/type_text = clean_input("Which type path?","")
if(!type_text) return
var/type_path = text2path(type_text)
if(!type_path) return
var/count = 0
for(var/atom/A in world)
if(istype(A,type_path))
count++
to_chat(world, "There are [count] objects of type [type_path] in the game world.")
feedback_add_details("admin_verb","mOBJ") //If you are copy-pasting this, ensure the 2nd parameter is unique to the new proc!
//- Are all the floors with or without air, as they should be? (regular or airless)
//- Does the area have an APC?
//- Does the area have an Air Alarm?
//- Does the area have a Request Console?
//- Does the area have lights?
//- Does the area have a light switch?
//- Does the area have enough intercoms?
//- Does the area have enough security cameras? (Use the 'Camera Range Display' verb under Debug)
//- Is the area connected to the scrubbers air loop?
//- Is the area connected to the vent air loop? (vent pumps)
//- Is everything wired properly?
//- Does the area have a fire alarm and firedoors?
//- Do all pod doors work properly?
//- Are accesses set properly on doors, pod buttons, etc.
//- Are all items placed properly? (not below vents, scrubbers, tables)
//- Does the disposal system work properly from all the disposal units in this room and all the units, the pipes of which pass through this room?
//- Check for any misplaced or stacked piece of pipe (air and disposal)
//- Check for any misplaced or stacked piece of wire
//- Identify how hard it is to break into the area and where the weak points are
//- Check if the area has too much empty space. If so, make it smaller and replace the rest with maintenance tunnels.
GLOBAL_VAR_INIT(camera_range_display_status, 0)
GLOBAL_VAR_INIT(intercom_range_display_status, 0)
/obj/effect/debugging/camera_range
icon = 'icons/480x480.dmi'
icon_state = "25percent"
New()
src.pixel_x = -224
src.pixel_y = -224
/obj/effect/debugging/mapfix_marker
name = "map fix marker"
icon = 'icons/mob/screen_gen.dmi'
icon_state = "mapfixmarker"
desc = "I am a mappers mistake."
/obj/effect/debugging/marker
icon = 'icons/turf/areas.dmi'
icon_state = "yellow"
/obj/effect/debugging/marker/Move()
return 0
/client/proc/camera_view()
set category = "Mapping"
set name = "Camera Range Display"
if(!check_rights(R_DEBUG))
return
if(GLOB.camera_range_display_status)
GLOB.camera_range_display_status = 0
else
GLOB.camera_range_display_status = 1
for(var/obj/effect/debugging/camera_range/C in world)
qdel(C)
if(GLOB.camera_range_display_status)
for(var/obj/machinery/camera/C in GLOB.cameranet.cameras)
new/obj/effect/debugging/camera_range(C.loc)
feedback_add_details("admin_verb","mCRD") //If you are copy-pasting this, ensure the 2nd parameter is unique to the new proc!
/client/proc/sec_camera_report()
set category = "Mapping"
set name = "Camera Report"
if(!check_rights(R_DEBUG))
return
var/list/obj/machinery/camera/CL = list()
for(var/obj/machinery/camera/C in GLOB.cameranet.cameras)
CL += C
var/output = {"<B>CAMERA ANOMALIES REPORT</B><HR>
<B>The following anomalies have been detected. The ones in red need immediate attention: Some of those in black may be intentional.</B><BR><ul>"}
for(var/obj/machinery/camera/C1 in CL)
for(var/obj/machinery/camera/C2 in CL)
if(C1 != C2)
if(C1.c_tag == C2.c_tag)
output += "<li><font color='red'>c_tag match for sec. cameras at \[[C1.x], [C1.y], [C1.z]\] ([C1.loc.loc]) and \[[C2.x], [C2.y], [C2.z]\] ([C2.loc.loc]) - c_tag is [C1.c_tag]</font></li>"
if(C1.loc == C2.loc && C1.dir == C2.dir && C1.pixel_x == C2.pixel_x && C1.pixel_y == C2.pixel_y)
output += "<li><font color='red'>FULLY overlapping sec. cameras at \[[C1.x], [C1.y], [C1.z]\] ([C1.loc.loc]) Networks: [C1.network] and [C2.network]</font></li>"
if(C1.loc == C2.loc)
output += "<li>overlapping sec. cameras at \[[C1.x], [C1.y], [C1.z]\] ([C1.loc.loc]) Networks: [C1.network] and [C2.network]</font></li>"
var/turf/T = get_step(C1,turn(C1.dir,180))
if(!T || !isturf(T) || !T.density )
if(!(locate(/obj/structure/grille,T)))
var/window_check = 0
for(var/obj/structure/window/W in T)
if(W.dir == turn(C1.dir,180) || W.fulltile)
window_check = 1
break
if(!window_check)
output += "<li><font color='red'>Camera not connected to wall at \[[C1.x], [C1.y], [C1.z]\] ([C1.loc.loc]) Network: [C1.network]</color></li>"
output += "</ul>"
usr << browse(output,"window=airreport;size=1000x500")
feedback_add_details("admin_verb","mCRP") //If you are copy-pasting this, ensure the 2nd parameter is unique to the new proc!
/client/proc/intercom_view()
set category = "Mapping"
set name = "Intercom Range Display"
if(!check_rights(R_DEBUG))
return
if(GLOB.intercom_range_display_status)
GLOB.intercom_range_display_status = 0
else
GLOB.intercom_range_display_status = 1
for(var/obj/effect/debugging/marker/M in world)
qdel(M)
if(GLOB.intercom_range_display_status)
for(var/obj/item/radio/intercom/I in world)
for(var/turf/T in orange(7,I))
var/obj/effect/debugging/marker/F = new/obj/effect/debugging/marker(T)
if(!(F in view(7,I.loc)))
qdel(F)
feedback_add_details("admin_verb","mIRD") //If you are copy-pasting this, ensure the 2nd parameter is unique to the new proc!
/client/proc/count_objects_on_z_level()
set category = "Mapping"
set name = "Count Objects On Level"
if(!check_rights(R_DEBUG))
return
var/level = clean_input("Which z-level?","Level?")
if(!level) return
var/num_level = text2num(level)
if(!num_level) return
if(!isnum(num_level)) return
var/type_text = clean_input("Which type path?","Path?")
if(!type_text) return
var/type_path = text2path(type_text)
if(!type_path) return
var/count = 0
var/list/atom/atom_list = list()
for(var/atom/A in world)
if(istype(A,type_path))
var/atom/B = A
while(!(isturf(B.loc)))
if(B && B.loc)
B = B.loc
else
break
if(B)
if(B.z == num_level)
count++
atom_list += A
to_chat(world, "There are [count] objects of type [type_path] on z-level [num_level].")
feedback_add_details("admin_verb","mOBJZ") //If you are copy-pasting this, ensure the 2nd parameter is unique to the new proc!
/client/proc/count_objects_all()
set category = "Mapping"
set name = "Count Objects All"
if(!check_rights(R_DEBUG))
return
var/type_text = clean_input("Which type path?","")
if(!type_text) return
var/type_path = text2path(type_text)
if(!type_path) return
var/count = 0
for(var/atom/A in world)
if(istype(A,type_path))
count++
to_chat(world, "There are [count] objects of type [type_path] in the game world.")
feedback_add_details("admin_verb","mOBJ") //If you are copy-pasting this, ensure the 2nd parameter is unique to the new proc!
+272 -272
View File
@@ -1,272 +1,272 @@
/client/proc/cmd_mass_modify_object_variables(atom/A, var/var_name)
set category = "Debug"
set name = "Mass Edit Variables"
set desc="(target) Edit all instances of a target item's variables"
var/method = 0 //0 means strict type detection while 1 means this type and all subtypes (IE: /obj/item with this set to 1 will set it to ALL itms)
if(!check_rights(R_VAREDIT)) return
if(A && A.type)
if(typesof(A.type))
switch(input("Strict object type detection?") as null|anything in list("Strictly this type","This type and subtypes", "Cancel"))
if("Strictly this type")
method = 0
if("This type and subtypes")
method = 1
if("Cancel")
return
if(null)
return
src.massmodify_variables(A, var_name, method)
feedback_add_details("admin_verb","MEV") //If you are copy-pasting this, ensure the 2nd parameter is unique to the new proc!
/client/proc/massmodify_variables(datum/O, var_name = "", method = 0)
if(!check_rights(R_VAREDIT))
return
if(!istype(O))
return
var/variable = ""
if(!var_name)
var/list/names = list()
for(var/V in O.vars)
names += V
names = sortList(names)
variable = input("Which var?", "Var") as null|anything in names
else
variable = var_name
if(!variable || !O.can_vv_get(variable))
return
var/default
var/var_value = O.vars[variable]
if(variable in VVckey_edit)
to_chat(src, "It's forbidden to mass-modify ckeys. It'll crash everyone's client you dummy.")
return
if(variable in VVlocked)
if(!check_rights(R_DEBUG))
return
if(variable in VVicon_edit_lock)
if(!check_rights(R_EVENT | R_DEBUG))
return
if(variable in VVpixelmovement)
if(!check_rights(R_DEBUG))
return
var/prompt = alert(src, "Editing this var may irreparably break tile gliding for the rest of the round. THIS CAN'T BE UNDONE", "DANGER", "ABORT ", "Continue", " ABORT")
if(prompt != "Continue")
return
default = vv_get_class(var_value)
if(isnull(default))
to_chat(src, "Unable to determine variable type.")
else
to_chat(src, "Variable appears to be <b>[uppertext(default)]</b>.")
to_chat(src, "Variable contains: [var_value]")
if(default == VV_NUM)
var/dir_text = ""
if(dir < 0 && dir < 16)
if(dir & 1)
dir_text += "NORTH"
if(dir & 2)
dir_text += "SOUTH"
if(dir & 4)
dir_text += "EAST"
if(dir & 8)
dir_text += "WEST"
if(dir_text)
to_chat(src, "If a direction, direction is: [dir_text]")
var/value = vv_get_value(default_class = default)
var/new_value = value["value"]
var/class = value["class"]
if(!class || !new_value == null && class != VV_NULL)
return
if(class == VV_MESSAGE)
class = VV_TEXT
if(value["type"])
class = VV_NEW_TYPE
var/original_name = "[O]"
var/rejected = 0
var/accepted = 0
switch(class)
if(VV_RESTORE_DEFAULT)
to_chat(src, "Finding items...")
var/list/items = get_all_of_type(O.type, method)
to_chat(src, "Changing [items.len] items...")
for(var/thing in items)
if(!thing)
continue
var/datum/D = thing
if(D.vv_edit_var(variable, initial(D.vars[variable])) != FALSE)
accepted++
else
rejected++
CHECK_TICK
if(VV_TEXT)
var/list/varsvars = vv_parse_text(O, new_value)
var/pre_processing = new_value
var/unique
if(varsvars && varsvars.len)
unique = alert(usr, "Process vars unique to each instance, or same for all?", "Variable Association", "Unique", "Same")
if(unique == "Unique")
unique = TRUE
else
unique = FALSE
for(var/V in varsvars)
new_value = replacetext(new_value,"\[[V]]","[O.vars[V]]")
to_chat(src, "Finding items...")
var/list/items = get_all_of_type(O.type, method)
to_chat(src, "Changing [items.len] items...")
for(var/thing in items)
if(!thing)
continue
var/datum/D = thing
if(unique)
new_value = pre_processing
for(var/V in varsvars)
new_value = replacetext(new_value,"\[[V]]","[D.vars[V]]")
if(D.vv_edit_var(variable, new_value) != FALSE)
accepted++
else
rejected++
CHECK_TICK
if(VV_NEW_TYPE)
var/many = alert(src, "Create only one [value["type"]] and assign each or a new one for each thing", "How Many", "One", "Many", "Cancel")
if(many == "Cancel")
return
if(many == "Many")
many = TRUE
else
many = FALSE
var/type = value["type"]
to_chat(src, "Finding items...")
var/list/items = get_all_of_type(O.type, method)
to_chat(src, "Changing [items.len] items...")
for(var/thing in items)
if(!thing)
continue
var/datum/D = thing
if(many && !new_value)
new_value = new type()
if(D.vv_edit_var(variable, new_value) != FALSE)
accepted++
else
rejected++
new_value = null
CHECK_TICK
else
to_chat(src, "Finding items...")
var/list/items = get_all_of_type(O.type, method)
to_chat(src, "Changing [items.len] items...")
for(var/thing in items)
if(!thing)
continue
var/datum/D = thing
if(D.vv_edit_var(variable, new_value) != FALSE)
accepted++
else
rejected++
CHECK_TICK
var/count = rejected+accepted
if(!count)
to_chat(src, "No objects found")
return
if(!accepted)
to_chat(src, "Every object rejected your edit")
return
if(rejected)
to_chat(src, "[rejected] out of [count] objects rejected your edit")
log_world("### MassVarEdit by [src]: [O.type] (A/R [accepted]/[rejected]) [variable]=[html_encode("[O.vars[variable]]")]([list2params(value)])")
log_admin("[key_name(src)] mass modified [original_name]'s [variable] to [O.vars[variable]] ([accepted] objects modified)")
message_admins("[key_name_admin(src)] mass modified [original_name]'s [variable] to [O.vars[variable]] ([accepted] objects modified)")
/proc/get_all_of_type(var/T, subtypes = TRUE)
var/list/typecache = list()
typecache[T] = 1
if(subtypes)
typecache = typecacheof(typecache)
. = list()
if(ispath(T, /mob))
for(var/mob/thing in GLOB.mob_list)
if(typecache[thing.type])
. += thing
CHECK_TICK
else if(ispath(T, /obj/machinery/door))
for(var/obj/machinery/door/thing in GLOB.airlocks)
if(typecache[thing.type])
. += thing
CHECK_TICK
else if(ispath(T, /obj/machinery))
for(var/obj/machinery/thing in GLOB.machines)
if(typecache[thing.type])
. += thing
CHECK_TICK
else if(ispath(T, /obj))
for(var/obj/thing in world)
if(typecache[thing.type])
. += thing
CHECK_TICK
else if(ispath(T, /atom/movable))
for(var/atom/movable/thing in world)
if(typecache[thing.type])
. += thing
CHECK_TICK
else if(ispath(T, /turf))
for(var/turf/thing in world)
if(typecache[thing.type])
. += thing
CHECK_TICK
else if(ispath(T, /atom))
for(var/atom/thing in world)
if(typecache[thing.type])
. += thing
CHECK_TICK
else if(ispath(T, /client))
for(var/client/thing in GLOB.clients)
if(typecache[thing.type])
. += thing
CHECK_TICK
else if(ispath(T, /datum))
for(var/datum/thing)
if(typecache[thing.type])
. += thing
CHECK_TICK
else
for(var/datum/thing in world)
if(typecache[thing.type])
. += thing
CHECK_TICK
/client/proc/cmd_mass_modify_object_variables(atom/A, var/var_name)
set category = "Debug"
set name = "Mass Edit Variables"
set desc="(target) Edit all instances of a target item's variables"
var/method = 0 //0 means strict type detection while 1 means this type and all subtypes (IE: /obj/item with this set to 1 will set it to ALL itms)
if(!check_rights(R_VAREDIT)) return
if(A && A.type)
if(typesof(A.type))
switch(input("Strict object type detection?") as null|anything in list("Strictly this type","This type and subtypes", "Cancel"))
if("Strictly this type")
method = 0
if("This type and subtypes")
method = 1
if("Cancel")
return
if(null)
return
src.massmodify_variables(A, var_name, method)
feedback_add_details("admin_verb","MEV") //If you are copy-pasting this, ensure the 2nd parameter is unique to the new proc!
/client/proc/massmodify_variables(datum/O, var_name = "", method = 0)
if(!check_rights(R_VAREDIT))
return
if(!istype(O))
return
var/variable = ""
if(!var_name)
var/list/names = list()
for(var/V in O.vars)
names += V
names = sortList(names)
variable = input("Which var?", "Var") as null|anything in names
else
variable = var_name
if(!variable || !O.can_vv_get(variable))
return
var/default
var/var_value = O.vars[variable]
if(variable in GLOB.VVckey_edit)
to_chat(src, "It's forbidden to mass-modify ckeys. It'll crash everyone's client you dummy.")
return
if(variable in GLOB.VVlocked)
if(!check_rights(R_DEBUG))
return
if(variable in GLOB.VVicon_edit_lock)
if(!check_rights(R_EVENT | R_DEBUG))
return
if(variable in GLOB.VVpixelmovement)
if(!check_rights(R_DEBUG))
return
var/prompt = alert(src, "Editing this var may irreparably break tile gliding for the rest of the round. THIS CAN'T BE UNDONE", "DANGER", "ABORT ", "Continue", " ABORT")
if(prompt != "Continue")
return
default = vv_get_class(var_value)
if(isnull(default))
to_chat(src, "Unable to determine variable type.")
else
to_chat(src, "Variable appears to be <b>[uppertext(default)]</b>.")
to_chat(src, "Variable contains: [var_value]")
if(default == VV_NUM)
var/dir_text = ""
if(dir < 0 && dir < 16)
if(dir & 1)
dir_text += "NORTH"
if(dir & 2)
dir_text += "SOUTH"
if(dir & 4)
dir_text += "EAST"
if(dir & 8)
dir_text += "WEST"
if(dir_text)
to_chat(src, "If a direction, direction is: [dir_text]")
var/value = vv_get_value(default_class = default)
var/new_value = value["value"]
var/class = value["class"]
if(!class || !new_value == null && class != VV_NULL)
return
if(class == VV_MESSAGE)
class = VV_TEXT
if(value["type"])
class = VV_NEW_TYPE
var/original_name = "[O]"
var/rejected = 0
var/accepted = 0
switch(class)
if(VV_RESTORE_DEFAULT)
to_chat(src, "Finding items...")
var/list/items = get_all_of_type(O.type, method)
to_chat(src, "Changing [items.len] items...")
for(var/thing in items)
if(!thing)
continue
var/datum/D = thing
if(D.vv_edit_var(variable, initial(D.vars[variable])) != FALSE)
accepted++
else
rejected++
CHECK_TICK
if(VV_TEXT)
var/list/varsvars = vv_parse_text(O, new_value)
var/pre_processing = new_value
var/unique
if(varsvars && varsvars.len)
unique = alert(usr, "Process vars unique to each instance, or same for all?", "Variable Association", "Unique", "Same")
if(unique == "Unique")
unique = TRUE
else
unique = FALSE
for(var/V in varsvars)
new_value = replacetext(new_value,"\[[V]]","[O.vars[V]]")
to_chat(src, "Finding items...")
var/list/items = get_all_of_type(O.type, method)
to_chat(src, "Changing [items.len] items...")
for(var/thing in items)
if(!thing)
continue
var/datum/D = thing
if(unique)
new_value = pre_processing
for(var/V in varsvars)
new_value = replacetext(new_value,"\[[V]]","[D.vars[V]]")
if(D.vv_edit_var(variable, new_value) != FALSE)
accepted++
else
rejected++
CHECK_TICK
if(VV_NEW_TYPE)
var/many = alert(src, "Create only one [value["type"]] and assign each or a new one for each thing", "How Many", "One", "Many", "Cancel")
if(many == "Cancel")
return
if(many == "Many")
many = TRUE
else
many = FALSE
var/type = value["type"]
to_chat(src, "Finding items...")
var/list/items = get_all_of_type(O.type, method)
to_chat(src, "Changing [items.len] items...")
for(var/thing in items)
if(!thing)
continue
var/datum/D = thing
if(many && !new_value)
new_value = new type()
if(D.vv_edit_var(variable, new_value) != FALSE)
accepted++
else
rejected++
new_value = null
CHECK_TICK
else
to_chat(src, "Finding items...")
var/list/items = get_all_of_type(O.type, method)
to_chat(src, "Changing [items.len] items...")
for(var/thing in items)
if(!thing)
continue
var/datum/D = thing
if(D.vv_edit_var(variable, new_value) != FALSE)
accepted++
else
rejected++
CHECK_TICK
var/count = rejected+accepted
if(!count)
to_chat(src, "No objects found")
return
if(!accepted)
to_chat(src, "Every object rejected your edit")
return
if(rejected)
to_chat(src, "[rejected] out of [count] objects rejected your edit")
log_world("### MassVarEdit by [src]: [O.type] (A/R [accepted]/[rejected]) [variable]=[html_encode("[O.vars[variable]]")]([list2params(value)])")
log_admin("[key_name(src)] mass modified [original_name]'s [variable] to [O.vars[variable]] ([accepted] objects modified)")
message_admins("[key_name_admin(src)] mass modified [original_name]'s [variable] to [O.vars[variable]] ([accepted] objects modified)")
/proc/get_all_of_type(var/T, subtypes = TRUE)
var/list/typecache = list()
typecache[T] = 1
if(subtypes)
typecache = typecacheof(typecache)
. = list()
if(ispath(T, /mob))
for(var/mob/thing in GLOB.mob_list)
if(typecache[thing.type])
. += thing
CHECK_TICK
else if(ispath(T, /obj/machinery/door))
for(var/obj/machinery/door/thing in GLOB.airlocks)
if(typecache[thing.type])
. += thing
CHECK_TICK
else if(ispath(T, /obj/machinery))
for(var/obj/machinery/thing in GLOB.machines)
if(typecache[thing.type])
. += thing
CHECK_TICK
else if(ispath(T, /obj))
for(var/obj/thing in world)
if(typecache[thing.type])
. += thing
CHECK_TICK
else if(ispath(T, /atom/movable))
for(var/atom/movable/thing in world)
if(typecache[thing.type])
. += thing
CHECK_TICK
else if(ispath(T, /turf))
for(var/turf/thing in world)
if(typecache[thing.type])
. += thing
CHECK_TICK
else if(ispath(T, /atom))
for(var/atom/thing in world)
if(typecache[thing.type])
. += thing
CHECK_TICK
else if(ispath(T, /client))
for(var/client/thing in GLOB.clients)
if(typecache[thing.type])
. += thing
CHECK_TICK
else if(ispath(T, /datum))
for(var/datum/thing)
if(typecache[thing.type])
. += thing
CHECK_TICK
else
for(var/datum/thing in world)
if(typecache[thing.type])
. += thing
CHECK_TICK
File diff suppressed because it is too large Load Diff
File diff suppressed because it is too large Load Diff
+104 -104
View File
@@ -1,104 +1,104 @@
/client/proc/only_one()
if(!SSticker)
alert("The game hasn't started yet!")
return
var/list/incompatible_species = list(/datum/species/plasmaman, /datum/species/vox)
for(var/mob/living/carbon/human/H in GLOB.player_list)
if(H.stat == DEAD || !(H.client))
continue
if(is_special_character(H))
continue
if(is_type_in_list(H.dna.species, incompatible_species))
H.set_species(/datum/species/human)
var/datum/preferences/A = new() // Randomize appearance
A.copy_to(H)
SSticker.mode.traitors += H.mind
H.mind.special_role = SPECIAL_ROLE_TRAITOR
var/datum/objective/hijack/hijack_objective = new
hijack_objective.owner = H.mind
H.mind.objectives += hijack_objective
to_chat(H, "<B>You are a Highlander. Kill all other Highlanders. There can be only one.</B>")
var/obj_count = 1
for(var/datum/objective/OBJ in H.mind.objectives)
to_chat(H, "<B>Objective #[obj_count]</B>: [OBJ.explanation_text]")
obj_count++
for(var/obj/item/I in H)
if(istype(I, /obj/item/implant))
continue
if(istype(I, /obj/item/organ))
continue
qdel(I)
H.equip_to_slot_or_del(new /obj/item/clothing/under/kilt(H), slot_w_uniform)
H.equip_to_slot_or_del(new /obj/item/radio/headset/heads/captain(H), slot_l_ear)
H.equip_to_slot_or_del(new /obj/item/clothing/head/beret(H), slot_head)
H.equip_to_slot_or_del(new /obj/item/claymore/highlander(H), slot_r_hand)
H.equip_to_slot_or_del(new /obj/item/clothing/shoes/combat(H), slot_shoes)
H.equip_to_slot_or_del(new /obj/item/pinpointer(H.loc), slot_l_store)
var/obj/item/card/id/W = new(H)
W.name = "[H.real_name]'s ID Card"
W.icon_state = "centcom"
W.access = get_all_accesses()
W.access += get_all_centcom_access()
W.assignment = "Highlander"
W.registered_name = H.real_name
H.equip_to_slot_or_del(W, slot_wear_id)
H.dna.species.after_equip_job(null, H)
H.regenerate_icons()
message_admins("[key_name_admin(usr)] used THERE CAN BE ONLY ONE! -NO ATTACK LOGS WILL BE SENT TO ADMINS FROM THIS POINT FORTH-", 1)
log_admin("[key_name(usr)] used there can be only one.")
nologevent = 1
world << sound('sound/music/thunderdome.ogg')
/client/proc/only_me()
if(!SSticker)
alert("The game hasn't started yet!")
return
for(var/mob/living/carbon/human/H in GLOB.player_list)
if(H.stat == 2 || !(H.client)) continue
if(is_special_character(H)) continue
SSticker.mode.traitors += H.mind
H.mind.special_role = "[H.real_name] Prime"
var/datum/objective/hijackclone/hijack_objective = new /datum/objective/hijackclone
hijack_objective.owner = H.mind
H.mind.objectives += hijack_objective
to_chat(H, "<B>You are the multiverse summoner. Activate your blade to summon copies of yourself from another universe to fight by your side.</B>")
var/obj_count = 1
for(var/datum/objective/OBJ in H.mind.objectives)
to_chat(H, "<B>Objective #[obj_count]</B>: [OBJ.explanation_text]")
obj_count++
var/obj/item/slot_item_ID = H.get_item_by_slot(slot_wear_id)
qdel(slot_item_ID)
var/obj/item/slot_item_hand = H.get_item_by_slot(slot_r_hand)
H.unEquip(slot_item_hand)
var /obj/item/multisword/pure_evil/multi = new(H)
H.equip_to_slot_or_del(multi, slot_r_hand)
var/obj/item/card/id/W = new(H)
W.icon_state = "centcom"
W.access = get_all_accesses()
W.access += get_all_centcom_access()
W.assignment = "Multiverse Summoner"
W.registered_name = H.real_name
W.update_label(H.real_name)
H.equip_to_slot_or_del(W, slot_wear_id)
H.update_icons()
message_admins("[key_name_admin(usr)] used THERE CAN BE ONLY ME! -NO ATTACK LOGS WILL BE SENT TO ADMINS FROM THIS POINT FORTH-", 1)
log_admin("[key_name(usr)] used there can be only me.")
nologevent = 1
world << sound('sound/music/thunderdome.ogg')
/client/proc/only_one()
if(!SSticker)
alert("The game hasn't started yet!")
return
var/list/incompatible_species = list(/datum/species/plasmaman, /datum/species/vox)
for(var/mob/living/carbon/human/H in GLOB.player_list)
if(H.stat == DEAD || !(H.client))
continue
if(is_special_character(H))
continue
if(is_type_in_list(H.dna.species, incompatible_species))
H.set_species(/datum/species/human)
var/datum/preferences/A = new() // Randomize appearance
A.copy_to(H)
SSticker.mode.traitors += H.mind
H.mind.special_role = SPECIAL_ROLE_TRAITOR
var/datum/objective/hijack/hijack_objective = new
hijack_objective.owner = H.mind
H.mind.objectives += hijack_objective
to_chat(H, "<B>You are a Highlander. Kill all other Highlanders. There can be only one.</B>")
var/obj_count = 1
for(var/datum/objective/OBJ in H.mind.objectives)
to_chat(H, "<B>Objective #[obj_count]</B>: [OBJ.explanation_text]")
obj_count++
for(var/obj/item/I in H)
if(istype(I, /obj/item/implant))
continue
if(istype(I, /obj/item/organ))
continue
qdel(I)
H.equip_to_slot_or_del(new /obj/item/clothing/under/kilt(H), slot_w_uniform)
H.equip_to_slot_or_del(new /obj/item/radio/headset/heads/captain(H), slot_l_ear)
H.equip_to_slot_or_del(new /obj/item/clothing/head/beret(H), slot_head)
H.equip_to_slot_or_del(new /obj/item/claymore/highlander(H), slot_r_hand)
H.equip_to_slot_or_del(new /obj/item/clothing/shoes/combat(H), slot_shoes)
H.equip_to_slot_or_del(new /obj/item/pinpointer(H.loc), slot_l_store)
var/obj/item/card/id/W = new(H)
W.name = "[H.real_name]'s ID Card"
W.icon_state = "centcom"
W.access = get_all_accesses()
W.access += get_all_centcom_access()
W.assignment = "Highlander"
W.registered_name = H.real_name
H.equip_to_slot_or_del(W, slot_wear_id)
H.dna.species.after_equip_job(null, H)
H.regenerate_icons()
message_admins("[key_name_admin(usr)] used THERE CAN BE ONLY ONE! -NO ATTACK LOGS WILL BE SENT TO ADMINS FROM THIS POINT FORTH-", 1)
log_admin("[key_name(usr)] used there can be only one.")
GLOB.nologevent = 1
world << sound('sound/music/thunderdome.ogg')
/client/proc/only_me()
if(!SSticker)
alert("The game hasn't started yet!")
return
for(var/mob/living/carbon/human/H in GLOB.player_list)
if(H.stat == 2 || !(H.client)) continue
if(is_special_character(H)) continue
SSticker.mode.traitors += H.mind
H.mind.special_role = "[H.real_name] Prime"
var/datum/objective/hijackclone/hijack_objective = new /datum/objective/hijackclone
hijack_objective.owner = H.mind
H.mind.objectives += hijack_objective
to_chat(H, "<B>You are the multiverse summoner. Activate your blade to summon copies of yourself from another universe to fight by your side.</B>")
var/obj_count = 1
for(var/datum/objective/OBJ in H.mind.objectives)
to_chat(H, "<B>Objective #[obj_count]</B>: [OBJ.explanation_text]")
obj_count++
var/obj/item/slot_item_ID = H.get_item_by_slot(slot_wear_id)
qdel(slot_item_ID)
var/obj/item/slot_item_hand = H.get_item_by_slot(slot_r_hand)
H.unEquip(slot_item_hand)
var /obj/item/multisword/pure_evil/multi = new(H)
H.equip_to_slot_or_del(multi, slot_r_hand)
var/obj/item/card/id/W = new(H)
W.icon_state = "centcom"
W.access = get_all_accesses()
W.access += get_all_centcom_access()
W.assignment = "Multiverse Summoner"
W.registered_name = H.real_name
W.update_label(H.real_name)
H.equip_to_slot_or_del(W, slot_wear_id)
H.update_icons()
message_admins("[key_name_admin(usr)] used THERE CAN BE ONLY ME! -NO ATTACK LOGS WILL BE SENT TO ADMINS FROM THIS POINT FORTH-", 1)
log_admin("[key_name(usr)] used there can be only me.")
GLOB.nologevent = 1
world << sound('sound/music/thunderdome.ogg')
+6 -6
View File
@@ -29,7 +29,7 @@
H.equip_to_slot_or_del(new /obj/item/clothing/shoes/white(H), slot_shoes)
if(!team_toggle)
team_alpha += H
GLOB.team_alpha += H
H.equip_to_slot_or_del(new /obj/item/clothing/under/color/red/dodgeball(H), slot_w_uniform)
var/obj/item/card/id/W = new(H)
@@ -42,7 +42,7 @@
H.equip_to_slot_or_del(W, slot_wear_id)
else
team_bravo += H
GLOB.team_bravo += H
H.equip_to_slot_or_del(new /obj/item/clothing/under/color/blue/dodgeball(H), slot_w_uniform)
var/obj/item/card/id/W = new(H)
@@ -60,7 +60,7 @@
message_admins("[key_name_admin(usr)] used DODGEBAWWWWWWWL! -NO ATTACK LOGS WILL BE SENT TO ADMINS FROM THIS POINT FORTH-", 1)
log_admin("[key_name(usr)] used dodgeball.")
nologevent = 1
GLOB.nologevent = 1
/obj/item/beach_ball/dodgeball
name = "dodgeball"
@@ -76,13 +76,13 @@
if(H.r_hand == src) return
if(H.l_hand == src) return
var/mob/A = H.LAssailant
if((H in team_alpha) && (A in team_alpha))
if((H in GLOB.team_alpha) && (A in GLOB.team_alpha))
to_chat(A, "<span class='warning'>He's on your team!</span>")
return
else if((H in team_bravo) && (A in team_bravo))
else if((H in GLOB.team_bravo) && (A in GLOB.team_bravo))
to_chat(A, "<span class='warning'>He's on your team!</span>")
return
else if(!A in team_alpha && !A in team_bravo)
else if(!(A in GLOB.team_alpha) && !(A in GLOB.team_bravo))
to_chat(A, "<span class='warning'>You're not part of the dodgeball game, sorry!</span>")
return
else
+153 -153
View File
@@ -1,153 +1,153 @@
var/list/sounds_cache = list()
/client/proc/stop_global_admin_sounds()
set category = "Event"
set name = "Stop Global Admin Sounds"
if(!check_rights(R_SOUNDS))
return
var/sound/awful_sound = sound(null, repeat = 0, wait = 0, channel = CHANNEL_ADMIN)
log_admin("[key_name(src)] stopped admin sounds.")
message_admins("[key_name_admin(src)] stopped admin sounds.", 1)
for(var/mob/M in GLOB.player_list)
M << awful_sound
/client/proc/play_sound(S as sound)
set category = "Event"
set name = "Play Global Sound"
if(!check_rights(R_SOUNDS)) return
var/sound/uploaded_sound = sound(S, repeat = 0, wait = 1, channel = CHANNEL_ADMIN)
uploaded_sound.priority = 250
sounds_cache += S
if(alert("Are you sure?\nSong: [S]\nNow you can also play this sound using \"Play Server Sound\".", "Confirmation request" ,"Play", "Cancel") == "Cancel")
return
log_admin("[key_name(src)] played sound [S]")
message_admins("[key_name_admin(src)] played sound [S]", 1)
for(var/mob/M in GLOB.player_list)
if(M.client.prefs.sound & SOUND_MIDI)
if(isnewplayer(M) && (M.client.prefs.sound & SOUND_LOBBY))
M.stop_sound_channel(CHANNEL_LOBBYMUSIC)
SEND_SOUND(M, uploaded_sound)
feedback_add_details("admin_verb","PGS") //If you are copy-pasting this, ensure the 2nd parameter is unique to the new proc!
/client/proc/play_local_sound(S as sound)
set category = "Event"
set name = "Play Local Sound"
if(!check_rights(R_SOUNDS)) return
log_admin("[key_name(src)] played a local sound [S]")
message_admins("[key_name_admin(src)] played a local sound [S]", 1)
playsound(get_turf(src.mob), S, 50, 0, 0)
feedback_add_details("admin_verb","PLS") //If you are copy-pasting this, ensure the 2nd parameter is unique to the new proc!
/client/proc/play_server_sound()
set category = "Event"
set name = "Play Server Sound"
if(!check_rights(R_SOUNDS)) return
var/list/sounds = file2list("sound/serversound_list.txt");
sounds += sounds_cache
var/melody = input("Select a sound from the server to play", "Server sound list") as null|anything in sounds
if(!melody) return
play_sound(melody)
feedback_add_details("admin_verb","PSS") //If you are copy-pasting this, ensure the 2nd paramter is unique to the new proc!
/client/proc/play_intercomm_sound()
set category = "Event"
set name = "Play Sound via Intercomms"
set desc = "Plays a sound at every intercomm on the station z level. Works best with small sounds."
if(!check_rights(R_SOUNDS)) return
var/A = alert("This will play a sound at every intercomm, are you sure you want to continue? This works best with short sounds, beware.","Warning","Yep","Nope")
if(A != "Yep") return
var/list/sounds = file2list("sound/serversound_list.txt");
sounds += sounds_cache
var/melody = input("Select a sound from the server to play", "Server sound list") as null|anything in sounds
if(!melody) return
var/cvol = 35
var/inputvol = input("How loud would you like this to be? (1-70)", "Volume", "35") as num | null
if(!inputvol) return
if(inputvol && inputvol >= 1 && inputvol <= 70)
cvol = inputvol
//Allows for override to utilize intercomms on all z-levels
var/B = alert("Do you want to play through intercomms on ALL Z-levels, or just the station?", "Override", "All", "Station")
var/ignore_z = 0
if(B == "All")
ignore_z = 1
//Allows for override to utilize incomplete and unpowered intercomms
var/C = alert("Do you want to play through unpowered / incomplete intercomms, so the crew can't silence it?", "Override", "Yep", "Nope")
var/ignore_power = 0
if(C == "Yep")
ignore_power = 1
for(var/O in GLOB.global_intercoms)
var/obj/item/radio/intercom/I = O
if(!is_station_level(I.z) && !ignore_z)
continue
if(!I.on && !ignore_power)
continue
playsound(I, melody, cvol)
/*
/client/proc/cuban_pete()
set category = "Event"
set name = "Cuban Pete Time"
message_admins("[key_name_admin(usr)] has declared Cuban Pete Time!", 1)
for(var/mob/M in world)
if(M.client)
if(M.client.midis)
M << 'cubanpetetime.ogg'
for(var/mob/living/carbon/human/CP in world)
if(CP.real_name=="Cuban Pete" && CP.key!="Rosham")
C << "Your body can't contain the rhumba beat"
CP.gib()
/client/proc/bananaphone()
set category = "Event"
set name = "Banana Phone"
message_admins("[key_name_admin(usr)] has activated Banana Phone!", 1)
for(var/mob/M in world)
if(M.client)
if(M.client.midis)
M << 'bananaphone.ogg'
client/proc/space_asshole()
set category = "Event"
set name = "Space Asshole"
message_admins("[key_name_admin(usr)] has played the Space Asshole Hymn.", 1)
for(var/mob/M in world)
if(M.client)
if(M.client.midis)
M << 'sound/music/space_asshole.ogg'
client/proc/honk_theme()
set category = "Event"
set name = "Honk"
message_admins("[key_name_admin(usr)] has creeped everyone out with Blackest Honks.", 1)
for(var/mob/M in world)
if(M.client)
if(M.client.midis)
M << 'honk_theme.ogg'*/
GLOBAL_LIST_EMPTY(sounds_cache)
/client/proc/stop_global_admin_sounds()
set category = "Event"
set name = "Stop Global Admin Sounds"
if(!check_rights(R_SOUNDS))
return
var/sound/awful_sound = sound(null, repeat = 0, wait = 0, channel = CHANNEL_ADMIN)
log_admin("[key_name(src)] stopped admin sounds.")
message_admins("[key_name_admin(src)] stopped admin sounds.", 1)
for(var/mob/M in GLOB.player_list)
M << awful_sound
/client/proc/play_sound(S as sound)
set category = "Event"
set name = "Play Global Sound"
if(!check_rights(R_SOUNDS)) return
var/sound/uploaded_sound = sound(S, repeat = 0, wait = 1, channel = CHANNEL_ADMIN)
uploaded_sound.priority = 250
GLOB.sounds_cache += S
if(alert("Are you sure?\nSong: [S]\nNow you can also play this sound using \"Play Server Sound\".", "Confirmation request" ,"Play", "Cancel") == "Cancel")
return
log_admin("[key_name(src)] played sound [S]")
message_admins("[key_name_admin(src)] played sound [S]", 1)
for(var/mob/M in GLOB.player_list)
if(M.client.prefs.sound & SOUND_MIDI)
if(isnewplayer(M) && (M.client.prefs.sound & SOUND_LOBBY))
M.stop_sound_channel(CHANNEL_LOBBYMUSIC)
SEND_SOUND(M, uploaded_sound)
feedback_add_details("admin_verb","PGS") //If you are copy-pasting this, ensure the 2nd parameter is unique to the new proc!
/client/proc/play_local_sound(S as sound)
set category = "Event"
set name = "Play Local Sound"
if(!check_rights(R_SOUNDS)) return
log_admin("[key_name(src)] played a local sound [S]")
message_admins("[key_name_admin(src)] played a local sound [S]", 1)
playsound(get_turf(src.mob), S, 50, 0, 0)
feedback_add_details("admin_verb","PLS") //If you are copy-pasting this, ensure the 2nd parameter is unique to the new proc!
/client/proc/play_server_sound()
set category = "Event"
set name = "Play Server Sound"
if(!check_rights(R_SOUNDS)) return
var/list/sounds = file2list("sound/serversound_list.txt");
sounds += GLOB.sounds_cache
var/melody = input("Select a sound from the server to play", "Server sound list") as null|anything in sounds
if(!melody) return
play_sound(melody)
feedback_add_details("admin_verb","PSS") //If you are copy-pasting this, ensure the 2nd paramter is unique to the new proc!
/client/proc/play_intercomm_sound()
set category = "Event"
set name = "Play Sound via Intercomms"
set desc = "Plays a sound at every intercomm on the station z level. Works best with small sounds."
if(!check_rights(R_SOUNDS)) return
var/A = alert("This will play a sound at every intercomm, are you sure you want to continue? This works best with short sounds, beware.","Warning","Yep","Nope")
if(A != "Yep") return
var/list/sounds = file2list("sound/serversound_list.txt");
sounds += GLOB.sounds_cache
var/melody = input("Select a sound from the server to play", "Server sound list") as null|anything in sounds
if(!melody) return
var/cvol = 35
var/inputvol = input("How loud would you like this to be? (1-70)", "Volume", "35") as num | null
if(!inputvol) return
if(inputvol && inputvol >= 1 && inputvol <= 70)
cvol = inputvol
//Allows for override to utilize intercomms on all z-levels
var/B = alert("Do you want to play through intercomms on ALL Z-levels, or just the station?", "Override", "All", "Station")
var/ignore_z = 0
if(B == "All")
ignore_z = 1
//Allows for override to utilize incomplete and unpowered intercomms
var/C = alert("Do you want to play through unpowered / incomplete intercomms, so the crew can't silence it?", "Override", "Yep", "Nope")
var/ignore_power = 0
if(C == "Yep")
ignore_power = 1
for(var/O in GLOB.global_intercoms)
var/obj/item/radio/intercom/I = O
if(!is_station_level(I.z) && !ignore_z)
continue
if(!I.on && !ignore_power)
continue
playsound(I, melody, cvol)
/*
/client/proc/cuban_pete()
set category = "Event"
set name = "Cuban Pete Time"
message_admins("[key_name_admin(usr)] has declared Cuban Pete Time!", 1)
for(var/mob/M in world)
if(M.client)
if(M.client.midis)
M << 'cubanpetetime.ogg'
for(var/mob/living/carbon/human/CP in world)
if(CP.real_name=="Cuban Pete" && CP.key!="Rosham")
C << "Your body can't contain the rhumba beat"
CP.gib()
/client/proc/bananaphone()
set category = "Event"
set name = "Banana Phone"
message_admins("[key_name_admin(usr)] has activated Banana Phone!", 1)
for(var/mob/M in world)
if(M.client)
if(M.client.midis)
M << 'bananaphone.ogg'
client/proc/space_asshole()
set category = "Event"
set name = "Space Asshole"
message_admins("[key_name_admin(usr)] has played the Space Asshole Hymn.", 1)
for(var/mob/M in world)
if(M.client)
if(M.client.midis)
M << 'sound/music/space_asshole.ogg'
client/proc/honk_theme()
set category = "Event"
set name = "Honk"
message_admins("[key_name_admin(usr)] has creeped everyone out with Blackest Honks.", 1)
for(var/mob/M in world)
if(M.client)
if(M.client.midis)
M << 'honk_theme.ogg'*/
+89 -89
View File
@@ -1,89 +1,89 @@
/mob/living/verb/pray(msg as text)
set category = "IC"
set name = "Pray"
msg = sanitize(copytext(msg, 1, MAX_MESSAGE_LEN))
if(!msg)
return
if(usr.client)
if(usr.client.prefs.muted & MUTE_PRAY)
to_chat(usr, "<span class='warning'>You cannot pray (muted).</span>")
return
if(client.handle_spam_prevention(msg, MUTE_PRAY, OOC_COOLDOWN))
return
var/image/cross = image('icons/obj/storage.dmi',"bible")
var/font_color = "purple"
var/prayer_type = "PRAYER"
var/deity
if(usr.job == "Chaplain")
if(SSticker && SSticker.Bible_deity_name)
deity = SSticker.Bible_deity_name
cross = image('icons/obj/storage.dmi',"kingyellow")
font_color = "blue"
prayer_type = "CHAPLAIN PRAYER"
else if(iscultist(usr))
cross = image('icons/obj/storage.dmi',"tome")
font_color = "red"
prayer_type = "CULTIST PRAYER"
deity = SSticker.cultdat.entity_name
log_say("(PRAYER) [msg]", usr)
msg = "<span class='notice'>[bicon(cross)]<b><font color=[font_color]>[prayer_type][deity ? " (to [deity])" : ""][mind && mind.isholy ? " (blessings: [mind.num_blessed])" : ""]:</font> [key_name(src, 1)] ([ADMIN_QUE(src,"?")]) ([ADMIN_PP(src,"PP")]) ([ADMIN_VV(src,"VV")]) ([ADMIN_TP(src,"TP")]) ([ADMIN_SM(src,"SM")]) ([admin_jump_link(src)]) ([ADMIN_SC(src,"SC")]) (<A HREF='?_src_=holder;Bless=[UID()]'>BLESS</A>) (<A HREF='?_src_=holder;Smite=[UID()]'>SMITE</A>):</b> [msg]</span>"
for(var/client/X in GLOB.admins)
if(check_rights(R_EVENT,0,X.mob))
to_chat(X, msg)
to_chat(usr, "Your prayers have been received by the gods.")
feedback_add_details("admin_verb","PR") //If you are copy-pasting this, ensure the 2nd parameter is unique to the new proc!
/proc/Centcomm_announce(var/text , var/mob/Sender)
var/msg = sanitize(copytext(text, 1, MAX_MESSAGE_LEN))
msg = "<span class='boldnotice'><font color=orange>CENTCOMM: </font>[key_name(Sender, 1)] ([ADMIN_PP(Sender,"PP")]) ([ADMIN_VV(Sender,"VV")]) ([ADMIN_TP(Sender,"TP")]) ([ADMIN_SM(Sender,"SM")]) ([admin_jump_link(Sender)]) ([ADMIN_BSA(Sender,"BSA")]) ([ADMIN_CENTCOM_REPLY(Sender,"RPLY")])):</span> [msg]"
for(var/client/X in GLOB.admins)
if(R_EVENT & X.holder.rights)
to_chat(X, msg)
if(X.prefs.sound & SOUND_ADMINHELP)
X << 'sound/effects/adminhelp.ogg'
/proc/Syndicate_announce(var/text , var/mob/Sender)
var/msg = sanitize(copytext(text, 1, MAX_MESSAGE_LEN))
msg = "<span class='boldnotice'><font color='#DC143C'>SYNDICATE: </font>[key_name(Sender, 1)] ([ADMIN_PP(Sender,"PP")]) ([ADMIN_VV(Sender,"VV")]) ([ADMIN_TP(Sender,"TP")]) ([ADMIN_SM(Sender,"SM")]) ([admin_jump_link(Sender)]) ([ADMIN_BSA(Sender,"BSA")]) ([ADMIN_SYNDICATE_REPLY(Sender,"RPLY")]):</span> [msg]"
for(var/client/X in GLOB.admins)
if(check_rights(R_EVENT,0,X.mob))
to_chat(X, msg)
if(X.prefs.sound & SOUND_ADMINHELP)
X << 'sound/effects/adminhelp.ogg'
/proc/HONK_announce(var/text , var/mob/Sender)
var/msg = sanitize(copytext(text, 1, MAX_MESSAGE_LEN))
msg = "<span class='boldnotice'><font color=pink>HONK: </font>[key_name(Sender, 1)] ([ADMIN_PP(Sender,"PP")]) ([ADMIN_VV(Sender,"VV")]) ([ADMIN_TP(Sender,"TP")]) ([ADMIN_SM(Sender,"SM")]) ([admin_jump_link(Sender)]) ([ADMIN_BSA(Sender,"BSA")]) (<A HREF='?_src_=holder;HONKReply=[Sender.UID()]'>RPLY</A>):</span> [msg]"
for(var/client/X in GLOB.admins)
if(R_EVENT & X.holder.rights)
to_chat(X, msg)
if(X.prefs.sound & SOUND_ADMINHELP)
X << 'sound/effects/adminhelp.ogg'
/proc/ERT_Announce(var/text , var/mob/Sender, var/repeat_warning)
var/msg = sanitize(copytext(text, 1, MAX_MESSAGE_LEN))
msg = "<span class='adminnotice'><b><font color=orange>ERT REQUEST: </font>[key_name(Sender, 1)] ([ADMIN_PP(Sender,"PP")]) ([ADMIN_VV(Sender,"VV")]) ([ADMIN_TP(Sender,"TP")]) ([ADMIN_SM(Sender,"SM")]) ([admin_jump_link(Sender)]) ([ADMIN_BSA(Sender,"BSA")]) (<A HREF='?_src_=holder;ErtReply=[Sender.UID()]'>RESPOND</A>):</b> [msg]</span>"
if(repeat_warning)
msg += "<BR><span class='adminnotice'><b>WARNING: ERT request has gone 5 minutes with no reply!</b></span>"
for(var/client/X in GLOB.admins)
if(check_rights(R_EVENT,0,X.mob))
to_chat(X, msg)
if(X.prefs.sound & SOUND_ADMINHELP)
X << 'sound/effects/adminhelp.ogg'
/proc/Nuke_request(text , mob/Sender)
var/nuke_code = get_nuke_code()
var/msg = sanitize(copytext(text, 1, MAX_MESSAGE_LEN))
msg = "<span class='adminnotice'><b><font color=orange>NUKE CODE REQUEST: </font>[key_name(Sender)] ([ADMIN_PP(Sender,"PP")]) ([ADMIN_VV(Sender,"VV")]) ([ADMIN_TP(Sender,"TP")]) ([ADMIN_SM(Sender,"SM")]) ([admin_jump_link(Sender)]) ([ADMIN_BSA(Sender,"BSA")]) ([ADMIN_CENTCOM_REPLY(Sender,"RPLY")]):</b> [msg]</span>"
for(var/client/X in GLOB.admins)
if(check_rights(R_EVENT,0,X.mob))
to_chat(X, msg)
to_chat(X, "<span class='adminnotice'><b>The nuke code is [nuke_code].</b></span>")
if(X.prefs.sound & SOUND_ADMINHELP)
X << 'sound/effects/adminhelp.ogg'
/mob/living/verb/pray(msg as text)
set category = "IC"
set name = "Pray"
msg = sanitize(copytext(msg, 1, MAX_MESSAGE_LEN))
if(!msg)
return
if(usr.client)
if(usr.client.prefs.muted & MUTE_PRAY)
to_chat(usr, "<span class='warning'>You cannot pray (muted).</span>")
return
if(client.handle_spam_prevention(msg, MUTE_PRAY, OOC_COOLDOWN))
return
var/image/cross = image('icons/obj/storage.dmi',"bible")
var/font_color = "purple"
var/prayer_type = "PRAYER"
var/deity
if(usr.job == "Chaplain")
if(SSticker && SSticker.Bible_deity_name)
deity = SSticker.Bible_deity_name
cross = image('icons/obj/storage.dmi',"kingyellow")
font_color = "blue"
prayer_type = "CHAPLAIN PRAYER"
else if(iscultist(usr))
cross = image('icons/obj/storage.dmi',"tome")
font_color = "red"
prayer_type = "CULTIST PRAYER"
deity = SSticker.cultdat.entity_name
log_say("(PRAYER) [msg]", usr)
msg = "<span class='notice'>[bicon(cross)]<b><font color=[font_color]>[prayer_type][deity ? " (to [deity])" : ""][mind && mind.isholy ? " (blessings: [mind.num_blessed])" : ""]:</font> [key_name(src, 1)] ([ADMIN_QUE(src,"?")]) ([ADMIN_PP(src,"PP")]) ([ADMIN_VV(src,"VV")]) ([ADMIN_TP(src,"TP")]) ([ADMIN_SM(src,"SM")]) ([admin_jump_link(src)]) ([ADMIN_SC(src,"SC")]) (<A HREF='?_src_=holder;Bless=[UID()]'>BLESS</A>) (<A HREF='?_src_=holder;Smite=[UID()]'>SMITE</A>):</b> [msg]</span>"
for(var/client/X in GLOB.admins)
if(check_rights(R_EVENT,0,X.mob))
to_chat(X, msg)
to_chat(usr, "Your prayers have been received by the gods.")
feedback_add_details("admin_verb","PR") //If you are copy-pasting this, ensure the 2nd parameter is unique to the new proc!
/proc/Centcomm_announce(var/text , var/mob/Sender)
var/msg = sanitize(copytext(text, 1, MAX_MESSAGE_LEN))
msg = "<span class='boldnotice'><font color=orange>CENTCOMM: </font>[key_name(Sender, 1)] ([ADMIN_PP(Sender,"PP")]) ([ADMIN_VV(Sender,"VV")]) ([ADMIN_TP(Sender,"TP")]) ([ADMIN_SM(Sender,"SM")]) ([admin_jump_link(Sender)]) ([ADMIN_BSA(Sender,"BSA")]) ([ADMIN_CENTCOM_REPLY(Sender,"RPLY")])):</span> [msg]"
for(var/client/X in GLOB.admins)
if(R_EVENT & X.holder.rights)
to_chat(X, msg)
if(X.prefs.sound & SOUND_ADMINHELP)
X << 'sound/effects/adminhelp.ogg'
/proc/Syndicate_announce(var/text , var/mob/Sender)
var/msg = sanitize(copytext(text, 1, MAX_MESSAGE_LEN))
msg = "<span class='boldnotice'><font color='#DC143C'>SYNDICATE: </font>[key_name(Sender, 1)] ([ADMIN_PP(Sender,"PP")]) ([ADMIN_VV(Sender,"VV")]) ([ADMIN_TP(Sender,"TP")]) ([ADMIN_SM(Sender,"SM")]) ([admin_jump_link(Sender)]) ([ADMIN_BSA(Sender,"BSA")]) ([ADMIN_SYNDICATE_REPLY(Sender,"RPLY")]):</span> [msg]"
for(var/client/X in GLOB.admins)
if(check_rights(R_EVENT,0,X.mob))
to_chat(X, msg)
if(X.prefs.sound & SOUND_ADMINHELP)
X << 'sound/effects/adminhelp.ogg'
/proc/HONK_announce(var/text , var/mob/Sender)
var/msg = sanitize(copytext(text, 1, MAX_MESSAGE_LEN))
msg = "<span class='boldnotice'><font color=pink>HONK: </font>[key_name(Sender, 1)] ([ADMIN_PP(Sender,"PP")]) ([ADMIN_VV(Sender,"VV")]) ([ADMIN_TP(Sender,"TP")]) ([ADMIN_SM(Sender,"SM")]) ([admin_jump_link(Sender)]) ([ADMIN_BSA(Sender,"BSA")]) (<A HREF='?_src_=holder;HONKReply=[Sender.UID()]'>RPLY</A>):</span> [msg]"
for(var/client/X in GLOB.admins)
if(R_EVENT & X.holder.rights)
to_chat(X, msg)
if(X.prefs.sound & SOUND_ADMINHELP)
X << 'sound/effects/adminhelp.ogg'
/proc/ERT_Announce(var/text , var/mob/Sender, var/repeat_warning)
var/msg = sanitize(copytext(text, 1, MAX_MESSAGE_LEN))
msg = "<span class='adminnotice'><b><font color=orange>ERT REQUEST: </font>[key_name(Sender, 1)] ([ADMIN_PP(Sender,"PP")]) ([ADMIN_VV(Sender,"VV")]) ([ADMIN_TP(Sender,"TP")]) ([ADMIN_SM(Sender,"SM")]) ([admin_jump_link(Sender)]) ([ADMIN_BSA(Sender,"BSA")]) (<A HREF='?_src_=holder;ErtReply=[Sender.UID()]'>RESPOND</A>):</b> [msg]</span>"
if(repeat_warning)
msg += "<BR><span class='adminnotice'><b>WARNING: ERT request has gone 5 minutes with no reply!</b></span>"
for(var/client/X in GLOB.admins)
if(check_rights(R_EVENT,0,X.mob))
to_chat(X, msg)
if(X.prefs.sound & SOUND_ADMINHELP)
X << 'sound/effects/adminhelp.ogg'
/proc/Nuke_request(text , mob/Sender)
var/nuke_code = get_nuke_code()
var/msg = sanitize(copytext(text, 1, MAX_MESSAGE_LEN))
msg = "<span class='adminnotice'><b><font color=orange>NUKE CODE REQUEST: </font>[key_name(Sender)] ([ADMIN_PP(Sender,"PP")]) ([ADMIN_VV(Sender,"VV")]) ([ADMIN_TP(Sender,"TP")]) ([ADMIN_SM(Sender,"SM")]) ([admin_jump_link(Sender)]) ([ADMIN_BSA(Sender,"BSA")]) ([ADMIN_CENTCOM_REPLY(Sender,"RPLY")]):</b> [msg]</span>"
for(var/client/X in GLOB.admins)
if(check_rights(R_EVENT,0,X.mob))
to_chat(X, msg)
to_chat(X, "<span class='adminnotice'><b>The nuke code is [nuke_code].</b></span>")
if(X.prefs.sound & SOUND_ADMINHELP)
X << 'sound/effects/adminhelp.ogg'
File diff suppressed because it is too large Load Diff
+1 -1
View File
@@ -23,4 +23,4 @@
var/json_text = input("Enter the JSON code:","Text") as message|null
if(json_text)
json_to_object(json_text, get_turf(usr))
json_to_object(json_text, get_turf(usr))
@@ -13,7 +13,7 @@
message_admins("[key_name_admin(usr)] re-assigned all space transitions")
space_manager.do_transition_setup()
GLOB.space_manager.do_transition_setup()
log_admin("[key_name(usr)] re-assigned all space transitions")
feedback_add_details("admin_verb","SPCRST") //If you are copy-pasting this, ensure the 2nd parameter is unique to the new proc!
@@ -37,5 +37,5 @@
message_admins("[key_name_admin(usr)] made a space map")
space_manager.map_as_turfs(get_turf(usr))
GLOB.space_manager.map_as_turfs(get_turf(usr))
log_admin("[key_name(usr)] made a space map")
+206 -204
View File
@@ -1,204 +1,206 @@
//STRIKE TEAMS
var/const/commandos_possible = 6 //if more Commandos are needed in the future
var/global/sent_strike_team = 0
/client/proc/strike_team()
if(!SSticker)
to_chat(usr, "<span class='userdanger'>The game hasn't started yet!</span>")
return
if(sent_strike_team == 1)
to_chat(usr, "<span class='userdanger'>CentComm is already sending a team.</span>")
return
if(alert("Do you want to send in the CentComm death squad? Once enabled, this is irreversible.",,"Yes","No")!="Yes")
return
alert("This 'mode' will go on until everyone is dead or the station is destroyed. You may also admin-call the evac shuttle when appropriate. Spawned commandos have internals cameras which are viewable through a monitor inside the Spec. Ops. Office. The first one selected/spawned will be the team leader.")
message_admins("<span class='notice'>[key_name_admin(usr)] has started to spawn a CentComm DeathSquad.</span>", 1)
var/input = null
while(!input)
input = sanitize(copytext(input(src, "Please specify which mission the death commando squad shall undertake.", "Specify Mission", ""),1,MAX_MESSAGE_LEN))
if(!input)
if(alert("Error, no mission set. Do you want to exit the setup process?",,"Yes","No")=="Yes")
return
if(sent_strike_team)
to_chat(usr, "Looks like someone beat you to it.")
return
// Find the nuclear auth code
var/nuke_code
var/temp_code
for(var/obj/machinery/nuclearbomb/N in world)
temp_code = text2num(N.r_code)
if(temp_code)//if it's actually a number. It won't convert any non-numericals.
nuke_code = N.r_code
break
// Find ghosts willing to be DS
var/list/commando_ghosts = pollCandidatesWithVeto(src, usr, commandos_possible, "Join the DeathSquad?",, 21, 600, 1, role_playtime_requirements[ROLE_DEATHSQUAD], TRUE, FALSE)
if(!commando_ghosts.len)
to_chat(usr, "<span class='userdanger'>Nobody volunteered to join the DeathSquad.</span>")
return
sent_strike_team = 1
// Spawns commandos and equips them.
var/commando_number = commandos_possible //for selecting a leader
var/is_leader = TRUE // set to FALSE after leader is spawned
for(var/obj/effect/landmark/L in GLOB.landmarks_list)
if(commando_number <= 0)
break
if(L.name == "Commando")
if(!commando_ghosts.len)
break
var/use_ds_borg = FALSE
var/mob/ghost_mob = pick(commando_ghosts)
commando_ghosts -= ghost_mob
if(!ghost_mob || !ghost_mob.key || !ghost_mob.client)
continue
if(!is_leader)
var/new_dstype = alert(ghost_mob.client, "Select Deathsquad Type.", "DS Character Generation", "Organic", "Cyborg")
if(new_dstype == "Cyborg")
use_ds_borg = TRUE
if(!ghost_mob || !ghost_mob.key || !ghost_mob.client) // Have to re-check this due to the above alert() call
continue
if(use_ds_borg)
var/mob/living/silicon/robot/deathsquad/R = new()
R.forceMove(get_turf(L))
var/rnum = rand(1,1000)
var/borgname = "Epsilon [rnum]"
R.name = borgname
R.custom_name = borgname
R.real_name = R.name
R.mind = new
R.mind.current = R
R.mind.original = R
R.mind.assigned_role = SPECIAL_ROLE_DEATHSQUAD
R.mind.special_role = SPECIAL_ROLE_DEATHSQUAD
R.mind.offstation_role = TRUE
if(!(R.mind in SSticker.minds))
SSticker.minds += R.mind
SSticker.mode.traitors += R.mind
R.key = ghost_mob.key
if(nuke_code)
R.mind.store_memory("<B>Nuke Code:</B> <span class='warning'>[nuke_code].</span>")
R.mind.store_memory("<B>Mission:</B> <span class='warning'>[input].</span>")
to_chat(R, "<span class='userdanger'>You are a Special Operations cyborg, in the service of Central Command. \nYour current mission is: <span class='danger'>[input]</span></span>")
else
var/mob/living/carbon/human/new_commando = create_death_commando(L, is_leader)
new_commando.mind.key = ghost_mob.key
new_commando.key = ghost_mob.key
new_commando.internal = new_commando.s_store
new_commando.update_action_buttons_icon()
if(nuke_code)
new_commando.mind.store_memory("<B>Nuke Code:</B> <span class='warning'>[nuke_code].</span>")
new_commando.mind.store_memory("<B>Mission:</B> <span class='warning'>[input].</span>")
to_chat(new_commando, "<span class='userdanger'>You are a Special Ops [is_leader ? "<B>TEAM LEADER</B>" : "commando"] in the service of Central Command. Check the table ahead for detailed instructions.\nYour current mission is: <span class='danger'>[input]</span></span>")
is_leader = FALSE
commando_number--
//Spawns the rest of the commando gear.
for(var/obj/effect/landmark/L in GLOB.landmarks_list)
if(L.name == "Commando_Manual")
//new /obj/item/gun/energy/pulse_rifle(L.loc)
var/obj/item/paper/P = new(L.loc)
P.info = "<p><b>Good morning soldier!</b>. This compact guide will familiarize you with standard operating procedure. There are three basic rules to follow:<br>#1 Work as a team.<br>#2 Accomplish your objective at all costs.<br>#3 Leave no witnesses.<br>You are fully equipped and stocked for your mission--before departing on the Spec. Ops. Shuttle due South, make sure that all operatives are ready. Actual mission objective will be relayed to you by Central Command through your headsets.<br>If deemed appropriate, Central Command will also allow members of your team to equip assault power-armor for the mission. You will find the armor storage due West of your position. Once you are ready to leave, utilize the Special Operations shuttle console and toggle the hull doors via the other console.</p><p>In the event that the team does not accomplish their assigned objective in a timely manner, or finds no other way to do so, attached below are instructions on how to operate a Nanotrasen Nuclear Device. Your operations <b>LEADER</b> is provided with a nuclear authentication disk and a pin-pointer for this reason. You may easily recognize them by their rank: Lieutenant, Captain, or Major. The nuclear device itself will be present somewhere on your destination.</p><p>Hello and thank you for choosing Nanotrasen for your nuclear information needs. Today's crash course will deal with the operation of a Fission Class Nanotrasen made Nuclear Device.<br>First and foremost, <b>DO NOT TOUCH ANYTHING UNTIL THE BOMB IS IN PLACE.</b> Pressing any button on the compacted bomb will cause it to extend and bolt itself into place. If this is done to unbolt it one must completely log in which at this time may not be possible.<br>To make the device functional:<br>#1 Place bomb in designated detonation zone<br> #2 Extend and anchor bomb (attack with hand).<br>#3 Insert Nuclear Auth. Disk into slot.<br>#4 Type numeric code into keypad ([nuke_code]).<br>Note: If you make a mistake press R to reset the device.<br>#5 Press the E button to log onto the device.<br>You now have activated the device. To deactivate the buttons at anytime, for example when you have already prepped the bomb for detonation, remove the authentication disk OR press the R on the keypad. Now the bomb CAN ONLY be detonated using the timer. A manual detonation is not an option.<br>Note: Toggle off the <b>SAFETY</b>.<br>Use the - - and + + to set a detonation time between 5 seconds and 10 minutes. Then press the timer toggle button to start the countdown. Now remove the authentication disk so that the buttons deactivate.<br>Note: <b>THE BOMB IS STILL SET AND WILL DETONATE</b><br>Now before you remove the disk if you need to move the bomb you can: Toggle off the anchor, move it, and re-anchor.</p><p>The nuclear authorization code is: <b>[nuke_code ? nuke_code : "None provided"]</b></p><p><b>Good luck, soldier!</b></p>"
P.name = "Spec. Ops Manual"
P.icon = "pamphlet-ds"
var/obj/item/stamp/centcom/stamp = new
P.stamp(stamp)
qdel(stamp)
for(var/obj/effect/landmark/L in GLOB.landmarks_list)
if(L.name == "Commando-Bomb")
new /obj/effect/spawner/newbomb/timer/syndicate(L.loc)
qdel(L)
message_admins("<span class='notice'>[key_name_admin(usr)] has spawned a CentComm DeathSquad.</span>", 1)
log_admin("[key_name(usr)] used Spawn Death Squad.")
return 1
/client/proc/create_death_commando(obj/spawn_location, is_leader = FALSE)
var/mob/living/carbon/human/new_commando = new(spawn_location.loc)
var/commando_leader_rank = pick("Lieutenant", "Captain", "Major")
var/commando_rank = pick("Corporal", "Sergeant", "Staff Sergeant", "Sergeant 1st Class", "Master Sergeant", "Sergeant Major")
var/commando_name = pick(GLOB.last_names)
var/datum/preferences/A = new()//Randomize appearance for the commando.
if(is_leader)
A.age = rand(35,45)
A.real_name = "[commando_leader_rank] [commando_name]"
else
A.real_name = "[commando_rank] [commando_name]"
A.copy_to(new_commando)
new_commando.dna.ready_dna(new_commando)//Creates DNA.
//Creates mind stuff.
new_commando.mind_initialize()
new_commando.mind.assigned_role = SPECIAL_ROLE_DEATHSQUAD
new_commando.mind.special_role = SPECIAL_ROLE_DEATHSQUAD
SSticker.mode.traitors |= new_commando.mind//Adds them to current traitor list. Which is really the extra antagonist list.
new_commando.equip_death_commando(is_leader)
return new_commando
/mob/living/carbon/human/proc/equip_death_commando(is_leader = FALSE)
var/obj/item/radio/R = new /obj/item/radio/headset/alt(src)
R.set_frequency(DTH_FREQ)
equip_to_slot_or_del(R, slot_l_ear)
if(is_leader)
equip_to_slot_or_del(new /obj/item/clothing/under/rank/centcom_officer(src), slot_w_uniform)
else
equip_to_slot_or_del(new /obj/item/clothing/under/color/green(src), slot_w_uniform)
equip_to_slot_or_del(new /obj/item/clothing/shoes/magboots/advance(src), slot_shoes)
equip_to_slot_or_del(new /obj/item/clothing/suit/space/deathsquad(src), slot_wear_suit)
equip_to_slot_or_del(new /obj/item/clothing/gloves/combat(src), slot_gloves)
equip_to_slot_or_del(new /obj/item/clothing/head/helmet/space/deathsquad(src), slot_head)
equip_to_slot_or_del(new /obj/item/clothing/mask/gas/sechailer/swat(src), slot_wear_mask)
equip_to_slot_or_del(new /obj/item/clothing/glasses/thermal(src), slot_glasses)
equip_to_slot_or_del(new /obj/item/storage/backpack/security(src), slot_back)
equip_to_slot_or_del(new /obj/item/storage/box(src), slot_in_backpack)
equip_to_slot_or_del(new /obj/item/ammo_box/a357(src), slot_in_backpack)
equip_to_slot_or_del(new /obj/item/reagent_containers/hypospray/combat/nanites(src), slot_in_backpack)
equip_to_slot_or_del(new /obj/item/storage/box/flashbangs(src), slot_in_backpack)
equip_to_slot_or_del(new /obj/item/flashlight(src), slot_in_backpack)
equip_to_slot_or_del(new /obj/item/pinpointer(src), slot_in_backpack)
if(is_leader)
equip_to_slot_or_del(new /obj/item/disk/nuclear/unrestricted(src), slot_in_backpack)
else
equip_to_slot_or_del(new /obj/item/grenade/plastic/x4(src), slot_in_backpack)
equip_to_slot_or_del(new /obj/item/melee/energy/sword/saber(src), slot_l_store)
equip_to_slot_or_del(new /obj/item/shield/energy(src), slot_r_store)
equip_to_slot_or_del(new /obj/item/tank/emergency_oxygen/double/full(src), slot_s_store)
equip_to_slot_or_del(new /obj/item/gun/projectile/revolver/mateba(src), slot_belt)
equip_to_slot_or_del(new /obj/item/gun/energy/pulse(src), slot_r_hand)
var/obj/item/implant/mindshield/L = new/obj/item/implant/mindshield(src)
L.implant(src)
var/obj/item/card/id/W = new(src)
W.name = "[real_name]'s ID Card"
W.icon_state = "deathsquad"
W.assignment = "Death Commando"
W.access = get_centcom_access(W.assignment)
W.registered_name = real_name
equip_to_slot_or_del(W, slot_wear_id)
return 1
//STRIKE TEAMS
#define COMMANDOS_POSSIBLE 6 //if more Commandos are needed in the future
GLOBAL_VAR_INIT(sent_strike_team, 0)
/client/proc/strike_team()
if(!SSticker)
to_chat(usr, "<span class='userdanger'>The game hasn't started yet!</span>")
return
if(GLOB.sent_strike_team == 1)
to_chat(usr, "<span class='userdanger'>CentComm is already sending a team.</span>")
return
if(alert("Do you want to send in the CentComm death squad? Once enabled, this is irreversible.",,"Yes","No")!="Yes")
return
alert("This 'mode' will go on until everyone is dead or the station is destroyed. You may also admin-call the evac shuttle when appropriate. Spawned commandos have internals cameras which are viewable through a monitor inside the Spec. Ops. Office. The first one selected/spawned will be the team leader.")
message_admins("<span class='notice'>[key_name_admin(usr)] has started to spawn a CentComm DeathSquad.</span>", 1)
var/input = null
while(!input)
input = sanitize(copytext(input(src, "Please specify which mission the death commando squad shall undertake.", "Specify Mission", ""),1,MAX_MESSAGE_LEN))
if(!input)
if(alert("Error, no mission set. Do you want to exit the setup process?",,"Yes","No")=="Yes")
return
if(GLOB.sent_strike_team)
to_chat(usr, "Looks like someone beat you to it.")
return
// Find the nuclear auth code
var/nuke_code
var/temp_code
for(var/obj/machinery/nuclearbomb/N in world)
temp_code = text2num(N.r_code)
if(temp_code)//if it's actually a number. It won't convert any non-numericals.
nuke_code = N.r_code
break
// Find ghosts willing to be DS
var/list/commando_ghosts = pollCandidatesWithVeto(src, usr, COMMANDOS_POSSIBLE, "Join the DeathSquad?",, 21, 600, 1, GLOB.role_playtime_requirements[ROLE_DEATHSQUAD], TRUE, FALSE)
if(!commando_ghosts.len)
to_chat(usr, "<span class='userdanger'>Nobody volunteered to join the DeathSquad.</span>")
return
GLOB.sent_strike_team = 1
// Spawns commandos and equips them.
var/commando_number = COMMANDOS_POSSIBLE //for selecting a leader
var/is_leader = TRUE // set to FALSE after leader is spawned
for(var/obj/effect/landmark/L in GLOB.landmarks_list)
if(commando_number <= 0)
break
if(L.name == "Commando")
if(!commando_ghosts.len)
break
var/use_ds_borg = FALSE
var/mob/ghost_mob = pick(commando_ghosts)
commando_ghosts -= ghost_mob
if(!ghost_mob || !ghost_mob.key || !ghost_mob.client)
continue
if(!is_leader)
var/new_dstype = alert(ghost_mob.client, "Select Deathsquad Type.", "DS Character Generation", "Organic", "Cyborg")
if(new_dstype == "Cyborg")
use_ds_borg = TRUE
if(!ghost_mob || !ghost_mob.key || !ghost_mob.client) // Have to re-check this due to the above alert() call
continue
if(use_ds_borg)
var/mob/living/silicon/robot/deathsquad/R = new()
R.forceMove(get_turf(L))
var/rnum = rand(1,1000)
var/borgname = "Epsilon [rnum]"
R.name = borgname
R.custom_name = borgname
R.real_name = R.name
R.mind = new
R.mind.current = R
R.mind.original = R
R.mind.assigned_role = SPECIAL_ROLE_DEATHSQUAD
R.mind.special_role = SPECIAL_ROLE_DEATHSQUAD
R.mind.offstation_role = TRUE
if(!(R.mind in SSticker.minds))
SSticker.minds += R.mind
SSticker.mode.traitors += R.mind
R.key = ghost_mob.key
if(nuke_code)
R.mind.store_memory("<B>Nuke Code:</B> <span class='warning'>[nuke_code].</span>")
R.mind.store_memory("<B>Mission:</B> <span class='warning'>[input].</span>")
to_chat(R, "<span class='userdanger'>You are a Special Operations cyborg, in the service of Central Command. \nYour current mission is: <span class='danger'>[input]</span></span>")
else
var/mob/living/carbon/human/new_commando = create_death_commando(L, is_leader)
new_commando.mind.key = ghost_mob.key
new_commando.key = ghost_mob.key
new_commando.internal = new_commando.s_store
new_commando.update_action_buttons_icon()
if(nuke_code)
new_commando.mind.store_memory("<B>Nuke Code:</B> <span class='warning'>[nuke_code].</span>")
new_commando.mind.store_memory("<B>Mission:</B> <span class='warning'>[input].</span>")
to_chat(new_commando, "<span class='userdanger'>You are a Special Ops [is_leader ? "<B>TEAM LEADER</B>" : "commando"] in the service of Central Command. Check the table ahead for detailed instructions.\nYour current mission is: <span class='danger'>[input]</span></span>")
is_leader = FALSE
commando_number--
//Spawns the rest of the commando gear.
for(var/obj/effect/landmark/L in GLOB.landmarks_list)
if(L.name == "Commando_Manual")
//new /obj/item/gun/energy/pulse_rifle(L.loc)
var/obj/item/paper/P = new(L.loc)
P.info = "<p><b>Good morning soldier!</b>. This compact guide will familiarize you with standard operating procedure. There are three basic rules to follow:<br>#1 Work as a team.<br>#2 Accomplish your objective at all costs.<br>#3 Leave no witnesses.<br>You are fully equipped and stocked for your mission--before departing on the Spec. Ops. Shuttle due South, make sure that all operatives are ready. Actual mission objective will be relayed to you by Central Command through your headsets.<br>If deemed appropriate, Central Command will also allow members of your team to equip assault power-armor for the mission. You will find the armor storage due West of your position. Once you are ready to leave, utilize the Special Operations shuttle console and toggle the hull doors via the other console.</p><p>In the event that the team does not accomplish their assigned objective in a timely manner, or finds no other way to do so, attached below are instructions on how to operate a Nanotrasen Nuclear Device. Your operations <b>LEADER</b> is provided with a nuclear authentication disk and a pin-pointer for this reason. You may easily recognize them by their rank: Lieutenant, Captain, or Major. The nuclear device itself will be present somewhere on your destination.</p><p>Hello and thank you for choosing Nanotrasen for your nuclear information needs. Today's crash course will deal with the operation of a Fission Class Nanotrasen made Nuclear Device.<br>First and foremost, <b>DO NOT TOUCH ANYTHING UNTIL THE BOMB IS IN PLACE.</b> Pressing any button on the compacted bomb will cause it to extend and bolt itself into place. If this is done to unbolt it one must completely log in which at this time may not be possible.<br>To make the device functional:<br>#1 Place bomb in designated detonation zone<br> #2 Extend and anchor bomb (attack with hand).<br>#3 Insert Nuclear Auth. Disk into slot.<br>#4 Type numeric code into keypad ([nuke_code]).<br>Note: If you make a mistake press R to reset the device.<br>#5 Press the E button to log onto the device.<br>You now have activated the device. To deactivate the buttons at anytime, for example when you have already prepped the bomb for detonation, remove the authentication disk OR press the R on the keypad. Now the bomb CAN ONLY be detonated using the timer. A manual detonation is not an option.<br>Note: Toggle off the <b>SAFETY</b>.<br>Use the - - and + + to set a detonation time between 5 seconds and 10 minutes. Then press the timer toggle button to start the countdown. Now remove the authentication disk so that the buttons deactivate.<br>Note: <b>THE BOMB IS STILL SET AND WILL DETONATE</b><br>Now before you remove the disk if you need to move the bomb you can: Toggle off the anchor, move it, and re-anchor.</p><p>The nuclear authorization code is: <b>[nuke_code ? nuke_code : "None provided"]</b></p><p><b>Good luck, soldier!</b></p>"
P.name = "Spec. Ops Manual"
P.icon = "pamphlet-ds"
var/obj/item/stamp/centcom/stamp = new
P.stamp(stamp)
qdel(stamp)
for(var/obj/effect/landmark/L in GLOB.landmarks_list)
if(L.name == "Commando-Bomb")
new /obj/effect/spawner/newbomb/timer/syndicate(L.loc)
qdel(L)
message_admins("<span class='notice'>[key_name_admin(usr)] has spawned a CentComm DeathSquad.</span>", 1)
log_admin("[key_name(usr)] used Spawn Death Squad.")
return 1
/client/proc/create_death_commando(obj/spawn_location, is_leader = FALSE)
var/mob/living/carbon/human/new_commando = new(spawn_location.loc)
var/commando_leader_rank = pick("Lieutenant", "Captain", "Major")
var/commando_rank = pick("Corporal", "Sergeant", "Staff Sergeant", "Sergeant 1st Class", "Master Sergeant", "Sergeant Major")
var/commando_name = pick(GLOB.last_names)
var/datum/preferences/A = new()//Randomize appearance for the commando.
if(is_leader)
A.age = rand(35,45)
A.real_name = "[commando_leader_rank] [commando_name]"
else
A.real_name = "[commando_rank] [commando_name]"
A.copy_to(new_commando)
new_commando.dna.ready_dna(new_commando)//Creates DNA.
//Creates mind stuff.
new_commando.mind_initialize()
new_commando.mind.assigned_role = SPECIAL_ROLE_DEATHSQUAD
new_commando.mind.special_role = SPECIAL_ROLE_DEATHSQUAD
SSticker.mode.traitors |= new_commando.mind//Adds them to current traitor list. Which is really the extra antagonist list.
new_commando.equip_death_commando(is_leader)
return new_commando
/mob/living/carbon/human/proc/equip_death_commando(is_leader = FALSE)
var/obj/item/radio/R = new /obj/item/radio/headset/alt(src)
R.set_frequency(DTH_FREQ)
R.requires_tcomms = FALSE
R.instant = TRUE
equip_to_slot_or_del(R, slot_l_ear)
if(is_leader)
equip_to_slot_or_del(new /obj/item/clothing/under/rank/centcom_officer(src), slot_w_uniform)
else
equip_to_slot_or_del(new /obj/item/clothing/under/color/green(src), slot_w_uniform)
equip_to_slot_or_del(new /obj/item/clothing/shoes/magboots/advance(src), slot_shoes)
equip_to_slot_or_del(new /obj/item/clothing/suit/space/deathsquad(src), slot_wear_suit)
equip_to_slot_or_del(new /obj/item/clothing/gloves/combat(src), slot_gloves)
equip_to_slot_or_del(new /obj/item/clothing/head/helmet/space/deathsquad(src), slot_head)
equip_to_slot_or_del(new /obj/item/clothing/mask/gas/sechailer/swat(src), slot_wear_mask)
equip_to_slot_or_del(new /obj/item/clothing/glasses/thermal(src), slot_glasses)
equip_to_slot_or_del(new /obj/item/storage/backpack/security(src), slot_back)
equip_to_slot_or_del(new /obj/item/storage/box(src), slot_in_backpack)
equip_to_slot_or_del(new /obj/item/ammo_box/a357(src), slot_in_backpack)
equip_to_slot_or_del(new /obj/item/reagent_containers/hypospray/combat/nanites(src), slot_in_backpack)
equip_to_slot_or_del(new /obj/item/storage/box/flashbangs(src), slot_in_backpack)
equip_to_slot_or_del(new /obj/item/flashlight(src), slot_in_backpack)
equip_to_slot_or_del(new /obj/item/pinpointer(src), slot_in_backpack)
if(is_leader)
equip_to_slot_or_del(new /obj/item/disk/nuclear/unrestricted(src), slot_in_backpack)
else
equip_to_slot_or_del(new /obj/item/grenade/plastic/x4(src), slot_in_backpack)
equip_to_slot_or_del(new /obj/item/melee/energy/sword/saber(src), slot_l_store)
equip_to_slot_or_del(new /obj/item/shield/energy(src), slot_r_store)
equip_to_slot_or_del(new /obj/item/tank/emergency_oxygen/double/full(src), slot_s_store)
equip_to_slot_or_del(new /obj/item/gun/projectile/revolver/mateba(src), slot_belt)
equip_to_slot_or_del(new /obj/item/gun/energy/pulse(src), slot_r_hand)
var/obj/item/implant/mindshield/L = new/obj/item/implant/mindshield(src)
L.implant(src)
var/obj/item/card/id/W = new(src)
W.name = "[real_name]'s ID Card"
W.icon_state = "deathsquad"
W.assignment = "Death Commando"
W.access = get_centcom_access(W.assignment)
W.registered_name = real_name
equip_to_slot_or_del(W, slot_wear_id)
return 1
+169 -169
View File
@@ -1,169 +1,169 @@
//STRIKE TEAMS
var/const/syndicate_commandos_possible = 6 //if more Commandos are needed in the future
var/global/sent_syndicate_strike_team = 0
/client/proc/syndicate_strike_team()
set category = "Event"
set name = "Spawn Syndicate Strike Team"
set desc = "Spawns a squad of commandos in the Syndicate Mothership if you want to run an admin event."
if(!src.holder)
to_chat(src, "Only administrators may use this command.")
return
if(!SSticker)
alert("The game hasn't started yet!")
return
if(sent_syndicate_strike_team == 1)
alert("The Syndicate are already sending a team, Mr. Dumbass.")
return
if(alert("Do you want to send in the Syndicate Strike Team? Once enabled, this is irreversible.",,"Yes","No")=="No")
return
alert("This 'mode' will go on until everyone is dead or the station is destroyed. You may also admin-call the evac shuttle when appropriate. Spawned syndicates have internals cameras which are viewable through a monitor inside the Syndicate Mothership Bridge. Assigning the team's detailed task is recommended from there. The first one selected/spawned will be the team leader.")
message_admins("<span class='notice'>[key_name_admin(usr)] has started to spawn a Syndicate Strike Team.</span>", 1)
var/input = null
while(!input)
input = sanitize(copytext(input(src, "Please specify which mission the syndicate strike team shall undertake.", "Specify Mission", ""),1,MAX_MESSAGE_LEN))
if(!input)
if(alert("Error, no mission set. Do you want to exit the setup process?",,"Yes","No")=="Yes")
return
if(sent_syndicate_strike_team)
to_chat(src, "Looks like someone beat you to it.")
return
var/syndicate_commando_number = syndicate_commandos_possible //for selecting a leader
var/is_leader = TRUE // set to FALSE after leader is spawned
// Find the nuclear auth code
var/nuke_code
var/temp_code
for(var/obj/machinery/nuclearbomb/N in world)
temp_code = text2num(N.r_code)
if(temp_code)//if it's actually a number. It won't convert any non-numericals.
nuke_code = N.r_code
break
// Find ghosts willing to be SST
var/list/commando_ghosts = pollCandidatesWithVeto(src, usr, syndicate_commandos_possible, "Join the Syndicate Strike Team?",, 21, 600, 1, role_playtime_requirements[ROLE_DEATHSQUAD], TRUE, FALSE)
if(!commando_ghosts.len)
to_chat(usr, "<span class='userdanger'>Nobody volunteered to join the SST.</span>")
return
sent_syndicate_strike_team = 1
//Spawns commandos and equips them.
for(var/obj/effect/landmark/L in GLOB.landmarks_list)
if(syndicate_commando_number <= 0)
break
if(L.name == "Syndicate-Commando")
if(!commando_ghosts.len)
break
var/mob/ghost_mob = pick(commando_ghosts)
commando_ghosts -= ghost_mob
if(!ghost_mob || !ghost_mob.key || !ghost_mob.client)
continue
var/mob/living/carbon/human/new_syndicate_commando = create_syndicate_death_commando(L, is_leader)
if(!new_syndicate_commando)
continue
new_syndicate_commando.key = ghost_mob.key
new_syndicate_commando.internal = new_syndicate_commando.s_store
new_syndicate_commando.update_action_buttons_icon()
//So they don't forget their code or mission.
if(nuke_code)
new_syndicate_commando.mind.store_memory("<B>Nuke Code:</B> <span class='warning'>[nuke_code]</span>.")
new_syndicate_commando.mind.store_memory("<B>Mission:</B> <span class='warning'>[input]</span>.")
to_chat(new_syndicate_commando, "<span class='notice'>You are an Elite Syndicate [is_leader ? "<B>TEAM LEADER</B>" : "commando"] in the service of the Syndicate. \nYour current mission is: <span class='userdanger'>[input]</span></span>")
new_syndicate_commando.faction += "syndicate"
var/datum/atom_hud/antag/opshud = huds[ANTAG_HUD_OPS]
opshud.join_hud(new_syndicate_commando.mind.current)
set_antag_hud(new_syndicate_commando.mind.current, "hudoperative")
new_syndicate_commando.regenerate_icons()
is_leader = FALSE
syndicate_commando_number--
message_admins("<span class='notice'>[key_name_admin(usr)] has spawned a Syndicate strike squad.</span>", 1)
log_admin("[key_name(usr)] used Spawn Syndicate Squad.")
feedback_add_details("admin_verb","SDTHS") //If you are copy-pasting this, ensure the 2nd parameter is unique to the new proc!
/client/proc/create_syndicate_death_commando(obj/spawn_location, is_leader = FALSE)
var/mob/living/carbon/human/new_syndicate_commando = new(spawn_location.loc)
var/syndicate_commando_leader_rank = pick("Lieutenant", "Captain", "Major")
var/syndicate_commando_rank = pick("Corporal", "Sergeant", "Staff Sergeant", "Sergeant 1st Class", "Master Sergeant", "Sergeant Major")
var/syndicate_commando_name = pick(GLOB.last_names)
var/datum/preferences/A = new()//Randomize appearance for the commando.
if(is_leader)
A.age = rand(35,45)
A.real_name = "[syndicate_commando_leader_rank] [syndicate_commando_name]"
else
A.real_name = "[syndicate_commando_rank] [syndicate_commando_name]"
A.copy_to(new_syndicate_commando)
new_syndicate_commando.dna.ready_dna(new_syndicate_commando)//Creates DNA.
//Creates mind stuff.
new_syndicate_commando.mind_initialize()
new_syndicate_commando.mind.assigned_role = SPECIAL_ROLE_SYNDICATE_DEATHSQUAD
new_syndicate_commando.mind.special_role = SPECIAL_ROLE_SYNDICATE_DEATHSQUAD
new_syndicate_commando.mind.offstation_role = TRUE
SSticker.mode.traitors |= new_syndicate_commando.mind //Adds them to current traitor list. Which is really the extra antagonist list.
new_syndicate_commando.equip_syndicate_commando(is_leader)
qdel(spawn_location)
return new_syndicate_commando
/mob/living/carbon/human/proc/equip_syndicate_commando(is_leader = FALSE, full_gear = FALSE)
var/obj/item/radio/R = new /obj/item/radio/headset/syndicate/alt/syndteam(src)
R.set_frequency(SYNDTEAM_FREQ)
equip_to_slot_or_del(R, slot_l_ear)
equip_to_slot_or_del(new /obj/item/clothing/under/syndicate(src), slot_w_uniform)
if(!full_gear)
equip_to_slot_or_del(new /obj/item/clothing/shoes/combat(src), slot_shoes)
equip_to_slot_or_del(new /obj/item/clothing/gloves/combat(src), slot_gloves)
equip_to_slot_or_del(new /obj/item/storage/backpack/security(src), slot_back)
equip_to_slot_or_del(new /obj/item/storage/box/survival_syndi(src), slot_in_backpack)
equip_to_slot_or_del(new /obj/item/gun/projectile/revolver(src), slot_in_backpack)
equip_to_slot_or_del(new /obj/item/ammo_box/a357(src), slot_in_backpack)
equip_to_slot_or_del(new /obj/item/reagent_containers/hypospray/combat/nanites(src), slot_in_backpack)
equip_to_slot_or_del(new /obj/item/grenade/plastic/x4(src), slot_in_backpack)
if(is_leader)
equip_to_slot_or_del(new /obj/item/pinpointer(src), slot_in_backpack)
equip_to_slot_or_del(new /obj/item/disk/nuclear/unrestricted(src), slot_in_backpack)
else
equip_to_slot_or_del(new /obj/item/grenade/plastic/x4(src), slot_in_backpack)
equip_to_slot_or_del(new /obj/item/card/emag(src), slot_r_store)
equip_to_slot_or_del(new /obj/item/melee/energy/sword/saber/red(src), slot_l_store)
if(full_gear)
equip_to_slot_or_del(new /obj/item/clothing/mask/gas/syndicate(src), slot_wear_mask)
equip_to_slot_or_del(new /obj/item/clothing/suit/space/hardsuit/syndi/elite/sst(src), slot_wear_suit)
equip_to_slot_or_del(new /obj/item/clothing/glasses/thermal(src), slot_glasses)
equip_to_slot_or_del(new /obj/item/storage/belt/military/sst(src), slot_belt)
equip_to_slot_or_del(new /obj/item/tank/jetpack/oxygen/harness(src), slot_s_store)
equip_to_slot_or_del(new /obj/item/clothing/shoes/magboots/syndie/advance(src), slot_shoes)
equip_to_slot_or_del(new /obj/item/gun/projectile/automatic/l6_saw(src), slot_r_hand)
equip_to_slot_or_del(new /obj/item/ammo_box/magazine/mm556x45(src), slot_in_backpack)
var/obj/item/implant/dust/D = new /obj/item/implant/dust(src)
D.implant(src)
var/obj/item/card/id/syndicate/W = new(src) //Untrackable by AI
W.name = "[real_name]'s ID Card"
W.icon_state = "syndie"
W.assignment = "Syndicate Commando"
W.access += get_syndicate_access(W.assignment)
W.registered_name = real_name
equip_to_slot_or_del(W, slot_wear_id)
return 1
//STRIKE TEAMS
#define SYNDICATE_COMMANDOS_POSSIBLE 6 //if more Commandos are needed in the future
GLOBAL_VAR_INIT(sent_syndicate_strike_team, 0)
/client/proc/syndicate_strike_team()
set category = "Event"
set name = "Spawn Syndicate Strike Team"
set desc = "Spawns a squad of commandos in the Syndicate Mothership if you want to run an admin event."
if(!src.holder)
to_chat(src, "Only administrators may use this command.")
return
if(!SSticker)
alert("The game hasn't started yet!")
return
if(GLOB.sent_syndicate_strike_team == 1)
alert("The Syndicate are already sending a team, Mr. Dumbass.")
return
if(alert("Do you want to send in the Syndicate Strike Team? Once enabled, this is irreversible.",,"Yes","No")=="No")
return
alert("This 'mode' will go on until everyone is dead or the station is destroyed. You may also admin-call the evac shuttle when appropriate. Spawned syndicates have internals cameras which are viewable through a monitor inside the Syndicate Mothership Bridge. Assigning the team's detailed task is recommended from there. The first one selected/spawned will be the team leader.")
message_admins("<span class='notice'>[key_name_admin(usr)] has started to spawn a Syndicate Strike Team.</span>", 1)
var/input = null
while(!input)
input = sanitize(copytext(input(src, "Please specify which mission the syndicate strike team shall undertake.", "Specify Mission", ""),1,MAX_MESSAGE_LEN))
if(!input)
if(alert("Error, no mission set. Do you want to exit the setup process?",,"Yes","No")=="Yes")
return
if(GLOB.sent_syndicate_strike_team)
to_chat(src, "Looks like someone beat you to it.")
return
var/syndicate_commando_number = SYNDICATE_COMMANDOS_POSSIBLE //for selecting a leader
var/is_leader = TRUE // set to FALSE after leader is spawned
// Find the nuclear auth code
var/nuke_code
var/temp_code
for(var/obj/machinery/nuclearbomb/N in world)
temp_code = text2num(N.r_code)
if(temp_code)//if it's actually a number. It won't convert any non-numericals.
nuke_code = N.r_code
break
// Find ghosts willing to be SST
var/list/commando_ghosts = pollCandidatesWithVeto(src, usr, SYNDICATE_COMMANDOS_POSSIBLE, "Join the Syndicate Strike Team?",, 21, 600, 1, GLOB.role_playtime_requirements[ROLE_DEATHSQUAD], TRUE, FALSE)
if(!commando_ghosts.len)
to_chat(usr, "<span class='userdanger'>Nobody volunteered to join the SST.</span>")
return
GLOB.sent_syndicate_strike_team = 1
//Spawns commandos and equips them.
for(var/obj/effect/landmark/L in GLOB.landmarks_list)
if(syndicate_commando_number <= 0)
break
if(L.name == "Syndicate-Commando")
if(!commando_ghosts.len)
break
var/mob/ghost_mob = pick(commando_ghosts)
commando_ghosts -= ghost_mob
if(!ghost_mob || !ghost_mob.key || !ghost_mob.client)
continue
var/mob/living/carbon/human/new_syndicate_commando = create_syndicate_death_commando(L, is_leader)
if(!new_syndicate_commando)
continue
new_syndicate_commando.key = ghost_mob.key
new_syndicate_commando.internal = new_syndicate_commando.s_store
new_syndicate_commando.update_action_buttons_icon()
//So they don't forget their code or mission.
if(nuke_code)
new_syndicate_commando.mind.store_memory("<B>Nuke Code:</B> <span class='warning'>[nuke_code]</span>.")
new_syndicate_commando.mind.store_memory("<B>Mission:</B> <span class='warning'>[input]</span>.")
to_chat(new_syndicate_commando, "<span class='notice'>You are an Elite Syndicate [is_leader ? "<B>TEAM LEADER</B>" : "commando"] in the service of the Syndicate. \nYour current mission is: <span class='userdanger'>[input]</span></span>")
new_syndicate_commando.faction += "syndicate"
var/datum/atom_hud/antag/opshud = GLOB.huds[ANTAG_HUD_OPS]
opshud.join_hud(new_syndicate_commando.mind.current)
set_antag_hud(new_syndicate_commando.mind.current, "hudoperative")
new_syndicate_commando.regenerate_icons()
is_leader = FALSE
syndicate_commando_number--
message_admins("<span class='notice'>[key_name_admin(usr)] has spawned a Syndicate strike squad.</span>", 1)
log_admin("[key_name(usr)] used Spawn Syndicate Squad.")
feedback_add_details("admin_verb","SDTHS") //If you are copy-pasting this, ensure the 2nd parameter is unique to the new proc!
/client/proc/create_syndicate_death_commando(obj/spawn_location, is_leader = FALSE)
var/mob/living/carbon/human/new_syndicate_commando = new(spawn_location.loc)
var/syndicate_commando_leader_rank = pick("Lieutenant", "Captain", "Major")
var/syndicate_commando_rank = pick("Corporal", "Sergeant", "Staff Sergeant", "Sergeant 1st Class", "Master Sergeant", "Sergeant Major")
var/syndicate_commando_name = pick(GLOB.last_names)
var/datum/preferences/A = new()//Randomize appearance for the commando.
if(is_leader)
A.age = rand(35,45)
A.real_name = "[syndicate_commando_leader_rank] [syndicate_commando_name]"
else
A.real_name = "[syndicate_commando_rank] [syndicate_commando_name]"
A.copy_to(new_syndicate_commando)
new_syndicate_commando.dna.ready_dna(new_syndicate_commando)//Creates DNA.
//Creates mind stuff.
new_syndicate_commando.mind_initialize()
new_syndicate_commando.mind.assigned_role = SPECIAL_ROLE_SYNDICATE_DEATHSQUAD
new_syndicate_commando.mind.special_role = SPECIAL_ROLE_SYNDICATE_DEATHSQUAD
new_syndicate_commando.mind.offstation_role = TRUE
SSticker.mode.traitors |= new_syndicate_commando.mind //Adds them to current traitor list. Which is really the extra antagonist list.
new_syndicate_commando.equip_syndicate_commando(is_leader)
qdel(spawn_location)
return new_syndicate_commando
/mob/living/carbon/human/proc/equip_syndicate_commando(is_leader = FALSE, full_gear = FALSE)
var/obj/item/radio/R = new /obj/item/radio/headset/syndicate/alt/syndteam(src)
R.set_frequency(SYNDTEAM_FREQ)
equip_to_slot_or_del(R, slot_l_ear)
equip_to_slot_or_del(new /obj/item/clothing/under/syndicate(src), slot_w_uniform)
if(!full_gear)
equip_to_slot_or_del(new /obj/item/clothing/shoes/combat(src), slot_shoes)
equip_to_slot_or_del(new /obj/item/clothing/gloves/combat(src), slot_gloves)
equip_to_slot_or_del(new /obj/item/storage/backpack/security(src), slot_back)
equip_to_slot_or_del(new /obj/item/storage/box/survival_syndi(src), slot_in_backpack)
equip_to_slot_or_del(new /obj/item/gun/projectile/revolver(src), slot_in_backpack)
equip_to_slot_or_del(new /obj/item/ammo_box/a357(src), slot_in_backpack)
equip_to_slot_or_del(new /obj/item/reagent_containers/hypospray/combat/nanites(src), slot_in_backpack)
equip_to_slot_or_del(new /obj/item/grenade/plastic/x4(src), slot_in_backpack)
if(is_leader)
equip_to_slot_or_del(new /obj/item/pinpointer(src), slot_in_backpack)
equip_to_slot_or_del(new /obj/item/disk/nuclear/unrestricted(src), slot_in_backpack)
else
equip_to_slot_or_del(new /obj/item/grenade/plastic/x4(src), slot_in_backpack)
equip_to_slot_or_del(new /obj/item/card/emag(src), slot_r_store)
equip_to_slot_or_del(new /obj/item/melee/energy/sword/saber/red(src), slot_l_store)
if(full_gear)
equip_to_slot_or_del(new /obj/item/clothing/mask/gas/syndicate(src), slot_wear_mask)
equip_to_slot_or_del(new /obj/item/clothing/suit/space/hardsuit/syndi/elite/sst(src), slot_wear_suit)
equip_to_slot_or_del(new /obj/item/clothing/glasses/thermal(src), slot_glasses)
equip_to_slot_or_del(new /obj/item/storage/belt/military/sst(src), slot_belt)
equip_to_slot_or_del(new /obj/item/tank/jetpack/oxygen/harness(src), slot_s_store)
equip_to_slot_or_del(new /obj/item/clothing/shoes/magboots/syndie/advance(src), slot_shoes)
equip_to_slot_or_del(new /obj/item/gun/projectile/automatic/l6_saw(src), slot_r_hand)
equip_to_slot_or_del(new /obj/item/ammo_box/magazine/mm556x45(src), slot_in_backpack)
var/obj/item/implant/dust/D = new /obj/item/implant/dust(src)
D.implant(src)
var/obj/item/card/id/syndicate/W = new(src) //Untrackable by AI
W.name = "[real_name]'s ID Card"
W.icon_state = "syndie"
W.assignment = "Syndicate Commando"
W.access += get_syndicate_access(W.assignment)
W.registered_name = real_name
equip_to_slot_or_del(W, slot_wear_id)
return 1
+21 -21
View File
@@ -1,21 +1,21 @@
//Merged Doohl's and the existing ticklag as they both had good elements about them ~Carn
/client/proc/ticklag()
set category = "Debug"
set name = "Set Ticklag"
set desc = "Sets a new tick lag. Recommend you don't mess with this too much! Stable, time-tested ticklag value is 0.9"
if(!check_rights(R_DEBUG)) return
var/newtick = input("Sets a new tick lag. Please don't mess with this too much! The stable, time-tested ticklag value is 0.9","Lag of Tick", world.tick_lag) as num|null
//I've used ticks of 2 before to help with serious singulo lags
if(newtick && newtick <= 2 && newtick > 0)
log_admin("[key_name(src)] has modified world.tick_lag to [newtick]", 0)
message_admins("[key_name_admin(src)] has modified world.tick_lag to [newtick]", 0)
world.tick_lag = newtick
feedback_add_details("admin_verb","TICKLAG") //If you are copy-pasting this, ensure the 2nd parameter is unique to the new proc!
else
to_chat(src, "<span class='warning'>Error: ticklag(): Invalid world.ticklag value. No changes made.</span>")
//Merged Doohl's and the existing ticklag as they both had good elements about them ~Carn
/client/proc/ticklag()
set category = "Debug"
set name = "Set Ticklag"
set desc = "Sets a new tick lag. Recommend you don't mess with this too much! Stable, time-tested ticklag value is 0.9"
if(!check_rights(R_DEBUG)) return
var/newtick = input("Sets a new tick lag. Please don't mess with this too much! The stable, time-tested ticklag value is 0.9","Lag of Tick", world.tick_lag) as num|null
//I've used ticks of 2 before to help with serious singulo lags
if(newtick && newtick <= 2 && newtick > 0)
log_admin("[key_name(src)] has modified world.tick_lag to [newtick]", 0)
message_admins("[key_name_admin(src)] has modified world.tick_lag to [newtick]", 0)
world.tick_lag = newtick
feedback_add_details("admin_verb","TICKLAG") //If you are copy-pasting this, ensure the 2nd parameter is unique to the new proc!
else
to_chat(src, "<span class='warning'>Error: ticklag(): Invalid world.ticklag value. No changes made.</span>")
+3 -3
View File
@@ -1,4 +1,4 @@
var/list/admin_verbs_show_debug_verbs = list(
GLOBAL_LIST_INIT(admin_verbs_show_debug_verbs, list(
/client/proc/camera_view,
/client/proc/sec_camera_report,
/client/proc/intercom_view,
@@ -22,7 +22,7 @@ var/list/admin_verbs_show_debug_verbs = list(
/client/proc/admin_redo_space_transitions,
/client/proc/make_turf_space_map,
/client/proc/vv_by_ref
)
))
// Would be nice to make this a permanent admin pref so we don't need to click it each time
/client/proc/enable_debug_verbs()
@@ -32,6 +32,6 @@ var/list/admin_verbs_show_debug_verbs = list(
if(!check_rights(R_DEBUG))
return
verbs += admin_verbs_show_debug_verbs
verbs += GLOB.admin_verbs_show_debug_verbs
feedback_add_details("admin_verb","mDV") //If you are copy-pasting this, ensure the 2nd parameter is unique to the new proc!
+22 -22
View File
@@ -1,22 +1,22 @@
/client/proc/triple_ai()
set category = "Event"
set name = "Create AI Triumvirate"
if(SSticker.current_state > GAME_STATE_PREGAME)
to_chat(usr, "This option is currently only usable during pregame. This may change at a later date.")
return
if(SSjobs && SSticker)
var/datum/job/job = SSjobs.GetJob("AI")
if(!job)
to_chat(usr, "Unable to locate the AI job")
return
if(SSticker.triai)
SSticker.triai = 0
to_chat(usr, "Only one AI will be spawned at round start.")
message_admins("<span class='notice'>[key_name_admin(usr)] has toggled off triple AIs at round start.</span>", 1)
else
SSticker.triai = 1
to_chat(usr, "There will be an AI Triumvirate at round start.")
message_admins("<span class='notice'>[key_name_admin(usr)] has toggled on triple AIs at round start.</span>", 1)
return
/client/proc/triple_ai()
set category = "Event"
set name = "Create AI Triumvirate"
if(SSticker.current_state > GAME_STATE_PREGAME)
to_chat(usr, "This option is currently only usable during pregame. This may change at a later date.")
return
if(SSjobs && SSticker)
var/datum/job/job = SSjobs.GetJob("AI")
if(!job)
to_chat(usr, "Unable to locate the AI job")
return
if(SSticker.triai)
SSticker.triai = 0
to_chat(usr, "Only one AI will be spawned at round start.")
message_admins("<span class='notice'>[key_name_admin(usr)] has toggled off triple AIs at round start.</span>", 1)
else
SSticker.triai = 1
to_chat(usr, "There will be an AI Triumvirate at round start.")
message_admins("<span class='notice'>[key_name_admin(usr)] has toggled on triple AIs at round start.</span>", 1)
return
+4 -4
View File
@@ -1,4 +1,4 @@
var/global/vox_tick = 1
GLOBAL_VAR_INIT(vox_tick, 1)
/mob/living/carbon/human/proc/equip_vox_raider()
@@ -10,7 +10,7 @@ var/global/vox_tick = 1
equip_to_slot_or_del(new /obj/item/clothing/shoes/magboots/vox(src), slot_shoes) // REPLACE THESE WITH CODED VOX ALTERNATIVES.
equip_to_slot_or_del(new /obj/item/clothing/gloves/color/yellow/vox(src), slot_gloves) // AS ABOVE.
switch(vox_tick)
switch(GLOB.vox_tick)
if(1) // Vox raider!
equip_to_slot_or_del(new /obj/item/clothing/suit/space/vox/carapace(src), slot_wear_suit)
equip_to_slot_or_del(new /obj/item/clothing/head/helmet/space/vox/carapace(src), slot_head)
@@ -59,7 +59,7 @@ var/global/vox_tick = 1
W.registered_user = src
equip_to_slot_or_del(W, slot_wear_id)
vox_tick++
if(vox_tick > 4) vox_tick = 1
GLOB.vox_tick++
if(GLOB.vox_tick > 4) GLOB.vox_tick = 1
return 1
+8 -10
View File
@@ -6,7 +6,7 @@
if(!new_ckey)
return
new_ckey = sanitizeSQL(new_ckey)
var/DBQuery/query_watchfind = dbcon.NewQuery("SELECT ckey FROM [format_table_name("player")] WHERE ckey = '[new_ckey]'")
var/DBQuery/query_watchfind = GLOB.dbcon.NewQuery("SELECT ckey FROM [format_table_name("player")] WHERE ckey = '[new_ckey]'")
if(!query_watchfind.Execute())
var/err = query_watchfind.ErrorMsg()
log_game("SQL ERROR obtaining ckey from player table. Error : \[[err]\]\n")
@@ -29,7 +29,7 @@
if(!adminckey)
return
var/admin_sql_ckey = sanitizeSQL(adminckey)
var/DBQuery/query_watchadd = dbcon.NewQuery("INSERT INTO [format_table_name("watch")] (ckey, reason, adminckey, timestamp) VALUES ('[target_sql_ckey]', '[reason]', '[admin_sql_ckey]', '[timestamp]')")
var/DBQuery/query_watchadd = GLOB.dbcon.NewQuery("INSERT INTO [format_table_name("watch")] (ckey, reason, adminckey, timestamp) VALUES ('[target_sql_ckey]', '[reason]', '[admin_sql_ckey]', '[timestamp]')")
if(!query_watchadd.Execute())
var/err = query_watchadd.ErrorMsg()
log_game("SQL ERROR during adding new watch entry. Error : \[[err]\]\n")
@@ -43,7 +43,7 @@
if(!check_rights(R_ADMIN))
return
var/target_sql_ckey = sanitizeSQL(target_ckey)
var/DBQuery/query_watchdel = dbcon.NewQuery("DELETE FROM [format_table_name("watch")] WHERE ckey = '[target_sql_ckey]'")
var/DBQuery/query_watchdel = GLOB.dbcon.NewQuery("DELETE FROM [format_table_name("watch")] WHERE ckey = '[target_sql_ckey]'")
if(!query_watchdel.Execute())
var/err = query_watchdel.ErrorMsg()
log_game("SQL ERROR during removing watch entry. Error : \[[err]\]\n")
@@ -57,7 +57,7 @@
if(!check_rights(R_ADMIN))
return
var/target_sql_ckey = sanitizeSQL(target_ckey)
var/DBQuery/query_watchreason = dbcon.NewQuery("SELECT reason FROM [format_table_name("watch")] WHERE ckey = '[target_sql_ckey]'")
var/DBQuery/query_watchreason = GLOB.dbcon.NewQuery("SELECT reason FROM [format_table_name("watch")] WHERE ckey = '[target_sql_ckey]'")
if(!query_watchreason.Execute())
var/err = query_watchreason.ErrorMsg()
log_game("SQL ERROR obtaining reason from watch table. Error : \[[err]\]\n")
@@ -71,7 +71,7 @@
var/sql_ckey = sanitizeSQL(usr.ckey)
var/edit_text = "Edited by [sql_ckey] on [SQLtime()] from \"[watch_reason]\" to \"[new_reason]\""
edit_text = sanitizeSQL(edit_text)
var/DBQuery/query_watchupdate = dbcon.NewQuery("UPDATE [format_table_name("watch")] SET reason = '[new_reason]', last_editor = '[sql_ckey]', edits = CONCAT(IFNULL(edits,''),'[edit_text]') WHERE ckey = '[target_sql_ckey]'")
var/DBQuery/query_watchupdate = GLOB.dbcon.NewQuery("UPDATE [format_table_name("watch")] SET reason = '[new_reason]', last_editor = '[sql_ckey]', edits = CONCAT(IFNULL(edits,''),'[edit_text]') WHERE ckey = '[target_sql_ckey]'")
if(!query_watchupdate.Execute())
var/err = query_watchupdate.ErrorMsg()
log_game("SQL ERROR editing watchlist reason. Error : \[[err]\]\n")
@@ -96,7 +96,7 @@
else
search = "^."
search = sanitizeSQL(search)
var/DBQuery/query_watchlist = dbcon.NewQuery("SELECT ckey, reason, adminckey, timestamp, last_editor FROM [format_table_name("watch")] WHERE ckey REGEXP '[search]' ORDER BY ckey")
var/DBQuery/query_watchlist = GLOB.dbcon.NewQuery("SELECT ckey, reason, adminckey, timestamp, last_editor FROM [format_table_name("watch")] WHERE ckey REGEXP '[search]' ORDER BY ckey")
if(!query_watchlist.Execute())
var/err = query_watchlist.ErrorMsg()
log_game("SQL ERROR obtaining ckey, reason, adminckey, timestamp, last_editor from watch table. Error : \[[err]\]\n")
@@ -113,11 +113,9 @@
output += "<br>[reason]<hr style='background:#000000; border:0; height:1px'>"
usr << browse(output, "window=watchwin;size=900x500")
/client/proc/check_watchlist(target_ckey)
if(!check_rights(R_ADMIN,0))
return
/proc/check_watchlist(target_ckey)
var/target_sql_ckey = sanitizeSQL(target_ckey)
var/DBQuery/query_watch = dbcon.NewQuery("SELECT reason FROM [format_table_name("watch")] WHERE ckey = '[target_sql_ckey]'")
var/DBQuery/query_watch = GLOB.dbcon.NewQuery("SELECT reason FROM [format_table_name("watch")] WHERE ckey = '[target_sql_ckey]'")
if(!query_watch.Execute())
var/err = query_watch.ErrorMsg()
log_game("SQL ERROR obtaining reason from watch table. Error : \[[err]\]\n")
+1 -1
View File
@@ -1,2 +1,2 @@
/datum/alarm_handler/camera
category = "Camera Alarms"
category = "Camera Alarms"
+1 -1
View File
@@ -1,2 +1,2 @@
/datum/alarm_handler/motion
category = "Motion Alarms"
category = "Motion Alarms"
@@ -134,4 +134,4 @@ GLOBAL_LIST_EMPTY(antagonists)
//Displayed at the end of roundend_category section
/datum/antagonist/proc/roundend_report_footer()
return
return
@@ -16,4 +16,4 @@
continue
var/datum/team/T = A.get_team()
if(!team_type || istype(T, team_type))
. |= T
. |= T
@@ -47,11 +47,11 @@
newhud.join_hud(current)
/datum/mind/proc/leave_all_huds()
for(var/datum/atom_hud/antag/hud in huds)
for(var/datum/atom_hud/antag/hud in GLOB.huds)
if(current in hud.hudusers)
hud.leave_hud(current)
for(var/datum/atom_hud/data/hud in huds)
for(var/datum/atom_hud/data/hud in GLOB.huds)
if(current in hud.hudusers)
hud.remove_hud_from(current)
@@ -77,4 +77,4 @@
/datum/mindslaves/proc/leave_serv_hud(datum/mind/free_mind)
thrallhud.leave_hud(free_mind.current)
set_antag_hud(free_mind.current, null)
set_antag_hud(free_mind.current, null)
@@ -266,7 +266,7 @@
to_chat(user, "<span class='notice'>The sludge does not respond to your attempt to awake it. Perhaps you should try again later.</span>")
/obj/item/antag_spawner/morph/spawn_antag(client/C, turf/T, type = "", mob/user)
var/mob/living/simple_animal/hostile/morph/wizard/M = new /mob/living/simple_animal/hostile/morph/wizard(pick(xeno_spawn))
var/mob/living/simple_animal/hostile/morph/wizard/M = new /mob/living/simple_animal/hostile/morph/wizard(pick(GLOB.xeno_spawn))
M.key = C.key
M.mind.assigned_role = SPECIAL_ROLE_MORPH
M.mind.special_role = SPECIAL_ROLE_MORPH
@@ -38,4 +38,4 @@
var/datum/objective/steal_five_of_type/summon_magic/magic = new
magic.owner = owner
objectives += magic
..()
..()
@@ -44,10 +44,10 @@
owner.objectives -= O
/datum/antagonist/mindslave/proc/update_mindslave_icons_added()
var/datum/atom_hud/antag/traitorhud = huds[ANTAG_HUD_TRAITOR]
var/datum/atom_hud/antag/traitorhud = GLOB.huds[ANTAG_HUD_TRAITOR]
traitorhud.join_hud(owner.current, null)
set_antag_hud(owner.current, "hudmindslave")
/datum/antagonist/mindslave/proc/update_mindslave_icons_removed()
var/datum/atom_hud/antag/traitorhud = huds[ANTAG_HUD_TRAITOR]
var/datum/atom_hud/antag/traitorhud = GLOB.huds[ANTAG_HUD_TRAITOR]
traitorhud.leave_hud(owner.current, null)
@@ -118,7 +118,7 @@
var/objective_amount = config.traitor_objectives_amount
if(is_hijacker && objective_count <= objective_amount) //Don't assign hijack if it would exceed the number of objectives set in config.traitor_objectives_amount
if (!(locate(/datum/objective/hijack) in objectives))
var/datum/objective/hijack/hijack_objective = new
@@ -152,8 +152,7 @@
var/objective_count = 0
var/try_again = TRUE
if(prob(30))
objective_count += forge_single_objective()
objective_count += forge_single_objective()
for(var/i = objective_count, i < config.traitor_objectives_amount)
var/datum/objective/assassinate/kill_objective = new
@@ -188,7 +187,7 @@
destroy_objective.owner = owner
destroy_objective.find_target()
if("[destroy_objective]" in assigned_targets) // Is this target already in their list of assigned targets? If so, don't add this objective and return
return 0
return 0
else if(destroy_objective.target) // Is the target a real one and not null? If so, add it to our list of targets to avoid duplicate targets
assigned_targets.Add("[destroy_objective.target]") // This logic is applied to all traitor objectives including steal objectives
add_objective(destroy_objective)
@@ -222,7 +221,7 @@
else if(kill_objective.target)
assigned_targets.Add("[kill_objective.target]")
add_objective(kill_objective)
else
var/datum/objective/steal/steal_objective = new
steal_objective.owner = owner
@@ -232,32 +231,13 @@
else if(steal_objective.steal_target)
assigned_targets.Add("[steal_objective.steal_target]")
add_objective(steal_objective)
/datum/antagonist/traitor/proc/forge_single_AI_objective()
. = 1
var/special_pick = rand(1,2)
switch(special_pick)
if(1) // AI hijack
var/datum/objective/block/block_objective = new
block_objective.owner = owner
add_objective(block_objective)
if(2) // Protect and strand a target
var/datum/objective/protect/yandere_one = new
yandere_one.owner = owner
yandere_one.find_target()
if("[yandere_one.target]" in assigned_targets)
return 0
else if(yandere_one.target)
assigned_targets.Add("[yandere_one.target]")
add_objective(yandere_one)
var/datum/objective/maroon/yandere_two = new
yandere_two.owner = owner
yandere_two.target = yandere_one.target
yandere_two.explanation_text = "Prevent [yandere_one.target], the [yandere_one.target.assigned_role] from escaping alive."
add_objective(yandere_two)
var/datum/objective/block/block_objective = new
block_objective.owner = owner
add_objective(block_objective)
/datum/antagonist/traitor/greet()
@@ -271,13 +251,13 @@
/datum/antagonist/traitor/proc/update_traitor_icons_added(datum/mind/traitor_mind)
var/datum/atom_hud/antag/traitorhud = huds[ANTAG_HUD_TRAITOR]
var/datum/atom_hud/antag/traitorhud = GLOB.huds[ANTAG_HUD_TRAITOR]
traitorhud.join_hud(owner.current, null)
set_antag_hud(owner.current, "hudsyndicate")
/datum/antagonist/traitor/proc/update_traitor_icons_removed(datum/mind/traitor_mind)
var/datum/atom_hud/antag/traitorhud = huds[ANTAG_HUD_TRAITOR]
var/datum/atom_hud/antag/traitorhud = GLOB.huds[ANTAG_HUD_TRAITOR]
traitorhud.leave_hud(owner.current, null)
set_antag_hud(owner.current, null)
@@ -293,7 +273,7 @@
if(should_equip)
equip_traitor()
owner.current.playsound_local(get_turf(owner.current), 'sound/ambience/antag/tatoralert.ogg', 100, FALSE, pressure_affected = FALSE)
/datum/antagonist/traitor/proc/give_codewords()
if(!owner.current)
@@ -329,7 +309,7 @@
if(traitor_kind == TRAITOR_HUMAN)
var/mob/living/carbon/human/traitor_mob = owner.current
// find a radio! toolbox(es), backpack, belt, headset
var/obj/item/R = locate(/obj/item/pda) in traitor_mob.contents //Hide the uplink in a PDA if available, otherwise radio
if(!R)
@@ -22,57 +22,57 @@
if(!istype(H))
return
H.ignore_gene_stability = TRUE
H.dna.SetSEState(HULKBLOCK, TRUE)
genemutcheck(H, HULKBLOCK, null, MUTCHK_FORCED)
H.dna.SetSEState(GLOB.hulkblock, TRUE)
genemutcheck(H, GLOB.hulkblock, null, MUTCHK_FORCED)
H.dna.SetSEState(XRAYBLOCK, TRUE)
genemutcheck(H, XRAYBLOCK, null, MUTCHK_FORCED)
H.dna.SetSEState(GLOB.xrayblock, TRUE)
genemutcheck(H, GLOB.xrayblock, null, MUTCHK_FORCED)
H.dna.SetSEState(FIREBLOCK, TRUE)
genemutcheck(H, FIREBLOCK, null, MUTCHK_FORCED)
H.dna.SetSEState(GLOB.fireblock, TRUE)
genemutcheck(H, GLOB.fireblock, null, MUTCHK_FORCED)
H.dna.SetSEState(COLDBLOCK, TRUE)
genemutcheck(H, COLDBLOCK, null, MUTCHK_FORCED)
H.dna.SetSEState(GLOB.coldblock, TRUE)
genemutcheck(H, GLOB.coldblock, null, MUTCHK_FORCED)
H.dna.SetSEState(TELEBLOCK, TRUE)
genemutcheck(H, TELEBLOCK, null, MUTCHK_FORCED)
H.dna.SetSEState(GLOB.teleblock, TRUE)
genemutcheck(H, GLOB.teleblock, null, MUTCHK_FORCED)
H.dna.SetSEState(INCREASERUNBLOCK, TRUE)
genemutcheck(H, INCREASERUNBLOCK, null, MUTCHK_FORCED)
H.dna.SetSEState(GLOB.increaserunblock, TRUE)
genemutcheck(H, GLOB.increaserunblock, null, MUTCHK_FORCED)
H.dna.SetSEState(BREATHLESSBLOCK, TRUE)
genemutcheck(H, BREATHLESSBLOCK, null, MUTCHK_FORCED)
H.dna.SetSEState(GLOB.breathlessblock, TRUE)
genemutcheck(H, GLOB.breathlessblock, null, MUTCHK_FORCED)
H.dna.SetSEState(REGENERATEBLOCK, TRUE)
genemutcheck(H, REGENERATEBLOCK, null, MUTCHK_FORCED)
H.dna.SetSEState(GLOB.regenerateblock, TRUE)
genemutcheck(H, GLOB.regenerateblock, null, MUTCHK_FORCED)
H.dna.SetSEState(SHOCKIMMUNITYBLOCK, TRUE)
genemutcheck(H, SHOCKIMMUNITYBLOCK, null, MUTCHK_FORCED)
H.dna.SetSEState(GLOB.shockimmunityblock, TRUE)
genemutcheck(H, GLOB.shockimmunityblock, null, MUTCHK_FORCED)
H.dna.SetSEState(SMALLSIZEBLOCK, TRUE)
genemutcheck(H, SMALLSIZEBLOCK, null, MUTCHK_FORCED)
H.dna.SetSEState(GLOB.smallsizeblock, TRUE)
genemutcheck(H, GLOB.smallsizeblock, null, MUTCHK_FORCED)
H.dna.SetSEState(SOBERBLOCK, TRUE)
genemutcheck(H, SOBERBLOCK, null, MUTCHK_FORCED)
H.dna.SetSEState(GLOB.soberblock, TRUE)
genemutcheck(H, GLOB.soberblock, null, MUTCHK_FORCED)
H.dna.SetSEState(PSYRESISTBLOCK, TRUE)
genemutcheck(H, PSYRESISTBLOCK, null, MUTCHK_FORCED)
H.dna.SetSEState(GLOB.psyresistblock, TRUE)
genemutcheck(H, GLOB.psyresistblock, null, MUTCHK_FORCED)
H.dna.SetSEState(SHADOWBLOCK, TRUE)
genemutcheck(H, SHADOWBLOCK, null, MUTCHK_FORCED)
H.dna.SetSEState(GLOB.shadowblock, TRUE)
genemutcheck(H, GLOB.shadowblock, null, MUTCHK_FORCED)
H.dna.SetSEState(CRYOBLOCK, TRUE)
genemutcheck(H, CRYOBLOCK, null, MUTCHK_FORCED)
H.dna.SetSEState(GLOB.cryoblock, TRUE)
genemutcheck(H, GLOB.cryoblock, null, MUTCHK_FORCED)
H.dna.SetSEState(EATBLOCK, TRUE)
genemutcheck(H, EATBLOCK, null, MUTCHK_FORCED)
H.dna.SetSEState(GLOB.eatblock, TRUE)
genemutcheck(H, GLOB.eatblock, null, MUTCHK_FORCED)
H.dna.SetSEState(JUMPBLOCK, TRUE)
genemutcheck(H, JUMPBLOCK, null, MUTCHK_FORCED)
H.dna.SetSEState(GLOB.jumpblock, TRUE)
genemutcheck(H, GLOB.jumpblock, null, MUTCHK_FORCED)
H.dna.SetSEState(IMMOLATEBLOCK, TRUE)
genemutcheck(H, IMMOLATEBLOCK, null, MUTCHK_FORCED)
H.dna.SetSEState(GLOB.immolateblock, TRUE)
genemutcheck(H, GLOB.immolateblock, null, MUTCHK_FORCED)
H.mutations.Add(LASER)
H.update_mutations()
H.update_body()
H.update_body()
+1 -1
View File
@@ -78,7 +78,7 @@
tokens += 1
return
if(panel_open && component_parts && istype(O, /obj/item/crowbar))
default_deconstruction_crowbar(O)
default_deconstruction_crowbar(user, O)
return
return ..()
+2 -2
View File
@@ -20,7 +20,7 @@
opening = 1
playsound(src.loc, 'sound/items/bubblewrap.ogg', 30, 1, extrarange = -4, falloff = 10)
icon_state = "prizeconfetti"
src.color = pick(random_color_list)
src.color = pick(GLOB.random_color_list)
var/prize_inside = pick(possible_contents)
spawn(10)
user.unEquip(src)
@@ -85,4 +85,4 @@
if(25 to 74)
icon_state = "tickets_3" // Buncha tickets
else
icon_state = "tickets_4" // Ticket snake
icon_state = "tickets_4" // Ticket snake
+6 -6
View File
@@ -1,4 +1,4 @@
/var/claw_game_html = null
GLOBAL_VAR(claw_game_html)
/obj/machinery/arcade/claw
name = "Claw Game"
@@ -30,8 +30,8 @@
component_parts += new /obj/item/stack/sheet/glass(null, 1)
RefreshParts()
if(!claw_game_html)
claw_game_html = file2text('code/modules/arcade/crane.html')
if(!GLOB.claw_game_html)
GLOB.claw_game_html = file2text('code/modules/arcade/crane.html')
/obj/machinery/arcade/claw/RefreshParts()
var/bin_upgrades = 0
@@ -58,14 +58,14 @@
atom_say("WINNER!")
new /obj/item/toy/prizeball(get_turf(src))
playsound(src.loc, 'sound/arcade/win.ogg', 50, 1, extrarange = -3, falloff = 10)
addtimer(CALLBACK(src, .update_icon), 10)
addtimer(CALLBACK(src, .proc/update_icon), 10)
/obj/machinery/arcade/claw/start_play(mob/user as mob)
..()
user << browse_rsc('page.css')
for(var/i in 1 to img_resources.len)
user << browse_rsc(img_resources[i])
var/my_game_html = replacetext(claw_game_html, "/* ref src */", UID())
var/my_game_html = replacetext(GLOB.claw_game_html, "/* ref src */", UID())
user << browse(my_game_html, "window=[window_name];size=915x600;can_resize=0")
/obj/machinery/arcade/claw/Topic(href, list/href_list)
@@ -76,4 +76,4 @@
if(!isnull(prize_won))
close_game()
if(prize_won == "1")
win()
win()
@@ -302,4 +302,4 @@
to_chat(user, "<span class='warning'>This mob is already at maximum health!</span>")
return
patient.mob_data.cur_health = patient.mob_data.max_health
to_chat(user, "<span class='notify'>[patient.mob_data.nickname ? patient.mob_data.nickname : patient.mob_data.mob_name] has been restored to full health!</span>")
to_chat(user, "<span class='notify'>[patient.mob_data.nickname ? patient.mob_data.nickname : patient.mob_data.mob_name] has been restored to full health!</span>")
@@ -27,6 +27,7 @@
desc = "A random Nano-Mob Trading Card from a Booster Pack. Wonder what it is?"
/obj/item/nanomob_card/booster/New()
..()
var/datum/mob_hunt/mob_info = pick(subtypesof(/datum/mob_hunt))
mob_data = new mob_info(0,null,1)
update_info()
+2 -2
View File
@@ -108,7 +108,7 @@
/datum/mob_hunt/proc/get_possible_areas()
var/list/possible_areas = list()
//setup, sets all station areas (and subtypes) to weight 1
for(var/A in the_station_areas)
for(var/A in GLOB.the_station_areas)
if(A == /area/holodeck) //don't allow holodeck areas as possible spawns since it will allow it to spawn in the holodeck rooms on z2 as well
continue
if(A in possible_areas)
@@ -498,4 +498,4 @@
turf_blacklist = list()
area_whitelist = list()
turf_whitelist = list()
lifetime = 2000
lifetime = 2000
@@ -253,4 +253,4 @@
TYPE_FLYING,
TYPE_BLUESPACE,
TYPE_STEEL)
immunity = list(TYPE_POISON)
immunity = list(TYPE_POISON)
+1 -1
View File
@@ -89,4 +89,4 @@ body {
.button {
cursor: pointer;
}
}
+5 -5
View File
@@ -52,7 +52,7 @@
if(component_parts && istype(O, /obj/item/crowbar))
if(tickets) //save the tickets!
print_tickets()
default_deconstruction_crowbar(O)
default_deconstruction_crowbar(user, O)
return
return ..()
@@ -140,11 +140,11 @@ th.cost.toomuch {background:maroon;}
<tbody>
"}
for(var/datum/prize_item/item in global_prizes.prizes)
for(var/datum/prize_item/item in GLOB.global_prizes.prizes)
var/cost_class="affordable"
if(item.cost>tickets)
cost_class="toomuch"
var/itemID = global_prizes.prizes.Find(item)
var/itemID = GLOB.global_prizes.prizes.Find(item)
var/row_color="light"
if(itemID%2 == 0)
row_color="dark"
@@ -185,12 +185,12 @@ th.cost.toomuch {background:maroon;}
if(href_list["buy"])
var/itemID = text2num(href_list["buy"])
var/datum/prize_item/item = global_prizes.prizes[itemID]
var/datum/prize_item/item = GLOB.global_prizes.prizes[itemID]
var/sure = alert(usr,"Are you sure you wish to purchase [item.name] for [item.cost] tickets?","You sure?","Yes","No") in list("Yes","No")
if(sure=="No")
updateUsrDialog()
return
if(!global_prizes.PlaceOrder(src, itemID))
if(!GLOB.global_prizes.PlaceOrder(src, itemID))
to_chat(usr, "<span class='warning'>Unable to complete the exchange.</span>")
else
to_chat(usr, "<span class='notice'>You've successfully purchased the item.</span>")
+2 -3
View File
@@ -1,5 +1,4 @@
var/global/datum/prizes/global_prizes = new
GLOBAL_DATUM_INIT(global_prizes, /datum/prizes, new())
/datum/prizes
var/list/prizes = list()
@@ -14,7 +13,7 @@ var/global/datum/prizes/global_prizes = new
return
if(!prize_counter)
return 0
var/datum/prize_item/item = global_prizes.prizes[itemID]
var/datum/prize_item/item = GLOB.global_prizes.prizes[itemID]
if(!item)
return 0
if(prize_counter.tickets >= item.cost)
+150 -146
View File
@@ -1,146 +1,150 @@
/obj/item/assembly
name = "assembly"
desc = "A small electronic device that should never exist."
icon = 'icons/obj/assemblies/new_assemblies.dmi'
icon_state = ""
flags = CONDUCT
w_class = WEIGHT_CLASS_SMALL
materials = list(MAT_METAL = 100)
throwforce = 2
throw_speed = 3
throw_range = 10
origin_tech = "magnets=1;engineering=1"
toolspeed = 1
usesound = 'sound/items/deconstruct.ogg'
var/bomb_name = "bomb" // used for naming bombs / mines
var/secured = TRUE
var/list/attached_overlays = null
var/obj/item/assembly_holder/holder = null
var/cooldown = FALSE //To prevent spam
var/wires = WIRE_RECEIVE | WIRE_PULSE
var/datum/wires/connected = null // currently only used by timer/signaler
var/const/WIRE_RECEIVE = 1 //Allows Pulsed(0) to call Activate()
var/const/WIRE_PULSE = 2 //Allows Pulse(0) to act on the holder
var/const/WIRE_PULSE_SPECIAL = 4 //Allows Pulse(0) to act on the holders special assembly
var/const/WIRE_RADIO_RECEIVE = 8 //Allows Pulsed(1) to call Activate()
var/const/WIRE_RADIO_PULSE = 16 //Allows Pulse(1) to send a radio message
/obj/item/assembly/proc/activate() //What the device does when turned on
return
/obj/item/assembly/proc/pulsed(radio = FALSE) //Called when another assembly acts on this one, var/radio will determine where it came from for wire calcs
return
/obj/item/assembly/proc/pulse(radio = FALSE) //Called when this device attempts to act on another device, var/radio determines if it was sent via radio or direct
return
/obj/item/assembly/proc/toggle_secure() //Code that has to happen when the assembly is un\secured goes here
return
/obj/item/assembly/proc/attach_assembly(obj/A, mob/user) //Called when an assembly is attacked by another
return
/obj/item/assembly/proc/process_cooldown() //Called via spawn(10) to have it count down the cooldown var
return
/obj/item/assembly/proc/holder_movement() //Called when the holder is moved
return
/obj/item/assembly/proc/describe() // Called by grenades to describe the state of the trigger (time left, etc)
return "The trigger assembly looks broken!"
/obj/item/assembly/interact(mob/user) //Called when attack_self is called
return
/obj/item/assembly/process_cooldown()
cooldown--
if(cooldown <= 0)
return FALSE
spawn(10)
process_cooldown()
return TRUE
/obj/item/assembly/Destroy()
if(istype(loc, /obj/item/assembly_holder) || istype(holder))
var/obj/item/assembly_holder/A = loc
if(A.a_left == src)
A.a_left = null
else if(A.a_right == src)
A.a_right = null
holder = null
return ..()
/obj/item/assembly/pulsed(radio = FALSE)
if(holder && (wires & WIRE_RECEIVE))
activate()
if(radio && (wires & WIRE_RADIO_RECEIVE))
activate()
return TRUE
/obj/item/assembly/pulse(radio = FALSE)
if(holder && (wires & WIRE_PULSE))
holder.process_activation(src, 1, 0)
if(holder && (wires & WIRE_PULSE_SPECIAL))
holder.process_activation(src, 0, 1)
if(istype(loc, /obj/item/grenade)) // This is a hack. Todo: Manage this better -Sayu
var/obj/item/grenade/G = loc
G.prime() // Adios, muchachos
return TRUE
/obj/item/assembly/activate()
if(!secured || cooldown > 0)
return FALSE
cooldown = 2
spawn(10)
process_cooldown()
return TRUE
/obj/item/assembly/toggle_secure()
secured = !secured
update_icon()
return secured
/obj/item/assembly/attach_assembly(obj/item/assembly/A, mob/user)
holder = new /obj/item/assembly_holder(get_turf(src))
if(holder.attach(A, src, user))
to_chat(user, "<span class='notice'>You attach [A] to [src]!</span>")
return TRUE
return FALSE
/obj/item/assembly/attackby(obj/item/W, mob/user, params)
if(isassembly(W))
var/obj/item/assembly/A = W
if(!A.secured && !secured)
attach_assembly(A, user)
return
if(isscrewdriver(W))
if(toggle_secure())
to_chat(user, "<span class='notice'>[src] is ready!</span>")
else
to_chat(user, "<span class='notice'>[src] can now be attached!</span>")
return
return ..()
/obj/item/assembly/process()
STOP_PROCESSING(SSobj, src)
/obj/item/assembly/examine(mob/user)
. = ..()
if(in_range(src, user) || loc == user)
if(secured)
. += "[src] is ready!"
else
. += "[src] can be attached!"
/obj/item/assembly/attack_self(mob/user)
if(!user)
return
user.set_machine(src)
interact(user)
return TRUE
/obj/item/assembly/interact(mob/user)
return
/obj/item/assembly
name = "assembly"
desc = "A small electronic device that should never exist."
icon = 'icons/obj/assemblies/new_assemblies.dmi'
icon_state = ""
flags = CONDUCT
w_class = WEIGHT_CLASS_SMALL
materials = list(MAT_METAL = 100)
throwforce = 2
throw_speed = 3
throw_range = 10
origin_tech = "magnets=1;engineering=1"
toolspeed = 1
usesound = 'sound/items/deconstruct.ogg'
var/bomb_name = "bomb" // used for naming bombs / mines
var/secured = TRUE
var/list/attached_overlays = null
var/obj/item/assembly_holder/holder = null
var/cooldown = FALSE //To prevent spam
var/wires = WIRE_RECEIVE | WIRE_PULSE
var/datum/wires/connected = null // currently only used by timer/signaler
var/const/WIRE_RECEIVE = 1 //Allows Pulsed(0) to call Activate()
var/const/WIRE_PULSE = 2 //Allows Pulse(0) to act on the holder
var/const/WIRE_PULSE_SPECIAL = 4 //Allows Pulse(0) to act on the holders special assembly
var/const/WIRE_RADIO_RECEIVE = 8 //Allows Pulsed(1) to call Activate()
var/const/WIRE_RADIO_PULSE = 16 //Allows Pulse(1) to send a radio message
/obj/item/assembly/proc/activate() //What the device does when turned on
return
/obj/item/assembly/proc/pulsed(radio = FALSE) //Called when another assembly acts on this one, var/radio will determine where it came from for wire calcs
return
/obj/item/assembly/proc/pulse(radio = FALSE) //Called when this device attempts to act on another device, var/radio determines if it was sent via radio or direct
return
/obj/item/assembly/proc/toggle_secure() //Code that has to happen when the assembly is un\secured goes here
return
/obj/item/assembly/proc/attach_assembly(obj/A, mob/user) //Called when an assembly is attacked by another
return
/obj/item/assembly/proc/process_cooldown() //Called via spawn(10) to have it count down the cooldown var
return
/obj/item/assembly/proc/holder_movement() //Called when the holder is moved
return
/obj/item/assembly/proc/describe() // Called by grenades to describe the state of the trigger (time left, etc)
return "The trigger assembly looks broken!"
/obj/item/assembly/interact(mob/user) //Called when attack_self is called
return
/obj/item/assembly/process_cooldown()
cooldown--
if(cooldown <= 0)
return FALSE
spawn(10)
process_cooldown()
return TRUE
/obj/item/assembly/Destroy()
if(istype(loc, /obj/item/assembly_holder) || istype(holder))
var/obj/item/assembly_holder/A = loc
if(A.a_left == src)
A.a_left = null
else if(A.a_right == src)
A.a_right = null
holder = null
return ..()
/obj/item/assembly/pulsed(radio = FALSE)
if(holder && (wires & WIRE_RECEIVE))
activate()
if(radio && (wires & WIRE_RADIO_RECEIVE))
activate()
return TRUE
/obj/item/assembly/pulse(radio = FALSE)
if(holder && (wires & WIRE_PULSE))
holder.process_activation(src, 1, 0)
if(holder && (wires & WIRE_PULSE_SPECIAL))
holder.process_activation(src, 0, 1)
if(istype(loc, /obj/item/grenade)) // This is a hack. Todo: Manage this better -Sayu
var/obj/item/grenade/G = loc
G.prime() // Adios, muchachos
return TRUE
/obj/item/assembly/activate()
if(!secured || cooldown > 0)
return FALSE
cooldown = 2
spawn(10)
process_cooldown()
return TRUE
/obj/item/assembly/toggle_secure()
secured = !secured
update_icon()
return secured
/obj/item/assembly/attach_assembly(obj/item/assembly/A, mob/user)
holder = new /obj/item/assembly_holder(get_turf(src))
if(holder.attach(A, src, user))
to_chat(user, "<span class='notice'>You attach [A] to [src]!</span>")
return TRUE
return FALSE
/obj/item/assembly/attackby(obj/item/W, mob/user, params)
if(isassembly(W))
var/obj/item/assembly/A = W
if(!A.secured && !secured)
attach_assembly(A, user)
return
return ..()
/obj/item/assembly/screwdriver_act(mob/user, obj/item/I)
. = TRUE
if(!I.use_tool(src, user, 0, volume = I.tool_volume))
return
if(toggle_secure())
to_chat(user, "<span class='notice'>[src] is ready!</span>")
else
to_chat(user, "<span class='notice'>[src] can now be attached!</span>")
/obj/item/assembly/process()
STOP_PROCESSING(SSobj, src)
/obj/item/assembly/examine(mob/user)
. = ..()
if(in_range(src, user) || loc == user)
if(secured)
. += "[src] is ready!"
else
. += "[src] can be attached!"
/obj/item/assembly/attack_self(mob/user)
if(!user)
return
user.set_machine(src)
interact(user)
return TRUE
/obj/item/assembly/interact(mob/user)
return
+180 -177
View File
@@ -1,177 +1,180 @@
/obj/item/onetankbomb
name = "bomb"
icon = 'icons/obj/tank.dmi'
item_state = "assembly"
throwforce = 5
w_class = WEIGHT_CLASS_NORMAL
throw_speed = 2
throw_range = 4
flags = CONDUCT //Copied this from old code, so this may or may not be necessary
var/status = 0 //0 - not readied //1 - bomb finished with welder
var/obj/item/assembly_holder/bombassembly = null //The first part of the bomb is an assembly holder, holding an igniter+some device
var/obj/item/tank/bombtank = null //the second part of the bomb is a plasma tank
origin_tech = "materials=1;engineering=1"
/obj/item/onetankbomb/examine(mob/user)
. = ..()
. += bombtank.examine(user)
/obj/item/onetankbomb/update_icon()
if(bombtank)
icon_state = bombtank.icon_state
if(bombassembly)
overlays += bombassembly.icon_state
overlays += bombassembly.overlays
overlays += "bomb_assembly"
/obj/item/onetankbomb/attackby(obj/item/W, mob/user, params)
if(istype(W, /obj/item/analyzer))
bombtank.attackby(W, user, params)
return
if(iswrench(W) && !status) //This is basically bomb assembly code inverted. apparently it works.
to_chat(user, "<span class='notice'>You disassemble [src].</span>")
bombassembly.loc = user.loc
bombassembly.master = null
bombassembly = null
bombtank.loc = user.loc
bombtank.master = null
bombtank = null
qdel(src)
return
if(iswelder(W))
var/obj/item/weldingtool/WT = W
if(WT.welding)
if(!status)
status = TRUE
investigate_log("[key_name(user)] welded a single tank bomb. Temperature: [bombtank.air_contents.temperature-T0C]", INVESTIGATE_BOMB)
msg_admin_attack("[key_name_admin(user)] welded a single tank bomb. Temperature: [bombtank.air_contents.temperature-T0C]", ATKLOG_FEW)
log_game("[key_name(user)] welded a single tank bomb. Temperature: [bombtank.air_contents.temperature - T0C]")
to_chat(user, "<span class='notice'>A pressure hole has been bored to [bombtank] valve. [bombtank] can now be ignited.</span>")
else
status = FALSE
investigate_log("[key_name(user)] unwelded a single tank bomb. Temperature: [bombtank.air_contents.temperature-T0C]", INVESTIGATE_BOMB)
to_chat(user, "<span class='notice'>The hole has been closed.</span>")
add_fingerprint(user)
..()
/obj/item/onetankbomb/attack_self(mob/user) //pressing the bomb accesses its assembly
bombassembly.attack_self(user, 1)
add_fingerprint(user)
return
/obj/item/onetankbomb/receive_signal() //This is mainly called by the sensor through sense() to the holder, and from the holder to here.
visible_message("[bicon(src)] *beep* *beep*", "*beep* *beep*")
sleep(10)
if(!src)
return
if(status)
bombtank.detonate() //if its not a dud, boom (or not boom if you made shitty mix) the ignite proc is below, in this file
else
bombtank.release()
/obj/item/onetankbomb/HasProximity(atom/movable/AM)
if(bombassembly)
bombassembly.HasProximity(AM)
/obj/item/onetankbomb/Crossed(atom/movable/AM, oldloc) //for mousetraps
if(bombassembly)
bombassembly.Crossed(AM, oldloc)
/obj/item/onetankbomb/on_found(mob/finder) //for mousetraps
if(bombassembly)
bombassembly.on_found(finder)
/obj/item/onetankbomb/hear_talk(mob/living/M, list/message_pieces)
if(bombassembly)
bombassembly.hear_talk(M, message_pieces)
/obj/item/onetankbomb/hear_message(mob/living/M, msg)
if(bombassembly)
bombassembly.hear_message(M, msg)
// ---------- Procs below are for tanks that are used exclusively in 1-tank bombs ----------
/obj/item/tank/proc/bomb_assemble(W,user) //Bomb assembly proc. This turns assembly+tank into a bomb
var/obj/item/assembly_holder/S = W
var/mob/M = user
if(!S.secured) //Check if the assembly is secured
return
if(isigniter(S.a_left) == isigniter(S.a_right)) //Check if either part of the assembly has an igniter, but if both parts are igniters, then fuck it
return
var/obj/item/onetankbomb/R = new /obj/item/onetankbomb(loc)
M.drop_item() //Remove the assembly from your hands
M.remove_from_mob(src) //Remove the tank from your character,in case you were holding it
M.put_in_hands(R) //Equips the bomb if possible, or puts it on the floor.
R.bombassembly = S //Tell the bomb about its assembly part
S.master = R //Tell the assembly about its new owner
S.loc = R //Move the assembly out of the fucking way
R.bombtank = src //Same for tank
master = R
loc = R
R.update_icon()
return
/obj/item/tank/proc/detonate() //This happens when a bomb is told to explode
var/fuel_moles = air_contents.toxins + air_contents.oxygen/6
var/strength = 1
var/turf/ground_zero = get_turf(loc)
loc = null
if(air_contents.temperature > (T0C + 400))
strength = (fuel_moles/15)
if(strength >=1)
explosion(ground_zero, round(strength,1), round(strength*2,1), round(strength*3,1), round(strength*4,1))
else if(strength >=0.5)
explosion(ground_zero, 0, 1, 2, 4)
else if(strength >=0.2)
explosion(ground_zero, -1, 0, 1, 2)
else
ground_zero.assume_air(air_contents)
ground_zero.hotspot_expose(1000, 125)
else if(air_contents.temperature > (T0C + 250))
strength = (fuel_moles/20)
if(strength >=1)
explosion(ground_zero, 0, round(strength,1), round(strength*2,1), round(strength*3,1))
else if(strength >=0.5)
explosion(ground_zero, -1, 0, 1, 2)
else
ground_zero.assume_air(air_contents)
ground_zero.hotspot_expose(1000, 125)
else if(air_contents.temperature > (T0C + 100))
strength = (fuel_moles/25)
if(strength >=1)
explosion(ground_zero, -1, 0, round(strength,1), round(strength*3,1))
else
ground_zero.assume_air(air_contents)
ground_zero.hotspot_expose(1000, 125)
else
ground_zero.assume_air(air_contents)
ground_zero.hotspot_expose(1000, 125)
air_update_turf()
if(master)
qdel(master)
qdel(src)
/obj/item/tank/proc/release() //This happens when the bomb is not welded. Tank contents are just spat out.
var/datum/gas_mixture/removed = air_contents.remove(air_contents.total_moles())
var/turf/simulated/T = get_turf(src)
if(!T)
return
T.assume_air(removed)
air_update_turf()
/obj/item/onetankbomb
name = "bomb"
icon = 'icons/obj/tank.dmi'
item_state = "assembly"
throwforce = 5
w_class = WEIGHT_CLASS_NORMAL
throw_speed = 2
throw_range = 4
flags = CONDUCT //Copied this from old code, so this may or may not be necessary
var/status = 0 //0 - not readied //1 - bomb finished with welder
var/obj/item/assembly_holder/bombassembly = null //The first part of the bomb is an assembly holder, holding an igniter+some device
var/obj/item/tank/bombtank = null //the second part of the bomb is a plasma tank
origin_tech = "materials=1;engineering=1"
/obj/item/onetankbomb/examine(mob/user)
. = ..()
. += bombtank.examine(user)
/obj/item/onetankbomb/update_icon()
if(bombtank)
icon_state = bombtank.icon_state
if(bombassembly)
overlays += bombassembly.icon_state
overlays += bombassembly.overlays
overlays += "bomb_assembly"
/obj/item/onetankbomb/attackby(obj/item/W, mob/user, params)
if(istype(W, /obj/item/analyzer))
bombtank.attackby(W, user, params)
return
return ..()
/obj/item/onetankbomb/wrench_act(mob/user, obj/item/I) //This is basically bomb assembly code inverted. apparently it works.
if(status)
return
. = TRUE
if(!I.use_tool(src, user, 0, volume = I.tool_volume))
return
to_chat(user, "<span class='notice'>You disassemble [src].</span>")
bombassembly.loc = user.loc
bombassembly.master = null
bombassembly = null
bombtank.loc = user.loc
bombtank.master = null
bombtank = null
qdel(src)
/obj/item/onetankbomb/welder_act(mob/user, obj/item/I)
. = TRUE
if(!I.use_tool(src, user, volume = I.tool_volume))
return
if(!status)
status = TRUE
investigate_log("[key_name(user)] welded a single tank bomb. Temperature: [bombtank.air_contents.temperature-T0C]", INVESTIGATE_BOMB)
msg_admin_attack("[key_name_admin(user)] welded a single tank bomb. Temperature: [bombtank.air_contents.temperature-T0C]", ATKLOG_FEW)
log_game("[key_name(user)] welded a single tank bomb. Temperature: [bombtank.air_contents.temperature - T0C]")
to_chat(user, "<span class='notice'>A pressure hole has been bored to [bombtank] valve. [bombtank] can now be ignited.</span>")
else
status = FALSE
investigate_log("[key_name(user)] unwelded a single tank bomb. Temperature: [bombtank.air_contents.temperature-T0C]", INVESTIGATE_BOMB)
to_chat(user, "<span class='notice'>The hole has been closed.</span>")
/obj/item/onetankbomb/attack_self(mob/user) //pressing the bomb accesses its assembly
bombassembly.attack_self(user, 1)
add_fingerprint(user)
return
/obj/item/onetankbomb/receive_signal() //This is mainly called by the sensor through sense() to the holder, and from the holder to here.
visible_message("[bicon(src)] *beep* *beep*", "*beep* *beep*")
sleep(10)
if(!src)
return
if(status)
bombtank.detonate() //if its not a dud, boom (or not boom if you made shitty mix) the ignite proc is below, in this file
else
bombtank.release()
/obj/item/onetankbomb/HasProximity(atom/movable/AM)
if(bombassembly)
bombassembly.HasProximity(AM)
/obj/item/onetankbomb/Crossed(atom/movable/AM, oldloc) //for mousetraps
if(bombassembly)
bombassembly.Crossed(AM, oldloc)
/obj/item/onetankbomb/on_found(mob/finder) //for mousetraps
if(bombassembly)
bombassembly.on_found(finder)
/obj/item/onetankbomb/hear_talk(mob/living/M, list/message_pieces)
if(bombassembly)
bombassembly.hear_talk(M, message_pieces)
/obj/item/onetankbomb/hear_message(mob/living/M, msg)
if(bombassembly)
bombassembly.hear_message(M, msg)
// ---------- Procs below are for tanks that are used exclusively in 1-tank bombs ----------
/obj/item/tank/proc/bomb_assemble(W,user) //Bomb assembly proc. This turns assembly+tank into a bomb
var/obj/item/assembly_holder/S = W
var/mob/M = user
if(!S.secured) //Check if the assembly is secured
return
if(isigniter(S.a_left) == isigniter(S.a_right)) //Check if either part of the assembly has an igniter, but if both parts are igniters, then fuck it
return
var/obj/item/onetankbomb/R = new /obj/item/onetankbomb(loc)
M.drop_item() //Remove the assembly from your hands
M.remove_from_mob(src) //Remove the tank from your character,in case you were holding it
M.put_in_hands(R) //Equips the bomb if possible, or puts it on the floor.
R.bombassembly = S //Tell the bomb about its assembly part
S.master = R //Tell the assembly about its new owner
S.loc = R //Move the assembly out of the fucking way
R.bombtank = src //Same for tank
master = R
loc = R
R.update_icon()
return
/obj/item/tank/proc/detonate() //This happens when a bomb is told to explode
var/fuel_moles = air_contents.toxins + air_contents.oxygen/6
var/strength = 1
var/turf/ground_zero = get_turf(loc)
loc = null
if(air_contents.temperature > (T0C + 400))
strength = (fuel_moles/15)
if(strength >=1)
explosion(ground_zero, round(strength,1), round(strength*2,1), round(strength*3,1), round(strength*4,1))
else if(strength >=0.5)
explosion(ground_zero, 0, 1, 2, 4)
else if(strength >=0.2)
explosion(ground_zero, -1, 0, 1, 2)
else
ground_zero.assume_air(air_contents)
ground_zero.hotspot_expose(1000, 125)
else if(air_contents.temperature > (T0C + 250))
strength = (fuel_moles/20)
if(strength >=1)
explosion(ground_zero, 0, round(strength,1), round(strength*2,1), round(strength*3,1))
else if(strength >=0.5)
explosion(ground_zero, -1, 0, 1, 2)
else
ground_zero.assume_air(air_contents)
ground_zero.hotspot_expose(1000, 125)
else if(air_contents.temperature > (T0C + 100))
strength = (fuel_moles/25)
if(strength >=1)
explosion(ground_zero, -1, 0, round(strength,1), round(strength*3,1))
else
ground_zero.assume_air(air_contents)
ground_zero.hotspot_expose(1000, 125)
else
ground_zero.assume_air(air_contents)
ground_zero.hotspot_expose(1000, 125)
air_update_turf()
if(master)
qdel(master)
qdel(src)
/obj/item/tank/proc/release() //This happens when the bomb is not welded. Tank contents are just spat out.
var/datum/gas_mixture/removed = air_contents.remove(air_contents.total_moles())
var/turf/simulated/T = get_turf(src)
if(!T)
return
T.assume_air(removed)
air_update_turf()
+9 -10
View File
@@ -28,17 +28,16 @@
update_icon()
return secured
/obj/item/assembly/health/attackby(obj/item/W, mob/user)
if(ismultitool(W))
if(alarm_health == 0)
alarm_health = -90
user.show_message("You toggle [src] to \"detect death\" mode.")
else
alarm_health = 0
user.show_message("You toggle [src] to \"detect critical state\" mode.")
/obj/item/assembly/health/multitool_act(mob/user, obj/item/I)
. = TRUE
if(!I.use_tool(src, user, 0, volume = I.tool_volume))
return
if(alarm_health == 0)
alarm_health = -90
user.show_message("You toggle [src] to \"detect death\" mode.")
else
return ..()
alarm_health = 0
user.show_message("You toggle [src] to \"detect critical state\" mode.")
/obj/item/assembly/health/process()
if(!scanning || !secured)
@@ -105,4 +104,4 @@
return
attack_self(user)
return
return
+44 -44
View File
@@ -1,44 +1,44 @@
/proc/isassembly(O)
if(istype(O, /obj/item/assembly))
return 1
return 0
/proc/isigniter(O)
if(istype(O, /obj/item/assembly/igniter))
return 1
return 0
/proc/isinfared(O)
if(istype(O, /obj/item/assembly/infra))
return 1
return 0
/proc/isprox(O)
if(istype(O, /obj/item/assembly/prox_sensor))
return 1
return 0
/proc/issignaler(O)
if(istype(O, /obj/item/assembly/signaler))
return 1
return 0
/proc/istimer(O)
if(istype(O, /obj/item/assembly/timer))
return 1
return 0
/*
Name: IsSpecialAssembly
Desc: If true is an object that can be attached to an assembly holder but is a special thing like a plasma can or door
*/
/obj/proc/IsSpecialAssembly()
return 0
/*
Name: IsAssemblyHolder
Desc: If true is an object that can hold an assemblyholder object
*/
/obj/proc/IsAssemblyHolder()
return 0
/proc/isassembly(O)
if(istype(O, /obj/item/assembly))
return 1
return 0
/proc/isigniter(O)
if(istype(O, /obj/item/assembly/igniter))
return 1
return 0
/proc/isinfared(O)
if(istype(O, /obj/item/assembly/infra))
return 1
return 0
/proc/isprox(O)
if(istype(O, /obj/item/assembly/prox_sensor))
return 1
return 0
/proc/issignaler(O)
if(istype(O, /obj/item/assembly/signaler))
return 1
return 0
/proc/istimer(O)
if(istype(O, /obj/item/assembly/timer))
return 1
return 0
/*
Name: IsSpecialAssembly
Desc: If true is an object that can be attached to an assembly holder but is a special thing like a plasma can or door
*/
/obj/proc/IsSpecialAssembly()
return 0
/*
Name: IsAssemblyHolder
Desc: If true is an object that can hold an assemblyholder object
*/
/obj/proc/IsAssemblyHolder()
return 0
+197 -200
View File
@@ -1,200 +1,197 @@
/obj/item/assembly_holder
name = "Assembly"
icon = 'icons/obj/assemblies/new_assemblies.dmi'
icon_state = "holder"
item_state = "assembly"
flags = CONDUCT
throwforce = 5
w_class = WEIGHT_CLASS_SMALL
throw_speed = 3
throw_range = 10
var/secured = FALSE
var/obj/item/assembly/a_left = null
var/obj/item/assembly/a_right = null
/obj/item/assembly_holder/proc/attach(obj/item/D, obj/item/D2, mob/user)
return
/obj/item/assembly_holder/proc/process_activation(var/obj/item/D)
return
/obj/item/assembly_holder/IsAssemblyHolder()
return TRUE
/obj/item/assembly_holder/Destroy()
if(a_left)
a_left.holder = null
if(a_right)
a_right.holder = null
return ..()
/obj/item/assembly_holder/attach(obj/item/D, obj/item/D2, mob/user)
if(!D || !D2)
return FALSE
if(!isassembly(D) || !isassembly(D2))
return FALSE
var/obj/item/assembly/A1 = D
var/obj/item/assembly/A2 = D2
if(A1.secured || A2.secured)
return FALSE
if(!A1.remove_item_from_storage(src))
if(user)
user.remove_from_mob(A1)
A1.loc = src
if(!A2.remove_item_from_storage(src))
if(user)
user.remove_from_mob(A2)
A2.loc = src
A1.holder = src
A2.holder = src
a_left = A1
a_right = A2
name = "[A1.name]-[A2.name] assembly"
update_icon()
return TRUE
/obj/item/assembly_holder/update_icon()
overlays.Cut()
if(a_left)
overlays += "[a_left.icon_state]_left"
for(var/O in a_left.attached_overlays)
overlays += "[O]_l"
if(a_right)
overlays += "[a_right.icon_state]_right"
for(var/O in a_right.attached_overlays)
overlays += "[O]_r"
if(master)
master.update_icon()
/obj/item/assembly_holder/examine(mob/user)
. = ..()
if(in_range(src, user) || loc == user)
if(secured)
. += "[src] is ready!"
else
. += "[src] can be attached!"
/obj/item/assembly_holder/HasProximity(atom/movable/AM)
if(a_left)
a_left.HasProximity(AM)
if(a_right)
a_right.HasProximity(AM)
/obj/item/assembly_holder/Crossed(atom/movable/AM, oldloc)
if(a_left)
a_left.Crossed(AM, oldloc)
if(a_right)
a_right.Crossed(AM, oldloc)
/obj/item/assembly_holder/on_found(mob/finder)
if(a_left)
a_left.on_found(finder)
if(a_right)
a_right.on_found(finder)
/obj/item/assembly_holder/hear_talk(mob/living/M, list/message_pieces)
if(a_left)
a_left.hear_talk(M, message_pieces)
if(a_right)
a_right.hear_talk(M, message_pieces)
/obj/item/assembly_holder/hear_message(mob/living/M, msg)
if(a_left)
a_left.hear_message(M, msg)
if(a_right)
a_right.hear_message(M, msg)
/obj/item/assembly_holder/proc/process_movement() // infrared beams and prox sensors
if(a_left && a_right)
a_left.holder_movement()
a_right.holder_movement()
/obj/item/assembly_holder/Move()
. = ..()
process_movement()
return
/obj/item/assembly_holder/pickup()
. = ..()
process_movement()
/obj/item/assembly_holder/Bump()
..()
process_movement()
/obj/item/assembly_holder/throw_impact() // called when a throw stops
..()
process_movement()
/obj/item/assembly_holder/attack_hand()//Perhapse this should be a holder_pickup proc instead, can add if needbe I guess
if(a_left && a_right)
a_left.holder_movement()
a_right.holder_movement()
..()
return
/obj/item/assembly_holder/attackby(obj/item/W, mob/user, params)
if(isscrewdriver(W))
if(!a_left || !a_right)
to_chat(user, "<span class='warning'>BUG:Assembly part missing, please report this!</span>")
return
a_left.toggle_secure()
a_right.toggle_secure()
secured = !secured
if(secured)
to_chat(user, "<span class='notice'>[src] is ready!</span>")
else
to_chat(user, "<span class='notice'>[src] can now be taken apart!</span>")
update_icon()
return
else
..()
return
/obj/item/assembly_holder/attack_self(mob/user)
add_fingerprint(user)
if(secured)
if(!a_left || !a_right)
to_chat(user, "<span class='warning'>Assembly part missing!</span>")
return
if(istype(a_left, a_right.type))//If they are the same type it causes issues due to window code
switch(alert("Which side would you like to use?",,"Left","Right"))
if("Left")
a_left.attack_self(user)
if("Right")
a_right.attack_self(user)
return
else
a_left.attack_self(user)
a_right.attack_self(user)
else
var/turf/T = get_turf(src)
if(!T)
return FALSE
if(a_left)
a_left.holder = null
a_left.loc = T
if(a_right)
a_right.holder = null
a_right.loc = T
qdel(src)
/obj/item/assembly_holder/process_activation(obj/D, normal = TRUE, special = TRUE)
if(!D)
return FALSE
if(normal && a_right && a_left)
if(a_right != D)
a_right.pulsed(0)
if(a_left != D)
a_left.pulsed(0)
if(master)
master.receive_signal()
return TRUE
/obj/item/assembly_holder
name = "Assembly"
icon = 'icons/obj/assemblies/new_assemblies.dmi'
icon_state = "holder"
item_state = "assembly"
flags = CONDUCT
throwforce = 5
w_class = WEIGHT_CLASS_SMALL
throw_speed = 3
throw_range = 10
var/secured = FALSE
var/obj/item/assembly/a_left = null
var/obj/item/assembly/a_right = null
/obj/item/assembly_holder/proc/attach(obj/item/D, obj/item/D2, mob/user)
return
/obj/item/assembly_holder/proc/process_activation(var/obj/item/D)
return
/obj/item/assembly_holder/IsAssemblyHolder()
return TRUE
/obj/item/assembly_holder/Destroy()
if(a_left)
a_left.holder = null
if(a_right)
a_right.holder = null
return ..()
/obj/item/assembly_holder/attach(obj/item/D, obj/item/D2, mob/user)
if(!D || !D2)
return FALSE
if(!isassembly(D) || !isassembly(D2))
return FALSE
var/obj/item/assembly/A1 = D
var/obj/item/assembly/A2 = D2
if(A1.secured || A2.secured)
return FALSE
if(!A1.remove_item_from_storage(src))
if(user)
user.remove_from_mob(A1)
A1.loc = src
if(!A2.remove_item_from_storage(src))
if(user)
user.remove_from_mob(A2)
A2.loc = src
A1.holder = src
A2.holder = src
a_left = A1
a_right = A2
name = "[A1.name]-[A2.name] assembly"
update_icon()
return TRUE
/obj/item/assembly_holder/update_icon()
overlays.Cut()
if(a_left)
overlays += "[a_left.icon_state]_left"
for(var/O in a_left.attached_overlays)
overlays += "[O]_l"
if(a_right)
overlays += "[a_right.icon_state]_right"
for(var/O in a_right.attached_overlays)
overlays += "[O]_r"
if(master)
master.update_icon()
/obj/item/assembly_holder/examine(mob/user)
. = ..()
if(in_range(src, user) || loc == user)
if(secured)
. += "[src] is ready!"
else
. += "[src] can be attached!"
/obj/item/assembly_holder/HasProximity(atom/movable/AM)
if(a_left)
a_left.HasProximity(AM)
if(a_right)
a_right.HasProximity(AM)
/obj/item/assembly_holder/Crossed(atom/movable/AM, oldloc)
if(a_left)
a_left.Crossed(AM, oldloc)
if(a_right)
a_right.Crossed(AM, oldloc)
/obj/item/assembly_holder/on_found(mob/finder)
if(a_left)
a_left.on_found(finder)
if(a_right)
a_right.on_found(finder)
/obj/item/assembly_holder/hear_talk(mob/living/M, list/message_pieces)
if(a_left)
a_left.hear_talk(M, message_pieces)
if(a_right)
a_right.hear_talk(M, message_pieces)
/obj/item/assembly_holder/hear_message(mob/living/M, msg)
if(a_left)
a_left.hear_message(M, msg)
if(a_right)
a_right.hear_message(M, msg)
/obj/item/assembly_holder/proc/process_movement() // infrared beams and prox sensors
if(a_left && a_right)
a_left.holder_movement()
a_right.holder_movement()
/obj/item/assembly_holder/Move()
. = ..()
process_movement()
return
/obj/item/assembly_holder/pickup()
. = ..()
process_movement()
/obj/item/assembly_holder/Bump()
..()
process_movement()
/obj/item/assembly_holder/throw_impact() // called when a throw stops
..()
process_movement()
/obj/item/assembly_holder/attack_hand()//Perhapse this should be a holder_pickup proc instead, can add if needbe I guess
if(a_left && a_right)
a_left.holder_movement()
a_right.holder_movement()
..()
return
/obj/item/assembly_holder/screwdriver_act(mob/user, obj/item/I)
if(!a_left || !a_right)
to_chat(user, "<span class='warning'>BUG:Assembly part missing, please report this!</span>")
return
. = TRUE
if(!I.use_tool(src, user, 0, volume = I.tool_volume))
return
a_left.toggle_secure()
a_right.toggle_secure()
secured = !secured
if(secured)
to_chat(user, "<span class='notice'>[src] is ready!</span>")
else
to_chat(user, "<span class='notice'>[src] can now be taken apart!</span>")
update_icon()
/obj/item/assembly_holder/attack_self(mob/user)
add_fingerprint(user)
if(secured)
if(!a_left || !a_right)
to_chat(user, "<span class='warning'>Assembly part missing!</span>")
return
if(istype(a_left, a_right.type))//If they are the same type it causes issues due to window code
switch(alert("Which side would you like to use?",,"Left","Right"))
if("Left")
a_left.attack_self(user)
if("Right")
a_right.attack_self(user)
return
else
a_left.attack_self(user)
a_right.attack_self(user)
else
var/turf/T = get_turf(src)
if(!T)
return FALSE
if(a_left)
a_left.holder = null
a_left.loc = T
if(a_right)
a_right.holder = null
a_right.loc = T
qdel(src)
/obj/item/assembly_holder/process_activation(obj/D, normal = TRUE, special = TRUE)
if(!D)
return FALSE
if(normal && a_right && a_left)
if(a_right != D)
a_right.pulsed(0)
if(a_left != D)
a_left.pulsed(0)
if(master)
master.receive_signal()
return TRUE
+45 -45
View File
@@ -1,45 +1,45 @@
/obj/item/assembly/igniter
name = "igniter"
desc = "A small electronic device able to ignite combustable substances."
icon_state = "igniter"
materials = list(MAT_METAL=500, MAT_GLASS=50)
origin_tech = "magnets=1"
var/datum/effect_system/spark_spread/sparks = new /datum/effect_system/spark_spread
/obj/item/assembly/igniter/New()
..()
sparks.set_up(2, 0, src)
sparks.attach(src)
/obj/item/assembly/igniter/Destroy()
QDEL_NULL(sparks)
return ..()
/obj/item/assembly/igniter/describe()
return "The igniter is [secured ? "secured." : "unsecured."]"
/obj/item/assembly/igniter/activate()
if(!..())
return FALSE//Cooldown check
var/turf/location = get_turf(loc)
if(location)
location.hotspot_expose(1000,1000)
if(istype(loc, /obj/item/assembly_holder))
if(istype(loc.loc, /obj/structure/reagent_dispensers/fueltank))
var/obj/structure/reagent_dispensers/fueltank/tank = loc.loc
if(tank)
tank.boom(TRUE)
if(istype(loc.loc, /obj/item/reagent_containers/glass/beaker))
var/obj/item/reagent_containers/glass/beaker/beakerbomb = loc.loc
if(beakerbomb)
beakerbomb.heat_beaker()
sparks.start()
return TRUE
/obj/item/assembly/igniter/attack_self(mob/user)
activate()
add_fingerprint(user)
return
/obj/item/assembly/igniter
name = "igniter"
desc = "A small electronic device able to ignite combustable substances."
icon_state = "igniter"
materials = list(MAT_METAL=500, MAT_GLASS=50)
origin_tech = "magnets=1"
var/datum/effect_system/spark_spread/sparks = new /datum/effect_system/spark_spread
/obj/item/assembly/igniter/New()
..()
sparks.set_up(2, 0, src)
sparks.attach(src)
/obj/item/assembly/igniter/Destroy()
QDEL_NULL(sparks)
return ..()
/obj/item/assembly/igniter/describe()
return "The igniter is [secured ? "secured." : "unsecured."]"
/obj/item/assembly/igniter/activate()
if(!..())
return FALSE//Cooldown check
var/turf/location = get_turf(loc)
if(location)
location.hotspot_expose(1000,1000)
if(istype(loc, /obj/item/assembly_holder))
if(istype(loc.loc, /obj/structure/reagent_dispensers/fueltank))
var/obj/structure/reagent_dispensers/fueltank/tank = loc.loc
if(tank)
tank.boom(TRUE)
if(istype(loc.loc, /obj/item/reagent_containers/glass/beaker))
var/obj/item/reagent_containers/glass/beaker/beakerbomb = loc.loc
if(beakerbomb)
beakerbomb.heat_beaker()
sparks.start()
return TRUE
/obj/item/assembly/igniter/attack_self(mob/user)
activate()
add_fingerprint(user)
return
+286 -286
View File
@@ -1,286 +1,286 @@
/obj/item/assembly/infra
name = "infrared emitter"
desc = "Emits a visible or invisible beam and is triggered when the beam is interrupted."
icon_state = "infrared"
materials = list(MAT_METAL=1000, MAT_GLASS=500)
origin_tech = "magnets=2;materials=2"
bomb_name = "tripwire mine"
secured = FALSE // toggle_secure()'ed in New() for correct adding to processing_objects, won't work otherwise
dir = EAST
var/on = FALSE
var/visible = TRUE
var/obj/effect/beam/i_beam/first = null
var/obj/effect/beam/i_beam/last = null
var/max_nesting_level = 10
var/turf/fire_location
var/emission_cycles = 0
var/emission_cap = 20
/obj/item/assembly/infra/Destroy()
if(first)
QDEL_NULL(first)
last = null
fire_location = null
return ..()
/obj/item/assembly/infra/describe()
return "The assembly is [secured ? "secure" : "not secure"]. The infrared trigger is [on ? "on" : "off"]."
/obj/item/assembly/infra/examine(mob/user)
. = ..()
. += describe()
/obj/item/assembly/infra/activate()
if(!..())
return FALSE//Cooldown check
on = !on
update_icon()
return TRUE
/obj/item/assembly/infra/toggle_secure()
secured = !secured
if(secured)
START_PROCESSING(SSobj, src)
else
on = FALSE
if(first)
qdel(first)
STOP_PROCESSING(SSobj, src)
update_icon()
return secured
/obj/item/assembly/infra/New()
..()
if(!secured)
toggle_secure()
/obj/item/assembly/infra/proc/arm() // Forces the device to arm no matter its current state.
if(!secured) // Checked because arm() might be called sometime after the object is spawned.
toggle_secure()
on = 1
/obj/item/assembly/infra/update_icon()
overlays.Cut()
attached_overlays = list()
if(on)
overlays += "infrared_on"
attached_overlays += "infrared_on"
if(holder)
holder.update_icon()
/obj/item/assembly/infra/process()
var/turf/T = get_turf(src)
if(first && (!on || !fire_location || fire_location != T || emission_cycles >= emission_cap))
qdel(first)
return
if(!on)
return
if(!secured)
return
if(first && last)
last.process()
emission_cycles++
return
if(T)
fire_location = T
emission_cycles = 0
var/obj/effect/beam/i_beam/I = new /obj/effect/beam/i_beam(T)
I.master = src
I.density = 1
I.dir = dir
I.update_icon()
first = I
step(I, I.dir)
if(first)
I.density = FALSE
I.vis_spread(visible)
I.limit = 8
I.process()
/obj/item/assembly/infra/attack_hand()
qdel(first)
..()
/obj/item/assembly/infra/Move()
var/t = dir
. = ..()
dir = t
qdel(first)
/obj/item/assembly/infra/holder_movement()
if(!holder)
return FALSE
qdel(first)
return TRUE
/obj/item/assembly/infra/equipped(var/mob/user, var/slot)
qdel(first)
return ..()
/obj/item/assembly/infra/pickup(mob/user)
qdel(first)
return ..()
/obj/item/assembly/infra/proc/trigger_beam()
if(!secured || !on || cooldown > 0)
return FALSE
pulse(0)
audible_message("[bicon(src)] *beep* *beep*", null, 3)
if(first)
qdel(first)
cooldown = 2
spawn(10)
process_cooldown()
/obj/item/assembly/infra/interact(mob/user)//TODO: change this this to the wire control panel
if(!secured) return
user.set_machine(src)
var/dat = {"<TT><B>Infrared Laser</B>
<B>Status</B>: [on ? "<A href='?src=[UID()];state=0'>On</A>" : "<A href='?src=[UID()];state=1'>Off</A>"]<BR>
<B>Visibility</B>: [visible ? "<A href='?src=[UID()];visible=0'>Visible</A>" : "<A href='?src=[UID()];visible=1'>Invisible</A>"]<BR>
<B>Current Direction</B>: <A href='?src=[UID()];rotate=1'>[capitalize(dir2text(dir))]</A><BR>
</TT>
<BR><BR><A href='?src=[UID()];refresh=1'>Refresh</A>
<BR><BR><A href='?src=[UID()];close=1'>Close</A>"}
var/datum/browser/popup = new(user, "infra", name, 400, 400)
popup.set_content(dat)
popup.open(0)
onclose(user, "infra")
/obj/item/assembly/infra/Topic(href, href_list)
..()
if(!usr.canmove || usr.stat || usr.restrained() || !in_range(loc, usr))
usr << browse(null, "window=infra")
onclose(usr, "infra")
return
if(href_list["state"])
on = !(on)
update_icon()
if(href_list["visible"])
visible = !(visible)
if(first)
first.vis_spread(visible)
if(href_list["rotate"])
rotate()
if(href_list["close"])
usr << browse(null, "window=infra")
return
if(usr)
attack_self(usr)
/obj/item/assembly/infra/verb/rotate()//This could likely be better
set name = "Rotate Infrared Laser"
set category = "Object"
set src in usr
if(usr.stat || !usr.canmove || usr.restrained())
return
dir = turn(dir, 90)
if(usr.machine == src)
interact(usr)
if(first)
qdel(first)
/obj/item/assembly/infra/armed/New()
..()
spawn(3)
if(holder)
if(holder.master)
dir = holder.master.dir
arm()
/obj/item/assembly/infra/armed/stealth
visible = FALSE
/***************************IBeam*********************************/
/obj/effect/beam/i_beam
name = "i beam"
icon = 'icons/obj/projectiles.dmi'
icon_state = "ibeam"
var/obj/effect/beam/i_beam/next = null
var/obj/effect/beam/i_beam/previous = null
var/obj/item/assembly/infra/master = null
var/limit = null
var/visible = FALSE
var/left = null
var/life_cycles = 0
var/life_cap = 20
anchored = TRUE
pass_flags = PASSTABLE | PASSGLASS | PASSGRILLE
/obj/effect/beam/i_beam/proc/hit()
if(master)
master.trigger_beam()
qdel(src)
/obj/effect/beam/i_beam/proc/vis_spread(v)
visible = v
if(next)
next.vis_spread(v)
/obj/effect/beam/i_beam/update_icon()
transform = turn(matrix(), dir2angle(dir))
/obj/effect/beam/i_beam/process()
life_cycles++
if(loc.density || !master || life_cycles >= life_cap)
qdel(src)
return
if(left > 0)
left--
if(left < 1)
if(!(visible))
invisibility = 101
else
invisibility = FALSE
else
invisibility = FALSE
if(!next && (limit > 0))
var/obj/effect/beam/i_beam/I = new /obj/effect/beam/i_beam(loc)
I.master = master
I.density = 1
I.dir = dir
I.update_icon()
I.previous = src
next = I
step(I, I.dir)
if(next)
I.density = FALSE
I.vis_spread(visible)
I.limit = limit - 1
master.last = I
I.process()
/obj/effect/beam/i_beam/Bump()
qdel(src)
/obj/effect/beam/i_beam/Bumped()
hit()
/obj/effect/beam/i_beam/Crossed(atom/movable/AM, oldloc)
if(!isobj(AM) && !isliving(AM))
return
if(istype(AM, /obj/effect))
return
hit()
/obj/effect/beam/i_beam/Destroy()
if(master.first == src)
master.first = null
QDEL_NULL(next)
if(previous)
previous.next = null
master.last = previous
return ..()
/obj/item/assembly/infra
name = "infrared emitter"
desc = "Emits a visible or invisible beam and is triggered when the beam is interrupted."
icon_state = "infrared"
materials = list(MAT_METAL=1000, MAT_GLASS=500)
origin_tech = "magnets=2;materials=2"
bomb_name = "tripwire mine"
secured = FALSE // toggle_secure()'ed in New() for correct adding to processing_objects, won't work otherwise
dir = EAST
var/on = FALSE
var/visible = TRUE
var/obj/effect/beam/i_beam/first = null
var/obj/effect/beam/i_beam/last = null
var/max_nesting_level = 10
var/turf/fire_location
var/emission_cycles = 0
var/emission_cap = 20
/obj/item/assembly/infra/Destroy()
if(first)
QDEL_NULL(first)
last = null
fire_location = null
return ..()
/obj/item/assembly/infra/describe()
return "The assembly is [secured ? "secure" : "not secure"]. The infrared trigger is [on ? "on" : "off"]."
/obj/item/assembly/infra/examine(mob/user)
. = ..()
. += describe()
/obj/item/assembly/infra/activate()
if(!..())
return FALSE//Cooldown check
on = !on
update_icon()
return TRUE
/obj/item/assembly/infra/toggle_secure()
secured = !secured
if(secured)
START_PROCESSING(SSobj, src)
else
on = FALSE
if(first)
qdel(first)
STOP_PROCESSING(SSobj, src)
update_icon()
return secured
/obj/item/assembly/infra/New()
..()
if(!secured)
toggle_secure()
/obj/item/assembly/infra/proc/arm() // Forces the device to arm no matter its current state.
if(!secured) // Checked because arm() might be called sometime after the object is spawned.
toggle_secure()
on = 1
/obj/item/assembly/infra/update_icon()
overlays.Cut()
attached_overlays = list()
if(on)
overlays += "infrared_on"
attached_overlays += "infrared_on"
if(holder)
holder.update_icon()
/obj/item/assembly/infra/process()
var/turf/T = get_turf(src)
if(first && (!on || !fire_location || fire_location != T || emission_cycles >= emission_cap))
qdel(first)
return
if(!on)
return
if(!secured)
return
if(first && last)
last.process()
emission_cycles++
return
if(T)
fire_location = T
emission_cycles = 0
var/obj/effect/beam/i_beam/I = new /obj/effect/beam/i_beam(T)
I.master = src
I.density = 1
I.dir = dir
I.update_icon()
first = I
step(I, I.dir)
if(first)
I.density = FALSE
I.vis_spread(visible)
I.limit = 8
I.process()
/obj/item/assembly/infra/attack_hand()
qdel(first)
..()
/obj/item/assembly/infra/Move()
var/t = dir
. = ..()
dir = t
qdel(first)
/obj/item/assembly/infra/holder_movement()
if(!holder)
return FALSE
qdel(first)
return TRUE
/obj/item/assembly/infra/equipped(var/mob/user, var/slot)
qdel(first)
return ..()
/obj/item/assembly/infra/pickup(mob/user)
qdel(first)
return ..()
/obj/item/assembly/infra/proc/trigger_beam()
if(!secured || !on || cooldown > 0)
return FALSE
pulse(0)
audible_message("[bicon(src)] *beep* *beep*", null, 3)
if(first)
qdel(first)
cooldown = 2
spawn(10)
process_cooldown()
/obj/item/assembly/infra/interact(mob/user)//TODO: change this this to the wire control panel
if(!secured) return
user.set_machine(src)
var/dat = {"<TT><B>Infrared Laser</B>
<B>Status</B>: [on ? "<A href='?src=[UID()];state=0'>On</A>" : "<A href='?src=[UID()];state=1'>Off</A>"]<BR>
<B>Visibility</B>: [visible ? "<A href='?src=[UID()];visible=0'>Visible</A>" : "<A href='?src=[UID()];visible=1'>Invisible</A>"]<BR>
<B>Current Direction</B>: <A href='?src=[UID()];rotate=1'>[capitalize(dir2text(dir))]</A><BR>
</TT>
<BR><BR><A href='?src=[UID()];refresh=1'>Refresh</A>
<BR><BR><A href='?src=[UID()];close=1'>Close</A>"}
var/datum/browser/popup = new(user, "infra", name, 400, 400)
popup.set_content(dat)
popup.open(0)
onclose(user, "infra")
/obj/item/assembly/infra/Topic(href, href_list)
..()
if(!usr.canmove || usr.stat || usr.restrained() || !in_range(loc, usr))
usr << browse(null, "window=infra")
onclose(usr, "infra")
return
if(href_list["state"])
on = !(on)
update_icon()
if(href_list["visible"])
visible = !(visible)
if(first)
first.vis_spread(visible)
if(href_list["rotate"])
rotate()
if(href_list["close"])
usr << browse(null, "window=infra")
return
if(usr)
attack_self(usr)
/obj/item/assembly/infra/verb/rotate()//This could likely be better
set name = "Rotate Infrared Laser"
set category = "Object"
set src in usr
if(usr.stat || !usr.canmove || usr.restrained())
return
dir = turn(dir, 90)
if(usr.machine == src)
interact(usr)
if(first)
qdel(first)
/obj/item/assembly/infra/armed/New()
..()
spawn(3)
if(holder)
if(holder.master)
dir = holder.master.dir
arm()
/obj/item/assembly/infra/armed/stealth
visible = FALSE
/***************************IBeam*********************************/
/obj/effect/beam/i_beam
name = "i beam"
icon = 'icons/obj/projectiles.dmi'
icon_state = "ibeam"
var/obj/effect/beam/i_beam/next = null
var/obj/effect/beam/i_beam/previous = null
var/obj/item/assembly/infra/master = null
var/limit = null
var/visible = FALSE
var/left = null
var/life_cycles = 0
var/life_cap = 20
anchored = TRUE
pass_flags = PASSTABLE | PASSGLASS | PASSGRILLE
/obj/effect/beam/i_beam/proc/hit()
if(master)
master.trigger_beam()
qdel(src)
/obj/effect/beam/i_beam/proc/vis_spread(v)
visible = v
if(next)
next.vis_spread(v)
/obj/effect/beam/i_beam/update_icon()
transform = turn(matrix(), dir2angle(dir))
/obj/effect/beam/i_beam/process()
life_cycles++
if(loc.density || !master || life_cycles >= life_cap)
qdel(src)
return
if(left > 0)
left--
if(left < 1)
if(!(visible))
invisibility = 101
else
invisibility = FALSE
else
invisibility = FALSE
if(!next && (limit > 0))
var/obj/effect/beam/i_beam/I = new /obj/effect/beam/i_beam(loc)
I.master = master
I.density = 1
I.dir = dir
I.update_icon()
I.previous = src
next = I
step(I, I.dir)
if(next)
I.density = FALSE
I.vis_spread(visible)
I.limit = limit - 1
master.last = I
I.process()
/obj/effect/beam/i_beam/Bump()
qdel(src)
/obj/effect/beam/i_beam/Bumped()
hit()
/obj/effect/beam/i_beam/Crossed(atom/movable/AM, oldloc)
if(!isobj(AM) && !isliving(AM))
return
if(istype(AM, /obj/effect))
return
hit()
/obj/effect/beam/i_beam/Destroy()
if(master.first == src)
master.first = null
QDEL_NULL(next)
if(previous)
previous.next = null
master.last = previous
return ..()
+144 -144
View File
@@ -1,144 +1,144 @@
/obj/item/assembly/mousetrap
name = "mousetrap"
desc = "A handy little spring-loaded trap for catching pesty rodents."
icon_state = "mousetrap"
materials = list(MAT_METAL=100)
origin_tech = "combat=1;materials=2;engineering=1"
var/armed = FALSE
bomb_name = "contact mine"
/obj/item/assembly/mousetrap/examine(mob/user)
. = ..()
if(armed)
. += "It looks like it's armed."
/obj/item/assembly/mousetrap/activate()
if(..())
armed = !armed
if(!armed)
if(ishuman(usr))
var/mob/living/carbon/human/user = usr
if((user.getBrainLoss() >= 60 || (CLUMSY in user.mutations)) && prob(50))
to_chat(user, "Your hand slips, setting off the trigger.")
pulse(0)
update_icon()
if(usr)
playsound(usr.loc, 'sound/weapons/handcuffs.ogg', 30, 1, -3)
/obj/item/assembly/mousetrap/describe()
return "The pressure switch is [armed ? "primed" : "safe"]."
/obj/item/assembly/mousetrap/update_icon()
if(armed)
icon_state = "mousetraparmed"
else
icon_state = "mousetrap"
if(holder)
holder.update_icon()
/obj/item/assembly/mousetrap/proc/triggered(mob/target, type = "feet")
if(!armed)
return
var/obj/item/organ/external/affecting = null
if(ishuman(target))
var/mob/living/carbon/human/H = target
if(PIERCEIMMUNE in H.dna.species.species_traits)
playsound(src, 'sound/effects/snap.ogg', 50, TRUE)
armed = FALSE
update_icon()
pulse(FALSE)
return FALSE
switch(type)
if("feet")
if(!H.shoes)
affecting = H.get_organ(pick("l_leg", "r_leg"))
H.Weaken(3)
if("l_hand", "r_hand")
if(!H.gloves)
affecting = H.get_organ(type)
H.Stun(3)
if(affecting)
affecting.receive_damage(1, 0)
else if(ismouse(target))
var/mob/living/simple_animal/mouse/M = target
visible_message("<span class='danger'>SPLAT!</span>")
M.splat()
playsound(loc, 'sound/effects/snap.ogg', 50, 1)
layer = MOB_LAYER - 0.2
armed = FALSE
update_icon()
pulse(0)
/obj/item/assembly/mousetrap/attack_self(mob/living/user)
if(!armed)
to_chat(user, "<span class='notice'>You arm [src].</span>")
else
if((user.getBrainLoss() >= 60 || (CLUMSY in user.mutations)) && prob(50))
var/which_hand = "l_hand"
if(!user.hand)
which_hand = "r_hand"
triggered(user, which_hand)
user.visible_message("<span class='warning'>[user] accidentally sets off [src], breaking [user.p_their()] fingers.</span>", \
"<span class='warning'>You accidentally trigger [src]!</span>")
return
to_chat(user, "<span class='notice'>You disarm [src].</span>")
armed = !armed
update_icon()
playsound(user.loc, 'sound/weapons/handcuffs.ogg', 30, 1, -3)
/obj/item/assembly/mousetrap/attack_hand(mob/living/user)
if(armed)
if((user.getBrainLoss() >= 60 || CLUMSY in user.mutations) && prob(50))
var/which_hand = "l_hand"
if(!user.hand)
which_hand = "r_hand"
triggered(user, which_hand)
user.visible_message("<span class='warning'>[user] accidentally sets off [src], breaking [user.p_their()] fingers.</span>", \
"<span class='warning'>You accidentally trigger [src]!</span>")
return
..()
/obj/item/assembly/mousetrap/Crossed(atom/movable/AM, oldloc)
if(armed)
if(ishuman(AM))
var/mob/living/carbon/H = AM
if(H.m_intent == MOVE_INTENT_RUN)
triggered(H)
H.visible_message("<span class='warning'>[H] accidentally steps on [src].</span>", \
"<span class='warning'>You accidentally step on [src]</span>")
else if(ismouse(AM))
triggered(AM)
else if(AM.density) // For mousetrap grenades, set off by anything heavy
triggered(AM)
..()
/obj/item/assembly/mousetrap/on_found(mob/finder)
if(armed)
finder.visible_message("<span class='warning'>[finder] accidentally sets off [src], breaking [finder.p_their()] fingers.</span>", \
"<span class='warning'>You accidentally trigger [src]!</span>")
triggered(finder, finder.hand ? "l_hand" : "r_hand")
return TRUE //end the search!
return FALSE
/obj/item/assembly/mousetrap/hitby(atom/movable/AM, skipcatch, hitpush, blocked, datum/thrownthing/throwingdatum)
if(!armed)
return ..()
visible_message("<span class='warning'>[src] is triggered by [AM].</span>")
triggered(null)
/obj/item/assembly/mousetrap/armed
icon_state = "mousetraparmed"
armed = 1
/obj/item/assembly/mousetrap/verb/hide_under()
set src in oview(1)
set name = "Hide"
set category = "Object"
if(usr.stat)
return
layer = TURF_LAYER+0.2
to_chat(usr, "<span class='notice'>You hide [src].</span>")
/obj/item/assembly/mousetrap
name = "mousetrap"
desc = "A handy little spring-loaded trap for catching pesty rodents."
icon_state = "mousetrap"
materials = list(MAT_METAL=100)
origin_tech = "combat=1;materials=2;engineering=1"
var/armed = FALSE
bomb_name = "contact mine"
/obj/item/assembly/mousetrap/examine(mob/user)
. = ..()
if(armed)
. += "It looks like it's armed."
/obj/item/assembly/mousetrap/activate()
if(..())
armed = !armed
if(!armed)
if(ishuman(usr))
var/mob/living/carbon/human/user = usr
if((user.getBrainLoss() >= 60 || (CLUMSY in user.mutations)) && prob(50))
to_chat(user, "Your hand slips, setting off the trigger.")
pulse(0)
update_icon()
if(usr)
playsound(usr.loc, 'sound/weapons/handcuffs.ogg', 30, 1, -3)
/obj/item/assembly/mousetrap/describe()
return "The pressure switch is [armed ? "primed" : "safe"]."
/obj/item/assembly/mousetrap/update_icon()
if(armed)
icon_state = "mousetraparmed"
else
icon_state = "mousetrap"
if(holder)
holder.update_icon()
/obj/item/assembly/mousetrap/proc/triggered(mob/target, type = "feet")
if(!armed)
return
var/obj/item/organ/external/affecting = null
if(ishuman(target))
var/mob/living/carbon/human/H = target
if(PIERCEIMMUNE in H.dna.species.species_traits)
playsound(src, 'sound/effects/snap.ogg', 50, TRUE)
armed = FALSE
update_icon()
pulse(FALSE)
return FALSE
switch(type)
if("feet")
if(!H.shoes)
affecting = H.get_organ(pick("l_leg", "r_leg"))
H.Weaken(3)
if("l_hand", "r_hand")
if(!H.gloves)
affecting = H.get_organ(type)
H.Stun(3)
if(affecting)
affecting.receive_damage(1, 0)
else if(ismouse(target))
var/mob/living/simple_animal/mouse/M = target
visible_message("<span class='danger'>SPLAT!</span>")
M.splat()
playsound(loc, 'sound/effects/snap.ogg', 50, 1)
layer = MOB_LAYER - 0.2
armed = FALSE
update_icon()
pulse(0)
/obj/item/assembly/mousetrap/attack_self(mob/living/user)
if(!armed)
to_chat(user, "<span class='notice'>You arm [src].</span>")
else
if((user.getBrainLoss() >= 60 || (CLUMSY in user.mutations)) && prob(50))
var/which_hand = "l_hand"
if(!user.hand)
which_hand = "r_hand"
triggered(user, which_hand)
user.visible_message("<span class='warning'>[user] accidentally sets off [src], breaking [user.p_their()] fingers.</span>", \
"<span class='warning'>You accidentally trigger [src]!</span>")
return
to_chat(user, "<span class='notice'>You disarm [src].</span>")
armed = !armed
update_icon()
playsound(user.loc, 'sound/weapons/handcuffs.ogg', 30, 1, -3)
/obj/item/assembly/mousetrap/attack_hand(mob/living/user)
if(armed)
if((user.getBrainLoss() >= 60 || (CLUMSY in user.mutations)) && prob(50))
var/which_hand = "l_hand"
if(!user.hand)
which_hand = "r_hand"
triggered(user, which_hand)
user.visible_message("<span class='warning'>[user] accidentally sets off [src], breaking [user.p_their()] fingers.</span>", \
"<span class='warning'>You accidentally trigger [src]!</span>")
return
..()
/obj/item/assembly/mousetrap/Crossed(atom/movable/AM, oldloc)
if(armed)
if(ishuman(AM))
var/mob/living/carbon/H = AM
if(H.m_intent == MOVE_INTENT_RUN)
triggered(H)
H.visible_message("<span class='warning'>[H] accidentally steps on [src].</span>", \
"<span class='warning'>You accidentally step on [src]</span>")
else if(ismouse(AM))
triggered(AM)
else if(AM.density) // For mousetrap grenades, set off by anything heavy
triggered(AM)
..()
/obj/item/assembly/mousetrap/on_found(mob/finder)
if(armed)
finder.visible_message("<span class='warning'>[finder] accidentally sets off [src], breaking [finder.p_their()] fingers.</span>", \
"<span class='warning'>You accidentally trigger [src]!</span>")
triggered(finder, finder.hand ? "l_hand" : "r_hand")
return TRUE //end the search!
return FALSE
/obj/item/assembly/mousetrap/hitby(atom/movable/AM, skipcatch, hitpush, blocked, datum/thrownthing/throwingdatum)
if(!armed)
return ..()
visible_message("<span class='warning'>[src] is triggered by [AM].</span>")
triggered(null)
/obj/item/assembly/mousetrap/armed
icon_state = "mousetraparmed"
armed = 1
/obj/item/assembly/mousetrap/verb/hide_under()
set src in oview(1)
set name = "Hide"
set category = "Object"
if(usr.stat)
return
layer = TURF_LAYER+0.2
to_chat(usr, "<span class='notice'>You hide [src].</span>")
+134 -134
View File
@@ -1,134 +1,134 @@
/obj/item/assembly/prox_sensor
name = "proximity sensor"
desc = "Used for scanning and alerting when someone enters a certain proximity."
icon_state = "prox"
materials = list(MAT_METAL = 800, MAT_GLASS = 200)
origin_tech = "magnets=1;engineering=1"
secured = 0
bomb_name = "proximity mine"
var/scanning = 0
var/timing = 0
var/time = 10
/obj/item/assembly/prox_sensor/describe()
if(timing)
return "<span class='notice'>The proximity sensor is arming.</span>"
return "The proximity sensor is [scanning ? "armed" : "disarmed"]."
/obj/item/assembly/prox_sensor/activate()
if(!..())
return FALSE //Cooldown check
timing = !timing
update_icon()
return FALSE
/obj/item/assembly/prox_sensor/toggle_secure()
secured = !secured
if(secured)
START_PROCESSING(SSobj, src)
else
scanning = 0
timing = 0
STOP_PROCESSING(SSobj, src)
update_icon()
return secured
/obj/item/assembly/prox_sensor/HasProximity(atom/movable/AM)
if(!isobj(AM) && !isliving(AM))
return
if(istype(AM, /obj/effect))
return
if(AM.move_speed < 12)
sense()
/obj/item/assembly/prox_sensor/proc/sense()
if(!secured || !scanning || cooldown > 0)
return FALSE
pulse(0)
visible_message("[bicon(src)] *beep* *beep*", "*beep* *beep*")
cooldown = 2
spawn(10)
process_cooldown()
/obj/item/assembly/prox_sensor/process()
if(timing && (time >= 0))
time--
if(timing && time <= 0)
timing = 0
toggle_scan()
time = 10
/obj/item/assembly/prox_sensor/dropped()
..()
spawn(0)
sense()
return
/obj/item/assembly/prox_sensor/proc/toggle_scan()
if(!secured)
return FALSE
scanning = !scanning
update_icon()
/obj/item/assembly/prox_sensor/update_icon()
overlays.Cut()
attached_overlays = list()
if(timing)
overlays += "prox_timing"
attached_overlays += "prox_timing"
if(scanning)
overlays += "prox_scanning"
attached_overlays += "prox_scanning"
if(holder)
holder.update_icon()
/obj/item/assembly/prox_sensor/Move()
..()
sense()
/obj/item/assembly/prox_sensor/holder_movement()
sense()
/obj/item/assembly/prox_sensor/interact(mob/user)//TODO: Change this to the wires thingy
if(!secured)
user.show_message("<span class='warning'>The [name] is unsecured!</span>")
return FALSE
var/second = time % 60
var/minute = (time - second) / 60
var/dat = text("<TT><B>Proximity Sensor</B>\n[] []:[]\n<A href='?src=[UID()];tp=-30'>-</A> <A href='?src=[UID()];tp=-1'>-</A> <A href='?src=[UID()];tp=1'>+</A> <A href='?src=[UID()];tp=30'>+</A>\n</TT>", (timing ? "<A href='?src=[UID()];time=0'>Arming</A>" : "<A href='?src=[UID()];time=1'>Not Arming</A>"), minute, second)
dat += "<BR><A href='?src=[UID()];scanning=1'>[scanning?"Armed":"Unarmed"]</A> (Movement sensor active when armed!)"
dat += "<BR><BR><A href='?src=[UID()];refresh=1'>Refresh</A>"
dat += "<BR><BR><A href='?src=[UID()];close=1'>Close</A>"
var/datum/browser/popup = new(user, "prox", name, 400, 400)
popup.set_content(dat)
popup.open(0)
onclose(user, "prox")
/obj/item/assembly/prox_sensor/Topic(href, href_list)
..()
if(!usr.canmove || usr.stat || usr.restrained() || !in_range(loc, usr))
usr << browse(null, "window=prox")
onclose(usr, "prox")
return
if(href_list["scanning"])
toggle_scan()
if(href_list["time"])
timing = text2num(href_list["time"])
update_icon()
if(href_list["tp"])
var/tp = text2num(href_list["tp"])
time += tp
time = min(max(round(time), 0), 600)
if(href_list["close"])
usr << browse(null, "window=prox")
return
if(usr)
attack_self(usr)
/obj/item/assembly/prox_sensor
name = "proximity sensor"
desc = "Used for scanning and alerting when someone enters a certain proximity."
icon_state = "prox"
materials = list(MAT_METAL = 800, MAT_GLASS = 200)
origin_tech = "magnets=1;engineering=1"
secured = 0
bomb_name = "proximity mine"
var/scanning = 0
var/timing = 0
var/time = 10
/obj/item/assembly/prox_sensor/describe()
if(timing)
return "<span class='notice'>The proximity sensor is arming.</span>"
return "The proximity sensor is [scanning ? "armed" : "disarmed"]."
/obj/item/assembly/prox_sensor/activate()
if(!..())
return FALSE //Cooldown check
timing = !timing
update_icon()
return FALSE
/obj/item/assembly/prox_sensor/toggle_secure()
secured = !secured
if(secured)
START_PROCESSING(SSobj, src)
else
scanning = 0
timing = 0
STOP_PROCESSING(SSobj, src)
update_icon()
return secured
/obj/item/assembly/prox_sensor/HasProximity(atom/movable/AM)
if(!isobj(AM) && !isliving(AM))
return
if(istype(AM, /obj/effect))
return
if(AM.move_speed < 12)
sense()
/obj/item/assembly/prox_sensor/proc/sense()
if(!secured || !scanning || cooldown > 0)
return FALSE
pulse(0)
visible_message("[bicon(src)] *beep* *beep*", "*beep* *beep*")
cooldown = 2
spawn(10)
process_cooldown()
/obj/item/assembly/prox_sensor/process()
if(timing && (time >= 0))
time--
if(timing && time <= 0)
timing = 0
toggle_scan()
time = 10
/obj/item/assembly/prox_sensor/dropped()
..()
spawn(0)
sense()
return
/obj/item/assembly/prox_sensor/proc/toggle_scan()
if(!secured)
return FALSE
scanning = !scanning
update_icon()
/obj/item/assembly/prox_sensor/update_icon()
overlays.Cut()
attached_overlays = list()
if(timing)
overlays += "prox_timing"
attached_overlays += "prox_timing"
if(scanning)
overlays += "prox_scanning"
attached_overlays += "prox_scanning"
if(holder)
holder.update_icon()
/obj/item/assembly/prox_sensor/Move()
..()
sense()
/obj/item/assembly/prox_sensor/holder_movement()
sense()
/obj/item/assembly/prox_sensor/interact(mob/user)//TODO: Change this to the wires thingy
if(!secured)
user.show_message("<span class='warning'>The [name] is unsecured!</span>")
return FALSE
var/second = time % 60
var/minute = (time - second) / 60
var/dat = text("<TT><B>Proximity Sensor</B>\n[] []:[]\n<A href='?src=[UID()];tp=-30'>-</A> <A href='?src=[UID()];tp=-1'>-</A> <A href='?src=[UID()];tp=1'>+</A> <A href='?src=[UID()];tp=30'>+</A>\n</TT>", (timing ? "<A href='?src=[UID()];time=0'>Arming</A>" : "<A href='?src=[UID()];time=1'>Not Arming</A>"), minute, second)
dat += "<BR><A href='?src=[UID()];scanning=1'>[scanning?"Armed":"Unarmed"]</A> (Movement sensor active when armed!)"
dat += "<BR><BR><A href='?src=[UID()];refresh=1'>Refresh</A>"
dat += "<BR><BR><A href='?src=[UID()];close=1'>Close</A>"
var/datum/browser/popup = new(user, "prox", name, 400, 400)
popup.set_content(dat)
popup.open(0)
onclose(user, "prox")
/obj/item/assembly/prox_sensor/Topic(href, href_list)
..()
if(!usr.canmove || usr.stat || usr.restrained() || !in_range(loc, usr))
usr << browse(null, "window=prox")
onclose(usr, "prox")
return
if(href_list["scanning"])
toggle_scan()
if(href_list["time"])
timing = text2num(href_list["time"])
update_icon()
if(href_list["tp"])
var/tp = text2num(href_list["tp"])
time += tp
time = min(max(round(time), 0), 600)
if(href_list["close"])
usr << browse(null, "window=prox")
return
if(usr)
attack_self(usr)
+46 -46
View File
@@ -1,46 +1,46 @@
/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/radio/electropack/part2 = null
var/status = 0
w_class = WEIGHT_CLASS_HUGE
flags = CONDUCT
/obj/item/assembly/shock_kit/Destroy()
QDEL_NULL(part1)
QDEL_NULL(part2)
return ..()
/obj/item/assembly/shock_kit/attackby(obj/item/W as obj, mob/user as mob, params)
if(istype(W, /obj/item/wrench) && !status)
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
if(istype(W, /obj/item/screwdriver))
status = !status
to_chat(user, "<span class='notice'>[src] is now [status ? "secured" : "unsecured"]!</span>")
add_fingerprint(user)
return
/obj/item/assembly/shock_kit/attack_self(mob/user as mob)
part1.attack_self(user, status)
part2.attack_self(user, status)
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
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/radio/electropack/part2 = null
var/status = 0
w_class = WEIGHT_CLASS_HUGE
flags = CONDUCT
/obj/item/assembly/shock_kit/Destroy()
QDEL_NULL(part1)
QDEL_NULL(part2)
return ..()
/obj/item/assembly/shock_kit/attackby(obj/item/W as obj, mob/user as mob, params)
if(istype(W, /obj/item/wrench) && !status)
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
if(istype(W, /obj/item/screwdriver))
status = !status
to_chat(user, "<span class='notice'>[src] is now [status ? "secured" : "unsecured"]!</span>")
add_fingerprint(user)
return
/obj/item/assembly/shock_kit/attack_self(mob/user as mob)
part1.attack_self(user, status)
part2.attack_self(user, status)
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
+177 -177
View File
@@ -1,177 +1,177 @@
/obj/item/assembly/signaler
name = "remote signaling device"
desc = "Used to remotely activate devices."
icon_state = "signaller"
item_state = "signaler"
materials = list(MAT_METAL=400, MAT_GLASS=120)
origin_tech = "magnets=1;bluespace=1"
wires = WIRE_RECEIVE | WIRE_PULSE | WIRE_RADIO_PULSE | WIRE_RADIO_RECEIVE
secured = 1
var/receiving = FALSE
bomb_name = "remote-control bomb"
var/code = 30
var/frequency = RSD_FREQ
var/delay = 0
var/datum/radio_frequency/radio_connection
var/airlock_wire = null
/obj/item/assembly/signaler/New()
..()
if(SSradio)
set_frequency(frequency)
/obj/item/assembly/signaler/Initialize()
..()
if(SSradio)
set_frequency(frequency)
/obj/item/assembly/signaler/Destroy()
if(SSradio)
SSradio.remove_object(src, frequency)
radio_connection = null
return ..()
/obj/item/assembly/signaler/describe()
return "[src]'s power light is [receiving ? "on" : "off"]"
/obj/item/assembly/signaler/activate()
if(cooldown > 0)
return FALSE
cooldown = 2
spawn(10)
process_cooldown()
signal()
return TRUE
/obj/item/assembly/signaler/update_icon()
if(holder)
holder.update_icon()
return
/obj/item/assembly/signaler/interact(mob/user, flag1)
var/t1 = "-------"
var/dat = {"
<TT>
"}
if(!flag1)
dat += {"
<A href='byond://?src=[UID()];send=1'>Send Signal</A><BR>
Receiver is <A href='byond://?src=[UID()];receive=1'>[receiving?"on":"off"]</A><BR>
"}
dat += {"
<B>Frequency/Code</B> for signaler:<BR>
Frequency:
<A href='byond://?src=[UID()];freq=-10'>-</A>
<A href='byond://?src=[UID()];freq=-2'>-</A>
[format_frequency(frequency)]
<A href='byond://?src=[UID()];freq=2'>+</A>
<A href='byond://?src=[UID()];freq=10'>+</A><BR>
Code:
<A href='byond://?src=[UID()];code=-5'>-</A>
<A href='byond://?src=[UID()];code=-1'>-</A>
[code]
<A href='byond://?src=[UID()];code=1'>+</A>
<A href='byond://?src=[UID()];code=5'>+</A><BR>
[t1]
</TT>
"}
var/datum/browser/popup = new(user, "radio", name, 400, 400)
popup.set_content(dat)
popup.open(0)
onclose(user, "radio")
/obj/item/assembly/signaler/Topic(href, href_list)
..()
if(!usr.canmove || usr.stat || usr.restrained() || !in_range(loc, usr))
usr << browse(null, "window=radio")
onclose(usr, "radio")
return
if(href_list["freq"])
var/new_frequency = (frequency + text2num(href_list["freq"]))
if(new_frequency < RADIO_LOW_FREQ || new_frequency > RADIO_HIGH_FREQ)
new_frequency = sanitize_frequency(new_frequency, RADIO_LOW_FREQ, RADIO_HIGH_FREQ)
set_frequency(new_frequency)
if(href_list["code"])
code += text2num(href_list["code"])
code = round(code)
code = min(100, code)
code = max(1, code)
if(href_list["receive"])
receiving = !receiving
if(href_list["send"])
spawn( 0 )
signal()
if(usr)
attack_self(usr)
/obj/item/assembly/signaler/proc/signal()
if(!radio_connection)
return
var/datum/signal/signal = new
signal.source = src
signal.encryption = code
signal.data["message"] = "ACTIVATE"
radio_connection.post_signal(src, signal)
var/time = time2text(world.realtime,"hh:mm:ss")
var/turf/T = get_turf(src)
if(usr)
lastsignalers.Add("[time] <B>:</B> [usr.key] used [src] @ location ([T.x],[T.y],[T.z]) <B>:</B> [format_frequency(frequency)]/[code]")
/obj/item/assembly/signaler/pulse(var/radio = FALSE)
if(connected && wires)
connected.Pulse(src)
else
return ..(radio)
/obj/item/assembly/signaler/receive_signal(datum/signal/signal)
if(!receiving || !signal)
return FALSE
if(signal.encryption != code)
return FALSE
if(!(wires & WIRE_RADIO_RECEIVE))
return FALSE
pulse(1)
for(var/mob/O in hearers(1, loc))
O.show_message("[bicon(src)] *beep* *beep*", 3, "*beep* *beep*", 2)
return TRUE
/obj/item/assembly/signaler/proc/set_frequency(new_frequency)
if(!SSradio)
sleep(20)
if(!SSradio)
return
SSradio.remove_object(src, frequency)
frequency = new_frequency
radio_connection = SSradio.add_object(src, frequency, RADIO_CHAT)
// Embedded signaller used in anomalies.
/obj/item/assembly/signaler/anomaly
name = "anomaly core"
desc = "The neutralized core of an anomaly. It'd probably be valuable for research."
icon_state = "anomaly core"
item_state = "electronic"
resistance_flags = FIRE_PROOF
receiving = TRUE
/obj/item/assembly/signaler/anomaly/receive_signal(datum/signal/signal)
if(..())
for(var/obj/effect/anomaly/A in orange(0, src))
A.anomalyNeutralize()
/obj/item/assembly/signaler/anomaly/attack_self()
return
/obj/item/assembly/signaler
name = "remote signaling device"
desc = "Used to remotely activate devices."
icon_state = "signaller"
item_state = "signaler"
materials = list(MAT_METAL=400, MAT_GLASS=120)
origin_tech = "magnets=1;bluespace=1"
wires = WIRE_RECEIVE | WIRE_PULSE | WIRE_RADIO_PULSE | WIRE_RADIO_RECEIVE
secured = 1
var/receiving = FALSE
bomb_name = "remote-control bomb"
var/code = 30
var/frequency = RSD_FREQ
var/delay = 0
var/datum/radio_frequency/radio_connection
var/airlock_wire = null
/obj/item/assembly/signaler/New()
..()
if(SSradio)
set_frequency(frequency)
/obj/item/assembly/signaler/Initialize()
..()
if(SSradio)
set_frequency(frequency)
/obj/item/assembly/signaler/Destroy()
if(SSradio)
SSradio.remove_object(src, frequency)
radio_connection = null
return ..()
/obj/item/assembly/signaler/describe()
return "[src]'s power light is [receiving ? "on" : "off"]"
/obj/item/assembly/signaler/activate()
if(cooldown > 0)
return FALSE
cooldown = 2
spawn(10)
process_cooldown()
signal()
return TRUE
/obj/item/assembly/signaler/update_icon()
if(holder)
holder.update_icon()
return
/obj/item/assembly/signaler/interact(mob/user, flag1)
var/t1 = "-------"
var/dat = {"
<TT>
"}
if(!flag1)
dat += {"
<A href='byond://?src=[UID()];send=1'>Send Signal</A><BR>
Receiver is <A href='byond://?src=[UID()];receive=1'>[receiving?"on":"off"]</A><BR>
"}
dat += {"
<B>Frequency/Code</B> for signaler:<BR>
Frequency:
<A href='byond://?src=[UID()];freq=-10'>-</A>
<A href='byond://?src=[UID()];freq=-2'>-</A>
[format_frequency(frequency)]
<A href='byond://?src=[UID()];freq=2'>+</A>
<A href='byond://?src=[UID()];freq=10'>+</A><BR>
Code:
<A href='byond://?src=[UID()];code=-5'>-</A>
<A href='byond://?src=[UID()];code=-1'>-</A>
[code]
<A href='byond://?src=[UID()];code=1'>+</A>
<A href='byond://?src=[UID()];code=5'>+</A><BR>
[t1]
</TT>
"}
var/datum/browser/popup = new(user, "radio", name, 400, 400)
popup.set_content(dat)
popup.open(0)
onclose(user, "radio")
/obj/item/assembly/signaler/Topic(href, href_list)
..()
if(!usr.canmove || usr.stat || usr.restrained() || !in_range(loc, usr))
usr << browse(null, "window=radio")
onclose(usr, "radio")
return
if(href_list["freq"])
var/new_frequency = (frequency + text2num(href_list["freq"]))
if(new_frequency < RADIO_LOW_FREQ || new_frequency > RADIO_HIGH_FREQ)
new_frequency = sanitize_frequency(new_frequency, RADIO_LOW_FREQ, RADIO_HIGH_FREQ)
set_frequency(new_frequency)
if(href_list["code"])
code += text2num(href_list["code"])
code = round(code)
code = min(100, code)
code = max(1, code)
if(href_list["receive"])
receiving = !receiving
if(href_list["send"])
spawn( 0 )
signal()
if(usr)
attack_self(usr)
/obj/item/assembly/signaler/proc/signal()
if(!radio_connection)
return
var/datum/signal/signal = new
signal.source = src
signal.encryption = code
signal.data["message"] = "ACTIVATE"
radio_connection.post_signal(src, signal)
var/time = time2text(world.realtime,"hh:mm:ss")
var/turf/T = get_turf(src)
if(usr)
GLOB.lastsignalers.Add("[time] <B>:</B> [usr.key] used [src] @ location ([T.x],[T.y],[T.z]) <B>:</B> [format_frequency(frequency)]/[code]")
/obj/item/assembly/signaler/pulse(var/radio = FALSE)
if(connected && wires)
connected.Pulse(src)
else
return ..(radio)
/obj/item/assembly/signaler/receive_signal(datum/signal/signal)
if(!receiving || !signal)
return FALSE
if(signal.encryption != code)
return FALSE
if(!(wires & WIRE_RADIO_RECEIVE))
return FALSE
pulse(1)
for(var/mob/O in hearers(1, loc))
O.show_message("[bicon(src)] *beep* *beep*", 3, "*beep* *beep*", 2)
return TRUE
/obj/item/assembly/signaler/proc/set_frequency(new_frequency)
if(!SSradio)
sleep(20)
if(!SSradio)
return
SSradio.remove_object(src, frequency)
frequency = new_frequency
radio_connection = SSradio.add_object(src, frequency, RADIO_CHAT)
// Embedded signaller used in anomalies.
/obj/item/assembly/signaler/anomaly
name = "anomaly core"
desc = "The neutralized core of an anomaly. It'd probably be valuable for research."
icon_state = "anomaly core"
item_state = "electronic"
resistance_flags = FIRE_PROOF
receiving = TRUE
/obj/item/assembly/signaler/anomaly/receive_signal(datum/signal/signal)
if(..())
for(var/obj/effect/anomaly/A in orange(0, src))
A.anomalyNeutralize()
/obj/item/assembly/signaler/anomaly/attack_self()
return
+127 -127
View File
@@ -1,127 +1,127 @@
/obj/item/assembly/timer
name = "timer"
desc = "Used to time things. Works well with contraptions which has to count down. Tick tock."
icon_state = "timer"
materials = list(MAT_METAL=500, MAT_GLASS=50)
origin_tech = "magnets=1;engineering=1"
secured = FALSE
bomb_name = "time bomb"
var/timing = FALSE
var/time = 10
var/repeat = FALSE
var/set_time = 10
/obj/item/assembly/timer/describe()
if(timing)
return "The timer is counting down from [time]!"
return "The timer is set for [time] seconds."
/obj/item/assembly/timer/activate()
if(!..())
return FALSE//Cooldown check
timing = !timing
update_icon()
return FALSE
/obj/item/assembly/timer/toggle_secure()
secured = !secured
if(secured)
START_PROCESSING(SSobj, src)
else
timing = FALSE
STOP_PROCESSING(SSobj, src)
update_icon()
return secured
/obj/item/assembly/timer/proc/timer_end()
if(!secured || cooldown > 0)
return FALSE
pulse(0)
if(loc)
loc.visible_message("[bicon(src)] *beep* *beep*", "*beep* *beep*")
cooldown = 2
spawn(10)
process_cooldown()
/obj/item/assembly/timer/process()
if(timing && (time > 0))
time -= 2 // 2 seconds per process()
if(timing && time <= 0)
timing = repeat
timer_end()
time = set_time
/obj/item/assembly/timer/update_icon()
overlays.Cut()
attached_overlays = list()
if(timing)
overlays += "timer_timing"
attached_overlays += "timer_timing"
if(holder)
holder.update_icon()
/obj/item/assembly/timer/interact(mob/user as mob)//TODO: Have this use the wires
if(!secured)
user.show_message("<span class='warning'>The [name] is unsecured!</span>")
return FALSE
var/second = time % 60
var/minute = (time - second) / 60
var/set_second = set_time % 60
var/set_minute = (set_time - set_second) / 60
if(second < 10) second = "0[second]"
if(set_second < 10) set_second = "0[set_second]"
var/dat = {"
<TT>
<center><h2>Timing Unit</h2>
[minute]:[second] <a href='?src=[UID()];time=1'>[timing?"Stop":"Start"]</a> <a href='?src=[UID()];reset=1'>Reset</a><br>
Repeat: <a href='?src=[UID()];repeat=1'>[repeat?"On":"Off"]</a><br>
Timer set for
<A href='?src=[UID()];tp=-30'>-</A> <A href='?src=[UID()];tp=-1'>-</A> [set_minute]:[set_second] <A href='?src=[UID()];tp=1'>+</A> <A href='?src=[UID()];tp=30'>+</A>
</center>
</TT>
<BR><BR>
<A href='?src=[UID()];refresh=1'>Refresh</A>
<BR><BR>
<A href='?src=[UID()];close=1'>Close</A>"}
var/datum/browser/popup = new(user, "timer", name, 400, 400)
popup.set_content(dat)
popup.open(0)
onclose(user, "timer")
/obj/item/assembly/timer/Topic(href, href_list)
..()
if(usr.incapacitated() || !in_range(loc, usr))
usr << browse(null, "window=timer")
onclose(usr, "timer")
return
if(href_list["time"])
timing = !timing
if(timing && istype(holder, /obj/item/transfer_valve))
message_admins("[key_name_admin(usr)] activated [src] attachment on [holder].")
investigate_log("[key_name(usr)] activated [src] attachment for [loc]", INVESTIGATE_BOMB)
log_game("[key_name(usr)] activated [src] attachment for [loc]")
update_icon()
if(href_list["reset"])
time = set_time
if(href_list["repeat"])
repeat = !repeat
if(href_list["tp"])
var/tp = text2num(href_list["tp"])
set_time += tp
set_time = min(max(round(set_time), 6), 600)
if(!timing)
time = set_time
if(href_list["close"])
usr << browse(null, "window=timer")
return
if(usr)
attack_self(usr)
/obj/item/assembly/timer
name = "timer"
desc = "Used to time things. Works well with contraptions which has to count down. Tick tock."
icon_state = "timer"
materials = list(MAT_METAL=500, MAT_GLASS=50)
origin_tech = "magnets=1;engineering=1"
secured = FALSE
bomb_name = "time bomb"
var/timing = FALSE
var/time = 10
var/repeat = FALSE
var/set_time = 10
/obj/item/assembly/timer/describe()
if(timing)
return "The timer is counting down from [time]!"
return "The timer is set for [time] seconds."
/obj/item/assembly/timer/activate()
if(!..())
return FALSE//Cooldown check
timing = !timing
update_icon()
return FALSE
/obj/item/assembly/timer/toggle_secure()
secured = !secured
if(secured)
START_PROCESSING(SSobj, src)
else
timing = FALSE
STOP_PROCESSING(SSobj, src)
update_icon()
return secured
/obj/item/assembly/timer/proc/timer_end()
if(!secured || cooldown > 0)
return FALSE
pulse(0)
if(loc)
loc.visible_message("[bicon(src)] *beep* *beep*", "*beep* *beep*")
cooldown = 2
spawn(10)
process_cooldown()
/obj/item/assembly/timer/process()
if(timing && (time > 0))
time -= 2 // 2 seconds per process()
if(timing && time <= 0)
timing = repeat
timer_end()
time = set_time
/obj/item/assembly/timer/update_icon()
overlays.Cut()
attached_overlays = list()
if(timing)
overlays += "timer_timing"
attached_overlays += "timer_timing"
if(holder)
holder.update_icon()
/obj/item/assembly/timer/interact(mob/user as mob)//TODO: Have this use the wires
if(!secured)
user.show_message("<span class='warning'>The [name] is unsecured!</span>")
return FALSE
var/second = time % 60
var/minute = (time - second) / 60
var/set_second = set_time % 60
var/set_minute = (set_time - set_second) / 60
if(second < 10) second = "0[second]"
if(set_second < 10) set_second = "0[set_second]"
var/dat = {"
<TT>
<center><h2>Timing Unit</h2>
[minute]:[second] <a href='?src=[UID()];time=1'>[timing?"Stop":"Start"]</a> <a href='?src=[UID()];reset=1'>Reset</a><br>
Repeat: <a href='?src=[UID()];repeat=1'>[repeat?"On":"Off"]</a><br>
Timer set for
<A href='?src=[UID()];tp=-30'>-</A> <A href='?src=[UID()];tp=-1'>-</A> [set_minute]:[set_second] <A href='?src=[UID()];tp=1'>+</A> <A href='?src=[UID()];tp=30'>+</A>
</center>
</TT>
<BR><BR>
<A href='?src=[UID()];refresh=1'>Refresh</A>
<BR><BR>
<A href='?src=[UID()];close=1'>Close</A>"}
var/datum/browser/popup = new(user, "timer", name, 400, 400)
popup.set_content(dat)
popup.open(0)
onclose(user, "timer")
/obj/item/assembly/timer/Topic(href, href_list)
..()
if(usr.incapacitated() || !in_range(loc, usr))
usr << browse(null, "window=timer")
onclose(usr, "timer")
return
if(href_list["time"])
timing = !timing
if(timing && istype(holder, /obj/item/transfer_valve))
message_admins("[key_name_admin(usr)] activated [src] attachment on [holder].")
investigate_log("[key_name(usr)] activated [src] attachment for [loc]", INVESTIGATE_BOMB)
log_game("[key_name(usr)] activated [src] attachment for [loc]")
update_icon()
if(href_list["reset"])
time = set_time
if(href_list["repeat"])
repeat = !repeat
if(href_list["tp"])
var/tp = text2num(href_list["tp"])
set_time += tp
set_time = min(max(round(set_time), 6), 600)
if(!timing)
time = set_time
if(href_list["close"])
usr << browse(null, "window=timer")
return
if(usr)
attack_self(usr)
+1 -1
View File
@@ -74,4 +74,4 @@
/obj/item/assembly/voice/noise/hear_message(mob/living/M as mob, msg)
pulse(0)
var/turf/T = get_turf(src) //otherwise it won't work in hand
T.visible_message("<span class='warning'>[bicon(src)] beeps!</span>")
T.visible_message("<span class='warning'>[bicon(src)] beeps!</span>")
+2 -2
View File
@@ -54,7 +54,7 @@
/obj/machinery/computer/general_air_control/atmos_automation/proc/selectValidChildFor(datum/automation/parent, mob/user, list/valid_returntypes)
var/list/choices=list()
for(var/childtype in automation_types)
for(var/childtype in GLOB.automation_types)
var/datum/automation/A = new childtype(src)
if(A.returntype == null)
continue
@@ -217,7 +217,7 @@
testing("AAC: Null cData in root JS array.")
continue
var/Atype=text2path(cData["type"])
if(!(Atype in automation_types))
if(!(Atype in GLOB.automation_types))
testing("AAC: Unrecognized Atype [Atype].")
continue
var/datum/automation/A = new Atype(src)
@@ -41,4 +41,4 @@
return
valve = input("Select a valve:", "Sensor Data", valve) as null|anything in valves
parent.updateUsrDialog()
return 1
return 1
@@ -39,4 +39,4 @@
return
emitter = input("Select an emitter:", "Emitter", emitter) as null|anything in emitters
parent.updateUsrDialog()
return 1
return 1
@@ -80,4 +80,4 @@
injector_names|=I.id_tag
injector = input("Select an injector:", "Sensor Data", injector) as null|anything in injector_names
parent.updateUsrDialog()
return 1
return 1
@@ -84,13 +84,13 @@
parent.updateUsrDialog()
return 1
var/global/list/gas_labels=list(
GLOBAL_LIST_INIT(gas_labels, list(
"co2" = "CO<sub>2</sub>",
"tox" = "Plasma",
"n2o" = "N<sub>2</sub>O",
"o2" = "O<sub>2</sub>",
"n2" = "N<sub>2</sub>"
)
))
/datum/automation/set_scrubber_gasses
name="Scrubber: Gasses"
@@ -131,7 +131,7 @@ var/global/list/gas_labels=list(
GetText()
var/txt = "Set Scrubber <a href=\"?src=[UID()];set_scrubber=1\">[fmtString(scrubber)]</a> to scrub "
for(var/gas in gasses)
txt += " [gas_labels[gas]] (<a href=\"?src=[UID()];tog_gas=[gas]\">[gasses[gas] ? "on" : "off"]</a>),"
txt += " [GLOB.gas_labels[gas]] (<a href=\"?src=[UID()];tog_gas=[gas]\">[gasses[gas] ? "on" : "off"]</a>),"
return txt
Topic(href,href_list)
@@ -150,4 +150,4 @@ var/global/list/gas_labels=list(
injector_names|=S.id_tag
scrubber = input("Select a scrubber:", "Scrubbers", scrubber) as null|anything in injector_names
parent.updateUsrDialog()
return 1
return 1
@@ -22,7 +22,7 @@
field = json["field"]
Evaluate()
if(sensor && field && sensor in parent.sensor_information)
if(sensor && field && (sensor in parent.sensor_information))
return parent.sensor_information[sensor][field]
return 0
@@ -53,4 +53,4 @@
sensor_list|=M.id_tag
sensor = input("Select a sensor:", "Sensor Data", field) as null|anything in sensor_list
parent.updateUsrDialog()
return 1
return 1
+4 -4
View File
@@ -1,4 +1,4 @@
var/global/automation_types = subtypesof(/datum/automation)
GLOBAL_LIST_INIT(automation_types, subtypesof(/datum/automation))
#define AUTOM_RT_NULL 0
#define AUTOM_RT_NUM 1
@@ -56,7 +56,7 @@ var/global/automation_types = subtypesof(/datum/automation)
if(isnull(cData) || !("type" in cData))
return null
var/Atype=text2path(cData["type"])
if(!(Atype in automation_types))
if(!(Atype in GLOB.automation_types))
return null
var/datum/automation/A = new Atype(parent)
A.Import(cData)
@@ -70,7 +70,7 @@ var/global/automation_types = subtypesof(/datum/automation)
. += null
continue
var/Atype=text2path(cData["type"])
if(!(Atype in automation_types))
if(!(Atype in GLOB.automation_types))
continue
var/datum/automation/A = new Atype(parent)
A.Import(cData)
@@ -454,4 +454,4 @@ var/global/automation_types = subtypesof(/datum/automation)
if(href_list["set_value"])
value = input("Set a value:", "Static Value", value) as num
parent.updateUsrDialog()
return 1
return 1

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