Merge pull request #398 from VOREStation/sync

Polaris Sync
This commit is contained in:
Arokha Sieyes
2016-07-03 19:47:47 -04:00
committed by GitHub
197 changed files with 10450 additions and 8061 deletions

View File

@@ -71,38 +71,61 @@
screen_loc = "NORTH,WEST+1"
Click()
switch(master.cl.buildmode)
if(1)
usr << "\blue ***********************************************************"
usr << "\blue Left Mouse Button = Construct / Upgrade"
usr << "\blue Right Mouse Button = Deconstruct / Delete / Downgrade"
usr << "\blue Left Mouse Button + ctrl = R-Window"
usr << "\blue Left Mouse Button + alt = Airlock"
if(1) // Basic Build
usr << "<span class='notice'>***********************************************************</span>"
usr << "<span class='notice'>Left Mouse Button = Construct / Upgrade</span>"
usr << "<span class='notice'>Right Mouse Button = Deconstruct / Delete / Downgrade</span>"
usr << "<span class='notice'>Left Mouse Button + ctrl = R-Window</span>"
usr << "<span class='notice'>Left Mouse Button + alt = Airlock</span>"
usr << ""
usr << "\blue Use the button in the upper left corner to"
usr << "\blue change the direction of built objects."
usr << "\blue ***********************************************************"
if(2)
usr << "\blue ***********************************************************"
usr << "\blue Right Mouse Button on buildmode button = Set object type"
usr << "\blue Middle Mouse Button on buildmode button= On/Off object type saying"
usr << "\blue Middle Mouse Button on turf/obj = Capture object type"
usr << "\blue Left Mouse Button on turf/obj = Place objects"
usr << "\blue Right Mouse Button = Delete objects"
usr << "<span class='notice'>Use the button in the upper left corner to</span>"
usr << "<span class='notice'>change the direction of built objects.</span>"
usr << "<span class='notice'>***********************************************************</span>"
if(2) // Adv. Build
usr << "<span class='notice'>***********************************************************</span>"
usr << "<span class='notice'>Right Mouse Button on buildmode button = Set object type</span>"
usr << "<span class='notice'>Middle Mouse Button on buildmode button= On/Off object type saying</span>"
usr << "<span class='notice'>Middle Mouse Button on turf/obj = Capture object type</span>"
usr << "<span class='notice'>Left Mouse Button on turf/obj = Place objects</span>"
usr << "<span class='notice'>Right Mouse Button = Delete objects</span>"
usr << "<span class='notice'>Mouse Button + ctrl = Copy object type</span>"
usr << ""
usr << "\blue Use the button in the upper left corner to"
usr << "\blue change the direction of built objects."
usr << "\blue ***********************************************************"
if(3)
usr << "\blue ***********************************************************"
usr << "\blue Right Mouse Button on buildmode button = Select var(type) & value"
usr << "\blue Left Mouse Button on turf/obj/mob = Set var(type) & value"
usr << "\blue Right Mouse Button on turf/obj/mob = Reset var's value"
usr << "\blue ***********************************************************"
if(4)
usr << "\blue ***********************************************************"
usr << "\blue Left Mouse Button on turf/obj/mob = Select"
usr << "\blue Right Mouse Button on turf/obj/mob = Throw"
usr << "\blue ***********************************************************"
usr << "<span class='notice'>Use the button in the upper left corner to</span>"
usr << "<span class='notice'>change the direction of built objects.</span>"
usr << "<span class='notice'>***********************************************************</span>"
if(3) // Edit
usr << "<span class='notice'>***********************************************************</span>"
usr << "<span class='notice'>Right Mouse Button on buildmode button = Select var(type) & value</span>"
usr << "<span class='notice'>Left Mouse Button on turf/obj/mob = Set var(type) & value</span>"
usr << "<span class='notice'>Right Mouse Button on turf/obj/mob = Reset var's value</span>"
usr << "<span class='notice'>***********************************************************</span>"
if(4) // Throw
usr << "<span class='notice'>***********************************************************</span>"
usr << "<span class='notice'>Left Mouse Button on turf/obj/mob = Select</span>"
usr << "<span class='notice'>Right Mouse Button on turf/obj/mob = Throw</span>"
usr << "<span class='notice'>***********************************************************</span>"
if(5) // Room Build
usr << "<span class='notice'>***********************************************************</span>"
usr << "<span class='notice'>Left Mouse Button on turf = Select as point A</span>"
usr << "<span class='notice'>Right Mouse Button on turf = Select as point B</span>"
usr << "<span class='notice'>Right Mouse Button on buildmode button = Change floor/wall type</span>"
usr << "<span class='notice'>***********************************************************</span>"
if(6) // Make Ladders
usr << "<span class='notice'>***********************************************************</span>"
usr << "<span class='notice'>Left Mouse Button on turf = Set as upper ladder loc</span>"
usr << "<span class='notice'>Right Mouse Button on turf = Set as lower ladder loc</span>"
usr << "<span class='notice'>***********************************************************</span>"
if(7) // Move Into Contents
usr << "<span class='notice'>***********************************************************</span>"
usr << "<span class='notice'>Left Mouse Button on turf/obj/mob = Select</span>"
usr << "<span class='notice'>Right Mouse Button on turf/obj/mob = Move into selection</span>"
usr << "<span class='notice'>***********************************************************</span>"
if(8) // Make Lights
usr << "<span class='notice'>***********************************************************</span>"
usr << "<span class='notice'>Left Mouse Button on turf/obj/mob = Make it glow</span>"
usr << "<span class='notice'>Right Mouse Button on turf/obj/mob = Reset glowing</span>"
usr << "<span class='notice'>Right Mouse Button on buildmode button = Change glow properties</span>"
usr << "<span class='notice'>***********************************************************</span>"
return 1
/obj/effect/bmode/buildquit
@@ -144,62 +167,100 @@
var/objholder = /obj/structure/closet
var/objsay = 1
Click(location, control, params)
var/list/pa = params2list(params)
var/wall_holder = /turf/simulated/wall
var/floor_holder = /turf/simulated/floor/plating
var/turf/coordA = null
var/turf/coordB = null
if(pa.Find("middle"))
switch(master.cl.buildmode)
if(2)
objsay=!objsay
var/new_light_color = "#FFFFFF"
var/new_light_range = 3
var/new_light_intensity = 3
/obj/effect/bmode/buildmode/Click(location, control, params)
var/list/pa = params2list(params)
if(pa.Find("middle"))
switch(master.cl.buildmode)
if(2)
objsay=!objsay
if(pa.Find("left"))
switch(master.cl.buildmode)
if(1)
master.cl.buildmode = 2
src.icon_state = "buildmode2"
if(2)
master.cl.buildmode = 3
src.icon_state = "buildmode3"
if(3)
master.cl.buildmode = 4
src.icon_state = "buildmode4"
if(4)
master.cl.buildmode = 1
src.icon_state = "buildmode1"
if(pa.Find("left"))
switch(master.cl.buildmode)
if(1)
master.cl.buildmode = 2
src.icon_state = "buildmode2"
if(2)
master.cl.buildmode = 3
src.icon_state = "buildmode3"
if(3)
master.cl.buildmode = 4
src.icon_state = "buildmode4"
if(4)
master.cl.buildmode = 5
src.icon_state = "buildmode5"
if(5)
master.cl.buildmode = 6
src.icon_state = "buildmode6"
if(6)
master.cl.buildmode = 7
src.icon_state = "buildmode7"
if(7)
master.cl.buildmode = 8
src.icon_state = "buildmode8"
if(8)
master.cl.buildmode = 1
src.icon_state = "buildmode1"
else if(pa.Find("right"))
switch(master.cl.buildmode)
if(1)
else if(pa.Find("right"))
switch(master.cl.buildmode)
if(1) // Basic Build
return 1
if(2) // Adv. Build
objholder = get_path_from_partial_text(/obj/structure/closet)
if(3) // Edit
var/list/locked = list("vars", "key", "ckey", "client", "firemut", "ishulk", "telekinesis", "xray", "virus", "viruses", "cuffed", "ka", "last_eaten", "urine")
master.buildmode.varholder = input(usr,"Enter variable name:" ,"Name", "name")
if(master.buildmode.varholder in locked && !check_rights(R_DEBUG,0))
return 1
if(2)
objholder = text2path(input(usr,"Enter typepath:" ,"Typepath","/obj/structure/closet"))
if(!ispath(objholder))
objholder = /obj/structure/closet
alert("That path is not allowed.")
else
if(ispath(objholder,/mob) && !check_rights(R_DEBUG,0))
objholder = /obj/structure/closet
if(3)
var/list/locked = list("vars", "key", "ckey", "client", "firemut", "ishulk", "telekinesis", "xray", "virus", "viruses", "cuffed", "ka", "last_eaten", "urine")
master.buildmode.varholder = input(usr,"Enter variable name:" ,"Name", "name")
if(master.buildmode.varholder in locked && !check_rights(R_DEBUG,0))
return 1
var/thetype = input(usr,"Select variable type:" ,"Type") in list("text","number","mob-reference","obj-reference","turf-reference")
if(!thetype) return 1
switch(thetype)
if("text")
master.buildmode.valueholder = input(usr,"Enter variable value:" ,"Value", "value") as text
if("number")
master.buildmode.valueholder = input(usr,"Enter variable value:" ,"Value", 123) as num
if("mob-reference")
master.buildmode.valueholder = input(usr,"Enter variable value:" ,"Value") as mob in mob_list
if("obj-reference")
master.buildmode.valueholder = input(usr,"Enter variable value:" ,"Value") as obj in world
if("turf-reference")
master.buildmode.valueholder = input(usr,"Enter variable value:" ,"Value") as turf in world
return 1
var/thetype = input(usr,"Select variable type:" ,"Type") in list("text","number","mob-reference","obj-reference","turf-reference")
if(!thetype) return 1
switch(thetype)
if("text")
master.buildmode.valueholder = input(usr,"Enter variable value:" ,"Value", "value") as text
if("number")
master.buildmode.valueholder = input(usr,"Enter variable value:" ,"Value", 123) as num
if("mob-reference")
master.buildmode.valueholder = input(usr,"Enter variable value:" ,"Value") as mob in mob_list
if("obj-reference")
master.buildmode.valueholder = input(usr,"Enter variable value:" ,"Value") as obj in world
if("turf-reference")
master.buildmode.valueholder = input(usr,"Enter variable value:" ,"Value") as turf in world
if(5) // Room build
var/choice = alert("Would you like to change the floor or wall holders?","Room Builder", "Floor", "Wall")
switch(choice)
if("Floor")
floor_holder = get_path_from_partial_text(/turf/simulated/floor/plating)
if("Wall")
wall_holder = get_path_from_partial_text(/turf/simulated/wall)
if(8) // Lights
var/choice = alert("Change the new light range, power, or color?", "Light Maker", "Range", "Power", "Color")
switch(choice)
if("Range")
var/input = input("New light range.","Light Maker",3) as null|num
if(input)
new_light_range = input
if("Power")
var/input = input("New light power.","Light Maker",3) as null|num
if(input)
new_light_intensity = input
if("Color")
var/input = input("New light color.","Light Maker",3) as null|color
if(input)
new_light_color = input
return 1
/proc/build_click(var/mob/user, buildmode, params, var/obj/object)
var/obj/effect/bmode/buildholder/holder = null
@@ -211,7 +272,7 @@
var/list/pa = params2list(params)
switch(buildmode)
if(1)
if(1) // Basic Build
if(istype(object,/turf) && pa.Find("left") && !pa.Find("alt") && !pa.Find("ctrl") )
if(istype(object,/turf/space))
var/turf/T = object
@@ -260,8 +321,8 @@
if(NORTHWEST)
var/obj/structure/window/reinforced/WIN = new/obj/structure/window/reinforced(get_turf(object))
WIN.set_dir(NORTHWEST)
if(2)
if(pa.Find("left"))
if(2) // Adv. Build
if(pa.Find("left") && !pa.Find("ctrl"))
if(ispath(holder.buildmode.objholder,/turf))
var/turf/T = get_turf(object)
T.ChangeTurf(holder.buildmode.objholder)
@@ -269,27 +330,31 @@
var/obj/A = new holder.buildmode.objholder (get_turf(object))
A.set_dir(holder.builddir.dir)
else if(pa.Find("right"))
if(isobj(object)) qdel(object)
if(isobj(object))
qdel(object)
else if(pa.Find("ctrl"))
holder.buildmode.objholder = object.type
user << "<span class='notice'>[object]([object.type]) copied to buildmode.</span>"
if(pa.Find("middle"))
holder.buildmode.objholder = text2path("[object.type]")
if(holder.buildmode.objsay) usr << "[object.type]"
if(3)
if(3) // Edit
if(pa.Find("left")) //I cant believe this shit actually compiles.
if(object.vars.Find(holder.buildmode.varholder))
log_admin("[key_name(usr)] modified [object.name]'s [holder.buildmode.varholder] to [holder.buildmode.valueholder]")
object.vars[holder.buildmode.varholder] = holder.buildmode.valueholder
else
usr << "\red [initial(object.name)] does not have a var called '[holder.buildmode.varholder]'"
user << "<span class='danger'>[initial(object.name)] does not have a var called '[holder.buildmode.varholder]'</span>"
if(pa.Find("right"))
if(object.vars.Find(holder.buildmode.varholder))
log_admin("[key_name(usr)] modified [object.name]'s [holder.buildmode.varholder] to [holder.buildmode.valueholder]")
object.vars[holder.buildmode.varholder] = initial(object.vars[holder.buildmode.varholder])
else
usr << "\red [initial(object.name)] does not have a var called '[holder.buildmode.varholder]'"
user << "<span class='danger'>[initial(object.name)] does not have a var called '[holder.buildmode.varholder]'</span>"
if(4)
if(4) // Throw
if(pa.Find("left"))
if(istype(object, /atom/movable))
holder.throw_atom = object
@@ -297,3 +362,127 @@
if(holder.throw_atom)
holder.throw_atom.throw_at(object, 10, 1)
log_admin("[key_name(usr)] threw [holder.throw_atom] at [object]")
if(5) // Room build
if(pa.Find("left"))
holder.buildmode.coordA = get_turf(object)
user << "<span class='notice'>Defined [object] ([object.type]) as point A.</span>"
if(pa.Find("right"))
holder.buildmode.coordB = get_turf(object)
user << "<span class='notice'>Defined [object] ([object.type]) as point B.</span>"
if(holder.buildmode.coordA && holder.buildmode.coordB)
user << "<span class='notice'>A and B set, creating rectangle.</span>"
holder.buildmode.make_rectangle(
holder.buildmode.coordA,
holder.buildmode.coordB,
holder.buildmode.wall_holder,
holder.buildmode.floor_holder
)
holder.buildmode.coordA = null
holder.buildmode.coordB = null
if(6) // Ladders
if(pa.Find("left"))
holder.buildmode.coordA = get_turf(object)
user << "<span class='notice'>Defined [object] ([object.type]) as upper ladder location.</span>"
if(pa.Find("right"))
holder.buildmode.coordB = get_turf(object)
user << "<span class='notice'>Defined [object] ([object.type]) as lower ladder location.</span>"
if(holder.buildmode.coordA && holder.buildmode.coordB)
user << "<span class='notice'>Ladder locations set, building ladders.</span>"
var/obj/structure/ladder/A = new /obj/structure/ladder(holder.buildmode.coordA)
var/obj/structure/ladder/B = new /obj/structure/ladder(holder.buildmode.coordB)
A.target = B
B.target = A
B.icon_state = "ladderup"
holder.buildmode.coordA = null
holder.buildmode.coordB = null
if(7) // Move into contents
if(pa.Find("left"))
if(istype(object, /atom))
holder.throw_atom = object
if(pa.Find("right"))
if(holder.throw_atom && istype(object, /atom/movable))
object.forceMove(holder.throw_atom)
log_admin("[key_name(usr)] moved [object] into [holder.throw_atom].")
if(8) // Lights
if(pa.Find("left"))
if(object)
object.set_light(holder.buildmode.new_light_range, holder.buildmode.new_light_intensity, holder.buildmode.new_light_color)
if(pa.Find("right"))
if(object)
object.set_light(0, 0, "#FFFFFF")
/obj/effect/bmode/buildmode/proc/get_path_from_partial_text(default_path)
var/desired_path = input("Enter full or partial typepath.","Typepath","[default_path]")
var/list/types = typesof(/atom)
var/list/matches = list()
for(var/path in types)
if(findtext("[path]", desired_path))
matches += path
if(matches.len==0)
alert("No results found. Sorry.")
return
var/result = null
if(matches.len==1)
result = matches[1]
else
result = input("Select an atom type", "Spawn Atom", matches[1]) as null|anything in matches
if(!objholder)
result = default_path
return result
/obj/effect/bmode/buildmode/proc/make_rectangle(var/turf/A, var/turf/B, var/turf/wall_type, var/turf/floor_type)
if(!A || !B) // No coords
return
if(A.z != B.z) // Not same z-level
return
var/height = A.y - B.y
var/width = A.x - B.x
var/z_level = A.z
var/turf/lower_left_corner = null
// First, try to find the lowest part
var/desired_y = 0
if(A.y <= B.y)
desired_y = A.y
else
desired_y = B.y
//Now for the left-most part.
var/desired_x = 0
if(A.x <= B.x)
desired_x = A.x
else
desired_x = B.x
lower_left_corner = locate(desired_x, desired_y, z_level)
// Now we can begin building the actual room. This defines the boundries for the room.
var/low_bound_x = lower_left_corner.x
var/low_bound_y = lower_left_corner.y
var/high_bound_x = lower_left_corner.x + abs(width)
var/high_bound_y = lower_left_corner.y + abs(height)
for(var/i = low_bound_x, i <= high_bound_x, i++)
for(var/j = low_bound_y, j <= high_bound_y, j++)
var/turf/T = locate(i, j, z_level)
if(i == low_bound_x || i == high_bound_x || j == low_bound_y || j == high_bound_y)
if(isturf(wall_type))
T.ChangeTurf(wall_type)
else
new wall_type(T)
else
if(isturf(floor_type))
T.ChangeTurf(floor_type)
else
new floor_type(T)

View File

@@ -7,7 +7,7 @@
src << "Only administrators may use this command."
return
var/input = sanitize(input(usr, "Enter the description of the custom event. Be descriptive. To cancel the event, make this blank or hit cancel.", "Custom Event", custom_event_msg) as message|null, MAX_BOOK_MESSAGE_LEN, extra = 0)
var/input = sanitize(input(usr, "Enter the description of the custom event. Be descriptive. To cancel the event, make this blank or hit cancel.", "Custom Event", custom_event_msg) as message|null, MAX_PAPER_MESSAGE_LEN, extra = 0)
if(!input || input == "")
custom_event_msg = null
log_admin("[usr.key] has cleared the custom event text.")

View File

@@ -21,6 +21,7 @@
if(R_ADMIN & C.holder.rights)
if(C.is_preference_enabled(/datum/client_preference/admin/show_chat_prayers))
C << msg
C << 'sound/effects/ding.ogg'
usr << "Your prayers have been received by the gods."
feedback_add_details("admin_verb","PR") //If you are copy-pasting this, ensure the 2nd parameter is unique to the new proc!
@@ -31,9 +32,11 @@
for(var/client/C in admins)
if(R_ADMIN & C.holder.rights)
C << msg
C << 'sound/machines/signal.ogg'
/proc/Syndicate_announce(var/msg, var/mob/Sender)
msg = "\blue <b><font color=crimson>ILLEGAL:</font>[key_name(Sender, 1)] (<A HREF='?_src_=holder;adminplayeropts=\ref[Sender]'>PP</A>) (<A HREF='?_src_=vars;Vars=\ref[Sender]'>VV</A>) (<A HREF='?_src_=holder;subtlemessage=\ref[Sender]'>SM</A>) ([admin_jump_link(Sender, src)]) (<A HREF='?_src_=holder;secretsadmin=check_antagonist'>CA</A>) (<A HREF='?_src_=holder;BlueSpaceArtillery=\ref[Sender]'>BSA</A>) (<A HREF='?_src_=holder;SyndicateReply=\ref[Sender]'>RPLY</A>):</b> [msg]"
for(var/client/C in admins)
if(R_ADMIN & C.holder.rights)
C << msg
C << 'sound/machines/signal.ogg'

View File

@@ -158,6 +158,7 @@
if(!void)
void = new()
void.MakeGreed()
screen += void
if(prefs.lastchangelog != changelog_hash) //bolds the changelog button on the interface so we know there are updates.

View File

@@ -7,19 +7,29 @@ var/global/list/uplink_locations = list("PDA", "Headset", "None")
/datum/category_item/player_setup_item/antagonism/basic/load_character(var/savefile/S)
S["uplinklocation"] >> pref.uplinklocation
S["exploit_record"] >> pref.exploit_record
S["antag_faction"] >> pref.antag_faction
S["antag_vis"] >> pref.antag_vis
/datum/category_item/player_setup_item/antagonism/basic/save_character(var/savefile/S)
S["uplinklocation"] << pref.uplinklocation
S["exploit_record"] << pref.exploit_record
S["antag_faction"] << pref.antag_faction
S["antag_vis"] << pref.antag_vis
/datum/category_item/player_setup_item/antagonism/basic/sanitize_character()
pref.uplinklocation = sanitize_inlist(pref.uplinklocation, uplink_locations, initial(pref.uplinklocation))
if(!pref.antag_faction) pref.antag_faction = "None"
if(!pref.antag_vis) pref.antag_vis = "Hidden"
// Moved from /datum/preferences/proc/copy_to()
/datum/category_item/player_setup_item/antagonism/basic/copy_to_mob(var/mob/living/carbon/human/character)
character.exploit_record = pref.exploit_record
character.antag_faction = pref.antag_faction
character.antag_vis = pref.antag_vis
/datum/category_item/player_setup_item/antagonism/basic/content(var/mob/user)
. += "Faction: <a href='?src=\ref[src];antagfaction=1'>[pref.antag_faction]</a><br/>"
. += "Visibility: <a href='?src=\ref[src];antagvis=1'>[pref.antag_vis]</a><br/>"
. +="<b>Uplink Type : <a href='?src=\ref[src];antagtask=1'>[pref.uplinklocation]</a></b>"
. +="<br>"
. +="<b>Exploitable information:</b><br>"
@@ -34,9 +44,29 @@ var/global/list/uplink_locations = list("PDA", "Headset", "None")
return TOPIC_REFRESH
if(href_list["exploitable_record"])
var/exploitmsg = sanitize(input(user,"Set exploitable information about you here.","Exploitable Information", html_decode(pref.exploit_record)) as message|null, MAX_PAPER_MESSAGE_LEN, extra = 0)
var/exploitmsg = sanitize(input(user,"Set exploitable information about you here.","Exploitable Information", html_decode(pref.exploit_record)) as message|null, MAX_RECORD_LENGTH, extra = 0)
if(!isnull(exploitmsg) && !jobban_isbanned(user, "Records") && CanUseTopic(user))
pref.exploit_record = exploitmsg
return TOPIC_REFRESH
if(href_list["antagfaction"])
var/choice = input(user, "Please choose an antagonistic faction to work for.", "Character Preference", pref.antag_faction) as null|anything in antag_faction_choices + list("None","Other")
if(!choice || !CanUseTopic(user))
return TOPIC_NOACTION
if(choice == "Other")
var/raw_choice = sanitize(input(user, "Please enter a faction.", "Character Preference") as text|null, MAX_NAME_LEN)
if(raw_choice)
pref.antag_faction = raw_choice
else
pref.antag_faction = choice
return TOPIC_REFRESH
if(href_list["antagvis"])
var/choice = input(user, "Please choose an antagonistic visibility level.", "Character Preference", pref.antag_vis) as null|anything in antag_visiblity_choices
if(!choice || !CanUseTopic(user))
return TOPIC_NOACTION
else
pref.antag_vis = choice
return TOPIC_REFRESH
return ..()

View File

@@ -121,6 +121,8 @@ var/global/list/valid_bloodtypes = list("A+", "A-", "B+", "B-", "AB+", "AB-", "O
I.mechassist()
else if(status == "mechanical")
I.robotize()
else if(status == "digital")
I.digitize()
return
/datum/category_item/player_setup_item/general/body/content(var/mob/user)
@@ -197,6 +199,11 @@ var/global/list/valid_bloodtypes = list("A+", "A-", "B+", "B-", "AB+", "AB-", "O
if(ind > 1)
. += ", "
. += "\tSynthetic [organ_name]"
else if(status == "digital")
++ind
if(ind > 1)
. += ", "
. += "\tDigital [organ_name]"
else if(status == "assisted")
++ind
if(ind > 1)
@@ -549,6 +556,8 @@ var/global/list/valid_bloodtypes = list("A+", "A-", "B+", "B-", "AB+", "AB-", "O
var/list/organ_choices = list("Normal","Assisted","Mechanical")
if(pref.organ_data[BP_TORSO] == "cyborg")
organ_choices -= "Normal"
if(organ_name == "Brain")
organ_choices += "Digital"
var/new_state = input(user, "What state do you wish the organ to be in?") as null|anything in organ_choices
if(!new_state) return
@@ -560,6 +569,8 @@ var/global/list/valid_bloodtypes = list("A+", "A-", "B+", "B-", "AB+", "AB-", "O
pref.organ_data[organ] = "assisted"
if("Mechanical")
pref.organ_data[organ] = "mechanical"
if("Digital")
pref.organ_data[organ] = "digital"
return TOPIC_REFRESH
else if(href_list["disabilities"])

View File

@@ -115,19 +115,19 @@
return TOPIC_REFRESH
else if(href_list["set_medical_records"])
var/new_medical = sanitize(input(user,"Enter medical information here.","Character Preference", html_decode(pref.med_record)) as message|null, MAX_PAPER_MESSAGE_LEN, extra = 0)
var/new_medical = sanitize(input(user,"Enter medical information here.","Character Preference", html_decode(pref.med_record)) as message|null, MAX_RECORD_LENGTH, extra = 0)
if(!isnull(new_medical) && !jobban_isbanned(user, "Records") && CanUseTopic(user))
pref.med_record = new_medical
return TOPIC_REFRESH
else if(href_list["set_general_records"])
var/new_general = sanitize(input(user,"Enter employment information here.","Character Preference", html_decode(pref.gen_record)) as message|null, MAX_PAPER_MESSAGE_LEN, extra = 0)
var/new_general = sanitize(input(user,"Enter employment information here.","Character Preference", html_decode(pref.gen_record)) as message|null, MAX_RECORD_LENGTH, extra = 0)
if(!isnull(new_general) && !jobban_isbanned(user, "Records") && CanUseTopic(user))
pref.gen_record = new_general
return TOPIC_REFRESH
else if(href_list["set_security_records"])
var/sec_medical = sanitize(input(user,"Enter security information here.","Character Preference", html_decode(pref.sec_record)) as message|null, MAX_PAPER_MESSAGE_LEN, extra = 0)
var/sec_medical = sanitize(input(user,"Enter security information here.","Character Preference", html_decode(pref.sec_record)) as message|null, MAX_RECORD_LENGTH, extra = 0)
if(!isnull(sec_medical) && !jobban_isbanned(user, "Records") && CanUseTopic(user))
pref.sec_record = sec_medical
return TOPIC_REFRESH

View File

@@ -3,8 +3,12 @@
path = /obj/item/weapon/cane
/datum/gear/dice
display_name = "d20"
path = /obj/item/weapon/dice/d20
display_name = "dice pack"
path = /obj/item/weapon/storage/pill_bottle/dice
/datum/gear/dice/nerd
display_name = "dice pack (gaming)"
path = /obj/item/weapon/storage/pill_bottle/dice_nerd
/datum/gear/cards
display_name = "deck of cards"

View File

@@ -48,4 +48,12 @@
/datum/gear/gloves/white
display_name = "gloves, white"
path = /obj/item/clothing/gloves/white
path = /obj/item/clothing/gloves/white
/datum/gear/gloves/evening
display_name = "evening gloves"
path = /obj/item/clothing/gloves/evening
/datum/gear/gloves/evening/New()
..()
gear_tweaks = list(gear_tweak_free_color_choice)

View File

@@ -54,8 +54,10 @@ datum/preferences
//Some faction information.
var/home_system = "Unset" //System of birth.
var/citizenship = "None" //Current home system.
var/faction = "None" //Antag faction/general associated faction.
var/faction = "None" //General associated faction.
var/religion = "None" //Religious association.
var/antag_faction = "None" //Antag associated faction.
var/antag_vis = "Hidden" //How visible antag association is to others.
//Mob preview
var/icon/preview_icon = null

View File

@@ -1,6 +1,7 @@
var/global/list/seen_citizenships = list()
var/global/list/seen_systems = list()
var/global/list/seen_factions = list()
var/global/list/seen_antag_factions = list()
var/global/list/seen_religions = list()
//Commenting this out for now until I work the lists it into the event generator/journalist/chaplain.
@@ -25,6 +26,7 @@ var/global/list/home_system_choices = list(
starsys_name,
"Nyx",
"Tau Ceti",
"Qerr'Vallis",
"Epsilon Ursae Minoris",
"S'randarr"
)
@@ -42,6 +44,14 @@ var/global/list/faction_choices = list(
"Zeng-Hu Pharmaceuticals",
"Hesphaistos Industries"
)
var/global/list/antag_faction_choices = list() //Should be populated after brainstorming. Leaving as blank in case brainstorming does not occur.
var/global/list/antag_visiblity_choices = list(
"Hidden",
"Shared",
"Known"
)
var/global/list/religion_choices = list(
"Unitarianism",

View File

@@ -16,7 +16,7 @@
New()
//average of 0.5, somewhat better than regular gloves' 0.75
siemens_coefficient = pick(0,0.1,0.3,0.5,0.5,0.75,1.35)
siemens_coefficient = pick(0,0.1,0.3,0.5,0.5,0.75,1.35)
/obj/item/clothing/gloves/black
desc = "These work gloves are thick and fire-resistant."
@@ -84,3 +84,14 @@
desc = "A pair of gloves, they don't look special in any way."
icon_state = "brown"
item_state = "browngloves"
/obj/item/clothing/gloves/evening
desc = "A pair of gloves that reach past the elbow. Fancy!"
name = "evening gloves"
icon_state = "evening_gloves"
item_state = "graygloves"
cold_protection = HANDS
min_cold_protection_temperature = GLOVES_MIN_COLD_PROTECTION_TEMPERATURE
heat_protection = HANDS
max_heat_protection_temperature = GLOVES_MAX_HEAT_PROTECTION_TEMPERATURE

View File

@@ -434,6 +434,8 @@
holder.spark_system.start()
playsound(H.loc, 'sound/effects/sparks2.ogg', 50, 1)
H.break_cloak()
if(!holder.cell)
H << "<span class = 'danger'>Your power sink flashes an error; there is no cell in your rig.</span>"
drain_complete(H)

View File

@@ -42,7 +42,7 @@
anim(get_turf(H), H, 'icons/effects/effects.dmi', "electricity",null,20,null)
H.visible_message("[H.name] vanishes into thin air!",1)
H.visible_message("[H.name] vanishes into thin air!")
/obj/item/rig_module/stealth_field/deactivate()

View File

@@ -74,7 +74,7 @@
/obj/item/weapon/rig/light/ninja
name = "ominous suit control module"
suit_type = "ominous"
desc = "A unique, vaccum-proof suit of nano-enhanced armor designed specifically for Spider Clan assassins."
desc = "A unique suit of nano-enhanced armor designed for covert operations."
icon_state = "ninja_rig"
armor = list(melee = 50, bullet = 15, laser = 30, energy = 10, bomb = 25, bio = 100, rad = 30)
emp_protection = 40 //change this to 30 if too high.

View File

@@ -12,6 +12,8 @@
var/image/mob_overlay = null
var/overlay_state = null
sprite_sheets = list("Teshari" = 'icons/mob/species/seromi/ties.dmi') //Teshari can into webbing, too!
/obj/item/clothing/accessory/Destroy()
on_removed()
return ..()

View File

@@ -134,7 +134,7 @@
if(P.name != "Blank Card")
user << "You cannot write on that card."
return
var/cardtext = sanitize(input(user, "What do you wish to write on the card?", "Card Editing") as text|null, MAX_BOOK_MESSAGE_LEN)
var/cardtext = sanitize(input(user, "What do you wish to write on the card?", "Card Editing") as text|null, MAX_PAPER_MESSAGE_LEN)
if(!cardtext)
return
P.name = cardtext

View File

@@ -30,62 +30,60 @@
"Snow Field" = "snowfield", \
"Theatre" = "theatre", \
"Meeting Hall" = "meetinghall", \
"Courtroom" = "courtroom" \
"Courtroom" = "courtroom", \
"Turn Off" = "turnoff" \
)
var/list/restricted_programs = list("Atmospheric Burn Simulation" = "burntest", "Wildlife Simulation" = "wildlifecarp")
var/current_program = "turnoff"
/obj/machinery/computer/HolodeckControl/attack_ai(var/mob/user as mob)
return src.attack_hand(user)
/obj/machinery/computer/HolodeckControl/attack_hand(var/mob/user as mob)
if(..())
return
user.set_machine(src)
var/dat
dat += "<B>Holodeck Control System</B><BR>"
dat += "<HR>Current Loaded Programs:<BR>"
for(var/prog in supported_programs)
dat += "<A href='?src=\ref[src];program=[supported_programs[prog]]'>([prog])</A><BR>"
ui_interact(user)
dat += "<BR>"
dat += "<A href='?src=\ref[src];program=turnoff'>(Turn Off)</A><BR>"
/**
* Display the NanoUI window for the Holodeck Computer.
*
* See NanoUI documentation for details.
*/
/obj/machinery/computer/HolodeckControl/ui_interact(mob/user, ui_key = "main", var/datum/nanoui/ui = null, var/force_open = 1)
user.set_machine(src)
dat += "<BR>"
dat += "Please ensure that only holographic weapons are used in the holodeck if a combat simulation has been loaded.<BR>"
var/list/data = list()
var/program_list[0]
var/restricted_program_list[0]
for(var/P in supported_programs)
program_list[++program_list.len] = list("name" = P, "program" = supported_programs[P])
for(var/P in restricted_programs)
restricted_program_list[++restricted_program_list.len] = list("name" = P, "program" = restricted_programs[P])
data["supportedPrograms"] = program_list
data["restrictedPrograms"] = restricted_program_list
data["currentProgram"] = current_program
if(issilicon(user))
dat += "<BR>"
if(safety_disabled)
if (emagged)
dat += "<font color=red><b>ERROR</b>: Cannot re-enable Safety Protocols.</font><BR>"
else
dat += "<A href='?src=\ref[src];AIoverride=1'>(<font color=green>Re-Enable Safety Protocols?</font>)</A><BR>"
else
dat += "<A href='?src=\ref[src];AIoverride=1'>(<font color=red>Override Safety Protocols?</font>)</A><BR>"
dat += "<BR>"
if(safety_disabled)
for(var/prog in restricted_programs)
dat += "<A href='?src=\ref[src];program=[restricted_programs[prog]]'>(<font color=red>Begin [prog]</font>)</A><BR>"
dat += "Ensure the holodeck is empty before testing.<BR>"
dat += "<BR>"
dat += "Safety Protocols are <font color=red> DISABLED </font><BR>"
data["isSilicon"] = 1
else
dat += "Safety Protocols are <font color=green> ENABLED </font><BR>"
data["isSilicon"] = null
data["safetyDisabled"] = safety_disabled
data["emagged"] = emagged
if(linkedholodeck.has_gravity)
dat += "Gravity is <A href='?src=\ref[src];gravity=1'><font color=green>(ON)</font></A><BR>"
data["gravity"] = 1
else
dat += "Gravity is <A href='?src=\ref[src];gravity=1'><font color=blue>(OFF)</font></A><BR>"
user << browse(dat, "window=computer;size=400x500")
onclose(user, "computer")
return
data["gravity"] = null
ui = nanomanager.try_update_ui(user, src, ui_key, ui, data, force_open)
if (!ui)
ui = new(user, src, ui_key, "holodeck.tmpl", src.name, 400, 550)
ui.set_initial_data(data)
ui.open()
ui.set_auto_update(20)
/obj/machinery/computer/HolodeckControl/Topic(href, href_list)
if(..())
@@ -97,6 +95,7 @@
var/prog = href_list["program"]
if(prog in holodeck_programs)
loadProgram(holodeck_programs[prog])
current_program = href_list["program"]
else if(href_list["AIoverride"])
if(!issilicon(usr))
@@ -118,8 +117,8 @@
toggleGravity(linkedholodeck)
src.add_fingerprint(usr)
src.updateUsrDialog()
return
nanomanager.update_uis(src)
/obj/machinery/computer/HolodeckControl/emag_act(var/remaining_charges, var/mob/user as mob)
playsound(src.loc, 'sound/effects/sparks4.ogg', 75, 1)
@@ -132,7 +131,6 @@
user << "Warning. Automatic shutoff and derezing protocols have been corrupted. Please call [company_name] maintenance and do not use the simulator."
log_game("[key_name(usr)] emagged the Holodeck Control Computer")
return 1
src.updateUsrDialog()
return
/obj/machinery/computer/HolodeckControl/proc/update_projections()

View File

@@ -73,7 +73,7 @@
set_trait(TRAIT_PRODUCTION,5)
set_trait(TRAIT_YIELD,2)
set_trait(TRAIT_POTENCY,10)
set_trait(TRAIT_PRODUCT_COLOUR,"c9fa16")
set_trait(TRAIT_PRODUCT_COLOUR,"#c9fa16")
set_trait(TRAIT_WATER_CONSUMPTION, 3)
set_trait(TRAIT_NUTRIENT_CONSUMPTION, 0.25)

View File

@@ -450,7 +450,7 @@ var/list/mining_overlay_cache = list()
if(prob(50))
M.adjustBruteLoss(5)
else
flick("flash",M.flash)
M.flash_eyes()
if(prob(50))
M.Stun(5)
M.apply_effect(25, IRRADIATE)

View File

@@ -66,9 +66,6 @@
layer = MOB_LAYER
if(blind && client)
blind.layer = 0
sight |= SEE_TURFS|SEE_MOBS|SEE_OBJS
see_in_dark = 8
see_invisible = SEE_INVISIBLE_LEVEL_TWO

View File

@@ -114,6 +114,11 @@ var/list/holder_mob_icon_cache = list()
if(!holder_type || buckled || pinned.len)
return
if(self_grab)
if(src.incapacitated()) return
else
if(grabber.incapacitated()) return
var/obj/item/weapon/holder/H = new holder_type(get_turf(src))
H.held_mob = src
src.forceMove(H)

View File

@@ -1,7 +1,7 @@
/mob/living/carbon/alien/ex_act(severity)
if(!blinded)
flick("flash", flash)
flash_eyes()
var/b_loss = null
var/f_loss = null

View File

@@ -124,21 +124,16 @@
if (client)
client.screen.Remove(global_hud.blurry,global_hud.druggy,global_hud.vimpaired)
if ((blind && stat != 2))
if ( stat != 2)
if ((blinded))
blind.layer = 18
overlay_fullscreen("blind", /obj/screen/fullscreen/blind)
else
blind.layer = 0
if (disabilities & NEARSIGHTED)
client.screen += global_hud.vimpaired
if (eye_blurry)
client.screen += global_hud.blurry
if (druggy)
client.screen += global_hud.druggy
if (stat != 2)
if (machine)
if ( machine.check_eye(src) < 0)
clear_fullscreen("blind")
set_fullscreen(disabilities & NEARSIGHTED, "impaired", /obj/screen/fullscreen/impaired, 1)
set_fullscreen(eye_blurry, "blurry", /obj/screen/fullscreen/blurry)
set_fullscreen(druggy, "high", /obj/screen/fullscreen/high)
if(machine)
if(machine.check_eye(src) < 0)
reset_view(null)
else
if(client && !client.adminobs)

View File

@@ -21,6 +21,9 @@
/obj/item/organ/internal/brain/mechassist()
replace_self_with(/obj/item/organ/internal/mmi_holder)
/obj/item/organ/internal/brain/digitize()
replace_self_with(/obj/item/organ/internal/mmi_holder/robot)
/obj/item/organ/internal/brain/proc/replace_self_with(replace_path)
var/mob/living/carbon/human/tmp_owner = owner
qdel(src)

View File

@@ -208,22 +208,15 @@
if (client)
client.screen.Remove(global_hud.blurry,global_hud.druggy,global_hud.vimpaired)
if ((blind && stat != 2))
if ((blinded))
blind.layer = 18
else
blind.layer = 0
if (disabilities & NEARSIGHTED)
client.screen += global_hud.vimpaired
if (eye_blurry)
client.screen += global_hud.blurry
if (druggy)
client.screen += global_hud.druggy
if (stat != 2)
if ((blinded))
overlay_fullscreen("blind", /obj/screen/fullscreen/blind)
else
clear_fullscreen("blind")
set_fullscreen(disabilities & NEARSIGHTED, "impaired", /obj/screen/fullscreen/impaired, 1)
set_fullscreen(eye_blurry, "blurry", /obj/screen/fullscreen/blurry)
set_fullscreen(druggy, "high", /obj/screen/fullscreen/high)
if (machine)
if (!( machine.check_eye(src) ))
reset_view(null)
@@ -239,17 +232,4 @@
reset_view(null)
else
if(client && !client.adminobs)
reset_view(null)
/*/mob/living/carbon/brain/emp_act(severity)
if(!(container && istype(container, /obj/item/device/mmi)))
return
else
switch(severity)
if(1)
emp_damage += rand(20,30)
if(2)
emp_damage += rand(10,20)
if(3)
emp_damage += rand(0,10)
..()*/
reset_view(null)

View File

@@ -194,7 +194,7 @@
status += "hurts when touched"
if(org.status & ORGAN_DEAD)
status += "is bruised and necrotic"
if(!org.is_usable())
if(!org.is_usable() || org.is_dislocated())
status += "dangling uselessly"
if(status.len)
src.show_message("My [org.name] is <span class='warning'> [english_list(status)].</span>",1)
@@ -309,14 +309,19 @@
if(!item) return
var/throw_range = item.throw_range
if (istype(item, /obj/item/weapon/grab))
var/obj/item/weapon/grab/G = item
item = G.throw_held() //throw the person instead of the grab
if(ismob(item))
var/mob/M = item
//limit throw range by relative mob size
throw_range = round(M.throw_range * min(src.mob_size/M.mob_size, 1))
var/turf/start_T = get_turf(loc) //Get the start and target tile for the descriptors
var/turf/end_T = get_turf(target)
if(start_T && end_T)
var/mob/M = item
var/start_T_descriptor = "<font color='#6b5d00'>tile at [start_T.x], [start_T.y], [start_T.z] in area [get_area(start_T)]</font>"
var/end_T_descriptor = "<font color='#6b4400'>tile at [end_T.x], [end_T.y], [end_T.z] in area [get_area(end_T)]</font>"
@@ -324,31 +329,28 @@
usr.attack_log += text("\[[time_stamp()]\] <font color='red'>Has thrown [M.name] ([M.ckey]) from [start_T_descriptor] with the target [end_T_descriptor]</font>")
msg_admin_attack("[usr.name] ([usr.ckey]) has thrown [M.name] ([M.ckey]) from [start_T_descriptor] with the target [end_T_descriptor] (<A HREF='?_src_=holder;adminplayerobservecoodjump=1;X=[usr.x];Y=[usr.y];Z=[usr.z]'>JMP</a>)")
if(!item) return //Grab processing has a chance of returning null
src.remove_from_mob(item)
item.loc = src.loc
src.drop_from_inventory(item)
if(!item || !isturf(item.loc))
return
//actually throw it!
if (item)
src.visible_message("\red [src] has thrown [item].")
src.visible_message("<span class='warning'>[src] has thrown [item].</span>")
if(!src.lastarea)
src.lastarea = get_area(src.loc)
if((istype(src.loc, /turf/space)) || (src.lastarea.has_gravity == 0))
src.inertia_dir = get_dir(target, src)
step(src, inertia_dir)
if(!src.lastarea)
src.lastarea = get_area(src.loc)
if((istype(src.loc, /turf/space)) || (src.lastarea.has_gravity == 0))
src.inertia_dir = get_dir(target, src)
step(src, inertia_dir)
/*
if(istype(src.loc, /turf/space) || (src.flags & NOGRAV)) //they're in space, move em one space in the opposite direction
src.inertia_dir = get_dir(target, src)
step(src, inertia_dir)
if(istype(src.loc, /turf/space) || (src.flags & NOGRAV)) //they're in space, move em one space in the opposite direction
src.inertia_dir = get_dir(target, src)
step(src, inertia_dir)
*/
item.throw_at(target, item.throw_range, item.throw_speed, src)
item.throw_at(target, throw_range, item.throw_speed, src)
/mob/living/carbon/fire_act(datum/gas_mixture/air, exposed_temperature, exposed_volume)
..()

View File

@@ -84,7 +84,7 @@
/mob/living/carbon/human/ex_act(severity)
if(!blinded)
flick("flash", flash)
flash_eyes()
var/shielded = 0
var/b_loss = null
@@ -779,13 +779,6 @@
b_eyes = hex2num(copytext(new_eyes, 6, 8))
update_eyes()
var/new_tone = input("Please select skin tone level: 1-220 (1=albino, 35=caucasian, 150=black, 220='very' black)", "Character Generation", "[35-s_tone]") as text
if (!new_tone)
new_tone = 35
s_tone = max(min(round(text2num(new_tone)), 220), 1)
s_tone = -s_tone + 35
// hair
var/list/all_hairs = typesof(/datum/sprite_accessory/hair) - /datum/sprite_accessory/hair
var/list/hairs = list()
@@ -1336,8 +1329,8 @@
var/list/limbs = list()
for(var/limb in organs_by_name)
var/obj/item/organ/external/current_limb = organs_by_name[limb]
if(current_limb && current_limb.dislocated == 2)
limbs |= limb
if(current_limb && current_limb.dislocated > 0 && !current_limb.is_parent_dislocated()) //if the parent is also dislocated you will have to relocate that first
limbs |= current_limb
var/choice = input(usr,"Which joint do you wish to relocate?") as null|anything in limbs
if(!choice)

View File

@@ -9,7 +9,6 @@
return null
/mob/living/carbon/human/attack_hand(mob/living/carbon/M as mob)
var/mob/living/carbon/human/H = M
if(istype(H))
var/obj/item/organ/external/temp = H.organs_by_name["r_hand"]
@@ -18,7 +17,7 @@
if(!temp || !temp.is_usable())
H << "\red You can't use your hand."
return
break_cloak()
H.break_cloak()
..()
// Should this all be in Touch()?
@@ -331,7 +330,7 @@
if(!target_zone)
return 0
var/obj/item/organ/external/organ = get_organ(check_zone(target_zone))
if(!organ || organ.is_dislocated() || organ.dislocated == -1)
if(!organ || organ.dislocated > 0 || organ.dislocated == -1) //don't use is_dislocated() here, that checks parent
return 0
user.visible_message("<span class='warning'>[user] begins to dislocate [src]'s [organ.joint]!</span>")

View File

@@ -187,11 +187,13 @@ emp_act
// Handle striking to cripple.
if(user.a_intent == I_DISARM)
effective_force /= 2
if(..(I, user, effective_force, blocked, hit_zone))
attack_joint(affecting, I, blocked)
else
effective_force *= 0.66 //reduced effective force...
if(!..(I, user, effective_force, blocked, hit_zone))
return 0
//set the dislocate mult less than the effective force mult so that
//dislocating limbs on disarm is a bit easier than breaking limbs on harm
attack_joint(affecting, I, effective_force, 0.5, blocked) //...but can dislocate joints
else if(!..())
return 0
@@ -242,10 +244,16 @@ emp_act
return 1
/mob/living/carbon/human/proc/attack_joint(var/obj/item/organ/external/organ, var/obj/item/W, var/blocked)
/mob/living/carbon/human/proc/attack_joint(var/obj/item/organ/external/organ, var/obj/item/W, var/effective_force, var/dislocate_mult, var/blocked)
if(!organ || (organ.dislocated == 2) || (organ.dislocated == -1) || blocked >= 100)
return 0
if(prob(W.force * (100 - blocked)/100))
if(W.damtype != BRUTE)
return 0
//want the dislocation chance to be such that the limb is expected to dislocate after dealing a fraction of the damage needed to break the limb
var/dislocate_chance = effective_force/(dislocate_mult * organ.min_broken_damage * config.organ_health_multiplier)*100
if(prob(dislocate_chance * (100 - blocked)/100))
visible_message("<span class='danger'>[src]'s [organ.joint] [pick("gives way","caves in","crumbles","collapses")]!</span>")
organ.dislocate(1)
return 1

View File

@@ -45,6 +45,8 @@
var/citizenship = ""
var/personal_faction = ""
var/religion = ""
var/antag_faction = ""
var/antag_vis = ""
//Equipment slots
var/obj/item/wear_suit = null

View File

@@ -68,7 +68,7 @@
/mob/living/carbon/human/proc/handle_stance()
// Don't need to process any of this if they aren't standing anyways
// unless their stance is damaged, and we want to check if they should stay down
if (!stance_damage && (lying || resting) && (life_tick % 4) == 0)
if (!stance_damage && (lying || resting) && (life_tick % 4) != 0)
return
stance_damage = 0
@@ -80,7 +80,7 @@
var/limb_pain
for(var/limb_tag in list("l_leg","r_leg","l_foot","r_foot"))
var/obj/item/organ/external/E = organs_by_name[limb_tag]
if(!E || (E.status & (ORGAN_MUTATED|ORGAN_DEAD)) || E.is_stump()) //should just be !E.is_usable() here but dislocation screws that up.
if(!E || !E.is_usable())
stance_damage += 2 // let it fail even if just foot&leg
else if (E.is_malfunctioning())
//malfunctioning only happens intermittently so treat it as a missing limb when it procs
@@ -93,7 +93,7 @@
spark_system.start()
spawn(10)
qdel(spark_system)
else if (E.is_broken() || !E.is_usable())
else if (E.is_broken())
stance_damage += 1
else if (E.is_dislocated())
stance_damage += 0.5

View File

@@ -32,7 +32,6 @@
var/temperature_alert = 0
var/in_stasis = 0
var/heartbeat = 0
var/global/list/overlays_cache = null
/mob/living/carbon/human/Life()
set invisibility = 0
@@ -619,11 +618,11 @@
if(!istype(loc, /obj/machinery/atmospherics/unary/cryo_cell))
var/burn_dam = 0
switch(bodytemperature)
if(-INFINITY to species.cold_level_3)
if(species.cold_level_1 to species.cold_level_2)
burn_dam = COLD_DAMAGE_LEVEL_1
if(species.cold_level_3 to species.cold_level_2)
if(species.cold_level_2 to species.cold_level_3)
burn_dam = COLD_DAMAGE_LEVEL_2
if(species.cold_level_2 to species.cold_level_1)
if(species.cold_level_3 to -INFINITY)
burn_dam = COLD_DAMAGE_LEVEL_3
take_overall_damage(burn=burn_dam, used_weapon = "Low Body Temperature")
fire_alert = max(fire_alert, 1)
@@ -847,7 +846,10 @@
if(!isSynthetic() && (species.flags & IS_PLANT) && (!light_organ || light_organ.is_broken()))
if(nutrition < 200)
take_overall_damage(2,0)
traumatic_shock++
//traumatic_shock is updated every tick, incrementing that is pointless - shock_stage is the counter.
//Not that it matters much for diona, who have NO_PAIN.
shock_stage++
// TODO: stomach and bloodstream organ.
if(!isSynthetic())
@@ -1011,33 +1013,6 @@
return 1
/mob/living/carbon/human/handle_regular_hud_updates()
if(!overlays_cache)
overlays_cache = list()
overlays_cache.len = 23
overlays_cache[1] = image('icons/mob/screen1_full.dmi', "icon_state" = "passage1")
overlays_cache[2] = image('icons/mob/screen1_full.dmi', "icon_state" = "passage2")
overlays_cache[3] = image('icons/mob/screen1_full.dmi', "icon_state" = "passage3")
overlays_cache[4] = image('icons/mob/screen1_full.dmi', "icon_state" = "passage4")
overlays_cache[5] = image('icons/mob/screen1_full.dmi', "icon_state" = "passage5")
overlays_cache[6] = image('icons/mob/screen1_full.dmi', "icon_state" = "passage6")
overlays_cache[7] = image('icons/mob/screen1_full.dmi', "icon_state" = "passage7")
overlays_cache[8] = image('icons/mob/screen1_full.dmi', "icon_state" = "passage8")
overlays_cache[9] = image('icons/mob/screen1_full.dmi', "icon_state" = "passage9")
overlays_cache[10] = image('icons/mob/screen1_full.dmi', "icon_state" = "passage10")
overlays_cache[11] = image('icons/mob/screen1_full.dmi', "icon_state" = "oxydamageoverlay1")
overlays_cache[12] = image('icons/mob/screen1_full.dmi', "icon_state" = "oxydamageoverlay2")
overlays_cache[13] = image('icons/mob/screen1_full.dmi', "icon_state" = "oxydamageoverlay3")
overlays_cache[14] = image('icons/mob/screen1_full.dmi', "icon_state" = "oxydamageoverlay4")
overlays_cache[15] = image('icons/mob/screen1_full.dmi', "icon_state" = "oxydamageoverlay5")
overlays_cache[16] = image('icons/mob/screen1_full.dmi', "icon_state" = "oxydamageoverlay6")
overlays_cache[17] = image('icons/mob/screen1_full.dmi', "icon_state" = "oxydamageoverlay7")
overlays_cache[18] = image('icons/mob/screen1_full.dmi', "icon_state" = "brutedamageoverlay1")
overlays_cache[19] = image('icons/mob/screen1_full.dmi', "icon_state" = "brutedamageoverlay2")
overlays_cache[20] = image('icons/mob/screen1_full.dmi', "icon_state" = "brutedamageoverlay3")
overlays_cache[21] = image('icons/mob/screen1_full.dmi', "icon_state" = "brutedamageoverlay4")
overlays_cache[22] = image('icons/mob/screen1_full.dmi', "icon_state" = "brutedamageoverlay5")
overlays_cache[23] = image('icons/mob/screen1_full.dmi', "icon_state" = "brutedamageoverlay6")
if(hud_updateflag) // update our mob's hud overlays, AKA what others see flaoting above our head
handle_hud_list()
@@ -1056,75 +1031,53 @@
var/obj/machinery/camera/cam = client.eye
client.screen |= cam.client_huds
if(damageoverlay.overlays)
damageoverlay.overlays = list()
if(stat == UNCONSCIOUS)
if(stat == UNCONSCIOUS && health <= 0)
//Critical damage passage overlay
if(health <= 0)
var/image/I
switch(health)
if(-20 to -10)
I = overlays_cache[1]
if(-30 to -20)
I = overlays_cache[2]
if(-40 to -30)
I = overlays_cache[3]
if(-50 to -40)
I = overlays_cache[4]
if(-60 to -50)
I = overlays_cache[5]
if(-70 to -60)
I = overlays_cache[6]
if(-80 to -70)
I = overlays_cache[7]
if(-90 to -80)
I = overlays_cache[8]
if(-95 to -90)
I = overlays_cache[9]
if(-INFINITY to -95)
I = overlays_cache[10]
damageoverlay.overlays += I
var/severity = 0
switch(health)
if(-20 to -10) severity = 1
if(-30 to -20) severity = 2
if(-40 to -30) severity = 3
if(-50 to -40) severity = 4
if(-60 to -50) severity = 5
if(-70 to -60) severity = 6
if(-80 to -70) severity = 7
if(-90 to -80) severity = 8
if(-95 to -90) severity = 9
if(-INFINITY to -95) severity = 10
overlay_fullscreen("crit", /obj/screen/fullscreen/crit, severity)
else
clear_fullscreen("crit")
//Oxygen damage overlay
if(oxyloss)
var/image/I
var/severity = 0
switch(oxyloss)
if(10 to 20)
I = overlays_cache[11]
if(20 to 25)
I = overlays_cache[12]
if(25 to 30)
I = overlays_cache[13]
if(30 to 35)
I = overlays_cache[14]
if(35 to 40)
I = overlays_cache[15]
if(40 to 45)
I = overlays_cache[16]
if(45 to INFINITY)
I = overlays_cache[17]
damageoverlay.overlays += I
if(10 to 20) severity = 1
if(20 to 25) severity = 2
if(25 to 30) severity = 3
if(30 to 35) severity = 4
if(35 to 40) severity = 5
if(40 to 45) severity = 6
if(45 to INFINITY) severity = 7
overlay_fullscreen("oxy", /obj/screen/fullscreen/oxy, severity)
else
clear_fullscreen("oxy")
//Fire and Brute damage overlay (BSSR)
var/hurtdamage = src.getBruteLoss() + src.getFireLoss() + damageoverlaytemp
damageoverlaytemp = 0 // We do this so we can detect if someone hits us or not.
if(hurtdamage)
var/image/I
var/severity = 0
switch(hurtdamage)
if(10 to 25)
I = overlays_cache[18]
if(25 to 40)
I = overlays_cache[19]
if(40 to 55)
I = overlays_cache[20]
if(55 to 70)
I = overlays_cache[21]
if(70 to 85)
I = overlays_cache[22]
if(85 to INFINITY)
I = overlays_cache[23]
damageoverlay.overlays += I
if(10 to 25) severity = 1
if(25 to 40) severity = 2
if(40 to 55) severity = 3
if(55 to 70) severity = 4
if(70 to 85) severity = 5
if(85 to INFINITY) severity = 6
overlay_fullscreen("brute", /obj/screen/fullscreen/brute, severity)
else
clear_fullscreen("brute")
if( stat == DEAD )
sight |= SEE_TURFS|SEE_MOBS|SEE_OBJS|SEE_SELF
@@ -1268,20 +1221,20 @@
bodytemp.icon_state = "temp-1"
else
bodytemp.icon_state = "temp0"
if(blind)
if(blinded) blind.layer = 18
else blind.layer = 0
if(blinded) overlay_fullscreen("blind", /obj/screen/fullscreen/blind)
else clear_fullscreens()
if(disabilities & NEARSIGHTED) //this looks meh but saves a lot of memory by not requiring to add var/prescription
if(glasses) //to every /obj/item
var/obj/item/clothing/glasses/G = glasses
if(!G.prescription)
client.screen += global_hud.vimpaired
set_fullscreen(disabilities & NEARSIGHTED, "impaired", /obj/screen/fullscreen/impaired, 1)
else
client.screen += global_hud.vimpaired
set_fullscreen(disabilities & NEARSIGHTED, "impaired", /obj/screen/fullscreen/impaired, 1)
if(eye_blurry) client.screen += global_hud.blurry
if(druggy) client.screen += global_hud.druggy
set_fullscreen(eye_blurry, "blurry", /obj/screen/fullscreen/blurry)
set_fullscreen(druggy, "high", /obj/screen/fullscreen/high)
if(config.welder_vision)
var/found_welder
@@ -1684,4 +1637,4 @@
..()
#undef HUMAN_MAX_OXYLOSS
#undef HUMAN_CRIT_MAX_OXYLOSS
#undef HUMAN_CRIT_MAX_OXYLOSS

View File

@@ -190,6 +190,7 @@
/datum/species/proc/create_organs(var/mob/living/carbon/human/H) //Handles creation of mob organs.
H.mob_size = mob_size
for(var/obj/item/organ/organ in H.contents)
if((organ in H.organs) || (organ in H.internal_organs))
qdel(organ)
@@ -249,7 +250,6 @@
H.mob_swap_flags = swap_flags
H.mob_push_flags = push_flags
H.pass_flags = pass_flags
H.mob_size = mob_size
/datum/species/proc/handle_death(var/mob/living/carbon/human/H) //Handles any species-specific death events (such as dionaea nymph spawns).
return

View File

@@ -23,8 +23,10 @@
if(istype(src,/mob/living/carbon/human))
var/mob/living/carbon/human/M = src
for(var/obj/item/organ/external/organ in M.organs)
if(organ && (organ.is_broken() || organ.open))
if(organ.is_broken() || organ.open)
src.traumatic_shock += 30
else if(organ.is_dislocated())
src.traumatic_shock += 15
if(src.traumatic_shock < 0)
src.traumatic_shock = 0

View File

@@ -0,0 +1,3 @@
/mob/living/death()
clear_fullscreens()
. = ..()

View File

@@ -467,6 +467,7 @@ default behaviour is:
BITSET(hud_updateflag, LIFE_HUD)
failed_last_breath = 0 //So mobs that died of oxyloss don't revive and have perpetual out of breath.
reload_fullscreen()
return
@@ -637,26 +638,9 @@ default behaviour is:
/mob/living/proc/resist_grab()
var/resisting = 0
for(var/obj/O in requests)
requests.Remove(O)
qdel(O)
resisting++
for(var/obj/item/weapon/grab/G in grabbed_by)
resisting++
switch(G.state)
if(GRAB_PASSIVE)
qdel(G)
if(GRAB_AGGRESSIVE)
//Not standing up makes it much harder to break, so it is easier to cuff someone who is down without forcing them into unconsciousness.
//Otherwise, it's the same chance of breaking the grab as disarm.
if(incapacitated(INCAPACITATION_KNOCKDOWN)? prob(15) : prob(60))
visible_message("<span class='warning'>[src] has broken free of [G.assailant]'s grip!</span>")
qdel(G)
if(GRAB_NECK)
//If the you move when grabbing someone then it's easier for them to break free. Same if the affected mob is immune to stun.
if (((world.time - G.assailant.l_move_time < 30 || !stunned) && prob(15)) || prob(3))
visible_message("<span class='warning'>[src] has broken free of [G.assailant]'s headlock!</span>")
qdel(G)
G.handle_resist()
if(resisting)
visible_message("<span class='danger'>[src] resists!</span>")
@@ -675,6 +659,15 @@ default behaviour is:
return 0
return ..()
//called when the mob receives a bright flash
/mob/living/flash_eyes(intensity = FLASH_PROTECTION_MODERATE, override_blindness_check = FALSE, affect_silicon = FALSE, visual = FALSE, type = /obj/screen/fullscreen/flash)
if(override_blindness_check || !(disabilities & BLIND))
overlay_fullscreen("flash", type)
spawn(25)
if(src)
clear_fullscreen("flash", 25)
return 1
/mob/living/proc/handle_ventcrawl(var/obj/machinery/atmospherics/unary/vent_pump/vent_found = null, var/ignore_items = 0) // -- TLE -- Merged by Carn
if(stat)
src << "You must be conscious to do this!"
@@ -682,7 +675,6 @@ default behaviour is:
if(lying)
src << "You can't vent crawl while you're stunned!"
return
var/special_fail_msg = cannot_use_vents()
if(special_fail_msg)
src << "<span class='warning'>[special_fail_msg]</span>"

View File

@@ -56,18 +56,18 @@
if (aiRestorePowerRoutine==2)
src << "Alert cancelled. Power has been restored without our assistance."
aiRestorePowerRoutine = 0
src.blind.layer = 0
clear_fullscreen("blind")
updateicon()
return
else if (aiRestorePowerRoutine==3)
src << "Alert cancelled. Power has been restored."
aiRestorePowerRoutine = 0
src.blind.layer = 0
clear_fullscreen("blind")
updateicon()
return
else if (APU_power)
aiRestorePowerRoutine = 0
src.blind.layer = 0
clear_fullscreen("blind")
updateicon()
return
else
@@ -79,9 +79,7 @@
//Blind the AI
updateicon()
src.blind.screen_loc = ui_entire_screen
if (src.blind.layer!=18)
src.blind.layer = 18
overlay_fullscreen("blind", /obj/screen/fullscreen/blind)
src.sight = src.sight&~SEE_TURFS
src.sight = src.sight&~SEE_MOBS
src.sight = src.sight&~SEE_OBJS
@@ -99,7 +97,7 @@
if (!istype(T, /turf/space))
src << "Alert cancelled. Power has been restored without our assistance."
aiRestorePowerRoutine = 0
src.blind.layer = 0
clear_fullscreen("blind")
return
src << "Fault confirmed: missing external power. Shutting down main control system to save power."
sleep(20)
@@ -129,7 +127,7 @@
if (!istype(T, /turf/space))
src << "Alert cancelled. Power has been restored without our assistance."
aiRestorePowerRoutine = 0
src.blind.layer = 0 //This, too, is a fix to issue 603
clear_fullscreen("blind") //This, too, is a fix to issue 603
return
switch(PRP)
if (1) src << "APC located. Optimizing route to APC to avoid needless power waste."

View File

@@ -2,19 +2,6 @@
..()
for(var/obj/effect/rune/rune in rune_list)
client.images += rune.blood_image
regenerate_icons()
flash = new /obj/screen()
flash.icon_state = "blank"
flash.name = "flash"
flash.screen_loc = ui_entire_screen
flash.layer = 17
blind = new /obj/screen()
blind.icon_state = "black"
blind.name = " "
blind.screen_loc = ui_entire_screen
blind.layer = 0
client.screen.Add( blind, flash )
if(stat != DEAD)
for(var/obj/machinery/ai_status_display/O in machines) //change status
O.mode = 1

View File

@@ -240,7 +240,7 @@ var/list/mob_hat_cache = list()
//Drones killed by damage will gib.
/mob/living/silicon/robot/drone/handle_regular_status_updates()
var/turf/T = get_turf(src)
if((!T || health <= -35 || (master_fabricator && T.z != master_fabricator.z)) && src.stat != DEAD)
if(!T || health <= -35 )
timeofdeath = world.time
death() //Possibly redundant, having trouble making death() cooperate.
gib()

View File

@@ -275,29 +275,21 @@
// if (src.oxygen) src.oxygen.icon_state = "oxy[src.oxygen_alert ? 1 : 0]"
// if (src.fire) src.fire.icon_state = "fire[src.fire_alert ? 1 : 0]"
client.screen.Remove(global_hud.blurry,global_hud.druggy,global_hud.vimpaired)
if ((src.blind && src.stat != 2))
if(src.blinded)
src.blind.layer = 18
if(stat != 2)
if(blinded)
overlay_fullscreen("blind", /obj/screen/fullscreen/blind)
else
src.blind.layer = 0
if (src.disabilities & NEARSIGHTED)
src.client.screen += global_hud.vimpaired
clear_fullscreen("blind")
set_fullscreen(disabilities & NEARSIGHTED, "impaired", /obj/screen/fullscreen/impaired, 1)
set_fullscreen(eye_blurry, "blurry", /obj/screen/fullscreen/blurry)
set_fullscreen(druggy, "high", /obj/screen/fullscreen/high)
if (src.eye_blurry)
src.client.screen += global_hud.blurry
if (src.druggy)
src.client.screen += global_hud.druggy
if (src.stat != 2)
if (src.machine)
if (src.machine.check_eye(src) < 0)
src.reset_view(null)
else
if(client && !client.adminobs)
reset_view(null)
if (src.machine)
if (src.machine.check_eye(src) < 0)
src.reset_view(null)
else
if(client && !client.adminobs)
reset_view(null)
return 1

View File

@@ -684,7 +684,7 @@ var/global/list/robot_modules = list(
hide_on_manifest = 1
sprites = list("Combat Android" = "droid-combat")
/obj/item/weapon/robot_module/combat/New()
/obj/item/weapon/robot_module/security/combat/New()
src.modules += new /obj/item/device/flash(src)
src.modules += new /obj/item/borg/sight/thermal(src)
src.modules += new /obj/item/weapon/gun/energy/laser/mounted(src)

View File

@@ -67,7 +67,7 @@
if(2)
src.take_organ_damage(0,10,emp=1)
confused = (min(confused + 2, 30))
flick("noise", src.flash)
flash_eyes(affect_silicon = 1)
src << "<span class='danger'><B>*BZZZT*</B></span>"
src << "<span class='danger'>Warning: Electromagnetic pulse detected.</span>"
..()
@@ -264,7 +264,7 @@
/mob/living/silicon/ex_act(severity)
if(!blinded)
flick("flash", flash)
flash_eyes()
switch(severity)
if(1.0)
@@ -361,3 +361,7 @@
..()
if(cameraFollow)
cameraFollow = null
/mob/living/silicon/flash_eyes(intensity = FLASH_PROTECTION_MODERATE, override_blindness_check = FALSE, affect_silicon = FALSE, visual = FALSE, type = /obj/screen/fullscreen/flash)
if(affect_silicon)
return ..()

View File

@@ -381,7 +381,7 @@
/mob/living/simple_animal/ex_act(severity)
if(!blinded)
flick("flash", flash)
flash_eyes()
switch (severity)
if (1.0)
adjustBruteLoss(500)

View File

@@ -45,6 +45,7 @@
else
client.eye = src
client.perspective = MOB_PERSPECTIVE
reload_fullscreen() // Reload any fullscreen overlays this mob has.
add_click_catcher()
//set macro to normal incase it was overriden (like cyborg currently does)
winset(src, null, "mainwindow.macro=macro hotkey_toggle.is-checked=false input.focus=true input.background-color=#D3B5B5")

View File

@@ -4,6 +4,7 @@
living_mob_list -= src
unset_machine()
qdel(hud_used)
clear_fullscreen()
if(client)
for(var/obj/screen/movable/spell_master/spell_master in spell_masters)
qdel(spell_master)
@@ -17,8 +18,6 @@
..()
/mob/proc/remove_screen_obj_references()
flash = null
blind = null
hands = null
pullin = null
purged = null
@@ -33,7 +32,6 @@
throw_icon = null
nutrition_icon = null
pressure = null
damageoverlay = null
pain = null
item_use_icon = null
gun_move_icon = null
@@ -361,8 +359,8 @@
var/deathtimeseconds = round((deathtime - deathtimeminutes * 600) / 10,1)
usr << "You have been dead for[pluralcheck] [deathtimeseconds] seconds."
if (deathtime < 600)
usr << "You must wait 1 minute to respawn!"
if (deathtime < (600)) //VOREStation Edit
usr << "You must wait 60 seconds to respawn!" //VOREStation Edit
return
else
usr << "You can respawn now, enjoy your new life!"

View File

@@ -10,8 +10,6 @@
//Not in use yet
var/obj/effect/organstructure/organStructure = null
var/obj/screen/flash = null
var/obj/screen/blind = null
var/obj/screen/hands = null
var/obj/screen/pullin = null
var/obj/screen/purged = null
@@ -26,7 +24,6 @@
var/obj/screen/throw_icon = null
var/obj/screen/nutrition_icon = null
var/obj/screen/pressure = null
var/obj/screen/damageoverlay = null
var/obj/screen/pain = null
var/obj/screen/gun/item/item_use_icon = null
var/obj/screen/gun/radio/radio_use_icon = null
@@ -124,7 +121,6 @@
var/datum/hud/hud_used = null
var/list/grabbed_by = list( )
var/list/requests = list( )
var/list/mapobjs = list()

View File

@@ -3,10 +3,15 @@
///Process_Grab()
///Called by client/Move()
///Checks to see if you are grabbing anything and if moving will affect your grab.
///Checks to see if you are grabbing or being grabbed by anything and if moving will affect your grab.
/client/proc/Process_Grab()
if(istype(mob, /mob/living))
//if we are being grabbed
if(isliving(mob))
var/mob/living/L = mob
if(!L.canmove && L.grabbed_by.len)
L.resist() //shortcut for resisting grabs
//if we are grabbing someone
for(var/obj/item/weapon/grab/G in list(L.l_hand, L.r_hand))
G.reset_kill_state() //no wandering across the station/asteroid while choking someone
@@ -131,7 +136,7 @@
handle_eye_mouth_covering(affecting, assailant, assailant.zone_sel.selecting)
if(force_down)
if(affecting.loc != assailant.loc)
if(affecting.loc != assailant.loc || size_difference(affecting, assailant) > 0)
force_down = 0
else
affecting.Weaken(2)
@@ -232,7 +237,7 @@
if(state < GRAB_AGGRESSIVE)
if(!allow_upgrade)
return
if(!affecting.lying)
if(!affecting.lying || size_difference(affecting, assailant) > 0)
assailant.visible_message("<span class='warning'>[assailant] has grabbed [affecting] aggressively (now hands)!</span>")
else
assailant.visible_message("<span class='warning'>[assailant] pins [affecting] down to the ground (now hands)!</span>")
@@ -335,6 +340,40 @@
hud.icon_state = "kill"
state = GRAB_NECK
/obj/item/weapon/grab/proc/handle_resist()
var/grab_name
var/break_strength = 1
var/list/break_chance_table = list(100)
switch(state)
//if(GRAB_PASSIVE)
if(GRAB_AGGRESSIVE)
grab_name = "grip"
//Being knocked down makes it harder to break a grab, so it is easier to cuff someone who is down without forcing them into unconsciousness.
if(!affecting.incapacitated(INCAPACITATION_KNOCKDOWN))
break_strength++
break_chance_table = list(15, 60, 100)
if(GRAB_NECK)
grab_name = "headlock"
//If the you move when grabbing someone then it's easier for them to break free. Same if the affected mob is immune to stun.
if(world.time - assailant.l_move_time < 30 || !affecting.stunned)
break_strength++
break_chance_table = list(3, 18, 45, 100)
//It's easier to break out of a grab by a smaller mob
break_strength += max(size_difference(affecting, assailant), 0)
var/break_chance = break_chance_table[Clamp(break_strength, 1, break_chance_table.len)]
if(prob(break_chance))
if(grab_name)
affecting.visible_message("<span class='warning'>[affecting] has broken free of [assailant]'s [grab_name]!</span>")
qdel(src)
//returns the number of size categories between affecting and assailant, rounded. Positive means A is larger than B
/obj/item/weapon/grab/proc/size_difference(mob/A, mob/B)
return mob_size_difference(A.mob_size, B.mob_size)
/obj/item/weapon/grab
var/destroying = 0

View File

@@ -51,10 +51,16 @@
return
attacker.visible_message("<span class='danger'>[attacker] [pick("bent", "twisted")] [target]'s [organ.name] into a jointlock!</span>")
if(target.species.flags & NO_PAIN)
return
var/armor = target.run_armor_check(target, "melee")
if(armor < 60)
target << "<span class='danger'>You feel extreme pain!</span>"
affecting.adjustHalLoss(Clamp(0, 60-affecting.halloss, 30)) //up to 60 halloss
var/max_halloss = round(target.species.total_health * 0.8) //up to 80% of passing out
affecting.adjustHalLoss(Clamp(0, max_halloss - affecting.halloss, 30))
/obj/item/weapon/grab/proc/attack_eye(mob/living/carbon/human/target, mob/living/carbon/human/attacker)
if(!istype(attacker))
@@ -125,6 +131,10 @@
return
if(force_down)
attacker << "<span class='warning'>You are already pinning [target] to the ground.</span>"
return
if(size_difference(affecting, assailant) > 0)
attacker << "<span class='warning'>You are too small to do that!</span>"
return
attacker.visible_message("<span class='danger'>[attacker] starts forcing [target] to the ground!</span>")
if(do_after(attacker, 20) && target)

View File

@@ -5,6 +5,9 @@
return L.mob_size <= MOB_SMALL
return 0
//returns the number of size categories between two mob_sizes, rounded. Positive means A is larger than B
/proc/mob_size_difference(var/mob_size_A, var/mob_size_B)
return round(log(2, mob_size_A/mob_size_B), 1)
/proc/istiny(A)
if(A && istype(A, /mob/living))
@@ -570,4 +573,7 @@ var/list/global/organ_rel_size = list(
"r_hand" = 10,
"l_foot" = 10,
"r_foot" = 10,
)
)
/mob/proc/flash_eyes(intensity = FLASH_PROTECTION_MODERATE, override_blindness_check = FALSE, affect_silicon = FALSE, visual = FALSE, type = /obj/screen/fullscreen/flash)
return

View File

@@ -50,6 +50,7 @@ var/list/organ_cache = list()
max_damage = min_broken_damage * 2
if(istype(holder))
src.owner = holder
src.w_class = max(src.w_class + mob_size_difference(holder.mob_size, MOB_MEDIUM), 1) //smaller mobs have smaller organs.
species = all_species["Human"]
if(holder.dna)
dna = holder.dna.Clone()
@@ -258,6 +259,9 @@ var/list/organ_cache = list()
min_bruised_damage = 15
min_broken_damage = 35
/obj/item/organ/proc/digitize() //Used to make the circuit-brain. On this level in the event more circuit-organs are added/tweaks are wanted.
robotize()
/obj/item/organ/emp_act(severity)
if(!(robotic >= ORGAN_ROBOT))
return

View File

@@ -60,7 +60,7 @@
var/cannot_gib // Impossible to gib, distinct from amputation.
var/joint = "joint" // Descriptive string used in dislocation.
var/amputation_point // Descriptive string used in amputation.
var/dislocated = 0 // If you target a joint, you can dislocate the limb, causing temporary damage to the organ.
var/dislocated = 0 // If you target a joint, you can dislocate the limb, impairing it's usefulness and causing pain
var/encased // Needs to be opened with a saw to access the organs.
// Surgery vars.
@@ -156,32 +156,38 @@
/obj/item/organ/external/proc/is_dislocated()
if(dislocated > 0)
return 1
if(parent)
return parent.is_dislocated()
if(is_parent_dislocated())
return 1//if any parent is dislocated, we are considered dislocated as well
return 0
/obj/item/organ/external/proc/dislocate(var/primary)
if(dislocated != -1)
if(primary)
dislocated = 2
else
dislocated = 1
owner.verbs |= /mob/living/carbon/human/proc/undislocate
if(children && children.len)
for(var/obj/item/organ/external/child in children)
child.dislocate()
/obj/item/organ/external/proc/is_parent_dislocated()
var/obj/item/organ/external/O = parent
while(O && O.dislocated != -1)
if(O.dislocated == 1)
return 1
O = O.parent
return 0
/obj/item/organ/external/proc/dislocate()
if(dislocated == -1)
return
dislocated = 1
if(owner)
owner.verbs |= /mob/living/carbon/human/proc/undislocate
/obj/item/organ/external/proc/undislocate()
if(dislocated != -1)
dislocated = 0
if(children && children.len)
for(var/obj/item/organ/external/child in children)
if(child.dislocated == 1)
child.undislocate()
if(dislocated == -1)
return
dislocated = 0
if(owner)
owner.shock_stage += 20
//check to see if we still need the verb
for(var/obj/item/organ/external/limb in owner.organs)
if(limb.dislocated == 2)
if(limb.dislocated == 1)
return
owner.verbs -= /mob/living/carbon/human/proc/undislocate
@@ -1085,7 +1091,7 @@ Note that amputating the affected organ does in fact remove the infection from t
return 0
/obj/item/organ/external/proc/is_usable()
return !is_dislocated() && !(status & (ORGAN_MUTATED|ORGAN_DEAD))
return !(status & (ORGAN_MUTATED|ORGAN_DEAD))
/obj/item/organ/external/proc/is_malfunctioning()
return ((robotic >= ORGAN_ROBOT) && (brute_dam + burn_dam) >= 10 && prob(brute_dam + burn_dam))

View File

@@ -43,6 +43,11 @@ var/const/standard_monitor_styles = "blank=ipc_blank;\
var/list/monitor_styles //If empty, the model of limbs offers a head compatible with monitors.
var/parts = BP_ALL //Defines what parts said brand can replace on a body.
/datum/robolimb/nanotrasen
company = "NanoTrasen"
desc = "A simple but efficient robotic limb, created by NanoTrasen."
icon = 'icons/mob/human_races/cyberlimbs/nanotrasen/nanotrasen_main.dmi'
/datum/robolimb/bishop
company = "Bishop"
desc = "This limb has a white polymer casing with blue holo-displays."
@@ -191,6 +196,9 @@ var/const/standard_monitor_styles = "blank=ipc_blank;\
zenghu
company = "Zeng-Hu"
nanotrasen
company = "NanoTrasen"
/obj/item/weapon/disk/limb/New(var/newloc)
..()
if(company)

View File

@@ -206,4 +206,5 @@
amputation_point = "branch"
joint = "structural ligament"
dislocated = -1
vital = 0
vital = 0
slot_flags = SLOT_BELT

View File

@@ -85,9 +85,18 @@
/obj/item/organ/internal/mmi_holder/posibrain
name = "positronic brain interface"
brain_type = /obj/item/device/mmi/digital/posibrain
/obj/item/organ/internal/mmi_holder/posibrain/update_from_mmi()
..()
stored_mmi.icon_state = "posibrain-occupied"
icon_state = stored_mmi.icon_state
/obj/item/organ/internal/mmi_holder/robot
name = "digital brain interface"
brain_type = /obj/item/device/mmi/digital/robot
/obj/item/organ/internal/mmi_holder/robot/update_from_mmi()
..()
stored_mmi.icon_state = "mainboard"
icon_state = stored_mmi.icon_state

View File

@@ -2,6 +2,8 @@
ORGAN DEFINES
****************************************************/
//Make sure that w_class is set as if the parent mob was medium sized! This is because w_class is adjusted automatically for mob_size in New()
/obj/item/organ/external/chest
name = "upper body"
organ_tag = BP_TORSO
@@ -148,6 +150,7 @@
organ_tag = BP_HEAD
icon_name = "head"
name = "head"
slot_flags = SLOT_BELT
max_damage = 75
min_broken_damage = 35
w_class = 3

View File

@@ -32,54 +32,37 @@ var/list/adminfaxes = list() //cache for faxes that have been sent to admins
/obj/machinery/photocopier/faxmachine/attack_hand(mob/user as mob)
user.set_machine(src)
var/dat = "Fax Machine<BR>"
ui_interact(user)
var/scan_name
/**
* Display the NanoUI window for the fax machine.
*
* See NanoUI documentation for details.
*/
/obj/machinery/photocopier/faxmachine/ui_interact(mob/user, ui_key = "main", var/datum/nanoui/ui = null, var/force_open = 1)
user.set_machine(src)
var/list/data = list()
if(scan)
scan_name = scan.name
data["scanName"] = scan.name
else
scan_name = "--------"
dat += "Confirm Identity: <a href='byond://?src=\ref[src];scan=1'>[scan_name]</a><br>"
if(authenticated)
dat += "<a href='byond://?src=\ref[src];logout=1'>{Log Out}</a>"
data["scanName"] = null
data["bossName"] = boss_name
data["authenticated"] = authenticated
data["copyItem"] = copyitem
if(copyitem)
data["copyItemName"] = copyitem.name
else
dat += "<a href='byond://?src=\ref[src];auth=1'>{Log In}</a>"
data["copyItemName"] = null
data["cooldown"] = sendcooldown
data["destination"] = destination
dat += "<hr>"
if(authenticated)
dat += "<b>Logged in to:</b> [boss_name] Quantum Entanglement Network<br><br>"
if(copyitem)
dat += "<a href='byond://?src=\ref[src];remove=1'>Remove Item</a><br><br>"
if(sendcooldown)
dat += "<b>Transmitter arrays realigning. Please stand by.</b><br>"
else
dat += "<a href='byond://?src=\ref[src];send=1'>Send</a><br>"
dat += "<b>Currently sending:</b> [copyitem.name]<br>"
dat += "<b>Sending to:</b> <a href='byond://?src=\ref[src];dept=1'>[destination]</a><br>"
else
if(sendcooldown)
dat += "Please insert paper to send via secure connection.<br><br>"
dat += "<b>Transmitter arrays realigning. Please stand by.</b><br>"
else
dat += "Please insert paper to send via secure connection.<br><br>"
else
dat += "Proper authentication is required to use this device.<br><br>"
if(copyitem)
dat += "<a href ='byond://?src=\ref[src];remove=1'>Remove Item</a><br>"
user << browse(dat, "window=copier")
onclose(user, "copier")
return
ui = nanomanager.try_update_ui(user, src, ui_key, ui, data, force_open)
if (!ui)
ui = new(user, src, ui_key, "fax.tmpl", src.name, 500, 500)
ui.set_initial_data(data)
ui.open()
ui.set_auto_update(10) //this machine is so unimportant let's not have it update that often.
/obj/machinery/photocopier/faxmachine/Topic(href, href_list)
if(href_list["send"])
@@ -99,7 +82,6 @@ var/list/adminfaxes = list() //cache for faxes that have been sent to admins
usr.put_in_hands(copyitem)
usr << "<span class='notice'>You take \the [copyitem] out of \the [src].</span>"
copyitem = null
updateUsrDialog()
if(href_list["scan"])
if (scan)
@@ -131,7 +113,7 @@ var/list/adminfaxes = list() //cache for faxes that have been sent to admins
if(href_list["logout"])
authenticated = 0
updateUsrDialog()
nanomanager.update_uis(src)
/obj/machinery/photocopier/faxmachine/proc/sendfax(var/destination)
if(stat & (BROKEN|NOPOWER))
@@ -158,7 +140,7 @@ var/list/adminfaxes = list() //cache for faxes that have been sent to admins
return 0 //You can't send faxes to "Unknown"
flick("faxreceive", src)
playsound(loc, "sound/items/polaroid1.ogg", 50, 1)
playsound(loc, "sound/effects/printer.ogg", 50, 1)
// give the sprite some time to flick
sleep(20)
@@ -216,3 +198,4 @@ var/list/adminfaxes = list() //cache for faxes that have been sent to admins
for(var/client/C in admins)
if(R_ADMIN & C.holder.rights)
C << msg
C << 'sound/effects/printer.ogg'

View File

@@ -30,24 +30,32 @@
/obj/machinery/photocopier/attack_hand(mob/user as mob)
user.set_machine(src)
var/dat = "Photocopier<BR><BR>"
if(copyitem)
dat += "<a href='byond://?src=\ref[src];remove=1'>Remove Item</a><BR>"
if(toner)
dat += "<a href='byond://?src=\ref[src];copy=1'>Copy</a><BR>"
dat += "Printing: [copies] copies."
dat += "<a href='byond://?src=\ref[src];min=1'>-</a> "
dat += "<a href='byond://?src=\ref[src];add=1'>+</a><BR><BR>"
else if(toner)
dat += "Please insert something to copy.<BR><BR>"
ui_interact(user)
/**
* Display the NanoUI window for the photocopier.
*
* See NanoUI documentation for details.
*/
/obj/machinery/photocopier/ui_interact(mob/user, ui_key = "main", var/datum/nanoui/ui = null, var/force_open = 1)
user.set_machine(src)
var/list/data = list()
data["copyItem"] = copyitem
data["toner"] = toner
data["copies"] = copies
data["maxCopies"] = maxcopies
if(istype(user,/mob/living/silicon))
dat += "<a href='byond://?src=\ref[src];aipic=1'>Print photo from database</a><BR><BR>"
dat += "Current toner level: [toner]"
if(!toner)
dat +="<BR>Please insert a new toner cartridge!"
user << browse(dat, "window=copier")
onclose(user, "copier")
return
data["isSilicon"] = 1
else
data["isSilicon"] = null
ui = nanomanager.try_update_ui(user, src, ui_key, ui, data, force_open)
if (!ui)
ui = new(user, src, ui_key, "photocopier.tmpl", src.name, 300, 250)
ui.set_initial_data(data)
ui.open()
ui.set_auto_update(10)
/obj/machinery/photocopier/Topic(href, href_list)
if(href_list["copy"])
@@ -72,22 +80,18 @@
break
use_power(active_power_usage)
updateUsrDialog()
else if(href_list["remove"])
if(copyitem)
copyitem.loc = usr.loc
usr.put_in_hands(copyitem)
usr << "<span class='notice'>You take \the [copyitem] out of \the [src].</span>"
copyitem = null
updateUsrDialog()
else if(href_list["min"])
if(copies > 1)
copies--
updateUsrDialog()
else if(href_list["add"])
if(copies < maxcopies)
copies++
updateUsrDialog()
else if(href_list["aipic"])
if(!istype(usr,/mob/living/silicon)) return
if(stat & (BROKEN|NOPOWER)) return
@@ -109,7 +113,8 @@
p.desc += " - Copied by [tempAI.name]"
toner -= 5
sleep(15)
updateUsrDialog()
nanomanager.update_uis(src)
/obj/machinery/photocopier/attackby(obj/item/O as obj, mob/user as mob)
if(istype(O, /obj/item/weapon/paper) || istype(O, /obj/item/weapon/photo) || istype(O, /obj/item/weapon/paper_bundle))
@@ -119,7 +124,6 @@
O.loc = src
user << "<span class='notice'>You insert \the [O] into \the [src].</span>"
flick(insert_anim, src)
updateUsrDialog()
else
user << "<span class='notice'>There is already something in \the [src].</span>"
else if(istype(O, /obj/item/device/toner))
@@ -129,7 +133,6 @@
var/obj/item/device/toner/T = O
toner += T.toner_amount
qdel(O)
updateUsrDialog()
else
user << "<span class='notice'>This cartridge is not yet ready for replacement! Use up the rest of the toner.</span>"
else if(istype(O, /obj/item/weapon/wrench))

View File

@@ -68,13 +68,14 @@ obj/item/weapon/gun/energy/retro
fire_sound = 'sound/weapons/lasercannonfire.ogg'
origin_tech = list(TECH_COMBAT = 4, TECH_MATERIAL = 3, TECH_POWER = 3)
slot_flags = SLOT_BELT|SLOT_BACK
projectile_type = /obj/item/projectile/beam/heavylaser
charge_cost = 400
max_shots = 6
fire_delay = 20
projectile_type = /obj/item/projectile/beam/heavylaser/cannon
max_shots = 1
fire_delay = 30
// requires_two_hands = 1
one_handed_penalty = 6 // The thing's heavy and huge.
accuracy = 2
accuracy = 3
charge_cost = 400
/obj/item/weapon/gun/energy/lasercannon/mounted
name = "mounted laser cannon"
@@ -83,6 +84,10 @@ obj/item/weapon/gun/energy/retro
recharge_time = 10
accuracy = 0 // Mounted cannons are just fine the way they are.
requires_two_hands = 0 // Not sure if two-handing gets checked for mounted weapons, but better safe than sorry.
projectile_type = /obj/item/projectile/beam/heavylaser
charge_cost = 400
max_shots = 6
fire_delay = 20
/obj/item/weapon/gun/energy/xray
name = "xray laser gun"

View File

@@ -10,15 +10,14 @@
slot_flags = SLOT_BACK
origin_tech = list(TECH_COMBAT = 8, TECH_MATERIAL = 2, TECH_ILLEGAL = 8)
caliber = "14.5mm"
recoil = 3 //extra kickback
recoil = 5 //extra kickback
fire_sound = 'sound/weapons/sniper.ogg' // extra boom
handle_casings = HOLD_CASINGS
load_method = SINGLE_CASING
max_shells = 1
ammo_type = /obj/item/ammo_casing/a145
//+2 accuracy over the LWAP because only one shot
accuracy = -1
scoped_accuracy = 2
accuracy = -5
scoped_accuracy = 5
var/bolt_open = 0
/obj/item/weapon/gun/projectile/heavysniper/update_icon()

View File

@@ -42,6 +42,10 @@
tracer_type = /obj/effect/projectile/laser_heavy/tracer
impact_type = /obj/effect/projectile/laser_heavy/impact
/obj/item/projectile/beam/heavylaser/cannon
damage = 90
armor_penetration = 100
/obj/item/projectile/beam/xray
name = "xray beam"
icon_state = "xray"

View File

@@ -23,7 +23,7 @@
//blind adjacent people
for (var/mob/living/carbon/M in viewers(T, flash_range))
if(M.eyecheck() < 1)
flick("e_flash", M.flash)
M.flash_eyes()
//snap pop
playsound(src, 'sound/effects/snap.ogg', 50, 1)
@@ -80,7 +80,8 @@
icon_state = "toxin"
damage = 5
damage_type = TOX
weaken = 5
agony = 120
check_armour = "energy"
/obj/item/projectile/energy/bolt

View File

@@ -2,7 +2,6 @@
#define LIQUID 2
#define GAS 3
#define BOTTLE_SPRITES list("bottle-1", "bottle-2", "bottle-3", "bottle-4") //list of available bottle sprites
#define REAGENTS_PER_SHEET 20
@@ -23,10 +22,11 @@
var/condi = 0
var/useramount = 15 // Last used amount
var/pillamount = 10
var/bottlesprite = "bottle-1" //yes, strings
var/bottlesprite = "1"
var/pillsprite = "1"
var/client/has_sprites = list()
var/max_pill_count = 20
var/tab = "home"
var/analyze_data[0]
flags = OPENCONTAINER
/obj/machinery/chem_master/New()
@@ -56,7 +56,6 @@
user.drop_item()
B.loc = src
user << "You add the beaker to the machine!"
src.updateUsrDialog()
icon_state = "mixer1"
else if(istype(B, /obj/item/weapon/storage/pill_bottle))
@@ -69,9 +68,74 @@
user.drop_item()
B.loc = src
user << "You add the pill bottle into the dispenser slot!"
src.updateUsrDialog()
return
/obj/machinery/chem_master/attack_hand(mob/user as mob)
if(stat & BROKEN)
return
user.set_machine(src)
ui_interact(user)
/**
* Display the NanoUI window for the chem master.
*
* See NanoUI documentation for details.
*/
/obj/machinery/chem_master/ui_interact(mob/user, ui_key = "main", var/datum/nanoui/ui = null, var/force_open = 1)
user.set_machine(src)
var/list/data = list()
data["tab"] = tab
data["condi"] = condi
if(loaded_pill_bottle)
data["pillBottle"] = list("total" = loaded_pill_bottle.contents.len, "max" = loaded_pill_bottle.max_storage_space)
else
data["pillBottle"] = null
if(beaker)
var/datum/reagents/R = beaker:reagents
var/ui_reagent_beaker_list[0]
for(var/datum/reagent/G in R.reagent_list)
ui_reagent_beaker_list[++ui_reagent_beaker_list.len] = list("name" = G.name, "volume" = G.volume, "description" = G.description, "id" = G.id)
data["beaker"] = list("total_volume" = R.total_volume, "reagent_list" = ui_reagent_beaker_list)
else
data["beaker"] = null
if(reagents.total_volume)
var/ui_reagent_list[0]
for(var/datum/reagent/N in reagents.reagent_list)
ui_reagent_list[++ui_reagent_list.len] = list("name" = N.name, "volume" = N.volume, "description" = N.description, "id" = N.id)
data["reagents"] = list("total_volume" = reagents.total_volume, "reagent_list" = ui_reagent_list)
else
data["reagents"] = null
data["mode"] = mode
if(analyze_data)
data["analyzeData"] = list("name" = analyze_data["name"], "desc" = analyze_data["desc"], "blood_type" = analyze_data["blood_type"], "blood_DNA" = analyze_data["blood_DNA"])
else
data["analyzeData"] = null
data["pillSprite"] = pillsprite
data["bottleSprite"] = bottlesprite
var/P[20] //how many pill sprites there are. Sprites are taken from chemical.dmi and can be found in nano/images/pill.png
for(var/i = 1 to P.len)
P[i] = i
data["pillSpritesAmount"] = P
data["bottleSpritesAmount"] = list(1, 2, 3, 4) //how many bottle sprites there are. Sprites are taken from chemical.dmi and can be found in nano/images/pill.png
ui = nanomanager.try_update_ui(user, src, ui_key, ui, data, force_open)
if (!ui)
ui = new(user, src, ui_key, "chem_master.tmpl", src.name, 575, 400)
ui.set_initial_data(data)
ui.open()
ui.set_auto_update(5)
/obj/machinery/chem_master/Topic(href, href_list)
if(stat & (BROKEN|NOPOWER)) return
if(usr.stat || usr.restrained()) return
@@ -80,20 +144,19 @@
src.add_fingerprint(usr)
usr.set_machine(src)
if(href_list["tab_select"])
tab = href_list["tab_select"]
if (href_list["ejectp"])
if(loaded_pill_bottle)
loaded_pill_bottle.loc = src.loc
loaded_pill_bottle = null
else if(href_list["close"])
usr << browse(null, "window=chemmaster")
usr.unset_machine()
return
if(beaker)
var/datum/reagents/R = beaker:reagents
if (href_list["analyze"])
var/dat = ""
if (tab == "analyze")
analyze_data["name"] = href_list["name"]
analyze_data["desc"] = href_list["desc"]
if(!condi)
if(href_list["name"] == "Blood")
var/datum/reagent/blood/G
@@ -101,16 +164,9 @@
if(F.name == href_list["name"])
G = F
break
var/A = G.name
var/B = G.data["blood_type"]
var/C = G.data["blood_DNA"]
dat += "<TITLE>Chemmaster 3000</TITLE>Chemical infos:<BR><BR>Name:<BR>[A]<BR><BR>Description:<BR>Blood Type: [B]<br>DNA: [C]<BR><BR><BR><A href='?src=\ref[src];main=1'>(Back)</A>"
else
dat += "<TITLE>Chemmaster 3000</TITLE>Chemical infos:<BR><BR>Name:<BR>[href_list["name"]]<BR><BR>Description:<BR>[href_list["desc"]]<BR><BR><BR><A href='?src=\ref[src];main=1'>(Back)</A>"
else
dat += "<TITLE>Condimaster 3000</TITLE>Condiment infos:<BR><BR>Name:<BR>[href_list["name"]]<BR><BR>Description:<BR>[href_list["desc"]]<BR><BR><BR><A href='?src=\ref[src];main=1'>(Back)</A>"
usr << browse(dat, "window=chem_master;size=575x400")
return
analyze_data["name"] = G.name
analyze_data["blood_type"] = G.data["blood_type"]
analyze_data["blood_DNA"] = G.data["blood_DNA"]
else if (href_list["add"])
@@ -147,9 +203,6 @@
else if (href_list["toggle"])
mode = !mode
else if (href_list["main"])
attack_hand(usr)
return
else if (href_list["eject"])
if(beaker)
beaker:loc = src.loc
@@ -185,9 +238,8 @@
P.icon_state = "pill"+pillsprite
reagents.trans_to_obj(P,amount_per_pill)
if(src.loaded_pill_bottle)
if(loaded_pill_bottle.contents.len < loaded_pill_bottle.storage_slots)
if(loaded_pill_bottle.contents.len < loaded_pill_bottle.max_storage_space)
P.loc = loaded_pill_bottle
src.updateUsrDialog()
else if (href_list["createbottle"])
if(!condi)
@@ -197,106 +249,23 @@
P.name = "[name] bottle"
P.pixel_x = rand(-7, 7) //random position
P.pixel_y = rand(-7, 7)
P.icon_state = bottlesprite
P.icon_state = "bottle-"+bottlesprite
reagents.trans_to_obj(P,60)
P.update_icon()
else
var/obj/item/weapon/reagent_containers/food/condiment/P = new/obj/item/weapon/reagent_containers/food/condiment(src.loc)
reagents.trans_to_obj(P,50)
else if(href_list["change_pill"])
#define MAX_PILL_SPRITE 20 //max icon state of the pill sprites
var/dat = "<table>"
for(var/i = 1 to MAX_PILL_SPRITE)
dat += "<tr><td><a href=\"?src=\ref[src]&pill_sprite=[i]\"><img src=\"pill[i].png\" /></a></td></tr>"
dat += "</table>"
usr << browse(dat, "window=chem_master")
return
else if(href_list["change_bottle"])
var/dat = "<table>"
for(var/sprite in BOTTLE_SPRITES)
dat += "<tr><td><a href=\"?src=\ref[src]&bottle_sprite=[sprite]\"><img src=\"[sprite].png\" /></a></td></tr>"
dat += "</table>"
usr << browse(dat, "window=chem_master")
return
else if(href_list["pill_sprite"])
pillsprite = href_list["pill_sprite"]
else if(href_list["bottle_sprite"])
bottlesprite = href_list["bottle_sprite"]
src.updateUsrDialog()
return
nanomanager.update_uis(src)
/obj/machinery/chem_master/attack_ai(mob/user as mob)
return src.attack_hand(user)
/obj/machinery/chem_master/attack_hand(mob/user as mob)
if(stat & BROKEN)
return
user.set_machine(src)
if(!(user.client in has_sprites))
spawn()
has_sprites += user.client
for(var/i = 1 to MAX_PILL_SPRITE)
usr << browse_rsc(icon('icons/obj/chemical.dmi', "pill" + num2text(i)), "pill[i].png")
for(var/sprite in BOTTLE_SPRITES)
usr << browse_rsc(icon('icons/obj/chemical.dmi', sprite), "[sprite].png")
var/dat = ""
if(!beaker)
dat = "Please insert beaker.<BR>"
if(src.loaded_pill_bottle)
dat += "<A href='?src=\ref[src];ejectp=1'>Eject Pill Bottle \[[loaded_pill_bottle.contents.len]/[loaded_pill_bottle.storage_slots]\]</A><BR><BR>"
else
dat += "No pill bottle inserted.<BR><BR>"
dat += "<A href='?src=\ref[src];close=1'>Close</A>"
else
var/datum/reagents/R = beaker:reagents
dat += "<A href='?src=\ref[src];eject=1'>Eject beaker and Clear Buffer</A><BR>"
if(src.loaded_pill_bottle)
dat += "<A href='?src=\ref[src];ejectp=1'>Eject Pill Bottle \[[loaded_pill_bottle.contents.len]/[loaded_pill_bottle.storage_slots]\]</A><BR><BR>"
else
dat += "No pill bottle inserted.<BR><BR>"
if(!R.total_volume)
dat += "Beaker is empty."
else
dat += "Add to buffer:<BR>"
for(var/datum/reagent/G in R.reagent_list)
dat += "[G.name] , [G.volume] Units - "
dat += "<A href='?src=\ref[src];analyze=1;desc=[G.description];name=[G.name]'>(Analyze)</A> "
dat += "<A href='?src=\ref[src];add=[G.id];amount=1'>(1)</A> "
dat += "<A href='?src=\ref[src];add=[G.id];amount=5'>(5)</A> "
dat += "<A href='?src=\ref[src];add=[G.id];amount=10'>(10)</A> "
dat += "<A href='?src=\ref[src];add=[G.id];amount=30'>(30)</A> "
dat += "<A href='?src=\ref[src];add=[G.id];amount=60'>(60)</A> "
dat += "<A href='?src=\ref[src];add=[G.id];amount=[G.volume]'>(All)</A> "
dat += "<A href='?src=\ref[src];addcustom=[G.id]'>(Custom)</A><BR>"
dat += "<HR>Transfer to <A href='?src=\ref[src];toggle=1'>[(!mode ? "disposal" : "beaker")]:</A><BR>"
if(reagents.total_volume)
for(var/datum/reagent/N in reagents.reagent_list)
dat += "[N.name] , [N.volume] Units - "
dat += "<A href='?src=\ref[src];analyze=1;desc=[N.description];name=[N.name]'>(Analyze)</A> "
dat += "<A href='?src=\ref[src];remove=[N.id];amount=1'>(1)</A> "
dat += "<A href='?src=\ref[src];remove=[N.id];amount=5'>(5)</A> "
dat += "<A href='?src=\ref[src];remove=[N.id];amount=10'>(10)</A> "
dat += "<A href='?src=\ref[src];remove=[N.id];amount=30'>(30)</A> "
dat += "<A href='?src=\ref[src];remove=[N.id];amount=60'>(60)</A> "
dat += "<A href='?src=\ref[src];remove=[N.id];amount=[N.volume]'>(All)</A> "
dat += "<A href='?src=\ref[src];removecustom=[N.id]'>(Custom)</A><BR>"
else
dat += "Empty<BR>"
if(!condi)
dat += "<HR><BR><A href='?src=\ref[src];createpill=1'>Create pill (60 units max)</A><a href=\"?src=\ref[src]&change_pill=1\"><img src=\"pill[pillsprite].png\" /></a><BR>"
dat += "<A href='?src=\ref[src];createpill_multiple=1'>Create multiple pills</A><BR>"
dat += "<A href='?src=\ref[src];createbottle=1'>Create bottle (60 units max)<a href=\"?src=\ref[src]&change_bottle=1\"><img src=\"[bottlesprite].png\" /></A>"
else
dat += "<A href='?src=\ref[src];createbottle=1'>Create bottle (50 units max)</A>"
if(!condi)
user << browse("<TITLE>Chemmaster 3000</TITLE>Chemmaster menu:<BR><BR>[dat]", "window=chem_master;size=575x400")
else
user << browse("<TITLE>Condimaster 3000</TITLE>Condimaster menu:<BR><BR>[dat]", "window=chem_master;size=575x400")
onclose(user, "chem_master")
return
/obj/machinery/chem_master/condimaster
name = "CondiMaster 3000"
condi = 1

View File

@@ -622,7 +622,7 @@
if(istype(M:glasses, /obj/item/clothing/glasses/sunglasses))
continue
flick("e_flash", M.flash)
M.flash_eyes()
M.Weaken(15)
if(4 to 5)
@@ -630,7 +630,7 @@
if(istype(M:glasses, /obj/item/clothing/glasses/sunglasses))
continue
flick("e_flash", M.flash)
M.flash_eyes()
M.Stun(5)
/datum/chemical_reaction/emp_pulse
@@ -1003,7 +1003,7 @@
if(holder.my_atom && istype(holder.my_atom, required))
return ..()
return 0
/datum/chemical_reaction/slime/golem
name = "Prometheans"
id = "m_promethean"
@@ -1016,7 +1016,7 @@
var/location = get_turf(holder.my_atom)
new /obj/item/slime_cube(location)
qdel(holder.my_atom)
/* Food */
/datum/chemical_reaction/tofu
@@ -1499,7 +1499,7 @@
name = "Allies Cocktail"
id = "alliescocktail"
result = "alliescocktail"
required_reagents = list("classicmartini" = 1, "vodka" = 1)
required_reagents = list("martini" = 1, "vodka" = 1)
result_amount = 2
/datum/chemical_reaction/demonsblood

View File

@@ -87,11 +87,11 @@
var/list/borks = typesof(/obj/item/weapon/reagent_containers/food/snacks) - /obj/item/weapon/reagent_containers/food/snacks // BORK BORK BORK
playsound(get_turf(holder.my_atom), 'sound/effects/phasein.ogg', 100, 1)
/* Removed at some point, unsure what to replace with
for(var/mob/living/carbon/human/M in viewers(get_turf(holder.my_atom), null))
if(M:eyecheck() <= 0)
flick("e_flash", M.flash)
*/
for(var/i = 1, i <= 4 + rand(1,2), i++)
var/chosen = pick(borks)
var/obj/B = new chosen
@@ -134,11 +134,11 @@
var/list/material = typesof(/obj/item/stack/material) - blocked
playsound(get_turf(holder.my_atom), 'sound/effects/phasein.ogg', 100, 1)
/* Removed at some point, unsure what to replace with
for(var/mob/living/carbon/human/M in viewers(get_turf(holder.my_atom), null))
if(M:eyecheck() <= 0)
flick("e_flash", M.flash)
*/
var/spawn_amount = rand(1,50)
var/chosen = pick(material)
var/obj/item/stack/material/C = new chosen
@@ -269,11 +269,11 @@
var/list/voremobs = typesof(mob_path) - mob_path - blocked // list of possible hostile mobs
playsound(get_turf(holder.my_atom), 'sound/effects/phasein.ogg', 100, 1)
/* Removed at some point, unsure what to replace with
for(var/mob/living/carbon/human/M in viewers(get_turf(holder.my_atom), null))
if(M:eyecheck() <= 0)
flick("e_flash", M.flash)
*/
var/spawn_count = rand(1,3)
for(var/i = 1, i <= spawn_count, i++)
var/chosen = pick(voremobs)

View File

@@ -12,8 +12,15 @@
slot_flags = SLOT_EARS
volume = 5
/obj/item/weapon/reagent_containers/dropper/afterattack(var/obj/target, var/mob/user, var/flag)
if(!target.reagents || !flag) return
/obj/item/weapon/reagent_containers/dropper/do_surgery(mob/living/carbon/M, mob/living/user)
if(user.a_intent != I_HELP) //in case it is ever used as a surgery tool
return ..()
afterattack(M, user, 1)
return 1
/obj/item/weapon/reagent_containers/dropper/afterattack(var/obj/target, var/mob/user, var/proximity)
if(!target.reagents || !proximity) return
if(reagents.total_volume)

View File

@@ -11,8 +11,14 @@
var/slices_num
var/dried_type = null
var/dry = 0
var/nutriment_amt = 0
center_of_mass = list("x"=16, "y"=16)
w_class = 2
/obj/item/weapon/reagent_containers/food/snacks/New()
..()
if(nutriment_amt)
reagents.add_reagent("nutriment", nutriment_amt)
//Placeholder for effect that trigger on eating that aren't tied to reagents.
/obj/item/weapon/reagent_containers/food/snacks/proc/On_Consume(var/mob/M)

View File

@@ -69,8 +69,15 @@
flags |= OPENCONTAINER
update_icon()
/obj/item/weapon/reagent_containers/glass/afterattack(var/obj/target, var/mob/user, var/flag)
if(!is_open_container() || !flag)
/obj/item/weapon/reagent_containers/glass/do_surgery(mob/living/carbon/M, mob/living/user)
if(user.a_intent != I_HELP) //in case it is ever used as a surgery tool
return ..()
afterattack(M, user, 1)
return 1
/obj/item/weapon/reagent_containers/glass/afterattack(var/obj/target, var/mob/user, var/proximity)
if(!is_open_container() || !proximity)
return
for(var/type in can_be_placed_into)

View File

@@ -20,6 +20,12 @@
// reagents.add_reagent("tricordrazine", 30)
// return
/obj/item/weapon/reagent_containers/hypospray/do_surgery(mob/living/carbon/M, mob/living/user)
if(user.a_intent != I_HELP) //in case it is ever used as a surgery tool
return ..()
attack(M, user)
return 1
/obj/item/weapon/reagent_containers/hypospray/attack(mob/living/M as mob, mob/user as mob)
if(!reagents.total_volume)
user << "<span class='warning'>[src] is empty.</span>"

View File

@@ -52,6 +52,14 @@
/obj/item/weapon/reagent_containers/syringe/attackby(obj/item/I as obj, mob/user as mob)
return
/obj/item/weapon/reagent_containers/syringe/do_surgery(mob/living/carbon/M, mob/living/user)
if(user.a_intent == I_HURT)
return 0
if(user.a_intent != I_HELP) //in case it is ever used as a surgery tool
return ..()
afterattack(M, user, 1)
return 1
/obj/item/weapon/reagent_containers/syringe/afterattack(obj/target, mob/user, proximity)
if(!proximity || !target.reagents)
return
@@ -66,7 +74,6 @@
syringestab(target, user)
return
switch(mode)
if(SYRINGE_DRAW)

View File

@@ -26,7 +26,7 @@
for(var/mob/living/target in targets)
target.visible_message( "<span class='danger'>[target]'s face lights up in fire, and after the event a horse's head takes its place!</span>", \
"<span class='danger'>Your face burns up, and shortly after the fire you realise you have the face of a horse!</span>")
flick("e_flash", target.flash)
target.flash_eyes()
/spell/targeted/equip_item/horsemask/summon_item(var/new_type)
var/obj/item/new_item = new new_type

View File

@@ -149,6 +149,7 @@
if(container.reagents.has_reagent("peridaxon"))
affected.status &= ~ORGAN_DEAD
affected.owner.update_body(1)
user.visible_message("\blue [user] applies [trans] units of the solution to affected tissue in [target]'s [affected.name]", \
"\blue You apply [trans] units of the solution to affected tissue in [target]'s [affected.name] with \the [tool].")

View File

@@ -166,15 +166,18 @@
if(..())
var/obj/item/stack/cable_coil/C = tool
var/obj/item/organ/external/affected = target.get_organ(target_zone)
var/limb_can_operate = ((affected && affected.open >= 3) && (affected.disfigured || affected.burn_dam > 0) && target_zone != O_MOUTH)
if(limb_can_operate)
if(istype(C))
if(!C.get_amount() >= 3)
user << "<span class='danger'>You need three or more cable pieces to repair this damage.</span>"
return SURGERY_FAILURE
C.use(3)
return 1
return SURGERY_FAILURE
var/limb_can_operate = (affected && affected.open == 2 && affected.burn_dam > 0 && target_zone != "mouth")
if(!limb_can_operate)
return 0
if(istype(C))
if(!C.can_use(10))
user << "<span class='danger'>You need ten or more cable pieces to repair this damage.</span>" //usage amount made more consistent with regular cable repair
return SURGERY_FAILURE
C.use(10)
return 1
begin_step(mob/user, mob/living/carbon/human/target, target_zone, obj/item/tool)
var/obj/item/organ/external/affected = target.get_organ(target_zone)

View File

@@ -68,7 +68,7 @@
proc/fail_step(mob/living/user, mob/living/carbon/human/target, target_zone, obj/item/tool)
return null
proc/spread_germs_to_organ(var/obj/item/organ/external/E, var/mob/living/carbon/human/user)
/proc/spread_germs_to_organ(var/obj/item/organ/external/E, var/mob/living/carbon/human/user)
if(!istype(user) || !istype(E)) return
var/germ_level = user.germ_level
@@ -77,7 +77,7 @@ proc/spread_germs_to_organ(var/obj/item/organ/external/E, var/mob/living/carbon/
E.germ_level = max(germ_level,E.germ_level) //as funny as scrubbing microbes out with clean gloves is - no.
proc/do_surgery(mob/living/carbon/M, mob/living/user, obj/item/tool)
/obj/item/proc/do_surgery(mob/living/carbon/M, mob/living/user)
if(!istype(M))
return 0
if (user.a_intent == I_HURT) //check for Hippocratic Oath
@@ -88,18 +88,18 @@ proc/do_surgery(mob/living/carbon/M, mob/living/user, obj/item/tool)
return 1
for(var/datum/surgery_step/S in surgery_steps)
//check if tool is right or close enough and if this step is possible
if(S.tool_quality(tool))
var/step_is_valid = S.can_use(user, M, zone, tool)
if(S.tool_quality(src))
var/step_is_valid = S.can_use(user, M, zone, src)
if(step_is_valid && S.is_valid_target(M))
if(step_is_valid == SURGERY_FAILURE) // This is a failure that already has a message for failing.
return 1
M.op_stage.in_progress += zone
S.begin_step(user, M, zone, tool) //start on it
S.begin_step(user, M, zone, src) //start on it
//We had proper tools! (or RNG smiled.) and user did not move or change hands.
if(prob(S.tool_quality(tool)) && do_mob(user, M, rand(S.min_duration, S.max_duration)))
S.end_step(user, M, zone, tool) //finish successfully
else if ((tool in user.contents) && user.Adjacent(M)) //or
S.fail_step(user, M, zone, tool) //malpractice~
if(prob(S.tool_quality(src)) && do_mob(user, M, rand(S.min_duration, S.max_duration)))
S.end_step(user, M, zone, src) //finish successfully
else if ((src in user.contents) && user.Adjacent(M)) //or
S.fail_step(user, M, zone, src) //malpractice~
else // This failing silently was a pain.
user << "<span class='warning'>You must remain close to your patient to conduct surgery.</span>"
M.op_stage.in_progress -= zone // Clear the in-progress flag.
@@ -109,11 +109,11 @@ proc/do_surgery(mob/living/carbon/M, mob/living/user, obj/item/tool)
return 1 //don't want to do weapony things after surgery
if (user.a_intent == I_HELP)
user << "<span class='warning'>You can't see any useful way to use [tool] on [M].</span>"
user << "<span class='warning'>You can't see any useful way to use [src] on [M].</span>"
return 1
return 0
proc/sort_surgeries()
/proc/sort_surgeries()
var/gap = surgery_steps.len
var/swapped = 1
while (gap > 1 || swapped)