mirror of
https://github.com/Bubberstation/Bubberstation.git
synced 2026-08-26 06:29:23 +01:00
Merge branch 'master' of https://github.com/tgstation/-tg-station into NewPlants
Conflicts: icons/mob/head.dmi
This commit is contained in:
@@ -42,10 +42,15 @@ world/IsBanned(key,address,computer_id)
|
||||
return ..()
|
||||
|
||||
//Guest Checking
|
||||
if(!guests_allowed && IsGuestKey(key))
|
||||
log_access("Failed Login: [key] - Guests not allowed")
|
||||
message_admins("<span class='adminnotice'>Failed Login: [key] - Guests not allowed</span>")
|
||||
return list("reason"="guest", "desc"="\nReason: Guests not allowed. Please sign in with a byond account.")
|
||||
if(IsGuestKey(key))
|
||||
if (!guests_allowed)
|
||||
log_access("Failed Login: [key] - Guests not allowed")
|
||||
message_admins("<span class='adminnotice'>Failed Login: [key] - Guests not allowed</span>")
|
||||
return list("reason"="guest", "desc"="\nReason: Guests not allowed. Please sign in with a byond account.")
|
||||
if (config.panic_bunker && dbcon && dbcon.IsConnected())
|
||||
log_access("Failed Login: [key] - Guests not allowed during panic bunker")
|
||||
message_admins("<span class='adminnotice'>Failed Login: [key] - Guests not allowed during panic bunker</span>")
|
||||
return list("reason"="guest", "desc"="\nReason: Sorry but the server is currently not accepting connections from never before seen players or guests. If you have played on this server with a byond account before, please log in to the byond account you have played from.")
|
||||
|
||||
//Population Cap Checking
|
||||
if(config.extreme_popcap && living_player_count() >= config.extreme_popcap && !(ckey(key) in admin_datums))
|
||||
|
||||
@@ -815,22 +815,29 @@ var/global/floorIsLava = 0
|
||||
var/J_title = html_encode(job.title)
|
||||
var/J_opPos = html_encode(job.total_positions - (job.total_positions - job.current_positions))
|
||||
var/J_totPos = html_encode(job.total_positions)
|
||||
if(job.total_positions <= 0)
|
||||
dat += "[J_title]: [J_opPos]"
|
||||
if(job.total_positions < 0)
|
||||
dat += "[J_title]: [J_opPos] (unlimited)"
|
||||
else
|
||||
dat += "[J_title]: [J_opPos]/[J_totPos]"
|
||||
if(initial(job.total_positions) > 0)
|
||||
|
||||
if(job.title == "AI" || job.title == "Cyborg")
|
||||
dat += " (Cannot Late Join)<br>"
|
||||
continue
|
||||
if(job.total_positions >= 0)
|
||||
dat += " <A href='?src=\ref[src];addjobslot=[job.title]'>Add</A> | "
|
||||
if(job.total_positions > job.current_positions)
|
||||
dat += "<A href='?src=\ref[src];removejobslot=[job.title]'>Remove</A>"
|
||||
dat += "<A href='?src=\ref[src];removejobslot=[job.title]'>Remove</A> | "
|
||||
else
|
||||
dat += "Remove"
|
||||
dat += "Remove | "
|
||||
dat += "<A href='?src=\ref[src];unlimitjobslot=[job.title]'>Unlimit</A>"
|
||||
else
|
||||
dat += " <A href='?src=\ref[src];limitjobslot=[job.title]'>Limit</A>"
|
||||
dat += "<br>"
|
||||
|
||||
dat += "</body>"
|
||||
var/winheight = 100 + (count * 20)
|
||||
winheight = min(winheight, 690)
|
||||
usr << browse(dat, "window=players;size=316x[winheight]")
|
||||
usr << browse(dat, "window=players;size=375x[winheight]")
|
||||
|
||||
//
|
||||
//
|
||||
|
||||
@@ -100,7 +100,8 @@ var/list/admin_verbs_server = list(
|
||||
/datum/admins/proc/toggleAI,
|
||||
/client/proc/cmd_admin_delete, /*delete an instance/object/mob/etc*/
|
||||
/client/proc/cmd_debug_del_all,
|
||||
/client/proc/toggle_random_events
|
||||
/client/proc/toggle_random_events,
|
||||
/client/proc/panicbunker
|
||||
)
|
||||
var/list/admin_verbs_debug = list(
|
||||
/client/proc/restart_controller,
|
||||
@@ -190,7 +191,8 @@ var/list/admin_verbs_hideable = list(
|
||||
/proc/possess,
|
||||
/proc/release,
|
||||
/client/proc/reload_admins,
|
||||
/client/proc/reset_all_tcs
|
||||
/client/proc/reset_all_tcs,
|
||||
/client/proc/panicbunker
|
||||
)
|
||||
|
||||
/client/proc/add_admin_verbs()
|
||||
|
||||
@@ -1364,7 +1364,7 @@
|
||||
if (1) status = "<font color='orange'><b>Unconscious</b></font>"
|
||||
if (2) status = "<font color='red'><b>Dead</b></font>"
|
||||
health_description = "Status = [status]"
|
||||
health_description += "<BR>Oxy: [L.getOxyLoss()] - Tox: [L.getToxLoss()] - Fire: [L.getFireLoss()] - Brute: [L.getBruteLoss()] - Clone: [L.getCloneLoss()] - Brain: [L.getBrainLoss()]"
|
||||
health_description += "<BR>Oxy: [L.getOxyLoss()] - Tox: [L.getToxLoss()] - Fire: [L.getFireLoss()] - Brute: [L.getBruteLoss()] - Clone: [L.getCloneLoss()] - Brain: [L.getBrainLoss()] - Stamina: [L.getStaminaLoss()]"
|
||||
else
|
||||
health_description = "This mob type has no health to speak of."
|
||||
|
||||
@@ -1404,6 +1404,31 @@
|
||||
|
||||
src.manage_free_slots()
|
||||
|
||||
else if(href_list["unlimitjobslot"])
|
||||
if(!check_rights(R_ADMIN)) return
|
||||
|
||||
var/Unlimit = href_list["unlimitjobslot"]
|
||||
|
||||
for(var/datum/job/job in SSjob.occupations)
|
||||
if(job.title == Unlimit)
|
||||
job.total_positions = -1
|
||||
break
|
||||
|
||||
src.manage_free_slots()
|
||||
|
||||
else if(href_list["limitjobslot"])
|
||||
if(!check_rights(R_ADMIN)) return
|
||||
|
||||
var/Limit = href_list["limitjobslot"]
|
||||
|
||||
for(var/datum/job/job in SSjob.occupations)
|
||||
if(job.title == Limit)
|
||||
job.total_positions = job.current_positions
|
||||
break
|
||||
|
||||
src.manage_free_slots()
|
||||
|
||||
|
||||
else if(href_list["adminspawncookie"])
|
||||
if(!check_rights(R_ADMIN|R_FUN)) return
|
||||
|
||||
|
||||
@@ -85,9 +85,26 @@ var/list/adminhelp_ignored_words = list("unknown","the","a","an","of","monkey","
|
||||
if(!mob) return //this doesn't happen
|
||||
|
||||
var/ref_mob = "\ref[mob]"
|
||||
msg = "<span class='adminnotice'><b><font color=red>HELP: </font>[key_name(src, 1)] (<A HREF='?_src_=holder;adminmoreinfo=[ref_mob]'>?</A>) (<A HREF='?_src_=holder;adminplayeropts=[ref_mob]'>PP</A>) (<A HREF='?_src_=vars;Vars=[ref_mob]'>VV</A>) (<A HREF='?_src_=holder;subtlemessage=[ref_mob]'>SM</A>) (<A HREF='?_src_=holder;adminplayerobservejump=[ref_mob]'>JMP</A>) (<A HREF='?_src_=holder;secretsadmin=check_antagonist'>CA</A>) [ai_found ? " (<A HREF='?_src_=holder;adminchecklaws=[ref_mob]'>CL</A>)" : ""]:</b> [msg]</span>"
|
||||
msg = "<span class='adminnotice'><b><font color=red>HELP: </font>[key_name(src, 1)] (<A HREF='?_src_=holder;adminmoreinfo=[ref_mob]'>?</A>) (<A HREF='?_src_=holder;adminplayeropts=[ref_mob]'>PP</A>) (<A HREF='?_src_=vars;Vars=[ref_mob]'>VV</A>) (<A HREF='?_src_=holder;subtlemessage=[ref_mob]'>SM</A>) (<A HREF='?_src_=holder;adminplayerobservejump=[ref_mob]'>JMP</A>) (<A HREF='?_src_=holder;traitor=[ref_mob]'>TP</A>) [ai_found ? " (<A HREF='?_src_=holder;adminchecklaws=[ref_mob]'>CL</A>)" : ""]:</b> [msg]</span>"
|
||||
|
||||
//send this msg to all admins
|
||||
|
||||
for(var/client/X in admins)
|
||||
if(X.prefs.toggles & SOUND_ADMINHELP)
|
||||
X << 'sound/effects/adminhelp.ogg'
|
||||
X << msg
|
||||
|
||||
|
||||
//show it to the person adminhelping too
|
||||
src << "<span class='adminnotice'>PM to-<b>Admins</b>: [original_msg]</span>"
|
||||
|
||||
//send it to irc if nobody is on and tell us how many were on
|
||||
var/admin_number_present = send2irc_adminless_only(original_msg)
|
||||
log_admin("HELP: [key_name(src)]: [original_msg] - heard by [admin_number_present] non-AFK admins who have +BAN.")
|
||||
feedback_add_details("admin_verb","AH") //If you are copy-pasting this, ensure the 2nd parameter is unique to the new proc!
|
||||
return
|
||||
|
||||
proc/send2irc_adminless_only(source, msg, requiredflags = R_BAN)
|
||||
var/admin_number_total = 0 //Total number of admins
|
||||
var/admin_number_afk = 0 //Holds the number of admins who are afk
|
||||
var/admin_number_ignored = 0 //Holds the number of admins without +BAN (so admins who are not really admins)
|
||||
@@ -95,30 +112,24 @@ var/list/adminhelp_ignored_words = list("unknown","the","a","an","of","monkey","
|
||||
for(var/client/X in admins)
|
||||
admin_number_total++;
|
||||
var/invalid = 0
|
||||
if(!check_rights_for(X, R_BAN))
|
||||
if(requiredflags != 0 && !check_rights_for(X, requiredflags))
|
||||
admin_number_ignored++
|
||||
invalid = 1
|
||||
if(X.is_afk())
|
||||
admin_number_afk++
|
||||
invalid = 1
|
||||
if(X.holder.fakekey)
|
||||
admin_number_ignored++
|
||||
invalid = 1
|
||||
if(invalid)
|
||||
admin_number_decrease++
|
||||
if(X.prefs.toggles & SOUND_ADMINHELP)
|
||||
X << 'sound/effects/adminhelp.ogg'
|
||||
X << msg
|
||||
|
||||
//show it to the person adminhelping too
|
||||
src << "<span class='adminnotice'>PM to-<b>Admins</b>: [original_msg]</span>"
|
||||
|
||||
var/admin_number_present = admin_number_total - admin_number_decrease //Number of admins who are neither afk nor invalid
|
||||
log_admin("HELP: [key_name(src)]: [original_msg] - heard by [admin_number_present] non-AFK admins who have +BAN.")
|
||||
if(admin_number_present <= 0)
|
||||
if(!admin_number_afk && !admin_number_ignored)
|
||||
send2irc(ckey, "[original_msg] - No admins online")
|
||||
send2irc(source, "[msg] - No admins online")
|
||||
else
|
||||
send2irc(ckey, "[original_msg] - All admins AFK ([admin_number_afk]/[admin_number_total]) or skipped ([admin_number_ignored]/[admin_number_total])")
|
||||
feedback_add_details("admin_verb","AH") //If you are copy-pasting this, ensure the 2nd parameter is unique to the new proc!
|
||||
return
|
||||
send2irc(source, "[msg] - All admins AFK ([admin_number_afk]/[admin_number_total]) or skipped ([admin_number_ignored]/[admin_number_total])")
|
||||
return admin_number_present
|
||||
|
||||
proc/send2irc(msg,msg2)
|
||||
if(config.useircbot)
|
||||
|
||||
@@ -0,0 +1,15 @@
|
||||
/client/proc/panicbunker()
|
||||
set category = "Server"
|
||||
set name = "Toggle Panic Bunker"
|
||||
if (!config.sql_enabled)
|
||||
usr << "<span class='adminnotice'>The Database is not enabled!</span>"
|
||||
return
|
||||
|
||||
config.panic_bunker = (!config.panic_bunker)
|
||||
|
||||
log_admin("[key_name(usr)] has toggled the Panic Bunker, it is now [(config.panic_bunker?"on":"off")]")
|
||||
message_admins("[key_name_admin(usr)] has toggled the Panic Bunker, it is now [(config.panic_bunker?"enabled":"disabled")].")
|
||||
if (config.panic_bunker && (!dbcon || !dbcon.IsConnected()))
|
||||
message_admins("The Database is not connected! Panic bunker will not work until the connection is reestablished.")
|
||||
feedback_add_details("admin_verb","PANIC") //If you are copy-pasting this, ensure the 2nd parameter is unique to the new proc!
|
||||
|
||||
@@ -17,7 +17,7 @@
|
||||
return
|
||||
|
||||
var/image/cross = image('icons/obj/storage.dmi',"bible")
|
||||
msg = "<span class='adminnotice'>\icon[cross] <b><font color=purple>PRAY: </font>[key_name(src, 1)] (<A HREF='?_src_=holder;adminmoreinfo=\ref[src]'>?</A>) (<A HREF='?_src_=holder;adminplayeropts=\ref[src]'>PP</A>) (<A HREF='?_src_=vars;Vars=\ref[src]'>VV</A>) (<A HREF='?_src_=holder;subtlemessage=\ref[src]'>SM</A>) (<A HREF='?_src_=holder;adminplayerobservejump=\ref[src]'>JMP</A>) (<A HREF='?_src_=holder;secretsadmin=check_antagonist'>CA</A>) (<A HREF='?_src_=holder;adminspawncookie=\ref[src]'>SC</a>):</b> [msg]</span>"
|
||||
msg = "<span class='adminnotice'>\icon[cross] <b><font color=purple>PRAY: </font>[key_name(src, 1)] (<A HREF='?_src_=holder;adminmoreinfo=\ref[src]'>?</A>) (<A HREF='?_src_=holder;adminplayeropts=\ref[src]'>PP</A>) (<A HREF='?_src_=vars;Vars=\ref[src]'>VV</A>) (<A HREF='?_src_=holder;subtlemessage=\ref[src]'>SM</A>) (<A HREF='?_src_=holder;adminplayerobservejump=\ref[src]'>JMP</A>) (<A HREF='?_src_=holder;traitor=\ref[src]'>TP</A>) (<A HREF='?_src_=holder;adminspawncookie=\ref[src]'>SC</a>):</b> [msg]</span>"
|
||||
|
||||
for(var/client/C in admins)
|
||||
if(C.prefs.toggles & CHAT_PRAYER)
|
||||
@@ -29,16 +29,16 @@
|
||||
|
||||
/proc/Centcomm_announce(var/text , var/mob/Sender)
|
||||
var/msg = copytext(sanitize(text), 1, MAX_MESSAGE_LEN)
|
||||
msg = "<span class='adminnotice'> <b><font color=orange>CENTCOM:</font>[key_name(Sender, 1)] (<A HREF='?_src_=holder;adminmoreinfo=\ref[Sender]'>?</A>) (<A HREF='?_src_=holder;adminplayeropts=\ref[Sender]'>PP</A>) (<A HREF='?_src_=vars;Vars=\ref[Sender]'>VV</A>) (<A HREF='?_src_=holder;subtlemessage=\ref[Sender]'>SM</A>) (<A HREF='?_src_=holder;adminplayerobservejump=\ref[Sender]'>JMP</A>) (<A HREF='?_src_=holder;secretsadmin=check_antagonist'>CA</A>) (<A HREF='?_src_=holder;BlueSpaceArtillery=\ref[Sender]'>BSA</A>) (<A HREF='?_src_=holder;CentcommReply=\ref[Sender]'>RPLY</A>):</b> [msg]</span>"
|
||||
msg = "<span class='adminnotice'> <b><font color=orange>CENTCOM:</font>[key_name(Sender, 1)] (<A HREF='?_src_=holder;adminmoreinfo=\ref[Sender]'>?</A>) (<A HREF='?_src_=holder;adminplayeropts=\ref[Sender]'>PP</A>) (<A HREF='?_src_=vars;Vars=\ref[Sender]'>VV</A>) (<A HREF='?_src_=holder;subtlemessage=\ref[Sender]'>SM</A>) (<A HREF='?_src_=holder;adminplayerobservejump=\ref[Sender]'>JMP</A>) (<A HREF='?_src_=holder;traitor=\ref[Sender]'>TP</A>) (<A HREF='?_src_=holder;BlueSpaceArtillery=\ref[Sender]'>BSA</A>) (<A HREF='?_src_=holder;CentcommReply=\ref[Sender]'>RPLY</A>):</b> [msg]</span>"
|
||||
admins << msg
|
||||
|
||||
/proc/Syndicate_announce(var/text , var/mob/Sender)
|
||||
var/msg = copytext(sanitize(text), 1, MAX_MESSAGE_LEN)
|
||||
msg = "<span class='adminnotice'><b><font color=crimson>SYNDICATE:</font>[key_name(Sender, 1)] (<A HREF='?_src_=holder;adminmoreinfo=\ref[Sender]'>?</A>) (<A HREF='?_src_=holder;adminplayeropts=\ref[Sender]'>PP</A>) (<A HREF='?_src_=vars;Vars=\ref[Sender]'>VV</A>) (<A HREF='?_src_=holder;subtlemessage=\ref[Sender]'>SM</A>) (<A HREF='?_src_=holder;adminplayerobservejump=\ref[Sender]'>JMP</A>) (<A HREF='?_src_=holder;secretsadmin=check_antagonist'>CA</A>) (<A HREF='?_src_=holder;BlueSpaceArtillery=\ref[Sender]'>BSA</A>) (<A HREF='?_src_=holder;SyndicateReply=\ref[Sender]'>RPLY</A>):</b> [msg]</span>"
|
||||
msg = "<span class='adminnotice'><b><font color=crimson>SYNDICATE:</font>[key_name(Sender, 1)] (<A HREF='?_src_=holder;adminmoreinfo=\ref[Sender]'>?</A>) (<A HREF='?_src_=holder;adminplayeropts=\ref[Sender]'>PP</A>) (<A HREF='?_src_=vars;Vars=\ref[Sender]'>VV</A>) (<A HREF='?_src_=holder;subtlemessage=\ref[Sender]'>SM</A>) (<A HREF='?_src_=holder;adminplayerobservejump=\ref[Sender]'>JMP</A>) (<A HREF='?_src_=holder;traitor=\ref[Sender]'>TP</A>) (<A HREF='?_src_=holder;BlueSpaceArtillery=\ref[Sender]'>BSA</A>) (<A HREF='?_src_=holder;SyndicateReply=\ref[Sender]'>RPLY</A>):</b> [msg]</span>"
|
||||
admins << msg
|
||||
|
||||
/proc/Nuke_request(var/text , var/mob/Sender)
|
||||
var/msg = copytext(sanitize(text), 1, MAX_MESSAGE_LEN)
|
||||
msg = "<span class='adminnotice'> <b><font color=orange>NUKE CODE REQUEST:</font>[key_name(Sender, 1)] (<A HREF='?_src_=holder;adminmoreinfo=\ref[Sender]'>?</A>) (<A HREF='?_src_=holder;adminplayeropts=\ref[Sender]'>PP</A>) (<A HREF='?_src_=vars;Vars=\ref[Sender]'>VV</A>) (<A HREF='?_src_=holder;subtlemessage=\ref[Sender]'>SM</A>) (<A HREF='?_src_=holder;adminplayerobservejump=\ref[Sender]'>JMP</A>) (<A HREF='?_src_=holder;secretsadmin=check_antagonist'>CA</A>) (<A HREF='?_src_=holder;BlueSpaceArtillery=\ref[Sender]'>BSA</A>) (<A HREF='?_src_=holder;CentcommReply=\ref[Sender]'>RPLY</A>):</b> [msg]</span>"
|
||||
msg = "<span class='adminnotice'> <b><font color=orange>NUKE CODE REQUEST:</font>[key_name(Sender, 1)] (<A HREF='?_src_=holder;adminmoreinfo=\ref[Sender]'>?</A>) (<A HREF='?_src_=holder;adminplayeropts=\ref[Sender]'>PP</A>) (<A HREF='?_src_=vars;Vars=\ref[Sender]'>VV</A>) (<A HREF='?_src_=holder;subtlemessage=\ref[Sender]'>SM</A>) (<A HREF='?_src_=holder;adminplayerobservejump=\ref[Sender]'>JMP</A>) (<A HREF='?_src_=holder;traitor=\ref[Sender]'>TP</A>) (<A HREF='?_src_=holder;BlueSpaceArtillery=\ref[Sender]'>BSA</A>) (<A HREF='?_src_=holder;CentcommReply=\ref[Sender]'>RPLY</A>):</b> [msg]</span>"
|
||||
admins << msg
|
||||
admins << "<span class='adminnotice'><b>At this current time, the nuke must have the code manually set via varedit.</b></span>"
|
||||
@@ -90,7 +90,9 @@ var/list/external_rsc_urls
|
||||
var/next_external_rsc = 0
|
||||
#endif
|
||||
|
||||
|
||||
/client/New(TopicData)
|
||||
|
||||
TopicData = null //Prevent calls to client.Topic from connect
|
||||
|
||||
if(connection != "seeker") //Invalid connection type.
|
||||
@@ -136,6 +138,25 @@ var/next_external_rsc = 0
|
||||
add_verbs_from_config()
|
||||
set_client_age_from_db()
|
||||
|
||||
if (isnum(player_age) && player_age == -1) //first connection
|
||||
if (config.panic_bunker && !holder && !(ckey in deadmins))
|
||||
log_access("Failed Login: [key] - New account attempting to connect during panic bunker")
|
||||
message_admins("<span class='adminnotice'>Failed Login: [key] - New account attempting to connect during panic bunker</span>")
|
||||
src << "Sorry but the server is currently not accepting connections from never before seen players."
|
||||
del(src)
|
||||
return 0
|
||||
|
||||
if (config.notify_new_player_age >= 0)
|
||||
message_admins("New user: [key_name_admin(src)] is connecting here for the first time.")
|
||||
if (config.irc_first_connection_alert)
|
||||
send2irc_adminless_only("New user", "[key_name(src)] is connecting for the first time!")
|
||||
|
||||
player_age = 0 // set it from -1 to 0 so the job selection code doesn't have a panic attack
|
||||
|
||||
else if (isnum(player_age) && player_age < config.notify_new_player_age)
|
||||
message_admins("New user: [key_name_admin(src)] just connected with an age of [player_age] day[(player_age==1?"":"s")]")
|
||||
|
||||
|
||||
if (!ticker || ticker.current_state == GAME_STATE_PREGAME)
|
||||
spawn (rand(10,150))
|
||||
if (src)
|
||||
@@ -146,7 +167,7 @@ var/next_external_rsc = 0
|
||||
send_resources()
|
||||
|
||||
if(prefs.lastchangelog != changelog_hash) //bolds the changelog button on the interface so we know there are updates.
|
||||
winset(src, "rpane.changelog", "background-color=#eaeaea;font-style=bold")
|
||||
winset(src, "rpane.changelogb", "background-color=#eaeaea;font-style=bold")
|
||||
|
||||
|
||||
//////////////
|
||||
@@ -172,14 +193,15 @@ var/next_external_rsc = 0
|
||||
var/sql_ckey = sanitizeSQL(src.ckey)
|
||||
|
||||
var/DBQuery/query = dbcon.NewQuery("SELECT id, datediff(Now(),firstseen) as age FROM [format_table_name("player")] WHERE ckey = '[sql_ckey]'")
|
||||
query.Execute()
|
||||
if (!query.Execute())
|
||||
return
|
||||
|
||||
while (query.NextRow())
|
||||
player_age = text2num(query.item[2])
|
||||
return
|
||||
//player not found.
|
||||
player_age = 0
|
||||
message_admins("[key_name_admin(src)] is connecting here for the first time.")
|
||||
|
||||
//no match mark it as a first connection for use in client/New()
|
||||
player_age = -1
|
||||
|
||||
|
||||
/client/proc/sync_client_with_db()
|
||||
@@ -239,25 +261,9 @@ var/next_external_rsc = 0
|
||||
|
||||
//send resources to the client. It's here in its own proc so we can move it around easiliy if need be
|
||||
/client/proc/send_resources()
|
||||
//Send nanoui files to client
|
||||
SSnano.send_resources(src)
|
||||
getFiles(
|
||||
'nano/js/libraries.min.js',
|
||||
'nano/js/nano_update.js',
|
||||
'nano/js/nano_config.js',
|
||||
'nano/js/nano_base_helpers.js',
|
||||
'nano/css/shared.css',
|
||||
'nano/css/icons.css',
|
||||
'nano/templates/chem_dispenser.tmpl',
|
||||
'nano/templates/chem_heater.tmpl',
|
||||
'nano/templates/smes.tmpl',
|
||||
'nano/templates/apc.tmpl',
|
||||
'nano/templates/cryo.tmpl',
|
||||
'nano/templates/solar_control.tmpl',
|
||||
'nano/images/uiBackground.png',
|
||||
'nano/images/uiIcons16.png',
|
||||
'nano/images/uiIcons24.png',
|
||||
'nano/images/uiLinkPendingIcon.gif',
|
||||
'nano/images/uiNoticeBackground.jpg',
|
||||
'nano/images/uiTitleFluff.png',
|
||||
'html/search.js',
|
||||
'html/panels.css',
|
||||
'html/browser/common.css',
|
||||
|
||||
@@ -39,6 +39,7 @@ datum/preferences
|
||||
var/UI_style = "Midnight"
|
||||
var/toggles = TOGGLES_DEFAULT
|
||||
var/ghost_form = "ghost"
|
||||
var/allow_midround_antag = 1
|
||||
|
||||
//character preferences
|
||||
var/real_name //our character's name
|
||||
@@ -226,7 +227,7 @@ datum/preferences
|
||||
dat += "<b>Ghost sight:</b> <a href='?_src_=prefs;preference=ghost_sight'>[(toggles & CHAT_GHOSTSIGHT) ? "Nearest Creatures" : "All Emotes"]</a><br>"
|
||||
dat += "<b>Ghost whispers:</b> <a href='?_src_=prefs;preference=ghost_whispers'>[(toggles & CHAT_GHOSTWHISPER) ? "Nearest Creatures" : "All Speech"]</a><br>"
|
||||
dat += "<b>Pull requests:</b> <a href='?_src_=prefs;preference=pull_requests'>[(toggles & CHAT_PULLR) ? "Yes" : "No"]</a><br>"
|
||||
|
||||
dat += "<b>Midround Antagonist:</b> <a href='?_src_=prefs;preference=allow_midround_antag'>[(toggles & MIDROUND_ANTAG) ? "Yes" : "No"]</a><br>"
|
||||
if(config.allow_Metadata)
|
||||
dat += "<b>OOC Notes:</b> <a href='?_src_=prefs;preference=metadata;task=input'> Edit </a><br>"
|
||||
|
||||
@@ -785,6 +786,9 @@ datum/preferences
|
||||
if("pull_requests")
|
||||
toggles ^= CHAT_PULLR
|
||||
|
||||
if("allow_midround_antag")
|
||||
toggles ^= MIDROUND_ANTAG
|
||||
|
||||
if("save")
|
||||
save_preferences()
|
||||
save_character()
|
||||
|
||||
@@ -73,6 +73,15 @@
|
||||
src << "You will [(prefs.toggles & CHAT_PULLR) ? "now" : "no longer"] see new pull request announcements."
|
||||
feedback_add_details("admin_verb","TPullR") //If you are copy-pasting this, ensure the 2nd parameter is unique to the new proc!
|
||||
|
||||
/client/verb/togglemidroundantag()
|
||||
set name = "Toggle Midround Antagonist"
|
||||
set category = "Preferences"
|
||||
set desc = "Toggles whether or not you will be considered for antagonist status given during a round."
|
||||
prefs.toggles ^= MIDROUND_ANTAG
|
||||
prefs.save_preferences()
|
||||
src << "You will [(prefs.toggles & MIDROUND_ANTAG) ? "now" : "no longer"] be considered for midround antagonist positions."
|
||||
feedback_add_details("admin_verb","TMidroundA") //If you are copy-pasting this, ensure the 2nd parameter is unique to the new proc!
|
||||
|
||||
/client/verb/toggletitlemusic()
|
||||
set name = "Hear/Silence LobbyMusic"
|
||||
set category = "Preferences"
|
||||
|
||||
@@ -7,7 +7,7 @@
|
||||
var/visor_flags_inv = 0 // same as visor_flags, but for flags_inv
|
||||
lefthand_file = 'icons/mob/inhands/clothing_lefthand.dmi'
|
||||
righthand_file = 'icons/mob/inhands/clothing_righthand.dmi'
|
||||
|
||||
var/alt_desc = null
|
||||
|
||||
//Ears: currently only used for headsets and earmuffs
|
||||
/obj/item/clothing/ears
|
||||
@@ -191,7 +191,6 @@ BLIND // can't see anything
|
||||
strip_delay = 80
|
||||
put_on_delay = 80
|
||||
|
||||
|
||||
//Under clothing
|
||||
/obj/item/clothing/under
|
||||
icon = 'icons/obj/clothing/uniforms.dmi'
|
||||
|
||||
@@ -144,6 +144,14 @@
|
||||
flags = BLOCKHAIR
|
||||
flags_inv = HIDEMASK|HIDEEARS|HIDEEYES|HIDEFACE
|
||||
|
||||
/obj/item/clothing/head/griffin
|
||||
name = "griffon head"
|
||||
desc = "Why not 'eagle head'? Who knows."
|
||||
icon_state = "griffinhat"
|
||||
item_state = "griffinhat"
|
||||
flags = BLOCKHAIR
|
||||
flags_inv = HIDEMASK|HIDEEARS|HIDEEYES|HIDEFACE
|
||||
|
||||
/obj/item/clothing/head/bearpelt
|
||||
name = "bear pelt hat"
|
||||
desc = "Fuzzy."
|
||||
|
||||
@@ -137,4 +137,10 @@
|
||||
icon_state = "roman"
|
||||
item_state = "roman"
|
||||
strip_delay = 100
|
||||
put_on_delay = 100
|
||||
put_on_delay = 100
|
||||
|
||||
/obj/item/clothing/shoes/griffin
|
||||
name = "griffon boots"
|
||||
desc = "A pair of costume boots fashioned after bird talons."
|
||||
icon_state = "griffinboots"
|
||||
item_state = "griffinboots"
|
||||
@@ -116,6 +116,7 @@
|
||||
/obj/item/clothing/head/helmet/space/hardsuit/syndi
|
||||
name = "blood-red hardsuit helmet"
|
||||
desc = "A dual-mode advanced helmet designed for work in special operations. It is in travel mode. Property of Gorlex Marauders."
|
||||
alt_desc = "A dual-mode advanced helmet designed for work in special operations. It is in combat mode. Property of Gorlex Marauders."
|
||||
icon_state = "hardsuit1-syndi"
|
||||
item_state = "syndie_helm"
|
||||
item_color = "syndi"
|
||||
@@ -134,16 +135,16 @@
|
||||
on = !on
|
||||
if(on)
|
||||
user << "<span class='notice'>You switch your helmet to travel mode.</span>"
|
||||
name = "blood-red hardsuit helmet"
|
||||
desc = "A dual-mode advanced helmet designed for work in special operations. It is in travel mode. Property of Gorlex Marauders."
|
||||
name = initial(name)
|
||||
desc = initial(desc)
|
||||
flags = HEADCOVERSEYES | BLOCKHAIR | HEADCOVERSMOUTH | STOPSPRESSUREDMAGE | THICKMATERIAL
|
||||
flags_inv = HIDEMASK|HIDEEARS|HIDEEYES|HIDEFACE
|
||||
cold_protection = HEAD
|
||||
user.AddLuminosity(brightness_on)
|
||||
else
|
||||
user << "<span class='notice'>You switch your helmet to combat mode.</span>"
|
||||
name = "blood-red hardsuit helmet (combat)"
|
||||
desc = "A dual-mode advanced helmet designed for work in special operations. It is in combat mode. Property of Gorlex Marauders."
|
||||
name += " (combat)"
|
||||
desc = alt_desc
|
||||
flags = BLOCKHAIR
|
||||
flags_inv = HIDEEARS
|
||||
cold_protection = null
|
||||
@@ -156,6 +157,7 @@
|
||||
/obj/item/clothing/suit/space/hardsuit/syndi
|
||||
name = "blood-red hardsuit"
|
||||
desc = "A dual-mode advanced hardsuit designed for work in special operations. It is in travel mode. Property of Gorlex Marauders."
|
||||
alt_desc = "A dual-mode advanced hardsuit designed for work in special operations. It is in combat mode. Property of Gorlex Marauders."
|
||||
icon_state = "hardsuit1-syndi"
|
||||
item_state = "syndie_hardsuit"
|
||||
item_color = "syndi"
|
||||
@@ -174,16 +176,16 @@
|
||||
on = !on
|
||||
if(on)
|
||||
user << "<span class='notice'>You switch your hardsuit to travel mode.</span>"
|
||||
name = "blood-red hardsuit helmet"
|
||||
desc = "A dual-mode advanced hardsuit designed for work in special operations. It is in travel mode. Property of Gorlex Marauders."
|
||||
name = initial(name)
|
||||
desc = initial(desc)
|
||||
slowdown = 1
|
||||
flags = STOPSPRESSUREDMAGE | THICKMATERIAL
|
||||
flags_inv = HIDEGLOVES|HIDESHOES|HIDEJUMPSUIT
|
||||
cold_protection = CHEST | GROIN | LEGS | FEET | ARMS | HANDS
|
||||
else
|
||||
user << "<span class='notice'>You switch your hardsuit to combat mode.</span>"
|
||||
name = "blood-red hardsuit helmet (combat)"
|
||||
desc = "A dual-mode advanced hardsuit designed for work in special operations. It is in combat mode. Property of Gorlex Marauders."
|
||||
name += " (combat)"
|
||||
desc = alt_desc
|
||||
slowdown = 0
|
||||
flags = BLOCKHAIR
|
||||
flags_inv = null
|
||||
@@ -194,6 +196,26 @@
|
||||
user.update_inv_wear_suit()
|
||||
user.update_inv_w_uniform()
|
||||
|
||||
//The Owl Hardsuit
|
||||
/obj/item/clothing/head/helmet/space/hardsuit/syndi/owl
|
||||
name = "owl hardsuit helmet"
|
||||
desc = "A dual-mode advanced helmet designed for any crime-fighting situation. It is in travel mode."
|
||||
alt_desc = "A dual-mode advanced helmet designed for any crime-fighting situation. It is in combat mode."
|
||||
icon_state = "hardsuit1-owl"
|
||||
item_state = "s_helmet"
|
||||
item_color = "owl"
|
||||
|
||||
/obj/item/clothing/suit/space/hardsuit/syndi/owl
|
||||
name = "owl hardsuit"
|
||||
desc = "A dual-mode advanced hardsuit designed for any crime-fighting situation. It is in travel mode."
|
||||
alt_desc = "A dual-mode advanced hardsuit designed for any crime-fighting situation. It is in combat mode."
|
||||
icon_state = "hardsuit1-owl"
|
||||
item_state = "s_suit"
|
||||
item_color = "owl"
|
||||
|
||||
/obj/item/clothing/head/helmet/space/hardsuit/syndi/update_icon()
|
||||
icon_state = "hardsuit[on]-[item_color]"
|
||||
|
||||
|
||||
//Wizard hardsuit
|
||||
/obj/item/clothing/head/helmet/space/hardsuit/wizard
|
||||
|
||||
@@ -126,6 +126,22 @@
|
||||
body_parts_covered = CHEST|ARMS|GROIN|LEGS|FEET|HANDS
|
||||
flags_inv = HIDEGLOVES|HIDESHOES|HIDEJUMPSUIT
|
||||
|
||||
/obj/item/clothing/suit/toggle/owlwings
|
||||
name = "owl cloak"
|
||||
desc = "A soft brown cloak made of synthetic feathers. Soft to the touch, stylish, and a 2 meter wing span that will drive the ladies mad."
|
||||
icon_state = "owl_wings"
|
||||
item_state = "owl_wings"
|
||||
togglename = "wings"
|
||||
body_parts_covered = ARMS|CHEST
|
||||
allowed = list(/obj/item/weapon/gun/energy,/obj/item/weapon/reagent_containers/spray/pepper,/obj/item/weapon/gun/projectile,/obj/item/ammo_box,/obj/item/ammo_casing,/obj/item/weapon/melee/baton,/obj/item/weapon/restraints/handcuffs,/obj/item/device/flashlight/seclite,/obj/item/weapon/melee/classic_baton/telescopic)
|
||||
action_button_name = "Toggle Owl Wings"
|
||||
|
||||
/obj/item/clothing/suit/toggle/owlwings/griffinwings
|
||||
name = "griffon cloak"
|
||||
desc = "A plush white cloak made of synthetic feathers. Soft to the touch, stylish, and a 2 meter wing span that will drive your captives mad."
|
||||
icon_state = "griffin_wings"
|
||||
item_state = "griffin_wings"
|
||||
|
||||
|
||||
/obj/item/clothing/suit/holidaypriest
|
||||
name = "holiday priest"
|
||||
|
||||
@@ -128,11 +128,18 @@
|
||||
|
||||
/obj/item/clothing/under/owl
|
||||
name = "owl uniform"
|
||||
desc = "A jumpsuit with owl wings. Photorealistic owl feathers! Twooooo!"
|
||||
desc = "A soft brown jumpsuit made of synthetic feathers and strong conviction."
|
||||
icon_state = "owl"
|
||||
item_color = "owl"
|
||||
can_adjust = 0
|
||||
|
||||
/obj/item/clothing/under/griffin
|
||||
name = "griffon uniform"
|
||||
desc = "A soft brown jumpsuit with a white feather collar made of synthetic feathers and a lust for mayhem."
|
||||
icon_state = "griffin"
|
||||
item_color = "griffin"
|
||||
can_adjust = 0
|
||||
|
||||
/obj/item/clothing/under/rainbow
|
||||
name = "rainbow"
|
||||
desc = "rainbow"
|
||||
|
||||
@@ -518,7 +518,7 @@
|
||||
name = "shot of nothing"
|
||||
desc = "The mime insists there's booze in the glass. You're not so sure."
|
||||
if ("goldschlager")
|
||||
icon_state = "shotglassschlag"
|
||||
icon_state = "shotglassgold"
|
||||
name = "shot of goldschlager"
|
||||
desc = "Yup. You're officially a college girl."
|
||||
if ("cognac")
|
||||
|
||||
@@ -168,7 +168,7 @@
|
||||
/obj/item/weapon/reagent_containers/food/snacks/grown/harebell
|
||||
seed = /obj/item/seeds/harebell
|
||||
name = "harebell"
|
||||
desc = "\"I'll sweeten thy sad grave: thou shalt not lack the flower that's like thy face, pale primrose, nor the azured hare-bell, like thy veins; no, nor the leaf of eglantine, whom not to slander, out-sweeten’d not thy breath.\""
|
||||
desc = "\"I'll sweeten thy sad grave: thou shalt not lack the flower that's like thy face, pale primrose, nor the azured hare-bell, like thy veins; no, nor the leaf of eglantine, whom not to slander, out-sweeten’d not thy breath.\""
|
||||
icon_state = "harebell"
|
||||
slot_flags = SLOT_HEAD
|
||||
filling_color = "#E6E6FA"
|
||||
@@ -392,7 +392,6 @@
|
||||
..()
|
||||
reagents.add_reagent("omnizine", 1 + round(potency / 8, 1))
|
||||
reagents.add_reagent("synaptizine", 1 + round(potency / 8, 1))
|
||||
reagents.add_reagent("morphine", 1 + round(potency / 10, 1))
|
||||
reagents.add_reagent("space_drugs", 1 + round(potency / 10, 1))
|
||||
reagents.add_reagent("vitamin", 1 + round((potency / 25), 1))
|
||||
|
||||
|
||||
@@ -842,7 +842,7 @@ obj/machinery/hydroponics/attackby(var/obj/item/O as obj, var/mob/user as mob, p
|
||||
podman.ckey = ckey_holder
|
||||
podman.gender = blood_gender
|
||||
podman.faction |= factions
|
||||
hardset_dna(podman,null,null,podman.real_name,blood_type,/datum/species/plant/pod,"#59CE00")//Discard SE's and UI's, podman cloning is inaccurate, and always make them a podman
|
||||
hardset_dna(podman,null,null,podman.real_name,blood_type,/datum/species/plant/pod)//Discard SE's and UI's, podman cloning is inaccurate, and always make them a podman
|
||||
podman.set_cloned_appearance()
|
||||
|
||||
else //else, one packet of seeds. maybe two
|
||||
|
||||
@@ -2,4 +2,10 @@
|
||||
..()
|
||||
if(client.prefs.unlock_content)
|
||||
icon_state = client.prefs.ghost_form
|
||||
if (ghostimage)
|
||||
ghostimage.icon_state = src.icon_state
|
||||
|
||||
updateghostimages()
|
||||
|
||||
|
||||
update_interface()
|
||||
@@ -1,4 +1,6 @@
|
||||
/mob/dead/observer/Logout()
|
||||
if (client)
|
||||
client.images -= ghost_darkness_images
|
||||
..()
|
||||
spawn(0)
|
||||
if(src && !key) //we've transferred to another mob. This ghost should be deleted.
|
||||
|
||||
@@ -1,9 +1,10 @@
|
||||
var/list/image/ghost_darkness_images = list() //this is a list of images for things ghosts should still be able to see when they toggle darkness
|
||||
/mob/dead/observer
|
||||
name = "ghost"
|
||||
desc = "It's a g-g-g-g-ghooooost!" //jinkies!
|
||||
icon = 'icons/mob/mob.dmi'
|
||||
icon_state = "ghost"
|
||||
layer = 4
|
||||
layer = MOB_LAYER + 1
|
||||
stat = DEAD
|
||||
density = 0
|
||||
canmove = 0
|
||||
@@ -18,6 +19,9 @@
|
||||
//Note that this is not a reliable way to determine if admins started as observers, since they change mobs a lot.
|
||||
var/atom/movable/following = null
|
||||
var/fun_verbs = 0
|
||||
var/image/ghostimage = null //this mobs ghost image, for deleting and stuff
|
||||
var/ghostvision = 1 //is the ghost able to see things humans can't?
|
||||
var/seedarkness = 1
|
||||
|
||||
/mob/dead/observer/New(mob/body)
|
||||
sight |= SEE_TURFS | SEE_MOBS | SEE_OBJS | SEE_SELF
|
||||
@@ -26,6 +30,9 @@
|
||||
verbs += /mob/dead/observer/proc/dead_tele
|
||||
stat = DEAD
|
||||
|
||||
ghostimage = image(src.icon,src,src.icon_state)
|
||||
ghost_darkness_images |= ghostimage
|
||||
updateallghostimages()
|
||||
var/turf/T
|
||||
if(ismob(body))
|
||||
T = get_turf(body) //Where is the body located?
|
||||
@@ -55,6 +62,14 @@
|
||||
|
||||
animate(src, pixel_y = 2, time = 10, loop = -1)
|
||||
|
||||
|
||||
..()
|
||||
/mob/dead/observer/Destroy()
|
||||
if (ghostimage)
|
||||
ghost_darkness_images -= ghostimage
|
||||
qdel(ghostimage)
|
||||
ghostimage = null
|
||||
updateallghostimages()
|
||||
..()
|
||||
|
||||
/mob/dead/CanPass(atom/movable/mover, turf/target, height=0)
|
||||
@@ -254,14 +269,43 @@ This is the proc mobs get to turn into a ghost. Forked from ghostize due to comp
|
||||
set hidden = 1
|
||||
src << "<span class='danger'>You are dead! You have no mind to store memory!</span>"
|
||||
|
||||
/mob/dead/observer/verb/toggle_ghostsee()
|
||||
set name = "Toggle Ghost Vision"
|
||||
set desc = "Toggles your ability to see things only ghosts can see, like other ghosts"
|
||||
set category = "Ghost"
|
||||
ghostvision = !(ghostvision)
|
||||
updateghostsight()
|
||||
usr << "You [(ghostvision?"now":"no longer")] have ghost vision."
|
||||
|
||||
/mob/dead/observer/verb/toggle_darkness()
|
||||
set name = "Toggle Darkness"
|
||||
set category = "Ghost"
|
||||
seedarkness = !(seedarkness)
|
||||
updateghostsight()
|
||||
|
||||
if (see_invisible == SEE_INVISIBLE_OBSERVER_NOLIGHTING)
|
||||
see_invisible = SEE_INVISIBLE_OBSERVER
|
||||
else
|
||||
/mob/dead/observer/proc/updateghostsight()
|
||||
if (!seedarkness)
|
||||
see_invisible = SEE_INVISIBLE_OBSERVER_NOLIGHTING
|
||||
else
|
||||
see_invisible = SEE_INVISIBLE_OBSERVER
|
||||
if (!ghostvision)
|
||||
see_invisible = SEE_INVISIBLE_LIVING;
|
||||
updateghostimages()
|
||||
|
||||
/proc/updateallghostimages()
|
||||
for (var/mob/dead/observer/O in player_list)
|
||||
O.updateghostimages()
|
||||
|
||||
/mob/dead/observer/proc/updateghostimages()
|
||||
if (!client)
|
||||
return
|
||||
if (seedarkness || !ghostvision)
|
||||
client.images -= ghost_darkness_images
|
||||
else
|
||||
//add images for the 60inv things ghosts can normally see when darkness is enabled so they can see them now
|
||||
client.images |= ghost_darkness_images
|
||||
if (ghostimage)
|
||||
client.images -= ghostimage //remove ourself
|
||||
|
||||
/mob/dead/observer/verb/possess()
|
||||
set category = "Ghost"
|
||||
|
||||
@@ -82,6 +82,9 @@
|
||||
else if(copytext(input,1,9) == "exclaims")
|
||||
src << "<span class='danger'>Invalid emote.</span>"
|
||||
return
|
||||
else if(copytext(input,1,6) == "yells")
|
||||
src << "<span class='danger'>Invalid emote.</span>"
|
||||
return
|
||||
else if(copytext(input,1,5) == "asks")
|
||||
src << "<span class='danger'>Invalid emote.</span>"
|
||||
return
|
||||
@@ -203,6 +206,9 @@
|
||||
else if(copytext(message,1,9) == "exclaims")
|
||||
src << "<span class='danger'>Invalid emote.</span>"
|
||||
return
|
||||
else if(copytext(message,1,6) == "yells")
|
||||
src << "<span class='danger'>Invalid emote.</span>"
|
||||
return
|
||||
else if(copytext(message,1,5) == "asks")
|
||||
src << "<span class='danger'>Invalid emote.</span>"
|
||||
return
|
||||
|
||||
@@ -717,3 +717,19 @@
|
||||
H.w_uniform.add_fingerprint(M)
|
||||
|
||||
..()
|
||||
|
||||
|
||||
/mob/living/carbon/human/generateStaticOverlay()
|
||||
var/image/staticOverlay = image(icon('icons/effects/effects.dmi', "static"), loc = src)
|
||||
staticOverlay.override = 1
|
||||
staticOverlays["static"] = staticOverlay
|
||||
|
||||
staticOverlay = image(icon('icons/effects/effects.dmi', "blank"), loc = src)
|
||||
staticOverlay.override = 1
|
||||
staticOverlays["blank"] = staticOverlay
|
||||
|
||||
staticOverlay = getLetterImage(src, "H", 1)
|
||||
staticOverlay.override = 1
|
||||
staticOverlays["letter"] = staticOverlay
|
||||
|
||||
|
||||
|
||||
@@ -10,9 +10,11 @@
|
||||
var/mob/living/L = src
|
||||
if (L.getBrainLoss() >= 60)
|
||||
return "gibbers, \"[text]\"";
|
||||
if (ending == "?")
|
||||
if(ending == "?")
|
||||
return "asks, \"[text]\"";
|
||||
if (ending == "!")
|
||||
if(copytext(text, length(text) - 1) == "!!")
|
||||
return "yells, \"<span class = 'yell'>[text]</span>\"";
|
||||
if(ending == "!")
|
||||
return "exclaims, \"[text]\"";
|
||||
|
||||
if(dna)
|
||||
|
||||
@@ -1,8 +1,11 @@
|
||||
// This code handles different species in the game.
|
||||
|
||||
#define SPECIES_LAYER 23
|
||||
#define BODY_LAYER 22
|
||||
#define HAIR_LAYER 8
|
||||
#define SPECIES_LAYER 26
|
||||
#define BODY_BEHIND_LAYER 25
|
||||
#define BODY_LAYER 24
|
||||
#define BODY_ADJ_LAYER 23
|
||||
#define HAIR_LAYER 9
|
||||
#define BODY_FRONT_LAYER 2
|
||||
|
||||
#define TINT_IMPAIR 2
|
||||
#define TINT_BLIND 3
|
||||
@@ -44,6 +47,8 @@
|
||||
|
||||
var/say_mod = "says" // affects the speech message
|
||||
|
||||
var/list/mutant_bodyparts = list() // Parts of the body that are diferent enough from the standard human model that they cause clipping with some equipment
|
||||
|
||||
var/speedmod = 0 // this affects the race's speed. positive numbers make it move slower, negative numbers make it move faster
|
||||
var/armor = 0 // overall defense for the race... or less defense, if it's negative.
|
||||
var/brutemod = 1 // multiplier for brute damage
|
||||
@@ -87,19 +92,24 @@
|
||||
|
||||
var/g = (H.gender == FEMALE) ? "f" : "m"
|
||||
|
||||
if(!config.mutant_colors)
|
||||
H.dna.mutant_color = default_color
|
||||
|
||||
if(MUTCOLORS in specflags)
|
||||
var/image/spec_base
|
||||
var/icon_state_string = "[id]_"
|
||||
if(sexes)
|
||||
spec_base = image("icon" = 'icons/mob/human.dmi', "icon_state" = "[id]_[g]_s", "layer" = -SPECIES_LAYER)
|
||||
icon_state_string += "[g]_s"
|
||||
else
|
||||
spec_base = image("icon" = 'icons/mob/human.dmi', "icon_state" = "[id]_s", "layer" = -SPECIES_LAYER)
|
||||
if(!config.mutant_colors)
|
||||
H.dna.mutant_color = default_color
|
||||
icon_state_string += "_s"
|
||||
|
||||
spec_base = image("icon" = 'icons/mob/human.dmi', "icon_state" = icon_state_string, "layer" = -SPECIES_LAYER)
|
||||
|
||||
spec_base.color = "#[H.dna.mutant_color]"
|
||||
standing = spec_base
|
||||
|
||||
if(standing)
|
||||
H.overlays_standing[SPECIES_LAYER] = standing
|
||||
H.overlays_standing[SPECIES_LAYER] += standing
|
||||
|
||||
H.apply_overlay(SPECIES_LAYER)
|
||||
|
||||
@@ -172,6 +182,8 @@
|
||||
|
||||
var/list/standing = list()
|
||||
|
||||
handle_mutant_bodyparts(H)
|
||||
|
||||
// lipstick
|
||||
if(H.lip_style && LIPS in specflags)
|
||||
standing += image("icon"='icons/mob/human_face.dmi', "icon_state"="lips_[H.lip_style]_s", "layer" = -BODY_LAYER)
|
||||
@@ -208,6 +220,53 @@
|
||||
|
||||
return
|
||||
|
||||
/datum/species/proc/handle_mutant_bodyparts(var/mob/living/carbon/human/H)
|
||||
var/list/bodyparts_to_add = mutant_bodyparts.Copy()
|
||||
var/list/relevent_layers = list(BODY_BEHIND_LAYER, BODY_ADJ_LAYER, BODY_FRONT_LAYER)
|
||||
var/list/standing = list()
|
||||
|
||||
H.remove_overlay(BODY_BEHIND_LAYER)
|
||||
H.remove_overlay(BODY_ADJ_LAYER)
|
||||
H.remove_overlay(BODY_FRONT_LAYER)
|
||||
|
||||
if(!mutant_bodyparts)
|
||||
return
|
||||
|
||||
if("tail" in mutant_bodyparts)
|
||||
if(H.wear_suit && (H.wear_suit.flags_inv & HIDEJUMPSUIT))
|
||||
bodyparts_to_add -= "tail"
|
||||
|
||||
if("snout" in mutant_bodyparts) //Take a closer look at that snout!
|
||||
if(H.wear_mask && (H.wear_mask.flags_inv & HIDEFACE))
|
||||
bodyparts_to_add -= "snout"
|
||||
|
||||
if(!bodyparts_to_add)
|
||||
return
|
||||
|
||||
var/icon_state_string = "[id]_"
|
||||
var/g = (H.gender == FEMALE) ? "f" : "m"
|
||||
var/image/I
|
||||
|
||||
if(sexes)
|
||||
icon_state_string += "[g]_s"
|
||||
else
|
||||
icon_state_string += "_s"
|
||||
|
||||
if(!config.mutant_colors)
|
||||
H.dna.mutant_color = default_color
|
||||
|
||||
for(var/layer in relevent_layers)
|
||||
for(var/bodypart in bodyparts_to_add)
|
||||
I = image("icon" = 'icons/mob/mutant_bodyparts.dmi', "icon_state" = "[icon_state_string]_[bodypart]_[layer]", "layer" =- layer)
|
||||
I.color = "#[H.dna.mutant_color]"
|
||||
standing += I
|
||||
H.overlays_standing[layer] = standing.Copy()
|
||||
standing = list()
|
||||
|
||||
H.apply_overlay(BODY_BEHIND_LAYER)
|
||||
H.apply_overlay(BODY_ADJ_LAYER)
|
||||
H.apply_overlay(BODY_FRONT_LAYER)
|
||||
|
||||
/datum/species/proc/spec_life(var/mob/living/carbon/human/H)
|
||||
return
|
||||
|
||||
@@ -1336,8 +1395,11 @@
|
||||
H.update_fire()
|
||||
|
||||
#undef SPECIES_LAYER
|
||||
#undef BODY_BEHIND_LAYER
|
||||
#undef BODY_LAYER
|
||||
#undef BODY_ADJ_LAYER
|
||||
#undef HAIR_LAYER
|
||||
#undef BODY_FRONT_LAYER
|
||||
|
||||
#undef HUMAN_MAX_OXYLOSS
|
||||
#undef HUMAN_CRIT_MAX_OXYLOSS
|
||||
|
||||
@@ -30,6 +30,7 @@
|
||||
default_color = "00FF00"
|
||||
roundstart = 1
|
||||
specflags = list(MUTCOLORS,EYECOLOR,LIPS)
|
||||
mutant_bodyparts = list("tail", "snout")
|
||||
attack_verb = "slash"
|
||||
attack_sound = 'sound/weapons/slash.ogg'
|
||||
miss_sound = 'sound/weapons/slashmiss.ogg'
|
||||
|
||||
@@ -55,30 +55,33 @@ Please contact me on #coderbus IRC. ~Carnie x
|
||||
*/
|
||||
|
||||
//Human Overlays Indexes/////////
|
||||
#define SPECIES_LAYER 23 // mutantrace colors... these are on a seperate layer in order to prvent
|
||||
#define BODY_LAYER 22 //underwear, undershirts, socks, eyes, lips(makeup)
|
||||
#define MUTATIONS_LAYER 21 //Tk headglows etc.
|
||||
#define AUGMENTS_LAYER 20
|
||||
#define DAMAGE_LAYER 19 //damage indicators (cuts and burns)
|
||||
#define UNIFORM_LAYER 18
|
||||
#define ID_LAYER 17
|
||||
#define SHOES_LAYER 16
|
||||
#define GLOVES_LAYER 15
|
||||
#define EARS_LAYER 14
|
||||
#define SUIT_LAYER 13
|
||||
#define GLASSES_LAYER 12
|
||||
#define BELT_LAYER 11 //Possible make this an overlay of somethign required to wear a belt?
|
||||
#define SUIT_STORE_LAYER 10
|
||||
#define BACK_LAYER 9
|
||||
#define HAIR_LAYER 8 //TODO: make part of head layer?
|
||||
#define FACEMASK_LAYER 7
|
||||
#define HEAD_LAYER 6
|
||||
#define HANDCUFF_LAYER 5
|
||||
#define LEGCUFF_LAYER 4
|
||||
#define L_HAND_LAYER 3
|
||||
#define R_HAND_LAYER 2 //Having the two hands seperate seems rather silly, merge them together? It'll allow for code to be reused on mobs with arbitarily many hands
|
||||
#define SPECIES_LAYER 26 // mutantrace colors... these are on a seperate layer in order to prvent
|
||||
#define BODY_BEHIND_LAYER 25
|
||||
#define BODY_LAYER 24 //underwear, undershirts, socks, eyes, lips(makeup)
|
||||
#define BODY_ADJ_LAYER 23
|
||||
#define MUTATIONS_LAYER 22 //Tk headglows etc.
|
||||
#define AUGMENTS_LAYER 21
|
||||
#define DAMAGE_LAYER 20 //damage indicators (cuts and burns)
|
||||
#define UNIFORM_LAYER 19
|
||||
#define ID_LAYER 18
|
||||
#define SHOES_LAYER 17
|
||||
#define GLOVES_LAYER 16
|
||||
#define EARS_LAYER 15
|
||||
#define SUIT_LAYER 14
|
||||
#define GLASSES_LAYER 13
|
||||
#define BELT_LAYER 12 //Possible make this an overlay of somethign required to wear a belt?
|
||||
#define SUIT_STORE_LAYER 11
|
||||
#define BACK_LAYER 10
|
||||
#define HAIR_LAYER 9 //TODO: make part of head layer?
|
||||
#define FACEMASK_LAYER 8
|
||||
#define HEAD_LAYER 7
|
||||
#define HANDCUFF_LAYER 6
|
||||
#define LEGCUFF_LAYER 5
|
||||
#define L_HAND_LAYER 4
|
||||
#define R_HAND_LAYER 3 //Having the two hands seperate seems rather silly, merge them together? It'll allow for code to be reused on mobs with arbitarily many hands
|
||||
#define BODY_FRONT_LAYER 2
|
||||
#define FIRE_LAYER 1 //If you're on fire
|
||||
#define TOTAL_LAYERS 23 //KEEP THIS UP-TO-DATE OR SHIT WILL BREAK ;_;
|
||||
#define TOTAL_LAYERS 26 //KEEP THIS UP-TO-DATE OR SHIT WILL BREAK ;_;
|
||||
//////////////////////////////////
|
||||
|
||||
/mob/living/carbon/human
|
||||
@@ -158,6 +161,11 @@ Please contact me on #coderbus IRC. ~Carnie x
|
||||
if(dna && !(disabilities & HUSK))
|
||||
dna.species.update_color(src)
|
||||
|
||||
/mob/living/carbon/human/proc/update_mutant_bodyparts()
|
||||
if(dna)
|
||||
dna.species.handle_mutant_bodyparts(src)
|
||||
|
||||
|
||||
/mob/living/carbon/human/proc/update_body()
|
||||
remove_overlay(BODY_LAYER)
|
||||
|
||||
@@ -438,8 +446,9 @@ Please contact me on #coderbus IRC. ~Carnie x
|
||||
standing.overlays += image("icon"='icons/effects/blood.dmi', "icon_state"="[S.blood_overlay_type]blood")
|
||||
|
||||
src.update_hair()
|
||||
apply_overlay(SUIT_LAYER)
|
||||
src.update_mutant_bodyparts()
|
||||
|
||||
apply_overlay(SUIT_LAYER)
|
||||
|
||||
/mob/living/carbon/human/update_inv_pockets()
|
||||
if(l_store)
|
||||
@@ -467,10 +476,10 @@ Please contact me on #coderbus IRC. ~Carnie x
|
||||
if(wear_mask.blood_DNA && !istype(wear_mask, /obj/item/clothing/mask/cigarette))
|
||||
standing.overlays += image("icon"='icons/effects/blood.dmi', "icon_state"="maskblood")
|
||||
|
||||
update_mutant_bodyparts()
|
||||
|
||||
apply_overlay(FACEMASK_LAYER)
|
||||
|
||||
|
||||
|
||||
/mob/living/carbon/human/update_inv_back()
|
||||
remove_overlay(BACK_LAYER)
|
||||
|
||||
|
||||
@@ -8,12 +8,49 @@ Sorry Giacom. Please don't be mad :(
|
||||
push_mob_back(src, A.push_dir)
|
||||
*/
|
||||
|
||||
|
||||
/mob/living/New()
|
||||
. = ..()
|
||||
generateStaticOverlay()
|
||||
if(staticOverlays.len)
|
||||
for(var/mob/living/simple_animal/drone/D in player_list)
|
||||
if(D && D.seeStatic)
|
||||
if(D.staticChoice in staticOverlays)
|
||||
D.staticOverlays |= staticOverlays[D.staticChoice]
|
||||
D.client.images |= staticOverlays[D.staticChoice]
|
||||
else //no choice? force static
|
||||
D.staticOverlays |= staticOverlays["static"]
|
||||
D.client.images |= staticOverlays["static"]
|
||||
|
||||
|
||||
/mob/living/Destroy()
|
||||
// if(mind)
|
||||
// mind.current = null
|
||||
..()
|
||||
. = ..()
|
||||
|
||||
for(var/mob/living/simple_animal/drone/D in player_list)
|
||||
for(var/image/I in staticOverlays)
|
||||
D.staticOverlays.Remove(I)
|
||||
D.client.images.Remove(I)
|
||||
del(I)
|
||||
staticOverlays.len = 0
|
||||
|
||||
del(src)
|
||||
|
||||
|
||||
/mob/living/proc/generateStaticOverlay()
|
||||
staticOverlays.Add(list("static", "blank", "letter"))
|
||||
var/image/staticOverlay = image(getStaticIcon(new/icon(icon,icon_state)), loc = src)
|
||||
staticOverlay.override = 1
|
||||
staticOverlays["static"] = staticOverlay
|
||||
|
||||
staticOverlay = image(getBlankIcon(new/icon(icon, icon_state)), loc = src)
|
||||
staticOverlay.override = 1
|
||||
staticOverlays["blank"] = staticOverlay
|
||||
|
||||
staticOverlay = getLetterImage(src)
|
||||
staticOverlay.override = 1
|
||||
staticOverlays["letter"] = staticOverlay
|
||||
|
||||
|
||||
//Generic Bump(). Override MobBump() and ObjBump() instead of this.
|
||||
/mob/living/Bump(atom/A, yes)
|
||||
if (buckled || !yes || now_pushing)
|
||||
@@ -495,7 +532,7 @@ Sorry Giacom. Please don't be mad :(
|
||||
M.stop_pulling()
|
||||
|
||||
//this is the gay blood on floor shit -- Added back -- Skie
|
||||
if(M.lying && (prob(M.getBruteLoss() / 2)))
|
||||
if(M.lying && !M.buckled && (prob(M.getBruteLoss() / 2)))
|
||||
makeTrail(T, M)
|
||||
pulling.Move(T, get_dir(pulling, T))
|
||||
if(M)
|
||||
|
||||
@@ -41,4 +41,6 @@
|
||||
var/floating = 0
|
||||
var/nightvision = 0
|
||||
var/mob_size = 1 //size of the mob. 0 is small, 1 is human sized, and 2 is large.
|
||||
var/metabolism_efficiency = 1 //more or less efficiency to metabolize helpful/harmful reagents and regulate body temperature..
|
||||
var/metabolism_efficiency = 1 //more or less efficiency to metabolize helpful/harmful reagents and regulate body temperature..
|
||||
|
||||
var/list/image/staticOverlays = list()
|
||||
@@ -22,10 +22,12 @@
|
||||
/mob/living/silicon/ai/say_quote(var/text)
|
||||
var/ending = copytext(text, length(text))
|
||||
|
||||
if (ending == "?")
|
||||
if(ending == "?")
|
||||
return "queries, \"<span class = 'robot'>[text]</span>\"";
|
||||
else if (ending == "!")
|
||||
return "declares, \"<span class = 'robot'>[text]</span>\"";
|
||||
else if(copytext(text, length(text) - 1) == "!!")
|
||||
return "alarms, \"<span class = 'robot'><span class = 'yell'>[text]</span></span>\"";
|
||||
else if(ending == "!")
|
||||
return "declares, \"[text]\"";
|
||||
|
||||
return "states, \"<span class = 'robot'>[text]</span>\"";
|
||||
|
||||
|
||||
@@ -15,6 +15,7 @@
|
||||
|
||||
var/speakStatement = "states"
|
||||
var/speakExclamation = "declares"
|
||||
var/speakDoubleExclamation = "alarms"
|
||||
var/speakQuery = "queries"
|
||||
|
||||
var/obj/item/weapon/pai_cable/cable // The cable we produce and use when door or camera jacking
|
||||
|
||||
@@ -3,6 +3,8 @@
|
||||
|
||||
if (ending == "?")
|
||||
return "[src.speakQuery], \"<span class = 'robot'>[text]</span>\"";
|
||||
else if(copytext(text, length(text) - 1) == "!!")
|
||||
return "[src.speakDoubleExclamation], \"<span class = 'robot'><span class = 'yell'>[text]</span></span>\"";
|
||||
else if (ending == "!")
|
||||
return "[src.speakExclamation], \"<span class = 'robot'>[text]</span>\"";
|
||||
|
||||
|
||||
@@ -1,9 +1,11 @@
|
||||
/mob/living/silicon/robot/say_quote(var/text)
|
||||
var/ending = copytext(text, length(text))
|
||||
|
||||
if (ending == "?")
|
||||
if(ending == "?")
|
||||
return "queries, \"<span class = 'robot'>[text]</span>\"";
|
||||
else if (ending == "!")
|
||||
else if(copytext(text, length(text) - 1) == "!!")
|
||||
return "alarms, \"<span class = 'robot'><span class = 'yell'>[text]</span></span>\"";
|
||||
else if(ending == "!")
|
||||
return "declares, \"<span class = 'robot'>[text]</span>\"";
|
||||
|
||||
return "states, \"<span class = 'robot'>[text]</span>\"";
|
||||
|
||||
@@ -150,6 +150,7 @@
|
||||
//The objects that corgis can wear on their backs.
|
||||
var/list/allowed_types = list(
|
||||
/obj/item/clothing/suit/armor/vest,
|
||||
/obj/item/clothing/suit/space/deathsquad,
|
||||
/obj/item/device/radio,
|
||||
/obj/item/device/radio/off,
|
||||
/obj/item/clothing/suit/cardborg,
|
||||
@@ -253,7 +254,7 @@
|
||||
|
||||
if(/obj/item/clothing/head/nursehat)
|
||||
name = "Nurse [real_name]"
|
||||
desc = "[name] needs 100cc of beef jerky...STAT!"
|
||||
desc = "[name] needs 100cc of beef jerky... STAT!"
|
||||
valid = 1
|
||||
|
||||
if(/obj/item/clothing/head/pirate, /obj/item/clothing/head/collectable/pirate)
|
||||
@@ -267,10 +268,10 @@
|
||||
if(/obj/item/clothing/head/ushanka)
|
||||
name = "[pick("Comrade","Commissar","Glorious Leader")] [real_name]"
|
||||
desc = "A follower of Karl Barx."
|
||||
emote_see = list("contemplates the failings of the capitalist economic model.", "ponders the pros and cons of vangaurdism.")
|
||||
emote_see = list("contemplates the failings of the capitalist economic model.", "ponders the pros and cons of vanguardism.")
|
||||
valid = 1
|
||||
|
||||
if(/obj/item/clothing/head/collectable/police)
|
||||
if(/obj/item/clothing/head/warden, /obj/item/clothing/head/collectable/police)
|
||||
name = "Officer [real_name]"
|
||||
emote_see = list("drools.","looks for donuts.")
|
||||
desc = "Stop right there criminal scum!"
|
||||
@@ -298,7 +299,7 @@
|
||||
|
||||
if(/obj/item/clothing/head/helmet/space/santahat)
|
||||
name = "Santa's Corgi Helper"
|
||||
emote_hear = list("barks christmas songs.", "yaps merrily!")
|
||||
emote_hear = list("barks Christmas songs.", "yaps merrily!")
|
||||
emote_see = list("looks for presents.", "checks his list.")
|
||||
desc = "He's very fond of milk and cookies."
|
||||
valid = 1
|
||||
@@ -325,6 +326,11 @@
|
||||
desc = "Can actually be trusted to not run off on his own."
|
||||
valid = 1
|
||||
|
||||
if(/obj/item/clothing/head/helmet/space/deathsquad)
|
||||
name = "Trooper [real_name]"
|
||||
desc = "That's not red paint. That's real corgi blood."
|
||||
valid = 1
|
||||
|
||||
if(valid)
|
||||
if(user && !user.drop_item())
|
||||
user << "<span class='notice'>\The [item_to_add] is stuck to your hand, you cannot put it on [src]'s head!</span>"
|
||||
|
||||
@@ -1,609 +0,0 @@
|
||||
|
||||
#define HANDS_LAYER 1
|
||||
#define HEAD_LAYER 2
|
||||
#define TOTAL_LAYERS 2
|
||||
|
||||
#define DRONE_NET_CONNECT "<span class='notice'>DRONE NETWORK: [name] connected.</span>"
|
||||
#define DRONE_NET_DISCONNECT "<span class='danger'>DRONE NETWORK: [name] is not responding.</span>"
|
||||
|
||||
|
||||
/mob/living/simple_animal/drone
|
||||
name = "Drone"
|
||||
desc = "A maintenance drone, an expendable robot built to perform station repairs."
|
||||
icon = 'icons/mob/drone.dmi'
|
||||
icon_state = "drone_grey"
|
||||
icon_living = "drone_grey"
|
||||
icon_dead = "drone_dead"
|
||||
gender = NEUTER
|
||||
health = 30
|
||||
maxHealth = 30
|
||||
heat_damage_per_tick = 0
|
||||
cold_damage_per_tick = 0
|
||||
unsuitable_atmos_damage = 0
|
||||
wander = 0
|
||||
speed = 0
|
||||
ventcrawler = 2
|
||||
pass_flags = PASSTABLE | PASSMOB
|
||||
sight = (SEE_TURFS | SEE_OBJS)
|
||||
status_flags = (CANPUSH | CANSTUN | CANWEAKEN)
|
||||
gender = NEUTER
|
||||
voice_name = "synthesized chirp"
|
||||
languages = DRONE
|
||||
mob_size = 0
|
||||
has_unlimited_silicon_privilege = 1
|
||||
var/picked = FALSE
|
||||
var/list/drone_overlays[TOTAL_LAYERS]
|
||||
var/laws = \
|
||||
"1. You may not involve yourself in the matters of another being, even if such matters conflict with Law Two or Law Three, unless the other being is another Drone.\n"+\
|
||||
"2. You may not harm any being, regardless of intent or circumstance.\n"+\
|
||||
"3. Your goals are to build, maintain, repair, improve, and power to the best of your abilities, You must never actively work against these goals."
|
||||
var/light_on = 0
|
||||
var/heavy_emp_damage = 25 //Amount of damage sustained if hit by a heavy EMP pulse
|
||||
var/health_repair_max = 0 //Drone will only be able to be repaired/reactivated up to this point, defaults to health
|
||||
var/alarms = list("Atmosphere" = list(), "Fire" = list(), "Power" = list())
|
||||
var/obj/item/internal_storage //Drones can store one item, of any size/type in their body
|
||||
var/obj/item/head
|
||||
var/obj/item/default_storage = /obj/item/weapon/storage/toolbox/drone //If this exists, it will spawn in internal storage
|
||||
var/obj/item/default_hatmask //If this exists, it will spawn in the hat/mask slot if it can fit
|
||||
|
||||
|
||||
/mob/living/simple_animal/drone/New()
|
||||
..()
|
||||
|
||||
name = name + " ([rand(100,999)])"
|
||||
real_name = name
|
||||
|
||||
access_card = new /obj/item/weapon/card/id(src)
|
||||
var/datum/job/captain/C = new /datum/job/captain
|
||||
access_card.access = C.get_access()
|
||||
|
||||
if(!health_repair_max)
|
||||
health_repair_max = initial(health)
|
||||
|
||||
if(default_storage)
|
||||
var/obj/item/I = new default_storage(src)
|
||||
equip_to_slot_or_del(I, "drone_storage_slot")
|
||||
if(default_hatmask)
|
||||
var/obj/item/I = new default_hatmask(src)
|
||||
equip_to_slot_or_del(I, slot_head)
|
||||
|
||||
alert_drones(DRONE_NET_CONNECT)
|
||||
|
||||
/mob/living/simple_animal/drone/attack_hand(mob/user)
|
||||
if(isdrone(user))
|
||||
var/mob/living/simple_animal/drone/D = user
|
||||
if(D != src)
|
||||
if(stat == DEAD)
|
||||
var/d_input = alert(D,"Perform which action?","Drone Interaction","Reactivate","Cannibalize","Nothing")
|
||||
if(d_input)
|
||||
switch(d_input)
|
||||
if("Reactivate")
|
||||
var/mob/dead/observer/G = get_ghost()
|
||||
if(!client && (!G || !G.client))
|
||||
var/list/faux_gadgets = list("hypertext inflator","failsafe directory","DRM switch","stack initializer",\
|
||||
"anti-freeze capacitor","data stream diode","TCP bottleneck","supercharged I/O bolt",\
|
||||
"tradewind stablizer","radiated XML cable","registry fluid tank","open-source debunker")
|
||||
|
||||
var/list/faux_problems = list("won't be able to tune their bootstrap projector","will constantly remix their binary pool"+\
|
||||
" even though the BMX calibrator is working","will start leaking their XSS coolant",\
|
||||
"can't tell if their ethernet detour is moving or not", "won't be able to reseed enough"+\
|
||||
" kernels to function properly","can't start their neurotube console")
|
||||
|
||||
D << "<span class='notice'>You can't seem to find the [pick(faux_gadgets)]. Without it, [src] [pick(faux_problems)].</span>"
|
||||
return
|
||||
D.visible_message("<span class='notice'>[D] begins to reactivate [src].</span>")
|
||||
if(do_after(user,30,needhand = 1))
|
||||
health = health_repair_max
|
||||
stat = CONSCIOUS
|
||||
icon_state = icon_living
|
||||
dead_mob_list -= src
|
||||
living_mob_list += src
|
||||
D.visible_message("<span class='notice'>[D] reactivates [src]!</span>")
|
||||
alert_drones(DRONE_NET_CONNECT)
|
||||
if(G)
|
||||
G << "<span class='boldnotice'>DRONE NETWORK: </span><span class='ghostalert'>You were reactivated by [D]!</span>"
|
||||
else
|
||||
D << "<span class='notice'>You need to remain still to reactivate [src].</span>"
|
||||
|
||||
if("Cannibalize")
|
||||
if(D.health < D.maxHealth)
|
||||
D.visible_message("<span class='notice'>[D] begins to cannibalize parts from [src].</span>")
|
||||
if(do_after(D, 60,5,0))
|
||||
D.visible_message("<span class='notice'>[D] repairs itself using [src]'s remains!</span>")
|
||||
D.adjustBruteLoss(-src.maxHealth)
|
||||
new /obj/effect/decal/cleanable/oil/streak(get_turf(src))
|
||||
qdel(src)
|
||||
else
|
||||
D << "<span class='notice'>You need to remain still to cannibalize [src].</span>"
|
||||
else
|
||||
D << "<span class='notice'>You're already in perfect condition!</span>"
|
||||
if("Nothing")
|
||||
return
|
||||
|
||||
return
|
||||
|
||||
|
||||
if(ishuman(user))
|
||||
if(stat == DEAD)
|
||||
..()
|
||||
return
|
||||
if(user.get_active_hand())
|
||||
user << "<span class='notice'>Your hands are full.</span>"
|
||||
return
|
||||
src << "<span class='warning'>[user] is trying to pick you up!</span>"
|
||||
user << "<span class='notice'>You pick [src] up.</span>"
|
||||
drop_l_hand()
|
||||
drop_r_hand()
|
||||
var/obj/item/clothing/head/drone_holder/DH = new /obj/item/clothing/head/drone_holder(src)
|
||||
DH.contents += src
|
||||
DH.drone = src
|
||||
user.put_in_hands(DH)
|
||||
src.loc = DH
|
||||
return
|
||||
|
||||
..()
|
||||
|
||||
/mob/living/simple_animal/drone/Destroy()
|
||||
qdel(access_card) //Otherwise it ends up on the floor!
|
||||
..()
|
||||
|
||||
/mob/living/simple_animal/drone/attackby(obj/item/I, mob/user, params)
|
||||
if(istype(I, /obj/item/weapon/screwdriver) && stat != DEAD)
|
||||
if(health < health_repair_max)
|
||||
user << "<span class='notice'>You start to tighten loose screws on [src].</span>"
|
||||
if(do_after(user,80))
|
||||
health = health_repair_max
|
||||
visible_message("<span class='notice'>[user] tightens [src == user ? "their" : "[src]'s"] loose screws!</span>")
|
||||
else
|
||||
user << "<span class='notice'>You need to remain still to tighten [src]'s screws.</span>"
|
||||
else
|
||||
user << "<span class='notice'>[src]'s screws can't get any tighter!</span>"
|
||||
else
|
||||
..()
|
||||
|
||||
/mob/living/simple_animal/drone/examine(mob/user)
|
||||
. = ..()
|
||||
if(!client && stat != DEAD)
|
||||
user << "<span class='notice'>A small blue LED is blinking on and off at a steady rate.</span>"
|
||||
|
||||
/mob/living/simple_animal/drone/Move()
|
||||
if(pullin)
|
||||
if(pulling)
|
||||
pullin.icon_state = "pull"
|
||||
else
|
||||
pullin.icon_state = "pull0"
|
||||
..()
|
||||
|
||||
/mob/living/simple_animal/drone/IsAdvancedToolUser()
|
||||
return 1
|
||||
|
||||
/mob/living/simple_animal/drone/say(var/message)
|
||||
return ..(message, "R")
|
||||
|
||||
/mob/living/simple_animal/drone/lang_treat(atom/movable/speaker, message_langs, raw_message) //This is so drones can understand humans without being able to speak human
|
||||
. = ..()
|
||||
var/hear_override_langs = HUMAN
|
||||
if(message_langs & hear_override_langs)
|
||||
return ..(speaker, languages, raw_message)
|
||||
|
||||
/mob/living/simple_animal/drone/handle_inherent_channels(message, message_mode)
|
||||
if(message_mode == MODE_BINARY)
|
||||
drone_chat(message)
|
||||
return ITALICS | REDUCE_RANGE
|
||||
else
|
||||
..()
|
||||
|
||||
|
||||
/mob/living/simple_animal/drone/UnarmedAttack(atom/A, proximity)
|
||||
A.attack_hand(src)
|
||||
|
||||
|
||||
/mob/living/simple_animal/drone/swap_hand()
|
||||
var/obj/item/held_item = get_active_hand()
|
||||
if(held_item)
|
||||
if(istype(held_item, /obj/item/weapon/twohanded))
|
||||
var/obj/item/weapon/twohanded/T = held_item
|
||||
if(T.wielded == 1)
|
||||
usr << "<span class='warning'>Your other hand is too busy holding the [T.name].</span>"
|
||||
return
|
||||
|
||||
hand = !hand
|
||||
if(hud_used.l_hand_hud_object && hud_used.r_hand_hud_object)
|
||||
if(hand)
|
||||
hud_used.l_hand_hud_object.icon_state = "hand_l_active"
|
||||
hud_used.r_hand_hud_object.icon_state = "hand_r_inactive"
|
||||
else
|
||||
hud_used.l_hand_hud_object.icon_state = "hand_l_inactive"
|
||||
hud_used.r_hand_hud_object.icon_state = "hand_r_active"
|
||||
|
||||
|
||||
/mob/living/simple_animal/drone/verb/check_laws()
|
||||
set category = "Drone"
|
||||
set name = "Check Laws"
|
||||
|
||||
src << "<b>Drone Laws</b>"
|
||||
src << laws
|
||||
|
||||
/mob/living/simple_animal/drone/verb/toggle_light()
|
||||
set category = "Drone"
|
||||
set name = "Toggle drone light"
|
||||
if(light_on)
|
||||
AddLuminosity(-4)
|
||||
else
|
||||
AddLuminosity(4)
|
||||
|
||||
light_on = !light_on
|
||||
|
||||
src << "<span class='notice'>Your light is now [light_on ? "on" : "off"]</span>"
|
||||
|
||||
/mob/living/simple_animal/drone/verb/drone_ping()
|
||||
set category = "Drone"
|
||||
set name = "Drone ping"
|
||||
|
||||
var/alert_s = input(src,"Alert severity level","Drone ping",null) as null|anything in list("Low","Medium","High","Critical")
|
||||
|
||||
var/area/A = get_area(loc)
|
||||
|
||||
if(alert_s && A && stat != DEAD)
|
||||
var/msg = "<span class='boldnotice'>DRONE PING: [name]: [alert_s] priority alert in [A.name]!</span>"
|
||||
alert_drones(msg)
|
||||
|
||||
/mob/living/simple_animal/drone/proc/alert_drones(msg, dead_can_hear = 0)
|
||||
for(var/mob/M in player_list)
|
||||
var/send_msg = 0
|
||||
|
||||
if(istype(M, /mob/living/simple_animal/drone) && M.stat != DEAD)
|
||||
for(var/F in src.faction)
|
||||
if(F in M.faction)
|
||||
send_msg = 1
|
||||
break
|
||||
else if(dead_can_hear && (M in dead_mob_list))
|
||||
send_msg = 1
|
||||
|
||||
if(send_msg)
|
||||
M << msg
|
||||
|
||||
/mob/living/simple_animal/drone/proc/drone_chat(msg)
|
||||
var/rendered = "<i><span class='game say'>DRONE CHAT: <span class='name'>[name]</span>: [msg]</span></i>"
|
||||
alert_drones(rendered, 1)
|
||||
|
||||
/mob/living/simple_animal/drone/Login()
|
||||
..()
|
||||
update_inv_hands()
|
||||
update_inv_head()
|
||||
update_inv_internal_storage()
|
||||
check_laws()
|
||||
|
||||
if(!picked)
|
||||
pick_colour()
|
||||
|
||||
/mob/living/simple_animal/drone/Die()
|
||||
..()
|
||||
drop_l_hand()
|
||||
drop_r_hand()
|
||||
if(internal_storage)
|
||||
unEquip(internal_storage)
|
||||
if(head)
|
||||
unEquip(head)
|
||||
|
||||
alert_drones(DRONE_NET_DISCONNECT)
|
||||
|
||||
/mob/living/simple_animal/drone/gib()
|
||||
dust()
|
||||
|
||||
|
||||
/mob/living/simple_animal/drone/unEquip(obj/item/I, force)
|
||||
if(..(I,force))
|
||||
update_inv_hands()
|
||||
if(I == head)
|
||||
head = null
|
||||
update_inv_head()
|
||||
if(I == internal_storage)
|
||||
internal_storage = null
|
||||
update_inv_internal_storage()
|
||||
return 1
|
||||
return 0
|
||||
|
||||
/mob/living/simple_animal/drone/can_equip(obj/item/I, slot)
|
||||
switch(slot)
|
||||
if(slot_head)
|
||||
if(head)
|
||||
return 0
|
||||
if(!((I.slot_flags & SLOT_HEAD) || (I.slot_flags & SLOT_MASK)))
|
||||
return 0
|
||||
return 1
|
||||
if("drone_storage_slot")
|
||||
if(internal_storage)
|
||||
return 0
|
||||
return 1
|
||||
..()
|
||||
|
||||
/mob/living/simple_animal/drone/get_item_by_slot(slot_id)
|
||||
switch(slot_id)
|
||||
if(slot_head)
|
||||
return head
|
||||
if("drone_storage_slot")
|
||||
return internal_storage
|
||||
..()
|
||||
|
||||
/mob/living/simple_animal/drone/equip_to_slot(obj/item/I, slot)
|
||||
if(!slot) return
|
||||
if(!istype(I)) return
|
||||
|
||||
if(I == l_hand)
|
||||
l_hand = null
|
||||
else if(I == r_hand)
|
||||
r_hand = null
|
||||
update_inv_hands()
|
||||
|
||||
I.screen_loc = null // will get moved if inventory is visible
|
||||
I.loc = src
|
||||
I.equipped(src, slot)
|
||||
I.layer = 20
|
||||
|
||||
switch(slot)
|
||||
if(slot_head)
|
||||
head = I
|
||||
update_inv_head()
|
||||
if("drone_storage_slot")
|
||||
internal_storage = I
|
||||
update_inv_internal_storage()
|
||||
else
|
||||
src << "<span class='danger'>You are trying to equip this item to an unsupported inventory slot. Report this to a coder!</span>"
|
||||
return
|
||||
|
||||
/mob/living/simple_animal/drone/stripPanelUnequip(obj/item/what, mob/who, where)
|
||||
..(what, who, where, 1)
|
||||
|
||||
/mob/living/simple_animal/drone/stripPanelEquip(obj/item/what, mob/who, where)
|
||||
..(what, who, where, 1)
|
||||
|
||||
/mob/living/simple_animal/drone/emp_act(severity)
|
||||
Stun(5)
|
||||
src << "<span class='danger'><b>ER@%R: MME^RY CO#RU9T!</b> R&$b@0tin)...</span>"
|
||||
if(severity == 1)
|
||||
adjustBruteLoss(heavy_emp_damage)
|
||||
src << "<span class='userdanger'>HeAV% DA%^MMA+G TO I/O CIR!%UUT!</span>"
|
||||
|
||||
|
||||
/mob/living/simple_animal/drone/proc/triggerAlarm(var/class, area/A, var/O, var/obj/alarmsource)
|
||||
if(alarmsource.z != z)
|
||||
return
|
||||
if(stat != DEAD)
|
||||
var/list/L = src.alarms[class]
|
||||
for (var/I in L)
|
||||
if (I == A.name)
|
||||
var/list/alarm = L[I]
|
||||
var/list/sources = alarm[2]
|
||||
if (!(alarmsource in sources))
|
||||
sources += alarmsource
|
||||
return
|
||||
L[A.name] = list(A, list(alarmsource))
|
||||
src << "--- [class] alarm detected in [A.name]!"
|
||||
|
||||
/mob/living/simple_animal/drone/proc/cancelAlarm(var/class, area/A as area, obj/origin)
|
||||
if(stat != DEAD)
|
||||
var/list/L = alarms[class]
|
||||
var/cleared = 0
|
||||
for (var/I in L)
|
||||
if (I == A.name)
|
||||
var/list/alarm = L[I]
|
||||
var/list/srcs = alarm[2]
|
||||
if (origin in srcs)
|
||||
srcs -= origin
|
||||
if (srcs.len == 0)
|
||||
cleared = 1
|
||||
L -= I
|
||||
if(cleared)
|
||||
src << "--- [class] alarm in [A.name] has been cleared."
|
||||
|
||||
/mob/living/simple_animal/drone/proc/pick_colour()
|
||||
var/colour = input("Choose your colour!", "Colour", "grey") in list("grey", "blue", "red", "green", "pink", "orange")
|
||||
icon_state = "drone_[colour]"
|
||||
icon_living = "drone_[colour]"
|
||||
picked = TRUE
|
||||
|
||||
/mob/living/simple_animal/drone/proc/apply_overlay(cache_index)
|
||||
var/image/I = drone_overlays[cache_index]
|
||||
if(I)
|
||||
overlays += I
|
||||
|
||||
/mob/living/simple_animal/drone/proc/remove_overlay(cache_index)
|
||||
if(drone_overlays[cache_index])
|
||||
overlays -= drone_overlays[cache_index]
|
||||
drone_overlays[cache_index] = null
|
||||
|
||||
|
||||
/mob/living/simple_animal/drone/proc/update_inv_hands()
|
||||
remove_overlay(HANDS_LAYER)
|
||||
var/list/hands_overlays = list()
|
||||
if(r_hand)
|
||||
var/r_state = r_hand.item_state
|
||||
if(!r_state)
|
||||
r_state = r_hand.icon_state
|
||||
|
||||
hands_overlays += image("icon" = r_hand.righthand_file, "icon_state"="[r_state]", "layer"=-HANDS_LAYER)
|
||||
|
||||
if(client && hud_used)
|
||||
r_hand.layer = 20
|
||||
r_hand.screen_loc = ui_rhand
|
||||
client.screen |= r_hand
|
||||
|
||||
if(l_hand)
|
||||
var/l_state = l_hand.item_state
|
||||
if(!l_state)
|
||||
l_state = l_hand.icon_state
|
||||
|
||||
hands_overlays += image("icon" = l_hand.lefthand_file, "icon_state"="[l_state]", "layer"=-HANDS_LAYER)
|
||||
|
||||
if(client && hud_used)
|
||||
l_hand.layer = 20
|
||||
l_hand.screen_loc = ui_lhand
|
||||
client.screen |= l_hand
|
||||
|
||||
|
||||
if(hands_overlays.len)
|
||||
drone_overlays[HANDS_LAYER] = hands_overlays
|
||||
apply_overlay(HANDS_LAYER)
|
||||
|
||||
|
||||
/mob/living/simple_animal/drone/proc/update_inv_internal_storage()
|
||||
if(internal_storage && client && hud_used)
|
||||
internal_storage.screen_loc = ui_drone_storage
|
||||
client.screen += internal_storage
|
||||
|
||||
|
||||
/mob/living/simple_animal/drone/update_inv_head()
|
||||
remove_overlay(HEAD_LAYER)
|
||||
|
||||
if(head)
|
||||
if(client && hud_used)
|
||||
head.screen_loc = ui_drone_head
|
||||
client.screen += head
|
||||
|
||||
|
||||
var/image/head_overlay = image("icon"='icons/mob/head.dmi', "icon_state"="[head.icon_state]", "layer"=-HEAD_LAYER)
|
||||
if(istype(head, /obj/item/clothing/mask))
|
||||
head_overlay.icon = 'icons/mob/mask.dmi'
|
||||
head_overlay.color = head.color
|
||||
head_overlay.alpha = head.alpha
|
||||
head_overlay.pixel_y = -15
|
||||
|
||||
drone_overlays[HEAD_LAYER] = head_overlay
|
||||
|
||||
apply_overlay(HEAD_LAYER)
|
||||
|
||||
//These procs serve as redirection so that the drone updates as expected when other things call these procs
|
||||
/mob/living/simple_animal/drone/update_inv_l_hand()
|
||||
update_inv_hands()
|
||||
|
||||
/mob/living/simple_animal/drone/update_inv_r_hand()
|
||||
update_inv_hands()
|
||||
|
||||
/mob/living/simple_animal/drone/update_inv_wear_mask()
|
||||
update_inv_head()
|
||||
|
||||
|
||||
/mob/living/simple_animal/drone/canUseTopic()
|
||||
if(stat)
|
||||
return
|
||||
return 1
|
||||
|
||||
/mob/living/simple_animal/drone/activate_hand(var/selhand)
|
||||
|
||||
if(istext(selhand))
|
||||
selhand = lowertext(selhand)
|
||||
|
||||
if(selhand == "right" || selhand == "r")
|
||||
selhand = 0
|
||||
if(selhand == "left" || selhand == "l")
|
||||
selhand = 1
|
||||
|
||||
if(selhand != src.hand)
|
||||
swap_hand()
|
||||
else
|
||||
mode()
|
||||
|
||||
/mob/living/simple_animal/drone/assess_threat() //Secbots won't hunt maintenance drones.
|
||||
return -10
|
||||
|
||||
|
||||
#undef HANDS_LAYER
|
||||
#undef HEAD_LAYER
|
||||
#undef TOTAL_LAYERS
|
||||
|
||||
#undef DRONE_NET_CONNECT
|
||||
#undef DRONE_NET_DISCONNECT
|
||||
|
||||
//DRONE SHELL
|
||||
/obj/item/drone_shell
|
||||
name = "drone shell"
|
||||
desc = "A shell of a maintenance drone, an expendable robot built to perform station repairs."
|
||||
icon = 'icons/mob/drone.dmi'
|
||||
icon_state = "drone_item"
|
||||
origin_tech = "programming=2;biotech=4"
|
||||
var/drone_type = /mob/living/simple_animal/drone //Type of drone that will be spawned
|
||||
|
||||
/obj/item/drone_shell/attack_ghost(mob/user)
|
||||
if(jobban_isbanned(user,"pAI"))
|
||||
return
|
||||
|
||||
var/be_drone = alert("Become a drone? (Warning, You can no longer be cloned!)",,"Yes","No")
|
||||
if(be_drone == "No" || gc_destroyed)
|
||||
return
|
||||
var/mob/living/simple_animal/drone/D = new drone_type(get_turf(loc))
|
||||
D.key = user.key
|
||||
qdel(src)
|
||||
|
||||
|
||||
//DRONE HOLDER
|
||||
|
||||
/obj/item/clothing/head/drone_holder//Only exists in someones hand.or on their head
|
||||
name = "drone (hiding)"
|
||||
desc = "This drone is scared and has curled up into a ball"
|
||||
icon = 'icons/mob/drone.dmi'
|
||||
icon_state = "drone_item"
|
||||
var/mob/living/simple_animal/drone/drone //stored drone
|
||||
|
||||
/obj/item/clothing/head/drone_holder/proc/uncurl()
|
||||
if(!drone)
|
||||
return
|
||||
|
||||
if(istype(loc, /mob/living))
|
||||
var/mob/living/L = loc
|
||||
L.show_message("<span class='notice'>[drone] is trying to escape!</span>")
|
||||
if(!do_after(L, 50) || loc != L)
|
||||
return
|
||||
L.unEquip(src)
|
||||
|
||||
contents -= drone
|
||||
drone.loc = get_turf(src)
|
||||
drone.reset_view()
|
||||
drone.dir = SOUTH //Looks better
|
||||
drone.visible_message("<span class='notice'>[drone] uncurls!</span>")
|
||||
drone = null
|
||||
qdel(src)
|
||||
|
||||
|
||||
/obj/item/clothing/head/drone_holder/relaymove()
|
||||
uncurl()
|
||||
|
||||
/obj/item/clothing/head/drone_holder/container_resist()
|
||||
uncurl()
|
||||
|
||||
|
||||
//More types of drones
|
||||
|
||||
/mob/living/simple_animal/drone/syndrone
|
||||
name = "Syndrone"
|
||||
desc = "A modified maintenance drone. This one brings with it the feeling of terror."
|
||||
icon_state = "drone_synd"
|
||||
icon_living = "drone_synd"
|
||||
picked = TRUE
|
||||
health = 30
|
||||
maxHealth = 120 //If you murder other drones and cannibalize them you can get much stronger
|
||||
faction = list("syndicate")
|
||||
heavy_emp_damage = 10
|
||||
laws = \
|
||||
"1. Interfere.\n"+\
|
||||
"2. Kill.\n"+\
|
||||
"3. Destroy."
|
||||
default_storage = /obj/item/device/radio/uplink
|
||||
default_hatmask = /obj/item/clothing/head/helmet/space/hardsuit/syndi
|
||||
|
||||
/mob/living/simple_animal/drone/syndrone/New()
|
||||
..()
|
||||
if(internal_storage && internal_storage.hidden_uplink)
|
||||
internal_storage.hidden_uplink.uses = (initial(internal_storage.hidden_uplink.uses) / 2)
|
||||
internal_storage.name = "syndicate uplink"
|
||||
|
||||
/mob/living/simple_animal/drone/syndrone/Login()
|
||||
..()
|
||||
src << "<span class='notice'>You can kill and eat other drones to increase your health!</span>" //Inform the evil lil guy
|
||||
|
||||
/obj/item/drone_shell/syndrone
|
||||
name = "syndrone shell"
|
||||
desc = "A shell of a syndrone, a modified maintenance drone designed to infiltrate and annihilate."
|
||||
icon_state = "syndrone_item"
|
||||
drone_type = /mob/living/simple_animal/drone/syndrone
|
||||
|
||||
@@ -0,0 +1,183 @@
|
||||
|
||||
#define DRONE_HANDS_LAYER 1
|
||||
#define DRONE_HEAD_LAYER 2
|
||||
#define DRONE_TOTAL_LAYERS 2
|
||||
|
||||
#define DRONE_NET_CONNECT "<span class='notice'>DRONE NETWORK: [name] connected.</span>"
|
||||
#define DRONE_NET_DISCONNECT "<span class='danger'>DRONE NETWORK: [name] is not responding.</span>"
|
||||
|
||||
#define MAINTDRONE "drone_maint"
|
||||
#define REPAIRDRONE "drone_repair"
|
||||
|
||||
/mob/living/simple_animal/drone
|
||||
name = "Drone"
|
||||
desc = "A maintenance drone, an expendable robot built to perform station repairs."
|
||||
icon = 'icons/mob/drone.dmi'
|
||||
icon_state = "drone_maint_grey"
|
||||
icon_living = "drone_maint_grey"
|
||||
icon_dead = "drone_maint_dead"
|
||||
gender = NEUTER
|
||||
health = 30
|
||||
maxHealth = 30
|
||||
heat_damage_per_tick = 0
|
||||
cold_damage_per_tick = 0
|
||||
unsuitable_atmos_damage = 0
|
||||
wander = 0
|
||||
speed = 0
|
||||
ventcrawler = 2
|
||||
pass_flags = PASSTABLE | PASSMOB
|
||||
sight = (SEE_TURFS | SEE_OBJS)
|
||||
status_flags = (CANPUSH | CANSTUN | CANWEAKEN)
|
||||
gender = NEUTER
|
||||
voice_name = "synthesized chirp"
|
||||
languages = DRONE
|
||||
mob_size = 0
|
||||
has_unlimited_silicon_privilege = 1
|
||||
staticOverlays = list()
|
||||
var/staticChoice = "static"
|
||||
var/list/staticChoices = list("static", "blank", "letter")
|
||||
var/picked = FALSE //Have we picked our visual appearence (+ colour if applicable)
|
||||
var/list/drone_overlays[DRONE_TOTAL_LAYERS]
|
||||
var/laws = \
|
||||
"1. You may not involve yourself in the matters of another being, even if such matters conflict with Law Two or Law Three, unless the other being is another Drone.\n"+\
|
||||
"2. You may not harm any being, regardless of intent or circumstance.\n"+\
|
||||
"3. Your goals are to build, maintain, repair, improve, and power to the best of your abilities, You must never actively work against these goals."
|
||||
var/light_on = 0
|
||||
var/heavy_emp_damage = 25 //Amount of damage sustained if hit by a heavy EMP pulse
|
||||
var/health_repair_max = 0 //Drone will only be able to be repaired/reactivated up to this point, defaults to health
|
||||
var/alarms = list("Atmosphere" = list(), "Fire" = list(), "Power" = list())
|
||||
var/obj/item/internal_storage //Drones can store one item, of any size/type in their body
|
||||
var/obj/item/head
|
||||
var/obj/item/default_storage = /obj/item/weapon/storage/toolbox/drone //If this exists, it will spawn in internal storage
|
||||
var/obj/item/default_hatmask //If this exists, it will spawn in the hat/mask slot if it can fit
|
||||
var/seeStatic = 1 //Whether we see static instead of mobs
|
||||
var/visualAppearence = MAINTDRONE //What we appear as
|
||||
|
||||
|
||||
/mob/living/simple_animal/drone/New()
|
||||
..()
|
||||
|
||||
name = name + " ([rand(100,999)])"
|
||||
real_name = name
|
||||
|
||||
access_card = new /obj/item/weapon/card/id(src)
|
||||
var/datum/job/captain/C = new /datum/job/captain
|
||||
access_card.access = C.get_access()
|
||||
|
||||
if(!health_repair_max)
|
||||
health_repair_max = initial(health)
|
||||
|
||||
if(default_storage)
|
||||
var/obj/item/I = new default_storage(src)
|
||||
equip_to_slot_or_del(I, "drone_storage_slot")
|
||||
if(default_hatmask)
|
||||
var/obj/item/I = new default_hatmask(src)
|
||||
equip_to_slot_or_del(I, slot_head)
|
||||
|
||||
alert_drones(DRONE_NET_CONNECT)
|
||||
|
||||
|
||||
/mob/living/simple_animal/drone/Destroy()
|
||||
qdel(access_card) //Otherwise it ends up on the floor!
|
||||
..()
|
||||
|
||||
/mob/living/simple_animal/drone/Login()
|
||||
..()
|
||||
update_inv_hands()
|
||||
update_inv_head()
|
||||
update_inv_internal_storage()
|
||||
check_laws()
|
||||
|
||||
updateSeeStaticMobs()
|
||||
|
||||
if(!picked)
|
||||
pickVisualAppearence()
|
||||
|
||||
|
||||
/mob/living/simple_animal/drone/Die()
|
||||
..()
|
||||
drop_l_hand()
|
||||
drop_r_hand()
|
||||
if(internal_storage)
|
||||
unEquip(internal_storage)
|
||||
if(head)
|
||||
unEquip(head)
|
||||
|
||||
alert_drones(DRONE_NET_DISCONNECT)
|
||||
|
||||
|
||||
/mob/living/simple_animal/drone/gib()
|
||||
dust()
|
||||
|
||||
|
||||
/mob/living/simple_animal/drone/examine(mob/user)
|
||||
. = ..()
|
||||
if(!client && stat != DEAD)
|
||||
user << "<span class='notice'>A small blue LED is blinking on and off at a steady rate.</span>"
|
||||
|
||||
if(stat == DEAD)
|
||||
user << "<span class='notice'>The drone's LED screen shows a BSOD, Blue screen of Death!</span>"
|
||||
|
||||
|
||||
/mob/living/simple_animal/drone/Move()
|
||||
if(pullin)
|
||||
if(pulling)
|
||||
pullin.icon_state = "pull"
|
||||
else
|
||||
pullin.icon_state = "pull0"
|
||||
..()
|
||||
|
||||
|
||||
/mob/living/simple_animal/drone/IsAdvancedToolUser()
|
||||
return 1
|
||||
|
||||
|
||||
/mob/living/simple_animal/drone/canUseTopic()
|
||||
if(stat)
|
||||
return
|
||||
return 1
|
||||
|
||||
|
||||
/mob/living/simple_animal/drone/assess_threat() //Secbots won't hunt maintenance drones.
|
||||
return -10
|
||||
|
||||
|
||||
/mob/living/simple_animal/drone/emp_act(severity)
|
||||
Stun(5)
|
||||
src << "<span class='danger'><b>ER@%R: MME^RY CO#RU9T!</b> R&$b@0tin)...</span>"
|
||||
if(severity == 1)
|
||||
adjustBruteLoss(heavy_emp_damage)
|
||||
src << "<span class='userdanger'>HeAV% DA%^MMA+G TO I/O CIR!%UUT!</span>"
|
||||
|
||||
|
||||
/mob/living/simple_animal/drone/proc/triggerAlarm(var/class, area/A, var/O, var/obj/alarmsource)
|
||||
if(alarmsource.z != z)
|
||||
return
|
||||
if(stat != DEAD)
|
||||
var/list/L = src.alarms[class]
|
||||
for (var/I in L)
|
||||
if (I == A.name)
|
||||
var/list/alarm = L[I]
|
||||
var/list/sources = alarm[2]
|
||||
if (!(alarmsource in sources))
|
||||
sources += alarmsource
|
||||
return
|
||||
L[A.name] = list(A, list(alarmsource))
|
||||
src << "--- [class] alarm detected in [A.name]!"
|
||||
|
||||
|
||||
/mob/living/simple_animal/drone/proc/cancelAlarm(var/class, area/A as area, obj/origin)
|
||||
if(stat != DEAD)
|
||||
var/list/L = alarms[class]
|
||||
var/cleared = 0
|
||||
for (var/I in L)
|
||||
if (I == A.name)
|
||||
var/list/alarm = L[I]
|
||||
var/list/srcs = alarm[2]
|
||||
if (origin in srcs)
|
||||
srcs -= origin
|
||||
if (srcs.len == 0)
|
||||
cleared = 1
|
||||
L -= I
|
||||
if(cleared)
|
||||
src << "--- [class] alarm in [A.name] has been cleared."
|
||||
@@ -0,0 +1,69 @@
|
||||
|
||||
///////////////////
|
||||
//DRONES AS ITEMS//
|
||||
///////////////////
|
||||
//Drone shells
|
||||
//Drones as hats
|
||||
|
||||
|
||||
//DRONE SHELL
|
||||
/obj/item/drone_shell
|
||||
name = "drone shell"
|
||||
desc = "A shell of a maintenance drone, an expendable robot built to perform station repairs."
|
||||
icon = 'icons/mob/drone.dmi'
|
||||
icon_state = "drone_maint_hat"//yes reuse the _hat state.
|
||||
origin_tech = "programming=2;biotech=4"
|
||||
var/drone_type = /mob/living/simple_animal/drone //Type of drone that will be spawned
|
||||
|
||||
/obj/item/drone_shell/attack_ghost(mob/user)
|
||||
if(jobban_isbanned(user,"pAI"))
|
||||
return
|
||||
|
||||
var/be_drone = alert("Become a drone? (Warning, You can no longer be cloned!)",,"Yes","No")
|
||||
if(be_drone == "No" || gc_destroyed)
|
||||
return
|
||||
var/mob/living/simple_animal/drone/D = new drone_type(get_turf(loc))
|
||||
D.key = user.key
|
||||
qdel(src)
|
||||
|
||||
|
||||
//DRONE HOLDER
|
||||
/obj/item/clothing/head/drone_holder//Only exists in someones hand.or on their head
|
||||
name = "drone (hiding)"
|
||||
desc = "This drone is scared and has curled up into a ball"
|
||||
icon = 'icons/mob/drone.dmi'
|
||||
icon_state = "drone_maint_hat"
|
||||
var/mob/living/simple_animal/drone/drone //stored drone
|
||||
|
||||
/obj/item/clothing/head/drone_holder/proc/uncurl()
|
||||
if(!drone)
|
||||
return
|
||||
|
||||
if(istype(loc, /mob/living))
|
||||
var/mob/living/L = loc
|
||||
L.show_message("<span class='notice'>[drone] is trying to escape!</span>")
|
||||
if(!do_after(L, 50) || loc != L)
|
||||
return
|
||||
L.unEquip(src)
|
||||
|
||||
contents -= drone
|
||||
drone.loc = get_turf(src)
|
||||
drone.reset_view()
|
||||
drone.dir = SOUTH //Looks better
|
||||
drone.visible_message("<span class='notice'>[drone] uncurls!</span>")
|
||||
drone = null
|
||||
qdel(src)
|
||||
|
||||
|
||||
/obj/item/clothing/head/drone_holder/relaymove()
|
||||
uncurl()
|
||||
|
||||
/obj/item/clothing/head/drone_holder/container_resist()
|
||||
uncurl()
|
||||
|
||||
|
||||
/obj/item/clothing/head/drone_holder/proc/updateVisualAppearence(var/mob/living/simple_animal/drone/D)
|
||||
if(!D)
|
||||
return
|
||||
icon_state = "[D.visualAppearence]_hat"
|
||||
. = icon_state
|
||||
@@ -0,0 +1,46 @@
|
||||
|
||||
////////////////////
|
||||
//MORE DRONE TYPES//
|
||||
////////////////////
|
||||
//Drones with custom laws
|
||||
//Drones with custom shells
|
||||
//Drones with overriden procs
|
||||
|
||||
|
||||
//More types of drones
|
||||
/mob/living/simple_animal/drone/syndrone
|
||||
name = "Syndrone"
|
||||
desc = "A modified maintenance drone. This one brings with it the feeling of terror."
|
||||
icon_state = "drone_synd"
|
||||
icon_living = "drone_synd"
|
||||
picked = TRUE //the appearence of syndrones is static, you don't get to change it.
|
||||
health = 30
|
||||
maxHealth = 120 //If you murder other drones and cannibalize them you can get much stronger
|
||||
faction = list("syndicate")
|
||||
heavy_emp_damage = 10
|
||||
laws = \
|
||||
"1. Interfere.\n"+\
|
||||
"2. Kill.\n"+\
|
||||
"3. Destroy."
|
||||
default_storage = /obj/item/device/radio/uplink
|
||||
default_hatmask = /obj/item/clothing/head/helmet/space/hardsuit/syndi
|
||||
seeStatic = 0 //Our programming is superior.
|
||||
|
||||
|
||||
/mob/living/simple_animal/drone/syndrone/New()
|
||||
..()
|
||||
if(internal_storage && internal_storage.hidden_uplink)
|
||||
internal_storage.hidden_uplink.uses = (initial(internal_storage.hidden_uplink.uses) / 2)
|
||||
internal_storage.name = "syndicate uplink"
|
||||
|
||||
|
||||
/mob/living/simple_animal/drone/syndrone/Login()
|
||||
..()
|
||||
src << "<span class='notice'>You can kill and eat other drones to increase your health!</span>" //Inform the evil lil guy
|
||||
|
||||
|
||||
/obj/item/drone_shell/syndrone
|
||||
name = "syndrone shell"
|
||||
desc = "A shell of a syndrone, a modified maintenance drone designed to infiltrate and annihilate."
|
||||
icon_state = "syndrone_item"
|
||||
drone_type = /mob/living/simple_animal/drone/syndrone
|
||||
@@ -0,0 +1,106 @@
|
||||
|
||||
/////////////////////
|
||||
//DRONE INTERACTION//
|
||||
/////////////////////
|
||||
//How drones interact with the world
|
||||
//How the world interacts with drones
|
||||
|
||||
|
||||
/mob/living/simple_animal/drone/UnarmedAttack(atom/A, proximity)
|
||||
A.attack_hand(src)
|
||||
|
||||
|
||||
/mob/living/simple_animal/drone/attack_hand(mob/user)
|
||||
if(isdrone(user))
|
||||
var/mob/living/simple_animal/drone/D = user
|
||||
if(D != src)
|
||||
if(stat == DEAD)
|
||||
var/d_input = alert(D,"Perform which action?","Drone Interaction","Reactivate","Cannibalize","Nothing")
|
||||
if(d_input)
|
||||
switch(d_input)
|
||||
if("Reactivate")
|
||||
var/mob/dead/observer/G = get_ghost()
|
||||
if(!client && (!G || !G.client))
|
||||
var/list/faux_gadgets = list("hypertext inflator","failsafe directory","DRM switch","stack initializer",\
|
||||
"anti-freeze capacitor","data stream diode","TCP bottleneck","supercharged I/O bolt",\
|
||||
"tradewind stablizer","radiated XML cable","registry fluid tank","open-source debunker")
|
||||
|
||||
var/list/faux_problems = list("won't be able to tune their bootstrap projector","will constantly remix their binary pool"+\
|
||||
" even though the BMX calibrator is working","will start leaking their XSS coolant",\
|
||||
"can't tell if their ethernet detour is moving or not", "won't be able to reseed enough"+\
|
||||
" kernels to function properly","can't start their neurotube console")
|
||||
|
||||
D << "<span class='notice'>You can't seem to find the [pick(faux_gadgets)]. Without it, [src] [pick(faux_problems)].</span>"
|
||||
return
|
||||
D.visible_message("<span class='notice'>[D] begins to reactivate [src].</span>")
|
||||
if(do_after(user,30,needhand = 1))
|
||||
health = health_repair_max
|
||||
stat = CONSCIOUS
|
||||
icon_state = icon_living
|
||||
dead_mob_list -= src
|
||||
living_mob_list += src
|
||||
D.visible_message("<span class='notice'>[D] reactivates [src]!</span>")
|
||||
alert_drones(DRONE_NET_CONNECT)
|
||||
if(G)
|
||||
G << "<span class='boldnotice'>DRONE NETWORK: </span><span class='ghostalert'>You were reactivated by [D]!</span>"
|
||||
else
|
||||
D << "<span class='notice'>You need to remain still to reactivate [src].</span>"
|
||||
|
||||
if("Cannibalize")
|
||||
if(D.health < D.maxHealth)
|
||||
D.visible_message("<span class='notice'>[D] begins to cannibalize parts from [src].</span>")
|
||||
if(do_after(D, 60,5,0))
|
||||
D.visible_message("<span class='notice'>[D] repairs itself using [src]'s remains!</span>")
|
||||
D.adjustBruteLoss(-src.maxHealth)
|
||||
new /obj/effect/decal/cleanable/oil/streak(get_turf(src))
|
||||
qdel(src)
|
||||
else
|
||||
D << "<span class='notice'>You need to remain still to cannibalize [src].</span>"
|
||||
else
|
||||
D << "<span class='notice'>You're already in perfect condition!</span>"
|
||||
if("Nothing")
|
||||
return
|
||||
|
||||
return
|
||||
|
||||
|
||||
if(ishuman(user))
|
||||
if(stat == DEAD)
|
||||
..()
|
||||
return
|
||||
if(user.get_active_hand())
|
||||
user << "<span class='notice'>Your hands are full.</span>"
|
||||
return
|
||||
src << "<span class='warning'>[user] is trying to pick you up!</span>"
|
||||
if(buckled)
|
||||
user << "<span class='warning'>[src] is buckled to the [buckled.name] and cannot be picked up!</span>"
|
||||
return
|
||||
user << "<span class='notice'>You pick [src] up.</span>"
|
||||
drop_l_hand()
|
||||
drop_r_hand()
|
||||
var/obj/item/clothing/head/drone_holder/DH = new /obj/item/clothing/head/drone_holder(src)
|
||||
DH.updateVisualAppearence(src)
|
||||
DH.contents += src
|
||||
DH.drone = src
|
||||
user.put_in_hands(DH)
|
||||
src.loc = DH
|
||||
return
|
||||
|
||||
..()
|
||||
|
||||
|
||||
/mob/living/simple_animal/drone/attackby(obj/item/I, mob/user)
|
||||
if(istype(I, /obj/item/weapon/screwdriver) && stat != DEAD)
|
||||
if(health < health_repair_max)
|
||||
user << "<span class='notice'>You start to tighten loose screws on [src].</span>"
|
||||
if(do_after(user,80))
|
||||
health = health_repair_max
|
||||
visible_message("<span class='notice'>[user] tightens [src == user ? "their" : "[src]'s"] loose screws!</span>")
|
||||
else
|
||||
user << "<span class='notice'>You need to remain still to tighten [src]'s screws.</span>"
|
||||
else
|
||||
user << "<span class='notice'>[src]'s screws can't get any tighter!</span>"
|
||||
else
|
||||
..()
|
||||
|
||||
|
||||
@@ -0,0 +1,115 @@
|
||||
|
||||
///////////////////
|
||||
//DRONE INVENTORY//
|
||||
///////////////////
|
||||
//Drone inventory
|
||||
//Drone hands
|
||||
|
||||
|
||||
|
||||
|
||||
/mob/living/simple_animal/drone/activate_hand(var/selhand)
|
||||
|
||||
if(istext(selhand))
|
||||
selhand = lowertext(selhand)
|
||||
|
||||
if(selhand == "right" || selhand == "r")
|
||||
selhand = 0
|
||||
if(selhand == "left" || selhand == "l")
|
||||
selhand = 1
|
||||
|
||||
if(selhand != src.hand)
|
||||
swap_hand()
|
||||
else
|
||||
mode()
|
||||
|
||||
|
||||
/mob/living/simple_animal/drone/swap_hand()
|
||||
var/obj/item/held_item = get_active_hand()
|
||||
if(held_item)
|
||||
if(istype(held_item, /obj/item/weapon/twohanded))
|
||||
var/obj/item/weapon/twohanded/T = held_item
|
||||
if(T.wielded == 1)
|
||||
usr << "<span class='warning'>Your other hand is too busy holding the [T.name].</span>"
|
||||
return
|
||||
|
||||
hand = !hand
|
||||
if(hud_used.l_hand_hud_object && hud_used.r_hand_hud_object)
|
||||
if(hand)
|
||||
hud_used.l_hand_hud_object.icon_state = "hand_l_active"
|
||||
hud_used.r_hand_hud_object.icon_state = "hand_r_inactive"
|
||||
else
|
||||
hud_used.l_hand_hud_object.icon_state = "hand_l_inactive"
|
||||
hud_used.r_hand_hud_object.icon_state = "hand_r_active"
|
||||
|
||||
|
||||
/mob/living/simple_animal/drone/unEquip(obj/item/I, force)
|
||||
if(..(I,force))
|
||||
update_inv_hands()
|
||||
if(I == head)
|
||||
head = null
|
||||
update_inv_head()
|
||||
if(I == internal_storage)
|
||||
internal_storage = null
|
||||
update_inv_internal_storage()
|
||||
return 1
|
||||
return 0
|
||||
|
||||
|
||||
/mob/living/simple_animal/drone/can_equip(obj/item/I, slot)
|
||||
switch(slot)
|
||||
if(slot_head)
|
||||
if(head)
|
||||
return 0
|
||||
if(!((I.slot_flags & SLOT_HEAD) || (I.slot_flags & SLOT_MASK)))
|
||||
return 0
|
||||
return 1
|
||||
if("drone_storage_slot")
|
||||
if(internal_storage)
|
||||
return 0
|
||||
return 1
|
||||
..()
|
||||
|
||||
|
||||
/mob/living/simple_animal/drone/get_item_by_slot(slot_id)
|
||||
switch(slot_id)
|
||||
if(slot_head)
|
||||
return head
|
||||
if("drone_storage_slot")
|
||||
return internal_storage
|
||||
..()
|
||||
|
||||
|
||||
/mob/living/simple_animal/drone/equip_to_slot(obj/item/I, slot)
|
||||
if(!slot) return
|
||||
if(!istype(I)) return
|
||||
|
||||
if(I == l_hand)
|
||||
l_hand = null
|
||||
else if(I == r_hand)
|
||||
r_hand = null
|
||||
update_inv_hands()
|
||||
|
||||
I.screen_loc = null // will get moved if inventory is visible
|
||||
I.loc = src
|
||||
I.equipped(src, slot)
|
||||
I.layer = 20
|
||||
|
||||
switch(slot)
|
||||
if(slot_head)
|
||||
head = I
|
||||
update_inv_head()
|
||||
if("drone_storage_slot")
|
||||
internal_storage = I
|
||||
update_inv_internal_storage()
|
||||
else
|
||||
src << "<span class='danger'>You are trying to equip this item to an unsupported inventory slot. Report this to a coder!</span>"
|
||||
return
|
||||
|
||||
|
||||
/mob/living/simple_animal/drone/stripPanelUnequip(obj/item/what, mob/who, where)
|
||||
..(what, who, where, 1)
|
||||
|
||||
|
||||
/mob/living/simple_animal/drone/stripPanelEquip(obj/item/what, mob/who, where)
|
||||
..(what, who, where, 1)
|
||||
@@ -0,0 +1,46 @@
|
||||
|
||||
/////////////
|
||||
//DRONE SAY//
|
||||
/////////////
|
||||
//Drone speach
|
||||
//Drone hearing
|
||||
|
||||
|
||||
/mob/living/simple_animal/drone/say(var/message)
|
||||
return ..(message, "R")
|
||||
|
||||
|
||||
/mob/living/simple_animal/drone/lang_treat(atom/movable/speaker, message_langs, raw_message) //This is so drones can understand humans without being able to speak human
|
||||
. = ..()
|
||||
var/hear_override_langs = HUMAN
|
||||
if(message_langs & hear_override_langs)
|
||||
return ..(speaker, languages, raw_message)
|
||||
|
||||
|
||||
/mob/living/simple_animal/drone/handle_inherent_channels(message, message_mode)
|
||||
if(message_mode == MODE_BINARY)
|
||||
drone_chat(message)
|
||||
return ITALICS | REDUCE_RANGE
|
||||
else
|
||||
..()
|
||||
|
||||
|
||||
/mob/living/simple_animal/drone/proc/alert_drones(msg, dead_can_hear = 0)
|
||||
for(var/mob/M in player_list)
|
||||
var/send_msg = 0
|
||||
|
||||
if(istype(M, /mob/living/simple_animal/drone) && M.stat != DEAD)
|
||||
for(var/F in src.faction)
|
||||
if(F in M.faction)
|
||||
send_msg = 1
|
||||
break
|
||||
else if(dead_can_hear && (M in dead_mob_list))
|
||||
send_msg = 1
|
||||
|
||||
if(send_msg)
|
||||
M << msg
|
||||
|
||||
|
||||
/mob/living/simple_animal/drone/proc/drone_chat(msg)
|
||||
var/rendered = "<i><span class='game say'>DRONE CHAT: <span class='name'>[name]</span>: [msg]</span></i>"
|
||||
alert_drones(rendered, 1)
|
||||
@@ -0,0 +1,53 @@
|
||||
|
||||
///////////////
|
||||
//DRONE VERBS//
|
||||
///////////////
|
||||
//Drone verbs that appear in the Drone tab and on buttons
|
||||
|
||||
|
||||
/mob/living/simple_animal/drone/verb/check_laws()
|
||||
set category = "Drone"
|
||||
set name = "Check Laws"
|
||||
|
||||
src << "<b>Drone Laws</b>"
|
||||
src << laws
|
||||
|
||||
/mob/living/simple_animal/drone/verb/toggle_light()
|
||||
set category = "Drone"
|
||||
set name = "Toggle drone light"
|
||||
if(light_on)
|
||||
AddLuminosity(-4)
|
||||
else
|
||||
AddLuminosity(4)
|
||||
|
||||
light_on = !light_on
|
||||
|
||||
src << "<span class='notice'>Your light is now [light_on ? "on" : "off"]</span>"
|
||||
|
||||
/mob/living/simple_animal/drone/verb/drone_ping()
|
||||
set category = "Drone"
|
||||
set name = "Drone ping"
|
||||
|
||||
var/alert_s = input(src,"Alert severity level","Drone ping",null) as null|anything in list("Low","Medium","High","Critical")
|
||||
|
||||
var/area/A = get_area(loc)
|
||||
|
||||
if(alert_s && A && stat != DEAD)
|
||||
var/msg = "<span class='boldnotice'>DRONE PING: [name]: [alert_s] priority alert in [A.name]!</span>"
|
||||
alert_drones(msg)
|
||||
|
||||
|
||||
/mob/living/simple_animal/drone/verb/toggle_statics()
|
||||
set name = "Change Vision Filter"
|
||||
set desc = "Change the filter on the system used to remove non drone beings from your viewscreen."
|
||||
set category = "Drone"
|
||||
|
||||
if(!seeStatic)
|
||||
src << "<span class='notice'>You have no vision filter to change!</span>"
|
||||
return
|
||||
|
||||
var/selectedStatic = input("Select a vision filter", "Vision Filter") as null|anything in staticChoices
|
||||
if(selectedStatic in staticChoices)
|
||||
staticChoice = selectedStatic
|
||||
|
||||
updateSeeStaticMobs()
|
||||
@@ -0,0 +1,159 @@
|
||||
|
||||
/////////////////
|
||||
//DRONE VISUALS//
|
||||
/////////////////
|
||||
//Drone overlays
|
||||
//Drone visuals
|
||||
|
||||
|
||||
/mob/living/simple_animal/drone/proc/apply_overlay(cache_index)
|
||||
var/image/I = drone_overlays[cache_index]
|
||||
if(I)
|
||||
overlays += I
|
||||
|
||||
|
||||
/mob/living/simple_animal/drone/proc/remove_overlay(cache_index)
|
||||
if(drone_overlays[cache_index])
|
||||
overlays -= drone_overlays[cache_index]
|
||||
drone_overlays[cache_index] = null
|
||||
|
||||
|
||||
/mob/living/simple_animal/drone/proc/update_inv_hands()
|
||||
remove_overlay(DRONE_HANDS_LAYER)
|
||||
var/list/hands_overlays = list()
|
||||
|
||||
var/y_shift = getItemPixelShiftY()
|
||||
|
||||
if(r_hand)
|
||||
var/r_state = r_hand.item_state
|
||||
if(!r_state)
|
||||
r_state = r_hand.icon_state
|
||||
|
||||
var/image/r_hand_image = image("icon" = r_hand.righthand_file, "icon_state"="[r_state]", "layer"=-DRONE_HANDS_LAYER)
|
||||
if(y_shift != 0)
|
||||
r_hand_image.pixel_y = y_shift
|
||||
|
||||
hands_overlays += r_hand_image
|
||||
|
||||
if(client && hud_used)
|
||||
r_hand.layer = 20
|
||||
r_hand.screen_loc = ui_rhand
|
||||
client.screen |= r_hand
|
||||
|
||||
if(l_hand)
|
||||
var/l_state = l_hand.item_state
|
||||
if(!l_state)
|
||||
l_state = l_hand.icon_state
|
||||
|
||||
var/image/l_hand_image = image("icon" = l_hand.lefthand_file, "icon_state"="[l_state]", "layer"=-DRONE_HANDS_LAYER)
|
||||
if(y_shift != 0)
|
||||
l_hand_image.pixel_y = y_shift
|
||||
|
||||
hands_overlays += l_hand_image
|
||||
|
||||
if(client && hud_used)
|
||||
l_hand.layer = 20
|
||||
l_hand.screen_loc = ui_lhand
|
||||
client.screen |= l_hand
|
||||
|
||||
|
||||
if(hands_overlays.len)
|
||||
drone_overlays[DRONE_HANDS_LAYER] = hands_overlays
|
||||
apply_overlay(DRONE_HANDS_LAYER)
|
||||
|
||||
|
||||
/mob/living/simple_animal/drone/proc/update_inv_internal_storage()
|
||||
if(internal_storage && client && hud_used)
|
||||
internal_storage.screen_loc = ui_drone_storage
|
||||
client.screen += internal_storage
|
||||
|
||||
|
||||
/mob/living/simple_animal/drone/update_inv_head()
|
||||
remove_overlay(DRONE_HEAD_LAYER)
|
||||
|
||||
if(head)
|
||||
if(client && hud_used)
|
||||
head.screen_loc = ui_drone_head
|
||||
client.screen += head
|
||||
|
||||
|
||||
var/image/head_overlay = image("icon"='icons/mob/head.dmi', "icon_state"="[head.icon_state]", "layer"=-DRONE_HEAD_LAYER)
|
||||
if(istype(head, /obj/item/clothing/mask))
|
||||
head_overlay.icon = 'icons/mob/mask.dmi'
|
||||
head_overlay.color = head.color
|
||||
head_overlay.alpha = head.alpha
|
||||
head_overlay.pixel_y = -15
|
||||
|
||||
drone_overlays[DRONE_HEAD_LAYER] = head_overlay
|
||||
|
||||
apply_overlay(DRONE_HEAD_LAYER)
|
||||
|
||||
|
||||
//These procs serve as redirection so that the drone updates as expected when other things call these procs
|
||||
/mob/living/simple_animal/drone/update_inv_l_hand()
|
||||
update_inv_hands()
|
||||
|
||||
|
||||
/mob/living/simple_animal/drone/update_inv_r_hand()
|
||||
update_inv_hands()
|
||||
|
||||
|
||||
/mob/living/simple_animal/drone/update_inv_wear_mask()
|
||||
update_inv_head()
|
||||
|
||||
|
||||
/mob/living/simple_animal/drone/proc/pickVisualAppearence()
|
||||
picked = FALSE
|
||||
var/appearence = input("Choose your appearence!", "Appearence", "Maintenance Drone") in list("Maintenance Drone", "Repair Drone")
|
||||
switch(appearence)
|
||||
if("Maintenance Drone")
|
||||
visualAppearence = MAINTDRONE
|
||||
var/colour = input("Choose your colour!", "Colour", "grey") in list("grey", "blue", "red", "green", "pink", "orange")
|
||||
icon_state = "[visualAppearence]_[colour]"
|
||||
icon_living = "[visualAppearence]_[colour]"
|
||||
icon_dead = "[visualAppearence]_dead"
|
||||
|
||||
if("Repair Drone")
|
||||
visualAppearence = REPAIRDRONE
|
||||
icon_state = visualAppearence
|
||||
icon_living = visualAppearence
|
||||
icon_dead = "[visualAppearence]_dead"
|
||||
|
||||
else
|
||||
return
|
||||
|
||||
picked = TRUE
|
||||
|
||||
|
||||
|
||||
/mob/living/simple_animal/drone/proc/getItemPixelShiftY()
|
||||
switch(visualAppearence)
|
||||
if(MAINTDRONE)
|
||||
. = 0
|
||||
if(REPAIRDRONE)
|
||||
. = -6
|
||||
|
||||
/mob/living/simple_animal/drone/proc/updateSeeStaticMobs()
|
||||
if(!client)
|
||||
return
|
||||
|
||||
for(var/i in staticOverlays)
|
||||
client.images.Remove(i)
|
||||
staticOverlays.Remove(i)
|
||||
staticOverlays.len = 0
|
||||
|
||||
if(seeStatic)
|
||||
for(var/mob/living/L in mob_list)
|
||||
if(isdrone(L))
|
||||
continue
|
||||
var/image/chosen
|
||||
if(staticChoice in L.staticOverlays)
|
||||
chosen = L.staticOverlays[staticChoice]
|
||||
else
|
||||
chosen = L.staticOverlays["static"]
|
||||
staticOverlays |= chosen
|
||||
client.images |= chosen
|
||||
|
||||
|
||||
/mob/living/simple_animal/drone/generateStaticOverlay()
|
||||
return
|
||||
@@ -7,7 +7,7 @@
|
||||
status_flags = CANPUSH
|
||||
|
||||
var/icon_living = ""
|
||||
var/icon_dead = ""
|
||||
var/icon_dead = "" //icon when the animal is dead. Don't use animated icons for this.
|
||||
var/icon_gib = null //We only try to show a gibbing animation if this exists.
|
||||
|
||||
var/list/speak = list()
|
||||
|
||||
+1
-10
@@ -470,13 +470,6 @@ var/list/slot_equipment_priority = list( \
|
||||
if (popup)
|
||||
memory()
|
||||
|
||||
/*
|
||||
/mob/verb/help()
|
||||
set name = "Help"
|
||||
src << browse('html/help.html', "window=help")
|
||||
return
|
||||
*/
|
||||
|
||||
/mob/verb/abandon_mob()
|
||||
set name = "Respawn"
|
||||
set category = "OOC"
|
||||
@@ -513,8 +506,6 @@ var/list/slot_equipment_priority = list( \
|
||||
set name = "Changelog"
|
||||
set category = "OOC"
|
||||
getFiles(
|
||||
'html/postcardsmall.jpg',
|
||||
'html/somerights20.png',
|
||||
'html/88x31.png',
|
||||
'html/bug-minus.png',
|
||||
'html/cross-circle.png',
|
||||
@@ -537,7 +528,7 @@ var/list/slot_equipment_priority = list( \
|
||||
if(prefs.lastchangelog != changelog_hash)
|
||||
prefs.lastchangelog = changelog_hash
|
||||
prefs.save_preferences()
|
||||
winset(src, "rpane.changelog", "background-color=none;font-style=;")
|
||||
winset(src, "rpane.changelogb", "background-color=none;font-style=;")
|
||||
|
||||
/mob/verb/observe()
|
||||
set name = "Observe"
|
||||
|
||||
@@ -135,17 +135,18 @@
|
||||
|
||||
if(isturf(mob.loc))
|
||||
|
||||
move_delay = world.time//set move delay
|
||||
|
||||
if(mob.restrained()) //Why being pulled while cuffed prevents you from moving
|
||||
for(var/mob/M in range(mob, 1))
|
||||
if(M.pulling == mob)
|
||||
if(!M.incapacitated() && mob.Adjacent(M))
|
||||
src << "<span class='notice'>You're restrained! You can't move!</span>"
|
||||
move_delay += 10
|
||||
return 0
|
||||
else
|
||||
M.stop_pulling()
|
||||
|
||||
move_delay = world.time//set move delay
|
||||
|
||||
switch(mob.m_intent)
|
||||
if("run")
|
||||
if(mob.drowsyness > 0)
|
||||
|
||||
@@ -126,8 +126,12 @@
|
||||
if(!ticker || ticker.current_state != GAME_STATE_PLAYING)
|
||||
usr << "<span class='danger'>The round is either not ready, or has already finished...</span>"
|
||||
return
|
||||
var/relevent_cap = max(config.hard_popcap, config.extreme_popcap)
|
||||
if(relevent_cap && living_player_count() >= relevent_cap && !(ckey(key) in admin_datums))
|
||||
var/relevant_cap
|
||||
if(config.hard_popcap && config.extreme_popcap)
|
||||
relevant_cap = min(config.hard_popcap, config.extreme_popcap)
|
||||
else
|
||||
relevant_cap = max(config.hard_popcap, config.extreme_popcap)
|
||||
if(relevant_cap && living_player_count() >= relevant_cap && !(ckey(key) in admin_datums))
|
||||
usr << "<span class='danger'>[config.hard_popcap_message]</span>"
|
||||
return
|
||||
LateChoices()
|
||||
@@ -246,7 +250,12 @@
|
||||
if(!job)
|
||||
return 0
|
||||
if((job.current_positions >= job.total_positions) && job.total_positions != -1)
|
||||
return 0
|
||||
if(job.title == "Assistant")
|
||||
for(var/datum/job/J in SSjob.occupations)
|
||||
if(J && J.current_positions < J.total_positions && J.title != job.title)
|
||||
return 0
|
||||
else
|
||||
return 0
|
||||
if(jobban_isbanned(src,rank))
|
||||
return 0
|
||||
if(!job.player_old_enough(src.client))
|
||||
@@ -329,6 +338,11 @@
|
||||
if (job.title in command_positions)
|
||||
position_class = "commandPosition"
|
||||
dat += "<a class='[position_class]' href='byond://?src=\ref[src];SelectedJob=[job.title]'>[job.title] ([job.current_positions])</a><br>"
|
||||
if(!job_count) //if there's nowhere to go, assistant opens up.
|
||||
for(var/datum/job/job in SSjob.occupations)
|
||||
if(job.title != "Assistant") continue
|
||||
dat += "<a class='otherPosition' href='byond://?src=\ref[src];SelectedJob=[job.title]'>[job.title] ([job.current_positions])</a><br>"
|
||||
break
|
||||
dat += "</div></div>"
|
||||
|
||||
// Removing the old window method but leaving it here for reference
|
||||
|
||||
@@ -182,3 +182,7 @@
|
||||
|
||||
return 1 // success
|
||||
|
||||
//Send all needed nano ui files to the client
|
||||
/datum/subsystem/nano/proc/send_resources(client)
|
||||
for(var/file in asset_files)
|
||||
client << browse_rsc(file)
|
||||
|
||||
@@ -228,7 +228,7 @@ datum/reagent/crank/addiction_act_stage4(var/mob/living/M as mob)
|
||||
name = "methamphetamine"
|
||||
id = "methamphetamine"
|
||||
result = "methamphetamine"
|
||||
required_reagents = list("ephedrine" = 1, "iodine" = 1, "phosphorous" = 1, "hydrogen" = 1)
|
||||
required_reagents = list("ephedrine" = 1, "iodine" = 1, "phosphorus" = 1, "hydrogen" = 1)
|
||||
result_amount = 4
|
||||
required_temp = 374
|
||||
|
||||
@@ -506,4 +506,4 @@ datum/reagent/hotline/addiction_act_stage4(var/mob/living/M as mob)
|
||||
M.visible_message("<span class = 'userdanger'>[M] clutches at their chest! It looks like they're having a heart attack!</span>")
|
||||
M.adjustBruteLoss(80) // don't do drugs kids
|
||||
..()
|
||||
return
|
||||
return
|
||||
|
||||
@@ -101,10 +101,10 @@
|
||||
id = "liquid_dark_matter"
|
||||
result = "liquid_dark_matter"
|
||||
required_reagents = list("stable_plasma" = 1, "radium" = 1, "carbon" = 1)
|
||||
result_amount = 3
|
||||
result_amount = null
|
||||
required_temp = 474
|
||||
|
||||
/datum/reagent/liquid_dark_matter/reaction_turf(var/turf/simulated/T, var/volume)
|
||||
/*/datum/reagent/liquid_dark_matter/reaction_turf(var/turf/simulated/T, var/volume)
|
||||
if(istype(T, /turf/simulated/floor/))
|
||||
goonchem_vortex(T, 0, 5, 3)
|
||||
return
|
||||
@@ -114,13 +114,13 @@
|
||||
if(method == TOUCH)
|
||||
var/turf/simulated/T = get_turf(M)
|
||||
goonchem_vortex(T, 0, 5, 3)
|
||||
return
|
||||
return*/ //o god what the fuck goof
|
||||
/datum/chemical_reaction/liquid_dark_matter/on_reaction(var/datum/reagents/holder, var/created_volume)
|
||||
var/turf/simulated/T = get_turf(holder.my_atom)
|
||||
goonchem_vortex(T, 0, 5, 6)
|
||||
return
|
||||
|
||||
proc/goonchem_vortex(var/turf/simulated/T, var/setting_type, var/range, var/pull_times)
|
||||
/proc/goonchem_vortex(var/turf/simulated/T, var/setting_type, var/range, var/pull_times)
|
||||
for(var/atom/movable/X in orange(range, T))
|
||||
if(istype(X, /obj/effect))
|
||||
continue //stop pulling smoke and hotspots please
|
||||
|
||||
@@ -67,6 +67,7 @@ datum/reagent/blob/lung_destroying_toxin
|
||||
datum/reagent/blob/lung_destroying_toxin/reaction_mob(var/mob/living/M as mob, var/method=TOUCH, var/volume,var/show_message = 1)
|
||||
if(method == TOUCH)
|
||||
M.apply_damage(20, OXY)
|
||||
M.losebreath += 15
|
||||
M.apply_damage(20, TOX)
|
||||
if(show_message)
|
||||
M << "<span class = 'userdanger'>The blob strikes you, and your lungs feel heavy and weak!</span>"
|
||||
@@ -95,13 +96,11 @@ datum/reagent/blob/radioactive_liquid/reaction_mob(var/mob/living/M as mob, var/
|
||||
if(method == TOUCH)
|
||||
if(istype(M, /mob/living/carbon/human))
|
||||
M.apply_damage(10, BRUTE)
|
||||
M.apply_effect(10,IRRADIATE,0)
|
||||
M.apply_effect(40,IRRADIATE,0) // irradiate the shit out of these fuckers
|
||||
if(prob(33))
|
||||
randmuti(M)
|
||||
if(prob(98))
|
||||
randmutb(M)
|
||||
else
|
||||
randmutg(M)
|
||||
domutcheck(M, null)
|
||||
updateappearance(M)
|
||||
if(show_message)
|
||||
@@ -151,7 +150,7 @@ datum/reagent/blob/explosive/reaction_mob(var/mob/living/M as mob, var/method=TO
|
||||
var/turf/pull = get_turf(M)
|
||||
for(var/atom/movable/X in orange(4,pull))
|
||||
if(istype(X, /atom/movable))
|
||||
if((X))
|
||||
if((X) && !X.anchored)
|
||||
if(setting_type)
|
||||
step_away(X,pull)
|
||||
step_away(X,pull)
|
||||
|
||||
@@ -261,10 +261,12 @@ datum/reagent/water/reaction_turf(var/turf/simulated/T, var/volume)
|
||||
G.temperature = max(min(G.temperature-(CT*1000),G.temperature/CT),0)
|
||||
G.react()
|
||||
qdel(hotspot)
|
||||
T.color = initial(T.color)
|
||||
return
|
||||
|
||||
datum/reagent/water/reaction_obj(var/obj/O, var/volume)
|
||||
src = null
|
||||
O.color = initial(O.color)
|
||||
if(istype(O,/obj/item/weapon/reagent_containers/food/snacks/monkeycube))
|
||||
var/obj/item/weapon/reagent_containers/food/snacks/monkeycube/cube = O
|
||||
if(!cube.wrapped)
|
||||
@@ -274,6 +276,7 @@ datum/reagent/water/reaction_obj(var/obj/O, var/volume)
|
||||
datum/reagent/water/reaction_mob(var/mob/living/M, var/method=TOUCH, var/volume)//Splashing people with water can help put them out!
|
||||
if(!istype(M, /mob/living))
|
||||
return
|
||||
M.color = initial(M.color)
|
||||
if(method == TOUCH)
|
||||
M.adjust_fire_stacks(-(volume / 10))
|
||||
if(M.fire_stacks <= 0)
|
||||
@@ -721,7 +724,7 @@ datum/reagent/cryptobiolin
|
||||
id = "cryptobiolin"
|
||||
description = "Cryptobiolin causes confusion and dizzyness."
|
||||
color = "#C8A5DC" // rgb: 200, 165, 220
|
||||
metabolization_rate = 0.5 * REAGENTS_METABOLISM
|
||||
metabolization_rate = 1.5 * REAGENTS_METABOLISM
|
||||
|
||||
datum/reagent/cryptobiolin/on_mob_life(var/mob/living/M as mob)
|
||||
M.Dizzy(1)
|
||||
|
||||
+2
-1
@@ -315,9 +315,10 @@ datum/reagent/consumable/ethanol/beepsky_smash
|
||||
description = "Deny drinking this and prepare for THE LAW."
|
||||
color = "#664300" // rgb: 102, 67, 0
|
||||
boozepwr = 25
|
||||
metabolization_rate = 0.8
|
||||
|
||||
datum/reagent/consumable/ethanol/beepsky_smash/on_mob_life(var/mob/living/M as mob)
|
||||
M.Stun(2)
|
||||
M.Stun(1)
|
||||
..()
|
||||
return
|
||||
|
||||
|
||||
@@ -255,7 +255,7 @@ datum/reagent/toxin/chloralhydrate
|
||||
reagent_state = SOLID
|
||||
color = "#000067" // rgb: 0, 0, 103
|
||||
toxpwr = 0
|
||||
metabolization_rate = 0.5 * REAGENTS_METABOLISM
|
||||
metabolization_rate = 1.5 * REAGENTS_METABOLISM
|
||||
|
||||
datum/reagent/toxin/chloralhydrate/on_mob_life(var/mob/living/M as mob)
|
||||
if(!data)
|
||||
@@ -278,7 +278,7 @@ datum/reagent/toxin/beer2 //disguised as normal beer for use by emagged brobots
|
||||
id = "beer2"
|
||||
description = "An alcoholic beverage made from malted grains, hops, yeast, and water."
|
||||
color = "#664300" // rgb: 102, 67, 0
|
||||
metabolization_rate = 0.5 * REAGENTS_METABOLISM
|
||||
metabolization_rate = 1.5 * REAGENTS_METABOLISM
|
||||
|
||||
datum/reagent/toxin/beer2/on_mob_life(var/mob/living/M as mob)
|
||||
if(!data)
|
||||
|
||||
@@ -187,7 +187,7 @@
|
||||
amount_per_transfer_from_this = (amount_per_transfer_from_this == 10 ? 5 : 10)
|
||||
user << "<span class='notice'>You adjust the output switch. You'll now use [amount_per_transfer_from_this] units per spray.</span>"
|
||||
|
||||
/obj/item/weapon/reagent_containers/spray/chemsprayer/bioterror/New()
|
||||
/obj/item/weapon/reagent_containers/spray/chemsprayer/bioterror
|
||||
list_reagents = list("spore" = 150, "cryptobiolin" = 150, "mutagen" = 150, "chloralhydrate" = 150)
|
||||
|
||||
// Plant-B-Gone
|
||||
|
||||
@@ -98,6 +98,8 @@
|
||||
..()
|
||||
if(istype(Proj ,/obj/item/projectile/beam)||istype(Proj,/obj/item/projectile/bullet))
|
||||
if((Proj.damage_type == BURN) || (Proj.damage_type == BRUTE))
|
||||
if(Proj.nodamage)
|
||||
return
|
||||
message_admins("[key_name_admin(Proj.firer)] triggered a fueltank explosion.")
|
||||
log_game("[key_name(Proj.firer)] triggered a fueltank explosion.")
|
||||
explosion(src.loc,-1,0,2, flame_range = 2)
|
||||
|
||||
@@ -61,13 +61,13 @@ using metal and glass, it uses glass and reagents (usually sulfuric acis).
|
||||
/obj/machinery/r_n_d/circuit_imprinter/proc/check_mat(datum/design/being_built, var/M)
|
||||
switch(M)
|
||||
if("$glass")
|
||||
return (g_amount - (being_built.materials[M]/efficiency_coeff) >= 0) ? 1 : 0
|
||||
return (g_amount - (being_built.materials[M]/efficiency_coeff) >= 0)
|
||||
if("$gold")
|
||||
return (gold_amount - (being_built.materials[M]/efficiency_coeff) >= 0) ? 1 : 0
|
||||
return (gold_amount - (being_built.materials[M]/efficiency_coeff) >= 0)
|
||||
if("$diamond")
|
||||
return (diamond_amount - (being_built.materials[M]/efficiency_coeff) >= 0) ? 1 : 0
|
||||
return (diamond_amount - (being_built.materials[M]/efficiency_coeff) >= 0)
|
||||
else
|
||||
return (reagents.has_reagent(M, (being_built.materials[M]/efficiency_coeff)) != 0) ? 1 : 0
|
||||
return (reagents.has_reagent(M, (being_built.materials[M]/efficiency_coeff)) != 0)
|
||||
|
||||
|
||||
/obj/machinery/r_n_d/circuit_imprinter/proc/TotalMaterials()
|
||||
|
||||
@@ -328,8 +328,8 @@
|
||||
R.delete()
|
||||
ejectItem(TRUE)
|
||||
if(prob(EFFECT_PROB_VERYLOW-badThingCoeff))
|
||||
visible_message("<span class='notice'>[src]'s chemical chamber has sprung a leak!.</span>")
|
||||
chosenchem = pick("mutationtoxin","nanomachines","xenomicrobes")
|
||||
visible_message("<span class='danger'>[src]'s chemical chamber has sprung a leak!</span>")
|
||||
chosenchem = pick("mutationtoxin","nanomachines","sacid")
|
||||
var/datum/reagents/R = new/datum/reagents(50)
|
||||
R.my_atom = src
|
||||
R.add_reagent(chosenchem , 50)
|
||||
@@ -720,4 +720,4 @@
|
||||
/obj/item/weapon/relic/proc/warn_admins(var/mob/user, var/RelicType)
|
||||
var/turf/T = get_turf(src)
|
||||
message_admins("[RelicType] relic activated by [key_name(user, user.client)](<A HREF='?_src_=holder;adminmoreinfo=\ref[user]'>?</A>) in ([T.x],[T.y],[T.z] - <A HREF='?_src_=holder;adminplayerobservecoodjump=1;X=[T.x];Y=[T.y];Z=[T.z]'>JMP</a>)",0,1)
|
||||
log_game("[RelicType] relic used by [user.ckey]([user]) in ([T.x],[T.y],[T.z])")
|
||||
log_game("[RelicType] relic used by [user.ckey]([user]) in ([T.x],[T.y],[T.z])")
|
||||
|
||||
@@ -369,34 +369,38 @@ won't update every console in existence) but it's more of a hassle to do. Also,
|
||||
|
||||
|
||||
if (g2g) //If input is incorrect, nothing happens
|
||||
var/enough_materials = 1
|
||||
linked_lathe.busy = 1
|
||||
flick("protolathe_n",linked_lathe)
|
||||
use_power(power)
|
||||
|
||||
for(var/M in being_built.materials)
|
||||
if(!linked_lathe.check_mat(being_built, M))
|
||||
if(linked_lathe.check_mat(being_built, M) < amount)
|
||||
src.visible_message("<span class='notice'>The [src.name] beeps, \"Not enough materials to complete prototype.\"</span>")
|
||||
enough_materials = 0
|
||||
g2g = 0
|
||||
break
|
||||
switch(M)
|
||||
if("$metal")
|
||||
linked_lathe.m_amount = max(0, (linked_lathe.m_amount-(being_built.materials[M]/coeff * amount)))
|
||||
if("$glass")
|
||||
linked_lathe.g_amount = max(0, (linked_lathe.g_amount-(being_built.materials[M]/coeff * amount)))
|
||||
if("$gold")
|
||||
linked_lathe.gold_amount = max(0, (linked_lathe.gold_amount-(being_built.materials[M]/coeff * amount)))
|
||||
if("$silver")
|
||||
linked_lathe.silver_amount = max(0, (linked_lathe.silver_amount-(being_built.materials[M]/coeff * amount)))
|
||||
if("$plasma")
|
||||
linked_lathe.plasma_amount = max(0, (linked_lathe.plasma_amount-(being_built.materials[M]/coeff * amount)))
|
||||
if("$uranium")
|
||||
linked_lathe.uranium_amount = max(0, (linked_lathe.uranium_amount-(being_built.materials[M]/coeff * amount)))
|
||||
if("$diamond")
|
||||
linked_lathe.diamond_amount = max(0, (linked_lathe.diamond_amount-(being_built.materials[M]/coeff * amount)))
|
||||
if("$bananium")
|
||||
linked_lathe.clown_amount = max(0, (linked_lathe.clown_amount-(being_built.materials[M]/coeff * amount)))
|
||||
else
|
||||
linked_lathe.reagents.remove_reagent(M, being_built.materials[M]/coeff * amount)
|
||||
if(enough_materials)
|
||||
for(var/M in being_built.materials)
|
||||
switch(M)
|
||||
if("$metal")
|
||||
linked_lathe.m_amount = max(0, (linked_lathe.m_amount-(being_built.materials[M]/coeff * amount)))
|
||||
if("$glass")
|
||||
linked_lathe.g_amount = max(0, (linked_lathe.g_amount-(being_built.materials[M]/coeff * amount)))
|
||||
if("$gold")
|
||||
linked_lathe.gold_amount = max(0, (linked_lathe.gold_amount-(being_built.materials[M]/coeff * amount)))
|
||||
if("$silver")
|
||||
linked_lathe.silver_amount = max(0, (linked_lathe.silver_amount-(being_built.materials[M]/coeff * amount)))
|
||||
if("$plasma")
|
||||
linked_lathe.plasma_amount = max(0, (linked_lathe.plasma_amount-(being_built.materials[M]/coeff * amount)))
|
||||
if("$uranium")
|
||||
linked_lathe.uranium_amount = max(0, (linked_lathe.uranium_amount-(being_built.materials[M]/coeff * amount)))
|
||||
if("$diamond")
|
||||
linked_lathe.diamond_amount = max(0, (linked_lathe.diamond_amount-(being_built.materials[M]/coeff * amount)))
|
||||
if("$bananium")
|
||||
linked_lathe.clown_amount = max(0, (linked_lathe.clown_amount-(being_built.materials[M]/coeff * amount)))
|
||||
else
|
||||
linked_lathe.reagents.remove_reagent(M, being_built.materials[M]/coeff * amount)
|
||||
|
||||
var/P = being_built.build_path //lets save these values before the spawn() just in case. Nobody likes runtimes.
|
||||
var/R = being_built.reliability
|
||||
@@ -827,17 +831,17 @@ won't update every console in existence) but it's more of a hassle to do. Also,
|
||||
for(var/M in D.materials)
|
||||
t = linked_lathe.check_mat(D, M)
|
||||
temp_material += " | "
|
||||
if (!t)
|
||||
if (t < 1)
|
||||
temp_material += "<span class='bad'>[D.materials[M]/coeff] [CallMaterialName(M)]</span>"
|
||||
else
|
||||
temp_material += " [D.materials[M]/coeff] [CallMaterialName(M)]"
|
||||
c = min(c,t)
|
||||
|
||||
if (c)
|
||||
if (c >= 1)
|
||||
dat += "<A href='?src=\ref[src];build=[D.id];amount=1'>[D.name]</A>"
|
||||
if(c >= 5.0)
|
||||
if(c >= 5)
|
||||
dat += "<A href='?src=\ref[src];build=[D.id];amount=5'>x5</A>"
|
||||
if(c >= 10.0)
|
||||
if(c >= 10)
|
||||
dat += "<A href='?src=\ref[src];build=[D.id];amount=10'>x10</A>"
|
||||
dat += "[temp_material]"
|
||||
else
|
||||
@@ -860,17 +864,17 @@ won't update every console in existence) but it's more of a hassle to do. Also,
|
||||
for(var/M in D.materials)
|
||||
t = linked_lathe.check_mat(D, M)
|
||||
temp_material += " | "
|
||||
if (!t)
|
||||
if (t < 1)
|
||||
temp_material += "<span class='bad'>[D.materials[M]/coeff] [CallMaterialName(M)]</span>"
|
||||
else
|
||||
temp_material += " [D.materials[M]/coeff] [CallMaterialName(M)]"
|
||||
c = min(c,t)
|
||||
|
||||
if (c)
|
||||
if (c >= 1)
|
||||
dat += "<A href='?src=\ref[src];build=[D.id];amount=1'>[D.name]</A>"
|
||||
if(c >= 5.0)
|
||||
if(c >= 5)
|
||||
dat += "<A href='?src=\ref[src];build=[D.id];amount=5'>x5</A>"
|
||||
if(c >= 10.0)
|
||||
if(c >= 10)
|
||||
dat += "<A href='?src=\ref[src];build=[D.id];amount=10'>x10</A>"
|
||||
dat += "[temp_material]"
|
||||
else
|
||||
|
||||
Reference in New Issue
Block a user