Revert "12/21 modernizations from TG live"

This commit is contained in:
LetterJay
2016-12-22 22:35:44 -06:00
committed by GitHub
parent cf59ac1c3d
commit ae40d4134e
2215 changed files with 86928 additions and 707332 deletions
-55
View File
@@ -1,55 +0,0 @@
/mob/living/carbon/human/virtual_reality
var/mob/living/carbon/human/real_me //The human controlling us, can be any human (including virtual ones... inception...)
var/obj/machinery/vr_sleeper/vr_sleeper
var/datum/action/quit_vr/quit_action
/mob/living/carbon/human/virtual_reality/New()
..()
quit_action = new()
quit_action.Grant(src)
/mob/living/carbon/human/virtual_reality/death()
revert_to_reality()
..()
/mob/living/carbon/human/virtual_reality/Destroy()
revert_to_reality()
return ..()
/mob/living/carbon/human/virtual_reality/ghost()
set category = "OOC"
set name = "Ghost"
set desc = "Relinquish your life and enter the land of the dead."
var/mob/living/carbon/human/H = real_me
revert_to_reality(FALSE, FALSE)
if(H)
H.ghost()
/mob/living/carbon/human/virtual_reality/proc/revert_to_reality(refcleanup = TRUE, deathchecks = TRUE)
if(real_me && mind)
mind.transfer_to(real_me)
if(deathchecks && vr_sleeper && vr_sleeper.you_die_in_the_game_you_die_for_real)
real_me.death(0)
if(refcleanup)
vr_sleeper.vr_human = null
vr_sleeper = null
real_me = null
/datum/action/quit_vr
name = "Quit Virtual Reality"
/datum/action/quit_vr/Trigger()
if(..())
if(istype(owner, /mob/living/carbon/human/virtual_reality))
var/mob/living/carbon/human/virtual_reality/VR = owner
VR.revert_to_reality(FALSE, FALSE)
else
Remove(owner)
-184
View File
@@ -1,184 +0,0 @@
//Glorified teleporter that puts you in a new human body.
// it's """VR"""
/obj/machinery/vr_sleeper
name = "virtual reality sleeper"
desc = "a sleeper modified to alter the subconscious state of the user, allowing them to visit virtual worlds"
icon = 'icons/obj/Cryogenic2.dmi'
icon_state = "sleeper"
state_open = TRUE
anchored = TRUE
var/you_die_in_the_game_you_die_for_real = FALSE
var/datum/effect_system/spark_spread/sparks
var/mob/living/carbon/human/virtual_reality/vr_human
var/static/list/available_vr_spawnpoints
var/vr_category = "default" //Specific category of spawn points to pick from
var/allow_creating_vr_humans = TRUE //So you can have vr_sleepers that always spawn you as a specific person or 1 life/chance vr games
var/outfit = /datum/outfit/vr_basic
/obj/machinery/vr_sleeper/New()
..()
sparks = new /datum/effect_system/spark_spread()
sparks.set_up(2,0)
sparks.attach(src)
update_icon()
if(!available_vr_spawnpoints || !available_vr_spawnpoints.len) //(re)build spawnpoint lists
available_vr_spawnpoints = list()
for(var/obj/effect/landmark/vr_spawn/V in landmarks_list)
available_vr_spawnpoints[V.vr_category] = list()
var/turf/T = get_turf(V)
if(T)
available_vr_spawnpoints[V.vr_category] |= T
/obj/machinery/vr_sleeper/attack_hand(mob/user)
if(occupant)
ui_interact(user)
else
if(state_open)
close_machine()
else
open_machine()
/obj/machinery/vr_sleeper/relaymove(mob/user)
open_machine()
/obj/machinery/vr_sleeper/Destroy()
open_machine()
cleanup_vr_human()
qdel(sparks)
sparks = null
return ..()
/obj/machinery/vr_sleeper/emag_act(mob/user)
you_die_in_the_game_you_die_for_real = TRUE
sparks.start()
/obj/machinery/vr_sleeper/update_icon()
icon_state = "[initial(icon_state)][state_open ? "-open" : ""]"
/obj/machinery/vr_sleeper/open_machine()
if(!state_open)
if(vr_human)
vr_human.revert_to_reality(FALSE, FALSE)
if(occupant)
SStgui.close_user_uis(occupant, src)
..()
/obj/machinery/vr_sleeper/close_machine()
..()
if(occupant)
ui_interact(occupant)
/obj/machinery/vr_sleeper/ui_interact(mob/user, ui_key = "main", datum/tgui/ui = null, force_open = 0, datum/tgui/master_ui = null, datum/ui_state/state = default_state)
ui = SStgui.try_update_ui(user, src, ui_key, ui, force_open)
if(!ui)
ui = new(user, src, ui_key, "vr_sleeper", "VR Sleeper", 475, 340, master_ui, state)
ui.open()
/obj/machinery/vr_sleeper/ui_act(action, params)
if(..())
return
switch(action)
if("vr_connect")
if(ishuman(occupant) && occupant.mind)
occupant << "<span class='warning'>Transfering to virtual reality...</span>"
if(vr_human)
vr_human.revert_to_reality(FALSE, FALSE)
occupant.mind.transfer_to(vr_human)
vr_human.real_me = occupant
vr_human << "<span class='notice'>Transfer successful! you are now playing as [vr_human] in VR!</span>"
SStgui.close_user_uis(vr_human, src)
else
if(allow_creating_vr_humans)
occupant << "<span class='warning'>Virtual avatar not found, attempting to create one...</span>"
var/turf/T = get_vr_spawnpoint()
if(T)
build_virtual_human(occupant, T)
vr_human << "<span class='notice'>Transfer successful! you are now playing as [vr_human] in VR!</span>"
else
occupant << "<span class='warning'>Virtual world misconfigured, aborting transfer</span>"
else
occupant << "<span class='warning'>The virtual world does not support the creation of new virtual avatars, aborting transfer</span>"
. = TRUE
if("delete_avatar")
if(!occupant || usr == occupant)
if(vr_human)
qdel(vr_human)
else
usr << "<span class='warning'>The VR Sleeper's safeties prevent you from doing that."
. = TRUE
if("toggle_open")
if(state_open)
close_machine()
else
open_machine()
. = TRUE
/obj/machinery/vr_sleeper/ui_data(mob/user)
var/list/data = list()
if(vr_human && !qdeleted(vr_human))
data["can_delete_avatar"] = TRUE
var/status
switch(user.stat)
if(CONSCIOUS)
status = "Conscious"
if(DEAD)
status = "Dead"
if(UNCONSCIOUS)
status = "Unconscious"
data["vr_avatar"] = list("name" = vr_human.name, "status" = status, "health" = vr_human.health, "maxhealth" = vr_human.maxHealth)
data["toggle_open"] = state_open
data["isoccupant"] = (user == occupant)
return data
/obj/machinery/vr_sleeper/proc/get_vr_spawnpoint() //proc so it can be overriden for team games or something
return safepick(available_vr_spawnpoints[vr_category])
/obj/machinery/vr_sleeper/proc/build_virtual_human(mob/living/carbon/human/H, location, transfer = TRUE)
if(H)
cleanup_vr_human()
vr_human = new /mob/living/carbon/human/virtual_reality(location)
vr_human.vr_sleeper = src
vr_human.real_me = H
H.dna.transfer_identity(vr_human)
vr_human.name = H.name
vr_human.real_name = H.real_name
vr_human.socks = H.socks
vr_human.undershirt = H.undershirt
vr_human.underwear = H.underwear
vr_human.updateappearance(1,1,1)
if(outfit)
var/datum/outfit/O = new outfit()
O.equip(vr_human)
if(transfer && H.mind)
H.mind.transfer_to(vr_human)
/obj/machinery/vr_sleeper/proc/cleanup_vr_human()
if(vr_human)
vr_human.death(0)
/obj/effect/landmark/vr_spawn //places you can spawn in VR, auto selected by the vr_sleeper during get_vr_spawnpoint()
var/vr_category = "default" //So we can have specific sleepers, eg: "Basketball VR Sleeper", etc.
/datum/outfit/vr_basic
name = "basic vr"
uniform = /obj/item/clothing/under/color/random
shoes = /obj/item/clothing/shoes/sneakers/black
+12 -3
View File
@@ -8,7 +8,6 @@
establish_db_connection()
if(!dbcon.IsConnected())
src << "<span class='danger'>Failed to establish database connection.</span>"
return
var/serverip = "[world.internet_address]:[world.port]"
@@ -37,6 +36,10 @@
if(BANTYPE_JOB_TEMP)
bantype_str = "JOB_TEMPBAN"
bantype_pass = 1
if(BANTYPE_APPEARANCE)
bantype_str = "APPEARANCE_PERMABAN"
duration = -1
bantype_pass = 1
if(BANTYPE_ADMIN_PERMA)
bantype_str = "ADMIN_PERMABAN"
duration = -1
@@ -133,8 +136,8 @@
if(kickbannedckey)
if(banned_mob && banned_mob.client && banned_mob.client.ckey == banckey)
qdel(banned_mob.client)
return 1
del(banned_mob.client)
/datum/admins/proc/DB_ban_unban(ckey, bantype, job = "")
@@ -157,6 +160,9 @@
if(BANTYPE_JOB_TEMP)
bantype_str = "JOB_TEMPBAN"
bantype_pass = 1
if(BANTYPE_APPEARANCE)
bantype_str = "APPEARANCE_PERMABAN"
bantype_pass = 1
if(BANTYPE_ADMIN_PERMA)
bantype_str = "ADMIN_PERMABAN"
bantype_pass = 1
@@ -355,6 +361,7 @@
output += "<option value='[BANTYPE_TEMP]'>TEMPBAN</option>"
output += "<option value='[BANTYPE_JOB_PERMA]'>JOB PERMABAN</option>"
output += "<option value='[BANTYPE_JOB_TEMP]'>JOB TEMPBAN</option>"
output += "<option value='[BANTYPE_APPEARANCE]'>IDENTITY BAN</option>"
output += "<option value='[BANTYPE_ADMIN_PERMA]'>ADMIN PERMABAN</option>"
output += "<option value='[BANTYPE_ADMIN_TEMP]'>ADMIN TEMPBAN</option>"
output += "</select></td>"
@@ -446,6 +453,8 @@
typedesc = "<b>JOBBAN</b><br><font size='2'>([job])"
if("JOB_TEMPBAN")
typedesc = "<b>TEMP JOBBAN</b><br><font size='2'>([job])<br>([duration] minutes [(unbanned) ? "" : "(<a href=\"byond://?src=\ref[src];dbbanedit=duration;dbbanid=[banid]\">Edit</a>))"]<br>Expires [expiration]"
if("APPEARANCE_PERMABAN")
typedesc = "<b>IDENTITY PERMABAN</b>"
if("ADMIN_PERMABAN")
typedesc = "<b>ADMIN PERMABAN</b>"
if("ADMIN_TEMPBAN")
+9 -92
View File
@@ -1,17 +1,11 @@
//Blocks an attempt to connect before even creating our client datum thing.
//How many new ckey matches before we revert the stickyban to it's roundstart state
//These are exclusive, so once it goes over one of these numbers, it reverts the ban
#define STICKYBAN_MAX_MATCHES 20
#define STICKYBAN_MAX_EXISTING_USER_MATCHES 5 //ie, users who were connected before the ban triggered
#define STICKYBAN_MAX_ADMIN_MATCHES 2
/world/IsBanned(key,address,computer_id)
if (!key || !address || !computer_id)
log_access("Failed Login (invalid data): [key] [address]-[computer_id]")
return list("reason"="invalid login data", "desc"="Error: Could not check ban status, Please try again. Error message: Your computer provided invalid or blank information to the server on connection (byond username, IP, and Computer ID.) Provided information for reference: Username:'[key]' IP:'[address]' Computer ID:'[computer_id]'. (If you continue to get this error, please restart byond or contact byond support.)")
if (text2num(computer_id) == 2147483647) //this cid causes stickybans to go haywire
if (text2num(computer_id) == 2147483647) //this cid causes stickybans to go haywire
log_access("Failed Login (invalid cid): [key] [address]-[computer_id]")
return list("reason"="invalid login data", "desc"="Error: Could not check ban status, Please try again. Error message: Your computer provided an invalid Computer ID.)")
var/admin = 0
@@ -19,17 +13,6 @@
if((ckey in admin_datums) || (ckey in deadmins))
admin = 1
//Whitelist
if(config.usewhitelist)
if(!check_whitelist(ckey(key)))
if (admin)
log_admin("The admin [key] has been allowed to bypass the whitelist")
message_admins("<span class='adminnotice'>The admin [key] has been allowed to bypass the whitelist</span>")
addclientmessage(ckey,"<span class='adminnotice'>You have been allowed to bypass the whitelist</span>")
else
log_access("Failed Login: [key] - Not on whitelist")
return list("reason"="whitelist", "desc" = "\nReason: You are not on the white list for this server")
//Guest Checking
if(IsGuestKey(key))
if (!guests_allowed)
@@ -116,83 +99,17 @@
log_access("Failed Login: [key] [computer_id] [address] - Banned [.["reason"]]")
return .
var/list/ban = ..() //default pager ban stuff
if (ban)
var/bannedckey = "ERROR"
if (ban["ckey"])
bannedckey = ban["ckey"]
var/newmatch = FALSE
var/client/C = directory[ckey]
var/cachedban = SSstickyban.cache[bannedckey]
//rogue ban in the process of being reverted.
if (cachedban && cachedban["reverting"])
return null
if (cachedban && ckey != bannedckey)
newmatch = TRUE
if (cachedban["keys"])
if (cachedban["keys"][ckey])
newmatch = FALSE
if (cachedban["matches_this_round"][ckey])
newmatch = FALSE
if (newmatch && cachedban)
var/list/newmatches = cachedban["matches_this_round"]
var/list/newmatches_connected = cachedban["existing_user_matches_this_round"]
var/list/newmatches_admin = cachedban["admin_matches_this_round"]
newmatches[ckey] = ckey
if (C)
newmatches_connected[ckey] = ckey
if (admin)
newmatches_admin[ckey] = ckey
if (\
newmatches.len > STICKYBAN_MAX_MATCHES || \
newmatches_connected.len > STICKYBAN_MAX_EXISTING_USER_MATCHES || \
newmatches_admin.len > STICKYBAN_MAX_ADMIN_MATCHES \
)
if (cachedban["reverting"])
return null
cachedban["reverting"] = TRUE
world.SetConfig("ban", bannedckey, null)
log_game("Stickyban on [bannedckey] detected as rogue, reverting to it's roundstart state")
message_admins("Stickyban on [bannedckey] detected as rogue, reverting to it's roundstart state")
//do not convert to timer.
spawn (5)
world.SetConfig("ban", bannedckey, null)
sleep(1)
world.SetConfig("ban", bannedckey, null)
cachedban["matches_this_round"] = list()
cachedban["existing_user_matches_this_round"] = list()
cachedban["admin_matches_this_round"] = list()
cachedban -= "reverting"
world.SetConfig("ban", bannedckey, list2stickyban(cachedban))
return null
. = ..() //default pager ban stuff
if (.)
//byond will not trigger isbanned() for "global" host bans,
//ie, ones where the "apply to this game only" checkbox is not checked (defaults to not checked)
//So it's safe to let admins walk thru host/sticky bans here
if (admin)
log_admin("The admin [key] has been allowed to bypass a matching host/sticky ban on [bannedckey]")
message_admins("<span class='adminnotice'>The admin [key] has been allowed to bypass a matching host/sticky ban on [bannedckey]</span>")
addclientmessage(ckey,"<span class='adminnotice'>You have been allowed to bypass a matching host/sticky ban on [bannedckey]</span>")
log_admin("The admin [key] has been allowed to bypass a matching host/sticky ban")
message_admins("<span class='adminnotice'>The admin [key] has been allowed to bypass a matching host/sticky ban</span>")
addclientmessage(ckey,"<span class='adminnotice'>You have been allowed to bypass a matching host/sticky ban</span>")
return null
if (C) //user is already connected!.
C << "You are about to get disconnected for matching a sticky ban after you connected. If this turns out to be the ban evasion detection system going haywire, we will automatically detect this and revert the matches. if you feel that this is the case, please wait EXACTLY 6 seconds then reconnect using file -> reconnect to see if the match was reversed."
var/desc = "\nReason:(StickyBan) You, or another user of this computer or connection ([bannedckey]) is banned from playing here. The ban reason is:\n[ban["message"]]\nThis ban was applied by [ban["admin"]]\nThis is a BanEvasion Detection System ban, if you think this ban is a mistake, please wait EXACTLY 6 seconds, then try again before filing an appeal.\n"
. = list("reason" = "Stickyban", "desc" = desc)
log_access("Failed Login: [key] [computer_id] [address] - StickyBanned [ban["message"]] Target Username: [bannedckey] Placed by [ban["admin"]]")
else
log_access("Failed Login: [key] [computer_id] [address] - Banned [.["message"]]")
return .
#undef STICKYBAN_MAX_MATCHES
#undef STICKYBAN_MAX_EXISTING_USER_MATCHES
#undef STICKYBAN_MAX_ADMIN_MATCHES
+2 -2
View File
@@ -117,9 +117,9 @@ var/savefile/Banlist
if (temp)
Banlist["minutes"] << bantimestamp
if(!temp)
add_note(ckey, "Permanently banned - [reason]", null, bannedby, 0, null, 0)
add_note(ckey, "Permanently banned - [reason]", null, bannedby, 0)
else
add_note(ckey, "Banned for [minutes] minutes - [reason]", null, bannedby, 0, null, 0)
add_note(ckey, "Banned for [minutes] minutes - [reason]", null, bannedby, 0)
return 1
/proc/RemoveBan(foldername)
+8 -15
View File
@@ -34,7 +34,7 @@ var/global/BSACooldown = 0
body += " played by <b>[M.client]</b> "
body += "\[<A href='?_src_=holder;editrights=rank;ckey=[M.ckey]'>[M.client.holder ? M.client.holder.rank : "Player"]</A>\]"
if(isnewplayer(M))
if(istype(M, /mob/new_player))
body += " <B>Hasn't Entered Game</B> "
else
body += " \[<A href='?_src_=holder;revive=\ref[M]'>Heal</A>\] "
@@ -91,7 +91,7 @@ var/global/BSACooldown = 0
body += "<A href='?_src_=holder;subtlemessage=\ref[M]'>Subtle message</A>"
if (M.client)
if(!isnewplayer(M))
if(!istype(M, /mob/new_player))
body += "<br><br>"
body += "<b>Transformation:</b>"
body += "<br>"
@@ -633,8 +633,7 @@ var/global/BSACooldown = 0
var/turf/T = get_turf(usr.loc)
T.ChangeTurf(chosen)
else
var/atom/A = new chosen(usr.loc)
A.admin_spawned = TRUE
new chosen(usr.loc)
log_admin("[key_name(usr)] spawned [chosen] at ([usr.x],[usr.y],[usr.z])")
feedback_add_details("admin_verb","SA") //If you are copy-pasting this, ensure the 2nd parameter is unique to the new proc!
@@ -688,7 +687,7 @@ var/global/BSACooldown = 0
ai_number++
if(isAI(S))
usr << "<b>AI [key_name(S, usr)]'s laws:</b>"
else if(iscyborg(S))
else if(isrobot(S))
var/mob/living/silicon/robot/R = S
usr << "<b>CYBORG [key_name(S, usr)] [R.connected_ai?"(Slaved to: [R.connected_ai])":"(Independant)"]: laws:</b>"
else if (ispAI(S))
@@ -703,7 +702,7 @@ var/global/BSACooldown = 0
if(!ai_number)
usr << "<b>No AIs located</b>" //Just so you know the thing is actually working and not just ignoring you.
/datum/admins/proc/output_all_devil_info()
/datum/admins/proc/output_devil_info()
var/devil_number = 0
for(var/D in ticker.mode.devils)
devil_number++
@@ -711,12 +710,6 @@ var/global/BSACooldown = 0
if(!devil_number)
usr << "<b>No Devils located</b>" //Just so you know the thing is actually working and not just ignoring you.
/datum/admins/proc/output_devil_info(mob/living/M)
if(istype(M) && M.mind && M.mind.devilinfo)
usr << ticker.mode.printdevilinfo(M.mind)
else
usr << "<b>[M] is not a devil."
/datum/admins/proc/manage_free_slots()
if(!check_rights())
return
@@ -773,13 +766,13 @@ var/global/BSACooldown = 0
/proc/kick_clients_in_lobby(message, kick_only_afk = 0)
var/list/kicked_client_names = list()
for(var/client/C in clients)
if(isnewplayer(C.mob))
if(kick_only_afk && !C.is_afk()) //Ignore clients who are not afk
if(istype(C.mob, /mob/new_player))
if(kick_only_afk && !C.is_afk()) //Ignore clients who are not afk
continue
if(message)
C << message
kicked_client_names.Add("[C.ckey]")
qdel(C)
del(C)
return kicked_client_names
//returns 1 to let the dragdrop code know we are trapping this event
+9 -7
View File
@@ -37,14 +37,16 @@
src << "<font color='red'>Error: admin_investigate: [INVESTIGATE_DIR][subject] is an invalid path or cannot be accessed.</font>"
return
src << browse(F,"window=investigate[subject];size=800x300")
if("hrefs") //persistent logs and stuff
if(href_logfile)
src << browse(href_logfile,"window=investigate[subject];size=800x300")
else if(!config.log_hrefs)
src << "<span class='danger'>Href logging is off and no logfile was found.</span>"
return
if("hrefs") //persistant logs and stuff
if(config && config.log_hrefs)
if(href_logfile)
src << browse(href_logfile,"window=investigate[subject];size=800x300")
else
src << "<font color='red'>Error: admin_investigate: No href logfile found.</font>"
return
else
src << "<span class='danger'>No href logfile was found.</span>"
src << "<font color='red'>Error: admin_investigate: Href Logging is not on.</font>"
return
if("notes")
show_note()
+1 -11
View File
@@ -23,9 +23,6 @@ var/list/admin_ranks = list() //list of all admin_rank datums
adds = init_adds
subs = init_subs
/datum/admin_rank/vv_edit_var(var_name, var_value)
return FALSE
/proc/admin_keyword_to_flag(word, previous_rights=0)
var/flag = 0
switch(ckey(word))
@@ -164,9 +161,6 @@ var/list/admin_ranks = list() //list of all admin_rank datums
C.holder = null
admins.Cut()
load_admin_ranks()
//Clear profile access
for(var/A in world.GetConfig("admin"))
world.SetConfig("APP/admin", A, null)
var/list/rank_names = list()
for(var/datum/admin_rank/R in admin_ranks)
@@ -195,8 +189,6 @@ var/list/admin_ranks = list() //list of all admin_rank datums
var/datum/admins/D = new(rank_names[rank], ckey) //create the admin datum and store it for later use
if(!D)
continue //will occur if an invalid rank is provided
if(D.rank.rights & R_DEBUG) //grant profile access
world.SetConfig("APP/admin", ckey, "role=admin")
D.associate(directory[ckey]) //find the client for a ckey if they are connected and associate them with the new admin datum
else
establish_db_connection()
@@ -222,8 +214,6 @@ var/list/admin_ranks = list() //list of all admin_rank datums
var/datum/admins/D = new(rank_names[rank], ckey) //create the admin datum and store it for later use
if(!D)
continue //will occur if an invalid rank is provided
if(D.rank.rights & R_DEBUG) //grant profile access
world.SetConfig("APP/admin", ckey, "role=admin")
D.associate(directory[ckey]) //find the client for a ckey if they are connected and associate them with the new admin datum
#ifdef TESTING
@@ -379,4 +369,4 @@ var/list/admin_ranks = list() //list of all admin_rank datums
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()
query_update.Execute()
+19 -94
View File
@@ -53,7 +53,6 @@ var/list/admin_verbs_admin = list(
/client/proc/jumptocoord, /*we ghost and jump to a coordinate*/
/client/proc/Getmob, /*teleports a mob to our location*/
/client/proc/Getkey, /*teleports a mob with a certain ckey to our location*/
// /client/proc/sendmob, /*sends a mob somewhere*/ -Removed due to it needing two sorting procs to work, which were executed every time an admin right-clicked. ~Errorage
/client/proc/jumptoarea,
/client/proc/jumptokey, /*allows us to jump to the location of a mob with a certain ckey*/
/client/proc/jumptomob, /*allows us to jump to a specific mob*/
@@ -85,9 +84,6 @@ var/list/admin_verbs_sounds = list(
var/list/admin_verbs_fun = list(
/client/proc/cmd_admin_dress,
/client/proc/cmd_admin_gib_self,
/client/proc/drop_bomb,
/client/proc/set_dynex_scale,
/client/proc/drop_dynex_bomb,
/client/proc/cinematic,
/client/proc/one_click_antag,
/client/proc/send_space_ninja,
@@ -100,12 +96,16 @@ var/list/admin_verbs_fun = list(
/client/proc/forceEvent,
/client/proc/bluespace_artillery,
/client/proc/admin_change_sec_level,
/client/proc/show_tip,
/client/proc/toggle_nuke,
/client/proc/reset_latejoin_spawns,
/client/proc/mass_zombie_infection,
/client/proc/mass_zombie_cure,
/client/proc/polymorph_all,
/client/proc/show_tip
/client/proc/everyone_random,
/client/proc/drop_bomb
)
var/list/admin_verbs_spawn = list(
/datum/admins/proc/spawn_atom, /*allows us to spawn instances*/
/client/proc/respawn_character
@@ -117,7 +117,6 @@ var/list/admin_verbs_server = list(
/datum/admins/proc/delay,
/datum/admins/proc/toggleaban,
/client/proc/toggle_log_hrefs,
/client/proc/everyone_random,
/datum/admins/proc/toggleAI,
/client/proc/cmd_admin_delete, /*delete an instance/object/mob/etc*/
/client/proc/cmd_debug_del_all,
@@ -126,8 +125,7 @@ var/list/admin_verbs_server = list(
/client/proc/forcerandomrotate,
/client/proc/adminchangemap,
#endif
/client/proc/panicbunker,
/client/proc/toggle_hub
/client/proc/panicbunker
)
var/list/admin_verbs_debug = list(
@@ -149,19 +147,12 @@ var/list/admin_verbs_debug = list(
/client/proc/check_bomb_impacts,
/proc/machine_upgrade,
/client/proc/populate_world,
/client/proc/get_dynex_power, //*debug verbs for dynex explosions.
/client/proc/get_dynex_range, //*debug verbs for dynex explosions.
/client/proc/set_dynex_scale,
/client/proc/cmd_display_del_log,
/client/proc/reset_latejoin_spawns,
/client/proc/create_outfits,
/client/proc/modify_goals,
/client/proc/debug_huds,
/client/proc/map_template_load,
/client/proc/map_template_upload,
/client/proc/jump_to_ruin,
/client/proc/clear_dynamic_transit,
/client/proc/toggle_medal_disable
/client/proc/jump_to_ruin
)
var/list/admin_verbs_possess = list(
/proc/possess,
@@ -206,10 +197,6 @@ var/list/admin_verbs_hideable = list(
/client/proc/cmd_admin_dress,
/client/proc/cmd_admin_gib_self,
/client/proc/drop_bomb,
/client/proc/drop_dynex_bomb,
/client/proc/get_dynex_range,
/client/proc/get_dynex_power,
/client/proc/set_dynex_scale,
/client/proc/cinematic,
/client/proc/send_space_ninja,
/client/proc/cmd_admin_add_freeform_ai_law,
@@ -315,7 +302,7 @@ var/list/admin_verbs_hideable = list(
/client/proc/count_objects_all,
/client/proc/cmd_assume_direct_control,
/client/proc/startSinglo,
/client/proc/set_server_fps,
/client/proc/set_fps,
/client/proc/cmd_admin_grantfullaccess,
/client/proc/cmd_admin_areatest,
/client/proc/readmin
@@ -363,7 +350,7 @@ var/list/admin_verbs_hideable = list(
set name = "Aghost"
if(!holder)
return
if(isobserver(mob))
if(istype(mob,/mob/dead/observer))
//re-enter
var/mob/dead/observer/ghost = mob
if(!ghost.mind || !ghost.mind.current) //won't do anything if there is no body
@@ -374,7 +361,7 @@ var/list/admin_verbs_hideable = list(
ghost.can_reenter_corpse = 1 //force re-entering even when otherwise not possible
ghost.reenter_corpse()
feedback_add_details("admin_verb","P") //If you are copy-pasting this, ensure the 2nd parameter is unique to the new proc!
else if(isnewplayer(mob))
else if(istype(mob,/mob/new_player))
src << "<font color='red'>Error: Aghost: Can't admin-ghost whilst in the lobby. Join or Observe first.</font>"
else
//ghostize
@@ -485,7 +472,7 @@ var/list/admin_verbs_hideable = list(
holder.fakekey = new_key
createStealthKey()
if(isobserver(mob))
mob.invisibility = INVISIBILITY_MAXIMUM //JUST IN CASE
mob.invisibility = INVISIBILITY_ABSTRACT //JUST IN CASE
mob.alpha = 0 //JUUUUST IN CASE
mob.name = " "
mob.mouse_opacity = 0
@@ -501,7 +488,6 @@ var/list/admin_verbs_hideable = list(
var/list/choices = list("Small Bomb", "Medium Bomb", "Big Bomb", "Custom Bomb")
var/choice = input("What size explosion would you like to produce?") in choices
var/turf/epicenter = mob.loc
switch(choice)
if(null)
return 0
@@ -526,53 +512,9 @@ var/list/admin_verbs_hideable = list(
return
epicenter = mob.loc //We need to reupdate as they may have moved again
explosion(epicenter, devastation_range, heavy_impact_range, light_impact_range, flash_range)
message_admins("[ADMIN_LOOKUPFLW(usr)] creating an admin explosion at [epicenter.loc].")
log_admin("[key_name(usr)] created an admin explosion at [epicenter.loc].")
message_admins("<span class='adminnotice'>[ckey] creating an admin explosion at [epicenter.loc].</span>")
feedback_add_details("admin_verb","DB") //If you are copy-pasting this, ensure the 2nd parameter is unique to the new proc!
/client/proc/drop_dynex_bomb()
set category = "Special Verbs"
set name = "Drop DynEx Bomb"
set desc = "Cause an explosion of varying strength at your location."
var/ex_power = input("Explosive Power:") as null|num
var/turf/epicenter = mob.loc
if(ex_power && epicenter)
dyn_explosion(epicenter, ex_power)
message_admins("[ADMIN_LOOKUPFLW(usr)] creating an admin explosion at [epicenter.loc].")
log_admin("[key_name(usr)] created an admin explosion at [epicenter.loc].")
feedback_add_details("admin_verb","DDXB") //If you are copy-pasting this, ensure the 2nd parameter is unique to the new proc!
/client/proc/get_dynex_range()
set category = "Debug"
set name = "Get DynEx Range"
set desc = "Get the estimated range of a bomb, using explosive power."
var/ex_power = input("Explosive Power:") as null|num
var/range = round((2 * ex_power)**DYN_EX_SCALE)
usr << "Estimated Explosive Range: (Devestation: [round(range*0.25)], Heavy: [round(range*0.5)], Light: [round(range)])"
/client/proc/get_dynex_power()
set category = "Debug"
set name = "Get DynEx Power"
set desc = "Get the estimated required power of a bomb, to reach a specific range."
var/ex_range = input("Light Explosion Range:") as null|num
var/power = (0.5 * ex_range)**(1/DYN_EX_SCALE)
usr << "Estimated Explosive Power: [power]"
/client/proc/set_dynex_scale()
set category = "Debug"
set name = "Set DynEx Scale"
set desc = "Set the scale multiplier of dynex explosions. The default is 0.5."
var/ex_scale = input("New DynEx Scale:") as null|num
if(!ex_scale)
return
DYN_EX_SCALE = ex_scale
log_admin("[key_name(usr)] has modified Dynamic Explosion Scale: [ex_scale]")
message_admins("[key_name_admin(usr)] has modified Dynamic Explosion Scale: [ex_scale]")
/client/proc/give_spell(mob/T in mob_list)
set category = "Fun"
set name = "Give Spell"
@@ -585,30 +527,16 @@ var/list/admin_verbs_hideable = list(
var/obj/effect/proc_holder/spell/S = input("Choose the spell to give to that guy", "ABRAKADABRA") as null|anything in spell_list
if(!S)
return
S = spell_list[S]
feedback_add_details("admin_verb","GS") //If you are copy-pasting this, ensure the 2nd parameter is unique to the new proc!
log_admin("[key_name(usr)] gave [key_name(T)] the spell [S].")
message_admins("<span class='adminnotice'>[key_name_admin(usr)] gave [key_name(T)] the spell [S].</span>")
S = spell_list[S]
if(T.mind)
T.mind.AddSpell(new S)
else
T.AddSpell(new S)
message_admins("<span class='danger'>Spells given to mindless mobs will not be transferred in mindswap or cloning!</span>")
/client/proc/remove_spell(mob/T in mob_list)
set category = "Fun"
set name = "Remove Spell"
set desc = "Remove a spell from the selected mob."
if(T && T.mind)
var/obj/effect/proc_holder/spell/S = input("Choose the spell to remove", "NO ABRAKADABRA") as null|anything in T.mind.spell_list
if(S)
T.mind.RemoveSpell(S)
log_admin("[key_name(usr)] removed the spell [S] from [key_name(T)].")
message_admins("<span class='adminnotice'>[key_name_admin(usr)] removed the spell [S] from [key_name(T)].</span>")
feedback_add_details("admin_verb","RS") //If you are copy-pasting this, ensure the 2nd parameter is unique to the new proc!
/client/proc/give_disease(mob/T in mob_list)
set category = "Fun"
@@ -735,13 +663,10 @@ var/list/admin_verbs_hideable = list(
while (!area && --j > 0)
/client/proc/toggle_AI_interact()
set name = "Toggle Admin AI Interact"
set category = "Admin"
set desc = "Allows you to interact with most machines as an AI would as a ghost"
set name = "Toggle Admin AI Interact"
set category = "Admin"
set desc = "Allows you to interact with most machines as an AI would as a ghost"
AI_Interact = !AI_Interact
if(mob && IsAdminGhost(mob))
mob.has_unlimited_silicon_privilege = AI_Interact
log_admin("[key_name(usr)] has [AI_Interact ? "activated" : "deactivated"] Admin AI Interact")
message_admins("[key_name_admin(usr)] has [AI_Interact ? "activated" : "deactivated"] their AI interaction")
AI_Interact = !AI_Interact
log_admin("[key_name(usr)] has [AI_Interact ? "activated" : "deactivated"] Admin AI Interact")
message_admins("[key_name_admin(usr)] has [AI_Interact ? "activated" : "deactivated"] their AI interaction")
+11 -26
View File
@@ -34,7 +34,7 @@
return
/client/proc/create_poll_function()
var/polltype = input("Choose poll type.","Poll Type") in list("Single Option","Text Reply","Rating","Multiple Choice", "Instant Runoff Voting")|null
var/polltype = input("Choose poll type.","Poll Type") in list("Single Option","Text Reply","Rating","Multiple Choice")
var/choice_amount = 0
switch(polltype)
if("Single Option")
@@ -48,10 +48,6 @@
choice_amount = input("How many choices should be allowed?","Select choice amount") as num|null
if(!choice_amount)
return
if ("Instant Runoff Voting")
polltype = POLLTYPE_IRV
else
return 0
var/starttime = SQLtime()
var/endtime = input("Set end time for poll as format YYYY-MM-DD HH:MM:SS. All times in server time. HH:MM:SS is optional and 24-hour. Must be later than starting time for obvious reasons.", "Set end time", SQLtime()) as text
if(!endtime)
@@ -85,20 +81,12 @@
adminonly = 0
else
return
var/dontshow
switch(alert("Hide poll results from tracking until completed?",,"Yes","No","Cancel"))
if("Yes")
dontshow = 1
if("No")
dontshow = 0
else
return
var/sql_ckey = sanitizeSQL(ckey)
var/question = input("Write your question","Question") as message|null
if(!question)
return
question = sanitizeSQL(question)
var/DBQuery/query_polladd_question = dbcon.NewQuery("INSERT INTO [format_table_name("poll_question")] (polltype, starttime, endtime, question, adminonly, multiplechoiceoptions, createdby_ckey, createdby_ip, dontshow) VALUES ('[polltype]', '[starttime]', '[endtime]', '[question]', '[adminonly]', '[choice_amount]', '[sql_ckey]', '[address]', '[dontshow]')")
var/DBQuery/query_polladd_question = dbcon.NewQuery("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]')")
if(!query_polladd_question.Execute())
var/err = query_polladd_question.ErrorMsg()
log_game("SQL ERROR adding new poll question to table. Error : \[[err]\]\n")
@@ -121,15 +109,14 @@
if(!option)
return pollid
option = sanitizeSQL(option)
var/percentagecalc = 1
if (polltype != POLLTYPE_IRV)
switch(alert("Calculate option results as percentage?",,"Yes","No","Cancel"))
if("Yes")
percentagecalc = 1
if("No")
percentagecalc = 0
else
return pollid
var/percentagecalc
switch(alert("Calculate option results as percentage?",,"Yes","No","Cancel"))
if("Yes")
percentagecalc = 1
if("No")
percentagecalc = 0
else
return pollid
var/minval = 0
var/maxval = 0
var/descmin = ""
@@ -165,11 +152,9 @@
var/err = query_polladd_option.ErrorMsg()
log_game("SQL ERROR adding new poll option to table. Error : \[[err]\]\n")
return pollid
switch(alert(" ",,"Add option","Finish", "Cancel"))
switch(alert(" ",,"Add option","Finish"))
if("Add option")
add_option = 1
if("Finish")
add_option = 0
else
return 0
return pollid
+1 -69
View File
@@ -51,7 +51,7 @@
bodies += M
var/question = "Would you like to be [group_name]?"
var/list/candidates = pollCandidatesForMobs(question, "pAI", null, FALSE, 100, bodies)
var/list/candidates = pollCandidates(question, "pAI", null, FALSE, 100)
while(candidates.len && bodies.len)
var/mob/dead/observer/ghost = pick_n_take(candidates)
var/mob/living/body = pick_n_take(bodies)
@@ -83,71 +83,3 @@
PoolOrNew(/obj/effect/overlay/temp/sparkle, M)
M.forceMove(T)
M << "<span class='notice'>Pop!</span>"
/obj/effect/station_crash
name = "station crash"
desc = "With no survivors!"
icon = 'icons/obj/weapons.dmi'
icon_state = "syndballoon"
anchored = TRUE
/obj/effect/station_crash/New()
for(var/S in SSshuttle.stationary)
var/obj/docking_port/stationary/SM = S
if(SM.id == "emergency_home")
var/new_dir = turn(SM.dir, 180)
SM.loc = get_ranged_target_turf(SM, new_dir, rand(3,15))
break
qdel(src)
//Luxury Shuttle Blockers
/obj/effect/forcefield/luxury_shuttle
var/threshhold = 500
var/list/approved_passengers = list()
/obj/effect/forcefield/luxury_shuttle/CanPass(atom/movable/mover, turf/target, height=0)
if(mover in approved_passengers)
return 1
if(!isliving(mover)) //No stowaways
return 0
var/total_cash = 0
var/list/counted_money = list()
for(var/obj/item/weapon/coin/C in mover)
total_cash += C.value
counted_money += C
if(total_cash >= threshhold)
break
for(var/obj/item/stack/spacecash/S in mover)
total_cash += S.value * S.amount
counted_money += S
if(total_cash >= threshhold)
break
if(total_cash >= threshhold)
for(var/obj/I in counted_money)
qdel(I)
mover << "Thank you for your payment! Please enjoy your flight."
approved_passengers += mover
return 1
else
mover << "You don't have enough money to enter the main shuttle. You'll have to fly coach."
return 0
//Shuttle Build
/obj/effect/shuttle_build
name = "shuttle_build"
desc = "Some assembly required"
icon = 'icons/obj/weapons.dmi'
icon_state = "syndballoon"
anchored = TRUE
/obj/effect/shuttle_build/New()
SSshuttle.emergency.dock(SSshuttle.getDock("emergency_home"))
qdel(src)
+1 -4
View File
@@ -56,16 +56,13 @@ var/list/admin_datums = list()
return 1 //we have all the rights they have and more
return 0
/datum/admins/vv_edit_var(var_name, var_value)
return FALSE //nice try trialmin
/*
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()
proc/admin_proc()
if(!check_rights(R_ADMIN)) return
world << "you have enough rights!"
+3 -3
View File
@@ -53,9 +53,9 @@
if (query.NextRow())
res.cache = TRUE
res.cachedate = query.item[1]
res.intel = text2num(query.item[2])
res.cacheminutesago = text2num(query.item[3])
res.cacherealtime = world.realtime - (text2num(query.item[3])*10*60)
res.intel = query.item[2]
res.cacheminutesago = query.item[3]
res.cacherealtime = world.realtime - (query.item[3]*10*60)
SSipintel.cache[ip] = res
return
res.intel = ip_intel_query(ip)
+82 -22
View File
@@ -244,7 +244,7 @@
M_job = "AI"
else if(ispAI(M))
M_job = "pAI"
else if(iscyborg(M))
else if(isrobot(M))
M_job = "Cyborg"
else
M_job = "Silicon-based"
@@ -260,7 +260,7 @@
else
M_job = "Living"
else if(isnewplayer(M))
else if(istype(M,/mob/new_player))
M_job = "New player"
else if(isobserver(M))
@@ -346,7 +346,7 @@
for(var/datum/mind/N in ticker.mode.syndicates)
var/mob/M = N.current
if(M)
dat += "<tr><td><a href='?_src_=holder;adminplayeropts=\ref[M]'>[M.real_name]</a>[M.client ? "" : " <i>(No Client)</i>"][M.stat == 2 ? " <b><font color=red>(DEAD)</font></b>" : ""]</td>"
dat += "<tr><td><a href='?_src_=holder;adminplayeropts=\ref[M]'>[M.real_name]</a>[M.client ? "" : " <i>(ghost)</i>"][M.stat == 2 ? " <b><font color=red>(DEAD)</font></b>" : ""]</td>"
dat += "<td><A href='?priv_msg=[M.ckey]'>PM</A></td>"
dat += "<td><A href='?_src_=holder;adminplayerobservefollow=\ref[M]'>FLW</a></td></tr>"
else
@@ -356,11 +356,11 @@
for(var/obj/item/weapon/disk/nuclear/N in poi_list)
dat += "<tr><td>[N.name], "
var/atom/disk_loc = N.loc
while(!isturf(disk_loc))
if(ismob(disk_loc))
while(!istype(disk_loc, /turf))
if(istype(disk_loc, /mob))
var/mob/M = disk_loc
dat += "carried by <a href='?_src_=holder;adminplayeropts=\ref[M]'>[M.real_name]</a> "
if(isobj(disk_loc))
if(istype(disk_loc, /obj))
var/obj/O = disk_loc
dat += "in \a [O.name] "
disk_loc = disk_loc.loc
@@ -375,20 +375,20 @@
dat += "<tr><td><a href='?_src_=vars;Vars=\ref[N]'>[N.name]([N.key])</a><i>Head Revolutionary body destroyed!</i></td>"
dat += "<td><A href='?priv_msg=[N.key]'>PM</A></td></tr>"
else
dat += "<tr><td><a href='?_src_=holder;adminplayeropts=\ref[M]'>[M.real_name]</a> <b>(Leader)</b>[M.client ? "" : " <i>(No Client)</i>"][M.stat == 2 ? " <b><font color=red>(DEAD)</font></b>" : ""]</td>"
dat += "<tr><td><a href='?_src_=holder;adminplayeropts=\ref[M]'>[M.real_name]</a> <b>(Leader)</b>[M.client ? "" : " <i>(ghost)</i>"][M.stat == 2 ? " <b><font color=red>(DEAD)</font></b>" : ""]</td>"
dat += "<td><A href='?priv_msg=[M.ckey]'>PM</A></td>"
dat += "<td><A href='?_src_=holder;adminplayerobservefollow=\ref[M]'>FLW</a></td></tr>"
for(var/datum/mind/N in ticker.mode.revolutionaries)
var/mob/M = N.current
if(M)
dat += "<tr><td><a href='?_src_=holder;adminplayeropts=\ref[M]'>[M.real_name]</a>[M.client ? "" : " <i>(No Client)</i>"][M.stat == 2 ? " <b><font color=red>(DEAD)</font></b>" : ""]</td>"
dat += "<tr><td><a href='?_src_=holder;adminplayeropts=\ref[M]'>[M.real_name]</a>[M.client ? "" : " <i>(ghost)</i>"][M.stat == 2 ? " <b><font color=red>(DEAD)</font></b>" : ""]</td>"
dat += "<td><A href='?priv_msg=[M.ckey]'>PM</A></td>"
dat += "<td><A href='?_src_=holder;adminplayerobservefollow=\ref[M]'>FLW</a></td></tr>"
dat += "</table><table cellspacing=5><tr><td><B>Target(s)</B></td><td></td><td><B>Location</B></td></tr>"
for(var/datum/mind/N in ticker.mode.get_living_heads())
var/mob/M = N.current
if(M)
dat += "<tr><td><a href='?_src_=holder;adminplayeropts=\ref[M]'>[M.real_name]</a>[M.client ? "" : " <i>(No Client)</i>"][M.stat == 2 ? " <b><font color=red>(DEAD)</font></b>" : ""]</td>"
dat += "<tr><td><a href='?_src_=holder;adminplayeropts=\ref[M]'>[M.real_name]</a>[M.client ? "" : " <i>(ghost)</i>"][M.stat == 2 ? " <b><font color=red>(DEAD)</font></b>" : ""]</td>"
dat += "<td><A href='?priv_msg=[M.ckey]'>PM</A></td>"
dat += "<td><A href='?_src_=holder;adminplayerobservefollow=\ref[M]'>FLW</a></td>"
var/turf/mob_loc = get_turf(M)
@@ -406,13 +406,13 @@
dat += "<tr><td><a href='?_src_=vars;Vars=\ref[N]'>[N.name]([N.key])</a><i>Gang Boss body destroyed!</i></td>"
dat += "<td><A href='?priv_msg=[N.key]'>PM</A></td></tr>"
else
dat += "<tr><td><a href='?_src_=holder;adminplayeropts=\ref[M]'>[M.real_name]</a> <b>(Boss)</b>[M.client ? "" : " <i>(No Client)</i>"][M.stat == 2 ? " <b><font color=red>(DEAD)</font></b>" : ""]</td>"
dat += "<tr><td><a href='?_src_=holder;adminplayeropts=\ref[M]'>[M.real_name]</a> <b>(Boss)</b>[M.client ? "" : " <i>(ghost)</i>"][M.stat == 2 ? " <b><font color=red>(DEAD)</font></b>" : ""]</td>"
dat += "<td><A href='?priv_msg=[M.ckey]'>PM</A></td>"
dat += "<td><A href='?_src_=holder;adminplayerobservefollow=\ref[M]'>FLW</a></td></tr>"
for(var/datum/mind/N in G.gangsters)
var/mob/M = N.current
if(M)
dat += "<tr><td><a href='?_src_=holder;adminplayeropts=\ref[M]'>[M.real_name]</a>[M.client ? "" : " <i>(No Client)</i>"][M.stat == 2 ? " <b><font color=red>(DEAD)</font></b>" : ""]</td>"
dat += "<tr><td><a href='?_src_=holder;adminplayeropts=\ref[M]'>[M.real_name]</a>[M.client ? "" : " <i>(ghost)</i>"][M.stat == 2 ? " <b><font color=red>(DEAD)</font></b>" : ""]</td>"
dat += "<td><A href='?priv_msg=[M.ckey]'>PM</A></td></tr>"
dat += "</table>"
@@ -421,7 +421,7 @@
for(var/datum/mind/changeling in ticker.mode.changelings)
var/mob/M = changeling.current
if(M)
dat += "<tr><td>[M.mind.changeling.changelingID] as <a href='?_src_=holder;adminplayeropts=\ref[M]'>[M.real_name]</a>[M.client ? "" : " <i>(No Client)</i>"][M.stat == 2 ? " <b><font color=red>(DEAD)</font></b>" : ""]</td>"
dat += "<tr><td>[M.mind.changeling.changelingID] as <a href='?_src_=holder;adminplayeropts=\ref[M]'>[M.real_name]</a>[M.client ? "" : " <i>(ghost)</i>"][M.stat == 2 ? " <b><font color=red>(DEAD)</font></b>" : ""]</td>"
dat += "<td><A href='?priv_msg=[M.ckey]'>PM</A></td>"
dat += "<td><A href='?_src_=holder;adminplayerobservefollow=\ref[M]'>FLW</a></td>"
dat += "<td><A HREF='?_src_=holder;traitor=\ref[M]'>Show Objective</A></td></tr>"
@@ -435,7 +435,7 @@
for(var/datum/mind/wizard in ticker.mode.wizards)
var/mob/M = wizard.current
if(M)
dat += "<tr><td><a href='?_src_=holder;adminplayeropts=\ref[M]'>[M.real_name]</a>[M.client ? "" : " <i>(No Client)</i>"][M.stat == 2 ? " <b><font color=red>(DEAD)</font></b>" : ""]</td>"
dat += "<tr><td><a href='?_src_=holder;adminplayeropts=\ref[M]'>[M.real_name]</a>[M.client ? "" : " <i>(ghost)</i>"][M.stat == 2 ? " <b><font color=red>(DEAD)</font></b>" : ""]</td>"
dat += "<td><A href='?priv_msg=[M.ckey]'>PM</A></td>"
dat += "<td><A href='?_src_=holder;adminplayerobservefollow=\ref[M]'>FLW</a></td>"
dat += "<td><A HREF='?_src_=holder;traitor=\ref[M]'>Show Objective</A></td></tr>"
@@ -449,7 +449,7 @@
for(var/datum/mind/apprentice in ticker.mode.apprentices)
var/mob/M = apprentice.current
if(M)
dat += "<tr><td><a href='?_src_=holder;adminplayeropts=\ref[M]'>[M.real_name]</a>[M.client ? "" : " <i>(No Client)</i>"][M.stat == 2 ? " <b><font color=red>(DEAD)</font></b>" : ""]</td>"
dat += "<tr><td><a href='?_src_=holder;adminplayeropts=\ref[M]'>[M.real_name]</a>[M.client ? "" : " <i>(ghost)</i>"][M.stat == 2 ? " <b><font color=red>(DEAD)</font></b>" : ""]</td>"
dat += "<td><A href='?priv_msg=[M.ckey]'>PM</A></td>"
dat += "<td><A href='?_src_=holder;adminplayerobservefollow=\ref[M]'>FLW</a></td>"
dat += "<td><A HREF='?_src_=holder;traitor=\ref[M]'>Show Objective</A></td></tr>"
@@ -463,7 +463,7 @@
for(var/datum/mind/N in ticker.mode.cult)
var/mob/M = N.current
if(M)
dat += "<tr><td><a href='?_src_=holder;adminplayeropts=\ref[M]'>[M.real_name]</a>[M.client ? "" : " <i>(No Client)</i>"][M.stat == 2 ? " <b><font color=red>(DEAD)</font></b>" : ""]</td>"
dat += "<tr><td><a href='?_src_=holder;adminplayeropts=\ref[M]'>[M.real_name]</a>[M.client ? "" : " <i>(ghost)</i>"][M.stat == 2 ? " <b><font color=red>(DEAD)</font></b>" : ""]</td>"
dat += "<td><A href='?priv_msg=[M.ckey]'>PM</A></td>"
dat += "<td><A href='?_src_=holder;adminplayerobservefollow=\ref[M]'>FLW</a></td></tr>"
dat += "</table>"
@@ -478,12 +478,72 @@
dat += "<td><A href='?_src_=holder;adminplayerobservefollow=\ref[M]'>FLW</a></td></tr>"
dat += "</table>"
if(ticker.mode.red_deities.len || ticker.mode.red_deity_prophets.len || ticker.mode.blue_deity_prophets.len || ticker.mode.red_deity_followers.len || ticker.mode.blue_deity_followers.len)
dat += "<br><table cellspacing=5><tr><td><B>Red Deity</B></td><td></td></tr>"
for(var/datum/mind/N in ticker.mode.red_deities)
var/mob/M = N.current
if(M)
dat += "<tr><td>Red Deity: <a href='?_src_=holder;adminplayeropts=\ref[M]'>[M.real_name]</a>[M.client ? "" : " <i>(ghost)</i>"][M.stat == 2 ? " <b><font color=red>(DEAD)</font></b>" : ""]</td>"
dat += "<td><A href='?priv_msg=[M.ckey]'>PM</A></td>"
dat += "<td><A href='?_src_=holder;adminplayerobservefollow=\ref[M]'>FLW</a></td></tr>"
dat += "</table>"
if(ticker.mode.blue_deities.len)
dat += "<br><table cellspacing=5><tr><td><B>Blue Deity</B></td><td></td></tr>"
for(var/datum/mind/N in ticker.mode.blue_deities)
var/mob/M = N.current
if(M)
dat += "<tr><td>Blue Deity: <a href='?_src_=holder;adminplayeropts=\ref[M]'>[M.real_name]</a>[M.client ? "" : " <i>(ghost)</i>"][M.stat == 2 ? " <b><font color=red>(DEAD)</font></b>" : ""]</td>"
dat += "<td><A href='?priv_msg=[M.ckey]'>PM</A></td>"
dat += "<td><A href='?_src_=holder;adminplayerobservefollow=\ref[M]'>FLW</a></td></tr>"
dat += "</table>"
if(ticker.mode.red_deity_prophets.len)
dat += "<br><table cellspacing=5><tr><td><B>Red Deity Prophets</B></td><td></td></tr>"
for(var/datum/mind/N in ticker.mode.red_deity_prophets)
var/mob/M = N.current
if(M)
dat += "<tr><td>Red Deity Prophet: <a href='?_src_=holder;adminplayeropts=\ref[M]'>[M.real_name]</a>[M.client ? "" : " <i>(ghost)</i>"][M.stat == 2 ? " <b><font color=red>(DEAD)</font></b>" : ""]</td>"
dat += "<td><A href='?priv_msg=[M.ckey]'>PM</A></td>"
dat += "<td><A href='?_src_=holder;adminplayerobservefollow=\ref[M]'>FLW</a></td></tr>"
dat += "</table>"
if(ticker.mode.blue_deity_prophets.len)
dat += "<br><table cellspacing=5><tr><td><B>Blue Deity Prophets</B></td><td></td></tr>"
for(var/datum/mind/N in ticker.mode.blue_deity_prophets)
var/mob/M = N.current
if(M)
dat += "<tr><td>Blue Deity Prophet: <a href='?_src_=holder;adminplayeropts=\ref[M]'>[M.real_name]</a>[M.client ? "" : " <i>(ghost)</i>"][M.stat == 2 ? " <b><font color=red>(DEAD)</font></b>" : ""]</td>"
dat += "<td><A href='?priv_msg=[M.ckey]'>PM</A></td>"
dat += "<td><A href='?_src_=holder;adminplayerobservefollow=\ref[M]'>FLW</a></td></tr>"
dat += "</table>"
if(ticker.mode.red_deity_followers.len)
dat += "<br><table cellspacing=5><tr><td><B>Red Deity Followers</B></td><td></td></tr>"
for(var/datum/mind/N in ticker.mode.red_deity_followers)
var/mob/M = N.current
if(M)
dat += "<tr><td>Red Deity Followers: <a href='?_src_=holder;adminplayeropts=\ref[M]'>[M.real_name]</a>[M.client ? "" : " <i>(ghost)</i>"][M.stat == 2 ? " <b><font color=red>(DEAD)</font></b>" : ""]</td>"
dat += "<td><A href='?priv_msg=[M.ckey]'>PM</A></td>"
dat += "<td><A href='?_src_=holder;adminplayerobservefollow=\ref[M]'>FLW</a></td></tr>"
dat += "</table>"
if(ticker.mode.blue_deity_followers.len)
dat += "<br><table cellspacing=5><tr><td><B>Blue Deity Followers</B></td><td></td></tr>"
for(var/datum/mind/N in ticker.mode.blue_deity_followers)
var/mob/M = N.current
if(M)
dat += "<tr><td>Blue Deity Followers: <a href='?_src_=holder;adminplayeropts=\ref[M]'>[M.real_name]</a>[M.client ? "" : " <i>(ghost)</i>"][M.stat == 2 ? " <b><font color=red>(DEAD)</font></b>" : ""]</td>"
dat += "<td><A href='?priv_msg=[M.ckey]'>PM</A></td>"
dat += "<td><A href='?_src_=holder;adminplayerobservefollow=\ref[M]'>FLW</a></td></tr>"
dat += "</table>"
if(ticker.mode.traitors.len > 0)
dat += "<br><table cellspacing=5><tr><td><B>Traitors</B></td><td></td><td></td></tr>"
for(var/datum/mind/traitor in ticker.mode.traitors)
var/mob/M = traitor.current
if(M)
dat += "<tr><td><a href='?_src_=holder;adminplayeropts=\ref[M]'>[M.real_name]</a>[M.client ? "" : " <i>(No Client)</i>"][M.stat == 2 ? " <b><font color=red>(DEAD)</font></b>" : ""]</td>"
dat += "<tr><td><a href='?_src_=holder;adminplayeropts=\ref[M]'>[M.real_name]</a>[M.client ? "" : " <i>(ghost)</i>"][M.stat == 2 ? " <b><font color=red>(DEAD)</font></b>" : ""]</td>"
dat += "<td><A href='?priv_msg=[M.ckey]'>PM</A></td>"
dat += "<td><A href='?_src_=holder;adminplayerobservefollow=\ref[M]'>FLW</a></td>"
dat += "<td><A HREF='?_src_=holder;traitor=\ref[M]'>Show Objective</A></td></tr>"
@@ -497,7 +557,7 @@
for(var/datum/mind/abductor in ticker.mode.abductors)
var/mob/M = abductor.current
if(M)
dat += "<tr><td><a href='?_src_=holder;adminplayeropts=\ref[M]'>[M.real_name]</a>[M.client ? "" : " <i>(No Client)</i>"][M.stat == 2 ? " <b><font color=red>(DEAD)</font></b>" : ""]</td>"
dat += "<tr><td><a href='?_src_=holder;adminplayeropts=\ref[M]'>[M.real_name]</a>[M.client ? "" : " <i>(ghost)</i>"][M.stat == 2 ? " <b><font color=red>(DEAD)</font></b>" : ""]</td>"
dat += "<td><A href='?priv_msg=[M.ckey]'>PM</A></td>"
dat += "<td><A href='?_src_=holder;adminplayerobservefollow=\ref[M]'>FLW</a></td>"
dat += "<td><A HREF='?_src_=holder;traitor=\ref[M]'>Show Objective</A></td></tr>"
@@ -510,7 +570,7 @@
for(var/datum/mind/abductee in E.abductee_minds)
var/mob/M = abductee.current
if(M)
dat += "<tr><td><a href='?_src_=holder;adminplayeropts=\ref[M]'>[M.real_name]</a>[M.client ? "" : " <i>(No Client)</i>"][M.stat == 2 ? " <b><font color=red>(DEAD)</font></b>" : ""]</td>"
dat += "<tr><td><a href='?_src_=holder;adminplayeropts=\ref[M]'>[M.real_name]</a>[M.client ? "" : " <i>(ghost)</i>"][M.stat == 2 ? " <b><font color=red>(DEAD)</font></b>" : ""]</td>"
dat += "<td><A href='?priv_msg=[M.ckey]'>PM</A></td>"
dat += "<td><A href='?_src_=holder;adminplayerobservefollow=\ref[M]'>FLW</a></td>"
dat += "<td><A HREF='?_src_=holder;traitor=\ref[M]'>Show Objective</A></td></tr>"
@@ -525,7 +585,7 @@
var/datum/mind/devil = X
var/mob/M = devil.current
if(M)
dat += "<tr><td><a href='?_src_=holder;adminplayeropts=\ref[M]'>[M.real_name] : [devil.devilinfo.truename]</a>[M.client ? "" : " <i>(No Client)</i>"][M.stat == 2 ? " <b><font color=red>(DEAD)</font></b>" : ""]</td>"
dat += "<tr><td><a href='?_src_=holder;adminplayeropts=\ref[M]'>[M.real_name] : [devil.devilinfo.truename]</a>[M.client ? "" : " <i>(ghost)</i>"][M.stat == 2 ? " <b><font color=red>(DEAD)</font></b>" : ""]</td>"
dat += "<td><A href='?priv_msg=[M.ckey]'>PM</A></td>"
dat += "<td><A HREF='?_src_=holder;traitor=\ref[M]'>Show Objective</A></td></tr>"
dat += "<td><A HREF='?_src_=holder;admincheckdevilinfo=\ref[M]'>Show all devil info</A></td></tr>"
@@ -540,7 +600,7 @@
var/datum/mind/sintouched = X
var/mob/M = sintouched.current
if(M)
dat += "<tr><td><a href='?_src_=holder;adminplayeropts=\ref[M]'>[M.real_name]</a>[M.client ? "" : " <i>(No Client)</i>"][M.stat == 2 ? " <b><font color=red>(DEAD)</font></b>" : ""]</td>"
dat += "<tr><td><a href='?_src_=holder;adminplayeropts=\ref[M]'>[M.real_name]</a>[M.client ? "" : " <i>(ghost)</i>"][M.stat == 2 ? " <b><font color=red>(DEAD)</font></b>" : ""]</td>"
dat += "<td><A href='?priv_msg=[M.ckey]'>PM</A></td>"
dat += "<td><A HREF='?_src_=holder;traitor=\ref[M]'>Show Objective</A></td></tr>"
else
@@ -562,7 +622,7 @@
for(var/datum/mind/blob in blob_minds)
var/mob/M = blob.current
if(M)
dat += "<tr><td><a href='?_src_=holder;adminplayeropts=\ref[M]'>[M.real_name]</a>[M.client ? "" : " <i>(No Client)</i>"][M.stat == 2 ? " <b><font color=red>(DEAD)</font></b>" : ""]</td>"
dat += "<tr><td><a href='?_src_=holder;adminplayeropts=\ref[M]'>[M.real_name]</a>[M.client ? "" : " <i>(ghost)</i>"][M.stat == 2 ? " <b><font color=red>(DEAD)</font></b>" : ""]</td>"
dat += "<td><A href='?priv_msg=[M.ckey]'>PM</A></td>"
dat += "<td><A href='?_src_=holder;adminplayerobservefollow=\ref[M]'>FLW</a></td></tr>"
else
@@ -578,7 +638,7 @@
for(var/datum/mind/eek in mode.ape_infectees)
var/mob/M = eek.current
if(M)
dat += "<tr><td><a href='?_src_=holder;adminplayeropts=\ref[M]'>[M.real_name]</a>[M.client ? "" : " <i>(No Client)</i>"][M.stat == 2 ? " <b><font color=red>(DEAD)</font></b>" : ""]</td>"
dat += "<tr><td><a href='?_src_=holder;adminplayeropts=\ref[M]'>[M.real_name]</a>[M.client ? "" : " <i>(ghost)</i>"][M.stat == 2 ? " <b><font color=red>(DEAD)</font></b>" : ""]</td>"
dat += "<td><A href='?priv_msg=[M.ckey]'>PM</A></td>"
dat += "<td><A href='?_src_=holder;adminplayerobservefollow=\ref[M]'>FLW</a></td></tr>"
else
+1 -9
View File
@@ -9,7 +9,6 @@
<A href='?src=\ref[src];secrets=list_job_debug'>Show Job Debug</A><BR>
<A href='?src=\ref[src];secrets=admin_log'>Admin Log</A><BR>
<A href='?src=\ref[src];secrets=show_admins'>Show Admin List</A><BR>
<A href='?src=\ref[src];secrets=show_current_watchlist'>Show online players in the watchlist</A><BR>
<BR>
"}
@@ -120,13 +119,6 @@
dat += "[ckey] - [D.rank.name]<br>"
usr << browse(dat, "window=showadmins;size=600x500")
if("show_current_watchlist")
var/dat = "<B>Watchlist: </B><HR>"
if(current_watchlist)
for(var/ckey in current_watchlist)
dat += "[ckey] - [current_watchlist[ckey]]"
usr << browse(dat, "window=showcurrentwatchlist;size=600x500")
if("tdomereset")
if(!check_rights(R_ADMIN))
return
@@ -397,7 +389,7 @@
feedback_add_details("admin_secrets_fun_used","BO")
message_admins("[key_name_admin(usr)] broke all lights")
for(var/obj/machinery/light/L in machines)
L.break_light_tube()
L.broken()
if("anime")
if(!check_rights(R_FUN))
+12 -53
View File
@@ -1,4 +1,4 @@
/proc/add_note(target_ckey, notetext, timestamp, adminckey, logged = 1, server, secret)
/proc/add_note(target_ckey, notetext, timestamp, adminckey, logged = 1, server)
if(!dbcon.IsConnected())
usr << "<span class='danger'>Failed to establish database connection.</span>"
return
@@ -13,12 +13,12 @@
log_game("SQL ERROR obtaining ckey from player table. Error : \[[err]\]\n")
return
if(!query_find_ckey.NextRow())
if(alert(usr, "[new_ckey] has not been seen before, are you sure you want to add a note for them?", "Unknown ckey", "Yes", "No", "Cancel") != "Yes")
if(alert(usr, "[new_ckey] has not been seen before, are you sure you want to add them to the watchlist?", "Unknown ckey", "Yes", "No", "Cancel") != "Yes")
return
target_ckey = new_ckey
var/target_sql_ckey = sanitizeSQL(target_ckey)
if(!notetext)
notetext = input(usr,"Write your Note","Add Note") as null|message
notetext = input(usr,"Write your Note","Add Note") as message
if(!notetext)
return
notetext = sanitizeSQL(notetext)
@@ -33,15 +33,7 @@
if (config && config.server_name)
server = config.server_name
server = sanitizeSQL(server)
if(isnull(secret))
switch(alert("Hide note from being viewed by players?", "Secret Note?","Yes","No","Cancel"))
if("Yes")
secret = 1
if("No")
secret = 0
else
return
var/DBQuery/query_noteadd = dbcon.NewQuery("INSERT INTO [format_table_name("notes")] (ckey, timestamp, notetext, adminckey, server, secret) VALUES ('[target_sql_ckey]', '[timestamp]', '[notetext]', '[admin_sql_ckey]', '[server]', '[secret]')")
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]')")
if(!query_noteadd.Execute())
var/err = query_noteadd.ErrorMsg()
log_game("SQL ERROR adding new note to table. Error : \[[err]\]\n")
@@ -97,7 +89,7 @@
target_ckey = query_find_note_edit.item[1]
var/old_note = query_find_note_edit.item[2]
var/adminckey = query_find_note_edit.item[3]
var/new_note = input("Input new note", "New Note", "[old_note]") as null|message
var/new_note = input("Input new note", "New Note", "[old_note]") as message
if(!new_note)
return
new_note = sanitizeSQL(new_note)
@@ -112,33 +104,6 @@
message_admins("[key_name_admin(usr)] has edited [target_ckey]'s note made by [adminckey] from<br>[old_note]<br>to<br>[new_note]")
show_note(target_ckey)
/proc/toggle_note_secrecy(note_id)
if(!dbcon.IsConnected())
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_secret = dbcon.NewQuery("SELECT ckey, adminckey, secret FROM [format_table_name("notes")] WHERE id = [note_id]")
if(!query_find_note_secret.Execute())
var/err = query_find_note_secret.ErrorMsg()
log_game("SQL ERROR obtaining ckey, adminckey, secret from notes table. Error : \[[err]\]\n")
return
if(query_find_note_secret.NextRow())
var/target_ckey = query_find_note_secret.item[1]
var/adminckey = query_find_note_secret.item[2]
var/secret = text2num(query_find_note_secret.item[3])
var/sql_ckey = sanitizeSQL(usr.ckey)
var/edit_text = "Made [secret ? "not secret" : "secret"] by [sql_ckey] on [SQLtime()]<hr>"
var/DBQuery/query_update_note = dbcon.NewQuery("UPDATE [format_table_name("notes")] SET secret = NOT secret, 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 toggling note secrecy. Error : \[[err]\]\n")
return
log_admin("[key_name(usr)] has toggled [target_ckey]'s note made by [adminckey] to [secret ? "not secret" : "secret"]")
message_admins("[key_name_admin(usr)] has toggled [target_ckey]'s note made by [adminckey] to [secret ? "not secret" : "secret"]")
show_note(target_ckey)
/proc/show_note(target_ckey, index, linkless = 0)
var/output
var/navbar
@@ -155,31 +120,25 @@
output = navbar
if(target_ckey)
var/target_sql_ckey = sanitizeSQL(target_ckey)
var/DBQuery/query_get_notes = dbcon.NewQuery("SELECT secret, timestamp, notetext, adminckey, last_editor, server, id FROM [format_table_name("notes")] WHERE ckey = '[target_sql_ckey]' ORDER BY timestamp")
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")
if(!query_get_notes.Execute())
var/err = query_get_notes.ErrorMsg()
log_game("SQL ERROR obtaining secret, timestamp, notetext, adminckey, last_editor, server, id from notes table. Error : \[[err]\]\n")
log_game("SQL ERROR obtaining ckey, notetext, adminckey, last_editor, server from notes table. Error : \[[err]\]\n")
return
output += "<h2><center>Notes of [target_ckey]</center></h2>"
if(!linkless)
output += "<center><a href='?_src_=holder;addnote=[target_ckey]'>\[Add Note\]</a>"
output += " <a href='?_src_=holder;shownoteckey=[target_ckey]'>\[Refresh Page\]</a></center>"
else
output += " <a href='?_src_=holder;shownoteckeylinkless=[target_ckey]'>\[Refresh Page\]</a></center>"
output += "<center><a href='?_src_=holder;addnote=[target_ckey]'>\[Add Note\]</a></center>"
output += ruler
while(query_get_notes.NextRow())
var/secret = text2num(query_get_notes.item[1])
if(linkless && secret)
continue
var/id = query_get_notes.item[1]
var/timestamp = query_get_notes.item[2]
var/notetext = query_get_notes.item[3]
var/adminckey = query_get_notes.item[4]
var/last_editor = query_get_notes.item[5]
var/server = query_get_notes.item[6]
var/id = query_get_notes.item[7]
output += "<b>[timestamp] | [server] | [adminckey]</b>"
if(!linkless)
output += " <a href='?_src_=holder;removenote=[id]'>\[Remove Note\]</a> <a href='?_src_=holder;secretnote=[id]'>[secret ? "<b>\[Secret\]</b>" : "\[Not Secret\]"]</a> <a href='?_src_=holder;editnote=[id]'>\[Edit Note\]</a>"
output += " <a href='?_src_=holder;removenote=[id]'>\[Remove Note\]</a> <a href='?_src_=holder;editnote=[id]'>\[Edit Note\]</a>"
if(last_editor)
output += " <font size='2'>Last edit by [last_editor] <a href='?_src_=holder;noteedits=[id]'>(Click here to see edit log)</a></font>"
output += "<br>[notetext]<hr style='background:#000000; border:0; height:1px'>"
@@ -237,7 +196,7 @@
if(query_convert_time.NextRow())
timestamp = query_convert_time.item[1]
if(ckey && notetext && timestamp && adminckey && server)
add_note(ckey, notetext, timestamp, adminckey, 0, server, 1)
add_note(ckey, notetext, timestamp, adminckey, 0, server)
notesfile.cd = "/"
notesfile.dir.Remove(ckey)
@@ -255,4 +214,4 @@ this proc can take several minutes to execute fully if converting and cause DD t
world << "Deleting NOTESFILE"
fdel(NOTESFILE)
world << "Finished mass note conversion, remember to turn off AUTOCONVERT_NOTES"*/
#undef NOTESFILE
#undef NOTESFILE
+7 -51
View File
@@ -18,8 +18,6 @@
if (!ckey)
return
ckey = ckey(ckey)
ban["ckey"] = ckey
if (get_stickyban_from_ckey(ckey))
usr << "<span class='adminnotice'>Error: Can not add a stickyban: User already has a current sticky ban</span>"
@@ -127,37 +125,9 @@
log_admin("[key_name(usr)] has edited [ckey]'s sticky ban reason from [oldreason] to [reason]")
message_admins("<span class='adminnotice'>[key_name_admin(usr)] has edited [ckey]'s sticky ban reason from [oldreason] to [reason]</span>")
if ("revert")
if (!data["ckey"])
return
var/ckey = data["ckey"]
if (alert("Are you sure you want to revert the sticky ban on [ckey] to its state at round start?","Are you sure","Yes","No") == "No")
return
var/ban = get_stickyban_from_ckey(ckey)
if (!ban)
usr << "<span class='adminnotice'>Error: No sticky ban for [ckey] found!"
return
var/cached_ban = SSstickyban.cache[ckey]
if (!cached_ban)
usr << "<span class='adminnotice'>Error: No cached sticky ban for [ckey] found!"
world.SetConfig("ban",ckey,null)
log_admin("[key_name(usr)] has reverted [ckey]'s sticky ban to it's state at round start.")
message_admins("<span class='adminnotice'>[key_name_admin(usr)] has reverted [ckey]'s sticky ban to it's state at round start.</span>")
//revert is mostly used when shit goes rouge, so we have to set it to null
// and wait a byond tick before assigning it to ensure byond clears its shit.
sleep(world.tick_lag)
world.SetConfig("ban",ckey,list2stickyban(cached_ban))
/datum/admins/proc/stickyban_gethtml(ckey, ban)
. = {"
<a href='?_src_=holder;stickyban=remove&ckey=[ckey]'>\[-\]</a>
<a href='?_src_=holder;stickyban=revert&ckey=[ckey]'>\[revert\]</a>
<b>[ckey]</b>
<br />"
[ban["message"]] <b><a href='?_src_=holder;stickyban=edit&ckey=[ckey]'>\[Edit\]</a></b><br />
"}
. = "<a href='?_src_=holder;stickyban=remove&ckey=[ckey]'>\[-\]</a><b>[ckey]</b><br />"
. += "[ban["message"]] <b><a href='?_src_=holder;stickyban=edit&ckey=[ckey]'>\[Edit\]</a></b><br />"
if (ban["admin"])
. += "[ban["admin"]]<br />"
else
@@ -205,13 +175,7 @@
if (!ban)
return null
. = params2list(ban)
if (.["keys"])
var/keys = splittext(.["keys"], ",")
var/ckeys = list()
for (var/key in keys)
var/ckey = ckey(key)
ckeys[ckey] = ckey //to make searching faster.
.["keys"] = ckeys
.["keys"] = splittext(.["keys"], ",")
.["type"] = splittext(.["type"], ",")
.["IP"] = splittext(.["IP"], ",")
.["computer_id"] = splittext(.["computer_id"], ",")
@@ -225,18 +189,10 @@
.["keys"] = jointext(.["keys"], ",")
if (.["type"])
.["type"] = jointext(.["type"], ",")
//internal tracking only, shouldn't be stored
. -= "existing_user_matches_this_round"
. -= "admin_matches_this_round"
. -= "matches_this_round"
. -= "reverting"
//storing these can sometimes cause sticky bans to start matching everybody
// and isn't even needed for sticky ban matching, as the hub tracks these seperately
. -= "IP"
. -= "computer_id"
if (.["IP"])
.["IP"] = jointext(.["IP"], ",")
if (.["computer_id"])
.["computer_id"] = jointext(.["computer_id"], ",")
. = list2params(.)
File diff suppressed because it is too large Load Diff
+1 -1
View File
@@ -134,7 +134,7 @@
vals += v
vals[v] = SDQL_expression(d, set_list[v])
if(isturf(d))
if(istype(d, /turf))
for(var/v in vals)
if(v == "x" || v == "y" || v == "z")
continue
+38 -37
View File
@@ -1,4 +1,4 @@
/proc/keywords_lookup(msg,irc)
/proc/keywords_lookup(msg)
//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", "i")
@@ -10,7 +10,6 @@
var/list/surnames = list()
var/list/forenames = list()
var/list/ckeys = list()
var/founds = ""
for(var/mob/M in mob_list)
var/list/indexing = list(M.real_name, M.name)
if(M.mind)
@@ -57,16 +56,9 @@
var/is_antag = 0
if(found.mind && found.mind.special_role)
is_antag = 1
founds += "Name: [found.name]([found.real_name]) Ckey: [found.ckey] [is_antag ? "(Antag)" : null] "
msg += "[original_word]<font size='1' color='[is_antag ? "red" : "black"]'>(<A HREF='?_src_=holder;adminmoreinfo=\ref[found]'>?</A>|<A HREF='?_src_=holder;adminplayerobservefollow=\ref[found]'>F</A>)</font> "
continue
msg += "[original_word] "
if(irc)
if(founds == "")
return "Search Failed"
else
return founds
return msg
@@ -91,38 +83,62 @@
if(src.handle_spam_prevention(msg,MUTE_ADMINHELP))
return
var/ref_mob = "\ref[mob]"
for(var/datum/adminticket/T in admintickets)
if(T.permckey == src.ckey && T.resolved == "No")
if(alert(usr,"You already have an adminhelp open, would you like to bump it?", "Bump Adminhelp", "Yes", "No") == "Yes")
T.logs += "[src.ckey] has bumped this adminhelp!"
if(T.admin == "N/A")
usr << "<b>Due to the fact your Adminhelp had no assigned admin, admins have been pinged.</b>"
message_admins("[src.ckey] has bumped their adminhelp #[T.ID], still no assigned admin!")
msg = "<span class='adminnotice'><b><font color=red>ADMINHELP: </font><A HREF='?priv_msg=[ckey];ahelp_reply=1'>[key_name(src)]</A> (<A HREF='?_src_=holder;adminmoreinfo=[ref_mob]'>?</A>) (<A HREF='?_src_=holder;adminplayeropts=[ref_mob]'>PP</A>) (<A HREF='?_src_=vars;Vars=[ref_mob]'>VV</A>) (<A HREF='?_src_=holder;subtlemessage=[ref_mob]'>SM</A>) (<A HREF='?_src_=holder;traitor=[ref_mob]'>TP</A>) (<A HREF='?_src_=holder;adminplayerobservefollow=[ref_mob]'>FLW</A>) (<a href='?src=\ref[T];resolve=\ref[T]'>R</a>):</b> [T.msg]</span>"
for(var/client/X in admins)
if(X.prefs.toggles & SOUND_ADMINHELP)
X << 'sound/effects/adminhelp.ogg'
X << msg
else
usr << "<b>Admins have been notified.</b>"
message_admins("[src.ckey] has bumped their adminhelp #[T.ID].")
src.verbs -= /client/verb/adminhelp
adminhelptimerid = addtimer(src,"giveadminhelpverb",1200, FALSE)
return
usr << "<b>Thank you for your patience.</b>"
return
src.verbs -= /client/verb/adminhelp
adminhelptimerid = addtimer(src,"giveadminhelpverb",1200, FALSE)
//clean the input msg
if(!msg)
return
if(!msg) return
msg = sanitize(copytext(msg,1,MAX_MESSAGE_LEN))
if(!msg) return
var/original_msg = msg
//remove our adminhelp verb temporarily to prevent spamming of admins.
src.verbs -= /client/verb/adminhelp
adminhelptimerid = addtimer(src, "giveadminhelpverb", 1200, TIMER_NORMAL) //2 minute cooldown of admin helps
msg = keywords_lookup(msg)
if(!mob)
return //this doesn't happen
if(!mob) return //this doesn't happen
var/ref_mob = "\ref[mob]"
var/ref_client = "\ref[src]"
msg = "<span class='adminnotice'><b><font color=red>HELP: </font><A HREF='?priv_msg=[ckey];ahelp_reply=1'>[key_name(src)]</A> (<A HREF='?_src_=holder;adminmoreinfo=[ref_mob]'>?</A>) (<A HREF='?_src_=holder;adminplayeropts=[ref_mob]'>PP</A>) (<A HREF='?_src_=vars;Vars=[ref_mob]'>VV</A>) (<A HREF='?_src_=holder;subtlemessage=[ref_mob]'>SM</A>) (<A HREF='?_src_=holder;adminplayerobservefollow=[ref_mob]'>FLW</A>) (<A HREF='?_src_=holder;traitor=[ref_mob]'>TP</A>) (<A HREF='?_src_=holder;rejectadminhelp=[ref_client]'>REJT</A>):</b> [msg]</span>"
createticket(src, msg, src.ckey, mob)
var/datum/adminticket/ticket
for(var/datum/adminticket/T in admintickets)
if(T.permckey == src.ckey)
ticket = T
msg = "<span class='adminnotice'><b><font color=red>ADMINHELP: </font><A HREF='?priv_msg=[ckey];ahelp_reply=1'>[key_name(src)]</A> (<A HREF='?_src_=holder;adminmoreinfo=[ref_mob]'>?</A>) (<A HREF='?_src_=holder;adminplayeropts=[ref_mob]'>PP</A>) (<A HREF='?_src_=vars;Vars=[ref_mob]'>VV</A>) (<A HREF='?_src_=holder;subtlemessage=[ref_mob]'>SM</A>) (<A HREF='?_src_=holder;traitor=[ref_mob]'>TP</A>) (<A HREF='?_src_=holder;adminplayerobservefollow=[ref_mob]'>FLW</A>) (<a href='?src=\ref[ticket];resolve=\ref[ticket]'>R</a>):</b> [msg]</span>"
//send this msg to all admins
for(var/client/X in admins)
if(X.prefs.toggles & SOUND_ADMINHELP)
X << 'sound/effects/adminhelp.ogg'
window_flash(X)
X << msg
//show it to the person adminhelping too
src << "<span class='adminnotice'>PM to-<b>Admins</b>: [original_msg]</span>"
//send it to irc if nobody is on and tell us how many were on
var/admin_number_present = send2irc_adminless_only(ckey,original_msg)
log_admin("HELP: [key_name(src)]: [original_msg] - heard by [admin_number_present] non-AFK admins who have +BAN.")
@@ -169,19 +185,4 @@
message["key"] = global.comms_key
message["crossmessage"] = type
world.Export("[global.cross_address]?[list2params(message)]")
/proc/ircadminwho()
var/msg = "Admins: "
for(var/client/C in admins)
msg += "[C] "
if(C.holder.fakekey)
msg += "(Stealth)"
if(C.is_afk())
msg += "(AFK)"
msg += ", "
return msg
world.Export("[global.cross_address]?[list2params(message)]")
+2 -2
View File
@@ -20,9 +20,9 @@
var/list/client/targets[0]
for(var/client/T)
if(T.mob)
if(isnewplayer(T.mob))
if(istype(T.mob, /mob/new_player))
targets["(New Player) - [T]"] = T
else if(isobserver(T.mob))
else if(istype(T.mob, /mob/dead/observer))
targets["[T.mob.name](Ghost) - [T]"] = T
else
targets["[T.mob.real_name](as [T.mob.name]) - [T]"] = T
+2 -2
View File
@@ -24,8 +24,8 @@
T.break_tile()
target << "<span class='userdanger'>You're hit by bluespace artillery!</span>"
log_admin("[key_name(target)] has been hit by Bluespace Artillery fired by [key_name(usr)]")
message_admins("[ADMIN_LOOKUPFLW(target)] has been hit by Bluespace Artillery fired by [ADMIN_LOOKUPFLW(usr)]")
log_admin("[target.name] has been hit by Bluespace Artillery fired by [usr]")
message_admins("[target.name] has been hit by Bluespace Artillery fired by [usr]")
if(target.health <= 1)
target.gib(1, 1)
+9 -9
View File
@@ -242,34 +242,34 @@
. = 1
switch(mode)
if(BASIC_BUILDMODE)
if(isturf(object) && left_click && !alt_click && !ctrl_click)
if(istype(object,/turf) && left_click && !alt_click && !ctrl_click)
var/turf/T = object
if(isspaceturf(object))
if(istype(object,/turf/open/space))
T.ChangeTurf(/turf/open/floor/plasteel)
else if(isfloorturf(object))
else if(istype(object,/turf/open/floor))
T.ChangeTurf(/turf/closed/wall)
else if(iswallturf(object))
else if(istype(object,/turf/closed/wall))
T.ChangeTurf(/turf/closed/wall/r_wall)
log_admin("Build Mode: [key_name(user)] built [T] at ([T.x],[T.y],[T.z])")
return
else if(right_click)
log_admin("Build Mode: [key_name(user)] deleted [object] at ([object.x],[object.y],[object.z])")
if(iswallturf(object))
if(istype(object,/turf/closed/wall))
var/turf/T = object
T.ChangeTurf(/turf/open/floor/plasteel)
else if(isfloorturf(object))
else if(istype(object,/turf/open/floor))
var/turf/T = object
T.ChangeTurf(/turf/open/space)
else if(istype(object,/turf/closed/wall/r_wall))
var/turf/T = object
T.ChangeTurf(/turf/closed/wall)
else if(isobj(object))
else if(istype(object,/obj))
qdel(object)
return
else if(isturf(object) && alt_click && left_click)
else if(istype(object,/turf) && alt_click && left_click)
log_admin("Build Mode: [key_name(user)] built an airlock at ([object.x],[object.y],[object.z])")
new/obj/machinery/door/airlock(get_turf(object))
else if(isturf(object) && ctrl_click && left_click)
else if(istype(object,/turf) && ctrl_click && left_click)
switch(build_dir)
if(NORTH)
var/obj/structure/window/reinforced/WIN = new/obj/structure/window/reinforced(get_turf(object))
+1 -1
View File
@@ -24,7 +24,7 @@
var/rendered = "<span class='game deadsay'><span class='prefix'>DEAD:</span> <span class='name'>ADMIN([src.holder.fakekey ? pick(nicknames) : src.key])</span> says, <span class='message'>\"[msg]\"</span></span>"
for (var/mob/M in player_list)
if(isnewplayer(M))
if (istype(M, /mob/new_player))
continue
if (M.stat == DEAD || (M.client && M.client.holder && (M.client.prefs.chat_toggles & CHAT_DEAD))) //admins can toggle deadchat on and off. This is a proc in admin.dm and is only give to Administrators and above
M.show_message(rendered, 2)
+103 -90
View File
@@ -33,17 +33,36 @@ But you can call procs that are of type /mob/living/carbon/human/proc/ for that
if(!check_rights(R_DEBUG)) return
var/datum/target = null
var/target = null
var/targetselected = 0
var/returnval = null
var/class = null
switch(alert("Proc owned by something?",,"Yes","No"))
if("Yes")
targetselected = 1
var/list/value = vv_get_value(default_class = VV_ATOM_REFERENCE, classes = list(VV_ATOM_REFERENCE, VV_DATUM_REFERENCE, VV_MOB_REFERENCE, VV_CLIENT))
if (!value["class"] || !value["value"])
return
target = value["value"]
if(src.holder && src.holder.marked_datum)
class = input("Proc owned by...","Owner",null) as null|anything in list("Obj","Mob","Area or Turf","Client","Marked datum ([holder.marked_datum.type])")
if(class == "Marked datum ([holder.marked_datum.type])")
class = "Marked datum"
else
class = input("Proc owned by...","Owner",null) as null|anything in list("Obj","Mob","Area or Turf","Client")
switch(class)
if("Obj")
target = input("Enter target:","Target",usr) as obj in world
if("Mob")
target = input("Enter target:","Target",usr) as mob in world
if("Area or Turf")
target = input("Enter target:","Target",usr.loc) as area|turf in world
if("Client")
var/list/keys = list()
for(var/client/C)
keys += C
target = input("Please, select a player!", "Selection", null, null) as null|anything in keys
if("Marked datum")
target = holder.marked_datum
else
return
if("No")
target = null
targetselected = 0
@@ -51,9 +70,8 @@ But you can call procs that are of type /mob/living/carbon/human/proc/ for that
var/procname = input("Proc path, eg: /proc/fake_blood","Path:", null) as text|null
if(!procname)
return
if(targetselected && !hascall(target,procname))
usr << "<font color='red'>Error: callproc(): type [target.type] has no proc named [procname].</font>"
usr << "<font color='red'>Error: callproc(): target has no such call [procname].</font>"
return
else
var/procpath = text2path(procname)
@@ -81,7 +99,7 @@ But you can call procs that are of type /mob/living/carbon/human/proc/ for that
usr << .
feedback_add_details("admin_verb","APC") //If you are copy-pasting this, ensure the 2nd parameter is unique to the new proc!
/client/proc/callproc_datum(datum/A as null|area|mob|obj|turf)
/client/proc/callproc_datum(A as null|area|mob|obj|turf)
set category = "Debug"
set name = "Atom ProcCall"
set waitfor = 0
@@ -93,7 +111,7 @@ But you can call procs that are of type /mob/living/carbon/human/proc/ for that
if(!procname)
return
if(!hascall(A,procname))
usr << "<font color='red'>Error: callproc_datum(): type [A.type] has no proc named [procname].</font>"
usr << "<span class='warning'>Error: callproc_datum(): target has no such call [procname].</span>"
return
var/list/lst = get_callproc_args()
if(!lst)
@@ -115,17 +133,59 @@ But you can call procs that are of type /mob/living/carbon/human/proc/ for that
/client/proc/get_callproc_args()
var/argnum = input("Number of arguments","Number:",0) as num|null
if(isnull(argnum))
if(!argnum && (argnum!=0))
return
var/list/lst = list()
//TODO: make a list to store whether each argument was initialised as null.
//Reason: So we can abort the proccall if say, one of our arguments was a mob which no longer exists
//this will protect us from a fair few errors ~Carn
while(argnum--)
var/value = vv_get_value(restricted_classes = list(VV_RESTORE_DEFAULT))
if (!value["class"])
return
lst += value["value"]
var/class = null
// Make a list with each index containing one variable, to be given to the proc
if(src.holder && src.holder.marked_datum)
class = input("What kind of variable?","Variable Type") in list("text","num","type","reference","mob reference","icon","file","client","mob's area","Marked datum ([holder.marked_datum.type])","CANCEL")
if(holder.marked_datum && class == "Marked datum ([holder.marked_datum.type])")
class = "Marked datum"
else
class = input("What kind of variable?","Variable Type") in list("text","num","type","reference","mob reference","icon","file","client","mob's area","CANCEL")
switch(class)
if("CANCEL")
return null
if("text")
lst += input("Enter new text:","Text",null) as text
if("num")
lst += input("Enter new number:","Num",0) as num
if("type")
lst += input("Enter type:","Type") in typesof(/obj,/mob,/area,/turf)
if("reference")
lst += input("Select reference:","Reference",src) as mob|obj|turf|area in world
if("mob reference")
lst += input("Select reference:","Reference",usr) as mob in world
if("file")
lst += input("Pick file:","File") as file
if("icon")
lst += input("Pick icon:","Icon") as icon
if("client")
var/list/keys = list()
for(var/mob/M in world)
keys += M.client
lst += input("Please, select a player!", "Selection", null, null) as null|anything in keys
if("mob's area")
var/mob/temp = input("Select mob", "Selection", usr) as mob in world
lst += temp.loc
if("Marked datum")
lst += holder.marked_datum
return lst
@@ -150,7 +210,7 @@ But you can call procs that are of type /mob/living/carbon/human/proc/ for that
. += "</font>"
else
. = "<font color='blue'>[procname] returned: [!isnull(returnval) ? returnval : "null"]</font>"
. = "<font color='blue'>[procname] returned: [returnval ? returnval : "null"]</font>"
/client/proc/Cell()
@@ -160,7 +220,7 @@ But you can call procs that are of type /mob/living/carbon/human/proc/ for that
return
var/turf/T = mob.loc
if(!isturf(T))
if (!( istype(T, /turf) ))
return
var/datum/gas_mixture/env = T.return_air()
@@ -181,7 +241,7 @@ But you can call procs that are of type /mob/living/carbon/human/proc/ for that
if(!ticker || !ticker.mode)
alert("Wait until the game starts")
return
if(ishuman(M))
if(istype(M, /mob/living/carbon/human))
log_admin("[key_name(src)] has robotized [M.key].")
var/mob/living/carbon/human/H = M
spawn(0)
@@ -197,11 +257,11 @@ But you can call procs that are of type /mob/living/carbon/human/proc/ for that
if(!ticker || !ticker.mode)
alert("Wait until the game starts")
return
if(ishuman(M))
if(istype(M, /mob/living/carbon/human))
log_admin("[key_name(src)] has blobized [M.key].")
var/mob/living/carbon/human/H = M
spawn(0)
var/mob/camera/blob/B = H.become_overmind(FALSE)
var/mob/camera/blob/B = H.become_overmind()
B.place_blob_core(B.base_point_rate, -1) //place them wherever they are
else
@@ -220,7 +280,7 @@ But you can call procs that are of type /mob/living/carbon/human/proc/ for that
alert("That mob doesn't seem to exist, close the panel and try again.")
return
if(isnewplayer(M))
if(istype(M, /mob/new_player))
alert("The mob must not be a new_player.")
return
@@ -241,7 +301,7 @@ But you can call procs that are of type /mob/living/carbon/human/proc/ for that
var/mob/choice = input("Choose a player to play the pAI", "Spawn pAI") in available
if(!choice)
return 0
if(!isobserver(choice))
if(!istype(choice, /mob/dead/observer))
var/confirm = input("[choice.key] isn't ghosting right now. Are you sure you want to yank him out of them out of their body and place them in this pAI?", "Spawn pAI Confirmation", "No") in list("Yes", "No")
if(confirm != "Yes")
return 0
@@ -298,51 +358,26 @@ var/list/TYPES_SHORTCUTS = list(
/obj/item/weapon/reagent_containers/food/drinks = "DRINK", //longest paths comes first
/obj/item/weapon/reagent_containers/food = "FOOD",
/obj/item/weapon/reagent_containers = "REAGENT_CONTAINERS",
/obj/item/weapon = "WEAPON",
/obj/machinery/atmospherics = "ATMOS_MECH",
/obj/machinery/atmospherics = "ATMOS",
/obj/machinery/portable_atmospherics = "PORT_ATMOS",
/obj/item/mecha_parts/mecha_equipment/weapon/ballistic/launcher/missile_rack = "MECHA_MISSILE_RACK",
/obj/item/mecha_parts/mecha_equipment = "MECHA_EQUIP",
/obj/item/organ = "ORGAN",
/obj/item = "ITEM",
/obj/machinery = "MACHINERY",
/obj/effect = "EFFECT",
/obj = "O",
/datum = "D",
/turf/open = "OPEN",
/turf/closed = "CLOSED",
/turf = "T",
/mob/living/carbon = "CARBON",
/mob/living/simple_animal = "SIMPLE",
/mob/living = "LIVING",
/mob = "M"
)
/proc/make_types_fancy(var/list/types)
if (ispath(types))
types = list(types)
. = list()
for(var/type in types)
var/typename = "[type]"
for (var/tn in TYPES_SHORTCUTS)
if (copytext(typename,1, length("[tn]/")+1)=="[tn]/" /*findtextEx(typename,"[tn]/",1,2)*/ )
typename = TYPES_SHORTCUTS[tn]+copytext(typename,length("[tn]/"))
break
.[typename] = type
/proc/get_fancy_list_of_atom_types()
var/static/list/pre_generated_list
if (!pre_generated_list) //init
pre_generated_list = make_types_fancy(typesof(/atom))
return pre_generated_list
/proc/get_fancy_list_of_datum_types()
var/static/list/pre_generated_list
if (!pre_generated_list) //init
pre_generated_list = make_types_fancy(sortList(typesof(/datum) - typesof(/atom)))
return pre_generated_list
var/global/list/g_fancy_list_of_types = null
/proc/get_fancy_list_of_types()
if (isnull(g_fancy_list_of_types)) //init
var/list/temp = sortList(subtypesof(/atom) - typesof(/area) - /atom/movable)
g_fancy_list_of_types = new(temp.len)
for(var/type in temp)
var/typename = "[type]"
for (var/tn in TYPES_SHORTCUTS)
if (copytext(typename,1, length("[tn]/")+1)=="[tn]/" /*findtextEx(typename,"[tn]/",1,2)*/ )
typename = TYPES_SHORTCUTS[tn]+copytext(typename,length("[tn]/"))
break
g_fancy_list_of_types[typename] = type
return g_fancy_list_of_types
/proc/filter_fancy_list(list/L, filter as text)
var/list/matches = new
@@ -357,7 +392,7 @@ var/list/TYPES_SHORTCUTS = list(
set category = "Debug"
set name = "Del-All"
var/list/matches = get_fancy_list_of_atom_types()
var/list/matches = get_fancy_list_of_types()
if (!isnull(object) && object!="")
matches = filter_fancy_list(matches, object)
@@ -392,7 +427,7 @@ var/list/TYPES_SHORTCUTS = list(
if(!ticker || !ticker.mode)
alert("Wait until the game starts")
return
if(ishuman(M))
if (istype(M, /mob/living/carbon/human))
var/mob/living/carbon/human/H = M
var/obj/item/worn = H.wear_id
var/obj/item/weapon/card/id/id = null
@@ -538,6 +573,7 @@ var/list/TYPES_SHORTCUTS = list(
if(!ishuman(M))
alert("Invalid mob")
return
//log_admin("[key_name(src)] has alienized [M.key].")
var/list/outfits = list("Naked","Custom","As Job...")
@@ -570,7 +606,9 @@ var/list/TYPES_SHORTCUTS = list(
return
feedback_add_details("admin_verb","SEQ") //If you are copy-pasting this, ensure the 2nd parameter is unique to the new proc!
for (var/obj/item/I in M.get_equipped_items())
for (var/obj/item/I in M)
if (istype(I, /obj/item/weapon/implant))
continue
qdel(I)
switch(dresscode)
if ("Naked")
@@ -592,6 +630,7 @@ var/list/TYPES_SHORTCUTS = list(
log_admin("[key_name(usr)] changed the equipment of [key_name(M)] to [dresscode].")
message_admins("<span class='adminnotice'>[key_name_admin(usr)] changed the equipment of [key_name_admin(M)] to [dresscode]..</span>")
return
/client/proc/startSinglo()
@@ -727,30 +766,4 @@ var/list/TYPES_SHORTCUTS = list(
var/datum/map_template/ruin/template = landmark.ruin_template
usr.forceMove(get_turf(landmark))
usr << "<span class='name'>[template.name]</span>"
usr << "<span class='italics'>[template.description]</span>"
/client/proc/clear_dynamic_transit()
set category = "Debug"
set name = "Clear Dynamic Transit"
set desc = "Deallocates all transit space, restoring it to round start \
conditions."
if(!holder)
return
SSshuttle.clear_transit = TRUE
message_admins("<span class='adminnotice'>[key_name_admin(src)] cleared dynamic transit space.</span>")
feedback_add_details("admin_verb","CDT") // If...
log_admin("[key_name(src)] cleared dynamic transit space.")
/client/proc/toggle_medal_disable()
set category = "Debug"
set name = "Toggle Medal Disable"
set desc = "Toggles the safety lock on trying to contact the medal hub."
if(!holder)
return
global.medals_enabled = !global.medals_enabled
message_admins("<span class='adminnotice'>[key_name_admin(src)] [global.medals_enabled ? "disabled" : "enabled"] the medal hub lockout.</span>")
feedback_add_details("admin_verb","TMH") // If...
log_admin("[key_name(src)] [global.medals_enabled ? "disabled" : "enabled"] the medal hub lockout.")
usr << "<span class='italics'>[template.description]</span>"
+1 -1
View File
@@ -8,7 +8,7 @@
var/datum/gas_mixture/GM = target.return_air()
var/list/GM_gases
var/burning = 0
if(isopenturf(target))
if(istype(target, /turf/open))
var/turf/open/T = target
if(T.active_hotspot)
burning = 1
+9 -9
View File
@@ -1,24 +1,24 @@
//replaces the old Ticklag verb, fps is easier to understand
/client/proc/set_server_fps()
/client/proc/set_fps()
set category = "Debug"
set name = "Set server fps"
set name = "Set fps"
set desc = "Sets game speed in frames-per-second. Can potentially break the game"
if(!check_rights(R_DEBUG))
return
var/new_fps = round(input("Sets game frames-per-second. Can potentially break the game (default: [config.fps])","FPS", world.fps) as num|null)
var/fps = round(input("Sets game frames-per-second. Can potentially break the game","FPS", config.fps) as num|null)
if(new_fps <= 0)
src << "<span class='danger'>Error: set_server_fps(): Invalid world.fps value. No changes made.</span>"
if(fps <= 0)
src << "<span class='danger'>Error: ticklag(): Invalid world.ticklag value. No changes made.</span>"
return
if(new_fps > config.fps*1.5)
if(alert(src, "You are setting fps to a high value:\n\t[new_fps] frames-per-second\n\tconfig.fps = [config.fps]","Warning!","Confirm","ABORT-ABORT-ABORT") != "Confirm")
if(fps > config.fps)
if(alert(src, "You are setting fps to a high value:\n\t[fps] frames-per-second\n\tconfig.fps = [config.fps]","Warning!","Confirm","ABORT-ABORT-ABORT") != "Confirm")
return
var/msg = "[key_name(src)] has modified world.fps to [new_fps]"
var/msg = "[key_name(src)] has modified world.fps to [fps]"
log_admin(msg, 0)
message_admins(msg, 0)
feedback_add_details("admin_verb","TICKLAG") //If you are copy-pasting this, ensure the 2nd parameter is unique to the new proc!
world.fps = new_fps
world.fps = fps
@@ -26,12 +26,10 @@
organ.implant(C)
if("drop organ/implant", "remove organ/implant")
for(var/X in C.internal_organs)
var/obj/item/organ/I = X
for(var/obj/item/organ/I in C.internal_organs)
organs["[I.name] ([I.type])"] = I
for(var/X in C.implants)
var/obj/item/weapon/implant/I = X
for(var/obj/item/weapon/implant/I in C)
organs["[I.name] ([I.type])"] = I
var/obj/item/organ = input("Select organ/implant:", "Organ Manipulation", null) in organs
+1 -1
View File
@@ -33,7 +33,7 @@ var/list/admin_verbs_debug_mapping = list(
/client/proc/count_objects_all,
/client/proc/cmd_assume_direct_control, //-errorage
/client/proc/startSinglo,
/client/proc/set_server_fps, //allows you to set the ticklag.
/client/proc/set_fps, //allows you to set the ticklag.
/client/proc/cmd_admin_grantfullaccess,
/client/proc/cmd_admin_areatest,
/client/proc/cmd_admin_rejuvenate,
+475 -203
View File
@@ -3,32 +3,46 @@
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 items)
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)
method = vv_subtype_prompt(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)
/client/proc/massmodify_variables(atom/O, var_name = "", method = 0)
if(!check_rights(R_VAREDIT))
return
if(!istype(O))
return
for(var/p in forbidden_varedit_object_types)
if( istype(O,p) )
usr << "<span class='danger'>It is forbidden to edit this object's variables.</span>"
return
var/list/names = list()
for (var/V in O.vars)
names += V
names = sortList(names)
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
variable = input("Which var?","Var") as null|anything in names
else
variable = var_name
@@ -36,9 +50,10 @@
return
var/default
var/var_value = O.vars[variable]
var/dir
if(variable in VVckey_edit)
src << "It's forbidden to mass-modify ckeys. It'll crash everyone's client you dummy."
usr << "It's forbidden to mass-modify ckeys. I'll crash everyone's client you dummy."
return
if(variable in VVlocked)
if(!check_rights(R_DEBUG))
@@ -46,221 +61,478 @@
if(variable in VVicon_edit_lock)
if(!check_rights(R_FUN|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(var_value))
usr << "Unable to determine variable type."
else if(isnum(var_value))
usr << "Variable appears to be <b>NUM</b>."
default = "num"
setDir(1)
else if(istext(var_value))
usr << "Variable appears to be <b>TEXT</b>."
default = "text"
else if(isloc(var_value))
usr << "Variable appears to be <b>REFERENCE</b>."
default = "reference"
else if(isicon(var_value))
usr << "Variable appears to be <b>ICON</b>."
var_value = "\icon[var_value]"
default = "icon"
else if(istype(var_value,/atom) || istype(var_value,/datum))
usr << "Variable appears to be <b>TYPE</b>."
default = "type"
else if(istype(var_value,/list))
usr << "Variable appears to be <b>LIST</b>."
default = "list"
else if(istype(var_value,/client))
usr << "Variable appears to be <b>CLIENT</b>."
default = "cancel"
if(isnull(default))
src << "Unable to determine variable type."
else
src << "Variable appears to be <b>[uppertext(default)]</b>."
usr << "Variable appears to be <b>FILE</b>."
default = "file"
src << "Variable contains: [var_value]"
usr << "Variable contains: [var_value]"
if(dir)
switch(var_value)
if(1)
setDir("NORTH")
if(2)
setDir("SOUTH")
if(4)
setDir("EAST")
if(8)
setDir("WEST")
if(5)
setDir("NORTHEAST")
if(6)
setDir("SOUTHEAST")
if(9)
setDir("NORTHWEST")
if(10)
setDir("SOUTHWEST")
else
setDir(null)
if(dir)
usr << "If a direction, direction is: [dir]"
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"
var/class = input("What kind of variable?","Variable Type",default) as null|anything in list("text",
"num","type","icon","file","edit referenced object","restore to default")
if(dir_text)
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)
if(!class)
return
if (class == VV_MESSAGE)
class = VV_TEXT
var/original_name
if (value["type"])
class = VV_NEW_TYPE
var/original_name = "[O]"
var/rejected = 0
var/accepted = 0
if (!istype(O, /atom))
original_name = "\ref[O] ([O])"
else
original_name = O:name
switch(class)
if(VV_RESTORE_DEFAULT)
src << "Finding items..."
var/list/items = get_all_of_type(O.type, method)
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
if("restore to default")
O.vars[variable] = initial(O.vars[variable])
if(method)
if(istype(O, /mob))
for(var/mob/M in mob_list)
if ( istype(M , O.type) )
M.vars[variable] = O.vars[variable]
CHECK_TICK
else if(istype(O, /obj))
for(var/obj/A in world)
if ( istype(A , O.type) )
A.vars[variable] = O.vars[variable]
CHECK_TICK
else if(istype(O, /turf))
for(var/turf/A in world)
if ( istype(A , O.type) )
A.vars[variable] = O.vars[variable]
CHECK_TICK
else
if(istype(O, /mob))
for(var/mob/M in mob_list)
if (M.type == O.type)
M.vars[variable] = O.vars[variable]
CHECK_TICK
else if(istype(O, /obj))
for(var/obj/A in world)
if (A.type == O.type)
A.vars[variable] = O.vars[variable]
CHECK_TICK
else if(istype(O, /turf))
for(var/turf/A in world)
if (A.type == O.type)
A.vars[variable] = O.vars[variable]
CHECK_TICK
if("edit referenced object")
return .(O.vars[variable])
if("text")
var/new_value = input("Enter new text:","Text",O.vars[variable]) as message|null
if(new_value == null) return
var/process_vars = 0
var/unique = 0
if(findtext(new_value,"\["))
process_vars = alert(usr,"\[] detected in string, process as variables?","Process Variables?","Yes","No")
if(process_vars == "Yes")
process_vars = 1
unique = alert(usr,"Process vars unique to each instance, or same for all?","Variable Association","Unique","Same")
if(unique == "Unique")
unique = 1
else
unique = 0
else
unique = FALSE
process_vars = 0
var/pre_processing = new_value
var/list/varsvars = list()
if(process_vars)
varsvars = string2listofvars(new_value, O)
if(varsvars.len)
for(var/V in varsvars)
new_value = replacetext(new_value,"\[[V]]","[O.vars[V]]")
src << "Finding items..."
var/list/items = get_all_of_type(O.type, method)
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]]")
O.vars[variable] = new_value
if (D.vv_edit_var(variable, new_value) != FALSE)
accepted++
else
rejected++
CHECK_TICK
//Convert the string vars for anything that's not O
if(method)
if(istype(O, /mob))
for(var/mob/M in mob_list)
if ( istype(M , O.type) )
new_value = pre_processing //reset new_value, ready to convert it uniquely for the next iteration
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
if(process_vars)
if(unique)
for(var/V in varsvars)
new_value = replacetext(new_value,"\[[V]]","[M.vars[V]]")
else
new_value = O.vars[variable] //We already processed the non-unique form for O, reuse it
M.vars[variable] = new_value
CHECK_TICK
else if(istype(O, /obj))
for(var/obj/A in world)
if ( istype(A , O.type) )
new_value = pre_processing
if(process_vars)
if(unique)
for(var/V in varsvars)
new_value = replacetext(new_value,"\[[V]]","[A.vars[V]]")
else
new_value = O.vars[variable]
A.vars[variable] = new_value
CHECK_TICK
else if(istype(O, /turf))
for(var/turf/A in world)
if ( istype(A , O.type) )
new_value = pre_processing
if(process_vars)
if(unique)
for(var/V in varsvars)
new_value = replacetext(new_value,"\[[V]]","[A.vars[V]]")
else
new_value = O.vars[variable]
A.vars[variable] = new_value
CHECK_TICK
else
many = FALSE
if(istype(O, /mob))
for(var/mob/M in mob_list)
if (M.type == O.type)
new_value = pre_processing
var/type = value["type"]
src << "Finding items..."
var/list/items = get_all_of_type(O.type, method)
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(process_vars)
if(unique)
for(var/V in varsvars)
new_value = replacetext(new_value,"\[[V]]","[M.vars[V]]")
else
new_value = O.vars[variable]
if (D.vv_edit_var(variable, new_value) != FALSE)
accepted++
else
rejected++
new_value = null
M.vars[variable] = new_value
CHECK_TICK
else if(istype(O, /obj))
for(var/obj/A in world)
if (A.type == O.type)
new_value = pre_processing
if(process_vars)
if(unique)
for(var/V in varsvars)
new_value = replacetext(new_value,"\[[V]]","[A.vars[V]]")
else
new_value = O.vars[variable]
A.vars[variable] = new_value
CHECK_TICK
else if(istype(O, /turf))
for(var/turf/A in world)
if (A.type == O.type)
new_value = pre_processing
if(process_vars)
if(unique)
for(var/V in varsvars)
new_value = replacetext(new_value,"\[[V]]","[A.vars[V]]")
else
new_value = O.vars[variable]
A.vars[variable] = new_value
CHECK_TICK
if("num")
var/new_value = input("Enter new number:","Num",\
O.vars[variable]) as num|null
if(new_value == null) return
if(variable=="luminosity")
O.set_light(new_value)
else
O.vars[variable] = new_value
if(method)
if(istype(O, /mob))
for(var/mob/M in mob_list)
if ( istype(M , O.type) )
if(variable=="luminosity")
M.set_light(new_value)
else
M.vars[variable] = O.vars[variable]
CHECK_TICK
else if(istype(O, /obj))
for(var/obj/A in world)
if ( istype(A , O.type) )
if(variable=="luminosity")
A.set_light(new_value)
else
A.vars[variable] = O.vars[variable]
CHECK_TICK
else if(istype(O, /turf))
for(var/turf/A in world)
if ( istype(A , O.type) )
if(variable=="luminosity")
A.set_light(new_value)
else
A.vars[variable] = O.vars[variable]
CHECK_TICK
else
if(istype(O, /mob))
for(var/mob/M in mob_list)
if (M.type == O.type)
if(variable=="luminosity")
M.set_light(new_value)
else
M.vars[variable] = O.vars[variable]
CHECK_TICK
else if(istype(O, /obj))
for(var/obj/A in world)
if (A.type == O.type)
if(variable=="luminosity")
A.set_light(new_value)
else
A.vars[variable] = O.vars[variable]
CHECK_TICK
else if(istype(O, /turf))
for(var/turf/A in world)
if (A.type == O.type)
if(variable=="luminosity")
A.set_light(new_value)
else
A.vars[variable] = O.vars[variable]
CHECK_TICK
if("type")
var/new_value
new_value = input("Enter type:","Type",O.vars[variable]) as null|anything in typesof(/obj,/mob,/area,/turf)
if(new_value == null) return
O.vars[variable] = new_value
if(method)
if(istype(O, /mob))
for(var/mob/M in mob_list)
if ( istype(M , O.type) )
M.vars[variable] = O.vars[variable]
CHECK_TICK
else if(istype(O, /obj))
for(var/obj/A in world)
if ( istype(A , O.type) )
A.vars[variable] = O.vars[variable]
CHECK_TICK
else if(istype(O, /turf))
for(var/turf/A in world)
if ( istype(A , O.type) )
A.vars[variable] = O.vars[variable]
CHECK_TICK
else
if(istype(O, /mob))
for(var/mob/M in mob_list)
if (M.type == O.type)
M.vars[variable] = O.vars[variable]
CHECK_TICK
else if(istype(O, /obj))
for(var/obj/A in world)
if (A.type == O.type)
A.vars[variable] = O.vars[variable]
CHECK_TICK
else if(istype(O, /turf))
for(var/turf/A in world)
if (A.type == O.type)
A.vars[variable] = O.vars[variable]
CHECK_TICK
if("file")
var/new_value = input("Pick file:","File",O.vars[variable]) as null|file
if(new_value == null) return
O.vars[variable] = new_value
if(method)
if(istype(O, /mob))
for(var/mob/M in mob_list)
if ( istype(M , O.type) )
M.vars[variable] = O.vars[variable]
CHECK_TICK
else if(istype(O.type, /obj))
for(var/obj/A in world)
if ( istype(A , O.type) )
A.vars[variable] = O.vars[variable]
CHECK_TICK
else if(istype(O.type, /turf))
for(var/turf/A in world)
if ( istype(A , O.type) )
A.vars[variable] = O.vars[variable]
CHECK_TICK
else
if(istype(O, /mob))
for(var/mob/M in mob_list)
if (M.type == O.type)
M.vars[variable] = O.vars[variable]
CHECK_TICK
else if(istype(O, /obj))
for(var/obj/A in world)
if (A.type == O.type)
A.vars[variable] = O.vars[variable]
CHECK_TICK
else if(istype(O, /turf))
for(var/turf/A in world)
if (A.type == O.type)
A.vars[variable] = O.vars[variable]
CHECK_TICK
if("icon")
var/new_value = input("Pick icon:","Icon",O.vars[variable]) as null|icon
if(new_value == null) return
O.vars[variable] = new_value
if(method)
if(istype(O, /mob))
for(var/mob/M in mob_list)
if ( istype(M , O.type) )
M.vars[variable] = O.vars[variable]
CHECK_TICK
else if(istype(O, /obj))
for(var/obj/A in world)
if ( istype(A , O.type) )
A.vars[variable] = O.vars[variable]
CHECK_TICK
else if(istype(O, /turf))
for(var/turf/A in world)
if ( istype(A , O.type) )
A.vars[variable] = O.vars[variable]
CHECK_TICK
else
if(istype(O, /mob))
for(var/mob/M in mob_list)
if (M.type == O.type)
M.vars[variable] = O.vars[variable]
CHECK_TICK
else if(istype(O, /obj))
for(var/obj/A in world)
if (A.type == O.type)
A.vars[variable] = O.vars[variable]
CHECK_TICK
else if(istype(O, /turf))
for(var/turf/A in world)
if (A.type == O.type)
A.vars[variable] = O.vars[variable]
CHECK_TICK
if(method)
if(istype(O,/mob))
for(var/mob/M in mob_list)
if(istype(M,O.type))
M.on_varedit(variable)
CHECK_TICK
else
src << "Finding items..."
var/list/items = get_all_of_type(O.type, method)
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++
else if(istype(O,/obj))
for(var/obj/A in world)
if(istype(A,O.type))
A.on_varedit(variable)
CHECK_TICK
var/count = rejected+accepted
if (!count)
src << "No objects found"
return
if (!accepted)
src << "Every object rejected your edit"
return
if (rejected)
src << "[rejected] out of [count] objects rejected your edit"
world.log << "### 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 mob_list)
if (typecache[thing.type])
. += thing
CHECK_TICK
else if (ispath(T, /obj/machinery/door))
for(var/obj/machinery/door/thing in airlocks)
if (typecache[thing.type])
. += thing
CHECK_TICK
else if (ispath(T, /obj/machinery))
for(var/obj/machinery/thing in 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 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 if(istype(O,/turf))
for(var/turf/A in block(locate(1,1,1),locate(world.maxx,world.maxy,world.maxz)))
if(istype(A,O.type))
A.on_varedit(variable)
CHECK_TICK
else
for(var/datum/thing in world)
if (typecache[thing.type])
. += thing
CHECK_TICK
if(istype(O, /mob))
for(var/mob/M in mob_list)
if(M.type == O.type)
M.on_varedit(variable)
CHECK_TICK
else if(istype(O, /obj))
for(var/obj/A in world)
if(A.type == O.type)
A.on_varedit(variable)
CHECK_TICK
else if(istype(O, /turf))
for(var/turf/A in world)
if(A.type == O.type)
A.on_varedit(variable)
CHECK_TICK
world.log << "### MassVarEdit by [src]: [O.type] [variable]=[html_encode("[O.vars[variable]]")]"
log_admin("[key_name(src)] mass modified [original_name]'s [variable] to [O.vars[variable]]")
message_admins("[key_name_admin(src)] mass modified [original_name]'s [variable] to [O.vars[variable]]")
File diff suppressed because it is too large Load Diff
+15 -15
View File
@@ -11,18 +11,18 @@
/datum/admins/proc/one_click_antag()
var/dat = {"
<a href='?src=\ref[src];makeAntag=traitors'>Make Traitors</a><br>
<a href='?src=\ref[src];makeAntag=changelings'>Make Changelings</a><br>
<a href='?src=\ref[src];makeAntag=revs'>Make Revs</a><br>
<a href='?src=\ref[src];makeAntag=cult'>Make Cult</a><br>
<a href='?src=\ref[src];makeAntag=clockcult'>Make Clockwork Cult</a><br>
<a href='?src=\ref[src];makeAntag=blob'>Make Blob</a><br>
<a href='?src=\ref[src];makeAntag=gangs'>Make Gangsters</a><br>
<a href='?src=\ref[src];makeAntag=wizard'>Make Wizard (Requires Ghosts)</a><br>
<a href='?src=\ref[src];makeAntag=nukeops'>Make Nuke Team (Requires Ghosts)</a><br>
<a href='?src=\ref[src];makeAntag=centcom'>Make Centcom Response Team (Requires Ghosts)</a><br>
<a href='?src=\ref[src];makeAntag=abductors'>Make Abductor Team (Requires Ghosts)</a><br>
<a href='?src=\ref[src];makeAntag=revenant'>Make Revenant (Requires Ghost)</a><br>
<a href='?src=\ref[src];makeAntag=1'>Make Traitors</a><br>
<a href='?src=\ref[src];makeAntag=2'>Make Changelings</a><br>
<a href='?src=\ref[src];makeAntag=3'>Make Revs</a><br>
<a href='?src=\ref[src];makeAntag=4'>Make Cult</a><br>
<a href='?src=\ref[src];makeAntag=15'>Make Clockwork Cult</a><br>
<a href='?src=\ref[src];makeAntag=11'>Make Blob</a><br>
<a href='?src=\ref[src];makeAntag=12'>Make Gangsters</a><br>
<a href='?src=\ref[src];makeAntag=6'>Make Wizard (Requires Ghosts)</a><br>
<a href='?src=\ref[src];makeAntag=7'>Make Nuke Team (Requires Ghosts)</a><br>
<a href='?src=\ref[src];makeAntag=13'>Make Centcom Response Team (Requires Ghosts)</a><br>
<a href='?src=\ref[src];makeAntag=14'>Make Abductor Team (Requires Ghosts)</a><br>
<a href='?src=\ref[src];makeAntag=15'>Make Revenant (Requires Ghost)</a><br>
"}
var/datum/browser/popup = new(usr, "oneclickantag", "Quick-Create Antagonist", 400, 400)
@@ -134,7 +134,7 @@
var/list/mob/dead/observer/candidates = pollCandidates("Do you wish to be considered for the position of a Wizard Foundation 'diplomat'?", "wizard", null)
var/mob/dead/observer/selected = pick_n_take(candidates)
var/mob/dead/observer/selected = popleft(candidates)
var/mob/living/carbon/human/new_character = makeBody(selected)
new_character.mind.make_Wizard()
@@ -239,7 +239,7 @@
if(agentcount < 3)
return 0
var/nuke_code = random_nukecode()
var/nuke_code = "[rand(10000, 99999)]"
var/obj/machinery/nuclearbomb/nuke = locate("syndienuke") in nuke_list
if(nuke)
@@ -552,5 +552,5 @@
return 1
/datum/admins/proc/makeRevenant()
new /datum/round_event/ghost_role/revenant(TRUE, TRUE)
new /datum/round_event/ghost_role/revenant
return 1
+49 -75
View File
@@ -1,77 +1,54 @@
var/highlander = FALSE
/client/proc/only_one() //Gives everyone kilts, berets, claymores, and pinpointers, with the objective to hijack the emergency shuttle.
/client/proc/only_one()
if(!ticker || !ticker.mode)
alert("The game hasn't started yet!")
return
highlander = TRUE
world << "<span class='userdanger'><i>THERE CAN BE ONLY ONE!!!</i></span>"
world << sound('sound/misc/highlander.ogg')
for(var/obj/item/weapon/disk/nuclear/N in poi_list)
N.relocate() //Gets it out of bags and such
for(var/mob/living/carbon/human/H in player_list)
if(H.stat == DEAD || !(H.client))
continue
H.make_scottish()
if(H.stat == 2 || !(H.client)) continue
if(is_special_character(H)) continue
ticker.mode.traitors += H.mind
H.mind.special_role = "traitor"
var/datum/objective/steal/steal_objective = new
steal_objective.owner = H.mind
steal_objective.set_target(new /datum/objective_item/steal/nukedisc)
H.mind.objectives += steal_objective
var/datum/objective/hijack/hijack_objective = new
hijack_objective.owner = H.mind
H.mind.objectives += hijack_objective
H << "<B>You are the traitor.</B>"
var/obj_count = 1
for(var/datum/objective/OBJ in H.mind.objectives)
H << "<B>Objective #[obj_count]</B>: [OBJ.explanation_text]"
obj_count++
for (var/obj/item/I in H)
if (istype(I, /obj/item/weapon/implant))
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/device/radio/headset/heads/captain(H), slot_ears)
H.equip_to_slot_or_del(new /obj/item/clothing/head/beret(H), slot_head)
H.equip_to_slot_or_del(new /obj/item/weapon/claymore(H), slot_l_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/weapon/pinpointer(H.loc), slot_l_store)
var/obj/item/weapon/card/id/W = new(H)
W.icon_state = "centcom"
W.access = get_all_accesses()
W.access += get_all_centcom_access()
W.assignment = "Highlander"
W.registered_name = H.real_name
W.update_label(H.real_name)
H.equip_to_slot_or_del(W, slot_wear_id)
message_admins("<span class='adminnotice'>[key_name_admin(usr)] used THERE CAN BE ONLY ONE!</span>")
log_admin("[key_name(usr)] used THERE CAN BE ONLY ONE.")
addtimer(SSshuttle.emergency, "request", 50, TIMER_NORMAL, null, 1)
log_admin("[key_name(usr)] used there can be only one.")
/mob/living/carbon/human/proc/make_scottish()
ticker.mode.traitors += mind
mind.special_role = "highlander"
dna.species.species_traits |= NOGUNS //nice try jackass
var/datum/objective/steal/steal_objective = new
steal_objective.owner = mind
steal_objective.set_target(new /datum/objective_item/steal/nukedisc)
mind.objectives += steal_objective
var/datum/objective/hijack/hijack_objective = new
hijack_objective.explanation_text = "Escape on the shuttle alone. Ensure that nobody else makes it out."
hijack_objective.owner = mind
mind.objectives += hijack_objective
mind.announce_objectives()
for(var/obj/item/I in get_equipped_items())
qdel(I)
for(var/obj/item/I in held_items)
qdel(I)
equip_to_slot_or_del(new /obj/item/clothing/under/kilt/highlander(src), slot_w_uniform)
equip_to_slot_or_del(new /obj/item/device/radio/headset/heads/captain(src), slot_ears)
equip_to_slot_or_del(new /obj/item/clothing/head/beret/highlander(src), slot_head)
equip_to_slot_or_del(new /obj/item/clothing/shoes/combat(src), slot_shoes)
equip_to_slot_or_del(new /obj/item/weapon/pinpointer(src), slot_l_store)
for(var/obj/item/weapon/pinpointer/P in src)
P.attack_self(src)
var/obj/item/weapon/card/id/W = new(src)
W.icon_state = "centcom"
W.access = get_all_accesses()
W.access += get_all_centcom_access()
W.assignment = "Highlander"
W.registered_name = real_name
W.flags |= NODROP
W.update_label(real_name)
equip_to_slot_or_del(W, slot_wear_id)
var/obj/item/weapon/claymore/highlander/H1 = new(src)
if(!highlander)
H1.admin_spawned = TRUE //To prevent announcing
put_in_hands(H1)
H1.pickup(src) //For the stun shielding
var/obj/item/weapon/bloodcrawl/antiwelder = new(src)
antiwelder.name = "compulsion of honor"
antiwelder.desc = "You are unable to hold anything in this hand until you're the last one left!"
antiwelder.icon_state = "bloodhand_right"
put_in_hands(antiwelder)
src << "<span class='boldannounce'>Your [H1.name] cries out for blood. Join in the slaughter, lest you be claimed yourself...\n\
Activate it in your hand, and it will lead to the nearest target. Attack the nuclear authentication disk with it, and you will store it.</span>"
/proc/only_me()
if(!ticker || !ticker.mode)
@@ -90,21 +67,18 @@ var/highlander = FALSE
H.mind.objectives += hijack_objective
H << "<B>You are the multiverse summoner. Activate your blade to summon copies of yourself from another universe to fight by your side.</B>"
H.mind.announce_objectives()
var/datum/gang/multiverse/G = new(src, "[H.real_name]")
ticker.mode.gangs += G
G.bosses += H.mind
G.add_gang_hud(H.mind)
H.mind.gang_datum = G
var/obj_count = 1
for(var/datum/objective/OBJ in H.mind.objectives)
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_for_held_index(2)
var/obj/item/slot_item_hand = H.get_item_by_slot(slot_r_hand)
H.unEquip(slot_item_hand)
var /obj/item/weapon/multisword/multi = new(H)
H.put_in_hands_or_del(multi)
H.equip_to_slot_or_del(multi, slot_r_hand)
var/obj/item/weapon/card/id/W = new(H)
W.icon_state = "centcom"
+9 -32
View File
@@ -18,26 +18,15 @@
return
var/image/cross = image('icons/obj/storage.dmi',"bible")
var/font_color = "purple"
var/prayer_type = "PRAYER"
var/deity
if(usr.job == "Chaplain")
cross = image('icons/obj/storage.dmi',"kingyellow")
font_color = "blue"
prayer_type = "CHAPLAIN PRAYER"
if(SSreligion.Bible_deity_name)
deity = SSreligion.Bible_deity_name
msg = "<span class='adminnotice'>\icon[cross] <b><font color=blue>CHAPLAIN PRAYER: </font>[key_name_admin(src)] (<A HREF='?_src_=holder;adminmoreinfo=\ref[src]'>?</A>) (<A HREF='?_src_=holder;adminplayeropts=\ref[src]'>PP</A>) (<A HREF='?_src_=vars;Vars=\ref[src]'>VV</A>) (<A HREF='?_src_=holder;subtlemessage=\ref[src]'>SM</A>) (<A HREF='?_src_=holder;adminplayerobservefollow=\ref[src]'>FLW</A>) (<A HREF='?_src_=holder;traitor=\ref[src]'>TP</A>) (<A HREF='?_src_=holder;adminspawncookie=\ref[src]'>SC</a>):</b> [msg]</span>"
else if(iscultist(usr))
cross = image('icons/obj/storage.dmi',"tome")
font_color = "red"
prayer_type = "CULTIST PRAYER"
deity = "Nar-Sie"
msg = "<span class='adminnotice'>\icon[cross] \
<b><font color=[font_color]>[prayer_type][deity ? " (to [deity])" : ""]: </font>\
[ADMIN_FULLMONTY(src)] [ADMIN_SC(src)]:</b> \
[msg]</span>"
msg = "<span class='adminnotice'>\icon[cross] <b><font color=red>CULTIST PRAYER: </font>[key_name_admin(src)] (<A HREF='?_src_=holder;adminmoreinfo=\ref[src]'>?</A>) (<A HREF='?_src_=holder;adminplayeropts=\ref[src]'>PP</A>) (<A HREF='?_src_=vars;Vars=\ref[src]'>VV</A>) (<A HREF='?_src_=holder;subtlemessage=\ref[src]'>SM</A>) (<A HREF='?_src_=holder;adminplayerobservefollow=\ref[src]'>FLW</A>) (<A HREF='?_src_=holder;traitor=\ref[src]'>TP</A>) (<A HREF='?_src_=holder;adminspawncookie=\ref[src]'>SC</a>):</b> [msg]</span>"
else
cross = image('icons/obj/storage.dmi',"bible")
msg = "<span class='adminnotice'>\icon[cross] <b><font color=purple>PRAYER: </font>[key_name_admin(src)] (<A HREF='?_src_=holder;adminmoreinfo=\ref[src]'>?</A>) (<A HREF='?_src_=holder;adminplayeropts=\ref[src]'>PP</A>) (<A HREF='?_src_=vars;Vars=\ref[src]'>VV</A>) (<A HREF='?_src_=holder;subtlemessage=\ref[src]'>SM</A>) (<A HREF='?_src_=holder;adminplayerobservefollow=\ref[src]'>FLW</A>) (<A HREF='?_src_=holder;traitor=\ref[src]'>TP</A>) (<A HREF='?_src_=holder;adminspawncookie=\ref[src]'>SC</a>):</b> [msg]</span>"
for(var/client/C in admins)
if(C.prefs.chat_toggles & CHAT_PRAYER)
C << msg
@@ -51,34 +40,22 @@
/proc/Centcomm_announce(text , mob/Sender)
var/msg = copytext(sanitize(text), 1, MAX_MESSAGE_LEN)
msg = "<span class='adminnotice'>\
<b><font color=orange>CENTCOM:</font>\
[ADMIN_FULLMONTY(Sender)] [ADMIN_BSA(Sender)] \
[ADMIN_CENTCOM_REPLY(Sender)]:</b> \
[msg]</span>"
msg = "<span class='adminnotice'><b><font color=orange>CENTCOM:</font>[key_name_admin(Sender)] (<A HREF='?_src_=holder;adminmoreinfo=\ref[Sender]'>?</A>) (<A HREF='?_src_=holder;adminplayeropts=\ref[Sender]'>PP</A>) (<A HREF='?_src_=vars;Vars=\ref[Sender]'>VV</A>) (<A HREF='?_src_=holder;subtlemessage=\ref[Sender]'>SM</A>) (<A HREF='?_src_=holder;adminplayerobservefollow=\ref[Sender]'>FLW</A>) (<A HREF='?_src_=holder;traitor=\ref[Sender]'>TP</A>) (<A HREF='?_src_=holder;BlueSpaceArtillery=\ref[Sender]'>BSA</A>) (<A HREF='?_src_=holder;CentcommReply=\ref[Sender]'>RPLY</A>):</b> [msg]</span>"
admins << msg
for(var/obj/machinery/computer/communications/C in machines)
C.overrideCooldown()
/proc/Syndicate_announce(text , mob/Sender)
var/msg = copytext(sanitize(text), 1, MAX_MESSAGE_LEN)
msg = "<span class='adminnotice'><b>\
<font color=crimson>SYNDICATE:</font>\
[ADMIN_FULLMONTY(Sender)] [ADMIN_BSA(Sender)] \
[ADMIN_SYNDICATE_REPLY(Sender)]:</b> \
[msg]</span>"
msg = "<span class='adminnotice'><b><font color=crimson>SYNDICATE:</font>[key_name_admin(Sender)] (<A HREF='?_src_=holder;adminmoreinfo=\ref[Sender]'>?</A>) (<A HREF='?_src_=holder;adminplayeropts=\ref[Sender]'>PP</A>) (<A HREF='?_src_=vars;Vars=\ref[Sender]'>VV</A>) (<A HREF='?_src_=holder;subtlemessage=\ref[Sender]'>SM</A>) (<A HREF='?_src_=holder;adminplayerobservefollow=\ref[Sender]'>FLW</A>) (<A HREF='?_src_=holder;traitor=\ref[Sender]'>TP</A>) (<A HREF='?_src_=holder;BlueSpaceArtillery=\ref[Sender]'>BSA</A>) (<A HREF='?_src_=holder;SyndicateReply=\ref[Sender]'>RPLY</A>):</b> [msg]</span>"
admins << msg
for(var/obj/machinery/computer/communications/C in machines)
C.overrideCooldown()
/proc/Nuke_request(text , mob/Sender)
var/msg = copytext(sanitize(text), 1, MAX_MESSAGE_LEN)
msg = "<span class='adminnotice'>\
<b><font color=orange>NUKE CODE REQUEST:</font>\
[ADMIN_FULLMONTY(Sender)] [ADMIN_BSA(Sender)] \
[ADMIN_CENTCOM_REPLY(Sender)] \
[ADMIN_SET_SD_CODE]:</b> \
[msg]</span>"
msg = "<span class='adminnotice'><b><font color=orange>NUKE CODE REQUEST:</font>[key_name_admin(Sender)] (<A HREF='?_src_=holder;adminmoreinfo=\ref[Sender]'>?</A>) (<A HREF='?_src_=holder;adminplayeropts=\ref[Sender]'>PP</A>) (<A HREF='?_src_=vars;Vars=\ref[Sender]'>VV</A>) (<A HREF='?_src_=holder;subtlemessage=\ref[Sender]'>SM</A>) (<A HREF='?_src_=holder;adminplayerobservefollow=\ref[Sender]'>FLW</A>) (<A HREF='?_src_=holder;traitor=\ref[Sender]'>TP</A>) (<A HREF='?_src_=holder;BlueSpaceArtillery=\ref[Sender]'>BSA</A>) (<A HREF='?_src_=holder;CentcommReply=\ref[Sender]'>RPLY</A>):</b> [msg]</span>"
admins << msg
admins << "<span class='adminnotice'><b>At this current time, the nuke must have the code manually set via varedit.</b></span>"
for(var/obj/machinery/computer/communications/C in machines)
C.overrideCooldown()
+14 -47
View File
@@ -70,7 +70,7 @@
return
if(!M)
M = input("Direct narrate to whom?", "Active Players") as null|anything in player_list
M = input("Direct narrate to who?", "Active Players") as null|anything in player_list
if(!M)
return
@@ -521,7 +521,7 @@ Traitors and the like can also be revived with the previous role mostly intact.
feedback_add_details("admin_verb","MFS") //If you are copy-pasting this, ensure the 2nd parameter is unique to the new proc!
/client/proc/cmd_admin_explosion(atom/O as obj|mob|turf in world)
set category = "Special Verbs"
set category = "Abusive"
set name = "Explosion"
if (!holder)
@@ -594,8 +594,8 @@ Traitors and the like can also be revived with the previous role mostly intact.
log_admin("[key_name(usr)] has gibbed [key_name(M)]")
message_admins("[key_name_admin(usr)] has gibbed [key_name_admin(M)]")
if(isobserver(M))
new /obj/effect/gibspawner/generic(M.loc, M.viruses)
if(istype(M, /mob/dead/observer))
gibs(M.loc, M.viruses)
return
if(confirm == "Yes")
M.gib()
@@ -612,7 +612,7 @@ Traitors and the like can also be revived with the previous role mostly intact.
log_admin("[key_name(usr)] used gibself.")
message_admins("<span class='adminnotice'>[key_name_admin(usr)] used gibself.</span>")
feedback_add_details("admin_verb","GIBS") //If you are copy-pasting this, ensure the 2nd parameter is unique to the new proc!
mob.gib(1, 1, 1)
mob.gib(1, 1)
/client/proc/cmd_admin_check_contents(mob/living/M in mob_list)
set category = "Special Verbs"
@@ -689,7 +689,7 @@ Traitors and the like can also be revived with the previous role mostly intact.
/client/proc/everyone_random()
set category = "Fun"
set category = "Abusive"
set name = "Make Everyone Random"
set desc = "Make everyone have a random appearance. You can only use this before rounds!"
@@ -754,32 +754,29 @@ Traitors and the like can also be revived with the previous role mostly intact.
/client/proc/toggle_nuke(obj/machinery/nuclearbomb/N in nuke_list)
set name = "Toggle Nuke"
set category = "Fun"
set category = "Abusive"
set popup_menu = 0
if(!check_rights(R_DEBUG))
return
if(!N.timing)
var/newtime = input(usr, "Set activation timer.", "Activate Nuke", "[N.timer_set]") as num
var/newtime = input(usr, "Set activation timer.", "Activate Nuke", "[N.timeleft]") as num
if(!newtime)
return
N.timer_set = newtime
N.timeleft = newtime
N.set_safety()
N.set_active()
log_admin("[key_name(usr)] [N.timing ? "activated" : "deactivated"] a nuke at ([N.x],[N.y],[N.z]).")
message_admins("[ADMIN_LOOKUPFLW(usr)] [N.timing ? "activated" : "deactivated"] a nuke at [ADMIN_COORDJMP(N)].")
message_admins("[key_name_admin(usr)] (<A HREF='?_src_=holder;adminplayerobservefollow=\ref[usr]'>FLW</A>) [N.timing ? "activated" : "deactivated"] a nuke at ([N.x],[N.y],[N.z] - <A HREF='?_src_=holder;adminplayerobservecoodjump=1;X=[N.x];Y=[N.y];Z=[N.z]'>JMP</a>).")
feedback_add_details("admin_verb","TN") //If you are copy-pasting this, ensure the 2nd parameter is unique to the new proc!
/client/proc/reset_latejoin_spawns()
set category = "Debug"
set category = "Abusive"
set name = "Remove Latejoin Spawns"
if(!check_rights(R_DEBUG))
return
var/confirm = alert(src, "Disable Latejoin spawns??", "Message", "Yes", "No")
if(confirm != "Yes")
return
latejoin.Cut()
@@ -997,7 +994,7 @@ var/list/datum/outfit/custom_outfits = list() //Admin created outfits
M.ui_interact(usr)
/client/proc/mass_zombie_infection()
set category = "Fun"
set category = "Abusive"
set name = "Mass Zombie Infection"
set desc = "Infects all humans with a latent organ that will zombify \
them on death."
@@ -1017,7 +1014,7 @@ var/list/datum/outfit/custom_outfits = list() //Admin created outfits
feedback_add_details("admin_verb","MZI")
/client/proc/mass_zombie_cure()
set category = "Fun"
set category = "Abusive"
set name = "Mass Zombie Cure"
set desc = "Removes the zombie infection from all humans, returning them to normal."
if(!holder)
@@ -1035,7 +1032,7 @@ var/list/datum/outfit/custom_outfits = list() //Admin created outfits
feedback_add_details("admin_verb","MZC")
/client/proc/polymorph_all()
set category = "Fun"
set category = "Abusive"
set name = "Polymorph All"
set desc = "Applies the effects of the bolt of change to every single mob."
@@ -1140,33 +1137,3 @@ var/list/datum/outfit/custom_outfits = list() //Admin created outfits
H.regenerate_icons()
#undef ON_PURRBATION
/client/proc/modify_goals()
set category = "Debug"
set name = "Modify goals"
if(!check_rights(R_ADMIN))
return
holder.modify_goals()
/datum/admins/proc/modify_goals()
var/dat = ""
for(var/datum/station_goal/S in ticker.mode.station_goals)
dat += "[S.name] - <a href='?src=\ref[S];announce=1'>Announce</a> | <a href='?src=\ref[S];remove=1'>Remove</a><br>"
dat += "<br><a href='?src=\ref[src];add_station_goal=1'>Add New Goal</a>"
usr << browse(dat, "window=goals;size=400x400")
/client/proc/toggle_hub()
set category = "Server"
set name = "Toggle Hub"
world.visibility = (!world.visibility)
log_admin("[key_name(usr)] has toggled the server's hub status for the round, it is now [(world.visibility?"on":"off")] the hub.")
message_admins("[key_name_admin(usr)] has toggled the server's hub status for the round, it is now [(world.visibility?"on":"off")] the hub.")
if (world.visibility && !world.reachable)
message_admins("WARNING: The server will not show up on the hub because byond is detecting that a filewall is blocking incoming connections.")
feedback_add_details("admin_verb","HUB") //If you are copy-pasting this, ensure the 2nd parameter is unique to the new proc!
-22
View File
@@ -1,22 +0,0 @@
#define WHITELISTFILE "config/whitelist.txt"
var/list/whitelist
/proc/load_whitelist()
whitelist = list()
for(var/line in file2list(WHITELISTFILE))
if(!line)
continue
if(findtextEx(line,"#",1,2))
continue
whitelist += line
if(!whitelist.len)
whitelist = null
/proc/check_whitelist(var/ckey)
if(!whitelist)
return FALSE
. = (ckey in whitelist)
#undef WHITELISTFILE
+18 -7
View File
@@ -4,7 +4,7 @@
icon = 'icons/obj/assemblies/new_assemblies.dmi'
icon_state = ""
flags = CONDUCT
w_class = WEIGHT_CLASS_SMALL
w_class = 2
materials = list(MAT_METAL=100)
throwforce = 2
throw_speed = 3
@@ -14,6 +14,7 @@
var/secured = 1
var/list/attached_overlays = null
var/obj/item/device/assembly_holder/holder = null
var/cooldown = 0//To prevent spam
var/wire_type = WIRE_RECEIVE | WIRE_PULSE
var/attachable = 0 // can this be attached to wires
var/datum/wires/connected = null
@@ -24,8 +25,6 @@
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
var/next_activate = 0 //When we're next allowed to activate - for spam control
/obj/item/device/assembly/proc/on_attach()
/obj/item/device/assembly/proc/on_detach()
@@ -44,6 +43,16 @@
return 1
//Called via spawn(10) to have it count down the cooldown var
/obj/item/device/assembly/proc/process_cooldown()
cooldown--
if(cooldown <= 0)
return 0
spawn(10)
process_cooldown()
return 1
//Called when another assembly acts on this one, var/radio will determine where it came from for wire calcs
/obj/item/device/assembly/proc/pulsed(radio = 0)
if(wire_type & WIRE_RECEIVE)
@@ -69,10 +78,12 @@
// What the device does when turned on
/obj/item/device/assembly/proc/activate()
if(qdeleted(src) || !secured || (next_activate > world.time))
return FALSE
next_activate = world.time + 30
return TRUE
if(!secured || (cooldown > 0))
return 0
cooldown = 2
spawn(10)
process_cooldown()
return 1
/obj/item/device/assembly/proc/toggle_secure()
+1 -1
View File
@@ -3,7 +3,7 @@
icon = 'icons/obj/tank.dmi'
item_state = "assembly"
throwforce = 5
w_class = WEIGHT_CLASS_NORMAL
w_class = 3
throw_speed = 2
throw_range = 4
flags = CONDUCT
+5 -11
View File
@@ -6,7 +6,6 @@
attachable = 1
var/id = null
var/can_change_id = 0
var/cooldown = 0//Door cooldowns
/obj/item/device/assembly/control/examine(mob/user)
..()
@@ -47,14 +46,13 @@
/obj/item/device/assembly/control/airlock/activate()
cooldown = 1
var/doors_need_closing = FALSE
var/list/obj/machinery/door/airlock/open_or_close = list()
for(var/obj/machinery/door/airlock/D in airlocks)
if(D.id_tag == src.id)
if(specialfunctions & OPEN)
open_or_close += D
if(!D.density)
doors_need_closing = TRUE
if(D.density)
D.open()
else
D.close()
if(specialfunctions & IDSCAN)
D.aiDisabledIdScanner = !D.aiDisabledIdScanner
if(specialfunctions & BOLTS)
@@ -70,10 +68,6 @@
D.secondsElectrified = 0
if(specialfunctions & SAFE)
D.safe = !D.safe
for(var/D in open_or_close)
addtimer(D, doors_need_closing ? "close" : "open",0, TIMER_NORMAL)
sleep(10)
cooldown = 0
@@ -153,4 +147,4 @@
C.cremate(usr)
sleep(50)
cooldown = 0
cooldown = 0
+23 -101
View File
@@ -4,7 +4,7 @@
icon_state = "flash"
item_state = "flashtool"
throwforce = 0
w_class = WEIGHT_CLASS_TINY
w_class = 1
materials = list(MAT_METAL = 300, MAT_GLASS = 300)
origin_tech = "magnets=2;combat=1"
@@ -48,8 +48,7 @@
crit_fail = 1
update_icon()
var/turf/T = get_turf(src)
if(T)
T.visible_message("[src] burns out!")
T.visible_message("The [src.name] burns out!")
/obj/item/device/assembly/flash/proc/flash_recharge(interval=10)
@@ -86,7 +85,7 @@
if(user && targeted)
if(M.weakeyes)
M.Weaken(3) //quick weaken bypasses eye protection but has no eye flash
if(M.flash_act(1, 1))
if(M.flash_eyes(1, 1))
M.confused += power
terrible_conversion_proc(M, user)
M.Stun(1)
@@ -101,7 +100,7 @@
user << "<span class='warning'>You fail to blind [M] with the flash!</span>"
M << "<span class='danger'>[user] fails to blind you with the flash!</span>"
else
if(M.flash_act())
if(M.flash_eyes())
M.confused += power
/obj/item/device/assembly/flash/attack(mob/living/M, mob/user)
@@ -116,9 +115,9 @@
var/mob/living/silicon/robot/R = M
add_logs(user, R, "flashed", src)
update_icon(1)
M.Weaken(6)
M.Weaken(3)
R.confused += 5
R.flash_act(affect_silicon = 1)
R.flash_eyes(affect_silicon = 1)
user.visible_message("<span class='disarm'>[user] overloads [R]'s sensors with the flash!</span>", "<span class='danger'>You overload [R]'s sensors with the flash!</span>")
return 1
@@ -136,10 +135,10 @@
/obj/item/device/assembly/flash/emp_act(severity)
if(!try_use_flash())
if(!try_use_flash() || !loc)
return 0
if(iscarbon(loc))
flash_carbon(loc, null, 10, 0)
for(var/mob/living/carbon/M in viewers(3, loc))
flash_carbon(M, null, 10, 0)
burn_out()
..()
@@ -151,7 +150,7 @@
if(M.stat == CONSCIOUS)
M.mind_initialize() //give them a mind datum if they don't have one.
var/resisted
if(!M.isloyal())
if(!isloyal(M))
if(user.mind in ticker.mode.head_revolutionaries)
if(ticker.mode.add_revolutionary(M.mind))
M.Stun(3)
@@ -174,15 +173,26 @@
/obj/item/device/assembly/flash/cyborg/attack(mob/living/M, mob/user)
..()
PoolOrNew(/obj/effect/overlay/temp/borgflash, get_turf(src))
cyborg_flash_animation(user)
/obj/item/device/assembly/flash/cyborg/attack_self(mob/user)
..()
PoolOrNew(/obj/effect/overlay/temp/borgflash, get_turf(src))
cyborg_flash_animation(user)
/obj/item/device/assembly/flash/cyborg/attackby(obj/item/weapon/W, mob/user, params)
return
/obj/item/device/assembly/flash/cyborg/proc/cyborg_flash_animation(mob/living/user)
var/atom/movable/overlay/animation = new(user.loc)
animation.layer = user.layer + 1
animation.icon_state = "blank"
animation.icon = 'icons/mob/mob.dmi'
animation.master = user
flick("blspell", animation)
sleep(5)
qdel(animation)
/obj/item/device/assembly/flash/memorizer
name = "memorizer"
desc = "If you see this, you're not likely to remember it any time soon."
@@ -191,91 +201,3 @@
item_state = "nullrod"
/obj/item/device/assembly/flash/handheld //this is now the regular pocket flashes
/obj/item/device/assembly/flash/armimplant
name = "photon projector"
desc = "A high-powered photon projector implant normally used for lighting purposes, but also doubles as a flashbulb weapon. Self-repair protocals fix the flashbulb if it ever burns out."
var/flashcd = 20
var/overheat = 0
var/obj/item/organ/cyberimp/arm/flash/I = null
/obj/item/device/assembly/flash/armimplant/burn_out()
if(I && I.owner)
I.owner << "<span class='warning'>Your photon projector implant overheats and deactivates!</span>"
I.Retract()
overheat = FALSE
addtimer(src, "cooldown", flashcd * 2)
/obj/item/device/assembly/flash/armimplant/try_use_flash(mob/user = null)
if(overheat)
if(I && I.owner)
I.owner << "<span class='warning'>Your photon projector is running too hot to be used again so quickly!</span>"
return FALSE
overheat = TRUE
addtimer(src, "cooldown", flashcd)
playsound(src.loc, 'sound/weapons/flash.ogg', 100, 1)
update_icon(1)
return TRUE
/obj/item/device/assembly/flash/armimplant/proc/cooldown()
overheat = FALSE
/obj/item/device/assembly/flash/shield
name = "strobe shield"
desc = "A shield with a built in, high intensity light capable of blinding and disorienting suspects. Takes regular handheld flashes as bulbs."
icon = 'icons/obj/weapons.dmi'
icon_state = "flashshield"
item_state = "flashshield"
slot_flags = SLOT_BACK
force = 10
throwforce = 5
throw_speed = 2
throw_range = 3
w_class = WEIGHT_CLASS_BULKY
materials = list(MAT_GLASS=7500, MAT_METAL=1000)
origin_tech = "materials=3;combat=4"
attack_verb = list("shoved", "bashed")
block_chance = 50
armor = list(melee = 50, bullet = 50, laser = 50, energy = 0, bomb = 30, bio = 0, rad = 0, fire = 80, acid = 70)
/obj/item/device/assembly/flash/shield/flash_recharge(interval=10)
if(times_used >= 4)
burn_out()
return 0
return 1
/obj/item/device/assembly/flash/shield/attackby(obj/item/weapon/W, mob/user)
if(istype(W, /obj/item/device/assembly/flash/handheld))
var/obj/item/device/assembly/flash/handheld/flash = W
if(flash.crit_fail)
user << "No sense replacing it with a broken bulb."
return
else
user << "You begin to replace the bulb."
if(do_after(user, 20, target = src))
if(flash.crit_fail || !flash || qdeleted(flash))
return
crit_fail = FALSE
times_used = 0
playsound(src.loc, 'sound/items/Deconstruct.ogg', 50, 1)
update_icon()
flash.crit_fail = TRUE
flash.update_icon()
return
..()
/obj/item/device/assembly/flash/shield/update_icon(flash = 0)
item_state = "flashshield"
item_state = "flashshield"
if(crit_fail)
icon_state = "riot"
item_state = "riot"
else if(flash)
item_state = "flashshield_flash"
item_state = "flashshield_flash"
addtimer(src, "update_icon", 5)
if(holder)
holder.update_icon()
+1 -1
View File
@@ -5,7 +5,7 @@
item_state = "assembly"
flags = CONDUCT
throwforce = 5
w_class = WEIGHT_CLASS_SMALL
w_class = 2
throw_speed = 2
throw_range = 7
+4 -7
View File
@@ -15,7 +15,8 @@
/obj/item/device/assembly/igniter/Destroy()
qdel(sparks)
sparks = null
. = ..()
return ..()
/obj/item/device/assembly/igniter/activate()
if(!..())
@@ -26,12 +27,8 @@
sparks.start()
return 1
/obj/item/device/assembly/igniter/attack_self(mob/user)
activate()
add_fingerprint(user)
/obj/item/device/assembly/igniter/ignition_effect(atom/A, mob/user)
. = "<span class='notice'>[user] fiddles with [src], and manages to \
light [A].</span>"
activate()
add_fingerprint(user)
return
+5 -3
View File
@@ -92,15 +92,17 @@
/obj/item/device/assembly/infra/holder_movement()
if(!holder)
return 0
// setDir(holder.dir)
qdel(first)
return 1
/obj/item/device/assembly/infra/proc/trigger_beam()
if(!secured || !on || next_activate > world.time)
return FALSE
if((!secured)||(!on)||(cooldown > 0))
return 0
pulse(0)
audible_message("\icon[src] *beep* *beep*", null, 3)
next_activate = world.time + 30
cooldown = 2
addtimer(src, "process_cooldown", 10)
/obj/item/device/assembly/infra/interact(mob/user)//TODO: change this this to the wire control panel
if(is_secured(user))
+17 -15
View File
@@ -43,7 +43,7 @@
var/obj/item/bodypart/affecting = null
if(ishuman(target))
var/mob/living/carbon/human/H = target
if(PIERCEIMMUNE in H.dna.species.species_traits)
if(PIERCEIMMUNE in H.dna.species.specflags)
playsound(src.loc, 'sound/effects/snap.ogg', 50, 1)
armed = 0
update_icon()
@@ -59,8 +59,9 @@
affecting = H.get_bodypart(type)
H.Stun(3)
if(affecting)
if(affecting.receive_damage(1, 0))
H.update_damage_overlays()
if(affecting.take_damage(1, 0))
H.update_damage_overlays(0)
H.updatehealth()
else if(ismouse(target))
var/mob/living/simple_animal/mouse/M = target
visible_message("<span class='boldannounce'>SPLAT!</span>")
@@ -77,7 +78,7 @@
else
if(((user.getBrainLoss() >= 60) || user.disabilities & CLUMSY) && prob(50))
var/which_hand = "l_hand"
if(!(user.active_hand_index % 2))
if(!user.hand)
which_hand = "r_hand"
triggered(user, which_hand)
user.visible_message("<span class='warning'>[user] accidentally sets off [src], breaking their fingers.</span>", \
@@ -93,7 +94,7 @@
if(armed)
if(((user.getBrainLoss() >= 60) || user.disabilities & CLUMSY) && prob(50))
var/which_hand = "l_hand"
if(!(user.active_hand_index % 2))
if(!user.hand)
which_hand = "r_hand"
triggered(user, which_hand)
user.visible_message("<span class='warning'>[user] accidentally sets off [src], breaking their fingers.</span>", \
@@ -104,15 +105,16 @@
/obj/item/device/assembly/mousetrap/Crossed(atom/movable/AM as mob|obj)
if(armed)
if(ismob(AM))
var/mob/MM = AM
if(!(MM.movement_type & FLYING))
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>")
if(ishuman(AM))
var/mob/living/carbon/H = AM
if(H.m_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(isanimal(AM))
var/mob/living/simple_animal/SA = AM
if(!SA.flying)
triggered(AM)
else if(AM.density) // For mousetrap grenades, set off by anything heavy
triggered(AM)
..()
@@ -122,7 +124,7 @@
if(armed)
finder.visible_message("<span class='warning'>[finder] accidentally sets off [src], breaking their fingers.</span>", \
"<span class='warning'>You accidentally trigger [src]!</span>")
triggered(finder, (finder.active_hand_index % 2 == 0) ? "r_hand" : "l_hand")
triggered(finder, finder.hand ? "l_hand" : "r_hand")
return 1 //end the search!
return 0
+3 -5
View File
@@ -59,11 +59,12 @@
/obj/item/device/assembly/prox_sensor/sense()
if(!secured || next_activate > world.time)
if((!secured)||(cooldown > 0))
return 0
pulse(0)
audible_message("\icon[src] *beep* *beep*", null, 3)
next_activate = world.time + 30
cooldown = 2
addtimer(src, "process_cooldown", 10)
/obj/item/device/assembly/prox_sensor/process()
@@ -80,9 +81,6 @@
if(scanning)
addtimer(src, "sense", 0)
/obj/item/device/assembly/prox_sensor/Destroy()
remove_from_proximity_list(src, sensitivity)
..()
/obj/item/device/assembly/prox_sensor/toggle_scan(scan)
if(!secured)
+1 -1
View File
@@ -5,7 +5,7 @@
icon_state = "shock_kit"
var/obj/item/clothing/head/helmet/part1 = null
var/obj/item/device/electropack/part2 = null
w_class = WEIGHT_CLASS_HUGE
w_class = 5
flags = CONDUCT
/obj/item/assembly/shock_kit/Destroy()
+8 -4
View File
@@ -25,10 +25,14 @@
return ..()
/obj/item/device/assembly/signaler/activate()
if(!..())//cooldown processing
return FALSE
if(cooldown > 0)
return 0
cooldown = 2
spawn(10)
process_cooldown()
signal()
return TRUE
return 1
/obj/item/device/assembly/signaler/update_icon()
if(holder)
@@ -184,4 +188,4 @@ Code:
A.anomalyNeutralize()
/obj/item/device/assembly/signaler/anomaly/attack_self()
return
return
+7 -4
View File
@@ -42,12 +42,15 @@
/obj/item/device/assembly/timer/proc/timer_end()
if(!secured || next_activate > world.time)
return FALSE
if((!secured)||(cooldown > 0))
return 0
pulse(0)
audible_message("\icon[src] *beep* *beep*", null, 3)
if(loop)
timing = 1
cooldown = 2
spawn(10)
process_cooldown()
if(loop)
timing = 1
update_icon()
@@ -46,6 +46,7 @@
/obj/effect/hotspot
anchored = 1
mouse_opacity = 0
unacidable = 1//So you can't melt fire with acid.
icon = 'icons/effects/fire.dmi'
icon_state = "1"
layer = ABOVE_OPEN_TURF_LAYER
@@ -58,6 +59,7 @@
/obj/effect/hotspot/New()
..()
set_light(3,1,LIGHT_COLOR_FIRE)
SSair.hotspots += src
perform_exposure()
setDir(pick(cardinal))
@@ -69,8 +71,6 @@
if(!istype(location) || !(location.air))
return 0
location.active_hotspot = src
if(volume > CELL_VOLUME*0.95)
bypassing = 1
else
@@ -89,9 +89,9 @@
location.assume_air(affected)
for(var/A in loc)
var/atom/AT = A
if(AT && AT != src) // It's possible that the item is deleted in temperature_expose
AT.fire_act(temperature, volume)
var/atom/item = A
if(item && item != src) // It's possible that the item is deleted in temperature_expose
item.fire_act(null, temperature, volume)
return 0
@@ -147,10 +147,9 @@
return 1
/obj/effect/hotspot/Destroy()
SetLuminosity(0)
SSair.hotspots -= src
DestroyTurf()
if(isturf(loc))
if(istype(loc, /turf))
var/turf/open/T = loc
if(T.active_hotspot == src)
T.active_hotspot = null
@@ -159,7 +158,8 @@
return QDEL_HINT_PUTINPOOL
/obj/effect/hotspot/proc/DestroyTurf()
if(isturf(loc))
if(istype(loc, /turf))
var/turf/T = loc
if(T.to_be_destroyed)
var/chance_of_deletion
@@ -176,4 +176,4 @@
/obj/effect/hotspot/Crossed(mob/living/L)
..()
if(isliving(L))
L.fire_act(temperature, volume)
L.fire_act()
@@ -1,16 +1,8 @@
/atom/var/CanAtmosPass = ATMOS_PASS_YES
/atom/proc/CanAtmosPass(turf/T)
switch (CanAtmosPass)
if (ATMOS_PASS_PROC)
return ATMOS_PASS_YES
if (ATMOS_PASS_DENSITY)
return !density
else
return CanAtmosPass
/turf/proc/CanAtmosPass(turf/T)
/turf/closed/CanAtmosPass = ATMOS_PASS_NO
/turf/closed/CanAtmosPass(turf/T)
return 0
/turf/open/CanAtmosPass = ATMOS_PASS_PROC
/turf/open/CanAtmosPass(turf/T)
var/R
if(blocks_air || T.blocks_air)
@@ -18,7 +10,7 @@
for(var/obj/O in contents+T.contents)
var/turf/other = (O.loc == src ? T : src)
if(!CANATMOSPASS(O, other))
if(!O.CanAtmosPass(other))
R = 1
if(O.BlockSuperconductivity()) //the direction and open/closed are already checked on CanAtmosPass() so there are no arguments
var/D = get_dir(src, T)
@@ -32,44 +24,53 @@
return !R
/atom/movable/proc/CanAtmosPass()
return 1
/atom/proc/CanPass(atom/movable/mover, turf/target, height=1.5)
return (!density || !height)
/turf/CanPass(atom/movable/mover, turf/target, height=1.5)
if(!target) return 0
if(istype(mover)) // turf/Enter(...) will perform more advanced checks
return !density
else // Now, doing more detailed checks for air movement and air group formation
if(target.blocks_air||blocks_air)
return 0
for(var/obj/obstacle in src)
if(!obstacle.CanPass(mover, target, height))
return 0
for(var/obj/obstacle in target)
if(!obstacle.CanPass(mover, src, height))
return 0
return 1
/atom/movable/proc/BlockSuperconductivity() // objects that block air and don't let superconductivity act. Only firelocks atm.
return 0
/turf/proc/CalculateAdjacentTurfs()
var/list/atmos_adjacent_turfs = src.atmos_adjacent_turfs
for(var/direction in cardinal)
var/turf/T = get_step(src, direction)
if(!T)
var/turf/open/T = get_step(src, direction)
if(!istype(T))
continue
if(CANATMOSPASS(T, src))
LAZYINITLIST(atmos_adjacent_turfs)
LAZYINITLIST(T.atmos_adjacent_turfs)
atmos_adjacent_turfs[T] = TRUE
T.atmos_adjacent_turfs[src] = TRUE
if(CanAtmosPass(T))
atmos_adjacent_turfs |= T
T.atmos_adjacent_turfs |= src
else
if (atmos_adjacent_turfs)
atmos_adjacent_turfs -= T
if (T.atmos_adjacent_turfs)
T.atmos_adjacent_turfs -= src
UNSETEMPTY(T.atmos_adjacent_turfs)
UNSETEMPTY(atmos_adjacent_turfs)
src.atmos_adjacent_turfs = atmos_adjacent_turfs
atmos_adjacent_turfs -= T
T.atmos_adjacent_turfs -= src
//returns a list of adjacent turfs that can share air with this one.
//alldir includes adjacent diagonal tiles that can share
// air with both of the related adjacent cardinal tiles
/turf/proc/GetAtmosAdjacentTurfs(alldir = 0)
var/adjacent_turfs
if (atmos_adjacent_turfs)
adjacent_turfs = atmos_adjacent_turfs.Copy()
else
adjacent_turfs = list()
var/adjacent_turfs = atmos_adjacent_turfs.Copy()
if (!alldir)
return adjacent_turfs
var/turf/curloc = src
for (var/direction in diagonals)
@@ -78,10 +79,10 @@
for (var/checkDirection in cardinal)
var/turf/checkTurf = get_step(S, checkDirection)
if(!S.atmos_adjacent_turfs || !S.atmos_adjacent_turfs[checkTurf])
if(!(checkTurf in S.atmos_adjacent_turfs))
continue
if (adjacent_turfs[checkTurf])
if (checkTurf in adjacent_turfs)
matchingDirections++
if (matchingDirections >= 2)
@@ -90,29 +91,29 @@
return adjacent_turfs
/atom/proc/air_update_turf(command = 0)
if(!isturf(loc) && command)
/atom/movable/proc/air_update_turf(command = 0)
if(!istype(loc,/turf) && command)
return
var/turf/T = get_turf(loc)
T.air_update_turf(command)
/turf/air_update_turf(command = 0)
/turf/proc/air_update_turf(command = 0)
if(command)
CalculateAdjacentTurfs()
SSair.add_to_active(src,command)
/atom/movable/proc/move_update_air(turf/T)
if(isturf(T))
if(istype(T,/turf))
T.air_update_turf(1)
air_update_turf(1)
/atom/proc/atmos_spawn_air(text) //because a lot of people loves to copy paste awful code lets just make a easy proc to spawn your plasma fires
/atom/movable/proc/atmos_spawn_air(text) //because a lot of people loves to copy paste awful code lets just make a easy proc to spawn your plasma fires
var/turf/open/T = get_turf(src)
if(!istype(T))
return
T.atmos_spawn_air(text)
/turf/open/atmos_spawn_air(text)
/turf/open/proc/atmos_spawn_air(text)
if(!text || !air)
return
@@ -5,7 +5,7 @@
var/temperature_archived
//list of open turfs adjacent to us
var/list/atmos_adjacent_turfs
var/list/atmos_adjacent_turfs = list()
//bitfield of dirs in which we are superconducitng
var/atmos_supeconductivity = 0
@@ -33,7 +33,7 @@
var/atmos_cooldown = 0
var/planetary_atmos = FALSE //air will revert to initial_gas_mix over time
var/list/atmos_overlay_types //gas IDs of current active gas overlays
var/list/atmos_overlay_types = list() //gas IDs of current active gas overlays
/turf/open/New()
..()
@@ -98,17 +98,13 @@
/turf/open/proc/update_visuals()
var/list/new_overlay_types = tile_graphic()
if (atmos_overlay_types)
for(var/overlay in atmos_overlay_types-new_overlay_types) //doesn't remove overlays that would only be added
overlays -= overlay
for(var/overlay in atmos_overlay_types-new_overlay_types) //doesn't remove overlays that would only be added
overlays -= overlay
atmos_overlay_types -= overlay
if (new_overlay_types.len)
if (atmos_overlay_types)
add_overlay(new_overlay_types - atmos_overlay_types) //don't add overlays that already exist
else
add_overlay(new_overlay_types)
for(var/overlay in new_overlay_types-atmos_overlay_types) //doesn't add overlays that already exist
add_overlay(overlay)
UNSETEMPTY(new_overlay_types)
atmos_overlay_types = new_overlay_types
/turf/open/proc/tile_graphic()
@@ -134,7 +130,7 @@
//cache for sanic speed
var/list/adjacent_turfs = atmos_adjacent_turfs
var/datum/excited_group/our_excited_group = excited_group
var/adjacent_turfs_length = LAZYLEN(adjacent_turfs)
var/adjacent_turfs_length = adjacent_turfs.len
atmos_cooldown++
if (planetary_atmos)
adjacent_turfs_length++
@@ -250,24 +246,16 @@
for(var/atom/movable/M in src)
M.experience_pressure_difference(pressure_difference, pressure_direction)
/atom/movable/var/pressure_resistance = 10
/atom/movable/var/pressure_resistance = 5
/atom/movable/var/last_high_pressure_movement_air_cycle = 0
/atom/movable/proc/experience_pressure_difference(pressure_difference, direction, pressure_resistance_prob_delta = 0)
var/const/PROBABILITY_OFFSET = 25
var/const/PROBABILITY_BASE_PRECENT = 75
/atom/movable/proc/experience_pressure_difference(pressure_difference, direction)
set waitfor = 0
. = 0
if (!anchored && !pulledby)
if(!anchored && !pulledby)
. = 1
if (last_high_pressure_movement_air_cycle < SSair.times_fired)
var/move_prob = 100
if (pressure_resistance > 0)
move_prob = (pressure_difference/pressure_resistance*PROBABILITY_BASE_PRECENT)-PROBABILITY_OFFSET
move_prob += pressure_resistance_prob_delta
if (move_prob > PROBABILITY_OFFSET && prob(move_prob))
step(src, direction)
last_high_pressure_movement_air_cycle = SSair.times_fired
if(pressure_difference > pressure_resistance && last_high_pressure_movement_air_cycle < SSair.times_fired)
last_high_pressure_movement_air_cycle = SSair.times_fired
step(src, direction)
///////////////////////////EXCITED GROUPS/////////////////////////////
@@ -457,4 +445,4 @@
(heat_capacity*sharer.heat_capacity/(heat_capacity+sharer.heat_capacity))
temperature -= heat/heat_capacity
sharer.temperature += heat/sharer.heat_capacity
sharer.temperature += heat/sharer.heat_capacity
@@ -6,6 +6,7 @@ What are the archived variables for?
#define MINIMUM_HEAT_CAPACITY 0.0003
#define QUANTIZE(variable) (round(variable,0.0000001))/*I feel the need to document what happens here. Basically this is used to catch most rounding errors, however it's previous value made it so that
once gases got hot enough, most procedures wouldnt occur due to the fact that the mole counts would get rounded away. Thus, we lowered it a few orders of magnititude */
var/list/meta_gas_info = meta_gas_list() //see ATMOSPHERICS/gas_types.dm
var/list/gaslist_cache = null
@@ -38,7 +39,6 @@ var/list/gaslist_cache = null
var/volume //liters
var/last_share
var/tmp/fuel_burnt
var/atom/holder
/datum/gas_mixture/New(volume = CELL_VOLUME)
..()
@@ -179,17 +179,6 @@ var/list/gaslist_cache = null
//Prevents whatever mechanism is causing it to hit negative temperatures.
//world << "post [temperature], [cached_gases["plasma"][MOLES]], [cached_gases["co2"][MOLES]]
*/
if(holder)
if(cached_gases["freon"])
if(cached_gases["freon"][MOLES] >= MOLES_PLASMA_VISIBLE)
if(holder.freon_gas_act())
cached_gases["freon"][MOLES] -= MOLES_PLASMA_VISIBLE
if(cached_gases["water_vapor"])
if(cached_gases["water_vapor"][MOLES] >= MOLES_PLASMA_VISIBLE)
if(holder.water_vapor_gas_act())
cached_gases["water_vapor"][MOLES] -= MOLES_PLASMA_VISIBLE
fuel_burnt = 0
if(temperature > FIRE_MINIMUM_TEMPERATURE_TO_EXIST)
//world << "pre [temperature], [cached_gases["o2"][MOLES]], [cached_gases["plasma"][MOLES]]"
@@ -344,6 +333,7 @@ var/list/gaslist_cache = null
amount = min(amount, sum) //Can not take more air than tile has!
if(amount <= 0)
return null
var/list/cached_gases = gases
var/datum/gas_mixture/removed = new
var/list/removed_gases = removed.gases //accessing datum vars is slower than proc vars
@@ -371,7 +361,6 @@ var/list/gaslist_cache = null
removed.add_gas(id)
removed_gases[id][MOLES] = QUANTIZE(cached_gases[id][MOLES] * ratio)
cached_gases[id][MOLES] -= removed_gases[id][MOLES]
garbage_collect()
return removed
@@ -383,7 +372,7 @@ var/list/gaslist_cache = null
copy.temperature = temperature
for(var/id in cached_gases)
copy.add_gas(id)
add_gas(id)
copy_gases[id][MOLES] = cached_gases[id][MOLES]
return copy
@@ -396,7 +385,6 @@ var/list/gaslist_cache = null
for(var/id in sample_gases)
assert_gas(id)
cached_gases[id][MOLES] = sample_gases[id][MOLES]
//remove all gases not in the sample
cached_gases &= sample_gases
@@ -51,20 +51,6 @@ var/list/hardcoded_gases = list("o2","n2","co2","plasma") //the main four gases,
gas_overlay = "plasma"
moles_visible = MOLES_PLASMA_VISIBLE
/datum/gas/water_vapor
id = "water_vapor"
specific_heat = 40
name = "Water Vapor"
gas_overlay = "water_vapor"
moles_visible = MOLES_PLASMA_VISIBLE
/datum/gas/freon
id = "freon"
specific_heat = 2000
name = "Freon"
gas_overlay = "freon"
moles_visible = MOLES_PLASMA_VISIBLE
/datum/gas/nitrous_oxide
id = "n2o"
specific_heat = 40
@@ -87,11 +73,11 @@ var/list/hardcoded_gases = list("o2","n2","co2","plasma") //the main four gases,
specific_heat = 20
name = "BZ"
/obj/effect/overlay/gas
/obj/effect/overlay/gas/
icon = 'icons/effects/tile_effects.dmi'
mouse_opacity = 0
layer = FLY_LAYER
appearance_flags = TILE_BOUND
appearance_flags = RESET_COLOR|TILE_BOUND
/obj/effect/overlay/gas/New(state)
. = ..()
+17 -48
View File
@@ -55,11 +55,6 @@
active_power_usage = 8
power_channel = ENVIRON
req_access = list(access_atmospherics)
obj_integrity = 250
max_integrity = 250
integrity_failure = 80
armor = list(melee = 0, bullet = 0, laser = 0, energy = 100, bomb = 0, bio = 100, rad = 100, fire = 90, acid = 30)
resistance_flags = FIRE_PROOF
var/danger_level = 0
var/mode = AALARM_MODE_SCRUBBING
@@ -81,9 +76,7 @@
"co2" = new/datum/tlv(-1, -1, 5, 10), // Partial pressure, kpa
"plasma" = new/datum/tlv(-1, -1, 0.2, 0.5), // Partial pressure, kpa
"n2o" = new/datum/tlv(-1, -1, 0.2, 0.5), // Partial pressure, kpa
"bz" = new/datum/tlv(-1, -1, 0.2, 0.5),
"freon" = new/datum/tlv(-1, -1, 0.2, 0.5),
"water_vapor" = new/datum/tlv(-1, -1, 0.2, 0.5)
"bz" = new/datum/tlv(-1, -1, 0.2, 0.5)
)
/obj/machinery/airalarm/server // No checks here.
@@ -96,8 +89,6 @@
"plasma" = new/datum/tlv(-1, -1, -1, -1),
"n2o" = new/datum/tlv(-1, -1, -1, -1),
"bz" = new/datum/tlv(-1, -1, -1, -1),
"freon" = new/datum/tlv(-1, -1, -1, -1),
"water_vapor" = new/datum/tlv(-1, -1, -1, -1)
)
/obj/machinery/airalarm/kitchen_cold_room // Copypasta: to check temperatures.
@@ -110,8 +101,6 @@
"plasma" = new/datum/tlv(-1, -1, 0.2, 0.5), // Partial pressure, kpa
"n2o" = new/datum/tlv(-1, -1, 0.2, 0.5), // Partial pressure, kpa
"bz" = new/datum/tlv(-1, -1, 0.2, 0.5), // Partial pressure, kpa
"freon" = new/datum/tlv(-1, -1, 0.2, 0.5), // Partial pressure, kpa
"water_vapor" = new/datum/tlv(-1, -1, 0.2, 0.5)
)
//all air alarms in area are connected via magic
@@ -236,24 +225,22 @@
if(!info || info["frequency"] != frequency)
continue
data["scrubbers"] += list(list(
"id_tag" = id_tag,
"long_name" = sanitize(long_name),
"power" = info["power"],
"scrubbing" = info["scrubbing"],
"widenet" = info["widenet"],
"filter_co2" = info["filter_co2"],
"filter_toxins" = info["filter_toxins"],
"filter_n2o" = info["filter_n2o"],
"filter_bz" = info["filter_bz"],
"filter_freon" = info["filter_freon"],
"filter_water_vapor" = info["filter_water_vapor"]
"id_tag" = id_tag,
"long_name" = sanitize(long_name),
"power" = info["power"],
"scrubbing" = info["scrubbing"],
"widenet" = info["widenet"],
"filter_co2" = info["filter_co2"],
"filter_toxins" = info["filter_toxins"],
"filter_n2o" = info["filter_n2o"],
"filter_bz" = info["filter_bz"]
))
data["mode"] = mode
data["modes"] = list()
data["modes"] += list(list("name" = "Filtering - Scrubs out contaminants", "mode" = AALARM_MODE_SCRUBBING, "selected" = mode == AALARM_MODE_SCRUBBING, "danger" = 0))
data["modes"] += list(list("name" = "Contaminated - Scrubs out ALL contaminants quickly","mode" = AALARM_MODE_CONTAMINATED, "selected" = mode == AALARM_MODE_CONTAMINATED, "danger" = 0))
data["modes"] += list(list("name" = "Draught - Siphons out air while replacing", "mode" = AALARM_MODE_VENTING, "selected" = mode == AALARM_MODE_VENTING, "danger" = 0))
data["modes"] += list(list("name" = "Refill - Triple vent output", "mode" = AALARM_MODE_REFILL, "selected" = mode == AALARM_MODE_REFILL, "danger" = 1))
data["modes"] += list(list("name" = "Refill - Triple vent output", "mode" = AALARM_MODE_REFILL, "selected" = mode == AALARM_MODE_REFILL, "danger" = 0))
data["modes"] += list(list("name" = "Cycle - Siphons air before replacing", "mode" = AALARM_MODE_REPLACEMENT, "selected" = mode == AALARM_MODE_REPLACEMENT, "danger" = 1))
data["modes"] += list(list("name" = "Siphon - Siphons air out of the room", "mode" = AALARM_MODE_SIPHON, "selected" = mode == AALARM_MODE_SIPHON, "danger" = 1))
data["modes"] += list(list("name" = "Panic Siphon - Siphons air out of the room quickly","mode" = AALARM_MODE_PANIC, "selected" = mode == AALARM_MODE_PANIC, "danger" = 1))
@@ -302,7 +289,7 @@
if(usr.has_unlimited_silicon_privilege && !wires.is_cut(WIRE_IDSCAN))
locked = !locked
. = TRUE
if("power", "co2_scrub", "tox_scrub", "n2o_scrub", "bz_scrub", "freon_scrub","water_vapor_scrub", "widenet", "scrubbing")
if("power", "co2_scrub", "tox_scrub", "n2o_scrub", "bz_scrub", "widenet", "scrubbing")
send_signal(device_id, list("[action]" = text2num(params["val"])))
. = TRUE
if("excheck")
@@ -369,7 +356,7 @@
var/datum/effect_system/spark_spread/s = new /datum/effect_system/spark_spread
s.set_up(5, 1, src)
s.start() //sparks always.
if (electrocute_mob(user, get_area(src), src, 1, TRUE))
if (electrocute_mob(user, get_area(src), src))
return 1
else
return 0
@@ -420,8 +407,6 @@
"tox_scrub" = 0,
"n2o_scrub" = 0,
"bz_scrub" = 0,
"freon_scrub"= 0,
"water_vapor_scrub"= 0,
"scrubbing" = 1,
"widenet" = 0,
))
@@ -439,8 +424,6 @@
"tox_scrub" = 1,
"n2o_scrub" = 1,
"bz_scrub" = 1,
"freon_scrub"= 1,
"water_vapor_scrub"= 1,
"scrubbing" = 1,
"widenet" = 1,
))
@@ -471,8 +454,6 @@
"tox_scrub" = 0,
"n2o_scrub" = 0,
"bz_scrub" = 0,
"freon_scrub"= 0,
"water_vapor_scrub"= 0,
"scrubbing" = 1,
"widenet" = 0,
))
@@ -633,7 +614,8 @@
if(istype(W, /obj/item/weapon/wirecutters) && panel_open && wires.is_all_cut())
playsound(src.loc, W.usesound, 50, 1)
user << "<span class='notice'>You cut the final wires.</span>"
new /obj/item/stack/cable_coil(loc, 5)
var/obj/item/stack/cable_coil/cable = new /obj/item/stack/cable_coil(loc)
cable.amount = 5
buildstage = 1
update_icon()
return
@@ -661,7 +643,7 @@
user.visible_message("[user.name] removes the electronics from [src.name].",\
"<span class='notice'>You start prying out the circuit...</span>")
playsound(src.loc, W.usesound, 50, 1)
if (do_after(user, 20*W.toolspeed, target = src))
if (do_after(user, 20/W.toolspeed, target = src))
if (buildstage == 1)
user <<"<span class='notice'>You remove the air alarm electronics.</span>"
new /obj/item/weapon/electronics/airalarm( src.loc )
@@ -717,17 +699,4 @@
return
emagged = TRUE
visible_message("<span class='warning'>Sparks fly out of the [src]!</span>", "<span class='notice'>You emag the [src], disabling its safeties.</span>")
playsound(src.loc, 'sound/effects/sparks4.ogg', 50, 1)
/obj/machinery/airalarm/obj_break(damage_flag)
..()
update_icon()
/obj/machinery/airalarm/deconstruct(disassembled = TRUE)
if(!(flags & NODECONSTRUCT))
new /obj/item/stack/sheet/metal(loc, 2)
var/obj/item/I = new /obj/item/weapon/electronics/airalarm(loc)
if(!disassembled)
I.obj_integrity = I.max_integrity * 0.5
new /obj/item/stack/cable_coil(loc, 3)
qdel(src)
playsound(src.loc, 'sound/effects/sparks4.ogg', 50, 1)
@@ -16,36 +16,36 @@ Pipelines + Other Objects -> Pipe network
power_channel = ENVIRON
on_blueprints = TRUE
layer = GAS_PIPE_LAYER //under wires
resistance_flags = FIRE_PROOF
obj_integrity = 200
max_integrity = 200
var/nodealert = 0
var/can_unwrench = 0
var/initialize_directions = 0
var/pipe_color
var/obj/item/pipe/stored
var/global/list/iconsetids = list()
var/global/list/pipeimages = list()
var/image/pipe_vision_img = null
var/device_type = 0
var/list/obj/machinery/atmospherics/nodes
var/list/obj/machinery/atmospherics/nodes = list()
/obj/machinery/atmospherics/New(loc, process = TRUE)
nodes = new(device_type)
if (!armor)
armor = list(melee = 25, bullet = 10, laser = 10, energy = 100, bomb = 0, bio = 100, rad = 100, fire = 100, acid = 70)
nodes.len = device_type
..()
if(process)
SSair.atmos_machinery += src
SetInitDirections()
if(can_unwrench)
stored = new(src, make_from=src)
/obj/machinery/atmospherics/Destroy()
for(DEVICE_TYPE_LOOP)
nullifyNode(I)
SSair.atmos_machinery -= src
if(stored)
qdel(stored)
stored = null
dropContents()
if(pipe_vision_img)
@@ -136,13 +136,13 @@ Pipelines + Other Objects -> Pipe network
var/unsafe_wrenching = FALSE
var/internal_pressure = int_air.return_pressure()-env_air.return_pressure()
playsound(src.loc, W.usesound, 50, 1)
playsound(src.loc, 'sound/items/Ratchet.ogg', 50, 1)
user << "<span class='notice'>You begin to unfasten \the [src]...</span>"
if (internal_pressure > 2*ONE_ATMOSPHERE)
user << "<span class='warning'>As you begin unwrenching \the [src] a gush of air blows in your face... maybe you should reconsider?</span>"
unsafe_wrenching = TRUE //Oh dear oh dear
if (do_after(user, 20*W.toolspeed, target = src) && !qdeleted(src))
if (do_after(user, 20/W.toolspeed, target = src) && !qdeleted(src))
user.visible_message( \
"[user] unfastens \the [src].", \
"<span class='notice'>You unfasten \the [src].</span>", \
@@ -152,10 +152,11 @@ Pipelines + Other Objects -> Pipe network
//You unwrenched a pipe full of pressure? Let's splat you into the wall, silly.
if(unsafe_wrenching)
unsafe_pressure_release(user, internal_pressure)
deconstruct(TRUE)
Deconstruct()
else
return ..()
/obj/machinery/atmospherics/proc/can_unwrench(mob/user)
return can_unwrench
@@ -178,14 +179,13 @@ Pipelines + Other Objects -> Pipe network
user.visible_message("<span class='danger'>[user] is sent flying by pressure!</span>","<span class='userdanger'>The pressure sends you flying!</span>")
user.throw_at(target, range, speed)
/obj/machinery/atmospherics/deconstruct(disassembled = TRUE)
if(!(flags & NODECONSTRUCT))
if(can_unwrench)
var/obj/item/pipe/stored = new(loc, make_from=src)
if(!disassembled)
stored.obj_integrity = stored.max_integrity * 0.5
transfer_fingerprints_to(stored)
..()
/obj/machinery/atmospherics/Deconstruct()
if(can_unwrench)
stored.loc = src.loc
transfer_fingerprints_to(stored)
stored = null
qdel(src)
/obj/machinery/atmospherics/proc/getpipeimage(iconset, iconstate, direction, col=rgb(255,255,255))
@@ -208,10 +208,13 @@ Pipelines + Other Objects -> Pipe network
return img
/obj/machinery/atmospherics/on_construction(pipe_type, obj_color)
/obj/machinery/atmospherics/construction(pipe_type, obj_color)
if(can_unwrench)
add_atom_colour(obj_color, FIXED_COLOUR_PRIORITY)
color = obj_color
pipe_color = obj_color
stored.setDir(src.dir )//need to define them here, because the obj directions...
stored.pipe_type = pipe_type //... were not set at the time the stored pipe was created
stored.color = obj_color
var/turf/T = loc
level = T.intact ? 2 : 1
atmosinit()
@@ -223,7 +226,7 @@ Pipelines + Other Objects -> Pipe network
/obj/machinery/atmospherics/singularity_pull(S, current_size)
if(current_size >= STAGE_FIVE)
deconstruct(FALSE)
Deconstruct()
//Find a connecting /obj/machinery/atmospherics in specified direction
@@ -280,10 +283,7 @@ Pipelines + Other Objects -> Pipe network
return list()
/obj/machinery/atmospherics/update_remote_sight(mob/user)
if(isborer(user))
user.sight |= (SEE_PIXELS)
else
user.sight |= (SEE_TURFS|BLIND)
user.sight |= (SEE_TURFS|BLIND)
//Used for certain children of obj/machinery/atmospherics to not show pipe vision when mob is inside it.
/obj/machinery/atmospherics/proc/can_see_pipes()
@@ -65,7 +65,7 @@ Acts like a normal vent, but has an input AND output.
..()
if(!on)
return FALSE
return 0
var/datum/gas_mixture/air1 = AIR1
var/datum/gas_mixture/air2 = AIR2
@@ -85,9 +85,6 @@ Acts like a normal vent, but has an input AND output.
var/transfer_moles = pressure_delta*environment.volume/(air1.temperature * R_IDEAL_GAS_EQUATION)
var/datum/gas_mixture/removed = air1.remove(transfer_moles)
//Removed can be null if there is no atmosphere in air1
if(!removed)
return FALSE
loc.assume_air(removed)
air_update_turf()
@@ -108,9 +105,6 @@ Acts like a normal vent, but has an input AND output.
var/transfer_moles = pressure_delta*air2.volume/(environment.temperature * R_IDEAL_GAS_EQUATION)
var/datum/gas_mixture/removed = loc.remove_air(transfer_moles)
//removed can be null if there is no air in the location
if(!removed)
return FALSE
air2.merge(removed)
air_update_turf()
@@ -118,7 +112,7 @@ Acts like a normal vent, but has an input AND output.
var/datum/pipeline/parent2 = PARENT2
parent2.update = 1
return TRUE
return 1
//Radio remote control
@@ -201,4 +195,4 @@ Acts like a normal vent, but has an input AND output.
#undef EXT_BOUND
#undef INPUT_MIN
#undef OUTPUT_MAX
#undef OUTPUT_MAX
@@ -54,10 +54,6 @@ It's like a regular ol' straight pipe, but you can turn it on and off.
close()
return
open()
investigate_log("Valve, [src.name], was manipiulated by [key_name(usr)] at [x], [y], [z], [loc.loc]", "atmos")
message_admins("Valve, [src.name], was manipulated by [key_name(usr)] at [x], [y], [z], [loc.loc]")
log_admin("[key_name(usr)] manipulated a manual valve at [x], [y], [z]")
/obj/machinery/atmospherics/components/binary/valve/digital // can be controlled by AI
name = "digital valve"
@@ -119,10 +119,7 @@ Thus, the two variables affect pump operation are set in New():
switch(action)
if("power")
on = !on
investigate_log("Volume Pump, [src.name], was turned [on ? "on" : "off"] by [key_name(usr)] at [x], [y], [z], [loc.loc]", "atmos")
message_admins("Volume Pump, [src.name], turned [on ? "on" : "off"] by [key_name(usr)] at [x], [y], [z], [loc.loc]")
log_admin("[key_name(usr)] manipulated a volume pump at [x], [y], [z]")
investigate_log("was turned [on ? "on" : "off"] by [key_name(usr)]", "atmos")
. = TRUE
if("rate")
var/rate = params["rate"]
@@ -138,9 +135,7 @@ Thus, the two variables affect pump operation are set in New():
. = TRUE
if(.)
transfer_rate = Clamp(rate, 0, MAX_TRANSFER_RATE)
investigate_log("Volume Pump, [src.name], was set to [transfer_rate] L/s by [key_name(usr)] at [x], [y], [z], [loc.loc]", "atmos")
message_admins("Volume Pump, [src.name], was set to [transfer_rate] L/s by [key_name(usr)] at [x], [y], [z], [loc.loc]")
log_admin("[key_name(usr)] manipulated a volume pump at [x], [y], [z]")
investigate_log("was set to [transfer_rate] L/s by [key_name(usr)]", "atmos")
update_icon()
/obj/machinery/atmospherics/components/binary/volume_pump/receive_signal(datum/signal/signal)
@@ -179,9 +174,5 @@ Thus, the two variables affect pump operation are set in New():
if(!(stat & NOPOWER) && on)
user << "<span class='warning'>You cannot unwrench this [src], turn it off first!</span>"
else
investigate_log("Volume Pump, [src.name], was unwrenched by [key_name(usr)] at [x], [y], [z], [loc.loc]", "atmos")
message_admins("Volume Pump, [src.name], was unwrenched by [key_name(usr)] at [x], [y], [z], [loc.loc]")
log_admin("[key_name(usr)] unwrenched a volume pump at [x], [y], [z]")
return 1
@@ -7,12 +7,12 @@ On top of that, now people can add component-speciic procs/vars if they want!
var/welded = 0 //Used on pumps and scrubbers
var/showpipe = 0
var/list/datum/pipeline/parents
var/list/datum/gas_mixture/airs
var/list/datum/pipeline/parents = list()
var/list/datum/gas_mixture/airs = list()
/obj/machinery/atmospherics/components/New()
parents = new(device_type)
airs = new(device_type)
parents.len = device_type
airs.len = device_type
..()
for(DEVICE_TYPE_LOOP)
@@ -72,7 +72,7 @@ Pipenet stuff; housekeeping
qdel(AIR_I)
AIR_I = null
/obj/machinery/atmospherics/components/on_construction()
/obj/machinery/atmospherics/components/construction()
..()
update_parents()
@@ -83,25 +83,18 @@
if(!removed)
return
var/filtering = filter_type ? TRUE : FALSE
if(filtering && !istext(filter_type))
WARNING("Wrong gas ID in [src]'s filter_type var. filter_type == [filter_type]")
filtering = FALSE
if(filtering && removed.gases[filter_type])
var/datum/gas_mixture/filtered_out = new
filtered_out.temperature = removed.temperature
var/datum/gas_mixture/filtered_out = new
filtered_out.temperature = removed.temperature
if(filter_type && removed.gases[filter_type])
filtered_out.assert_gas(filter_type)
filtered_out.gases[filter_type][MOLES] = removed.gases[filter_type][MOLES]
removed.gases[filter_type][MOLES] = 0
removed.garbage_collect()
else
filtered_out = null
air2.merge(filtered_out)
air2.merge(filtered_out)
air3.merge(removed)
update_parents()
@@ -116,7 +109,7 @@
datum/tgui/master_ui = null, datum/ui_state/state = default_state)
ui = SStgui.try_update_ui(user, src, ui_key, ui, force_open)
if(!ui)
ui = new(user, src, ui_key, "atmos_filter", name, 475, 155, master_ui, state)
ui = new(user, src, ui_key, "atmos_filter", name, 475, 140, master_ui, state)
ui.open()
/obj/machinery/atmospherics/components/trinary/filter/ui_data()
@@ -1,18 +1,15 @@
/obj/machinery/atmospherics/components/unary/cryo_cell
name = "cryo cell"
icon = 'icons/obj/cryogenics.dmi'
icon_state = "cell-off"
icon_state = "pod0"
density = 1
anchored = 1
obj_integrity = 350
max_integrity = 350
armor = list(melee = 0, bullet = 0, laser = 0, energy = 100, bomb = 0, bio = 100, rad = 100, fire = 30, acid = 30)
var/on = FALSE
state_open = FALSE
var/autoeject = FALSE
var/volume = 100
var/running_bob_animation = 0
var/efficiency = 1
var/sleep_factor = 750
var/paralyze_factor = 1000
@@ -38,7 +35,7 @@
/obj/item/weapon/stock_parts/console_screen = 1,
/obj/item/stack/sheet/glass = 2)
/obj/machinery/atmospherics/components/unary/cryo_cell/on_construction()
/obj/machinery/atmospherics/components/unary/cryo_cell/construction()
..(dir, dir)
/obj/machinery/atmospherics/components/unary/cryo_cell/RefreshParts()
@@ -53,39 +50,63 @@
conduction_coefficient = initial(conduction_coefficient) * C
/obj/machinery/atmospherics/components/unary/cryo_cell/Destroy()
if(beaker)
qdel(beaker)
beaker = null
beaker = null
return ..()
/obj/machinery/atmospherics/components/unary/cryo_cell/contents_explosion(severity, target)
..()
if(beaker)
beaker.ex_act(severity, target)
/obj/machinery/atmospherics/components/unary/cryo_cell/handle_atom_del(atom/A)
..()
if(A == beaker)
beaker = null
updateUsrDialog()
/obj/machinery/atmospherics/components/unary/cryo_cell/on_deconstruction()
if(beaker)
beaker.forceMove(loc)
beaker = null
/obj/machinery/atmospherics/components/unary/cryo_cell/update_icon()
handle_update_icon()
/obj/machinery/atmospherics/components/unary/cryo_cell/proc/handle_update_icon() //making another proc to avoid spam in update_icon
overlays.Cut() //empty the overlay proc, just in case
if(panel_open)
icon_state = "cell-o"
icon_state = "pod0-o"
else if(state_open)
icon_state = "cell-open"
icon_state = "pod0"
else if(on && is_operational())
if(occupant)
icon_state = "cell-occupied"
var/image/pickle = image(occupant.icon, occupant.icon_state)
pickle.overlays = occupant.overlays
pickle.pixel_y = 22
overlays += pickle
icon_state = "pod1"
var/up = 0 //used to see if we are going up or down, 1 is down, 2 is up
spawn(0) // Without this, the icon update will block. The new thread will die once the occupant leaves.
running_bob_animation = 1
while(occupant)
overlays -= "lid1" //have to remove the overlays first, to force an update- remove cloning pod overlay
overlays -= pickle //remove mob overlay
switch(pickle.pixel_y) //this looks messy as fuck but it works, switch won't call itself twice
if(23) //inbetween state, for smoothness
switch(up) //this is set later in the switch, to keep track of where the mob is supposed to go
if(2) //2 is up
pickle.pixel_y = 24 //set to highest
if(1) //1 is down
pickle.pixel_y = 22 //set to lowest
if(22) //mob is at it's lowest
pickle.pixel_y = 23 //set to inbetween
up = 2 //have to go up
if(24) //mob is at it's highest
pickle.pixel_y = 23 //set to inbetween
up = 1 //have to go down
overlays += pickle //re-add the mob to the icon
overlays += "lid1" //re-add the overlay of the pod, they are inside it, not floating
sleep(7) //don't want to jiggle violently, just slowly bob
return
running_bob_animation = 0
else
icon_state = "cell-on"
icon_state = "pod1"
overlays += "lid0" //have to remove the overlays first, to force an update- remove cloning pod overlay
else
icon_state = "cell-off"
icon_state = "pod0"
overlays += "lid0" //if no occupant, just put the lid overlay on, and ignore the rest
/obj/machinery/atmospherics/components/unary/cryo_cell/process()
..()
@@ -106,18 +127,18 @@
return
else if(occupant.stat == DEAD) // We don't bother with dead people.
return
if(air1.gases.len)
if(occupant.bodytemperature < T0C) // Sleepytime. Why? More cryo magic.
occupant.Sleeping((occupant.bodytemperature / sleep_factor) * 100)
occupant.Paralyse((occupant.bodytemperature / paralyze_factor) * 100)
if(beaker)
if(reagent_transfer == 0) // Magically transfer reagents. Because cryo magic.
beaker.reagents.trans_to(occupant, 1, 10 * efficiency) // Transfer reagents, multiplied because cryo magic.
beaker.reagents.reaction(occupant, VAPOR)
air1.gases["o2"][MOLES] -= 2 / efficiency // Lets use gas for this.
if(++reagent_transfer >= 10 * efficiency) // Throttle reagent transfer (higher efficiency will transfer the same amount but consume less from the beaker).
reagent_transfer = 0
if(occupant.bodytemperature < T0C) // Sleepytime. Why? More cryo magic.
occupant.Sleeping((occupant.bodytemperature / sleep_factor) * 100)
occupant.Paralyse((occupant.bodytemperature / paralyze_factor) * 100)
if(beaker)
if(reagent_transfer == 0) // Magically transfer reagents. Because cryo magic.
beaker.reagents.trans_to(occupant, 1, 10 * efficiency) // Transfer reagents, multiplied because cryo magic.
beaker.reagents.reaction(occupant, VAPOR)
air1.gases["o2"][MOLES] -= 2 / efficiency // Lets use gas for this.
if(++reagent_transfer >= 10 * efficiency) // Throttle reagent transfer (higher efficiency will transfer the same amount but consume less from the beaker).
reagent_transfer = 0
return 1
/obj/machinery/atmospherics/components/unary/cryo_cell/process_atmos()
@@ -125,7 +146,7 @@
if(!on)
return
var/datum/gas_mixture/air1 = AIR1
if(!NODE1 || !AIR1 || !air1.gases.len || air1.gases["o2"][MOLES] < 5) // Turn off if the machine won't work.
if(!NODE1 || !AIR1 || air1.gases["o2"][MOLES] < 5) // Turn off if the machine won't work.
on = FALSE
update_icon()
return
@@ -158,14 +179,14 @@
on = FALSE
..()
if(beaker)
beaker.forceMove(src)
beaker.loc = src
/obj/machinery/atmospherics/components/unary/cryo_cell/close_machine(mob/living/carbon/user)
if((isnull(user) || istype(user)) && state_open && !panel_open)
..(user)
return occupant
/obj/machinery/atmospherics/components/unary/cryo_cell/container_resist(mob/living/user)
/obj/machinery/atmospherics/components/unary/cryo_cell/container_resist(mob/user)
user << "<span class='notice'>You struggle inside the cryotube, kicking the release with your foot... (This will take around 30 seconds.)</span>"
audible_message("<span class='notice'>You hear a thump from [src].</span>")
if(do_after(user, 300))
@@ -233,7 +254,7 @@
occupantData["stat"] = occupant.stat
occupantData["health"] = occupant.health
occupantData["maxHealth"] = occupant.maxHealth
occupantData["minHealth"] = HEALTH_THRESHOLD_DEAD
occupantData["minHealth"] = config.health_threshold_dead
occupantData["bruteLoss"] = occupant.getBruteLoss()
occupantData["oxyLoss"] = occupant.getOxyLoss()
occupantData["toxLoss"] = occupant.getToxLoss()
@@ -274,7 +295,7 @@
. = TRUE
if("ejectbeaker")
if(beaker)
beaker.forceMove(loc)
beaker.loc = loc
beaker = null
. = TRUE
update_icon()
@@ -14,7 +14,7 @@
if(NODE1)
icon_state = "he_intact"
var/obj/machinery/atmospherics/node = NODE1
add_atom_colour(node.color, FIXED_COLOUR_PRIORITY)
color = node.color
else
icon_state = "he_exposed"
@@ -4,8 +4,6 @@
icon_state = "generic"
name = "pressure tank"
desc = "A large vessel containing pressurized gas."
obj_integrity = 800
max_integrity = 800
var/volume = 10000 //in liters, 1 meters by 1 meters by 2 meters
density = 1
var/gas_type = 0
@@ -48,4 +46,4 @@
var/datum/gas_mixture/air_contents = AIR1
air_contents.assert_gases("o2", "n2")
air_contents.gases["o2"][MOLES] = AIR_CONTENTS * 0.2
air_contents.gases["n2"][MOLES] = AIR_CONTENTS * 0.8
air_contents.gases["n2"][MOLES] = AIR_CONTENTS * 0.8
@@ -6,9 +6,6 @@
var/icon_state_open = "cold_off"
density = TRUE
anchored = TRUE
obj_integrity = 300
max_integrity = 300
armor = list(melee = 0, bullet = 0, laser = 0, energy = 100, bomb = 0, bio = 100, rad = 100, fire = 80, acid = 30)
var/on = FALSE
var/min_temperature = 0
@@ -52,7 +49,7 @@
else
return ..()
/obj/machinery/atmospherics/components/unary/thermomachine/on_construction()
/obj/machinery/atmospherics/components/unary/thermomachine/construction()
..(dir,dir)
/obj/machinery/atmospherics/components/unary/thermomachine/RefreshParts()
@@ -247,9 +247,9 @@
if(istype(W, /obj/item/weapon/weldingtool))
var/obj/item/weapon/weldingtool/WT = W
if (WT.remove_fuel(0,user))
playsound(loc, WT.usesound, 40, 1)
playsound(loc, 'sound/items/Welder.ogg', 40, 1)
user << "<span class='notice'>You begin welding the vent...</span>"
if(do_after(user, 20*W.toolspeed, target = src))
if(do_after(user, 20/W.toolspeed, target = src))
if(!src || !WT.isOn()) return
playsound(src.loc, 'sound/items/Welder2.ogg', 50, 1)
if(!welded)
@@ -260,7 +260,6 @@
welded = 0
update_icon()
pipe_vision_img = image(src, loc, layer = ABOVE_HUD_LAYER, dir = dir)
pipe_vision_img.plane = ABOVE_HUD_PLANE
return 0
else
return ..()
@@ -291,7 +290,6 @@
welded = 0
update_icon()
pipe_vision_img = image(src, loc, layer = ABOVE_HUD_LAYER, dir = dir)
pipe_vision_img.plane = ABOVE_HUD_PLANE
playsound(loc, 'sound/weapons/bladeslice.ogg', 100, 1)
@@ -300,4 +298,4 @@
#undef NO_BOUND
#undef SIPHONING
#undef RELEASING
#undef RELEASING
@@ -20,9 +20,6 @@
var/scrub_Toxins = 0
var/scrub_N2O = 0
var/scrub_BZ = 0
var/scrub_Freon = 0
var/scrub_WaterVapor = 0
var/volume_rate = 200
var/widenet = 0 //is this scrubber acting on the 3x3 area around it.
@@ -72,10 +69,6 @@
amount += idle_power_usage
if(scrub_BZ)
amount += idle_power_usage
if(scrub_Freon)
amount += idle_power_usage
if(scrub_WaterVapor)
amount += idle_power_usage
else //scrubbing == SIPHONING
amount = active_power_usage
@@ -126,8 +119,6 @@
"filter_toxins" = scrub_Toxins,
"filter_n2o" = scrub_N2O,
"filter_bz" = scrub_BZ,
"filter_freon" = scrub_Freon,
"filter_water_vapor" = scrub_WaterVapor,
"sigtype" = "status"
)
@@ -184,10 +175,9 @@
//Take a gas sample
var/datum/gas_mixture/removed = tile.remove_air(transfer_moles)
//Nothing left to remove from the tile
if (isnull(removed))
return
var/list/removed_gases = removed.gases
if (isnull(removed)) //in space
return
//Filter it
var/datum/gas_mixture/filtered_out = new
@@ -219,16 +209,6 @@
filtered_out.gases["bz"][MOLES] = removed_gases["bz"][MOLES]
removed.gases["bz"][MOLES] = 0
if(scrub_Freon && removed_gases["freon"])
filtered_out.assert_gas("freon")
filtered_out.gases["freon"][MOLES] = removed_gases["freon"][MOLES]
removed.gases["freon"][MOLES] = 0
if(scrub_WaterVapor && removed_gases["water_vapor"])
filtered_out.assert_gas("water_vapor")
filtered_out.gases["water_vapor"][MOLES] = removed_gases["water_vapor"][MOLES]
removed.gases["water_vapor"][MOLES] = 0
removed.garbage_collect()
//Remix the resulting gases
@@ -309,16 +289,6 @@
if("toggle_bz_scrub" in signal.data)
scrub_BZ = !scrub_BZ
if("freon_scrub" in signal.data)
scrub_Freon = text2num(signal.data["freon_scrub"])
if("toggle_freon_scrub" in signal.data)
scrub_Freon = !scrub_Freon
if("water_vapor_scrub" in signal.data)
scrub_WaterVapor = text2num(signal.data["water_vapor_scrub"])
if("toggle_water_vapor_scrub" in signal.data)
scrub_WaterVapor = !scrub_WaterVapor
if("init" in signal.data)
name = signal.data["init"]
return
@@ -339,9 +309,9 @@
if(istype(W, /obj/item/weapon/weldingtool))
var/obj/item/weapon/weldingtool/WT = W
if(WT.remove_fuel(0,user))
playsound(loc, WT.usesound, 40, 1)
playsound(loc, 'sound/items/Welder.ogg', 40, 1)
user << "<span class='notice'>Now welding the scrubber.</span>"
if(do_after(user, 20*W.toolspeed, target = src))
if(do_after(user, 20/W.toolspeed, target = src))
if(!src || !WT.isOn())
return
playsound(src.loc, 'sound/items/Welder2.ogg', 50, 1)
@@ -353,7 +323,6 @@
welded = 0
update_icon()
pipe_vision_img = image(src, loc, layer = ABOVE_HUD_LAYER, dir = dir)
pipe_vision_img.plane = ABOVE_HUD_PLANE
return 0
else
return ..()
@@ -375,7 +344,6 @@
welded = 0
update_icon()
pipe_vision_img = image(src, loc, layer = ABOVE_HUD_LAYER, dir = dir)
pipe_vision_img.plane = ABOVE_HUD_PLANE
playsound(loc, 'sound/weapons/bladeslice.ogg', 100, 1)
@@ -1,16 +1,13 @@
/datum/pipeline
var/datum/gas_mixture/air
var/list/datum/gas_mixture/other_airs
var/list/datum/gas_mixture/other_airs = list()
var/list/obj/machinery/atmospherics/pipe/members
var/list/obj/machinery/atmospherics/components/other_atmosmch
var/list/obj/machinery/atmospherics/pipe/members = list()
var/list/obj/machinery/atmospherics/components/other_atmosmch = list()
var/update = 1
/datum/pipeline/New()
other_airs = list()
members = list()
other_atmosmch = list()
SSair.networks += src
/datum/pipeline/Destroy()
@@ -44,7 +41,6 @@ var/pipenetwarnings = 10
addMachineryMember(base)
if(!air)
air = new
air.holder = src
var/list/possible_expansions = list(base)
while(possible_expansions.len>0)
for(var/obj/machinery/atmospherics/borderline in possible_expansions)
@@ -147,7 +143,7 @@ var/pipenetwarnings = 10
var/target_temperature
var/target_heat_capacity
if(isopenturf(target))
if(istype(target, /turf/open))
var/turf/open/modeled_location = target
target_temperature = modeled_location.GetTemperature()
@@ -197,12 +193,6 @@ var/pipenetwarnings = 10
air.temperature -= heat/total_heat_capacity
update = 1
/datum/pipeline/proc/return_air()
. = other_airs + air
if(null in .)
stack_trace("[src] has one or more null gas mixtures, which may cause bugs. Null mixtures will not be considered in reconcile_air().")
return removeNullsFromList(.)
/datum/pipeline/proc/reconcile_air()
var/list/datum/gas_mixture/GL = list()
var/list/datum/pipeline/PL = list()
@@ -210,7 +200,8 @@ var/pipenetwarnings = 10
for(var/i = 1; i <= PL.len; i++) //can't do a for-each here because we may add to the list within the loop
var/datum/pipeline/P = PL[i]
GL += P.return_air()
GL += P.air
GL += P.other_airs
for(var/obj/machinery/atmospherics/components/binary/valve/V in P.other_atmosmch)
if(V.open)
PL |= V.PARENT1
@@ -11,10 +11,6 @@
use_power = 1
idle_power_usage = 2
active_power_usage = 4
obj_integrity = 150
max_integrity = 150
armor = list(melee = 0, bullet = 0, laser = 0, energy = 100, bomb = 0, bio = 100, rad = 100, fire = 40, acid = 0)
/obj/machinery/meter/New()
..()
@@ -98,9 +94,9 @@
/obj/machinery/meter/attackby(obj/item/weapon/W, mob/user, params)
if (istype(W, /obj/item/weapon/wrench))
playsound(src.loc, W.usesound, 50, 1)
playsound(src.loc, 'sound/items/Ratchet.ogg', 50, 1)
user << "<span class='notice'>You begin to unfasten \the [src]...</span>"
if (do_after(user, 40*W.toolspeed, target = src))
if (do_after(user, 40/W.toolspeed, target = src))
user.visible_message( \
"[user] unfastens \the [src].", \
"<span class='notice'>You unfasten \the [src].</span>", \
@@ -141,3 +137,4 @@
/obj/machinery/meter/turf/initialize()
if (!target)
src.target = loc
@@ -20,7 +20,7 @@
/obj/machinery/zvent/process_atmos()
//all this object does, is make its turf share air with the ones above and below it, if they have a vent too.
if(isturf(loc)) //if we're not on a valid turf, forget it
if (istype(loc,/turf)) //if we're not on a valid turf, forget it
for (var/new_z in list(-1,1)) //change this list if a fancier system of z-levels gets implemented
var/turf/open/zturf_conn = locate(x,y,z+new_z)
if (istype(zturf_conn))
@@ -1,4 +1,4 @@
/obj/machinery/atmospherics/pipe/heat_exchanging
/obj/machinery/atmospherics/pipe/heat_exchanging/
icon = 'icons/obj/atmospherics/pipes/heat.dmi'
level = 2
var/initialize_directions_he
@@ -7,11 +7,11 @@
color = "#404040"
buckle_lying = 1
var/icon_temperature = T20C //stop small changes in temperature causing icon refresh
resistance_flags = LAVA_PROOF | FIRE_PROOF
burn_state = LAVA_PROOF
/obj/machinery/atmospherics/pipe/heat_exchanging/New()
..()
add_atom_colour("#404040", FIXED_COLOUR_PRIORITY)
color = "#404040"
/obj/machinery/atmospherics/pipe/heat_exchanging/can_be_node(obj/machinery/atmospherics/pipe/heat_exchanging/target)
if(!istype(target))
@@ -50,7 +50,7 @@
var/hc = pipe_air.heat_capacity()
var/mob/living/heat_source = buckled_mobs[1]
//Best guess-estimate of the total bodytemperature of all the mobs, since they share the same environment it's ~ok~ to guess like this
var/avg_temp = (pipe_air.temperature * hc + (heat_source.bodytemperature * buckled_mobs.len) * 3500) / (hc + (buckled_mobs ? buckled_mobs.len * 3500 : 0))
var/avg_temp = (pipe_air.temperature * hc + (heat_source.bodytemperature * buckled_mobs.len) * 3500) / (hc + (buckled_mobs.len * 3500))
for(var/m in buckled_mobs)
var/mob/living/L = m
L.bodytemperature = avg_temp
@@ -14,7 +14,7 @@
buckle_lying = -1
/obj/machinery/atmospherics/pipe/New()
add_atom_colour(pipe_color, FIXED_COLOUR_PRIORITY)
color = pipe_color
volume = 35 * device_type
..()
@@ -38,7 +38,7 @@
..()
/obj/machinery/atmospherics/pipe/hide(i)
if(level == 1 && isturf(loc))
if(level == 1 && istype(loc, /turf))
invisibility = i ? INVISIBILITY_MAXIMUM : 0
update_icon()
@@ -97,9 +97,4 @@
N.update_icon()
/obj/machinery/atmospherics/pipe/returnPipenets()
. = list(parent)
/obj/machinery/atmospherics/pipe/run_obj_armor(damage_amount, damage_type, damage_flag = 0, attack_dir)
if(damage_flag == "melee" && damage_amount < 12)
return 0
. = ..()
. = list(parent)
@@ -17,13 +17,9 @@
var/gas_type = ""
var/release_pressure = ONE_ATMOSPHERE
armor = list(melee = 50, bullet = 50, laser = 50, energy = 100, bomb = 10, bio = 100, rad = 100, fire = 80, acid = 50)
obj_integrity = 250
max_integrity = 250
integrity_failure = 100
var/health = 100
pressure_resistance = 7 * ONE_ATMOSPHERE
var/temperature_resistance = 1000 + T0C
var/starter_temp
var/update = 0
var/static/list/label2types = list(
@@ -34,8 +30,6 @@
"n2o" = /obj/machinery/portable_atmospherics/canister/nitrous_oxide,
"bz" = /obj/machinery/portable_atmospherics/canister/bz,
"air" = /obj/machinery/portable_atmospherics/canister/air,
"freon" = /obj/machinery/portable_atmospherics/canister/freon,
"water vapor" = /obj/machinery/portable_atmospherics/canister/water_vapor,
"caution" = /obj/machinery/portable_atmospherics/canister,
)
@@ -44,67 +38,47 @@
desc = "Nitrogen gas. Reportedly useful for something."
icon_state = "red"
gas_type = "n2"
/obj/machinery/portable_atmospherics/canister/oxygen
name = "o2 canister"
desc = "Oxygen. Necessary for human life."
icon_state = "blue"
gas_type = "o2"
/obj/machinery/portable_atmospherics/canister/carbon_dioxide
name = "co2 canister"
desc = "Carbon dioxide. What the fuck is carbon dioxide?"
icon_state = "black"
gas_type = "co2"
/obj/machinery/portable_atmospherics/canister/toxins
name = "plasma canister"
desc = "Plasma gas. The reason YOU are here. Highly toxic."
icon_state = "orange"
gas_type = "plasma"
/obj/machinery/portable_atmospherics/canister/agent_b
name = "agent b canister"
desc = "Oxygen Agent B. You're not quite sure what it does."
gas_type = "agent_b"
/obj/machinery/portable_atmospherics/canister/bz
name = "BZ canister"
desc = "BZ, a powerful hallucinogenic nerve agent."
icon_state = "purple"
gas_type = "bz"
/obj/machinery/portable_atmospherics/canister/nitrous_oxide
name = "n2o canister"
desc = "Nitrous oxide gas. Known to cause drowsiness."
icon_state = "redws"
gas_type = "n2o"
/obj/machinery/portable_atmospherics/canister/air
name = "air canister"
desc = "Pre-mixed air."
icon_state = "grey"
/obj/machinery/portable_atmospherics/canister/freon
name = "freon canister"
desc = "Freon. Great for the atmosphere!"
icon_state = "freon"
gas_type = "freon"
starter_temp = 120
/obj/machinery/portable_atmospherics/canister/water_vapor
name = "water vapor canister"
desc = "Water Vapor. We get it, you vape."
icon_state = "water_vapor"
gas_type = "water_vapor"
filled = 1
/obj/machinery/portable_atmospherics/canister/New(loc, datum/gas_mixture/existing_mixture)
..()
if(existing_mixture)
air_contents.copy_from(existing_mixture)
else
create_gas()
pump = new(src, FALSE)
pump.on = TRUE
pump.stat = 0
@@ -120,11 +94,8 @@
/obj/machinery/portable_atmospherics/canister/proc/create_gas()
if(gas_type)
air_contents.add_gas(gas_type)
if(starter_temp)
air_contents.temperature = starter_temp
air_contents.gases[gas_type][MOLES] = (maximum_pressure * filled) * air_contents.volume / (R_IDEAL_GAS_EQUATION * air_contents.temperature)
if(starter_temp)
air_contents.temperature = starter_temp
/obj/machinery/portable_atmospherics/canister/air/create_gas()
air_contents.add_gases("o2","n2")
air_contents.gases["o2"][MOLES] = (O2STANDARD * maximum_pressure * filled) * air_contents.volume / (R_IDEAL_GAS_EQUATION * air_contents.temperature)
@@ -184,56 +155,40 @@
/obj/machinery/portable_atmospherics/canister/temperature_expose(datum/gas_mixture/air, exposed_temperature, exposed_volume)
if(exposed_temperature > temperature_resistance)
take_damage(5, BURN, 0)
take_damage(5, BRUTE, 0)
/obj/machinery/portable_atmospherics/canister/deconstruct(disassembled = TRUE)
if(!(flags & NODECONSTRUCT))
if(!(stat & BROKEN))
canister_break()
if(disassembled)
new /obj/item/stack/sheet/metal (loc, 10)
/obj/machinery/portable_atmospherics/canister/take_damage(damage, damage_type = BRUTE, sound_effect = 1)
switch(damage_type)
if(BRUTE)
if(sound_effect)
if(damage)
playsound(loc, 'sound/weapons/smash.ogg', 50, 1)
else
playsound(loc, 'sound/weapons/tap.ogg', 50, 1)
if(BURN)
if(sound_effect)
playsound(src.loc, 'sound/items/Welder.ogg', 100, 1)
else
new /obj/item/stack/sheet/metal (loc, 5)
qdel(src)
/obj/machinery/portable_atmospherics/canister/attackby(obj/item/weapon/W, mob/user, params)
if(user.a_intent != INTENT_HARM && istype(W, /obj/item/weapon/weldingtool))
var/obj/item/weapon/weldingtool/WT = W
if(stat & BROKEN)
if(!WT.remove_fuel(0, user))
return
playsound(loc, WT.usesound, 40, 1)
user << "<span class='notice'>You begin cutting [src] apart...</span>"
if(do_after(user, 30, target = src))
deconstruct(TRUE)
else
user << "<span class='notice'>You cannot slice [src] apart when it isn't broken.</span>"
return 1
else
return ..()
/obj/machinery/portable_atmospherics/canister/obj_break(damage_flag)
if((stat & BROKEN) || (flags & NODECONSTRUCT))
return
if(stat & BROKEN)
return
canister_break()
health = max( health - damage, 0)
if(!health)
disconnect()
var/datum/gas_mixture/expelled_gas = air_contents.remove(air_contents.total_moles())
var/turf/T = get_turf(src)
T.assume_air(expelled_gas)
air_update_turf()
/obj/machinery/portable_atmospherics/canister/proc/canister_break()
disconnect()
var/datum/gas_mixture/expelled_gas = air_contents.remove(air_contents.total_moles())
var/turf/T = get_turf(src)
T.assume_air(expelled_gas)
air_update_turf()
stat |= BROKEN
density = 0
playsound(src.loc, 'sound/effects/spray.ogg', 10, 1, -3)
update_icon()
investigate_log("was destroyed.", "atmos")
stat |= BROKEN
density = 0
playsound(src.loc, 'sound/effects/spray.ogg', 10, 1, -3)
update_icon()
investigate_log("was destroyed.", "atmos")
if(holding)
holding.forceMove(T)
holding = null
if(holding)
holding.loc = T
holding = null
/obj/machinery/portable_atmospherics/canister/process_atmos()
..()
@@ -254,6 +209,39 @@
air_update_turf() // Update the environment if needed.
update_icon()
/obj/machinery/portable_atmospherics/canister/blob_act(obj/effect/blob/B)
take_damage(100, BRUTE, 0)
/obj/machinery/portable_atmospherics/canister/burn()
take_damage(health, BURN, 1)
..()
/obj/machinery/portable_atmospherics/canister/bullet_act(obj/item/projectile/P)
. = ..()
take_damage(P.damage / 2, P.damage_type, 0)
/obj/machinery/portable_atmospherics/canister/ex_act(severity, target)
switch(severity)
if(1)
if((stat & BROKEN) || prob(30))
qdel(src)
else
take_damage(100, BRUTE, 0)
if(2)
if(stat & BROKEN)
qdel(src)
else
take_damage(rand(40, 110), BRUTE, 0)
if(3)
take_damage(rand(15, 40), BRUTE, 0)
/obj/machinery/portable_atmospherics/canister/attacked_by(obj/item/I, mob/user)
if(I.force)
user.visible_message("<span class='danger'>[user] has hit [src] with [I]!</span>", "<span class='danger'>You hit [src] with [I]!</span>")
investigate_log("was smacked with \a [I] by [key_name(user)].", "atmos")
add_fingerprint(user)
take_damage(I.force, I.damtype, 1)
/obj/machinery/portable_atmospherics/canister/ui_interact(mob/user, ui_key = "main", datum/tgui/ui = null, force_open = 0, \
datum/tgui/master_ui = null, datum/ui_state/state = physical_state)
ui = SStgui.try_update_ui(user, src, ui_key, ui, force_open)
@@ -288,9 +276,6 @@
var/newtype = label2types[label]
if(newtype)
var/obj/machinery/portable_atmospherics/canister/replacement = new newtype(loc, air_contents)
if(connected_port)
replacement.connected_port = connected_port
replacement.connected_port.connected_device = replacement
replacement.interact(usr)
qdel(src)
if("pressure")
@@ -323,22 +308,9 @@
var/plasma = air_contents.gases["plasma"]
var/n2o = air_contents.gases["n2o"]
var/bz = air_contents.gases["bz"]
var/freon = air_contents.gases["freon"]
if(n2o || plasma || bz || freon)
message_admins("[key_name_admin(usr)] (<A HREF='?_src_=holder;adminmoreinfo=\ref[usr]'>?</A>) (<A HREF='?_src_=holder;adminplayerobservefollow=\ref[usr]'>FLW</A>) opened a canister that contains the following: (<A HREF='?_src_=holder;adminplayerobservecoodjump=1;X=[x];Y=[y];Z=[z]'>JMP</a>)")
log_admin("[key_name(usr)] opened a canister that contains the following at [x], [y], [z]:")
if(plasma)
log_admin("Plasma")
message_admins("Plasma")
if(n2o)
log_admin("N2O")
message_admins("N2O")
if(bz)
log_admin("BZ Gas")
message_admins("BZ Gas")
if(freon)
log_admin("Freon")
message_admins("Freon")
if(n2o || plasma || bz)
message_admins("[key_name_admin(usr)] (<A HREF='?_src_=holder;adminmoreinfo=\ref[usr]'>?</A>) (<A HREF='?_src_=holder;adminplayerobservefollow=\ref[usr]'>FLW</A>) opened a canister that contains [n2o ? "N2O" : ""][n2o && plasma ? " & " : ""][plasma ? "Plasma" : ""][(n2o || plasma) && bz ? " & " : ""][bz ? "BZ" : ""]! (<A HREF='?_src_=holder;adminplayerobservecoodjump=1;X=[x];Y=[y];Z=[z]'>JMP</a>)")
log_admin("[key_name(usr)] opened a canister that contains [n2o ? "N2O" : ""][n2o && plasma ? " & " : ""][plasma ? "Plasma" : ""][(n2o || plasma) && bz ? " & " : ""][bz ? "BZ" : ""] at [x], [y], [z]")
else
logmsg = "Valve was <b>closed</b> by [key_name(usr)], stopping the transfer into \the [holding || "air"].<br>"
investigate_log(logmsg, "atmos")
@@ -2,10 +2,6 @@
name = "portable_atmospherics"
icon = 'icons/obj/atmos.dmi'
use_power = 0
obj_integrity = 250
max_integrity = 250
armor = list(melee = 0, bullet = 0, laser = 0, energy = 100, bomb = 0, bio = 100, rad = 100, fire = 60, acid = 30)
var/datum/gas_mixture/air_contents
var/obj/machinery/atmospherics/components/unary/portables_connector/connected_port
@@ -22,7 +18,6 @@
air_contents = new
air_contents.volume = volume
air_contents.temperature = T20C
air_contents.holder = src
return 1
@@ -62,11 +57,6 @@
anchored = 1 //Prevent movement
return 1
/obj/machinery/portable_atmospherics/Move()
. = ..()
if(.)
disconnect()
/obj/machinery/portable_atmospherics/proc/disconnect()
if(!connected_port)
return 0
@@ -91,7 +81,7 @@
if(!(stat & BROKEN))
if(connected_port)
disconnect()
playsound(src.loc, W.usesound, 50, 1)
playsound(src.loc, 'sound/items/Ratchet.ogg', 50, 1)
user.visible_message( \
"[user] disconnects [src].", \
"<span class='notice'>You unfasten [src] from the port.</span>", \
@@ -106,7 +96,7 @@
if(!connect(possible_port))
user << "<span class='notice'>[name] failed to connect to the port.</span>"
return
playsound(src.loc, W.usesound, 50, 1)
playsound(src.loc, 'sound/items/Ratchet.ogg', 50, 1)
user.visible_message( \
"[user] connects [src].", \
"<span class='notice'>You fasten [src] to the port.</span>", \
@@ -115,12 +105,4 @@
else if(istype(W, /obj/item/device/analyzer) && Adjacent(user))
atmosanalyzer_scan(air_contents, user)
else
return ..()
/obj/machinery/portable_atmospherics/attacked_by(obj/item/I, mob/user)
if(I.force < 10 && !(stat & BROKEN))
take_damage(0)
else
investigate_log("was smacked with \a [I] by [key_name(user)].", "atmos")
add_fingerprint(user)
..()
return ..()
@@ -7,7 +7,7 @@
var/volume_rate = 1000
volume = 1000
var/list/scrubbing = list("plasma", "co2", "n2o", "agent_b", "bz", "freon", "water_vapor")
var/list/scrubbing = list("plasma", "co2", "n2o", "agent_b", "bz")
/obj/machinery/portable_atmospherics/scrubber/Destroy()
var/turf/T = get_turf(src)
@@ -12,8 +12,8 @@
anchored = 1
/obj/machinery/artillerycontrol/process()
if(reload < ARTILLERY_RELOAD_TIME)
reload++
if(src.reload<ARTILLERY_RELOAD_TIME)
src.reload++
/obj/structure/artilleryplaceholder
name = "artillery"
@@ -39,13 +39,11 @@
if(..())
return
var/A
A = input("Area to bombard", "Open Fire", A) in teleportlocs
A = input("Area to jump bombard", "Open Fire", A) in teleportlocs
var/area/thearea = teleportlocs[A]
if(usr.stat || usr.restrained())
return
if(src.reload < ARTILLERY_RELOAD_TIME)
return
if(usr.contents.Find(src) || (in_range(src, usr) && isturf(loc)) || issilicon(usr))
if (usr.stat || usr.restrained()) return
if(src.reload < ARTILLERY_RELOAD_TIME) return
if ((usr.contents.Find(src) || (in_range(src, usr) && istype(src.loc, /turf))) || (istype(usr, /mob/living/silicon)))
priority_announce("Bluespace artillery fire detected. Brace for impact.")
message_admins("[key_name_admin(usr)] has launched an artillery strike.")
var/list/L = list()
+62 -144
View File
@@ -4,7 +4,6 @@
#define FLAG_RETURN_TIME 200 // 20 seconds
#define INSTAGIB_RESPAWN 50 //5 seconds
#define DEFAULT_RESPAWN 150 //15 seconds
#define AMMO_DROP_LIFETIME 300
@@ -19,7 +18,6 @@
throw_range = 1
force = 200
armour_penetration = 1000
resistance_flags = INDESTRUCTIBLE
anchored = TRUE
flags = HANDSLOW
var/team = WHITE_TEAM
@@ -28,7 +26,6 @@
var/reset_path = /obj/effect/ctf/flag_reset
/obj/item/weapon/twohanded/required/ctf/New()
..()
if(!reset)
reset = new reset_path(get_turf(src))
@@ -125,7 +122,6 @@
icon = 'icons/obj/device.dmi'
icon_state = "syndbeacon"
anchored = 1
resistance_flags = INDESTRUCTIBLE
var/team = WHITE_TEAM
//Capture the Flag scoring
var/points = 0
@@ -135,8 +131,6 @@
var/control_points = 0
var/control_points_to_win = 180
var/list/team_members = list()
var/list/spawned_mobs = list()
var/list/recently_dead_ckeys = list()
var/ctf_enabled = FALSE
var/ctf_gear = /datum/outfit/ctf
var/instagib_gear = /datum/outfit/ctf/instagib
@@ -163,21 +157,6 @@
poi_list.Remove(src)
..()
/obj/machinery/capture_the_flag/process()
for(var/i in spawned_mobs)
if(!i)
spawned_mobs -= i
continue
// Anyone in crit, automatically reap
var/mob/living/M = i
if(M.InCritical() || M.stat == DEAD)
ctf_dust_old(M)
else
// The changes that you've been hit with no shield but not
// instantly critted are low, but have some healing.
M.adjustBruteLoss(-1)
M.adjustFireLoss(-1)
/obj/machinery/capture_the_flag/red
name = "Red CTF Controller"
icon_state = "syndbeacon"
@@ -198,12 +177,11 @@
if(ticker.current_state != GAME_STATE_PLAYING)
return
if(user.ckey in team_members)
if(user.ckey in recently_dead_ckeys)
if(user.mind.current && user.mind.current.timeofdeath + respawn_cooldown > world.time)
user << "It must be more than [respawn_cooldown/10] seconds from your last death to respawn!"
return
var/client/new_team_member = user.client
if(user.mind && user.mind.current)
ctf_dust_old(user.mind.current)
dust_old(user)
spawn_team_member(new_team_member)
return
@@ -218,20 +196,15 @@
return
team_members |= user.ckey
var/client/new_team_member = user.client
if(user.mind && user.mind.current)
ctf_dust_old(user.mind.current)
dust_old(user)
spawn_team_member(new_team_member)
/obj/machinery/capture_the_flag/proc/ctf_dust_old(mob/living/body)
if(isliving(body) && body.z == src.z)
var/turf/T = get_turf(body)
new /obj/effect/ctf/ammo(T)
recently_dead_ckeys += body.ckey
addtimer(src, "clear_cooldown", respawn_cooldown, TIMER_UNIQUE, body.ckey)
body.dust()
/obj/machinery/capture_the_flag/proc/dust_old(mob/user)
if(user.mind && user.mind.current && user.mind.current.z == src.z)
new /obj/item/ammo_box/magazine/recharge/ctf (get_turf(user.mind.current))
new /obj/item/ammo_box/magazine/recharge/ctf (get_turf(user.mind.current))
user.mind.current.dust()
/obj/machinery/capture_the_flag/proc/clear_cooldown(var/ckey)
recently_dead_ckeys -= ckey
/obj/machinery/capture_the_flag/proc/spawn_team_member(client/new_team_member)
var/mob/living/carbon/human/M = new/mob/living/carbon/human(get_turf(src))
@@ -239,7 +212,6 @@
M.key = new_team_member.key
M.faction += team
M.equipOutfit(ctf_gear)
spawned_mobs += M
/obj/machinery/capture_the_flag/Topic(href, href_list)
if(href_list["join"])
@@ -309,15 +281,12 @@
/obj/machinery/capture_the_flag/proc/stop_ctf()
ctf_enabled = FALSE
arena_cleared = FALSE
var/area/A = get_area(src)
for(var/i in mob_list)
var/mob/M = i
if((get_area(A) == A) && (M.ckey in team_members))
M.dust()
team_members.Cut()
spawned_mobs.Cut()
recently_dead_ckeys.Cut()
/obj/machinery/capture_the_flag/proc/instagib_mode()
for(var/obj/machinery/capture_the_flag/CTF in machines)
@@ -331,45 +300,25 @@
CTF.ctf_gear = initial(ctf_gear)
CTF.respawn_cooldown = DEFAULT_RESPAWN
/obj/item/weapon/gun/ballistic/automatic/pistol/deagle/ctf
/obj/item/weapon/gun/projectile/automatic/pistol/deagle/CTF
desc = "This looks like it could really hurt in melee."
force = 75
/obj/item/weapon/gun/ballistic/automatic/pistol/deagle/ctf/dropped()
. = ..()
addtimer(src, "floor_vanish", 1)
/obj/item/weapon/gun/ballistic/automatic/pistol/deagle/ctf/proc/floor_vanish()
if(isturf(loc))
qdel(src)
/obj/item/weapon/gun/ballistic/automatic/laser/ctf
/obj/item/weapon/gun/projectile/automatic/laser/ctf
mag_type = /obj/item/ammo_box/magazine/recharge/ctf
desc = "This looks like it could really hurt in melee."
force = 50
flags = NODROP | DROPDEL
/obj/item/ammo_box/magazine/recharge/ctf
ammo_type = /obj/item/ammo_casing/caseless/laser/ctf
/obj/item/ammo_box/magazine/recharge/ctf/dropped()
. = ..()
addtimer(src, "floor_vanish", 1)
/obj/item/ammo_box/magazine/recharge/ctf/proc/floor_vanish()
if(isturf(loc))
qdel(src)
/obj/item/ammo_casing/caseless/laser/ctf
projectile_type = /obj/item/projectile/beam/ctf
/obj/item/projectile/beam/ctf
damage = 150
icon_state = "omnilaser"
// RED TEAM GUNS
/obj/item/weapon/gun/ballistic/automatic/laser/ctf/red
/obj/item/weapon/gun/projectile/automatic/laser/ctf/red
mag_type = /obj/item/ammo_box/magazine/recharge/ctf/red
/obj/item/ammo_box/magazine/recharge/ctf/red
@@ -381,9 +330,7 @@
/obj/item/projectile/beam/ctf/red
icon_state = "laser"
// BLUE TEAM GUNS
/obj/item/weapon/gun/ballistic/automatic/laser/ctf/blue
/obj/item/weapon/gun/projectile/automatic/laser/ctf/blue
mag_type = /obj/item/ammo_box/magazine/recharge/ctf/blue
/obj/item/ammo_box/magazine/recharge/ctf/blue
@@ -397,34 +344,16 @@
/datum/outfit/ctf
name = "CTF"
ears = /obj/item/device/radio/headset
/obj/item/device/radio/headset
uniform = /obj/item/clothing/under/syndicate
suit = /obj/item/clothing/suit/space/hardsuit/shielded/ctf
shoes = /obj/item/clothing/shoes/combat
gloves = /obj/item/clothing/gloves/combat
id = /obj/item/weapon/card/id/syndicate
belt = /obj/item/weapon/gun/ballistic/automatic/pistol/deagle/ctf
belt = /obj/item/weapon/gun/projectile/automatic/pistol/deagle/CTF
l_pocket = /obj/item/ammo_box/magazine/recharge/ctf
r_pocket = /obj/item/ammo_box/magazine/recharge/ctf
r_hand = /obj/item/weapon/gun/ballistic/automatic/laser/ctf
/datum/outfit/ctf/post_equip(mob/living/carbon/human/H, visualsOnly=FALSE)
if(visualsOnly)
return
var/list/no_drops = list()
var/obj/item/weapon/card/id/W = H.wear_id
no_drops += W
W.registered_name = H.real_name
W.update_label(W.registered_name, W.assignment)
// The shielded hardsuit is already NODROP
no_drops += H.get_item_by_slot(slot_gloves)
no_drops += H.get_item_by_slot(slot_shoes)
no_drops += H.get_item_by_slot(slot_w_uniform)
no_drops += H.get_item_by_slot(slot_ears)
for(var/i in no_drops)
var/obj/item/I = i
I.flags |= NODROP
r_hand = /obj/item/weapon/gun/projectile/automatic/laser/ctf
/datum/outfit/ctf/instagib
r_hand = /obj/item/weapon/gun/energy/laser/instakill
@@ -433,9 +362,7 @@
/datum/outfit/ctf/red
ears = /obj/item/device/radio/headset/syndicate/alt
suit = /obj/item/clothing/suit/space/hardsuit/shielded/ctf/red
r_hand = /obj/item/weapon/gun/ballistic/automatic/laser/ctf/red
l_pocket = /obj/item/ammo_box/magazine/recharge/ctf/red
r_pocket = /obj/item/ammo_box/magazine/recharge/ctf/red
r_hand = /obj/item/weapon/gun/projectile/automatic/laser/ctf/red
/datum/outfit/ctf/red/instagib
r_hand = /obj/item/weapon/gun/energy/laser/instakill/red
@@ -444,50 +371,49 @@
/datum/outfit/ctf/blue
ears = /obj/item/device/radio/headset/headset_cent/commander
suit = /obj/item/clothing/suit/space/hardsuit/shielded/ctf/blue
r_hand = /obj/item/weapon/gun/ballistic/automatic/laser/ctf/blue
l_pocket = /obj/item/ammo_box/magazine/recharge/ctf/blue
r_pocket = /obj/item/ammo_box/magazine/recharge/ctf/blue
r_hand = /obj/item/weapon/gun/projectile/automatic/laser/ctf/blue
/datum/outfit/ctf/blue/instagib
r_hand = /obj/item/weapon/gun/energy/laser/instakill/blue
shoes = /obj/item/clothing/shoes/jackboots/fast
/datum/outfit/ctf/red/post_equip(mob/living/carbon/human/H)
..()
var/obj/item/device/radio/R = H.ears
R.set_frequency(SYND_FREQ)
R.freqlock = 1
/datum/outfit/ctf/blue/post_equip(mob/living/carbon/human/H)
..()
var/obj/item/device/radio/R = H.ears
R.set_frequency(CENTCOM_FREQ)
R.freqlock = 1
/obj/structure/trap/ctf
/obj/structure/divine/trap/ctf
name = "Spawn protection"
desc = "Stay outta the enemy spawn!"
icon_state = "trap"
resistance_flags = INDESTRUCTIBLE
health = INFINITY
maxhealth = INFINITY
var/team = WHITE_TEAM
constructable = FALSE
time_between_triggers = 1
alpha = 255
/obj/structure/trap/examine(mob/user)
/obj/structure/divine/trap/examine(mob/user)
return
/obj/structure/trap/ctf/trap_effect(mob/living/L)
/obj/structure/divine/trap/ctf/trap_effect(mob/living/L)
if(!(src.team in L.faction))
L << "<span class='danger'><B>Stay out of the enemy spawn!</B></span>"
L.death()
L.dust()
/obj/structure/trap/ctf/red
/obj/structure/divine/trap/ctf/red
team = RED_TEAM
icon_state = "trap-fire"
/obj/structure/trap/ctf/blue
/obj/structure/divine/trap/ctf/blue
team = BLUE_TEAM
icon_state = "trap-frost"
@@ -503,50 +429,8 @@
anchored = TRUE
invisibility = INVISIBILITY_OBSERVER
alpha = 100
resistance_flags = INDESTRUCTIBLE
/obj/effect/ctf/ammo
name = "ammo pickup"
desc = "You like revenge, right? Everybody likes revenge! Well, \
let's go get some!"
icon = 'icons/effects/effects.dmi'
icon_state = "at_shield1"
layer = ABOVE_MOB_LAYER
alpha = 255
invisibility = 0
/obj/effect/ctf/ammo/New()
..()
QDEL_IN(src, AMMO_DROP_LIFETIME)
/obj/effect/ctf/ammo/Crossed(atom/movable/AM)
reload(AM)
/obj/effect/ctf/ammo/Bump(atom/movable/AM)
reload(AM)
/obj/effect/ctf/ammo/Bumped(atom/movable/AM)
reload(AM)
/obj/effect/ctf/ammo/proc/reload(mob/living/M)
if(!ishuman(M))
return
for(var/obj/machinery/capture_the_flag/CTF in machines)
if(M in CTF.spawned_mobs)
var/outfit = CTF.ctf_gear
var/datum/outfit/O = new outfit
for(var/obj/item/weapon/gun/G in M)
M.unEquip(G)
qdel(G)
O.equip(M)
M << "<span class='notice'>Ammunition reloaded!</span>"
playsound(get_turf(M), 'sound/weapons/shotgunpump.ogg', 50, 1, -1)
qdel(src)
break
/obj/effect/ctf/dead_barricade
name = "dead barrier"
desc = "It provided cover in fire fights. And now it's gone."
icon = 'icons/obj/objects.dmi'
icon_state = "barrier0"
@@ -559,6 +443,41 @@
new /obj/structure/barricade/security/ctf(get_turf(src))
qdel(src)
//Areas
/area/ctf
name = "Capture the Flag"
icon_state = "yellow"
requires_power = 0
has_gravity = 1
/area/ctf/control_room
name = "Control Room A"
/area/ctf/control_room2
name = "Control Room B"
/area/ctf/central
name = "Central"
/area/ctf/main_hall
name = "Main Hall A"
/area/ctf/main_hall2
name = "Main Hall B"
/area/ctf/corridor
name = "Corridor A"
/area/ctf/corridor2
name = "Corridor B"
/area/ctf/flag_room
name = "Flag Room A"
/area/ctf/flag_room2
name = "Flag Room B"
//Control Point
@@ -568,7 +487,6 @@
icon = 'icons/obj/machines/dominator.dmi'
icon_state = "dominator"
anchored = 1
resistance_flags = INDESTRUCTIBLE
var/obj/machinery/capture_the_flag/controlling
var/team = "none"
var/point_rate = 1
+4 -15
View File
@@ -27,9 +27,6 @@
if(!uses)
user << "<span class='warning'>This spawner is out of charges!</span>"
return
if(jobban_isbanned(user, "lavaland"))
user << "<span class='warning'>You are jobanned!</span>"
return
var/ghost_role = alert("Become [mob_name]? (Warning, You can no longer be cloned!)",,"Yes","No")
if(ghost_role == "No" || !loc)
return
@@ -109,7 +106,6 @@
var/radio = null
var/glasses = null
var/mask = null
var/neck = null
var/helmet = null
var/belt = null
var/pocket1 = null
@@ -118,7 +114,6 @@
var/has_id = 0 //Just set to 1 if you want them to have an ID
var/id_job = null // Needs to be in quotes, such as "Clown" or "Chef." This just determines what the ID reads as, not their access
var/id_access = null //This is for access. See access.dm for which jobs give what access. Again, put in quotes. Use "Captain" if you want it to be all access.
var/id_access_list = null //Allows you to manually add access to an ID card.
var/id_icon = null //For setting it to be a gold, silver, centcom etc ID
var/husk = null
var/outfit_type = null // Will start with this if exists then apply specific slots
@@ -145,8 +140,6 @@
H.equip_to_slot_or_del(new glasses(H), slot_glasses)
if(mask)
H.equip_to_slot_or_del(new mask(H), slot_wear_mask)
if(neck)
H.equip_to_slot_or_del(new neck(H), slot_neck)
if(helmet)
H.equip_to_slot_or_del(new helmet(H), slot_head)
if(belt)
@@ -158,9 +151,9 @@
if(back)
H.equip_to_slot_or_del(new back(H), slot_back)
if(l_hand)
H.put_in_hands_or_del(new l_hand(H))
H.equip_to_slot_or_del(new l_hand(H), slot_l_hand)
if(r_hand)
H.put_in_hands_or_del(new r_hand(H))
H.equip_to_slot_or_del(new r_hand(H), slot_r_hand)
if(has_id)
var/obj/item/weapon/card/id/W = new(H)
if(id_icon)
@@ -176,10 +169,6 @@
W.access = jobdatum.get_access()
else
W.access = list()
if(id_access_list)
if(!W.access)
W.access = list()
W.access |= id_access_list
if(id_job)
W.assignment = id_job
W.registered_name = H.real_name
@@ -266,7 +255,7 @@
back = /obj/item/weapon/storage/backpack
has_id = 1
id_job = "Operative"
id_access_list = list(access_syndicate)
id_access = "Syndicate"
/obj/effect/mob_spawn/human/syndicatecommando
name = "Syndicate Commando"
@@ -281,7 +270,7 @@
pocket1 = /obj/item/weapon/tank/internals/emergency_oxygen
has_id = 1
id_job = "Operative"
id_access_list = list(access_syndicate)
id_access = "Syndicate"
///////////Civilians//////////////////////
+31
View File
@@ -1,3 +1,34 @@
//Exile implants will allow you to use the station gate, but not return home.
//This will allow security to exile badguys/for badguys to exile their kill targets
/obj/item/weapon/implant/exile
name = "exile implant"
desc = "Prevents you from returning from away missions"
origin_tech = "materials=2;biotech=3;magnets=2;bluespace=3"
activated = 0
/obj/item/weapon/implant/exile/get_data()
var/dat = {"<b>Implant Specifications:</b><BR>
<b>Name:</b> Nanotrasen Employee Exile Implant<BR>
<b>Implant Details:</b> The onboard gateway system has been modified to reject entry by individuals containing this implant<BR>"}
return dat
/obj/item/weapon/implanter/exile
name = "implanter (exile)"
/obj/item/weapon/implanter/exile/New()
imp = new /obj/item/weapon/implant/exile( src )
..()
/obj/item/weapon/implantcase/exile
name = "implant case - 'Exile'"
desc = "A glass case containing an exile implant."
/obj/item/weapon/implantcase/exile/New()
imp = new /obj/item/weapon/implant/exile(src)
..()
/obj/structure/closet/secure_closet/exile
name = "exile implants"
+5 -5
View File
@@ -7,7 +7,7 @@ var/obj/machinery/gateway/centerstation/the_gateway = null
icon_state = "off"
density = 1
anchored = 1
resistance_flags = INDESTRUCTIBLE | LAVA_PROOF | FIRE_PROOF | UNACIDABLE | ACID_PROOF
unacidable = 1
var/active = 0
@@ -253,10 +253,10 @@ var/obj/machinery/gateway/centerstation/the_gateway = null
if(!stationgate || qdeleted(stationgate))
return
if(istype(AM, /mob/living/carbon))
var/mob/living/carbon/C = AM
for(var/obj/item/weapon/implant/exile/E in C.implants)//Checking that there is an exile implant
AM << "\black The station gate has detected your exile implant and is blocking your entry."
return
for(var/obj/item/weapon/implant/exile/E in AM)//Checking that there is an exile implant in the contents
if(E.imp_in == AM)//Checking that it's actually implanted vs just in their pocket
AM << "\black The station gate has detected your exile implant and is blocking your entry."
return
AM.forceMove(get_step(stationgate.loc, SOUTH))
AM.setDir(SOUTH)
if (ismob(AM))
@@ -41,9 +41,8 @@ var/global/dmm_suite/preloader/_preloader = new
var/list/grid_models = list()
var/key_len = 0
var/stored_index = 1
while(dmmRegex.Find(tfile, stored_index))
stored_index = dmmRegex.next
dmmRegex.next = 1
while(dmmRegex.Find(tfile, dmmRegex.next))
// "aa" = (/type{vars=blah})
if(dmmRegex.group[1]) // Model
@@ -362,6 +361,13 @@ var/global/dmm_suite/preloader/_preloader = new
return to_return
//atom creation method that preloads variables at creation
/atom/New()
if(use_preloader && (src.type == _preloader.target_path))//in case the instanciated atom is creating other atoms in New()
_preloader.load(src)
. = ..()
/dmm_suite/Destroy()
..()
return QDEL_HINT_HARDDEL_NOW
+13 -13
View File
@@ -1,4 +1,4 @@
//This file was auto-corrected by findeclaration.exe on 25.5.2012 20:42:32
/*
SwapMaps library by Lummox JR
@@ -509,7 +509,7 @@ var/swapmaps_initialized
var/swapmaps_loaded
var/swapmaps_byname
/proc/InitializeSwapMaps()
proc/InitializeSwapMaps()
if(swapmaps_initialized) return
swapmaps_initialized=1
swapmaps_compiled_maxx=world.maxx
@@ -523,16 +523,16 @@ var/swapmaps_byname
// so you can look up an icon file by name or vice-versa
swapmaps_iconcache[swapmaps_iconcache[V]]=V
/proc/SwapMaps_AddIconToCache(name,icon)
proc/SwapMaps_AddIconToCache(name,icon)
if(!swapmaps_iconcache) swapmaps_iconcache=list()
swapmaps_iconcache[name]=icon
swapmaps_iconcache[icon]=name
/proc/SwapMaps_Find(id)
proc/SwapMaps_Find(id)
InitializeSwapMaps()
return swapmaps_byname[id]
/proc/SwapMaps_Load(id)
proc/SwapMaps_Load(id)
InitializeSwapMaps()
var/swapmap/M=swapmaps_byname[id]
if(!M)
@@ -553,29 +553,29 @@ var/swapmaps_byname
M.mode=text
return M
/proc/SwapMaps_Save(id)
proc/SwapMaps_Save(id)
InitializeSwapMaps()
var/swapmap/M=swapmaps_byname[id]
if(M) M.Save()
return M
/proc/SwapMaps_Save_All()
proc/SwapMaps_Save_All()
InitializeSwapMaps()
for(var/swapmap/M in swapmaps_loaded)
if(M) M.Save()
/proc/SwapMaps_Unload(id)
proc/SwapMaps_Unload(id)
InitializeSwapMaps()
var/swapmap/M=swapmaps_byname[id]
if(!M) return // return silently from an error
M.Unload()
return 1
/proc/SwapMaps_DeleteFile(id)
proc/SwapMaps_DeleteFile(id)
fdel("map_[id].sav")
fdel("map_[id].txt")
/proc/SwapMaps_CreateFromTemplate(template_id)
proc/SwapMaps_CreateFromTemplate(template_id)
var/swapmap/M=new
var/savefile/S
var/text=0
@@ -602,7 +602,7 @@ var/swapmaps_byname
while(M.locked) sleep(1)
return M
/proc/SwapMaps_LoadChunk(chunk_id,turf/locorner)
proc/SwapMaps_LoadChunk(chunk_id,turf/locorner)
var/swapmap/M=new
var/savefile/S
var/text=0
@@ -629,7 +629,7 @@ var/swapmaps_byname
qdel(M)
return 1
/proc/SwapMaps_SaveChunk(chunk_id,turf/corner1,turf/corner2)
proc/SwapMaps_SaveChunk(chunk_id,turf/corner1,turf/corner2)
if(!corner1 || !corner2)
world.log << "SwapMaps error in SwapMaps_SaveChunk():"
if(!corner1) world.log << " corner1 turf is null"
@@ -650,7 +650,7 @@ var/swapmaps_byname
qdel(M)
return 1
/proc/SwapMaps_GetSize(id)
proc/SwapMaps_GetSize(id)
var/savefile/S
var/text=0
if(swapmaps_mode==SWAPMAPS_TEXT && fexists("map_[id].txt"))
@@ -1,3 +1,32 @@
//Academy Areas
/area/awaymission/academy
name = "Academy Asteroids"
icon_state = "away"
/area/awaymission/academy/headmaster
name = "Academy Fore Block"
icon_state = "away1"
/area/awaymission/academy/classrooms
name = "Academy Classroom Block"
icon_state = "away2"
/area/awaymission/academy/academyaft
name = "Academy Ship Aft Block"
icon_state = "away3"
/area/awaymission/academy/academygate
name = "Academy Gateway"
icon_state = "away4"
/area/awaymission/academy/academycellar
name = "Academy Cellar"
icon_state = "away4"
/area/awaymission/academy/academyengine
name = "Academy Engine"
icon_state = "away4"
//Academy Items
@@ -28,22 +57,17 @@
icon = 'icons/obj/cult.dmi'
icon_state = "forge"
anchored = 1
obj_integrity = 200
max_integrity = 200
var/health = 200
var/mob/living/current_wizard = null
var/next_check = 0
var/cooldown = 600
var/faction = "wizard"
var/broken = 0
var/braindead_check = 0
/obj/structure/academy_wizard_spawner/New()
START_PROCESSING(SSobj, src)
/obj/structure/academy_wizard_spawner/Destroy()
if(!broken)
STOP_PROCESSING(SSobj, src)
return ..()
/obj/structure/academy_wizard_spawner/process()
if(next_check < world.time)
if(!current_wizard)
@@ -67,7 +91,7 @@
if(!current_wizard)
return
spawn(0)
var/list/mob/dead/observer/candidates = pollCandidatesForMob("Do you want to play as Wizard Academy Defender?", "wizard", null, ROLE_WIZARD, current_wizard)
var/list/mob/dead/observer/candidates = pollCandidates("Do you want to play as Wizard Academy Defender?", "wizard", null, ROLE_WIZARD)
var/mob/dead/observer/chosen = null
if(candidates.len)
@@ -97,18 +121,34 @@
wizmind.AddSpell(new /obj/effect/proc_holder/spell/targeted/ethereal_jaunt)
wizmind.AddSpell(new /obj/effect/proc_holder/spell/targeted/projectile/magic_missile)
wizmind.AddSpell(new /obj/effect/proc_holder/spell/fireball)
wizmind.AddSpell(new /obj/effect/proc_holder/spell/dumbfire/fireball)
current_wizard = wizbody
give_control()
/obj/structure/academy_wizard_spawner/deconstruct(disassembled = TRUE)
if(!broken)
broken = 1
/obj/structure/academy_wizard_spawner/proc/update_status()
if(health<0)
visible_message("<span class='warning'>[src] breaks down!</span>")
icon_state = "forge_off"
STOP_PROCESSING(SSobj, src)
broken = 1
/obj/structure/academy_wizard_spawner/attackby(obj/item/weapon/W, mob/living/user, params)
add_fingerprint(user)
user.changeNext_move(CLICK_CD_MELEE)
if(!broken)
health -= W.force
update_status()
..()
/obj/structure/academy_wizard_spawner/bullet_act(obj/item/projectile/Proj)
if(!broken)
if((Proj.damage_type == BRUTE || Proj.damage_type == BURN))
health -= Proj.damage
update_status()
..()
return
/datum/outfit/wizard/academy
name = "Academy Wizard"
@@ -123,9 +163,9 @@
desc = "A die with twenty sides. You can feel unearthly energies radiating from it. Using this might be VERY risky."
icon_state = "d20"
sides = 20
can_be_rigged = FALSE
var/reusable = 1
var/used = 0
var/rigged = -1
/obj/item/weapon/dice/d20/fate/one_use
reusable = 0
@@ -136,7 +176,7 @@
if(!ishuman(user) || !user.mind || (user.mind in ticker.mode.wizards))
user << "<span class='warning'>You feel the magic of the dice is restricted to ordinary humans!</span>"
return
if(rigged)
if(rigged > 0)
effect(user,rigged)
else
effect(user,result)
@@ -213,7 +253,7 @@
new /obj/item/weapon/coin/gold(M)
if(14)
//Free Gun
new /obj/item/weapon/gun/ballistic/revolver/mateba(get_turf(src))
new /obj/item/weapon/gun/projectile/revolver/mateba(get_turf(src))
if(15)
//Random One-use spellbook
new /obj/item/weapon/spellbook/oneuse/random(get_turf(src))
@@ -226,7 +266,7 @@
servant_mind.objectives += O
servant_mind.transfer_to(H)
var/list/mob/dead/observer/candidates = pollCandidatesForMob("Do you want to play as [user.real_name] Servant?", "wizard", mob = H)
var/list/mob/dead/observer/candidates = pollCandidates("Do you want to play as [user.real_name] Servant?", "wizard")
var/mob/dead/observer/chosen = null
if(candidates.len)
+47 -34
View File
@@ -1,57 +1,74 @@
/*Cabin areas*/
/area/awaymission/snowforest
name = "Snow Forest"
icon_state = "away"
requires_power = 0
luminosity = 1
dynamic_lighting = DYNAMIC_LIGHTING_ENABLED
/obj/structure/firepit
name = "firepit"
/area/awaymission/cabin
name = "Cabin"
icon_state = "away2"
requires_power = 1
luminosity = 0
dynamic_lighting = DYNAMIC_LIGHTING_ENABLED
/area/awaymission/snowforest/lumbermill
name = "Lumbermill"
icon_state = "away3"
/*Cabin code*/
/obj/structure/fireplace
name = "fireplace"
desc = "warm and toasty"
icon = 'icons/obj/fireplace.dmi'
icon_state = "firepit-active"
icon = 'icons/obj/stationobjs.dmi'
icon_state = "fireplace-active"
density = 0
var/active = 1
/obj/structure/firepit/initialize()
/obj/structure/fireplace/initialize()
..()
toggleFirepit()
toggleFireplace()
/obj/structure/firepit/attack_hand(mob/living/user)
/obj/structure/fireplace/attack_hand(mob/living/user)
if(active)
active = 0
toggleFirepit()
toggleFireplace()
else
..()
/obj/structure/firepit/attackby(obj/item/W,mob/living/user,params)
/obj/structure/fireplace/attackby(obj/item/W,mob/living/user,params)
if(!active)
var/msg = W.ignition_effect(src, user)
if(msg)
active = TRUE
visible_message(msg)
toggleFirepit()
if(W.is_hot())
active = 1
toggleFireplace()
else
return ..()
else
W.fire_act()
/obj/structure/firepit/proc/toggleFirepit()
/obj/structure/fireplace/proc/toggleFireplace()
if(active)
SetLuminosity(8)
icon_state = "firepit-active"
set_light(8)
icon_state = "fireplace-active"
else
SetLuminosity(0)
icon_state = "firepit"
set_light(0)
icon_state = "fireplace"
/obj/structure/firepit/extinguish()
/obj/structure/fireplace/extinguish()
if(active)
active = FALSE
toggleFirepit()
active = 0
toggleFireplace()
/obj/structure/firepit/fire_act(exposed_temperature, exposed_volume)
/obj/structure/fireplace/fire_act()
if(!active)
active = TRUE
toggleFirepit()
//other Cabin Stuff//
active = 1
toggleFireplace()
/obj/machinery/recycler/lumbermill
name = "lumbermill saw"
@@ -79,8 +96,7 @@
/*Cabin's forest*/
/datum/mapGenerator/snowy
modules = list(/datum/mapGeneratorModule/bottomlayer/snow, \
/datum/mapGeneratorModule/snow/pineTrees, \
modules = list(/datum/mapGeneratorModule/snow/pineTrees, \
/datum/mapGeneratorModule/snow/deadTrees, \
/datum/mapGeneratorModule/snow/randBushes, \
/datum/mapGeneratorModule/snow/randIceRocks, \
@@ -90,9 +106,6 @@
if(istype(T,/turf/open/floor/plating/asteroid/snow))
return ..(T)
return 0
/datum/mapGeneratorModule/bottomlayer/snow
spawnableTurfs = list(/turf/open/floor/plating/asteroid/snow/atmosphere = 100)
/datum/mapGeneratorModule/snow/pineTrees
spawnableAtoms = list(/obj/structure/flora/tree/pine = 30)
@@ -1,4 +1,38 @@
//centcomAway areas
/area/awaymission/centcomAway
name = "XCC-P5831"
icon_state = "away"
requires_power = 0
/area/awaymission/centcomAway/general
name = "XCC-P5831"
music = "music/ambigen3.ogg"
/area/awaymission/centcomAway/maint
name = "XCC-P5831 Maintenance"
icon_state = "away1"
music = "music/ambisin1.ogg"
/area/awaymission/centcomAway/thunderdome
name = "XCC-P5831 Thunderdome"
icon_state = "away2"
music = "music/ambisin2.ogg"
/area/awaymission/centcomAway/cafe
name = "XCC-P5831 Kitchen Arena"
icon_state = "away3"
music = "music/ambisin3.ogg"
/area/awaymission/centcomAway/courtroom
name = "XCC-P5831 Courtroom"
icon_state = "away4"
music = "music/ambisin4.ogg"
/area/awaymission/centcomAway/hangar
name = "XCC-P5831 Hangars"
icon_state = "away4"
music = "music/ambigen5.ogg"
//centcomAway items
@@ -1,3 +1,19 @@
//Challenge Areas
/area/awaymission/challenge/start
name = "Where Am I?"
icon_state = "away"
/area/awaymission/challenge/main
name = "Danger Room"
icon_state = "away1"
requires_power = 0
/area/awaymission/challenge/end
name = "Administration"
icon_state = "away2"
requires_power = 0
/obj/machinery/power/emitter/energycannon
name = "Energy Cannon"
@@ -6,7 +22,6 @@
icon_state = "emitter"
anchored = 1
density = 1
resistance_flags = INDESTRUCTIBLE | FIRE_PROOF | ACID_PROOF
use_power = 0
idle_power_usage = 0
@@ -4,7 +4,7 @@
name = "Research Outpost"
icon_state = "away"
luminosity = 0
// dynamic_lighting = DYNAMIC_LIGHTING_ENABLED
dynamic_lighting = DYNAMIC_LIGHTING_ENABLED
/area/awaymission/research/interior
name = "Research Inside"
@@ -1,15 +1,51 @@
//Snow Valley Areas//--
/area/awaymission/snowdin
name = "Snowdin Tundra Plains"
icon_state = "away"
requires_power = 0
luminosity = 1
dynamic_lighting = DYNAMIC_LIGHTING_ENABLED
/area/awaymission/snowdin/post
name = "Snowdin Outpost"
requires_power = 1
/area/awaymission/snowdin/igloo
name = "Snowdin Igloos"
icon_state = "away2"
/area/awaymission/snowdin/cave
name = "Snowdin Caves"
icon_state = "away2"
luminosity = 0
/area/awaymission/snowdin/base
name = "Snowdin Main Base"
icon_state = "away3"
requires_power = 1
/area/awaymission/snowdin/dungeon1
name = "Snowdin Depths"
icon_state = "away2"
luminosity = 0
/area/awaymission/snowdin/sekret
name = "Snowdin Operations"
icon_state = "away3"
requires_power = 1
//notes for lore or treasure hints wow//--
/obj/item/weapon/paper/crumpled/snowdin/snowdingatewaynotice
name = "scribbled note"
info = {"The gateway has been inactive for months, engineers think it's due to the recent drop in tempature fucking with the
info = {"The gateway has been inactive for months, engineers think its due to the recent drop in tempature fucking with the
circuitry or something. Without a constant supply of resources from central command, our stock is getting awfully low. Some of the security members have taken to
using the sparse rifle ammo left to hunting some of the wildlife to try and keep our food supply from emptying. God forbid if the heating goes out, I don't want to
die as a fucking popsicle down here."}
/obj/item/weapon/paper/crumpled/snowdin/misc1
name = "Mission Prologue"
name = "Mission Prologe"
info = {"Holy shit, what a rush! Those Nanotrasen bastards didn't even know what hit 'em! All five of us dropped in right on the captain, didn't even have time to yell! We were in and out with that disk in mere minutes!
Crew didn't even know what was happening till the delta alert went down and by then were were already gone. We got a case to drink on the way home to celebrate, fuckin' job well done!"}
@@ -26,45 +62,45 @@
freezing shut along with a couple storage crates with supplies. Nothing on the radio so far, what the hell do they even expect to hear down here, anyway?<br><br><b>September 15th</b>
<br>Another supply shipment through the gateway, they've sent some heavier sets of clothes for the coming winter months. Central said they might encounter issues with shipments
during December to Feburary, so we should try to be frugal with the next shipment.<br><br><b>November 20th</b><br>Final shipment from central for the next few months. Going outside
for more than 10-15 minutes without losing feeling in your fingers is difficult. We've finally gotten a signal on the radio, it's mostly some weird static though. One of the researchers is trying to decypher it.
<br><br><b>December 10th</b><br>Signal has gotten much stronger, it almost seems like it's coming from under us according to what the researcher managed to decypher. We're waiting from the go from central before investigating.<br><br>
<i>The rest of the paper seems to be a mixture of scribbles and smudged ink.</i> "}
for more than 10-15 minutes without losing feeling in your fingers is difficult. We've finally gotten a signal on the radio, its mostly some weird static though. One of the researchers is trying to decypher it.
<br><br><b>December 10th</b><br>Signal has gotten much stronger, it almost seems like its coming from under us according to what the researcher managed to decypher. We're waiting from the go from central before investigating.<br><br>
<i>The rest of the paper seems to be a mixture of scribles and smudged ink.</i> "}
/obj/item/weapon/paper/snowdin/snowdinlog2
name = "Activity Log"
info = {"<b><center>ACTIVITY LOG</b></center><br><br><b>June 14th</b><br>Movement to the second post is finally done. We're located on the southernmost area of the valley with a similar objective as the northern post.
There are two mid-way stops on the eastern and western sides of the valley so movement in between bases isn't horrible. Not too big of a fan of relying on the northern base for
info = {"<b><center>ACTIVITY LOG</b></center><br><br><b>June 14th</b><br>Movement to the second post is finally done. We're located on the most-southern area of the valley with a similar objective as the northen post.
Theres two mid-way stops on the eastern and western sides of the valley so movement inbetween bases isn't horrible. Not too big of a fan of relying on the northen base for
equal supply distribution, though.<br><br><b>August 27h</b><br>First shipment arrived finally, about 4 days after the gateway shipped. Insulation on these buildings is awful, thank god for the spare heaters at least.<br><br>
<b>September 20th</b><br>Another shipment arrival, standard shit. Our radios have been picking up a weird signal during the nights recently, we've sent the transcripts over to the northern
<b>September 20th</b><br>Another shipment arrival, standard shit. Our radios have been picking up a weird signal during the nights recently, we've sent the transcripts over to the northen
base to be decyphered. Probably some drunk russians or something equally stupid.<br><br><b>November 24th</b><br>We've lost communications with the northern base after recieving the last
shipment of supplies. The snow has really kicked up recently, shits almost like a constant blizzard right now. Maybe it'll drop down soon so we can get a word in.<br><br>
<i>The rest of the paper seems to be a mixture of scribbles and smudged ink.</i> "}
<i>The rest of the paper seems to be a mixture of scribles and smudged ink.</i> "}
/obj/item/weapon/paper/snowdin/secnotice
obj/item/weapon/paper/snowdin/secnotice
name = "Security Notice"
info = {"You have been assigned a position on a listening outpost. Here you'll be watching over several crewmembers assigned to watching signals of the general area.
info = {"You have been assigned a postion on a listening outpost. Here you'll be watching over a several crewmembers assigned to watching signals of the general area.
As not much is expected in terms of issues, we've only assigned one guard per outpost. Crewmembers are expected to keep to their regulated work schedules and may be
disciplined properly if found slacking. Food hoarding is heavily discouraged as all outposts will be sharing from the same shipment every 2-3 months. Hoarding of supplies
disciplined properly if found slacking. Food hording is heavily discouraged as all outposts will be sharing from the same shipment every 2-3 months. Hording of supplies
should be punished severely as to prevent future incidients. Mutiny and/or rioting should be reported to central and dealt with swiftly. You're here to secure and protect
Nanotrasen assets, not be a police officer. Do what you must, but make sure it's not messy."}
Nanotrasen assets, not be a police officer. Do what you must, but make sure its not messy."}
/obj/item/weapon/paper/snowdin/syndienotice
obj/item/weapon/paper/snowdin/syndienotice
name = "Assignment Notice"
info = {"You've been assigned as an agent to listen in on Nanotrasen activities from passing ships and nearby stations. The outpost you've been assigned to is under lays of solid
ice and we've supplied you with a scrambler to help avoid Nanotrasen discovery, as they've recently built a listening post of their own aboveground. Get aquainted with your new
crewmates, because you're gonna be here for awhile. Enjoy the free syndicakes."}
/obj/item/weapon/paper/crumpled/snowdin/syndielava
obj/item/weapon/paper/crumpled/snowdin/syndielava
name = "scribbled note"
info = {"Some cracks in the ice nearby have exposed some sort of hidden magma stream under all this shit ice. I don't know whats worse at this point honestly; freezing to death or
burning alive."}
/obj/item/weapon/paper/crumpled/snowdin/lootstructures
obj/item/weapon/paper/crumpled/snowdin/lootstructures
name = "scribbled note"
info = {"From what we've seen so far, theres a ton of iced-over ruins down here in the caves. We sent a few men out to check things out and they never came back, so we decided to
info = {"From what we've seen so far, theres a ton of iced over ruins down here in the caves. We sent a few men out to check things out and they never came back, so we decided to
border up majority of the ruins. We've heard some weird shit coming out of these caves and I'm not gonna find out the hard way myself."}
/obj/item/weapon/paper/crumpled/snowdin/shovel
obj/item/weapon/paper/crumpled/snowdin/shovel
name = "shoveling duties"
info = {"Snow piles up bad here all-year round, even worse during the winter months. Keeping a constant rotation of shoveling that shit out of the way of the airlocks and keeping the paths decently clear
is a good step towards not getting stuck walking through knee-deep snow."}
@@ -130,7 +166,7 @@
/obj/item/organ/brain/alien = 17,
/obj/item/weapon/twohanded/dualsaber = 15,
/obj/item/organ/heart/demon = 7,
/obj/item/weapon/gun/ballistic/automatic/c20r/unrestricted = 16,
/obj/item/weapon/gun/projectile/automatic/c20r/unrestricted = 16,
/obj/item/weapon/gun/magic/wand/resurrection/inert = 15,
/obj/item/weapon/gun/magic/wand/resurrection = 10,
/obj/item/device/radio/uplink/old = 2,
@@ -157,7 +193,7 @@
/obj/item/clothing/under/syndicate/coldres
name = "insulated tactical turtleneck"
desc = "A non-descript and slightly suspicious looking turtleneck with digital camouflage cargo pants. The interior has been padded with special insulation for both warmth and protection"
armor = list(melee = 20, bullet = 10, laser = 0,energy = 5, bomb = 0, bio = 0, rad = 0, fire = 25, acid = 25)
armor = list(melee = 20, bullet = 10, laser = 0,energy = 5, bomb = 0, bio = 0, rad = 0)
cold_protection = CHEST|GROIN|ARMS|LEGS
min_cold_protection_temperature = FIRE_SUIT_MIN_TEMP_PROTECT
/obj/item/clothing/shoes/combat/coldres
@@ -184,16 +220,16 @@
hidden_uplink.name = "dusty radio"
hidden_uplink.telecrystals = 10
/obj/effect/mob_spawn/human/syndicatesoldier/coldres
obj/effect/mob_spawn/human/syndicatesoldier/coldres
name = "Syndicate Snow Operative"
uniform = /obj/item/clothing/under/syndicate/coldres
shoes = /obj/item/clothing/shoes/combat/coldres
radio = /obj/item/device/radio/headset/syndicate/alt
pocket1 = /obj/item/weapon/gun/ballistic/automatic/pistol
pocket1 = /obj/item/weapon/gun/projectile/automatic/pistol
pocket2 = /obj/item/weapon/card/id/syndicate
has_id = 0
/obj/effect/mob_spawn/human/syndicatesoldier/coldres/alive
obj/effect/mob_spawn/human/syndicatesoldier/coldres/alive
name = "sleeper"
mob_name = "Syndicate Snow Operative"
icon = 'icons/obj/Cryogenic2.dmi'
@@ -205,7 +241,7 @@
flavour_text = {"You are a syndicate operative recently awoken from cyrostatis in an underground outpost. Monitor Nanotrasen communications and record infomation. All intruders should be
disposed of swirfly to assure no gathered infomation is stolen or lost. Try not to wander too far from the outpost as the caves can be a deadly place even for a trained operative such as yourself."}
/obj/effect/mob_spawn/human/syndicatesoldier/coldres/alive/female
obj/effect/mob_spawn/human/syndicatesoldier/coldres/alive/female
mob_gender = FEMALE
//mobs//--
@@ -241,4 +277,3 @@
name = "icey rocks"
color = rgb(114,228,250)
@@ -0,0 +1,33 @@
//Spacebattle Areas
/area/awaymission/spacebattle
name = "Space Battle"
icon_state = "away"
requires_power = 0
/area/awaymission/spacebattle/cruiser
name = "Nanotrasen Cruiser"
/area/awaymission/spacebattle/syndicate1
name = "Syndicate Assault Ship 1"
/area/awaymission/spacebattle/syndicate2
name = "Syndicate Assault Ship 2"
/area/awaymission/spacebattle/syndicate3
name = "Syndicate Assault Ship 3"
/area/awaymission/spacebattle/syndicate4
name = "Syndicate War Sphere 1"
/area/awaymission/spacebattle/syndicate5
name = "Syndicate War Sphere 2"
/area/awaymission/spacebattle/syndicate6
name = "Syndicate War Sphere 3"
/area/awaymission/spacebattle/syndicate7
name = "Syndicate Fighter"
/area/awaymission/spacebattle/secret
name = "Hidden Chamber"
@@ -7,6 +7,7 @@
* for anyone who wants to make their own stuff.
*
* Contains:
* Areas
* Landmarks
* Guns
* Safe code hints
@@ -14,6 +15,29 @@
* Modified Nar-Sie
*/
/*
* Areas
*/
//Gateroom gets its own APC specifically for the gate
/area/awaymission/gateroom
//Library, medbay, storage room
/area/awaymission/southblock
//Arrivals, security, hydroponics, shuttles (since they dont move, they dont need specific areas)
/area/awaymission/arrivalblock
//Crew quarters, cafeteria, chapel
/area/awaymission/midblock
//engineering, bridge (not really north but it doesnt really need its own APC)
/area/awaymission/northblock
//That massive research room
/area/awaymission/research
//Syndicate shuttle
/area/awaymission/syndishuttle
/*
@@ -36,7 +60,7 @@
* Guns - I'm making these specifically so that I dont spawn a pile of fully loaded weapons on the map.
*/
//Captain's retro laser - Fires practice laser shots instead.
/obj/item/weapon/gun/energy/laser/retro/sc_retro
obj/item/weapon/gun/energy/laser/retro/sc_retro
name ="retro laser"
icon_state = "retro"
desc = "An older model of the basic lasergun, no longer used by Nanotrasen's security or military forces."
@@ -44,18 +68,18 @@
clumsy_check = 0 //No sense in having a harmless gun blow up in the clowns face
//Syndicate sub-machine guns.
/obj/item/weapon/gun/ballistic/automatic/c20r/sc_c20r
/obj/item/weapon/gun/projectile/automatic/c20r/sc_c20r
/obj/item/weapon/gun/ballistic/automatic/c20r/sc_c20r/New()
/obj/item/weapon/gun/projectile/automatic/c20r/sc_c20r/New()
..()
for(var/ammo in magazine.stored_ammo)
if(prob(95)) //95% chance
magazine.stored_ammo -= ammo
//Barman's shotgun
/obj/item/weapon/gun/ballistic/shotgun/sc_pump
/obj/item/weapon/gun/projectile/shotgun/sc_pump
/obj/item/weapon/gun/ballistic/shotgun/sc_pump/New()
/obj/item/weapon/gun/projectile/shotgun/sc_pump/New()
..()
for(var/ammo in magazine.stored_ammo)
if(prob(95)) //95% chance
@@ -151,7 +175,7 @@ var/sc_safecode5 = "[rand(0,9)]"
/obj/singularity/narsie/sc_Narsie/consume(atom/A)
if(is_type_in_list(A, uneatable))
return 0
if(isliving(A))
if (istype(A,/mob/living))
var/mob/living/L = A
L.gib()
else if(istype(A,/obj/))
@@ -4,6 +4,36 @@
* Meat Grinder
*/
//Wild West Areas
/area/awaymission/wwmines
name = "Wild West Mines"
icon_state = "away1"
luminosity = 1
requires_power = 0
/area/awaymission/wwgov
name = "Wild West Mansion"
icon_state = "away2"
luminosity = 1
requires_power = 0
/area/awaymission/wwrefine
name = "Wild West Refinery"
icon_state = "away3"
luminosity = 1
requires_power = 0
/area/awaymission/wwvault
name = "Wild West Vault"
icon_state = "away3"
luminosity = 0
/area/awaymission/wwvaultdoors
name = "Wild West Vault Doors" // this is to keep the vault area being entirely lit because of requires_power
icon_state = "away2"
requires_power = 0
luminosity = 0
/*
* Wish Granter
@@ -28,7 +58,7 @@
user << "The Wish Granter lies silent."
return
else if(!ishuman(user))
else if(!istype(user, /mob/living/carbon/human))
user << "You feel a dark stirring inside of the Wish Granter, something you want nothing of. Your instincts are better than any man's."
return
@@ -70,7 +100,10 @@
hijack.owner = user.mind
user.mind.objectives += hijack
user << "<B>Your inhibitions are swept away, the bonds of loyalty broken, you are free to murder as you please!</B>"
user.mind.announce_objectives()
var/obj_count = 1
for(var/datum/objective/OBJ in user.mind.objectives)
user << "<B>Objective #[obj_count]</B>: [OBJ.explanation_text]"
obj_count++
user.set_species(/datum/species/shadow)
if("Peace")
user << "<B>Whatever alien sentience that the Wish Granter possesses is satisfied with your wish. There is a distant wailing as the last of the Faithless begin to die, then silence.</B>"
@@ -91,15 +124,15 @@
icon_state = "blobpod"
var/triggered = 0
/obj/effect/meatgrinder/Crossed(AM)
/obj/effect/meatgrinder/Crossed(AM as mob|obj)
Bumped(AM)
/obj/effect/meatgrinder/Bumped(mob/M)
/obj/effect/meatgrinder/Bumped(mob/M as mob|obj)
if(triggered)
return
if(ishuman(M) && M.stat != DEAD && M.ckey)
if(istype(M, /mob/living/carbon/human) && M.stat != DEAD && M.ckey)
for(var/mob/O in viewers(world.view, src.loc))
visible_message("<span class='warning'>[M] triggered the [src]!</span>")
triggered = 1
+1 -1
View File
@@ -9,7 +9,7 @@
/obj/structure/signpost/New()
. = ..()
SetLuminosity(2)
set_light(2)
/obj/structure/signpost/attackby(obj/item/weapon/W, mob/user, params)
return attack_hand(user)
@@ -1,121 +0,0 @@
/obj/structure/speaking_tile
name = "strange tile"
desc = "A weird tile that beckons you towards it. Maybe it can help you get out of this mess..."
verb_say = "intones"
icon = 'icons/obj/structures.dmi'
icon_state = "speaking_tile"
layer = 5
var/speaking = FALSE
var/times_spoken_to = 0
var/list/shenanigans = list()
/obj/structure/speaking_tile/New()
var/savefile/S = new /savefile("data/npc_saves/Poly.sav")
S["phrases"] >> shenanigans
..()
/obj/structure/speaking_tile/interact(mob/user)
if(!isliving(user) || speaking)
return
speaking = TRUE
switch(times_spoken_to)
if(0)
SpeakPeace(list("Welcome to the error handling room.","Something's goofed up bad to send you here.","You should probably tell an admin what you were doing, or make a bug report."))
for(var/obj/structure/signpost/salvation/S in orange(7))
S.invisibility = 0
var/datum/effect_system/smoke_spread/smoke = new
smoke.set_up(1, S.loc)
smoke.start()
break
if(1)
SpeakPeace(list("Take that ladder up.","It'll send you back to the station.","Hopefully you'll never need to see this place again."))
if(2)
SpeakPeace(list("Curious about what happened?","Somehow your corporeal form was sent to nullspace with you still in it.","Lucky for you this room exists to save you from that horrible fate."))
if(3)
SpeakPeace(list("So yeah, you're welcome.","Anyway don't you have things to do?","There's no real point to sticking around here forever."))
if(4)
SpeakPeace(list("I'm flattered you care this much about this room.","However it's not proper to just stand in here all shift and see what I'll say.","I'm going to work hard to be more boring so you'll leave."))
if(5 to 8)
SpeakPeace(list("..."))
if(9)
SpeakPeace(list("Alright maybe that's <b>too</b> boring.", "I can't keep manually typing these lines out though.", "It's hard to explain but the code structure I'm using is kind of terrible."))
if(10)
SpeakPeace(list("Oh I have an idea!", "Lets outsource this endless banter to Poly!", "Then you'll be able to keep listening to this without getting bored!"))
if(isnull(shenanigans))
shenanigans = list("Except the poly file is missing...")
if(11 to 14, 16 to 50, 52 to 99, 103 to 107, 109 to 203, 205 to 249, 252 to 665, 667 to 999, 1001 to 5642)
SpeakPeace(list(pick(shenanigans),pick(shenanigans),pick(shenanigans)))
if(times_spoken_to * 0.1 == round(times_spoken_to * 0.1))
SpeakPeace(list("That's [times_spoken_to] times you've spoken to me by the way."))
if(15)
SpeakPeace(list("See? Isn't this fun?","Now you can mash this for hours without getting bored.","Anyway I'll leave you it."))
if(51)
SpeakPeace(list("The fun never ends around here.", "The Poly text files stores up to 500 statements.", "But you've probably heard a few repeats by now."))
if(100)
SpeakPeace(list("And that's a solid hundred.", "Good hustle I guess.", "You've probably heard a lot of repeats by now."))
if(101)
SpeakPeace(list("I hope you're getting the reference this room is presenting.", "As well as the more obscure meta reference this conversation is presenting.", "This stuff has layers."))
if(102)
SpeakPeace(list("I am very tempted to just stretch this out forever.","It's technically easier than doing this.","Just an option."))
if(108)
SpeakPeace(list("But you have my respect for being this dedicated to the joke.", "So tell you what we're going to do, we're going to set a goal.", "250 is your final mission."))
if(204)
SpeakPeace(list("Notice how there was no special message at 200?", "The slow automation of what used to be meaningful milestones?","It's all part of the joke."))
if(250)
SpeakPeace(list("Congratulations.", "By my very loose calculations you've now wasted a decent chunk of the round doing this.", "But you've seen this meme to its conclusion, and that's a experience in itself, right?"))
if(251)
SpeakPeace(list("Anyway, here.", "I can't give you anything that would impact the progression of the round.","But you've earned this at least."))
var/obj/item/weapon/reagent_containers/food/drinks/trophy/silver_cup/the_ride = new(get_turf(user))
the_ride.name = "Overextending The Joke: Second Place"
the_ride.desc = "There's a point where this needed to stop, and we've clearly passed it."
if(252)
SpeakPeace(list("You know what this means right?", "Of course it's not over!", "The question becomes now is it more impressive to solider on to an unknown finish, or to have to common sense to stop here?"))
if(666)
SpeakPeace(list("The darkness in your heart won't be filled by simple platitudes.","You won't stop now, you're in this to the end.", "Will you reach the finish line before the round ends?"))
if(1000)
SpeakPeace(list("The ends exists somewhere beyond meaningful milestones.", "There will be no more messages until then.", "You disgust me."))
if(5643)
var/obj/item/weapon/reagent_containers/food/drinks/trophy/gold_cup/never_ends = new(get_turf(user))
never_ends.name = "Overextending The Joke: First Place"
never_ends.desc = "And so we are left alone with our regrets."
else
y += 2
speaking = FALSE
times_spoken_to++
/obj/structure/speaking_tile/proc/SpeakPeace(list/statements)
for(var/i in 1 to statements.len)
say("<span class='deadsay'>[statements[i]]</span>")
if(i != statements.len)
sleep(30)
/obj/item/rupee
name = "weird crystal"
desc = "Your excitement boils away as you realize it's just colored glass. Why would someone hoard these things?"
icon = 'icons/obj/economy.dmi'
icon_state = "rupee"
w_class = WEIGHT_CLASS_SMALL
materials = list(MAT_GLASS = 500)
/obj/item/rupee/New()
var/newcolor = color2hex(pick(10;"green", 5;"blue", 3;"red", 1;"purple"))
add_atom_colour(newcolor, FIXED_COLOUR_PRIORITY)
..()
/obj/item/rupee/Crossed(mob/M)
if(!istype(M))
return
if(M.put_in_hands(src))
if(src != M.get_active_held_item())
M.swap_hand()
equip_to_best_slot(M)
..()
/obj/item/rupee/equipped(mob/user, slot)
playsound(get_turf(loc), 'sound/misc/server-ready.ogg', 50, 1, -1)
..()
/obj/effect/landmark/error
name = "error"
-2
View File
@@ -127,8 +127,6 @@ var/global/list/potentialRandomZlevels = generateMapList(filename = "config/away
var/turf/T = i
for(var/mob/living/simple_animal/monster in T)
qdel(monster)
for(var/obj/structure/flora/ash/plant in T)
qdel(plant)
template.load(central_turf,centered = TRUE)
template.loaded++
var/datum/map_template/ruin = template
+6 -7
View File
@@ -8,6 +8,7 @@
var/safety_warning = "For safety reasons the automated supply shuttle \
cannot transport live organisms, classified nuclear weaponry or \
homing beacons."
light_color = LIGHT_COLOR_BROWN
/obj/machinery/computer/cargo/request
name = "supply request console"
@@ -61,7 +62,7 @@
"name" = P.group,
"packs" = list()
)
if((P.hidden && !emagged) || (P.contraband && !contraband) || (P.special && !P.special_enabled))
if((P.hidden && !emagged) || (P.contraband && !contraband))
continue
data["supplies"][P.group]["packs"] += list(list(
"name" = P.name,
@@ -96,7 +97,7 @@
return
switch(action)
if("send")
if(!SSshuttle.supply.canMove())
if(SSshuttle.supply.canMove())
say(safety_warning)
return
if(SSshuttle.supply.getDockedId() == "supply_home")
@@ -113,11 +114,10 @@
if("loan")
if(!SSshuttle.shuttle_loan)
return
else if(SSshuttle.supply.mode != SHUTTLE_IDLE)
if(SSshuttle.supply.canMove())
say(safety_warning)
return
else if(SSshuttle.supply.getDockedId() != "supply_away")
return
else
else if(SSshuttle.supply.mode == SHUTTLE_IDLE)
SSshuttle.shuttle_loan.loan_shuttle()
say("The supply shuttle has been loaned to Centcom.")
. = TRUE
@@ -198,4 +198,3 @@
status_signal.data["command"] = command
frequency.post_signal(src, status_signal)
+1 -1
View File
@@ -4,7 +4,7 @@
icon_state = "export_scanner"
item_state = "radio"
flags = NOBLUDGEON
w_class = WEIGHT_CLASS_SMALL
w_class = 2
siemens_coefficient = 1
var/obj/machinery/computer/cargo/cargo_console = null
@@ -81,11 +81,23 @@
unit_name = "pipe dispenser"
export_types = list(/obj/machinery/pipedispenser)
/datum/export/large/singularitygen
cost = 4000 // If you have one left after engine setup, sell it.
unit_name = "unused gravitational singularity generator"
export_types = list(/obj/machinery/the_singularitygen)
include_subtypes = FALSE
/datum/export/large/singularitygen/tesla
unit_name = "unused energy ball generator"
export_types = list(/obj/machinery/the_singularitygen/tesla)
/datum/export/large/supermatter
cost = 9000
unit_name = "supermatter shard"
export_types = list(/obj/machinery/power/supermatter_shard)
// Misc
/datum/export/large/iv
cost = 300
-6
View File
@@ -73,12 +73,6 @@
material_id = MAT_SILVER
message = "cm3 of silver"
// Titanium.
/datum/export/material/titanium
cost = 250
material_id = MAT_TITANIUM
message = "cm3 of titanium"
// Metal. Common building material.
/datum/export/material/metal
message = "cm3 of metal"
+6 -12
View File
@@ -7,19 +7,13 @@
/datum/export/tech/get_cost(obj/O)
var/obj/item/weapon/disk/tech_disk/D = O
var/cost = 0
for(var/V in D.tech_stored)
if(!V)
continue
var/datum/tech/tech = V
cost += tech.getCost(techLevels[tech.id])
return ..() * cost
if(!D.stored)
return 0
var/datum/tech/tech = D.stored
return ..() * tech.getCost(techLevels[tech.id])
/datum/export/tech/sell_object(obj/O)
..()
var/obj/item/weapon/disk/tech_disk/D = O
for(var/V in D.tech_stored)
if(!V)
continue
var/datum/tech/tech = V
techLevels[tech.id] = tech.level
var/datum/tech/tech = D.stored
techLevels[tech.id] = tech.level
+3 -3
View File
@@ -31,6 +31,6 @@
if(!cost)
return 0
var/potDiff = (S.potency - discoveredPlants[S.type])
return round(..() * potDiff)
var/potDiff = max(S.potency - discoveredPlants[S.type], 0)
return round(..() * potDiff)
+4 -4
View File
@@ -19,7 +19,7 @@
/datum/export/weapon/taser
cost = 250
unit_name = "advanced taser"
export_types = list(/obj/item/weapon/gun/energy/e_gun/advtaser)
export_types = list(/obj/item/weapon/gun/energy/gun/advtaser)
/datum/export/weapon/laser
cost = 250
@@ -34,18 +34,18 @@
/datum/export/weapon/energy_gun
cost = 900
unit_name = "energy gun"
export_types = list(/obj/item/weapon/gun/energy/e_gun)
export_types = list(/obj/item/weapon/gun/energy/gun)
/datum/export/weapon/wt550
cost = 1400
unit_name = "WT-550 automatic rifle"
export_types = list(/obj/item/weapon/gun/ballistic/automatic/wt550)
export_types = list(/obj/item/weapon/gun/projectile/automatic/wt550)
/datum/export/weapon/shotgun
cost = 350
unit_name = "combat shotgun"
export_types = list(/obj/item/weapon/gun/ballistic/shotgun/automatic/combat)
export_types = list(/obj/item/weapon/gun/projectile/shotgun/automatic/combat)
/datum/export/weapon/flashbang

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