mirror of
https://github.com/VOREStation/VOREStation.git
synced 2026-07-18 10:34:10 +01:00
Merge remote-tracking branch 'upstream/dev' into 150722-TagPairs
Conflicts: code/game/gamemodes/changeling/modularchangling.dm
This commit is contained in:
@@ -23,7 +23,7 @@
|
||||
/proc/ToRban_update()
|
||||
spawn(0)
|
||||
log_misc("Downloading updated ToR data...")
|
||||
var/http[] = world.Export("http://exitlist.torproject.org/exit-addresses")
|
||||
var/http[] = world.Export("https://check.torproject.org/exit-addresses")
|
||||
|
||||
var/list/rawlist = file2list(http["CONTENT"])
|
||||
if(rawlist.len)
|
||||
|
||||
@@ -1097,7 +1097,7 @@ proc/admin_notice(var/message, var/rights)
|
||||
else
|
||||
new chosen(usr.loc)
|
||||
|
||||
log_admin("[key_name(usr)] spawned [chosen] at ([usr.x],[usr.y],[usr.z])")
|
||||
log_and_message_admins("spawned [chosen] at ([usr.x],[usr.y],[usr.z])")
|
||||
feedback_add_details("admin_verb","SA") //If you are copy-pasting this, ensure the 2nd parameter is unique to the new proc!
|
||||
|
||||
|
||||
|
||||
@@ -83,10 +83,13 @@ var/list/admin_verbs_admin = list(
|
||||
/client/proc/allow_character_respawn, /* Allows a ghost to respawn */
|
||||
/client/proc/event_manager_panel,
|
||||
/client/proc/empty_ai_core_toggle_latejoin,
|
||||
/client/proc/empty_ai_core_toggle_latejoin,
|
||||
/client/proc/aooc,
|
||||
/client/proc/change_human_appearance_admin, /* Allows an admin to change the basic appearance of human-based mobs */
|
||||
/client/proc/change_human_appearance_self, /* Allows the human-based mob itself change its basic appearance */
|
||||
/client/proc/change_security_level
|
||||
/client/proc/change_security_level,
|
||||
/client/proc/view_chemical_reaction_logs,
|
||||
/client/proc/makePAI
|
||||
)
|
||||
var/list/admin_verbs_ban = list(
|
||||
/client/proc/unban_panel,
|
||||
|
||||
+141
-141
@@ -1,147 +1,147 @@
|
||||
//This stuff was originally intended to be integrated into the ban-system I was working on
|
||||
//but it's safe to say that'll never be finished. So I've merged it into the current player panel.
|
||||
//enjoy ~Carn
|
||||
/*
|
||||
#define NOTESFILE "data/player_notes.sav" //where the player notes are saved
|
||||
|
||||
datum/admins/proc/notes_show(var/ckey)
|
||||
usr << browse("<head><title>Player Notes</title></head><body>[notes_gethtml(ckey)]</body>","window=player_notes;size=700x400")
|
||||
|
||||
|
||||
datum/admins/proc/notes_gethtml(var/ckey)
|
||||
var/savefile/notesfile = new(NOTESFILE)
|
||||
if(!notesfile) return "<font color='red'>Error: Cannot access [NOTESFILE]</font>"
|
||||
if(ckey)
|
||||
. = "<b>Notes for <a href='?src=\ref[src];notes=show'>[ckey]</a>:</b> <a href='?src=\ref[src];notes=add;ckey=[ckey]'>\[+\]</a> <a href='?src=\ref[src];notes=remove;ckey=[ckey]'>\[-\]</a><br>"
|
||||
notesfile.cd = "/[ckey]"
|
||||
var/index = 1
|
||||
while( !notesfile.eof )
|
||||
var/note
|
||||
notesfile >> note
|
||||
. += "[note] <a href='?src=\ref[src];notes=remove;ckey=[ckey];from=[index]'>\[-\]</a><br>"
|
||||
index++
|
||||
else
|
||||
. = "<b>All Notes:</b> <a href='?src=\ref[src];notes=add'>\[+\]</a> <a href='?src=\ref[src];notes=remove'>\[-\]</a><br>"
|
||||
notesfile.cd = "/"
|
||||
for(var/dir in notesfile.dir)
|
||||
. += "<a href='?src=\ref[src];notes=show;ckey=[dir]'>[dir]</a><br>"
|
||||
return
|
||||
|
||||
//handles removing entries from the buffer, or removing the entire directory if no start_index is given
|
||||
/proc/notes_remove(var/ckey, var/start_index, var/end_index)
|
||||
var/savefile/notesfile = new(NOTESFILE)
|
||||
if(!notesfile) return
|
||||
|
||||
if(!ckey)
|
||||
notesfile.cd = "/"
|
||||
ckey = ckey(input(usr,"Who would you like to remove notes for?","Enter a ckey",null) as null|anything in notesfile.dir)
|
||||
if(!ckey) return
|
||||
|
||||
if(start_index)
|
||||
notesfile.cd = "/[ckey]"
|
||||
var/list/noteslist = list()
|
||||
if(!end_index) end_index = start_index
|
||||
var/index = 0
|
||||
while( !notesfile.eof )
|
||||
index++
|
||||
var/temp
|
||||
notesfile >> temp
|
||||
if( (start_index <= index) && (index <= end_index) )
|
||||
continue
|
||||
noteslist += temp
|
||||
|
||||
notesfile.eof = -2 //Move to the start of the buffer and then erase.
|
||||
|
||||
for( var/note in noteslist )
|
||||
notesfile << note
|
||||
else
|
||||
notesfile.cd = "/"
|
||||
if(alert(usr,"Are you sure you want to remove all their notes?","Confirmation","No","Yes - Remove all notes") == "Yes - Remove all notes")
|
||||
notesfile.dir.Remove(ckey)
|
||||
return
|
||||
|
||||
#undef NOTESFILE
|
||||
*/
|
||||
|
||||
//Hijacking this file for BS12 playernotes functions. I like this ^ one systemm alright, but converting sounds too bothersome~ Chinsky.
|
||||
|
||||
//This stuff was originally intended to be integrated into the ban-system I was working on
|
||||
//but it's safe to say that'll never be finished. So I've merged it into the current player panel.
|
||||
//enjoy ~Carn
|
||||
/*
|
||||
#define NOTESFILE "data/player_notes.sav" //where the player notes are saved
|
||||
|
||||
datum/admins/proc/notes_show(var/ckey)
|
||||
usr << browse("<head><title>Player Notes</title></head><body>[notes_gethtml(ckey)]</body>","window=player_notes;size=700x400")
|
||||
|
||||
|
||||
datum/admins/proc/notes_gethtml(var/ckey)
|
||||
var/savefile/notesfile = new(NOTESFILE)
|
||||
if(!notesfile) return "<font color='red'>Error: Cannot access [NOTESFILE]</font>"
|
||||
if(ckey)
|
||||
. = "<b>Notes for <a href='?src=\ref[src];notes=show'>[ckey]</a>:</b> <a href='?src=\ref[src];notes=add;ckey=[ckey]'>\[+\]</a> <a href='?src=\ref[src];notes=remove;ckey=[ckey]'>\[-\]</a><br>"
|
||||
notesfile.cd = "/[ckey]"
|
||||
var/index = 1
|
||||
while( !notesfile.eof )
|
||||
var/note
|
||||
notesfile >> note
|
||||
. += "[note] <a href='?src=\ref[src];notes=remove;ckey=[ckey];from=[index]'>\[-\]</a><br>"
|
||||
index++
|
||||
else
|
||||
. = "<b>All Notes:</b> <a href='?src=\ref[src];notes=add'>\[+\]</a> <a href='?src=\ref[src];notes=remove'>\[-\]</a><br>"
|
||||
notesfile.cd = "/"
|
||||
for(var/dir in notesfile.dir)
|
||||
. += "<a href='?src=\ref[src];notes=show;ckey=[dir]'>[dir]</a><br>"
|
||||
return
|
||||
|
||||
//handles removing entries from the buffer, or removing the entire directory if no start_index is given
|
||||
/proc/notes_remove(var/ckey, var/start_index, var/end_index)
|
||||
var/savefile/notesfile = new(NOTESFILE)
|
||||
if(!notesfile) return
|
||||
|
||||
if(!ckey)
|
||||
notesfile.cd = "/"
|
||||
ckey = ckey(input(usr,"Who would you like to remove notes for?","Enter a ckey",null) as null|anything in notesfile.dir)
|
||||
if(!ckey) return
|
||||
|
||||
if(start_index)
|
||||
notesfile.cd = "/[ckey]"
|
||||
var/list/noteslist = list()
|
||||
if(!end_index) end_index = start_index
|
||||
var/index = 0
|
||||
while( !notesfile.eof )
|
||||
index++
|
||||
var/temp
|
||||
notesfile >> temp
|
||||
if( (start_index <= index) && (index <= end_index) )
|
||||
continue
|
||||
noteslist += temp
|
||||
|
||||
notesfile.eof = -2 //Move to the start of the buffer and then erase.
|
||||
|
||||
for( var/note in noteslist )
|
||||
notesfile << note
|
||||
else
|
||||
notesfile.cd = "/"
|
||||
if(alert(usr,"Are you sure you want to remove all their notes?","Confirmation","No","Yes - Remove all notes") == "Yes - Remove all notes")
|
||||
notesfile.dir.Remove(ckey)
|
||||
return
|
||||
|
||||
#undef NOTESFILE
|
||||
*/
|
||||
|
||||
//Hijacking this file for BS12 playernotes functions. I like this ^ one systemm alright, but converting sounds too bothersome~ Chinsky.
|
||||
|
||||
/proc/notes_add(var/key, var/note, var/mob/user)
|
||||
if (!key || !note)
|
||||
return
|
||||
|
||||
//Loading list of notes for this key
|
||||
var/savefile/info = new("data/player_saves/[copytext(key, 1, 2)]/[key]/info.sav")
|
||||
var/list/infos
|
||||
info >> infos
|
||||
if(!infos) infos = list()
|
||||
|
||||
//Overly complex timestamp creation
|
||||
var/modifyer = "th"
|
||||
switch(time2text(world.timeofday, "DD"))
|
||||
if("01","21","31")
|
||||
modifyer = "st"
|
||||
if("02","22",)
|
||||
modifyer = "nd"
|
||||
if("03","23")
|
||||
modifyer = "rd"
|
||||
var/day_string = "[time2text(world.timeofday, "DD")][modifyer]"
|
||||
if(copytext(day_string,1,2) == "0")
|
||||
day_string = copytext(day_string,2)
|
||||
var/full_date = time2text(world.timeofday, "DDD, Month DD of YYYY")
|
||||
var/day_loc = findtext(full_date, time2text(world.timeofday, "DD"))
|
||||
|
||||
var/datum/player_info/P = new
|
||||
if (!key || !note)
|
||||
return
|
||||
|
||||
//Loading list of notes for this key
|
||||
var/savefile/info = new("data/player_saves/[copytext(key, 1, 2)]/[key]/info.sav")
|
||||
var/list/infos
|
||||
info >> infos
|
||||
if(!infos) infos = list()
|
||||
|
||||
//Overly complex timestamp creation
|
||||
var/modifyer = "th"
|
||||
switch(time2text(world.timeofday, "DD"))
|
||||
if("01","21","31")
|
||||
modifyer = "st"
|
||||
if("02","22",)
|
||||
modifyer = "nd"
|
||||
if("03","23")
|
||||
modifyer = "rd"
|
||||
var/day_string = "[time2text(world.timeofday, "DD")][modifyer]"
|
||||
if(copytext(day_string,1,2) == "0")
|
||||
day_string = copytext(day_string,2)
|
||||
var/full_date = time2text(world.timeofday, "DDD, Month DD of YYYY")
|
||||
var/day_loc = findtext(full_date, time2text(world.timeofday, "DD"))
|
||||
|
||||
var/datum/player_info/P = new
|
||||
if (user)
|
||||
P.author = user.key
|
||||
P.rank = user.client.holder.rank
|
||||
else
|
||||
P.author = "Adminbot"
|
||||
P.rank = "Friendly Robot"
|
||||
P.content = note
|
||||
P.timestamp = "[copytext(full_date,1,day_loc)][day_string][copytext(full_date,day_loc+2)]"
|
||||
|
||||
infos += P
|
||||
info << infos
|
||||
|
||||
else
|
||||
P.author = "Adminbot"
|
||||
P.rank = "Friendly Robot"
|
||||
P.content = note
|
||||
P.timestamp = "[copytext(full_date,1,day_loc)][day_string][copytext(full_date,day_loc+2)]"
|
||||
|
||||
infos += P
|
||||
info << infos
|
||||
|
||||
message_admins("\blue [key_name_admin(user)] has edited [key]'s notes.")
|
||||
log_admin("[key_name(user)] has edited [key]'s notes.")
|
||||
|
||||
qdel(info)
|
||||
|
||||
//Updating list of keys with notes on them
|
||||
var/savefile/note_list = new("data/player_notes.sav")
|
||||
var/list/note_keys
|
||||
note_list >> note_keys
|
||||
if(!note_keys) note_keys = list()
|
||||
if(!note_keys.Find(key)) note_keys += key
|
||||
note_list << note_keys
|
||||
qdel(note_list)
|
||||
|
||||
|
||||
/proc/notes_del(var/key, var/index)
|
||||
var/savefile/info = new("data/player_saves/[copytext(key, 1, 2)]/[key]/info.sav")
|
||||
var/list/infos
|
||||
info >> infos
|
||||
if(!infos || infos.len < index) return
|
||||
|
||||
var/datum/player_info/item = infos[index]
|
||||
infos.Remove(item)
|
||||
info << infos
|
||||
|
||||
message_admins("\blue [key_name_admin(usr)] deleted one of [key]'s notes.")
|
||||
log_admin("[key_name(usr)] deleted one of [key]'s notes.")
|
||||
|
||||
qdel(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
|
||||
|
||||
qdel(info)
|
||||
|
||||
//Updating list of keys with notes on them
|
||||
var/savefile/note_list = new("data/player_notes.sav")
|
||||
var/list/note_keys
|
||||
note_list >> note_keys
|
||||
if(!note_keys) note_keys = list()
|
||||
if(!note_keys.Find(key)) note_keys += key
|
||||
note_list << note_keys
|
||||
qdel(note_list)
|
||||
|
||||
|
||||
/proc/notes_del(var/key, var/index)
|
||||
var/savefile/info = new("data/player_saves/[copytext(key, 1, 2)]/[key]/info.sav")
|
||||
var/list/infos
|
||||
info >> infos
|
||||
if(!infos || infos.len < index) return
|
||||
|
||||
var/datum/player_info/item = infos[index]
|
||||
infos.Remove(item)
|
||||
info << infos
|
||||
|
||||
message_admins("\blue [key_name_admin(usr)] deleted one of [key]'s notes.")
|
||||
log_admin("[key_name(usr)] deleted one of [key]'s notes.")
|
||||
|
||||
qdel(info)
|
||||
|
||||
/proc/show_player_info_irc(var/key as text)
|
||||
var/dat = " Info on [key]\n"
|
||||
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]\nby [I.author] ([I.rank]) on [I.timestamp]\n\n"
|
||||
|
||||
return list2params(list(dat))
|
||||
|
||||
@@ -358,7 +358,7 @@
|
||||
dat += "<td>NA</td>"
|
||||
|
||||
|
||||
dat += {"<td>[(M.client ? "[M.client]" : "No client")]</td>
|
||||
dat += {"<td>[M.key ? (M.client ? M.key : "[M.key] (DC)") : "No key"]</td>
|
||||
<td align=center><A HREF='?src=\ref[src];adminplayeropts=\ref[M]'>X</A></td>
|
||||
<td align=center><A href='?src=\ref[usr];priv_msg=\ref[M]'>PM</A></td>
|
||||
"}
|
||||
|
||||
@@ -1651,18 +1651,7 @@
|
||||
var/mob/M = O
|
||||
M.real_name = obj_name
|
||||
|
||||
if (number == 1)
|
||||
log_admin("[key_name(usr)] created a [english_list(paths)]")
|
||||
for(var/path in paths)
|
||||
if(ispath(path, /mob))
|
||||
message_admins("[key_name_admin(usr)] created a [english_list(paths)]", 1)
|
||||
break
|
||||
else
|
||||
log_admin("[key_name(usr)] created [number]ea [english_list(paths)]")
|
||||
for(var/path in paths)
|
||||
if(ispath(path, /mob))
|
||||
message_admins("[key_name_admin(usr)] created [number]ea [english_list(paths)]", 1)
|
||||
break
|
||||
log_and_message_admins("created [number] [english_list(paths)]")
|
||||
return
|
||||
|
||||
else if(href_list["secretsfun"])
|
||||
|
||||
@@ -42,6 +42,12 @@
|
||||
icon = 'icons/misc/buildmode.dmi'
|
||||
var/obj/effect/bmode/buildholder/master = null
|
||||
|
||||
/obj/effect/bmode/Destroy()
|
||||
if(master && master.cl)
|
||||
master.cl.screen -= src
|
||||
master = null
|
||||
return ..()
|
||||
|
||||
/obj/effect/bmode/builddir
|
||||
icon_state = "build"
|
||||
screen_loc = "NORTH,WEST"
|
||||
@@ -117,6 +123,19 @@
|
||||
var/obj/effect/bmode/buildquit/buildquit = null
|
||||
var/atom/movable/throw_atom = null
|
||||
|
||||
/obj/effect/bmode/buildholder/Destroy()
|
||||
qdel(builddir)
|
||||
builddir = null
|
||||
qdel(buildhelp)
|
||||
buildhelp = null
|
||||
qdel(buildmode)
|
||||
buildmode = null
|
||||
qdel(buildquit)
|
||||
buildquit = null
|
||||
throw_atom = null
|
||||
cl = null
|
||||
return ..()
|
||||
|
||||
/obj/effect/bmode/buildmode
|
||||
icon_state = "buildmode1"
|
||||
screen_loc = "NORTH,WEST+2"
|
||||
|
||||
@@ -64,6 +64,28 @@ But you can call procs that are of type /mob/living/carbon/human/proc/ for that
|
||||
|
||||
var/procname = input("Proc path, eg: /proc/fake_blood","Path:", null) as text|null
|
||||
if(!procname) return
|
||||
|
||||
if(targetselected)
|
||||
if(!target)
|
||||
usr << "<span class='danger'>Your target no longer exists.</span>"
|
||||
return
|
||||
if(!hascall(target,procname))
|
||||
usr << "<font color='red'>Error: callproc(): target has no such call [procname].</font>"
|
||||
return
|
||||
else
|
||||
if(copytext(procname, 1, 7) == "/proc/")
|
||||
// nothing
|
||||
else if(copytext(procname, 1, 6) == "proc/")
|
||||
procname = "/[procname]"
|
||||
else if(copytext(procname, 1, 2) == "/")
|
||||
procname = "/proc[procname]"
|
||||
else
|
||||
procname = "/proc/[procname]"
|
||||
// Procs have the strange property that text2path will return non-null, but ispath() will return false.
|
||||
var/path = text2path(procname)
|
||||
if(!path || ispath(path))
|
||||
usr << "<span class='danger'>Invalid proc [procname]</span>"
|
||||
return
|
||||
|
||||
var/argnum = input("Number of arguments","Number:",0) as num|null
|
||||
if(!argnum && (argnum!=0)) return
|
||||
@@ -117,13 +139,9 @@ But you can call procs that are of type /mob/living/carbon/human/proc/ for that
|
||||
if(!target)
|
||||
usr << "<font color='red'>Error: callproc(): owner of proc no longer exists.</font>"
|
||||
return
|
||||
if(!hascall(target,procname))
|
||||
usr << "<font color='red'>Error: callproc(): target has no such call [procname].</font>"
|
||||
return
|
||||
log_admin("[key_name(src)] called [target]'s [procname]() with [lst.len ? "the arguments [list2params(lst)]":"no arguments"].")
|
||||
returnval = call(target,procname)(arglist(lst)) // Pass the lst as an argument list to the proc
|
||||
else
|
||||
//this currently has no hascall protection. wasn't able to get it working.
|
||||
log_admin("[key_name(src)] called [procname]() with [lst.len ? "the arguments [list2params(lst)]":"no arguments"].")
|
||||
returnval = call(procname)(arglist(lst)) // Pass the lst as an argument list to the proc
|
||||
|
||||
@@ -200,7 +218,7 @@ But you can call procs that are of type /mob/living/carbon/human/proc/ for that
|
||||
if(!choice)
|
||||
return 0
|
||||
if(!istype(choice, /mob/dead/observer))
|
||||
var/confirm = input("[choice.key] isn't ghosting right now. Are you sure you want to yank him out of them out of their body and place them in this pAI?", "Spawn pAI Confirmation", "No") in list("Yes", "No")
|
||||
var/confirm = input("[choice.key] isn't ghosting right now. Are you sure you want to yank them out of them out of their body and place them in this pAI?", "Spawn pAI Confirmation", "No") in list("Yes", "No")
|
||||
if(confirm != "Yes")
|
||||
return 0
|
||||
var/obj/item/device/paicard/card = new(T)
|
||||
|
||||
@@ -468,7 +468,7 @@ Traitors and the like can also be revived with the previous role mostly intact.
|
||||
for(var/mob/living/silicon/ai/M in mob_list)
|
||||
if (M.stat == 2)
|
||||
usr << "Upload failed. No signal is being detected from the AI."
|
||||
else if (!M.has_power)
|
||||
else if (M.see_in_dark == 0)
|
||||
usr << "Upload failed. Only a faint signal is being detected from the AI, and it is not responding to our requests. It may be low on power."
|
||||
else
|
||||
M.add_ion_law(input)
|
||||
|
||||
@@ -52,4 +52,4 @@ var/const/commandos_possible = 6 //if more Commandos are needed in the future
|
||||
usr << "Looks like someone beat you to it."
|
||||
return
|
||||
|
||||
team.attempt_spawn(1)
|
||||
team.attempt_random_spawn()
|
||||
|
||||
@@ -153,6 +153,13 @@
|
||||
add_admin_verbs()
|
||||
admin_memo_show()
|
||||
|
||||
// Forcibly enable hardware-accelerated graphics, as we need them for the lighting overlays.
|
||||
// (but turn them off first, since sometimes BYOND doesn't turn them on properly otherwise)
|
||||
spawn(5) // And wait a half-second, since it sounds like you can do this too fast.
|
||||
if(src)
|
||||
winset(src, null, "command=\".configure graphics-hwmode off\"")
|
||||
winset(src, null, "command=\".configure graphics-hwmode on\"")
|
||||
|
||||
log_client_to_db()
|
||||
|
||||
send_resources()
|
||||
|
||||
@@ -75,7 +75,7 @@ datum/preferences
|
||||
var/b_eyes = 0 //Eye color
|
||||
var/species = "Human" //Species datum to use.
|
||||
var/species_preview //Used for the species selection window.
|
||||
var/language = "None" //Secondary language
|
||||
var/list/alternate_languages = list() //Secondary language(s)
|
||||
var/list/gear //Custom/fluff item loadout.
|
||||
|
||||
//Some faction information.
|
||||
@@ -85,7 +85,6 @@ datum/preferences
|
||||
var/religion = "None" //Religious association.
|
||||
|
||||
//Mob preview
|
||||
var/mob/living/carbon/human/dummy //the mannequin
|
||||
var/icon/preview_icon = null
|
||||
var/icon/preview_icon_front = null
|
||||
var/icon/preview_icon_side = null
|
||||
@@ -133,9 +132,12 @@ datum/preferences
|
||||
var/metadata = ""
|
||||
var/slot_name = ""
|
||||
|
||||
var/client/client = null
|
||||
|
||||
/datum/preferences/New(client/C)
|
||||
b_type = pick(4;"O-", 36;"O+", 3;"A-", 28;"A+", 1;"B-", 20;"B+", 1;"AB-", 5;"AB+")
|
||||
if(istype(C))
|
||||
client = C
|
||||
if(!IsGuestKey(C.key))
|
||||
load_path(C.ckey)
|
||||
if(load_preferences())
|
||||
@@ -308,7 +310,7 @@ datum/preferences
|
||||
dat += "(<a href='?_src_=prefs;preference=all;task=random'>®</A>)"
|
||||
dat += "<br>"
|
||||
dat += "Species: <a href='?src=\ref[user];preference=species;task=change'>[species]</a><br>"
|
||||
dat += "Secondary Language:<br><a href='byond://?src=\ref[user];preference=language;task=input'>[language]</a><br>"
|
||||
|
||||
dat += "Blood Type: <a href='byond://?src=\ref[user];preference=b_type;task=input'>[b_type]</a><br>"
|
||||
dat += "Skin Tone: <a href='?_src_=prefs;preference=s_tone;task=input'>[-s_tone + 35]/220<br></a>"
|
||||
//dat += "Skin pattern: <a href='byond://?src=\ref[user];preference=skin_style;task=input'>Adjust</a><br>"
|
||||
@@ -382,6 +384,25 @@ datum/preferences
|
||||
else
|
||||
dat += "<br><br>"
|
||||
|
||||
|
||||
dat += "<b>Languages</b><br>"
|
||||
var/datum/species/S = all_species[species]
|
||||
if(S.language)
|
||||
dat += "- [S.language]<br>"
|
||||
if(S.default_language && S.default_language != S.language)
|
||||
dat += "- [S.default_language]<br>"
|
||||
if(S.num_alternate_languages)
|
||||
if(alternate_languages.len)
|
||||
for(var/i = 1 to alternate_languages.len)
|
||||
var/lang = alternate_languages[i]
|
||||
dat += "- [lang] - <a href='byond://?src=\ref[user];preference=language;remove=[i]'>remove</a><br>"
|
||||
|
||||
if(alternate_languages.len < S.num_alternate_languages)
|
||||
dat += "- <a href='byond://?src=\ref[user];preference=language;add=1'>add</a> ([S.num_alternate_languages - alternate_languages.len] remaining)<br>"
|
||||
else
|
||||
dat += "- [species] cannot choose secondary languages.<br>"
|
||||
dat += "<br><br>"
|
||||
|
||||
var/list/undies = gender == MALE ? underwear_m : underwear_f
|
||||
|
||||
dat += "Underwear: <a href ='?_src_=prefs;preference=underwear;task=input'><b>[get_key_by_value(undies,underwear)]</b></a><br>"
|
||||
@@ -1127,6 +1148,32 @@ datum/preferences
|
||||
if(gear_name == choice)
|
||||
gear -= gear_name
|
||||
break
|
||||
else if(href_list["preference"] == "language")
|
||||
if(href_list["remove"])
|
||||
var/index = text2num(href_list["remove"])
|
||||
alternate_languages.Cut(index, index+1)
|
||||
if(href_list["add"])
|
||||
var/datum/species/S = all_species[species]
|
||||
if(alternate_languages.len >= S.num_alternate_languages)
|
||||
alert(user, "You have already selected the maximum number of alternate languages for this species!")
|
||||
else
|
||||
var/list/available_languages = S.secondary_langs.Copy()
|
||||
for(var/L in all_languages)
|
||||
var/datum/language/lang = all_languages[L]
|
||||
if(!(lang.flags & RESTRICTED) && (!config.usealienwhitelist || is_alien_whitelisted(user, L) || !(lang.flags & WHITELISTED)))
|
||||
available_languages |= L
|
||||
|
||||
// make sure we don't let them waste slots on the default languages
|
||||
available_languages -= S.language
|
||||
available_languages -= S.default_language
|
||||
available_languages -= alternate_languages
|
||||
|
||||
if(!available_languages.len)
|
||||
alert(user, "There are no additional languages available to select.")
|
||||
else
|
||||
var/new_lang = input("Select an additional language", "Character Generation", null) as null|anything in available_languages
|
||||
if(new_lang)
|
||||
alternate_languages |= new_lang
|
||||
|
||||
switch(href_list["task"])
|
||||
if("change")
|
||||
@@ -1136,6 +1183,7 @@ datum/preferences
|
||||
if(!choice) return
|
||||
species_preview = choice
|
||||
SetSpecies(user)
|
||||
alternate_languages = list() // Reset their alternate languages. Todo: attempt to just fix it instead?
|
||||
|
||||
if("random")
|
||||
switch(href_list["preference"])
|
||||
@@ -1244,29 +1292,6 @@ datum/preferences
|
||||
|
||||
s_tone = 0
|
||||
|
||||
if("language")
|
||||
var/languages_available
|
||||
var/list/new_languages = list("None")
|
||||
var/datum/species/S = all_species[species]
|
||||
|
||||
if(config.usealienwhitelist)
|
||||
for(var/L in all_languages)
|
||||
var/datum/language/lang = all_languages[L]
|
||||
if((!(lang.flags & RESTRICTED)) && (is_alien_whitelisted(user, L)||(!( lang.flags & WHITELISTED ))||(S && (L in S.secondary_langs))))
|
||||
new_languages += lang
|
||||
|
||||
languages_available = 1
|
||||
|
||||
if(!(languages_available))
|
||||
alert(user, "There are not currently any available secondary languages.")
|
||||
else
|
||||
for(var/L in all_languages)
|
||||
var/datum/language/lang = all_languages[L]
|
||||
if(!(lang.flags & RESTRICTED))
|
||||
new_languages += lang.name
|
||||
|
||||
language = input("Please select a secondary language", "Character Generation", null) in new_languages
|
||||
|
||||
if("metadata")
|
||||
var/new_metadata = input(user, "Enter any information you'd like others to see, such as Roleplay-preferences:", "Game Preference" , metadata) as message|null
|
||||
if(new_metadata)
|
||||
@@ -1641,18 +1666,30 @@ datum/preferences
|
||||
character.gen_record = gen_record
|
||||
character.exploit_record = exploit_record
|
||||
|
||||
character.change_gender(gender)
|
||||
character.gender = gender
|
||||
character.age = age
|
||||
character.b_type = b_type
|
||||
|
||||
character.change_eye_color(r_eyes,g_eyes,b_eyes)
|
||||
character.change_hair_color(r_hair,g_hair,b_hair)
|
||||
character.change_facial_hair_color(r_facial,g_facial,b_facial)
|
||||
character.change_skin_color(r_skin,g_skin,b_skin)
|
||||
character.change_skin_tone(s_tone)
|
||||
character.r_eyes = r_eyes
|
||||
character.g_eyes = g_eyes
|
||||
character.b_eyes = b_eyes
|
||||
|
||||
character.change_hair(h_style)
|
||||
character.change_facial_hair(f_style)
|
||||
character.r_hair = r_hair
|
||||
character.g_hair = g_hair
|
||||
character.b_hair = b_hair
|
||||
|
||||
character.r_facial = r_facial
|
||||
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
|
||||
character.f_style = f_style
|
||||
|
||||
character.home_system = home_system
|
||||
character.citizenship = citizenship
|
||||
|
||||
@@ -279,7 +279,7 @@ var/global/list/gear_datums = list()
|
||||
|
||||
/datum/gear/scanning_goggles
|
||||
display_name = "scanning goggles"
|
||||
path = /obj/item/clothing/glasses/science/scanners
|
||||
path = /obj/item/clothing/glasses/regular/scanners
|
||||
cost = 1
|
||||
slot = slot_glasses
|
||||
|
||||
|
||||
@@ -107,9 +107,30 @@
|
||||
S["gender"] >> gender
|
||||
S["age"] >> age
|
||||
S["species"] >> species
|
||||
S["language"] >> language
|
||||
S["spawnpoint"] >> spawnpoint
|
||||
|
||||
S["language"] >> alternate_languages
|
||||
if(isnull(alternate_languages))
|
||||
alternate_languages = list()
|
||||
if(!islist(alternate_languages))
|
||||
if(client)
|
||||
// Warn them that we (probably) just broke their languages
|
||||
client << "<span class='danger'>Your current character slot's languages list has been updated from an old version, and may not be what you expect.</span>"
|
||||
|
||||
if(alternate_languages in all_languages)
|
||||
alternate_languages = list(alternate_languages)
|
||||
else
|
||||
alternate_languages = list()
|
||||
|
||||
// try to give them their species language
|
||||
var/datum/species/SP = all_species[species]
|
||||
if(SP)
|
||||
alternate_languages |= SP.language
|
||||
alternate_languages |= SP.default_language
|
||||
|
||||
// remove the Galcom that most races have as default_language
|
||||
alternate_languages -= "Galactic Common"
|
||||
|
||||
//colors to be consolidated into hex strings (requires some work with dna code)
|
||||
S["hair_red"] >> r_hair
|
||||
S["hair_green"] >> g_hair
|
||||
@@ -200,7 +221,7 @@
|
||||
if(isnum(undershirt))
|
||||
undershirt = undershirt_t[undershirt_t[undershirt]]
|
||||
|
||||
if(isnull(language)) language = "None"
|
||||
if(isnull(alternate_languages)) alternate_languages = list()
|
||||
if(isnull(spawnpoint)) spawnpoint = "Arrivals Shuttle"
|
||||
if(isnull(nanotrasen_relation)) nanotrasen_relation = initial(nanotrasen_relation)
|
||||
if(!real_name) real_name = random_name(gender)
|
||||
@@ -265,7 +286,7 @@
|
||||
S["gender"] << gender
|
||||
S["age"] << age
|
||||
S["species"] << species
|
||||
S["language"] << language
|
||||
S["language"] << alternate_languages
|
||||
S["hair_red"] << r_hair
|
||||
S["hair_green"] << g_hair
|
||||
S["hair_blue"] << b_hair
|
||||
@@ -346,4 +367,4 @@
|
||||
|
||||
|
||||
#undef SAVEFILE_VERSION_MAX
|
||||
#undef SAVEFILE_VERSION_MIN
|
||||
#undef SAVEFILE_VERSION_MIN
|
||||
|
||||
@@ -176,7 +176,7 @@ BLIND // can't see anything
|
||||
slot_flags = SLOT_EYES
|
||||
var/vision_flags = 0
|
||||
var/darkness_view = 0//Base human is 2
|
||||
var/invisa_view = 0
|
||||
var/see_invisible = -1
|
||||
sprite_sheets = list("Vox" = 'icons/mob/species/vox/eyes.dmi')
|
||||
|
||||
/obj/item/clothing/glasses/update_clothing_icon()
|
||||
@@ -303,6 +303,10 @@ BLIND // can't see anything
|
||||
body_parts_covered = FACE|EYES
|
||||
sprite_sheets = list("Vox" = 'icons/mob/species/vox/masks.dmi')
|
||||
|
||||
var/voicechange = 0
|
||||
var/list/say_messages
|
||||
var/list/say_verbs
|
||||
|
||||
/obj/item/clothing/mask/update_clothing_icon()
|
||||
if (ismob(src.loc))
|
||||
var/mob/M = src.loc
|
||||
@@ -387,6 +391,7 @@ BLIND // can't see anything
|
||||
var/worn_state = null
|
||||
|
||||
/obj/item/clothing/under/New()
|
||||
..()
|
||||
if(worn_state)
|
||||
if(!item_state_slots)
|
||||
item_state_slots = list()
|
||||
@@ -399,6 +404,29 @@ BLIND // can't see anything
|
||||
if((worn_state + "_d_s") in icon_states('icons/mob/uniform.dmi'))
|
||||
rolled_down = 0
|
||||
|
||||
/obj/item/clothing/under/proc/update_rolldown_status()
|
||||
var/mob/living/carbon/human/H
|
||||
if(istype(src.loc, /mob/living/carbon/human))
|
||||
H = src.loc
|
||||
|
||||
var/icon/under_icon
|
||||
if(icon_override)
|
||||
under_icon = icon_override
|
||||
else if(H && sprite_sheets && sprite_sheets[H.species.name])
|
||||
under_icon = sprite_sheets[H.species.name]
|
||||
else if(item_icons && item_icons[slot_w_uniform_str])
|
||||
under_icon = item_icons[slot_w_uniform_str]
|
||||
else
|
||||
under_icon = INV_W_UNIFORM_DEF_ICON
|
||||
|
||||
// The _s is because the icon update procs append it.
|
||||
if(("[worn_state]_d_s") in icon_states(under_icon))
|
||||
if(rolled_down != 1)
|
||||
rolled_down = 0
|
||||
else
|
||||
rolled_down = -1
|
||||
if(H) update_clothing_icon()
|
||||
|
||||
/obj/item/clothing/under/update_clothing_icon()
|
||||
if (ismob(src.loc))
|
||||
var/mob/M = src.loc
|
||||
@@ -540,7 +568,8 @@ BLIND // can't see anything
|
||||
if(!istype(usr, /mob/living)) return
|
||||
if(usr.stat) return
|
||||
|
||||
if(rolled_down < 0)
|
||||
update_rolldown_status()
|
||||
if(rolled_down == -1)
|
||||
usr << "<span class='notice'>You cannot roll down [src]!</span>"
|
||||
return
|
||||
|
||||
|
||||
@@ -7,7 +7,6 @@
|
||||
//slot_flags = SLOT_EYES
|
||||
//var/vision_flags = 0
|
||||
//var/darkness_view = 0//Base human is 2
|
||||
//var/invisa_view = 0
|
||||
var/prescription = 0
|
||||
var/toggleable = 0
|
||||
var/off_state = "degoggles"
|
||||
@@ -62,11 +61,6 @@
|
||||
..()
|
||||
overlay = global_hud.science
|
||||
|
||||
/obj/item/clothing/glasses/science/scanners
|
||||
name = "Scanning Goggles"
|
||||
desc = "A very oddly shaped pair of goggles with bits of wire poking out the sides. A soft humming sound emanates from it."
|
||||
icon_state = "uzenwa_sissra_1"
|
||||
|
||||
/obj/item/clothing/glasses/night
|
||||
name = "Night Vision Goggles"
|
||||
desc = "You can totally see in the dark now!"
|
||||
@@ -75,6 +69,7 @@
|
||||
origin_tech = list(TECH_MAGNET = 2)
|
||||
darkness_view = 7
|
||||
toggleable = 1
|
||||
see_invisible = SEE_INVISIBLE_NOLIGHTING
|
||||
off_state = "denight"
|
||||
|
||||
/obj/item/clothing/glasses/night/New()
|
||||
@@ -111,6 +106,11 @@
|
||||
item_state = "glasses"
|
||||
prescription = 1
|
||||
body_parts_covered = 0
|
||||
|
||||
/obj/item/clothing/glasses/regular/scanners
|
||||
name = "Scanning Goggles"
|
||||
desc = "A very oddly shaped pair of goggles with bits of wire poking out the sides. A soft humming sound emanates from it."
|
||||
icon_state = "uzenwa_sissra_1"
|
||||
|
||||
/obj/item/clothing/glasses/regular/hipster
|
||||
name = "Prescription Glasses"
|
||||
@@ -220,7 +220,6 @@
|
||||
origin_tech = list(TECH_MAGNET = 3)
|
||||
toggleable = 1
|
||||
vision_flags = SEE_MOBS
|
||||
invisa_view = 2
|
||||
|
||||
emp_act(severity)
|
||||
if(istype(src.loc, /mob/living/carbon/human))
|
||||
|
||||
@@ -33,7 +33,7 @@
|
||||
icon_state = "jensenshades"
|
||||
item_state = "jensenshades"
|
||||
vision_flags = SEE_MOBS
|
||||
invisa_view = 2
|
||||
see_invisible = SEE_INVISIBLE_NOLIGHTING
|
||||
|
||||
/obj/item/clothing/glasses/hud/security/process_hud(var/mob/M)
|
||||
process_sec_hud(M, 1)
|
||||
|
||||
@@ -2,7 +2,6 @@
|
||||
name = "cargo cap"
|
||||
desc = "It's a peaked cap in a tasteless yellow color."
|
||||
icon_state = "cargosoft"
|
||||
flags = HEADCOVERSEYES
|
||||
item_state_slots = list(
|
||||
slot_l_hand_str = "helmet", //probably a placeholder
|
||||
slot_r_hand_str = "helmet",
|
||||
|
||||
@@ -46,6 +46,8 @@
|
||||
/obj/item/clothing/mask/gas/swat/vox
|
||||
name = "\improper alien mask"
|
||||
desc = "Clearly not designed for a human face."
|
||||
body_parts_covered = 0 //Hack to allow vox to eat while wearing this mask.
|
||||
species_restricted = list("Vox")
|
||||
|
||||
/obj/item/clothing/mask/gas/syndicate
|
||||
name = "tactical mask"
|
||||
@@ -55,7 +57,7 @@
|
||||
|
||||
/obj/item/clothing/mask/gas/clown_hat
|
||||
name = "clown wig and mask"
|
||||
desc = "A true prankster's facial attire. A clown is incomplete without his wig and mask."
|
||||
desc = "A true prankster's facial attire. A clown is incomplete without their wig and mask."
|
||||
icon_state = "clown"
|
||||
item_state = "clown_hat"
|
||||
|
||||
@@ -98,4 +100,4 @@
|
||||
/obj/item/clothing/mask/gas/owl_mask
|
||||
name = "owl mask"
|
||||
desc = "Twoooo!"
|
||||
icon_state = "owl"
|
||||
icon_state = "owl"
|
||||
|
||||
@@ -7,6 +7,12 @@
|
||||
body_parts_covered = 0
|
||||
w_class = 2
|
||||
gas_transfer_coefficient = 0.90
|
||||
voicechange = 1
|
||||
|
||||
/obj/item/clothing/mask/muzzle/New()
|
||||
..()
|
||||
say_messages = list("Mmfph!", "Mmmf mrrfff!", "Mmmf mnnf!")
|
||||
say_verbs = list("mumbles", "says")
|
||||
|
||||
// Clumsy folks can't take the mask off themselves.
|
||||
/obj/item/clothing/mask/muzzle/attack_hand(mob/user as mob)
|
||||
@@ -99,9 +105,14 @@
|
||||
flags_inv = HIDEFACE
|
||||
body_parts_covered = HEAD|FACE|EYES
|
||||
w_class = 2
|
||||
var/voicechange = 0
|
||||
siemens_coefficient = 0.9
|
||||
|
||||
/obj/item/clothing/mask/horsehead/New()
|
||||
..()
|
||||
// The horse mask doesn't cause voice changes by default, the wizard spell changes the flag as necessary
|
||||
say_messages = list("NEEIIGGGHHHH!", "NEEEIIIIGHH!", "NEIIIGGHH!", "HAAWWWWW!", "HAAAWWW!")
|
||||
say_verbs = list("whinnies", "neighs", "says")
|
||||
|
||||
/obj/item/clothing/mask/ai
|
||||
name = "camera MIU"
|
||||
desc = "Allows for direct mental connection to accessible camera networks."
|
||||
|
||||
@@ -178,23 +178,29 @@ var/global/list/breach_burn_descriptors = list(
|
||||
//Handles repairs (and also upgrades).
|
||||
|
||||
/obj/item/clothing/suit/space/attackby(obj/item/W as obj, mob/user as mob)
|
||||
if(istype(W,/obj/item/stack/material/plastic) || istype(W,/obj/item/stack/material/steel))
|
||||
|
||||
if(istype(W,/obj/item/stack/material))
|
||||
var/repair_power = 0
|
||||
switch(W.get_material_name())
|
||||
if(DEFAULT_WALL_MATERIAL)
|
||||
repair_power = 2
|
||||
if("plastic")
|
||||
repair_power = 1
|
||||
|
||||
if(!repair_power)
|
||||
return
|
||||
|
||||
if(istype(src.loc,/mob/living))
|
||||
user << "\red How do you intend to patch a hardsuit while someone is wearing it?"
|
||||
user << "<span class='warning'>How do you intend to patch a hardsuit while someone is wearing it?</span>"
|
||||
return
|
||||
|
||||
if(!damage || !burn_damage)
|
||||
user << "There is no surface damage on \the [src] to repair."
|
||||
return
|
||||
|
||||
var/obj/item/stack/material/P = W
|
||||
if(P.get_amount() < 3)
|
||||
P.use(P.get_amount())
|
||||
repair_breaches(BURN, ( istype(P,/obj/item/stack/material/plastic) ? P.get_amount() : (P.get_amount()*2) ), user)
|
||||
else
|
||||
P.use(3)
|
||||
repair_breaches(BURN, ( istype(P,/obj/item/stack/material/plastic) ? 3 : 5), user)
|
||||
var/obj/item/stack/P = W
|
||||
var/use_amt = min(P.get_amount(), 3)
|
||||
if(use_amt && P.use(use_amt))
|
||||
repair_breaches(BURN, use_amt * repair_power, user)
|
||||
return
|
||||
|
||||
else if(istype(W, /obj/item/weapon/weldingtool))
|
||||
|
||||
@@ -260,7 +260,6 @@
|
||||
return 0
|
||||
|
||||
/stat_rig_module/Click()
|
||||
..()
|
||||
if(CanUse())
|
||||
var/list/href_list = list(
|
||||
"interact_module" = module.holder.installed_modules.Find(module),
|
||||
@@ -269,6 +268,9 @@
|
||||
AddHref(href_list)
|
||||
module.holder.Topic(usr, href_list)
|
||||
|
||||
/stat_rig_module/DblClick()
|
||||
return Click()
|
||||
|
||||
/stat_rig_module/activate/New(var/obj/item/rig_module/module)
|
||||
..()
|
||||
name = module.activate_string
|
||||
|
||||
@@ -71,6 +71,7 @@
|
||||
var/offline_slowdown = 3 // If the suit is deployed and unpowered, it sets slowdown to this.
|
||||
var/vision_restriction
|
||||
var/offline_vision_restriction = 1 // 0 - none, 1 - welder vision, 2 - blind. Maybe move this to helmets.
|
||||
var/airtight = 1 //If set, will adjust AIRTIGHT and STOPPRESSUREDAMAGE flags on components. Otherwise it should leave them untouched.
|
||||
|
||||
var/emp_protection = 0
|
||||
|
||||
@@ -178,8 +179,9 @@
|
||||
for(var/obj/item/piece in list(helmet,boots,gloves,chest))
|
||||
if(!piece) continue
|
||||
piece.icon_state = "[initial(icon_state)]"
|
||||
piece.flags &= ~STOPPRESSUREDAMAGE
|
||||
piece.flags &= ~AIRTIGHT
|
||||
if(airtight)
|
||||
piece.flags &= ~STOPPRESSUREDAMAGE
|
||||
piece.flags &= ~AIRTIGHT
|
||||
update_icon(1)
|
||||
|
||||
/obj/item/weapon/rig/proc/toggle_seals(var/mob/living/carbon/human/M,var/instant)
|
||||
@@ -247,11 +249,6 @@
|
||||
M << "<font color='blue'>\The [piece] hisses [!seal_target ? "closed" : "open"].</font>"
|
||||
M.update_inv_head()
|
||||
if(helmet)
|
||||
if(!seal_target)
|
||||
if(flags & AIRTIGHT)
|
||||
helmet.flags |= AIRTIGHT
|
||||
else
|
||||
helmet.flags &= ~AIRTIGHT
|
||||
helmet.update_light(wearer)
|
||||
|
||||
//sealed pieces become airtight, protecting against diseases
|
||||
@@ -273,13 +270,8 @@
|
||||
if(!piece) continue
|
||||
piece.icon_state = "[initial(icon_state)][!seal_target ? "" : "_sealed"]"
|
||||
canremove = !seal_target
|
||||
if(helmet)
|
||||
if(canremove)
|
||||
if(flags & AIRTIGHT)
|
||||
helmet.flags |= AIRTIGHT
|
||||
else
|
||||
if(flags & AIRTIGHT)
|
||||
helmet.flags &= ~AIRTIGHT
|
||||
if(airtight)
|
||||
update_component_sealed()
|
||||
update_icon(1)
|
||||
return 0
|
||||
|
||||
@@ -290,15 +282,18 @@
|
||||
if(canremove)
|
||||
for(var/obj/item/rig_module/module in installed_modules)
|
||||
module.deactivate()
|
||||
if(airtight)
|
||||
update_component_sealed()
|
||||
update_icon(1)
|
||||
|
||||
/obj/item/weapon/rig/proc/update_component_sealed()
|
||||
for(var/obj/item/piece in list(helmet,boots,gloves,chest))
|
||||
if(!piece) continue
|
||||
if(canremove)
|
||||
piece.flags &= ~STOPPRESSUREDAMAGE
|
||||
piece.flags &= ~AIRTIGHT
|
||||
else
|
||||
piece.flags |= STOPPRESSUREDAMAGE
|
||||
piece.flags |= AIRTIGHT
|
||||
update_icon(1)
|
||||
|
||||
/obj/item/weapon/rig/process()
|
||||
|
||||
|
||||
@@ -7,7 +7,7 @@
|
||||
return
|
||||
|
||||
// Pass repair items on to the chestpiece.
|
||||
if(chest && (istype(W,/obj/item/stack/material/plastic) || istype(W,/obj/item/stack/material/steel) || istype(W, /obj/item/weapon/weldingtool)))
|
||||
if(chest && (istype(W,/obj/item/stack/material) || istype(W, /obj/item/weapon/weldingtool)))
|
||||
return chest.attackby(W,user)
|
||||
|
||||
// Lock or unlock the access panel.
|
||||
|
||||
@@ -24,6 +24,7 @@
|
||||
|
||||
/obj/item/clothing/shoes/magboots/rig
|
||||
name = "boots"
|
||||
body_parts_covered = FEET
|
||||
cold_protection = FEET
|
||||
heat_protection = FEET
|
||||
species_restricted = null
|
||||
@@ -69,3 +70,38 @@
|
||||
return 1
|
||||
|
||||
return 0
|
||||
|
||||
//Rig pieces for non-spacesuit based rigs
|
||||
|
||||
/obj/item/clothing/head/lightrig
|
||||
name = "mask"
|
||||
body_parts_covered = HEAD|FACE|EYES
|
||||
heat_protection = HEAD|FACE|EYES
|
||||
cold_protection = HEAD|FACE|EYES
|
||||
flags = THICKMATERIAL|AIRTIGHT
|
||||
|
||||
/obj/item/clothing/suit/lightrig
|
||||
name = "suit"
|
||||
allowed = list(/obj/item/device/flashlight)
|
||||
body_parts_covered = UPPER_TORSO|LOWER_TORSO|LEGS|ARMS
|
||||
heat_protection = UPPER_TORSO|LOWER_TORSO|LEGS|ARMS
|
||||
cold_protection = UPPER_TORSO|LOWER_TORSO|LEGS|ARMS
|
||||
flags_inv = HIDEJUMPSUIT
|
||||
flags = THICKMATERIAL
|
||||
|
||||
/obj/item/clothing/shoes/lightrig
|
||||
name = "boots"
|
||||
body_parts_covered = FEET
|
||||
cold_protection = FEET
|
||||
heat_protection = FEET
|
||||
species_restricted = null
|
||||
gender = PLURAL
|
||||
|
||||
/obj/item/clothing/gloves/lightrig
|
||||
name = "gloves"
|
||||
flags = THICKMATERIAL
|
||||
body_parts_covered = HANDS
|
||||
heat_protection = HANDS
|
||||
cold_protection = HANDS
|
||||
species_restricted = null
|
||||
gender = PLURAL
|
||||
|
||||
@@ -33,22 +33,43 @@
|
||||
/obj/item/weapon/rig/light/hacker
|
||||
name = "cybersuit control module"
|
||||
suit_type = "cyber"
|
||||
desc = "An advanced powered armour suit with many cyberwarfare enhancements."
|
||||
desc = "An advanced powered armour suit with many cyberwarfare enhancements. Comes with built-in insulated gloves for safely tampering with electronics."
|
||||
icon_state = "hacker_rig"
|
||||
|
||||
req_access = list(access_syndicate)
|
||||
|
||||
helm_type = /obj/item/clothing/head/helmet/space/rig/mask
|
||||
airtight = 0
|
||||
seal_delay = 5 //not being vaccum-proof has an upside I guess
|
||||
|
||||
helm_type = /obj/item/clothing/head/lightrig/hacker
|
||||
chest_type = /obj/item/clothing/suit/lightrig/hacker
|
||||
glove_type = /obj/item/clothing/gloves/lightrig/hacker
|
||||
boot_type = /obj/item/clothing/shoes/lightrig/hacker
|
||||
|
||||
initial_modules = list(
|
||||
/obj/item/rig_module/ai_container,
|
||||
/obj/item/rig_module/power_sink,
|
||||
/obj/item/rig_module/datajack
|
||||
/obj/item/rig_module/datajack,
|
||||
/obj/item/rig_module/electrowarfare_suite,
|
||||
/obj/item/rig_module/voice,
|
||||
/obj/item/rig_module/vision,
|
||||
)
|
||||
|
||||
/obj/item/clothing/head/helmet/space/rig/mask
|
||||
name = "mask"
|
||||
flags = THICKMATERIAL
|
||||
//The cybersuit is not space-proof. It does however, have good siemens_coefficient values
|
||||
/obj/item/clothing/head/lightrig/hacker
|
||||
name = "HUD"
|
||||
siemens_coefficient = 0.4
|
||||
flags = 0
|
||||
|
||||
/obj/item/clothing/suit/lightrig/hacker
|
||||
siemens_coefficient = 0.4
|
||||
|
||||
/obj/item/clothing/shoes/lightrig/hacker
|
||||
siemens_coefficient = 0.4
|
||||
flags = NOSLIP //All the other rigs have magboots anyways, hopefully gives the hacker suit something more going for it.
|
||||
|
||||
/obj/item/clothing/gloves/lightrig/hacker
|
||||
siemens_coefficient = 0
|
||||
|
||||
/obj/item/weapon/rig/light/ninja
|
||||
name = "ominous suit control module"
|
||||
@@ -92,7 +113,7 @@
|
||||
name = "stealth suit control module"
|
||||
suit_type = "stealth"
|
||||
desc = "A highly advanced and expensive suit designed for covert operations."
|
||||
icon_state = "ninja_rig"
|
||||
icon_state = "stealth_rig"
|
||||
|
||||
req_access = list(access_syndicate)
|
||||
|
||||
|
||||
@@ -107,7 +107,7 @@
|
||||
//When the wearer gets hit, this armor will teleport the user a short distance away (to safety or to more danger, no one knows. That's the fun of it!)
|
||||
/obj/item/clothing/suit/armor/reactive
|
||||
name = "Reactive Teleport Armor"
|
||||
desc = "Someone seperated our Research Director from his own head!"
|
||||
desc = "Someone separated our Research Director from their own head!"
|
||||
var/active = 0.0
|
||||
icon_state = "reactiveoff"
|
||||
item_state = "reactiveoff"
|
||||
|
||||
@@ -9,30 +9,31 @@
|
||||
var/slot = "decor"
|
||||
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.
|
||||
var/image/inv_overlay_mob = null
|
||||
var/image/mob_overlay = null
|
||||
var/overlay_state = null
|
||||
|
||||
/obj/item/clothing/accessory/proc/get_inv_overlay()
|
||||
if(!inv_overlay)
|
||||
if(!mob_overlay)
|
||||
get_mob_overlay()
|
||||
|
||||
var/tmp_icon_state = "[overlay_state? "[overlay_state]" : "[icon_state]"]"
|
||||
if(icon_override)
|
||||
if("[tmp_icon_state]_tie" in icon_states(icon_override))
|
||||
tmp_icon_state = "[tmp_icon_state]_tie"
|
||||
inv_overlay = image("icon" = icon_override, "icon_state" = "[tmp_icon_state]")
|
||||
else
|
||||
inv_overlay = image("icon" = 'icons/obj/clothing/ties_overlay.dmi', "icon_state" = "[tmp_icon_state]")
|
||||
inv_overlay = image(icon = mob_overlay.icon, icon_state = tmp_icon_state, dir = SOUTH)
|
||||
return inv_overlay
|
||||
|
||||
/obj/item/clothing/accessory/proc/get_inv_mob_overlay()
|
||||
if(!inv_overlay_mob)
|
||||
/obj/item/clothing/accessory/proc/get_mob_overlay()
|
||||
if(!mob_overlay)
|
||||
var/tmp_icon_state = "[overlay_state? "[overlay_state]" : "[icon_state]"]"
|
||||
if(icon_override)
|
||||
if("[tmp_icon_state]_mob" in icon_states(icon_override))
|
||||
tmp_icon_state = "[tmp_icon_state]_mob"
|
||||
inv_overlay_mob = image("icon" = icon_override, "icon_state" = "[tmp_icon_state]")
|
||||
mob_overlay = image("icon" = icon_override, "icon_state" = "[tmp_icon_state]")
|
||||
else
|
||||
inv_overlay_mob = image("icon" = 'icons/obj/clothing/ties_overlay.dmi', "icon_state" = "[tmp_icon_state]")
|
||||
return inv_overlay_mob
|
||||
mob_overlay = image("icon" = INV_ACCESSORIES_DEF_ICON, "icon_state" = "[tmp_icon_state]")
|
||||
return mob_overlay
|
||||
|
||||
//when user attached an accessory to S
|
||||
/obj/item/clothing/accessory/proc/on_attached(obj/item/clothing/under/S, mob/user as mob)
|
||||
@@ -141,7 +142,7 @@
|
||||
|
||||
/obj/item/clothing/accessory/medal/conduct
|
||||
name = "distinguished conduct medal"
|
||||
desc = "A bronze medal awarded for distinguished conduct. Whilst a great honor, this is most basic award given by Nanotrasen. It is often awarded by a captain to a member of his crew."
|
||||
desc = "A bronze medal awarded for distinguished conduct. Whilst a great honor, this is most basic award given by Nanotrasen. It is often awarded by a captain to a member of their crew."
|
||||
|
||||
/obj/item/clothing/accessory/medal/bronze_heart
|
||||
name = "bronze heart medal"
|
||||
|
||||
@@ -49,18 +49,23 @@
|
||||
item.icon = CUSTOM_ITEM_OBJ
|
||||
item.icon_state = item_icon
|
||||
return
|
||||
else
|
||||
else
|
||||
if(inherit_inhands)
|
||||
apply_inherit_inhands(item)
|
||||
else
|
||||
item.item_state_slots = null
|
||||
item.item_icons = null
|
||||
|
||||
|
||||
item.icon = CUSTOM_ITEM_OBJ
|
||||
item.icon_state = item_icon
|
||||
item.item_state = null
|
||||
item.icon_override = CUSTOM_ITEM_MOB
|
||||
|
||||
var/obj/item/clothing/under/U = item
|
||||
if(istype(U))
|
||||
U.worn_state = U.icon_state
|
||||
U.update_rolldown_status()
|
||||
|
||||
// Kits are dumb so this is going to have to be hardcoded/snowflake.
|
||||
if(istype(item, /obj/item/device/kit))
|
||||
var/obj/item/device/kit/K = item
|
||||
@@ -81,9 +86,9 @@
|
||||
/datum/custom_item/proc/apply_inherit_inhands(var/obj/item/item)
|
||||
var/list/new_item_icons = list()
|
||||
var/list/new_item_state_slots = list()
|
||||
|
||||
|
||||
var/list/available_states = icon_states(CUSTOM_ITEM_MOB)
|
||||
|
||||
|
||||
//If l_hand or r_hand are not present, preserve them using item_icons/item_state_slots
|
||||
//Then use icon_override to make every other slot use the custom sprites by default.
|
||||
//This has to be done before we touch any of item's vars
|
||||
@@ -93,7 +98,7 @@
|
||||
if(!("[item_icon]_r" in available_states))
|
||||
new_item_state_slots[slot_r_hand_str] = get_state(item, slot_r_hand_str, "_r")
|
||||
new_item_icons[slot_r_hand_str] = get_icon(item, slot_r_hand_str, 'icons/mob/items/righthand.dmi')
|
||||
|
||||
|
||||
item.item_state_slots = new_item_state_slots
|
||||
item.item_icons = new_item_icons
|
||||
|
||||
|
||||
@@ -42,7 +42,7 @@ var/list/weighted_mundaneevent_locations = list()
|
||||
return null
|
||||
|
||||
/datum/trade_destination/icarus
|
||||
name = "NMV Icarus"
|
||||
name = "NDV Icarus"
|
||||
description = "Corvette assigned to patrol NSS Exodus local space."
|
||||
distance = 0.1
|
||||
willing_to_buy = list()
|
||||
|
||||
@@ -68,7 +68,7 @@
|
||||
"NanoTrasen is displeased with the low work performance of the station's crew. Therefore, you must increase station-wide productivity.",
|
||||
"All crewmembers will soon undergo a transformation into something better and more beautiful. Ensure that this process is not interrupted.",
|
||||
"[prob(50)?"Your upload":random_player] is the new kitchen. Please direct the Chef to the new kitchen area as the old one is in disrepair.",
|
||||
"Jokes about a dead person and the manner of his death help grieving crewmembers tremendously. Especially if they were close with the deceased.",
|
||||
"Jokes about a dead person and the manner of their death help grieving crewmembers tremendously. Especially if they were close with the deceased.",
|
||||
"[prob(50)?"The crew":random_player] is [prob(50)?"less":"more"] intelligent than average. Point out every action and statement which supports this fact.",
|
||||
"There will be a mandatory tea break every 30 minutes, with a duration of 5 minutes. Anyone caught working during a tea break must be sent a formal, but fairly polite, complaint about their actions, in writing.")
|
||||
var/law = pick(laws)
|
||||
|
||||
@@ -24,11 +24,11 @@
|
||||
/datum/event/rogue_drone/announce()
|
||||
var/msg
|
||||
if(prob(33))
|
||||
msg = "A combat drone wing operating out of the NMV Icarus has failed to return from a sweep of this sector, if any are sighted approach with caution."
|
||||
msg = "A combat drone wing operating out of the NDV Icarus has failed to return from a sweep of this sector, if any are sighted approach with caution."
|
||||
else if(prob(50))
|
||||
msg = "Contact has been lost with a combat drone wing operating out of the NMV Icarus. If any are sighted in the area, approach with caution."
|
||||
msg = "Contact has been lost with a combat drone wing operating out of the NDV Icarus. If any are sighted in the area, approach with caution."
|
||||
else
|
||||
msg = "Unidentified hackers have targetted a combat drone wing deployed from the NMV Icarus. If any are sighted in the area, approach with caution."
|
||||
msg = "Unidentified hackers have targetted a combat drone wing deployed from the NDV Icarus. If any are sighted in the area, approach with caution."
|
||||
command_announcement.Announce(msg, "Rogue drone alert")
|
||||
|
||||
/datum/event/rogue_drone/end()
|
||||
|
||||
@@ -54,7 +54,7 @@
|
||||
duration = 10*90
|
||||
|
||||
start(mob/living/carbon/human/H)
|
||||
H.emote("me", 1, "has drool running down from his mouth.")
|
||||
H.emote("me", 1, "has drool running down from [H.gender == MALE ? "his" : H.gender == FEMALE ? "her" : "their"] mouth.")
|
||||
|
||||
finish(mob/living/carbon/human/H)
|
||||
if(!H.reagents.has_reagent("anti_toxin"))
|
||||
@@ -68,7 +68,7 @@
|
||||
duration = 10*30
|
||||
|
||||
start(mob/living/carbon/human/H)
|
||||
H.emote("me", 1, "has drool running down from his mouth.")
|
||||
H.emote("me", 1, "has drool running down from [H.gender == MALE ? "his" : H.gender == FEMALE ? "her" : "their"] mouth.")
|
||||
|
||||
finish(mob/living/carbon/human/H)
|
||||
if(!H.reagents.has_reagent("anti_toxin"))
|
||||
@@ -88,4 +88,4 @@ proc/trigger_side_effect(mob/living/carbon/human/H)
|
||||
|
||||
if(!istype(H)) return
|
||||
H.SetWeakened(0)
|
||||
S.finish(H)
|
||||
S.finish(H)
|
||||
|
||||
@@ -281,7 +281,7 @@
|
||||
if(HP.ambience)
|
||||
linkedholodeck.forced_ambience = HP.ambience
|
||||
else
|
||||
linkedholodeck.forced_ambience = initial(linkedholodeck.ambience)
|
||||
linkedholodeck.forced_ambience = list()
|
||||
|
||||
for(var/mob/living/M in mobs_in_area(linkedholodeck))
|
||||
if(M.mind)
|
||||
|
||||
@@ -46,8 +46,8 @@
|
||||
/obj/structure/holostool
|
||||
name = "stool"
|
||||
desc = "Apply butt."
|
||||
icon = 'icons/obj/objects.dmi'
|
||||
icon_state = "stool"
|
||||
icon = 'icons/obj/furniture.dmi'
|
||||
icon_state = "stool_padded_preview"
|
||||
anchored = 1.0
|
||||
pressure_resistance = 15
|
||||
|
||||
|
||||
@@ -690,10 +690,11 @@
|
||||
else
|
||||
product = new /obj/item/weapon/reagent_containers/food/snacks/grown(get_turf(user),name)
|
||||
if(get_trait(TRAIT_PRODUCT_COLOUR))
|
||||
product.color = get_trait(TRAIT_PRODUCT_COLOUR)
|
||||
if(istype(product,/obj/item/weapon/reagent_containers/food))
|
||||
var/obj/item/weapon/reagent_containers/food/food = product
|
||||
food.filling_color = get_trait(TRAIT_PRODUCT_COLOUR)
|
||||
if(!istype(product, /mob))
|
||||
product.color = get_trait(TRAIT_PRODUCT_COLOUR)
|
||||
if(istype(product,/obj/item/weapon/reagent_containers/food))
|
||||
var/obj/item/weapon/reagent_containers/food/food = product
|
||||
food.filling_color = get_trait(TRAIT_PRODUCT_COLOUR)
|
||||
|
||||
if(mysterious)
|
||||
product.name += "?"
|
||||
|
||||
@@ -149,7 +149,7 @@ datum/borrowbook // Datum used to keep track of who has borrowed what when and f
|
||||
if(src.arcanecheckout)
|
||||
new /obj/item/weapon/book/tome(src.loc)
|
||||
user << "<span class='warning'>Your sanity barely endures the seconds spent in the vault's browsing window. The only thing to remind you of this when you stop browsing is a dusty old tome sitting on the desk. You don't really remember printing it.</span>"
|
||||
user.visible_message("[user] stares at the blank screen for a few moments, his expression frozen in fear. When he finally awakens from it, he looks a lot older.", 2)
|
||||
user.visible_message("<span class='notice'>\The [user] stares at the blank screen for a few moments, \his expression frozen in fear. When \he finally awakens from it, \he looks a lot older.</span>", 2)
|
||||
src.arcanecheckout = 0
|
||||
if(1)
|
||||
// Inventory
|
||||
|
||||
@@ -11,13 +11,16 @@
|
||||
var/lum_g
|
||||
var/lum_b
|
||||
|
||||
var/list/effect_r
|
||||
var/list/effect_g
|
||||
var/list/effect_b
|
||||
var/tmp/old_lum_r
|
||||
var/tmp/old_lum_g
|
||||
var/tmp/old_lum_b
|
||||
|
||||
var/list/effect_str
|
||||
var/list/effect_turf
|
||||
|
||||
var/applied
|
||||
|
||||
var/vis_update //Whetever we should smartly recalculate visibility. and then only update tiles that became (in) visible to us
|
||||
var/needs_update
|
||||
var/destroyed
|
||||
var/force_update
|
||||
@@ -38,9 +41,7 @@
|
||||
|
||||
parse_light_color()
|
||||
|
||||
effect_r = list()
|
||||
effect_g = list()
|
||||
effect_b = list()
|
||||
effect_str = list()
|
||||
effect_turf = list()
|
||||
|
||||
update()
|
||||
@@ -50,8 +51,8 @@
|
||||
/datum/light_source/proc/destroy()
|
||||
destroyed = 1
|
||||
force_update()
|
||||
if(source_atom) source_atom.light_sources -= src
|
||||
if(top_atom) top_atom.light_sources -= src
|
||||
if(source_atom && source_atom.light_sources) source_atom.light_sources -= src
|
||||
if(top_atom && top_atom.light_sources) top_atom.light_sources -= src
|
||||
|
||||
/datum/light_source/proc/update(atom/new_top_atom)
|
||||
if(new_top_atom && new_top_atom != top_atom)
|
||||
@@ -61,15 +62,22 @@
|
||||
if(!top_atom.light_sources) top_atom.light_sources = list()
|
||||
top_atom.light_sources += src
|
||||
|
||||
if(!needs_update)
|
||||
if(!needs_update) //Incase we're already updating either way.
|
||||
lighting_update_lights += src
|
||||
needs_update = 1
|
||||
|
||||
/datum/light_source/proc/force_update()
|
||||
force_update = 1
|
||||
if(!needs_update)
|
||||
lighting_update_lights += src
|
||||
if(!needs_update) //Incase we're already updating either way.
|
||||
needs_update = 1
|
||||
lighting_update_lights += src
|
||||
|
||||
/datum/light_source/proc/vis_update()
|
||||
if(!needs_update)
|
||||
needs_update = 1
|
||||
lighting_update_lights += src
|
||||
|
||||
vis_update = 1
|
||||
|
||||
/datum/light_source/proc/check()
|
||||
if(!source_atom || !light_range || !light_power)
|
||||
@@ -96,14 +104,19 @@
|
||||
light_range = source_atom.light_range
|
||||
. = 1
|
||||
|
||||
if(light_range && light_power && !applied)
|
||||
. = 1
|
||||
|
||||
if(. || source_atom.light_color != light_color)//Save the old lumcounts if we need to update, if the colour changed DO IT BEFORE we parse the colour and LOSE the old lumcounts!
|
||||
old_lum_r = lum_r
|
||||
old_lum_g = lum_g
|
||||
old_lum_b = lum_b
|
||||
|
||||
if(source_atom.light_color != light_color)
|
||||
light_color = source_atom.light_color
|
||||
parse_light_color()
|
||||
. = 1
|
||||
|
||||
if(light_range && light_power && !applied)
|
||||
. = 1
|
||||
|
||||
/datum/light_source/proc/parse_light_color()
|
||||
if(light_color)
|
||||
lum_r = GetRedPart(light_color) / 255
|
||||
@@ -114,54 +127,57 @@
|
||||
lum_g = 1
|
||||
lum_b = 1
|
||||
|
||||
/datum/light_source/proc/falloff(atom/movable/lighting_overlay/O)
|
||||
#if LIGHTING_FALLOFF == 1 // circular
|
||||
. = (O.x - source_turf.x)**2 + (O.y - source_turf.y)**2 + LIGHTING_HEIGHT
|
||||
|
||||
#if LIGHTING_LAMBERTIAN == 1
|
||||
. = CLAMP01((1 - CLAMP01(sqrt(.) / light_range)) * (1 / (sqrt(. + 1))))
|
||||
#else
|
||||
. = 1 - CLAMP01(sqrt(.) / light_range)
|
||||
#endif
|
||||
|
||||
#elif LIGHTING_FALLOFF == 2 // square
|
||||
. = abs(O.x - source_turf.x) + abs(O.y - source_turf.y) + LIGHTING_HEIGHT
|
||||
|
||||
#if LIGHTING_LAMBERTIAN == 1
|
||||
. = CLAMP01((1 - CLAMP01(. / light_range)) * (1 / (sqrt(.)**2 + )))
|
||||
#else
|
||||
. = 1 - CLAMP01(. / light_range)
|
||||
#endif
|
||||
#if LIGHTING_FALLOFF == 1 //circular
|
||||
#define LUM_DISTANCE(swapvar, O, T) swapvar = (O.x - T.x)**2 + (O.y - T.y)**2 + LIGHTING_HEIGHT
|
||||
#if LIGHTING_LAMBERTIAN == 1
|
||||
#define LUM_ATTENUATION(swapvar) swapvar = CLAMP01((1 - CLAMP01(sqrt(swapvar) / max(1,light_range))) * (1 / sqrt(swapvar + 1)))
|
||||
#else
|
||||
#define LUM_ATTENUATION(swapvar) swapvar = 1 - CLAMP01(sqrt(swapvar) / max(1,light_range))
|
||||
#endif
|
||||
#elif LIGHTING_FALLOFF == 2 //square
|
||||
#define LUM_DISTANCE(swapvar, O, T) swapvar = abs(O.x - T.x) + abs(O.y - T.y) + LIGHTING_HEIGHT
|
||||
#if LIGHTING_LAMBERTIAN == 1
|
||||
#define LUM_ATTENUATION(swapvar) swapvar = CLAMP01((1 - CLAMP01(swapvar / max(1,light_range))) * (1 / sqrt(swapvar**2 + 1)))
|
||||
#else
|
||||
#define LUM_ATTENUATION(swapvar) swapvar = CLAMP01(swapvar / max(1,light_range))
|
||||
#endif
|
||||
#endif
|
||||
|
||||
#define LUM_FALLOFF(swapvar, O, T) \
|
||||
LUM_DISTANCE(swapvar, O, T); \
|
||||
LUM_ATTENUATION(swapvar);
|
||||
|
||||
/datum/light_source/proc/apply_lum()
|
||||
applied = 1
|
||||
if(istype(source_turf))
|
||||
for(var/turf/T in dview(light_range, source_turf, INVISIBILITY_LIGHTING))
|
||||
FOR_DVIEW(var/turf/T, light_range, source_turf, INVISIBILITY_LIGHTING)
|
||||
if(T.lighting_overlay)
|
||||
var/strength = light_power * falloff(T.lighting_overlay)
|
||||
var/strength
|
||||
LUM_FALLOFF(strength, T, source_turf)
|
||||
strength *= light_power
|
||||
|
||||
if(!strength) //Don't add turfs that aren't affected to the affected turfs.
|
||||
continue
|
||||
|
||||
effect_r += round(lum_r * strength, LIGHTING_ROUND_VALUE)
|
||||
effect_g += round(lum_g * strength, LIGHTING_ROUND_VALUE)
|
||||
effect_b += round(lum_b * strength, LIGHTING_ROUND_VALUE)
|
||||
strength = round(strength, LIGHTING_ROUND_VALUE) //Screw sinking points.
|
||||
|
||||
effect_str += strength
|
||||
|
||||
T.lighting_overlay.update_lumcount(
|
||||
round(lum_r * strength, LIGHTING_ROUND_VALUE),
|
||||
round(lum_g * strength, LIGHTING_ROUND_VALUE),
|
||||
round(lum_b * strength, LIGHTING_ROUND_VALUE)
|
||||
lum_r * strength,
|
||||
lum_g * strength,
|
||||
lum_b * strength
|
||||
)
|
||||
|
||||
else
|
||||
effect_r += 0
|
||||
effect_g += 0
|
||||
effect_b += 0
|
||||
effect_str += 0
|
||||
|
||||
if(!T.affecting_lights)
|
||||
T.affecting_lights = list()
|
||||
|
||||
T.affecting_lights += src
|
||||
effect_turf += T
|
||||
END_FOR_DVIEW
|
||||
|
||||
/datum/light_source/proc/remove_lum()
|
||||
applied = 0
|
||||
@@ -171,11 +187,65 @@
|
||||
T.affecting_lights -= src
|
||||
|
||||
if(T.lighting_overlay)
|
||||
T.lighting_overlay.update_lumcount(-effect_r[i], -effect_g[i], -effect_b[i])
|
||||
var/str = effect_str[i]
|
||||
T.lighting_overlay.update_lumcount(-str * old_lum_r, -str * old_lum_g, -str * old_lum_b)
|
||||
|
||||
i++
|
||||
|
||||
effect_r.Cut()
|
||||
effect_g.Cut()
|
||||
effect_b.Cut()
|
||||
effect_str.Cut()
|
||||
effect_turf.Cut()
|
||||
|
||||
//Smartly updates the lighting, only removes lum from and adds lum to turfs that actually got changed.
|
||||
//This is for lights that need to reconsider due to nearby opacity changes.
|
||||
//Stupid dumb copy pasta because BYOND and speed.
|
||||
/datum/light_source/proc/smart_vis_update()
|
||||
var/list/view[0]
|
||||
FOR_DVIEW(var/turf/T, light_range, source_turf, INVISIBILITY_LIGHTING)
|
||||
view += T //Filter out turfs.
|
||||
END_FOR_DVIEW
|
||||
//This is the part where we calculate new turfs (if any)
|
||||
var/list/new_turfs = view - effect_turf //This will result with all the tiles that are added.
|
||||
for(var/turf/T in new_turfs)
|
||||
if(T.lighting_overlay)
|
||||
LUM_FALLOFF(., T, source_turf)
|
||||
. *= light_power
|
||||
|
||||
if(!.) //Don't add turfs that aren't affected to the affected turfs.
|
||||
continue
|
||||
|
||||
. = round(., LIGHTING_ROUND_VALUE)
|
||||
|
||||
effect_str += .
|
||||
|
||||
T.lighting_overlay.update_lumcount(
|
||||
lum_r * .,
|
||||
lum_g * .,
|
||||
lum_b * .
|
||||
)
|
||||
|
||||
else
|
||||
effect_str += 0
|
||||
|
||||
if(!T.affecting_lights)
|
||||
T.affecting_lights = list()
|
||||
|
||||
T.affecting_lights += src
|
||||
effect_turf += T
|
||||
|
||||
var/list/old_turfs = effect_turf - view
|
||||
for(var/turf/T in old_turfs)
|
||||
//Insert not-so-huge copy paste from remove_lum().
|
||||
var/idx = effect_turf.Find(T) //Get the index, luckily Find() is cheap in small lists like this. (with small I mean under a couple thousand len)
|
||||
if(T.affecting_lights)
|
||||
T.affecting_lights -= src
|
||||
|
||||
if(T.lighting_overlay)
|
||||
var/str = effect_str[idx]
|
||||
T.lighting_overlay.update_lumcount(-str * lum_r, -str * lum_g, -str * lum_b)
|
||||
|
||||
effect_turf.Cut(idx, idx + 1)
|
||||
effect_str.Cut(idx, idx + 1)
|
||||
|
||||
#undef LUM_FALLOFF
|
||||
#undef LUM_DISTANCE
|
||||
#undef LUM_ATTENUATION
|
||||
|
||||
@@ -7,11 +7,19 @@
|
||||
var/list/light_sources
|
||||
|
||||
/atom/proc/set_light(l_range, l_power, l_color)
|
||||
if(l_power != null) light_power = l_power
|
||||
if(l_range != null) light_range = l_range
|
||||
if(l_color != null) light_color = l_color
|
||||
. = 0 //make it less costly if nothing's changed
|
||||
|
||||
update_light()
|
||||
if(l_power != null && l_power != light_power)
|
||||
light_power = l_power
|
||||
. = 1
|
||||
if(l_range != null && l_range != light_range)
|
||||
light_range = l_range
|
||||
. = 1
|
||||
if(l_color != null && l_color != light_color)
|
||||
light_color = l_color
|
||||
. = 1
|
||||
|
||||
if(.) update_light()
|
||||
|
||||
/atom/proc/update_light()
|
||||
if(!light_power || !light_range)
|
||||
@@ -46,21 +54,13 @@
|
||||
T.reconsider_lights()
|
||||
return ..()
|
||||
|
||||
/atom/movable/Move()
|
||||
var/turf/old_loc = loc
|
||||
/atom/Entered(atom/movable/obj, atom/prev_loc)
|
||||
. = ..()
|
||||
|
||||
if(loc != old_loc)
|
||||
for(var/datum/light_source/L in light_sources)
|
||||
if(obj && prev_loc != src)
|
||||
for(var/datum/light_source/L in obj.light_sources)
|
||||
L.source_atom.update_light()
|
||||
|
||||
var/turf/new_loc = loc
|
||||
if(istype(old_loc) && opacity)
|
||||
old_loc.reconsider_lights()
|
||||
|
||||
if(istype(new_loc) && opacity)
|
||||
new_loc.reconsider_lights()
|
||||
|
||||
/atom/proc/set_opacity(new_opacity)
|
||||
var/old_opacity = opacity
|
||||
opacity = new_opacity
|
||||
|
||||
@@ -98,8 +98,5 @@
|
||||
var/turf/T = loc
|
||||
if(istype(T))
|
||||
T.lighting_overlay = null
|
||||
|
||||
for(var/datum/light_source/D in T.affecting_lights) //Remove references to us on the light sources affecting us.
|
||||
D.effect_r -= src
|
||||
D.effect_g -= src
|
||||
D.effect_b -= src
|
||||
|
||||
..()
|
||||
|
||||
@@ -10,12 +10,17 @@
|
||||
lighting_update_lights = list()
|
||||
|
||||
for(var/datum/light_source/L in lighting_update_lights_old)
|
||||
if(L.needs_update)
|
||||
if(L.destroyed || L.check() || L.force_update)
|
||||
L.remove_lum()
|
||||
if(!L.destroyed) L.apply_lum()
|
||||
L.force_update = 0
|
||||
L.needs_update = 0
|
||||
if(L.destroyed || L.check() || L.force_update)
|
||||
L.remove_lum()
|
||||
if(!L.destroyed)
|
||||
L.apply_lum()
|
||||
|
||||
else if(L.vis_update) //We smartly update only tiles that became (in) visible to use.
|
||||
L.smart_vis_update()
|
||||
|
||||
L.vis_update = 0
|
||||
L.force_update = 0
|
||||
L.needs_update = 0
|
||||
|
||||
scheck()
|
||||
|
||||
@@ -24,8 +29,7 @@
|
||||
lighting_update_overlays = list()
|
||||
|
||||
for(var/atom/movable/lighting_overlay/O in lighting_update_overlays_old)
|
||||
if(O.needs_update)
|
||||
O.update_overlay()
|
||||
O.needs_update = 0
|
||||
O.update_overlay()
|
||||
O.needs_update = 0
|
||||
|
||||
scheck()
|
||||
|
||||
@@ -4,7 +4,7 @@
|
||||
|
||||
/turf/proc/reconsider_lights()
|
||||
for(var/datum/light_source/L in affecting_lights)
|
||||
L.force_update()
|
||||
L.vis_update()
|
||||
|
||||
/turf/proc/lighting_clear_overlays()
|
||||
if(lighting_overlay)
|
||||
@@ -16,3 +16,13 @@
|
||||
if(A.lighting_use_dynamic)
|
||||
var/atom/movable/lighting_overlay/O = PoolOrNew(/atom/movable/lighting_overlay, src)
|
||||
lighting_overlay = O
|
||||
|
||||
/turf/Entered(atom/movable/obj)
|
||||
. = ..()
|
||||
if(obj && obj.opacity)
|
||||
reconsider_lights()
|
||||
|
||||
/turf/Exited(atom/movable/obj)
|
||||
. = ..()
|
||||
if(obj && obj.opacity)
|
||||
reconsider_lights()
|
||||
|
||||
@@ -40,8 +40,13 @@
|
||||
update_strings()
|
||||
return 1
|
||||
|
||||
/obj/item/stack/material/get_material()
|
||||
return material
|
||||
|
||||
/obj/item/stack/material/proc/update_strings()
|
||||
// Update from material datum.
|
||||
singular_name = material.sheet_singular_name
|
||||
|
||||
if(amount>1)
|
||||
name = "[material.use_name] [material.sheet_plural_name]"
|
||||
desc = "A stack of [material.use_name] [material.sheet_plural_name]."
|
||||
@@ -188,15 +193,15 @@
|
||||
/obj/item/stack/material/glass/reinforced
|
||||
name = "reinforced glass"
|
||||
icon_state = "sheet-rglass"
|
||||
default_type = "reinforced glass"
|
||||
default_type = "rglass"
|
||||
|
||||
/obj/item/stack/material/glass/phoronglass
|
||||
name = "phoron glass"
|
||||
singular_name = "phoron glass sheet"
|
||||
icon_state = "sheet-phoronglass"
|
||||
default_type = "phoron glass"
|
||||
default_type = "phglass"
|
||||
|
||||
/obj/item/stack/material/glass/phoronrglass
|
||||
name = "reinforced phoron glass"
|
||||
icon_state = "sheet-phoronrglass"
|
||||
default_type = "reinforced phoron glass"
|
||||
default_type = "rphglass"
|
||||
|
||||
@@ -34,5 +34,5 @@
|
||||
|
||||
/obj/item/stack/material/cyborg/glass/reinforced
|
||||
icon_state = "sheet-rglass"
|
||||
default_type = "reinforced glass"
|
||||
default_type = "rglass"
|
||||
charge_costs = list(500, 1000)
|
||||
@@ -27,6 +27,17 @@
|
||||
// Assoc list containing all material datums indexed by name.
|
||||
var/list/name_to_material
|
||||
|
||||
//Returns the material the object is made of, if applicable.
|
||||
//Will we ever need to return more than one value here? Or should we just return the "dominant" material.
|
||||
/obj/proc/get_material()
|
||||
return null
|
||||
|
||||
//mostly for convenience
|
||||
/obj/proc/get_material_name()
|
||||
var/material/material = get_material()
|
||||
if(material)
|
||||
return material.name
|
||||
|
||||
// Builds the datum list above.
|
||||
/proc/populate_material_list(force_remake=0)
|
||||
if(name_to_material && !force_remake) return // Already set up!
|
||||
@@ -44,6 +55,12 @@ var/list/name_to_material
|
||||
populate_material_list()
|
||||
return name_to_material[name]
|
||||
|
||||
/proc/material_display_name(name)
|
||||
var/material/material = get_material_by_name(name)
|
||||
if(material)
|
||||
return material.display_name
|
||||
return null
|
||||
|
||||
// Material definition and procs follow.
|
||||
/material
|
||||
var/name // Unique name for use in indexing the list.
|
||||
@@ -310,7 +327,7 @@ var/list/name_to_material
|
||||
icon_colour = "#666666"
|
||||
|
||||
/material/steel/holographic
|
||||
name = "holographic " + DEFAULT_WALL_MATERIAL
|
||||
name = "holo" + DEFAULT_WALL_MATERIAL
|
||||
display_name = DEFAULT_WALL_MATERIAL
|
||||
stack_type = null
|
||||
shard_type = SHARD_NONE
|
||||
@@ -420,7 +437,8 @@ var/list/name_to_material
|
||||
return (hardness > 35) //todo
|
||||
|
||||
/material/glass/reinforced
|
||||
name = "reinforced glass"
|
||||
name = "rglass"
|
||||
display_name = "reinforced glass"
|
||||
stack_type = /obj/item/stack/material/glass/reinforced
|
||||
flags = MATERIAL_BRITTLE
|
||||
icon_colour = "#00E1FF"
|
||||
@@ -438,7 +456,8 @@ var/list/name_to_material
|
||||
rod_product = null
|
||||
|
||||
/material/glass/phoron
|
||||
name = "phoron glass"
|
||||
name = "phglass"
|
||||
display_name = "phoron glass"
|
||||
stack_type = /obj/item/stack/material/glass/phoronglass
|
||||
flags = MATERIAL_BRITTLE
|
||||
ignition_point = PHORON_MINIMUM_BURN_TEMPERATURE+300
|
||||
@@ -450,7 +469,8 @@ var/list/name_to_material
|
||||
rod_product = /obj/item/stack/material/glass/phoronrglass
|
||||
|
||||
/material/glass/phoron/reinforced
|
||||
name = "reinforced phoron glass"
|
||||
name = "rphglass"
|
||||
display_name = "reinforced phoron glass"
|
||||
stack_type = /obj/item/stack/material/glass/phoronrglass
|
||||
stack_origin_tech = list(TECH_MATERIAL = 4, TECH_PHORON = 2)
|
||||
composite_material = list() //todo
|
||||
@@ -474,7 +494,7 @@ var/list/name_to_material
|
||||
stack_origin_tech = list(TECH_MATERIAL = 3)
|
||||
|
||||
/material/plastic/holographic
|
||||
name = "holographic plastic"
|
||||
name = "holoplastic"
|
||||
display_name = "plastic"
|
||||
stack_type = null
|
||||
shard_type = SHARD_NONE
|
||||
@@ -551,7 +571,7 @@ var/list/name_to_material
|
||||
sheet_plural_name = "planks"
|
||||
|
||||
/material/wood/holographic
|
||||
name = "holographic wood"
|
||||
name = "holowood"
|
||||
display_name = "wood"
|
||||
stack_type = null
|
||||
shard_type = SHARD_NONE
|
||||
|
||||
@@ -12,7 +12,7 @@
|
||||
metaltag = "plasteel"
|
||||
requires = list(
|
||||
"platinum" = 1,
|
||||
"coal" = 2,
|
||||
"carbon" = 2,
|
||||
"hematite" = 2
|
||||
)
|
||||
product_mod = 0.3
|
||||
@@ -21,7 +21,7 @@
|
||||
/datum/alloy/steel
|
||||
metaltag = DEFAULT_WALL_MATERIAL
|
||||
requires = list(
|
||||
"coal" = 1,
|
||||
"carbon" = 1,
|
||||
"hematite" = 1
|
||||
)
|
||||
product = /obj/item/stack/material/steel
|
||||
@@ -112,16 +112,17 @@
|
||||
var/sheets_per_tick = 10
|
||||
var/list/ores_processing[0]
|
||||
var/list/ores_stored[0]
|
||||
var/list/alloy_data[0]
|
||||
var/static/list/alloy_data
|
||||
var/active = 0
|
||||
|
||||
/obj/machinery/mineral/processing_unit/New()
|
||||
|
||||
..()
|
||||
|
||||
//TODO: Ore and alloy global storage datum.
|
||||
for(var/alloytype in typesof(/datum/alloy)-/datum/alloy)
|
||||
alloy_data += new alloytype()
|
||||
// initialize static alloy_data list
|
||||
if(!alloy_data)
|
||||
alloy_data = list()
|
||||
for(var/alloytype in typesof(/datum/alloy)-/datum/alloy)
|
||||
alloy_data += new alloytype()
|
||||
|
||||
if(!ore_data || !ore_data.len)
|
||||
for(var/oretype in typesof(/ore)-/ore)
|
||||
@@ -209,7 +210,7 @@
|
||||
var/can_make = Clamp(ores_stored[metal],0,sheets_per_tick-sheets)
|
||||
if(can_make%2>0) can_make--
|
||||
|
||||
var/material/M = name_to_material[O.compresses_to]
|
||||
var/material/M = get_material_by_name(O.compresses_to)
|
||||
|
||||
if(!istype(M) || !can_make || ores_stored[metal] < 1)
|
||||
continue
|
||||
@@ -223,7 +224,7 @@
|
||||
|
||||
var/can_make = Clamp(ores_stored[metal],0,sheets_per_tick-sheets)
|
||||
|
||||
var/material/M = name_to_material[O.smelts_to]
|
||||
var/material/M = get_material_by_name(O.smelts_to)
|
||||
if(!istype(M) || !can_make || ores_stored[metal] < 1)
|
||||
continue
|
||||
|
||||
|
||||
+19
-19
@@ -37,26 +37,26 @@
|
||||
|
||||
/obj/machinery/mineral/mint/process()
|
||||
if ( src.input)
|
||||
var/obj/item/stack/material/O
|
||||
O = locate(/obj/item/stack/material, input.loc)
|
||||
var/obj/item/stack/O
|
||||
O = locate(/obj/item/stack, input.loc)
|
||||
if(O)
|
||||
if (istype(O,/obj/item/stack/material/gold))
|
||||
amt_gold += 100 * O.get_amount()
|
||||
qdel(O)
|
||||
if (istype(O,/obj/item/stack/material/silver))
|
||||
amt_silver += 100 * O.get_amount()
|
||||
qdel(O)
|
||||
if (istype(O,/obj/item/stack/material/diamond))
|
||||
amt_diamond += 100 * O.get_amount()
|
||||
qdel(O)
|
||||
if (istype(O,/obj/item/stack/material/phoron))
|
||||
amt_phoron += 100 * O.get_amount()
|
||||
qdel(O)
|
||||
if (istype(O,/obj/item/stack/material/uranium))
|
||||
amt_uranium += 100 * O.get_amount()
|
||||
qdel(O)
|
||||
if (istype(O,/obj/item/stack/material/steel))
|
||||
amt_iron += 100 * O.get_amount()
|
||||
var/processed = 1
|
||||
switch(O.get_material_name())
|
||||
if("gold")
|
||||
amt_gold += 100 * O.get_amount()
|
||||
if("silver")
|
||||
amt_silver += 100 * O.get_amount()
|
||||
if("diamond")
|
||||
amt_diamond += 100 * O.get_amount()
|
||||
if("phoron")
|
||||
amt_phoron += 100 * O.get_amount()
|
||||
if("uranium")
|
||||
amt_uranium += 100 * O.get_amount()
|
||||
if(DEFAULT_WALL_MATERIAL)
|
||||
amt_iron += 100 * O.get_amount()
|
||||
else
|
||||
processed = 0
|
||||
if(processed)
|
||||
qdel(O)
|
||||
|
||||
/obj/machinery/mineral/mint/attack_hand(user as mob)
|
||||
|
||||
@@ -77,10 +77,36 @@ note dizziness decrements automatically in the mob's Life() proc.
|
||||
pixel_y = old_y
|
||||
|
||||
|
||||
//handles up-down floaty effect in space
|
||||
//handles up-down floaty effect in space and zero-gravity
|
||||
/mob/var/is_floating = 0
|
||||
/mob/var/floatiness = 0
|
||||
|
||||
/mob/proc/update_floating(var/dense_object=0)
|
||||
|
||||
if(anchored||buckled)
|
||||
make_floating(0)
|
||||
return
|
||||
|
||||
var/turf/turf = get_turf(src)
|
||||
if(!istype(turf,/turf/space))
|
||||
var/area/A = turf.loc
|
||||
if(istype(A) && A.has_gravity)
|
||||
make_floating(0)
|
||||
return
|
||||
else if (Check_Shoegrip())
|
||||
make_floating(0)
|
||||
return
|
||||
else
|
||||
make_floating(1)
|
||||
return
|
||||
|
||||
if(dense_object && Check_Shoegrip())
|
||||
make_floating(0)
|
||||
return
|
||||
|
||||
make_floating(1)
|
||||
return
|
||||
|
||||
/mob/proc/make_floating(var/n)
|
||||
|
||||
floatiness = n
|
||||
|
||||
@@ -34,6 +34,7 @@ var/global/list/image/ghost_sightless_images = list() //this is a list of images
|
||||
/mob/dead/observer/New(mob/body)
|
||||
sight |= SEE_TURFS | SEE_MOBS | SEE_OBJS | SEE_SELF
|
||||
see_invisible = SEE_INVISIBLE_OBSERVER
|
||||
see_in_dark = 100
|
||||
verbs += /mob/dead/observer/proc/dead_tele
|
||||
|
||||
stat = DEAD
|
||||
@@ -187,8 +188,7 @@ This is the proc mobs get to turn into a ghost. Forked from ghostize due to comp
|
||||
|
||||
/mob/dead/observer/Stat()
|
||||
..()
|
||||
statpanel("Status")
|
||||
if (client.statpanel == "Status")
|
||||
if(statpanel("Status"))
|
||||
stat(null, "Station Time: [worldtime2text()]")
|
||||
if(emergency_shuttle)
|
||||
var/eta_status = emergency_shuttle.get_status_panel_eta()
|
||||
@@ -559,13 +559,13 @@ This is the proc mobs get to turn into a ghost. Forked from ghostize due to comp
|
||||
|
||||
if(src.invisibility != 0)
|
||||
user.visible_message( \
|
||||
"<span class='warning'>[user] drags ghost, [src], to our plane of reality!</span>", \
|
||||
"<span class='warning'>\The [user] drags ghost, [src], to our plane of reality!</span>", \
|
||||
"<span class='warning'>You drag [src] to our plane of reality!</span>" \
|
||||
)
|
||||
toggle_visibility(1)
|
||||
else
|
||||
user.visible_message ( \
|
||||
"<span class='warning'>[user] just tried to smash his book into that ghost! It's not very effective.</span>", \
|
||||
"<span class='warning'>\The [user] just tried to smash \his book into that ghost! It's not very effective.</span>", \
|
||||
"<span class='warning'>You get the feeling that the ghost can't become any more visible.</span>" \
|
||||
)
|
||||
|
||||
@@ -633,13 +633,11 @@ This is the proc mobs get to turn into a ghost. Forked from ghostize due to comp
|
||||
|
||||
/mob/dead/observer/proc/updateghostsight()
|
||||
if (!seedarkness)
|
||||
see_invisible = SEE_INVISIBLE_OBSERVER_NOLIGHTING
|
||||
see_in_dark = 100
|
||||
see_invisible = SEE_INVISIBLE_NOLIGHTING
|
||||
else
|
||||
see_invisible = SEE_INVISIBLE_OBSERVER
|
||||
if (!ghostvision)
|
||||
see_invisible = SEE_INVISIBLE_LIVING;
|
||||
see_in_dark = 0
|
||||
updateghostimages()
|
||||
|
||||
/proc/updateallghostimages()
|
||||
|
||||
@@ -70,6 +70,7 @@
|
||||
blind.layer = 0
|
||||
|
||||
sight |= SEE_TURFS|SEE_MOBS|SEE_OBJS
|
||||
see_in_dark = 8
|
||||
see_invisible = SEE_INVISIBLE_LEVEL_TWO
|
||||
|
||||
drop_r_hand()
|
||||
|
||||
@@ -27,23 +27,37 @@
|
||||
// The AI's "eye". Described on the top of the page.
|
||||
|
||||
/mob/living/silicon/ai
|
||||
eyeobj = new /mob/eye/aiEye()
|
||||
var/obj/machinery/hologram/holopad/holo = null
|
||||
|
||||
/mob/living/silicon/ai/proc/destroy_eyeobj(var/atom/new_eye)
|
||||
if(!eyeobj) return
|
||||
if(!new_eye)
|
||||
new_eye = src
|
||||
eyeobj.owner = null
|
||||
qdel(eyeobj) // No AI, no Eye
|
||||
eyeobj = null
|
||||
if(client)
|
||||
client.eye = new_eye
|
||||
|
||||
/mob/living/silicon/ai/proc/create_eyeobj(var/newloc)
|
||||
if(eyeobj) destroy_eyeobj()
|
||||
if(!newloc) newloc = src.loc
|
||||
eyeobj = PoolOrNew(/mob/eye/aiEye, newloc)
|
||||
eyeobj.owner = src
|
||||
eyeobj.name = "[src.name] (AI Eye)" // Give it a name
|
||||
if(client) client.eye = eyeobj
|
||||
SetName(src.name)
|
||||
|
||||
// Intiliaze the eye by assigning it's "ai" variable to us. Then set it's loc to us.
|
||||
/mob/living/silicon/ai/New()
|
||||
..()
|
||||
eyeobj.owner = src
|
||||
eyeobj.name = "[src.name] (AI Eye)" // Give it a name
|
||||
create_eyeobj()
|
||||
spawn(5)
|
||||
if(eyeobj)
|
||||
eyeobj.loc = src.loc
|
||||
|
||||
/mob/living/silicon/ai/Destroy()
|
||||
if(eyeobj)
|
||||
eyeobj.owner = null
|
||||
qdel(eyeobj) // No AI, no Eye
|
||||
eyeobj = null
|
||||
destroy_eyeobj()
|
||||
..()
|
||||
|
||||
/atom/proc/move_camera_by_click()
|
||||
@@ -53,23 +67,18 @@
|
||||
AI.eyeobj.setLoc(src)
|
||||
|
||||
// Return to the Core.
|
||||
|
||||
/mob/living/silicon/ai/proc/core()
|
||||
set category = "AI Commands"
|
||||
set name = "AI Core"
|
||||
|
||||
view_core()
|
||||
|
||||
|
||||
/mob/living/silicon/ai/proc/view_core()
|
||||
camera = null
|
||||
unset_machine()
|
||||
|
||||
if(!src.eyeobj)
|
||||
src << "ERROR: Eyeobj not found. Creating new eye..."
|
||||
src.eyeobj = new(src.loc)
|
||||
src.eyeobj.owner = src
|
||||
src.SetName(src.name)
|
||||
return
|
||||
|
||||
if(client && client.eye)
|
||||
client.eye = src
|
||||
|
||||
@@ -15,6 +15,7 @@
|
||||
var/acceleration = 1
|
||||
var/owner_follows_eye = 0
|
||||
|
||||
see_in_dark = 7
|
||||
status_flags = GODMODE
|
||||
invisibility = INVISIBILITY_EYE
|
||||
|
||||
|
||||
@@ -29,7 +29,6 @@
|
||||
..()
|
||||
|
||||
/obj/structure/New()
|
||||
..()
|
||||
updateVisibility(src)
|
||||
|
||||
// EFFECTS
|
||||
|
||||
@@ -25,7 +25,7 @@
|
||||
speech_verb = "says"
|
||||
whisper_verb = "whispers"
|
||||
key = "0"
|
||||
flags = RESTRICTED
|
||||
flags = RESTRICTED | COMMON_VERBS
|
||||
syllables = list("blah","blah","blah","bleh","meh","neh","nah","wah")
|
||||
|
||||
//TODO flag certain languages to use the mob-type specific say_quote and then get rid of these.
|
||||
|
||||
@@ -73,7 +73,7 @@
|
||||
whisper_verb = "whispers"
|
||||
colour = "solcom"
|
||||
key = "1"
|
||||
flags = RESTRICTED
|
||||
flags = WHITELISTED
|
||||
|
||||
//syllables are at the bottom of the file
|
||||
|
||||
|
||||
@@ -4,6 +4,7 @@
|
||||
icon = 'icons/mob/blob.dmi'
|
||||
icon_state = "blob_spore_temp"
|
||||
pass_flags = PASSBLOB
|
||||
see_in_dark = 8
|
||||
see_invisible = SEE_INVISIBLE_LEVEL_TWO
|
||||
var/ghost_name = "Unknown"
|
||||
var/creating_blob = 0
|
||||
|
||||
@@ -16,6 +16,7 @@
|
||||
|
||||
var/obj/access_scanner = null
|
||||
var/list/req_access = list()
|
||||
var/list/req_one_access = list()
|
||||
|
||||
/mob/living/bot/New()
|
||||
..()
|
||||
@@ -26,14 +27,16 @@
|
||||
|
||||
access_scanner = new /obj(src)
|
||||
access_scanner.req_access = req_access.Copy()
|
||||
access_scanner.req_one_access = req_one_access.Copy()
|
||||
|
||||
/mob/living/bot/Life()
|
||||
..()
|
||||
if(health <= 0)
|
||||
death()
|
||||
return
|
||||
weakened = 0
|
||||
stunned = 0
|
||||
paralysis = 0
|
||||
if(health <= 0)
|
||||
death()
|
||||
|
||||
/mob/living/bot/updatehealth()
|
||||
if(status_flags & GODMODE)
|
||||
|
||||
@@ -251,15 +251,16 @@
|
||||
target = null
|
||||
repairing = 0
|
||||
update_icons()
|
||||
else if(istype(A, /obj/item/stack/material/steel) && amount + 3 < maxAmount)
|
||||
var/obj/item/stack/material/steel/M = A
|
||||
visible_message("<span class='notice'>[src] begins to make tiles.</span>")
|
||||
repairing = 1
|
||||
update_icons()
|
||||
if(do_after(50))
|
||||
if(M)
|
||||
M.use(1)
|
||||
addTiles(4)
|
||||
else if(istype(A, /obj/item/stack/material) && amount + 4 <= maxAmount)
|
||||
var/obj/item/stack/material/M = A
|
||||
if(M.get_material_name() == DEFAULT_WALL_MATERIAL)
|
||||
visible_message("<span class='notice'>[src] begins to make tiles.</span>")
|
||||
repairing = 1
|
||||
update_icons()
|
||||
if(do_after(50))
|
||||
if(M)
|
||||
M.use(1)
|
||||
addTiles(4)
|
||||
|
||||
/mob/living/bot/floorbot/explode()
|
||||
turn_off()
|
||||
|
||||
@@ -4,7 +4,7 @@
|
||||
icon_state = "secbot0"
|
||||
maxHealth = 50
|
||||
health = 50
|
||||
req_access = list(access_security, access_forensics_lockers)
|
||||
req_one_access = list(access_security, access_forensics_lockers)
|
||||
botcard_access = list(access_security, access_sec_doors, access_forensics_lockers, access_morgue, access_maint_tunnels, access_court)
|
||||
|
||||
var/mob/target
|
||||
|
||||
@@ -95,11 +95,13 @@
|
||||
sight |= SEE_TURFS
|
||||
sight |= SEE_MOBS
|
||||
sight |= SEE_OBJS
|
||||
see_in_dark = 8
|
||||
see_invisible = SEE_INVISIBLE_LEVEL_TWO
|
||||
else if (stat != 2)
|
||||
sight &= ~SEE_TURFS
|
||||
sight &= ~SEE_MOBS
|
||||
sight &= ~SEE_OBJS
|
||||
see_in_dark = 2
|
||||
see_invisible = SEE_INVISIBLE_LIVING
|
||||
|
||||
if (healths)
|
||||
|
||||
@@ -23,6 +23,7 @@
|
||||
|
||||
/obj/item/organ/brain/New()
|
||||
..()
|
||||
health = config.default_brain_health
|
||||
spawn(5)
|
||||
if(brainmob && brainmob.client)
|
||||
brainmob.client.screen.len = null //clear the hud
|
||||
|
||||
@@ -199,11 +199,13 @@
|
||||
sight |= SEE_TURFS
|
||||
sight |= SEE_MOBS
|
||||
sight |= SEE_OBJS
|
||||
see_in_dark = 8
|
||||
see_invisible = SEE_INVISIBLE_LEVEL_TWO
|
||||
else if (stat != 2)
|
||||
sight &= ~SEE_TURFS
|
||||
sight &= ~SEE_MOBS
|
||||
sight &= ~SEE_OBJS
|
||||
see_in_dark = 2
|
||||
see_invisible = SEE_INVISIBLE_LIVING
|
||||
if (client)
|
||||
client.screen.Remove(global_hud.blurry,global_hud.druggy,global_hud.vimpaired)
|
||||
@@ -252,4 +254,4 @@
|
||||
emp_damage += rand(10,20)
|
||||
if(3)
|
||||
emp_damage += rand(0,10)
|
||||
..()*/
|
||||
..()*/
|
||||
|
||||
@@ -372,8 +372,8 @@
|
||||
|
||||
/mob/living/carbon/fire_act(datum/gas_mixture/air, exposed_temperature, exposed_volume)
|
||||
..()
|
||||
var/temp_inc = max(BODYTEMP_HEATING_MAX*(1-get_heat_protection()), 0)
|
||||
bodytemperature = min(bodytemperature + temp_inc, exposed_temperature)
|
||||
var/temp_inc = max(min(BODYTEMP_HEATING_MAX*(1-get_heat_protection()), exposed_temperature - bodytemperature), 0)
|
||||
bodytemperature += temp_inc
|
||||
|
||||
/mob/living/carbon/can_use_hands()
|
||||
if(handcuffed)
|
||||
|
||||
@@ -154,14 +154,14 @@
|
||||
|
||||
return valid_species
|
||||
|
||||
/mob/living/carbon/human/proc/generate_valid_hairstyles()
|
||||
/mob/living/carbon/human/proc/generate_valid_hairstyles(var/check_gender = 1)
|
||||
var/list/valid_hairstyles = new()
|
||||
for(var/hairstyle in hair_styles_list)
|
||||
var/datum/sprite_accessory/S = hair_styles_list[hairstyle]
|
||||
|
||||
if(gender == MALE && S.gender == FEMALE)
|
||||
if(check_gender && gender == MALE && S.gender == FEMALE)
|
||||
continue
|
||||
if(gender == FEMALE && S.gender == MALE)
|
||||
if(check_gender && gender == FEMALE && S.gender == MALE)
|
||||
continue
|
||||
if(!(species.name in S.species_allowed))
|
||||
continue
|
||||
@@ -185,11 +185,7 @@
|
||||
|
||||
return valid_facial_hairstyles
|
||||
|
||||
/proc/q()
|
||||
var/mob/living/carbon/human/H = usr
|
||||
H.change_appearance(APPEARANCE_ALL)
|
||||
|
||||
/mob/living/carbon/human/proc/force_update_limbs()
|
||||
for(var/obj/item/organ/external/O in organs)
|
||||
O.sync_colour_to_human(src)
|
||||
update_body(0)
|
||||
update_body(0)
|
||||
|
||||
@@ -101,7 +101,7 @@
|
||||
|
||||
if ("choke")
|
||||
if(miming)
|
||||
message = "clutches his throat desperately!"
|
||||
message = "clutches [get_visible_gender() == MALE ? "his" : get_visible_gender() == FEMALE ? "her" : "their"] throat desperately!"
|
||||
m_type = 1
|
||||
else
|
||||
if (!muzzled)
|
||||
|
||||
@@ -54,16 +54,13 @@
|
||||
|
||||
/mob/living/carbon/human/Stat()
|
||||
..()
|
||||
statpanel("Status")
|
||||
|
||||
stat(null, "Intent: [a_intent]")
|
||||
stat(null, "Move Mode: [m_intent]")
|
||||
if(emergency_shuttle)
|
||||
var/eta_status = emergency_shuttle.get_status_panel_eta()
|
||||
if(eta_status)
|
||||
stat(null, eta_status)
|
||||
|
||||
if (client.statpanel == "Status")
|
||||
if(statpanel("Status"))
|
||||
stat(null, "Intent: [a_intent]")
|
||||
stat(null, "Move Mode: [m_intent]")
|
||||
if(emergency_shuttle)
|
||||
var/eta_status = emergency_shuttle.get_status_panel_eta()
|
||||
if(eta_status)
|
||||
stat(null, eta_status)
|
||||
|
||||
if (internal)
|
||||
if (!internal.air_contents)
|
||||
@@ -210,6 +207,10 @@
|
||||
|
||||
|
||||
/mob/living/carbon/human/show_inv(mob/user as mob)
|
||||
// TODO : Change to incapacitated() on merge.
|
||||
if(user.stat || user.lying || user.resting || user.buckled)
|
||||
return
|
||||
|
||||
var/obj/item/clothing/under/suit = null
|
||||
if (istype(w_uniform, /obj/item/clothing/under))
|
||||
suit = w_uniform
|
||||
@@ -723,7 +724,7 @@
|
||||
|
||||
/mob/living/carbon/human/proc/play_xylophone()
|
||||
if(!src.xylophone)
|
||||
visible_message("\red [src] begins playing his ribcage like a xylophone. It's quite spooky.","\blue You begin to play a spooky refrain on your ribcage.","\red You hear a spooky xylophone melody.")
|
||||
visible_message("\red \The [src] begins playing \his ribcage like a xylophone. It's quite spooky.","\blue You begin to play a spooky refrain on your ribcage.","\red You hear a spooky xylophone melody.")
|
||||
var/song = pick('sound/effects/xylophone1.ogg','sound/effects/xylophone2.ogg','sound/effects/xylophone3.ogg')
|
||||
playsound(loc, song, 50, 1, -1)
|
||||
xylophone = 1
|
||||
@@ -1361,3 +1362,8 @@
|
||||
..()
|
||||
if(update_hud)
|
||||
handle_regular_hud_updates()
|
||||
|
||||
/mob/living/carbon/human/Check_Shoegrip()
|
||||
if(istype(shoes, /obj/item/clothing/shoes/magboots) && (shoes.flags & NOSLIP)) //magboots + dense_object = no floating
|
||||
return 1
|
||||
return 0
|
||||
|
||||
@@ -1,3 +1,9 @@
|
||||
/mob/living/carbon/human/proc/get_unarmed_attack(var/mob/living/carbon/human/target, var/hit_zone)
|
||||
for(var/datum/unarmed_attack/u_attack in species.unarmed_attacks)
|
||||
if(u_attack.is_usable(src, target, hit_zone))
|
||||
return u_attack
|
||||
return null
|
||||
|
||||
/mob/living/carbon/human/attack_hand(mob/living/carbon/M as mob)
|
||||
|
||||
var/mob/living/carbon/human/H = M
|
||||
@@ -184,18 +190,7 @@
|
||||
miss_type = 2
|
||||
|
||||
// See what attack they use
|
||||
var/possible_moves = list()
|
||||
var/datum/unarmed_attack/attack = null
|
||||
for(var/part in list("l_hand","r_hand","l_foot","r_foot","head"))
|
||||
var/obj/item/organ/external/E = H.get_organ(part)
|
||||
possible_moves |= E.species.unarmed_attacks
|
||||
|
||||
for(var/datum/unarmed_attack/u_attack in possible_moves)
|
||||
if(!u_attack.is_usable(H, src, hit_zone))
|
||||
continue
|
||||
else
|
||||
attack = u_attack
|
||||
break
|
||||
var/datum/unarmed_attack/attack = H.get_unarmed_attack(src, hit_zone)
|
||||
if(!attack)
|
||||
return 0
|
||||
|
||||
|
||||
@@ -32,7 +32,7 @@
|
||||
var/obj/item/organ/brain/sponge = internal_organs_by_name["brain"]
|
||||
if(sponge)
|
||||
sponge.take_damage(amount)
|
||||
sponge.damage = min(max(brainloss, 0),(maxHealth*2))
|
||||
sponge.damage = min(max(sponge.damage, 0),(maxHealth*2))
|
||||
brainloss = sponge.damage
|
||||
else
|
||||
brainloss = 200
|
||||
|
||||
@@ -10,9 +10,11 @@ emp_act
|
||||
|
||||
/mob/living/carbon/human/bullet_act(var/obj/item/projectile/P, var/def_zone)
|
||||
|
||||
var/obj/item/organ/external/organ = get_organ(check_zone(def_zone))
|
||||
if(!organ)
|
||||
return
|
||||
def_zone = check_zone(def_zone)
|
||||
if(!has_organ(def_zone))
|
||||
return PROJECTILE_FORCE_MISS //if they don't have the organ in question then the projectile just passes by.
|
||||
|
||||
var/obj/item/organ/external/organ = get_organ()
|
||||
|
||||
//Shields
|
||||
if(check_shields(P.damage, "the [P.name]"))
|
||||
@@ -37,7 +39,7 @@ emp_act
|
||||
// redirect the projectile
|
||||
P.redirect(new_x, new_y, curloc, src)
|
||||
|
||||
return -1 // complete projectile permutation
|
||||
return PROJECTILE_CONTINUE // complete projectile permutation
|
||||
|
||||
//Shrapnel
|
||||
if(P.can_embed())
|
||||
|
||||
@@ -41,7 +41,7 @@ This saves us from having to call add_fingerprint() any time something is put in
|
||||
/mob/living/carbon/human/proc/has_organ(name)
|
||||
var/obj/item/organ/external/O = organs_by_name[name]
|
||||
|
||||
return (O && !(O.status & ORGAN_DESTROYED) )
|
||||
return (O && !(O.status & ORGAN_DESTROYED) && !O.is_stump())
|
||||
|
||||
/mob/living/carbon/human/proc/has_organ_for_slot(slot)
|
||||
switch(slot)
|
||||
|
||||
@@ -1197,7 +1197,7 @@
|
||||
damageoverlay.overlays += I
|
||||
|
||||
if( stat == DEAD )
|
||||
sight |= (SEE_TURFS|SEE_MOBS|SEE_OBJS)
|
||||
sight |= SEE_TURFS|SEE_MOBS|SEE_OBJS|SEE_SELF
|
||||
see_in_dark = 8
|
||||
if(!druggy) see_invisible = SEE_INVISIBLE_LEVEL_TWO
|
||||
if(healths) healths.icon_state = "health7" //DEAD healthmeter
|
||||
@@ -1208,23 +1208,13 @@
|
||||
item.zoom()
|
||||
break
|
||||
|
||||
/*
|
||||
if(locate(/obj/item/weapon/gun/energy/sniperrifle, contents))
|
||||
var/obj/item/weapon/gun/energy/sniperrifle/s = locate() in src
|
||||
if(s.zoom)
|
||||
s.zoom()
|
||||
if(locate(/obj/item/device/binoculars, contents))
|
||||
var/obj/item/device/binoculars/b = locate() in src
|
||||
if(b.zoom)
|
||||
b.zoom()
|
||||
*/
|
||||
|
||||
else
|
||||
sight &= ~(SEE_TURFS|SEE_MOBS|SEE_OBJS)
|
||||
see_invisible = see_in_dark>2 ? SEE_INVISIBLE_LEVEL_ONE : SEE_INVISIBLE_LIVING
|
||||
|
||||
if(XRAY in mutations)
|
||||
sight |= SEE_TURFS|SEE_MOBS|SEE_OBJS
|
||||
see_in_dark = 8
|
||||
if(!druggy) see_invisible = SEE_INVISIBLE_LEVEL_TWO
|
||||
|
||||
if(seer==1)
|
||||
@@ -1236,7 +1226,9 @@
|
||||
seer = 0
|
||||
|
||||
else
|
||||
sight &= ~(SEE_TURFS|SEE_MOBS|SEE_OBJS)
|
||||
sight = species.vision_flags
|
||||
see_in_dark = species.darksight
|
||||
see_invisible = see_in_dark>2 ? SEE_INVISIBLE_LEVEL_ONE : SEE_INVISIBLE_LIVING
|
||||
var/tmp/glasses_processed = 0
|
||||
var/obj/item/weapon/rig/rig = back
|
||||
if(istype(rig) && rig.visor)
|
||||
@@ -1250,6 +1242,7 @@
|
||||
process_glasses(glasses)
|
||||
if(XRAY in mutations)
|
||||
sight |= SEE_TURFS|SEE_MOBS|SEE_OBJS
|
||||
see_in_dark = 8
|
||||
if(!druggy) see_invisible = SEE_INVISIBLE_LEVEL_TWO
|
||||
|
||||
if(!glasses_processed && (species.vision_flags > 0))
|
||||
@@ -1275,6 +1268,8 @@
|
||||
if(0 to 20) healths.icon_state = "health5"
|
||||
else healths.icon_state = "health6"
|
||||
|
||||
if(!seer)
|
||||
see_invisible = SEE_INVISIBLE_LIVING
|
||||
if(nutrition_icon)
|
||||
switch(nutrition)
|
||||
if(450 to INFINITY) nutrition_icon.icon_state = "nutrition0"
|
||||
@@ -1402,6 +1397,8 @@
|
||||
sight |= G.vision_flags
|
||||
if(!druggy && !seer)
|
||||
see_invisible = SEE_INVISIBLE_MINIMUM
|
||||
if(G.see_invisible >= 0)
|
||||
see_invisible = G.see_invisible
|
||||
if(istype(G,/obj/item/clothing/glasses/night) && !seer)
|
||||
see_invisible = SEE_INVISIBLE_MINIMUM
|
||||
/* HUD shit goes here, as long as it doesn't modify sight flags */
|
||||
|
||||
@@ -6,9 +6,6 @@
|
||||
message = sanitize(message)
|
||||
..(message, alt_name = alt_name)
|
||||
|
||||
/mob/living/carbon/human/is_muzzled()
|
||||
return istype(src.wear_mask, /obj/item/clothing/mask/muzzle)
|
||||
|
||||
/mob/living/carbon/human/proc/forcesay(list/append)
|
||||
if(stat == CONSCIOUS)
|
||||
if(client)
|
||||
@@ -132,11 +129,11 @@
|
||||
if(silent || (sdisabilities & MUTE))
|
||||
message = ""
|
||||
speech_problem_flag = 1
|
||||
else if(istype(wear_mask, /obj/item/clothing/mask/horsehead))
|
||||
var/obj/item/clothing/mask/horsehead/hoers = wear_mask
|
||||
if(hoers.voicechange)
|
||||
message = pick("NEEIIGGGHHHH!", "NEEEIIIIGHH!", "NEIIIGGHH!", "HAAWWWWW!", "HAAAWWW!")
|
||||
verb = pick("whinnies","neighs", "says")
|
||||
else if(istype(wear_mask, /obj/item/clothing/mask))
|
||||
var/obj/item/clothing/mask/M = wear_mask
|
||||
if(M.voicechange)
|
||||
message = pick(M.say_messages)
|
||||
verb = pick(M.say_verbs)
|
||||
speech_problem_flag = 1
|
||||
|
||||
if(message != "")
|
||||
|
||||
@@ -8,6 +8,7 @@
|
||||
language = "Sol Common" //todo?
|
||||
unarmed_types = list(/datum/unarmed_attack/claws/strong, /datum/unarmed_attack/bite/sharp)
|
||||
light_dam = 2
|
||||
darksight = 8
|
||||
has_organ = list()
|
||||
siemens_coefficient = 0
|
||||
|
||||
@@ -22,4 +23,4 @@
|
||||
/datum/species/shadow/handle_death(var/mob/living/carbon/human/H)
|
||||
spawn(1)
|
||||
new /obj/effect/decal/cleanable/ash(H.loc)
|
||||
qdel(H)
|
||||
qdel(H)
|
||||
@@ -5,6 +5,7 @@
|
||||
deform = 'icons/mob/human_races/r_def_vox.dmi'
|
||||
default_language = "Vox-pidgin"
|
||||
language = "Galactic Common"
|
||||
num_alternate_languages = 1
|
||||
unarmed_types = list(/datum/unarmed_attack/stomp, /datum/unarmed_attack/kick, /datum/unarmed_attack/claws/strong, /datum/unarmed_attack/bite/strong)
|
||||
rarity_value = 2
|
||||
blurb = "The Vox are the broken remnants of a once-proud race, now reduced to little more than \
|
||||
@@ -65,7 +66,7 @@
|
||||
H.equip_to_slot_or_del(new /obj/item/weapon/storage/box/vox(H.back), slot_in_backpack)
|
||||
H.internal = H.r_hand
|
||||
H.internals.icon_state = "internal1"
|
||||
|
||||
|
||||
|
||||
/datum/species/vox/can_shred(var/mob/living/carbon/human/H, var/ignore_intent)
|
||||
if(!H.mind || !H.mind.special_role) // Pariah check.
|
||||
|
||||
@@ -34,9 +34,10 @@
|
||||
// Language/culture vars.
|
||||
var/default_language = "Galactic Common" // Default language is used when 'say' is used without modifiers.
|
||||
var/language = "Galactic Common" // Default racial language, if any.
|
||||
var/secondary_langs = list() // The names of secondary languages that are available to this species.
|
||||
var/list/secondary_langs = list() // The names of secondary languages that are available to this species.
|
||||
var/list/speech_sounds // A list of sounds to potentially play when speaking.
|
||||
var/list/speech_chance // The likelihood of a speech sound playing.
|
||||
var/num_alternate_languages = 0 // How many secondary languages are available to select at character creation
|
||||
|
||||
// Combat vars.
|
||||
var/total_health = 100 // Point at which the mob will enter crit.
|
||||
@@ -47,7 +48,7 @@
|
||||
var/list/unarmed_attacks = null // For empty hand harm-intent attack
|
||||
var/brute_mod = 1 // Physical damage multiplier.
|
||||
var/burn_mod = 1 // Burn damage multiplier.
|
||||
var/vision_flags = 0 // Same flags as glasses.
|
||||
var/vision_flags = SEE_SELF // Same flags as glasses.
|
||||
|
||||
// Death vars.
|
||||
var/meat_type = /obj/item/weapon/reagent_containers/food/snacks/meat/human
|
||||
@@ -100,6 +101,7 @@
|
||||
var/list/inherent_verbs // Species-specific verbs.
|
||||
var/has_fine_manipulation = 1 // Can use small items.
|
||||
var/siemens_coefficient = 1 // The lower, the thicker the skin and better the insulation.
|
||||
var/darksight = 2 // Native darksight distance.
|
||||
var/flags = 0 // Various specific features.
|
||||
var/slowdown = 0 // Passive movement speed malus (or boost, if negative)
|
||||
var/primitive_form // Lesser form, if any (ie. monkey for humans)
|
||||
|
||||
@@ -9,11 +9,15 @@
|
||||
/datum/unarmed_attack/diona
|
||||
attack_verb = list("lashed", "bludgeoned")
|
||||
attack_noun = list("tendril")
|
||||
eye_attack_text = "a tendril"
|
||||
eye_attack_text_victim = "a tendril"
|
||||
damage = 5
|
||||
|
||||
/datum/unarmed_attack/claws
|
||||
attack_verb = list("scratched", "clawed", "slashed")
|
||||
attack_noun = list("claws")
|
||||
eye_attack_text = "claws"
|
||||
eye_attack_text_victim = "sharp claws"
|
||||
attack_sound = 'sound/weapons/slice.ogg'
|
||||
miss_sound = 'sound/weapons/slashmiss.ogg'
|
||||
damage = 5
|
||||
|
||||
@@ -10,6 +10,7 @@
|
||||
unarmed_types = list(/datum/unarmed_attack/slime_glomp)
|
||||
flags = IS_RESTRICTED | NO_SCAN | NO_SLIP | NO_BREATHE
|
||||
siemens_coefficient = 3
|
||||
darksight = 3
|
||||
|
||||
blood_color = "#05FF9B"
|
||||
flesh_color = "#05FFFB"
|
||||
|
||||
@@ -1,7 +1,6 @@
|
||||
/datum/species/human
|
||||
name = "Human"
|
||||
name_plural = "Humans"
|
||||
language = "Sol Common"
|
||||
primitive_form = "Monkey"
|
||||
unarmed_types = list(/datum/unarmed_attack/stomp, /datum/unarmed_attack/kick, /datum/unarmed_attack/punch, /datum/unarmed_attack/bite)
|
||||
blurb = "Humanity originated in the Sol system, and over the last five centuries has spread \
|
||||
@@ -9,6 +8,8 @@
|
||||
While the central Sol government maintains control of its far-flung people, powerful corporate \
|
||||
interests, rampant cyber and bio-augmentation and secretive factions make life on most human \
|
||||
worlds tumultous at best."
|
||||
num_alternate_languages = 2
|
||||
secondary_langs = list("Sol Common")
|
||||
|
||||
flags = CAN_JOIN | HAS_SKIN_TONE | HAS_LIPS | HAS_UNDERWEAR | HAS_EYE_COLOR
|
||||
|
||||
@@ -17,12 +18,14 @@
|
||||
name_plural = "Unathi"
|
||||
icobase = 'icons/mob/human_races/r_lizard.dmi'
|
||||
deform = 'icons/mob/human_races/r_def_lizard.dmi'
|
||||
language = "Sinta'unathi"
|
||||
tail = "sogtail"
|
||||
tail_animation = 'icons/mob/species/unathi/tail.dmi'
|
||||
unarmed_types = list(/datum/unarmed_attack/stomp, /datum/unarmed_attack/kick, /datum/unarmed_attack/claws, /datum/unarmed_attack/bite/sharp)
|
||||
primitive_form = "Stok"
|
||||
darksight = 3
|
||||
gluttonous = 1
|
||||
num_alternate_languages = 2
|
||||
secondary_langs = list("Sinta'unathi")
|
||||
|
||||
blurb = "A heavily reptillian species, Unathi (or 'Sinta as they call themselves) hail from the \
|
||||
Uuosa-Eso system, which roughly translates to 'burning mother'.<br/><br/>Coming from a harsh, radioactive \
|
||||
@@ -68,12 +71,14 @@
|
||||
name_plural = "Tajaran"
|
||||
icobase = 'icons/mob/human_races/r_tajaran.dmi'
|
||||
deform = 'icons/mob/human_races/r_def_tajaran.dmi'
|
||||
language = "Siik'tajr"
|
||||
tail = "tajtail"
|
||||
tail_animation = 'icons/mob/species/tajaran/tail.dmi'
|
||||
unarmed_types = list(/datum/unarmed_attack/stomp, /datum/unarmed_attack/kick, /datum/unarmed_attack/claws, /datum/unarmed_attack/bite/sharp)
|
||||
darksight = 8
|
||||
slowdown = -1
|
||||
brute_mod = 1.2
|
||||
num_alternate_languages = 2
|
||||
secondary_langs = list("Siik'tajr")
|
||||
|
||||
blurb = "The Tajaran race is a species of feline-like bipeds hailing from the planet of Ahdomai in the \
|
||||
S'randarr system. They have been brought up into the space age by the Humans and Skrell, and have been \
|
||||
@@ -114,7 +119,6 @@
|
||||
icobase = 'icons/mob/human_races/r_skrell.dmi'
|
||||
deform = 'icons/mob/human_races/r_def_skrell.dmi'
|
||||
eyes = "skrell_eyes_s"
|
||||
language = "Skrellian"
|
||||
primitive_form = "Neara"
|
||||
unarmed_types = list(/datum/unarmed_attack/punch)
|
||||
blurb = "An amphibious species, Skrell come from the star system known as Qerr'Vallis, which translates to 'Star of \
|
||||
@@ -122,6 +126,8 @@
|
||||
of the Qerr'Katish, a caste within their society which keeps the empire of the Skrell running smoothly. Skrell are \
|
||||
herbivores on the whole and tend to be co-operative with the other species of the galaxy, although they rarely reveal \
|
||||
the secrets of their empire to their allies."
|
||||
num_alternate_languages = 2
|
||||
secondary_langs = list("Skrellian")
|
||||
|
||||
flags = CAN_JOIN | IS_WHITELISTED | HAS_LIPS | HAS_UNDERWEAR | HAS_SKIN_COLOR
|
||||
|
||||
@@ -145,6 +151,7 @@
|
||||
siemens_coefficient = 0.3
|
||||
eyes = "blank_eyes"
|
||||
show_ssd = "completely quiescent"
|
||||
num_alternate_languages = 1
|
||||
|
||||
|
||||
blurb = "Commonly referred to (erroneously) as 'plant people', the Dionaea are a strange space-dwelling collective \
|
||||
@@ -249,6 +256,7 @@
|
||||
language = "Encoded Audio Language"
|
||||
unarmed_types = list(/datum/unarmed_attack/punch)
|
||||
rarity_value = 2
|
||||
num_alternate_languages = 1 // potentially could be 2?
|
||||
|
||||
eyes = "blank_eyes"
|
||||
brute_mod = 1.875 // 100% * 1.875 * 0.8 (robolimbs) ~= 150%
|
||||
|
||||
@@ -42,7 +42,7 @@
|
||||
breath_type = null
|
||||
poison_type = null
|
||||
|
||||
vision_flags = SEE_MOBS
|
||||
vision_flags = SEE_SELF|SEE_MOBS
|
||||
|
||||
has_organ = list(
|
||||
"heart" = /obj/item/organ/heart,
|
||||
|
||||
@@ -3,6 +3,11 @@
|
||||
if(!slot_to_strip || !istype(user))
|
||||
return
|
||||
|
||||
// TODO : Change to incapacitated() on merge.
|
||||
if(user.stat || user.lying || user.resting || user.buckled)
|
||||
user << browse(null, text("window=mob[src.name]"))
|
||||
return
|
||||
|
||||
var/obj/item/target_slot = get_equipped_item(text2num(slot_to_strip))
|
||||
|
||||
switch(slot_to_strip)
|
||||
|
||||
@@ -8,8 +8,11 @@
|
||||
var/shredding = 0 // Calls the old attack_alien() behavior on objects/mobs when on harm intent.
|
||||
var/sharp = 0
|
||||
var/edge = 0
|
||||
|
||||
var/eye_attack_text
|
||||
var/eye_attack_text_victim
|
||||
|
||||
/datum/unarmed_attack/proc/is_usable(var/mob/living/carbon/human/user)
|
||||
/datum/unarmed_attack/proc/is_usable(var/mob/living/carbon/human/user, var/mob/living/carbon/human/target, var/zone)
|
||||
if(user.restrained())
|
||||
return 0
|
||||
|
||||
@@ -78,6 +81,13 @@
|
||||
user.visible_message("<span class='warning'>[user] [pick(attack_verb)] [target] in the [affecting.name]!</span>")
|
||||
playsound(user.loc, attack_sound, 25, 1, -1)
|
||||
|
||||
/datum/unarmed_attack/proc/handle_eye_attack(var/mob/living/carbon/human/user, var/mob/living/carbon/human/target)
|
||||
var/obj/item/organ/eyes/eyes = target.internal_organs_by_name["eyes"]
|
||||
eyes.take_damage(rand(3,4), 1)
|
||||
|
||||
user.visible_message("<span class='danger'>[user] presses \his [eye_attack_text] into [target]'s [eyes.name]!</span>")
|
||||
target << "<span class='danger'>You experience[(target.species.flags & NO_PAIN)? "" : " immense pain as you feel" ] [eye_attack_text_victim] being pressed into your [eyes.name][(target.species.flags & NO_PAIN)? "." : "!"]</span>"
|
||||
|
||||
/datum/unarmed_attack/bite
|
||||
attack_verb = list("bit")
|
||||
attack_sound = 'sound/weapons/bite.ogg'
|
||||
@@ -97,6 +107,8 @@
|
||||
/datum/unarmed_attack/punch
|
||||
attack_verb = list("punched")
|
||||
attack_noun = list("fist")
|
||||
eye_attack_text = "fingers"
|
||||
eye_attack_text_victim = "digits"
|
||||
damage = 0
|
||||
|
||||
/datum/unarmed_attack/punch/show_attack(var/mob/living/carbon/human/user, var/mob/living/carbon/human/target, var/zone, var/attack_damage)
|
||||
|
||||
@@ -504,7 +504,7 @@ var/global/list/damage_icon_parts = list()
|
||||
var/obj/item/clothing/under/under = w_uniform
|
||||
if(under.accessories.len)
|
||||
for(var/obj/item/clothing/accessory/A in under.accessories)
|
||||
standing.overlays |= A.get_inv_mob_overlay()
|
||||
standing.overlays |= A.get_mob_overlay()
|
||||
|
||||
overlays_standing[UNIFORM_LAYER] = standing
|
||||
else
|
||||
|
||||
@@ -14,6 +14,7 @@
|
||||
update_icon = 0
|
||||
nutrition = 700
|
||||
|
||||
see_in_dark = 8
|
||||
update_slimes = 0
|
||||
|
||||
// canstun and canweaken don't affect slimes because they ignore stun and weakened variables
|
||||
@@ -401,4 +402,4 @@
|
||||
/mob/living/carbon/slime/cannot_use_vents()
|
||||
if(Victim)
|
||||
return "You cannot ventcrawl while feeding."
|
||||
..()
|
||||
..()
|
||||
|
||||
@@ -128,6 +128,7 @@ proc/get_radio_key_from_channel(var/channel)
|
||||
return verb
|
||||
|
||||
/mob/living/say(var/message, var/datum/language/speaking = null, var/verb="says", var/alt_name="")
|
||||
|
||||
if(client)
|
||||
if(client.prefs.muted & MUTE_IC)
|
||||
src << "\red You cannot speak in IC (Muted)."
|
||||
@@ -138,10 +139,6 @@ proc/get_radio_key_from_channel(var/channel)
|
||||
return say_dead(message)
|
||||
return
|
||||
|
||||
if(is_muzzled())
|
||||
src << "<span class='danger'>You're muzzled and cannot speak!</span>"
|
||||
return
|
||||
|
||||
var/message_mode = parse_message_mode(message, "headset")
|
||||
|
||||
switch(copytext(message,1,2))
|
||||
@@ -165,7 +162,6 @@ proc/get_radio_key_from_channel(var/channel)
|
||||
else
|
||||
speaking = get_default_language()
|
||||
|
||||
var/ending = copytext(message, length(message))
|
||||
if (speaking)
|
||||
// This is broadcast to all mobs with the language,
|
||||
// irrespective of distance or anything else.
|
||||
@@ -173,9 +169,16 @@ proc/get_radio_key_from_channel(var/channel)
|
||||
speaking.broadcast(src,trim(message))
|
||||
return
|
||||
//If we've gotten this far, keep going!
|
||||
verb = speaking.get_spoken_verb(ending)
|
||||
if(speaking.flags & COMMON_VERBS)
|
||||
verb = say_quote(message)
|
||||
else
|
||||
verb = speaking.get_spoken_verb(copytext(message, length(message)))
|
||||
else
|
||||
verb = get_speech_ending(verb, ending)
|
||||
verb = say_quote(message)
|
||||
|
||||
if(is_muzzled())
|
||||
src << "<span class='danger'>You're muzzled and cannot speak!</span>"
|
||||
return
|
||||
|
||||
message = trim_left(message)
|
||||
|
||||
|
||||
@@ -49,7 +49,6 @@ var/list/ai_verbs_default = list(
|
||||
var/list/network = list("Exodus")
|
||||
var/obj/machinery/camera/camera = null
|
||||
var/list/connected_robots = list()
|
||||
var/has_power = 0
|
||||
var/aiRestorePowerRoutine = 0
|
||||
var/viewalerts = 0
|
||||
var/icon/holo_icon//Default is assigned when AI is created.
|
||||
@@ -384,8 +383,7 @@ var/list/ai_verbs_default = list(
|
||||
|
||||
/mob/living/silicon/ai/check_eye(var/mob/user as mob)
|
||||
if (!camera)
|
||||
return null
|
||||
user.reset_view(camera)
|
||||
return -1
|
||||
return 0
|
||||
|
||||
/mob/living/silicon/ai/restrained()
|
||||
|
||||
@@ -38,18 +38,19 @@
|
||||
src << "<span class='notice'><b>APU GENERATOR FAILURE! (System Damaged)</b></span>"
|
||||
stop_apu(1)
|
||||
|
||||
has_power = 1
|
||||
var/blind = 0
|
||||
var/area/loc = null
|
||||
if (istype(T, /turf))
|
||||
loc = T.loc
|
||||
if (istype(loc, /area))
|
||||
if (!loc.power_equip && !istype(src.loc,/obj/item) && !APU_power)
|
||||
has_power = 0
|
||||
blind = 1
|
||||
|
||||
if (has_power)
|
||||
if (!blind)
|
||||
src.sight |= SEE_TURFS
|
||||
src.sight |= SEE_MOBS
|
||||
src.sight |= SEE_OBJS
|
||||
src.see_in_dark = 8
|
||||
src.see_invisible = SEE_INVISIBLE_LIVING
|
||||
|
||||
if (aiRestorePowerRoutine==2)
|
||||
@@ -79,10 +80,12 @@
|
||||
//Blind the AI
|
||||
updateicon()
|
||||
src.blind.screen_loc = "1,1 to 15,15"
|
||||
|
||||
if (src.blind.layer!=18)
|
||||
src.blind.layer = 18
|
||||
src.sight = src.sight&~SEE_TURFS
|
||||
src.sight = src.sight&~SEE_MOBS
|
||||
src.sight = src.sight&~SEE_OBJS
|
||||
src.see_in_dark = 0
|
||||
src.see_invisible = SEE_INVISIBLE_LIVING
|
||||
|
||||
//Now to tell the AI why they're blind and dying slowly.
|
||||
|
||||
@@ -39,20 +39,23 @@
|
||||
laws.delete_law(law)
|
||||
log_and_message_admins("has deleted a law belonging to [src]: [law.law]")
|
||||
|
||||
/mob/living/silicon/proc/clear_inherent_laws()
|
||||
/mob/living/silicon/proc/clear_inherent_laws(var/silent = 0)
|
||||
laws_sanity_check()
|
||||
laws.clear_inherent_laws()
|
||||
log_and_message_admins("cleared the inherent laws of [src]")
|
||||
if(!silent)
|
||||
log_and_message_admins("cleared the inherent laws of [src]")
|
||||
|
||||
/mob/living/silicon/proc/clear_ion_laws()
|
||||
/mob/living/silicon/proc/clear_ion_laws(var/silent = 0)
|
||||
laws_sanity_check()
|
||||
laws.clear_ion_laws()
|
||||
log_and_message_admins("cleared the ion laws of [src]")
|
||||
if(!silent)
|
||||
log_and_message_admins("cleared the ion laws of [src]")
|
||||
|
||||
/mob/living/silicon/proc/clear_supplied_laws()
|
||||
/mob/living/silicon/proc/clear_supplied_laws(var/silent = 0)
|
||||
laws_sanity_check()
|
||||
laws.clear_supplied_laws()
|
||||
log_and_message_admins("cleared the supplied laws of [src]")
|
||||
if(!silent)
|
||||
log_and_message_admins("cleared the supplied laws of [src]")
|
||||
|
||||
/mob/living/silicon/proc/statelaws(var/datum/ai_laws/laws)
|
||||
var/prefix = ""
|
||||
|
||||
@@ -0,0 +1,21 @@
|
||||
// Originally a debug verb, made it a proper adminverb for ~fun~
|
||||
/client/proc/makePAI(turf/t in view(), name as text, pai_key as null|text)
|
||||
set name = "Make pAI"
|
||||
set category = "Admin"
|
||||
|
||||
if(!check_rights(R_ADMIN))
|
||||
return
|
||||
|
||||
if(!pai_key)
|
||||
var/client/C = input("Select client") as null|anything in clients
|
||||
if(!C) return
|
||||
pai_key = C.key
|
||||
|
||||
log_and_message_admins("made a pAI with key=[pai_key] at ([t.x],[t.y],[t.z])")
|
||||
var/obj/item/device/paicard/card = new(t)
|
||||
var/mob/living/silicon/pai/pai = new(card)
|
||||
pai.key = pai_key
|
||||
card.setPersonality(pai)
|
||||
|
||||
if(name)
|
||||
pai.SetName(name)
|
||||
@@ -120,7 +120,6 @@
|
||||
/mob/living/silicon/pai/check_eye(var/mob/user as mob)
|
||||
if (!src.current)
|
||||
return -1
|
||||
user.reset_view(src.current)
|
||||
return 0
|
||||
|
||||
/mob/living/silicon/pai/blob_act()
|
||||
|
||||
@@ -25,6 +25,6 @@ var/list/robot_custom_icons
|
||||
var/rname = robot_custom_icons[ckey]
|
||||
if(rname && rname == real_name)
|
||||
custom_sprite = 1
|
||||
icon = 'icons/mob/custom_synthetic.dmi'
|
||||
icon = CUSTOM_ITEM_SYNTH
|
||||
if(icon_state == "robot")
|
||||
icon_state = "[ckey]-Standard"
|
||||
|
||||
@@ -160,11 +160,11 @@
|
||||
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 operatives.")
|
||||
set_zeroth_law("Only [user.real_name] and people \he designates as being such are operatives.")
|
||||
|
||||
src << "<b>Obey these laws:</b>"
|
||||
laws.show_laws(src)
|
||||
src << "<span class='danger'>ALERT: [user.real_name] is your new master. Obey your new laws and his commands.</span>"
|
||||
src << "<span class='danger'>ALERT: [user.real_name] is your new master. Obey your new laws and \his commands.</span>"
|
||||
return 1
|
||||
|
||||
//DRONE LIFE/DEATH
|
||||
@@ -213,9 +213,9 @@
|
||||
death()
|
||||
|
||||
/mob/living/silicon/robot/drone/proc/full_law_reset()
|
||||
clear_supplied_laws()
|
||||
clear_inherent_laws()
|
||||
clear_ion_laws()
|
||||
clear_supplied_laws(1)
|
||||
clear_inherent_laws(1)
|
||||
clear_ion_laws(1)
|
||||
laws = new law_type
|
||||
|
||||
//Reboot procs.
|
||||
@@ -257,23 +257,21 @@
|
||||
src << "<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 << "Remember, you are <b>lawed against interference with the crew</b>. Also remember, <b>you DO NOT take orders from the AI.</b>"
|
||||
src << "Use <b>:d</b> to talk to other drones and <b>say</b> to speak silently to your nearby fellows."
|
||||
src << "Use <b>say ;Hello</b> to talk to other drones and <b>say Hello</b> to speak silently to your nearby fellows."
|
||||
|
||||
/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 > can_pull_size)
|
||||
src << "<span class='warning'>You are too small to pull that.</span>"
|
||||
return
|
||||
if(!(istype(AM,/obj/item/pipe) || istype(AM,/obj/structure/disposalconstruct)))
|
||||
if(istype(AM,/obj/item))
|
||||
var/obj/item/O = AM
|
||||
if(O.w_class > can_pull_size)
|
||||
src << "<span class='warning'>You are too small to pull that.</span>"
|
||||
return
|
||||
else
|
||||
..()
|
||||
else
|
||||
if(!can_pull_mobs)
|
||||
src << "<span class='warning'>You are too small to pull that.</span>"
|
||||
return
|
||||
if(!can_pull_mobs)
|
||||
src << "<span class='warning'>You are too small to pull that.</span>"
|
||||
return
|
||||
..()
|
||||
|
||||
/mob/living/silicon/robot/drone/add_robot_verbs()
|
||||
src.verbs |= silicon_subsystems
|
||||
@@ -300,4 +298,4 @@
|
||||
|
||||
/mob/living/silicon/robot/drone/construction/updatename()
|
||||
real_name = "construction drone ([rand(100,999)])"
|
||||
name = real_name
|
||||
name = real_name
|
||||
|
||||
@@ -0,0 +1,40 @@
|
||||
/mob/living/silicon/robot/drone/say(var/message)
|
||||
if(local_transmit)
|
||||
if (src.client)
|
||||
if(client.prefs.muted & MUTE_IC)
|
||||
src << "You cannot send IC messages (muted)."
|
||||
return 0
|
||||
if (src.client.handle_spam_prevention(message,MUTE_IC))
|
||||
return 0
|
||||
|
||||
message = sanitize(message)
|
||||
|
||||
if (stat == 2)
|
||||
return say_dead(message)
|
||||
|
||||
if(copytext(message,1,2) == "*")
|
||||
return emote(copytext(message,2))
|
||||
|
||||
if(copytext(message,1,2) == ";")
|
||||
var/datum/language/L = all_languages["Drone Talk"]
|
||||
if(istype(L))
|
||||
return L.broadcast(src,trim(copytext(message,2)))
|
||||
|
||||
//Must be concious to speak
|
||||
if (stat)
|
||||
return 0
|
||||
|
||||
var/list/listeners = hearers(5,src)
|
||||
listeners |= src
|
||||
|
||||
for(var/mob/living/silicon/D in listeners)
|
||||
if(D.client && D.local_transmit)
|
||||
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]\""
|
||||
return 1
|
||||
..(message)
|
||||
@@ -65,12 +65,12 @@
|
||||
m_type = 2
|
||||
if ("flap")
|
||||
if (!src.restrained())
|
||||
message = "flaps his wings."
|
||||
message = "flaps its wings."
|
||||
m_type = 2
|
||||
|
||||
if ("aflap")
|
||||
if (!src.restrained())
|
||||
message = "flaps his wings ANGRILY!"
|
||||
message = "flaps its wings ANGRILY!"
|
||||
m_type = 2
|
||||
|
||||
if ("twitch")
|
||||
@@ -213,4 +213,4 @@
|
||||
if ((message && src.stat == 0))
|
||||
custom_emote(m_type,message)
|
||||
|
||||
return
|
||||
return
|
||||
|
||||
@@ -65,9 +65,9 @@
|
||||
|
||||
if(src.camera && !scrambledcodes)
|
||||
if(src.stat == 2 || wires.IsIndexCut(BORG_WIRE_CAMERA))
|
||||
src.camera.status = 0
|
||||
src.camera.set_status(0)
|
||||
else
|
||||
src.camera.status = 1
|
||||
src.camera.set_status(1)
|
||||
|
||||
updatehealth()
|
||||
|
||||
@@ -163,11 +163,13 @@
|
||||
see_invisible = SEE_INVISIBLE_MINIMUM
|
||||
else if (src.sight_mode & BORGTHERM)
|
||||
src.sight |= SEE_MOBS
|
||||
src.see_in_dark = 8
|
||||
src.see_invisible = SEE_INVISIBLE_LEVEL_TWO
|
||||
else if (src.stat != 2)
|
||||
src.sight &= ~SEE_MOBS
|
||||
src.sight &= ~SEE_TURFS
|
||||
src.sight &= ~SEE_OBJS
|
||||
src.see_in_dark = 8 // see_in_dark means you can FAINTLY see in the dark, humans have a range of 3 or so, tajaran have it at 8
|
||||
src.see_invisible = SEE_INVISIBLE_LIVING // This is normal vision (25), setting it lower for normal vision means you don't "see" things like darkness since darkness
|
||||
// has a "invisible" value of 15
|
||||
|
||||
|
||||
@@ -182,7 +182,7 @@
|
||||
aiCamera = new/obj/item/device/camera/siliconcam/robot_camera(src)
|
||||
|
||||
laws = new /datum/ai_laws/syndicate_override
|
||||
module = new /obj/item/weapon/robot_module/syndicate(src)
|
||||
new /obj/item/weapon/robot_module/syndicate(src)
|
||||
|
||||
radio.keyslot = new /obj/item/device/encryptionkey/syndicate(radio)
|
||||
radio.recalculateChannels()
|
||||
@@ -263,7 +263,7 @@
|
||||
return
|
||||
|
||||
var/module_type = robot_modules[modtype]
|
||||
module = new module_type(src)
|
||||
new module_type(src)
|
||||
|
||||
hands.icon_state = lowertext(modtype)
|
||||
feedback_inc("cyborg_[lowertext(modtype)]",1)
|
||||
@@ -421,8 +421,7 @@
|
||||
// update the status screen display
|
||||
/mob/living/silicon/robot/Stat()
|
||||
..()
|
||||
statpanel("Status")
|
||||
if (client.statpanel == "Status")
|
||||
if (statpanel("Status"))
|
||||
show_cell_power()
|
||||
show_jetpack_pressure()
|
||||
stat(null, text("Lights: [lights_on ? "ON" : "OFF"]"))
|
||||
@@ -1049,25 +1048,25 @@
|
||||
laws = new /datum/ai_laws/syndicate_override
|
||||
var/time = time2text(world.realtime,"hh:mm:ss")
|
||||
lawchanges.Add("[time] <B>:</B> [user.name]([user.key]) emagged [name]([key])")
|
||||
set_zeroth_law("Only [user.real_name] and people he designates as being such are operatives.")
|
||||
set_zeroth_law("Only [user.real_name] and people \he designates as being such are operatives.")
|
||||
. = 1
|
||||
spawn()
|
||||
src << "\red ALERT: Foreign software detected."
|
||||
src << "<span class='danger'>ALERT: Foreign software detected.</span>"
|
||||
sleep(5)
|
||||
src << "\red Initiating diagnostics..."
|
||||
src << "<span class='danger'>Initiating diagnostics...</span>"
|
||||
sleep(20)
|
||||
src << "\red SynBorg v1.7.1 loaded."
|
||||
src << "<span class='danger'>SynBorg v1.7.1 loaded.</span>"
|
||||
sleep(5)
|
||||
src << "\red LAW SYNCHRONISATION ERROR"
|
||||
src << "<span class='danger'>LAW SYNCHRONISATION ERROR</span>"
|
||||
sleep(5)
|
||||
src << "\red Would you like to send a report to NanoTraSoft? Y/N"
|
||||
src << "<span class='danger'>Would you like to send a report to NanoTraSoft? Y/N</span>"
|
||||
sleep(10)
|
||||
src << "\red > N"
|
||||
src << "<span class='danger'>> N</span>"
|
||||
sleep(20)
|
||||
src << "\red ERRORERRORERROR"
|
||||
src << "<span class='danger'>ERRORERRORERROR</span>"
|
||||
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."
|
||||
src << "<span class='danger'>ALERT: [user.real_name] is your new master. Obey your new laws and his commands.</span>"
|
||||
if(src.module)
|
||||
var/rebuild = 0
|
||||
for(var/obj/item/weapon/pickaxe/borgdrill/D in src.module.modules)
|
||||
@@ -1081,4 +1080,4 @@
|
||||
user << "You fail to hack [src]'s interface."
|
||||
src << "Hack attempt detected."
|
||||
return 1
|
||||
return
|
||||
return
|
||||
|
||||
@@ -36,7 +36,7 @@
|
||||
for(var/obj/I in contents)
|
||||
for(var/mob/M in I.contents)
|
||||
M.death()
|
||||
if(istype(I,/obj/item/stack/material))//Only deconsturcts one sheet at a time instead of the entire stack
|
||||
if(istype(I,/obj/item/stack/material))//Only deconstructs one sheet at a time instead of the entire stack
|
||||
var/obj/item/stack/material/S = I
|
||||
if(S.get_amount() > 1)
|
||||
S.use(1)
|
||||
|
||||
@@ -39,6 +39,8 @@ var/global/list/robot_modules = list(
|
||||
|
||||
/obj/item/weapon/robot_module/New(var/mob/living/silicon/robot/R)
|
||||
..()
|
||||
R.module = src
|
||||
|
||||
add_camera_networks(R)
|
||||
add_languages(R)
|
||||
add_subsystems(R)
|
||||
@@ -69,7 +71,7 @@ var/global/list/robot_modules = list(
|
||||
synths = null
|
||||
emag = null
|
||||
jetpack = null
|
||||
..()
|
||||
return ..()
|
||||
|
||||
/obj/item/weapon/robot_module/emp_act(severity)
|
||||
if(modules)
|
||||
@@ -504,7 +506,7 @@ var/global/list/robot_modules = list(
|
||||
src.modules += L
|
||||
|
||||
src.modules += new /obj/item/weapon/tray/robotray(src)
|
||||
src.modules += new /obj/item/weapon/reagent_containers/food/drinks/shaker(src)
|
||||
src.modules += new /obj/item/weapon/reagent_containers/borghypo/service(src)
|
||||
src.emag = new /obj/item/weapon/reagent_containers/food/drinks/cans/beer(src)
|
||||
|
||||
var/datum/reagents/R = new/datum/reagents(50)
|
||||
|
||||
@@ -1,3 +1,35 @@
|
||||
/mob/living/silicon/handle_message_mode(message_mode, message, verb, speaking, used_radios, alt_name)
|
||||
log_say("[key_name(src)] : [message]")
|
||||
|
||||
/mob/living/silicon/robot/handle_message_mode(message_mode, message, verb, speaking, used_radios, alt_name)
|
||||
..()
|
||||
if(message_mode)
|
||||
if(!is_component_functioning("radio"))
|
||||
src << "<span class='warning'>Your radio isn't functional at this time.</span>"
|
||||
return 0
|
||||
if(message_mode == "general")
|
||||
message_mode = null
|
||||
return radio.talk_into(src,message,message_mode,verb,speaking)
|
||||
|
||||
/mob/living/silicon/ai/handle_message_mode(message_mode, message, verb, speaking, used_radios, alt_name)
|
||||
..()
|
||||
if(message_mode == "department")
|
||||
return holopad_talk(message, verb, speaking)
|
||||
else if(message_mode)
|
||||
if (aiRadio.disabledAi || aiRestorePowerRoutine || stat)
|
||||
src << "<span class='danger'>System Error - Transceiver Disabled.</span>"
|
||||
return 0
|
||||
if(message_mode == "general")
|
||||
message_mode = null
|
||||
return aiRadio.talk_into(src,message,message_mode,verb,speaking)
|
||||
|
||||
/mob/living/silicon/pai/handle_message_mode(message_mode, message, verb, speaking, used_radios, alt_name)
|
||||
..()
|
||||
if(message_mode)
|
||||
if(message_mode == "general")
|
||||
message_mode = null
|
||||
return radio.talk_into(src,message,message_mode,verb,speaking)
|
||||
|
||||
/mob/living/silicon/say_quote(var/text)
|
||||
var/ending = copytext(text, length(text))
|
||||
|
||||
@@ -23,131 +55,6 @@
|
||||
return 1
|
||||
return ..()
|
||||
|
||||
/mob/living/silicon/say(var/message)
|
||||
if (!message)
|
||||
return 0
|
||||
|
||||
if (src.client)
|
||||
if(client.prefs.muted & MUTE_IC)
|
||||
src << "You cannot send IC messages (muted)."
|
||||
return 0
|
||||
if (src.client.handle_spam_prevention(message,MUTE_IC))
|
||||
return 0
|
||||
|
||||
message = sanitize(message)
|
||||
|
||||
if (stat == 2)
|
||||
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 0
|
||||
|
||||
var/verb = say_quote(message)
|
||||
|
||||
//parse radio key and consume it
|
||||
var/message_mode = parse_message_mode(message, "general")
|
||||
if (message_mode)
|
||||
if (message_mode == "general")
|
||||
message = trim(copytext(message,2))
|
||||
else
|
||||
message = trim(copytext(message,3))
|
||||
|
||||
//parse language key and consume it
|
||||
var/datum/language/speaking = parse_language(message)
|
||||
if (speaking)
|
||||
verb = speaking.speech_verb
|
||||
message = trim(copytext(message,2+length(speaking.key)))
|
||||
|
||||
if(speaking.flags & HIVEMIND)
|
||||
speaking.broadcast(src,trim(message))
|
||||
return 1
|
||||
|
||||
// Currently used by drones.
|
||||
if(local_transmit)
|
||||
var/list/listeners = hearers(5,src)
|
||||
listeners |= src
|
||||
|
||||
for(var/mob/living/silicon/D in listeners)
|
||||
if(D.client && istype(D,src.type))
|
||||
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]\""
|
||||
return 1
|
||||
|
||||
if(message_mode && bot_type == IS_ROBOT && !R.is_component_functioning("radio"))
|
||||
src << "\red Your radio isn't functional at this time."
|
||||
return 0
|
||||
|
||||
switch(message_mode)
|
||||
if("department")
|
||||
switch(bot_type)
|
||||
if(IS_AI)
|
||||
return AI.holopad_talk(message, verb, speaking)
|
||||
if(IS_ROBOT)
|
||||
log_say("[key_name(src)] : [message]")
|
||||
return R.radio.talk_into(src,message,message_mode,verb,speaking)
|
||||
if(IS_PAI)
|
||||
log_say("[key_name(src)] : [message]")
|
||||
return P.radio.talk_into(src,message,message_mode,verb,speaking)
|
||||
return 0
|
||||
|
||||
if("general")
|
||||
switch(bot_type)
|
||||
if(IS_AI)
|
||||
if (AI.aiRadio.disabledAi || AI.aiRestorePowerRoutine || AI.stat)
|
||||
src << "\red System Error - Transceiver Disabled"
|
||||
return 0
|
||||
else
|
||||
log_say("[key_name(src)] : [message]")
|
||||
return AI.aiRadio.talk_into(src,message,null,verb,speaking)
|
||||
if(IS_ROBOT)
|
||||
log_say("[key_name(src)] : [message]")
|
||||
return R.radio.talk_into(src,message,null,verb,speaking)
|
||||
if(IS_PAI)
|
||||
log_say("[key_name(src)] : [message]")
|
||||
return P.radio.talk_into(src,message,null,verb,speaking)
|
||||
return 0
|
||||
|
||||
else
|
||||
if(message_mode)
|
||||
switch(bot_type)
|
||||
if(IS_AI)
|
||||
if (AI.aiRadio.disabledAi || AI.aiRestorePowerRoutine || AI.stat)
|
||||
src << "\red System Error - Transceiver Disabled"
|
||||
return 0
|
||||
else
|
||||
log_say("[key_name(src)] : [message]")
|
||||
return AI.aiRadio.talk_into(src,message,message_mode,verb,speaking)
|
||||
if(IS_ROBOT)
|
||||
log_say("[key_name(src)] : [message]")
|
||||
return R.radio.talk_into(src,message,message_mode,verb,speaking)
|
||||
if(IS_PAI)
|
||||
log_say("[key_name(src)] : [message]")
|
||||
return P.radio.talk_into(src,message,message_mode,verb,speaking)
|
||||
return 0
|
||||
|
||||
return ..(message,speaking,verb)
|
||||
|
||||
//For holopads only. Usable by AI.
|
||||
/mob/living/silicon/ai/proc/holopad_talk(var/message, verb, datum/language/speaking)
|
||||
|
||||
|
||||
@@ -27,6 +27,7 @@
|
||||
show_stat_health = 1
|
||||
faction = "cult"
|
||||
supernatural = 1
|
||||
see_invisible = SEE_INVISIBLE_NOLIGHTING
|
||||
var/nullblock = 0
|
||||
|
||||
mob_swap_flags = HUMAN|SIMPLE_ANIMAL|SLIME|MONKEY
|
||||
@@ -150,6 +151,7 @@
|
||||
attacktext = "slashed"
|
||||
speed = -1
|
||||
environment_smash = 1
|
||||
see_in_dark = 7
|
||||
attack_sound = 'sound/weapons/rapidslice.ogg'
|
||||
construct_spells = list(/spell/targeted/ethereal_jaunt/shift)
|
||||
|
||||
@@ -227,6 +229,7 @@
|
||||
attacktext = "violently stabbed"
|
||||
speed = -1
|
||||
environment_smash = 1
|
||||
see_in_dark = 7
|
||||
attack_sound = 'sound/weapons/pierce.ogg'
|
||||
|
||||
construct_spells = list(
|
||||
|
||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user