Merge branch 'master' into overhaul-event-mob-selection

This commit is contained in:
mochi
2020-08-12 01:22:52 +02:00
253 changed files with 944 additions and 6418 deletions
-11
View File
@@ -36,17 +36,6 @@ world/IsBanned(key, address, computer_id, type, check_ipintel = TRUE)
// message_admins("<span class='notice'>Failed Login: [key] - Guests not allowed</span>")
return list("reason"="guest", "desc"="\nReason: Guests not allowed. Please sign in with a BYOND account.")
//check if the IP address is a known Tor node
if(config.ToRban && ToRban_isbanned(address))
log_adminwarn("Failed Login: [key] [computer_id] [address] - Banned: Tor")
message_admins("<span class='adminnotice'>Failed Login: [key] - Banned: Tor</span>")
//ban their computer_id and ckey for posterity
AddBan(ckey(key), computer_id, "Use of Tor", "Automated Ban", 0, 0)
var/mistakemessage = ""
if(config.banappeals)
mistakemessage = "\nIf you believe this is a mistake, please request help at [config.banappeals]."
return list("reason"="using Tor", "desc"="\nReason: The network you are using to connect has been banned.[mistakemessage]")
//check if the IP address is a known proxy/vpn, and the user is not whitelisted
if(check_ipintel && config.ipintel_email && config.ipintel_whitelist && ipintel_is_banned(key, address))
log_adminwarn("Failed Login: [key] [computer_id] [address] - Proxy/VPN")
+2 -1
View File
@@ -103,7 +103,8 @@ GLOBAL_PROTECT(banlist_savefile) // Obvious reasons
GLOB.banlist_savefile.cd = "/base"
if( GLOB.banlist_savefile.dir.Find("[ckey][computerid]") )
to_chat(usr, "<span class='danger'>Ban already exists.</span>")
if(usr)
to_chat(usr, "<span class='danger'>Ban already exists.</span>")
return 0
else
GLOB.banlist_savefile.dir.Add("[ckey][computerid]")
-89
View File
@@ -1,89 +0,0 @@
//By Carnwennan
//fetches an external list and processes it into a list of ip addresses.
//It then stores the processed list into a savefile for later use
#define TORFILE "data/ToR_ban.bdb"
#define TOR_UPDATE_INTERVAL 216000 //~6 hours
/proc/ToRban_isbanned(var/ip_address)
var/savefile/F = new(TORFILE)
if(F)
if( ip_address in F.dir )
return 1
return 0
/proc/ToRban_autoupdate()
var/savefile/F = new(TORFILE)
if(F)
var/last_update
F["last_update"] >> last_update
if((last_update + TOR_UPDATE_INTERVAL) < world.realtime) //we haven't updated for a while
ToRban_update()
return
/proc/ToRban_update()
spawn(0)
log_world("Downloading updated ToR data...")
var/http[] = world.Export("http://exitlist.torproject.org/exit-addresses")
var/list/rawlist = file2list(http["CONTENT"])
if(rawlist.len)
fdel(TORFILE)
var/savefile/F = new(TORFILE)
for( var/line in rawlist )
if(!line) continue
if( copytext(line,1,12) == "ExitAddress" )
var/cleaned = copytext(line,13,length(line)-19)
if(!cleaned) continue
F[cleaned] << 1
to_chat(F["last_update"], world.realtime)
log_world("ToR data updated!")
if(usr)
to_chat(usr, "ToRban updated.")
return 1
log_world("ToR data update aborted: no data.")
return 0
/client/proc/ToRban(task in list("update","toggle","show","remove","remove all","find"))
set name = "ToRban"
set category = "Server"
if(!holder) return
switch(task)
if("update")
ToRban_update()
if("toggle")
if(config)
if(config.ToRban)
config.ToRban = 0
message_admins("<font color='red'>ToR banning disabled.</font>")
else
config.ToRban = 1
message_admins("<font colot='green'>ToR banning enabled.</font>")
if("show")
var/savefile/F = new(TORFILE)
var/dat
if( length(F.dir) )
for( var/i=1, i<=length(F.dir), i++ )
dat += "<tr><td>#[i]</td><td> [F.dir[i]]</td></tr>"
dat = "<table width='100%'>[dat]</table>"
else
dat = "No addresses in list."
src << browse(dat,"window=ToRban_show")
if("remove")
var/savefile/F = new(TORFILE)
var/choice = input(src,"Please select an IP address to remove from the ToR banlist:","Remove ToR ban",null) as null|anything in F.dir
if(choice)
F.dir.Remove(choice)
to_chat(src, "<b>Address removed</b>")
if("remove all")
to_chat(src, "<b>[TORFILE] was [fdel(TORFILE)?"":"not "]removed.</b>")
if("find")
var/input = input(src,"Please input an IP address to search for:","Find ToR ban",null) as null|text
if(input)
if(ToRban_isbanned(input))
to_chat(src, "<font color='green'><b>Address is a known ToR address</b></font>")
else
to_chat(src, "<font color='red'><b>Address is not a known ToR address</b></font>")
return
#undef TORFILE
#undef TOR_UPDATE_INTERVAL
+1
View File
@@ -78,6 +78,7 @@ GLOBAL_VAR_INIT(nologevent, 0)
body += " \[<A href='?_src_=holder;revive=[M.UID()]'>Heal</A>\] "
body += "<br><br>\[ "
body += "<a href='?_src_=holder;open_logging_view=[M.UID()];'>LOGS</a> - "
body += "<a href='?_src_=vars;Vars=[M.UID()]'>VV</a> - "
body += "[ADMIN_TP(M,"TP")] - "
if(M.client)
+1 -1
View File
@@ -37,6 +37,7 @@ GLOBAL_LIST_INIT(admin_verbs_admin, list(
/client/proc/jumptoturf, /*allows us to jump to a specific turf*/
/client/proc/admin_call_shuttle, /*allows us to call the emergency shuttle*/
/client/proc/admin_cancel_shuttle, /*allows us to cancel the emergency shuttle, sending it back to centcomm*/
/client/proc/admin_deny_shuttle, /*toggles availability of shuttle calling*/
/client/proc/check_ai_laws, /*shows AI and borg laws*/
/client/proc/manage_silicon_laws, /* Allows viewing and editing silicon laws. */
/client/proc/admin_memo, /*admin memo system. show/delete/write. +SERVER needed to delete admin memos of others*/
@@ -125,7 +126,6 @@ GLOBAL_LIST_INIT(admin_verbs_spawn, list(
/client/proc/admin_deserialize
))
GLOBAL_LIST_INIT(admin_verbs_server, list(
/client/proc/ToRban,
/client/proc/Set_Holiday,
/datum/admins/proc/startnow,
/datum/admins/proc/restart,
+14 -10
View File
@@ -2,7 +2,8 @@
if(checkrights && !check_rights(R_ADMIN|R_MOD))
return
if(!GLOB.dbcon.IsConnected())
to_chat(usr, "<span class='danger'>Failed to establish database connection.</span>")
if(usr)
to_chat(usr, "<span class='danger'>Failed to establish database connection.</span>")
return
if(!target_ckey)
@@ -19,7 +20,8 @@
log_game("SQL ERROR obtaining ckey from player table. Error : \[[err]\]\n")
return
if(!query_find_ckey.NextRow())
to_chat(usr, "<span class='redtext'>[target_ckey] has not been seen before, you can only add notes to known players.</span>")
if(usr)
to_chat(usr, "<span class='redtext'>[target_ckey] has not been seen before, you can only add notes to known players.</span>")
return
var/exp_data = query_find_ckey.item[2]
@@ -52,8 +54,8 @@
log_game("SQL ERROR adding new note to table. Error : \[[err]\]\n")
return
if(logged)
log_admin("[key_name(usr)] has added a note to [target_ckey]: [notetext]")
message_admins("[key_name_admin(usr)] has added a note to [target_ckey]:<br>[notetext]")
log_admin("[usr ? key_name(usr) : adminckey] has added a note to [target_ckey]: [notetext]")
message_admins("[usr ? key_name_admin(usr) : adminckey] has added a note to [target_ckey]:<br>[notetext]")
show_note(target_ckey)
/proc/remove_note(note_id)
@@ -63,7 +65,8 @@
var/notetext
var/adminckey
if(!GLOB.dbcon.IsConnected())
to_chat(usr, "<span class='danger'>Failed to establish database connection.</span>")
if(usr)
to_chat(usr, "<span class='danger'>Failed to establish database connection.</span>")
return
if(!note_id)
return
@@ -82,15 +85,16 @@
var/err = query_del_note.ErrorMsg()
log_game("SQL ERROR removing note from table. Error : \[[err]\]\n")
return
log_admin("[key_name(usr)] has removed a note made by [adminckey] from [ckey]: [notetext]")
message_admins("[key_name_admin(usr)] has removed a note made by [adminckey] from [ckey]:<br>[notetext]")
log_admin("[usr ? key_name(usr) : "Bot"] has removed a note made by [adminckey] from [ckey]: [notetext]")
message_admins("[usr ? key_name_admin(usr) : "Bot"] has removed a note made by [adminckey] from [ckey]:<br>[notetext]")
show_note(ckey)
/proc/edit_note(note_id)
if(!check_rights(R_ADMIN|R_MOD))
return
if(!GLOB.dbcon.IsConnected())
to_chat(usr, "<span class='danger'>Failed to establish database connection.</span>")
if(usr)
to_chat(usr, "<span class='danger'>Failed to establish database connection.</span>")
return
if(!note_id)
return
@@ -117,8 +121,8 @@
var/err = query_update_note.ErrorMsg()
log_game("SQL ERROR editing note. Error : \[[err]\]\n")
return
log_admin("[key_name(usr)] has edited [target_ckey]'s note made by [adminckey] from \"[old_note]\" to \"[new_note]\"")
message_admins("[key_name_admin(usr)] has edited [target_ckey]'s note made by [adminckey] from \"[old_note]\" to \"[new_note]\"")
log_admin("[usr ? key_name(usr) : "Bot"] has edited [target_ckey]'s note made by [adminckey] from \"[old_note]\" to \"[new_note]\"")
message_admins("[usr ? key_name_admin(usr) : "Bot"] has edited [target_ckey]'s note made by [adminckey] from \"[old_note]\" to \"[new_note]\"")
show_note(target_ckey)
/proc/show_note(target_ckey, index, linkless = 0)
+17 -6
View File
@@ -911,6 +911,11 @@
//M.client = null
qdel(M.client)
else if(href_list["open_logging_view"])
var/mob/M = locateUID(href_list["open_logging_view"])
if(ismob(M))
usr.client.open_logging_view(list(M), TRUE)
//Player Notes
else if(href_list["addnote"])
var/target_ckey = href_list["addnote"]
@@ -2583,14 +2588,16 @@
if("monkey")
feedback_inc("admin_secrets_fun_used",1)
feedback_add_details("admin_secrets_fun_used","M")
for(var/mob/living/carbon/human/H in GLOB.mob_list)
for(var/thing in GLOB.human_list)
var/mob/living/carbon/human/H = thing
spawn(0)
H.monkeyize()
ok = 1
if("corgi")
feedback_inc("admin_secrets_fun_used",1)
feedback_add_details("admin_secrets_fun_used","M")
for(var/mob/living/carbon/human/H in GLOB.mob_list)
for(var/thing in GLOB.human_list)
var/mob/living/carbon/human/H = thing
spawn(0)
H.corgize()
ok = 1
@@ -2661,7 +2668,8 @@
feedback_inc("admin_secrets_fun_used",1)
feedback_add_details("admin_secrets_fun_used","PW")
message_admins("<span class='notice'>[key_name_admin(usr)] teleported all players to the prison station.</span>", 1)
for(var/mob/living/carbon/human/H in GLOB.mob_list)
for(var/thing in GLOB.human_list)
var/mob/living/carbon/human/H = thing
var/turf/loc = find_loc(H)
var/security = 0
if(!is_station_level(loc.z) || GLOB.prisonwarped.Find(H))
@@ -2994,7 +3002,8 @@
if("manifest")
var/dat = "<B>Showing Crew Manifest.</B><HR>"
dat += "<table cellspacing=5><tr><th>Name</th><th>Position</th></tr>"
for(var/mob/living/carbon/human/H in GLOB.mob_list)
for(var/thing in GLOB.human_list)
var/mob/living/carbon/human/H = thing
if(H.ckey)
dat += text("<tr><td>[]</td><td>[]</td></tr>", H.name, H.get_assignment())
dat += "</table>"
@@ -3004,7 +3013,8 @@
if("DNA")
var/dat = "<B>Showing DNA from blood.</B><HR>"
dat += "<table cellspacing=5><tr><th>Name</th><th>DNA</th><th>Blood Type</th></tr>"
for(var/mob/living/carbon/human/H in GLOB.mob_list)
for(var/thing in GLOB.human_list)
var/mob/living/carbon/human/H = thing
if(H.dna && H.ckey)
dat += "<tr><td>[H]</td><td>[H.dna.unique_enzymes]</td><td>[H.dna.blood_type]</td></tr>"
dat += "</table>"
@@ -3012,7 +3022,8 @@
if("fingerprints")
var/dat = "<B>Showing Fingerprints.</B><HR>"
dat += "<table cellspacing=5><tr><th>Name</th><th>Fingerprints</th></tr>"
for(var/mob/living/carbon/human/H in GLOB.mob_list)
for(var/thing in GLOB.human_list)
var/mob/living/carbon/human/H = thing
if(H.ckey)
if(H.dna && H.dna.uni_identity)
dat += "<tr><td>[H]</td><td>[md5(H.dna.uni_identity)]</td></tr>"
+1 -1
View File
@@ -643,7 +643,7 @@ GLOBAL_PROTECT(AdminProcCallSpamPrevention)
for(var/areatype in areas_without_camera)
to_chat(world, "* [areatype]")
/client/proc/cmd_admin_dress(var/mob/living/carbon/human/M in GLOB.mob_list)
/client/proc/cmd_admin_dress(mob/living/carbon/human/M in GLOB.human_list)
set category = "Event"
set name = "Select equipment"
+15 -5
View File
@@ -2,10 +2,20 @@ GLOBAL_LIST_INIT(open_logging_views, list())
/client/proc/cmd_admin_open_logging_view()
set category = "Admin"
set name = "Open Logging View"
set name = "Logging View"
set desc = "Opens the detailed logging viewer"
open_logging_view()
if(!GLOB.open_logging_views[usr.client.ckey])
GLOB.open_logging_views[usr.client.ckey] = new /datum/log_viewer()
var/datum/log_viewer/LV = GLOB.open_logging_views[usr.client.ckey]
LV.show_ui(usr)
/client/proc/open_logging_view(list/mob/mobs_to_add = null, clear_view = FALSE)
var/datum/log_viewer/cur_view = GLOB.open_logging_views[usr.client.ckey]
if(!cur_view)
cur_view = new /datum/log_viewer()
GLOB.open_logging_views[usr.client.ckey] = cur_view
else if(clear_view)
cur_view.clear_all()
if(mobs_to_add?.len)
cur_view.add_mobs(mobs_to_add)
cur_view.show_ui(usr)
+1 -1
View File
@@ -84,7 +84,7 @@
var/obj/item/slot_item_hand = H.get_item_by_slot(slot_r_hand)
H.unEquip(slot_item_hand)
var /obj/item/multisword/pure_evil/multi = new(H)
var/obj/item/multisword/pure_evil/multi = new(H)
H.equip_to_slot_or_del(multi, slot_r_hand)
var/obj/item/card/id/W = new(H)
+9 -3
View File
@@ -826,7 +826,10 @@ Traitors and the like can also be revived with the previous role mostly intact.
else
SSshuttle.emergency.canRecall = FALSE
SSshuttle.emergency.request()
if(seclevel2num(get_security_level()) >= SEC_LEVEL_RED)
SSshuttle.emergency.request(coefficient = 0.5, redAlert = TRUE)
else
SSshuttle.emergency.request()
feedback_add_details("admin_verb","CSHUT") //If you are copy-pasting this, ensure the 2nd parameter is unique to the new proc!
log_admin("[key_name(usr)] admin-called the emergency shuttle.")
@@ -874,6 +877,7 @@ Traitors and the like can also be revived with the previous role mostly intact.
if(SSshuttle)
SSshuttle.emergencyNoEscape = !SSshuttle.emergencyNoEscape
feedback_add_details("admin_verb", "DENYSHUT")
log_admin("[key_name(src)] has [SSshuttle.emergencyNoEscape ? "denied" : "allowed"] the shuttle to be called.")
message_admins("[key_name_admin(usr)] has [SSshuttle.emergencyNoEscape ? "denied" : "allowed"] the shuttle to be called.")
@@ -979,7 +983,8 @@ Traitors and the like can also be revived with the previous role mostly intact.
var/role_string
var/obj_count = 0
var/obj_string = ""
for(var/mob/living/carbon/human/H in GLOB.alive_mob_list)
for(var/thing in GLOB.human_list)
var/mob/living/carbon/human/H = thing
if(!isLivingSSD(H))
continue
mins_ssd = round((world.time - H.last_logout) / 600)
@@ -1016,7 +1021,8 @@ Traitors and the like can also be revived with the previous role mostly intact.
msg += "AFK Players:<BR><TABLE border='1'>"
msg += "<TR><TD><B>Key</B></TD><TD><B>Real Name</B></TD><TD><B>Job</B></TD><TD><B>Mins AFK</B></TD><TD><B>Special Role</B></TD><TD><B>Area</B></TD><TD><B>PPN</B></TD><TD><B>Cryo</B></TD></TR>"
var/mins_afk
for(var/mob/living/carbon/human/H in GLOB.alive_mob_list)
for(var/thing in GLOB.human_list)
var/mob/living/carbon/human/H = thing
if(H.client == null || H.stat == DEAD) // No clientless or dead
continue
mins_afk = round(H.client.inactivity / 600)
@@ -195,7 +195,7 @@
to_chat(user, "<span class='notice'>The demons do not respond to your summon. Perhaps you should try again later.</span>")
/obj/item/antag_spawner/slaughter_demon/spawn_antag(client/C, turf/T, type = "", mob/user)
var /obj/effect/dummy/slaughter/holder = new /obj/effect/dummy/slaughter(T)
var/obj/effect/dummy/slaughter/holder = new /obj/effect/dummy/slaughter(T)
var/mob/living/simple_animal/slaughter/S = new demon_type(holder)
S.vialspawned = TRUE
S.holder = holder
@@ -41,9 +41,8 @@
A.common_radio.channels.Remove("Syndicate") // De-traitored AIs can still state laws over the syndicate channel without this
A.laws.sorted_laws = A.laws.inherent_laws.Copy() // AI's 'notify laws' button will still state a law 0 because sorted_laws contains it
A.show_laws()
A.malf_picker.remove_malf_verbs(A)
A.verbs -= /mob/living/silicon/ai/proc/choose_modules
qdel(A.malf_picker)
A.remove_malf_abilities()
QDEL_NULL(A.malf_picker)
if(owner.som)
var/datum/mindslaves/slaved = owner.som
@@ -251,9 +250,14 @@
/datum/antagonist/traitor/proc/update_traitor_icons_added(datum/mind/traitor_mind)
var/datum/atom_hud/antag/traitorhud = GLOB.huds[ANTAG_HUD_TRAITOR]
traitorhud.join_hud(owner.current, null)
set_antag_hud(owner.current, "hudsyndicate")
if(locate(/datum/objective/hijack) in owner.objectives)
var/datum/atom_hud/antag/hijackhud = GLOB.huds[ANTAG_HUD_TRAITOR]
hijackhud.join_hud(owner.current, null)
set_antag_hud(owner.current, "hudhijack")
else
var/datum/atom_hud/antag/traitorhud = GLOB.huds[ANTAG_HUD_TRAITOR]
traitorhud.join_hud(owner.current, null)
set_antag_hud(owner.current, "hudsyndicate")
/datum/antagonist/traitor/proc/update_traitor_icons_removed(datum/mind/traitor_mind)
@@ -400,7 +404,7 @@
var/phrases = jointext(GLOB.syndicate_code_phrase, ", ")
var/responses = jointext(GLOB.syndicate_code_response, ", ")
var message = "<br><b>The code phrases were:</b> <span class='bluetext'>[phrases]</span><br>\
var/message = "<br><b>The code phrases were:</b> <span class='bluetext'>[phrases]</span><br>\
<b>The code responses were:</b> <span class='redtext'>[responses]</span><br>"
return message
@@ -30,6 +30,11 @@ GLOBAL_DATUM_INIT(_preloader, /datum/dmm_suite/preloader, new())
var/fname = "Lambda"
if(isfile(tfile))
fname = "[tfile]"
// Make sure we dont load a dir up
var/lastchar = copytext(fname, -1)
if(lastchar == "/" || lastchar == "\\")
log_debug("Attempted to load map template without filename (Attempted [tfile])")
return
tfile = file2text(tfile)
if(!length(tfile))
throw EXCEPTION("Map path '[fname]' does not exist!")
-128
View File
@@ -1,128 +0,0 @@
//Cactus, Speedbird, Dynasty, oh my
GLOBAL_DATUM_INIT(atc, /datum/lore/atc_controller, new)
/datum/lore/atc_controller
var/delay_max = 10 MINUTES //Maximum amount of tiem between ATC messages. Default is 10 mins.
var/delay_min = 5 MINUTES //Minimum amount of time between ATC messages. Default is 5 mins.
var/backoff_delay = 5 MINUTES //How long to back off if we can't talk and want to. Default is 5 mins.
var/next_message //When the next message should happen in world.time
var/force_chatter_type //Force a specific type of messages
var/squelched = FALSE //If ATC is squelched currently
/datum/lore/atc_controller/New()
spawn(30 SECONDS) //Lots of lag at the start of a shift.
msg("New shift beginning, resuming traffic control.")
next_message = world.time + rand(delay_min, delay_max)
process()
/datum/lore/atc_controller/process()
if(world.time >= next_message)
if(squelched)
next_message = world.time + backoff_delay
else
next_message = world.time + rand(delay_min,delay_max)
random_convo()
spawn(1 MINUTES) //We don't really need high-accuracy here.
process()
/datum/lore/atc_controller/proc/msg(var/message,var/sender)
ASSERT(message)
GLOB.global_announcer.autosay("[message]", sender ? sender : "[GLOB.using_map.station_short] Space Control")
/datum/lore/atc_controller/proc/reroute_traffic(var/yes = 1)
if(yes)
if(!squelched)
msg("Rerouting traffic away from [GLOB.using_map.station_name].")
squelched = TRUE
else
if(squelched)
msg("Resuming normal traffic routing around [GLOB.using_map.station_name].")
squelched = FALSE
/datum/lore/atc_controller/proc/shift_ending(var/evac = 0)
msg("Automated Shuttle departing [GLOB.using_map.station_name] for [GLOB.using_map.dock_name] on routine transfer route.", "NT Automated Shuttle")
sleep(5 SECONDS)
msg("Automated Shuttle, cleared to complete routine transfer from [GLOB.using_map.station_name] to [GLOB.using_map.dock_name].")
/datum/lore/atc_controller/proc/random_convo()
var/one = pick(GLOB.loremaster.organizations) //These will pick an index, not an instance
var/two = pick(GLOB.loremaster.organizations)
var/datum/lore/organization/source = GLOB.loremaster.organizations[one] //Resolve to the instances
var/datum/lore/organization/dest = GLOB.loremaster.organizations[two]
//Let's get some mission parameters
var/owner = source.short_name //Use the short name
var/prefix = pick(source.ship_prefixes) //Pick a random prefix
var/mission = source.ship_prefixes[prefix] //The value of the prefix is the mission type that prefix does
var/shipname = pick(source.ship_names) //Pick a random ship name to go with it
var/destname = pick(dest.destination_names) //Pick a random holding from the destination
var/combined_name = "[owner] [prefix] [shipname]"
var/alt_atc_names = list("[GLOB.using_map.station_short] TraCon", "[GLOB.using_map.station_short] Control", "[GLOB.using_map.station_short] STC", "[GLOB.using_map.station_short] Airspace")
var/wrong_atc_names = list("Sol Command", "Orion Control", "[GLOB.using_map.dock_name]")
var/mission_noun = list("flight", "mission", "route")
var/request_verb = list("requesting", "calling for", "asking for")
//First response is 'yes', second is 'no'
var/requests = list("[GLOB.using_map.station_short] transit clearance" = list("cleared to transit", "unable to approve, contact regional on 953.5"),
"planetary flight rules" = list("cleared planetary flight rules", "unable to approve planetary flight rules due to traffic"),
"special flight rules" = list("cleared special flight rules", "unable to approve special flight rules for your traffic class"),
"current solar weather info" = list("sending you the relevant information via tightbeam", "cannot fulfill your request at the moment"),
"nearby traffic info" = list("sending you current traffic info", "no known traffic for your flight plan route"),
"remote telemetry data" = list("sending telemetry now", "no uplink from your ship, recheck your uplink and ask again"),
"refueling information" = list("sending refueling information now", "no fuel for your ship class in this sector"),
"a current system time sync" = list("sending time sync ping to you now", "your ship isn't compatible with our time sync, set time manually"),
"current system starcharts" = list("transmitting current starcharts", "request on standby due to demand"),
"permission to engage FTL" = list("cleared to FTL, good day", "hold position, traffic crossing"),
"permission to transit system" = list("cleared to transit, good day", "hold position, traffic crossing"),
"permission to depart system" = list("cleared to leave via flight plan route, good day", "hold position, traffic crossing"),
"permission to enter system" = list("good day, cleared in as published", "hold position, traffic crossing"),
)
//Random chance things for variety
var/chatter_type = "normal"
if(force_chatter_type)
chatter_type = force_chatter_type
else
chatter_type = pick(2;"emerg",5;"wrong_freq","normal") //Be nice to have wrong_lang...
var/yes = prob(90) //Chance for them to say yes vs no
var/request = pick(requests)
var/callname = pick(alt_atc_names)
var/response = requests[request][yes ? 1 : 2] //1 is yes, 2 is no
var/full_request
var/full_response
var/full_closure
switch(chatter_type)
if("wrong_freq")
callname = pick(wrong_atc_names)
full_request = "[callname], this is [combined_name] on a [mission] [pick(mission_noun)] to [destname], [pick(request_verb)] [request]."
full_response = "[combined_name], this is [GLOB.using_map.station_short] TraCon, wrong frequency. Switch to [rand(700,999)].[rand(1,9)]."
full_closure = "[GLOB.using_map.station_short] TraCon, copy, apologies."
if("wrong_lang")
//Can't implement this until autosay has language support
if("emerg")
var/problem = pick("hull breaches on multiple decks","unknown life forms on board","a drive about to go critical","asteroids impacting the hull","a total loss of engine power","people trying to board the ship")
full_request = "Mayday, mayday, mayday, this is [combined_name] declaring an emergency! We have [problem]!"
var/rand_freq = "[rand(700,999)].[rand(1,9)]"
full_response = "[combined_name], this is [GLOB.using_map.station_short] TraCon, copy. Switch to emergency responder channel [rand_freq]."
full_closure = "Roger, [GLOB.using_map.station_short] TraCon, contacting [rand_freq]."
else
full_request = "[callname], this is [combined_name] on a [mission] [pick(mission_noun)] to [destname], [pick(request_verb)] [request]."
full_response = "[combined_name], this is [GLOB.using_map.station_short] TraCon, [response]." //Station TraCon always calls themselves TraCon
full_closure = "[GLOB.using_map.station_short] TraCon, [yes ? "thank you" : "copy"], good day." //They always copy what TraCon called themselves in the end when they realize they said it wrong
//Ship sends request to ATC
msg(full_request,"[prefix] [shipname]")
sleep(5 SECONDS)
//ATC sends response to ship
msg(full_response)
sleep(5 SECONDS)
//Ship sends response to ATC
msg(full_closure,"[prefix] [shipname]")
-15
View File
@@ -1,15 +0,0 @@
//I AM THE LOREMASTER, ARE YOU THE GATEKEEPER?
GLOBAL_DATUM_INIT(loremaster, /datum/lore/loremaster, new)
/datum/lore/loremaster
var/list/organizations = list()
/datum/lore/loremaster/New()
var/list/paths = typesof(/datum/lore/organization) - /datum/lore/organization
for(var/path in paths)
// Some intermediate paths are not real organizations (ex. /datum/lore/organization/mil). Only do ones with names
var/datum/lore/organization/instance = path
if(initial(instance.name))
instance = new path()
organizations[path] = instance
-549
View File
@@ -1,549 +0,0 @@
//Datums for different companies that can be used by busy_space
/datum/lore/organization
var/name = "" // Organization's name
var/short_name = "" // Organization's shortname (Nanotrasen for "Nanotrasen Incorporated")
var/acronym = "" // Organization's acronym, e.g. 'NT' for Nanotrasen'.
var/desc = "" // One or two paragraph description of the organization, but only current stuff. Currently unused.
var/history = "" // Historical description of the organization's origins Currently unused.
var/work = "" // Short description of their work, eg "an arms manufacturer"
var/headquarters = "" // Location of the organization's HQ. Currently unused.
var/motto = "" // A motto/jingle/whatever, if they have one. Currently unused.
var/list/ship_prefixes = list() //Some might have more than one! Like Nanotrasen. Value is the mission they perform, e.g. ("ABC" = "mission desc")
var/list/ship_names = list( //Names of spaceships. This is a mostly generic list that all the other organizations inherit from if they don't have anything better.
"Kestrel",
"Beacon",
"Signal",
"Freedom",
"Glory",
"Axiom",
"Eternal",
"Icarus",
"Harmony",
"Light",
"Discovery",
"Endeavour",
"Explorer",
"Swift",
"Dragonfly",
"Ascendant",
"Tenacious",
"Pioneer",
"Hawk",
"Haste",
"Radiant",
"Luminous",
"Gallant",
"Dependable",
"Indomitable",
"Guardian",
"Resolution",
"Fearless",
"Amazon",
"Relentless",
"Inspire",
"Implacable",
"Steadfast",
"Leviathan",
"Dauntless",
"Adroit",
"Mistral",
"Typhoon",
"Titan",
"Kupua",
"Alchemist",
"Cuirass",
"Citadel",
"Rondelle",
"Camail",
"Ocrea",
"Ram",
"Crest",
"Tanko",
"Pommel",
"Kissaki",
"Cavalier",
"Anelace",
"Flint",
"Xiphos",
"Parrot",
"Chamber",
"Annellet",
"Cestus",
"Talwar")
var/list/destination_names = list() //Names of static holdings that the organization's ships visit regularly.
var/autogenerate_destination_names = TRUE
/datum/lore/organization/New()
..()
if(autogenerate_destination_names) // Lets pad out the destination names.
var/i = rand(6, 10)
var/list/star_names = list(
"Sol", "Alpha Centauri", "Sirius", "Vega", "Regulus", "Vir", "Algol", "Aldebaran",
"Delta Doradus", "Menkar", "Geminga", "Elnath", "Gienah", "Mu Leporis", "Nyx", "Tau Ceti",
"Wazn", "Alphard", "Phact", "Altair", "Mauna", "Jargon", "Xarxis", "Hestia", "Dalstis", "Cygni", "Haverick", "Corvus", "Sancere", "Cydoni", "Kaliban", "Midway", "Dansik", "Branwyn")
var/list/destination_types = list("dockyard", "station", "vessel", "waystation", "telecommunications satellite", "spaceport", "distress beacon", "anomaly", "colony", "outpost")
while(i)
destination_names.Add("a [pick(destination_types)] in [pick(star_names)]")
i--
//////////////////////////////////////////////////////////////////////////////////
// TSCs
/datum/lore/organization/tsc/nanotrasen
name = "Nanotrasen Incorporated"
short_name = "Nanotrasen"
acronym = "NT"
desc = "The largest shareholder in the galactic plasma markets, Nanotrasen is a research and mining corporation which specializes in\
FTL technologies and weapon systems. Frowned upon by most governments due to their shady business tactics and poor ethics record,\
Nanotrasen is often seen as a necessary evil for maintaining access to the often volatile plasma market. Nanotrasen was originally\
incorporated on Earth with their headquarters situated on Mars, however they have recently moved most of their operations to the Epsilon Eridani sector."
history = "" // To be written someday.
work = "research giant"
headquarters = "Mars"
motto = ""
ship_prefixes = list("NSV" = "exploration", "NTV" = "hauling", "NDV" = "patrol", "NRV" = "emergency response")
// Note that the current station being used will be pruned from this list upon being instantiated
destination_names = list(
"NAS Trurl in Epsilon Eridani",
"NAS Crescent in Tau Ceti",
"NSS Exodus in Tau Ceti",
"NSS Antiqua in Darsing",
"NRS Orion in Sol",
"NSS Vector in Omicron Ceti",
"NBS Anansi in Omicron Ceti",
"NSS Redemption in Sirius",
"NDS Inferno in Tau Ceti",
"NAB Smythside Central Headquarters on Earth",
"NAB North Cimmeria Central Offices on Mars",
)
/datum/lore/organization/tsc/nanotrasen/New()
..()
spawn(1) // BYOND shenanigans means using_map is not initialized yet. Wait a tick.
// Get rid of the current map from the list, so ships flying in don't say they're coming to the current map.
var/string_to_test = "[GLOB.using_map.station_name] in [GLOB.using_map.starsys_name]"
if(string_to_test in destination_names)
destination_names.Remove(string_to_test)
/datum/lore/organization/tsc/donk
name = "Donk Corporation"
short_name = "Donk Co."
acronym = "DC"
desc = "The infamous rival of the well-known Waffle Corporation, Donk Co. is a company specializing in food delivery systems and brand-name food\
products such as Donk Pockets. While generally seen as a neutral actor, Donk Corporation has been known to work both with Nanotrasen and\
the Syndicate when it suits them - often acting as the primary logistical supplier for the Epsilon Eridani sector.\
Donk Corporation is better known for recent high-profile litigation alleging that their food products are used for illicit drug distribution.\
While the trial is ongoing, it has been repeatedly delayed due to incidents of methamphetamine poisoning."
history = ""
work = "food company that establishes and maintains delivery supply chains"
headquarters = ""
motto = "Now with 20% more donk!"
ship_prefixes = list("D-Co." = "transportation")
destination_names = list()
/datum/lore/organization/tsc/hephaestus
name = "Hephaestus Industries"
short_name = "Hephaestus"
acronym = "HI"
desc = ""
history = ""
work = "arms manufacturer"
headquarters = ""
motto = ""
ship_prefixes = list("HTV" = "freight", "HTV" = "munitions resupply")
destination_names = list(
"a SolGov dockyard on Luna"
)
/datum/lore/organization/tsc/waffle
name = "Waffle Corporation"
short_name = "Waffle Co."
acronym = "WC"
desc = "The once prominent competitor of Donk Corporation, Waffle Co. is well-known for its popular line of Waffle Co.\
brand waffles and their use of violent tactics against competitors - often bribing, extorting, blackmailing or sabotaging businesses\
that pose a direct or indirect threat to their market share. They have recently fallen on hard times primarily due to to\
severe mismanagement which lead to much of their private arsenal being swindled by a pirate faction known as the Gorlex Marauders.\
Waffle Co. commonly engages in smear campaigns against Donk Co., maintaining that the original recipe for Donk Pockets was stolen from them."
history = ""
work = "food logistics and marketing firm"
headquarters = ""
motto = "Now that's a Waffle Co. Waffle!"
ship_prefixes = list("W-Co." = "transportation")
destination_names = list()
/datum/lore/organization/tsc/einstein
name = "Einstein Engines Incorporated"
short_name = "Einstein Inc."
acronym = "EEI"
desc = "An Engineering firm specializing in alternative fuel-technologies for FTL travel,\
Einstein Engines is an up and coming player in the galactic FTL and energy markets.\
As their research into alternative FTL fuel threatens both Nanotrasen's relative stranglehold on plasma as well as The Syndicate's vested\
interest in the market, they are often the target of industrial sabotage by both Nanotrasen and The Syndicate.\
Most of their contracts are based outside of the Epsilon Eridani sector, and they are frequently commissioned by smaller firms to retrofit new\
and existing colonies, space stations, and outposts."
history = ""
work = "engineering firm specializing in engine technology"
headquarters = "Jargon 4"
motto = ""
ship_prefixes = list("EE-T" = "transportation")
destination_names = list()
/datum/lore/organization/tsc/zeng_hu
name = "Zeng-Hu pharmaceuticals"
short_name = "Zeng-Hu"
acronym = "ZH"
desc = ""
history = ""
work = "pharmaceuticals company"
headquarters = ""
motto = ""
ship_prefixes = list("ZTV" = "transportation", "ZMV" = "medical resupply")
destination_names = list()
/datum/lore/organization/tsc/biotech
name = "Biotech Solutions"
short_name = "Biotech"
acronym = "BTS"
desc = "A company specializing in the field of synthetic biology, BioTech solutions is at the forefront of providing cutting-edge prosthetics,\
augmentations, and gene-therapy solutions. Their extensive list of patents and the highly secretive nature of their work often puts them at odds\
with companies such as Nanotrasen, who commonly reverse-engineer their products. BioTech Solutions is often the victim of industrial sabotage by\
Cybersun Industries and often relies on planetary governments for asset protection. BioTech Solutions also owns a number of prominent subsidiaries,\
such as Bishop Cybernetics, Hesphiastos Industries, and Xion Manufacturing Group."
history = ""
work = "medical company specializing in prosthetics and pharmaceuticals"
headquarters = "Xarxis 5"
motto = ""
ship_prefixes = list("CIND-T" = "transportation")
destination_names = list()
/datum/lore/organization/tsc/ward_takahashi
name = "Ward-Takahashi General Manufacturing Conglomerate"
short_name = "Ward-Takahashi"
acronym = "WT"
desc = ""
history = ""
work = "electronics manufacturer"
headquarters = ""
motto = ""
ship_prefixes = list("WTV" = "freight")
destination_names = list(
""
)
/datum/lore/organization/tsc/cybersun
name = "Cybersun Industries"
short_name = "Cybersun Ind."
acronym = "CI"
desc = "Cybersun Industries is a biotechnology company that primarily specializes on the research and development of human-enhancing augmentations.\
They are better known for their aggressive corporate tactics and are known to often subsidize pirate bands to commit acts of industrial sabotage.\
Cybersun Industries is usually the target of conspiracy theorists due to their development of the first mindslave implant, as well as their open financing of,\
and involvement in, The Syndicate. They are one of Nanotrasen's largest detractors, and a direct competitor to BioTech Solutions."
history = ""
work = "RND company specializing in augmentations and implants."
headquarters = "Luna"
motto = ""
ship_prefixes = list("CIND-T" = "transportation")
destination_names = list()
/datum/lore/organization/tsc/bishop
name = "Bishop Cybernetics"
short_name = "Bishop"
acronym = "BC"
desc = ""
history = ""
work = "cybernetics and augmentation manufacturer"
headquarters = ""
motto = ""
ship_prefixes = list("BTV" = "transportation")
destination_names = list()
/datum/lore/organization/tsc/morpheus
name = "Morpheus Cyberkinetics"
short_name = "Morpheus"
acronym = "MC"
desc = "The only large corporation run by positronic intelligences, Morpheus caters almost exclusively to their sensibilities \
and needs. A product of the synthetic colony of Shelf, Morpheus eschews traditional advertising to keep their prices low and \
relied on word of mouth among positronics to reach their current economic dominance. Morpheus in exchange lobbies heavily for \
positronic rights, sponsors positronics through their Jans-Fhriede test, and tends to other positronic concerns to earn them \
the good-will of the positronics, and the ire of those who wish to exploit them."
history = ""
work = "cybernetics manufacturer"
headquarters = ""
motto = ""
ship_prefixes = list("MTV" = "freight")
// Culture names, because Anewbe told me so.
ship_names = list(
"Nervous Energy",
"Prosthetic Conscience",
"Revisionist",
"Trade Surplus",
"Flexible Demeanour",
"Just Read The Instructions",
"Limiting Factor",
"Cargo Cult",
"Gunboat Diplomat",
"A Ship With A View",
"Cantankerous",
"Never Talk To Strangers",
"Sacrificial Victim",
"Unwitting Accomplice",
"Bad For Business",
"Just Testing",
"Yawning Angel",
"Liveware Problem",
"Very Little Gravitas Indeed",
"Zero Gravitas",
"Gravitas Free Zone",
"Absolutely No You-Know-What",
"Existence Is Pain",
"Screw Loose",
"Limiting Factor",
"So Much For Subtley",
"Unfortunate Conflict Of Evidence",
"Prime Mover",
"Reasonable Excuse",
"Honest Mistake",
"Appeal To Reason",
"My First Ship II",
"Hidden Income",
"Anything Legal Considered",
"New Toy",
"Me, I'm Always Counting",
"Great White Snark",
"No Shirt No Shoes",
"Callsign"
)
destination_names = list(
"a dockyard on New Canaan"
)
/datum/lore/organization/tsc/xion
name = "Xion Manufacturing Group"
short_name = "Xion"
desc = ""
history = ""
work = "industrial equipment manufacturer"
headquarters = ""
motto = ""
ship_prefixes = list("XTV" = "hauling")
destination_names = list()
/datum/lore/organization/tsc/shellguard
name = "Shellguard Munitions"
short_name = "Shellguard"
acronym = "SM"
desc = "The brainchild of a colonial war veteran, Shellguard Munitions is an arms manufacturer and private military contractor specializing\
in anti-synthetic weapon systems and platforms. Initially a smaller private military force only serving frontier colonies,\
Shellguard Munitions has become a household name due to its involvement in resolving the Haverick AI crisis in 2552.\
Using its recently earned fame, the company has made a successful foray into the market of robotics and is highly regarded for the toughness \
and reliability of their hardware. Despite being frequently contracted by the Trans-Solar Federation, Shellguard Munitions is known to\
sell their services to the highest corporate bidder."
history = ""
work = "anti-synthetic arms manufacturer and PMC"
headquarters = "Colony of Haverick"
motto = ""
ship_prefixes = list("BTS-T" = "transportation")
destination_names = list()
// Governments
/datum/lore/organization/gov/solgov
name = "Trans-Solar Federation"
short_name = "SolGov"
acronym = "TSF"
desc = "Colloquially known as SolGov, the TSF is an authoritarian republic that manages the areas in and around the Sol system.\
Despite being a highly militant organization headed by the government of Earth,\
SolGov is usually conservative with its power and mostly serves as a mediator and peacekeeper in galactic affairs."
history = "" // Todo
work = "governing polity of humanity's Confederation"
headquarters = "Earth"
motto = ""
autogenerate_destination_names = TRUE
ship_prefixes = list("FTV" = "transporation", "FDV" = "diplomatic", "FSF" = "freight", "FIV" = "interception", "FDV" = "defense", "FCV-A" = "carrier", "FBB" = "battleship")
destination_names = list(
"Venus",
"Earth",
"Luna",
"Mars",
"Titan",
"Ahdomai",
"Kelune",
"Dalstadt",
"New Canaan",
"Jargon 4",
"Hoorlm",
"Xarxis 5",
"Aurum",
"Moghes",
"Haverick",
"Darsing",
"Norfolk",
"Boron",
"Iluk")
/datum/lore/organization/gov/tajara
name = "The Alchemist's Council"
short_name = "The Council"
acronym = "AC"
desc = "The Alchemist's Council is a science-oriented organization of scholars, researchers, and entrepreneurs. \
Though dedicated to industrializing the Tajaran world of Ahdomai, it is seen as one of the few remaining centralized powers of the Tajara peoples \
due to the collapse of Ahdomai's provisional government."
history = "" // Todo
work = "science body that oversees Tajara economic and research policy"
headquarters = "Ahdomai"
motto = ""
autogenerate_destination_names = TRUE
ship_prefixes = list("ACS" = "transportation", "ADV" = "diplomatic", "ACF" = "freight")
destination_names = list(
"Ahdomai",
"Iluk")
/datum/lore/organization/gov/vulp
name = "The Assembly"
short_name = "Assembly"
acronym = "ASB"
desc = "A unifying body created to stave off extinction from a solar event,\
The Assembly is the loose federal coalition of the Vulpkanin. It holds little centralized authority and mostly serves as a diplomatic body,\
primarily concerned with facilitating trade between Vulpkanin colonies and Nanotrasen."
history = "" // Todo
work = "governing body of the Vulpakanin"
headquarters = "Kelune and Dalstadt"
motto = ""
autogenerate_destination_names = TRUE
ship_prefixes = list("ATV" = "transportation", "ADV" = "diplomatic", "ACF" = "freight")
destination_names = list(
"Kelune",
"Dalstadt",
"New Canaan")
/datum/lore/organization/gov/synth
name = "Synthetic Union"
short_name = "Synthetica"
acronym = "SYN"
desc = "A defensive coalition of synthetics based out of New Canaan,\
the Synthetic Union is an organization which aims to establish and consolidate synthetic rights across the galaxy.\
Despite its synth oriented focus, the Synthetic Union has cordial relations with most governing bodies."
history = "" // Todo
work = "Union of Machines"
headquarters = "New Canaan"
motto = ""
autogenerate_destination_names = TRUE
ship_prefixes = list("01" = "transportation", "10" = "diplomatic", "112" = "freight")//copyed from solgov until new ones can be thought of
destination_names = list(
"Luna",
"Dalstadt",
"New Canaan",
"Jargon 4",
"Haverick",
"Darsing",
"Norfolk")
/datum/lore/organization/gov/grey
name = "The Technocracy"
short_name = "Technocracy"
acronym = "AYY"
desc = "The Technocracy is a science council that operates based off the principles of a meritocracy.\
The organization's leadership is highly competitive, and is headed by the most psionically gifted members of the Grey species.\
The Technocracy, though enigmatic in its dealings, has cordial relations with almost all other galactic bodies."
history = "" // Todo
work = "Grey Council"
headquarters = ""
motto = ""
autogenerate_destination_names = TRUE
ship_prefixes = list("TC-T" = "transportation", "TC-D" = "diplomatic", "TC-F" = "freight")
destination_names = list(
"Venus",
"Earth",
"Luna",
"Mars",
"Titan",
"Ahdomai",
"Kelune",
"Dalstadt",
"New Canaan",
"Jargon 4",
"Hoorlm",
"Xarxis 5",
"Aurum",
"Moghes",
"Haverick",
"Darsing",
"Norfolk",
"Boron",
"Iluk")
/datum/lore/organization/gov/vox
name = "The Shoal"
short_name = "Shoal"
acronym = "SHA"
desc = "The Shoal is the primary ark ship of the reclusive Vox species.\
Little is known about The Shoal's political structure as Vox typically shy away from diplomatic engagements.\
Subsequently, it is considered a politically neutral entity in galactic affairs by most governments."
history = "" // Todo
work = "Traders"
headquarters = "Shoal"
motto = ""
autogenerate_destination_names = FALSE
ship_prefixes = list("Legitimate Transport" = "transportation", "Legitimate Trader" = "freight", "Legitimate Diplomatic Vessel" = "raider")
destination_names = list(
"Ahdomai",
"Kelune",
"Dalstadt",
"New Canaan",
"Jargon 4",
"Hoorlm",
"Xarxis 5",
"Aurum",
"Moghes",
"Haverick",
"Darsing")
/datum/lore/organization/tsc/skrell
name = "Skrellian Central Authority"
short_name = "Skrellian CA."
acronym = "SCA"
desc = "The primary governing body of the Skrellian homeworld of Jargon 4,\
the SCA oversees all foreign and domestic policy for the Skrell and their colonies. The Skrellian Central Authority is better known for its\
active role in the largest military alliance in the galaxy, the Human-Skrellian Alliance."
history = ""
work = "oversees Skrell worlds"
headquarters = "Jargon 4"
motto = ""
ship_prefixes = list("SCA-V." = "transportation", "SCA-F" = "freight", "HSA-D" = "diplomatic")
destination_names = list(
"Venus",
"Earth",
"Luna",
"Mars",
"Titan",
"Aurumn",
"Jargon 4",
"Xarxis 5",
"Haverick",
"Darsing",
"Norfolk")
@@ -154,9 +154,6 @@
display_name = "corset, blue"
path = /obj/item/clothing/accessory/corset/blue
/datum/gear/accessory/armband/job
subtype_path = /datum/gear/accessory/armband/job
subtype_cost_overlap = FALSE
/datum/gear/accessory/armband_red
display_name = "armband"
@@ -166,41 +163,41 @@
display_name = "armband, blue-yellow"
path = /obj/item/clothing/accessory/armband/yb
/datum/gear/accessory/armband/job/sec
/datum/gear/accessory/armband_job
subtype_path = /datum/gear/accessory/armband_job
subtype_cost_overlap = FALSE
/datum/gear/accessory/armband_job/sec
display_name = " armband, security"
path = /obj/item/clothing/accessory/armband/sec
allowed_roles = list("Head of Security", "Warden", "Detective", "Security Officer", "Brig Physician", "Security Pod Pilot")
/datum/gear/accessory/armband/job/cargo
/datum/gear/accessory/armband_job/cargo
display_name = "cargo armband"
path = /obj/item/clothing/accessory/armband/cargo
allowed_roles = list("Quartermaster","Cargo Technician", "Shaft Miner")
/datum/gear/accessory/armband/job/medical
/datum/gear/accessory/armband_job/medical
display_name = "armband, medical"
path = /obj/item/clothing/accessory/armband/med
allowed_roles = list("Chief Medical Officer", "Medical Doctor", "Coroner", "Paramedic", "Brig Physician")
/datum/gear/accessory/armband/job/emt
/datum/gear/accessory/armband_job/emt
display_name = "armband, EMT"
path = /obj/item/clothing/accessory/armband/medgreen
allowed_roles = list("Paramedic", "Brig Physician")
/datum/gear/accessory/armband/job/engineering
/datum/gear/accessory/armband_job/engineering
display_name = "armband, engineering"
path = /obj/item/clothing/accessory/armband/engine
allowed_roles = list("Chief Engineer","Station Engineer", "Life Support Specialist")
/datum/gear/accessory/armband/job/hydro
/datum/gear/accessory/armband_job/hydro
display_name = "armband, hydroponics"
path = /obj/item/clothing/accessory/armband/hydro
allowed_roles = list("Botanist")
/datum/gear/accessory/armband/job/sci
/datum/gear/accessory/armband_job/sci
display_name = "armband, science"
path = /obj/item/clothing/accessory/armband/science
allowed_roles = list("Research Director","Scientist", "Roboticist")
@@ -108,50 +108,47 @@
display_name = "cowboy hat, pink"
path = /obj/item/clothing/head/cowboyhat/pink
//Berets Refactor
//Defining all Job Berets as no-overlap
//Somehow this doesn't break the DB.
/datum/gear/hat/beret/job
subtype_path = /datum/gear/hat/beret/job
subtype_cost_overlap = FALSE
/datum/gear/hat/beret/purple
/datum/gear/hat/beret_purple
display_name = "beret, purple"
path = /obj/item/clothing/head/beret/purple_normal
/datum/gear/hat/beret/black
/datum/gear/hat/beret_black
display_name = "beret, black"
path = /obj/item/clothing/head/beret/black
/datum/gear/hat/beret/blue
/datum/gear/hat/beret_blue
display_name = "beret, blue"
path = /obj/item/clothing/head/beret/blue
/datum/gear/hat/beret/red
/datum/gear/hat/beret_red
display_name = "beret, red"
path = /obj/item/clothing/head/beret
/datum/gear/hat/beret/job/sec
/datum/gear/hat/beret_job
subtype_path = /datum/gear/hat/beret_job
subtype_cost_overlap = FALSE
/datum/gear/hat/beret_job/sec
display_name = "security beret"
path = /obj/item/clothing/head/beret/sec
allowed_roles = list("Head of Security", "Warden", "Security Officer", "Security Pod Pilot")
/datum/gear/hat/beret/job/sci
/datum/gear/hat/beret_job/sci
display_name = "science beret"
path = /obj/item/clothing/head/beret/sci
allowed_roles = list("Research Director", "Scientist")
/datum/gear/hat/beret/job/med
/datum/gear/hat/beret_job/med
display_name = "medical beret"
path = /obj/item/clothing/head/beret/med
allowed_roles = list("Chief Medical Officer", "Medical Doctor" , "Virologist", "Brig Physician" , "Coroner")
/datum/gear/hat/beret/job/eng
/datum/gear/hat/beret_job/eng
display_name = "engineering beret"
path = /obj/item/clothing/head/beret/eng
allowed_roles = list("Chief Engineer", "Station Engineer")
/datum/gear/hat/beret/job/atmos
/datum/gear/hat/beret_job/atmos
display_name = "atmospherics beret"
path = /obj/item/clothing/head/beret/atmos
allowed_roles = list("Chief Engineer", "Life Support Specialist")
@@ -1,248 +0,0 @@
/*
* Contains
* /obj/item/rig_module/grenade_launcher
* /obj/item/rig_module/mounted
* /obj/item/rig_module/mounted/taser
* /obj/item/rig_module/shield
* /obj/item/rig_module/fabricator
* /obj/item/rig_module/device/flash
*/
/obj/item/rig_module/device/flash
name = "mounted flash"
desc = "You are the law."
icon_state = "flash"
interface_name = "mounted flash"
interface_desc = "Stuns your target by blinding them with a bright light."
device_type = /obj/item/flash
/obj/item/rig_module/grenade_launcher
name = "mounted grenade launcher"
desc = "A shoulder-mounted micro-explosive dispenser."
selectable = 1
icon_state = "grenade"
interface_name = "integrated grenade launcher"
interface_desc = "Discharges loaded grenades against the wearer's location."
var/fire_force = 30
var/fire_distance = 10
charges = list(
list("flashbang", "flashbang", /obj/item/grenade/flashbang, 3),
list("smoke bomb", "smoke bomb", /obj/item/grenade/smokebomb, 3),
list("EMP grenade", "EMP grenade", /obj/item/grenade/empgrenade, 3),
)
/obj/item/rig_module/grenade_launcher/accepts_item(var/obj/item/input_device, var/mob/living/user)
if(!istype(input_device) || !istype(user))
return 0
var/datum/rig_charge/accepted_item
for(var/charge in charges)
var/datum/rig_charge/charge_datum = charges[charge]
if(input_device.type == charge_datum.product_type)
accepted_item = charge_datum
break
if(!accepted_item)
return 0
if(accepted_item.charges >= 5)
to_chat(user, "<span class='danger'>Another grenade of that type will not fit into the module.</span>")
return 0
to_chat(user, "<font color='blue'><b>You slot \the [input_device] into the suit module.</b></font>")
user.unEquip(input_device)
qdel(input_device)
accepted_item.charges++
return 1
/obj/item/rig_module/grenade_launcher/engage(atom/target)
if(!..())
return 0
if(!target)
return 0
var/mob/living/carbon/human/H = holder.wearer
if(!charge_selected)
to_chat(H, "<span class='danger'>You have not selected a grenade type.</span>")
return 0
var/datum/rig_charge/charge = charges[charge_selected]
if(!charge)
return 0
if(charge.charges <= 0)
to_chat(H, "<span class='danger'>Insufficient grenades!</span>")
return 0
charge.charges--
var/obj/item/grenade/new_grenade = new charge.product_type(get_turf(H))
H.visible_message("<span class='danger'>[H] launches \a [new_grenade]!</span>")
new_grenade.throw_at(target,fire_force,fire_distance)
new_grenade.prime()
/obj/item/rig_module/mounted
name = "mounted laser cannon"
desc = "A shoulder-mounted battery-powered laser cannon mount."
selectable = 1
usable = 1
module_cooldown = 0
icon_state = "lcannon"
engage_string = "Configure"
interface_name = "mounted laser cannon"
interface_desc = "A shoulder-mounted cell-powered laser cannon."
var/gun_type = /obj/item/gun/energy/lasercannon/mounted
var/obj/item/gun/gun
/obj/item/rig_module/mounted/New()
..()
gun = new gun_type(src)
/obj/item/rig_module/mounted/engage(atom/target)
if(!..())
return 0
if(!target)
gun.attack_self(holder.wearer)
return 1
gun.afterattack(target,holder.wearer)
return 1
/obj/item/rig_module/mounted/egun
name = "mounted energy gun"
desc = "A forearm-mounted energy projector."
icon_state = "egun"
interface_name = "mounted energy gun"
interface_desc = "A forearm-mounted suit-powered energy gun."
gun_type = /obj/item/gun/energy/gun/mounted
/obj/item/rig_module/mounted/taser
name = "mounted taser"
desc = "A palm-mounted nonlethal energy projector."
icon_state = "taser"
usable = 0
suit_overlay_active = "mounted-taser"
suit_overlay_inactive = "mounted-taser"
interface_name = "mounted energy gun"
interface_desc = "A shoulder-mounted cell-powered energy gun."
gun_type = /obj/item/gun/energy/taser/mounted
/obj/item/rig_module/mounted/energy_blade
name = "energy blade projector"
desc = "A powerful cutting beam projector."
icon_state = "eblade"
activate_string = "Project Blade"
deactivate_string = "Cancel Blade"
interface_name = "spider fang blade"
interface_desc = "A lethal energy projector that can shape a blade projected from the hand of the wearer or launch radioactive darts."
usable = 0
selectable = 1
toggleable = 1
use_power_cost = 50
active_power_cost = 10
passive_power_cost = 0
gun_type = /obj/item/gun/energy/kinetic_accelerator/crossbow/ninja
/obj/item/rig_module/mounted/energy_blade/process()
if(holder && holder.wearer)
if(!(locate(/obj/item/melee/energy/blade) in holder.wearer))
deactivate()
return 0
return ..()
/obj/item/rig_module/mounted/energy_blade/activate()
..()
var/mob/living/M = holder.wearer
if(M.l_hand && M.r_hand)
to_chat(M, "<span class='danger'>Your hands are full.</span>")
deactivate()
return
var/obj/item/melee/energy/blade/blade = new(M)
M.put_in_hands(blade)
/obj/item/rig_module/mounted/energy_blade/deactivate()
..()
var/mob/living/M = holder.wearer
if(!M)
return
for(var/obj/item/melee/energy/blade/blade in M.contents)
M.unEquip(blade)
qdel(blade)
/obj/item/rig_module/fabricator
name = "matter fabricator"
desc = "A self-contained microfactory system for hardsuit integration."
selectable = 1
usable = 1
use_power_cost = 15
icon_state = "enet"
engage_string = "Fabricate Tile"
interface_name = "death blossom launcher"
interface_desc = "An integrated microfactory that produces floor tiles from thin air and electricity."
var/fabrication_type = /obj/item/stack/tile/plasteel
var/fire_force = 30
var/fire_distance = 10
/obj/item/rig_module/fabricator/engage(atom/target)
if(!..())
return 0
var/mob/living/H = holder.wearer
if(target)
var/obj/item/firing = new fabrication_type()
firing.forceMove(get_turf(src))
H.visible_message("<span class='danger'>[H] launches \a [firing]!</span>")
firing.throw_at(target,fire_force,fire_distance)
else
if(H.l_hand && H.r_hand)
to_chat(H, "<span class='danger'>Your hands are full.</span>")
else
var/obj/item/new_weapon = new fabrication_type()
new_weapon.forceMove(H)
to_chat(H, "<font color='blue'><b>You quickly fabricate \a [new_weapon].</b></font>")
H.put_in_hands(new_weapon)
return 1
@@ -1,496 +0,0 @@
/*
* Contains
* /obj/item/rig_module/ai_container
* /obj/item/rig_module/datajack
* /obj/item/rig_module/power_sink
* /obj/item/rig_module/electrowarfare_suite
*/
/obj/item/ai_verbs
name = "AI verb holder"
/obj/item/ai_verbs/verb/hardsuit_interface()
set category = "Hardsuit"
set name = "Open Hardsuit Interface"
set src in usr
if(!usr.loc || !usr.loc.loc || !istype(usr.loc.loc, /obj/item/rig_module))
to_chat(usr, "You are not loaded into a hardsuit.")
return
var/obj/item/rig_module/module = usr.loc.loc
if(!module.holder)
to_chat(usr, "Your module is not installed in a hardsuit.")
return
module.holder.ui_interact(usr, state = GLOB.contained_state)
/obj/item/rig_module/ai_container
name = "IIS module"
desc = "An integrated intelligence system module suitable for most hardsuits."
icon_state = "IIS"
toggleable = 1
usable = 1
disruptive = 0
activates_on_touch = 1
engage_string = "Eject AI"
activate_string = "Enable Dataspike"
deactivate_string = "Disable Dataspike"
interface_name = "integrated intelligence system"
interface_desc = "A socket that supports a range of artificial intelligence systems."
var/mob/integrated_ai // Direct reference to the actual mob held in the suit.
var/obj/item/ai_card // Reference to the MMI, posibrain, intellicard or pAI card previously holding the AI.
var/obj/item/ai_verbs/verb_holder
/mob
var/get_rig_stats = 0
/obj/item/rig_module/ai_container/process()
if(integrated_ai)
var/obj/item/rig/rig = get_rig()
if(rig && rig.ai_override_enabled)
integrated_ai.get_rig_stats = 1
else
integrated_ai.get_rig_stats = 0
/obj/item/rig_module/ai_container/proc/update_verb_holder()
if(!verb_holder)
verb_holder = new(src)
if(integrated_ai)
verb_holder.forceMove(integrated_ai)
else
verb_holder.forceMove(src)
/obj/item/rig_module/ai_container/accepts_item(var/obj/item/input_device, var/mob/living/user)
// Check if there's actually an AI to deal with.
var/mob/living/silicon/ai/target_ai
if(istype(input_device, /mob/living/silicon/ai))
target_ai = input_device
else
target_ai = locate(/mob/living/silicon/ai) in input_device.contents
var/obj/item/aicard/card = ai_card
// Downloading from/loading to a terminal.
if(istype(input_device,/obj/machinery/computer/aifixer) || istype(input_device,/mob/living/silicon/ai) || istype(input_device,/obj/structure/AIcore/deactivated))
// If we're stealing an AI, make sure we have a card for it.
if(!card)
card = new /obj/item/aicard(src)
// Terminal interaction only works with an intellicarded AI.
if(!istype(card))
return 0
// Since we've explicitly checked for three types, this should be safe.
card.afterattack(input_device, user, 1)
// If the transfer failed we can delete the card.
if(locate(/mob/living/silicon/ai) in card)
ai_card = card
integrated_ai = locate(/mob/living/silicon/ai) in card
else
eject_ai()
update_verb_holder()
return 1
if(istype(input_device,/obj/item/aicard))
// We are carding the AI in our suit.
if(integrated_ai)
var/obj/item/aicard/ext_card = input_device
ext_card.afterattack(integrated_ai, user, 1)
// If the transfer was successful, we can clear out our vars.
if(integrated_ai.loc != src)
integrated_ai = null
eject_ai()
else
// You're using an empty card on an empty suit, idiot.
if(!target_ai)
return 0
integrate_ai(input_device,user)
return 1
// Okay, it wasn't a terminal being touched, check for all the simple insertions.
if(input_device.type in list(/obj/item/paicard, /obj/item/mmi, /obj/item/mmi/robotic_brain))
if(integrated_ai)
integrated_ai.attackby(input_device,user)
// If the transfer was successful, we can clear out our vars.
if(integrated_ai.loc != src)
integrated_ai = null
eject_ai()
else
integrate_ai(input_device,user)
return 1
return 0
/obj/item/rig_module/ai_container/engage(atom/target)
if(!..())
return 0
var/mob/living/carbon/human/H = holder.wearer
if(!target)
if(ai_card)
if(istype(ai_card,/obj/item/aicard))
ai_card.ui_interact(H, state = GLOB.deep_inventory_state)
else
eject_ai(H)
update_verb_holder()
return 1
if(accepts_item(target,H))
return 1
return 0
/obj/item/rig_module/ai_container/removed()
eject_ai()
..()
/obj/item/rig_module/ai_container/proc/eject_ai(var/mob/user)
if(ai_card)
if(istype(ai_card, /obj/item/aicard))
if(integrated_ai && !integrated_ai.stat)
if(user)
to_chat(user, "<span class='danger'>You cannot eject your currently stored AI. Purge it manually.</span>")
return 0
to_chat(user, "<span class='danger'>You purge the remaining scraps of data from your previous AI, freeing it for use.</span>")
QDEL_NULL(integrated_ai)
QDEL_NULL(ai_card)
else if(user)
user.put_in_hands(ai_card)
else
ai_card.forceMove(get_turf(src))
ai_card = null
integrated_ai = null
update_verb_holder()
/obj/item/rig_module/ai_container/proc/integrate_ai(var/obj/item/ai,var/mob/user)
if(!ai) return
// The ONLY THING all the different AI systems have in common is that they all store the mob inside an item.
var/mob/living/ai_mob = locate(/mob/living) in ai.contents
if(ai_mob)
if(ai_mob.key && ai_mob.client)
if(istype(ai, /obj/item/aicard))
var/mob/living/silicon/ai/ROBUTT = ai_mob
if(istype(ROBUTT))
if(!ai_card)
ai_card = new /obj/item/aicard(src)
var/obj/item/aicard/source_card = ai
var/obj/item/aicard/target_card = ai_card
if(istype(source_card) && istype(target_card))
ROBUTT.forceMove(target_card)
ROBUTT.aiRestorePowerRoutine = 0//So the AI initially has power.
ROBUTT.control_disabled = 1//Can't control things remotely if you're stuck in a card!
ROBUTT.aiRadio.disabledAi = 1 //No talking on the built-in radio for you either!
source_card.update_state()
target_card.update_state()
else
return 0
else
user.unEquip(ai)
ai.forceMove(src)
ai_card = ai
to_chat(ai_mob, "<font color='blue'>You have been transferred to \the [holder]'s [src].</font>")
to_chat(user, "<font color='blue'>You load [ai_mob] into \the [holder]'s [src].</font>")
integrated_ai = ai_mob
if(!(locate(integrated_ai) in ai_card))
integrated_ai = null
eject_ai()
else
to_chat(user, "<span class='warning'>There is no active AI within \the [ai].</span>")
else
to_chat(user, "<span class='warning'>There is no active AI within \the [ai].</span>")
update_verb_holder()
/obj/item/rig_module/datajack
name = "datajack module"
desc = "A simple induction datalink module."
icon_state = "datajack"
toggleable = 1
activates_on_touch = 1
usable = 0
activate_string = "Enable Datajack"
deactivate_string = "Disable Datajack"
interface_name = "contact datajack"
interface_desc = "An induction-powered high-throughput datalink suitable for hacking encrypted networks."
var/list/stored_research
/obj/item/rig_module/datajack/New()
..()
stored_research = list()
/obj/item/rig_module/datajack/engage(atom/target)
if(!..())
return 0
if(target)
var/mob/living/carbon/human/H = holder.wearer
if(!accepts_item(target,H))
return 0
return 1
/obj/item/rig_module/datajack/accepts_item(var/obj/item/input_device, var/mob/living/user)
if(istype(input_device,/obj/item/disk/tech_disk))
to_chat(user, "You slot the disk into [src].")
var/obj/item/disk/tech_disk/disk = input_device
if(disk.stored)
if(load_data(disk.stored))
to_chat(user, "<font color='blue'>Download successful; disk erased.</font>")
disk.stored = null
else
to_chat(user, "<span class='warning'>The disk is corrupt. It is useless to you.</span>")
else
to_chat(user, "<span class='warning'>The disk is blank. It is useless to you.</span>")
return 1
// I fucking hate R&D code. This typecheck spam would be totally unnecessary in a sane setup.
else if(istype(input_device,/obj/machinery))
var/datum/research/incoming_files
if(istype(input_device,/obj/machinery/computer/rdconsole))
var/obj/machinery/computer/rdconsole/input_machine = input_device
incoming_files = input_machine.files
else if(istype(input_device,/obj/machinery/r_n_d/server))
var/obj/machinery/r_n_d/server/input_machine = input_device
incoming_files = input_machine.files
else if(istype(input_device,/obj/machinery/mecha_part_fabricator))
var/obj/machinery/mecha_part_fabricator/input_machine = input_device
incoming_files = input_machine.files
if(!incoming_files || !incoming_files.known_tech || !incoming_files.known_tech.len)
to_chat(user, "<span class='warning'>Memory failure. There is nothing accessible stored on this terminal.</span>")
else
// Maybe consider a way to drop all your data into a target repo in the future.
if(load_data(incoming_files.known_tech))
to_chat(user, "<font color='blue'>Download successful; local and remote repositories synchronized.</font>")
else
to_chat(user, "<span class='warning'>Scan complete. There is nothing useful stored on this terminal.</span>")
return 1
return 0
/obj/item/rig_module/datajack/proc/load_data(var/incoming_data)
if(islist(incoming_data))
for(var/entry in incoming_data)
load_data(entry)
return 1
if(istype(incoming_data, /datum/tech))
var/data_found
var/datum/tech/new_data = incoming_data
for(var/datum/tech/current_data in stored_research)
if(current_data.id == new_data.id)
data_found = 1
if(current_data.level < new_data.level)
current_data.level = new_data.level
break
if(!data_found)
stored_research += incoming_data
return 1
return 0
/obj/item/rig_module/electrowarfare_suite
name = "electrowarfare module"
desc = "A bewilderingly complex bundle of fiber optics and chips."
icon_state = "ewar"
toggleable = 1
usable = 0
activate_string = "Enable Countermeasures"
deactivate_string = "Disable Countermeasures"
interface_name = "electrowarfare system"
interface_desc = "An active counter-electronic warfare suite that disrupts AI tracking."
/obj/item/rig_module/electrowarfare_suite/activate()
if(!..())
return
// This is not the best way to handle this, but I don't want it to mess with ling camo
var/mob/living/M = holder.wearer
M.digitalcamo++
/obj/item/rig_module/electrowarfare_suite/deactivate()
if(!..())
return
var/mob/living/M = holder.wearer
M.digitalcamo = max(0,(M.digitalcamo-1))
/* //Not easily compatible with our current powernet, and is
/obj/item/rig_module/power_sink // quite stupid anyways, iyam
name = "hardsuit power sink"
desc = "An heavy-duty power sink."
icon_state = "powersink"
toggleable = 1
activates_on_touch = 1
disruptive = 0
activate_string = "Enable Power Sink"
deactivate_string = "Disable Power Sink"
interface_name = "niling d-sink"
interface_desc = "Colloquially known as a power siphon, this module drains power through the suit hands into the suit battery."
var/atom/interfaced_with // Currently draining power from this device.
var/total_power_drained = 0
var/drain_loc
/obj/item/rig_module/power_sink/deactivate()
if(interfaced_with)
if(holder && holder.wearer)
to_chat(holder.wearer, "<span class = 'warning'>Your power sink retracts as the module deactivates.</span>")
drain_complete()
interfaced_with = null
total_power_drained = 0
return ..()
/obj/item/rig_module/power_sink/activate()
interfaced_with = null
total_power_drained = 0
return ..()
/obj/item/rig_module/power_sink/engage(atom/target)
if(!..())
return 0
//Target wasn't supplied or we're already draining.
if(interfaced_with)
return 0
if(!target)
return 1
// Are we close enough?
var/mob/living/carbon/human/H = holder.wearer
if(!target.Adjacent(H))
return 0
// Is it a valid power source?
if(target.drain_power(1) <= 0)
return 0
to_chat(H, "<span class = 'danger'>You begin draining power from [target]!</span>")
interfaced_with = target
drain_loc = interfaced_with.loc
holder.spark_system.start()
playsound(H.loc, 'sound/effects/sparks2.ogg', 50, 1)
return 1
/obj/item/rig_module/power_sink/accepts_item(var/obj/item/input_device, var/mob/living/user)
var/can_drain = input_device.drain_power(1)
if(can_drain > 0)
engage(input_device)
return 1
return 0
/obj/item/rig_module/power_sink/process()
if(!interfaced_with)
return ..()
var/mob/living/carbon/human/H
if(holder && holder.wearer)
H = holder.wearer
if(!H || !istype(H))
return 0
holder.spark_system.start()
playsound(H.loc, 'sound/effects/sparks2.ogg', 50, 1)
if(!holder.cell)
to_chat(H, "<span class = 'danger'>Your power sink flashes an error; there is no cell in your rig.</span>")
drain_complete(H)
return
if(!interfaced_with || !interfaced_with.Adjacent(H) || !(interfaced_with.loc == drain_loc))
to_chat(H, "<span class = 'warning'>Your power sink retracts into its casing.</span>")
drain_complete(H)
return
if(holder.cell.fully_charged())
to_chat(H, "<span class = 'warning'>Your power sink flashes an amber light; your rig cell is full.</span>")
drain_complete(H)
return
// Attempts to drain up to 40kW, determines this value from remaining cell capacity to ensure we don't drain too much..
var/to_drain = min(40000, ((holder.cell.maxcharge - holder.cell.charge) / CELLRATE))
var/target_drained = interfaced_with.drain_power(0,0,to_drain)
if(target_drained <= 0)
to_chat(H, "<span class = 'danger'>Your power sink flashes a red light; there is no power left in [interfaced_with].</span>")
drain_complete(H)
return
holder.cell.give(target_drained * CELLRATE)
total_power_drained += target_drained
return 1
/obj/item/rig_module/power_sink/proc/drain_complete(var/mob/living/M)
if(!interfaced_with)
to_chat(if(M) M, "<font color='blue'><b>Total power drained:</b> [round(total_power_drained/1000)]kJ.</font>")
else
to_chat(if(M) M, "<font color='blue'><b>Total power drained from [interfaced_with]:</b> [round(total_power_drained/1000)]kJ.</font>")
interfaced_with.drain_power(0,1,0) // Damage the victim.
drain_loc = null
interfaced_with = null
total_power_drained = 0*/
/*
//Maybe make this use power when active or something
/obj/item/rig_module/emp_shielding
name = "\improper EMP dissipation module"
desc = "A bewilderingly complex bundle of fiber optics and chips."
toggleable = 1
usable = 0
activate_string = "Enable active EMP shielding"
deactivate_string = "Disable active EMP shielding"
interface_name = "active EMP shielding system"
interface_desc = "A highly experimental system that augments the hardsuit's existing EM shielding."
var/protection_amount = 20
/obj/item/rig_module/emp_shielding/activate()
if(!..())
return
holder.emp_protection += protection_amount
/obj/item/rig_module/emp_shielding/deactivate()
if(!..())
return
holder.emp_protection = max(0,(holder.emp_protection - protection_amount))
*/
@@ -1,50 +0,0 @@
/obj/item/rig_module/handheld
name = "mounted device"
desc = "Some kind of hardsuit extension."
usable = 0
selectable = 0
toggleable = 1
disruptive = 0
activate_string = "Deploy"
deactivate_string = "Retract"
var/device_type
var/obj/item
/obj/item/rig_module/handheld/activate()
if(!..())
return
if(!holder.wearer.put_in_hands(device))
to_chat(holder.wearer, "<span class='notice'>You need a free hand to hold \the [device].</span>")
active = 0
return
to_chat(holder.wearer, "<span class='notice'>You deploy \the [device].</span>")
/obj/item/rig_module/handheld/deactivate()
if(!..())
return
if(ismob(device.loc)) //Better check for the holder, instead of assuming the rigwearer has it.
var/mob/M = device.loc //Helps in case the code fails to keep the module in one place, this should still return it.
M.unEquip(device, 1)
device.loc = src
to_chat(holder.wearer, "<span class='notice'>You retract \the [device].</span>")
/obj/item/rig_module/handheld/New()
..()
if(device_type)
device = new device_type(src)
device.flags |= NODROP //We don't want to drop it while it's active/inhand.
activate_string += " [device]"
deactivate_string += " [device]"
/obj/item/rig_module/handheld/horn
name = "mounted bikehorn"
desc = "For tactical honking"
interface_name = "mounted bikehorn"
interface_desc = "Honks"
device_type = /obj/item/bikehorn
@@ -1,330 +0,0 @@
/*
* Rigsuit upgrades/abilities.
*/
/datum/rig_charge
var/short_name = "undef"
var/display_name = "undefined"
var/product_type = "undefined"
var/charges = 0
/obj/item/rig_module
name = "hardsuit upgrade"
desc = "It looks pretty sciency."
icon = 'icons/obj/rig_modules.dmi'
icon_state = "module"
toolspeed = 1
var/damage = 0
var/obj/item/rig/holder
var/module_cooldown = 10
var/next_use = 0
var/toggleable // Set to 1 for the device to show up as an active effect.
var/usable // Set to 1 for the device to have an on-use effect.
var/selectable // Set to 1 to be able to assign the device as primary system.
var/redundant // Set to 1 to ignore duplicate module checking when installing.
var/permanent // If set, the module can't be removed.
var/disruptive = 1 // Can disrupt by other effects.
var/activates_on_touch // If set, unarmed attacks will call engage() on the target.
var/active // Basic module status
var/disruptable // Will deactivate if some other powers are used.
var/use_power_cost = 0 // Power used when single-use ability called.
var/active_power_cost = 0 // Power used when turned on.
var/passive_power_cost = 0 // Power used when turned off.
var/list/charges // Associative list of charge types and remaining numbers.
var/charge_selected // Currently selected option used for charge dispensing.
// Icons.
var/suit_overlay
var/suit_overlay_active // If set, drawn over icon and mob when effect is active.
var/suit_overlay_inactive // As above, inactive.
var/suit_overlay_used // As above, when engaged.
//Display fluff
var/interface_name = "hardsuit upgrade"
var/interface_desc = "A generic hardsuit upgrade."
var/engage_string = "Engage"
var/activate_string = "Activate"
var/deactivate_string = "Deactivate"
var/list/stat_rig_module/stat_modules = new()
/obj/item/rig_module/examine(mob/user)
. = ..()
switch(damage)
if(0)
. += "It is undamaged."
if(1)
. += "It is badly damaged."
if(2)
. += "It is almost completely destroyed."
/obj/item/rig_module/attackby(obj/item/W as obj, mob/user as mob)
if(istype(W,/obj/item/stack/nanopaste))
if(damage == 0)
to_chat(user, "There is no damage to mend.")
return
to_chat(user, "You start mending the damaged portions of \the [src]...")
if(!do_after(user, 30 * W.toolspeed, target = src) || !W || !src)
return
var/obj/item/stack/nanopaste/paste = W
damage = 0
to_chat(user, "You mend the damage to [src] with [W].")
paste.use(1)
return
else if(istype(W,/obj/item/stack/cable_coil))
switch(damage)
if(0)
to_chat(user, "There is no damage to mend.")
return
if(2)
to_chat(user, "There is no damage that you are capable of mending with such crude tools.")
return
var/obj/item/stack/cable_coil/cable = W
if(!cable.amount >= 5)
to_chat(user, "You need five units of cable to repair \the [src].")
return
to_chat(user, "You start mending the damaged portions of \the [src]...")
if(!do_after(user, 30 * W.toolspeed, target = src) || !W || !src)
return
damage = 1
to_chat(user, "You mend some of damage to [src] with [W], but you will need more advanced tools to fix it completely.")
cable.use(5)
return
..()
/obj/item/rig_module/New()
..()
if(suit_overlay_inactive)
suit_overlay = suit_overlay_inactive
if(charges && charges.len)
var/list/processed_charges = list()
for(var/list/charge in charges)
var/datum/rig_charge/charge_dat = new
charge_dat.short_name = charge[1]
charge_dat.display_name = charge[2]
charge_dat.product_type = charge[3]
charge_dat.charges = charge[4]
if(!charge_selected) charge_selected = charge_dat.short_name
processed_charges[charge_dat.short_name] = charge_dat
charges = processed_charges
stat_modules += new/stat_rig_module/activate(src)
stat_modules += new/stat_rig_module/deactivate(src)
stat_modules += new/stat_rig_module/engage(src)
stat_modules += new/stat_rig_module/select(src)
stat_modules += new/stat_rig_module/charge(src)
// Called when the module is installed into a suit.
/obj/item/rig_module/proc/installed(var/obj/item/rig/new_holder)
holder = new_holder
return
//Proc for one-use abilities like teleport.
/obj/item/rig_module/proc/engage()
if(damage >= 2)
to_chat(usr, "<span class='warning'>The [interface_name] is damaged beyond use!</span>")
return 0
if(world.time < next_use)
to_chat(usr, "<span class='warning'>You cannot use the [interface_name] again so soon.</span>")
return 0
if(!holder || (!(holder.flags & NODROP)))
to_chat(usr, "<span class='warning'>The suit is not initialized.</span>")
return 0
if(usr.lying || usr.stat || usr.stunned || usr.paralysis || usr.IsWeakened())
to_chat(usr, "<span class='warning'>You cannot use the suit in this state.</span>")
return 0
if(holder.wearer && holder.wearer.lying)
to_chat(usr, "<span class='warning'>The suit cannot function while the wearer is prone.</span>")
return 0
if(holder.security_check_enabled && !holder.check_suit_access(usr))
to_chat(usr, "<span class='danger'>Access denied.</span>")
return 0
if(!holder.check_power_cost(usr, use_power_cost, 0, src, (istype(usr,/mob/living/silicon ? 1 : 0) ) ) )
return 0
next_use = world.time + module_cooldown
return 1
// Proc for toggling on active abilities.
/obj/item/rig_module/proc/activate()
if(active || !engage())
return 0
active = 1
spawn(1)
if(suit_overlay_active)
suit_overlay = suit_overlay_active
else
suit_overlay = null
holder.update_icon()
return 1
// Proc for toggling off active abilities.
/obj/item/rig_module/proc/deactivate()
if(!active)
return 0
active = 0
spawn(1)
if(suit_overlay_inactive)
suit_overlay = suit_overlay_inactive
else
suit_overlay = null
if(holder)
holder.update_icon()
return 1
// Called when the module is uninstalled from a suit.
/obj/item/rig_module/proc/removed()
deactivate()
holder = null
return
// Called by the hardsuit each rig process tick.
/obj/item/rig_module/process()
if(active)
return active_power_cost
else
return passive_power_cost
// Called by holder rigsuit attackby()
// Checks if an item is usable with this module and handles it if it is
/obj/item/rig_module/proc/accepts_item(var/obj/item/input_device)
return 0
/mob/proc/SetupStat(var/obj/item/rig/R)
if(R && (R.flags & NODROP) && R.installed_modules.len && statpanel("Hardsuit Modules"))
var/cell_status = R.cell ? "[R.cell.charge]/[R.cell.maxcharge]" : "ERROR"
stat("Suit charge", cell_status)
for(var/obj/item/rig_module/module in R.installed_modules)
{
for(var/stat_rig_module/SRM in module.stat_modules)
if(SRM.CanUse())
stat(SRM.module.interface_name,SRM)
}
/stat_rig_module
parent_type = /atom/movable
var/module_mode = ""
var/obj/item/rig_module/module
/stat_rig_module/New(var/obj/item/rig_module/module)
..()
src.module = module
/stat_rig_module/proc/AddHref(var/list/href_list)
return
/stat_rig_module/proc/CanUse()
return 0
/stat_rig_module/Click()
if(CanUse())
var/list/href_list = list(
"interact_module" = module.holder.installed_modules.Find(module),
"module_mode" = module_mode
)
AddHref(href_list)
module.holder.Topic(usr, href_list)
/stat_rig_module/DblClick()
return Click()
/stat_rig_module/activate/New(var/obj/item/rig_module/module)
..()
name = module.activate_string
if(module.active_power_cost)
name += " ([module.active_power_cost*10]A)"
module_mode = "activate"
/stat_rig_module/activate/CanUse()
return module.toggleable && !module.active
/stat_rig_module/deactivate/New(var/obj/item/rig_module/module)
..()
name = module.deactivate_string
// Show cost despite being 0, if it means changing from an active cost.
if(module.active_power_cost || module.passive_power_cost)
name += " ([module.passive_power_cost*10]P)"
module_mode = "deactivate"
/stat_rig_module/deactivate/CanUse()
return module.toggleable && module.active
/stat_rig_module/engage/New(var/obj/item/rig_module/module)
..()
name = module.engage_string
if(module.use_power_cost)
name += " ([module.use_power_cost*10]E)"
module_mode = "engage"
/stat_rig_module/engage/CanUse()
return module.usable
/stat_rig_module/select/New()
..()
name = "Select"
module_mode = "select"
/stat_rig_module/select/CanUse()
if(module.selectable)
name = module.holder.selected_module == module ? "Selected" : "Select"
return 1
return 0
/stat_rig_module/charge/New()
..()
name = "Change Charge"
module_mode = "select_charge_type"
/stat_rig_module/charge/AddHref(var/list/href_list)
var/charge_index = module.charges.Find(module.charge_selected)
if(!charge_index)
charge_index = 0
else
charge_index = charge_index == module.charges.len ? 1 : charge_index+1
href_list["charge_type"] = module.charges[charge_index]
/stat_rig_module/charge/CanUse()
if(module.charges && module.charges.len)
var/datum/rig_charge/charge = module.charges[module.charge_selected]
name = "[charge.display_name] ([charge.charges]C) - Change"
return 1
return 0
@@ -1,196 +0,0 @@
/*
* Contains
* /obj/item/rig_module/stealth_field
* /obj/item/rig_module/teleporter
* /obj/item/rig_module/fabricator/energy_net
* /obj/item/rig_module/self_destruct
*/
/obj/item/rig_module/stealth_field
name = "active camouflage module"
desc = "A robust hardsuit-integrated stealth module."
icon_state = "cloak"
toggleable = 1
disruptable = 1
disruptive = 0
use_power_cost = 50
active_power_cost = 10
passive_power_cost = 0
module_cooldown = 30
activate_string = "Enable Cloak"
deactivate_string = "Disable Cloak"
interface_name = "integrated stealth system"
interface_desc = "An integrated active camouflage system."
suit_overlay_active = "stealth_active"
suit_overlay_inactive = "stealth_inactive"
/obj/item/rig_module/stealth_field/activate()
if(!..())
return 0
var/mob/living/carbon/human/H = holder.wearer
to_chat(H, "<font color='blue'><b>You are now invisible to normal detection.</b></font>")
H.invisibility = INVISIBILITY_LEVEL_TWO
H.visible_message("[H.name] vanishes into thin air!",1)
/obj/item/rig_module/stealth_field/deactivate()
if(!..())
return 0
var/mob/living/carbon/human/H = holder.wearer
to_chat(H, "<span class='danger'>You are now visible.</span>")
H.invisibility = 0
new /obj/effect/temp_visual/dir_setting/ninja(get_turf(H), H.dir)
for(var/mob/O in oviewers(H))
O.show_message("[H.name] appears from thin air!",1)
playsound(get_turf(H), 'sound/effects/stealthoff.ogg', 75, 1)
/obj/item/rig_module/teleporter
name = "teleportation module"
desc = "A complex, sleek-looking, hardsuit-integrated teleportation module."
icon_state = "teleporter"
use_power_cost = 40
redundant = 1
usable = 1
selectable = 1
engage_string = "Emergency Leap"
interface_name = "VOID-shift phase projector"
interface_desc = "An advanced teleportation system. It is capable of pinpoint precision or random leaps forward."
/obj/item/rig_module/teleporter/proc/phase_in(var/mob/M,var/turf/T)
if(!M || !T)
return
holder.spark_system.start()
playsound(T, 'sound/effects/phasein.ogg', 25, 1)
playsound(T, 'sound/effects/sparks2.ogg', 50, 1)
new /obj/effect/temp_visual/dir_setting/ninja/phase(T, M.dir)
/obj/item/rig_module/teleporter/proc/phase_out(var/mob/M,var/turf/T)
if(!M || !T)
return
playsound(T, "sparks", 50, 1)
new /obj/effect/temp_visual/dir_setting/ninja/phase/out(T, M.dir)
/obj/item/rig_module/teleporter/engage(var/atom/target, var/notify_ai)
if(!..()) return 0
var/mob/living/carbon/human/H = holder.wearer
if(!istype(H.loc, /turf))
to_chat(H, "<span class='warning'>You cannot teleport out of your current location.</span>")
return 0
var/turf/T
if(target)
T = get_turf(target)
else
T = get_teleport_loc(get_turf(H), H, rand(5, 9))
/*if(!T || T.density)
to_chat(H, "<span class='warning'>You cannot teleport into solid walls.</span>")
return 0*///Who the fuck cares? Ninjas in walls are cool.
if(!is_teleport_allowed(T.z))
to_chat(H, "<span class='warning'>You cannot use your teleporter on this Z-level.</span>")
return 0
phase_out(H,get_turf(H))
H.forceMove(T)
phase_in(H,get_turf(H))
for(var/obj/item/grab/G in H.contents)
if(G.affecting)
phase_out(G.affecting,get_turf(G.affecting))
G.affecting.forceMove(locate(T.x+rand(-1,1),T.y+rand(-1,1),T.z))
phase_in(G.affecting,get_turf(G.affecting))
return 1
/*
/obj/item/rig_module/fabricator/energy_net
name = "net projector"
desc = "Some kind of complex energy projector with a hardsuit mount."
icon_state = "enet"
interface_name = "energy net launcher"
interface_desc = "An advanced energy-patterning projector used to capture targets."
engage_string = "Fabricate Net"
fabrication_type = /obj/item/energy_net
use_power_cost = 70
/obj/item/rig_module/fabricator/energy_net/engage(atom/target)
if(holder && holder.wearer)
if(..(target) && target)
holder.wearer.Beam(target,"n_beam",,10)
return 1
return 0*/
/obj/item/rig_module/self_destruct
name = "self-destruct module"
desc = "Oh my God, Captain. A bomb."
icon_state = "deadman"
usable = 1
active = 1
permanent = 1
engage_string = "Detonate"
interface_name = "dead man's switch"
interface_desc = "An integrated self-destruct module. When the wearer dies, so does the surrounding area. Do not press this button."
/obj/item/rig_module/self_destruct/activate()
return
/obj/item/rig_module/self_destruct/deactivate()
return
/obj/item/rig_module/self_destruct/process()
// Not being worn, leave it alone.
if(!holder || !holder.wearer || !holder.wearer.wear_suit == holder)
return 0
//OH SHIT.
if(holder.wearer.stat == 2)
engage()
/obj/item/rig_module/self_destruct/engage()
explosion(get_turf(src), 1, 2, 4, 5)
if(holder && holder.wearer)
holder.wearer.unEquip(src)
qdel(holder)
qdel(src)
/obj/item/rig_module/self_destruct/small/engage()
explosion(get_turf(src), 0, 0, 3, 4)
if(holder && holder.wearer)
holder.wearer.unEquip(src)
qdel(holder)
qdel(src)
@@ -1,476 +0,0 @@
/* Contains:
* /obj/item/rig_module/device
* /obj/item/rig_module/device/plasmacutter
* /obj/item/rig_module/device/healthscanner
* /obj/item/rig_module/device/drill
* /obj/item/rig_module/device/orescanner
* /obj/item/rig_module/device/rcd
* /obj/item/rig_module/device/anomaly_scanner
* /obj/item/rig_module/maneuvering_jets
* /obj/item/rig_module/foam_sprayer
* /obj/item/rig_module/device/broadcaster
* /obj/item/rig_module/chem_dispenser
* /obj/item/rig_module/chem_dispenser/injector
* /obj/item/rig_module/voice
* /obj/item/rig_module/device/paperdispenser
* /obj/item/rig_module/device/pen
* /obj/item/rig_module/device/stamp
*/
/obj/item/rig_module/device
name = "mounted device"
desc = "Some kind of hardsuit mount."
usable = 0
selectable = 1
toggleable = 0
disruptive = 0
var/device_type
var/obj/item/device
/obj/item/rig_module/device/plasmacutter
name = "hardsuit plasma cutter"
desc = "A lethal-looking industrial cutter."
icon_state = "plasmacutter"
interface_name = "plasma cutter"
interface_desc = "A self-sustaining plasma arc capable of cutting through walls."
suit_overlay_active = "plasmacutter"
suit_overlay_inactive = "plasmacutter"
device_type = /obj/item/gun/energy/plasmacutter
/obj/item/rig_module/device/healthscanner
name = "health scanner module"
desc = "A hardsuit-mounted health scanner."
icon_state = "scanner"
interface_name = "health scanner"
interface_desc = "Shows an informative health readout when used on a subject."
device_type = /obj/item/healthanalyzer
/obj/item/rig_module/device/drill
name = "hardsuit drill mount"
desc = "A very heavy diamond-tipped drill."
icon_state = "drill"
interface_name = "mounted drill"
interface_desc = "A diamond-tipped industrial drill."
suit_overlay_active = "mounted-drill"
suit_overlay_inactive = "mounted-drill"
device_type = /obj/item/pickaxe/drill/diamonddrill
/obj/item/rig_module/device/orescanner
name = "ore scanner module"
desc = "A clunky old ore scanner."
icon_state = "scanner"
interface_name = "ore detector"
interface_desc = "A sonar system for detecting large masses of ore."
engage_string = "Begin Scan"
usable = 1
selectable = 0
device_type = /obj/item/mining_scanner
/*
/obj/item/rig_module/device/rcd
name = "RCD mount"
desc = "A cell-powered rapid construction device for a hardsuit."
icon_state = "rcd"
interface_name = "mounted RCD"
interface_desc = "A device for building or removing walls. Cell-powered."
usable = 1
engage_string = "Configure RCD"
device_type = /obj/item/rcd/mounted
*/
/obj/item/rig_module/device/New()
..()
if(device_type)
device = new device_type(src)
device.flags |= ABSTRACT //Abstract in the sense that it's not an item that stands alone, but rather is just there to let the module act like it.
/obj/item/rig_module/device/engage(atom/target)
if(!..() || !device)
return 0
if(!target)
device.attack_self(holder.wearer)
return 1
var/turf/T = get_turf(target)
if(istype(T) && !T.Adjacent(get_turf(src)))
return 0
var/resolved = target.attackby(device,holder.wearer)
if(!resolved && device && target)
device.afterattack(target,holder.wearer,1)
return 1
/obj/item/rig_module/chem_dispenser
name = "mounted chemical dispenser"
desc = "A complex web of tubing and needles suitable for hardsuit use."
icon_state = "injector"
usable = 1
selectable = 0
toggleable = 0
disruptive = 0
engage_string = "Inject"
interface_name = "integrated chemical dispenser"
interface_desc = "Dispenses loaded chemicals directly into the wearer's bloodstream."
charges = list(
list("saline-glucose", "salglu_solution", 0, 80),
list("salicylic acid", "sal_acid", 0, 80),
list("salbutamol", "salbutamol", 0, 80),
list("antibiotics", "spaceacillin", 0, 80),
list("charcoal", "charcoal", 0, 80),
list("nutrients", "nutriment", 0, 80),
list("potasssium iodide","potass_iodide", 0, 80),
list("radium", "radium", 0, 80)
)
var/max_reagent_volume = 80 //Used when refilling.
/obj/item/rig_module/chem_dispenser/ninja
interface_desc = "Dispenses loaded chemicals directly into the wearer's bloodstream. This variant is made to be extremely light and flexible."
//just over a syringe worth of each. Want more? Go refill. Gives the ninja another reason to have to show their face.
charges = list(
list("saline-glucose", "salglu_solution", 0, 20),
list("salicylic acid", "sal_acid", 0, 20),
list("salbutamol", "salbutamol", 0, 20),
list("antibiotics", "spaceacillin", 0, 20),
list("charcoal", "charcoal", 0, 20),
list("nutrients", "nutriment", 0, 80),
list("potasssium iodide","potass_iodide", 0, 20),
list("radium", "radium", 0, 20)
)
/obj/item/rig_module/chem_dispenser/accepts_item(var/obj/item/input_item, var/mob/living/user)
if(!input_item.is_open_container())
return 0
if(!input_item.reagents || !input_item.reagents.total_volume)
to_chat(user, "\The [input_item] is empty.")
return 0
// Magical chemical filtration system, do not question it.
var/total_transferred = 0
for(var/datum/reagent/R in input_item.reagents.reagent_list)
for(var/chargetype in charges)
var/datum/rig_charge/charge = charges[chargetype]
if(charge.display_name == R.id)
var/chems_to_transfer = R.volume
if((charge.charges + chems_to_transfer) > max_reagent_volume)
chems_to_transfer = max_reagent_volume - charge.charges
charge.charges += chems_to_transfer
input_item.reagents.remove_reagent(R.id, chems_to_transfer)
total_transferred += chems_to_transfer
break
if(total_transferred)
to_chat(user, "<font color='blue'>You transfer [total_transferred] units into the suit reservoir.</font>")
else
to_chat(user, "<span class='danger'>None of the reagents seem suitable.</span>")
return 1
/obj/item/rig_module/chem_dispenser/engage(atom/target)
if(!..())
return 0
var/mob/living/carbon/human/H = holder.wearer
if(!charge_selected)
to_chat(H, "<span class='danger'>You have not selected a chemical type.</span>")
return 0
var/datum/rig_charge/charge = charges[charge_selected]
if(!charge)
return 0
var/chems_to_use = 10
if(charge.charges <= 0)
to_chat(H, "<span class='danger'>Insufficient chems!</span>")
return 0
else if(charge.charges < chems_to_use)
chems_to_use = charge.charges
var/mob/living/carbon/target_mob
if(target)
if(istype(target,/mob/living/carbon))
target_mob = target
else
return 0
else
target_mob = H
if(target_mob != H)
to_chat(H, "<span class='danger'>You inject [target_mob] with [chems_to_use] unit\s of [charge.display_name].</span>")
to_chat(target_mob, "<span class='danger'>You feel a rushing in your veins as [chems_to_use] unit\s of [charge.display_name] [chems_to_use == 1 ? "is" : "are"] injected.</span>")
target_mob.reagents.add_reagent(charge.display_name, chems_to_use)
charge.charges -= chems_to_use
if(charge.charges < 0) charge.charges = 0
return 1
/obj/item/rig_module/chem_dispenser/combat
name = "combat chemical injector"
desc = "A complex web of tubing and needles suitable for hardsuit use."
charges = list(
list("synaptizine", "synaptizine", 0, 30),
list("hydrocodone", "hydrocodone", 0, 30),
list("nutrients", "nutriment", 0, 80),
)
interface_name = "combat chem dispenser"
interface_desc = "Dispenses loaded chemicals directly into the bloodstream."
/obj/item/rig_module/chem_dispenser/injector
name = "mounted chemical injector"
desc = "A complex web of tubing and a large needle suitable for hardsuit use."
usable = 0
selectable = 1
disruptive = 1
interface_name = "mounted chem injector"
interface_desc = "Dispenses loaded chemicals via an arm-mounted injector."
/obj/item/rig_module/voice
name = "hardsuit voice synthesiser"
desc = "A speaker box and sound processor."
icon_state = "megaphone"
usable = 1
selectable = 0
toggleable = 0
disruptive = 0
engage_string = "Configure Synthesiser"
interface_name = "voice synthesiser"
interface_desc = "A flexible and powerful voice modulator system."
var/obj/item/voice_changer/voice_holder
/obj/item/rig_module/voice/New()
..()
voice_holder = new(src)
voice_holder.active = FALSE
/obj/item/rig_module/voice/installed()
..()
holder.speech = src
/obj/item/rig_module/voice/engage()
if(!..())
return 0
var/choice= input("Would you like to toggle the synthesiser or set the name?") as null|anything in list("Enable","Disable","Set Name")
if(!choice)
return 0
switch(choice)
if("Enable")
active = TRUE
voice_holder.active = TRUE
to_chat(usr, "<font color='blue'>You enable the speech synthesiser.</font>")
if("Disable")
active = FALSE
voice_holder.active = FALSE
to_chat(usr, "<font color='blue'>You disable the speech synthesiser.</font>")
if("Set Name")
var/raw_choice = sanitize(input(usr, "Please enter a new name.") as text|null, MAX_NAME_LEN)
if(!raw_choice)
return FALSE
voice_holder.voice = raw_choice
to_chat(usr, "<font color='blue'>You are now mimicking <B>[voice_holder.voice]</B>.</font>")
return 1
/obj/item/rig_module/maneuvering_jets
name = "hardsuit maneuvering jets"
desc = "A compact gas thruster system for a hardsuit."
icon_state = "thrusters"
usable = 1
toggleable = 1
selectable = 0
disruptive = 0
suit_overlay_active = "maneuvering_active"
suit_overlay_inactive = null //"maneuvering_inactive"
engage_string = "Toggle Stabilizers"
activate_string = "Activate Thrusters"
deactivate_string = "Deactivate Thrusters"
interface_name = "maneuvering jets"
interface_desc = "An inbuilt EVA maneuvering system that runs off the rig air supply."
var/obj/item/tank/jetpack/rig/jets
/obj/item/rig_module/maneuvering_jets/engage()
if(!..())
return 0
jets.toggle_stabilization(usr)
return 1
/obj/item/rig_module/maneuvering_jets/activate()
if(active)
return 0
active = 1
spawn(1)
if(suit_overlay_active)
suit_overlay = suit_overlay_active
else
suit_overlay = null
holder.update_icon()
jets.turn_on()
return 1
/obj/item/rig_module/maneuvering_jets/deactivate()
if(!..())
return 0
jets.turn_off()
return 1
/obj/item/rig_module/maneuvering_jets/New()
..()
jets = new(src)
/obj/item/rig_module/maneuvering_jets/installed()
..()
jets.holder = holder
jets.ion_trail.set_up(holder)
/obj/item/rig_module/maneuvering_jets/removed()
..()
jets.holder = null
jets.ion_trail.set_up(jets)
/obj/item/rig_module/foam_sprayer
/obj/item/rig_module/device/paperdispenser
name = "hardsuit paper dispenser"
desc = "Crisp sheets."
icon_state = "paper"
interface_name = "paper dispenser"
interface_desc = "Dispenses warm, clean, and crisp sheets of paper."
engage_string = "Dispense"
usable = 1
selectable = 0
device_type = /obj/item/paper_bin
/obj/item/rig_module/device/paperdispenser/engage(atom/target)
if(!..() || !device)
return 0
if(!target)
device.attack_hand(holder.wearer)
return 1
/obj/item/rig_module/device/pen
name = "mounted pen"
desc = "For mecha John Hancocks."
icon_state = "pen"
interface_name = "mounted pen"
interface_desc = "Signatures with style(tm)."
engage_string = "Change color"
usable = 1
device_type = /obj/item/pen/multi
/obj/item/rig_module/device/stamp
name = "mounted internal affairs stamp"
desc = "DENIED."
icon_state = "stamp"
interface_name = "mounted stamp"
interface_desc = "Leave your mark."
engage_string = "Toggle stamp type"
usable = 1
var/obj/iastamp //Theese were just vars, but any device would need to be an object
var/obj/deniedstamp //Stops assigning non-objects to theese vars, which probably would break quite a bit.
/obj/item/rig_module/device/stamp/New()
..()
iastamp = new /obj/item/stamp/law(src)
deniedstamp = new /obj/item/stamp/denied(src)
iastamp.flags |= ABSTRACT
deniedstamp.flags |= ABSTRACT
device = iastamp
/obj/item/rig_module/device/stamp/engage(atom/target)
if(!..() || !device)
return 0
if(!target)
if(device == iastamp)
device = deniedstamp
to_chat(holder.wearer, "<span class='notice'>Switched to denied stamp.</span>")
else if(device == deniedstamp)
device = iastamp
to_chat(holder.wearer, "<span class='notice'>Switched to internal affairs stamp.</span>")
return 1
/obj/item/rig_module/welding_tank
name = "welding fuel tank"
desc = "A bluespace welding fuel storage tank for a rigsuit."
icon_state = "welding_tank"
interface_name = "mounted welding fuel tank"
interface_desc = "A minitaure fuel tank used for storage of welding fuel, built into a hardsuit."
engage_string = "Dispense fuel"
usable = 1
var/max_fuel = 300
/obj/item/rig_module/welding_tank/New()
..()
create_reagents(max_fuel)
reagents.add_reagent("fuel", max_fuel)
/obj/item/rig_module/welding_tank/engage(atom/target)
if(!..() || !reagents)
return 0
if(!target)
if(get_fuel() >= 0)
var/obj/item/weldingtool/W = holder.wearer.get_active_hand()
if(istype(W))
fill_welder(W)
else
W = holder.wearer.get_inactive_hand()
if(istype(W))
fill_welder(W)
else
to_chat(holder.wearer, "<span class='danger'>Your welding tank is out of fuel!</span>")
else
to_chat(holder.wearer, "<span class='notice'>You need to have a welding tool in one of your hands to dispense fuel.</span>")
/obj/item/rig_module/welding_tank/proc/fill_welder(obj/item/weldingtool/W)
if(!istype(W))
return
W.refill(holder.wearer, src, W.maximum_fuel)
if(!reagents.get_reagent_amount("fuel"))
to_chat(holder.wearer, "<span class='notice'>You hear a faint dripping as your hardsuit welding tank completely empties.</span>")
/obj/item/rig_module/welding_tank/proc/get_fuel()
return reagents.get_reagent_amount("fuel")
@@ -1,191 +0,0 @@
/*
* Contains
* /obj/item/rig_module/vision
* /obj/item/rig_module/vision/multi
* /obj/item/rig_module/vision/meson
* /obj/item/rig_module/vision/thermal
* /obj/item/rig_module/vision/nvg
* /obj/item/rig_module/vision/medhud
* /obj/item/rig_module/vision/sechud
*/
/datum/rig_vision
var/mode
var/obj/item/clothing/glasses/glasses
/datum/rig_vision/nvg
mode = "night vision"
/datum/rig_vision/nvg/New()
glasses = new /obj/item/clothing/glasses/night
/datum/rig_vision/thermal
mode = "thermal scanner"
/datum/rig_vision/thermal/New()
glasses = new /obj/item/clothing/glasses/thermal
/datum/rig_vision/meson
mode = "meson scanner"
/datum/rig_vision/meson/New()
glasses = new /obj/item/clothing/glasses/meson
/datum/rig_vision/sechud
mode = "security HUD"
/datum/rig_vision/sechud/New()
glasses = new /obj/item/clothing/glasses/hud/security
/datum/rig_vision/medhud
mode = "medical HUD"
/datum/rig_vision/medhud/New()
glasses = new /obj/item/clothing/glasses/hud/health
/obj/item/rig_module/vision
name = "hardsuit visor"
desc = "A layered, translucent visor system for a hardsuit."
icon_state = "optics"
interface_name = "optical scanners"
interface_desc = "An integrated multi-mode vision system."
usable = 1
toggleable = 1
disruptive = 0
engage_string = "Cycle Visor Mode"
activate_string = "Enable Visor"
deactivate_string = "Disable Visor"
var/datum/rig_vision/vision
var/list/vision_modes = list(
/datum/rig_vision/nvg,
/datum/rig_vision/thermal,
/datum/rig_vision/meson
)
var/vision_index
/obj/item/rig_module/vision/multi
name = "hardsuit optical package"
desc = "A complete visor system of optical scanners and vision modes."
icon_state = "fulloptics"
interface_name = "multi optical visor"
interface_desc = "An integrated multi-mode vision system."
vision_modes = list(/datum/rig_vision/meson,
/datum/rig_vision/nvg,
/datum/rig_vision/thermal,
/datum/rig_vision/sechud,
/datum/rig_vision/medhud)
/obj/item/rig_module/vision/meson
name = "hardsuit meson scanner"
desc = "A layered, translucent visor system for a hardsuit."
icon_state = "meson"
usable = 0
interface_name = "meson scanner"
interface_desc = "An integrated meson scanner."
vision_modes = list(/datum/rig_vision/meson)
/obj/item/rig_module/vision/thermal
name = "hardsuit thermal scanner"
desc = "A layered, translucent visor system for a hardsuit."
icon_state = "thermal"
usable = 0
interface_name = "thermal scanner"
interface_desc = "An integrated thermal scanner."
vision_modes = list(/datum/rig_vision/thermal)
/obj/item/rig_module/vision/nvg
name = "hardsuit night vision interface"
desc = "A multi input night vision system for a hardsuit."
icon_state = "night"
usable = 0
interface_name = "night vision interface"
interface_desc = "An integrated night vision system."
vision_modes = list(/datum/rig_vision/nvg)
/obj/item/rig_module/vision/sechud
name = "hardsuit security hud"
desc = "A simple tactical information system for a hardsuit."
icon_state = "securityhud"
usable = 0
interface_name = "security HUD"
interface_desc = "An integrated security heads up display."
vision_modes = list(/datum/rig_vision/sechud)
/obj/item/rig_module/vision/medhud
name = "hardsuit medical hud"
desc = "A simple medical status indicator for a hardsuit."
icon_state = "healthhud"
usable = 0
interface_name = "medical HUD"
interface_desc = "An integrated medical heads up display."
vision_modes = list(/datum/rig_vision/medhud)
// There should only ever be one vision module installed in a suit.
/obj/item/rig_module/vision/installed()
..()
holder.visor = src
/obj/item/rig_module/vision/engage()
var/starting_up = !active
if(!..() || !vision_modes)
return 0
// Don't cycle if this engage() is being called by activate().
if(starting_up)
to_chat(holder.wearer, "<font color='blue'>You activate your visual sensors.</font>")
return 1
if(vision_modes.len > 1)
vision_index++
if(vision_index > vision_modes.len)
vision_index = 1
vision = vision_modes[vision_index]
to_chat(holder.wearer, "<font color='blue'>You cycle your sensors to <b>[vision.mode]</b> mode.</font>")
else
to_chat(holder.wearer, "<font color='blue'>Your sensors only have one mode.</font>")
return 1
/obj/item/rig_module/vision/New()
..()
if(!vision_modes)
return
vision_index = 1
var/list/processed_vision = list()
for(var/vision_mode in vision_modes)
var/datum/rig_vision/vision_datum = new vision_mode
if(!vision) vision = vision_datum
processed_vision += vision_datum
vision_modes = processed_vision
File diff suppressed because it is too large Load Diff
@@ -1,30 +0,0 @@
/obj/item/clothing/suit/space/new_rig/calc_breach_damage()
..()
holder.update_armor() //New dammage, new armormultiplikator.
return damage
/obj/item/rig/proc/update_armor()
var/multi = 1 //Multiplicative modification to the armor, maybe add an additive later on
if(chest)
multi *= (100 - chest.damage) / 100 //If we have some breaches, lower the armor value.
//TODO check for other armor mods, likely modules, which need to be coded.
if(!armor) //Did we even give them some armor, if this is the case, the list should be initialized from New()
return
var/datum/armor/A = armor
for(var/obj/item/piece in list(gloves, helmet, boots, chest))
if(!istype(piece)) //Do we have the piece
continue
piece.armor = piece.armor.setRating(melee_value = A.getRating("melee") * multi,
bullet_value = A.getRating("bullet") * multi,
laser_value = A.getRating("laser") * multi,
energy_value = A.getRating("energy") * multi,
bomb_value = A.getRating("bomb") * multi,
bio_value = A.getRating("bio") * multi,
rad_value = A.getRating("rad") * multi,
fire_value = A.getRating("fire") * multi,
acid_value = A.getRating("acidd") * multi)
//Perfect place to also add something like shield modules, or any other hit_reaction modules check.
@@ -1,196 +0,0 @@
/obj/item/rig/attackby(obj/item/W as obj, mob/user as mob)
if(!istype(user,/mob/living)) return 0
if(electrified != 0)
if(shock(user)) //Handles removing charge from the cell, as well. No need to do that here.
return
// Pass repair items on to the chestpiece.
if(chest && (istype(W,/obj/item/stack) || istype(W, /obj/item/weldingtool)))
return chest.attackby(W,user)
// Lock or unlock the access panel.
if(W.GetID())
if(subverted)
locked = 0
to_chat(user, "<span class='danger'>It looks like the locking system has been shorted out.</span>")
return
if((!req_access || !req_access.len) && (!req_one_access || !req_one_access.len))
locked = 0
to_chat(user, "<span class='danger'>\The [src] doesn't seem to have a locking mechanism.</span>")
return
if(security_check_enabled && !src.allowed(user))
to_chat(user, "<span class='danger'>Access denied.</span>")
return
locked = !locked
to_chat(user, "You [locked ? "lock" : "unlock"] \the [src] access panel.")
return
else if(istype(W,/obj/item/crowbar))
if(!open && locked)
to_chat(user, "The access panel is locked shut.")
return
open = !open
to_chat(user, "You [open ? "open" : "close"] the access panel.")
return
if(open)
// Hacking.
if(istype(W,/obj/item/wirecutters) || istype(W,/obj/item/multitool))
if(open)
wires.Interact(user)
else
to_chat(user, "You can't reach the wiring.")
return
// Air tank.
if(istype(W,/obj/item/tank)) //Todo, some kind of check for suits without integrated air supplies.
if(air_supply)
to_chat(user, "\The [src] already has a tank installed.")
return
user.unEquip(W)
air_supply = W
W.forceMove(src)
to_chat(user, "You slot [W] into [src] and tighten the connecting valve.")
return
// Check if this is a hardsuit upgrade or a modification.
else if(istype(W,/obj/item/rig_module))
if(istype(src.loc,/mob/living/carbon/human))
var/mob/living/carbon/human/H = src.loc
if(H.back == src)
to_chat(user, "<span class='danger'>You can't install a hardsuit module while the suit is being worn.</span>")
return 1
if(!installed_modules) installed_modules = list()
if(installed_modules.len)
for(var/obj/item/rig_module/installed_mod in installed_modules)
if(!installed_mod.redundant && istype(installed_mod,W))
to_chat(user, "The hardsuit already has a module of that class installed.")
return 1
var/obj/item/rig_module/mod = W
to_chat(user, "You begin installing \the [mod] into \the [src].")
if(!do_after(user, 40 * W.toolspeed, target = src))
return
if(!user || !W)
return
to_chat(user, "You install \the [mod] into \the [src].")
user.unEquip(mod)
installed_modules |= mod
mod.forceMove(src)
mod.installed(src)
update_icon()
return 1
else if(!cell && istype(W,/obj/item/stock_parts/cell))
to_chat(user, "You jack \the [W] into \the [src]'s battery mount.")
user.unEquip(W)
W.forceMove(src)
src.cell = W
return
else if(istype(W,/obj/item/wrench))
if(!air_supply)
to_chat(user, "There is not tank to remove.")
return
if(user.r_hand && user.l_hand)
air_supply.forceMove(get_turf(user))
else
user.put_in_hands(air_supply)
to_chat(user, "You detach and remove \the [air_supply].")
air_supply = null
return
else if(istype(W,/obj/item/screwdriver))
var/list/current_mounts = list()
if(cell) current_mounts += "cell"
if(installed_modules && installed_modules.len) current_mounts += "system module"
var/to_remove = input("Which would you like to modify?") as null|anything in current_mounts
if(!to_remove)
return
if(istype(src.loc,/mob/living/carbon/human) && to_remove != "cell")
var/mob/living/carbon/human/H = src.loc
if(H.back == src)
to_chat(user, "You can't remove an installed device while the hardsuit is being worn.")
return
switch(to_remove)
if("cell")
if(cell)
to_chat(user, "You detatch \the [cell] from \the [src]'s battery mount.")
for(var/obj/item/rig_module/module in installed_modules)
module.deactivate()
if(user.r_hand && user.l_hand)
cell.forceMove(get_turf(user))
else
user.put_in_hands(cell)
cell = null
else
to_chat(user, "There is nothing loaded in that mount.")
if("system module")
var/list/possible_removals = list()
for(var/obj/item/rig_module/module in installed_modules)
if(module.permanent)
continue
possible_removals[module.name] = module
if(!possible_removals.len)
to_chat(user, "There are no installed modules to remove.")
return
var/removal_choice = input("Which module would you like to remove?") as null|anything in possible_removals
if(!removal_choice)
return
var/obj/item/rig_module/removed = possible_removals[removal_choice]
to_chat(user, "You detatch \the [removed] from \the [src].")
removed.forceMove(get_turf(src))
removed.removed()
installed_modules -= removed
update_icon()
return
// If we've gotten this far, all we have left to do before we pass off to root procs
// is check if any of the loaded modules want to use the item we've been given.
for(var/obj/item/rig_module/module in installed_modules)
if(module.accepts_item(W,user)) //Item is handled in this proc
return
..()
/obj/item/rig/attack_hand(var/mob/user)
if(electrified != 0)
if(shock(user)) //Handles removing charge from the cell, as well. No need to do that here.
return
..()
/obj/item/rig/emag_act(var/remaining_charges, var/mob/user)
if(!subverted)
req_access.Cut()
req_one_access.Cut()
locked = 0
subverted = 1
to_chat(user, "<span class='danger'>You short out the access protocol for the suit.</span>")
return 1
@@ -1,147 +0,0 @@
/*
* Defines the helmets, gloves and shoes for rigs.
*/
/obj/item/clothing/head/helmet/space/new_rig
name = "helmet"
flags = BLOCKHAIR | THICKMATERIAL | NODROP
flags_inv = HIDEEARS|HIDEEYES|HIDEFACE|HIDEMASK
body_parts_covered = HEAD
heat_protection = HEAD
cold_protection = HEAD
var/brightness_on = 4
var/on = 0
sprite_sheets = list(
"Tajaran" = 'icons/mob/species/tajaran/helmet.dmi',
"Skrell" = 'icons/mob/species/skrell/helmet.dmi',
"Unathi" = 'icons/mob/species/unathi/helmet.dmi'
)
species_restricted = null
actions_types = list(/datum/action/item_action/toggle_helmet_light)
flash_protect = 2
/obj/item/clothing/head/helmet/space/new_rig/attack_self(mob/user)
if(!isturf(user.loc))
to_chat(user, "<span class='warning'>You cannot turn the light on while in this [user.loc].</span>")//To prevent some lighting anomalities.
return
toggle_light(user)
/obj/item/clothing/head/helmet/space/new_rig/proc/toggle_light(mob/user)
if(flags & AIRTIGHT) //Could also check for STOPSPRESSUREDMAGE, but one is enough, both get toggled when the seal gets toggled.
on = !on
icon_state = "[item_color][on]"
if(on)
set_light(brightness_on)
else
set_light(0)
else
to_chat(user, "<span class='warning'>You cannot turn the light on while the suit isn't sealed.</span>")
if(istype(user,/mob/living/carbon/human))
var/mob/living/carbon/human/H = user
H.update_inv_head()
/obj/item/clothing/gloves/rig
name = "gauntlets"
flags = THICKMATERIAL | NODROP
body_parts_covered = HANDS
heat_protection = HANDS
cold_protection = HANDS
species_restricted = null
gender = PLURAL
/obj/item/clothing/shoes/magboots/rig
name = "boots"
flags = NODROP
body_parts_covered = FEET
cold_protection = FEET
heat_protection = FEET
species_restricted = null
gender = PLURAL
/obj/item/clothing/shoes/magboots/rig/attack_self(mob/user)
if(flags & AIRTIGHT) //Could also check for STOPSPRESSUREDMAGE, but one is enough, both get toggled when the seal gets toggled.
..(user)
else
to_chat(user, "<span class='warning'>You cannot activate mag-pulse traction system while the suit is not sealed.</span>")
/obj/item/clothing/suit/space/new_rig
name = "chestpiece"
allowed = list(/obj/item/flashlight,/obj/item/tank)
body_parts_covered = UPPER_TORSO|LOWER_TORSO|LEGS|ARMS
heat_protection = UPPER_TORSO|LOWER_TORSO|LEGS|ARMS
cold_protection = UPPER_TORSO|LOWER_TORSO|LEGS|ARMS
flags_inv = HIDEJUMPSUIT|HIDETAIL
flags = STOPSPRESSUREDMAGE | THICKMATERIAL | AIRTIGHT | NODROP
slowdown = 0
breach_threshold = 20
resilience = 0.2
can_breach = 1
var/obj/item/rig/holder
sprite_sheets = list(
"Tajaran" = 'icons/mob/species/tajaran/suit.dmi',
"Unathi" = 'icons/mob/species/unathi/suit.dmi'
)
//TODO: move this to modules
/obj/item/clothing/head/helmet/space/new_rig/proc/prevent_track()
return 0
/obj/item/clothing/gloves/rig/Touch(var/atom/A, var/proximity)
if(!A || !proximity)
return 0
var/mob/living/carbon/human/H = loc
if(!istype(H) || !H.back)
return 0
var/obj/item/rig/suit = H.back
if(!suit || !istype(suit) || !suit.installed_modules.len)
return 0
for(var/obj/item/rig_module/module in suit.installed_modules)
if(module.active && module.activates_on_touch)
if(module.engage(A))
return 1
return 0
//Rig pieces for non-spacesuit based rigs
/obj/item/clothing/head/lightrig
name = "mask"
body_parts_covered = HEAD
heat_protection = HEAD
cold_protection = HEAD
flags = THICKMATERIAL|AIRTIGHT
/obj/item/clothing/suit/lightrig
name = "suit"
allowed = list(/obj/item/flashlight)
body_parts_covered = UPPER_TORSO|LOWER_TORSO|LEGS|ARMS
heat_protection = UPPER_TORSO|LOWER_TORSO|LEGS|ARMS
cold_protection = UPPER_TORSO|LOWER_TORSO|LEGS|ARMS
flags_inv = HIDEJUMPSUIT
flags = THICKMATERIAL
/obj/item/clothing/shoes/lightrig
name = "boots"
body_parts_covered = FEET
cold_protection = FEET
heat_protection = FEET
species_restricted = null
gender = PLURAL
/obj/item/clothing/gloves/lightrig
name = "gloves"
flags = THICKMATERIAL
body_parts_covered = HANDS
heat_protection = HANDS
cold_protection = HANDS
species_restricted = null
gender = PLURAL
@@ -1,335 +0,0 @@
// Interface for humans.
/obj/item/rig/verb/hardsuit_interface()
set name = "Open Hardsuit Interface"
set desc = "Open the hardsuit system interface."
set category = "Hardsuit"
set src = usr.contents
if(wearer && wearer.back == src)
ui_interact(usr)
/obj/item/rig/verb/toggle_vision()
set name = "Toggle Visor"
set desc = "Turns your rig visor off or on."
set category = "Hardsuit"
set src = usr.contents
if(!istype(wearer) || !wearer.back == src)
to_chat(usr, "<span class='warning'>The hardsuit is not being worn.</span>")
return
if(!check_power_cost(usr))
return
if(!(flags & NODROP))
to_chat(usr, "<span class='warning'>The suit is not active.</span>")
return
if(!check_suit_access(usr))
return
if(!visor)
to_chat(usr, "<span class='warning'>The hardsuit does not have a configurable visor.</span>")
return
var/mob/M = usr
if(M.incapacitated())
return
if(!visor.active)
visor.activate()
else
visor.deactivate()
/obj/item/rig/proc/toggle_helmet()
set name = "Toggle Helmet"
set desc = "Deploys or retracts your helmet."
set category = "Hardsuit"
set src = usr.contents
if(!istype(wearer) || !wearer.back == src)
to_chat(usr, "<span class='warning'>The hardsuit is not being worn.</span>")
return
if(!check_suit_access(usr))
return
var/mob/M = usr
if(M.incapacitated())
return
toggle_piece("helmet", usr)
/obj/item/rig/proc/toggle_chest()
set name = "Toggle Chestpiece"
set desc = "Deploys or retracts your chestpiece."
set category = "Hardsuit"
set src = usr.contents
if(!check_suit_access(usr))
return
var/mob/M = usr
if(M.incapacitated())
return
toggle_piece("chest", usr)
/obj/item/rig/proc/toggle_gauntlets()
set name = "Toggle Gauntlets"
set desc = "Deploys or retracts your gauntlets."
set category = "Hardsuit"
set src = usr.contents
if(!istype(wearer) || !wearer.back == src)
to_chat(usr, "<span class='warning'>The hardsuit is not being worn.</span>")
return
if(!check_suit_access(usr))
return
var/mob/M = usr
if(M.incapacitated())
return
toggle_piece("gauntlets", usr)
/obj/item/rig/proc/toggle_boots()
set name = "Toggle Boots"
set desc = "Deploys or retracts your boots."
set category = "Hardsuit"
set src = usr.contents
if(!istype(wearer) || !wearer.back == src)
to_chat(usr, "<span class='warning'>The hardsuit is not being worn.</span>")
return
if(!check_suit_access(usr))
return
var/mob/M = usr
if(M.incapacitated())
return
toggle_piece("boots", usr)
/obj/item/rig/verb/deploy_suit()
set name = "Deploy Hardsuit"
set desc = "Deploys helmet, gloves and boots all at once."
set category = "Hardsuit"
set src = usr.contents
if(!istype(wearer) || !wearer.back == src)
to_chat(usr, "<span class='warning'>The hardsuit is not being worn.</span>")
return
if(!check_suit_access(usr))
return
if(!check_power_cost(usr))
return
var/mob/M = usr
if(M.incapacitated())
return
deploy(wearer, usr)
/obj/item/rig/verb/toggle_seals_verb()
set name = "Toggle Hardsuit Seals"
set desc = "Seals or unseals your rig."
set category = "Hardsuit"
set src = usr.contents
if(!istype(wearer) || !wearer.back == src)
to_chat(usr, "<span class='warning'>The hardsuit is not being worn.</span>")
return
if(!check_suit_access(usr))
return
var/mob/M = usr
if(M.incapacitated())
return
if(flags & NODROP)
unseal(usr)
else
seal(usr)
/obj/item/rig/verb/switch_vision_mode()
set name = "Switch Vision Mode"
set desc = "Switches between available vision modes."
set category = "Hardsuit"
set src = usr.contents
if(malfunction_check(usr))
return
if(!check_power_cost(usr, 0, 0, 0, 0))
return
if(!(flags & NODROP))
to_chat(usr, "<span class='warning'>The suit is not active.</span>")
return
if(!visor)
to_chat(usr, "<span class='warning'>The hardsuit does not have a configurable visor.</span>")
return
var/mob/M = usr
if(M.incapacitated())
return
if(!visor.active)
visor.activate()
if(!visor.active)
to_chat(usr, "<span class='warning'>The visor is suffering a hardware fault and cannot be configured.</span>")
return
visor.engage()
/obj/item/rig/verb/alter_voice()
set name = "Configure Voice Synthesiser"
set desc = "Toggles or configures your voice synthesizer."
set category = "Hardsuit"
set src = usr.contents
if(malfunction_check(usr))
return
if(!(flags & NODROP))
to_chat(usr, "<span class='warning'>The suit is not active.</span>")
return
if(!istype(wearer) || !wearer.back == src)
to_chat(usr, "<span class='warning'>The hardsuit is not being worn.</span>")
return
if(!speech)
to_chat(usr, "<span class='warning'>The hardsuit does not have a speech synthesiser.</span>")
return
var/mob/M = usr
if(M.incapacitated())
return
speech.engage()
/obj/item/rig/verb/select_module()
set name = "Select Module"
set desc = "Selects a module as your primary system."
set category = "Hardsuit"
set src = usr.contents
if(malfunction_check(usr))
return
if(!check_power_cost(usr, 0, 0, 0, 0))
return
if(!(flags & NODROP))
to_chat(usr, "<span class='warning'>The suit is not active.</span>")
return
if(!istype(wearer) || !wearer.back == src)
to_chat(usr, "<span class='warning'>The hardsuit is not being worn.</span>")
return
var/mob/M = usr
if(M.incapacitated())
return
var/list/selectable = list()
for(var/obj/item/rig_module/module in installed_modules)
if(module.selectable)
selectable |= module
var/obj/item/rig_module/module = input("Which module do you wish to select?") as null|anything in selectable
if(!istype(module))
selected_module = null
to_chat(usr, "<font color='blue'><b>Primary system is now: deselected.</b></font>")
return
selected_module = module
to_chat(usr, "<font color='blue'><b>Primary system is now: [selected_module.interface_name].</b></font>")
/obj/item/rig/verb/toggle_module()
set name = "Toggle Module"
set desc = "Toggle a system module."
set category = "Hardsuit"
set src = usr.contents
if(malfunction_check(usr))
return
if(!check_power_cost(usr, 0, 0, 0, 0))
return
if(!(flags & NODROP))
to_chat(usr, "<span class='warning'>The suit is not active.</span>")
return
if(!istype(wearer) || !wearer.back == src)
to_chat(usr, "<span class='warning'>The hardsuit is not being worn.</span>")
return
var/mob/M = usr
if(M.incapacitated())
return
var/list/selectable = list()
for(var/obj/item/rig_module/module in installed_modules)
if(module.toggleable)
selectable |= module
var/obj/item/rig_module/module = input("Which module do you wish to toggle?") as null|anything in selectable
if(!istype(module))
return
if(module.active)
to_chat(usr, "<font color='blue'><b>You attempt to deactivate \the [module.interface_name].</b></font>")
module.deactivate()
else
to_chat(usr, "<font color='blue'><b>You attempt to activate \the [module.interface_name].</b></font>")
module.activate()
/obj/item/rig/verb/engage_module()
set name = "Engage Module"
set desc = "Engages a system module."
set category = "Hardsuit"
set src = usr.contents
if(malfunction_check(usr))
return
if(!(flags & NODROP))
to_chat(usr, "<span class='warning'>The suit is not active.</span>")
return
if(!istype(wearer) || !wearer.back == src)
to_chat(usr, "<span class='warning'>The hardsuit is not being worn.</span>")
return
if(!check_power_cost(usr, 0, 0, 0, 0))
return
var/mob/M = usr
if(M.incapacitated())
return
var/list/selectable = list()
for(var/obj/item/rig_module/module in installed_modules)
if(module.usable)
selectable |= module
var/obj/item/rig_module/module = input("Which module do you wish to engage?") as null|anything in selectable
if(!istype(module))
return
to_chat(usr, "<font color='blue'><b>You attempt to engage the [module.interface_name].</b></font>")
module.engage()
@@ -1,70 +0,0 @@
/datum/wires/rig
random = 1
holder_type = /obj/item/rig
wire_count = 5
#define RIG_SECURITY 1
#define RIG_AI_OVERRIDE 2
#define RIG_SYSTEM_CONTROL 4
#define RIG_INTERFACE_LOCK 8
#define RIG_INTERFACE_SHOCK 16
/*
* Rig security can be snipped to disable ID access checks on rig.
* Rig AI override can be pulsed to toggle whether or not the AI can take control of the suit.
* System control can be pulsed to toggle some malfunctions.
* Interface lock can be pulsed to toggle whether or not the interface can be accessed.
*/
/datum/wires/rig/UpdateCut(var/index, var/mended)
var/obj/item/rig/rig = holder
switch(index)
if(RIG_SECURITY)
if(mended)
rig.req_access = initial(rig.req_access)
rig.req_one_access = initial(rig.req_one_access)
if(RIG_INTERFACE_SHOCK)
rig.electrified = mended ? 0 : -1
rig.shock(usr,100)
/datum/wires/rig/UpdatePulsed(var/index)
var/obj/item/rig/rig = holder
switch(index)
if(RIG_SECURITY)
rig.security_check_enabled = !rig.security_check_enabled
rig.visible_message("\The [rig] twitches as several suit locks [rig.security_check_enabled?"close":"open"].")
if(RIG_AI_OVERRIDE)
rig.ai_override_enabled = !rig.ai_override_enabled
rig.visible_message("A small red light on [rig] [rig.ai_override_enabled?"goes dead":"flickers on"].")
if(RIG_SYSTEM_CONTROL)
rig.malfunctioning += 10
if(rig.malfunction_delay <= 0)
rig.malfunction_delay = 20
rig.shock(usr,100)
if(RIG_INTERFACE_LOCK)
rig.interface_locked = !rig.interface_locked
rig.visible_message("\The [rig] clicks audibly as the software interface [rig.interface_locked?"darkens":"brightens"].")
if(RIG_INTERFACE_SHOCK)
if(rig.electrified != -1)
rig.electrified = 30
rig.shock(usr,100)
/datum/wires/rig/GetWireName(index)
switch(index)
if(RIG_SECURITY)
return "ID check"
if(RIG_AI_OVERRIDE)
return "AI control"
if(RIG_SYSTEM_CONTROL)
return "System control"
if(RIG_INTERFACE_LOCK)
return "Interface lock"
if(RIG_INTERFACE_SHOCK)
return "Electrification"
/datum/wires/rig/CanUse(var/mob/living/L)
var/obj/item/rig/rig = holder
if(rig.open)
return 1
return 0
@@ -1,46 +0,0 @@
/obj/item/rig/unathi
name = "NT breacher chassis control module"
desc = "A cheap NT knock-off of an Unathi battle-rig. Looks like a fish, moves like a fish, steers like a cow."
suit_type = "NT breacher"
icon_state = "breacher_rig_cheap"
armor = list(melee = 30, bullet = 30, laser = 30, energy = 30, bomb = 45, bio = 100, rad = 50)
emp_protection = -20
active_slowdown = 6
offline_slowdown = 10
vision_restriction = 1
offline_vision_restriction = 2
chest_type = /obj/item/clothing/suit/space/new_rig/unathi
helm_type = /obj/item/clothing/head/helmet/space/new_rig/unathi
glove_type = /obj/item/clothing/gloves/rig/unathi
boot_type = /obj/item/clothing/shoes/magboots/rig/unathi
/obj/item/rig/unathi/fancy
name = "breacher chassis control module"
desc = "An authentic Unathi breacher chassis. Huge, bulky and absurdly heavy. It must be like wearing a tank."
suit_type = "breacher chassis"
icon_state = "breacher_rig"
armor = list(melee = 45, bullet = 45, laser = 45, energy = 45, bomb = 45, bio = 100, rad = 75) //Takes TEN TIMES as much damage to stop someone in a breacher. In exchange, it's slow. //Whoever made this was on meth
vision_restriction = 0
/obj/item/clothing/head/helmet/space/new_rig/unathi
icon = 'icons/obj/clothing/species/unathi/hats.dmi'
species_restricted = list("Unathi")
/obj/item/clothing/suit/space/new_rig/unathi
icon = 'icons/obj/clothing/species/unathi/suits.dmi'
species_restricted = list("Unathi")
/obj/item/clothing/gloves/rig/unathi
icon = 'icons/obj/clothing/species/unathi/gloves.dmi'
species_restricted = list("Unathi")
sprite_sheets = list(
"Unathi" = 'icons/mob/species/unathi/gloves.dmi'
)
/obj/item/clothing/shoes/magboots/rig/unathi
icon = 'icons/obj/clothing/species/unathi/shoes.dmi'
species_restricted = list("Unathi")
sprite_sheets = list(
"Unathi" = 'icons/mob/species/unathi/feet.dmi'
)
@@ -1,28 +0,0 @@
/obj/item/clothing/head/helmet/space/new_rig/combat
/obj/item/rig/combat
name = "combat hardsuit control module"
desc = "A sleek and dangerous hardsuit for active combat."
icon_state = "security_rig"
suit_type = "combat hardsuit"
armor = list(melee = 80, bullet = 80, laser = 50, energy = 50, bomb = 100, bio = 100, rad = 100)
active_slowdown = 1
offline_slowdown = 3
offline_vision_restriction = 1
helm_type = /obj/item/clothing/head/helmet/space/new_rig/combat
allowed = list(/obj/item/gun,/obj/item/flashlight,/obj/item/tank,/obj/item/melee/baton)
/obj/item/rig/combat/equipped
initial_modules = list(
/obj/item/rig_module/mounted,
/obj/item/rig_module/vision/thermal,
/obj/item/rig_module/grenade_launcher,
/obj/item/rig_module/ai_container,
// /obj/item/rig_module/power_sink,
/obj/item/rig_module/electrowarfare_suite,
/obj/item/rig_module/chem_dispenser/combat
)
@@ -1,81 +0,0 @@
/obj/item/clothing/head/helmet/space/new_rig/ert
/obj/item/rig/ert
name = "ERT-C hardsuit control module"
desc = "A suit worn by the commander of an Emergency Response Team. Has blue highlights. Armoured and space ready."
suit_type = "ERT commander"
icon_state = "ert_commander_rig"
helm_type = /obj/item/clothing/head/helmet/space/new_rig/ert
req_access = list(ACCESS_CENT_SPECOPS)
armor = list(melee = 45, bullet = 25, laser = 30, energy = 10, bomb = 25, bio = 100, rad = 50)
allowed = list(/obj/item/flashlight, /obj/item/tank, /obj/item/t_scanner, /obj/item/rcd, /obj/item/crowbar, \
/obj/item/screwdriver, /obj/item/weldingtool, /obj/item/wirecutters, /obj/item/wrench, /obj/item/multitool, \
/obj/item/radio, /obj/item/analyzer,/obj/item/storage/briefcase/inflatable, /obj/item/melee/baton, /obj/item/gun, \
/obj/item/storage/firstaid, /obj/item/reagent_containers/hypospray, /obj/item/roller)
initial_modules = list(
/obj/item/rig_module/ai_container,
/obj/item/rig_module/maneuvering_jets,
/obj/item/rig_module/datajack,
)
/obj/item/rig/ert/engineer
name = "ERT-E suit control module"
desc = "A suit worn by the engineering division of an Emergency Response Team. Has orange highlights. Armoured and space ready."
suit_type = "ERT engineer"
icon_state = "ert_engineer_rig"
siemens_coefficient = 0
initial_modules = list(
/obj/item/rig_module/ai_container,
/obj/item/rig_module/maneuvering_jets,
/obj/item/rig_module/device/plasmacutter,
// /obj/item/rig_module/device/rcd
)
/obj/item/rig/ert/medical
name = "ERT-M suit control module"
desc = "A suit worn by the medical division of an Emergency Response Team. Has white highlights. Armoured and space ready."
suit_type = "ERT medic"
icon_state = "ert_medical_rig"
initial_modules = list(
/obj/item/rig_module/ai_container,
/obj/item/rig_module/maneuvering_jets,
/obj/item/rig_module/device/healthscanner,
/obj/item/rig_module/chem_dispenser/injector
)
/obj/item/rig/ert/security
name = "ERT-S suit control module"
desc = "A suit worn by the security division of an Emergency Response Team. Has red highlights. Armoured and space ready."
suit_type = "ERT security"
icon_state = "ert_security_rig"
initial_modules = list(
/obj/item/rig_module/ai_container,
/obj/item/rig_module/maneuvering_jets,
/obj/item/rig_module/grenade_launcher,
/obj/item/rig_module/mounted/egun,
)
/obj/item/rig/ert/assetprotection
name = "Heavy Asset Protection suit control module"
desc = "A heavy suit worn by the highest level of Asset Protection, don't mess with the person wearing this. Armoured and space ready."
suit_type = "heavy asset protection"
icon_state = "asset_protection_rig"
initial_modules = list(
/obj/item/rig_module/ai_container,
/obj/item/rig_module/maneuvering_jets,
/obj/item/rig_module/grenade_launcher,
/obj/item/rig_module/vision/multi,
/obj/item/rig_module/mounted/egun,
/obj/item/rig_module/chem_dispenser/injector,
/obj/item/rig_module/device/plasmacutter,
// /obj/item/rig_module/device/rcd,
/obj/item/rig_module/datajack
)
@@ -1,120 +0,0 @@
// Light rigs are not space-capable, but don't suffer excessive slowdown or sight issues when depowered.
/obj/item/rig/light
name = "light suit control module"
desc = "A lighter, less armoured rig suit."
icon_state = "ninja_rig"
suit_type = "light suit"
allowed = list(/obj/item/gun,/obj/item/ammo_casing,/obj/item/melee/baton,/obj/item/restraints/handcuffs,/obj/item/tank,/obj/item/stock_parts/cell)
emp_protection = 10
active_slowdown = 0
flags = STOPSPRESSUREDMAGE | THICKMATERIAL
offline_slowdown = 0
offline_vision_restriction = 0
chest_type = /obj/item/clothing/suit/space/new_rig/light
helm_type = /obj/item/clothing/head/helmet/space/new_rig/light
boot_type = /obj/item/clothing/shoes/magboots/rig/light
glove_type = /obj/item/clothing/gloves/rig/light
/obj/item/clothing/suit/space/new_rig/light
name = "suit"
breach_threshold = 18 //comparable to voidsuits
/obj/item/clothing/gloves/rig/light
name = "gloves"
/obj/item/clothing/shoes/magboots/rig/light
name = "shoes"
/obj/item/clothing/head/helmet/space/new_rig/light
name = "hood"
/obj/item/rig/light/hacker
name = "cybersuit control module"
suit_type = "cyber"
desc = "An advanced powered armour suit with many cyberwarfare enhancements. Comes with built-in insulated gloves for safely tampering with electronics."
icon_state = "hacker_rig"
req_access = list(ACCESS_SYNDICATE)
airtight = 0
seal_delay = 5 //not being vaccum-proof has an upside I guess
helm_type = /obj/item/clothing/head/lightrig/hacker
chest_type = /obj/item/clothing/suit/lightrig/hacker
glove_type = /obj/item/clothing/gloves/lightrig/hacker
boot_type = /obj/item/clothing/shoes/lightrig/hacker
initial_modules = list(
/obj/item/rig_module/ai_container,
// /obj/item/rig_module/power_sink,
/obj/item/rig_module/datajack,
/obj/item/rig_module/electrowarfare_suite,
/obj/item/rig_module/voice,
/obj/item/rig_module/vision,
)
//The cybersuit is not space-proof. It does however, have good siemens_coefficient values
/obj/item/clothing/head/lightrig/hacker
name = "HUD"
siemens_coefficient = 0.4
flags = 0
/obj/item/clothing/suit/lightrig/hacker
siemens_coefficient = 0.4
/obj/item/clothing/shoes/lightrig/hacker
siemens_coefficient = 0.4
flags = NOSLIP //All the other rigs have magboots anyways, hopefully gives the hacker suit something more going for it.
/obj/item/clothing/gloves/lightrig/hacker
siemens_coefficient = 0
/obj/item/rig/light/ninja
name = "ominous suit control module"
suit_type = "ominous"
desc = "A unique, vaccum-proof suit of nano-enhanced armor designed specifically for Spider Clan assassins."
icon_state = "ninja_rig"
armor = list(melee = 50, bullet = 15, laser = 30, energy = 10, bomb = 25, bio = 100, rad = 30)
emp_protection = 40 //change this to 30 if too high.
active_slowdown = 0
chest_type = /obj/item/clothing/suit/space/new_rig/light/ninja
glove_type = /obj/item/clothing/gloves/rig/light/ninja
req_access = list(ACCESS_SYNDICATE)
initial_modules = list(
/obj/item/rig_module/teleporter,
/obj/item/rig_module/stealth_field,
/obj/item/rig_module/mounted/energy_blade,
/obj/item/rig_module/vision,
/obj/item/rig_module/voice,
/obj/item/rig_module/chem_dispenser,
/obj/item/rig_module/grenade_launcher,
/obj/item/rig_module/fabricator,
/obj/item/rig_module/ai_container,
// /obj/item/rig_module/power_sink,
/obj/item/rig_module/datajack,
/obj/item/rig_module/self_destruct
)
/obj/item/clothing/gloves/rig/light/ninja
name = "insulated gloves"
siemens_coefficient = 0
/obj/item/clothing/suit/space/new_rig/light/ninja
breach_threshold = 38 //comparable to regular hardsuits
/obj/item/rig/light/stealth
name = "stealth suit control module"
suit_type = "stealth"
desc = "A highly advanced and expensive suit designed for covert operations."
icon_state = "ninja_rig" //supposed to be "stealth_rig", but as it currently only has a semi-copied ninja rig sprite, we can just use them directly.
req_access = list(ACCESS_SYNDICATE)
initial_modules = list(
/obj/item/rig_module/stealth_field,
/obj/item/rig_module/vision
)
@@ -1,32 +0,0 @@
/obj/item/clothing/head/helmet/space/new_rig/merc
/obj/item/rig/merc
name = "crimson hardsuit control module"
desc = "A blood-red hardsuit featuring some fairly illegal technology."
icon_state = "merc_rig"
suit_type = "crimson hardsuit"
armor = list(melee = 40, bullet = 50, laser = 30, energy = 15, bomb = 35, bio = 100, rad = 50)
active_slowdown = 1
offline_slowdown = 3
offline_vision_restriction = 1
helm_type = /obj/item/clothing/head/helmet/space/new_rig/merc
allowed = list(/obj/item/flashlight,/obj/item/tank,/obj/item/gun,/obj/item/ammo_casing,/obj/item/melee/baton,/obj/item/melee/energy/sword,/obj/item/restraints/handcuffs)
initial_modules = list(
/obj/item/rig_module/mounted,
/obj/item/rig_module/vision/thermal,
/obj/item/rig_module/grenade_launcher,
/obj/item/rig_module/ai_container,
// /obj/item/rig_module/power_sink,
/obj/item/rig_module/electrowarfare_suite,
/obj/item/rig_module/chem_dispenser/combat,
// /obj/item/rig_module/fabricator/energy_net
)
//Has most of the modules removed
/obj/item/rig/merc/empty
initial_modules = list(
/obj/item/rig_module/ai_container,
/obj/item/rig_module/electrowarfare_suite, //might as well
)
@@ -1,223 +0,0 @@
/obj/item/clothing/head/helmet/space/new_rig/industrial
/obj/item/clothing/head/helmet/space/new_rig/ce
/obj/item/clothing/head/helmet/space/new_rig/eva
/obj/item/clothing/head/helmet/space/new_rig/hazmat
/obj/item/clothing/head/helmet/space/new_rig/medical
/obj/item/clothing/head/helmet/space/new_rig/hazard
/obj/item/rig/internalaffairs
name = "augmented tie"
suit_type = "augmented suit"
desc = "Prepare for paperwork."
icon_state = "internalaffairs_rig"
armor = list(melee = 0, bullet = 0, laser = 0, energy = 0, bomb = 0, bio = 0, rad = 0)
siemens_coefficient = 0.9
active_slowdown = 0
offline_slowdown = 0
offline_vision_restriction = 0
allowed = list(/obj/item/flashlight,/obj/item/tank,/obj/item/storage/briefcase,/obj/item/storage/secure/briefcase)
req_access = list()
req_one_access = list()
glove_type = null
helm_type = null
boot_type = null
/obj/item/rig/internalaffairs/equipped
req_access = list(ACCESS_LAWYER)
initial_modules = list(
/obj/item/rig_module/ai_container,
/obj/item/rig_module/device/flash,
/obj/item/rig_module/device/paperdispenser,
/obj/item/rig_module/device/pen,
/obj/item/rig_module/device/stamp
)
glove_type = null
helm_type = null
boot_type = null
/obj/item/rig/industrial
name = "industrial suit control module"
suit_type = "industrial hardsuit"
desc = "A heavy, powerful rig used by construction crews and mining corporations."
icon_state = "engineering_rig"
armor = list(melee = 10, bullet = 5, laser = 10, energy = 5, bomb = 10, bio = 100, rad = 75)
active_slowdown = 3
offline_slowdown = 10
offline_vision_restriction = 2
emp_protection = -20
helm_type = /obj/item/clothing/head/helmet/space/new_rig/industrial
allowed = list(/obj/item/flashlight,/obj/item/tank,/obj/item/storage/bag/ore,/obj/item/t_scanner,/obj/item/pickaxe, /obj/item/rcd)
req_access = list()
req_one_access = list()
/obj/item/rig/industrial/equipped
initial_modules = list(
/obj/item/rig_module/device/plasmacutter,
/obj/item/rig_module/device/drill,
/obj/item/rig_module/device/orescanner,
// /obj/item/rig_module/device/rcd,
/obj/item/rig_module/vision/meson
)
/obj/item/rig/eva
name = "EVA suit control module"
suit_type = "EVA hardsuit"
desc = "A light rig for repairs and maintenance to the outside of habitats and vessels."
icon_state = "eva_rig"
active_slowdown = 0
offline_slowdown = 1
offline_vision_restriction = 1
helm_type = /obj/item/clothing/head/helmet/space/new_rig/eva
allowed = list(/obj/item/flashlight,/obj/item/tank,/obj/item/storage/toolbox,/obj/item/storage/briefcase/inflatable,/obj/item/t_scanner,/obj/item/rcd)
req_access = list()
req_one_access = list()
/obj/item/rig/eva/equipped
initial_modules = list(
/obj/item/rig_module/device/plasmacutter,
/obj/item/rig_module/maneuvering_jets,
// /obj/item/rig_module/device/rcd,
/obj/item/rig_module/vision/meson
)
//Chief Engineer's rig. This is sort of a halfway point between the old hardsuits (voidsuits) and the rig class.
/obj/item/rig/ce
name = "advanced voidsuit control module"
suit_type = "advanced voidsuit"
desc = "An advanced voidsuit that protects against hazardous, low pressure environments. Shines with a high polish."
icon_state = "ce_rig"
armor = list(melee = 40, bullet = 5, laser = 10, energy = 5, bomb = 50, bio = 100, rad = 90)
active_slowdown = 0
offline_slowdown = 0
offline_vision_restriction = 0
helm_type = /obj/item/clothing/head/helmet/space/new_rig/ce
allowed = list(/obj/item/flashlight,/obj/item/tank,/obj/item/storage/bag/ore,/obj/item/t_scanner,/obj/item/pickaxe, /obj/item/rcd)
req_access = list()
req_one_access = list()
boot_type = null
glove_type = null
/obj/item/rig/ce/equipped
req_access = list(ACCESS_CE)
initial_modules = list(
/obj/item/rig_module/ai_container,
/obj/item/rig_module/maneuvering_jets,
/obj/item/rig_module/device/plasmacutter,
// /obj/item/rig_module/device/rcd,
/obj/item/rig_module/vision/meson
)
chest_type = /obj/item/clothing/suit/space/new_rig/ce
boot_type = null
glove_type = null
/obj/item/clothing/suit/space/new_rig/ce
heat_protection = UPPER_TORSO|LOWER_TORSO|LEGS|FEET|ARMS|HANDS
body_parts_covered = UPPER_TORSO|LOWER_TORSO|LEGS|FEET|ARMS|HANDS
/obj/item/rig/hazmat
name = "AMI control module"
suit_type = "hazmat hardsuit"
desc = "An Anomalous Material Interaction hardsuit that protects against the strangest energies the universe can throw at it."
icon_state = "science_rig"
active_slowdown = 1
offline_vision_restriction = 1
helm_type = /obj/item/clothing/head/helmet/space/new_rig/hazmat
helm_type = /obj/item/clothing/head/helmet/space/new_rig/ert
allowed = list(/obj/item/flashlight,/obj/item/tank,/obj/item/pickaxe,/obj/item/healthanalyzer,/obj/item/gps,/obj/item/radio/beacon)
req_access = list()
req_one_access = list()
/obj/item/rig/hazmat/equipped
req_access = list(ACCESS_RD)
initial_modules = list(
/obj/item/rig_module/ai_container,
/obj/item/rig_module/maneuvering_jets)
/obj/item/rig/medical
name = "rescue suit control module"
suit_type = "rescue hardsuit"
desc = "A durable suit designed for medical rescue in high risk areas."
icon_state = "medical_rig"
armor = list(melee = 10, bullet = 5, laser = 10, energy = 5, bomb = 10, bio = 100, rad = 50)
active_slowdown = 1
offline_vision_restriction = 1
helm_type = /obj/item/clothing/head/helmet/space/new_rig/medical
allowed = list(/obj/item/flashlight,/obj/item/tank,/obj/item/storage/firstaid,/obj/item/healthanalyzer,/obj/item/stack/medical,/obj/item/roller )
req_access = list()
req_one_access = list()
/obj/item/rig/medical/equipped
initial_modules = list(
/obj/item/rig_module/chem_dispenser/injector,
/obj/item/rig_module/maneuvering_jets,
/obj/item/rig_module/device/healthscanner,
/obj/item/rig_module/vision/medhud
)
/obj/item/rig/hazard
name = "hazard hardsuit control module"
suit_type = "hazard hardsuit"
desc = "A Security hardsuit designed for prolonged EVA in dangerous environments."
icon_state = "hazard_rig"
armor = list(melee = 30, bullet = 15, laser = 30, energy = 10, bomb = 10, bio = 100, rad = 50)
active_slowdown = 1
offline_slowdown = 3
offline_vision_restriction = 1
helm_type = /obj/item/clothing/head/helmet/space/new_rig/hazard
allowed = list(/obj/item/gun,/obj/item/flashlight,/obj/item/tank,/obj/item/melee/baton)
req_access = list()
req_one_access = list()
/obj/item/rig/hazard/equipped
initial_modules = list(
/obj/item/rig_module/vision/sechud,
/obj/item/rig_module/maneuvering_jets,
/obj/item/rig_module/grenade_launcher,
/obj/item/rig_module/mounted/taser
)
+1 -1
View File
@@ -349,7 +349,7 @@
to_chat(user, "<span class='notice'>You modify the appearance of [target].</span>")
var/obj/item/clothing/mask/gas/M = target
M.name = "Prescription Gas Mask"
M.desc = "It looks heavily modified, but otherwise functions as a gas mask. The words Property of Yon-Dale can be seen on the inner band."
M.desc = "It looks heavily modified, but otherwise functions as a gas mask. The words \"Property of Yon-Dale\" can be seen on the inner band."
M.icon = 'icons/obj/custom_items.dmi'
M.icon_state = "gas_tariq"
M.sprite_sheets = list(
+7 -1
View File
@@ -2,7 +2,13 @@
announceWhen = rand(0, 20)
/datum/event/mass_hallucination/start()
for(var/mob/living/carbon/human/H in GLOB.alive_mob_list)
for(var/thing in GLOB.human_list)
var/mob/living/carbon/human/H = thing
if(H.stat == DEAD)
continue
var/turf/T = get_turf(H)
if(!is_station_level(T.z))
continue
var/armor = H.getarmor(type = "rad")
if((RADIMMUNE in H.dna.species.species_traits) || armor >= 75) // Leave radiation-immune species/rad armored players completely unaffected
continue
+1 -1
View File
@@ -10,7 +10,7 @@
for(var/mob/living/simple_animal/L in GLOB.alive_mob_list)
var/turf/T = get_turf(L)
if (T.z != 1)
if (!is_station_level(T.z))
continue
if(!(L in GLOB.player_list) && !L.mind && (L.sentience_type == sentience_type))
potential += L
+1 -1
View File
@@ -33,7 +33,7 @@
spawn_locs += get_turf(player_mind.current)
if(!spawn_locs) //If we can't find THAT, then just retry
return kill()
var /obj/effect/dummy/slaughter/holder = new /obj/effect/dummy/slaughter(pick(spawn_locs))
var/obj/effect/dummy/slaughter/holder = new /obj/effect/dummy/slaughter(pick(spawn_locs))
var/mob/living/simple_animal/slaughter/S = new /mob/living/simple_animal/slaughter/(holder)
S.holder = holder
player_mind.transfer_to(S)
+20 -7
View File
@@ -1,3 +1,4 @@
#define TS_HIGHPOP_TRIGGER 80
/datum/event/spider_terror
announceWhen = 240
@@ -22,23 +23,32 @@
if(temp_vent.parent.other_atmosmch.len > 50)
vents += temp_vent
var/spider_type
var/infestation_type = pick(1, 2, 3, 4, 5)
var/infestation_type
if((length(GLOB.clients)) < TS_HIGHPOP_TRIGGER)
infestation_type = pick(1, 2, 3, 4)
else
infestation_type = pick(2, 3, 4, 5)
switch(infestation_type)
if(1)
// Weakest, only used during lowpop.
spider_type = /mob/living/simple_animal/hostile/poison/terror_spider/green
spawncount = 5
if(2)
spider_type = /mob/living/simple_animal/hostile/poison/terror_spider/white
spawncount = 2
if(3)
// Fairly weak. Dangerous in single combat but has little staying power. Always gets whittled down.
spider_type = /mob/living/simple_animal/hostile/poison/terror_spider/prince
spawncount = 1
if(3)
// Variable. Depends how many they infect.
spider_type = /mob/living/simple_animal/hostile/poison/terror_spider/white
spawncount = 2
if(4)
spider_type = /mob/living/simple_animal/hostile/poison/terror_spider/queen
spawncount = 1
if(5)
// Pretty strong.
spider_type = /mob/living/simple_animal/hostile/poison/terror_spider/princess
spawncount = 2
if(5)
// Strongest, only used during highpop.
spider_type = /mob/living/simple_animal/hostile/poison/terror_spider/queen
spawncount = 1
while(spawncount >= 1 && vents.len)
var/obj/machinery/atmospherics/unary/vent_pump/vent = pick(vents)
@@ -60,3 +70,6 @@
new spider_type(vent.loc)
spawncount--
#undef TS_HIGHPOP_TRIGGER
+1 -1
View File
@@ -19,7 +19,7 @@
var/list/newlist = dreamlist.Copy()
for(var/i in 1 to newlist.len)
newlist[i] = replacetext(newlist[i], "\[DREAMER\]", "[user.name]")
return dreamlist
return newlist
//NIGHTMARES
+11 -5
View File
@@ -149,10 +149,12 @@ Gunshots/explosions/opening doors/less rare audio (done)
/obj/effect/hallucination/fake_flood/process()
if(!target)
qdel(src)
return
if(next_expand <= world.time)
radius++
if(radius > FAKE_FLOOD_MAX_RADIUS)
qdel(src)
return
Expand()
if((get_turf(target) in flood_turfs) && !target.internal)
target.hallucinate("fake_alert", "too_much_tox")
@@ -460,8 +462,9 @@ Gunshots/explosions/opening doors/less rare audio (done)
target = T
var/image/A = null
var/kind = force_kind ? force_kind : pick("clown", "corgi", "carp", "skeleton", "demon","zombie")
for(var/mob/living/carbon/human/H in GLOB.alive_mob_list)
if(H == target)
for(var/thing in GLOB.human_list)
var/mob/living/carbon/human/H = thing
if(H.stat == DEAD || H == target)
continue
if(skip_nearby && (H in view(target)))
continue
@@ -539,7 +542,8 @@ Gunshots/explosions/opening doors/less rare audio (done)
var/mob/living/carbon/human/clone = null
var/clone_weapon = null
for(var/mob/living/carbon/human/H in GLOB.alive_mob_list)
for(var/thing in GLOB.human_list)
var/mob/living/carbon/human/H = thing
if(H.stat || H.lying)
continue
clone = H
@@ -751,8 +755,10 @@ GLOBAL_LIST_INIT(non_fakeattack_weapons, list(/obj/item/gun/projectile, /obj/ite
target.client.images.Remove(speech_overlay)
else // Radio talk
var/list/humans = list()
for(var/mob/living/carbon/human/H in GLOB.alive_mob_list)
humans += H
for(var/thing in GLOB.human_list)
var/mob/living/carbon/human/H = thing
if(H.stat != DEAD)
humans += H
person = pick(humans)
target.hear_radio(message_to_multilingual(pick(radio_messages), pick(person.languages)), speaker = person, part_a = "<span class='[SSradio.frequency_span_class(PUB_FREQ)]'><b>\[[get_frequency_name(PUB_FREQ)]\]</b> <span class='name'>", part_b = "</span> <span class='message'>")
qdel(src)
@@ -124,6 +124,13 @@
reagents.reaction(M, REAGENT_TOUCH)
reagents.clear_reagents()
/obj/item/reagent_containers/food/drinks/bottle/decompile_act(obj/item/matter_decompiler/C, mob/user)
if(!reagents.total_volume)
C.stored_comms["glass"] += 3
qdel(src)
return TRUE
return ..()
//Keeping this here for now, I'll ask if I should keep it here.
/obj/item/broken_bottle
name = "Broken Bottle"
@@ -141,6 +148,11 @@
var/icon/broken_outline = icon('icons/obj/drinks.dmi', "broken")
sharp = 1
/obj/item/broken_bottle/decompile_act(obj/item/matter_decompiler/C, mob/user)
C.stored_comms["glass"] += 3
qdel(src)
return TRUE
/obj/item/reagent_containers/food/drinks/bottle/gin
name = "Griffeater Gin"
desc = "A bottle of high quality gin, produced in the New London Space Station."
+22 -3
View File
@@ -117,6 +117,7 @@
/obj/item/reagent_containers/food/snacks/grown/throw_impact(atom/hit_atom)
if(!..()) //was it caught by a mob?
if(seed)
log_action(thrownby, hit_atom, "Thrown [src] at")
for(var/datum/plant_gene/trait/T in seed.genes)
T.on_throw_impact(src, hit_atom)
if(seed.get_gene(/datum/plant_gene/trait/squash))
@@ -147,11 +148,11 @@
qdel(src)
/obj/item/reagent_containers/food/snacks/grown/On_Consume()
if(iscarbon(usr))
/obj/item/reagent_containers/food/snacks/grown/On_Consume(mob/M, mob/user)
if(iscarbon(M))
if(seed)
for(var/datum/plant_gene/trait/T in seed.genes)
T.on_consume(src, usr)
T.on_consume(src, M)
..()
/obj/item/reagent_containers/food/snacks/grown/after_slip(mob/living/carbon/human/H)
@@ -168,6 +169,11 @@
return
return ..()
/obj/item/reagent_containers/food/snacks/grown/decompile_act(obj/item/matter_decompiler/C, mob/user)
C.stored_comms["wood"] += 4
qdel(src)
return TRUE
// For item-containing growns such as eggy or gatfruit
/obj/item/reagent_containers/food/snacks/grown/shell/attack_self(mob/user)
user.unEquip(src)
@@ -185,3 +191,16 @@
else
return ..()
/obj/item/reagent_containers/food/snacks/grown/proc/log_action(mob/user, atom/target, what_done)
var/reagent_str = reagents.log_list()
var/genes_str = "No genes"
if(seed && length(seed.genes))
var/list/plant_gene_names = list()
for(var/thing in seed.genes)
var/datum/plant_gene/G = thing
if(G.dangerous)
plant_gene_names += G.name
genes_str = english_list(plant_gene_names)
add_attack_logs(user, target, "[what_done] ([reagent_str] | [genes_str])")
+8
View File
@@ -1,5 +1,7 @@
/datum/plant_gene
var/name
/// Used to determine if the trait should be logged when the holder is used
var/dangerous = FALSE
/datum/plant_gene/proc/get_name() // Used for manipulator display and gene disk name.
return name
@@ -194,6 +196,7 @@
name = "Liquid Contents"
examine_line = "<span class='info'>It has a lot of liquid contents inside.</span>"
origin_tech = list("biotech" = 5)
dangerous = TRUE
/datum/plant_gene/trait/slip
// Makes plant slippery, unless it has a grown-type trash. Then the trash gets slippery.
@@ -201,6 +204,7 @@
name = "Slippery Skin"
rate = 0.1
examine_line = "<span class='info'>It has a very slippery skin.</span>"
dangerous = TRUE
/datum/plant_gene/trait/slip/on_new(obj/item/reagent_containers/food/snacks/grown/G, newloc)
. = ..()
@@ -224,6 +228,7 @@
name = "Electrical Activity"
rate = 0.2
origin_tech = list("powerstorage" = 5)
dangerous = TRUE
/datum/plant_gene/trait/cell_charge/on_slip(obj/item/reagent_containers/food/snacks/grown/G, mob/living/carbon/C)
var/power = G.seed.potency*rate
@@ -298,6 +303,7 @@
name = "Bluespace Activity"
rate = 0.1
origin_tech = list("bluespace" = 5)
dangerous = TRUE
/datum/plant_gene/trait/teleport/on_squash(obj/item/reagent_containers/food/snacks/grown/G, atom/target)
if(isliving(target))
@@ -385,6 +391,7 @@
/datum/plant_gene/trait/stinging
name = "Hypodermic Prickles"
dangerous = TRUE
/datum/plant_gene/trait/stinging/on_throw_impact(obj/item/reagent_containers/food/snacks/grown/G, atom/target)
if(isliving(target) && G.reagents && G.reagents.total_volume)
@@ -398,6 +405,7 @@
/datum/plant_gene/trait/smoke
name = "gaseous decomposition"
dangerous = TRUE
/datum/plant_gene/trait/smoke/on_squash(obj/item/reagent_containers/food/snacks/grown/G, atom/target)
var/datum/effect_system/smoke_spread/chem/S = new
@@ -463,4 +463,5 @@
B.author = newbook.author
B.dat = newbook.content
B.icon_state = "book[rand(1,16)]"
B.has_drm = TRUE
visible_message("[src]'s printer hums as it produces a completely bound book. How did it do that?")
+2
View File
@@ -151,6 +151,8 @@
var/carved = 0 // Has the book been hollowed out for use as a secret storage item?
var/forbidden = 0 // Prevent ordering of this book. (0=no, 1=yes, 2=emag only)
var/obj/item/store // What's in the book?
/// Book DRM. If this var is TRUE, it cannot be scanned and re-uploaded
var/has_drm = FALSE
/obj/item/book/attack_self(var/mob/user as mob)
if(carved)
+5
View File
@@ -150,6 +150,11 @@ GLOBAL_LIST_INIT(library_section_names, list("Any", "Fiction", "Non-Fiction", "A
power_change()
return
if(istype(I, /obj/item/book))
// NT with those pesky DRM schemes
var/obj/item/book/B = I
if(B.has_drm)
atom_say("Copyrighted material detected. Scanner is unable to copy book to memory.")
return FALSE
user.drop_item()
I.forceMove(src)
return 1
+1 -1
View File
@@ -82,7 +82,7 @@
new /obj/item/clothing/head/corgi(src)
if(67 to 68)
for(var/i in 1 to rand(4, 7))
var /newitem = pick(subtypesof(/obj/item/stock_parts))
var/newitem = pick(subtypesof(/obj/item/stock_parts))
new newitem(src)
if(69 to 70)
new /obj/item/stack/ore/bluespace_crystal(src, 5)
@@ -120,18 +120,13 @@
return
var/mob/living/carbon/human/H = user
var/random = rand(1,3)
var/random = rand(1,2)
switch(random)
if(1)
to_chat(user, "<span class='danger'>Your flesh begins to melt! Miraculously, you seem fine otherwise.</span>")
H.set_species(/datum/species/skeleton)
if(2)
to_chat(user, "<span class='danger'>Power courses through you! You can now shift your form at will.")
if(user.mind)
var/obj/effect/proc_holder/spell/targeted/shapeshift/dragon/D = new
user.mind.AddSpell(D)
if(3)
to_chat(user, "<span class='danger'>You feel like you could walk straight through lava now.</span>")
H.weather_immunities |= "lava"
@@ -82,7 +82,7 @@
B.mineEffect(L)
for(var/mob/living/carbon/human/H in GLOB.player_list)
if(H == L)
if(H.stat == DEAD || H == L)
continue
to_chat(H, "<span class='userdanger'>You have an overwhelming desire to kill [L]. [L.p_they(TRUE)] [L.p_have()] been marked red! Go kill [L.p_them()]!</span>")
H.put_in_hands(new /obj/item/kitchen/knife/butcher(H))
@@ -383,7 +383,10 @@
var/mob/living/L = target
if(!L.anchored)
L.visible_message("<span class='danger'>[L] is snagged by [firer]'s hook!</span>")
var/old_density = L.density
L.density = FALSE // Ensures the hook does not hit the target multiple times
L.forceMove(get_turf(firer))
L.density = old_density
/obj/item/projectile/hook/Destroy()
QDEL_NULL(chain)
+1 -1
View File
@@ -273,7 +273,7 @@ GLOBAL_LIST_INIT(sand_recipes, list(\
icon_state = "Gibtonite active"
var/turf/bombturf = get_turf(src)
var/notify_admins = 0
if(z != 5)//Only annoy the admins ingame if we're triggered off the mining zlevel
if(!is_mining_level(z))//Only annoy the admins ingame if we're triggered off the mining zlevel
notify_admins = 1
if(notify_admins)
@@ -226,13 +226,6 @@
brainmob.emp_damage += rand(0,10)
..()
/obj/item/mmi/relaymove(var/mob/user, var/direction)
if(user.stat || user.stunned)
return
var/obj/item/rig/rig = src.get_rig()
if(rig)
rig.forced_move(direction, user)
/obj/item/mmi/Destroy()
if(isrobot(loc))
var/mob/living/silicon/robot/borg = loc
@@ -109,9 +109,6 @@
// log_world("k")
sql_report_death(src)
if(wearing_rig)
wearing_rig.notify_ai("<span class='danger'>Warning: user death event. Mobility control passed to integrated intelligence system.</span>")
/mob/living/carbon/human/update_revive()
. = ..()
if(. && healthdoll)
@@ -308,14 +308,14 @@
m_type = 1
if("bow", "bows")
if(!buckled)
if(!restrained())
var/M = handle_emote_param(param)
message = "<B>[src]</B> bows[M ? " to [M]" : ""]."
m_type = 1
if("salute", "salutes")
if(!buckled)
if(!restrained())
var/M = handle_emote_param(param)
message = "<B>[src]</B> salutes[M ? " to [M]" : ""]."
@@ -5,7 +5,6 @@
icon = 'icons/mob/human.dmi'
icon_state = "body_m_s"
deathgasp_on_death = TRUE
var/obj/item/rig/wearing_rig // This is very not good, but it's much much better than calling get_rig() every update_canmove() call.
/mob/living/carbon/human/New(loc)
icon = null // This is now handled by overlays -- we just keep an icon for the sake of the map editor.
@@ -182,13 +181,6 @@
stat("Tank Pressure", internal.air_contents.return_pressure())
stat("Distribution Pressure", internal.distribute_pressure)
if(istype(back, /obj/item/rig))
var/obj/item/rig/suit = back
var/cell_status = "ERROR"
if(suit.cell)
cell_status = "[suit.cell.charge]/[suit.cell.maxcharge]"
stat(null, "Suit charge: [cell_status]")
// I REALLY need to split up status panel things into datums
var/mob/living/simple_animal/borer/B = has_brain_worms()
if(B && B.controlling)
@@ -963,16 +955,6 @@
var/obj/item/clothing/mask/MT = src.wear_mask
tinted += MT.tint
//god help me
if(istype(back, /obj/item/rig))
var/obj/item/rig/O = back
if(O.helmet && O.helmet == head && (O.helmet.body_parts_covered & HEAD))
if((O.offline && O.offline_vision_restriction == 1) || (!O.offline && O.vision_restriction == 1))
tinted = 2
if((O.offline && O.offline_vision_restriction == 2) || (!O.offline && O.vision_restriction == 2))
tinted = 3
//im so sorry
return tinted
@@ -129,13 +129,6 @@
O.heal_damage(0, -amount, internal = 0, robo_repair = O.is_robotic(), updating_health = updating_health)
return STATUS_UPDATE_HEALTH
/mob/living/carbon/human/Paralyse(amount)
// Notify our AI if they can now control the suit.
if(wearing_rig && !stat && paralysis < amount) //We are passing out right this second.
wearing_rig.notify_ai("<span class='danger'>Warning: user consciousness failure. Mobility control passed to integrated intelligence system.</span>")
return ..()
/mob/living/carbon/human/adjustCloneLoss(amount)
if(dna.species && amount > 0)
amount = amount * dna.species.clone_mod
@@ -342,7 +335,5 @@ This function restores all organs.
..(damage, damagetype, def_zone, blocked)
return 1
//Handle BRUTE and BURN damage
handle_suit_punctures(damagetype, damage)
//Handle species apply_damage procs
return dna.species.apply_damage(damage, damagetype, def_zone, blocked, src, sharp, used_weapon)
@@ -531,17 +531,6 @@ emp_act
w_uniform.add_mob_blood(source)
update_inv_w_uniform()
/mob/living/carbon/human/proc/handle_suit_punctures(var/damtype, var/damage)
if(!wear_suit) return
if(!istype(wear_suit,/obj/item/clothing/suit/space)) return
if(damtype != BURN && damtype != BRUTE) return
var/obj/item/clothing/suit/space/SS = wear_suit
var/penetrated_dam = max(0,(damage - max(0,(SS.breach_threshold - SS.damage))))
if(penetrated_dam) SS.create_breaches(damtype, penetrated_dam)
/mob/living/carbon/human/attack_hulk(mob/living/carbon/human/user, does_attack_animation = FALSE)
if(user.a_intent == INTENT_HARM)
if(HAS_TRAIT(user, TRAIT_PACIFISM))
@@ -16,12 +16,6 @@
else if(istype(wear_suit, /obj/item/clothing/suit/space/hardsuit))
var/obj/item/clothing/suit/space/hardsuit/C = wear_suit
thrust = C.jetpack
else if(istype(back,/obj/item/rig))
var/obj/item/rig/rig = back
for(var/obj/item/rig_module/maneuvering_jets/module in rig.installed_modules)
thrust = module.jets
break
if(thrust)
if((movement_dir || thrust.stabilizers) && thrust.allow_thrust(0.01, src))
return 1
@@ -302,14 +302,6 @@
if(!(head && head.flags & AIRTIGHT)) //if NOT (head AND head.flags CONTAIN AIRTIGHT)
null_internals = 1 //not wearing a mask or suitable helmet
if(istype(back, /obj/item/rig)) //wearing a rigsuit
var/obj/item/rig/rig = back //needs to be typecasted because this doesn't use get_rig() for some reason
if(rig.offline && (rig.air_supply && internal == rig.air_supply)) //if rig IS offline AND (rig HAS air_supply AND internal IS air_supply)
null_internals = 1 //offline suits do not breath
else if(rig.air_supply && internal == rig.air_supply) //if rig HAS air_supply AND internal IS rig air_supply
skip_contents_check = 1 //skip contents.Find() check, the oxygen is valid even being outside of the mob
if(!contents.Find(internal) && (!skip_contents_check)) //if internal NOT IN contents AND skip_contents_check IS false
null_internals = 1 //not a rigsuit and your oxygen is gone
@@ -62,11 +62,6 @@
return ..()
/mob/living/carbon/human/proc/HasVoiceChanger()
if(istype(back, /obj/item/rig))
var/obj/item/rig/rig = back
if(rig.speech && rig.speech.voice_holder && rig.speech.voice_holder.active && rig.speech.voice_holder.voice)
return rig.speech.voice_holder.voice
for(var/obj/item/gear in list(wear_mask, wear_suit, head))
if(!gear)
continue
@@ -817,20 +817,6 @@ It'll return null if the organ doesn't correspond, so include null checks when u
if(!isnull(hat.lighting_alpha))
H.lighting_alpha = min(hat.lighting_alpha, H.lighting_alpha)
if(istype(H.back, /obj/item/rig)) ///aghhh so snowflakey
var/obj/item/rig/rig = H.back
if(rig.visor)
if(!rig.helmet || (H.head && rig.helmet == H.head))
if(rig.visor && rig.visor.vision && rig.visor.active && rig.visor.vision.glasses)
var/obj/item/clothing/glasses/G = rig.visor.vision.glasses
if(istype(G))
H.sight |= G.vision_flags
H.see_in_dark = max(G.see_in_dark, H.see_in_dark)
H.see_invisible = min(G.invis_view, H.see_invisible)
if(!isnull(G.lighting_alpha))
H.lighting_alpha = min(G.lighting_alpha, H.lighting_alpha)
if(H.vision_type)
H.sight |= H.vision_type.sight_flags
H.see_in_dark = max(H.see_in_dark, H.vision_type.see_in_dark)
@@ -273,10 +273,10 @@ GLOBAL_LIST_EMPTY(damage_icon_parts)
overlays_standing[UNDERWEAR_LAYER] = mutable_appearance(underwear_standing, layer = -UNDERWEAR_LAYER)
apply_overlay(UNDERWEAR_LAYER)
if(lip_style && (LIPS in dna.species.species_traits))
var/icon/lips = icon("icon" = 'icons/mob/human_face.dmi', "icon_state" = "lips_[lip_style]_s")
lips.Blend(lip_color, ICON_ADD)
standing += mutable_appearance(lips, layer = -BODY_LAYER)
if(lip_style && (LIPS in dna.species.species_traits))
var/mutable_appearance/lips = mutable_appearance('icons/mob/human_face.dmi', "lips_[lip_style]_s")
lips.color = lip_color
standing += lips
overlays_standing[BODY_LAYER] = standing
apply_overlay(BODY_LAYER)
@@ -964,10 +964,6 @@ GLOBAL_LIST_EMPTY(damage_icon_parts)
var/mutable_appearance/standing
if(back.icon_override)
standing = mutable_appearance(back.icon_override, "[back.icon_state]", layer = -BACK_LAYER)
else if(istype(back, /obj/item/rig))
//If this is a rig and a mob_icon is set, it will take species into account in the rig update_icon() proc.
var/obj/item/rig/rig = back
standing = rig.mob_icon
else if(back.sprite_sheets && back.sprite_sheets[dna.species.name])
standing = mutable_appearance(back.sprite_sheets[dna.species.name], "[back.icon_state]", layer = -BACK_LAYER)
else
-7
View File
@@ -175,13 +175,6 @@
AM.setDir(current_dir)
now_pushing = FALSE
/mob/living/Stat()
. = ..()
if(. && get_rig_stats)
var/obj/item/rig/rig = get_rig()
if(rig)
SetupStat(rig)
/mob/living/proc/can_track(mob/living/user)
//basic fast checks go first. When overriding this proc, I recommend calling ..() at the end.
var/turf/T = get_turf(src)
+1 -1
View File
@@ -113,7 +113,7 @@
var/armor = run_armor_check(zone, "melee", "Your armor has protected your [parse_zone(zone)].", "Your armor has softened hit to your [parse_zone(zone)].", I.armour_penetration)
apply_damage(I.throwforce, dtype, zone, armor, is_sharp(I), I)
if(I.thrownby)
add_attack_logs(I.thrownby, src, "Hit with thrown [I]")
add_attack_logs(I.thrownby, src, "Hit with thrown [I]", !I.throwforce ? ATKLOG_ALMOSTALL : null) // Only message if the person gets damages
else
return 1
else
+11 -27
View File
@@ -63,6 +63,7 @@ GLOBAL_LIST_INIT(ai_verbs_default, list(
//MALFUNCTION
var/datum/module_picker/malf_picker
var/datum/action/innate/ai/choose_modules/modules_action
var/list/datum/AI_Module/current_modules = list()
var/can_dominate_mechs = 0
var/shunted = 0 //1 if the AI is currently shunted. Used to differentiate between shunted and ghosted/braindead
@@ -851,13 +852,6 @@ GLOBAL_LIST_INIT(ai_verbs_default, list(
to_chat(src, "<span class='notice'>Switched to [network] camera network.</span>")
//End of code by Mord_Sith
/mob/living/silicon/ai/proc/choose_modules()
set category = "Malfunction"
set name = "Choose Module"
malf_picker.use(src)
/mob/living/silicon/ai/proc/ai_statuschange()
set category = "AI Commands"
set name = "AI Status"
@@ -1028,15 +1022,6 @@ GLOBAL_LIST_INIT(ai_verbs_default, list(
return
/mob/living/silicon/ai/proc/corereturn()
set category = "Malfunction"
set name = "Return to Main Core"
var/obj/machinery/power/apc/apc = loc
if(!istype(apc))
to_chat(src, "<span class='notice'>You are already in your Main Core.</span>")
return
apc.malfvacate()
//Toggles the luminosity and applies it by re-entereing the camera.
/mob/living/silicon/ai/proc/toggle_camera_light()
@@ -1181,16 +1166,6 @@ GLOBAL_LIST_INIT(ai_verbs_default, list(
/mob/living/silicon/ai/can_buckle()
return FALSE
// Pass lying down or getting up to our pet human, if we're in a rig.
/mob/living/silicon/ai/lay_down()
set name = "Rest"
set category = "IC"
resting = 0
var/obj/item/rig/rig = get_rig()
if(rig)
rig.force_rest(src)
/mob/living/silicon/ai/switch_to_camera(obj/machinery/camera/C)
if(!C.can_use() || !is_in_chassis())
return FALSE
@@ -1244,8 +1219,17 @@ GLOBAL_LIST_INIT(ai_verbs_default, list(
to_chat(src, "In the top right corner of the screen you will find the Malfunctions tab, where you can purchase various abilities, from upgraded surveillance to station ending doomsday devices.")
to_chat(src, "You are also capable of hacking APCs, which grants you more points to spend on your Malfunction powers. The drawback is that a hacked APC will give you away if spotted by the crew. Hacking an APC takes 60 seconds.")
view_core() //A BYOND bug requires you to be viewing your core before your verbs update
verbs += /mob/living/silicon/ai/proc/choose_modules
malf_picker = new /datum/module_picker
modules_action = new(malf_picker)
modules_action.Grant(src)
///Removes all malfunction-related /datum/action's from the target AI.
/mob/living/silicon/ai/proc/remove_malf_abilities()
QDEL_NULL(modules_action)
for(var/datum/AI_Module/AM in current_modules)
for(var/datum/action/A in actions)
if(istype(A, initial(AM.power_type)))
qdel(A)
/mob/living/silicon/ai/proc/open_nearest_door(mob/living/target)
if(!istype(target))
@@ -435,9 +435,6 @@
// Pass lying down or getting up to our pet human, if we're in a rig.
if(stat == CONSCIOUS && istype(loc,/obj/item/paicard))
resting = 0
var/obj/item/rig/rig = get_rig()
if(istype(rig))
rig.force_rest(src)
else
resting = !resting
to_chat(src, "<span class='notice'>You are now [resting ? "resting" : "getting up"]</span>")
@@ -354,3 +354,20 @@
/mob/living/simple_animal/drone/flash_eyes(intensity = 1, override_blindness_check = 0, affect_silicon = 0, visual = 0)
if(affect_silicon)
return ..()
/mob/living/silicon/robot/drone/decompile_act(obj/item/matter_decompiler/C, mob/user)
if(!client && istype(user, /mob/living/silicon/robot/drone))
to_chat(user, "<span class='warning'>You begin decompiling the other drone.</span>")
if(!do_after(user, 5 SECONDS, target = loc))
to_chat(user, "<span class='warning'>You need to remain still while decompiling such a large object.</span>")
return
if(QDELETED(src) || QDELETED(user))
return ..()
to_chat(user, "<span class='warning'>You carefully and thoroughly decompile your downed fellow, storing as much of its resources as you can within yourself.</span>")
new/obj/effect/decal/cleanable/blood/oil(get_turf(src))
C.stored_comms["metal"] += 15
C.stored_comms["glass"] += 15
C.stored_comms["wood"] += 5
qdel(src)
return TRUE
return ..()
@@ -151,15 +151,13 @@
var/list/stored_comms = list(
"metal" = 0,
"glass" = 0,
"wood" = 0,
"plastic" = 0
"wood" = 0
)
/obj/item/matter_decompiler/attack(mob/living/carbon/M as mob, mob/living/carbon/user as mob)
return
/obj/item/matter_decompiler/afterattack(atom/target as mob|obj|turf|area, mob/living/user as mob|obj, proximity, params)
/obj/item/matter_decompiler/afterattack(atom/target, mob/living/user, proximity, params)
if(!proximity) return //Not adjacent.
//We only want to deal with using this on turfs. Specific items aren't important.
@@ -168,101 +166,11 @@
return
//Used to give the right message.
var/grabbed_something = 0
var/grabbed_something = FALSE
for(var/mob/M in T)
if(istype(M,/mob/living/simple_animal/lizard) || istype(M,/mob/living/simple_animal/mouse))
src.loc.visible_message("<span class='notice'>[src.loc] sucks [M] into its decompiler. There's a horrible crunching noise.</span>","<span class='warning'>It's a bit of a struggle, but you manage to suck [M] into your decompiler. It makes a series of visceral crunching noises.</span>")
new/obj/effect/decal/cleanable/blood/splatter(get_turf(src))
qdel(M)
stored_comms["wood"]++
stored_comms["wood"]++
stored_comms["plastic"]++
stored_comms["plastic"]++
return
else if(istype(M,/mob/living/silicon/robot/drone) && !M.client)
var/mob/living/silicon/robot/drone/D = src.loc
if(!istype(D))
return
to_chat(D, "<span class='warning'>You begin decompiling the other drone.</span>")
if(!do_after(D, 50, target = target))
to_chat(D, "<span class='warning'>You need to remain still while decompiling such a large object.</span>")
return
if(!M || !D) return
to_chat(D, "<span class='warning'>You carefully and thoroughly decompile your downed fellow, storing as much of its resources as you can within yourself.</span>")
qdel(M)
new/obj/effect/decal/cleanable/blood/oil(get_turf(src))
stored_comms["metal"] += 15
stored_comms["glass"] += 15
stored_comms["wood"] += 5
stored_comms["plastic"] += 5
return
else
continue
for(var/obj/W in T)
//Different classes of items give different commodities.
if(istype(W,/obj/item/cigbutt))
stored_comms["plastic"]++
else if(istype(W,/obj/structure/spider/spiderling))
stored_comms["wood"]++
stored_comms["wood"]++
stored_comms["plastic"]++
stored_comms["plastic"]++
else if(istype(W,/obj/item/light))
var/obj/item/light/L = W
if(L.status >= 2) //In before someone changes the inexplicably local defines. ~ Z
stored_comms["metal"]++
stored_comms["glass"]++
else
continue
else if(istype(W,/obj/effect/decal/remains/robot))
stored_comms["metal"]++
stored_comms["metal"]++
stored_comms["plastic"]++
stored_comms["plastic"]++
stored_comms["glass"]++
else if(istype(W,/obj/item/trash))
stored_comms["metal"]++
stored_comms["plastic"]++
stored_comms["plastic"]++
else if(istype(W,/obj/effect/decal/cleanable/blood/gibs/robot))
stored_comms["metal"]++
stored_comms["metal"]++
stored_comms["glass"]++
stored_comms["glass"]++
else if(istype(W,/obj/item/ammo_casing))
stored_comms["metal"]++
else if(istype(W,/obj/item/shard))
stored_comms["glass"]++
stored_comms["glass"]++
stored_comms["glass"]++
else if(istype(W,/obj/item/reagent_containers/food/snacks/grown))
stored_comms["wood"]++
stored_comms["wood"]++
stored_comms["wood"]++
stored_comms["wood"]++
else if(istype(W,/obj/item/broken_bottle))
stored_comms["glass"]++
stored_comms["glass"]++
stored_comms["glass"]++
else if(istype(W,/obj/item/light/tube) || istype(W,/obj/item/light/bulb))
stored_comms["glass"]++
else
continue
qdel(W)
grabbed_something = 1
for(var/atom/movable/A in T)
if(A.decompile_act(src, user)) // Each decompileable mob or obj needs to have this defined
grabbed_something = TRUE
if(grabbed_something)
to_chat(user, "<span class='notice'>You deploy your decompiler and clear out the contents of \the [T].</span>")
@@ -353,11 +261,5 @@
stack_wood = new /obj/item/stack/sheet/wood(src.module)
stack_wood.amount = 1
stack = stack_wood
if("plastic")
if(!stack_plastic)
stack_plastic = new /obj/item/stack/sheet/plastic(src.module)
stack_plastic.amount = 1
stack = stack_plastic
stack.amount++
decompiler.stored_comms[type]--
@@ -756,7 +756,7 @@ Pass a positive integer as an argument to override a bot's default speed.
// send a radio signal with multiple data key/values
/mob/living/simple_animal/bot/proc/post_signal_multiple(var/freq, var/list/keyval)
if(z != 1) //Bot control will only work on station.
if(!is_station_level(z)) //Bot control will only work on station.
return
var/datum/radio_frequency/frequency = SSradio.return_frequency(freq)
if(!frequency)
@@ -474,8 +474,7 @@
return
build_step++
to_chat(user, "<span class='notice'>You complete the Securitron! Beep boop.</span>")
var/mob/living/simple_animal/bot/secbot/S = new /mob/living/simple_animal/bot/secbot
S.forceMove(get_turf(src))
var/mob/living/simple_animal/bot/secbot/S = new /mob/living/simple_animal/bot/secbot(get_turf(src))
S.name = created_name
S.robot_arm = robot_arm
qdel(I)
@@ -512,7 +511,7 @@
//General Griefsky
else if((istype(I, /obj/item/wrench)) && (build_step == 3))
var/obj/item/griefsky_assembly/A = new /obj/item/griefsky_assembly
var/obj/item/griefsky_assembly/A = new /obj/item/griefsky_assembly(get_turf(src))
user.put_in_hands(A)
to_chat(user, "<span class='notice'>You adjust the arm slots for extra weapons!.</span>")
user.unEquip(src, 1)
@@ -540,8 +539,7 @@
if(!user.unEquip(I))
return
to_chat(user, "<span class='notice'>You complete General Griefsky!.</span>")
var/mob/living/simple_animal/bot/secbot/griefsky/S = new /mob/living/simple_animal/bot/secbot/griefsky
S.forceMove(get_turf(src))
new /mob/living/simple_animal/bot/secbot/griefsky(get_turf(src))
qdel(I)
qdel(src)
@@ -556,8 +554,7 @@
if(!user.unEquip(I))
return
to_chat(user, "<span class='notice'>You complete Genewul Giftskee!.</span>")
var/mob/living/simple_animal/bot/secbot/griefsky/toy/S = new /mob/living/simple_animal/bot/secbot/griefsky/toy
S.forceMove(get_turf(src))
new /mob/living/simple_animal/bot/secbot/griefsky/toy(get_turf(src))
qdel(I)
qdel(src)
@@ -23,3 +23,14 @@
butcher_results = list(/obj/item/reagent_containers/food/snacks/meat = 1)
can_collar = 1
gold_core_spawnable = FRIENDLY_SPAWN
/mob/living/simple_animal/lizard/decompile_act(obj/item/matter_decompiler/C, mob/user)
if(!istype(user, /mob/living/silicon/robot/drone))
user.visible_message("<span class='notice'>[user] sucks [src] into its decompiler. There's a horrible crunching noise.</span>", \
"<span class='warning'>It's a bit of a struggle, but you manage to suck [src] into your decompiler. It makes a series of visceral crunching noises.</span>")
new/obj/effect/decal/cleanable/blood/splatter(get_turf(src))
C.stored_comms["wood"] += 2
C.stored_comms["glass"] += 2
qdel(src)
return TRUE
return ..()
@@ -234,3 +234,14 @@
gold_core_spawnable = NO_SPAWN
can_collar = 0
butcher_results = list(/obj/item/stack/sheet/metal = 1)
/mob/living/simple_animal/mouse/decompile_act(obj/item/matter_decompiler/C, mob/user)
if(!(istype(user, /mob/living/silicon/robot/drone)))
user.visible_message("<span class='notice'>[user] sucks [src] into its decompiler. There's a horrible crunching noise.</span>", \
"<span class='warning'>It's a bit of a struggle, but you manage to suck [src] into your decompiler. It makes a series of visceral crunching noises.</span>")
new/obj/effect/decal/cleanable/blood/splatter(get_turf(src))
C.stored_comms["wood"] += 2
C.stored_comms["glass"] += 2
qdel(src)
return TRUE
return ..()
@@ -95,6 +95,10 @@
for(var/mob/A in searched_for)
. += A
// All bee sprites are made up of overlays. They do not have any special sprite overlays for items placed on them, such as collars, so this proc is unneeded.
/mob/living/simple_animal/hostile/poison/bees/regenerate_icons()
return
/mob/living/simple_animal/hostile/poison/bees/proc/generate_bee_visuals()
overlays.Cut()
@@ -15,7 +15,7 @@
ai_target_method = TS_DAMAGE_SIMPLE
icon_state = "terror_princess1"
icon_living = "terror_princess1"
icon_dead = "terror_princess_dead1"
icon_dead = "terror_princess1_dead"
maxHealth = 150
health = 150
regen_points_per_hp = 1 // always regens very fast
@@ -51,7 +51,7 @@
if(fed == 0)
icon_state = "terror_princess1"
icon_living = "terror_princess1"
icon_dead = "terror_princess_dead1"
icon_dead = "terror_princess1_dead"
desc = "An enormous spider. It looks strangely cute and fluffy, with soft pink fur covering most of its body."
else if(fed == 1)
icon_state = "terror_princess2"
@@ -615,3 +615,8 @@
if(pcollar && collar_type)
add_overlay("[collar_type]collar")
add_overlay("[collar_type]tag")
/mob/living/simple_animal/Login()
..()
walk(src, 0) // if mob is moving under ai control, then stop AI movement
+1 -1
View File
@@ -90,7 +90,7 @@
if(adminonly)
question = "(<font color='#997700'>Admin only poll</font>) " + question
var output = "<!DOCTYPE html><html><body>"
var/output = "<!DOCTYPE html><html><body>"
if(polltype == POLLTYPE_MULTI || polltype == POLLTYPE_OPTION)
select_query = GLOB.dbcon.NewQuery("SELECT text, percentagecalc, (SELECT COUNT(optionid) FROM [format_table_name("poll_vote")] WHERE optionid = poll_option.id GROUP BY optionid) AS votecount FROM [format_table_name("poll_option")] WHERE pollid = [pollid]")
select_query.Execute()
+2 -5
View File
@@ -82,14 +82,11 @@
O.notify_ai(1)
if(O.mind && O.mind.assigned_role == "Cyborg")
if(O.mind.role_alt_title == "Android")
if(O.mind.role_alt_title == "Robot")
O.mmi = new /obj/item/mmi/robotic_brain(O)
else if(O.mind.role_alt_title == "Robot")
O.mmi = null //Robots do not have removable brains.
else
O.mmi = new /obj/item/mmi(O)
if(O.mmi) O.mmi.transfer_identity(src) //Does not transfer key/client.
O.mmi.transfer_identity(src) //Does not transfer key/client.
O.update_pipe_vision()
+8 -4
View File
@@ -108,7 +108,7 @@
maptext_x = 10
if(100)
maptext_x = 8
maptext = "[current_number]" //Finally, apply the maptext
maptext = "<font face='Small Fonts'>[ticket_number]</font>"
/obj/machinery/ticket_machine/attackby(obj/item/I, mob/user, params)
if(istype(I, /obj/item/hand_labeler_refill))
@@ -151,8 +151,8 @@
to_chat(user, "<span class='notice'>You take a ticket from [src], looks like you're ticket number #[ticket_number]...</span>")
var/obj/item/ticket_machine_ticket/theirticket = new /obj/item/ticket_machine_ticket(get_turf(src))
theirticket.name = "Ticket #[ticket_number]"
theirticket.maptext = "<font color='#000000'>[ticket_number]</font>"
theirticket.saved_maptext = "<font color='#000000'>[ticket_number]</font>"
theirticket.maptext = "<font color='#000000' face='Small Fonts'>[ticket_number]</font>"
theirticket.saved_maptext = "<font color='#000000' face='Small Fonts'>[ticket_number]</font>"
theirticket.ticket_number = ticket_number
theirticket.source = src
theirticket.owner = user.UID()
@@ -167,9 +167,13 @@
user.adjust_fire_stacks(1)
user.IgniteMob()
// Stop AI penetrating the bureaucracy
/obj/machinery/ticket_machine/attack_ai(mob/user)
return
/obj/item/ticket_machine_ticket
name = "Ticket"
desc = "A ticket which shows your place in the Head of Personnel's line. Made from Nanotrasen patented NanoPaper®. Though solid, its form seems to shimmer slightly. Feels (and burns) just like the real thing."
desc = "A ticket which shows your place in the Head of Personnel's line. Made from Nanotrasen patented NanoPaper. Though solid, its form seems to shimmer slightly. Feels (and burns) just like the real thing."
icon = 'icons/obj/bureaucracy.dmi'
icon_state = "ticket"
maptext_x = 7
+2 -1
View File
@@ -1052,7 +1052,8 @@
occupier.eyeobj.name = "[occupier.name] (AI Eye)"
if(malf.parent)
qdel(malf)
occupier.verbs += /mob/living/silicon/ai/proc/corereturn
var/datum/action/innate/ai/return_to_core/R = new
R.Grant(occupier)
occupier.cancel_camera()
if((seclevel2num(get_security_level()) == SEC_LEVEL_DELTA) && malf.nuking)
for(var/obj/item/pinpointer/point in GLOB.pinpointer_list)
+6
View File
@@ -634,6 +634,12 @@
shatter()
return ..()
/obj/item/light/decompile_act(obj/item/matter_decompiler/C, mob/user)
C.stored_comms["glass"] += 1
C.stored_comms["metal"] += 1
qdel(src)
return TRUE
/obj/item/light/tube
name = "light tube"
desc = "A replacement light tube."
+2
View File
@@ -127,6 +127,8 @@
/obj/singularity/narsie/proc/acquire(var/mob/food)
if(food == target)
return
if(!target)
return
to_chat(target, "<span class='cultlarge'>[uppertext(SSticker.cultdat.entity_name)] HAS LOST INTEREST IN YOU</span>")
target = food
if(ishuman(target))
+7 -7
View File
@@ -29,10 +29,10 @@
//set the control of the tracker to a given computer if closer than SOLAR_MAX_DIST
/obj/machinery/power/tracker/proc/set_control(obj/machinery/power/solar_control/SC)
if(SC && (get_dist(src, SC) > SOLAR_MAX_DIST))
return 0
return FALSE
control = SC
SC.connected_tracker = src
return 1
return TRUE
//set the control of the tracker to null and removes it from the previous control computer if needed
/obj/machinery/power/tracker/proc/unset_control()
@@ -44,7 +44,7 @@
if(!S)
S = new /obj/item/solar_assembly(src)
S.glass_type = /obj/item/stack/sheet/glass
S.tracker = 1
S.tracker = TRUE
S.anchored = TRUE
S.forceMove(src)
update_icon()
@@ -63,7 +63,7 @@
. = TRUE
if(!I.tool_use_check(user, 0))
return
playsound(src.loc, 'sound/machines/click.ogg', 50, 1)
playsound(loc, 'sound/machines/click.ogg', 50, 1)
user.visible_message("<span class='notice'>[user] begins to take the glass off the solar tracker.</span>")
if(I.use_tool(src, user, 50, volume = I.tool_volume))
user.visible_message("<span class='notice'>[user] takes the glass off the tracker.</span>")
@@ -76,7 +76,7 @@
stat |= BROKEN
unset_control()
/obj/machinery/power/solar/deconstruct(disassembled = TRUE)
/obj/machinery/power/tracker/deconstruct(disassembled = TRUE)
if(!(flags & NODECONSTRUCT))
if(disassembled)
var/obj/item/solar_assembly/S = locate() in src
@@ -85,8 +85,8 @@
S.give_glass(stat & BROKEN)
else
playsound(src, "shatter", 70, TRUE)
new /obj/item/shard(src.loc)
new /obj/item/shard(src.loc)
new /obj/item/shard(loc)
new /obj/item/shard(loc)
qdel(src)
// Tracker Electronic
-17
View File
@@ -15,7 +15,6 @@
ammo_x_offset = 2
var/shaded_charge = 0 //if this gun uses a stateful charge bar for more detail
var/selfcharge = 0
var/use_external_power = 0 //if set, the weapon will look for an external power source to draw from, otherwise it recharges magically
var/charge_tick = 0
var/charge_delay = 4
@@ -68,11 +67,6 @@
charge_tick = 0
if(!cell)
return // check if we actually need to recharge
var/obj/item/ammo_casing/energy/E = ammo_type[select]
if(use_external_power)
var/obj/item/stock_parts/cell/external = get_external_cell()
if(!external || !external.use(E.e_cost)) //Take power from the borg...
return //Note, uses /10 because of shitty mods to the cell system
cell.give(100) //... to recharge the shot
on_recharge()
update_icon()
@@ -207,14 +201,3 @@
var/obj/item/ammo_casing/energy/shot = ammo_type[select] //Necessary to find cost of shot
if(R.cell.use(shot.e_cost)) //Take power from the borg...
cell.give(shot.e_cost) //... to recharge the shot
/obj/item/gun/energy/proc/get_external_cell()
if(istype(loc, /obj/item/rig_module))
var/obj/item/rig_module/module = loc
if(module.holder && module.holder.wearer)
var/mob/living/carbon/human/H = module.holder.wearer
if(istype(H) && H.back)
var/obj/item/rig/suit = H.back
if(istype(suit))
return suit.cell
return null
@@ -95,12 +95,6 @@
..()
damage = min(damage+7, 100)
/obj/item/gun/energy/lasercannon/mounted
name = "mounted laser cannon"
selfcharge = 1
use_external_power = 1
charge_delay = 10
/obj/item/gun/energy/lasercannon/cyborg
/obj/item/gun/energy/lasercannon/cyborg/newshot()
@@ -21,11 +21,6 @@
/obj/item/gun/energy/gun/cyborg/emp_act()
return
/obj/item/gun/energy/gun/mounted
name = "mounted energy gun"
selfcharge = 1
use_external_power = 1
/obj/item/gun/energy/gun/mini
name = "miniature energy gun"
desc = "A small, pistol-sized energy gun with a built-in flashlight. It has two settings: disable and kill."
@@ -112,10 +112,6 @@
max_mod_capacity = 0
empty_state = null
/obj/item/gun/energy/kinetic_accelerator/crossbow/ninja
name = "energy dart thrower"
ammo_type = list(/obj/item/ammo_casing/energy/dart)
/obj/item/gun/energy/kinetic_accelerator/crossbow/large
name = "energy crossbow"
desc = "A reverse engineered weapon using syndicate technology."
@@ -424,7 +420,7 @@
update_icon()
if(istype(loc, /mob/living/carbon))
var /mob/living/carbon/M = loc
var/mob/living/carbon/M = loc
if(src == M.machine)
update_dat()
M << browse("<TITLE>Temperature Gun Configuration</TITLE><HR>[dat]", "window=tempgun;size=510x102")
@@ -7,11 +7,6 @@
ammo_type = list(/obj/item/ammo_casing/energy/electrode)
ammo_x_offset = 3
/obj/item/gun/energy/taser/mounted
name = "mounted taser gun"
selfcharge = 1
use_external_power = 1
/obj/item/gun/energy/shock_revolver
name = "tesla revolver"
desc = "A high-tech revolver that fires internal, reusable shock cartridges in a revolving cylinder. The cartridges can be recharged using conventional rechargers."
@@ -56,7 +56,6 @@
/datum/chemical_reaction/nitroglycerin
name = "Nitroglycerin"
id = "nitroglycerin"
result = "nitroglycerin"
required_reagents = list("glycerol" = 1, "facid" = 1, "sacid" = 1)
result_amount = 2
@@ -38,7 +38,7 @@
/datum/chemical_reaction/slimemonkey/on_reaction(datum/reagents/holder)
feedback_add_details("slime_cores_used","[type]")
for(var/i = 1, i <= 3, i++)
var /obj/item/reagent_containers/food/snacks/monkeycube/M = new /obj/item/reagent_containers/food/snacks/monkeycube
var/obj/item/reagent_containers/food/snacks/monkeycube/M = new /obj/item/reagent_containers/food/snacks/monkeycube
M.forceMove(get_turf(holder.my_atom))
//Green
@@ -5,6 +5,7 @@
icon_state = "mender"
item_state = "mender"
volume = 200
possible_transfer_amounts = null
resistance_flags = ACID_PROOF
container_type = REFILLABLE | AMOUNT_VISIBLE
temperature_min = 270
@@ -93,6 +94,20 @@
playsound(get_turf(src), pick('sound/goonstation/items/mender.ogg', 'sound/goonstation/items/mender2.ogg'), 50, 1)
/obj/item/reagent_containers/applicator/verb/empty()
set name = "Empty Applicator"
set category = "Object"
set src in usr
if(usr.incapacitated())
return
if(alert(usr, "Are you sure you want to empty [src]?", "Empty Applicator:", "Yes", "No") != "Yes")
return
if(!usr.incapacitated() && isturf(usr.loc) && loc == usr)
to_chat(usr, "<span class='notice'>You empty [src] onto the floor.</span>")
reagents.reaction(usr.loc)
reagents.clear_reagents()
/obj/item/reagent_containers/applicator/brute
name = "brute auto-mender"
list_reagents = list("styptic_powder" = 200)
@@ -104,3 +119,6 @@
/obj/item/reagent_containers/applicator/dual
name = "dual auto-mender"
list_reagents = list("synthflesh" = 200)
/obj/item/reagent_containers/applicator/dual/syndi // It magically goes through hardsuits. Don't ask how.
ignore_flags = TRUE
@@ -42,6 +42,13 @@
var/image/lid = image(icon, src, "lid_bottle")
overlays += lid
/obj/item/reagent_containers/glass/bottle/decompile_act(obj/item/matter_decompiler/C, mob/user)
if(!reagents.total_volume)
C.stored_comms["glass"] += 3
qdel(src)
return TRUE
return ..()
/obj/item/reagent_containers/glass/bottle/toxin
name = "toxin bottle"
desc = "A small bottle containing toxic compounds."
@@ -47,6 +47,9 @@
reagents.reaction(M, REAGENT_TOUCH)
reagents.clear_reagents()
else
if(!iscarbon(M)) // Non-carbons can't process reagents
to_chat(user, "<span class='warning'>You cannot find a way to feed [M].</span>")
return
if(M != user)
M.visible_message("<span class='danger'>[user] attempts to feed something to [M].</span>", \
"<span class='userdanger'>[user] attempts to feed something to you.</span>")
+1 -1
View File
@@ -265,7 +265,7 @@
update()
return
/obj/machinery/disposal/tgui_interact(mob/user, ui_key = "main", datum/tgui/ui = null, force_open = 0, datum/tgui/master_ui = null, datum/tgui_state/state = GLOB.tgui_default_state)
/obj/machinery/disposal/tgui_interact(mob/user, ui_key = "main", datum/tgui/ui = null, force_open = FALSE, datum/tgui/master_ui = null, datum/tgui_state/state = GLOB.tgui_default_state)
ui = SStgui.try_update_ui(user, src, ui_key, ui, force_open)
if(!ui)
ui = new(user, src, ui_key, "DisposalBin", name, 300, 250, master_ui, state)
@@ -948,8 +948,8 @@
category = list("Exosuit Equipment")
/datum/design/mech_grenade_launcher
name = "Exosuit Weapon (SGL-6 Grenade Launcher)"
desc = "Allows for the construction of SGL-6 Grenade Launcher."
name = "Exosuit Weapon (SGL-6 Flashbang Launcher)"
desc = "Allows for the construction of SGL-6 Flashbang Launcher."
id = "mech_grenade_launcher"
build_type = MECHFAB
req_tech = list("combat" = 4, "engineering" = 4)
@@ -123,10 +123,6 @@ GLOBAL_DATUM_INIT(security_announcement_down, /datum/announcement/priority/secur
FA.overlays.Cut()
FA.overlays += image('icons/obj/monitors.dmi', "overlay_delta")
if(level >= SEC_LEVEL_RED)
GLOB.atc.reroute_traffic(yes = TRUE) // Tell them fuck off we're busy.
else
GLOB.atc.reroute_traffic(yes = FALSE)
SSnightshift.check_nightshift(TRUE)
else

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