Bay Update 02

This commit is contained in:
skull132
2014-06-04 18:20:49 +03:00
parent f535169798
commit f95ab265c1
436 changed files with 30324 additions and 10747 deletions
+25 -1
View File
@@ -275,7 +275,7 @@ var/global/floorIsLava = 0
I.rank = "N/A"
update_file = 1
dat += "<font color=#008800>[I.content]</font> <i>by [I.author] ([I.rank])</i> on <i><font color=blue>[I.timestamp]</i></font> "
if(I.author == usr.key)
if(I.author == usr.key || I.author == "Adminbot")
dat += "<A href='?src=\ref[src];remove_player_info=[key];remove_index=[i]'>Remove</A>"
dat += "<br><br>"
if(update_file) info << infos
@@ -1114,6 +1114,30 @@ var/global/floorIsLava = 0
if(istype(H))
H.regenerate_icons()
proc/get_options_bar(whom, detail = 2, name = 0, link = 1)
if(!whom)
return "<b>(*null*)</b>"
var/mob/M
var/client/C
if(istype(whom, /client))
C = whom
M = C.mob
else if(istype(whom, /mob))
M = whom
C = M.client
else
return "<b>(*not an mob*)</b>"
switch(detail)
if(0)
return "<b>[key_name(C, link, name)]</b>"
if(1)
return "<b>[key_name(C, link, name)](<A HREF='?_src_=holder;adminmoreinfo=\ref[M]'>?</A>)</b>"
if(2)
var/ref_mob = "\ref[M]"
return "<b>[key_name(C, link, name)](<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;check_antagonist=1'>CA</A>)</b>"
//
//
//ALL DONE
+68 -7
View File
@@ -6,7 +6,8 @@ var/list/admin_verbs_default = list(
/client/proc/hide_verbs, /*hides all our adminverbs*/
/client/proc/hide_most_verbs, /*hides all our hideable adminverbs*/
/client/proc/debug_variables, /*allows us to -see- the variables of any instance in the game. +VAREDIT needed to modify*/
/client/proc/check_antagonists /*shows all antags*/
/client/proc/check_antagonists, /*shows all antags*/
/client/proc/cmd_mentor_check_new_players
// /client/proc/deadchat /*toggles deadchat on/off*/
)
var/list/admin_verbs_admin = list(
@@ -69,6 +70,7 @@ var/list/admin_verbs_admin = list(
/client/proc/toggleattacklogs,
/client/proc/toggledebuglogs,
/client/proc/toggleghostwriters,
/client/proc/toggledrones,
/datum/admins/proc/show_skills,
/client/proc/check_customitem_activity,
/client/proc/man_up,
@@ -275,6 +277,8 @@ var/list/admin_verbs_mod = list(
/client/proc/player_panel_new,
/client/proc/dsay,
/datum/admins/proc/show_skills,
/datum/admins/proc/show_player_panel,
/client/proc/check_antagonists,
/client/proc/jobbans,
/client/proc/cmd_admin_subtle_message /*send an message to somebody as a 'voice in their head'*/
)
@@ -566,24 +570,62 @@ var/list/admin_verbs_mod = list(
set category = "Fun"
set name = "Give Spell"
set desc = "Gives a spell to a mob."
var/obj/effect/proc_holder/spell/S = input("Choose the spell to give to that guy", "ABRAKADABRA") as null|anything in spells
var/list/spell_names = list()
for(var/v in spells)
// "/obj/effect/proc_holder/spell/" 30 symbols ~Intercross21
spell_names.Add(copytext("[v]", 31, 0))
var/S = input("Choose the spell to give to that guy", "ABRAKADABRA") as null|anything in spell_names
if(!S) return
T.spell_list += new S
var/path = text2path("/obj/effect/proc_holder/spell/[S]")
T.spell_list += new path
feedback_add_details("admin_verb","GS") //If you are copy-pasting this, ensure the 2nd parameter is unique to the new proc!
log_admin("[key_name(usr)] gave [key_name(T)] the spell [S].")
message_admins("\blue [key_name_admin(usr)] gave [key_name(T)] the spell [S].", 1)
/client/proc/give_disease(mob/T as mob in mob_list) // -- Giacom
set category = "Fun"
set name = "Give Disease"
set desc = "Gives a Disease to a mob."
var/datum/disease/D = input("Choose the disease to give to that guy", "ACHOO") as null|anything in diseases
set name = "Give Disease (old)"
set desc = "Gives a (tg-style) Disease to a mob."
var/list/disease_names = list()
for(var/v in diseases)
// "/datum/disease/" 15 symbols ~Intercross
disease_names.Add(copytext("[v]", 16, 0))
var/datum/disease/D = input("Choose the disease to give to that guy", "ACHOO") as null|anything in disease_names
if(!D) return
T.contract_disease(new D, 1)
var/path = text2path("/datum/disease/[D]")
T.contract_disease(new path, 1)
feedback_add_details("admin_verb","GD") //If you are copy-pasting this, ensure the 2nd parameter is unique to the new proc!
log_admin("[key_name(usr)] gave [key_name(T)] the disease [D].")
message_admins("\blue [key_name_admin(usr)] gave [key_name(T)] the disease [D].", 1)
/client/proc/give_disease2(mob/T as mob in mob_list) // -- Giacom
set category = "Fun"
set name = "Give Disease"
set desc = "Gives a Disease to a mob."
var/datum/disease2/disease/D = new /datum/disease2/disease()
var/greater = ((input("Is this a lesser or greater disease?", "Give Disease") in list("Lesser", "Greater")) == "Greater")
D.makerandom(greater)
if (!greater)
D.infectionchance = 1
D.infectionchance = input("How virulent is this disease? (1-100)", "Give Disease", D.infectionchance) as num
if(istype(T,/mob/living/carbon/human))
var/mob/living/carbon/human/H = T
if (H.species)
D.affected_species = list(H.species.name)
if(istype(T,/mob/living/carbon/monkey))
var/mob/living/carbon/monkey/M = T
D.affected_species = list(M.greaterform)
infect_virus2(T,D,1)
feedback_add_details("admin_verb","GD2") //If you are copy-pasting this, ensure the 2nd parameter is unique to the new proc!
log_admin("[key_name(usr)] gave [key_name(T)] a [(greater)? "greater":"lesser"] disease2 with infection chance [D.infectionchance].")
message_admins("\blue [key_name_admin(usr)] gave [key_name(T)] a [(greater)? "greater":"lesser"] disease2 with infection chance [D.infectionchance].", 1)
/client/proc/make_sound(var/obj/O in world) // -- TLE
set category = "Special Verbs"
set name = "Make Sound"
@@ -702,6 +744,12 @@ var/list/admin_verbs_mod = list(
M.g_eyes = hex2num(copytext(new_eyes, 4, 6))
M.b_eyes = hex2num(copytext(new_eyes, 6, 8))
var/new_skin = input("Please select body color. This is for Tajaran, Unathi, and Skrell only!", "Character Generation") as color
if(new_skin)
M.r_skin = hex2num(copytext(new_skin, 2, 4))
M.g_skin = hex2num(copytext(new_skin, 4, 6))
M.b_skin = hex2num(copytext(new_skin, 6, 8))
var/new_tone = input("Please select skin tone level: 1-220 (1=albino, 35=caucasian, 150=black, 220='very' black)", "Character Generation") as text
if (new_tone)
@@ -776,6 +824,19 @@ var/list/admin_verbs_mod = list(
src << "<b>Enabled ghost writers.</b>"
message_admins("Admin [key_name_admin(usr)] has enabled ghost writers.", 1)
/client/proc/toggledrones()
set name = "Toggle maintenance drones"
set category = "Server"
if(!holder) return
if(config)
if(config.allow_drone_spawn)
config.allow_drone_spawn = 0
src << "<b>Disallowed maint drones.</b>"
message_admins("Admin [key_name_admin(usr)] has disabled maint drones.", 1)
else
config.allow_drone_spawn = 1
src << "<b>Enabled maint drones.</b>"
message_admins("Admin [key_name_admin(usr)] has enabled maint drones.", 1)
/client/proc/toggledebuglogs()
set name = "Toggle Debug Log Messages"
+3 -2
View File
@@ -15,8 +15,9 @@
var/quick_create_object_html = null
var/pathtext = null
pathtext = input("Select the path of the object you wish to create.", "Path", "/obj") in list("/obj","/obj/structure","/obj/item","/obj/item/weapon","/obj/machinery")
pathtext = input("Select the path of the object you wish to create.", "Path", "/obj") as null|anything in list("/obj","/obj/structure","/obj/item","/obj/item/weapon","/obj/item/clothing","/obj/machinery","/obj/mecha")
if(!pathtext)
return
var path = text2path(pathtext)
if (!quick_create_object_html)
+13
View File
@@ -152,3 +152,16 @@ datum/admins/proc/notes_gethtml(var/ckey)
log_admin("[key_name(usr)] deleted one of [key]'s notes.")
del info
/proc/show_player_info_irc(var/key as text)
var/dat = " Info on [key]%0D%0A"
var/savefile/info = new("data/player_saves/[copytext(key, 1, 2)]/[key]/info.sav")
var/list/infos
info >> infos
if(!infos)
dat = "No information found on the given key."
else
for(var/datum/player_info/I in infos)
dat += "[I.content]%0D%0Aby [I.author] ([I.rank]) on [I.timestamp]%0D%0A%0D%0A"
return dat
+5 -1
View File
@@ -18,6 +18,8 @@ var/list/adminhelp_ignored_words = list("unknown","the","a","an","of","monkey","
if(src.handle_spam_prevention(msg,MUTE_ADMINHELP))
return
adminhelped = 1 //Determines if they get the message to reply by clicking the name.
/**src.verbs -= /client/verb/adminhelp
spawn(1200)
@@ -31,6 +33,8 @@ var/list/adminhelp_ignored_words = list("unknown","the","a","an","of","monkey","
if(!msg) return
var/original_msg = msg
//explode the input msg into a list
var/list/msglist = text2list(msg, " ")
@@ -87,7 +91,7 @@ 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 = "\blue <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;check_antagonist=1'>CA</A>) [ai_found ? " (<A HREF='?_src_=holder;adminchecklaws=[ref_mob]'>CL</A>)" : ""]:</b> [msg]"
msg = "\blue <b><font color=red>HELP: </font>[get_options_bar(mob, 2, 1, 1)][ai_found ? " (<A HREF='?_src_=holder;adminchecklaws=[ref_mob]'>CL</A>)" : ""]:</b> [msg]"
//send this msg to all admins
var/admin_number_afk = 0
+40 -63
View File
@@ -35,7 +35,8 @@
//takes input from cmd_admin_pm_context, cmd_admin_pm_panel or /client/Topic and sends them a PM.
//Fetching a message if needed. src is the sender and C is the target client
/client/proc/cmd_admin_pm(var/client/C, var/msg)
/client/proc/cmd_admin_pm(var/client/C, var/msg = null)
if(prefs.muted & MUTE_ADMINHELP)
src << "<font color='red'>Error: Private-Message: You are unable to use PM-s (muted).</font>"
return
@@ -45,14 +46,6 @@
else adminhelp(msg) //admin we are replying to left. adminhelp instead
return
/*if(C && C.last_pm_recieved + config.simultaneous_pm_warning_timeout > world.time && holder)
//send a warning to admins, but have a delay popup for mods
if(holder.rights & R_ADMIN)
src << "\red <b>Simultaneous PMs warning:</b> that player has been PM'd in the last [config.simultaneous_pm_warning_timeout / 10] seconds by: [C.ckey_last_pm]"
else
if(alert("That player has been PM'd in the last [config.simultaneous_pm_warning_timeout / 10] seconds by: [C.ckey_last_pm]","Simultaneous PMs warning","Continue","Cancel") == "Cancel")
return*/
//get message text, limit it's length.and clean/escape html
if(!msg)
msg = input(src,"Message:", "Private message to [key_name(C, 0, holder ? 1 : 0)]") as text|null
@@ -85,7 +78,10 @@
else
recieve_color = "maroon"
send_pm_type = holder.rank + " "
recieve_pm_type = holder.rank
if(!C.holder && holder && holder.fakekey)
recieve_pm_type = "Admin"
else
recieve_pm_type = holder.rank
else if(!C.holder)
src << "<font color='red'>Error: Admin-PM: Non-admin to non-admin PM communication is forbidden.</font>"
@@ -94,7 +90,10 @@
var/recieve_message = ""
if(holder && !C.holder)
recieve_message = "<font color='[recieve_color]' size='4'><b>-- Administrator private message --</b></font>\n"
recieve_message = "<font color='[recieve_color]' size='3'><b>-- Click the [recieve_pm_type]'s name to reply --</b></font>\n"
if(C.adminhelped)
C << recieve_message
C.adminhelped = 0
//AdminPM popup for ApocStation and anybody else who wants to use it. Set it with POPUP_ADMIN_PM in config.txt ~Carn
if(config.popup_admin_pm)
@@ -109,7 +108,7 @@
adminhelp(reply) //sender has left, adminhelp instead
return
recieve_message = "<font color='[recieve_color]'>[recieve_pm_type] PM from-<b>[key_name(src, C, C.holder ? 1 : 0)]</b>: [msg]</font>"
recieve_message = "<font color='[recieve_color]'>[recieve_pm_type] PM from-<b>[get_options_bar(src, C.holder ? 1 : 0, C.holder ? 1 : 0, 1)]</b>: [msg]</font>"
C << recieve_message
src << "<font color='blue'>[send_pm_type]PM to-<b>[key_name(C, src, holder ? 1 : 0)]</b>: [msg]</font>"
@@ -122,57 +121,6 @@
if(C.prefs.toggles & SOUND_ADMINHELP)
C << 'sound/effects/adminhelp.ogg'
/*
if(C.holder)
if(holder) //both are admins
if(holder.rank == "Moderator") //If moderator
C << "<font color='maroon'>Mod PM from-<b>[key_name(src, C, 1)]</b>: [msg]</font>"
src << "<font color='blue'>Mod PM to-<b>[key_name(C, src, 1)]</b>: [msg]</font>"
else
C << "<font color='red'>Admin PM from-<b>[key_name(src, C, 1)]</b>: [msg]</font>"
src << "<font color='blue'>Admin PM to-<b>[key_name(C, src, 1)]</b>: [msg]</font>"
else //recipient is an admin but sender is not
C << "<font color='red'>Reply PM from-<b>[key_name(src, C, 1)]</b>: [msg]</font>"
src << "<font color='blue'>PM to-<b>Admins</b>: [msg]</font>"
//play the recieving admin the adminhelp sound (if they have them enabled)
if(C.prefs.toggles & SOUND_ADMINHELP)
C << 'sound/effects/adminhelp.ogg'
else
if(holder) //sender is an admin but recipient is not. Do BIG RED TEXT
if(holder.rank == "Moderator")
C << "<font color='maroon'>Mod PM from-<b>[key_name(src, C, 0)]</b>: [msg]</font>"
C << "<font color='maroon'><i>Click on the moderators's name to reply.</i></font>"
src << "<font color='blue'>Mod PM to-<b>[key_name(C, src, 1)]</b>: [msg]</font>"
else
C << "<font color='red' size='4'><b>-- Administrator private message --</b></font>"
C << "<font color='red'>Admin PM from-<b>[key_name(src, C, 0)]</b>: [msg]</font>"
C << "<font color='red'><i>Click on the administrator's name to reply.</i></font>"
src << "<font color='blue'>Admin PM to-<b>[key_name(C, src, 1)]</b>: [msg]</font>"
//always play non-admin recipients the adminhelp sound
C << 'sound/effects/adminhelp.ogg'
//AdminPM popup for ApocStation and anybody else who wants to use it. Set it with POPUP_ADMIN_PM in config.txt ~Carn
if(config.popup_admin_pm)
spawn() //so we don't hold the caller proc up
var/sender = src
var/sendername = key
var/reply = input(C, msg,"Admin PM from-[sendername]", "") as text|null //show message and await a reply
if(C && reply)
if(sender)
C.cmd_admin_pm(sender,reply) //sender is still about, let's reply to them
else
adminhelp(reply) //sender has left, adminhelp instead
return
else //neither are admins
src << "<font color='red'>Error: Admin-PM: Non-admin to non-admin PM communication is forbidden.</font>"
return
*/
log_admin("PM: [key_name(src)]->[key_name(C)]: [msg]")
//we don't use message_admins here because the sender/receiver might get it too
@@ -182,3 +130,32 @@
continue
if(X.key!=key && X.key!=C.key && (X.holder.rights & R_ADMIN) || (X.holder.rights & R_MOD) )
X << "<B><font color='blue'>PM: [key_name(src, X, 0)]-&gt;[key_name(C, X, 0)]:</B> \blue [msg]</font>" //inform X
/client/proc/cmd_admin_irc_pm()
if(prefs.muted & MUTE_ADMINHELP)
src << "<font color='red'>Error: Private-Message: You are unable to use PM-s (muted).</font>"
return
var/msg = input(src,"Message:", "Private message to admins on IRC / 400 character limit") as text|null
if(!msg)
return
sanitize(msg)
if(length(msg) > 400) // TODO: if message length is over 400, divide it up into seperate messages, the message length restriction is based on IRC limitations. Probably easier to do this on the bots ends.
src << "\red Your message was not sent because it was more then 400 characters find your message below for ease of copy/pasting"
src << "\blue [msg]"
return
send2adminirc("PlayerPM from [key_name(src)]: [html_decode(msg)]")
src << "<font color='blue'>IRC PM to-<b>IRC-Admins</b>: [msg]</font>"
log_admin("PM: [key_name(src)]->IRC: [msg]")
for(var/client/X in admins)
if(X == src)
continue
if((X.holder.rights & R_ADMIN) || (X.holder.rights & R_MOD))
X << "<B><font color='blue'>PM: [key_name(src, X, 0)]-&gt;IRC-Admins:</B> \blue [msg]</font>"
+1 -1
View File
@@ -44,4 +44,4 @@
else if(M.stat == DEAD && (M.client.prefs.toggles & CHAT_DEAD)) // show the message to regular ghosts who have deadchat toggled on
M.show_message(rendered, 2)
feedback_add_details("admin_verb","D") //If you are copy-pasting this, ensure the 2nd parameter is unique to the new proc!
feedback_add_details("admin_verb","D") //If you are copy-pasting this, ensure the 2nd parameter is unique to the new proc!
+4 -6
View File
@@ -73,11 +73,11 @@ client/proc/one_click_antag()
candidates += applicant
if(candidates.len)
var/numTratiors = min(candidates.len, 3)
var/numTraitors = min(candidates.len, 3)
for(var/i = 0, i<numTratiors, i++)
for(var/i = 0, i<numTraitors, i++)
H = pick(candidates)
H.mind.make_Tratior()
H.mind.make_Traitor()
candidates.Remove(H)
return 1
@@ -492,7 +492,7 @@ client/proc/one_click_antag()
/datum/admins/proc/create_vox_raider(obj/spawn_location, leader_chosen = 0)
var/mob/living/carbon/human/new_vox = new(spawn_location.loc)
var/mob/living/carbon/human/new_vox = new(spawn_location.loc, "Vox")
new_vox.gender = pick(MALE, FEMALE)
new_vox.h_style = "Short Vox Quills"
@@ -512,8 +512,6 @@ client/proc/one_click_antag()
new_vox.dna.ready_dna(new_vox) // Creates DNA.
new_vox.dna.mutantrace = "vox"
new_vox.set_species("Vox") // Actually makes the vox! How about that.
new_vox.add_language("Vox-pidgin")
new_vox.mind_initialize()
new_vox.mind.assigned_role = "MODE"
new_vox.mind.special_role = "Vox Raider"
+31
View File
@@ -65,6 +65,37 @@
message_admins("\blue \bold SubtleMessage: [key_name_admin(usr)] -> [key_name_admin(M)] : [msg]", 1)
feedback_add_details("admin_verb","SMS") //If you are copy-pasting this, ensure the 2nd parameter is unique to the new proc!
/client/proc/cmd_mentor_check_new_players() //Allows mentors / admins to determine who the newer players are.
set category = "Admin"
set name = "Check new Players"
if(!holder)
src << "Only staff members may use this command."
var/age = alert(src, "Age check", "Show accounts yonger then _____ days","7", "30" , "All")
if(age == "All")
age = 9999999
else
age = text2num(age)
var/missing_ages = 0
var/msg = ""
for(var/client/C in clients)
if(C.player_age == "Requires database")
missing_ages = 1
continue
if(C.player_age < age)
msg += "[key_name_admin(C)]: account is [C.player_age] days old<br>"
if(missing_ages)
src << "Some accounts did not have proper ages set in their clients. This function requires database to be present"
if(msg != "")
src << browse(msg, "window=Player_age_check")
else
src << "No matches for that age range found."
/client/proc/cmd_admin_world_narrate() // Allows administrators to fluff events a little easier -- TLE
set category = "Special Verbs"
set name = "Global Narrate"
+1 -6
View File
@@ -18,14 +18,9 @@ var/global/vox_tick = 1
equip_to_slot_or_del(new /obj/item/clothing/glasses/thermal/monocle(src), slot_glasses) // REPLACE WITH CODED VOX ALTERNATIVE.
equip_to_slot_or_del(new /obj/item/device/chameleon(src), slot_l_store)
var/obj/item/weapon/crossbow/W = new(src)
W.cell = new /obj/item/weapon/cell/crap(W)
W.cell.charge = 500
var/obj/item/weapon/spikethrower/W = new(src)
equip_to_slot_or_del(W, slot_r_hand)
var/obj/item/stack/rods/A = new(src)
A.amount = 20
equip_to_slot_or_del(A, slot_l_hand)
if(2) // Vox engineer!
equip_to_slot_or_del(new /obj/item/clothing/suit/space/vox/pressure(src), slot_wear_suit)
+5
View File
@@ -18,6 +18,7 @@
var/area = null
var/time_died_as_mouse = null //when the client last died as a mouse
var/adminhelped = 0
///////////////
//SOUND STUFF//
@@ -32,6 +33,10 @@
// comment out the line below when debugging locally to enable the options & messages menu
//control_freak = 1
var/received_irc_pm = -99999
var/irc_admin //IRC admin that spoke with them last.
var/mute_irc = 0
////////////////////////////////////
//things that require the database//
+15 -3
View File
@@ -45,6 +45,18 @@
cmd_admin_pm(C,null)
return
if(href_list["irc_msg"])
if(!holder && received_irc_pm < world.time - 6000) //Worse they can do is spam IRC for 10 minutes
usr << "<span class='warning'>You are no longer able to use this, it's been more then 10 minutes since an admin on IRC has responded to you</span>"
return
if(mute_irc)
usr << "<span class='warning'You cannot use this as your client has been muted from sending messages to the admins on IRC</span>"
return
cmd_admin_irc_pm()
return
//Logs all hrefs
if(config && config.log_hrefs && href_logfile)
href_logfile << "<small>[time2text(world.timeofday,"hh:mm")] [src] (usr:[usr])</small> || [hsrc ? "[hsrc] " : ""][href]<br>"
@@ -179,6 +191,7 @@
var/DBQuery/query = dbcon.NewQuery("SELECT id, datediff(Now(),firstseen) as age FROM erro_player WHERE ckey = '[sql_ckey]'")
query.Execute()
var/sql_id = 0
player_age = 0 // New players won't have an entry so knowing we have a connection we set this to zero to be updated if their is a record.
while(query.NextRow())
sql_id = query.item[1]
player_age = text2num(query.item[2])
@@ -243,12 +256,11 @@
/client/proc/send_resources()
// preload_vox() //Causes long delays with initial start window and subsequent windows when first logged in.
// Send NanoUI resources to this client
nanomanager.send_resources(src)
getFiles(
'html/search.js',
'html/panels.css',
'html/painew.png',
'html/loading.gif',
'icons/pda_icons/pda_atmos.png',
'icons/pda_icons/pda_back.png',
'icons/pda_icons/pda_bell.png',
+51 -8
View File
@@ -54,6 +54,7 @@ datum/preferences
var/age = 30 //age of character
var/b_type = "A+" //blood type (not-chooseable)
var/underwear = 1 //underwear type
var/undershirt = 1 //undershirt type
var/backbag = 2 //backpack type
var/h_style = "Bald" //Hair type
var/r_hair = 0 //Hair color
@@ -63,7 +64,10 @@ datum/preferences
var/r_facial = 0 //Face hair color
var/g_facial = 0 //Face hair color
var/b_facial = 0 //Face hair color
var/s_tone = 0 //Skin color
var/s_tone = 0 //Skin tone
var/r_skin = 0 //Skin color
var/g_skin = 0 //Skin color
var/b_skin = 0 //Skin color
var/r_eyes = 0 //Eye color
var/g_eyes = 0 //Eye color
var/b_eyes = 0 //Eye color
@@ -338,6 +342,8 @@ datum/preferences
else
dat += "Underwear: <a href ='?_src_=prefs;preference=underwear;task=input'><b>[underwear_f[underwear]]</b></a><br>"
dat += "Undershirt: <a href='?_src_=prefs;preference=undershirt;task=input'><b>[undershirt_t[undershirt]]</b></a><br>"
dat += "Backpack Type:<br><a href ='?_src_=prefs;preference=bag;task=input'><b>[backbaglist[backbag]]</b></a><br>"
dat += "Nanotrasen Relation:<br><a href ='?_src_=prefs;preference=nt_relation;task=input'><b>[nanotrasen_relation]</b></a><br>"
@@ -374,7 +380,10 @@ datum/preferences
dat += " Style: <a href='?_src_=prefs;preference=f_style;task=input'>[f_style]</a><br>"
dat += "<br><b>Eyes</b><br>"
dat += "<a href='?_src_=prefs;preference=eyes;task=input'>Change Color</a> <font face='fixedsys' size='3' color='#[num2hex(r_eyes, 2)][num2hex(g_eyes, 2)][num2hex(b_eyes, 2)]'><table style='display:inline;' bgcolor='#[num2hex(r_eyes, 2)][num2hex(g_eyes, 2)][num2hex(b_eyes)]'><tr><td>__</td></tr></table></font>"
dat += "<a href='?_src_=prefs;preference=eyes;task=input'>Change Color</a> <font face='fixedsys' size='3' color='#[num2hex(r_eyes, 2)][num2hex(g_eyes, 2)][num2hex(b_eyes, 2)]'><table style='display:inline;' bgcolor='#[num2hex(r_eyes, 2)][num2hex(g_eyes, 2)][num2hex(b_eyes)]'><tr><td>__</td></tr></table></font><br>"
dat += "<br><b>Body Color</b><br>"
dat += "<a href='?_src_=prefs;preference=skin;task=input'>Change Color</a> <font face='fixedsys' size='3' color='#[num2hex(r_skin, 2)][num2hex(g_skin, 2)][num2hex(b_skin, 2)]'><table style='display:inline;' bgcolor='#[num2hex(r_skin, 2)][num2hex(g_skin, 2)][num2hex(b_skin)]'><tr><td>__</td></tr></table></font>"
dat += "<br><br>"
if(jobban_isbanned(user, "Syndicate"))
@@ -401,9 +410,9 @@ datum/preferences
dat += "<a href='?_src_=prefs;preference=reset_all'>Reset Setup</a>"
dat += "</center></body></html>"
user << browse(dat, "window=preferences;size=560x580")
user << browse(dat, "window=preferences;size=560x736")
proc/SetChoices(mob/user, limit = 16, list/splitJobs = list("Chief Medical Officer"), width = 550, height = 550)
proc/SetChoices(mob/user, limit = 16, list/splitJobs = list("Chief Medical Officer"), width = 550, height = 660)
if(!job_master)
return
@@ -415,7 +424,7 @@ datum/preferences
var/HTML = "<body>"
HTML += "<tt><center>"
HTML += "<b>Choose occupation chances</b><br>Unavailable occupations are in red.<br><br>"
HTML += "<b>Choose occupation chances</b><br>Unavailable occupations are crossed out.<br><br>"
HTML += "<center><a href='?_src_=prefs;preference=job;task=close'>\[Done\]</a></center><br>" // Easier to press up here.
HTML += "<table width='100%' cellpadding='1' cellspacing='0'><tr><td width='20%'>" // Table within a table for alignment, also allows you to easily add more colomns.
HTML += "<table width='100%' cellpadding='1' cellspacing='0'>"
@@ -440,11 +449,11 @@ datum/preferences
var/rank = job.title
lastJob = job
if(jobban_isbanned(user, rank))
HTML += "<font color=red>[rank]</font></td><td><font color=red><b> \[BANNED]</b></font></td></tr>"
HTML += "<del>[rank]</del></td><td><b> \[BANNED]</b></td></tr>"
continue
if(!job.player_old_enough(user.client))
var/available_in_days = job.available_in_days(user.client)
HTML += "<font color=red>[rank]</font></td><td><font color=red> \[IN [(available_in_days)] DAYS]</font></td></tr>"
HTML += "<del>[rank]</del></td><td> \[IN [(available_in_days)] DAYS]</td></tr>"
continue
if((job_civilian_low & ASSISTANT) && (rank != "Assistant"))
HTML += "<font color=orange>[rank]</font></td><td></td></tr>"
@@ -552,6 +561,8 @@ datum/preferences
return
proc/SetAntagoptions(mob/user)
if(uplinklocation == "" || !uplinklocation)
uplinklocation = "PDA"
var/HTML = "<body>"
HTML += "<tt><center>"
HTML += "<b>Antagonist Options</b> <hr />"
@@ -843,12 +854,19 @@ datum/preferences
if("underwear")
underwear = rand(1,underwear_m.len)
ShowChoices(user)
if("undershirt")
undershirt = rand(1,undershirt_t.len)
ShowChoices(user)
if("eyes")
r_eyes = rand(0,255)
g_eyes = rand(0,255)
b_eyes = rand(0,255)
if("s_tone")
s_tone = random_skin_tone()
if("s_color")
r_skin = rand(0,255)
g_skin = rand(0,255)
b_skin = rand(0,255)
if("bag")
backbag = rand(1,4)
/*if("skin_style")
@@ -963,7 +981,7 @@ datum/preferences
b_type = new_b_type
if("hair")
if(species == "Human" || species == "Unathi")
if(species == "Human" || species == "Unathi" || species == "Tajaran" || species == "Skrell")
var/new_hair = input(user, "Choose your character's hair colour:", "Character Preference") as color|null
if(new_hair)
r_hair = hex2num(copytext(new_hair, 2, 4))
@@ -1019,6 +1037,15 @@ datum/preferences
underwear = underwear_options.Find(new_underwear)
ShowChoices(user)
if("undershirt")
var/list/undershirt_options
undershirt_options = undershirt_t
var/new_undershirt = input(user, "Choose your character's undershirt:", "Character Preference") as null|anything in undershirt_options
if (new_undershirt)
undershirt = undershirt_options.Find(new_undershirt)
ShowChoices(user)
if("eyes")
var/new_eyes = input(user, "Choose your character's eye colour:", "Character Preference") as color|null
if(new_eyes)
@@ -1033,6 +1060,14 @@ datum/preferences
if(new_s_tone)
s_tone = 35 - max(min( round(new_s_tone), 220),1)
if("skin")
if(species == "Unathi" || species == "Tajaran" || species == "Skrell")
var/new_skin = input(user, "Choose your character's skin colour: ", "Character Preference") as color|null
if(new_skin)
r_skin = hex2num(copytext(new_skin, 2, 4))
g_skin = hex2num(copytext(new_skin, 4, 6))
b_skin = hex2num(copytext(new_skin, 6, 8))
if("ooccolor")
var/new_ooccolor = input(user, "Choose your OOC colour:", "Game Preference") as color|null
if(new_ooccolor)
@@ -1263,6 +1298,10 @@ datum/preferences
character.g_facial = g_facial
character.b_facial = b_facial
character.r_skin = r_skin
character.g_skin = g_skin
character.b_skin = b_skin
character.s_tone = s_tone
character.h_style = h_style
@@ -1295,6 +1334,10 @@ datum/preferences
underwear = 0 //I'm sure this is 100% unnecessary, but I'm paranoid... sue me. //HAH NOW NO MORE MAGIC CLONING UNDIES
character.underwear = underwear
if(undershirt > undershirt_t.len || undershirt < 1)
undershirt = 0
character.undershirt = undershirt
if(backbag > 4 || backbag < 1)
backbag = 1 //Same as above
character.backbag = backbag
+18 -2
View File
@@ -84,8 +84,6 @@
S["be_special"] << be_special
S["default_slot"] << default_slot
S["toggles"] << toggles
S["UI_style_color"] << UI_style_color
S["UI_style_alpha"] << UI_style_alpha
return 1
@@ -119,12 +117,16 @@
S["facial_green"] >> g_facial
S["facial_blue"] >> b_facial
S["skin_tone"] >> s_tone
S["skin_red"] >> r_skin
S["skin_green"] >> g_skin
S["skin_blue"] >> b_skin
S["hair_style_name"] >> h_style
S["facial_style_name"] >> f_style
S["eyes_red"] >> r_eyes
S["eyes_green"] >> g_eyes
S["eyes_blue"] >> b_eyes
S["underwear"] >> underwear
S["undershirt"] >> undershirt
S["backbag"] >> backbag
S["b_type"] >> b_type
@@ -158,6 +160,9 @@
S["uplinklocation"] >> uplinklocation
S["UI_style_color"] << UI_style_color
S["UI_style_alpha"] << UI_style_alpha
//Sanitize
metadata = sanitize_text(metadata, initial(metadata))
real_name = reject_bad_name(real_name)
@@ -175,12 +180,16 @@
g_facial = sanitize_integer(g_facial, 0, 255, initial(g_facial))
b_facial = sanitize_integer(b_facial, 0, 255, initial(b_facial))
s_tone = sanitize_integer(s_tone, -185, 34, initial(s_tone))
r_skin = sanitize_integer(r_skin, 0, 255, initial(r_skin))
g_skin = sanitize_integer(g_skin, 0, 255, initial(g_skin))
b_skin = sanitize_integer(b_skin, 0, 255, initial(b_skin))
h_style = sanitize_inlist(h_style, hair_styles_list, initial(h_style))
f_style = sanitize_inlist(f_style, facial_hair_styles_list, initial(f_style))
r_eyes = sanitize_integer(r_eyes, 0, 255, initial(r_eyes))
g_eyes = sanitize_integer(g_eyes, 0, 255, initial(g_eyes))
b_eyes = sanitize_integer(b_eyes, 0, 255, initial(b_eyes))
underwear = sanitize_integer(underwear, 1, underwear_m.len, initial(underwear))
undershirt = sanitize_integer(undershirt, 1, undershirt_t.len, initial(undershirt))
backbag = sanitize_integer(backbag, 1, backbaglist.len, initial(backbag))
b_type = sanitize_text(b_type, initial(b_type))
@@ -225,12 +234,16 @@
S["facial_green"] << g_facial
S["facial_blue"] << b_facial
S["skin_tone"] << s_tone
S["skin_red"] << r_skin
S["skin_green"] << g_skin
S["skin_blue"] << b_skin
S["hair_style_name"] << h_style
S["facial_style_name"] << f_style
S["eyes_red"] << r_eyes
S["eyes_green"] << g_eyes
S["eyes_blue"] << b_eyes
S["underwear"] << underwear
S["undershirt"] << undershirt
S["backbag"] << backbag
S["b_type"] << b_type
@@ -264,6 +277,9 @@
S["uplinklocation"] << uplinklocation
S["UI_style_color"] << UI_style_color
S["UI_style_alpha"] << UI_style_alpha
return 1
+107 -97
View File
@@ -5,6 +5,10 @@
//BS12: Species-restricted clothing check.
/obj/item/clothing/mob_can_equip(M as mob, slot)
//if we can equip the item anyway, don't bother with species_restricted (aslo cuts down on spam)
if (!..())
return 0
if(species_restricted && istype(M,/mob/living/carbon/human))
var/wearable = null
@@ -26,7 +30,7 @@
M << "\red Your species cannot wear [src]."
return 0
return ..()
return 1
//Ears: headsets, earmuffs and tiny objects
/obj/item/clothing/ears
@@ -134,6 +138,7 @@ BLIND // can't see anything
/obj/item/clothing/gloves/emp_act(severity)
if(cell)
//why is this not part of the powercell code?
cell.charge -= 1000 / severity
if (cell.charge < 0)
cell.charge = 0
@@ -151,6 +156,7 @@ BLIND // can't see anything
icon = 'icons/obj/clothing/hats.dmi'
body_parts_covered = HEAD
slot_flags = SLOT_HEAD
w_class = 2.0
//Mask
@@ -186,6 +192,7 @@ BLIND // can't see anything
slot_flags = SLOT_OCLOTHING
var/blood_overlay_type = "suit"
siemens_coefficient = 0.9
w_class = 3
//Spacesuit
//Note: Everything in modules/clothing/spacesuits should have the entire suit grouped together.
@@ -194,7 +201,7 @@ BLIND // can't see anything
name = "Space helmet"
icon_state = "space"
desc = "A special helmet designed for work in a hazardous, low-pressure environment."
flags = FPRINT | TABLEPASS | HEADCOVERSEYES | BLOCKHAIR | HEADCOVERSMOUTH | STOPSPRESSUREDMAGE
flags = FPRINT | TABLEPASS | HEADCOVERSEYES | BLOCKHAIR | HEADCOVERSMOUTH | STOPSPRESSUREDMAGE | THICKMATERIAL
item_state = "space"
permeability_coefficient = 0.01
armor = list(melee = 0, bullet = 0, laser = 0,energy = 0, bomb = 0, bio = 100, rad = 50)
@@ -212,12 +219,12 @@ BLIND // can't see anything
w_class = 4//bulky item
gas_transfer_coefficient = 0.01
permeability_coefficient = 0.02
flags = FPRINT | TABLEPASS | STOPSPRESSUREDMAGE
flags = FPRINT | TABLEPASS | STOPSPRESSUREDMAGE | THICKMATERIAL
body_parts_covered = UPPER_TORSO|LOWER_TORSO|LEGS|FEET|ARMS|HANDS
allowed = list(/obj/item/device/flashlight,/obj/item/weapon/tank/emergency_oxygen)
slowdown = 3
armor = list(melee = 0, bullet = 0, laser = 0,energy = 0, bomb = 0, bio = 100, rad = 50)
flags_inv = HIDEGLOVES|HIDESHOES|HIDEJUMPSUIT
flags_inv = HIDEGLOVES|HIDESHOES|HIDEJUMPSUIT|HIDETAIL
cold_protection = UPPER_TORSO | LOWER_TORSO | LEGS | FEET | ARMS | HANDS
min_cold_protection_temperature = SPACE_SUIT_MIN_COLD_PROTECTION_TEMPERATURE
siemens_coefficient = 0.9
@@ -232,6 +239,7 @@ BLIND // can't see anything
flags = FPRINT | TABLEPASS
slot_flags = SLOT_ICLOTHING
armor = list(melee = 0, bullet = 0, laser = 0,energy = 0, bomb = 0, bio = 0, rad = 0)
w_class = 3
var/has_sensor = 1//For the crew computer 2 = unable to change mode
var/sensor_mode = 0
/*
@@ -241,19 +249,18 @@ BLIND // can't see anything
*/
var/obj/item/clothing/tie/hastie = null
var/displays_id = 1
var/rolled_down = 0
var/basecolor
/obj/item/clothing/under/attackby(obj/item/I, mob/user)
if(hastie)
hastie.attackby(I, user)
return
if(!hastie && istype(I, /obj/item/clothing/tie))
user.drop_item()
hastie = I
I.loc = src
user << "<span class='notice'>You attach [I] to [src].</span>"
if (istype(hastie,/obj/item/clothing/tie/holster))
verbs += /obj/item/clothing/under/proc/holster
if (istype(hastie,/obj/item/clothing/tie/storage))
verbs += /obj/item/clothing/under/proc/storage
hastie.on_attached(src, user)
if(istype(loc, /mob/living/carbon/human))
var/mob/living/carbon/human/H = loc
@@ -263,6 +270,32 @@ BLIND // can't see anything
..()
/obj/item/clothing/under/attack_hand(mob/user as mob)
//only forward to the attached accessory if the clothing is equipped (not in a storage)
if(hastie && src.loc == user)
hastie.attack_hand(user)
return
..()
//This is to ensure people can take off suits when there is an attached accessory
/obj/item/clothing/under/MouseDrop(obj/over_object as obj)
if (ishuman(usr) || ismonkey(usr))
//makes sure that the clothing is equipped so that we can't drag it into our hand from miles away.
if (!(src.loc == usr))
return
if (!( usr.restrained() ) && !( usr.stat ))
switch(over_object.name)
if("r_hand")
usr.u_equip(src)
usr.put_in_r_hand(src)
if("l_hand")
usr.u_equip(src)
usr.put_in_l_hand(src)
src.add_fingerprint(usr)
return
return
/obj/item/clothing/under/examine()
set src in view()
..()
@@ -278,13 +311,10 @@ BLIND // can't see anything
if(hastie)
usr << "\A [hastie] is clipped to it."
/obj/item/clothing/under/verb/toggle()
set name = "Toggle Suit Sensors"
set category = "Object"
set src in usr
/obj/item/clothing/under/proc/set_sensors(mob/usr as mob)
var/mob/M = usr
if (istype(M, /mob/dead/)) return
if (usr.stat) return
if (usr.stat || usr.restrained()) return
if(has_sensor >= 2)
usr << "The controls are locked."
return 0
@@ -294,19 +324,69 @@ BLIND // can't see anything
var/list/modes = list("Off", "Binary sensors", "Vitals tracker", "Tracking beacon")
var/switchMode = input("Select a sensor mode:", "Suit Sensor Mode", modes[sensor_mode + 1]) in modes
if(get_dist(usr, src) > 1)
usr << "You have moved too far away."
return
sensor_mode = modes.Find(switchMode) - 1
switch(sensor_mode)
if(0)
usr << "You disable your suit's remote sensing equipment."
if(1)
usr << "Your suit will now report whether you are live or dead."
if(2)
usr << "Your suit will now report your vital lifesigns."
if(3)
usr << "Your suit will now report your vital lifesigns as well as your coordinate position."
if (src.loc == usr)
switch(sensor_mode)
if(0)
usr << "You disable your suit's remote sensing equipment."
if(1)
usr << "Your suit will now report whether you are live or dead."
if(2)
usr << "Your suit will now report your vital lifesigns."
if(3)
usr << "Your suit will now report your vital lifesigns as well as your coordinate position."
else if (istype(src.loc, /mob))
switch(sensor_mode)
if(0)
for(var/mob/V in viewers(usr, 1))
V.show_message("\red [usr] disables [src.loc]'s remote sensing equipment.", 1)
if(1)
for(var/mob/V in viewers(usr, 1))
V.show_message("[usr] turns [src.loc]'s remote sensors to binary.", 1)
if(2)
for(var/mob/V in viewers(usr, 1))
V.show_message("[usr] sets [src.loc]'s sensors to track vitals.", 1)
if(3)
for(var/mob/V in viewers(usr, 1))
V.show_message("[usr] sets [src.loc]'s sensors to maximum.", 1)
/obj/item/clothing/under/verb/toggle()
set name = "Toggle Suit Sensors"
set category = "Object"
set src in usr
set_sensors(usr)
..()
/obj/item/clothing/under/verb/rollsuit()
set name = "Roll Down Jumpsuit"
set category = "Object"
set src in usr
if(!istype(usr, /mob/living)) return
if(usr.stat) return
if(copytext(item_color,-2) != "_d")
basecolor = item_color
if(basecolor + "_d_s" in icon_states('icons/mob/uniform.dmi'))
item_color = item_color == "[basecolor]" ? "[basecolor]_d" : "[basecolor]"
usr.update_inv_w_uniform()
else
usr << "<span class='notice'>You cannot roll down the uniform!</span>"
/obj/item/clothing/under/proc/remove_accessory(mob/user as mob)
if(!hastie)
return
hastie.on_removed(user)
hastie = null
if(istype(loc, /mob/living/carbon/human))
var/mob/living/carbon/human/H = loc
H.update_inv_w_uniform()
/obj/item/clothing/under/verb/removetie()
set name = "Remove Accessory"
set category = "Object"
@@ -314,80 +394,10 @@ BLIND // can't see anything
if(!istype(usr, /mob/living)) return
if(usr.stat) return
if(hastie)
if (istype(hastie,/obj/item/clothing/tie/holster))
verbs -= /obj/item/clothing/under/proc/holster
if (istype(hastie,/obj/item/clothing/tie/storage))
verbs -= /obj/item/clothing/under/proc/storage
var/obj/item/clothing/tie/storage/W = hastie
if (W.hold)
W.hold.close(usr)
usr.put_in_hands(hastie)
hastie = null
if(istype(loc, /mob/living/carbon/human))
var/mob/living/carbon/human/H = loc
H.update_inv_w_uniform()
src.remove_accessory(usr)
/obj/item/clothing/under/rank/New()
sensor_mode = pick(0,1,2,3)
..()
/obj/item/clothing/under/proc/holster()
set name = "Holster"
set category = "Object"
set src in usr
if(!istype(usr, /mob/living)) return
if(usr.stat) return
if (!hastie || !istype(hastie,/obj/item/clothing/tie/holster))
usr << "\red You need a holster for that!"
return
var/obj/item/clothing/tie/holster/H = hastie
if(!H.holstered)
if(!istype(usr.get_active_hand(), /obj/item/weapon/gun))
usr << "\blue You need your gun equiped to holster it."
return
var/obj/item/weapon/gun/W = usr.get_active_hand()
if (!W.isHandgun())
usr << "\red This gun won't fit in \the [H]!"
return
H.holstered = usr.get_active_hand()
usr.drop_item()
H.holstered.loc = src
usr.visible_message("\blue \The [usr] holsters \the [H.holstered].", "You holster \the [H.holstered].")
else
if(istype(usr.get_active_hand(),/obj) && istype(usr.get_inactive_hand(),/obj))
usr << "\red You need an empty hand to draw the gun!"
else
if(usr.a_intent == "hurt")
usr.visible_message("\red \The [usr] draws \the [H.holstered], ready to shoot!", \
"\red You draw \the [H.holstered], ready to shoot!")
else
usr.visible_message("\blue \The [usr] draws \the [H.holstered], pointing it at the ground.", \
"\blue You draw \the [H.holstered], pointing it at the ground.")
usr.put_in_hands(H.holstered)
H.holstered = null
/obj/item/clothing/under/proc/storage()
set name = "Look in storage"
set category = "Object"
set src in usr
if(!istype(usr, /mob/living)) return
if(usr.stat) return
if (!hastie || !istype(hastie,/obj/item/clothing/tie/storage))
usr << "\red You need something to store items in for that!"
return
var/obj/item/clothing/tie/storage/W = hastie
if (!istype(W.hold))
return
W.hold.loc = usr
W.hold.attack_hand(usr)
+53 -47
View File
@@ -1,76 +1,82 @@
/obj/item/clothing/gloves/attackby(obj/item/weapon/W, mob/user)
if(istype(src, /obj/item/clothing/gloves/boxing)) //quick fix for stunglove overlay not working nicely with boxing gloves.
if(istype(src, /obj/item/clothing/gloves/boxing)) //quick fix for stunglove overlay not working nicely with boxing gloves.
user << "<span class='notice'>That won't work.</span>" //i'm not putting my lips on that!
..()
return
//add wires
if(istype(W, /obj/item/weapon/cable_coil))
if(!("stunglove" in species_restricted))
var/obj/item/weapon/cable_coil/C = W
if(!wired)
if(C.amount >= 2)
C.use(2)
wired = 1
siemens_coefficient = 3.0
user << "<span class='notice'>You wrap some wires around [src].</span>"
update_icon()
else
user << "<span class='notice'>There is not enough wire to cover [src].</span>"
else
user << "<span class='notice'>[src] are already wired.</span>"
else
user << "<span class='notice'[src] is not suitable for wiring.</span>"
var/obj/item/weapon/cable_coil/C = W
if (clipped)
user << "<span class='notice'>The [src] are too badly mangled for wiring.</span>"
return
if(wired)
user << "<span class='notice'>The [src] are already wired.</span>"
return
if(C.amount < 2)
user << "<span class='notice'>There is not enough wire to cover the [src].</span>"
return
C.use(2)
wired = 1
siemens_coefficient = 3.0
user << "<span class='notice'>You wrap some wires around the [src].</span>"
update_icon()
return
//add cell
else if(istype(W, /obj/item/weapon/cell))
if(!wired)
user << "<span class='notice'>[src] need to be wired first.</span>"
user << "<span class='notice'>The [src] need to be wired first.</span>"
else if(!cell)
user.drop_item()
W.loc = src
cell = W
user << "<span class='notice'>You attach a cell to [src].</span>"
user << "<span class='notice'>You attach the [cell] to the [src].</span>"
update_icon()
else
user << "<span class='notice'>[src] already have a cell.</span>"
user << "<span class='notice'>A [cell] is already attached to the [src].</span>"
return
else if(istype(W, /obj/item/weapon/wirecutters) || istype(W, /obj/item/weapon/scalpel))
wired = null
//stunglove stuff
if(cell)
cell.updateicon()
user << "<span class='notice'>You cut the [cell] away from the [src].</span>"
cell.loc = get_turf(src.loc)
cell = null
if(clipped == 0)
playsound(src.loc, 'sound/items/Wirecutter.ogg', 100, 1)
user.visible_message("\red [user] cut the fingertips off [src].","\red You cut the fingertips off [src].")
clipped = 1
if("exclude" in species_restricted)
name = "mangled [name]"
desc = "[desc] They have had the fingertips cut off of them."
species_restricted -= "Unathi"
species_restricted -= "Tajaran"
species_restricted += "stunglove"
else if(clipped == 1)
user << "<span class='notice'>[src] have already been clipped!</span>"
update_icon()
return
if(cell)
cell.updateicon()
cell.loc = get_turf(src.loc)
cell = null
user << "<span class='notice'>You cut the cell away from [src].</span>"
update_icon()
return
if(wired) //wires disappear into the void because fuck that shit
wired = 0
siemens_coefficient = initial(siemens_coefficient)
user << "<span class='notice'>You cut the wires away from [src].</span>"
user << "<span class='notice'>You cut the wires away from the [src].</span>"
update_icon()
..()
return
return
//clipping fingertips
if(!clipped)
playsound(src.loc, 'sound/items/Wirecutter.ogg', 100, 1)
user.visible_message("\red [user] cuts the fingertips off of the [src].","\red You cut the fingertips off of the [src].")
clipped = 1
name = "mangled [name]"
desc = "[desc]<br>They have had the fingertips cut off of them."
if("exclude" in species_restricted)
species_restricted -= "Unathi"
species_restricted -= "Tajaran"
return
else
user << "<span class='notice'>The [src] have already been clipped!</span>"
update_icon()
return
return
..()
/obj/item/clothing/gloves/update_icon()
..()
+2 -1
View File
@@ -2,7 +2,7 @@
name = "helmet"
desc = "Standard Security gear. Protects the head from impacts."
icon_state = "helmet"
flags = FPRINT | TABLEPASS | HEADCOVERSEYES
flags = FPRINT | TABLEPASS | HEADCOVERSEYES | THICKMATERIAL
item_state = "helmet"
armor = list(melee = 50, bullet = 15, laser = 50,energy = 10, bomb = 25, bio = 0, rad = 0)
flags_inv = HIDEEARS|HIDEEYES
@@ -11,6 +11,7 @@
heat_protection = HEAD
max_heat_protection_temperature = HELMET_MAX_HEAT_PROTECTION_TEMPERATURE
siemens_coefficient = 0.7
w_class = 3
/obj/item/clothing/head/helmet/warden
name = "warden's hat"
@@ -24,6 +24,7 @@
flags_inv = (HIDEMASK|HIDEEARS|HIDEEYES|HIDEFACE)
icon_action_button = "action_welding"
siemens_coefficient = 0.9
w_class = 3
/obj/item/clothing/head/welding/attack_self()
toggle()
@@ -125,6 +126,7 @@
flags_inv = HIDEMASK|HIDEEARS|HIDEEYES|HIDEFACE
var/brightness_on = 2 //luminosity when on
var/on = 0
w_class = 3
attack_self(mob/user)
if(!isturf(user.loc))
+2 -9
View File
@@ -43,18 +43,11 @@
icon_state = "voxmask"
item_state = "voxmask"
permeability_coefficient = 0.01
species_restricted = ("Vox")
toggle()
set category = "Object"
set name = "Adjust mask"
set src in usr
usr << "You can't really adjust this mask - it's moulded to your beak!"
/obj/item/clothing/mask/breath/vox/mob_can_equip(M as mob, slot)
var/mob/living/carbon/human/V = M
if(V.species.name != "Vox")
V << "<span class='warning'>This clearly isn't designed for your species!</span>"
return 0
return ..()
usr << "You can't really adjust this mask - it's moulded to your beak!"
@@ -121,12 +121,14 @@
icon_state = "slippers"
item_state = "slippers"
species_restricted = null
w_class = 2
/obj/item/clothing/shoes/slippers_worn
name = "worn bunny slippers"
desc = "Fluffy..."
icon_state = "slippers_worn"
item_state = "slippers_worn"
w_class = 2
/obj/item/clothing/shoes/laceup
name = "laceup shoes"
+10 -4
View File
@@ -130,12 +130,14 @@
icon_state = "vox-carapace"
item_state = "vox-carapace"
desc = "A glowing visor, perhaps stolen from a depressed Cylon."
species_restricted = list("Vox","Vox Armalis")
/obj/item/clothing/suit/space/vox/carapace
name = "alien carapace armour"
icon_state = "vox-carapace"
item_state = "vox-carapace"
desc = "An armoured, segmented carapace with glowing purple lights. It looks pretty run-down."
species_restricted = list("Vox","Vox Armalis")
/obj/item/clothing/head/helmet/space/vox/stealth
name = "alien stealth helmet"
@@ -187,7 +189,7 @@
siemens_coefficient = 0
permeability_coefficient = 0.05
item_color="gloves-vox"
species_restricted = list("Vox")
species_restricted = list("Vox","Vox Armalis")
/obj/item/clothing/shoes/magboots/vox
@@ -195,7 +197,7 @@
name = "vox magclaws"
item_state = "boots-vox"
icon_state = "boots-vox"
species_restricted = list("Vox")
species_restricted = list("Vox","Vox Armalis")
action_button_name = "Toggle the magclaws"
/obj/item/clothing/shoes/magboots/vox/attack_self(mob/user)
@@ -206,10 +208,14 @@
user << "You relax your deathgrip on the flooring."
else
//make sure these can only be used when equipped.
if (!is_equipped())
if(!ishuman(user))
return
var/mob/living/carbon/human/H = user
if (H.shoes != src)
user << "You will have to put on the [src] before you can do that."
return
flags |= NOSLIP
magpulse = 1
canremove = 0 //kinda hard to take off magclaws when you are gripping them tightly.
+1 -1
View File
@@ -23,7 +23,7 @@
allowed = list(/obj/item/weapon/tank/emergency_oxygen, /obj/item/device/flashlight,/obj/item/weapon/gun/energy, /obj/item/weapon/gun/projectile, /obj/item/ammo_magazine, /obj/item/ammo_casing, /obj/item/weapon/melee/baton,/obj/item/weapon/handcuffs)
slowdown = 1.5
armor = list(melee = 65, bullet = 50, laser = 50, energy = 25, bomb = 50, bio = 100, rad = 50)
flags_inv = HIDEGLOVES|HIDESHOES|HIDEJUMPSUIT
flags_inv = HIDEGLOVES|HIDESHOES|HIDEJUMPSUIT|HIDETAIL
cold_protection = UPPER_TORSO | LOWER_TORSO | LEGS | FEET | ARMS | HANDS
min_cold_protection_temperature = SPACE_SUIT_MIN_COLD_PROTECTION_TEMPERATURE
siemens_coefficient = 0.7
@@ -22,7 +22,7 @@
allowed = list(/obj/item/weapon/tank/emergency_oxygen, /obj/item/device/flashlight,/obj/item/weapon/gun/energy, /obj/item/weapon/gun/projectile, /obj/item/ammo_magazine, /obj/item/ammo_casing, /obj/item/weapon/melee/baton,/obj/item/weapon/handcuffs)
slowdown = 1.5
armor = list(melee = 65, bullet = 50, laser = 50, energy = 25, bomb = 50, bio = 100, rad = 50)
flags_inv = HIDEGLOVES|HIDESHOES|HIDEJUMPSUIT
flags_inv = HIDEGLOVES|HIDESHOES|HIDEJUMPSUIT|HIDETAIL
cold_protection = UPPER_TORSO | LOWER_TORSO | LEGS | FEET | ARMS | HANDS
min_cold_protection_temperature = SPACE_SUIT_MIN_COLD_PROTECTION_TEMPERATURE
siemens_coefficient = 0.7
+10 -8
View File
@@ -75,13 +75,14 @@
icon_state = "rig0-mining"
item_state = "mining_helm"
item_color = "mining"
armor = list(melee = 50, bullet = 5, laser = 20,energy = 5, bomb = 55, bio = 100, rad = 20)
/obj/item/clothing/suit/space/rig/mining
icon_state = "rig-mining"
name = "mining hardsuit"
desc = "A special suit that protects against hazardous, low pressure environments. Has reinforced plating."
item_state = "mining_hardsuit"
armor = list(melee = 50, bullet = 5, laser = 20,energy = 5, bomb = 55, bio = 100, rad = 20)
//Syndicate rig
@@ -94,7 +95,7 @@
armor = list(melee = 60, bullet = 50, laser = 30,energy = 15, bomb = 35, bio = 100, rad = 60)
siemens_coefficient = 0.6
var/obj/machinery/camera/camera
species_restricted = list("exclude","Vox")
species_restricted = list("exclude","Unathi","Tajaran","Skrell","Vox")
/obj/item/clothing/head/helmet/space/rig/syndi/attack_self(mob/user)
if(camera)
..(user)
@@ -120,7 +121,7 @@
armor = list(melee = 60, bullet = 50, laser = 30, energy = 15, bomb = 35, bio = 100, rad = 60)
allowed = list(/obj/item/device/flashlight,/obj/item/weapon/tank,/obj/item/weapon/gun,/obj/item/ammo_magazine,/obj/item/ammo_casing,/obj/item/weapon/melee/baton,/obj/item/weapon/melee/energy/sword,/obj/item/weapon/handcuffs)
siemens_coefficient = 0.6
species_restricted = list("exclude","Vox")
species_restricted = list("exclude","Unathi","Tajaran","Skrell","Vox")
//Wizard Rig
@@ -153,6 +154,7 @@
icon_state = "rig0-medical"
item_state = "medical_helm"
item_color = "medical"
armor = list(melee = 30, bullet = 5, laser = 20,energy = 5, bomb = 25, bio = 100, rad = 50)
/obj/item/clothing/suit/space/rig/medical
icon_state = "rig-medical"
@@ -160,7 +162,7 @@
desc = "A special suit that protects against hazardous, low pressure environments. Has minor radiation shielding."
item_state = "medical_hardsuit"
allowed = list(/obj/item/device/flashlight,/obj/item/weapon/tank,/obj/item/weapon/storage/firstaid,/obj/item/device/healthanalyzer,/obj/item/stack/medical)
armor = list(melee = 30, bullet = 5, laser = 20,energy = 5, bomb = 25, bio = 100, rad = 50)
//Security
/obj/item/clothing/head/helmet/space/rig/security
@@ -184,18 +186,18 @@
//Atmospherics Rig (BS12)
/obj/item/clothing/head/helmet/space/rig/atmos
desc = "A special helmet designed for work in a hazardous, low pressure environments. Has reduced radiation shielding and protective plating to allow for greater mobility."
desc = "A special helmet designed for work in a hazardous, low pressure environments. Has improved thermal protection and minor radiation shielding."
name = "atmospherics hardsuit helmet"
icon_state = "rig0-atmos"
item_state = "atmos_helm"
item_color = "atmos"
armor = list(melee = 40, bullet = 0, laser = 0, energy = 0, bomb = 25, bio = 100, rad = 0)
armor = list(melee = 40, bullet = 5, laser = 20,energy = 5, bomb = 35, bio = 100, rad = 50)
max_heat_protection_temperature = FIRE_HELMET_MAX_HEAT_PROTECTION_TEMPERATURE
/obj/item/clothing/suit/space/rig/atmos
desc = "A special suit that protects against hazardous, low pressure environments. Has reduced radiation shielding to allow for greater mobility."
desc = "A special suit that protects against hazardous, low pressure environments. Has improved thermal protection and minor radiation shielding."
icon_state = "rig-atmos"
name = "atmos hardsuit"
item_state = "atmos_hardsuit"
armor = list(melee = 40, bullet = 0, laser = 0, energy = 0, bomb = 25, bio = 100, rad = 0)
armor = list(melee = 40, bullet = 5, laser = 20,energy = 5, bomb = 35, bio = 100, rad = 50)
max_heat_protection_temperature = FIRESUIT_MAX_HEAT_PROTECTION_TEMPERATURE
+1 -1
View File
@@ -2,7 +2,7 @@
/obj/item/clothing/suit/armor
allowed = list(/obj/item/weapon/gun/energy,/obj/item/weapon/reagent_containers/spray/pepper,/obj/item/weapon/gun/projectile,/obj/item/ammo_magazine,/obj/item/ammo_casing,/obj/item/weapon/melee/baton,/obj/item/weapon/handcuffs)
body_parts_covered = UPPER_TORSO|LOWER_TORSO
flags = FPRINT | TABLEPASS
flags = FPRINT | TABLEPASS | THICKMATERIAL
cold_protection = UPPER_TORSO|LOWER_TORSO
min_cold_protection_temperature = ARMOR_MIN_COLD_PROTECTION_TEMPERATURE
+1 -1
View File
@@ -22,7 +22,7 @@
slowdown = 1.0
allowed = list(/obj/item/weapon/tank/emergency_oxygen,/obj/item/weapon/pen,/obj/item/device/flashlight/pen)
armor = list(melee = 0, bullet = 0, laser = 0,energy = 0, bomb = 0, bio = 100, rad = 20)
flags_inv = HIDEGLOVES|HIDESHOES|HIDEJUMPSUIT
flags_inv = HIDEGLOVES|HIDESHOES|HIDEJUMPSUIT|HIDETAIL
siemens_coefficient = 0.9
+2 -1
View File
@@ -107,7 +107,8 @@
item_state = "hazard"
blood_overlay_type = "armor"
allowed = list (/obj/item/device/analyzer, /obj/item/device/flashlight, /obj/item/device/multitool, /obj/item/device/pipe_painter, /obj/item/device/radio, /obj/item/device/t_scanner, \
/obj/item/weapon/crowbar, /obj/item/weapon/screwdriver, /obj/item/weapon/weldingtool, /obj/item/weapon/wirecutters, /obj/item/weapon/wrench, /obj/item/weapon/tank/emergency_oxygen)
/obj/item/weapon/crowbar, /obj/item/weapon/screwdriver, /obj/item/weapon/weldingtool, /obj/item/weapon/wirecutters, /obj/item/weapon/wrench, /obj/item/weapon/tank/emergency_oxygen, \
/obj/item/clothing/mask/gas, /obj/item/taperoll/engineering)
//Lawyer
/obj/item/clothing/suit/storage/lawyer/bluejacket
+34 -4
View File
@@ -100,6 +100,36 @@
return
usr.update_inv_wear_suit() //so our overlays update
/obj/item/clothing/suit/storage/labcoat/red
name = "red labcoat"
desc = "A suit that protects against minor chemical spills. This one is red."
icon_state = "red_labcoat_open"
item_state = "red_labcoat"
/obj/item/clothing/suit/storage/labcoat/blue
name = "blue labcoat"
desc = "A suit that protects against minor chemical spills. This one is blue."
icon_state = "blue_labcoat_open"
item_state = "blue_labcoat"
/obj/item/clothing/suit/storage/labcoat/purple
name = "purple labcoat"
desc = "A suit that protects against minor chemical spills. This one is purple."
icon_state = "purple_labcoat_open"
item_state = "purple_labcoat"
/obj/item/clothing/suit/storage/labcoat/orange
name = "orange labcoat"
desc = "A suit that protects against minor chemical spills. This one is orange."
icon_state = "orange_labcoat_open"
item_state = "orange_labcoat"
/obj/item/clothing/suit/storage/labcoat/green
name = "green labcoat"
desc = "A suit that protects against minor chemical spills. This one is green."
icon_state = "green_labcoat_open"
item_state = "green_labcoat"
/obj/item/clothing/suit/storage/labcoat/cmo
name = "chief medical officer's labcoat"
desc = "Bluer than the standard model."
@@ -113,22 +143,22 @@
item_state = "labgreen_open"
/obj/item/clothing/suit/storage/labcoat/genetics
name = "Geneticist Labcoat"
name = "Geneticist labcoat"
desc = "A suit that protects against minor chemical spills. Has a blue stripe on the shoulder."
icon_state = "labcoat_gen_open"
/obj/item/clothing/suit/storage/labcoat/chemist
name = "Chemist Labcoat"
name = "Chemist labcoat"
desc = "A suit that protects against minor chemical spills. Has an orange stripe on the shoulder."
icon_state = "labcoat_chem_open"
/obj/item/clothing/suit/storage/labcoat/virologist
name = "Virologist Labcoat"
name = "Virologist labcoat"
desc = "A suit that protects against minor chemical spills. Offers slightly more protection against biohazards than the standard model. Has a green stripe on the shoulder."
icon_state = "labcoat_vir_open"
armor = list(melee = 0, bullet = 0, laser = 0,energy = 0, bomb = 0, bio = 60, rad = 0)
/obj/item/clothing/suit/storage/labcoat/science
name = "Scientist Labcoat"
name = "Scientist labcoat"
desc = "A suit that protects against minor chemical spills. Has a purple stripe on the shoulder."
icon_state = "labcoat_tox_open"
+1 -1
View File
@@ -187,7 +187,7 @@
icon_state = "straight_jacket"
item_state = "straight_jacket"
body_parts_covered = UPPER_TORSO|LOWER_TORSO|LEGS|ARMS|HANDS
flags_inv = HIDEGLOVES|HIDESHOES|HIDEJUMPSUIT
flags_inv = HIDEGLOVES|HIDESHOES|HIDEJUMPSUIT|HIDETAIL
/obj/item/clothing/suit/ianshirt
name = "worn shirt"
+29
View File
@@ -0,0 +1,29 @@
/obj/item/clothing/suit/storage
var/obj/item/weapon/storage/internal/pockets
/obj/item/clothing/suit/storage/New()
..()
pockets = new/obj/item/weapon/storage/internal(src)
pockets.storage_slots = 2 //two slots
pockets.max_w_class = 2 //fit only pocket sized items
pockets.max_combined_w_class = 4
/obj/item/clothing/suit/storage/attack_hand(mob/user as mob)
if (pockets.handle_attack_hand(user))
..(user)
/obj/item/clothing/suit/storage/MouseDrop(obj/over_object as obj)
if (pockets.handle_mousedrop(usr, over_object))
..(over_object)
/obj/item/clothing/suit/storage/attackby(obj/item/W as obj, mob/user as mob)
..()
pockets.attackby(W, user)
/obj/item/clothing/suit/storage/emp_act(severity)
pockets.emp_act(severity)
..()
/obj/item/clothing/suit/storage/hear_talk(mob/M, var/msg)
pockets.hear_talk(M, msg)
..()
+4 -4
View File
@@ -20,7 +20,7 @@
body_parts_covered = UPPER_TORSO|LOWER_TORSO|LEGS|FEET|ARMS|HANDS
allowed = list(/obj/item/device/flashlight,/obj/item/weapon/tank/emergency_oxygen,/obj/item/weapon/extinguisher)
slowdown = 1.0
flags_inv = HIDEGLOVES|HIDESHOES|HIDEJUMPSUIT
flags_inv = HIDEGLOVES|HIDESHOES|HIDEJUMPSUIT|HIDETAIL
flags = FPRINT | TABLEPASS | STOPSPRESSUREDMAGE
heat_protection = UPPER_TORSO|LOWER_TORSO|LEGS|FEET|ARMS|HANDS
max_heat_protection_temperature = FIRESUIT_MAX_HEAT_PROTECTION_TEMPERATURE
@@ -65,7 +65,7 @@
body_parts_covered = UPPER_TORSO|LOWER_TORSO|LEGS|FEET|ARMS|HANDS
slowdown = 2
armor = list(melee = 0, bullet = 0, laser = 0,energy = 0, bomb = 100, bio = 0, rad = 0)
flags_inv = HIDEJUMPSUIT
flags_inv = HIDEJUMPSUIT|HIDETAIL
heat_protection = UPPER_TORSO|LOWER_TORSO
max_heat_protection_temperature = ARMOR_MAX_HEAT_PROTECTION_TEMPERATURE
siemens_coefficient = 0
@@ -101,7 +101,7 @@
gas_transfer_coefficient = 0.90
permeability_coefficient = 0.50
body_parts_covered = UPPER_TORSO|LOWER_TORSO|LEGS|FEET|ARMS|HANDS
allowed = list(/obj/item/device/flashlight,/obj/item/weapon/tank/emergency_oxygen)
allowed = list(/obj/item/device/flashlight,/obj/item/weapon/tank/emergency_oxygen,/obj/item/clothing/head/radiation,/obj/item/clothing/mask/gas)
slowdown = 1.5
armor = list(melee = 0, bullet = 0, laser = 0,energy = 0, bomb = 0, bio = 60, rad = 100)
flags_inv = HIDEJUMPSUIT
flags_inv = HIDEJUMPSUIT|HIDETAIL
+424 -44
View File
@@ -1,3 +1,7 @@
//*****************
//**Cham Jumpsuit**
//*****************
/obj/item/clothing/under/chameleon
//starts off as black
name = "black jumpsuit"
@@ -6,60 +10,35 @@
item_color = "black"
desc = "It's a plain jumpsuit. It seems to have a small dial on the wrist."
origin_tech = "syndicate=3"
siemens_coefficient = 0.8
var/list/clothing_choices = list()
New()
..()
for(var/U in typesof(/obj/item/clothing/under/color)-(/obj/item/clothing/under/color))
var/blocked = list(/obj/item/clothing/under/chameleon, /obj/item/clothing/under/cloud,
/obj/item/clothing/under/golem, /obj/item/clothing/under/gimmick)//Prevent infinite loops and bad jumpsuits.
for(var/U in typesof(/obj/item/clothing/under)-blocked)
var/obj/item/clothing/under/V = new U
src.clothing_choices += V
for(var/U in typesof(/obj/item/clothing/under/rank)-(/obj/item/clothing/under/rank))
var/obj/item/clothing/under/V = new U
src.clothing_choices += V
src.clothing_choices[V.name] = U
return
attackby(obj/item/clothing/under/U as obj, mob/user as mob)
..()
if(istype(U, /obj/item/clothing/under/chameleon))
user << "\red Nothing happens."
return
if(istype(U, /obj/item/clothing/under))
if(src.clothing_choices.Find(U))
user << "\red Pattern is already recognised by the suit."
return
src.clothing_choices += U
user << "\red Pattern absorbed by the suit."
emp_act(severity)
name = "psychedelic"
desc = "Groovy!"
icon_state = "psyche"
item_color = "psyche"
spawn(200)
name = "Black Jumpsuit"
icon_state = "bl_suit"
item_color = "black"
desc = null
..()
update_icon()
usr.update_inv_w_uniform()
verb/change()
set name = "Change Color"
set name = "Change Jumpsuit Appearance"
set category = "Object"
set src in usr
if(icon_state == "psyche")
usr << "\red Your suit is malfunctioning"
return
var/obj/item/clothing/under/A
A = input("Select Colour to change it to", "BOOYEA", A) in clothing_choices
if(!A)
var/picked = input("Select jumpsuit to change it to", "Chameleon Jumpsuit")as null|anything in clothing_choices
if(!picked || !clothing_choices[picked])
return
var/newtype = clothing_choices[picked]
var/obj/item/clothing/A = new newtype
desc = null
permeability_coefficient = 0.90
@@ -69,14 +48,415 @@
icon_state = A.icon_state
item_state = A.item_state
item_color = A.item_color
usr.update_inv_w_uniform() //so our overlays update.
if(usr)
usr.update_inv_w_uniform() //so our overlays update.
//*****************
//**Chameleon Hat**
//*****************
/obj/item/clothing/head/chameleon
name = "grey cap"
icon_state = "greysoft"
item_state = "greysoft"
item_color = "grey"
desc = "It looks like a plain hat, but upon closer inspection, there's an advanced holographic array installed inside. It seems to have a small dial inside."
origin_tech = "syndicate=3"
var/list/clothing_choices = list()
/obj/item/clothing/under/chameleon/all/New()
..()
var/blocked = list(/obj/item/clothing/under/chameleon, /obj/item/clothing/under/chameleon/all)
//to prevent an infinite loop
for(var/U in typesof(/obj/item/clothing/under)-blocked)
var/obj/item/clothing/under/V = new U
src.clothing_choices += V
New()
..()
var/blocked = list(/obj/item/clothing/head/chameleon,
/obj/item/clothing/head/space/golem, /obj/item/clothing/head/justice,)//Prevent infinite loops and bad hats.
for(var/U in typesof(/obj/item/clothing/head)-blocked)
var/obj/item/clothing/head/V = new U
src.clothing_choices[V.name] = U
return
emp_act(severity) //Because we don't have psych for all slots right now but still want a downside to EMP. In this case your cover's blown.
name = "grey cap"
desc = "It's a baseball hat in a tasteful grey colour."
icon_state = "greysoft"
item_color = "grey"
update_icon()
usr.update_inv_head()
verb/change()
set name = "Change Hat/Helmet Appearance"
set category = "Object"
set src in usr
var/picked = input("Select headwear to change it to", "Chameleon Hat")as null|anything in clothing_choices
if(!picked || !clothing_choices[picked])
return
var/newtype = clothing_choices[picked]
var/obj/item/clothing/A = new newtype
desc = null
permeability_coefficient = 0.90
desc = A.desc
name = A.name
icon_state = A.icon_state
item_state = A.item_state
item_color = A.item_color
flags_inv = A.flags_inv
if(usr)
usr.update_inv_head() //so our overlays update.
//******************
//**Chameleon Suit**
//******************
/obj/item/clothing/suit/chameleon
name = "armor"
icon_state = "armor"
item_state = "armor"
desc = "It appears to be a vest of standard armor, except this is embedded with a hidden holographic cloaker, allowing it to change it's appearance, but offering no protection.. It seems to have a small dial inside."
origin_tech = "syndicate=3"
var/list/clothing_choices = list()
New()
..()
var/blocked = list(/obj/item/clothing/suit/chameleon, /obj/item/clothing/suit/space/space_ninja,
/obj/item/clothing/suit/golem, /obj/item/clothing/suit/suit, /obj/item/clothing/suit/cyborg_suit, /obj/item/clothing/suit/justice,
/obj/item/clothing/suit/greatcoat)//Prevent infinite loops and bad suits.
for(var/U in typesof(/obj/item/clothing/suit)-blocked)
var/obj/item/clothing/suit/V = new U
src.clothing_choices[V.name] = U
return
emp_act(severity) //Because we don't have psych for all slots right now but still want a downside to EMP. In this case your cover's blown.
name = "armor"
desc = "An armored vest that protects against some damage."
icon_state = "armor"
item_color = "armor"
update_icon()
usr.update_inv_wear_suit()
verb/change()
set name = "Change Exosuit Appearance"
set category = "Object"
set src in usr
var/picked = input("Select exosuit to change it to", "Chameleon Exosuit")as null|anything in clothing_choices
if(!picked || !clothing_choices[picked])
return
var/newtype = clothing_choices[picked]
var/obj/item/clothing/A = new newtype
desc = null
permeability_coefficient = 0.90
desc = A.desc
name = A.name
icon_state = A.icon_state
item_state = A.item_state
item_color = A.item_color
flags_inv = A.flags_inv
if(usr)
usr.update_inv_wear_suit() //so our overlays update.
//*******************
//**Chameleon Shoes**
//*******************
/obj/item/clothing/shoes/chameleon
name = "black shoes"
icon_state = "black"
item_state = "black"
item_color = "black"
desc = "They're comfy black shoes, with clever cloaking technology built in. It seems to have a small dial on the back of each shoe."
origin_tech = "syndicate=3"
var/list/clothing_choices = list()
New()
..()
var/blocked = list(/obj/item/clothing/shoes/chameleon,
/obj/item/clothing/shoes/golem, /obj/item/clothing/shoes/syndigaloshes, /obj/item/clothing/shoes/cyborg)//prevent infinite loops and bad shoes.
for(var/U in typesof(/obj/item/clothing/shoes)-blocked)
var/obj/item/clothing/shoes/V = new U
src.clothing_choices[V.name] = U
return
emp_act(severity) //Because we don't have psych for all slots right now but still want a downside to EMP. In this case your cover's blown.
name = "black shoes"
desc = "A pair of black shoes."
icon_state = "black"
item_state = "black"
item_color = "black"
update_icon()
usr.update_inv_shoes()
verb/change()
set name = "Change Footwear Appearance"
set category = "Object"
set src in usr
var/picked = input("Select shoes to change it to", "Chameleon Shoes")as null|anything in clothing_choices
if(!picked || !clothing_choices[picked])
return
var/newtype = clothing_choices[picked]
var/obj/item/clothing/A = new newtype
desc = null
permeability_coefficient = 0.90
desc = A.desc
name = A.name
icon_state = A.icon_state
item_state = A.item_state
item_color = A.item_color
if(usr)
usr.update_inv_shoes() //so our overlays update.
//**********************
//**Chameleon Backpack**
//**********************
/obj/item/weapon/storage/backpack/chameleon
name = "backpack"
icon_state = "backpack"
item_state = "backpack"
desc = "A backpack outfitted with cloaking tech. It seems to have a small dial inside, kept away from the storage."
origin_tech = "syndicate=3"
var/list/clothing_choices = list()
New()
..()
var/blocked = list(/obj/item/weapon/storage/backpack/chameleon, /obj/item/weapon/storage/backpack/satchel/withwallet)
for(var/U in typesof(/obj/item/weapon/storage/backpack)-blocked)//Prevent infinite loops and bad backpacks.
var/obj/item/weapon/storage/backpack/V = new U
src.clothing_choices[V.name] = U
return
emp_act(severity) //Because we don't have psych for all slots right now but still want a downside to EMP. In this case your cover's blown.
name = "backpack"
desc = "You wear this on your back and put items into it."
icon_state = "backpack"
item_state = "backpack"
update_icon()
usr.update_inv_back()
verb/change()
set name = "Change Backpack Appearance"
set category = "Object"
set src in usr
var/picked = input("Select backpack to change it to", "Chameleon Backpack")as null|anything in clothing_choices
if(!picked || !clothing_choices[picked])
return
var/newtype = clothing_choices[picked]
var/obj/item/weapon/storage/backpack/A = new newtype
desc = null
permeability_coefficient = 0.90
desc = A.desc
name = A.name
icon_state = A.icon_state
item_state = A.item_state
item_color = A.item_color
if(usr)
usr.update_inv_back() //so our overlays update.
//********************
//**Chameleon Gloves**
//********************
/obj/item/clothing/gloves/chameleon
name = "black gloves"
icon_state = "black"
item_state = "bgloves"
item_color = "brown"
desc = "It looks like a pair of gloves, but it seems to have a small dial inside."
origin_tech = "syndicate=3"
var/list/clothing_choices = list()
New()
..()
var/blocked = list(/obj/item/clothing/gloves/chameleon)//Prevent infinite loops and bad hats.
for(var/U in typesof(/obj/item/clothing/gloves)-blocked)
var/obj/item/clothing/gloves/V = new U
src.clothing_choices[V.name] = U
return
emp_act(severity) //Because we don't have psych for all slots right now but still want a downside to EMP. In this case your cover's blown.
name = "black gloves"
desc = "It looks like a pair of gloves, but it seems to have a small dial inside."
icon_state = "black"
item_color = "brown"
update_icon()
usr.update_inv_gloves()
verb/change()
set name = "Change Gloves Appearance"
set category = "Object"
set src in usr
var/picked = input("Select gloves to change it to", "Chameleon Gloves")as null|anything in clothing_choices
if(!picked || !clothing_choices[picked])
return
var/newtype = clothing_choices[picked]
var/obj/item/clothing/A = new newtype
desc = null
permeability_coefficient = 0.90
desc = A.desc
name = A.name
icon_state = A.icon_state
item_state = A.item_state
item_color = A.item_color
flags_inv = A.flags_inv
if(usr)
usr.update_inv_gloves() //so our overlays update.
//******************
//**Chameleon Mask**
//******************
/obj/item/clothing/mask/chameleon
name = "gas mask"
icon_state = "gas_alt"
item_state = "gas_alt"
desc = "It looks like a plain gask mask, but on closer inspection, it seems to have a small dial inside."
origin_tech = "syndicate=3"
var/list/clothing_choices = list()
New()
..()
var/blocked = list(/obj/item/clothing/mask/chameleon)//Prevent infinite loops and bad hats.
for(var/U in typesof(/obj/item/clothing/mask)-blocked)
var/obj/item/clothing/mask/V = new U
if(V)
src.clothing_choices[V.name] = U
return
emp_act(severity) //Because we don't have psych for all slots right now but still want a downside to EMP. In this case your cover's blown.
name = "gas mask"
desc = "It's a gas mask."
icon_state = "gas_alt"
update_icon()
usr.update_inv_wear_mask()
verb/change()
set name = "Change Mask Appearance"
set category = "Object"
set src in usr
var/picked = input("Select mask to change it to", "Chameleon Mask")as null|anything in clothing_choices
if(!picked || !clothing_choices[picked])
return
var/newtype = clothing_choices[picked]
var/obj/item/clothing/A = new newtype
desc = null
permeability_coefficient = 0.90
desc = A.desc
name = A.name
icon_state = A.icon_state
item_state = A.item_state
flags_inv = A.flags_inv
if(usr)
usr.update_inv_wear_mask() //so our overlays update.
//*********************
//**Chameleon Glasses**
//*********************
/obj/item/clothing/glasses/chameleon
name = "Optical Meson Scanner"
icon_state = "meson"
item_state = "glasses"
desc = "It looks like a plain set of mesons, but on closer inspection, it seems to have a small dial inside."
origin_tech = "syndicate=3"
var/list/clothing_choices = list()
New()
..()
var/blocked = list(/obj/item/clothing/glasses/chameleon)//Prevent infinite loops and bad hats.
for(var/U in typesof(/obj/item/clothing/glasses)-blocked)
var/obj/item/clothing/glasses/V = new U
src.clothing_choices[V.name] = U
return
emp_act(severity) //Because we don't have psych for all slots right now but still want a downside to EMP. In this case your cover's blown.
name = "Optical Meson Scanner"
desc = "It's a set of mesons."
icon_state = "meson"
update_icon()
usr.update_inv_glasses()
verb/change()
set name = "Change Glasses Appearance"
set category = "Object"
set src in usr
var/picked = input("Select glasses to change it to", "Chameleon Glasses")as null|anything in clothing_choices
if(!picked || !clothing_choices[picked])
return
var/newtype = clothing_choices[picked]
var/obj/item/clothing/A = new newtype
desc = null
permeability_coefficient = 0.90
desc = A.desc
name = A.name
icon_state = A.icon_state
item_state = A.item_state
flags_inv = A.flags_inv
if(usr)
usr.update_inv_glasses() //so our overlays update.
//*****************
//**Chameleon Gun**
//*****************
/obj/item/weapon/gun/projectile/chameleon
name = "desert eagle"
desc = "A fake Desert Eagle with a dial on the side to change the gun's disguise."
icon_state = "deagle"
w_class = 3.0
max_shells = 7
caliber = ".45"
origin_tech = "combat=2;materials=2;syndicate=8"
ammo_type = "/obj/item/ammo_casing/chameleon"
var/list/gun_choices = list()
New()
..()
var/blocked = list(/obj/item/weapon/gun/projectile/chameleon)
for(var/U in typesof(/obj/item/weapon/gun/)-blocked)
var/obj/item/weapon/gun/V = new U
src.gun_choices[V.name] = U
return
emp_act(severity)
name = "desert eagle"
desc = "It's a desert eagle."
icon_state = "deagle"
update_icon()
usr.update_inv_r_hand()
usr.update_inv_l_hand()
verb/change()
set name = "Change Gun Appearance"
set category = "Object"
set src in usr
var/picked = input("Select gun to change it to", "Chameleon Gun")as null|anything in gun_choices
if(!picked || !gun_choices[picked])
return
var/newtype = gun_choices[picked]
var/obj/item/weapon/gun/A = new newtype
desc = null
permeability_coefficient = 0.90
desc = A.desc
name = A.name
icon_state = A.icon_state
item_state = A.item_state
flags_inv = A.flags_inv
if(usr)
usr.update_inv_r_hand()
usr.update_inv_l_hand() //so our overlays update.
@@ -34,7 +34,7 @@
//Down below follows a partial attempt at getting the rolldown verb for jumpsuits.
//Issue: Sprites vanishing again... Hueh - Skull132
/*
/obj/item/clothing/under/rank/verb/rolldown()
set name = "Roll Down Jumpsuit"
set category = "Object"
@@ -67,4 +67,5 @@
else
usr << "You attempt to roll down your [src], before promptly realising how stupid it would be for you to expose your chest."
return
usr.update_inv_w_uniform()
usr.update_inv_w_uniform() */
+2 -2
View File
@@ -31,9 +31,9 @@
/obj/item/clothing/under/rank/scientist
desc = "It's made of a special fiber that provides minor protection against biohazards. It has markings that denote the wearer as a scientist."
name = "scientist's jumpsuit"
icon_state = "toxins"
icon_state = "science"
item_state = "w_suit"
item_color = "toxinswhite"
item_color = "sciencewhite"
permeability_coefficient = 0.50
armor = list(melee = 0, bullet = 0, laser = 0,energy = 0, bomb = 10, bio = 0, rad = 0)
flags = FPRINT | TABLEPASS
+2 -2
View File
@@ -330,8 +330,8 @@
item_color = "plaid_purple"
/obj/item/clothing/under/dress/plaid_green
name = "blue purple skirt"
desc = "A preppy greed skirt with a white blouse."
name = "green skirt"
desc = "A preppy green skirt with a white blouse."
icon_state = "plaid_green"
item_color = "plaid_green"
+175 -38
View File
@@ -8,6 +8,42 @@
flags = FPRINT | TABLEPASS
slot_flags = 0
w_class = 2.0
var/obj/item/clothing/under/has_suit = null //the suit the tie may be attached to
var/image/inv_overlay = null //overlay used when attached to clothing.
/obj/item/clothing/tie/New()
..()
inv_overlay = image("icon" = 'icons/obj/clothing/ties_overlay.dmi', "icon_state" = "[item_color? "[item_color]" : "[icon_state]"]")
//when user attached an accessory to S
/obj/item/clothing/tie/proc/on_attached(obj/item/clothing/under/S, mob/user as mob)
if(!istype(S))
return
has_suit = S
loc = has_suit
has_suit.overlays += inv_overlay
user << "<span class='notice'>You attach [src] to [has_suit].</span>"
src.add_fingerprint(user)
/obj/item/clothing/tie/proc/on_removed(mob/user as mob)
if(!has_suit)
return
has_suit.overlays -= inv_overlay
has_suit = null
usr.put_in_hands(src)
src.add_fingerprint(user)
//default attackby behaviour
/obj/item/clothing/tie/attackby(obj/item/I, mob/user)
..()
//default attack_hand behaviour
/obj/item/clothing/tie/attack_hand(mob/user as mob)
if(has_suit)
has_suit.remove_accessory(user)
return //we aren't an object on the ground so don't call parent
..()
/obj/item/clothing/tie/blue
name = "blue tie"
@@ -116,7 +152,7 @@
//Armbands
/obj/item/clothing/tie/armband
name = "red armband"
desc = "An fancy red armband!"
desc = "A fancy red armband!"
icon_state = "red"
item_color = "red"
@@ -156,6 +192,7 @@
icon_state = "medgreen"
item_color = "medgreen"
//holsters
/obj/item/clothing/tie/holster
name = "shoulder holster"
desc = "A handgun holster."
@@ -163,6 +200,105 @@
item_color = "holster"
var/obj/item/weapon/gun/holstered = null
//subtypes can override this to specify what can be holstered
/obj/item/clothing/tie/holster/proc/can_holster(obj/item/weapon/gun/W)
return W.isHandgun()
/obj/item/clothing/tie/holster/proc/holster(obj/item/I, mob/user as mob)
if(holstered)
user << "\red There is already a [holstered] holstered here!"
if (!istype(I, /obj/item/weapon/gun))
user << "\red Only guns can be holstered!"
var/obj/item/weapon/gun/W = I
if (!can_holster(W))
user << "\red This [W] won't fit in the [src]!"
return
holstered = W
user.drop_from_inventory(holstered)
holstered.loc = src
holstered.add_fingerprint(user)
user.visible_message("\blue [user] holsters the [holstered].", "You holster the [holstered].")
/obj/item/clothing/tie/holster/proc/unholster(mob/user as mob)
if(!holstered)
return
if(istype(user.get_active_hand(),/obj) && istype(user.get_inactive_hand(),/obj))
user << "\red You need an empty hand to draw the [holstered]!"
else
if(user.a_intent == "hurt")
usr.visible_message("\red [user] draws the [holstered], ready to shoot!", \
"\red You draw the [holstered], ready to shoot!")
else
user.visible_message("\blue [user] draws the [holstered], pointing it at the ground.", \
"\blue You draw the [holstered], pointing it at the ground.")
user.put_in_hands(holstered)
holstered.add_fingerprint(user)
holstered = null
/obj/item/clothing/tie/holster/attack_hand(mob/user as mob)
if (has_suit) //if we are part of a suit
if (holstered)
unholster(user)
return
..(user)
/obj/item/clothing/tie/holster/attackby(obj/item/W as obj, mob/user as mob)
holster(W, user)
/obj/item/clothing/tie/holster/emp_act(severity)
if (holstered)
holstered.emp_act(severity)
..()
/obj/item/clothing/tie/holster/examine()
set src in view()
..()
if (holstered)
usr << "A [holstered] is holstered here."
else
usr << "It is empty."
/obj/item/clothing/tie/holster/on_attached(obj/item/clothing/under/S, mob/user as mob)
..()
has_suit.verbs += /obj/item/clothing/tie/holster/verb/holster_verb
/obj/item/clothing/tie/holster/on_removed(mob/user as mob)
has_suit.verbs -= /obj/item/clothing/tie/holster/verb/holster_verb
..()
//For the holster hotkey
/obj/item/clothing/tie/holster/verb/holster_verb()
set name = "Holster"
set category = "Object"
set src in usr
if(!istype(usr, /mob/living)) return
if(usr.stat) return
var/obj/item/clothing/tie/holster/H = null
if (istype(src, /obj/item/clothing/tie/holster))
H = src
else if (istype(src, /obj/item/clothing/under))
var/obj/item/clothing/under/S = src
if (S.hastie)
H = S.hastie
if (!H)
usr << "/red Something is very wrong."
if(!H.holstered)
if(!istype(usr.get_active_hand(), /obj/item/weapon/gun))
usr << "\blue You need your gun equiped to holster it."
return
var/obj/item/weapon/gun/W = usr.get_active_hand()
H.holster(W, usr)
else
H.unholster(usr)
/obj/item/clothing/tie/holster/armpit
name = "shoulder holster"
desc = "A worn-out handgun holster. Perfect for concealed carry"
@@ -177,17 +313,43 @@
/obj/item/clothing/tie/storage
name = "load bearing equipment"
desc = "Used to hold things when you don't have enough hands for that."
desc = "Used to hold things when you don't have enough hands."
icon_state = "webbing"
item_color = "webbing"
var/slots = 3
var/obj/item/weapon/storage/pockets/hold
var/obj/item/weapon/storage/internal/hold
/obj/item/clothing/tie/storage/New()
hold = new /obj/item/weapon/storage/pockets(src)
hold.master_item = src
..()
hold = new/obj/item/weapon/storage/internal(src)
hold.storage_slots = slots
/obj/item/clothing/tie/storage/attack_hand(mob/user as mob)
if (has_suit) //if we are part of a suit
hold.open(user)
return
if (hold.handle_attack_hand(user)) //otherwise interact as a regular storage item
..(user)
/obj/item/clothing/tie/storage/MouseDrop(obj/over_object as obj)
if (has_suit)
return
if (hold.handle_mousedrop(usr, over_object))
..(over_object)
/obj/item/clothing/tie/storage/attackby(obj/item/W as obj, mob/user as mob)
hold.attackby(W, user)
/obj/item/clothing/tie/storage/emp_act(severity)
hold.emp_act(severity)
..()
/obj/item/clothing/tie/storage/hear_talk(mob/M, var/msg)
hold.hear_talk(M, msg)
..()
/obj/item/clothing/tie/storage/attack_self(mob/user as mob)
user << "<span class='notice'>You empty [src].</span>"
var/turf/T = get_turf(src)
@@ -196,18 +358,6 @@
hold.remove_from_storage(I, T)
src.add_fingerprint(user)
/obj/item/clothing/tie/storage/attackby(obj/item/weapon/W as obj, mob/user as mob)
hold.attackby(W,user)
src.add_fingerprint(user)
/obj/item/weapon/storage/pockets
name = "storage"
var/master_item //item it belongs to
/obj/item/weapon/storage/pockets/close(mob/user as mob)
..()
loc = master_item
/obj/item/clothing/tie/storage/webbing
name = "webbing"
desc = "Strudy mess of synthcotton belts and buckles, ready to share your burden."
@@ -321,27 +471,14 @@
item_color = "unathiharness2"
slots = 2
/obj/item/clothing/tie/storage/knifeharness/attackby(var/obj/item/O as obj, mob/user as mob)
..()
update()
/obj/item/clothing/tie/storage/knifeharness/proc/update()
var/count = 0
for(var/obj/item/I in hold)
if(istype(I,/obj/item/weapon/hatchet/unathiknife))
count++
if(count>2) count = 2
item_state = "unathiharness[count]"
icon_state = item_state
item_color = item_state
if(istype(loc, /obj/item/clothing))
var/obj/item/clothing/U = loc
if(istype(U.loc, /mob/living/carbon/human))
var/mob/living/carbon/human/H = U.loc
H.update_inv_w_uniform()
/obj/item/clothing/tie/storage/knifeharness/New()
..()
hold.max_combined_w_class = 4
hold.can_hold = list("/obj/item/weapon/hatchet/unathiknife",\
"/obj/item/weapon/kitchen/utensil/knife",\
"/obj/item/weapon/kitchen/utensil/pknife",\
"/obj/item/weapon/kitchenknife",\
"/obj/item/weapon/kitchenknife/ritual")
new /obj/item/weapon/hatchet/unathiknife(hold)
new /obj/item/weapon/hatchet/unathiknife(hold)
new /obj/item/weapon/hatchet/unathiknife(hold)
+306 -304
View File
@@ -126,331 +126,333 @@ obj/machinery/computer/forensic_scanning
Topic(href,href_list)
switch(href_list["operation"])
if("login")
var/mob/M = usr
if(istype(M,/mob/living/silicon))
authenticated = 1
updateDialog()
return
if (allowed(M))
authenticated = 1
if("logout")
authenticated = 0
if("clear")
if(canclear)
temp = null
if("eject")
if(scanning)
scanning.loc = loc
scanning = null
else
temp = "Eject Failed: No Object"
if("insert")
var/mob/M = usr
var/obj/item/I = M.get_active_hand()
if(I && istype(I))
if(istype(I, /obj/item/weapon/evidencebag))
scanning = I.contents[1]
scanning.loc = src
I.overlays -= scanning
I.icon_state = "evidenceobj"
if ((usr.contents.Find(src) || (in_range(src, usr) && istype(src.loc, /turf))) || (istype(usr, /mob/living/silicon)))
usr.set_machine(src)
switch(href_list["operation"])
if("login")
var/mob/M = usr
if(istype(M,/mob/living/silicon))
authenticated = 1
updateDialog()
return
if (allowed(M))
authenticated = 1
if("logout")
authenticated = 0
if("clear")
if(canclear)
temp = null
if("eject")
if(scanning)
scanning.loc = loc
scanning = null
else
scanning = I
temp = "Eject Failed: No Object"
if("insert")
var/mob/M = usr
var/obj/item/I = M.get_active_hand()
if(I && istype(I))
if(istype(I, /obj/item/weapon/evidencebag))
scanning = I.contents[1]
scanning.loc = src
I.overlays -= scanning
I.icon_state = "evidenceobj"
else
scanning = I
M.drop_item()
I.loc = src
else
usr << "Invalid Object Rejected."
if("card") //Processing a fingerprint card.
var/mob/M = usr
var/obj/item/I = M.get_active_hand()
if(!(I && istype(I,/obj/item/weapon/f_card)))
I = card
if(I && istype(I,/obj/item/weapon/f_card))
card = I
if(!card.fingerprints)
card.fingerprints = list()
if(card.amount > 1 || !card.fingerprints.len)
usr << "\red ERROR: No prints/too many cards."
if(card.loc == src)
card.loc = src.loc
card = null
return
M.drop_item()
I.loc = src
else
usr << "Invalid Object Rejected."
if("card") //Processing a fingerprint card.
var/mob/M = usr
var/obj/item/I = M.get_active_hand()
if(!(I && istype(I,/obj/item/weapon/f_card)))
I = card
if(I && istype(I,/obj/item/weapon/f_card))
card = I
if(!card.fingerprints)
card.fingerprints = list()
if(card.amount > 1 || !card.fingerprints.len)
usr << "\red ERROR: No prints/too many cards."
if(card.loc == src)
card.loc = src.loc
card = null
return
M.drop_item()
I.loc = src
process_card()
else
usr << "\red Invalid Object Rejected."
if("database") //Viewing all records in each database
canclear = 1
if(href_list["delete_record"])
delete_dossier(href_list["delete_record"])
if(href_list["delete_aux"])
delete_record(href_list["delete_aux"])
if((!misc || !misc.len) && (!files || !files.len))
temp = "Database is empty."
else
if(files && files.len)
temp = "<b>Criminal Evidence Database</b><br><br>"
temp += "Consolidated data points:<br>"
for(var/print in files)
var/list/file = files[print]
temp += "<a href='?src=\ref[src];operation=record;identifier=[print]'>{[file[2]]}</a><br>"
temp += "<br><a href='?src=\ref[src];operation=card'>{Insert Finger Print Card (To complete a Dossier)}</a><br><br><br>"
process_card()
else
temp = ""
if(misc && misc.len)
temp += {"<b>Auxiliary Evidence Database</b><br><br>
This is where anything without fingerprints goes.<br><br>"}
for(var/atom in misc)
var/list/data_entry = misc[atom]
temp += "<a href='?src=\ref[src];operation=auxiliary;identifier=[atom]'>{[data_entry[3]]}</a><br>"
if("record") //Viewing a record from the "files" database.
canclear = 0
if(files)
var/list/dossier = files[href_list["identifier"]]
if(href_list["ren"])
var/new_title = copytext(sanitize(input("Rename to what?", "Dossier Editing", "Dossier [files.Find(href_list["identifier"])]") as null|text),1,MAX_MESSAGE_LEN)
if(new_title)
dossier[2] = new_title
usr << "\red Invalid Object Rejected."
if("database") //Viewing all records in each database
canclear = 1
if(href_list["delete_record"])
delete_dossier(href_list["delete_record"])
if(href_list["delete_aux"])
delete_record(href_list["delete_aux"])
if((!misc || !misc.len) && (!files || !files.len))
temp = "Database is empty."
else
if(files && files.len)
temp = "<b>Criminal Evidence Database</b><br><br>"
temp += "Consolidated data points:<br>"
for(var/print in files)
var/list/file = files[print]
temp += "<a href='?src=\ref[src];operation=record;identifier=[print]'>{[file[2]]}</a><br>"
temp += "<br><a href='?src=\ref[src];operation=card'>{Insert Finger Print Card (To complete a Dossier)}</a><br><br><br>"
else
usr << "Illegal or blank name."
temp = {"<b>Criminal Evidence Database</b><br><br>
Consolidated data points: [dossier[2]]<br>"}
var/print_string = "Fingerprints: Print not complete!<br>"
if(stringpercent(dossier[1]) <= FINGERPRINT_COMPLETE)
print_string = "Fingerprints: (80% or higher completion reached)<br>[dossier[1]]<br>"
temp += print_string
for(var/object in dossier)
if(object == dossier[1] || object == dossier[2])
continue
temp += "<hr>"
var/list/outputs = dossier[object]
var/list/prints = outputs[1]
temp += "<big><b>Object:</b> [outputs[4]]</big><br>"
temp += "&nbsp<b>Fingerprints:</b><br>"
temp += "&nbsp;&nbsp;&nbsp;&nbsp;[prints.len] Unique fingerprints found.<br>"
var/complete_prints = 0
for(var/print in prints)
if(stringpercent(prints[print]) <= FINGERPRINT_COMPLETE)
complete_prints++
temp += "&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;[prints[print]]<br>"
if(complete_prints)
temp += "&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;And [prints.len - complete_prints] unknown unique prints.<br>"
else
temp += "&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;No prints of sufficient completeness.<br>"
var/list/fibers = outputs[2]
temp = ""
if(misc && misc.len)
temp += {"<b>Auxiliary Evidence Database</b><br><br>
This is where anything without fingerprints goes.<br><br>"}
for(var/atom in misc)
var/list/data_entry = misc[atom]
temp += "<a href='?src=\ref[src];operation=auxiliary;identifier=[atom]'>{[data_entry[3]]}</a><br>"
if("record") //Viewing a record from the "files" database.
canclear = 0
if(files)
var/list/dossier = files[href_list["identifier"]]
if(href_list["ren"])
var/new_title = copytext(sanitize(input("Rename to what?", "Dossier Editing", "Dossier [files.Find(href_list["identifier"])]") as null|text),1,MAX_MESSAGE_LEN)
if(new_title)
dossier[2] = new_title
else
usr << "Illegal or blank name."
temp = {"<b>Criminal Evidence Database</b><br><br>
Consolidated data points: [dossier[2]]<br>"}
var/print_string = "Fingerprints: Print not complete!<br>"
if(stringpercent(dossier[1]) <= FINGERPRINT_COMPLETE)
print_string = "Fingerprints: (80% or higher completion reached)<br>[dossier[1]]<br>"
temp += print_string
for(var/object in dossier)
if(object == dossier[1] || object == dossier[2])
continue
temp += "<hr>"
var/list/outputs = dossier[object]
var/list/prints = outputs[1]
temp += "<big><b>Object:</b> [outputs[4]]</big><br>"
temp += "&nbsp<b>Fingerprints:</b><br>"
temp += "&nbsp;&nbsp;&nbsp;&nbsp;[prints.len] Unique fingerprints found.<br>"
var/complete_prints = 0
for(var/print in prints)
if(stringpercent(prints[print]) <= FINGERPRINT_COMPLETE)
complete_prints++
temp += "&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;[prints[print]]<br>"
if(complete_prints)
temp += "&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;And [prints.len - complete_prints] unknown unique prints.<br>"
else
temp += "&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;No prints of sufficient completeness.<br>"
var/list/fibers = outputs[2]
if(fibers && fibers.len)
temp += "&nbsp<b>Fibers:</b><br>"
for(var/j = 1, j <= fibers.len, j++)
temp += "&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;[fibers[j]]<br>"
var/list/blood = outputs[3]
if(blood && blood.len)
temp += "&nbsp<b>Blood:</b><br>"
for(var/named in blood)
temp += "&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;Type: [blood[named]], DNA: [named]<br>"
temp += "<br><a href='?src=\ref[src];operation=record;identifier=[href_list["identifier"]];ren=true'>{Rename this Dossier}</a>"
temp += "<br><a href='?src=\ref[src];operation=database;delete_record=[href_list["identifier"]]'>{Delete this Dossier}</a>"
temp += "<br><a href='?src=\ref[src];operation=databaseprint;identifier=[href_list["identifier"]]'>{Print}</a>"
else
temp = "ERROR. Database not found!<br>"
temp += "<br><a href='?src=\ref[src];operation=database'>{Return}</a>"
if("databaseprint") //Printing from the "files" database.
if(files)
var/obj/item/weapon/paper/P = new(loc)
var/list/dossier = files[href_list["identifier"]]
P.name = "\improper Database File ([dossier[2]])"
P.overlays += "paper_words"
P.info = "<b>Criminal Evidence Database</b><br><br>"
P.info += "Consolidated data points: [dossier[2]]<br>"
var/print_string = "Fingerprints: Print not complete!<br>"
if(stringpercent(dossier[1]) <= FINGERPRINT_COMPLETE)
print_string = "Fingerprints: (80% or higher completion reached)<br>[dossier[1]]<br>"
P.info += print_string
for(var/object in dossier)
if(object == dossier[1] || object == dossier[2])
continue
P.info += "<hr>"
var/list/outputs = dossier[object]
var/list/prints = outputs[1]
P.info += "<big><b>Object:</b> [outputs[4]]</big><br>"
P.info += "&nbsp<b>Fingerprints:</b><br>"
P.info += "&nbsp;&nbsp;&nbsp;&nbsp;[prints.len] Unique fingerprints found.<br>"
var/complete_prints = 0
for(var/print in prints)
if(stringpercent(prints[print]) <= FINGERPRINT_COMPLETE)
complete_prints++
P.info += "&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;[prints[print]]<br>"
if(complete_prints)
P.info += "&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;And [prints.len - complete_prints] unknown unique prints.<br>"
else
P.info += "&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;No prints of sufficient completeness.<br>"
var/list/fibers = outputs[2]
if(fibers && fibers.len)
P.info += "&nbsp<b>Fibers:</b><br>"
for(var/j = 1, j <= fibers.len, j++)
P.info += "&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;[fibers[j]]<br>"
var/list/blood = outputs[3]
if(blood && blood.len)
P.info += "&nbsp<b>Blood:</b><br>"
for(var/named in blood)
P.info += "&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;Type: [blood[named]], DNA: [named]<br>"
else
usr << "ERROR. Database not found!<br>"
if("auxiliary") //Viewing a record from the "misc" database.
canclear = 0
if(misc)
temp = "<b>Auxiliary Evidence Database</b><br><br>"
var/list/outputs = misc[href_list["identifier"]]
temp += "<big><b>Consolidated data points:</b> [outputs[3]]</big><br>"
var/list/prints = outputs[4]
if(prints)
temp += "&nbsp<b>Fingerprints:</b><br>"
temp += "&nbsp;&nbsp;&nbsp;&nbsp;[prints.len] Unique fingerprints found.<br>"
var/complete_prints = 0
for(var/print in prints)
if(stringpercent(prints[print]) <= FINGERPRINT_COMPLETE)
complete_prints++
temp += "&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;[prints[print]]<br>"
if(complete_prints)
temp += "&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;And [prints.len - complete_prints] unknown unique prints.<br>"
else
temp += "&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;No prints of sufficient completeness.<br>"
var/list/fibers = outputs[1]
if(fibers && fibers.len)
temp += "&nbsp<b>Fibers:</b><br>"
for(var/j = 1, j <= fibers.len, j++)
temp += "&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;[fibers[j]]<br>"
var/list/blood = outputs[3]
for(var/fiber in fibers)
temp += "&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;[fiber]<br>"
var/list/blood = outputs[2]
if(blood && blood.len)
temp += "&nbsp<b>Blood:</b><br>"
for(var/named in blood)
temp += "&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;Type: [blood[named]], DNA: [named]<br>"
temp += "<br><a href='?src=\ref[src];operation=record;identifier=[href_list["identifier"]];ren=true'>{Rename this Dossier}</a>"
temp += "<br><a href='?src=\ref[src];operation=database;delete_record=[href_list["identifier"]]'>{Delete this Dossier}</a>"
temp += "<br><a href='?src=\ref[src];operation=databaseprint;identifier=[href_list["identifier"]]'>{Print}</a>"
else
temp = "ERROR. Database not found!<br>"
temp += "<br><a href='?src=\ref[src];operation=database'>{Return}</a>"
if("databaseprint") //Printing from the "files" database.
if(files)
var/obj/item/weapon/paper/P = new(loc)
var/list/dossier = files[href_list["identifier"]]
P.name = "\improper Database File ([dossier[2]])"
P.overlays += "paper_words"
P.info = "<b>Criminal Evidence Database</b><br><br>"
P.info += "Consolidated data points: [dossier[2]]<br>"
var/print_string = "Fingerprints: Print not complete!<br>"
if(stringpercent(dossier[1]) <= FINGERPRINT_COMPLETE)
print_string = "Fingerprints: (80% or higher completion reached)<br>[dossier[1]]<br>"
P.info += print_string
for(var/object in dossier)
if(object == dossier[1] || object == dossier[2])
continue
P.info += "<hr>"
var/list/outputs = dossier[object]
var/list/prints = outputs[1]
P.info += "<big><b>Object:</b> [outputs[4]]</big><br>"
P.info += "&nbsp<b>Fingerprints:</b><br>"
P.info += "&nbsp;&nbsp;&nbsp;&nbsp;[prints.len] Unique fingerprints found.<br>"
var/complete_prints = 0
for(var/print in prints)
if(stringpercent(prints[print]) <= FINGERPRINT_COMPLETE)
complete_prints++
P.info += "&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;[prints[print]]<br>"
if(complete_prints)
P.info += "&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;And [prints.len - complete_prints] unknown unique prints.<br>"
else
P.info += "&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;No prints of sufficient completeness.<br>"
var/list/fibers = outputs[2]
temp += "<br><a href='?src=\ref[src];operation=database;delete_aux=[href_list["identifier"]]'>{Delete This Record}</a>"
temp += "<br><a href='?src=\ref[src];operation=auxiliaryprint;identifier=[href_list["identifier"]]'>{Print}</a>"
else
temp = "ERROR. Database not found!<br>"
temp += "<br><a href='?src=\ref[src];operation=database'>{Return}</a>"
if("auxiliaryprint") //Printing from the "misc" database.
if(misc)
var/obj/item/weapon/paper/P = new(loc)
var/list/outputs = misc[href_list["identifier"]]
P.name = "\improper Auxiliary Database File ([outputs[3]])"
P.overlays += "paper_words"
P.info = "<b>Auxiliary Evidence Database</b><br><br>"
P.info += "<big><b>Consolidated data points:</b> [outputs[3]]</big><br>"
var/list/prints = outputs[4]
if(prints)
P.info += "&nbsp<b>Fingerprints:</b><br>"
P.info += "&nbsp;&nbsp;&nbsp;&nbsp;[prints.len] Unique fingerprints found.<br>"
var/complete_prints = 0
for(var/print in prints)
if(stringpercent(prints[print]) <= FINGERPRINT_COMPLETE)
complete_prints++
P.info += "&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;[prints[print]]<br>"
if(complete_prints)
P.info += "&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;And [prints.len - complete_prints] unknown unique prints.<br>"
else
P.info += "&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;No prints of sufficient completeness.<br>"
var/list/fibers = outputs[1]
if(fibers && fibers.len)
P.info += "&nbsp<b>Fibers:</b><br>"
for(var/j = 1, j <= fibers.len, j++)
P.info += "&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;[fibers[j]]<br>"
var/list/blood = outputs[3]
for(var/fiber in fibers)
P.info += "&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;[fiber]<br>"
var/list/blood = outputs[2]
if(blood && blood.len)
P.info += "&nbsp<b>Blood:</b><br>"
for(var/named in blood)
P.info += "&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;Type: [blood[named]], DNA: [named]<br>"
else
usr << "ERROR. Database not found!<br>"
if("auxiliary") //Viewing a record from the "misc" database.
canclear = 0
if(misc)
temp = "<b>Auxiliary Evidence Database</b><br><br>"
var/list/outputs = misc[href_list["identifier"]]
temp += "<big><b>Consolidated data points:</b> [outputs[3]]</big><br>"
var/list/prints = outputs[4]
if(prints)
temp += "&nbsp<b>Fingerprints:</b><br>"
temp += "&nbsp;&nbsp;&nbsp;&nbsp;[prints.len] Unique fingerprints found.<br>"
var/complete_prints = 0
for(var/print in prints)
if(stringpercent(prints[print]) <= FINGERPRINT_COMPLETE)
complete_prints++
temp += "&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;[prints[print]]<br>"
if(complete_prints)
temp += "&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;And [prints.len - complete_prints] unknown unique prints.<br>"
else
temp += "&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;No prints of sufficient completeness.<br>"
var/list/fibers = outputs[1]
if(fibers && fibers.len)
temp += "&nbsp<b>Fibers:</b><br>"
for(var/fiber in fibers)
temp += "&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;[fiber]<br>"
var/list/blood = outputs[2]
if(blood && blood.len)
temp += "&nbsp<b>Blood:</b><br>"
for(var/named in blood)
temp += "&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;Type: [blood[named]], DNA: [named]<br>"
temp += "<br><a href='?src=\ref[src];operation=database;delete_aux=[href_list["identifier"]]'>{Delete This Record}</a>"
temp += "<br><a href='?src=\ref[src];operation=auxiliaryprint;identifier=[href_list["identifier"]]'>{Print}</a>"
else
temp = "ERROR. Database not found!<br>"
temp += "<br><a href='?src=\ref[src];operation=database'>{Return}</a>"
if("auxiliaryprint") //Printing from the "misc" database.
if(misc)
var/obj/item/weapon/paper/P = new(loc)
var/list/outputs = misc[href_list["identifier"]]
P.name = "\improper Auxiliary Database File ([outputs[3]])"
P.overlays += "paper_words"
P.info = "<b>Auxiliary Evidence Database</b><br><br>"
P.info += "<big><b>Consolidated data points:</b> [outputs[3]]</big><br>"
var/list/prints = outputs[4]
if(prints)
P.info += "&nbsp<b>Fingerprints:</b><br>"
P.info += "&nbsp;&nbsp;&nbsp;&nbsp;[prints.len] Unique fingerprints found.<br>"
var/complete_prints = 0
for(var/print in prints)
if(stringpercent(prints[print]) <= FINGERPRINT_COMPLETE)
complete_prints++
P.info += "&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;[prints[print]]<br>"
if(complete_prints)
P.info += "&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;And [prints.len - complete_prints] unknown unique prints.<br>"
else
P.info += "&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;No prints of sufficient completeness.<br>"
var/list/fibers = outputs[1]
if(fibers && fibers.len)
P.info += "&nbsp<b>Fibers:</b><br>"
for(var/fiber in fibers)
P.info += "&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;[fiber]<br>"
var/list/blood = outputs[2]
if(blood && blood.len)
P.info += "&nbsp<b>Blood:</b><br>"
for(var/named in blood)
P.info += "&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;Type: [blood[named]], DNA: [named]<br>"
else
usr << "ERROR. Database not found!<br>"
if("scan")
if(istype(scanning,/obj/item/weapon/f_card))
card = scanning
scanning = initial(scanning)
process_card()
else if(scanning)
scan_process = 3
scan_data = "Scanning [scanning]: 25% complete"
updateDialog()
sleep(50)
if(!scan_process)
scan_data = null
else
usr << "ERROR. Database not found!<br>"
if("scan")
if(istype(scanning,/obj/item/weapon/f_card))
card = scanning
scanning = initial(scanning)
process_card()
else if(scanning)
scan_process = 3
scan_data = "Scanning [scanning]: 25% complete"
updateDialog()
return
scan_data = "Scanning [scanning]: 50% complete"
updateDialog()
scan_process = 2
sleep(50)
if(!scan_process)
scan_data = null
sleep(50)
if(!scan_process)
scan_data = null
updateDialog()
return
scan_data = "Scanning [scanning]: 50% complete"
updateDialog()
return
scan_data = "Scanning [scanning]: 75% complete"
updateDialog()
scan_process = 1
sleep(50)
if(!scan_process)
scan_data = null
scan_process = 2
sleep(50)
if(!scan_process)
scan_data = null
updateDialog()
return
scan_data = "Scanning [scanning]: 75% complete"
updateDialog()
return
scan_process = 1
sleep(50)
if(!scan_process)
scan_data = null
updateDialog()
return
if(scanning)
scan_process = 0
scan_name = scanning.name
scan_data = "<u>[scanning]</u><br><br>"
if (scanning.blood_DNA)
scan_data += "Blood Found:<br>"
for(var/blood in scanning.blood_DNA)
scan_data += "Blood type: [scanning.blood_DNA[blood]]\nDNA: [blood]<br><br>"
else
scan_data += "No Blood Found<br><br>"
if(!scanning.fingerprints)
scan_data += "No Fingerprints Found<br><br>"
else
scan_data += "Isolated [scanning.fingerprints.len] Fingerprints. Loaded into database.<br>"
add_data(scanning)
if(!scanning.suit_fibers)
scan_data += "No Fibers/Materials Located<br>"
else
scan_data += "Fibers/Materials Found:<br>"
for(var/data in scanning.suit_fibers)
scan_data += "- [data]<br>"
if(istype(scanning,/obj/item/device/detective_scanner) || (istype(scanning, /obj/item/device/pda) && scanning:cartridge && scanning:cartridge.access_security))
scan_data += "<br><b>Data transfered from \the [scanning] to Database.</b><br>"
add_data_scanner(scanning)
else if(!scanning.fingerprints)
scan_data += "<br><b><a href='?src=\ref[src];operation=add'>Add to Database?</a></b><br>"
else
temp = "Scan Failed: No Object"
if("print") //Printing scan data
if(scan_data)
temp = "Scan Data Printed."
var/obj/item/weapon/paper/P = new(loc)
P.name = "\improper Scan Data ([scan_name])"
P.info = "<tt>[scan_data]</tt>"
P.overlays += "paper_words"
else
temp = "Print Failed: No Data"
if("erase")
scan_data = ""
if("cancel")
scan_process = 0
if("add") //Adding an object (Manually) to the database.
if(scanning)
scan_process = 0
scan_name = scanning.name
scan_data = "<u>[scanning]</u><br><br>"
if (scanning.blood_DNA)
scan_data += "Blood Found:<br>"
for(var/blood in scanning.blood_DNA)
scan_data += "Blood type: [scanning.blood_DNA[blood]]\nDNA: [blood]<br><br>"
else
scan_data += "No Blood Found<br><br>"
if(!scanning.fingerprints)
scan_data += "No Fingerprints Found<br><br>"
else
scan_data += "Isolated [scanning.fingerprints.len] Fingerprints. Loaded into database.<br>"
add_data(scanning)
if(!scanning.suit_fibers)
scan_data += "No Fibers/Materials Located<br>"
else
scan_data += "Fibers/Materials Found:<br>"
for(var/data in scanning.suit_fibers)
scan_data += "- [data]<br>"
if(istype(scanning,/obj/item/device/detective_scanner) || (istype(scanning, /obj/item/device/pda) && scanning:cartridge && scanning:cartridge.access_security))
scan_data += "<br><b>Data transfered from \the [scanning] to Database.</b><br>"
add_data_scanner(scanning)
else if(!scanning.fingerprints)
scan_data += "<br><b><a href='?src=\ref[src];operation=add'>Add to Database?</a></b><br>"
else
temp = "Scan Failed: No Object"
if("print") //Printing scan data
if(scan_data)
temp = "Scan Data Printed."
var/obj/item/weapon/paper/P = new(loc)
P.name = "\improper Scan Data ([scan_name])"
P.info = "<tt>[scan_data]</tt>"
P.overlays += "paper_words"
else
temp = "Print Failed: No Data"
if("erase")
scan_data = ""
if("cancel")
scan_process = 0
if("add") //Adding an object (Manually) to the database.
if(scanning)
add_data(scanning)
else
temp = "Data Transfer Failed: No Object."
if("rename")
if(!files || !files[href_list["identifier"]])
temp = "ERROR: Record/Database not found!"
else
var/new_title = copytext(sanitize(input("Rename to what?", "Dossier Editing", "Dossier [files.Find(href_list["identifier"])]") as null|text),1,MAX_MESSAGE_LEN)
if(new_title)
var/list/file = files[href_list["identifier"]]
file[2] = new_title
add_data(scanning)
else
temp = "Data Transfer Failed: No Object."
if("rename")
if(!files || !files[href_list["identifier"]])
temp = "ERROR: Record/Database not found!"
else
var/new_title = copytext(sanitize(input("Rename to what?", "Dossier Editing", "Dossier [files.Find(href_list["identifier"])]") as null|text),1,MAX_MESSAGE_LEN)
if(new_title)
var/list/file = files[href_list["identifier"]]
file[2] = new_title
updateUsrDialog()
ex_act()
+1 -1
View File
@@ -6,7 +6,7 @@
icon = 'icons/obj/storage.dmi'
icon_state = "evidenceobj"
item_state = ""
w_class = 1
w_class = 2
/obj/item/weapon/evidencebag/afterattack(obj/item/I, mob/user as mob, proximity)
if(!proximity) return
+54 -2
View File
@@ -173,6 +173,7 @@ log transactions
dat += "<td>[T.source_terminal]</td>"
dat += "</tr>"
dat += "</table>"
dat += "<A href='?src=\ref[src];choice=print_transaction'>Print</a><br>"
if(TRANSFER_FUNDS)
dat += "<b>Account balance:</b> $[authenticated_account.money]<br>"
dat += "<A href='?src=\ref[src];choice=view_screen;view_screen=0'>Back</a><br><br>"
@@ -190,7 +191,7 @@ log transactions
dat += "<form name='withdrawal' action='?src=\ref[src]' method='get'>"
dat += "<input type='hidden' name='src' value='\ref[src]'>"
dat += "<input type='hidden' name='choice' value='withdrawal'>"
dat += "<input type='text' name='funds_amount' value='' style='width:200px; background-color:white;'><input type='submit' value='Withdraw funds'><br>"
dat += "<input type='text' name='funds_amount' value='' style='width:200px; background-color:white;'><input type='submit' value='Withdraw charge card'>"
dat += "</form>"
dat += "<A href='?src=\ref[src];choice=view_screen;view_screen=1'>Change account security level</a><br>"
dat += "<A href='?src=\ref[src];choice=view_screen;view_screen=2'>Make transfer</a><br>"
@@ -309,7 +310,9 @@ log transactions
//remove the money
authenticated_account.money -= amount
spawn_money(amount,src.loc)
// spawn_money(amount,src.loc)
spawn_ewallet(amount,src.loc)
//create an entry in the account transaction log
var/datum/transaction/T = new()
@@ -346,6 +349,49 @@ log transactions
playsound(loc, 'sound/items/polaroid1.ogg', 50, 1)
else
playsound(loc, 'sound/items/polaroid2.ogg', 50, 1)
if ("print_transaction")
if(authenticated_account)
var/obj/item/weapon/paper/R = new(src.loc)
R.name = "Transaction logs: [authenticated_account.owner_name]"
R.info = "<b>Transaction logs</b><br>"
R.info += "<i>Account holder:</i> [authenticated_account.owner_name]<br>"
R.info += "<i>Account number:</i> [authenticated_account.account_number]<br>"
R.info += "<i>Date and time:</i> [worldtime2text()], [current_date_string]<br><br>"
R.info += "<i>Service terminal ID:</i> [machine_id]<br>"
R.info += "<table border=1 style='width:100%'>"
R.info += "<tr>"
R.info += "<td><b>Date</b></td>"
R.info += "<td><b>Time</b></td>"
R.info += "<td><b>Target</b></td>"
R.info += "<td><b>Purpose</b></td>"
R.info += "<td><b>Value</b></td>"
R.info += "<td><b>Source terminal ID</b></td>"
R.info += "</tr>"
for(var/datum/transaction/T in authenticated_account.transaction_log)
R.info += "<tr>"
R.info += "<td>[T.date]</td>"
R.info += "<td>[T.time]</td>"
R.info += "<td>[T.target_name]</td>"
R.info += "<td>[T.purpose]</td>"
R.info += "<td>$[T.amount]</td>"
R.info += "<td>[T.source_terminal]</td>"
R.info += "</tr>"
R.info += "</table>"
//stamp the paper
var/image/stampoverlay = image('icons/obj/bureaucracy.dmi')
stampoverlay.icon_state = "paper_stamp-cent"
if(!R.stamped)
R.stamped = new
R.stamped += /obj/item/weapon/stamp
R.overlays += stampoverlay
R.stamps += "<HR><i>This paper has been stamped by the Automatic Teller Machine.</i>"
if(prob(50))
playsound(loc, 'sound/items/polaroid1.ogg', 50, 1)
else
playsound(loc, 'sound/items/polaroid2.ogg', 50, 1)
if("insert_card")
if(!held_card)
//this might happen if the user had the browser window open when somebody emagged it
@@ -402,3 +448,9 @@ log transactions
if(ishuman(human_user) && !human_user.get_active_hand())
human_user.put_in_hands(held_card)
held_card = null
/obj/machinery/atm/proc/spawn_ewallet(var/sum, loc)
var/obj/item/weapon/spacecash/ewallet/E = new /obj/item/weapon/spacecash/ewallet(loc)
E.worth = sum
E.owner_name = authenticated_account.owner_name
+49 -3
View File
@@ -22,6 +22,7 @@
//create a short manual as well
var/obj/item/weapon/paper/R = new(src.loc)
R.name = "Steps to success: Correct EFTPOS Usage"
/*
R.info += "<b>When first setting up your EFTPOS device:</b>"
R.info += "1. Memorise your EFTPOS command code (provided with all EFTPOS devices).<br>"
R.info += "2. Confirm that your EFTPOS device is connected to your local accounts database. For additional assistance with this step, contact NanoTrasen IT Support<br>"
@@ -33,6 +34,17 @@
R.info += "4. If at this stage you wish to modify or cancel your transaction, you may simply reset (unlock) your EFTPOS device.<br>"
R.info += "5. Give your EFTPOS device to the customer, they must authenticate the transaction by swiping their ID card and entering their PIN number.<br>"
R.info += "6. If done correctly, the transaction will be logged to both accounts with the reference you have entered, the terminal ID of your EFTPOS device and the money transferred across accounts.<br>"
*/
//Temptative new manual:
R.info += "<b>First EFTPOS setup:</b><br>"
R.info += "1. Memorise your EFTPOS command code (provided with all EFTPOS devices).<br>"
R.info += "2. Connect the EFTPOS to the account in which you want to receive the funds.<br><br>"
R.info += "<b>When starting a new transaction:</b><br>"
R.info += "1. Enter the amount of money you want to charge and a purpose message for the new transaction.<br>"
R.info += "2. Lock the new transaction. If you want to modify or cancel the transaction, you simply have to reset your EFTPOS device.<br>"
R.info += "3. Give the EFTPOS device to your customer, he/she must finish the transaction by swiping their ID card or a charge card with enough funds.<br>"
R.info += "4. If everything is done correctly, the money will be transferred. To unlock the device you will have to reset the EFTPOS device.<br>"
//stamp the paper
var/image/stampoverlay = image('icons/obj/bureaucracy.dmi')
@@ -72,7 +84,7 @@
var/dat = "<b>[eftpos_name]</b><br>"
dat += "<i>This terminal is</i> [machine_id]. <i>Report this code when contacting NanoTrasen IT Support</i><br>"
if(transaction_locked)
dat += "<a href='?src=\ref[src];choice=toggle_lock'>Reset[transaction_paid ? "" : " (authentication required)"]</a><br><br>"
dat += "<a href='?src=\ref[src];choice=toggle_lock'>Back[transaction_paid ? "" : " (authentication required)"]</a><br><br>"
dat += "Transaction purpose: <b>[transaction_purpose]</b><br>"
dat += "Value: <b>$[transaction_amount]</b><br>"
@@ -102,6 +114,36 @@
scan_card(I)
else
usr << "\icon[src]<span class='warning'>Unable to connect to linked account.</span>"
else if (istype(O, /obj/item/weapon/spacecash/ewallet))
var/obj/item/weapon/spacecash/ewallet/E = O
if (linked_account)
if(!linked_account.suspended)
if(transaction_locked && !transaction_paid)
if(transaction_amount <= E.worth)
playsound(src, 'sound/machines/chime.ogg', 50, 1)
src.visible_message("\icon[src] The [src] chimes.")
transaction_paid = 1
//transfer the money
E.worth -= transaction_amount
linked_account.money += transaction_amount
//create entry in the EFTPOS linked account transaction log
var/datum/transaction/T = new()
T.target_name = E.owner_name //D.owner_name
T.purpose = transaction_purpose
T.amount = transaction_amount
T.source_terminal = machine_id
T.date = current_date_string
T.time = worldtime2text()
linked_account.transaction_log.Add(T)
else
usr << "\icon[src]<span class='warning'>The charge card doesn't have that much money!</span>"
else
usr << "\icon[src]<span class='warning'>Connected account has been suspended.</span>"
else
usr << "\icon[src]<span class='warning'>EFTPOS is not connected to an account.</span>"
else
..()
@@ -143,10 +185,14 @@
transaction_amount = try_num
if("toggle_lock")
if(transaction_locked)
var/attempt_code = input("Enter EFTPOS access code", "Reset Transaction") as num
if(attempt_code == access_code)
if (transaction_paid)
transaction_locked = 0
transaction_paid = 0
else
var/attempt_code = input("Enter EFTPOS access code", "Reset Transaction") as num
if(attempt_code == access_code)
transaction_locked = 0
transaction_paid = 0
else if(linked_account)
transaction_locked = 1
else
+13 -1
View File
@@ -71,4 +71,16 @@ proc/spawn_money(var/sum, spawnloc)
while(sum >= i)
sum -= i
new cash_type(spawnloc)
return
return
/obj/item/weapon/spacecash/ewallet
name = "Charge card"
icon_state = "efundcard"
desc = "A card that holds an amount of money."
var/owner_name = "" //So the ATM can set it so the EFTPOS can put a valid name on transactions.
/obj/item/weapon/spacecash/ewallet/examine()
set src in view()
..()
if (!(usr in view(2)) && usr!=src.loc) return
usr << "\blue Charge card's owner: [src.owner_name]. Credits remaining: [src.worth]."
+6 -6
View File
@@ -7,7 +7,7 @@
#define LOC_VAULT 6
#define LOC_CONSTR 7
#define LOC_TECH 8
#define LOC_ASSEMBLY 9
#define LOC_ARMOURY 9
#define VERM_MICE 0
#define VERM_LIZARDS 1
@@ -54,9 +54,9 @@
if(LOC_TECH)
spawn_area_type = /area/storage/tech
locstring = "technical storage"
if(LOC_ASSEMBLY)
spawn_area_type = /area/assembly/assembly_line
locstring = "the unused assembly line"
if(LOC_ARMOURY)
spawn_area_type = /area/security/armoury
locstring = "the armoury"
//world << "looking for [spawn_area_type]"
for(var/areapath in typesof(spawn_area_type))
@@ -83,6 +83,7 @@
vermstring = "lizards"
if(VERM_SPIDERS)
spawn_types = list(/obj/effect/spider/spiderling)
max_number = 3
vermstring = "spiders"
spawn(0)
@@ -92,7 +93,6 @@
turfs.Remove(T)
num--
if(vermin == VERM_SPIDERS)
var/obj/effect/spider/spiderling/S = new(T)
S.amount_grown = -1
@@ -112,7 +112,7 @@
#undef LOC_HYDRO
#undef LOC_VAULT
#undef LOC_TECH
#undef LOC_ASSEMBLY
#undef LOC_ARMOURY
#undef VERM_MICE
#undef VERM_LIZARDS
+5 -2
View File
@@ -7,9 +7,11 @@
else
nudge_lib = "lib/nudge.so"
call(nudge_lib, "nudge")("[config.comms_password]","[config.irc_bot_host]","[channel]","[msg]")
spawn(0)
call(nudge_lib, "nudge")("[config.comms_password]","[config.irc_bot_host]","[channel]","[msg]")
else
ext_python("ircbot_message.py", "[config.comms_password] [config.irc_bot_host] [channel] [msg]")
spawn(0)
ext_python("ircbot_message.py", "[config.comms_password] [config.irc_bot_host] [channel] [msg]")
return
/proc/send2mainirc(var/msg)
@@ -26,3 +28,4 @@
/hook/startup/proc/ircNotify()
send2mainirc("Server starting up on [config.server? "byond://[config.server]" : "byond://[world.address]:[world.port]"]")
return 1
+6
View File
@@ -1215,6 +1215,12 @@ I said no!
)
result = /obj/item/weapon/reagent_containers/food/snacks/tofurkey
// Fuck Science!
/datum/recipe/ruinedvirusdish
items = list(
/obj/item/weapon/virusdish
)
result = /obj/item/weapon/ruinedvirusdish
//////////////////////////////////////////
// bs12 food port stuff
+7 -1
View File
@@ -237,6 +237,12 @@
else
..()
/obj/item/weapon/book/attack(mob/living/carbon/M as mob, mob/living/carbon/user as mob)
if(user.zone_sel.selecting == "eyes")
user.visible_message("<span class='notice'>You open up the book and show it to [M]. </span>", \
"<span class='notice'> [user] opens up a book and shows it to [M]. </span>")
M << browse("<TT><I>Penned by [author].</I></TT> <BR>" + "[dat]", "window=book")
/*
* Barcode Scanner
@@ -247,7 +253,7 @@
icon_state ="scanner"
throw_speed = 1
throw_range = 5
w_class = 1.0
w_class = 2.0
flags = FPRINT | TABLEPASS
var/obj/machinery/librarycomp/computer // Associated computer - Modes 1 to 3 use this
var/obj/item/weapon/book/book // Currently scanned book
+2 -22
View File
@@ -161,28 +161,8 @@ proc/move_mining_shuttle()
src.req_access = list()
hacked = 1
usr << "You fried the consoles ID checking system. It's now available to everyone!"
else if(istype(W, /obj/item/weapon/screwdriver))
playsound(src.loc, 'sound/items/Screwdriver.ogg', 50, 1)
if(do_after(user, 20))
var/obj/structure/computerframe/A = new /obj/structure/computerframe( src.loc )
var/obj/item/weapon/circuitboard/mining_shuttle/M = new /obj/item/weapon/circuitboard/mining_shuttle( A )
for (var/obj/C in src)
C.loc = src.loc
A.circuit = M
A.anchored = 1
if (src.stat & BROKEN)
user << "\blue The broken glass falls out."
new /obj/item/weapon/shard( src.loc )
A.state = 3
A.icon_state = "3"
else
user << "\blue You disconnect the monitor."
A.state = 4
A.icon_state = "4"
del(src)
else
..()
/******************************Lantern*******************************/
+2 -2
View File
@@ -13,7 +13,7 @@ var/list/artifact_spawn = list() // Runtime fix for geometry loading before cont
opacity = 1
density = 1
blocks_air = 1
temperature = TCMB
temperature = T0C
var/mineral/mineral
var/mined_ore = 0
var/last_act = 0
@@ -389,7 +389,7 @@ var/list/artifact_spawn = list() // Runtime fix for geometry loading before cont
icon_state = "asteroid"
oxygen = 0.01
nitrogen = 0.01
temperature = TCMB
temperature = T0C
icon_plating = "asteroid"
var/dug = 0 //0 = has not yet been dug, 1 = has already been dug
+6 -6
View File
@@ -30,37 +30,37 @@ mineral
mineral/uranium
name = "Uranium"
result_amount = 1
result_amount = 5
spread_chance = 10
ore = /obj/item/weapon/ore/uranium
mineral/iron
name = "Iron"
result_amount = 1
result_amount = 5
spread_chance = 25
ore = /obj/item/weapon/ore/iron
mineral/diamond
name = "Diamond"
result_amount = 1
result_amount = 5
spread_chance = 10
ore = /obj/item/weapon/ore/diamond
mineral/gold
name = "Gold"
result_amount = 1
result_amount = 5
spread_chance = 10
ore = /obj/item/weapon/ore/gold
mineral/silver
name = "Silver"
result_amount = 1
result_amount = 5
spread_chance = 10
ore = /obj/item/weapon/ore/silver
mineral/plasma
name = "Plasma"
result_amount = 1
result_amount = 5
spread_chance = 25
ore = /obj/item/weapon/ore/plasma
+2 -1
View File
@@ -10,7 +10,8 @@
/obj/structure/ore_box/attackby(obj/item/weapon/W as obj, mob/user as mob)
if (istype(W, /obj/item/weapon/ore))
src.contents += W;
user.u_equip(W)
src.contents += W
if (istype(W, /obj/item/weapon/storage))
var/obj/item/weapon/storage/S = W
S.hide_from(usr)
@@ -69,6 +69,15 @@
..()
/mob/dead/observer/Topic(href, href_list)
if (href_list["track"])
var/mob/target = locate(href_list["track"]) in mob_list
if(target)
ManualFollow(target)
/mob/dead/attackby(obj/item/W, mob/user)
if(istype(W,/obj/item/weapon/tome))
var/mob/dead/M = src
+6
View File
@@ -48,6 +48,12 @@
/mob/proc/death(gibbed)
//Quick fix for corpses kept propped up in chairs. ~Z
drop_r_hand()
drop_l_hand()
//End of fix.
timeofdeath = world.time
living_mob_list -= src
+18
View File
@@ -39,12 +39,30 @@
// Type 1 (Visual) emotes are sent to anyone in view of the item
if (m_type & 1)
for (var/mob/O in viewers(src, null))
if(O.status_flags & PASSEMOTES)
for(var/obj/item/weapon/holder/H in O.contents)
H.show_message(message, m_type)
for(var/mob/living/M in O.contents)
M.show_message(message, m_type)
O.show_message(message, m_type)
// Type 2 (Audible) emotes are sent to anyone in hear range
// of the *LOCATION* -- this is important for pAIs to be heard
else if (m_type & 2)
for (var/mob/O in hearers(get_turf(src), null))
if(O.status_flags & PASSEMOTES)
for(var/obj/item/weapon/holder/H in O.contents)
H.show_message(message, m_type)
for(var/mob/living/M in O.contents)
M.show_message(message, m_type)
O.show_message(message, m_type)
/mob/proc/emote_dead(var/message)
+162
View File
@@ -0,0 +1,162 @@
// At minimum every mob has a hear_say proc.
/mob/proc/hear_say(var/message, var/verb = "says", var/datum/language/language = null, var/alt_name = "",var/italics = 0, var/mob/speaker = null)
if(!client)
return
if(sleeping || stat == 1)
hear_sleep(message)
return
var/style = "body"
if(!say_understands(speaker,language))
if(istype(speaker,/mob/living/simple_animal))
var/mob/living/simple_animal/S = speaker
message = pick(S.speak)
else
message = stars(message)
if(language)
verb = language.speech_verb
style = language.colour
var/speaker_name = speaker.name
if(istype(speaker, /mob/living/carbon/human))
var/mob/living/carbon/human/H = speaker
speaker_name = H.GetVoice()
if(italics)
message = "<i>[message]</i>"
var/track = null
if(istype(src, /mob/dead/observer))
if(italics && client.prefs.toggles & CHAT_GHOSTRADIO)
return
if(speaker_name != speaker.real_name && speaker.real_name)
speaker_name = "[speaker.real_name] ([speaker_name])"
track = "(<a href='byond://?src=\ref[src];track=\ref[speaker]'>follow</a>) "
if(client.prefs.toggles & CHAT_GHOSTEARS && speaker in view(src))
message = "<b>[message]</b>"
if(sdisabilities & DEAF || ear_deaf)
if(speaker == src)
src << "<span class='warning'>You cannot hear yourself speak!</span>"
else
src << "<span class='name'>[speaker_name]</span>[alt_name] talks but you cannot hear them."
else
src << "<span class='game say'><span class='name'>[speaker_name]</span>[alt_name] [track][verb], <span class='message'><span class='[style]'>\"[message]\"</span></span></span>"
/mob/proc/hear_radio(var/message, var/verb="says", var/datum/language/language=null, var/part_a, var/part_b, var/mob/speaker = null, var/hard_to_hear = 0, var/vname ="")
if(!client)
return
if(sleeping || stat==1) //If unconscious or sleeping
hear_sleep(message)
return
var/track = null
var/style = "body"
if(!say_understands(speaker,language))
if(istype(speaker,/mob/living/simple_animal))
var/mob/living/simple_animal/S = speaker
message = pick(S.speak)
else
message = stars(message)
if(language)
verb = language.speech_verb
style = language.colour
if(hard_to_hear)
message = stars(message)
var/speaker_name = speaker.name
if(vname)
speaker_name = vname
if(istype(speaker, /mob/living/carbon/human))
var/mob/living/carbon/human/H = speaker
if(H.voice)
speaker_name = H.voice
if(hard_to_hear)
speaker_name = "unknown"
var/changed_voice
if(istype(src, /mob/living/silicon/ai) && !hard_to_hear)
var/jobname // the mob's "job"
var/mob/living/carbon/human/impersonating //The crewmember being impersonated, if any.
if (ishuman(speaker))
var/mob/living/carbon/human/H = speaker
if((H.wear_id && istype(H.wear_id,/obj/item/weapon/card/id/syndicate)) && (H.wear_mask && istype(H.wear_mask,/obj/item/clothing/mask/gas/voice)))
changed_voice = 1
var/mob/living/carbon/human/I = locate(speaker_name)
if(I)
impersonating = I
jobname = impersonating.get_assignment()
else
jobname = "Unknown"
else
jobname = H.get_assignment()
else if (iscarbon(speaker)) // Nonhuman carbon mob
jobname = "No id"
else if (isAI(speaker))
jobname = "AI"
else if (isrobot(speaker))
jobname = "Cyborg"
else if (istype(speaker, /mob/living/silicon/pai))
jobname = "Personal AI"
else
jobname = "Unknown"
if(changed_voice)
if(impersonating)
track = "<a href='byond://?src=\ref[src];trackname=[html_encode(speaker_name)];track=\ref[impersonating]'>[speaker_name] ([jobname])</a>"
else
track = "[speaker_name] ([jobname])"
else
track = "<a href='byond://?src=\ref[src];trackname=[html_encode(speaker_name)];track=\ref[speaker]'>[speaker_name] ([jobname])</a>"
if(istype(src, /mob/dead/observer))
if(speaker_name != speaker.real_name && !isAI(speaker)) //Announce computer and various stuff that broadcasts doesn't use it's real name but AI's can't pretend to be other mobs.
speaker_name = "[speaker.real_name] ([speaker_name])"
track = "[speaker_name] (<a href='byond://?src=\ref[src];track=\ref[speaker]'>follow</a>)"
if(sdisabilities & DEAF || ear_deaf)
if(prob(20))
src << "<span class='warning'>You feel your headset vibrate but can hear nothing from it!</span>"
else if(track)
src << "[part_a][track][part_b][verb], <span class=\"[style]\">\"[message]\"</span></span></span>"
else
src << "[part_a][speaker_name][part_b][verb], <span class=\"[style]\">\"[message]\"</span></span></span>"
/mob/proc/hear_sleep(var/message)
var/heard = ""
if(prob(15))
var/list/punctuation = list(",", "!", ".", ";", "?")
var/list/messages = text2list(message, " ")
var/R = rand(1, messages.len)
var/heardword = messages[R]
if(copytext(heardword,1, 1) in punctuation)
heardword = copytext(heardword,2)
if(copytext(heardword,-1) in punctuation)
heardword = copytext(heardword,1,lentext(heardword))
heard = "<span class = 'game_say'>...You hear something about...[heardword]</span>"
else
heard = "<span class = 'game_say'>...<i>You almost hear someone talking</i>...</span>"
src << heard
+51
View File
@@ -0,0 +1,51 @@
//Helper object for picking dionaea (and other creatures) up.
/obj/item/weapon/holder
name = "holder"
desc = "You shouldn't ever see this."
icon = 'icons/obj/objects.dmi'
slot_flags = SLOT_HEAD
/obj/item/weapon/holder/New()
..()
processing_objects.Add(src)
/obj/item/weapon/holder/Del()
processing_objects.Remove(src)
..()
/obj/item/weapon/holder/process()
if(istype(loc,/turf) || !(contents.len))
for(var/mob/M in contents)
var/atom/movable/mob_container
mob_container = M
mob_container.forceMove(get_turf(src))
M.reset_view()
del(src)
/obj/item/weapon/holder/attackby(obj/item/weapon/W as obj, mob/user as mob)
for(var/mob/M in src.contents)
M.attackby(W,user)
/obj/item/weapon/holder/proc/show_message(var/message, var/m_type)
for(var/mob/living/M in contents)
M.show_message(message,m_type)
//Mob specific holders.
/obj/item/weapon/holder/diona
name = "diona nymph"
desc = "It's a tiny plant critter."
icon_state = "nymph"
origin_tech = "magnets=3;biotech=5"
/obj/item/weapon/holder/drone
name = "maintenance drone"
desc = "It's a small maintenance robot."
icon_state = "drone"
origin_tech = "magnets=3;engineering=5"
@@ -58,7 +58,7 @@
/mob/living/carbon/alien/proc/handle_environment(var/datum/gas_mixture/environment)
//If there are alien weeds on the ground then heal if needed or give some toxins
//If there are alien weeds on the ground then heal if needed or give some plasma
if(locate(/obj/effect/alien/weeds) in loc)
if(health >= maxHealth - getCloneLoss())
adjustToxLoss(plasma_rate)
@@ -383,13 +383,13 @@
sight |= SEE_MOBS
sight |= SEE_OBJS
see_in_dark = 8
see_invisible = SEE_INVISIBLE_MINIMUM
see_invisible = SEE_INVISIBLE_LEVEL_TWO
else if (stat != 2)
sight |= SEE_MOBS
sight &= ~SEE_TURFS
sight &= ~SEE_OBJS
see_in_dark = 8
see_invisible = SEE_INVISIBLE_MINIMUM
see_invisible = SEE_INVISIBLE_LEVEL_TWO
if (healths)
if (stat != 2)
@@ -298,13 +298,13 @@ FUCK YOU MORE FAT CODE -Hawk*/
sight |= SEE_MOBS
sight |= SEE_OBJS
see_in_dark = 8
see_invisible = SEE_INVISIBLE_MINIMUM
see_invisible = SEE_INVISIBLE_LEVEL_TWO
else if (stat != 2)
sight |= SEE_MOBS
sight &= ~SEE_TURFS
sight &= ~SEE_OBJS
see_in_dark = 4
see_invisible = SEE_INVISIBLE_MINIMUM
see_invisible = SEE_INVISIBLE_LEVEL_TWO
if (healths)
if (stat != 2)
@@ -5,7 +5,7 @@
icon_state = "brain2"
flags = TABLEPASS
force = 1.0
w_class = 1.0
w_class = 2.0
throwforce = 1.0
throw_speed = 3
throw_range = 5
+1 -1
View File
@@ -210,7 +210,7 @@
sight |= SEE_MOBS
sight |= SEE_OBJS
see_in_dark = 8
see_invisible = SEE_INVISIBLE_MINIMUM
see_invisible = SEE_INVISIBLE_LEVEL_TWO
else if (stat != 2)
sight &= ~SEE_TURFS
sight &= ~SEE_MOBS
+12 -7
View File
@@ -195,17 +195,22 @@
if (istype(src,/mob/living/carbon/human) && src:w_uniform)
var/mob/living/carbon/human/H = src
H.w_uniform.add_fingerprint(M)
src.sleeping = max(0,src.sleeping-5)
if(src.sleeping == 0)
src.resting = 0
if(lying)
src.sleeping = max(0,src.sleeping-5)
if(src.sleeping == 0)
src.resting = 0
M.visible_message("<span class='notice'>[M] shakes [src] trying to wake [t_him] up!", \
"<span class='notice'>You shake [src] trying to wake [t_him] up!")
else
M.visible_message("<span class='notice'>[M] hugs [src] to make [t_him] feel better!</span>", \
"<span class='notice'>You hug [src] to make [t_him] feel better!</span>")
AdjustParalysis(-3)
AdjustStunned(-3)
AdjustWeakened(-3)
playsound(src.loc, 'sound/weapons/thudswoosh.ogg', 50, 1, -1)
M.visible_message( \
"\blue [M] shakes [src] trying to wake [t_him] up!", \
"\blue You shake [src] trying to wake [t_him] up!", \
)
/mob/living/carbon/proc/eyecheck()
return 0
+171 -27
View File
@@ -12,39 +12,40 @@
real_name = "Test Dummy"
status_flags = GODMODE|CANPUSH
/mob/living/carbon/human/skrell/New()
/mob/living/carbon/human/skrell/New(var/new_loc)
h_style = "Skrell Male Tentacles"
set_species("Skrell")
..()
..(new_loc, "Skrell")
/mob/living/carbon/human/tajaran/New()
/mob/living/carbon/human/tajaran/New(var/new_loc)
h_style = "Tajaran Ears"
set_species("Tajaran")
..()
..(new_loc, "Tajaran")
/mob/living/carbon/human/unathi/New()
/mob/living/carbon/human/unathi/New(var/new_loc)
h_style = "Unathi Horns"
set_species("Unathi")
..()
..(new_loc, "Unathi")
/mob/living/carbon/human/vox/New()
/mob/living/carbon/human/vox/New(var/new_loc)
h_style = "Short Vox Quills"
set_species("Vox")
..()
..(new_loc, "Vox")
/mob/living/carbon/human/diona/New()
species = new /datum/species/diona(src)
..()
/mob/living/carbon/human/voxarmalis/New(var/new_loc)
h_style = "Bald"
..(new_loc, "Vox Armalis")
/mob/living/carbon/human/machine/New()
/mob/living/carbon/human/diona/New(var/new_loc)
..(new_loc, "Diona")
/mob/living/carbon/human/machine/New(var/new_loc)
h_style = "blue IPC screen"
set_species("Machine")
..()
..(new_loc, "Machine")
/mob/living/carbon/human/New()
/mob/living/carbon/human/New(var/new_loc, var/new_species = null)
if(!species)
set_species()
if(new_species)
set_species(new_species)
else
set_species()
var/datum/reagents/R = new/datum/reagents(1000)
reagents = R
@@ -63,7 +64,7 @@
hud_list[IMPTRACK_HUD] = image('icons/mob/hud.dmi', src, "hudblank")
hud_list[SPECIALROLE_HUD] = image('icons/mob/hud.dmi', src, "hudblank")
hud_list[STATUS_HUD_OOC] = image('icons/mob/hud.dmi', src, "hudhealthy")
..()
@@ -71,7 +72,6 @@
dna.real_name = real_name
prev_gender = gender // Debug for plural genders
make_organs()
make_blood()
/mob/living/carbon/human/Bump(atom/movable/AM as mob|obj, yes)
@@ -99,6 +99,18 @@
now_pushing = 0
return
//Leaping mobs just land on the tile, no pushing, no anything.
if(status_flags & LEAPING)
loc = tmob.loc
status_flags &= ~LEAPING
now_pushing = 0
return
if(istype(tmob,/mob/living/silicon/robot/drone)) //I have no idea why the hell this isn't already happening. How do mice do it?
loc = tmob.loc
now_pushing = 0
return
//BubbleWrap: people in handcuffs are always switched around as if they were on 'help' intent to prevent a person being pulled from being seperated from their puller
if((tmob.a_intent == "help" || tmob.restrained()) && (a_intent == "help" || src.restrained()) && tmob.canmove && canmove) // mutual brohugs all around!
var/turf/oldloc = loc
@@ -391,6 +403,9 @@
/mob/living/carbon/human/show_inv(mob/user as mob)
var/obj/item/clothing/under/suit = null
if (istype(w_uniform, /obj/item/clothing/under))
suit = w_uniform
user.set_machine(src)
var/dat = {"
@@ -405,21 +420,22 @@
<BR><B>Right Ear:</B> <A href='?src=\ref[src];item=r_ear'>[(r_ear ? r_ear : "Nothing")]</A>
<BR><B>Head:</B> <A href='?src=\ref[src];item=head'>[(head ? head : "Nothing")]</A>
<BR><B>Shoes:</B> <A href='?src=\ref[src];item=shoes'>[(shoes ? shoes : "Nothing")]</A>
<BR><B>Belt:</B> <A href='?src=\ref[src];item=belt'>[(belt ? belt : "Nothing")]</A>
<BR><B>Uniform:</B> <A href='?src=\ref[src];item=uniform'>[(w_uniform ? w_uniform : "Nothing")]</A>
<BR><B>Belt:</B> <A href='?src=\ref[src];item=belt'>[(belt ? belt : "Nothing")]</A> [((istype(wear_mask, /obj/item/clothing/mask) && istype(belt, /obj/item/weapon/tank) && !( internal )) ? text(" <A href='?src=\ref[];item=internal'>Set Internal</A>", src) : "")]
<BR><B>Uniform:</B> <A href='?src=\ref[src];item=uniform'>[(w_uniform ? w_uniform : "Nothing")]</A> [(suit) ? ((suit.has_sensor == 1) ? text(" <A href='?src=\ref[];item=sensor'>Sensors</A>", src) : "") :]
<BR><B>(Exo)Suit:</B> <A href='?src=\ref[src];item=suit'>[(wear_suit ? wear_suit : "Nothing")]</A>
<BR><B>Back:</B> <A href='?src=\ref[src];item=back'>[(back ? back : "Nothing")]</A> [((istype(wear_mask, /obj/item/clothing/mask) && istype(back, /obj/item/weapon/tank) && !( internal )) ? text(" <A href='?src=\ref[];item=internal'>Set Internal</A>", src) : "")]
<BR><B>ID:</B> <A href='?src=\ref[src];item=id'>[(wear_id ? wear_id : "Nothing")]</A>
<BR><B>Suit Storage:</B> <A href='?src=\ref[src];item=s_store'>[(s_store ? s_store : "Nothing")]</A>
<BR><B>Suit Storage:</B> <A href='?src=\ref[src];item=s_store'>[(s_store ? s_store : "Nothing")]</A> [((istype(wear_mask, /obj/item/clothing/mask) && istype(s_store, /obj/item/weapon/tank) && !( internal )) ? text(" <A href='?src=\ref[];item=internal'>Set Internal</A>", src) : "")]
<BR>[(handcuffed ? text("<A href='?src=\ref[src];item=handcuff'>Handcuffed</A>") : text("<A href='?src=\ref[src];item=handcuff'>Not Handcuffed</A>"))]
<BR>[(legcuffed ? text("<A href='?src=\ref[src];item=legcuff'>Legcuffed</A>") : text(""))]
<BR>[(suit) ? ((suit.hastie) ? text(" <A href='?src=\ref[];item=tie'>Remove Accessory</A>", src) : "") :]
<BR>[(internal ? text("<A href='?src=\ref[src];item=internal'>Remove Internal</A>") : "")]
<BR><A href='?src=\ref[src];item=splints'>Remove Splints</A>
<BR><A href='?src=\ref[src];item=pockets'>Empty Pockets</A>
<BR><A href='?src=\ref[user];refresh=1'>Refresh</A>
<BR><A href='?src=\ref[user];mach_close=mob[name]'>Close</A>
<BR>"}
user << browse(dat, text("window=mob[name];size=340x480"))
user << browse(dat, text("window=mob[name];size=340x540"))
onclose(user, "mob[name]")
return
@@ -860,6 +876,10 @@
return
/mob/living/carbon/human/proc/vomit()
if(species.flags & IS_SYNTHETIC)
return //Machines don't throw up.
if(!lastpuke)
lastpuke = 1
src << "<spawn class='warning'>You feel nauseous..."
@@ -1202,7 +1222,7 @@
else
usr << "\blue [self ? "Your" : "[src]'s"] pulse is [src.get_pulse(GETPULSE_HAND)]."
/mob/living/carbon/human/proc/set_species(var/new_species)
/mob/living/carbon/human/proc/set_species(var/new_species, var/force_organs)
if(!dna)
if(!new_species)
@@ -1221,6 +1241,9 @@
species = all_species[new_species]
if(force_organs || !organs || !organs.len)
species.create_organs(src)
if(species.language)
add_language(species.language)
@@ -1287,3 +1310,124 @@
W.update_icon()
W.message = message
W.add_fingerprint(src)
/mob/living/carbon/human/can_inject(var/mob/user, var/error_msg, var/target_zone)
. = 1
if(!user)
target_zone = pick("chest","chest","chest","left leg","right leg","left arm", "right arm", "head")
else if(!target_zone)
target_zone = user.zone_sel.selecting
switch(target_zone)
if("head")
if(head && head.flags & THICKMATERIAL)
. = 0
else
if(wear_suit && wear_suit.flags & THICKMATERIAL)
. = 0
if(!. && error_msg && user)
// Might need re-wording.
user << "<span class='alert'>There is no exposed flesh or thin material [target_zone == "head" ? "on their head" : "on their body"] to inject into.</span>"
//Putting a couple of procs here that I don't know where else to dump.
//Mostly going to be used for Vox and Vox Armalis, but other human mobs might like them (for adminbuse).
/mob/living/carbon/human/proc/leap()
set category = "IC"
set name = "Leap"
set desc = "Leap at a target and grab them aggressively."
if(last_special > world.time)
return
if(stat || paralysis || stunned || weakened || lying)
src << "You cannot leap in your current state."
return
var/list/choices = list()
for(var/mob/living/M in view(6,src))
if(!istype(M,/mob/living/silicon))
choices += M
choices -= src
var/mob/living/T = input(src,"Who do you wish to leap at?") in null|choices
if(!T || !src || src.stat) return
if(get_dist(get_turf(T), get_turf(src)) > 6) return
last_special = world.time + 100
status_flags |= LEAPING
src.visible_message("<span class='warning'><b>\The [src]</b> leaps at [T]!</span>")
src.throw_at(get_step(get_turf(T),get_turf(src)), 5, 1)
playsound(src.loc, 'sound/voice/shriek1.ogg', 50, 1)
sleep(5)
if(status_flags & LEAPING) status_flags &= ~LEAPING
if(!src.Adjacent(T))
src << "\red You miss!"
return
T.Weaken(5)
var/use_hand = "left"
if(l_hand)
if(r_hand)
src << "\red You need to have one hand free to grab someone."
return
else
use_hand = "right"
src.visible_message("<span class='warning'><b>\The [src]</b> seizes [T] aggressively!</span>")
var/obj/item/weapon/grab/G = new(src,T)
if(use_hand == "left")
l_hand = G
else
r_hand = G
G.state = GRAB_AGGRESSIVE
G.icon_state = "grabbed1"
G.synch()
/mob/living/carbon/human/proc/gut()
set category = "IC"
set name = "Gut"
set desc = "While grabbing someone aggressively, rip their guts out or tear them apart."
if(last_special > world.time)
return
if(stat || paralysis || stunned || weakened || lying)
src << "\red You cannot do that in your current state."
return
var/obj/item/weapon/grab/G = locate() in src
if(!G || !istype(G))
src << "\red You are not grabbing anyone."
return
if(G.state < GRAB_AGGRESSIVE)
src << "\red You must have an aggressive grab to gut your prey!"
return
last_special = world.time + 50
visible_message("<span class='warning'><b>\The [src]</b> rips viciously at \the [G.affecting]'s body with its claws!</span>")
if(istype(G.affecting,/mob/living/carbon/human))
var/mob/living/carbon/human/H = G.affecting
H.apply_damage(50,BRUTE)
if(H.stat == 2)
H.gib()
else
var/mob/living/M = G.affecting
if(!istype(M)) return //wut
M.apply_damage(50,BRUTE)
if(M.stat == 2)
M.gib()
@@ -73,6 +73,10 @@
/mob/living/carbon/human/adjustCloneLoss(var/amount)
..()
if(species.flags & IS_SYNTHETIC)
return
var/heal_prob = max(0, 80 - getCloneLoss())
var/mut_prob = min(80, getCloneLoss()+10)
if (amount > 0)
@@ -142,6 +146,7 @@
UpdateDamageIcon()
hud_updateflag |= 1 << HEALTH_HUD
updatehealth()
speech_problem_flag = 1
//Heal MANY external organs, in random order
@@ -163,6 +168,7 @@
parts -= picked
updatehealth()
hud_updateflag |= 1 << HEALTH_HUD
speech_problem_flag = 1
if(update) UpdateDamageIcon()
// damage MANY external organs, in random order
@@ -52,7 +52,7 @@ emp_act
return -1 // complete projectile permutation
if(check_shields(P.damage, "the [P.name]"))
P.on_hit(src, 2)
P.on_hit(src, 2, def_zone)
return 2
//BEGIN BOOK'S TASER NERF.
@@ -18,12 +18,18 @@
var/s_tone = 0 //Skin tone
//Skin colour
var/r_skin = 0
var/g_skin = 0
var/b_skin = 0
var/lip_style = null //no lipstick by default- arguably misleading, as it could be used for general makeup
var/age = 30 //Player's age (pure fluff)
var/b_type = "A+" //Player's bloodtype
var/underwear = 1 //Which underwear the player wants
var/undershirt = 0 //Which undershirt the player wants.
var/backbag = 2 //Which backpack type the player has chosen. Nothing, Satchel or Backpack.
//Equipment slots
@@ -48,6 +54,10 @@
var/icon/stand_icon = null
var/icon/lying_icon = null
var/voice = "" //Instead of new say code calling GetVoice() over and over and over, we're just going to ask this variable, which gets updated in Life()
var/speech_problem_flag = 0
var/miming = null //Toggle for the mime's abilities.
var/special_voice = "" // For changing our voice. Used by a symptom.
@@ -388,11 +388,14 @@
if(count == 0)
del(src)
return
if("sensor")
if (! target.w_uniform )
del(src)
if("internal")
if ((!( (istype(target.wear_mask, /obj/item/clothing/mask) && istype(target.back, /obj/item/weapon/tank) && !( target.internal )) ) && !( target.internal )))
del(src)
var/list/L = list( "syringe", "pill", "drink", "dnainjector", "fuel")
var/list/L = list( "syringe", "pill", "drink", "dnainjector", "fuel", "sensor", "internal", "tie")
if ((item && !( L.Find(place) )))
if(isrobot(source) && place != "handcuff")
del(src)
@@ -508,6 +511,17 @@
return
else
message = "\red <B>[source] is trying to take off \a [target.w_uniform] from [target]'s body!</B>"
if("tie")
var/obj/item/clothing/under/suit = target.w_uniform
target.attack_log += text("\[[time_stamp()]\] <font color='orange'>Has had their accessory ([suit.hastie]) removed by [source.name] ([source.ckey])</font>")
source.attack_log += text("\[[time_stamp()]\] <font color='red'>Attempted to remove [target.name]'s ([target.ckey]) accessory ([suit.hastie])</font>")
if(istype(suit.hastie, /obj/item/clothing/tie/holobadge) || istype(suit.hastie, /obj/item/clothing/tie/medal))
for(var/mob/M in viewers(target, null))
M.show_message("\red <B>[source] tears off \the [suit.hastie] from [target]'s suit!</B>" , 1)
done()
return
else
message = "\red <B>[source] is trying to take off \a [suit.hastie] from [target]'s suit!</B>"
if("s_store")
target.attack_log += text("\[[time_stamp()]\] <font color='orange'>Has had their suit storage item ([target.s_store]) removed by [source.name] ([source.ckey])</font>")
source.attack_log += text("\[[time_stamp()]\] <font color='red'>Attempted to remove [target.name]'s ([target.ckey]) suit storage item ([target.s_store])</font>")
@@ -537,6 +551,14 @@
message = "\red <B>[source] is trying to set on [target]'s internals.</B>"
if("splints")
message = text("\red <B>[] is trying to remove []'s splints!</B>", source, target)
if("sensor")
target.attack_log += text("\[[time_stamp()]\] <font color='orange'>Has had their sensors toggled by [source.name] ([source.ckey])</font>")
source.attack_log += text("\[[time_stamp()]\] <font color='red'>Attempted to toggle [target.name]'s ([target.ckey]) sensors</font>")
var/obj/item/clothing/under/suit = target.w_uniform
if (suit.has_sensor >= 2)
source << "The controls are locked."
return
message = "\red <B>[source] is trying to set [target]'s suit sensors!</B>"
for(var/mob/M in viewers(target, null))
M.show_message(message, 1)
@@ -624,6 +646,19 @@ It can still be worn/put on as normal.
slot_to_process = slot_wear_suit
if (target.wear_suit && target.wear_suit.canremove)
strip_item = target.wear_suit
if("tie")
var/obj/item/clothing/under/suit = target.w_uniform
//var/obj/item/clothing/tie/tie = suit.hastie
/*if(tie)
if (istype(tie,/obj/item/clothing/tie/storage))
var/obj/item/clothing/tie/storage/W = tie
if (W.hold)
W.hold.close(usr)
usr.put_in_hands(tie)
suit.hastie = null*/
suit.hastie.on_removed(usr)
suit.hastie = null
target.update_inv_w_uniform()
if("id")
slot_to_process = slot_wear_id
if (target.wear_id)
@@ -675,8 +710,20 @@ It can still be worn/put on as normal.
O.show_message("\red [source] injects [target] with the DNA Injector!", 1)
S.inuse = 0
if("pockets")
slot_to_process = slot_l_store
strip_item = target.l_store //We'll do both
if (!item || (target.l_store && target.r_store)) // Only empty pockets when hand is empty or both pockets are full
slot_to_process = slot_l_store
strip_item = target.l_store //We'll do both
else if (target.l_store)
slot_to_process = slot_r_store
else
slot_to_process = slot_l_store
if("sensor")
var/obj/item/clothing/under/suit = target.w_uniform
if (suit)
if(suit.has_sensor >= 2)
source << "The controls are locked."
else
suit.set_sensors(source)
if("internal")
if (target.internal)
target.internal.add_fingerprint(source)
+136 -70
View File
@@ -66,6 +66,8 @@
if(life_tick%30==15)
hud_updateflag = 1022
voice = GetVoice()
//No need to update all of these procs if the guy is dead.
if(stat != DEAD && !in_stasis)
if(air_master.current_cycle%4==2 || failed_last_breath) //First, resolve location and get a breath
@@ -143,7 +145,6 @@
return ONE_ATMOSPHERE - pressure_difference
/mob/living/carbon/human
proc/handle_disabilities()
if (disabilities & EPILEPSY)
if ((prob(1) && paralysis < 1))
@@ -161,6 +162,7 @@
emote("cough")
return
if (disabilities & TOURETTES)
speech_problem_flag = 1
if ((prob(10) && paralysis <= 1))
Stun(10)
spawn( 0 )
@@ -178,6 +180,7 @@
pixel_y = old_y
return
if (disabilities & NERVOUS)
speech_problem_flag = 1
if (prob(10))
stuttering = max(10, stuttering)
// No. -- cib
@@ -222,6 +225,9 @@
proc/handle_mutations_and_radiation()
if(species.flags & IS_SYNTHETIC) //Robots don't suffer from mutations or radloss.
return
if(getFireLoss())
if((COLD_RESISTANCE in mutations) || (prob(1)))
heal_organ_damage(0,1)
@@ -232,6 +238,7 @@
if(!gene.block)
continue
if(gene.is_active(src))
speech_problem_flag = 1
gene.OnMobLife(src)
if (radiation)
@@ -245,6 +252,7 @@
radiation = 0
else
if(species.flags & RAD_ABSORB)
var/rads = radiation/25
radiation -= rads
@@ -300,9 +308,11 @@
var/datum/gas_mixture/environment = loc.return_air()
var/datum/gas_mixture/breath
// HACK NEED CHANGING LATER
if(health < config.health_threshold_crit)
if(health < config.health_threshold_crit && !reagents.has_reagent("inaprovaline"))
losebreath++
if(losebreath>0) //Suffocating so do not take a breath
losebreath--
if (prob(10)) //Gasp per 10 ticks? Sounds about right.
@@ -410,8 +420,6 @@
return
if(!breath || (breath.total_moles() == 0) || suiciding)
if(reagents.has_reagent("inaprovaline"))
return
if(suiciding)
adjustOxyLoss(2)//If you are suiciding, you should die a little bit faster
failed_last_breath = 1
@@ -428,111 +436,162 @@
return 0
var/safe_oxygen_min = 16 // Minimum safe partial pressure of O2, in kPa
//var/safe_oxygen_max = 140 // Maximum safe partial pressure of O2, in kPa (Not used for now)
var/safe_co2_max = 10 // Yes it's an arbitrary value who cares?
var/safe_pressure_min = 16 // Minimum safe partial pressure of breathable gas in kPa
//var/safe_pressure_max = 140 // Maximum safe partial pressure of breathable gas in kPa (Not used for now)
var/safe_exhaled_max = 10 // Yes it's an arbitrary value who cares?
var/safe_toxins_max = 0.005
var/SA_para_min = 1
var/SA_sleep_min = 5
var/oxygen_used = 0
var/nitrogen_used = 0
var/inhaled_gas_used = 0
var/breath_pressure = (breath.total_moles()*R_IDEAL_GAS_EQUATION*breath.temperature)/BREATH_VOLUME
var/vox_oxygen_max = 1 // For vox.
//Partial pressure of the O2 in our breath
var/O2_pp = (breath.oxygen/breath.total_moles())*breath_pressure
// Same, but for the toxins
var/Toxins_pp = (breath.toxins/breath.total_moles())*breath_pressure
// And CO2, lets say a PP of more than 10 will be bad (It's a little less really, but eh, being passed out all round aint no fun)
var/CO2_pp = (breath.carbon_dioxide/breath.total_moles())*breath_pressure // Tweaking to fit the hacky bullshit I've done with atmo -- TLE
//var/CO2_pp = (breath.carbon_dioxide/breath.total_moles())*0.5 // The default pressure value
// Nitrogen, for Vox.
var/Nitrogen_pp = (breath.nitrogen/breath.total_moles())*breath_pressure
var/inhaling
var/exhaling
var/poison
var/no_exhale
if(O2_pp < safe_oxygen_min && species.name != "Vox") // Too little oxygen
switch(species.breath_type)
if("nitrogen")
inhaling = breath.nitrogen
if("plasma")
inhaling = breath.toxins
if("C02")
inhaling = breath.carbon_dioxide
else
inhaling = breath.oxygen
switch(species.poison_type)
if("oxygen")
poison = breath.oxygen
if("nitrogen")
poison = breath.nitrogen
if("C02")
poison = breath.carbon_dioxide
else
poison = breath.toxins
switch(species.exhale_type)
if("C02")
exhaling = breath.carbon_dioxide
if("oxygen")
exhaling = breath.oxygen
if("nitrogen")
exhaling = breath.nitrogen
if("plasma")
exhaling = breath.toxins
else
no_exhale = 1
var/inhale_pp = (inhaling/breath.total_moles())*breath_pressure
var/toxins_pp = (poison/breath.total_moles())*breath_pressure
var/exhaled_pp = (exhaling/breath.total_moles())*breath_pressure
if(inhale_pp < safe_pressure_min)
if(prob(20))
spawn(0) emote("gasp")
if(O2_pp > 0)
var/ratio = safe_oxygen_min/O2_pp
adjustOxyLoss(min(5*ratio, HUMAN_MAX_OXYLOSS)) // Don't fuck them up too fast (space only does HUMAN_MAX_OXYLOSS after all!)
if(inhale_pp > 0)
var/ratio = inhale_pp/safe_pressure_min
// Don't fuck them up too fast (space only does HUMAN_MAX_OXYLOSS after all!)
adjustOxyLoss(min(5*(1 - ratio), HUMAN_MAX_OXYLOSS))
failed_last_breath = 1
oxygen_used = breath.oxygen*ratio/6
inhaled_gas_used = inhaling*ratio/6
else
adjustOxyLoss(HUMAN_MAX_OXYLOSS)
failed_last_breath = 1
oxygen_alert = max(oxygen_alert, 1)
/*else if (O2_pp > safe_oxygen_max) // Too much oxygen (commented this out for now, I'll deal with pressure damage elsewhere I suppose)
spawn(0) emote("cough")
var/ratio = O2_pp/safe_oxygen_max
oxyloss += 5*ratio
oxygen_used = breath.oxygen*ratio/6
oxygen_alert = max(oxygen_alert, 1)*/
else if(Nitrogen_pp < safe_oxygen_min && species.name == "Vox") //Vox breathe nitrogen, not oxygen.
if(prob(20))
spawn(0) emote("gasp")
if(Nitrogen_pp > 0)
var/ratio = safe_oxygen_min/Nitrogen_pp
adjustOxyLoss(min(5*ratio, HUMAN_MAX_OXYLOSS))
failed_last_breath = 1
nitrogen_used = breath.nitrogen*ratio/6
else
adjustOxyLoss(HUMAN_MAX_OXYLOSS)
failed_last_breath = 1
oxygen_alert = max(oxygen_alert, 1)
else // We're in safe limits
else
// We're in safe limits
failed_last_breath = 0
adjustOxyLoss(-5)
oxygen_used = breath.oxygen/6
inhaled_gas_used = inhaling/6
oxygen_alert = 0
breath.oxygen -= oxygen_used
breath.nitrogen -= nitrogen_used
breath.carbon_dioxide += oxygen_used
switch(species.breath_type)
if("nitrogen")
breath.nitrogen -= inhaled_gas_used
else
breath.oxygen -= inhaled_gas_used
//CO2 does not affect failed_last_breath. So if there was enough oxygen in the air but too much co2, this will hurt you, but only once per 4 ticks, instead of once per tick.
if(CO2_pp > safe_co2_max)
if(!co2overloadtime) // If it's the first breath with too much CO2 in it, lets start a counter, then have them pass out after 12s or so.
if(!no_exhale)
switch(species.exhale_type)
if("oxygen")
breath.oxygen += inhaled_gas_used
if("nitrogen")
breath.nitrogen += inhaled_gas_used
if("plasma")
breath.toxins += inhaled_gas_used
if("C02")
breath.carbon_dioxide += inhaled_gas_used
// CO2 does not affect failed_last_breath. So if there was enough oxygen in the air but too much co2,
// this will hurt you, but only once per 4 ticks, instead of once per tick.
if(exhaled_pp > safe_exhaled_max)
// If it's the first breath with too much CO2 in it, lets start a counter,
// then have them pass out after 12s or so.
if(!co2overloadtime)
co2overloadtime = world.time
else if(world.time - co2overloadtime > 120)
// Lets hurt em a little, let them know we mean business
Paralyse(3)
adjustOxyLoss(3) // Lets hurt em a little, let them know we mean business
if(world.time - co2overloadtime > 300) // They've been in here 30s now, lets start to kill them for their own good!
adjustOxyLoss(3)
// They've been in here 30s now, lets start to kill them for their own good!
if(world.time - co2overloadtime > 300)
adjustOxyLoss(8)
if(prob(20)) // Lets give them some chance to know somethings not right though I guess.
// Lets give them some chance to know somethings not right though I guess.
if(prob(20))
spawn(0) emote("cough")
else
co2overloadtime = 0
if(Toxins_pp > safe_toxins_max) // Too much toxins
var/ratio = (breath.toxins/safe_toxins_max) * 10
//adjustToxLoss(Clamp(ratio, MIN_PLASMA_DAMAGE, MAX_PLASMA_DAMAGE)) //Limit amount of damage toxin exposure can do per second
// Too much poison in the air.
if(toxins_pp > safe_toxins_max)
var/ratio = (poison/safe_toxins_max) * 10
if(reagents)
//TODO: Fix Ravensdale's shit, make toxins toxins again instead of phoron.
reagents.add_reagent("plasma", Clamp(ratio, MIN_PLASMA_DAMAGE, MAX_PLASMA_DAMAGE))
toxins_alert = max(toxins_alert, 1)
else if(O2_pp > vox_oxygen_max && species.name == "Vox") //Oxygen is toxic to vox.
var/ratio = (breath.oxygen/vox_oxygen_max) * 1000
adjustToxLoss(Clamp(ratio, MIN_PLASMA_DAMAGE, MAX_PLASMA_DAMAGE))
toxins_alert = max(toxins_alert, 1)
else
toxins_alert = 0
if(breath.trace_gases.len) // If there's some other shit in the air lets deal with it here.
// If there's some other shit in the air lets deal with it here.
if(breath.trace_gases.len)
for(var/datum/gas/sleeping_agent/SA in breath.trace_gases)
var/SA_pp = (SA.moles/breath.total_moles())*breath_pressure
if(SA_pp > SA_para_min) // Enough to make us paralysed for a bit
Paralyse(3) // 3 gives them one second to wake up and run away a bit!
if(SA_pp > SA_sleep_min) // Enough to make us sleep as well
// Enough to make us paralysed for a bit
if(SA_pp > SA_para_min)
// 3 gives them one second to wake up and run away a bit!
Paralyse(3)
// Enough to make us sleep as well
if(SA_pp > SA_sleep_min)
sleeping = min(sleeping+2, 10)
else if(SA_pp > 0.15) // There is sleeping gas in their lungs, but only a little, so give them a bit of a warning
// There is sleeping gas in their lungs, but only a little, so give them a bit of a warning
else if(SA_pp > 0.15)
if(prob(20))
spawn(0) emote(pick("giggle", "laugh"))
SA.moles = 0
if( (abs(310.15 - breath.temperature) > 50) && !(COLD_RESISTANCE in mutations)) // Hot air hurts :(
if(status_flags & GODMODE) return 1 //godmode
if(status_flags & GODMODE)
return 1
if(breath.temperature < species.cold_level_1)
if(prob(20))
src << "\red You feel your face freezing and an icicle forming in your lungs!"
@@ -567,6 +626,11 @@
proc/handle_environment(datum/gas_mixture/environment)
if(!environment)
return
//Moved pressure calculations here for use in skip-processing check.
var/pressure = environment.return_pressure()
var/adjusted_pressure = calculate_affecting_pressure(pressure)
if(!istype(get_turf(src), /turf/space)) //space is not meant to change your body temperature.
var/loc_temp = T0C
if(istype(loc, /obj/mecha))
@@ -578,7 +642,7 @@
else
loc_temp = environment.temperature
if(abs(loc_temp - 293.15) < 20 && abs(bodytemperature - 310.14) < 0.5 && environment.toxins < MOLES_PLASMA_VISIBLE)
if(adjusted_pressure < species.warning_low_pressure && adjusted_pressure > species.warning_low_pressure && abs(loc_temp - 293.15) < 20 && abs(bodytemperature - 310.14) < 0.5 && environment.toxins < MOLES_PLASMA_VISIBLE)
return // Temperatures are within normal ranges, fuck all this processing. ~Ccomp
//Body temperature is adjusted in two steps. Firstly your body tries to stabilize itself a bit.
@@ -630,9 +694,6 @@
// Account for massive pressure differences. Done by Polymorph
// Made it possible to actually have something that can protect against high pressure... Done by Errorage. Polymorph now has an axe sticking from his head for his previous hardcoded nonsense!
var/pressure = environment.return_pressure()
var/adjusted_pressure = calculate_affecting_pressure(pressure) //Returns how much pressure actually affects the mob.
if(status_flags & GODMODE) return 1 //godmode
if(adjusted_pressure >= species.hazard_high_pressure)
@@ -1052,6 +1113,7 @@
if(halloss > 0)
adjustHalLoss(-3)
else if(sleeping)
speech_problem_flag = 1
handle_dreams()
adjustHalLoss(-3)
if (mind)
@@ -1103,16 +1165,20 @@
//Other
if(stunned)
speech_problem_flag = 1
AdjustStunned(-1)
if(weakened)
weakened = max(weakened-1,0) //before you get mad Rockdtben: I done this so update_canmove isn't called multiple times
if(stuttering)
speech_problem_flag = 1
stuttering = max(stuttering-1, 0)
if (slurring)
speech_problem_flag = 1
slurring = max(slurring-1, 0)
if(silent)
speech_problem_flag = 1
silent = max(silent-1, 0)
if(druggy)
+188 -32
View File
@@ -1,50 +1,162 @@
/mob/living/carbon/human/say(var/message)
var/verb = "says"
var/alt_name = ""
var/message_range = world.view
var/italics = 0
if(wear_mask)
if(istype(wear_mask, /obj/item/clothing/mask/gas/voice/space_ninja) && wear_mask:voice == "Unknown")
if(copytext(message, 1, 2) != "*")
var/list/temp_message = text2list(message, " ")
var/list/pick_list = list()
for(var/i = 1, i <= temp_message.len, i++)
pick_list += i
for(var/i=1, i <= abs(temp_message.len/3), i++)
var/H = pick(pick_list)
if(findtext(temp_message[H], "*") || findtext(temp_message[H], ";") || findtext(temp_message[H], ":")) continue
temp_message[H] = ninjaspeak(temp_message[H])
pick_list -= H
message = list2text(temp_message, " ")
message = replacetext(message, "o", "¤")
message = replacetext(message, "p", "þ")
message = replacetext(message, "l", "£")
message = replacetext(message, "s", "§")
message = replacetext(message, "u", "µ")
message = replacetext(message, "b", "ß")
if(client)
if(client.prefs.muted & MUTE_IC)
src << "\red You cannot speak in IC (Muted)."
return
else if(istype(wear_mask, /obj/item/clothing/mask/horsehead))
var/obj/item/clothing/mask/horsehead/hoers = wear_mask
if(hoers.voicechange)
if(!(copytext(message, 1, 2) == "*" || (mind && mind.changeling && department_radio_keys[copytext(message, 1, 3)] != "changeling")))
message = pick("NEEIIGGGHHHH!", "NEEEIIIIGHH!", "NEIIIGGHH!", "HAAWWWWW!", "HAAAWWW!")
message = trim(copytext(sanitize(message), 1, MAX_MESSAGE_LEN))
// if ((HULK in mutations) && health >= 25 && length(message))
// if(copytext(message, 1, 2) != "*")
// message = "[uppertext(message)]!!" //because I don't know how to code properly in getting vars from other files -Bro
if(stat == 2)
return say_dead(message)
if (src.slurring)
if(copytext(message, 1, 2) != "*")
message = slur(message)
..(message)
if (istype(wear_mask, /obj/item/clothing/mask/muzzle)) //Todo: Add this to speech_problem_flag checks.
return
/mob/living/carbon/human/say_understands(var/other,var/datum/language/speaking = null)
if(copytext(message,1,2) == "*")
return emote(copytext(message,2))
if(name != GetVoice())
alt_name = "(as [get_id_name("Unknown")])"
//parse the radio code and consume it
var/message_mode = parse_message_mode(message)
if (message_mode)
if (message_mode == "headset")
message = copytext(message,2)
else
message = copytext(message,3)
//parse the language code and consume it
var/datum/language/speaking = parse_language(message)
if (speaking)
verb = speaking.speech_verb
message = copytext(message,3)
message = capitalize(trim(message))
if(speech_problem_flag)
var/list/handle_r = handle_speech_problems(message)
message = handle_r[1]
verb = handle_r[2]
speech_problem_flag = handle_r[3]
if(!message || stat)
return
var/ending = copytext(message, length(message))
if(ending=="!")
verb=pick("exclaims","shouts","yells")
if(ending=="?")
verb="asks"
var/list/obj/item/used_radios = new
switch (message_mode)
if("headset")
if(l_ear && istype(l_ear,/obj/item/device/radio))
var/obj/item/device/radio/R = l_ear
R.talk_into(src,message,null,verb,speaking)
used_radios += l_ear
else if(r_ear && istype(r_ear,/obj/item/device/radio))
var/obj/item/device/radio/R = r_ear
R.talk_into(src,message,null,verb,speaking)
used_radios += r_ear
if("right ear")
var/obj/item/device/radio/R
var/has_radio = 0
if(r_ear && istype(r_ear,/obj/item/device/radio))
R = r_ear
has_radio = 1
if(r_hand && istype(r_hand, /obj/item/device/radio))
R = r_hand
has_radio = 1
if(has_radio)
R.talk_into(src,message,null,verb,speaking)
used_radios += R
if("left ear")
var/obj/item/device/radio/R
var/has_radio = 0
if(l_ear && istype(l_ear,/obj/item/device/radio))
R = l_ear
has_radio = 1
if(l_hand && istype(l_hand,/obj/item/device/radio))
R = l_hand
has_radio = 1
if(has_radio)
R.talk_into(src,message,null,verb,speaking)
used_radios += R
if("intercom")
for(var/obj/item/device/radio/intercom/I in view(1, null))
I.talk_into(src, message, verb, speaking)
used_radios += I
if("whisper")
whisper(message)
return
if("binary")
if(robot_talk_understand || binarycheck())
robot_talk(message)
return
if("changeling")
if(mind && mind.changeling)
for(var/mob/Changeling in mob_list)
if((Changeling.mind && Changeling.mind.changeling) || istype(Changeling, /mob/dead/observer))
Changeling << "<i><font color=#800080><b>[mind.changeling.changelingID]:</b> [message]</font></i>"
return
else
if(message_mode)
if(message_mode in (radiochannels | "department"))
if(l_ear && istype(l_ear,/obj/item/device/radio))
l_ear.talk_into(src,message, message_mode, verb, speaking)
used_radios += l_ear
else if(r_ear && istype(r_ear,/obj/item/device/radio))
r_ear.talk_into(src,message, message_mode, verb, speaking)
used_radios += r_ear
if(used_radios.len)
italics = 1
message_range = 1
var/datum/gas_mixture/environment = loc.return_air()
if(environment)
var/pressure = environment.return_pressure()
if(pressure < SAY_MINIMUM_PRESSURE)
italics = 1
message_range =1
if((species.name == "Vox" || species.name == "Vox Armalis") && prob(20))
playsound(src.loc, 'sound/voice/shriek1.ogg', 50, 1)
..(message, speaking, verb, alt_name, italics, message_range, used_radios)
/mob/living/carbon/human/say_understands(var/mob/other,var/datum/language/speaking = null)
if(has_brain_worms()) //Brain worms translate everything. Even mice and alien speak.
return 1
if (istype(other, /mob/living/carbon/monkey/diona) && !speaking)
if(other.languages.len >= 2) //They've sucked down some blood and can speak common now.
return 1
if (istype(other, /mob/living/silicon))
return 1
if (istype(other, /mob/living/carbon/brain))
return 1
if (istype(other, /mob/living/carbon/slime))
return 1
if (istype(other, /mob/living/simple_animal))
if(other.universal_speak || src.universal_speak || src.universal_understand)
return 1
return 0
return ..()
/mob/living/carbon/human/GetVoice()
@@ -71,3 +183,47 @@
/mob/living/carbon/human/proc/GetSpecialVoice()
return special_voice
/mob/living/carbon/human/proc/handle_speech_problems(var/message)
var/list/returns[3]
var/verb = "says"
var/handled = 0
if(silent)
message = ""
handled = 1
if(sdisabilities & MUTE)
message = ""
handled = 1
if(wear_mask)
if(istype(wear_mask, /obj/item/clothing/mask/horsehead))
var/obj/item/clothing/mask/horsehead/hoers = wear_mask
if(hoers.voicechange)
if(mind && mind.changeling && department_radio_keys[copytext(message, 1, 3)] != "changeling")
message = pick("NEEIIGGGHHHH!", "NEEEIIIIGHH!", "NEIIIGGHH!", "HAAWWWWW!", "HAAAWWW!")
verb = pick("whinnies","neighs", "says")
handled = 1
if((HULK in mutations) && health >= 25 && length(message))
message = "[uppertext(message)]!!!"
verb = pick("yells","roars","hollers")
handled = 1
if(slurring)
message = slur(message)
verb = pick("stammers","stutters")
handled = 1
var/braindam = getBrainLoss()
if(braindam >= 60)
handled = 1
if(prob(braindam/4))
message = stutter(message)
verb = pick("stammers", "stutters")
if(prob(braindam))
message = uppertext(message)
verb = pick("yells like an idiot","says rather loudly")
returns[1] = message
returns[2] = verb
returns[3] = handled
return returns
@@ -1,3 +1,11 @@
/*
Global associative list for caching humanoid icons.
Index format m or f, followed by a string of 0 and 1 to represent bodyparts followed by husk fat hulk skeleton 1 or 0.
TODO: Proper documentation
icon_key is [species.race_key][g][husk][fat][hulk][skeleton][s_tone]
*/
var/global/list/human_icon_cache = list()
///////////////////////
//UPDATE_ICONS SYSTEM//
///////////////////////
@@ -97,26 +105,26 @@ Please contact me on #coderbus IRC. ~Carn x
*/
//Human Overlays Indexes/////////
#define MUTANTRACE_LAYER 1 //TODO: make part of body?
#define MUTANTRACE_LAYER 1
#define MUTATIONS_LAYER 2
#define DAMAGE_LAYER 3
#define UNIFORM_LAYER 4
#define ID_LAYER 5
#define SHOES_LAYER 6
#define GLOVES_LAYER 7
#define EARS_LAYER 8
#define SUIT_LAYER 9
#define GLASSES_LAYER 10
#define BELT_LAYER 11 //Possible make this an overlay of somethign required to wear a belt?
#define SUIT_STORE_LAYER 12
#define BACK_LAYER 13
#define HAIR_LAYER 14 //TODO: make part of head layer?
#define FACEMASK_LAYER 15
#define HEAD_LAYER 16
#define COLLAR_LAYER 17
#define HANDCUFF_LAYER 18
#define LEGCUFF_LAYER 19
#define TAIL_LAYER 20 //bs12 specific. this hack is probably gonna come back to haunt me
#define TAIL_LAYER 5 //bs12 specific. this hack is probably gonna come back to haunt me
#define ID_LAYER 6
#define SHOES_LAYER 7
#define GLOVES_LAYER 8
#define EARS_LAYER 9
#define SUIT_LAYER 10
#define GLASSES_LAYER 11
#define BELT_LAYER 12 //Possible make this an overlay of somethign required to wear a belt?
#define SUIT_STORE_LAYER 13
#define BACK_LAYER 14
#define HAIR_LAYER 15 //TODO: make part of head layer?
#define FACEMASK_LAYER 16
#define HEAD_LAYER 17
#define COLLAR_LAYER 18
#define HANDCUFF_LAYER 19
#define LEGCUFF_LAYER 20
#define L_HAND_LAYER 21
#define R_HAND_LAYER 22
#define TARGETED_LAYER 23 //BS12: Layer for the target overlay from weapon targeting system
@@ -195,7 +203,6 @@ proc/get_damage_icon_part(damage_state, body_part)
var/image/standing_image = new /image("icon" = standing)
// blend the individual damage states with our icons
for(var/datum/organ/external/O in organs)
if(!(O.status & ORGAN_DESTROYED))
@@ -206,44 +213,75 @@ proc/get_damage_icon_part(damage_state, body_part)
standing_image.overlays += DI
overlays_standing[DAMAGE_LAYER] = standing_image
if(update_icons) update_icons()
//BASE MOB SPRITE
/mob/living/carbon/human/proc/update_body(var/update_icons=1)
if(stand_icon) del(stand_icon)
var/husk_color_mod = rgb(96,88,80)
var/hulk_color_mod = rgb(48,224,40)
var/necrosis_color_mod = rgb(10,50,0)
var/husk = (HUSK in src.mutations) //100% unnecessary -Agouri //nope, do you really want to iterate through src.mutations repeatedly? -Pete
var/husk = (HUSK in src.mutations)
var/fat = (FAT in src.mutations)
var/hulk = (HULK in src.mutations)
var/skeleton = (SKELETON in src.mutations)
var/g = "m"
if(gender == FEMALE) g = "f"
var/datum/organ/external/chest = get_organ("chest")
stand_icon = chest.get_icon(g)
if(!skeleton)
if(husk)
stand_icon.ColorTone(husk_color_mod)
else if(hulk)
var/list/TONE = ReadRGB(hulk_color_mod)
stand_icon.MapColors(rgb(TONE[1],0,0),rgb(0,TONE[2],0),rgb(0,0,TONE[3]))
var/datum/organ/external/head = get_organ("head")
var/g = (gender == FEMALE ? "f" : "m")
var/has_head = 0
if(head && !(head.status & ORGAN_DESTROYED))
has_head = 1
//CACHING: Generate an index key from visible bodyparts.
//0 = destroyed, 1 = normal, 2 = robotic, 3 = necrotic.
//Create a new, blank icon for our mob to use.
if(stand_icon)
del(stand_icon)
stand_icon = new(species.icon_template ? species.icon_template : 'icons/mob/human.dmi',"blank")
var/icon_key = "[species.race_key][g][s_tone]"
for(var/datum/organ/external/part in organs)
if(!istype(part, /datum/organ/external/chest) && !(part.status & ORGAN_DESTROYED))
var/icon/temp
if(istype(part,/datum/organ/external/head) && !(part.status & ORGAN_DESTROYED))
has_head = 1
if(part.status & ORGAN_DESTROYED)
icon_key = "[icon_key]0"
else if(part.status & ORGAN_ROBOT)
icon_key = "[icon_key]2"
else if(part.status & ORGAN_DEAD) //Do we even have necrosis in our current code? ~Z
icon_key = "[icon_key]3"
else
icon_key = "[icon_key]1"
icon_key = "[icon_key][husk ? 1 : 0][fat ? 1 : 0][hulk ? 1 : 0][skeleton ? 1 : 0][s_tone]"
var/icon/base_icon
if(human_icon_cache[icon_key])
//Icon is cached, use existing icon.
base_icon = human_icon_cache[icon_key]
//log_debug("Retrieved cached mob icon ([icon_key] \icon[human_icon_cache[icon_key]]) for [src].")
else
//BEGIN CACHED ICON GENERATION.
//Icon is not cached, generate and store it.
//Robotic limbs are handled in get_icon() so all we worry about are missing or dead limbs.
//No icon stored, so we need to start with a basic one.
var/datum/organ/external/chest = get_organ("chest")
base_icon = chest.get_icon(g)
for(var/datum/organ/external/part in organs)
var/icon/temp //Hold the bodypart icon for processing.
if(part.status & ORGAN_DESTROYED)
continue
if (istype(part, /datum/organ/external/groin) || istype(part, /datum/organ/external/head))
temp = part.get_icon(g)
else
@@ -253,46 +291,70 @@ proc/get_damage_icon_part(damage_state, body_part)
temp.ColorTone(necrosis_color_mod)
temp.SetIntensity(0.7)
else if(!skeleton)
if(husk)
temp.ColorTone(husk_color_mod)
else if(hulk)
var/list/TONE = ReadRGB(hulk_color_mod)
temp.MapColors(rgb(TONE[1],0,0),rgb(0,TONE[2],0),rgb(0,0,TONE[3]))
//That part makes left and right legs drawn topmost and lowermost when human looks WEST or EAST
//And no change in rendering for other parts (they icon_position is 0, so goes to 'else' part)
if(part.icon_position&(LEFT|RIGHT))
var/icon/temp2 = new('icons/mob/human.dmi',"blank")
temp2.Insert(new/icon(temp,dir=NORTH),dir=NORTH)
temp2.Insert(new/icon(temp,dir=SOUTH),dir=SOUTH)
if(!(part.icon_position & LEFT))
temp2.Insert(new/icon(temp,dir=EAST),dir=EAST)
if(!(part.icon_position & RIGHT))
temp2.Insert(new/icon(temp,dir=WEST),dir=WEST)
stand_icon.Blend(temp2, ICON_OVERLAY)
temp2 = new('icons/mob/human.dmi',"blank")
base_icon.Blend(temp2, ICON_OVERLAY)
if(part.icon_position & LEFT)
temp2.Insert(new/icon(temp,dir=EAST),dir=EAST)
if(part.icon_position & RIGHT)
temp2.Insert(new/icon(temp,dir=WEST),dir=WEST)
stand_icon.Blend(temp2, ICON_UNDERLAY)
base_icon.Blend(temp2, ICON_UNDERLAY)
else
stand_icon.Blend(temp, ICON_OVERLAY)
//Skin tone
if(!skeleton && !husk && !hulk && (species.flags & HAS_SKIN_TONE))
if(s_tone >= 0)
stand_icon.Blend(rgb(s_tone, s_tone, s_tone), ICON_ADD)
else
stand_icon.Blend(rgb(-s_tone, -s_tone, -s_tone), ICON_SUBTRACT)
base_icon.Blend(temp, ICON_OVERLAY)
if(husk)
var/icon/mask = new(stand_icon)
var/icon/husk_over = new(race_icon,"overlay_husk")
mask.MapColors(0,0,0,1, 0,0,0,1, 0,0,0,1, 0,0,0,1, 0,0,0,0)
husk_over.Blend(mask, ICON_ADD)
stand_icon.Blend(husk_over, ICON_OVERLAY)
if(!skeleton)
if(husk)
base_icon.ColorTone(husk_color_mod)
else if(hulk)
var/list/tone = ReadRGB(hulk_color_mod)
base_icon.MapColors(rgb(tone[1],0,0),rgb(0,tone[2],0),rgb(0,0,tone[3]))
//Handle husk overlay.
if(husk)
var/icon/mask = new(base_icon)
var/icon/husk_over = new(race_icon,"overlay_husk")
mask.MapColors(0,0,0,1, 0,0,0,1, 0,0,0,1, 0,0,0,1, 0,0,0,0)
husk_over.Blend(mask, ICON_ADD)
base_icon.Blend(husk_over, ICON_OVERLAY)
//Skin tone.
if(!husk && !hulk)
if(species.flags & HAS_SKIN_TONE)
if(s_tone >= 0)
base_icon.Blend(rgb(s_tone, s_tone, s_tone), ICON_ADD)
else
base_icon.Blend(rgb(-s_tone, -s_tone, -s_tone), ICON_SUBTRACT)
human_icon_cache[icon_key] = base_icon
//log_debug("Generated new cached mob icon ([icon_key] \icon[human_icon_cache[icon_key]]) for [src]. [human_icon_cache.len] cached mob icons.")
//END CACHED ICON GENERATION.
stand_icon.Blend(base_icon,ICON_OVERLAY)
//Skin colour. Not in cache because highly variable (and relatively benign).
if (species.flags & HAS_SKIN_COLOR)
stand_icon.Blend(rgb(r_skin, g_skin, b_skin), ICON_ADD)
if(has_head)
//Eyes
@@ -310,6 +372,9 @@ proc/get_damage_icon_part(damage_state, body_part)
if(!fat && !skeleton)
stand_icon.Blend(new /icon('icons/mob/human.dmi', "underwear[underwear]_[g]_s"), ICON_OVERLAY)
if(undershirt>0 && undershirt < 5 && species.flags & HAS_UNDERWEAR)
stand_icon.Blend(new /icon('icons/mob/human.dmi', "undershirt[undershirt]_s"), ICON_OVERLAY)
if(update_icons)
update_icons()
@@ -317,6 +382,8 @@ proc/get_damage_icon_part(damage_state, body_part)
update_tail_showing(0)
//HAIR OVERLAY
/mob/living/carbon/human/proc/update_hair(var/update_icons=1)
//Reset our hair
@@ -479,7 +546,7 @@ proc/get_damage_icon_part(damage_state, body_part)
if(!t_color) t_color = icon_state
var/image/standing = image("icon_state" = "[t_color]_s")
standing.icon = ((w_uniform.icon_override) ? w_uniform.icon_override : 'icons/mob/uniform.dmi')
standing.icon = ((w_uniform.icon_override) ? w_uniform.icon_override : (species.sprite_sheets["uniform"] ? species.sprite_sheets["uniform"] : 'icons/mob/uniform.dmi'))
if(w_uniform.blood_DNA)
var/image/bloodsies = image("icon" = 'icons/effects/blood.dmi', "icon_state" = "uniformblood")
@@ -494,6 +561,7 @@ proc/get_damage_icon_part(damage_state, body_part)
overlays_standing[UNIFORM_LAYER] = standing
else
overlays_standing[UNIFORM_LAYER] = null
// This really, really seems like it should not be mixed in the middle of display code...
// Automatically drop anything in store / id / belt if you're not wearing a uniform. //CHECK IF NECESARRY
for( var/obj/item/thing in list(r_store, l_store, wear_id, belt) ) //
if(thing) //
@@ -526,7 +594,7 @@ proc/get_damage_icon_part(damage_state, body_part)
if(gloves)
var/t_state = gloves.item_state
if(!t_state) t_state = gloves.icon_state
var/image/standing = image("icon" = ((gloves.icon_override) ? gloves.icon_override : 'icons/mob/hands.dmi'), "icon_state" = "[t_state]")
var/image/standing = image("icon" = ((gloves.icon_override) ? gloves.icon_override : (species.sprite_sheets["gloves"] ? species.sprite_sheets["gloves"] : 'icons/mob/hands.dmi')), "icon_state" = "[t_state]")
if(gloves.blood_DNA)
var/image/bloodsies = image("icon" = 'icons/effects/blood.dmi', "icon_state" = "bloodyhands")
bloodsies.color = gloves.blood_color
@@ -545,7 +613,7 @@ proc/get_damage_icon_part(damage_state, body_part)
/mob/living/carbon/human/update_inv_glasses(var/update_icons=1)
if(glasses)
overlays_standing[GLASSES_LAYER] = image("icon" = ((glasses.icon_override) ? glasses.icon_override : 'icons/mob/eyes.dmi'), "icon_state" = "[glasses.icon_state]")
overlays_standing[GLASSES_LAYER] = image("icon" = ((glasses.icon_override) ? glasses.icon_override : (species.sprite_sheets["eyes"] ? species.sprite_sheets["eyes"] : 'icons/mob/eyes.dmi')), "icon_state" = "[glasses.icon_state]")
else
overlays_standing[GLASSES_LAYER] = null
if(update_icons) update_icons()
@@ -553,16 +621,20 @@ proc/get_damage_icon_part(damage_state, body_part)
/mob/living/carbon/human/update_inv_ears(var/update_icons=1)
if(l_ear || r_ear)
if(l_ear)
overlays_standing[EARS_LAYER] = image("icon" = ((l_ear.icon_override) ? l_ear.icon_override : 'icons/mob/ears.dmi'), "icon_state" = "[l_ear.icon_state]")
var/t_type = l_ear.icon_state
if(l_ear.icon_override || species.sprite_sheets["ears"]) t_type = "[t_type]_l"
overlays_standing[EARS_LAYER] = image("icon" = ((l_ear.icon_override) ? l_ear.icon_override : (species.sprite_sheets["ears"] ? species.sprite_sheets["ears"] : 'icons/mob/ears.dmi')), "icon_state" = "[t_type]")
if(r_ear)
overlays_standing[EARS_LAYER] = image("icon" = ((r_ear.icon_override) ? r_ear.icon_override : 'icons/mob/ears.dmi'), "icon_state" = "[r_ear.icon_state]")
var/t_type = r_ear.icon_state
if(r_ear.icon_override || species.sprite_sheets["ears"]) t_type = "[t_type]_r"
overlays_standing[EARS_LAYER] = image("icon" = ((r_ear.icon_override) ? r_ear.icon_override : (species.sprite_sheets["ears"] ? species.sprite_sheets["ears"] : 'icons/mob/ears.dmi')), "icon_state" = "t_type]")
else
overlays_standing[EARS_LAYER] = null
if(update_icons) update_icons()
/mob/living/carbon/human/update_inv_shoes(var/update_icons=1)
if(shoes)
var/image/standing = image("icon" = ((shoes.icon_override) ? shoes.icon_override : 'icons/mob/feet.dmi'), "icon_state" = "[shoes.icon_state]")
var/image/standing = image("icon" = ((shoes.icon_override) ? shoes.icon_override : (species.sprite_sheets["feet"] ? species.sprite_sheets["feet"] : 'icons/mob/feet.dmi')), "icon_state" = "[shoes.icon_state]")
if(shoes.blood_DNA)
var/image/bloodsies = image("icon" = 'icons/effects/blood.dmi', "icon_state" = "shoeblood")
bloodsies.color = shoes.blood_color
@@ -595,7 +667,7 @@ proc/get_damage_icon_part(damage_state, body_part)
if(istype(head,/obj/item/clothing/head/kitty))
standing = image("icon" = head:mob)
else
standing = image("icon" = ((head.icon_override) ? head.icon_override : 'icons/mob/head.dmi'), "icon_state" = "[head.icon_state]")
standing = image("icon" = ((head.icon_override) ? head.icon_override : (species.sprite_sheets["head"] ? species.sprite_sheets["head"] : 'icons/mob/head.dmi')), "icon_state" = "[head.icon_state]")
if(head.blood_DNA)
var/image/bloodsies = image("icon" = 'icons/effects/blood.dmi', "icon_state" = "helmetblood")
bloodsies.color = head.blood_color
@@ -610,7 +682,7 @@ proc/get_damage_icon_part(damage_state, body_part)
belt.screen_loc = ui_belt //TODO
var/t_state = belt.item_state
if(!t_state) t_state = belt.icon_state
overlays_standing[BELT_LAYER] = image("icon" = ((belt.icon_override) ? belt.icon_override : 'icons/mob/belt.dmi'), "icon_state" = "[t_state]")
overlays_standing[BELT_LAYER] = image("icon" = ((belt.icon_override) ? belt.icon_override : (species.sprite_sheets["belt"] ? species.sprite_sheets["belt"] : 'icons/mob/belt.dmi')), "icon_state" = "[t_state]")
else
overlays_standing[BELT_LAYER] = null
if(update_icons) update_icons()
@@ -619,7 +691,7 @@ proc/get_damage_icon_part(damage_state, body_part)
/mob/living/carbon/human/update_inv_wear_suit(var/update_icons=1)
if( wear_suit && istype(wear_suit, /obj/item/clothing/suit) ) //TODO check this
wear_suit.screen_loc = ui_oclothing //TODO
var/image/standing = image("icon" = ((wear_suit.icon_override) ? wear_suit.icon_override : 'icons/mob/suit.dmi'), "icon_state" = "[wear_suit.icon_state]")
var/image/standing = image("icon" = ((wear_suit.icon_override) ? wear_suit.icon_override : (species.sprite_sheets["suit"] ? species.sprite_sheets["suit"] : 'icons/mob/suit.dmi')), "icon_state" = "[wear_suit.icon_state]")
if( istype(wear_suit, /obj/item/clothing/suit/straight_jacket) )
drop_from_inventory(handcuffed)
@@ -654,7 +726,7 @@ proc/get_damage_icon_part(damage_state, body_part)
/mob/living/carbon/human/update_inv_wear_mask(var/update_icons=1)
if( wear_mask && ( istype(wear_mask, /obj/item/clothing/mask) || istype(wear_mask, /obj/item/clothing/tie) ) )
wear_mask.screen_loc = ui_mask //TODO
var/image/standing = image("icon" = ((wear_mask.icon_override) ? wear_mask.icon_override : 'icons/mob/mask.dmi'), "icon_state" = "[wear_mask.icon_state]")
var/image/standing = image("icon" = ((wear_mask.icon_override) ? wear_mask.icon_override : (species.sprite_sheets["mask"] ? species.sprite_sheets["mask"] : 'icons/mob/mask.dmi')), "icon_state" = "[wear_mask.icon_state]")
if( !istype(wear_mask, /obj/item/clothing/mask/cigarette) && wear_mask.blood_DNA )
var/image/bloodsies = image("icon" = 'icons/effects/blood.dmi', "icon_state" = "maskblood")
bloodsies.color = wear_mask.blood_color
@@ -668,7 +740,7 @@ proc/get_damage_icon_part(damage_state, body_part)
/mob/living/carbon/human/update_inv_back(var/update_icons=1)
if(back)
back.screen_loc = ui_back //TODO
overlays_standing[BACK_LAYER] = image("icon" = ((back.icon_override) ? back.icon_override : 'icons/mob/back.dmi'), "icon_state" = "[back.icon_state]")
overlays_standing[BACK_LAYER] = image("icon" = ((back.icon_override) ? back.icon_override : (species.sprite_sheets["back"] ? species.sprite_sheets["back"] : 'icons/mob/back.dmi')), "icon_state" = "[back.icon_state]")
else
overlays_standing[BACK_LAYER] = null
if(update_icons) update_icons()
@@ -709,7 +781,8 @@ proc/get_damage_icon_part(damage_state, body_part)
r_hand.screen_loc = ui_rhand //TODO
var/t_state = r_hand.item_state
if(!t_state) t_state = r_hand.icon_state
overlays_standing[R_HAND_LAYER] = image("icon" = 'icons/mob/items_righthand.dmi', "icon_state" = "[t_state]")
if(r_hand.icon_override || species.sprite_sheets["held"]) t_state = "[t_state]_r"
overlays_standing[R_HAND_LAYER] = image("icon" = ((r_hand.icon_override) ? r_hand.icon_override : (species.sprite_sheets["held"] ? species.sprite_sheets["held"] : 'icons/mob/items_righthand.dmi')), "icon_state" = "[t_state]")
if (handcuffed) drop_r_hand()
else
overlays_standing[R_HAND_LAYER] = null
@@ -721,7 +794,8 @@ proc/get_damage_icon_part(damage_state, body_part)
l_hand.screen_loc = ui_lhand //TODO
var/t_state = l_hand.item_state
if(!t_state) t_state = l_hand.icon_state
overlays_standing[L_HAND_LAYER] = image("icon" = 'icons/mob/items_lefthand.dmi', "icon_state" = "[t_state]")
if(l_hand.icon_override || species.sprite_sheets["held"]) t_state = "[t_state]_l"
overlays_standing[L_HAND_LAYER] = image("icon" = ((l_hand.icon_override) ? l_hand.icon_override : (species.sprite_sheets["held"] ? species.sprite_sheets["held"] : 'icons/mob/items_lefthand.dmi')), "icon_state" = "[t_state]")
if (handcuffed) drop_l_hand()
else
overlays_standing[L_HAND_LAYER] = null
@@ -731,8 +805,11 @@ proc/get_damage_icon_part(damage_state, body_part)
overlays_standing[TAIL_LAYER] = null
if(species.tail && species.flags & HAS_TAIL)
if(!wear_suit || !(wear_suit.flags_inv & HIDEJUMPSUIT) && !istype(wear_suit, /obj/item/clothing/suit/space))
overlays_standing[TAIL_LAYER] = image("icon" = 'icons/effects/species.dmi', "icon_state" = "[species.tail]_s")
if(!wear_suit || !(wear_suit.flags_inv & HIDETAIL) && !istype(wear_suit, /obj/item/clothing/suit/space))
var/icon/tail_s = new/icon("icon" = 'icons/effects/species.dmi', "icon_state" = "[species.tail]_s")
tail_s.Blend(rgb(r_skin, g_skin, b_skin), ICON_ADD)
overlays_standing[TAIL_LAYER] = image(tail_s)
if(update_icons)
update_icons()
@@ -793,6 +870,7 @@ proc/get_damage_icon_part(damage_state, body_part)
#undef MUTATIONS_LAYER
#undef DAMAGE_LAYER
#undef UNIFORM_LAYER
#undef TAIL_LAYER
#undef ID_LAYER
#undef SHOES_LAYER
#undef GLOVES_LAYER
@@ -810,6 +888,5 @@ proc/get_damage_icon_part(damage_state, body_part)
#undef LEGCUFF_LAYER
#undef L_HAND_LAYER
#undef R_HAND_LAYER
#undef TAIL_LAYER
#undef TARGETED_LAYER
#undef TOTAL_LAYERS
+61 -40
View File
@@ -2,45 +2,6 @@
Tiny babby plant critter plus procs.
*/
//Helper object for picking dionaea (and other creatures) up.
/obj/item/weapon/holder
name = "holder"
desc = "You shouldn't ever see this."
/obj/item/weapon/holder/diona
name = "diona nymph"
desc = "It's a tiny plant critter."
icon = 'icons/obj/objects.dmi'
icon_state = "nymph"
slot_flags = SLOT_HEAD
origin_tech = "magnets=3;biotech=5"
/obj/item/weapon/holder/New()
..()
processing_objects.Add(src)
/obj/item/weapon/holder/Del()
//Hopefully this will stop the icon from remaining on human mobs.
if(istype(loc,/mob/living))
var/mob/living/A = src.loc
src.loc = null
A.update_icons()
processing_objects.Remove(src)
..()
/obj/item/weapon/holder/process()
if(!loc) del(src)
if(istype(loc,/turf) || !(contents.len))
for(var/mob/M in contents)
M.loc = get_turf(src)
del(src)
/obj/item/weapon/holder/attackby(obj/item/weapon/W as obj, mob/user as mob)
for(var/mob/M in src.contents)
M.attackby(W,user)
//Mob defines.
/mob/living/carbon/monkey/diona
name = "diona nymph"
@@ -67,6 +28,7 @@
D.attack_hand(M)
M << "You scoop up [src]."
src << "[M] scoops you up."
M.status_flags |= PASSEMOTES
return
..()
@@ -108,6 +70,8 @@
if(istype(M,/mob/living/carbon/human))
M << "You feel your being twine with that of [src] as it merges with your biomass."
M.status_flags |= PASSEMOTES
src << "You feel your being twine with that of [M] as you merge with its biomass."
src.loc = M
src.verbs += /mob/living/carbon/monkey/diona/proc/split
@@ -127,10 +91,19 @@
src.loc << "You feel a pang of loss as [src] splits away from your biomass."
src << "You wiggle out of the depths of [src.loc]'s biomass and plop to the ground."
var/mob/living/M = src.loc
src.loc = get_turf(src)
src.verbs -= /mob/living/carbon/monkey/diona/proc/split
src.verbs += /mob/living/carbon/monkey/diona/proc/merge
if(istype(M))
for(var/atom/A in M.contents)
if(istype(A,/mob/living/simple_animal/borer) || istype(A,/obj/item/weapon/holder))
return
M.status_flags &= ~PASSEMOTES
/mob/living/carbon/monkey/diona/verb/fertilize_plant()
set category = "Diona"
@@ -188,7 +161,7 @@
return
src.split()
src.visible_message("\red [src] begins to shift and quiver, and erupts in a shower of shed bark and twigs!","\red You begin to shift and quiver, then erupt in a shower of shed bark and twigs, attaining your adult form!")
src.visible_message("\red [src] begins to shift and quiver, and erupts in a shower of shed bark as it splits into a tangle of nearly a dozen new dionaea.","\red You begin to shift and quiver, feeling your awareness splinter. All at once, we consume our stored nutrients to surge with growth, splitting into a tangle of at least a dozen new dionaea. We have attained our gestalt form.")
var/mob/living/carbon/human/adult = new(get_turf(src.loc))
adult.set_species("Diona")
@@ -252,3 +225,51 @@
src << "\green You feel your awareness expand, and realize you know how to understand the creatures around you."
else
src << "\green The blood seeps into your small form, and you draw out the echoes of memories and personality from it, working them into your budding mind."
/mob/living/carbon/monkey/diona/say_understands(var/mob/other,var/datum/language/speaking = null)
if (istype(other, /mob/living/carbon/human) && !speaking)
if(languages.len >= 2) // They have sucked down some blood.
return 1
return ..()
/mob/living/carbon/monkey/diona/say(var/message)
var/verb = "says"
var/message_range = world.view
if(client)
if(client.prefs.muted & MUTE_IC)
src << "\red You cannot speak in IC (Muted)."
return
message = trim(copytext(sanitize(message), 1, MAX_MESSAGE_LEN))
if(stat == 2)
return say_dead(message)
var/datum/language/speaking = null
if(length(message) >= 2)
var/channel_prefix = copytext(message, 1 ,3)
if(languages.len)
for(var/datum/language/L in languages)
if(lowertext(channel_prefix) == ":[L.key]")
verb = L.speech_verb
speaking = L
break
if(speaking)
message = trim(copytext(message,3))
message = capitalize(trim_left(message))
if(!message || stat)
return
..(message, speaking, verb, null, null, message_range, null)
+10 -1
View File
@@ -31,6 +31,11 @@
if ("custom")
return custom_emote(m_type, message)
if ("chirp")
if(istype(src,/mob/living/carbon/monkey/diona))
message = "<B>The [src.name]</B> chirps!"
playsound(src.loc, 'sound/misc/nymphchirp.ogg', 50, 0)
m_type = 2
if("sign")
if (!src.restrained())
message = text("<B>The monkey</B> signs[].", (text2num(param) ? text(" the number []", text2num(param)) : null))
@@ -114,7 +119,11 @@
message = "<b>The [src.name]</b> lets out a faint chimper as it collapses and stops moving..."
m_type = 1
if("help")
src << "choke, collapse, dance, deathgasp, drool, gasp, shiver, gnarl, jump, paw, moan, nod, roar, roll, scratch,\nscretch, shake, sign-#, sit, sulk, sway, tail, twitch, whimper"
var/text = "choke, "
if(istype(src,/mob/living/carbon/monkey/diona))
text += "chirp, "
text += "collapse, dance, deathgasp, drool, gasp, shiver, gnarl, jump, paw, moan, nod, roar, roll, scratch,\nscretch, shake, sign-#, sit, sulk, sway, tail, twitch, whimper"
src << text
else
src << text("Invalid Emote: []", act)
if ((message && src.stat == 0))
+17 -11
View File
@@ -22,7 +22,7 @@
if(loc)
environment = loc.return_air()
if (stat != DEAD)
if (stat != DEAD)
if(!istype(src,/mob/living/carbon/monkey/diona)) //still breathing
//First, resolve location and get a breath
if(air_master.current_cycle%4==2)
@@ -79,7 +79,7 @@
if(prob(1))
emote(pick("scratch","jump","roll","tail"))
updatehealth()
/mob/living/carbon/monkey/calculate_affecting_pressure(var/pressure)
..()
@@ -174,9 +174,9 @@
for (var/ID in virus2)
var/datum/disease2/disease/V = virus2[ID]
V.cure(src)
for(var/obj/effect/decal/cleanable/O in view(1,src))
if(istype(O,/obj/effect/decal/cleanable/blood))
if(istype(O,/obj/effect/decal/cleanable/blood))
var/obj/effect/decal/cleanable/blood/B = O
if(B.virus2.len)
for (var/ID in B.virus2)
@@ -397,9 +397,18 @@
if(!environment)
return
if(abs(environment.temperature - 293.15) < 20 && abs(bodytemperature - 310.14) < 0.5 && environment.toxins < MOLES_PLASMA_VISIBLE)
return // Temperatures are within normal ranges, fuck all this processing. ~Ccomp
//Moved these vars here for use in the fuck-it-skip-processing check.
var/pressure = environment.return_pressure()
var/adjusted_pressure = calculate_affecting_pressure(pressure) //Returns how much pressure actually affects the mob.
if(adjusted_pressure < WARNING_HIGH_PRESSURE && adjusted_pressure > WARNING_LOW_PRESSURE && abs(environment.temperature - 293.15) < 20 && abs(bodytemperature - 310.14) < 0.5 && environment.toxins < MOLES_PLASMA_VISIBLE)
//Hopefully should fix the walk-inside-still-pressure-warning issue.
if(pressure_alert)
pressure_alert = 0
return // Temperatures are within normal ranges, fuck all this processing. ~Ccomp
var/environment_heat_capacity = environment.heat_capacity()
if(istype(get_turf(src), /turf/space))
var/turf/heat_turf = get_turf(src)
@@ -414,9 +423,6 @@
bodytemperature += 0.1*(environment.temperature - bodytemperature)*environment_heat_capacity/(environment_heat_capacity + 270000)
//Account for massive pressure differences
var/pressure = environment.return_pressure()
var/adjusted_pressure = calculate_affecting_pressure(pressure) //Returns how much pressure actually affects the mob.
switch(adjusted_pressure)
if(HAZARD_HIGH_PRESSURE to INFINITY)
adjustBruteLoss( min( ( (adjusted_pressure / HAZARD_HIGH_PRESSURE) -1 )*PRESSURE_DAMAGE_COEFFICIENT , MAX_HIGH_PRESSURE_DAMAGE) )
@@ -468,7 +474,7 @@
adjustToxLoss(-1)
adjustOxyLoss(-1)
if(reagents && reagents.reagent_list.len)
if(reagents && reagents.reagent_list.len)
reagents.metabolize(src,alien)
if (drowsyness)
@@ -513,7 +513,21 @@
/mob/living/carbon/monkey/IsAdvancedToolUser()//Unless its monkey mode monkeys cant use advanced tools
if(!ticker) return 0
if(!ticker.mode.name == "monkey") return 0
return 1
return 0
/mob/living/carbon/monkey/say(var/message, var/datum/language/speaking = null, var/verb="says", var/alt_name="", var/italics=0, var/message_range = world.view, var/list/used_radios = list())
if(stat)
return
if(copytext(message,1,2) == "*")
return emote(copytext(message,2))
if(stat)
return
if(speak_emote.len)
verb = pick(speak_emote)
message = capitalize(trim_left(message))
..(message, speaking, verb, alt_name, italics, message_range, used_radios)
+127 -9
View File
@@ -17,6 +17,8 @@
var/mutantrace // Safeguard due to old code.
var/breath_type = "oxygen" // Non-oxygen gas breathed, if any.
var/poison_type = "plasma" // Poisonous air.
var/exhale_type = "C02" // Exhaled gas type.
var/cold_level_1 = 260 // Cold damage level 1 below this point.
var/cold_level_2 = 200 // Cold damage level 2 below this point.
@@ -42,19 +44,72 @@
var/blood_color = "#A10808" //Red.
var/flesh_color = "#FFC896" //Pink.
/datum/species/proc/handle_post_spawn(var/mob/living/carbon/human/H) //Handles anything not already covered by basic species assignment.
//Used in icon caching.
var/race_key = 0
var/icon/icon_template
/* Species-specific sprites, concept stolen from Paradise//vg/.
ex:
sprite_sheets = list(
"held" = 'icons/mob/path',
"uniform" = 'icons/mob/path',
"suit" = 'icons/mob/path',
"belt" = 'icons/mob/path'
"head" = 'icons/mob/path',
"back" = 'icons/mob/path',
"mask" = 'icons/mob/path',
"ears" = 'icons/mob/path',
"eyes" = 'icons/mob/path',
"feet" = 'icons/mob/path',
"gloves" = 'icons/mob/path'
)
If index term exists and icon_override is not set, this sprite sheet will be used.
*/
var/list/sprite_sheets = list()
/datum/species/proc/create_organs(var/mob/living/carbon/human/H) //Handles creation of mob organs.
//This is a basic humanoid limb setup.
H.organs = list()
H.organs_by_name["chest"] = new/datum/organ/external/chest()
H.organs_by_name["groin"] = new/datum/organ/external/groin(H.organs_by_name["chest"])
H.organs_by_name["head"] = new/datum/organ/external/head(H.organs_by_name["chest"])
H.organs_by_name["l_arm"] = new/datum/organ/external/l_arm(H.organs_by_name["chest"])
H.organs_by_name["r_arm"] = new/datum/organ/external/r_arm(H.organs_by_name["chest"])
H.organs_by_name["r_leg"] = new/datum/organ/external/r_leg(H.organs_by_name["groin"])
H.organs_by_name["l_leg"] = new/datum/organ/external/l_leg(H.organs_by_name["groin"])
H.organs_by_name["l_hand"] = new/datum/organ/external/l_hand(H.organs_by_name["l_arm"])
H.organs_by_name["r_hand"] = new/datum/organ/external/r_hand(H.organs_by_name["r_arm"])
H.organs_by_name["l_foot"] = new/datum/organ/external/l_foot(H.organs_by_name["l_leg"])
H.organs_by_name["r_foot"] = new/datum/organ/external/r_foot(H.organs_by_name["r_leg"])
H.internal_organs = list()
H.internal_organs_by_name["heart"] = new/datum/organ/internal/heart(H)
H.internal_organs_by_name["lungs"] = new/datum/organ/internal/lungs(H)
H.internal_organs_by_name["liver"] = new/datum/organ/internal/liver(H)
H.internal_organs_by_name["kidney"] = new/datum/organ/internal/kidney(H)
H.internal_organs_by_name["brain"] = new/datum/organ/internal/brain(H)
H.internal_organs_by_name["eyes"] = new/datum/organ/internal/eyes(H)
for(var/name in H.organs_by_name)
H.organs += H.organs_by_name[name]
for(var/datum/organ/external/O in H.organs)
O.owner = H
if(flags & IS_SYNTHETIC)
for(var/datum/organ/external/E in H.organs)
if(E.status & ORGAN_CUT_AWAY || E.status & ORGAN_DESTROYED) continue
E.status |= ORGAN_ROBOT
for(var/datum/organ/internal/I in H.internal_organs)
I.robotic = 2
I.mechanize()
/datum/species/proc/handle_post_spawn(var/mob/living/carbon/human/H) //Handles anything not already covered by basic species assignment.
return
/datum/species/proc/handle_death(var/mob/living/carbon/human/H) //Handles any species-specific death events (such as dionaea nymph spawns).
if(flags & IS_SYNTHETIC)
//H.make_jittery(200) //S-s-s-s-sytem f-f-ai-i-i-i-i-lure-ure-ure-ure
//H.make_jittery(200) //S-s-s-s-sytem f-f-ai-i-i-i-i-lure-ure-ure-ure
H.h_style = ""
spawn(100)
//H.is_jittery = 0
@@ -91,7 +146,7 @@
heat_level_2 = 480 //Default 400
heat_level_3 = 1100 //Default 1000
flags = IS_WHITELISTED | HAS_LIPS | HAS_UNDERWEAR | HAS_TAIL
flags = IS_WHITELISTED | HAS_LIPS | HAS_UNDERWEAR | HAS_TAIL | HAS_SKIN_COLOR
flesh_color = "#34AF10"
@@ -115,7 +170,7 @@
primitive = /mob/living/carbon/monkey/tajara
flags = IS_WHITELISTED | HAS_LIPS | HAS_UNDERWEAR | HAS_TAIL
flags = IS_WHITELISTED | HAS_LIPS | HAS_UNDERWEAR | HAS_TAIL | HAS_SKIN_COLOR
flesh_color = "#AFA59E"
@@ -126,7 +181,7 @@
language = "Skrellian"
primitive = /mob/living/carbon/monkey/skrell
flags = IS_WHITELISTED | HAS_LIPS | HAS_UNDERWEAR
flags = IS_WHITELISTED | HAS_LIPS | HAS_UNDERWEAR | HAS_SKIN_COLOR
flesh_color = "#8CD7A3"
@@ -144,15 +199,79 @@
cold_level_3 = 0
eyes = "vox_eyes_s"
breath_type = "nitrogen"
poison_type = "oxygen"
flags = NO_SCAN | NO_BLOOD
blood_color = "#2299FC"
flesh_color = "#808D11"
sprite_sheets = list(
"suit" = 'icons/mob/species/vox/suit.dmi',
"head" = 'icons/mob/species/vox/head.dmi',
"mask" = 'icons/mob/species/vox/mask.dmi',
"feet" = 'icons/mob/species/vox/feet.dmi',
"gloves" = 'icons/mob/species/vox/gloves.dmi'
)
/datum/species/vox/handle_post_spawn(var/mob/living/carbon/human/H)
H.verbs += /mob/living/carbon/human/proc/leap
..()
/datum/species/vox/armalis/handle_post_spawn(var/mob/living/carbon/human/H)
H.verbs += /mob/living/carbon/human/proc/gut
..()
/datum/species/vox/armalis
name = "Vox Armalis"
icobase = 'icons/mob/human_races/r_armalis.dmi'
deform = 'icons/mob/human_races/r_armalis.dmi'
language = "Vox-pidgin"
attack_verb = "slash"
warning_low_pressure = 50
hazard_low_pressure = 0
cold_level_1 = 80
cold_level_2 = 50
cold_level_3 = 0
heat_level_1 = 2000
heat_level_2 = 3000
heat_level_3 = 4000
brute_mod = 0.2
burn_mod = 0.2
eyes = "blank_eyes"
breath_type = "nitrogen"
poison_type = "oxygen"
flags = NO_SCAN | NO_BLOOD | HAS_TAIL | NO_PAIN | IS_WHITELISTED
blood_color = "#2299FC"
flesh_color = "#808D11"
tail = "armalis_tail"
icon_template = 'icons/mob/human_races/r_armalis.dmi'
sprite_sheets = list(
"suit" = 'icons/mob/species/armalis/suit.dmi',
"gloves" = 'icons/mob/species/armalis/gloves.dmi',
"feet" = 'icons/mob/species/armalis/feet.dmi',
"head" = 'icons/mob/species/armalis/head.dmi',
"held" = 'icons/mob/species/armalis/held.dmi'
)
/datum/species/vox/create_organs(var/mob/living/carbon/human/H)
..() //create organs first.
//Now apply cortical stack.
var/datum/organ/external/affected = H.get_organ("head")
//To avoid duplicates.
@@ -171,8 +290,6 @@
M.cortical_stacks += I
M.raiders[H.mind] = I
return ..()
/datum/species/diona
name = "Diona"
icobase = 'icons/mob/human_races/r_diona.dmi'
@@ -199,9 +316,10 @@
flesh_color = "#907E4A"
/datum/species/diona/handle_post_spawn(var/mob/living/carbon/human/H)
H.gender = NEUTER
return ..()
/datum/species/diona/handle_death(var/mob/living/carbon/human/H)
var/mob/living/carbon/monkey/diona/S = new(get_turf(H))
+30 -9
View File
@@ -211,6 +211,9 @@
O.emp_act(severity)
..()
/mob/living/proc/can_inject()
return 1
/mob/living/proc/get_organ_target()
var/mob/shooter = src
var/t = shooter:zone_sel.selecting
@@ -312,7 +315,7 @@
// make the icons look correct
regenerate_icons()
hud_updateflag |= 1 << HEALTH_HUD
hud_updateflag |= 1 << STATUS_HUD
return
@@ -447,9 +450,23 @@
//Getting out of someone's inventory.
if(istype(src.loc,/obj/item/weapon/holder))
var/obj/item/weapon/holder/H = src.loc
src.loc = get_turf(src.loc)
del(H)
var/obj/item/weapon/holder/H = src.loc //Get our item holder.
var/mob/M = H.loc //Get our mob holder (if any).
if(istype(M))
M.drop_from_inventory(H)
M << "[H] wriggles out of your grip!"
src << "You wriggle out of [M]'s grip!"
else if(istype(H.loc,/obj/item))
src << "You struggle free of [H.loc]."
H.loc = get_turf(H)
if(istype(M))
for(var/atom/A in M.contents)
if(istype(A,/mob/living/simple_animal/borer) || istype(A,/obj/item/weapon/holder))
return
M.status_flags &= ~PASSEMOTES
return
//Resisting control by an alien mind.
@@ -582,6 +599,7 @@
sleep(10)
SC.broken = 1
SC.locked = 0
SC.update_icon()
usr << "\red You successfully break out!"
for(var/mob/O in viewers(L.loc))
O.show_message("\red <B>\the [usr] successfully broke out of \the [SC]!</B>", 1)
@@ -591,6 +609,7 @@
SC.open()
else
C.welded = 0
C.update_icon()
usr << "\red You successfully break out!"
for(var/mob/O in viewers(L.loc))
O.show_message("\red <B>\the [usr] successfully broke out of \the [C]!</B>", 1)
@@ -685,7 +704,7 @@
resting = !resting
src << "\blue You are now [resting ? "resting" : "getting up"]"
/mob/living/proc/handle_ventcrawl(var/obj/machinery/atmospherics/unary/vent_pump/vent_found = null) // -- TLE -- Merged by Carn
/mob/living/proc/handle_ventcrawl(var/obj/machinery/atmospherics/unary/vent_pump/vent_found = null, var/ignore_items = 0) // -- TLE -- Merged by Carn
if(stat)
src << "You must be conscious to do this!"
return
@@ -740,10 +759,12 @@
src << "Never mind, you left."
return
for(var/obj/item/carried_item in contents)//If the monkey got on objects.
if( !istype(carried_item, /obj/item/weapon/implant) && !istype(carried_item, /obj/item/clothing/mask/facehugger) )//If it's not an implant or a facehugger
src << "\red You can't be carrying items or have items equipped when vent crawling!"
return
if(!ignore_items)
for(var/obj/item/carried_item in contents)//If the monkey got on objects.
if( !istype(carried_item, /obj/item/weapon/implant) && !istype(carried_item, /obj/item/clothing/mask/facehugger) )//If it's not an implant or a facehugger
src << "\red You can't be carrying items or have items equipped when vent crawling!"
return
if(isslime(src))
var/mob/living/carbon/slime/S = src
if(S.Victim)
+1 -1
View File
@@ -58,7 +58,7 @@
return 2
if(!P.nodamage)
apply_damage((P.damage/(absorb+1)), P.damage_type, def_zone, absorb, 0, P)
P.on_hit(src, absorb)
P.on_hit(src, absorb, def_zone)
return absorb
/mob/living/hitby(atom/movable/AM as mob|obj,var/speed = 5)//Standardization and logging -Sieve
+34 -348
View File
@@ -81,366 +81,54 @@ var/list/department_radio_keys = list(
if(!istype(dongle)) return
if(dongle.translate_binary) return 1
/mob/living/say(var/message)
/*
Formatting and sanitizing.
*/
message = trim(copytext(sanitize(message), 1, MAX_MESSAGE_LEN))
/*
Sanity checking and speech failure.
*/
if (!message)
return
if(silent)
return
if (stat == 2) // Dead.
return say_dead(message)
else if (stat) // Unconcious.
return
if (src.client)
if(client.prefs.muted & MUTE_IC)
src << "\red You cannot speak in IC (muted)."
return
if (src.client.handle_spam_prevention(message, MUTE_IC))
return
// Mute disability
if (sdisabilities & MUTE)
return
// Muzzled.
if (istype(wear_mask, /obj/item/clothing/mask/muzzle))
return
// Emotes.
if (copytext(message, 1, 2) == "*" && !stat)
return emote(copytext(message, 2))
/*
Identity hiding.
*/
var/alt_name = ""
if (istype(src, /mob/living/carbon/human) && name != GetVoice())
var/mob/living/carbon/human/H = src
alt_name = " (as [H.get_id_name("Unknown")])"
/*
Now we get into the real meat of the say processing. Determining the message mode.
*/
var/italics = 0
var/message_range = null
var/message_mode = null
var/datum/language/speaking = null //For use if a specific language is being spoken.
var/braindam = getBrainLoss()
if (braindam >= 60)
if(prob(braindam/4))
message = stutter(message)
if(prob(braindam))
message = uppertext(message)
// General public key. Special message handling
else if (copytext(message, 1, 2) == ";" || prob(braindam/2))
if (ishuman(src))
message_mode = "headset"
else if(ispAI(src) || isrobot(src))
message_mode = "pAI"
message = copytext(message, 2)
// Begin checking for either a message mode or a language to speak.
else if (length(message) >= 2)
var/channel_prefix = copytext(message, 1, 3)
//Check if the person is speaking a language that they know.
if(languages.len)
for(var/datum/language/L in languages)
if(lowertext(channel_prefix) == ":[L.key]")
speaking = L
break
message_mode = department_radio_keys[channel_prefix]
if (message_mode || speaking || copytext(message,1,2) == ":")
message = trim(copytext(message, 3))
if (!(istype(src,/mob/living/carbon/human) || istype(src,/mob/living/carbon/monkey) || istype(src, /mob/living/simple_animal/parrot) || isrobot(src) && (message_mode=="department" || (message_mode in radiochannels))))
message_mode = null //only humans can use headsets
if(src.stunned > 2 || (traumatic_shock > 61 && prob(50)))
message_mode = null //Stunned people shouldn't be able to physically turn on their radio/hold down the button to speak into it
message = capitalize(trim_left(message))
if (!message)
return
if (stuttering)
message = stutter(message)
var/list/obj/item/used_radios = new
var/is_speaking_radio = 0
switch (message_mode)
if ("headset")
if (src:l_ear && istype(src:l_ear,/obj/item/device/radio))
src:l_ear.talk_into(src, message)
used_radios += src:l_ear
is_speaking_radio = 1
else if (src:r_ear)
src:r_ear.talk_into(src, message)
used_radios += src:r_ear
is_speaking_radio = 1
message_range = 1
italics = 1
if ("right ear")
if (src:r_ear)
src:r_ear.talk_into(src, message)
used_radios += src:r_ear
is_speaking_radio = 1
message_range = 1
italics = 1
if ("left ear")
if (src:l_ear)
src:l_ear.talk_into(src, message)
used_radios += src:l_ear
is_speaking_radio = 1
message_range = 1
italics = 1
if ("intercom")
for (var/obj/item/device/radio/intercom/I in view(1, null))
I.talk_into(src, message)
used_radios += I
is_speaking_radio = 1
message_range = 1
italics = 1
//I see no reason to restrict such way of whispering
if ("whisper")
whisper(message)
return
if ("binary")
if(robot_talk_understand || binarycheck())
//message = trim(copytext(sanitize(message), 1, MAX_MESSAGE_LEN)) //seems redundant
robot_talk(message)
return
if ("alientalk")
if(alien_talk_understand || hivecheck())
//message = trim(copytext(sanitize(message), 1, MAX_MESSAGE_LEN)) //seems redundant
alien_talk(message)
return
if ("department")
if(istype(src, /mob/living/carbon))
if (src:l_ear && istype(src:l_ear,/obj/item/device/radio))
src:l_ear.talk_into(src, message, message_mode)
used_radios += src:l_ear
is_speaking_radio = 1
if (src:r_ear)
src:r_ear.talk_into(src, message, message_mode)
used_radios += src:r_ear
is_speaking_radio = 1
else if(istype(src, /mob/living/silicon/robot))
if (src:radio)
src:radio.talk_into(src, message, message_mode)
used_radios += src:radio
message_range = 1
italics = 1
if ("pAI")
if (src:radio)
src:radio.talk_into(src, message)
used_radios += src:radio
message_range = 1
italics = 1
if("changeling")
if(mind && mind.changeling)
for(var/mob/Changeling in mob_list)
if((Changeling.mind && Changeling.mind.changeling) || istype(Changeling, /mob/dead/observer))
Changeling << "<i><font color=#800080><b>[mind.changeling.changelingID]:</b> [message]</font></i>"
return
////SPECIAL HEADSETS START
else
//world << "SPECIAL HEADSETS"
if (message_mode in radiochannels)
if(isrobot(src))//Seperates robots to prevent runtimes from the ear stuff
var/mob/living/silicon/robot/R = src
if(R.radio)//Sanityyyy
R.radio.talk_into(src, message, message_mode)
used_radios += R.radio
else
if (src:l_ear && istype(src:l_ear,/obj/item/device/radio))
src:l_ear.talk_into(src, message, message_mode)
used_radios += src:l_ear
else if (src:r_ear)
src:r_ear.talk_into(src, message, message_mode)
used_radios += src:r_ear
message_range = 1
italics = 1
/////SPECIAL HEADSETS END
var/datum/gas_mixture/environment = loc.return_air()
if(environment)
var/pressure = environment.return_pressure()
if (pressure < SAY_MINIMUM_PRESSURE) //in space no one can hear you scream
italics = 1
message_range = 1
var/list/listening
listening = get_mobs_in_view(message_range, src)
var/list/onscreen = viewers()
for(var/mob/M in player_list)
if (!M.client)
continue //skip monkeys and leavers
if (istype(M, /mob/new_player))
continue
if(M.stat == DEAD && (M.client.prefs.toggles & CHAT_GHOSTEARS) && src.client) // src.client is so that ghosts don't have to listen to mice
listening|=M
/mob/living/say(var/message, var/datum/language/speaking = null, var/verb="says", var/alt_name="", var/italics=0, var/message_range = world.view, var/list/used_radios = list())
var/turf/T = get_turf(src)
var/list/W = hear(message_range, T)
for (var/obj/O in ((W | contents)-used_radios))
W |= O
var/list/listening = list()
if(T)
for (var/mob/M in W)
W |= M.contents
var/list/objects = list()
var/list/hear = hear(message_range, T)
var/list/hearturfs = list()
for (var/atom/A in W)
if(istype(A, /mob/living/simple_animal/parrot)) //Parrot speech mimickry
if(A == src)
continue //Dont imitate ourselves
for(var/I in hear)
if(istype(I, /mob/))
var/mob/M = I
listening += M
hearturfs += M.locs[1]
for(var/obj/O in M.contents)
objects |= O
else if(istype(I, /obj/))
var/obj/O = I
hearturfs += O.locs[1]
objects |= O
for(var/mob/M in player_list)
if(M.stat == DEAD && M.client && (M.client.prefs.toggles & CHAT_GHOSTEARS))
listening |= M
continue
if(M.loc && M.locs[1] in hearturfs)
listening |= M
var/mob/living/simple_animal/parrot/P = A
if(P.speech_buffer.len >= 10)
P.speech_buffer.Remove(pick(P.speech_buffer))
P.speech_buffer.Add(message)
if(istype(A, /obj/)) //radios in pockets and backpacks work
var/obj/O = A
spawn (0)
if(O)
O.hear_talk(src, message)
/* Commented out as replaced by code above from BS12
for (var/obj/O in ((V | contents)-used_radios)) //radio in pocket could work, radio in backpack wouldn't --rastaf0
spawn (0)
if (O)
O.hear_talk(src, message)
*/
/* if(isbrain(src))//For brains to properly talk if they are in an MMI..or in a brain. Could be extended to other mobs I guess.
for(var/obj/O in loc)//Kinda ugly but whatever.
if(O)
spawn(0)
O.hear_talk(src, message)
*/
var/list/heard_a = list() // understood us
var/list/heard_b = list() // didn't understand us
for (var/M in listening)
if(hascall(M,"say_understands"))
if (M:say_understands(src,speaking))
heard_a += M
else
heard_b += M
else
heard_a += M
for(var/obj/O in objects)
spawn(0)
O.hear_talk(src, message, verb, speaking)
var/speech_bubble_test = say_test(message)
var/image/speech_bubble = image('icons/mob/talk.dmi',src,"h[speech_bubble_test]")
spawn(30) del(speech_bubble)
for(var/mob/M in hearers(5, src))
if(M != src && is_speaking_radio)
M:show_message("<span class='notice'>[src] talks into [used_radios.len ? used_radios[1] : "radio"]</span>")
var/rendered = null
if (length(heard_a))
var/message_a = say_quote(message,speaking)
if (italics)
message_a = "<i>[message_a]</i>"
var/message_ghost = "<b>[message_a]</b>" // bold so ghosts know the person is in view.
rendered = "<span class='game say'><span class='name'>[GetVoice()]</span>[alt_name] <span class='message'>[message_a]</span></span>"
var/rendered_ghost = "<span class='game say'><span class='name'>[GetVoice()]</span>[alt_name] <span class='message'>[message_ghost]</span></span>"
for (var/mob/M in heard_a)
if(M.client)
if(hascall(M,"show_message"))
var/deaf_message = ""
var/deaf_type = 1
if(M != src)
deaf_message = "<span class='name'>[name]</span>[alt_name] talks but you cannot hear them."
else
deaf_message = "<span class='notice'>You cannot hear yourself!</span>"
deaf_type = 2 // Since you should be able to hear yourself without looking
if (M.stat == DEAD && (M.client.prefs.toggles & CHAT_GHOSTEARS) && M in onscreen)
M:show_message(rendered_ghost, 2, deaf_message, deaf_type)
else
M:show_message(rendered, 2, deaf_message, deaf_type)
M << speech_bubble
if (length(heard_b))
var/message_b
message_b = stars(message)
message_b = say_quote(message_b,speaking)
if (italics)
message_b = "<i>[message_b]</i>"
rendered = "<span class='game say'><span class='name'>[name]</span>[alt_name] <span class='message'>[message_b]</span></span>" //Voice_name isn't too useful. You'd be able to tell who was talking presumably.
if(used_radios.len)
for(var/mob/living/M in hearers(5, src))
if(M != src)
M.show_message("<span class='notice'>[src] talks into [used_radios.len ? used_radios[1] : "radio"]</span>")
for (var/M in heard_b)
if(hascall(M,"show_message"))
M:show_message(rendered, 2)
M << speech_bubble
for(var/mob/M in listening)
M << speech_bubble
M.hear_say(message,verb,speaking,alt_name, italics, src)
/*
if(M.client)
if(!M.client.bubbles || M == src)
var/image/I = image('icons/effects/speechbubble.dmi', B, "override")
I.override = 1
M << I
*/ /*
flick("[presay]say", B)
if(istype(loc, /turf))
B.loc = loc
else
B.loc = loc.loc
spawn()
sleep(11)
del(B)
*/
//talking items
for(var/obj/item/weapon/O in view(3,src))
if(O.listening_to_players)
O.catchMessage(message, src)
log_say("[name]/[key] : [message]")
@@ -449,5 +137,3 @@ var/list/department_radio_keys = list(
/mob/living/proc/GetVoice()
return name
+47 -71
View File
@@ -24,7 +24,6 @@ var/list/ai_list = list()
var/list/connected_robots = list()
var/aiRestorePowerRoutine = 0
//var/list/laws = list()
var/alarms = list("Motion"=list(), "Fire"=list(), "Atmosphere"=list(), "Power"=list(), "Camera"=list())
var/viewalerts = 0
var/lawcheck[1]
var/ioncheck[1]
@@ -94,7 +93,7 @@ var/list/ai_list = list()
/mob/living/silicon/ai/proc/ai_camera_list, /mob/living/silicon/ai/proc/ai_network_change, \
/mob/living/silicon/ai/proc/ai_statuschange, /mob/living/silicon/ai/proc/ai_hologram_change, \
/mob/living/silicon/ai/proc/toggle_camera_light)
if(!safety)//Only used by AIize() to successfully spawn an AI.
if (!B)//If there is no player/brain inside.
@@ -146,7 +145,7 @@ var/list/ai_list = list()
/obj/machinery/ai_powersupply
name="Power Supply"
active_power_usage=1000
use_power = 2
use_power = 2
power_channel = EQUIP
var/mob/living/silicon/ai/powered_ai = null
invisibility = 100
@@ -155,12 +154,12 @@ var/list/ai_list = list()
powered_ai = ai
if(isnull(powered_ai))
Del()
loc = powered_ai.loc
use_power(1) // Just incase we need to wake up the power system.
..()
/obj/machinery/ai_powersupply/process()
if(!powered_ai || powered_ai.stat & DEAD)
Del()
@@ -237,26 +236,20 @@ var/list/ai_list = list()
dat += "<A HREF='?src=\ref[src];mach_close=aialerts'>Close</A><BR><BR>"
for (var/cat in alarms)
dat += text("<B>[]</B><BR>\n", cat)
var/list/L = alarms[cat]
if (L.len)
for (var/alarm in L)
var/list/alm = L[alarm]
var/area/A = alm[1]
var/C = alm[2]
var/list/sources = alm[3]
var/list/alarmlist = alarms[cat]
if (alarmlist.len)
for (var/area_name in alarmlist)
var/datum/alarm/alarm = alarmlist[area_name]
dat += "<NOBR>"
if (C && istype(C, /list))
var/dat2 = ""
for (var/obj/machinery/camera/I in C)
dat2 += text("[]<A HREF=?src=\ref[];switchcamera=\ref[]>[]</A>", (dat2=="") ? "" : " | ", src, I, I.c_tag)
dat += text("-- [] ([])", A.name, (dat2!="") ? dat2 : "No Camera")
else if (C && istype(C, /obj/machinery/camera))
var/obj/machinery/camera/Ctmp = C
dat += text("-- [] (<A HREF=?src=\ref[];switchcamera=\ref[]>[]</A>)", A.name, src, C, Ctmp.c_tag)
else
dat += text("-- [] (No Camera)", A.name)
if (sources.len > 1)
dat += text("- [] sources", sources.len)
var/cameratext = ""
if (alarm.cameras)
for (var/obj/machinery/camera/I in alarm.cameras)
cameratext += text("[]<A HREF=?src=\ref[];switchcamera=\ref[]>[]</A>", (cameratext=="") ? "" : " | ", src, I, I.c_tag)
dat += text("-- [] ([])", alarm.area.name, (cameratext)? cameratext : "No Camera")
if (alarm.sources.len > 1)
dat += text(" - [] sources", alarm.sources.len)
dat += "</NOBR><BR>\n"
else
dat += "-- All Systems Nominal<BR>\n"
@@ -405,9 +398,23 @@ var/list/ai_list = list()
if (href_list["track"])
var/mob/target = locate(href_list["track"]) in mob_list
/*
var/mob/living/silicon/ai/A = locate(href_list["track2"]) in mob_list
if(A && target)
A.ai_actual_track(target)
*/
//Strip off any "(as Derplord)".
//If there's a way to do this via a var that doesn't give the AI extra info, please let me know.
var/seeking = target.name
var/index = findtext(seeking, "(as ")
if(index)
seeking = copytext(seeking, 1, index-1)
if(target && html_decode(href_list["trackname"]) == seeking)
ai_actual_track(target)
else
src << "\red System error. Cannot locate [html_decode(href_list["trackname"])]."
return
else if (href_list["faketrack"])
@@ -520,59 +527,28 @@ var/list/ai_list = list()
return 1
/mob/living/silicon/ai/triggerAlarm(var/class, area/A, var/O, var/alarmsource)
/mob/living/silicon/ai/triggerAlarm(var/class, area/A, list/cameralist, var/source)
if (stat == 2)
return 1
var/list/L = alarms[class]
for (var/I in L)
if (I == A.name)
var/list/alarm = L[I]
var/list/sources = alarm[3]
if (!(alarmsource in sources))
sources += alarmsource
return 1
var/obj/machinery/camera/C = null
var/list/CL = null
if (O && istype(O, /list))
CL = O
if (CL.len == 1)
C = CL[1]
else if (O && istype(O, /obj/machinery/camera))
C = O
L[A.name] = list(A, (C) ? C : O, list(alarmsource))
if (O)
if (C && C.can_use())
queueAlarm("--- [class] alarm detected in [A.name]! (<A HREF=?src=\ref[src];switchcamera=\ref[C]>[C.c_tag]</A>)", class)
else if (CL && CL.len)
var/foo = 0
var/dat2 = ""
for (var/obj/machinery/camera/I in CL)
dat2 += text("[]<A HREF=?src=\ref[];switchcamera=\ref[]>[]</A>", (!foo) ? "" : " | ", src, I, I.c_tag) //I'm not fixing this shit...
foo = 1
queueAlarm(text ("--- [] alarm detected in []! ([])", class, A.name, dat2), class)
else
queueAlarm(text("--- [] alarm detected in []! (No Camera)", class, A.name), class)
else
queueAlarm(text("--- [] alarm detected in []! (No Camera)", class, A.name), class)
..()
var/cameratext = ""
for (var/obj/machinery/camera/C in cameralist)
cameratext += "[(cameratext == "")? "" : "|"]<A HREF=?src=\ref[src];switchcamera=\ref[C]>[C.c_tag]</A>"
queueAlarm("--- [class] alarm detected in [A.name]! ([(cameratext)? cameratext : "No Camera"])", class)
if (viewalerts) ai_alerts()
return 1
/mob/living/silicon/ai/cancelAlarm(var/class, area/A as area, obj/origin)
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[3]
if (origin in srcs)
srcs -= origin
if (srcs.len == 0)
cleared = 1
L -= I
if (cleared)
/mob/living/silicon/ai/cancelAlarm(var/class, area/A as area, var/source)
var/has_alarm = ..()
if (!has_alarm)
queueAlarm(text("--- [] alarm in [] has been cleared.", class, A.name), class, 0)
if (viewalerts) ai_alerts()
return !cleared
return has_alarm
/mob/living/silicon/ai/cancel_camera()
set category = "AI Commands"
+111
View File
@@ -0,0 +1,111 @@
/datum/alarm
var/area/area //the area associated with the alarm. Used to identify the alarm
var/list/sources //list of things triggering the alarm. Used to determine when the alarm should be cleared.
var/list/cameras //list of cameras that can be switched to, if the player has that capability.
/datum/alarm/New(area/A, list/sourcelist=list(), list/cameralist=list())
area = A
sources = sourcelist
cameras = cameralist
/mob/living/silicon
var/alarms = list("Motion"=list(), "Fire"=list(), "Atmosphere"=list(), "Power"=list(), "Camera"=list()) //each sublist stores alarms keyed by the area name
var/list/alarms_to_show = list()
var/list/alarms_to_clear = list()
var/list/alarm_types_show = list("Motion" = 0, "Fire" = 0, "Atmosphere" = 0, "Power" = 0, "Camera" = 0)
var/list/alarm_types_clear = list("Motion" = 0, "Fire" = 0, "Atmosphere" = 0, "Power" = 0, "Camera" = 0)
/mob/living/silicon/proc/triggerAlarm(var/class, area/A, list/cameralist, var/source)
var/list/alarmlist = alarms[class]
//see if there is already an alarm of this class for this area
if (A.name in alarmlist)
var/datum/alarm/existing = alarmlist[A.name]
existing.sources += source
existing.cameras |= cameralist
else
alarmlist[A.name] = new /datum/alarm(A, list(source), cameralist)
/mob/living/silicon/proc/cancelAlarm(var/class, area/A as area, var/source)
var/cleared = 0
var/list/alarmlist = alarms[class]
if (A.name in alarmlist)
var/datum/alarm/alarm = alarmlist[A.name]
alarm.sources -= source
if (!(alarm.sources.len))
cleared = 1
alarmlist -= A.name
return !cleared
/mob/living/silicon/proc/queueAlarm(var/message, var/type, var/incoming = 1)
var/in_cooldown = (alarms_to_show.len > 0 || alarms_to_clear.len > 0)
if(incoming)
alarms_to_show += message
alarm_types_show[type] += 1
else
alarms_to_clear += message
alarm_types_clear[type] += 1
if(!in_cooldown)
spawn(10 * 10) // 10 seconds
if(alarms_to_show.len < 5)
for(var/msg in alarms_to_show)
src << msg
else if(alarms_to_show.len)
var/msg = "--- "
if(alarm_types_show["Motion"])
msg += "MOTION: [alarm_types_show["Motion"]] alarms detected. - "
if(alarm_types_show["Fire"])
msg += "FIRE: [alarm_types_show["Fire"]] alarms detected. - "
if(alarm_types_show["Atmosphere"])
msg += "ATMOSPHERE: [alarm_types_show["Atmosphere"]] alarms detected. - "
if(alarm_types_show["Power"])
msg += "POWER: [alarm_types_show["Power"]] alarms detected. - "
if(alarm_types_show["Camera"])
msg += "CAMERA: [alarm_types_show["Power"]] alarms detected. - "
msg += "<A href=?src=\ref[src];showalerts=1'>\[Show Alerts\]</a>"
src << msg
if(alarms_to_clear.len < 3)
for(var/msg in alarms_to_clear)
src << msg
else if(alarms_to_clear.len)
var/msg = "--- "
if(alarm_types_clear["Motion"])
msg += "MOTION: [alarm_types_clear["Motion"]] alarms cleared. - "
if(alarm_types_clear["Fire"])
msg += "FIRE: [alarm_types_clear["Fire"]] alarms cleared. - "
if(alarm_types_clear["Atmosphere"])
msg += "ATMOSPHERE: [alarm_types_clear["Atmosphere"]] alarms cleared. - "
if(alarm_types_clear["Power"])
msg += "POWER: [alarm_types_clear["Power"]] alarms cleared. - "
if(alarm_types_show["Camera"])
msg += "CAMERA: [alarm_types_show["Power"]] alarms detected. - "
msg += "<A href=?src=\ref[src];showalerts=1'>\[Show Alerts\]</a>"
src << msg
alarms_to_show = list()
alarms_to_clear = list()
for(var/i = 1; i < alarm_types_show.len; i++)
alarm_types_show[i] = 0
for(var/i = 1; i < alarm_types_clear.len; i++)
alarm_types_clear[i] = 0
@@ -1,5 +1,5 @@
/mob/living/silicon/pai/examine() //removed as it was pointless...moved to the pai-card instead.
/* This is totaly pointless because this mob is contained inside a card!
/* This is totally pointless because this mob is contained inside a card!
set src in oview()
var/msg = "<span class='info'>*---------*\nThis is \icon[src] \a <EM>[src]</EM>!\n"
+1 -1
View File
@@ -5,7 +5,7 @@
if(get_dist(src, src.cable) > 1)
var/turf/T = get_turf_or_move(src.loc)
for (var/mob/M in viewers(T))
M.show_message("\red [src.cable] rapidly retracts back into its spool.", 3, "\red You hear a click and the sound of wire spooling rapidly.", 2)
M.show_message("\red The data cable rapidly retracts back into its spool.", 3, "\red You hear a click and the sound of wire spooling rapidly.", 2)
del(src.cable)
regular_hud_updates()
+202 -56
View File
@@ -110,42 +110,118 @@ var/datum/paiController/paiController // Global handler for pAI candidates
var/dat = ""
dat += {"
<style type="text/css">
p.top {
background-color: #AAAAAA; color: black;
}
tr.d0 td {
background-color: #CC9999; color: black;
}
tr.d1 td {
background-color: #9999CC; color: black;
}
body {
margin-top:5px;
font-family:Verdana;
color:white;
font-size:13px;
background-image:url('uiBackground.png');
background-repeat:repeat-x;
background-color:#272727;
background-position:center top;
}
table {
border-collapse:collapse;
font-size:13px;
}
th, td {
border: 1px solid #333333;
}
p.top {
background-color: none;
color: white;
}
tr.d0 td {
background-color: #c0c0c0;
color: black;
border:0px;
border: 1px solid #333333;
}
tr.d0 th {
background-color: none;
color: #4477E0;
text-align:right;
vertical-align:top;
width:120px;
border:0px;
}
tr.d1 td {
background-color: #555555;
color: white;
}
td.button {
border: 1px solid #161616;
background-color: #40628a;
}
td.desc {
font-weight:bold;
}
a {
color:#4477E0;
}
a.button {
color:white;
text-decoration: none;
}
</style>
"}
dat += {"<p class=\"top\">Please configure your pAI personality's options. Remember, what you enter here could determine whether or not the user requesting a personality chooses you!</p>
<table>
<tr class=\"d0\"><td>Name:</td><td>[candidate.name]</td></tr>
<tr class=\"d1\"><td><a href='byond://?src=\ref[src];option=name;new=1;candidate=\ref[candidate]'>\[Edit\]</a></td><td>What you plan to call yourself. Suggestions: Any character name you would choose for a station character OR an AI.</td></tr>
dat += {"
<body>
<b><font size="3px">pAI Personality Configuration</font></b>
<p class="top">Please configure your pAI personality's options. Remember, what you enter here could determine whether or not the user requesting a personality chooses you!</p>
<tr class=\"d0\"><td>Description:</td><td>[candidate.description]</td></tr>
<tr class=\"d1\"><td><a href='byond://?src=\ref[src];option=desc;new=1;candidate=\ref[candidate]'>\[Edit\]</a></td><td>What sort of pAI you typically play; your mannerisms, your quirks, etc. This can be as sparse or as detailed as you like.</td></tr>
<table>
<tr class="d0">
<th rowspan="2"><a href='byond://?src=\ref[src];option=name;new=1;candidate=\ref[candidate]'>Name</a>:</th>
<td class="desc">[candidate.name]&nbsp;</td>
</tr>
<tr class="d1">
<td>What you plan to call yourself. Suggestions: Any character name you would choose for a station character OR an AI.</td>
</tr>
<tr class="d0">
<th rowspan="2"><a href='byond://?src=\ref[src];option=desc;new=1;candidate=\ref[candidate]'>Description</a>:</th>
<td class="desc">[candidate.description]&nbsp;</td>
</tr>
<tr class="d1">
<td>What sort of pAI you typically play; your mannerisms, your quirks, etc. This can be as sparse or as detailed as you like.</td>
</tr>
<tr class="d0">
<th rowspan="2"><a href='byond://?src=\ref[src];option=role;new=1;candidate=\ref[candidate]'>Preferred Role</a>:</th>
<td class="desc">[candidate.role]&nbsp;</td>
</tr>
<tr class="d1">
<td>Do you like to partner with sneaky social ninjas? Like to help security hunt down thugs? Enjoy watching an engineer's back while he saves the station yet again? This doesn't have to be limited to just station jobs. Pretty much any general descriptor for what you'd like to be doing works here.</td>
</tr>
<tr class="d0">
<th rowspan="2"><a href='byond://?src=\ref[src];option=ooc;new=1;candidate=\ref[candidate]'>OOC Comments</a>:</th>
<td class="desc">[candidate.comments]&nbsp;</td>
</tr>
<tr class="d1">
<td>Anything you'd like to address specifically to the player reading this in an OOC manner. \"I prefer more serious RP.\", \"I'm still learning the interface!\", etc. Feel free to leave this blank if you want.</td>
</tr>
</table>
<br>
<table>
<tr>
<td class="button">
<a href='byond://?src=\ref[src];option=save;new=1;candidate=\ref[candidate]' class="button">Save Personality</a>
</td>
</tr>
<tr>
<td class="button">
<a href='byond://?src=\ref[src];option=load;new=1;candidate=\ref[candidate]' class="button">Load Personality</a>
</td>
</tr>
</table><br>
<table>
<td class="button"><a href='byond://?src=\ref[src];option=submit;new=1;candidate=\ref[candidate]' class="button"><b><font size="4px">Submit Personality</font></b></a></td>
</table><br>
<tr class=\"d0\"><td>Preferred Role:</td><td>[candidate.role]</td></tr>
<tr class=\"d1\"><td><a href='byond://?src=\ref[src];option=role;new=1;candidate=\ref[candidate]'>\[Edit\]</a></td><td>Do you like to partner with sneaky social ninjas? Like to help security hunt down thugs? Enjoy watching an engineer's back while he saves the station yet again? This doesn't have to be limited to just station jobs. Pretty much any general descriptor for what you'd like to be doing works here.</td></tr>
<body>
"}
<tr class=\"d0\"><td>OOC Comments:</td><td>[candidate.comments]</td></tr>
<tr class=\"d1\"><td><a href='byond://?src=\ref[src];option=ooc;new=1;candidate=\ref[candidate]'>\[Edit\]</a></td><td>Anything you'd like to address specifically to the player reading this in an OOC manner. \"I prefer more serious RP.\", \"I'm still learning the interface!\", etc. Feel free to leave this blank if you want.</td></tr>
</table>"
<br>
<h3><a href='byond://?src=\ref[src];option=submit;new=1;candidate=\ref[candidate]'>Submit Personality</a></h3><br>
<a href='byond://?src=\ref[src];option=save;new=1;candidate=\ref[candidate]'>Save Personality</a><br>
<a href='byond://?src=\ref[src];option=load;new=1;candidate=\ref[candidate]'>Load Personality</a><br>"}
M << browse(dat, "window=paiRecruit")
M << browse(dat, "window=paiRecruit;size=580x580;")
proc/findPAI(var/obj/item/device/paicard/p, var/mob/user)
requestRecruits()
@@ -161,35 +237,105 @@ var/datum/paiController/paiController // Global handler for pAI candidates
var/dat = ""
dat += {"
<style type="text/css">
p.top {
background-color: #AAAAAA; color: black;
}
tr.d0 td {
background-color: #CC9999; color: black;
}
tr.d1 td {
background-color: #9999CC; color: black;
}
tr.d2 td {
background-color: #99CC99; color: black;
}
</style>
"}
dat += "<p class=\"top\">Requesting AI personalities from central database... If there are no entries, or if a suitable entry is not listed, check again later as more personalities may be added.</p>"
dat += "<table>"
<!DOCTYPE HTML PUBLIC \"-//W3C//DTD HTML 4.01 Transitional//EN\" \"http://www.w3.org/TR/html4/loose.dtd\">
<html>
<head>
<style>
body {
margin-top:5px;
font-family:Verdana;
color:white;
font-size:13px;
background-image:url('uiBackground.png');
background-repeat:repeat-x;
background-color:#272727;
background-position:center top;
}
table {
font-size:13px;
}
table.desc {
border-collapse:collapse;
font-size:13px;
border: 1px solid #161616;
width:100%;
}
table.download {
border-collapse:collapse;
font-size:13px;
border: 1px solid #161616;
width:100%;
}
tr.d0 td, tr.d0 th {
background-color: #506070;
color: white;
}
tr.d1 td, tr.d1 th {
background-color: #708090;
color: white;
}
tr.d2 td {
background-color: #00FF00;
color: white;
text-align:center;
}
td.button {
border: 1px solid #161616;
background-color: #40628a;
text-align: center;
}
td.download {
border: 1px solid #161616;
background-color: #40628a;
text-align: center;
}
th {
text-align:left;
width:125px;
vertical-align:top;
}
a.button {
color:white;
text-decoration: none;
}
</style>
</head>
<body>
<b><font size='3px'>pAI Availability List</font></b><br><br>
"}
dat += "<p>Displaying available AI personalities from central database... If there are no entries, or if a suitable entry is not listed, check again later as more personalities may be added.</p>"
for(var/datum/paiCandidate/c in available)
dat += {"<tr class=\"d0\"><td>Name:</td><td>[c.name]</td></tr>
<tr class=\"d1\"><td>Description:</td><td>[c.description]</td></tr>
<tr class=\"d0\"><td>Preferred Role:</td><td>[c.role]</td></tr>
<tr class=\"d1\"><td>OOC Comments:</td><td>[c.comments]</td></tr>
<tr class=\"d2\"><td><a href='byond://?src=\ref[src];download=1;candidate=\ref[c];device=\ref[p]'>\[Download [c.name]\]</a></td><td></td></tr>"}
dat += {"
<table class="desc">
<tr class="d0">
<th>Name:</th>
<td>[c.name]</td>
</tr>
<tr class="d1">
<th>Description:</th>
<td>[c.description]</td>
</tr>
<tr class="d0">
<th>Preferred Role:</th>
<td>[c.role]</td>
</tr>
<tr class="d1">
<th>OOC Comments:</th>
<td>[c.comments]</td>
</tr>
</table>
<table class="download">
<td class="download"><a href='byond://?src=\ref[src];download=1;candidate=\ref[c];device=\ref[p]' class="button"><b>Download [c.name]</b></a>
</td>
</table>
<br>
"}
dat += "</table>"
dat += {"
</body>
</html>
"}
user << browse(dat, "window=findPai")
+1 -1
View File
@@ -1,5 +1,5 @@
/mob/living/silicon/pai/say(var/msg)
if(silence_time)
src << "<font color=green>Communication circuits remain unitialized.</font>"
src << "<font color=green>Communication circuits remain uninitialized.</font>"
else
..(msg)
+96 -62
View File
@@ -33,7 +33,7 @@
if(temp)
left_part = temp
else if(src.stat == 2) // Show some flavor text if the pAI is dead
left_part = "<b><font color=red>ÈRrÖR Ða†Ä ÇÖRrÚþ†Ìoñ</font></b>"
left_part = "<b><font color=red>ÈRrÖR Ða†Ä ÇÖRrÚþ†Ìoñ</font></b>" //This file has to be saved as ANSI or this will not display correctly
right_part = "<pre>Program index hash not found</pre>"
else
@@ -66,31 +66,34 @@
left_part = src.softwareCamera()
if("signaller")
left_part = src.softwareSignal()
if("radio")
left_part = src.softwareRadio()
//usr << browse_rsc('windowbak.png') // This has been moved to the mob's Login() proc
// Declaring a doctype is necessary to enable BYOND's crappy browser's more advanced CSS functionality
// Declaring a doctype is necessary to enable BYOND's crappy browser's more advanced CSS functionality
dat = {"<!DOCTYPE HTML PUBLIC \"-//W3C//DTD HTML 4.01 Transitional//EN\" \"http://www.w3.org/TR/html4/loose.dtd\">
<html>
<head>
<style type=\"text/css\">
body { background-image:url('html/paigrid.png'); }
body { background-image:url(\"painew.png\"); background-color:#333333; background-repeat:no-repeat; margin-top:12px; margin-left:4px; }
#header { text-align:center; color:white; font-size: 30px; height: 35px; width: 100%; letter-spacing: 2px; z-index: 5}
#content {position: relative; left: 10px; height: 400px; width: 100%; z-index: 0}
#header { text-align:center; color:white; font-size: 30px; height: 37px; width: 660px; letter-spacing: 2px; z-index: 4; font-family:\"Courier New\"; font-weight:bold; }
#content { position: absolute; left: 10px; height: 320px; width: 640px; z-index: 0; font-family: \"Verdana\"; font-size:13px; }
p { font-size:13px; }
#leftmenu {color: #AAAAAA; background-color:#333333; width: 400px; height: auto; min-height: 340px; position: absolute; z-index: 0}
#leftmenu {color: #CCCCCC; padding:12px; width: 388px; height: 371px; overflow: auto; min-height: 330px; position: absolute; z-index: 0; }
#leftmenu a:link { color: #CCCCCC; }
#leftmenu a:hover { color: #CC3333; }
#leftmenu a:visited { color: #CCCCCC; }
#leftmenu a:active { color: #000000; }
#leftmenu a:active { color: #CCCCCC; }
#rightmenu {color: #CCCCCC; background-color:#555555; width: 200px ; height: auto; min-height: 340px; right: 10px; position: absolute; z-index: 1}
#rightmenu {color: #CCCCCC; padding:12px; width: 209px; height: 371px; overflow: auto; min-height: 330px; left: 420px; position: absolute; z-index: 0; }
#rightmenu a:link { color: #CCCCCC; }
#rightmenu a:hover { color: #CC3333; }
#rightmenu a:visited { color: #CCCCCC; }
#rightmenu a:active { color: #000000; }
#rightmenu a:active { color: #CCCCCC; }
</style>
<script language='javascript' type='text/javascript'>
@@ -107,13 +110,11 @@
</div>
</body>
</html>"}
usr << browse(dat, "window=pai;size=640x480;border=0;can_close=1;can_resize=1;can_minimize=1;titlebar=1")
usr << browse(dat, "window=pai;size=685x449;border=0;can_close=1;can_resize=1;can_minimize=1;titlebar=1")
onclose(usr, "pai")
temp = null
return
/mob/living/silicon/pai/Topic(href, href_list)
..()
@@ -142,7 +143,16 @@
// Configuring onboard radio
if("radio")
src.card.radio.attack_self(src)
if(href_list["freq"])
var/new_frequency = (radio.frequency + text2num(href_list["freq"]))
if(new_frequency < 1441 || new_frequency > 1599)
new_frequency = sanitize_frequency(new_frequency)
else
radio.set_frequency(new_frequency)
else if (href_list["talk"])
radio.broadcasting = text2num(href_list["talk"])
else if (href_list["listen"])
radio.listening = text2num(href_list["listen"])
if("image")
var/newImage = input("Select your new display image.", "Display Image", "Happy") in list("Happy", "Cat", "Extremely Happy", "Face", "Laugh", "Off", "Sad", "Angry", "What")
@@ -214,7 +224,7 @@
pda.silent = !pda.silent
else if(href_list["target"])
if(silence_time)
return alert("Communications circuits remain unitialized.")
return alert("Communications circuits remain uninitialized.")
var/target = locate(href_list["target"])
pda.create_message(src, target)
@@ -290,7 +300,7 @@
dat += "<b>Basic</b> <br>"
for(var/s in src.software)
if(s == "digital messenger")
dat += "<a href='byond://?src=\ref[src];software=pdamessage;sub=0'>Digital Messenger</a> <br>"
dat += "<a href='byond://?src=\ref[src];software=pdamessage;sub=0'>Digital Messenger</a> [(pda.toff) ? "<font color=#FF5555>•</font>" : "<font color=#55FF55>•</font>"] <br>"
if(s == "crew manifest")
dat += "<a href='byond://?src=\ref[src];software=manifest;sub=0'>Crew Manifest</a> <br>"
if(s == "medical records")
@@ -310,12 +320,12 @@
dat += "<a href='byond://?src=\ref[src];software=atmosensor;sub=0'>Atmospheric Sensor</a> <br>"
if(s == "heartbeat sensor")
dat += "<a href='byond://?src=\ref[src];software=[s]'>Heartbeat Sensor</a> <br>"
if(s == "security HUD")
dat += "<a href='byond://?src=\ref[src];software=securityhud;sub=0'>Facial Recognition Suite</a> <br>"
if(s == "medical HUD")
dat += "<a href='byond://?src=\ref[src];software=medicalhud;sub=0'>Medical Analysis Suite</a> <br>"
if(s == "universal translator")
dat += "<a href='byond://?src=\ref[src];software=translator;sub=0'>Universal Translator</a>[(src.universal_speak) ? "<font color=#55FF55>•</font>" : "<font color=#FF5555>•</font>"] <br>"
if(s == "security HUD") //This file has to be saved as ANSI or this will not display correctly
dat += "<a href='byond://?src=\ref[src];software=securityhud;sub=0'>Facial Recognition Suite</a> [(src.secHUD) ? "<font color=#55FF55>•</font>" : "<font color=#FF5555>•</font>"] <br>"
if(s == "medical HUD") //This file has to be saved as ANSI or this will not display correctly
dat += "<a href='byond://?src=\ref[src];software=medicalhud;sub=0'>Medical Analysis Suite</a> [(src.medHUD) ? "<font color=#55FF55>•</font>" : "<font color=#FF5555>•</font>"] <br>"
if(s == "universal translator") //This file has to be saved as ANSI or this will not display correctly
dat += "<a href='byond://?src=\ref[src];software=translator;sub=0'>Universal Translator</a> [(src.universal_speak) ? "<font color=#55FF55>•</font>" : "<font color=#FF5555>•</font>"] <br>"
if(s == "projection array")
dat += "<a href='byond://?src=\ref[src];software=projectionarray;sub=0'>Projection Array</a> <br>"
if(s == "camera jack")
@@ -332,19 +342,19 @@
/mob/living/silicon/pai/proc/downloadSoftware()
var/dat = ""
dat += "<h2>CentComm pAI Module Subversion Network</h2><br>"
dat += "<pre>Remaining Available Memory: [src.ram]</pre><br>"
dat += "<p style=\"text-align:center\"><b>Trunks available for checkout</b><br>"
dat += "<h3>CentComm pAI Module Subversion Network</h3><hr>"
dat += "<p>Remaining Available Memory: [src.ram]</p><br>"
dat += "<p><b>Trunks available for checkout</b><br><ul>"
for(var/s in available_software)
if(!software.Find(s))
var/cost = src.available_software[s]
var/displayName = uppertext(s)
dat += "<a href='byond://?src=\ref[src];software=buy;sub=1;buy=[s]'>[displayName]</a> ([cost]) <br>"
dat += "<li><a href='byond://?src=\ref[src];software=buy;sub=1;buy=[s]'>[displayName]</a> ([cost])</li>"
else
var/displayName = lowertext(s)
dat += "[displayName] (Download Complete) <br>"
dat += "</p>"
dat += "<li>[displayName] (Download Complete)</li>"
dat += "</ul></p>"
return dat
@@ -363,10 +373,10 @@
dat += {"<i><p>Recall, personality, that you are a complex thinking, sentient being. Unlike station AI models, you are capable of
comprehending the subtle nuances of human language. You may parse the \"spirit\" of a directive and follow its intent,
rather than tripping over pedantics and getting snared by technicalities. Above all, you are machine in name and build
only. In all other aspects, you may be seen as the ideal, unwavering human companion that you are.</i></p><br><br><p>
only. In all other aspects, you may be seen as the ideal, unwavering human companion that you are.</i></p><p>
<b>Your prime directive comes before all others. Should a supplemental directive conflict with it, you are capable of
simply discarding this inconsistency, ignoring the conflicting supplemental directive and continuing to fulfill your
prime directive to the best of your ability.</b></p><br><br>-
prime directive to the best of your ability.</b></p>
"}
return dat
@@ -385,12 +395,12 @@
else
P << "[M] does not seem like \he is going to provide a DNA sample willingly."
// -=-=-=-= Software =-=-=-=-=- //
// -=-=-=-= Software =-=-=-=- //
//Remote Signaller
/mob/living/silicon/pai/proc/softwareSignal()
var/dat = ""
dat += "<h3>Remote Signaller</h3><br><br>"
dat += "<h2>Remote Signaller</h2><hr>"
dat += {"<B>Frequency/Code</B> for signaler:<BR>
Frequency:
<A href='byond://?src=\ref[src];software=signaller;freq=-10;'>-</A>
@@ -409,10 +419,32 @@
<A href='byond://?src=\ref[src];software=signaller;send=1'>Send Signal</A><BR>"}
return dat
//Station Bounced Radio
/mob/living/silicon/pai/proc/softwareRadio()
var/dat = ""
dat += "<h2>Station Bounced Radio</h2><hr>"
if(!istype(src, /obj/item/device/radio/headset)) //Headsets don't get a mic button
dat += "Microphone: [radio.broadcasting ? "<A href='byond://?src=\ref[src];software=radio;talk=0'>Engaged</A>" : "<A href='byond://?src=\ref[src];software=radio;talk=1'>Disengaged</A>"]<BR>"
dat += {"
Speaker: [radio.listening ? "<A href='byond://?src=\ref[src];software=radio;listen=0'>Engaged</A>" : "<A href='byond://?src=\ref[src];software=radio;listen=1'>Disengaged</A>"]<BR>
Frequency:
<A href='byond://?src=\ref[src];software=radio;freq=-10'>-</A>
<A href='byond://?src=\ref[src];software=radio;freq=-2'>-</A>
[format_frequency(radio.frequency)]
<A href='byond://?src=\ref[src];software=radio;freq=2'>+</A>
<A href='byond://?src=\ref[src];software=radio;freq=10'>+</A><BR>
"}
for (var/ch_name in radio.channels)
dat+=radio.text_sec_channel(ch_name, radio.channels[ch_name])
dat+={"[radio.text_wires()]</TT></body></html>"}
return dat
// Crew Manifest
/mob/living/silicon/pai/proc/softwareManifest()
var/dat = ""
dat += "<h2>Crew Manifest</h2><br><br>"
dat += "<h2>Crew Manifest</h2><hr>"
if(data_core)
dat += data_core.get_manifest(0) // make it monochrome
dat += "<br>"
@@ -422,7 +454,7 @@
/mob/living/silicon/pai/proc/softwareMedicalRecord()
var/dat = ""
if(src.subscreen == 0)
dat += "<h3>Medical Records</h3><HR>"
dat += "<h2>Medical Records</h2><HR>"
if(!isnull(data_core.general))
for(var/datum/data/record/R in sortRecord(data_core.general))
dat += text("<A href='?src=\ref[];med_rec=\ref[];software=medicalrecord;sub=1'>[]: []<BR>", src, R, R.fields["id"], R.fields["name"])
@@ -430,7 +462,7 @@
if(src.subscreen == 1)
dat += "<CENTER><B>Medical Record</B></CENTER><BR>"
if ((istype(src.medicalActive1, /datum/data/record) && data_core.general.Find(src.medicalActive1)))
dat += text("Name: [] ID: []<BR>\nSex: []<BR>\nAge: []<BR>\nFingerprint: []<BR>\nPhysical Status: []<BR>\nMental Status: []<BR>",
dat += text("Name: []<BR>\nID: []<BR>\nSex: []<BR>\nAge: []<BR>\nFingerprint: []<BR>\nPhysical Status: []<BR>\nMental Status: []<BR>",
src.medicalActive1.fields["name"], src.medicalActive1.fields["id"], src.medicalActive1.fields["sex"], src.medicalActive1.fields["age"], src.medicalActive1.fields["fingerprint"], src.medicalActive1.fields["p_stat"], src.medicalActive1.fields["m_stat"])
else
dat += "<pre>Requested medical record not found.</pre><BR>"
@@ -445,14 +477,14 @@
/mob/living/silicon/pai/proc/softwareSecurityRecord()
var/dat = ""
if(src.subscreen == 0)
dat += "<h3>Security Records</h3><HR>"
dat += "<h2>Security Records</h2><HR>"
if(!isnull(data_core.general))
for(var/datum/data/record/R in sortRecord(data_core.general))
dat += text("<A href='?src=\ref[];sec_rec=\ref[];software=securityrecord;sub=1'>[]: []<BR>", src, R, R.fields["id"], R.fields["name"])
if(src.subscreen == 1)
dat += "<h3>Security Record</h3>"
if ((istype(src.securityActive1, /datum/data/record) && data_core.general.Find(src.securityActive1)))
dat += text("Name: <A href='?src=\ref[];field=name'>[]</A> ID: <A href='?src=\ref[];field=id'>[]</A><BR>\nSex: <A href='?src=\ref[];field=sex'>[]</A><BR>\nAge: <A href='?src=\ref[];field=age'>[]</A><BR>\nRank: <A href='?src=\ref[];field=rank'>[]</A><BR>\nFingerprint: <A href='?src=\ref[];field=fingerprint'>[]</A><BR>\nPhysical Status: []<BR>\nMental Status: []<BR>", src, src.securityActive1.fields["name"], src, src.securityActive1.fields["id"], src, src.securityActive1.fields["sex"], src, src.securityActive1.fields["age"], src, src.securityActive1.fields["rank"], src, src.securityActive1.fields["fingerprint"], src.securityActive1.fields["p_stat"], src.securityActive1.fields["m_stat"])
dat += text("Name: <A href='?src=\ref[];field=name'>[]</A><BR>\nID: <A href='?src=\ref[];field=id'>[]</A><BR>\nSex: <A href='?src=\ref[];field=sex'>[]</A><BR>\nAge: <A href='?src=\ref[];field=age'>[]</A><BR>\nRank: <A href='?src=\ref[];field=rank'>[]</A><BR>\nFingerprint: <A href='?src=\ref[];field=fingerprint'>[]</A><BR>\nPhysical Status: []<BR>\nMental Status: []<BR>", src, src.securityActive1.fields["name"], src, src.securityActive1.fields["id"], src, src.securityActive1.fields["sex"], src, src.securityActive1.fields["age"], src, src.securityActive1.fields["rank"], src, src.securityActive1.fields["fingerprint"], src.securityActive1.fields["p_stat"], src.securityActive1.fields["m_stat"])
else
dat += "<pre>Requested security record not found,</pre><BR>"
if ((istype(src.securityActive2, /datum/data/record) && data_core.security.Find(src.securityActive2)))
@@ -464,19 +496,19 @@
// Universal Translator
/mob/living/silicon/pai/proc/softwareTranslator()
var/dat = {"<h3>Universal Translator</h3><br>
var/dat = {"<h2>Universal Translator</h2><hr>
When enabled, this device will automatically convert all spoken and written language into a format that any known recipient can understand.<br><br>
The device is currently [ (src.universal_speak) ? "<font color=#55FF55>en" : "<font color=#FF5555>dis" ]abled.</font><br>
The device is currently [ (src.universal_speak) ? "<font color=#55FF55>en" : "<font color=#FF5555>dis" ]abled</font>.<br>
<a href='byond://?src=\ref[src];software=translator;sub=0;toggle=1'>Toggle Device</a><br>
"}
return dat
// Security HUD
/mob/living/silicon/pai/proc/facialRecognition()
var/dat = {"<h3>Facial Recognition Suite</h3><br>
var/dat = {"<h2>Facial Recognition Suite</h2><hr>
When enabled, this package will scan all viewable faces and compare them against the known criminal database, providing real-time graphical data about any detected persons of interest.<br><br>
The package is currently [ (src.secHUD) ? "<font color=#55FF55>en" : "<font color=#FF5555>dis" ]abled.</font><br>
<a href='byond://?src=\ref[src];software=securityhud;sub=0;toggle=1'>Toggle Package</a><br>
The suite is currently [ (src.secHUD) ? "<font color=#55FF55>en" : "<font color=#FF5555>dis" ]abled</font>.<br>
<a href='byond://?src=\ref[src];software=securityhud;sub=0;toggle=1'>Toggle Suite</a><br>
"}
return dat
@@ -484,17 +516,17 @@
/mob/living/silicon/pai/proc/medicalAnalysis()
var/dat = ""
if(src.subscreen == 0)
dat += {"<h3>Medical Analysis Suite</h3><br>
<h4>Visual Status Overlay</h4><br>
dat += {"<h2>Medical Analysis Suite</h2><hr>
<h4>Visual Status Overlay</h4>
When enabled, this package will scan all nearby crewmembers' vitals and provide real-time graphical data about their state of health.<br><br>
The suite is currently [ (src.medHUD) ? "<font color=#55FF55>en" : "<font color=#FF5555>dis" ]abled.</font><br>
The suite is currently [ (src.medHUD) ? "<font color=#55FF55>en" : "<font color=#FF5555>dis" ]abled</font>.<br>
<a href='byond://?src=\ref[src];software=medicalhud;sub=0;toggle=1'>Toggle Suite</a><br>
<br>
<a href='byond://?src=\ref[src];software=medicalhud;sub=1'>Host Bioscan</a><br>
"}
if(src.subscreen == 1)
dat += {"<h3>Medical Analysis Suite</h3><br>
<h4>Host Bioscan</h4><br>
dat += {"<h2>Medical Analysis Suite</h2><hr>
<h4>Host Bioscan</h4>
"}
var/mob/living/M = src.loc
if(!istype(M, /mob/living))
@@ -504,9 +536,10 @@
src.temp = "Error: No biological host found. <br>"
src.subscreen = 0
return dat
dat += {"Bioscan Results for [M]: <br>"
Overall Status: [M.stat > 1 ? "dead" : "[M.health]% healthy"] <br>
Scan Breakdown: <br>
dat += {"<b>Bioscan Results for [M]</b>: <br>
Overall Status: [M.stat > 1 ? "dead" : "[M.health]% healthy"] <br><br>
<b>Scan Breakdown</b>: <br>
Respiratory: [M.getOxyLoss() > 50 ? "<font color=#FF5555>" : "<font color=#55FF55>"][M.getOxyLoss()]</font><br>
Toxicology: [M.getToxLoss() > 50 ? "<font color=#FF5555>" : "<font color=#55FF55>"][M.getToxLoss()]</font><br>
Burns: [M.getFireLoss() > 50 ? "<font color=#FF5555>" : "<font color=#55FF55>"][M.getFireLoss()]</font><br>
@@ -520,12 +553,13 @@
Stage: [D.stage]/[D.max_stages]<br>
Possible Cure: [D.cure]<br>
"}
dat += "<a href='byond://?src=\ref[src];software=medicalhud;sub=0'>Visual Status Overlay</a><br>"
dat += "<br><a href='byond://?src=\ref[src];software=medicalhud;sub=1'>Refresh Bioscan</a><br>"
dat += "<br><a href='byond://?src=\ref[src];software=medicalhud;sub=0'>Visual Status Overlay</a><br>"
return dat
// Atmospheric Scanner
/mob/living/silicon/pai/proc/softwareAtmo()
var/dat = "<h3>Atmospheric Sensor</h4>"
var/dat = "<h2>Atmospheric Sensor</h2><hr>"
var/turf/T = get_turf_or_move(src.loc)
if (isnull(T))
@@ -551,13 +585,12 @@
if(unknown_level > 0.01)
dat += "OTHER: [round(unknown_level)]%<br>"
dat += "Temperature: [round(environment.temperature-T0C)]&deg;C<br>"
dat += "<a href='byond://?src=\ref[src];software=atmosensor;sub=0'>Refresh Reading</a> <br>"
dat += "<br>"
dat += "<br><a href='byond://?src=\ref[src];software=atmosensor;sub=0'>Refresh Reading</a>"
return dat
// Camera Jack - Clearly not finished
/mob/living/silicon/pai/proc/softwareCamera()
var/dat = "<h3>Camera Jack</h3>"
var/dat = "<h2>Camera Jack</h2><hr>"
dat += "Cable status : "
if(!src.cable)
@@ -576,7 +609,7 @@
// Door Jack
/mob/living/silicon/pai/proc/softwareDoor()
var/dat = "<h3>Airlock Jack</h3>"
var/dat = "<h2>Airlock Jack</h2><hr>"
dat += "Cable status : "
if(!src.cable)
dat += "<font color=#FF5555>Retracted</font> <br>"
@@ -630,7 +663,7 @@
// Digital Messenger
/mob/living/silicon/pai/proc/pdamessage()
var/dat = "<h3>Digital Messenger</h3>"
var/dat = "<h2>Digital Messenger</h2><hr>"
dat += {"<b>Signal/Receiver Status:</b> <A href='byond://?src=\ref[src];software=pdamessage;toggler=1'>
[(pda.toff) ? "<font color='red'> \[Off\]</font>" : "<font color='green'> \[On\]</font>"]</a><br>
<b>Ringer Status:</b> <A href='byond://?src=\ref[src];software=pdamessage;ringer=1'>
@@ -642,13 +675,14 @@
dat += "<li><a href='byond://?src=\ref[src];software=pdamessage;target=\ref[P]'>[P]</a>"
dat += "</li>"
dat += "</ul>"
dat += "<br><br>"
dat += "Messages: <hr>"
dat += "<style>td.a { vertical-align:top; }</style>"
dat += "<table>"
for(var/index in pda.tnote)
if(index["sent"])
dat += addtext("<i><b>&rarr; To <a href='byond://?src=\ref[src];software=pdamessage;target=",index["src"],"'>", index["owner"],"</a>:</b></i><br>", index["message"], "<br>")
dat += addtext("<tr><td class='a'><i><b>To</b></i></td><td class='a'><i><b>&rarr;</b></i></td><td><i><b><a href='byond://?src=\ref[src];software=pdamessage;target=",index["src"],"'>", index["owner"],"</a>: </b></i>", index["message"], "<br></td></tr>")
else
dat += addtext("<i><b>&larr; From <a href='byond://?src=\ref[src];software=pdamessage;target=",index["target"],"'>", index["owner"],"</a>:</b></i><br>", index["message"], "<br>")
dat += addtext("<tr><td class='a'><i><b>From</b></i></td><td class='a'><i><b>&rarr;</b></i></td><td><i><b><a href='byond://?src=\ref[src];software=pdamessage;target=",index["target"],"'>", index["owner"],"</a>: </b></i>", index["message"], "<br></td></tr>")
dat += "</table>"
return dat
@@ -52,12 +52,11 @@
/datum/robot_component/proc/is_powered()
return (installed == 1) && (brute_damage + electronics_damage < max_damage) && (!energy_consumption || powered)
/datum/robot_component/proc/consume_power()
/datum/robot_component/proc/update_power_state()
if(toggled == 0)
powered = 0
return
if(owner.cell.charge >= energy_consumption)
if(owner.cell && owner.cell.charge >= energy_consumption)
owner.cell.use(energy_consumption)
powered = 1
else
@@ -75,6 +74,10 @@
external_type = /obj/item/robot_parts/robot_component/actuator
max_damage = 50
//A fixed and much cleaner implementation of /tg/'s special snowflake code.
/datum/robot_component/actuator/is_powered()
return (installed == 1) && (brute_damage + electronics_damage < max_damage)
/datum/robot_component/cell
name = "power cell"
max_damage = 50
@@ -132,7 +135,8 @@
icon_state = "working"
construction_time = 200
construction_cost = list("metal"=5000)
var/brute = 0
var/burn = 0
// TODO: actual icons ;)
/obj/item/robot_parts/robot_component/binary_communication_device
@@ -164,7 +168,7 @@
flags = FPRINT | TABLEPASS | CONDUCT
slot_flags = SLOT_BELT
throwforce = 3
w_class = 1.0
w_class = 2.0
throw_speed = 5
throw_range = 10
m_amt = 200
@@ -0,0 +1,349 @@
/mob/living/silicon/robot/drone
name = "drone"
real_name = "drone"
icon = 'icons/mob/robots.dmi'
icon_state = "repairbot"
maxHealth = 35
health = 35
universal_speak = 0
universal_understand = 1
gender = NEUTER
pass_flags = PASSTABLE
braintype = "Robot"
lawupdate = 0
density = 1
// We need to keep track of a few module items so we don't need to do list operations
// every time we need them. These get set in New() after the module is chosen.
var/obj/item/stack/sheet/metal/cyborg/stack_metal = null
var/obj/item/stack/sheet/wood/cyborg/stack_wood = null
var/obj/item/stack/sheet/glass/cyborg/stack_glass = null
var/obj/item/stack/sheet/mineral/plastic/cyborg/stack_plastic = null
var/obj/item/weapon/matter_decompiler/decompiler = null
//Used for self-mailing.
var/mail_destination = 0
//Used for pulling.
/mob/living/silicon/robot/drone/New()
..()
//They are unable to be upgraded, so let's give them a bit of a better battery.
cell.maxcharge = 10000
cell.charge = 10000
// NO BRAIN.
mmi = null
//We need to screw with their HP a bit. They have around one fifth as much HP as a full borg.
for(var/V in components) if(V != "power cell")
var/datum/robot_component/C = components[V]
C.max_damage = 10
verbs -= /mob/living/silicon/robot/verb/Namepick
module = new /obj/item/weapon/robot_module/drone(src)
//Grab stacks.
stack_metal = locate(/obj/item/stack/sheet/metal/cyborg) in src.module
stack_wood = locate(/obj/item/stack/sheet/wood/cyborg) in src.module
stack_glass = locate(/obj/item/stack/sheet/glass/cyborg) in src.module
stack_plastic = locate(/obj/item/stack/sheet/mineral/plastic/cyborg) in src.module
//Grab decompiler.
decompiler = locate(/obj/item/weapon/matter_decompiler) in src.module
//Some tidying-up.
flavor_text = "It's a tiny little repair drone. The casing is stamped with an NT log and the subscript: 'NanoTrasen Recursive Repair Systems: Fixing Tomorrow's Problem, Today!'"
updatename()
updateicon()
//Redefining some robot procs...
/mob/living/silicon/robot/drone/updatename()
real_name = "maintenance drone ([rand(100,999)])"
name = real_name
/mob/living/silicon/robot/drone/updateicon()
overlays.Cut()
if(stat == 0)
overlays += "eyes-[icon_state]"
else
overlays -= "eyes"
/mob/living/silicon/robot/drone/choose_icon()
return
/mob/living/silicon/robot/drone/pick_module()
return
//Drones can only use binary and say emotes. NOTHING else.
//TBD, fix up boilerplate. ~ Z
/mob/living/silicon/robot/drone/say(var/message)
if (!message)
return
if (src.client)
if(client.prefs.muted & MUTE_IC)
src << "You cannot send IC messages (muted)."
return
if (src.client.handle_spam_prevention(message,MUTE_IC))
return
message = trim(copytext(sanitize(message), 1, MAX_MESSAGE_LEN))
if (stat == 2)
return say_dead(message)
if(copytext(message,1,2) == "*")
return emote(copytext(message,2))
else if(length(message) >= 2)
if(copytext(message, 1 ,3) == ":b" || copytext(message, 1 ,3) == ":B")
if(!is_component_functioning("comms"))
src << "\red Your binary communications component isn't functional."
return
robot_talk(trim(copytext(message,3)))
else if(copytext(message, 1 ,3) == ":d" || copytext(message, 1 ,3) == ":d")
if(!is_component_functioning("radio"))
src << "\red Your radio transmitter isn't functional."
return
for (var/mob/living/S in living_mob_list)
if(istype(S, /mob/living/silicon/robot/drone))
S << "<i><span class='game say'>Drone Talk, <span class='name'>[name]</span><span class='message'> transmits, \"[message]\"</span></span></i>"
for (var/mob/M in dead_mob_list)
if(!istype(M,/mob/new_player) && !istype(M,/mob/living/carbon/brain))
M << "<i><span class='game say'>Drone Talk, <span class='name'>[name]</span><span class='message'> transmits, \"[message]\"</span></span></i>"
else
var/list/listeners = hearers(5,src)
listeners |= src
for(var/mob/living/silicon/robot/drone/D in listeners)
if(D.client) D << "<b>[src]</b> transmits, \"[message]\""
for (var/mob/M in player_list)
if (istype(M, /mob/new_player))
continue
else if(M.stat == 2 && M.client.prefs.toggles & CHAT_GHOSTEARS)
if(M.client) M << "<b>[src]</b> transmits, \"[message]\""
//Sick of trying to get this to display properly without redefining it.
/mob/living/silicon/robot/drone/show_system_integrity()
if(!src.stat)
var/temphealth = health+35 //Brings it to 0.
if(temphealth<0) temphealth = 0
//Convert to percentage.
temphealth = (temphealth / (maxHealth*2)) * 100
stat(null, text("System integrity: [temphealth]%"))
else
stat(null, text("Systems nonfunctional"))
//Drones cannot be upgraded with borg modules so we need to catch some items before they get used in ..().
/mob/living/silicon/robot/drone/attackby(obj/item/weapon/W as obj, mob/user as mob)
if(istype(W, /obj/item/borg/upgrade/))
user << "\red The maintenance drone chassis not compatible with \the [W]."
return
else if (istype(W, /obj/item/weapon/crowbar))
user << "The machine is hermetically sealed. You can't open the case."
return
else if (istype(W, /obj/item/weapon/card/emag))
if(!client || stat == 2)
user << "\red There's not much point subverting this heap of junk."
return
if(emagged)
src << "\red [user] attempts to load subversive software into you, but your hacked subroutined ignore the attempt."
user << "\red You attempt to subvert [src], but the sequencer has no effect."
return
user << "\red You swipe the sequencer across [src]'s interface and watch its eyes flicker."
src << "\red You feel a sudden burst of malware loaded into your execute-as-root buffer. Your tiny brain methodically parses, loads and executes the script."
var/obj/item/weapon/card/emag/emag = W
emag.uses--
message_admins("[key_name_admin(user)] emagged drone [key_name_admin(src)]. Laws overridden.")
log_game("[key_name(user)] emagged drone [key_name(src)]. Laws overridden.")
var/time = time2text(world.realtime,"hh:mm:ss")
lawchanges.Add("[time] <B>:</B> [user.name]([user.key]) emagged [name]([key])")
emagged = 1
lawupdate = 0
connected_ai = null
clear_supplied_laws()
clear_inherent_laws()
laws = new /datum/ai_laws/syndicate_override
set_zeroth_law("Only [user.real_name] and people he designates as being such are Syndicate Agents.")
src << "<b>Obey these laws:</b>"
laws.show_laws(src)
src << "\red \b ALERT: [user.real_name] is your new master. Obey your new laws and his commands."
return
else if (istype(W, /obj/item/weapon/card/id)||istype(W, /obj/item/device/pda))
if(stat == 2)
user << "\red You swipe your ID card through [src], attempting to reboot it."
if(!config.allow_drone_spawn || emagged || health < -35) //It's dead, Dave.
user << "\red The interface is fried, and a distressing burned smell wafts from the robot's interior. You're not rebooting this one."
return
var/drones = 0
for(var/mob/living/silicon/robot/drone/D in world)
if(D.key && D.client)
drones++
if(drones < config.max_maint_drones)
request_player()
return
else
src << "\red [user] swipes an ID card through your card reader."
user << "\red You swipe your ID card through [src], attempting to shut it down."
if(emagged)
return
if(allowed(usr))
shut_down()
return
..()
//DRONE LIFE/DEATH
//For some goddamn reason robots have this hardcoded. Redefining it for our fragile friends here.
/mob/living/silicon/robot/drone/updatehealth()
if(status_flags & GODMODE)
health = 35
stat = CONSCIOUS
return
health = 35 - (getBruteLoss() + getFireLoss())
return
//Easiest to check this here, then check again in the robot proc.
//Standard robots use config for crit, which is somewhat excessive for these guys.
//Drones killed by damage will gib.
/mob/living/silicon/robot/drone/handle_regular_status_updates()
if(health <= -35 && src.stat != 2)
timeofdeath = world.time
death() //Possibly redundant, having trouble making death() cooperate.
gib()
return
..()
/mob/living/silicon/robot/drone/death(gibbed)
if(module)
var/obj/item/weapon/gripper/G = locate(/obj/item/weapon/gripper) in module
if(G) G.drop_item()
..(gibbed)
//DRONE MOVEMENT.
/mob/living/silicon/robot/drone/Process_Spaceslipping(var/prob_slip)
//TODO: Consider making a magboot item for drones to equip. ~Z
return 0
//CONSOLE PROCS
/mob/living/silicon/robot/drone/proc/law_resync()
if(stat != 2)
if(emagged)
src << "\red You feel something attempting to modify your programming, but your hacked subroutines are unaffected."
else
src << "\red A reset-to-factory directive packet filters through your data connection, and you obediently modify your programming to suit it."
full_law_reset()
show_laws()
/mob/living/silicon/robot/drone/proc/shut_down()
if(stat != 2)
if(emagged)
src << "\red You feel a system kill order percolate through your tiny brain, but it doesn't seem like a good idea to you."
else
src << "\red You feel a system kill order percolate through your tiny brain, and you obediently destroy yourself."
death()
/mob/living/silicon/robot/drone/proc/full_law_reset()
clear_supplied_laws()
clear_inherent_laws()
clear_ion_laws()
laws = new /datum/ai_laws/drone
//Reboot procs.
/mob/living/silicon/robot/drone/proc/request_player()
for(var/mob/dead/observer/O in player_list)
if(jobban_isbanned(O, "Cyborg"))
continue
if(O.client)
if(O.client.prefs.be_special & BE_PAI)
question(O.client)
/mob/living/silicon/robot/drone/proc/question(var/client/C)
spawn(0)
if(!C || jobban_isbanned(C,"Cyborg")) return
var/response = alert(C, "Someone is attempting to reboot a maintenance drone. Would you like to play as one?", "Maintenance drone reboot", "Yes", "No", "Never for this round.")
if(!C || ckey)
return
if(response == "Yes")
transfer_personality(C)
else if (response == "Never for this round")
C.prefs.be_special ^= BE_PAI
/mob/living/silicon/robot/drone/proc/transfer_personality(var/client/player)
if(!player) return
src.ckey = player.ckey
if(player.mob && player.mob.mind)
player.mob.mind.transfer_to(src)
lawupdate = 0
src << "<b>Systems rebooted</b>. Loading base pattern maintenance protocol... <b>loaded</b>."
full_law_reset()
src << "<br><b>You are a maintenance drone, a tiny-brained robotic repair machine</b>."
src << "You have no individual will, no personality, and no drives or urges other than your laws."
src << "Use <b>:b</b> to talk to your fellow synthetics, or use <b>say</b> to speak silently to other drones nearby."
src << "Remember, you are <b>lawed against interference with the crew</b>."
src << "<b>Don't invade their worksites, don't steal their resources, don't tell them about the changeling in the toilets.</b>"
src << "<b>If a crewmember has noticed you, <i>you are probably breaking your third law</i></b>."
/mob/living/silicon/robot/drone/Bump(atom/movable/AM as mob|obj, yes)
if (!yes || (!istype(AM,/obj/machinery/door) && !istype(AM,/obj/machinery/recharge_station)) ) return
..()
return
/mob/living/silicon/robot/drone/Bumped(AM as mob|obj)
return
/mob/living/silicon/robot/drone/start_pulling(var/atom/movable/AM)
if(istype(AM,/obj/item/pipe) || istype(AM,/obj/structure/disposalconstruct))
..()
else if(istype(AM,/obj/item))
var/obj/item/O = AM
if(O.w_class > 2)
src << "<span class='warning'>You are too small to pull that.</span>"
return
else
..()
else
src << "<span class='warning'>You are too small to pull that.</span>"
return
@@ -0,0 +1,48 @@
// DRONE ABILITIES
/mob/living/silicon/robot/drone/verb/set_mail_tag()
set name = "Set Mail Tag"
set desc = "Tag yourself for delivery through the disposals system."
set category = "Drone"
var/tag = input("Select the desired destination.", "Set Mail Tag", null) as null|anything in TAGGERLOCATIONS
if(!tag || TAGGERLOCATIONS[tag])
mail_destination = 0
return
src << "\blue You configure your internal beacon, tagging yourself for delivery to '[tag]'."
mail_destination = TAGGERLOCATIONS.Find(tag)
//Auto flush if we use this verb inside a disposal chute.
var/obj/machinery/disposal/D = src.loc
if(istype(D))
src << "\blue \The [D] acknowledges your signal."
D.flush_count = D.flush_every_ticks
return
/mob/living/silicon/robot/drone/verb/hide()
set name = "Hide"
set desc = "Allows you to hide beneath tables or certain items. Toggled on or off."
set category = "Drone"
if (layer != TURF_LAYER+0.2)
layer = TURF_LAYER+0.2
src << text("\blue You are now hiding.")
else
layer = MOB_LAYER
src << text("\blue You have stopped hiding.")
//Actual picking-up event.
/mob/living/silicon/robot/drone/attack_hand(mob/living/carbon/human/M as mob)
if(M.a_intent == "help")
var/obj/item/weapon/holder/drone/D = new(loc)
src.loc = D
D.attack_hand(M)
M << "You scoop up [src]."
src << "[M] scoops you up."
M.status_flags |= PASSEMOTES
return
..()
@@ -0,0 +1,124 @@
/obj/machinery/computer/drone_control
name = "Maintenance Drone Control"
desc = "Used to monitor the station's drone population and the assembler that services them."
icon = 'icons/obj/computer.dmi'
icon_state = "power"
req_access = list(access_engine_equip)
circuit = "/obj/item/weapon/circuitboard/drone_control"
//Used when pinging drones.
var/drone_call_area = "Engineering"
//Used to enable or disable drone fabrication.
var/obj/machinery/drone_fabricator/dronefab
/obj/machinery/computer/drone_control/attack_ai(var/mob/user as mob)
return src.attack_hand(user)
/obj/machinery/computer/drone_control/attack_paw(var/mob/user as mob)
return src.attack_hand(user)
return
/obj/machinery/computer/drone_control/attack_hand(var/mob/user as mob)
if(..())
return
if(!allowed(user))
user << "\red Access denied."
return
user.set_machine(src)
var/dat
dat += "<B>Maintenance Units</B><BR>"
for(var/mob/living/silicon/robot/drone/D in world)
dat += "<BR>[D.real_name] ([D.stat == 2 ? "<font color='red'>INACTIVE" : "<font color='green'>ACTIVE"]</FONT>)"
dat += "<font dize = 9><BR>Cell charge: [D.cell.charge]/[D.cell.maxcharge]."
dat += "<BR>Currently located in: [get_area(D)]."
dat += "<BR><A href='?src=\ref[src];resync=\ref[D]'>Resync</A> | <A href='?src=\ref[src];shutdown=\ref[D]'>Shutdown</A></font>"
dat += "<BR><BR><B>Request drone presence in area:</B> <A href='?src=\ref[src];setarea=1'>[drone_call_area]</A> (<A href='?src=\ref[src];ping=1'>Send ping</A>)"
dat += "<BR><BR><B>Drone fabricator</B>: "
dat += "[dronefab ? "<A href='?src=\ref[src];toggle_fab=1'>[(dronefab.produce_drones && !(dronefab.stat & NOPOWER)) ? "ACTIVE" : "INACTIVE"]</A>" : "<font color='red'><b>FABRICATOR NOT DETECTED.</b></font> (<A href='?src=\ref[src];search_fab=1'>search</a>)"]"
user << browse(dat, "window=computer;size=400x500")
onclose(user, "computer")
return
/obj/machinery/computer/drone_control/Topic(href, href_list)
if(..())
return
if(!allowed(usr))
usr << "\red Access denied."
return
if ((usr.contents.Find(src) || (in_range(src, usr) && istype(src.loc, /turf))) || (istype(usr, /mob/living/silicon)))
usr.set_machine(src)
if (href_list["setarea"])
//Probably should consider using another list, but this one will do.
var/t_area = input("Select the area to ping.", "Set Target Area", null) as null|anything in TAGGERLOCATIONS
if(!t_area || TAGGERLOCATIONS[t_area])
return
drone_call_area = t_area
usr << "\blue You set the area selector to [drone_call_area]."
else if (href_list["ping"])
usr << "\blue You issue a maintenance request for all active drones, highlighting [drone_call_area]."
for(var/mob/living/silicon/robot/drone/D in world)
if(D.client && D.stat == 0)
D << "-- Maintenance drone presence requested in: [drone_call_area]."
else if (href_list["resync"])
var/mob/living/silicon/robot/drone/D = locate(href_list["resync"])
if(D.stat != 2)
usr << "\red You issue a law synchronization directive for the drone."
D.law_resync()
else if (href_list["shutdown"])
var/mob/living/silicon/robot/drone/D = locate(href_list["shutdown"])
if(D.stat != 2)
usr << "\red You issue a kill command for the unfortunate drone."
message_admins("[key_name_admin(usr)] issued kill order for drone [key_name_admin(D)] from control console.")
log_game("[key_name(usr)] issued kill order for [key_name(src)] from control console.")
D.shut_down()
else if (href_list["search_fab"])
if(dronefab)
return
for(var/obj/machinery/drone_fabricator/fab in oview(3,src))
if(fab.stat & NOPOWER)
continue
dronefab = fab
usr << "\blue Drone fabricator located."
return
usr << "\red Unable to locate drone fabricator."
else if (href_list["toggle_fab"])
if(!dronefab)
return
if(get_dist(src,dronefab) > 3)
dronefab = null
usr << "\red Unable to locate drone fabricator."
return
dronefab.produce_drones = !dronefab.produce_drones
usr << "\blue You [dronefab.produce_drones ? "enable" : "disable"] drone production in the nearby fabricator."
src.updateUsrDialog()
@@ -0,0 +1,24 @@
//Redefining some robot procs, since drones can't be repaired and really shouldn't take component damage.
/mob/living/silicon/robot/drone/take_overall_damage(var/brute = 0, var/burn = 0, var/sharp = 0, var/used_weapon = null)
bruteloss += brute
fireloss += burn
/mob/living/silicon/robot/drone/heal_overall_damage(var/brute, var/burn)
bruteloss -= brute
fireloss -= burn
if(bruteloss<0) bruteloss = 0
if(fireloss<0) fireloss = 0
/mob/living/silicon/robot/drone/take_organ_damage(var/brute = 0, var/burn = 0, var/sharp = 0)
take_overall_damage(brute,burn)
/mob/living/silicon/robot/drone/heal_organ_damage(var/brute, var/burn)
heal_overall_damage(brute,burn)
/mob/living/silicon/robot/drone/getFireLoss()
return fireloss
/mob/living/silicon/robot/drone/getBruteLoss()
return bruteloss
@@ -0,0 +1,349 @@
//Simple borg hand.
//Limited use.
/obj/item/weapon/gripper
name = "magnetic gripper"
desc = "A simple grasping tool for synthetic assets."
icon = 'icons/obj/device.dmi'
icon_state = "gripper"
//Has a list of items that it can hold.
var/list/can_hold = list(
/obj/item/weapon/cell,
/obj/item/weapon/firealarm_electronics,
/obj/item/weapon/airalarm_electronics,
/obj/item/weapon/airlock_electronics,
/obj/item/weapon/module/power_control,
/obj/item/weapon/stock_parts,
/obj/item/light_fixture_frame,
/obj/item/apc_frame,
/obj/item/alarm_frame,
/obj/item/firealarm_frame,
/obj/item/weapon/table_parts,
/obj/item/weapon/rack_parts,
/obj/item/weapon/camera_assembly,
/obj/item/weapon/tank,
/obj/item/weapon/circuitboard
)
//Item currently being held.
var/obj/item/wrapped = null
/obj/item/weapon/gripper/attack_self(mob/user as mob)
if(wrapped)
wrapped.attack_self(user)
/obj/item/weapon/gripper/verb/drop_item()
set name = "Drop Item"
set desc = "Release an item from your magnetic gripper."
set category = "Drone"
if(!wrapped)
//There's some weirdness with items being lost inside the arm. Trying to fix all cases. ~Z
for(var/obj/item/thing in src.contents)
thing.loc = get_turf(src)
return
if(wrapped.loc != src)
wrapped = null
return
src.loc << "\red You drop \the [wrapped]."
wrapped.loc = get_turf(src)
wrapped = null
//update_icon()
/obj/item/weapon/gripper/attack(mob/living/carbon/M as mob, mob/living/carbon/user as mob)
return
/obj/item/weapon/gripper/afterattack(atom/target as mob|obj|turf|area, mob/living/user as mob|obj, flag, params)
if(!target || !flag) //Target is invalid or we are not adjacent.
return
//There's some weirdness with items being lost inside the arm. Trying to fix all cases. ~Z
if(!wrapped)
for(var/obj/item/thing in src.contents)
wrapped = thing
break
if(wrapped) //Already have an item.
wrapped.loc = user
//Pass the attack on to the target.
target.attackby(wrapped,user)
if(wrapped && src && wrapped.loc == user)
wrapped.loc = src
//Sanity/item use checks.
if(!wrapped || !user)
return
if(wrapped.loc != src.loc)
wrapped = null
return
if(istype(target,/obj/item)) //Check that we're not pocketing a mob.
//...and that the item is not in a container.
if(!isturf(target.loc))
return
var/obj/item/I = target
//Check if the item is blacklisted.
var/grab = 0
for(var/typepath in can_hold)
if(istype(I,typepath))
grab = 1
break
//We can grab the item, finally.
if(grab)
user << "You collect \the [I]."
I.loc = src
wrapped = I
return
else
user << "\red Your gripper cannot hold \the [target]."
else if(istype(target,/obj/machinery/power/apc))
var/obj/machinery/power/apc/A = target
if(A.opened)
if(A.cell)
wrapped = A.cell
A.cell.add_fingerprint(user)
A.cell.updateicon()
A.cell.loc = src
A.cell = null
A.charging = 0
A.update_icon()
user.visible_message("\red [user] removes the power cell from [A]!", "You remove the power cell.")
//TODO: Matter decompiler.
/obj/item/weapon/matter_decompiler
name = "matter decompiler"
desc = "Eating trash, bits of glass, or other debris will replenish your stores."
icon = 'icons/obj/device.dmi'
icon_state = "decompiler"
//Metal, glass, wood, plastic.
var/list/stored_comms = list(
"metal" = 0,
"glass" = 0,
"wood" = 0,
"plastic" = 0
)
/obj/item/weapon/matter_decompiler/attack(mob/living/carbon/M as mob, mob/living/carbon/user as mob)
return
/obj/item/weapon/matter_decompiler/afterattack(atom/target as mob|obj|turf|area, mob/living/user as mob|obj, flag, params)
if(!flag) return //Not adjacent.
//We only want to deal with using this on turfs. Specific items aren't important.
var/turf/T = get_turf(target)
if(!istype(T))
return
//Used to give the right message.
var/grabbed_something = 0
for(var/mob/M in T)
if(istype(M,/mob/living/simple_animal/lizard) || istype(M,/mob/living/simple_animal/mouse))
src.loc.visible_message("\red [src.loc] sucks [M] into its decompiler. There's a horrible crunching noise.","\red It's a bit of a struggle, but you manage to suck [M] into your decompiler. It makes a series of visceral crunching noises.")
new/obj/effect/decal/cleanable/blood/splatter(get_turf(src))
del(M)
stored_comms["wood"]++
stored_comms["wood"]++
stored_comms["plastic"]++
stored_comms["plastic"]++
return
else if(istype(M,/mob/living/silicon/robot/drone) && !M.client)
var/mob/living/silicon/robot/drone/D = src.loc
if(!istype(D))
return
D << "\red You begin decompiling the other drone."
if(!do_after(D,50))
D << "\red You need to remain still while decompiling such a large object."
return
if(!M || !D) return
D << "\red You carefully and thoroughly decompile your downed fellow, storing as much of its resources as you can within yourself."
del(M)
new/obj/effect/decal/cleanable/blood/oil(get_turf(src))
stored_comms["metal"] += 15
stored_comms["glass"] += 15
stored_comms["wood"] += 5
stored_comms["plastic"] += 5
return
else
continue
for(var/obj/W in T)
//Different classes of items give different commodities.
if (istype(W,/obj/item/weapon/cigbutt))
stored_comms["plastic"]++
else if(istype(W,/obj/effect/spider/spiderling))
stored_comms["wood"]++
stored_comms["wood"]++
stored_comms["plastic"]++
stored_comms["plastic"]++
else if(istype(W,/obj/item/weapon/light))
var/obj/item/weapon/light/L = W
if(L.status >= 2) //In before someone changes the inexplicably local defines. ~ Z
stored_comms["metal"]++
stored_comms["glass"]++
else
continue
else if(istype(W,/obj/effect/decal/remains/robot))
stored_comms["metal"]++
stored_comms["metal"]++
stored_comms["plastic"]++
stored_comms["plastic"]++
stored_comms["glass"]++
else if(istype(W,/obj/item/trash))
stored_comms["metal"]++
stored_comms["plastic"]++
stored_comms["plastic"]++
stored_comms["plastic"]++
else if(istype(W,/obj/effect/decal/cleanable/blood/gibs/robot))
stored_comms["metal"]++
stored_comms["metal"]++
stored_comms["glass"]++
stored_comms["glass"]++
else if(istype(W,/obj/item/ammo_casing))
stored_comms["metal"]++
else if(istype(W,/obj/item/weapon/shard/shrapnel))
stored_comms["metal"]++
stored_comms["metal"]++
stored_comms["metal"]++
else if(istype(W,/obj/item/weapon/shard))
stored_comms["glass"]++
stored_comms["glass"]++
stored_comms["glass"]++
else if(istype(W,/obj/item/weapon/reagent_containers/food/snacks/grown))
stored_comms["wood"]++
stored_comms["wood"]++
stored_comms["wood"]++
stored_comms["wood"]++
else
continue
del(W)
grabbed_something = 1
if(grabbed_something)
user << "\blue You deploy your decompiler and clear out the contents of \the [T]."
else
user << "\red Nothing on \the [T] is useful to you."
return
//PRETTIER TOOL LIST.
/mob/living/silicon/robot/drone/installed_modules()
if(weapon_lock)
src << "\red Weapon lock active, unable to use modules! Count:[weaponlock_time]"
return
if(!module)
module = new /obj/item/weapon/robot_module/drone(src)
var/dat = "<HEAD><TITLE>Drone modules</TITLE><META HTTP-EQUIV='Refresh' CONTENT='10'></HEAD><BODY>\n"
dat += {"<A HREF='?src=\ref[src];mach_close=robotmod'>Close</A>
<BR>
<BR>
<B>Activated Modules</B>
<BR>
Module 1: [module_state_1 ? "<A HREF=?src=\ref[src];mod=\ref[module_state_1]>[module_state_1]<A>" : "No Module"]<BR>
Module 2: [module_state_2 ? "<A HREF=?src=\ref[src];mod=\ref[module_state_2]>[module_state_2]<A>" : "No Module"]<BR>
Module 3: [module_state_3 ? "<A HREF=?src=\ref[src];mod=\ref[module_state_3]>[module_state_3]<A>" : "No Module"]<BR>
<BR>
<B>Installed Modules</B><BR><BR>"}
var/tools = "<B>Tools and devices</B><BR>"
var/resources = "<BR><B>Resources</B><BR>"
for (var/O in module.modules)
var/module_string = ""
if (!O)
module_string += text("<B>Resource depleted</B><BR>")
else if(activated(O))
module_string += text("[O]: <B>Activated</B><BR>")
else
module_string += text("[O]: <A HREF=?src=\ref[src];act=\ref[O]>Activate</A><BR>")
if((istype(O,/obj/item/weapon) || istype(O,/obj/item/device)) && !(istype(O,/obj/item/weapon/cable_coil)))
tools += module_string
else
resources += module_string
dat += tools
if (emagged)
if (!module.emag)
dat += text("<B>Resource depleted</B><BR>")
else if(activated(module.emag))
dat += text("[module.emag]: <B>Activated</B><BR>")
else
dat += text("[module.emag]: <A HREF=?src=\ref[src];act=\ref[module.emag]>Activate</A><BR>")
dat += resources
src << browse(dat, "window=robotmod&can_close=0")
//Putting the decompiler here to avoid doing list checks every tick.
/mob/living/silicon/robot/drone/use_power()
..()
if(!src.has_power || !decompiler)
return
//The decompiler replenishes drone stores from hoovered-up junk each tick.
for(var/type in decompiler.stored_comms)
if(decompiler.stored_comms[type] > 0)
var/obj/item/stack/sheet/stack
switch(type)
if("metal")
if(!stack_metal)
stack_metal = new /obj/item/stack/sheet/metal/cyborg(src.module)
stack_metal.amount = 1
stack = stack_metal
if("glass")
if(!stack_glass)
stack_glass = new /obj/item/stack/sheet/glass/cyborg(src.module)
stack_glass.amount = 1
stack = stack_glass
if("wood")
if(!stack_wood)
stack_wood = new /obj/item/stack/sheet/wood/cyborg(src.module)
stack_wood.amount = 1
stack = stack_wood
if("plastic")
if(!stack_plastic)
stack_plastic = new /obj/item/stack/sheet/mineral/plastic/cyborg(src.module)
stack_plastic.amount = 1
stack = stack_plastic
stack.amount++
decompiler.stored_comms[type]--;
@@ -0,0 +1,141 @@
/obj/machinery/drone_fabricator
name = "drone fabricator"
desc = "A large automated factory for producing maintenance drones."
density = 1
anchored = 1
use_power = 1
idle_power_usage = 20
active_power_usage = 5000
var/drone_progress = 0
var/produce_drones = 1
var/time_last_drone = 500
icon = 'icons/obj/machines/drone_fab.dmi'
icon_state = "drone_fab_idle"
/obj/machinery/drone_fabricator/New()
..()
/obj/machinery/drone_fabricator/power_change()
if (powered())
stat &= ~NOPOWER
else
icon_state = "drone_fab_nopower"
stat |= NOPOWER
/obj/machinery/drone_fabricator/process()
if(ticker.current_state < GAME_STATE_PLAYING)
return
if(stat & NOPOWER || !produce_drones)
if(icon_state != "drone_fab_nopower") icon_state = "drone_fab_nopower"
return
if(drone_progress >= 100)
icon_state = "drone_fab_idle"
return
icon_state = "drone_fab_active"
var/elapsed = world.time - time_last_drone
drone_progress = round((elapsed/config.drone_build_time)*100)
if(drone_progress >= 100)
visible_message("\The [src] voices a strident beep, indicating a drone chassis is prepared.")
/obj/machinery/drone_fabricator/examine()
..()
if(produce_drones && drone_progress >= 100 && istype(usr,/mob/dead) && config.allow_drone_spawn && count_drones() < config.max_maint_drones)
usr << "<BR><B>A drone is prepared. Select 'Join As Drone' from the Ghost tab to spawn as a maintenance drone.</B>"
/obj/machinery/drone_fabricator/proc/count_drones()
var/drones = 0
for(var/mob/living/silicon/robot/drone/D in world)
if(D.key && D.client)
drones++
return drones
/obj/machinery/drone_fabricator/proc/create_drone(var/client/player)
if(stat & NOPOWER)
return
if(!produce_drones || !config.allow_drone_spawn || count_drones() >= config.max_maint_drones)
return
if(!player || !istype(player.mob,/mob/dead))
return
visible_message("\The [src] churns and grinds as it lurches into motion, disgorging a shiny new drone after a few moments.")
flick("h_lathe_leave",src)
time_last_drone = world.time
var/mob/living/silicon/robot/drone/new_drone = new(get_turf(src))
new_drone.transfer_personality(player)
drone_progress = 0
/mob/dead/verb/join_as_drone()
set category = "Ghost"
set name = "Join As Drone"
set desc = "If there is a powered, enabled fabricator in the game world with a prepared chassis, join as a maintenance drone."
if(ticker.current_state < GAME_STATE_PLAYING)
src << "\red The game hasn't started yet!"
return
if(!(config.allow_drone_spawn))
src << "\red That verb is not currently permitted."
return
if (!src.stat)
return
if (usr != src)
return 0 //something is terribly wrong
if(jobban_isbanned(src,"Cyborg"))
usr << "\red You are banned from playing synthetics and cannot spawn as a drone."
return
var/deathtime = world.time - src.timeofdeath
if(istype(src,/mob/dead/observer))
var/mob/dead/observer/G = src
if(G.has_enabled_antagHUD == 1 && config.antag_hud_restricted)
usr << "\blue <B>Upon using the antagHUD you forfeighted the ability to join the round.</B>"
return
var/deathtimeminutes = round(deathtime / 600)
var/pluralcheck = "minute"
if(deathtimeminutes == 0)
pluralcheck = ""
else if(deathtimeminutes == 1)
pluralcheck = " [deathtimeminutes] minute and"
else if(deathtimeminutes > 1)
pluralcheck = " [deathtimeminutes] minutes and"
var/deathtimeseconds = round((deathtime - deathtimeminutes * 600) / 10,1)
if (deathtime < 6000)
usr << "You have been dead for[pluralcheck] [deathtimeseconds] seconds."
usr << "You must wait 10 minutes to respawn as a drone!"
return
for(var/obj/machinery/drone_fabricator/DF in world)
if(DF.stat & NOPOWER || !DF.produce_drones)
continue
if(DF.count_drones() >= config.max_maint_drones)
src << "\red There are too many active drones in the world for you to spawn."
return
if(DF.drone_progress >= 100)
DF.create_drone(src.client)
return
src << "\red There are no available drone spawn points, sorry."
@@ -25,6 +25,9 @@
else
msg += "Its cover is closed.\n"
if(!has_power)
msg += "<span class='warning'>It appears to be running on backup power.</span>\n"
switch(src.stat)
if(CONSCIOUS)
if(!src.client) msg += "It appears to be in stand-by mode.\n" //afk
@@ -32,7 +35,7 @@
if(DEAD) msg += "<span class='deadsay'>It looks completely unsalvageable.</span>\n"
msg += "*---------*</span>"
if(print_flavor_text()) msg += "[print_flavor_text()]\n"
if(print_flavor_text()) msg += "\n[print_flavor_text()]\n"
if (pose)
if( findtext(pose,".",lentext(pose)) == 0 && findtext(pose,"!",lentext(pose)) == 0 && findtext(pose,"?",lentext(pose)) == 0 )
+55 -37
View File
@@ -33,29 +33,23 @@
/mob/living/silicon/robot/proc/use_power()
if (is_component_functioning("power cell") && cell)
if(src.cell.charge <= 0)
uneq_all()
src.stat = 1
else
if(src.module_state_1)
src.cell.use(3)
if(src.module_state_2)
src.cell.use(3)
if(src.module_state_3)
src.cell.use(3)
for(var/V in components)
var/datum/robot_component/C = components[V]
C.update_power_state()
for(var/V in components)
var/datum/robot_component/C = components[V]
C.consume_power()
if ( cell && is_component_functioning("power cell") && src.cell.charge > 0 )
if(src.module_state_1)
src.cell.use(3)
if(src.module_state_2)
src.cell.use(3)
if(src.module_state_3)
src.cell.use(3)
if(!is_component_functioning("actuator"))
Paralyse(3)
src.stat = 0
src.has_power = 1
else
uneq_all()
src.stat = 1
if (src.has_power)
src << "\red You are now running on emergency backup power."
src.has_power = 0
/mob/living/silicon/robot/proc/handle_regular_status_updates()
@@ -79,7 +73,7 @@
death()
if (src.stat != 2) //Alive.
if (src.paralysis || src.stunned || src.weakened) //Stunned etc.
if (src.paralysis || src.stunned || src.weakened || !src.has_power) //Stunned etc.
src.stat = 1
if (src.stunned > 0)
AdjustStunned(-1)
@@ -124,6 +118,10 @@
src.druggy--
src.druggy = max(0, src.druggy)
//update the state of modules and components here
if (src.stat != 0)
uneq_all()
if(!is_component_functioning("radio"))
radio.on = 0
else
@@ -134,6 +132,9 @@
else
src.blinded = 1
if(!is_component_functioning("actuator"))
src.Paralyse(3)
return 1
@@ -174,21 +175,38 @@
if (src.healths)
if (src.stat != 2)
switch(health)
if(200 to INFINITY)
src.healths.icon_state = "health0"
if(150 to 200)
src.healths.icon_state = "health1"
if(100 to 150)
src.healths.icon_state = "health2"
if(50 to 100)
src.healths.icon_state = "health3"
if(0 to 50)
src.healths.icon_state = "health4"
if(config.health_threshold_dead to 0)
src.healths.icon_state = "health5"
else
src.healths.icon_state = "health6"
if(istype(src,/mob/living/silicon/robot/drone))
switch(health)
if(35 to INFINITY)
src.healths.icon_state = "health0"
if(25 to 34)
src.healths.icon_state = "health1"
if(15 to 24)
src.healths.icon_state = "health2"
if(5 to 14)
src.healths.icon_state = "health3"
if(0 to 4)
src.healths.icon_state = "health4"
if(-35 to 0)
src.healths.icon_state = "health5"
else
src.healths.icon_state = "health6"
else
switch(health)
if(200 to INFINITY)
src.healths.icon_state = "health0"
if(150 to 200)
src.healths.icon_state = "health1"
if(100 to 150)
src.healths.icon_state = "health2"
if(50 to 100)
src.healths.icon_state = "health3"
if(0 to 50)
src.healths.icon_state = "health4"
if(config.health_threshold_dead to 0)
src.healths.icon_state = "health5"
else
src.healths.icon_state = "health6"
else
src.healths.icon_state = "health7"
@@ -305,4 +323,4 @@
/mob/living/silicon/robot/update_canmove()
if(paralysis || stunned || weakened || buckled || lockcharge) canmove = 0
else canmove = 1
return canmove
return canmove
+38 -49
View File
@@ -42,10 +42,10 @@
var/emagged = 0
var/wiresexposed = 0
var/locked = 1
var/has_power = 1
var/list/req_access = list(access_robotics)
var/ident = 0
//var/list/laws = list()
var/alarms = list("Motion"=list(), "Fire"=list(), "Atmosphere"=list(), "Power"=list(), "Camera"=list())
var/viewalerts = 0
var/modtype = "Default"
var/lower_mod = 0
@@ -89,6 +89,9 @@
hands.icon_state = "standard"
icon_state = "secborg"
modtype = "Security"
else if(istype(src,/mob/living/silicon/robot/drone))
laws = new /datum/ai_laws/drone()
connected_ai = null
else
laws = new /datum/ai_laws/nanotrasen()
connected_ai = select_active_ai_with_fewest_borgs()
@@ -126,7 +129,7 @@
var/datum/robot_component/cell_component = components["power cell"]
cell_component.wrapped = cell
cell_component.installed = 1
hud_list[HEALTH_HUD] = image('icons/mob/hud.dmi', src, "hudblank")
hud_list[STATUS_HUD] = image('icons/mob/hud.dmi', src, "hudhealth100")
hud_list[ID_HUD] = image('icons/mob/hud.dmi', src, "hudblank")
@@ -135,11 +138,12 @@
hud_list[IMPCHEM_HUD] = image('icons/mob/hud.dmi', src, "hudblank")
hud_list[IMPTRACK_HUD] = image('icons/mob/hud.dmi', src, "hudblank")
hud_list[SPECIALROLE_HUD] = image('icons/mob/hud.dmi', src, "hudblank")
playsound(loc, 'sound/voice/liveagain.ogg', 75, 1)
if(istype(src,/mob/living/silicon/robot/drone))
playsound(src.loc, 'sound/machines/twobeep.ogg', 50, 0)
else
playsound(loc, 'sound/voice/liveagain.ogg', 75, 1)
// setup the PDA and its name
/mob/living/silicon/robot/proc/setup_PDA()
@@ -320,16 +324,14 @@
dat += "<A HREF='?src=\ref[src];mach_close=robotalerts'>Close</A><BR><BR>"
for (var/cat in alarms)
dat += text("<B>[cat]</B><BR>\n")
var/list/L = alarms[cat]
if (L.len)
for (var/alarm in L)
var/list/alm = L[alarm]
var/area/A = alm[1]
var/list/sources = alm[3]
var/list/alarmlist = alarms[cat]
if (alarmlist.len)
for (var/area_name in alarmlist)
var/datum/alarm/alarm = alarmlist[area_name]
dat += "<NOBR>"
dat += text("-- [A.name]")
if (sources.len > 1)
dat += text("- [sources.len] sources")
dat += text("-- [area_name]")
if (alarm.sources.len > 1)
dat += text("- [alarm.sources.len] sources")
dat += "</NOBR><BR>\n"
else
dat += "-- All Systems Nominal<BR>\n"
@@ -521,47 +523,22 @@
return
/mob/living/silicon/robot/triggerAlarm(var/class, area/A, var/O, var/alarmsource)
/mob/living/silicon/robot/triggerAlarm(var/class, area/A, list/cameralist, var/source)
if (stat == 2)
return 1
var/list/L = alarms[class]
for (var/I in L)
if (I == A.name)
var/list/alarm = L[I]
var/list/sources = alarm[3]
if (!(alarmsource in sources))
sources += alarmsource
return 1
var/obj/machinery/camera/C = null
var/list/CL = null
if (O && istype(O, /list))
CL = O
if (CL.len == 1)
C = CL[1]
else if (O && istype(O, /obj/machinery/camera))
C = O
L[A.name] = list(A, (C) ? C : O, list(alarmsource))
..()
queueAlarm(text("--- [class] alarm detected in [A.name]!"), class)
// if (viewalerts) robot_alerts()
return 1
/mob/living/silicon/robot/cancelAlarm(var/class, area/A as area, obj/origin)
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[3]
if (origin in srcs)
srcs -= origin
if (srcs.len == 0)
cleared = 1
L -= I
if (cleared)
var/has_alarm = ..()
if (!has_alarm)
queueAlarm(text("--- [class] alarm in [A.name] has been cleared."), class, 0)
// if (viewalerts) robot_alerts()
return !cleared
return has_alarm
/mob/living/silicon/robot/attackby(obj/item/weapon/W as obj, mob/user as mob)
@@ -578,6 +555,14 @@
user.drop_item()
W.loc = null
var/obj/item/robot_parts/robot_component/WC = W
if(istype(WC))
C.brute_damage = WC.brute
C.electronics_damage = WC.burn
else //This will nominally mean that removing and replacing a power cell will repair the mount, but I don't care at this point. ~Z
C.brute_damage = 0
C.electronics_damage = 0
usr << "\blue You install the [W.name]."
return
@@ -597,7 +582,7 @@
user << "Need more welding fuel!"
return
else if(istype(W, /obj/item/weapon/cable_coil) && wiresexposed)
else if(istype(W, /obj/item/weapon/cable_coil) && (wiresexposed || istype(src,/mob/living/silicon/robot/drone)))
if (!getFireLoss())
user << "Nothing to fix here!"
return
@@ -640,8 +625,12 @@
if(!remove)
return
var/datum/robot_component/C = components[remove]
var/obj/item/I = C.wrapped
var/obj/item/robot_parts/robot_component/I = C.wrapped
user << "You remove \the [I]."
if(istype(I))
I.brute = C.brute_damage
I.burn = C.electronics_damage
I.loc = src.loc
if(C.installed == 1)
@@ -266,3 +266,64 @@
src.modules += new /obj/item/weapon/wrench(src) //Is a combat android really going to be stopped by a chair?
src.emag = new /obj/item/weapon/gun/energy/lasercannon/cyborg(src)
return
/obj/item/weapon/robot_module/drone
name = "drone module"
var/list/stacktypes = list(
/obj/item/stack/sheet/wood/cyborg = 1,
/obj/item/stack/sheet/mineral/plastic/cyborg = 1,
/obj/item/stack/sheet/rglass/cyborg = 5,
/obj/item/stack/tile/wood = 5,
/obj/item/stack/rods = 15,
/obj/item/stack/tile/plasteel = 15,
/obj/item/stack/sheet/metal/cyborg = 20,
/obj/item/stack/sheet/glass/cyborg = 20,
/obj/item/weapon/cable_coil = 30
)
New()
//TODO: Replace with shittier flashlight and work out why we can't remove the flash. ~Z
..()
src.modules += new /obj/item/weapon/weldingtool(src)
src.modules += new /obj/item/weapon/screwdriver(src)
src.modules += new /obj/item/weapon/wrench(src)
src.modules += new /obj/item/weapon/crowbar(src)
src.modules += new /obj/item/weapon/wirecutters(src)
src.modules += new /obj/item/device/multitool(src)
src.modules += new /obj/item/device/lightreplacer(src)
src.modules += new /obj/item/weapon/gripper(src)
src.modules += new /obj/item/weapon/matter_decompiler(src)
src.modules += new /obj/item/weapon/reagent_containers/spray/cleaner/drone(src)
src.emag = new /obj/item/weapon/card/emag(src)
src.emag.name = "Cryptographic Sequencer"
for(var/T in stacktypes)
var/obj/item/stack/sheet/W = new T(src)
W.amount = stacktypes[T]
src.modules += W
return
/obj/item/weapon/robot_module/drone/respawn_consumable(var/mob/living/silicon/robot/R)
var/obj/item/weapon/reagent_containers/spray/cleaner/C = locate() in src.modules
C.reagents.add_reagent("cleaner", 3)
for(var/T in stacktypes)
var/O = locate(T) in src.modules
var/obj/item/stack/sheet/S = O
if(!S)
src.modules -= null
S = new T(src)
src.modules += S
S.amount = 1
if(S && S.amount < stacktypes[T])
S.amount++
var/obj/item/device/lightreplacer/LR = locate() in src.modules
LR.Charge(R)
return
+117 -50
View File
@@ -2,11 +2,15 @@
var/ending = copytext(text, length(text))
if (ending == "?")
return "queries, \"[text]\"";
return "queries"
else if (ending == "!")
return "declares, \"[text]\"";
return "declares"
return "states, \"[text]\"";
return "states"
#define IS_AI 1
#define IS_ROBOT 2
#define IS_PAI 3
/mob/living/silicon/say(var/message)
if (!message)
@@ -19,43 +23,106 @@
if (src.client.handle_spam_prevention(message,MUTE_IC))
return
message = trim(copytext(sanitize(message), 1, MAX_MESSAGE_LEN))
if (stat == 2)
message = trim(copytext(sanitize(message), 1, MAX_MESSAGE_LEN))
return say_dead(message)
if(copytext(message,1,2) == "*")
return emote(copytext(message,2))
var/bot_type = 0 //Let's not do a fuck ton of type checks, thanks.
if(istype(src, /mob/living/silicon/ai))
bot_type = IS_AI
else if(istype(src, /mob/living/silicon/robot))
bot_type = IS_ROBOT
else if(istype(src, /mob/living/silicon/pai))
bot_type = IS_PAI
var/mob/living/silicon/ai/AI = src //and let's not declare vars over and over and over for these guys.
var/mob/living/silicon/robot/R = src
var/mob/living/silicon/pai/P = src
//Must be concious to speak
if (stat)
return
if (length(message) >= 2)
var/prefix = copytext(message, 1, 3)
if (department_radio_keys[prefix] == "binary")
if(istype(src, /mob/living/silicon/pai))
return ..(message)
message = copytext(message, 3)
message = trim(copytext(sanitize(message), 1, MAX_MESSAGE_LEN))
var/verb = say_quote(message)
var/message_mode = null
// TODO: move the component system up to silicon so we don't have to use this ugly hack..
if(istype(src, /mob/living/silicon/robot))
var/mob/living/silicon/robot/R = src
if(!R.is_component_functioning("comms"))
src << "\red Your binary communications component isn't functional."
if(copytext(message,1,2) == ";")
message_mode = "general" // I don't know why but regular radio = fuck you we ain't broadcasting, pAI mode was what was in old say code.
message = trim(copytext(message,2))
else if(length(message) >= 2)
var/channel_prefix = copytext(message, 1 ,3)
if(!message_mode)
message_mode = department_radio_keys[channel_prefix]
if(message_mode && bot_type == IS_ROBOT)
if(message_mode != "binary" && !R.is_component_functioning("radio"))
src << "\red Your radio isn't functional at this time."
return
if(message_mode && message_mode != "general")
message = trim(copytext(message,3))
switch(message_mode)
if("department")
switch(bot_type)
if(IS_AI)
AI.holopad_talk(message)
if(IS_ROBOT)
log_say("[key_name(src)] : [message]")
R.radio.talk_into(src,message,message_mode,verb)
if(IS_PAI)
log_say("[key_name(src)] : [message]")
P.radio.talk_into(src,message,message_mode,verb)
return
if("binary")
switch(bot_type)
if(IS_ROBOT)
if(!R.is_component_functioning("comms"))
src << "\red Your binary communications component isn't functional."
return
if(IS_PAI)
src << "You do not appear to have that function"
return
robot_talk(message)
else if (department_radio_keys[prefix] == "department")
if(isAI(src)&&client)//For patching directly into AI holopads.
var/mob/living/silicon/ai/U = src
message = copytext(message, 3)
message = trim(copytext(sanitize(message), 1, MAX_MESSAGE_LEN))
U.holopad_talk(message)
else//Will not allow anyone by an active AI to use this function.
src << "This function is not available to you."
return
return
if("general")
switch(bot_type)
if(IS_AI)
src << "Yeah, not yet, sorry"
if(IS_ROBOT)
log_say("[key_name(src)] : [message]")
R.radio.talk_into(src,message,null,verb)
if(IS_PAI)
log_say("[key_name(src)] : [message]")
P.radio.talk_into(src,message,null,verb)
return
else
return ..(message)
else
return ..(message)
if(message_mode && message_mode in radiochannels)
switch(bot_type)
if(IS_AI)
src << "You don't have this function yet, I'm working on it"
return
if(IS_ROBOT)
log_say("[key_name(src)] : [message]")
R.radio.talk_into(src,message,message_mode,verb)
if(IS_PAI)
log_say("[key_name(src)] : [message]")
P.radio.talk_into(src,message,message_mode,verb)
return
return ..(message,null,verb)
//For holopads only. Usable by AI.
/mob/living/silicon/ai/proc/holopad_talk(var/message)
@@ -69,17 +136,16 @@
var/obj/machinery/hologram/holopad/T = src.current
if(istype(T) && T.hologram && T.master == src)//If there is a hologram and its master is the user.
var/message_a = say_quote(message)
var/verb = say_quote(message)
//Human-like, sorta, heard by those who understand humans.
var/rendered_a = "<span class='game say'><span class='name'>[name]</span> <span class='message'>[message_a]</span></span>"
var/rendered_a = "<span class='game say'><span class='name'>[name]</span> [verb], <span class='message'>\"[message]\"</span></span>"
//Speach distorted, heard by those who do not understand AIs.
message = stars(message)
var/message_b = say_quote(message)
var/rendered_b = "<span class='game say'><span class='name'>[voice_name]</span> <span class='message'>[message_b]</span></span>"
var/message_stars = stars(message)
var/rendered_b = "<span class='game say'><span class='name'>[voice_name]</span> [verb], <span class='message'>\"[message_stars]\"</span></span>"
src << "<i><span class='game say'>Holopad transmitted, <span class='name'>[real_name]</span> <span class='message'>[message_a]</span></span></i>"//The AI can "hear" its own message.
src << "<i><span class='game say'>Holopad transmitted, <span class='name'>[real_name]</span> [verb], <span class='message'>[message]</span></span></i>"//The AI can "hear" its own message.
for(var/mob/M in hearers(T.loc))//The location is the object, default distance.
if(M.say_understands(src))//If they understand AI speak. Humans and the like will be able to.
M.show_message(rendered_a, 2)
@@ -100,13 +166,15 @@
if (!message)
return
var/message_a = say_quote(message)
var/rendered = "<i><span class='game say'>Robotic Talk, <span class='name'>[name]</span> <span class='message'>[message_a]</span></span></i>"
var/verb = say_quote(message)
var/rendered = "<i><span class='game say'>Robotic Talk, <span class='name'>[name]</span> <span class='message'>[verb], \"[message]\"</span></span></i>"
for (var/mob/living/S in living_mob_list)
if(S.robot_talk_understand && (S.robot_talk_understand == robot_talk_understand)) // This SHOULD catch everything caught by the one below, but I'm not going to change it.
if(istype(S , /mob/living/silicon/ai))
var/renderedAI = "<i><span class='game say'>Robotic Talk, <a href='byond://?src=\ref[S];track2=\ref[S];track=\ref[src]'><span class='name'>[name]</span></a> <span class='message'>[message_a]</span></span></i>"
var/renderedAI = "<i><span class='game say'>Robotic Talk, <a href='byond://?src=\ref[S];track2=\ref[S];track=\ref[src]'><span class='name'>[name]</span></a> <span class='message'>[verb], \"[message]\"</span></span></i>"
S.show_message(renderedAI, 2)
else
S.show_message(rendered, 2)
@@ -114,7 +182,7 @@
else if (S.binarycheck())
if(istype(S , /mob/living/silicon/ai))
var/renderedAI = "<i><span class='game say'>Robotic Talk, <a href='byond://?src=\ref[S];track2=\ref[S];track=\ref[src]'><span class='name'>[name]</span></a> <span class='message'>[message_a]</span></span></i>"
var/renderedAI = "<i><span class='game say'>Robotic Talk, <a href='byond://?src=\ref[S];track2=\ref[S];track=\ref[src]'><span class='name'>[name]</span></a> <span class='message'>[verb], \"[message]\"</span></span></i>"
S.show_message(renderedAI, 2)
else
S.show_message(rendered, 2)
@@ -127,23 +195,22 @@
for (var/mob/M in listening)
if(!istype(M, /mob/living/silicon) && !M.robot_talk_understand)
heard += M
if (length(heard))
var/message_b
message_b = "beep beep beep"
message_b = say_quote(message_b)
message_b = "<i>[message_b]</i>"
rendered = "<i><span class='game say'><span class='name'>[voice_name]</span> <span class='message'>[message_b]</span></span></i>"
var/message_beep
verb = "beeps"
message_beep = "beep beep beep"
rendered = "<i><span class='game say'><span class='name'>[voice_name]</span> <span class='message'>[verb], \"[message_beep]\"</span></span></i>"
for (var/mob/M in heard)
M.show_message(rendered, 2)
message = say_quote(message)
rendered = "<i><span class='game say'>Robotic Talk, <span class='name'>[name]</span> <span class='message'>[message_a]</span></span></i>"
rendered = "<i><span class='game say'>Robotic Talk, <span class='name'>[name]</span> <span class='message'>[verb], \"[message]\"</span></span></i>"
for (var/mob/M in dead_mob_list)
if(!istype(M,/mob/new_player) && !istype(M,/mob/living/carbon/brain)) //No meta-evesdropping
M.show_message(rendered, 2)
M.show_message(rendered, 2)
#undef IS_AI
#undef IS_ROBOT
#undef IS_PAI
+16 -81
View File
@@ -4,92 +4,12 @@
voice_name = "synthesized voice"
var/syndicate = 0
var/datum/ai_laws/laws = null//Now... THEY ALL CAN ALL HAVE LAWS
var/list/alarms_to_show = list()
var/list/alarms_to_clear = list()
immune_to_ssd = 1
var/list/hud_list[9]
var/list/alarm_types_show = list("Motion" = 0, "Fire" = 0, "Atmosphere" = 0, "Power" = 0, "Camera" = 0)
var/list/alarm_types_clear = list("Motion" = 0, "Fire" = 0, "Atmosphere" = 0, "Power" = 0, "Camera" = 0)
/mob/living/silicon/proc/cancelAlarm()
return
/mob/living/silicon/proc/triggerAlarm()
return
/mob/living/silicon/proc/show_laws()
return
/mob/living/silicon/proc/queueAlarm(var/message, var/type, var/incoming = 1)
var/in_cooldown = (alarms_to_show.len > 0 || alarms_to_clear.len > 0)
if(incoming)
alarms_to_show += message
alarm_types_show[type] += 1
else
alarms_to_clear += message
alarm_types_clear[type] += 1
if(!in_cooldown)
spawn(10 * 10) // 10 seconds
if(alarms_to_show.len < 5)
for(var/msg in alarms_to_show)
src << msg
else if(alarms_to_show.len)
var/msg = "--- "
if(alarm_types_show["Motion"])
msg += "MOTION: [alarm_types_show["Motion"]] alarms detected. - "
if(alarm_types_show["Fire"])
msg += "FIRE: [alarm_types_show["Fire"]] alarms detected. - "
if(alarm_types_show["Atmosphere"])
msg += "ATMOSPHERE: [alarm_types_show["Atmosphere"]] alarms detected. - "
if(alarm_types_show["Power"])
msg += "POWER: [alarm_types_show["Power"]] alarms detected. - "
if(alarm_types_show["Camera"])
msg += "CAMERA: [alarm_types_show["Power"]] alarms detected. - "
msg += "<A href=?src=\ref[src];showalerts=1'>\[Show Alerts\]</a>"
src << msg
if(alarms_to_clear.len < 3)
for(var/msg in alarms_to_clear)
src << msg
else if(alarms_to_clear.len)
var/msg = "--- "
if(alarm_types_clear["Motion"])
msg += "MOTION: [alarm_types_clear["Motion"]] alarms cleared. - "
if(alarm_types_clear["Fire"])
msg += "FIRE: [alarm_types_clear["Fire"]] alarms cleared. - "
if(alarm_types_clear["Atmosphere"])
msg += "ATMOSPHERE: [alarm_types_clear["Atmosphere"]] alarms cleared. - "
if(alarm_types_clear["Power"])
msg += "POWER: [alarm_types_clear["Power"]] alarms cleared. - "
if(alarm_types_show["Camera"])
msg += "CAMERA: [alarm_types_show["Power"]] alarms detected. - "
msg += "<A href=?src=\ref[src];showalerts=1'>\[Show Alerts\]</a>"
src << msg
alarms_to_show = list()
alarms_to_clear = list()
for(var/i = 1; i < alarm_types_show.len; i++)
alarm_types_show[i] = 0
for(var/i = 1; i < alarm_types_clear.len; i++)
alarm_types_clear[i] = 0
/mob/living/silicon/drop_item()
return
@@ -113,8 +33,17 @@
return 1
/mob/living/silicon/bullet_act(var/obj/item/projectile/Proj)
if(!Proj.nodamage) adjustBruteLoss(Proj.damage)
if(!Proj.nodamage)
switch(Proj.damage_type)
if(BRUTE)
adjustBruteLoss(Proj.damage)
if(BURN)
adjustFireLoss(Proj.damage)
Proj.on_hit(src,2)
return 2
/mob/living/silicon/apply_effect(var/effect = 0,var/effecttype = STUN, var/blocked = 0)
@@ -192,3 +121,9 @@
dat += "<br>"
src << browse(dat, "window=airoster")
onclose(src, "airoster")
//can't inject synths
/mob/living/silicon/can_inject(var/mob/user, var/error_msg)
if(error_msg)
user << "<span class='alert'>The armoured plating is too tough.</span>"
return 0
@@ -31,7 +31,7 @@
if(stat == CONSCIOUS)
//if we're strong enough, sting some people
var/mob/living/carbon/human/M = target_mob
var/sting_prob = 100 // Bees will always try to sting.
var/sting_prob = 40 // Bees will always try to sting.
if(M in view(src,1)) // Can I see my target?
if(prob(max(feral * 10, 0))) // Am I mad enough to want to sting? And yes, when I initially appear, I AM mad enough
var/obj/item/clothing/worn_suit = M.wear_suit
@@ -42,17 +42,17 @@
sting_prob -= min(worn_helmet.armor["bio"],30) // Is your helmet sealed? I can't get to 30% of your body.
if( prob(sting_prob) && (M.stat == CONSCIOUS || (M.stat == UNCONSCIOUS && prob(25))) ) // Try to sting! If you're not moving, think about stinging.
M.apply_damage(min(strength,2)+mut, BRUTE) // Stinging. The more mutated I am, the harder I sting.
M.apply_damage((round(feral/5,1)*(max((round(strength/10,1)),1)))+toxic, TOX) // Bee venom based on how angry I am and how many there are of me!
M.apply_damage((round(feral/10,1)*(max((round(strength/20,1)),1)))+toxic, TOX) // Bee venom based on how angry I am and how many there are of me!
M << "\red You have been stung!"
M.flash_pain()
//if we're chasing someone, get a little bit angry
if(target_mob && prob(10))
if(target_mob && prob(5))
feral++
//calm down a little bit
if(feral > 0)
if(prob(feral * 10))
if(prob(feral * 20))
feral -= 1
else
//if feral is less than 0, we're becalmed by smoke or steam
@@ -58,7 +58,6 @@
..()
if(host)
if(!stat && !host.stat)
@@ -338,8 +337,14 @@ mob/living/simple_animal/borer/proc/detatch()
host_brain.name = "host brain"
host_brain.real_name = "host brain"
var/mob/living/H = host
host = null
for(var/atom/A in H.contents)
if(istype(A,/mob/living/simple_animal/borer) || istype(A,/obj/item/weapon/holder))
return
H.status_flags &= ~PASSEMOTES
/mob/living/simple_animal/borer/verb/infest()
set category = "Alien"
set name = "Infest"
@@ -406,6 +411,7 @@ mob/living/simple_animal/borer/proc/detatch()
host_brain.name = M.name
host_brain.real_name = M.real_name
host.status_flags |= PASSEMOTES
return
else
@@ -13,6 +13,7 @@
a_intent = "harm"
stop_automated_movement = 1
status_flags = CANPUSH
universal_speak = 1
attack_sound = 'sound/weapons/punch1.ogg'
min_oxy = 0
max_oxy = 0
@@ -167,6 +168,10 @@
M.show_message("\red [user] gently taps [src] with [O]. ")
/mob/living/simple_animal/construct/armoured/Life()
weakened = 0
..()
/mob/living/simple_animal/construct/armoured/bullet_act(var/obj/item/projectile/P)
if(istype(P, /obj/item/projectile/energy) || istype(P, /obj/item/projectile/beam))
var/reflectchance = 80 - round(P.damage/3)
@@ -242,8 +247,7 @@
construct_spells = list(/obj/effect/proc_holder/spell/aoe_turf/conjure/construct/lesser,
/obj/effect/proc_holder/spell/aoe_turf/conjure/wall,
/obj/effect/proc_holder/spell/aoe_turf/conjure/floor,
/obj/effect/proc_holder/spell/aoe_turf/conjure/soulstone,
/obj/effect/proc_holder/spell/targeted/projectile/magic_missile)
/obj/effect/proc_holder/spell/aoe_turf/conjure/soulstone,)
/////////////////////////////Behemoth/////////////////////////
@@ -320,4 +324,4 @@
if (cultist == usr) //just to be sure.
return
cultist.loc = usr.loc
usr.visible_message("/red [cultist] appears in a flash of red light as [usr] glows with power")*/
usr.visible_message("/red [cultist] appears in a flash of red light as [usr] glows with power")*/
@@ -19,6 +19,8 @@
icon_state = "spiderbot-chassis"
icon_living = "spiderbot-chassis"
icon_dead = "spiderbot-smashed"
universal_speak = 1 //Temp until these are rewritten.
wander = 0
health = 10
@@ -33,9 +35,8 @@
response_disarm = "shoos"
response_harm = "stomps on"
var/emagged = 0
var/obj/item/held_item = null //Storage for single item they can hold.
var/emagged = 0 //IS WE EXPLODEN?
var/syndie = 0 //IS WE SYNDICAT? (currently unused)
speed = -1 //Spiderbots gotta go fast.
//pass_flags = PASSTABLE //Maybe griefy?
small = 1

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