Merge branch 'dev' of https://github.com/Baystation12/Baystation12 into inflatables-squashed

This commit is contained in:
Atlantis
2015-12-07 13:55:48 +01:00
212 changed files with 2359 additions and 1711 deletions

View File

@@ -118,7 +118,7 @@ client/proc/display_admin_reports()
usr << browse(output, "window=news;size=600x400")
client/proc/Report(mob/M as mob in world)
client/proc/Report(mob/M as mob in mob_list)
set category = "Admin"
if(!src.holder)
return

View File

@@ -640,7 +640,7 @@ var/list/admin_verbs_mentor = list(
log_admin("[key_name(usr)] gave [key_name(T)] a [greater] disease2 with infection chance [D.infectionchance].")
message_admins("\blue [key_name_admin(usr)] gave [key_name(T)] a [greater] disease2 with infection chance [D.infectionchance].", 1)
/client/proc/make_sound(var/obj/O in world) // -- TLE
/client/proc/make_sound(var/obj/O in range(world.view)) // -- TLE
set category = "Special Verbs"
set name = "Make Sound"
set desc = "Display a message to everyone who can hear the target"

View File

@@ -33,7 +33,7 @@
callproc_targetpicked(targetselected, target)
/client/proc/callproc_target(atom/A in world)
/client/proc/callproc_target(atom/A in range(world.view))
set category = "Debug"
set name = "Advanced ProcCall Target"

View File

@@ -21,7 +21,7 @@
else
alert("Admin jumping disabled")
/client/proc/jumptoturf(var/turf/T in world)
/client/proc/jumptoturf(var/turf/T in turfs)
set name = "Jump to Turf"
set category = "Admin"
if(!check_rights(R_ADMIN|R_MOD|R_DEBUG))

View File

@@ -296,3 +296,4 @@
if(pa.Find("right"))
if(holder.throw_atom)
holder.throw_atom.throw_at(object, 10, 1)
log_admin("[key_name(usr)] threw [holder.throw_atom] at [object]")

View File

@@ -119,7 +119,7 @@
alert("Invalid mob")
/*
/client/proc/cmd_admin_monkeyize(var/mob/M in world)
/client/proc/cmd_admin_monkeyize(var/mob/M in mob_list)
set category = "Fun"
set name = "Make Monkey"
@@ -134,7 +134,7 @@
else
alert("Invalid mob")
/client/proc/cmd_admin_changelinginize(var/mob/M in world)
/client/proc/cmd_admin_changelinginize(var/mob/M in mob_list)
set category = "Fun"
set name = "Make Changeling"
@@ -152,7 +152,7 @@
alert("Invalid mob")
*/
/*
/client/proc/cmd_admin_abominize(var/mob/M in world)
/client/proc/cmd_admin_abominize(var/mob/M in mob_list)
set category = null
set name = "Make Abomination"
@@ -169,7 +169,7 @@
*/
/*
/client/proc/make_cultist(var/mob/M in world) // -- TLE, modified by Urist
/client/proc/make_cultist(var/mob/M in mob_list) // -- TLE, modified by Urist
set category = "Fun"
set name = "Make Cultist"
set desc = "Makes target a cultist"

View File

@@ -9,7 +9,7 @@ var/list/VVicon_edit_lock = list("icon", "icon_state", "overlays", "underlays")
var/list/VVckey_edit = list("key", "ckey")
/*
/client/proc/cmd_modify_object_variables(obj/O as obj|mob|turf|area in world)
/client/proc/cmd_modify_object_variables(obj/O as obj|mob|turf|area in world) // Acceptable 'in world', as VV would be incredibly hampered otherwise
set category = "Debug"
set name = "Edit Variables"
set desc="(target) Edit a target item's variables"

View File

@@ -1,4 +1,4 @@
/proc/possess(obj/O as obj in world)
/proc/possess(obj/O as obj in range(world.view))
set name = "Possess Obj"
set category = "Object"
@@ -26,7 +26,7 @@
usr.control_object = O
feedback_add_details("admin_verb","PO") //If you are copy-pasting this, ensure the 2nd parameter is unique to the new proc!
/proc/release(obj/O as obj in world)
/proc/release(obj/O as obj in range(world.view))
set name = "Release Obj"
set category = "Object"
//usr.loc = get_turf(usr)

View File

@@ -536,7 +536,7 @@ Traitors and the like can also be revived with the previous role mostly intact.
message_admins("[key_name_admin(src)] has created a command report", 1)
feedback_add_details("admin_verb","CCR") //If you are copy-pasting this, ensure the 2nd parameter is unique to the new proc!
/client/proc/cmd_admin_delete(atom/O as obj|mob|turf in view())
/client/proc/cmd_admin_delete(atom/O as obj|mob|turf in range(world.view))
set category = "Admin"
set name = "Delete"
@@ -562,7 +562,7 @@ Traitors and the like can also be revived with the previous role mostly intact.
src << "[job.title]: [job.total_positions]"
feedback_add_details("admin_verb","LFS") //If you are copy-pasting this, ensure the 2nd parameter is unique to the new proc!
/client/proc/cmd_admin_explosion(atom/O as obj|mob|turf in world)
/client/proc/cmd_admin_explosion(atom/O as obj|mob|turf in range(world.view))
set category = "Special Verbs"
set name = "Explosion"
@@ -590,7 +590,7 @@ Traitors and the like can also be revived with the previous role mostly intact.
else
return
/client/proc/cmd_admin_emp(atom/O as obj|mob|turf in world)
/client/proc/cmd_admin_emp(atom/O as obj|mob|turf in range(world.view))
set category = "Special Verbs"
set name = "EM Pulse"

View File

@@ -6,6 +6,7 @@
// Variables not to expand the lists of. Vars is pointless to expand, and overlays/underlays cannot be expanded.
/var/list/view_variables_dont_expand = list("overlays", "underlays", "vars")
// Acceptable 'in world', as VV would be incredibly hampered otherwise
/client/proc/debug_variables(datum/D in world)
set category = "Debug"
set name = "View Variables"

View File

@@ -86,10 +86,10 @@
/turf/get_alarm_origin()
return get_area(src)
/datum/alarm_handler/proc/register(var/object, var/procName)
/datum/alarm_handler/proc/register_alarm(var/object, var/procName)
listeners[object] = procName
/datum/alarm_handler/proc/unregister(var/object)
/datum/alarm_handler/proc/unregister_alarm(var/object)
listeners -= object
/datum/alarm_handler/proc/notify_listeners(var/alarm, var/was_raised)

View File

@@ -187,13 +187,10 @@
return
/obj/effect/beam/i_beam/process()
//world << "i_beam \ref[src] : process"
if((loc.density || !(master)))
// world << "beam hit loc [loc] or no master [master], deleting"
if((loc && loc.density) || !master)
qdel(src)
return
//world << "proccess: [src.left] left"
if(left > 0)
left--

View File

@@ -40,6 +40,9 @@
HasProximity(atom/movable/AM as mob|obj)
if(!istype(AM))
log_debug("DEBUG: HasProximity called with [AM] on [src] ([usr]).")
return
if (istype(AM, /obj/effect/beam)) return
if (AM.move_speed < 12) sense()
return

View File

@@ -0,0 +1,15 @@
/client/New()
..()
dir = NORTH
/client/verb/spinleft()
set name = "Spin View CCW"
set category = "OOC"
dir = turn(dir, 90)
/client/verb/spinright()
set name = "Spin View CW"
set category = "OOC"
dir = turn(dir, -90)

View File

@@ -185,9 +185,9 @@ datum/preferences
if(path)
dat += "Slot - "
dat += "<a href=\"byond://?src=\ref[user];preference=open_load_dialog\">Load slot</a> - "
dat += "<a href=\"byond://?src=\ref[user];preference=save\">Save slot</a> - "
dat += "<a href=\"byond://?src=\ref[user];preference=reload\">Reload slot</a>"
dat += "<a href='?src=\ref[src];load=1'>Load slot</a> - "
dat += "<a href='?src=\ref[src];save=1'>Save slot</a> - "
dat += "<a href='?src=\ref[src];reload=1'>Reload slot</a>"
else
dat += "Please create an account to save your preferences."
@@ -211,26 +211,30 @@ datum/preferences
else
user << "<span class='danger'>The forum URL is not set in the server configuration.</span>"
return
ShowChoices(usr)
return 1
/datum/preferences/Topic(href, list/href_list)
if(..())
return 1
if(href_list["save"])
save_preferences()
save_character()
else if(href_list["reload"])
load_preferences()
load_character()
else if(href_list["load"])
if(!IsGuestKey(usr.key))
open_load_dialog(usr)
return 1
else if(href_list["changeslot"])
load_character(text2num(href_list["changeslot"]))
close_load_dialog(usr)
else
switch(href_list["preference"])
if("save")
save_preferences()
save_character()
return 0
if("reload")
load_preferences()
load_character()
if("open_load_dialog")
if(!IsGuestKey(user.key))
open_load_dialog(user)
return 1
if("changeslot")
load_character(text2num(href_list["num"]))
close_load_dialog(user)
ShowChoices(user)
ShowChoices(usr)
return 1
/datum/preferences/proc/copy_to(mob/living/carbon/human/character, safety = 0)
@@ -357,10 +361,9 @@ datum/preferences
if(!name) name = "Character[i]"
if(i==default_slot)
name = "<b>[name]</b>"
dat += "<a href='?_src_=prefs;preference=changeslot;num=[i];'>[name]</a><br>"
dat += "<a href='?src=\ref[src];changeslot=[i]'>[name]</a><br>"
dat += "<hr>"
dat += "<a href='byond://?src=\ref[user];preference=close_load_dialog'>Close</a><br>"
dat += "</center></tt>"
user << browse(dat, "window=saves;size=300x390")

View File

@@ -1104,6 +1104,12 @@ var/global/list/gear_datums = list()
sort_category = "misc"
cost = 1
/datum/gear/boot_knife
display_name = "boot knife"
path = /obj/item/weapon/material/kitchen/utensil/knife/boot
sort_category = "misc"
cost = 3
/datum/gear/cane
display_name = "cane"
path = /obj/item/weapon/cane

View File

@@ -6,6 +6,10 @@
var/list/species_restricted = null //Only these species can wear this kit.
var/gunshot_residue //Used by forensics.
var/list/accessories = list()
var/list/valid_accessory_slots
var/list/restricted_accessory_slots
/*
Sprites used when the clothing item is refit. This is done by setting icon_override.
For best results, if this is set then sprite_sheets should be null and vice versa, but that is by no means necessary.
@@ -395,6 +399,9 @@ BLIND // can't see anything
body_parts_covered = FEET
slot_flags = SLOT_FEET
var/can_hold_knife
var/obj/item/holding
permeability_coefficient = 0.50
slowdown = SHOES_SLOWDOWN
force = 2
@@ -405,6 +412,54 @@ BLIND // can't see anything
"Resomi" = 'icons/mob/species/resomi/shoes.dmi',
)
/obj/item/clothing/shoes/proc/draw_knife()
set name = "Draw Boot Knife"
set desc = "Pull out your boot knife."
set category = "IC"
set src in usr
if(usr.stat || usr.restrained() || usr.incapacitated())
return
holding.forceMove(get_turf(usr))
if(usr.put_in_hands(holding))
usr.visible_message("<span class='danger'>\The [usr] pulls a knife out of their boot!</span>")
holding = null
else
usr << "<span class='warning'>Your need an empty, unbroken hand to do that.</span>"
holding.forceMove(src)
if(!holding)
verbs -= /obj/item/clothing/shoes/proc/draw_knife
update_icon()
return
/obj/item/clothing/shoes/attackby(var/obj/item/I, var/mob/user)
if(can_hold_knife && istype(I, /obj/item/weapon/material/shard) || \
istype(I, /obj/item/weapon/material/butterfly) || \
istype(I, /obj/item/weapon/material/kitchen/utensil) || \
istype(I, /obj/item/weapon/material/hatchet/tacknife))
if(holding)
user << "<span class='warning'>\The [src] is already holding \a [holding].</span>"
return
user.unEquip(I)
I.forceMove(src)
holding = I
user.visible_message("<span class='notice'>\The [user] shoves \the [I] into \the [src].</span>")
verbs |= /obj/item/clothing/shoes/proc/draw_knife
update_icon()
else
return ..()
/obj/item/clothing/shoes/update_icon()
overlays.Cut()
if(holding)
overlays += image(icon, "[icon_state]_knife")
return ..()
/obj/item/clothing/shoes/proc/handle_movement(var/turf/walking, var/running)
return
@@ -458,7 +513,6 @@ BLIND // can't see anything
2 = Report detailed damages
3 = Report location
*/
var/list/accessories = list()
var/displays_id = 1
var/rolled_down = -1 //0 = unrolled, 1 = rolled, -1 = cannot be toggled
sprite_sheets = list(
@@ -469,6 +523,15 @@ BLIND // can't see anything
//convenience var for defining the icon state for the overlay used when the clothing is worn.
//Also used by rolling/unrolling.
var/worn_state = null
valid_accessory_slots = list("utility","armband","decor")
restricted_accessory_slots = list("utility", "armband")
/obj/item/clothing/under/attack_hand(var/mob/user)
if(accessories && accessories.len)
..()
if ((ishuman(usr) || issmall(usr)) && src.loc == user)
return
/obj/item/clothing/under/New()
..()
@@ -512,69 +575,6 @@ BLIND // can't see anything
var/mob/M = src.loc
M.update_inv_w_uniform()
/obj/item/clothing/under/proc/can_attach_accessory(obj/item/clothing/accessory/A)
if(istype(A))
.=1
else
return 0
if(accessories.len && (A.slot in list("utility","armband")))
for(var/obj/item/clothing/accessory/AC in accessories)
if (AC.slot == A.slot)
return 0
/obj/item/clothing/under/attackby(obj/item/I, mob/user)
if(istype(I, /obj/item/clothing/accessory))
var/obj/item/clothing/accessory/A = I
if(can_attach_accessory(A))
user.drop_item()
accessories += A
A.on_attached(src, user)
if(istype(loc, /mob/living/carbon/human))
var/mob/living/carbon/human/H = loc
H.update_inv_w_uniform()
return
else
user << "<span class='notice'>You cannot attach more accessories of this type to [src].</span>"
if(accessories.len)
for(var/obj/item/clothing/accessory/A in accessories)
A.attackby(I, user)
return
..()
/obj/item/clothing/under/attack_hand(mob/user as mob)
//only forward to the attached accessory if the clothing is equipped (not in a storage)
if(accessories.len && src.loc == user)
for(var/obj/item/clothing/accessory/A in accessories)
A.attack_hand(user)
return
if ((ishuman(usr) || issmall(usr)) && src.loc == user) //make it harder to accidentally undress yourself
return
..()
/obj/item/clothing/under/MouseDrop(obj/over_object as obj)
if (ishuman(usr) || issmall(usr))
//makes sure that the clothing is equipped so that we can't drag it into our hand from miles away.
if (!(src.loc == usr))
return
if (( usr.restrained() ) || ( usr.stat ))
return
if (!usr.unEquip(src))
return
switch(over_object.name)
if("r_hand")
usr.put_in_r_hand(src)
if("l_hand")
usr.put_in_l_hand(src)
src.add_fingerprint(usr)
/obj/item/clothing/under/examine(mob/user)
..(user)
@@ -587,9 +587,6 @@ BLIND // can't see anything
user << "Its vital tracker appears to be enabled."
if(3)
user << "Its vital tracker and tracking beacon appear to be enabled."
if(accessories.len)
for(var/obj/item/clothing/accessory/A in accessories)
user << "\A [A] is attached to it."
/obj/item/clothing/under/proc/set_sensors(mob/usr as mob)
var/mob/M = usr
@@ -662,34 +659,7 @@ BLIND // can't see anything
item_state_slots[slot_w_uniform_str] = "[worn_state]"
update_clothing_icon()
/obj/item/clothing/under/proc/remove_accessory(mob/user, obj/item/clothing/accessory/A)
if(!(A in accessories))
return
A.on_removed(user)
accessories -= A
update_clothing_icon()
/obj/item/clothing/under/verb/removetie()
set name = "Remove Accessory"
set category = "Object"
set src in usr
if(!istype(usr, /mob/living)) return
if(usr.stat) return
if(!accessories.len) return
var/obj/item/clothing/accessory/A
if(accessories.len > 1)
A = input("Select an accessory to remove from [src]") as null|anything in accessories
else
A = accessories[1]
src.remove_accessory(usr,A)
/obj/item/clothing/under/rank/New()
sensor_mode = pick(0,1,2,3)
..()
/obj/item/clothing/under/emp_act(severity)
if(accessories.len)
for(var/obj/item/clothing/accessory/A in accessories)
A.emp_act(severity)
..()

View File

@@ -0,0 +1,100 @@
/obj/item/clothing/proc/can_attach_accessory(obj/item/clothing/accessory/A)
if(valid_accessory_slots && istype(A) && (A.slot in valid_accessory_slots))
.=1
else
return 0
if(accessories.len && restricted_accessory_slots && (A.slot in restricted_accessory_slots))
for(var/obj/item/clothing/accessory/AC in accessories)
if (AC.slot == A.slot)
return 0
/obj/item/clothing/attackby(var/obj/item/I, var/mob/user)
if(istype(I, /obj/item/clothing/accessory))
if(!valid_accessory_slots || !valid_accessory_slots.len)
usr << "<span class='warning'>You cannot attach accessories of any kind to \the [src].</span>"
return
var/obj/item/clothing/accessory/A = I
if(can_attach_accessory(A))
user.drop_item()
accessories += A
A.on_attached(src, user)
src.verbs |= /obj/item/clothing/proc/removetie_verb
if(istype(loc, /mob/living/carbon/human))
var/mob/living/carbon/human/H = loc
H.update_inv_w_uniform()
return
else
user << "<span class='warning'>You cannot attach more accessories of this type to [src].</span>"
return
if(accessories.len)
for(var/obj/item/clothing/accessory/A in accessories)
A.attackby(I, user)
return
..()
/obj/item/clothing/attack_hand(var/mob/user)
//only forward to the attached accessory if the clothing is equipped (not in a storage)
if(accessories.len && src.loc == user)
for(var/obj/item/clothing/accessory/A in accessories)
A.attack_hand(user)
return
return ..()
/obj/item/clothing/MouseDrop(var/obj/over_object)
if (ishuman(usr) || issmall(usr))
//makes sure that the clothing is equipped so that we can't drag it into our hand from miles away.
if (!(src.loc == usr))
return
if (( usr.restrained() ) || ( usr.stat ))
return
if (!usr.unEquip(src))
return
switch(over_object.name)
if("r_hand")
usr.put_in_r_hand(src)
if("l_hand")
usr.put_in_l_hand(src)
src.add_fingerprint(usr)
/obj/item/clothing/examine(var/mob/user)
..(user)
if(accessories.len)
for(var/obj/item/clothing/accessory/A in accessories)
user << "\A [A] is attached to it."
/obj/item/clothing/proc/remove_accessory(mob/user, obj/item/clothing/accessory/A)
if(!(A in accessories))
return
A.on_removed(user)
accessories -= A
update_clothing_icon()
/obj/item/clothing/proc/removetie_verb()
set name = "Remove Accessory"
set category = "Object"
set src in usr
if(!istype(usr, /mob/living)) return
if(usr.stat) return
if(!accessories.len) return
var/obj/item/clothing/accessory/A
if(accessories.len > 1)
A = input("Select an accessory to remove from [src]") as null|anything in accessories
else
A = accessories[1]
src.remove_accessory(usr,A)
if(!accessories.len)
src.verbs -= /obj/item/clothing/proc/removetie_verb
/obj/item/clothing/emp_act(severity)
if(accessories.len)
for(var/obj/item/clothing/accessory/A in accessories)
A.emp_act(severity)
..()

View File

@@ -196,6 +196,14 @@
item_state = "blindfold"
tint = TINT_BLIND
/obj/item/clothing/glasses/sunglasses/blindfold/tape
name = "length of tape"
desc = "It's a robust DIY blindfold!"
icon = 'icons/obj/bureaucracy.dmi'
icon_state = "tape_cross"
item_state = null
w_class = 1
/obj/item/clothing/glasses/sunglasses/prescription
name = "prescription sunglasses"
prescription = 1

View File

@@ -8,6 +8,14 @@
gas_transfer_coefficient = 0.90
voicechange = 1
/obj/item/clothing/mask/muzzle/tape
name = "length of tape"
desc = "It's a robust DIY muzzle!"
icon = 'icons/obj/bureaucracy.dmi'
icon_state = "tape_cross"
item_state = null
w_class = 1
/obj/item/clothing/mask/muzzle/New()
..()
say_messages = list("Mmfph!", "Mmmf mrrfff!", "Mmmf mnnf!")

View File

@@ -15,6 +15,7 @@
force = 3
armor = list(melee = 30, bullet = 10, laser = 10, energy = 15, bomb = 20, bio = 0, rad = 0)
siemens_coefficient = 0.7
can_hold_knife = 1
/obj/item/clothing/shoes/jackboots/unathi
name = "toe-less jackboots"
@@ -30,3 +31,4 @@
item_state = "workboots"
armor = list(melee = 40, bullet = 0, laser = 0, energy = 15, bomb = 20, bio = 0, rad = 20)
siemens_coefficient = 0.7
can_hold_knife = 1

View File

@@ -144,8 +144,8 @@
suit_overlay_active = "mounted-taser"
suit_overlay_inactive = "mounted-taser"
interface_name = "mounted energy gun"
interface_desc = "A shoulder-mounted cell-powered energy gun."
interface_name = "mounted taser"
interface_desc = "A shoulder-mounted cell-powered taser."
gun_type = /obj/item/weapon/gun/energy/taser/mounted

View File

@@ -169,6 +169,10 @@
interface_name = "dead man's switch"
interface_desc = "An integrated self-destruct module. When the wearer dies, so does the surrounding area. Do not press this button."
var/list/explosion_values = list(1,2,4,5)
/obj/item/rig_module/self_destruct/small
explosion_values = list(0,0,3,4)
/obj/item/rig_module/self_destruct/activate()
return
@@ -184,17 +188,12 @@
//OH SHIT.
if(holder.wearer.stat == 2)
engage()
engage(1)
/obj/item/rig_module/self_destruct/engage()
explosion(get_turf(src), 1, 2, 4, 5)
if(holder && holder.wearer)
holder.wearer.drop_from_inventory(src)
qdel(holder)
qdel(src)
/obj/item/rig_module/self_destruct/small/engage()
explosion(get_turf(src), 0, 0, 3, 4)
/obj/item/rig_module/self_destruct/engage(var/skip_check)
if(!skip_check && usr && alert(usr, "Are you sure you want to push that button?", "Self-destruct", "No", "Yes") == "No")
return
explosion(get_turf(src), explosion_values[1], explosion_values[2], explosion_values[3], explosion_values[4])
if(holder && holder.wearer)
holder.wearer.drop_from_inventory(src)
qdel(holder)

View File

@@ -560,8 +560,8 @@
M.visible_message("<font color='blue'>[M] starts putting on \the [src]...</font>", "<font color='blue'>You start putting on \the [src]...</font>")
if(!do_after(M,seal_delay))
if(M && M.back == src)
M.back = null
M.drop_from_inventory(src)
if(!M.unEquip(src))
return
src.forceMove(get_turf(src))
return
@@ -632,12 +632,9 @@
use_obj.forceMove(src)
if(check_slot)
H << "<span class='danger'>You are unable to deploy \the [piece] as \the [check_slot] [check_slot.gender == PLURAL ? "are" : "is"] in the way.</span>"
return
else
use_obj.forceMove(H)
if(!H.equip_to_slot_if_possible(use_obj, equip_to, 0))
use_obj.forceMove(src)
else
H << "<span class='notice'>Your [use_obj.name] [use_obj.gender == PLURAL ? "deploy" : "deploys"] swiftly.</span>"
H << "<span class='notice'>Your [use_obj.name] [use_obj.gender == PLURAL ? "deploy" : "deploys"] swiftly.</span>"
if(piece == "helmet" && helmet)
helmet.update_light(H)

View File

@@ -56,7 +56,7 @@
user << "\The [src] already has a tank installed."
return
user.drop_from_inventory(W)
if(!user.unEquip(W)) return
air_supply = W
W.forceMove(src)
user << "You slot [W] into [src] and tighten the connecting valve."
@@ -84,8 +84,8 @@
return
if(!user || !W)
return
if(!user.unEquip(mod)) return
user << "You install \the [mod] into \the [src]."
user.drop_from_inventory(mod)
installed_modules |= mod
mod.forceMove(src)
mod.installed(src)
@@ -94,8 +94,8 @@
else if(!cell && istype(W,/obj/item/weapon/cell))
if(!user.unEquip(W)) return
user << "You jack \the [W] into \the [src]'s battery mount."
user.drop_from_inventory(W)
W.forceMove(src)
src.cell = W
return

View File

@@ -30,23 +30,32 @@
brightness_on = 4
on = 0
/obj/item/clothing/head/helmet/space/attack_self(mob/user)
/obj/item/clothing/head/helmet/space/initialize()
..()
if(camera_networks && camera_networks.len)
verbs += /obj/item/clothing/head/helmet/space/proc/toggle_camera
/obj/item/clothing/head/helmet/space/proc/toggle_camera()
set name = "Toggle Helmet Camera"
set category = "Object"
set src in usr
if(!camera && camera_networks)
camera = new /obj/machinery/camera(src)
camera.replace_networks(camera_networks)
camera.c_tag = user.name
user << "\blue User scanned as [camera.c_tag]. Camera activated."
user.update_action_buttons()
return 1
camera.set_status(0)
..()
if(camera)
camera.set_status(!camera.status)
if(camera.status)
camera.c_tag = FindNameFromID(usr)
usr << "<span class='notice'>User scanned as [camera.c_tag]. Camera activated.</span>"
else
usr << "<span class='notice'>Camera deactivated.</span>"
/obj/item/clothing/head/helmet/space/examine()
..()
if(camera_networks && get_dist(usr,src) <= 1)
usr << "This helmet has a built-in camera. It's [camera ? "" : "in"]active."
/obj/item/clothing/head/helmet/space/examine(var/mob/user)
if(..(user, 1) && camera_networks && camera_networks.len)
user << "This helmet has a built-in camera. It's [camera && camera.status ? "" : "in"]active."
/obj/item/clothing/suit/space
name = "Space suit"

View File

@@ -186,8 +186,11 @@
if(!istype(user,/mob/living)) return
if(istype(W,/obj/item/clothing/accessory) || istype(W, /obj/item/weapon/hand_labeler))
return ..()
if(istype(src.loc,/mob/living))
user << "<span class='danger'>How do you propose to modify a voidsuit while it is being worn?</span>"
user << "<span class='warning'>You cannot modify \the [src] while it is being worn.</span>"
return
if(istype(W,/obj/item/weapon/screwdriver))

View File

@@ -1,6 +1,6 @@
/obj/item/clothing/suit/armor
allowed = list(/obj/item/weapon/gun/energy,/obj/item/weapon/reagent_containers/spray/pepper,/obj/item/weapon/gun/projectile,/obj/item/ammo_magazine,/obj/item/ammo_casing,/obj/item/weapon/melee/baton,/obj/item/weapon/handcuffs)
allowed = list(/obj/item/weapon/gun/energy,/obj/item/device/radio,/obj/item/weapon/reagent_containers/spray/pepper,/obj/item/weapon/gun/projectile,/obj/item/ammo_magazine,/obj/item/ammo_casing,/obj/item/weapon/melee/baton,/obj/item/weapon/handcuffs)
body_parts_covered = UPPER_TORSO|LOWER_TORSO
item_flags = THICKMATERIAL
@@ -66,7 +66,7 @@
/obj/item/clothing/suit/armor/laserproof/handle_shield(mob/user, var/damage, atom/damage_source = null, mob/attacker = null, var/def_zone = null, var/attack_text = "the attack")
if(istype(damage_source, /obj/item/projectile/energy) || istype(damage_source, /obj/item/projectile/beam))
var/obj/item/projectile/P = damage_source
var/reflectchance = 40 - round(damage/3)
if(!(def_zone in list("chest", "groin")))
reflectchance /= 2
@@ -146,12 +146,12 @@
if(!turfs.len) turfs += pick(/turf in orange(6))
var/turf/picked = pick(turfs)
if(!isturf(picked)) return
var/datum/effect/effect/system/spark_spread/spark_system = new /datum/effect/effect/system/spark_spread()
spark_system.set_up(5, 0, user.loc)
spark_system.start()
playsound(user.loc, "sparks", 50, 1)
user.loc = picked
return PROJECTILE_FORCE_MISS
return 0
@@ -244,102 +244,58 @@
icon_state = "ertarmor_med"
//New Vests
/obj/item/clothing/suit/storage/vest
/obj/item/clothing/suit/armor/vest
name = "armor vest"
desc = "A simple kevlar plate carrier."
desc = "An armor vest made of synthetic fibers."
icon_state = "kvest"
item_state = "kvest"
item_state = "armor"
armor = list(melee = 50, bullet = 15, laser = 50, energy = 10, bomb = 25, bio = 0, rad = 0)
allowed = list(/obj/item/weapon/gun,/obj/item/weapon/reagent_containers/spray/pepper,/obj/item/ammo_magazine,/obj/item/ammo_casing,/obj/item/weapon/melee/baton,/obj/item/weapon/handcuffs)
/obj/item/clothing/suit/armor/vest/security
name = "security vest"
desc = "A synthetic armor vest. This one is marked with the crest of NanoTrasen."
icon_state = "secvest"
/obj/item/clothing/suit/armor/vest/detective
name = "detective armor vest"
desc = "An synthetic armor vest colored in a vintage brown."
icon_state = "detvest"
/obj/item/clothing/suit/storage/vest
name = "webbed armor vest"
desc = "A synthetic armor vest. This one has added webbing and ballistic plates."
icon_state = "webvest"
armor = list(melee = 50, bullet = 40, laser = 50, energy = 25, bomb = 30, bio = 0, rad = 0)
allowed = list(/obj/item/weapon/gun/energy,/obj/item/device/radio,/obj/item/weapon/reagent_containers/spray/pepper,/obj/item/weapon/gun/projectile,/obj/item/ammo_magazine,/obj/item/ammo_casing,/obj/item/weapon/melee/baton,/obj/item/weapon/handcuffs)
/obj/item/clothing/suit/storage/vest/officer
name = "officer armor vest"
desc = "A simple kevlar plate carrier. This one has a security holobadge clipped to the chest."
icon_state = "officervest_nobadge"
item_state = "officervest_nobadge"
icon_badge = "officervest_badge"
icon_nobadge = "officervest_nobadge"
name = "security armor vest"
desc = "A synthetic armor vest with SECURITY printed in red lettering on the chest. This one has added webbing and ballistic plates."
icon_state = "officervest"
/obj/item/clothing/suit/storage/vest/warden
name = "warden armor vest"
desc = "A simple kevlar plate carrier. This one has a silver badge clipped to the chest."
icon_state = "wardenvest_nobadge"
item_state = "wardenvest_nobadge"
icon_badge = "wardenvest_badge"
icon_nobadge = "wardenvest_nobadge"
desc = "A synthetic armor vest with WARDEN printed in silver lettering on the chest. This one has added webbing and ballistic plates."
icon_state = "wardenvest"
/obj/item/clothing/suit/storage/vest/hos
name = "commander armor vest"
desc = "A simple kevlar plate carrier. This one has a gold badge clipped to the chest."
icon_state = "hosvest_nobadge"
item_state = "hosvest_nobadge"
icon_badge = "hosvest_badge"
icon_nobadge = "hosvest_nobadge"
desc = "A synthetic armor vest with COMMANDER printed in gold lettering on the chest. This one has added webbing and ballistic plates."
icon_state = "hosvest"
/obj/item/clothing/suit/storage/vest/pcrc
name = "PCRC armor vest"
desc = "A simple kevlar plate carrier belonging to Proxima Centauri Risk Control. This one has a PCRC crest clipped to the chest."
icon_state = "pcrcvest_nobadge"
item_state = "pcrcvest_nobadge"
icon_badge = "pcrcvest_badge"
icon_nobadge = "pcrcvest_nobadge"
/obj/item/clothing/suit/storage/vest/detective
name = "detective armor vest"
desc = "A simple kevlar plate carrier in a vintage brown, it has a badge clipped to the chest that reads, 'Private investigator'."
icon_state = "detectivevest_nobadge"
item_state = "detectivevest_nobadge"
icon_badge = "detectivevest_badge"
icon_nobadge = "detectivevest_nobadge"
/obj/item/clothing/suit/storage/vest/heavy
name = "heavy armor vest"
desc = "A heavy kevlar plate carrier with webbing attached."
icon_state = "webvest"
item_state = "webvest"
armor = list(melee = 50, bullet = 40, laser = 50, energy = 25, bomb = 30, bio = 0, rad = 0)
slowdown = 1
/obj/item/clothing/suit/storage/vest/heavy/officer
name = "officer heavy armor vest"
desc = "A heavy kevlar plate carrier with webbing attached. This one has a security holobadge clipped to the chest."
icon_state = "officerwebvest_nobadge"
item_state = "officerwebvest_nobadge"
icon_badge = "officerwebvest_badge"
icon_nobadge = "officerwebvest_nobadge"
/obj/item/clothing/suit/storage/vest/heavy/warden
name = "warden heavy armor vest"
desc = "A heavy kevlar plate carrier with webbing attached. This one has a silver badge clipped to the chest."
icon_state = "wardenwebvest_nobadge"
item_state = "wardenwebvest_nobadge"
icon_badge = "wardenwebvest_badge"
icon_nobadge = "wardenwebvest_nobadge"
/obj/item/clothing/suit/storage/vest/heavy/hos
name = "commander heavy armor vest"
desc = "A heavy kevlar plate carrier with webbing attached. This one has a gold badge clipped to the chest."
icon_state = "hoswebvest_nobadge"
item_state = "hoswebvest_nobadge"
icon_badge = "hoswebvest_badge"
icon_nobadge = "hoswebvest_nobadge"
/obj/item/clothing/suit/storage/vest/heavy/pcrc
name = "PCRC heavy armor vest"
desc = "A heavy kevlar plate carrier belonging to Proxima Centauri Risk Control with webbing attached. This one has a PCRC crest clipped to the chest."
icon_state = "pcrcwebvest_nobadge"
item_state = "pcrcwebvest_nobadge"
icon_badge = "pcrcwebvest_badge"
icon_nobadge = "pcrcwebvest_nobadge"
desc = "A synthetic armor vest with SECURITY printed in cyan lettering on the chest. This one has added webbing and ballistic plates."
icon_state = "pcrcvest"
//Provides the protection of a merc voidsuit, but only covers the chest/groin, and also takes up a suit slot. In exchange it has no slowdown and provides storage.
/obj/item/clothing/suit/storage/vest/heavy/merc
/obj/item/clothing/suit/storage/vest/merc
name = "heavy armor vest"
desc = "A high-quality heavy kevlar plate carrier in a fetching tan. The vest is surprisingly flexible, and possibly made of an advanced material."
desc = "A high-quality armor vest in a fetching tan. It is surprisingly flexible and light, even with the added webbing and armor plating."
icon_state = "mercwebvest"
item_state = "mercwebvest"
armor = list(melee = 60, bullet = 60, laser = 60, energy = 40, bomb = 40, bio = 0, rad = 0)
slowdown = 0
//All of the armor below is mostly unused

View File

@@ -52,32 +52,10 @@
update_clothing_icon() //so our overlays update
//New Vest 4 pocket storage and badge toggles, until suit accessories are a thing.
/obj/item/clothing/suit/storage/vest/heavy/New()
/obj/item/clothing/suit/storage/vest/merc/New()
..()
pockets = new/obj/item/weapon/storage/internal(src)
pockets.storage_slots = 4
pockets.max_w_class = 2
pockets.max_storage_space = 8
/obj/item/clothing/suit/storage/vest
var/icon_badge
var/icon_nobadge
verb/toggle()
set name ="Adjust Badge"
set category = "Object"
set src in usr
if(!usr.canmove || usr.stat || usr.restrained())
return 0
if(icon_state == icon_badge)
icon_state = icon_nobadge
usr << "You conceal \the [src]'s badge."
else if(icon_state == icon_nobadge)
icon_state = icon_badge
usr << "You reveal \the [src]'s badge."
else
usr << "\The [src] does not have a vest badge."
return
update_clothing_icon()

View File

@@ -7,16 +7,20 @@
slot_flags = SLOT_TIE
w_class = 2.0
var/slot = "decor"
var/obj/item/clothing/under/has_suit = null //the suit the tie may be attached to
var/obj/item/clothing/has_suit = null //the suit the tie may be attached to
var/image/inv_overlay = null //overlay used when attached to clothing.
var/image/mob_overlay = null
var/overlay_state = null
/obj/item/clothing/accessory/Destroy()
on_removed()
return ..()
/obj/item/clothing/accessory/proc/get_inv_overlay()
if(!inv_overlay)
if(!mob_overlay)
get_mob_overlay()
var/tmp_icon_state = "[overlay_state? "[overlay_state]" : "[icon_state]"]"
if(icon_override)
if("[tmp_icon_state]_tie" in icon_states(icon_override))
@@ -36,23 +40,26 @@
return mob_overlay
//when user attached an accessory to S
/obj/item/clothing/accessory/proc/on_attached(obj/item/clothing/under/S, mob/user as mob)
/obj/item/clothing/accessory/proc/on_attached(var/obj/item/clothing/S, var/mob/user)
if(!istype(S))
return
has_suit = S
loc = has_suit
has_suit.overlays += get_inv_overlay()
user << "<span class='notice'>You attach [src] to [has_suit].</span>"
user << "<span class='notice'>You attach \the [src] to \the [has_suit].</span>"
src.add_fingerprint(user)
/obj/item/clothing/accessory/proc/on_removed(mob/user as mob)
/obj/item/clothing/accessory/proc/on_removed(var/mob/user)
if(!has_suit)
return
has_suit.overlays -= get_inv_overlay()
has_suit = null
usr.put_in_hands(src)
src.add_fingerprint(user)
if(user)
usr.put_in_hands(src)
src.add_fingerprint(user)
else
src.forceMove(get_turf(src))
//default attackby behaviour
/obj/item/clothing/accessory/attackby(obj/item/I, mob/user)

View File

@@ -6,8 +6,9 @@
/obj/item/clothing/accessory/badge
name = "detective's badge"
desc = "Security Department detective's badge, made from gold."
desc = "A corporate security badge, made from gold and set on false leather."
icon_state = "badge"
item_state = "marshalbadge"
slot_flags = SLOT_BELT | SLOT_TIE
var/stored_name
@@ -25,7 +26,7 @@
/obj/item/clothing/accessory/badge/attack_self(mob/user as mob)
if(!stored_name)
user << "You polish your old badge fondly, shining up the surface."
user << "You polish your badge fondly, shining up the surface."
set_name(user.real_name)
return
@@ -38,14 +39,13 @@
/obj/item/clothing/accessory/badge/attack(mob/living/carbon/human/M, mob/living/user)
if(isliving(user))
user.visible_message("<span class='danger'>[user] invades [M]'s personal space, thrusting [src] into their face insistently.</span>","<span class='danger'>You invade [M]'s personal space, thrusting [src] into their face insistently.</span>")
user.do_attack_animation(M)
user.setClickCooldown(DEFAULT_QUICK_COOLDOWN) //to prevent spam
//.Holobadges.
/obj/item/clothing/accessory/badge/holo
name = "holobadge"
desc = "This glowing blue badge marks the holder as THE LAW."
desc = "This glowing blue badge marks the holder as a member of corporate security."
icon_state = "holobadge"
item_state = "holobadge"
var/emagged //Emagging removes Sec check.
/obj/item/clothing/accessory/badge/holo/cord
@@ -98,3 +98,24 @@
new /obj/item/clothing/accessory/badge/holo/cord(src)
..()
return
/obj/item/clothing/accessory/badge/warden
name = "warden's badge"
desc = "A silver corporate security badge. Stamped with the words 'Brig Officer.'"
icon_state = "silverbadge"
slot_flags = SLOT_TIE
/obj/item/clothing/accessory/badge/hos
name = "commander's badge"
desc = "An immaculately polished gold security badge. Labeled 'Commander.'"
icon_state = "goldbadge"
slot_flags = SLOT_TIE
/obj/item/clothing/accessory/badge/marshal
name = "marshal's badge"
desc = "A leather-backed gold badge displaying the crest of the Colonial Marshals."
icon_state = "marshalbadge"
badge_string = "Colonial Marshal Bureau"

View File

@@ -25,10 +25,23 @@
material = "carbon"
/obj/item/weapon/ore/glass
name = "impure silicates"
name = "sand"
icon_state = "ore_glass"
origin_tech = list(TECH_MATERIAL = 1)
material = "sand"
slot_flags = SLOT_HOLSTER
// POCKET SAND!
/obj/item/weapon/ore/glass/throw_impact(atom/hit_atom)
..()
var/mob/living/carbon/human/H = hit_atom
if(istype(H) && H.has_eyes() && prob(85))
H << "<span class='danger'>Some of \the [src] gets in your eyes!</span>"
H.eye_blind += 5
H.eye_blurry += 10
spawn(1)
if(istype(loc, /turf/)) qdel(src)
/obj/item/weapon/ore/phoron
name = "phoron crystals"

View File

@@ -59,7 +59,7 @@ var/global/list/ore_data = list()
/ore/glass
name = "sand"
display_name = "impure silicates"
display_name = "sand"
smelts_to = "glass"
compresses_to = "sandstone"

View File

@@ -18,7 +18,7 @@
ai.ai_cancel_tracking()
//Holopad
if(ai.holo)
if(ai.holo && ai.hologram_follow)
ai.holo.move_hologram(ai)
return 1

View File

@@ -40,6 +40,17 @@ var/list/holder_mob_icon_cache = list()
qdel(src)
/obj/item/weapon/holder/GetID()
for(var/mob/M in contents)
var/obj/item/I = M.GetIdCard()
if(I)
return I
return null
/obj/item/weapon/holder/GetAccess()
var/obj/item/I = GetID()
return I ? I.GetAccess() : ..()
/obj/item/weapon/holder/proc/sync(var/mob/living/M)
dir = 2
overlays.Cut()

View File

@@ -103,64 +103,34 @@ var/list/slot_equipment_priority = list( \
//Puts the item into your l_hand if possible and calls all necessary triggers/updates. returns 1 on success.
/mob/proc/put_in_l_hand(var/obj/item/W)
if(lying) return 0
if(!istype(W)) return 0
if(!l_hand)
W.forceMove(src) //TODO: move to equipped?
l_hand = W
W.layer = 20 //TODO: move to equipped?
// l_hand.screen_loc = ui_lhand
W.equipped(src,slot_l_hand)
if(client) client.screen |= W
if(pulling == W) stop_pulling()
update_inv_l_hand()
return 1
return 0
if(lying || !istype(W))
return 0
return 1
//Puts the item into your r_hand if possible and calls all necessary triggers/updates. returns 1 on success.
/mob/proc/put_in_r_hand(var/obj/item/W)
if(lying) return 0
if(!istype(W)) return 0
if(!r_hand)
W.forceMove(src)
r_hand = W
W.layer = 20
// r_hand.screen_loc = ui_rhand
W.equipped(src,slot_r_hand)
if(client) client.screen |= W
if(pulling == W) stop_pulling()
update_inv_r_hand()
return 1
return 0
if(lying || !istype(W))
return 0
return 1
//Puts the item into our active hand if possible. returns 1 on success.
/mob/proc/put_in_active_hand(var/obj/item/W)
if(hand) return put_in_l_hand(W)
else return put_in_r_hand(W)
return 0 // Moved to human procs because only they need to use hands.
//Puts the item into our inactive hand if possible. returns 1 on success.
/mob/proc/put_in_inactive_hand(var/obj/item/W)
if(hand) return put_in_r_hand(W)
else return put_in_l_hand(W)
return 0 // As above.
//Puts the item our active hand if possible. Failing that it tries our inactive hand. Returns 1 on success.
//If both fail it drops it on the floor and returns 0.
//This is probably the main one you need to know :)
/mob/proc/put_in_hands(var/obj/item/W)
if(!W) return 0
if(put_in_active_hand(W))
update_inv_l_hand()
update_inv_r_hand()
return 1
else if(put_in_inactive_hand(W))
update_inv_l_hand()
update_inv_r_hand()
return 1
else
W.forceMove(get_turf(src))
W.layer = initial(W.layer)
W.dropped()
if(!W)
return 0
W.forceMove(get_turf(src))
W.layer = initial(W.layer)
W.dropped()
return 0
// Removes an item from inventory and places it in the target atom.
// If canremove or other conditions need to be checked then use unEquip instead.

View File

@@ -107,12 +107,9 @@
space_chance = 10
/datum/language/machine/get_random_name()
var/new_name
if(prob(70))
new_name = "[pick(list("PBU","HIU","SINA","ARMA","OSI"))]-[rand(100, 999)]"
else
new_name = pick(ai_names)
return new_name
return "[pick(list("PBU","HIU","SINA","ARMA","OSI"))]-[rand(100, 999)]"
return pick(ai_names)
/datum/language/resomi
name = "Resomi"

View File

@@ -83,7 +83,11 @@
break
. += copytext(message, 1, min_index)
if(copytext(message, min_index, min_index+1) == uppertext(min_char))
. += capitalize(pick(map[min_char]))
switch(text2ascii(message, min_index+1))
if(65 to 90) // A-Z, uppercase; uppercase R/S followed by another uppercase letter, uppercase the entire replacement string
. += uppertext(pick(map[min_char]))
else
. += capitalize(pick(map[min_char]))
else
. += pick(map[min_char])
message = copytext(message, min_index + 1)

View File

@@ -8,6 +8,10 @@
death_msg = "expires with a pitiful chirrup..."
universal_understand = 1
universal_speak = 0 // Dionaea do not need to speak to people other than other dionaea.
can_pull_size = 2
can_pull_mobs = MOB_PULL_SMALLER
holder_type = /obj/item/weapon/holder/diona
possession_candidate = 1
var/obj/item/hat
@@ -18,19 +22,6 @@
species = all_species["Diona"]
verbs += /mob/living/carbon/alien/diona/proc/merge
/mob/living/carbon/alien/diona/start_pulling(var/atom/movable/AM)
//TODO: Collapse these checks into one proc (see pai and drone)
if(istype(AM,/obj/item))
var/obj/item/O = AM
if(O.w_class > 2)
src << "<span class='warning'>You are too small to pull that.</span>"
return
else
..()
else
src << "<span class='warning'>You are too small to pull that.</span>"
return
/mob/living/carbon/alien/diona/put_in_hands(var/obj/item/W) // No hands.
W.loc = get_turf(src)
return 1

View File

@@ -1,53 +1,41 @@
mob/living/carbon/verb/give(var/mob/living/carbon/target in view(1)-usr)
/mob/living/carbon/human/verb/give(var/mob/living/target in view(1)-usr)
set category = "IC"
set name = "Give"
if(!istype(target) || target.stat == 2 || usr.stat == 2|| target.client == null)
if(incapacitated())
return
var/obj/item/I
if(!usr.hand && usr.r_hand == null)
usr << "<span class='warning'>You don't have anything in your right hand to give to [target.name]</span>"
if(!istype(target) || target.stat || target.lying || target.resting || target.buckled || target.client == null)
return
if(usr.hand && usr.l_hand == null)
usr << "<span class='warning'>You don't have anything in your left hand to give to [target.name]</span>"
return
if(usr.hand)
I = usr.l_hand
else if(!usr.hand)
I = usr.r_hand
var/obj/item/I = usr.get_active_hand()
if(!I)
I = usr.get_inactive_hand()
if(!I)
usr << "<span class='warning'>You don't have anything in your hands to give to \the [target].</span>"
return
if(target.r_hand == null || target.l_hand == null)
switch(alert(target,"[usr] wants to give you \a [I]?",,"Yes","No"))
if("Yes")
if(!I)
return
if(!Adjacent(usr))
usr << "<span class='warning'>You need to stay in reaching distance while giving an object.</span>"
target << "<span class='warning'>[usr.name] moved too far away.</span>"
return
if((usr.hand && usr.l_hand != I) || (!usr.hand && usr.r_hand != I))
usr << "<span class='warning'>You need to keep the item in your active hand.</span>"
target << "<span class='warning'>[usr.name] seem to have given up on giving \the [I.name] to you.</span>"
return
if(target.r_hand != null && target.l_hand != null)
target << "<span class='warning'>Your hands are full.</span>"
usr << "<span class='warning'>Their hands are full.</span>"
return
else
usr.drop_item()
if(target.r_hand == null)
target.r_hand = I
else
target.l_hand = I
I.loc = target
I.layer = 20
I.add_fingerprint(target)
target.update_inv_l_hand()
target.update_inv_r_hand()
usr.update_inv_l_hand()
usr.update_inv_r_hand()
target.visible_message("<span class='notice'>[usr.name] handed \the [I.name] to [target.name].</span>")
if("No")
target.visible_message("<span class='warning'>[usr.name] tried to hand [I.name] to [target.name] but [target.name] didn't want it.</span>")
else
usr << "<span class='warning'>[target.name]'s hands are full.</span>"
if(alert(target,"[usr] wants to give you \a [I]. Will you accept it?",,"No","Yes") == "No")
target.visible_message("<span class='notice'>\The [usr] tried to hand \the [I] to \the [target], \
but \the [target] didn't want it.</span>")
return
if(!I) return
if(!Adjacent(target))
usr << "<span class='warning'>You need to stay in reaching distance while giving an object.</span>"
target << "<span class='warning'>\The [usr] moved too far away.</span>"
return
if(I.loc != usr || (usr.l_hand != I && usr.r_hand != I))
usr << "<span class='warning'>You need to keep the item in your hands.</span>"
target << "<span class='warning'>\The [usr] seems to have given up on passing \the [I] to you.</span>"
return
if(target.r_hand != null && target.l_hand != null)
target << "<span class='warning'>Your hands are full.</span>"
usr << "<span class='warning'>Their hands are full.</span>"
return
if(usr.unEquip(I))
target.put_in_hands(I) // If this fails it will just end up on the floor, but that's fitting for things like dionaea.
target.visible_message("<span class='notice'>\The [usr] handed \the [I] to \the [target].</span>")

View File

@@ -215,6 +215,7 @@
msg += "<span class='warning'>[T.He] [T.is] on fire!.</span>\n"
msg += "<span class='warning'>"
/*
if(nutrition < 100)
msg += "[T.He] [T.is] severely malnourished.\n"
else if(nutrition >= 500)
@@ -222,6 +223,7 @@
msg += "[T.He] [T.is] plump and delicious looking - Like a fat little piggy. A tasty piggy.\n"
else*/
msg += "[T.He] [T.is] quite chubby.\n"
*/
msg += "</span>"

View File

@@ -1388,3 +1388,56 @@
get_scooped(H)
return
return ..()
//Puts the item into our active hand if possible. returns 1 on success.
/mob/living/carbon/human/put_in_active_hand(var/obj/item/W)
return (hand ? put_in_l_hand(W) : put_in_r_hand(W))
//Puts the item into our inactive hand if possible. returns 1 on success.
/mob/living/carbon/human/put_in_inactive_hand(var/obj/item/W)
return (hand ? put_in_r_hand(W) : put_in_l_hand(W))
/mob/living/carbon/human/put_in_hands(var/obj/item/W)
if(!W)
return 0
if(put_in_active_hand(W))
update_inv_l_hand()
update_inv_r_hand()
return 1
else if(put_in_inactive_hand(W))
update_inv_l_hand()
update_inv_r_hand()
return 1
else
return ..()
/mob/living/carbon/human/put_in_l_hand(var/obj/item/W)
if(!..() || l_hand)
return 0
W.forceMove(src)
l_hand = W
W.equipped(src,slot_l_hand)
W.add_fingerprint(src)
update_inv_l_hand()
return 1
/mob/living/carbon/human/put_in_r_hand(var/obj/item/W)
if(!..() || r_hand)
return 0
W.forceMove(src)
r_hand = W
W.equipped(src,slot_r_hand)
W.add_fingerprint(src)
update_inv_r_hand()
return 1
/mob/living/carbon/human/verb/pull_punches()
set name = "Pull Punches"
set desc = "Try not to hurt them."
set category = "IC"
if(stat) return
pulling_punches = !pulling_punches
src << "<span class='notice'>You are now [pulling_punches ? "pulling your punches" : "not pulling your punches"].</span>"
return

View File

@@ -1,6 +1,10 @@
/mob/living/carbon/human/proc/get_unarmed_attack(var/mob/living/carbon/human/target, var/hit_zone)
for(var/datum/unarmed_attack/u_attack in species.unarmed_attacks)
if(u_attack.is_usable(src, target, hit_zone))
if(pulling_punches)
var/datum/unarmed_attack/soft_variant = u_attack.get_sparring_variant()
if(soft_variant)
return soft_variant
return u_attack
return null
@@ -221,7 +225,7 @@
attack.apply_effects(H, src, armour, rand_damage, hit_zone)
// Finally, apply damage to target
apply_damage(real_damage, BRUTE, affecting, armour, sharp=attack.sharp, edge=attack.edge)
apply_damage(real_damage, (attack.deal_halloss ? HALLOSS : BRUTE), affecting, armour, sharp=attack.sharp, edge=attack.edge)
if(I_DISARM)
M.attack_log += text("\[[time_stamp()]\] <font color='red'>Disarmed [src.name] ([src.ckey])</font>")

View File

@@ -81,6 +81,7 @@
var/list/flavor_texts = list()
var/gunshot_residue
var/pulling_punches // Are you trying not to hurt your opponent?
mob_bump_flag = HUMAN
mob_push_flags = ~HEAVY

View File

@@ -1,15 +1,7 @@
/*
Add fingerprints to items when we put them in our hands.
This saves us from having to call add_fingerprint() any time something is put in a human's hands programmatically.
*/
/mob/living/carbon/human/put_in_l_hand(var/obj/item/W)
. = ..()
if(.) W.add_fingerprint(src)
/mob/living/carbon/human/put_in_r_hand(var/obj/item/W)
. = ..()
if(.) W.add_fingerprint(src)
/mob/living/carbon/human/verb/quick_equip()
set name = "quick-equip"

View File

@@ -173,11 +173,6 @@
for(var/u_type in unarmed_types)
unarmed_attacks += new u_type()
if(gluttonous)
if(!inherent_verbs)
inherent_verbs = list()
inherent_verbs |= /mob/living/carbon/human/proc/regurgitate
/datum/species/proc/get_station_variant()
return name

View File

@@ -273,7 +273,7 @@
halloss_message_self = "ERROR: Unrecoverable machine check exception.<BR>System halted, rebooting..."
warning_low_pressure = 50
hazard_low_pressure = 0
hazard_low_pressure = -1
cold_level_1 = 50
cold_level_2 = -1
@@ -316,11 +316,18 @@
"r_foot" = list("path" = /obj/item/organ/external/foot/right/ipc)
)
heat_discomfort_level = 373.15
heat_discomfort_strings = list(
"Your CPU temperature probes warn you that you are approaching critical heat levels!"
)
/datum/species/machine/handle_death(var/mob/living/carbon/human/H)
..()
H.h_style = ""
spawn(100)
if(H) H.update_hair()
/datum/species/machine/sanitize_name(var/name)
return sanitizeName(name, allow_numbers = 1)
/datum/species/machine/sanitize_name(var/new_name)
return sanitizeName(new_name, allow_numbers = 1)

View File

@@ -71,6 +71,7 @@ var/const/MAX_ACTIVE_TIME = 400
return
/obj/item/clothing/mask/facehugger/equipped(mob/M)
..()
Attach(M)
/obj/item/clothing/mask/facehugger/Crossed(atom/target)

View File

@@ -1,3 +1,5 @@
var/global/list/sparring_attack_cache = list()
//Species unarmed attacks
/datum/unarmed_attack
var/attack_verb = list("attack") // Empty hand hurt intent verb.
@@ -8,10 +10,19 @@
var/shredding = 0 // Calls the old attack_alien() behavior on objects/mobs when on harm intent.
var/sharp = 0
var/edge = 0
var/deal_halloss
var/sparring_variant_type = /datum/unarmed_attack/light_strike
var/eye_attack_text
var/eye_attack_text_victim
/datum/unarmed_attack/proc/get_sparring_variant()
if(sparring_variant_type)
if(!sparring_attack_cache[sparring_variant_type])
sparring_attack_cache[sparring_variant_type] = new sparring_variant_type()
return sparring_attack_cache[sparring_variant_type]
/datum/unarmed_attack/proc/is_usable(var/mob/living/carbon/human/user, var/mob/living/carbon/human/target, var/zone)
if(user.restrained())
return 0
@@ -87,7 +98,7 @@
/datum/unarmed_attack/proc/handle_eye_attack(var/mob/living/carbon/human/user, var/mob/living/carbon/human/target)
var/obj/item/organ/eyes/eyes = target.internal_organs_by_name["eyes"]
eyes.take_damage(rand(3,4), 1)
user.visible_message("<span class='danger'>[user] presses \his [eye_attack_text] into [target]'s [eyes.name]!</span>")
target << "<span class='danger'>You experience[(target.species.flags & NO_PAIN)? "" : " immense pain as you feel" ] [eye_attack_text_victim] being pressed into your [eyes.name][(target.species.flags & NO_PAIN)? "." : "!"]</span>"
@@ -237,3 +248,13 @@
switch(attack_damage)
if(1 to 4) user.visible_message("<span class='danger'>[pick("[user] stomped on", "[user] slammed \his [shoes ? copytext(shoes.name, 1, -1) : "foot"] down onto")] [target]'s [organ]!</span>")
if(5) user.visible_message("<span class='danger'>[pick("[user] landed a powerful stomp on", "[user] stomped down hard on", "[user] slammed \his [shoes ? copytext(shoes.name, 1, -1) : "foot"] down hard onto")] [target]'s [organ]!</span>") //Devastated lol. No. We want to say that the stomp was powerful or forceful, not that it /wrought devastation/
/datum/unarmed_attack/light_strike
deal_halloss = 3
attack_noun = list("tap","light strike")
attack_verb = list("tapped", "lightly struck")
damage = 2
shredding = 0
damage = 0
sharp = 0
edge = 0

View File

@@ -770,6 +770,12 @@ var/global/list/damage_icon_parts = list()
bloodsies.color = wear_suit.blood_color
standing.overlays += bloodsies
// Accessories - copied from uniform, BOILERPLATE because fuck this system.
var/obj/item/clothing/suit/suit = wear_suit
if(istype(suit) && suit.accessories.len)
for(var/obj/item/clothing/accessory/A in suit.accessories)
standing.overlays |= A.get_mob_overlay()
overlays_standing[SUIT_LAYER] = standing
update_tail_showing(0)

View File

@@ -20,7 +20,7 @@
return
..()
if(handcuffed)
spawn() escape_handcuffs()
else if(legcuffed)
@@ -29,9 +29,9 @@
/mob/living/carbon/proc/escape_handcuffs()
//if(!(last_special <= world.time)) return
//These two lines represent a significant buff to grabs...
if(!canClick()) return
setClickCooldown(100)
//This line represent a significant buff to grabs...
// We don't have to check the click cooldown because /mob/living/verb/resist() has done it for us, we can simply set the delay
setClickCooldown(100)
if(can_break_cuffs()) //Don't want to do a lot of logic gating here.
break_handcuffs()
@@ -47,8 +47,13 @@
breakouttime = HC.breakouttime
displaytime = breakouttime / 600 //Minutes
var/mob/living/carbon/human/H = src
if(istype(H) && H.gloves && istype(H.gloves,/obj/item/clothing/gloves/rig))
breakouttime /= 2
displaytime /= 2
visible_message(
"<span class='danger'>[src] attempts to remove \the [HC]!</span>",
"<span class='danger'>\The [src] attempts to remove \the [HC]!</span>",
"<span class='warning'>You attempt to remove \the [HC]. (This will take around [displaytime] minutes and you need to stand still)</span>"
)
@@ -56,16 +61,16 @@
if(!handcuffed || buckled)
return
visible_message(
"<span class='danger'>[src] manages to remove \the [handcuffed]!</span>",
"<span class='danger'>\The [src] manages to remove \the [handcuffed]!</span>",
"<span class='notice'>You successfully remove \the [handcuffed].</span>"
)
drop_from_inventory(handcuffed)
/mob/living/carbon/proc/escape_legcuffs()
/mob/living/carbon/proc/escape_legcuffs()
if(!canClick())
return
setClickCooldown(100)
setClickCooldown(100)
if(can_break_cuffs()) //Don't want to do a lot of logic gating here.
break_legcuffs()

View File

@@ -98,6 +98,9 @@ default behaviour is:
if(!can_move_mob(tmob, 0, 0))
now_pushing = 0
return
if(a_intent == I_HELP || src.restrained())
now_pushing = 0
return
if(istype(tmob, /mob/living/carbon/human) && (FAT in tmob.mutations))
if(prob(40) && !(FAT in src.mutations))
src << "<span class='danger'>You fail to push [tmob]'s fat ass out of the way.</span>"

View File

@@ -23,7 +23,8 @@ var/list/ai_verbs_default = list(
/mob/living/silicon/ai/proc/sensor_mode,
/mob/living/silicon/ai/proc/show_laws_verb,
/mob/living/silicon/ai/proc/toggle_acceleration,
/mob/living/silicon/ai/proc/toggle_camera_light
/mob/living/silicon/ai/proc/toggle_camera_light,
/mob/living/silicon/ai/proc/toggle_hologram_movement
)
//Not sure why this is necessary...
@@ -61,6 +62,7 @@ var/list/ai_verbs_default = list(
var/control_disabled = 0
var/datum/announcement/priority/announcement
var/obj/machinery/ai_powersupply/psupply = null // Backwards reference to AI's powersupply object.
var/hologram_follow = 1 //This is used for the AI eye, to determine if a holopad's hologram should follow it or not
//NEWMALF VARIABLES
var/malfunctioning = 0 // Master var that determines if AI is malfunctioning.
@@ -203,6 +205,7 @@ var/list/ai_verbs_default = list(
/mob/living/silicon/ai/Destroy()
ai_list -= src
qdel(eyeobj)
eyeobj = null
..()
/mob/living/silicon/ai/proc/setup_icon()
@@ -644,6 +647,14 @@ var/list/ai_verbs_default = list(
set desc = "Augment visual feed with internal sensor overlays"
toggle_sensor_mode()
/mob/living/silicon/ai/proc/toggle_hologram_movement()
set name = "Toggle Hologram Movement"
set category = "AI Commands"
set desc = "Toggles hologram movement based on moving with your virtual eye."
hologram_follow = !hologram_follow
usr << "<span class='info'>Your hologram will now [hologram_follow ? "follow" : "no longer follow"] you.</span>"
/mob/living/silicon/ai/proc/check_unable(var/flags = 0, var/feedback = 1)
if(stat == DEAD)
if(feedback) src << "<span class='warning'>You are dead!</span>"

View File

@@ -1,5 +1,5 @@
// Originally a debug verb, made it a proper adminverb for ~fun~
/client/proc/makePAI(turf/t in view(), name as text, pai_key as null|text)
/client/proc/makePAI(turf/t in range(world.view), name as text, pai_key as null|text)
set name = "Make pAI"
set category = "Admin"

View File

@@ -393,18 +393,6 @@
resting = 0
icon_state = "[chassis]"
/mob/living/silicon/pai/start_pulling(var/atom/movable/AM)
if(istype(AM,/obj/item))
var/obj/item/O = AM
if(O.w_class == 1)
..()
else
src << "<span class='warning'>You are too small to pull that.</span>"
else
src << "<span class='warning'>You are too small to pull that.</span>"
return
// No binary for pAIs.
/mob/living/silicon/pai/binarycheck()
return 0

View File

@@ -38,6 +38,9 @@ var/list/mob_hat_cache = list()
local_transmit = 1
possession_candidate = 1
can_pull_size = 3
can_pull_mobs = MOB_PULL_SMALLER
mob_bump_flag = SIMPLE_ANIMAL
mob_swap_flags = SIMPLE_ANIMAL
mob_push_flags = SIMPLE_ANIMAL
@@ -50,8 +53,6 @@ var/list/mob_hat_cache = list()
var/obj/machinery/drone_fabricator/master_fabricator
var/law_type = /datum/ai_laws/drone
var/module_type = /obj/item/weapon/robot_module/drone
var/can_pull_size = 2
var/can_pull_mobs
var/obj/item/hat
var/hat_x_offset = 0
var/hat_y_offset = -13
@@ -92,10 +93,10 @@ var/list/mob_hat_cache = list()
icon_state = "constructiondrone"
law_type = /datum/ai_laws/construction_drone
module_type = /obj/item/weapon/robot_module/drone/construction
can_pull_size = 5
can_pull_mobs = 1
hat_x_offset = 1
hat_y_offset = -12
can_pull_size = 5
can_pull_mobs = MOB_PULL_SAME
/mob/living/silicon/robot/drone/New()
@@ -341,20 +342,6 @@ var/list/mob_hat_cache = list()
src << "Remember, you are <b>lawed against interference with the crew</b>. Also remember, <b>you DO NOT take orders from the AI.</b>"
src << "Use <b>say ;Hello</b> to talk to other drones and <b>say Hello</b> to speak silently to your nearby fellows."
/mob/living/silicon/robot/drone/start_pulling(var/atom/movable/AM)
if(!(istype(AM,/obj/item/pipe) || istype(AM,/obj/structure/disposalconstruct)))
if(istype(AM,/obj/item))
var/obj/item/O = AM
if(O.w_class > can_pull_size)
src << "<span class='warning'>You are too small to pull that.</span>"
return
else
if(!can_pull_mobs)
src << "<span class='warning'>You are too small to pull that.</span>"
return
..()
/mob/living/silicon/robot/drone/add_robot_verbs()
src.verbs |= silicon_subsystems

View File

@@ -162,7 +162,8 @@ var/global/list/robot_modules = list(
sprites = list( "Basic" = "robot_old",
"Android" = "droid",
"Default" = "robot",
"Drone" = "drone-standard"
"Drone" = "drone-standard",
"Eyebot" = "eyebot-standard"
)
/obj/item/weapon/robot_module/standard/New()
@@ -189,7 +190,8 @@ var/global/list/robot_modules = list(
"Standard" = "surgeon",
"Advanced Droid" = "droid-medical",
"Needles" = "medicalrobot",
"Drone" = "drone-surgery"
"Drone" = "drone-surgery",
"Eyebot" = "eyebot-medical"
)
/obj/item/weapon/robot_module/medical/surgeon/New()
@@ -240,7 +242,8 @@ var/global/list/robot_modules = list(
"Advanced Droid" = "droid-medical",
"Needles" = "medicalrobot",
"Drone - Medical" = "drone-medical",
"Drone - Chemistry" = "drone-chemistry"
"Drone - Chemistry" = "drone-chemistry",
"Eyebot" = "eyebot-medical"
)
/obj/item/weapon/robot_module/medical/crisis/New()
@@ -305,7 +308,8 @@ var/global/list/robot_modules = list(
"Antique" = "engineerrobot",
"Landmate" = "landmate",
"Landmate - Treaded" = "engiborg+tread",
"Drone" = "drone-engineer"
"Drone" = "drone-engineer",
"Eyebot" = "eyebot-engineering"
)
/obj/item/weapon/robot_module/engineering/construction
@@ -420,7 +424,8 @@ var/global/list/robot_modules = list(
"Black Knight" = "securityrobot",
"Bloodhound" = "bloodhound",
"Bloodhound - Treaded" = "secborg+tread",
"Drone" = "drone-sec"
"Drone" = "drone-sec",
"Eyebot" = "eyebot-security"
)
/obj/item/weapon/robot_module/security/general/New()
@@ -452,7 +457,8 @@ var/global/list/robot_modules = list(
"Basic" = "JanBot2",
"Mopbot" = "janitorrobot",
"Mop Gear Rex" = "mopgearrex",
"Drone" = "drone-janitor"
"Drone" = "drone-janitor",
"Eyebot" = "eyebot-janitor"
)
/obj/item/weapon/robot_module/janitor/New()
@@ -495,7 +501,8 @@ var/global/list/robot_modules = list(
"Rich" = "maximillion",
"Default" = "Service2",
"Drone - Service" = "drone-service",
"Drone - Hydro" = "drone-hydro"
"Drone - Hydro" = "drone-hydro",
"Eyebot" = "eyebot-standard"
)
/obj/item/weapon/robot_module/clerical/butler/New()
@@ -537,7 +544,8 @@ var/global/list/robot_modules = list(
"Bro" = "Brobot",
"Rich" = "maximillion",
"Default" = "Service2",
"Drone" = "drone-service"
"Drone" = "drone-service",
"Eyebot" = "eyebot-standard"
)
/obj/item/weapon/robot_module/clerical/general/New()
@@ -565,7 +573,8 @@ var/global/list/robot_modules = list(
"Basic" = "Miner_old",
"Advanced Droid" = "droid-miner",
"Treadhead" = "Miner",
"Drone" = "drone-miner"
"Drone" = "drone-miner",
"Eyebot" = "eyebot-miner"
)
supported_upgrades = list(/obj/item/borg/upgrade/jetpack)
@@ -588,7 +597,8 @@ var/global/list/robot_modules = list(
channels = list("Science" = 1)
sprites = list(
"Droid" = "droid-science",
"Drone" = "drone-science"
"Drone" = "drone-science",
"Eyebot" = "eyebot-science"
)
/obj/item/weapon/robot_module/research/New()
@@ -672,7 +682,7 @@ var/global/list/robot_modules = list(
no_slip = 1
networks = list(NETWORK_ENGINEERING)
/obj/item/weapon/robot_module/drone/New()
/obj/item/weapon/robot_module/drone/New(var/mob/living/silicon/robot/robot)
src.modules += new /obj/item/weapon/weldingtool(src)
src.modules += new /obj/item/weapon/screwdriver(src)
src.modules += new /obj/item/weapon/wrench(src)
@@ -682,6 +692,11 @@ var/global/list/robot_modules = list(
src.modules += new /obj/item/device/lightreplacer(src)
src.modules += new /obj/item/weapon/gripper(src)
src.modules += new /obj/item/weapon/soap(src)
src.modules += new /obj/item/weapon/extinguisher(src)
robot.internals = new/obj/item/weapon/tank/jetpack/carbondioxide(src)
src.modules += robot.internals
src.emag = new /obj/item/weapon/pickaxe/plasmacutter(src)
src.emag.name = "Plasma Cutter"

View File

@@ -40,7 +40,7 @@
/mob/living/silicon/Destroy()
silicon_mob_list -= src
for(var/datum/alarm_handler/AH in alarm_manager.all_handlers)
AH.unregister(src)
AH.unregister_alarm(src)
..()
/mob/living/silicon/proc/init_id()

View File

@@ -39,7 +39,7 @@
return
for(var/datum/alarm_handler/AH in alarm_manager.all_handlers)
AH.register(src, /mob/living/silicon/proc/receive_alarm)
AH.register_alarm(src, /mob/living/silicon/proc/receive_alarm)
queued_alarms[AH] = list() // Makes sure alarms remain listed in consistent order
/********************

View File

@@ -31,6 +31,9 @@
mob_size = MOB_MINISCULE
possession_candidate = 1
can_pull_size = 1
can_pull_mobs = MOB_PULL_NONE
/mob/living/simple_animal/mouse/Life()
..()
if(!stat && prob(speak_chance))
@@ -90,10 +93,6 @@
return
..()
/mob/living/simple_animal/mouse/start_pulling(var/atom/movable/AM)//Prevents mouse from pulling things
src << "<span class='warning'>You are too small to pull anything.</span>"
return
/mob/living/simple_animal/mouse/Crossed(AM as mob|obj)
if( ishuman(AM) )
if(!stat)

View File

@@ -85,8 +85,7 @@
// blind_message (optional) is what blind people will hear e.g. "You hear something!"
/mob/visible_message(var/message, var/self_message, var/blind_message)
var/list/see = get_mobs_or_objects_in_view(world.view,src) | viewers(get_turf(src), null)
var/list/see = get_mobs_or_objects_in_view(world.view,src) | viewers(world.view,src)
for(var/I in see)
if(isobj(I))
@@ -152,8 +151,33 @@
//handle_typing_indicator() //You said the typing indicator would be fine. The test determined that was a lie.
return
/mob/proc/incapacitated()
return (stat || paralysis || stunned || weakened || restrained())
#define UNBUCKLED 0
#define PARTIALLY_BUCKLED 1
#define FULLY_BUCKLED 2
/mob/proc/buckled()
// Preliminary work for a future buckle rewrite,
// where one might be fully restrained (like an elecrical chair), or merely secured (shuttle chair, keeping you safe but not otherwise restrained from acting)
return buckled ? FULLY_BUCKLED : UNBUCKLED
/mob/proc/incapacitated(var/incapacitation_flags = INCAPACITATION_DEFAULT)
if (stat || paralysis || stunned || weakened || resting || sleeping || (status_flags & FAKEDEATH))
return 1
if((incapacitation_flags & INCAPACITATION_RESTRAINED) && restrained())
return 1
if((incapacitation_flags & (INCAPACITATION_BUCKLED_PARTIALLY|INCAPACITATION_BUCKLED_FULLY)))
var/buckling = buckled()
if(buckling >= PARTIALLY_BUCKLED && (incapacitation_flags & INCAPACITATION_BUCKLED_PARTIALLY))
return 1
if(buckling == FULLY_BUCKLED && (incapacitation_flags & INCAPACITATION_BUCKLED_FULLY))
return 1
return 0
#undef UNBUCKLED
#undef PARTIALLY_BUCKLED
#undef FULLY_BUCKLED
/mob/proc/restrained()
return
@@ -561,20 +585,44 @@
pullin.icon_state = "pull0"
/mob/proc/start_pulling(var/atom/movable/AM)
if ( !AM || !usr || src==AM || !isturf(src.loc) ) //if there's no person pulling OR the person is pulling themself OR the object being pulled is inside something: abort!
return
if (AM.anchored)
usr << "<span class='notice'>It won't budge!</span>"
src << "<span class='warning'>It won't budge!</span>"
return
var/mob/M = AM
if(ismob(AM))
if(!can_pull_mobs || !can_pull_size)
src << "<span class='warning'>It won't budge!</span>"
return
if((mob_size < M.mob_size) && (can_pull_mobs != MOB_PULL_LARGER))
src << "<span class='warning'>It won't budge!</span>"
return
if((mob_size == M.mob_size) && (can_pull_mobs == MOB_PULL_SMALLER))
src << "<span class='warning'>It won't budge!</span>"
return
// If your size is larger than theirs and you have some
// kind of mob pull value AT ALL, you will be able to pull
// them, so don't bother checking that explicitly.
if(!iscarbon(src))
M.LAssailant = null
else
M.LAssailant = usr
else if(isobj(AM))
var/obj/I = AM
if(!can_pull_size || can_pull_size < I.w_class)
src << "<span class='warning'>It won't budge!</span>"
return
if(pulling)
var/pulling_old = pulling
stop_pulling()
@@ -675,7 +723,7 @@
return 0
/mob/proc/cannot_stand()
return incapacitated() || restrained() || resting || sleeping || (status_flags & FAKEDEATH)
return incapacitated(INCAPACITATION_DEFAULT & (~INCAPACITATION_RESTRAINED))
//Updates canmove, lying and icons. Could perhaps do with a rename but I can't think of anything to describe it.
/mob/proc/update_canmove()

View File

@@ -149,6 +149,8 @@
var/const/deafness = 2//Carbon
var/const/muteness = 4//Carbon
var/can_pull_size = 10 // Maximum w_class the mob can pull.
var/can_pull_mobs = MOB_PULL_LARGER // Whether or not the mob can pull other mobs.
var/datum/dna/dna = null//Carbon
var/radiation = 0.0//Carbon

View File

@@ -1,5 +1,22 @@
/var/obj/effect/lobby_image = new/obj/effect/lobby_image()
/var/atom/movable/lobby_image = new /atom/movable{icon = 'icons/misc/title.dmi'; icon_state = "title"; screen_loc = "1,1"; name = "Baystation12"}
/obj/effect/lobby_image
name = "Baystation12"
desc = "This shouldn't be read"
icon = 'icons/misc/title.dmi'
screen_loc = "WEST,SOUTH"
/obj/effect/lobby_image/initialize()
var/list/known_icon_states = icon_states(icon)
for(var/lobby_screen in config.lobby_screens)
if(!(lobby_screen in known_icon_states))
error("Lobby screen '[lobby_screen]' did not exist in the icon set [icon].")
config.lobby_screens -= lobby_screen
if(config.lobby_screens.len)
icon_state = pick(config.lobby_screens)
else
icon_state = known_icon_states[1]
/mob/new_player
var/client/my_client // Need to keep track of this ourselves, since by the time Logout() is called the client has already been nulled

View File

@@ -1,6 +1,9 @@
/datum/proc/nano_host()
return src
/datum/proc/nano_container()
return src
/datum/proc/CanUseTopic(var/mob/user, var/datum/topic_state/state)
var/src_object = nano_host()
return state.can_use_topic(src_object, user)

View File

@@ -0,0 +1,7 @@
/*
This state always returns STATUS_INTERACTIVE
*/
/var/global/datum/topic_state/interactive/interactive_state = new()
/datum/topic_state/interactive/can_use_topic(var/src_object, var/mob/user)
return STATUS_INTERACTIVE

View File

@@ -0,0 +1,39 @@
/*
This state checks that user is capable, within range of the remoter, etc. and that src_object meets the basic requirements for interaction (being powered, non-broken, etc.
Whoever initializes this state is also responsible for deleting it properly.
*/
/datum/topic_state/remote
var/datum/remoter
var/datum/remote_target
var/datum/topic_state/remoter_state
/datum/topic_state/remote/New(var/remoter, var/remote_target, var/datum/topic_state/remoter_state = default_state)
src.remoter = remoter
src.remote_target = remote_target
src.remoter_state = remoter_state
..()
/datum/topic_state/remote/Destroy()
src.remoter = null
src.remoter_state = null
// Force an UI update before we go, ensuring that any windows we may have opened for the remote target closes.
nanomanager.update_uis(remote_target.nano_container())
remote_target = null
return ..()
/datum/topic_state/remote/can_use_topic(var/datum/src_object, var/mob/user)
if(!(remoter && remoter_state)) // The remoter is gone, let us leave
return STATUS_CLOSE
if(src_object != remote_target)
error("remote - Unexpected src_object: Expected '[remote_target]'/[remote_target.type], was '[src_object]'/[src_object.type]")
// This checks if src_object is powered, etc.
// The interactive state is otherwise simplistic and only returns STATUS_INTERACTIVE and never checks distances, etc.
. = src_object.CanUseTopic(user, interactive_state)
if(. == STATUS_CLOSE)
return
// This is the (generally) heavy checking, making sure the user is capable, within range of the remoter source, etc.
return min(., remoter.CanUseTopic(user, remoter_state))

View File

@@ -15,13 +15,13 @@
..()
alarm_handlers = list(camera_alarm, motion_alarm)
/datum/nano_module/alarm_monitor/proc/register(var/object, var/procName)
/datum/nano_module/alarm_monitor/proc/register_alarm(var/object, var/procName)
for(var/datum/alarm_handler/AH in alarm_handlers)
AH.register(object, procName)
AH.register_alarm(object, procName)
/datum/nano_module/alarm_monitor/proc/unregister(var/object)
/datum/nano_module/alarm_monitor/proc/unregister_alarm(var/object)
for(var/datum/alarm_handler/AH in alarm_handlers)
AH.unregister(object)
AH.unregister_alarm(object)
/datum/nano_module/alarm_monitor/proc/all_alarms()
var/list/all_alarms = new()

View File

@@ -47,7 +47,7 @@
// Allows us to process UI clicks, which are relayed in form of hrefs.
/datum/nano_module/power_monitor/Topic(href, href_list)
if(..())
return
return 1
if( href_list["clear"] )
active_sensor = null
if( href_list["refresh"] )

View File

@@ -140,6 +140,7 @@ nanoui is used to open and update nano browser uis
* @return nothing
*/
/datum/nanoui/proc/update_status(var/push_update = 0)
src_object = src_object.nano_host()
var/new_status = src_object.CanUseTopic(user, state)
if(master_ui)
new_status = min(new_status, master_ui.status)
@@ -428,6 +429,9 @@ nanoui is used to open and update nano browser uis
user << browse(null, "window=[window_id]")
for(var/datum/nanoui/child in children)
child.close()
children.Cut()
state = null
master_ui = null
/**
* Set the UI window to call the nanoclose verb when the window is closed

View File

@@ -7,7 +7,6 @@ var/global/datum/robolimb/basic_robolimb
for(var/limb_type in typesof(/datum/robolimb))
var/datum/robolimb/R = new limb_type()
all_robolimbs[R.company] = R
world << "Adding [R.company] as [R], [R.type]"
if(!R.unavailable_at_chargen)
chargen_robolimbs[R.company] = R

View File

@@ -498,8 +498,6 @@
user << "<span class='warning'>There is nothing to secure.</span>"
return
update_icon()
else if(emagged)
user << "The interface is broken."
else
wiresexposed = !wiresexposed
user << "The wires have been [wiresexposed ? "exposed" : "unexposed"]"
@@ -628,8 +626,9 @@
qdel(W)
stat &= ~BROKEN
// Malf AI, removes the APC from AI's hacked APCs list.
if(hacker && hacker.hacked_apcs && src in hacker.hacked_apcs)
if(hacker && hacker.hacked_apcs && (src in hacker.hacked_apcs))
hacker.hacked_apcs -= src
hacker = null
if (opened==2)
opened = 1
update_icon()
@@ -740,7 +739,7 @@
return
var/list/data = list(
"locked" = locked,
"locked" = (locked && !emagged) ? 1 : 0,
"isOperating" = operating,
"externalPower" = main_status,
"powerCellStatus" = cell ? cell.percent() : null,
@@ -854,7 +853,7 @@
user << "<span class='danger'>\The [src] have AI control disabled!</span>"
return 0
else
if ((!in_range(src, user) || !istype(src.loc, /turf) || hacker)) // AI-hacked APCs cannot be controlled by other AIs, unlinked cyborgs or humans.
if (!in_range(src, user) || !istype(src.loc, /turf))
return 0
var/mob/living/carbon/human/H = user
if (istype(H))
@@ -873,7 +872,7 @@
if(!can_use(usr, 1))
return 1
if(!istype(usr, /mob/living/silicon) && locked)
if(!istype(usr, /mob/living/silicon) && (locked && !emagged))
// Shouldn't happen, this is here to prevent href exploits
usr << "You must unlock the panel to use this!"
return 1

View File

@@ -18,7 +18,7 @@
if(propname == "mode_name")
name = propvalue
if(isnull(propvalue))
else if(isnull(propvalue))
settings[propname] = gun.vars[propname] //better than initial() as it handles list vars like burst_accuracy
else
settings[propname] = propvalue
@@ -261,7 +261,7 @@
for(var/obj/item/weapon/grab/G in M.grabbed_by)
grabstate = max(grabstate, G.state)
if(grabstate >= GRAB_NECK)
damage_mult = 3.0
damage_mult = 2.5
else if(grabstate >= GRAB_AGGRESSIVE)
damage_mult = 1.5
P.damage *= damage_mult
@@ -332,6 +332,7 @@
in_chamber.on_hit(M)
if (in_chamber.damage_type != HALLOSS)
log_and_message_admins("[key_name(user)] commited suicide using \a [src]")
user.apply_damage(in_chamber.damage*2.5, in_chamber.damage_type, "head", used_weapon = "Point blank shot in the mouth with \a [in_chamber]", sharp=1)
user.death()
else

View File

@@ -20,7 +20,8 @@
var/charge_tick = 0
/obj/item/weapon/gun/energy/switch_firemodes()
if(..())
. = ..()
if(.)
update_icon()
/obj/item/weapon/gun/energy/emp_act(severity)

View File

@@ -176,7 +176,7 @@
/obj/item/weapon/gun/projectile/attack_self(mob/user as mob)
if(firemodes.len > 1)
switch_firemodes(user)
..()
else
unload_ammo(user)

View File

@@ -9,7 +9,7 @@
load_method = MAGAZINE
/obj/item/weapon/gun/projectile/colt/detective
magazine_type = /obj/item/ammo_magazine/c45m/rubber
magazine_type = /obj/item/ammo_magazine/c45m/flash
/obj/item/weapon/gun/projectile/colt/detective/verb/rename_gun()
set name = "Name Gun"
@@ -33,7 +33,7 @@
name = ".45 pistol"
desc = "The NT Mk58 is a cheap, ubiquitous sidearm, produced by a NanoTrasen subsidiary. Found pretty much everywhere humans are. Uses .45 rounds."
icon_state = "secguncomp"
magazine_type = /obj/item/ammo_magazine/c45m/rubber
magazine_type = /obj/item/ammo_magazine/c45m/flash
caliber = ".45"
origin_tech = list(TECH_COMBAT = 2, TECH_MATERIAL = 2)
fire_sound = 'sound/weapons/Gunshot_light.ogg'
@@ -41,7 +41,6 @@
/obj/item/weapon/gun/projectile/sec/flash
name = ".45 signal pistol"
magazine_type = /obj/item/ammo_magazine/c45m/flash
/obj/item/weapon/gun/projectile/sec/wood
desc = "The NT Mk58 is a cheap, ubiquitous sidearm, produced by a NanoTrasen subsidiary. This one has a sweet wooden grip. Uses .45 rounds."

View File

@@ -86,17 +86,17 @@
var/total_pellets = get_pellets(distance)
var/spread = max(base_spread - (spread_step*distance), 0)
//shrapnel explosions miss prone mobs with a chance that increases with distance
var/prone_chance = 0
if(!base_spread)
prone_chance = max(spread_step*(distance - 2), 0)
var/hits = 0
for (var/i in 1 to total_pellets)
if(target_mob.lying && target_mob != original && prob(prone_chance))
continue
//pellet hits spread out across different zones, but 'aim at' the targeted zone with higher probability
//whether the pellet actually hits the def_zone or a different zone should still be determined by the parent using get_zone_with_miss_chance().
var/old_zone = def_zone
@@ -115,7 +115,7 @@
/obj/item/projectile/bullet/pellet/Move()
. = ..()
//If this is a shrapnel explosion, allow mobs that are prone to get hit, too
if(. && !base_spread && isturf(loc))
for(var/mob/living/M in loc)
@@ -137,8 +137,8 @@
/obj/item/projectile/bullet/pistol/rubber //"rubber" bullets
name = "rubber bullet"
check_armour = "melee"
damage = 10
agony = 40
damage = 5
agony = 25
embed = 0
sharp = 0
@@ -236,4 +236,4 @@
/obj/item/projectile/bullet/pistol/cap/process()
loc = null
qdel(src)
qdel(src)

View File

@@ -11,6 +11,7 @@
name = "chemical shell"
icon_state = "bullet"
damage = 5
agony = 10
kill_count = 15 //if the shell hasn't hit anything after travelling this far it just explodes.
var/flash_range = 0
var/brightness = 7

View File

@@ -115,10 +115,10 @@ var/global/list/datum/supply_drop_loot/supply_drop
/obj/item/clothing/suit/armor/riot,
/obj/item/clothing/head/helmet/riot,
/obj/item/clothing/suit/armor/riot,
/obj/item/clothing/suit/armor/vest,
/obj/item/clothing/suit/armor/vest,
/obj/item/clothing/suit/storage/vest,
/obj/item/clothing/suit/storage/vest,
/obj/item/clothing/suit/storage/vest/heavy,
/obj/item/clothing/suit/storage/vest/heavy,
/obj/item/clothing/suit/armor/laserproof,
/obj/item/clothing/suit/armor/bulletproof)

View File

@@ -39,7 +39,7 @@
playsound(src.loc, 'sound/effects/bang.ogg', 50, 1, 5)
// This is shit but it will do for the sake of testing.
for(var/obj/structure/droppod_door/D in range(5,src))
for(var/obj/structure/droppod_door/D in orange(1,src))
if(D.deployed)
continue
D.deploy()

View File

@@ -288,7 +288,7 @@
return splash_mob(target, amount, copy)
if(isturf(target))
return trans_to_turf(target, amount, multiplier, copy)
if(isobj(target))
if(isobj(target) && target.is_open_container())
return trans_to_obj(target, amount, multiplier, copy)
return 0

View File

@@ -905,7 +905,7 @@
/obj/item/weapon/reagent_containers/food/snacks/pie/throw_impact(atom/hit_atom)
..()
new/obj/effect/decal/cleanable/pie_smudge(src.loc)
src.visible_message("\red [src.name] splats.","\red You hear a splat.")
src.visible_message("<span class='danger'>\The [src.name] splats.</span>","<span class='danger'>You hear a splat.</span>")
qdel(src)
/obj/item/weapon/reagent_containers/food/snacks/berryclafoutis

View File

@@ -221,20 +221,31 @@
flags = OPENCONTAINER
unacidable = 0
attackby(var/obj/D, mob/user as mob)
if(isprox(D))
user << "You add [D] to [src]."
qdel(D)
user.put_in_hands(new /obj/item/weapon/bucket_sensor)
user.drop_from_inventory(src)
qdel(src)
/obj/item/weapon/reagent_containers/glass/bucket/attackby(var/obj/D, mob/user as mob)
update_icon()
overlays.Cut()
if(isprox(D))
user << "You add [D] to [src]."
qdel(D)
user.put_in_hands(new /obj/item/weapon/bucket_sensor)
user.drop_from_inventory(src)
qdel(src)
return
else if(istype(D, /obj/item/weapon/mop))
if(reagents.total_volume < 1)
user << "<span class='warning'>\The [src] is empty!</span>"
else
reagents.trans_to_obj(D, 5)
user << "<span class='notice'>You wet \the [D] in \the [src].</span>"
playsound(loc, 'sound/effects/slosh.ogg', 25, 1)
return
else
return ..()
if (!is_open_container())
var/image/lid = image(icon, src, "lid_[initial(icon_state)]")
overlays += lid
/obj/item/weapon/reagent_containers/glass/bucket/update_icon()
overlays.Cut()
if (!is_open_container())
var/image/lid = image(icon, src, "lid_[initial(icon_state)]")
overlays += lid
/*
/obj/item/weapon/reagent_containers/glass/blender_jug

View File

@@ -561,14 +561,14 @@
id = "mech_ccw_armor"
req_tech = list(TECH_MATERIAL = 5, TECH_COMBAT = 4)
materials = list(DEFAULT_WALL_MATERIAL = 20000, "silver" = 5000)
build_path = /obj/item/mecha_parts/mecha_equipment/anticcw_armor_booster
build_path = /obj/item/mecha_parts/mecha_equipment/armor_booster/anticcw_armor_booster
/datum/design/item/mecha/proj_armor
desc = "Exosuit projectile armor booster."
id = "mech_proj_armor"
req_tech = list(TECH_MATERIAL = 5, TECH_COMBAT = 5, TECH_ENGINEERING = 3)
materials = list(DEFAULT_WALL_MATERIAL = 20000, "gold" = 5000)
build_path = /obj/item/mecha_parts/mecha_equipment/antiproj_armor_booster
build_path = /obj/item/mecha_parts/mecha_equipment/armor_booster/antiproj_armor_booster
/datum/design/item/mecha/diamond_drill
name = "Diamond drill"

View File

@@ -85,6 +85,7 @@
var/obj/machinery/artifact/A = scanned_object
A.anchored = 0
A.being_used = 0
scanned_object = null
/obj/machinery/artifact_analyser/Topic(href, href_list)
if(href_list["begin_scan"])
@@ -97,8 +98,8 @@
continue
if(O.invisibility)
continue
if(istype(scanned_object, /obj/machinery/artifact))
var/obj/machinery/artifact/A = scanned_object
if(istype(O, /obj/machinery/artifact))
var/obj/machinery/artifact/A = O
if(A.being_used)
artifact_in_use = 1
else

View File

@@ -0,0 +1 @@
#define SURGERY_FAILURE -1

View File

@@ -72,8 +72,8 @@
for(var/obj/item/organ/I in affected.internal_organs)
if(I && I.damage > 0)
if(I.robotic < 2)
user.visible_message("\blue [user] treats damage to [target]'s [I.name] with [tool_name].", \
"\blue You treat damage to [target]'s [I.name] with [tool_name]." )
user.visible_message("<span class='notice'>[user] treats damage to [target]'s [I.name] with [tool_name].</span>", \
"<span class='notice'>You treat damage to [target]'s [I.name] with [tool_name].</span>" )
I.damage = 0
fail_step(mob/living/user, mob/living/carbon/human/target, target_zone, obj/item/tool)
@@ -82,8 +82,8 @@
return
var/obj/item/organ/external/affected = target.get_organ(target_zone)
user.visible_message("\red [user]'s hand slips, getting mess and tearing the inside of [target]'s [affected.name] with \the [tool]!", \
"\red Your hand slips, getting mess and tearing the inside of [target]'s [affected.name] with \the [tool]!")
user.visible_message("<span class='warning'>[user]'s hand slips, getting mess and tearing the inside of [target]'s [affected.name] with \the [tool]!</span>", \
"<span class='warning'>Your hand slips, getting mess and tearing the inside of [target]'s [affected.name] with \the [tool]!</span>")
var/dam_amt = 2
if (istype(tool, /obj/item/stack/medical/advanced/bruise_pack))
@@ -145,8 +145,8 @@
..()
end_step(mob/living/user, mob/living/carbon/human/target, target_zone, obj/item/tool)
user.visible_message("\blue [user] has separated [target]'s [target.op_stage.current_organ] with \the [tool]." , \
"\blue You have separated [target]'s [target.op_stage.current_organ] with \the [tool].")
user.visible_message("<span class='notice'>[user] has separated [target]'s [target.op_stage.current_organ] with \the [tool].</span>" , \
"<span class='notice'>You have separated [target]'s [target.op_stage.current_organ] with \the [tool].</span>")
var/obj/item/organ/I = target.internal_organs_by_name[target.op_stage.current_organ]
if(I && istype(I))
@@ -154,8 +154,8 @@
fail_step(mob/living/user, mob/living/carbon/human/target, target_zone, obj/item/tool)
var/obj/item/organ/external/affected = target.get_organ(target_zone)
user.visible_message("\red [user]'s hand slips, slicing an artery inside [target]'s [affected.name] with \the [tool]!", \
"\red Your hand slips, slicing an artery inside [target]'s [affected.name] with \the [tool]!")
user.visible_message("<span class='warning'>[user]'s hand slips, slicing an artery inside [target]'s [affected.name] with \the [tool]!</span>", \
"<span class='warning'>Your hand slips, slicing an artery inside [target]'s [affected.name] with \the [tool]!</span>")
affected.createwound(CUT, rand(30,50), 1)
/datum/surgery_step/internal/remove_organ
@@ -196,8 +196,8 @@
..()
end_step(mob/living/user, mob/living/carbon/human/target, target_zone, obj/item/tool)
user.visible_message("\blue [user] has removed [target]'s [target.op_stage.current_organ] with \the [tool].", \
"\blue You have removed [target]'s [target.op_stage.current_organ] with \the [tool].")
user.visible_message("<span class='notice'>[user] has removed [target]'s [target.op_stage.current_organ] with \the [tool].</span>", \
"<span class='notice'>You have removed [target]'s [target.op_stage.current_organ] with \the [tool].</span>")
// Extract the organ!
if(target.op_stage.current_organ)
@@ -208,8 +208,8 @@
fail_step(mob/living/user, mob/living/carbon/human/target, target_zone, obj/item/tool)
var/obj/item/organ/external/affected = target.get_organ(target_zone)
user.visible_message("\red [user]'s hand slips, damaging [target]'s [affected.name] with \the [tool]!", \
"\red Your hand slips, damaging [target]'s [affected.name] with \the [tool]!")
user.visible_message("<span class='warning'>[user]'s hand slips, damaging [target]'s [affected.name] with \the [tool]!</span>", \
"<span class='warning'>Your hand slips, damaging [target]'s [affected.name] with \the [tool]!</span>")
affected.createwound(BRUISE, 20)
/datum/surgery_step/internal/replace_organ
@@ -233,11 +233,11 @@
if((affected.status & ORGAN_ROBOT) && !(O.status & ORGAN_ROBOT))
user << "<span class='danger'>You cannot install a naked organ into a robotic body.</span>"
return 2
return SURGERY_FAILURE
if(!target.species)
user << "\red You have no idea what species this person is. Report this on the bug tracker."
return 2
user << "<span class='danger'>You have no idea what species this person is. Report this on the bug tracker.</span>"
return SURGERY_FAILURE
var/o_is = (O.gender == PLURAL) ? "are" : "is"
var/o_a = (O.gender == PLURAL) ? "" : "a "
@@ -248,23 +248,23 @@
else if(target.species.has_organ[O.organ_tag])
if(O.damage > (O.max_damage * 0.75))
user << "\red \The [O.organ_tag] [o_is] in no state to be transplanted."
return 2
user << "<span class='warning'>\The [O.organ_tag] [o_is] in no state to be transplanted.</span>"
return SURGERY_FAILURE
if(!target.internal_organs_by_name[O.organ_tag])
organ_missing = 1
else
user << "\red \The [target] already has [o_a][O.organ_tag]."
return 2
user << "<span class='warning'>\The [target] already has [o_a][O.organ_tag].</span>"
return SURGERY_FAILURE
if(O && affected.limb_name == O.parent_organ)
organ_compatible = 1
else
user << "\red \The [O.organ_tag] [o_do] normally go in \the [affected.name]."
return 2
user << "<span class='warning'>\The [O.organ_tag] [o_do] normally go in \the [affected.name].</span>"
return SURGERY_FAILURE
else
user << "\red You're pretty sure [target.species.name_plural] don't normally have [o_a][O.organ_tag]."
return 2
user << "<span class='warning'>You're pretty sure [target.species.name_plural] don't normally have [o_a][O.organ_tag].</span>"
return SURGERY_FAILURE
return ..() && organ_missing && organ_compatible
@@ -277,16 +277,16 @@
end_step(mob/living/user, mob/living/carbon/human/target, target_zone, obj/item/tool)
var/obj/item/organ/external/affected = target.get_organ(target_zone)
user.visible_message("\blue [user] has transplanted \the [tool] into [target]'s [affected.name].", \
"\blue You have transplanted \the [tool] into [target]'s [affected.name].")
user.visible_message("<span class='notice'>[user] has transplanted \the [tool] into [target]'s [affected.name].</span>", \
"<span class='notice'>You have transplanted \the [tool] into [target]'s [affected.name].</span>")
var/obj/item/organ/O = tool
if(istype(O))
user.remove_from_mob(O)
O.replaced(target,affected)
fail_step(mob/living/user, mob/living/carbon/human/target, target_zone, obj/item/tool)
user.visible_message("\red [user]'s hand slips, damaging \the [tool]!", \
"\red Your hand slips, damaging \the [tool]!")
user.visible_message("<span class='warning'>[user]'s hand slips, damaging \the [tool]!</span>", \
"<span class='warning'>Your hand slips, damaging \the [tool]!</span>")
var/obj/item/organ/I = tool
if(istype(I))
I.take_damage(rand(3,5),0)
@@ -327,8 +327,8 @@
..()
end_step(mob/living/user, mob/living/carbon/human/target, target_zone, obj/item/tool)
user.visible_message("\blue [user] has reattached [target]'s [target.op_stage.current_organ] with \the [tool]." , \
"\blue You have reattached [target]'s [target.op_stage.current_organ] with \the [tool].")
user.visible_message("<span class='notice'>[user] has reattached [target]'s [target.op_stage.current_organ] with \the [tool].</span>" , \
"<span class='notice'>You have reattached [target]'s [target.op_stage.current_organ] with \the [tool].</span>")
var/obj/item/organ/I = target.internal_organs_by_name[target.op_stage.current_organ]
if(I && istype(I))
@@ -336,8 +336,8 @@
fail_step(mob/living/user, mob/living/carbon/human/target, target_zone, obj/item/tool)
var/obj/item/organ/external/affected = target.get_organ(target_zone)
user.visible_message("\red [user]'s hand slips, damaging the flesh in [target]'s [affected.name] with \the [tool]!", \
"\red Your hand slips, damaging the flesh in [target]'s [affected.name] with \the [tool]!")
user.visible_message("<span class='warning'>[user]'s hand slips, damaging the flesh in [target]'s [affected.name] with \the [tool]!</span>", \
"<span class='warning'>Your hand slips, damaging the flesh in [target]'s [affected.name] with \the [tool]!</span>")
affected.createwound(BRUISE, 20)
//////////////////////////////////////////////////////////////////

View File

@@ -44,14 +44,14 @@
end_step(mob/living/user, mob/living/carbon/human/target, target_zone, obj/item/tool)
var/obj/item/organ/external/affected = target.get_organ(target_zone)
user.visible_message("\blue [user] has opened the maintenance hatch on [target]'s [affected.name] with \the [tool].", \
"\blue You have opened the maintenance hatch on [target]'s [affected.name] with \the [tool].",)
user.visible_message("<span class='notice'>[user] has opened the maintenance hatch on [target]'s [affected.name] with \the [tool].</span>", \
"<span class='notice'>You have opened the maintenance hatch on [target]'s [affected.name] with \the [tool].</span>",)
affected.open = 1
fail_step(mob/living/user, mob/living/carbon/human/target, target_zone, obj/item/tool)
var/obj/item/organ/external/affected = target.get_organ(target_zone)
user.visible_message("\red [user]'s [tool.name] slips, failing to unscrew [target]'s [affected.name].", \
"\red Your [tool] slips, failing to unscrew [target]'s [affected.name].")
user.visible_message("<span class='warning'>[user]'s [tool.name] slips, failing to unscrew [target]'s [affected.name].</span>", \
"<span class='warning'>Your [tool] slips, failing to unscrew [target]'s [affected.name].</span>")
/datum/surgery_step/robotics/open_hatch
allowed_tools = list(
@@ -76,14 +76,14 @@
end_step(mob/living/user, mob/living/carbon/human/target, target_zone, obj/item/tool)
var/obj/item/organ/external/affected = target.get_organ(target_zone)
user.visible_message("\blue [user] opens the maintenance hatch on [target]'s [affected.name] with \the [tool].", \
"\blue You open the maintenance hatch on [target]'s [affected.name] with \the [tool]." )
user.visible_message("<span class='notice'>[user] opens the maintenance hatch on [target]'s [affected.name] with \the [tool].</span>", \
"<span class='notice'>You open the maintenance hatch on [target]'s [affected.name] with \the [tool].</span>")
affected.open = 2
fail_step(mob/living/user, mob/living/carbon/human/target, target_zone, obj/item/tool)
var/obj/item/organ/external/affected = target.get_organ(target_zone)
user.visible_message("\red [user]'s [tool.name] slips, failing to open the hatch on [target]'s [affected.name].",
"\red Your [tool] slips, failing to open the hatch on [target]'s [affected.name].")
user.visible_message("<span class='warning'>[user]'s [tool.name] slips, failing to open the hatch on [target]'s [affected.name].</span>",
"<span class='warning'>Your [tool] slips, failing to open the hatch on [target]'s [affected.name].</span>")
/datum/surgery_step/robotics/close_hatch
allowed_tools = list(
@@ -108,15 +108,15 @@
end_step(mob/living/user, mob/living/carbon/human/target, target_zone, obj/item/tool)
var/obj/item/organ/external/affected = target.get_organ(target_zone)
user.visible_message("\blue [user] closes and secures the hatch on [target]'s [affected.name] with \the [tool].", \
"\blue You close and secure the hatch on [target]'s [affected.name] with \the [tool].")
user.visible_message("<span class='notice'>[user] closes and secures the hatch on [target]'s [affected.name] with \the [tool].</span>", \
"<span class='notice'>You close and secure the hatch on [target]'s [affected.name] with \the [tool].</span>")
affected.open = 0
affected.germ_level = 0
fail_step(mob/living/user, mob/living/carbon/human/target, target_zone, obj/item/tool)
var/obj/item/organ/external/affected = target.get_organ(target_zone)
user.visible_message("\red [user]'s [tool.name] slips, failing to close the hatch on [target]'s [affected.name].",
"\red Your [tool.name] slips, failing to close the hatch on [target]'s [affected.name].")
user.visible_message("<span class='warning'>[user]'s [tool.name] slips, failing to close the hatch on [target]'s [affected.name].</span>",
"<span class='warning'>Your [tool.name] slips, failing to close the hatch on [target]'s [affected.name].</span>")
/datum/surgery_step/robotics/repair_brute
allowed_tools = list(
@@ -144,14 +144,14 @@
end_step(mob/living/user, mob/living/carbon/human/target, target_zone, obj/item/tool)
var/obj/item/organ/external/affected = target.get_organ(target_zone)
user.visible_message("\blue [user] finishes patching damage to [target]'s [affected.name] with \the [tool].", \
"\blue You finish patching damage to [target]'s [affected.name] with \the [tool].")
user.visible_message("<span class='notice'>[user] finishes patching damage to [target]'s [affected.name] with \the [tool].</span>", \
"<span class='notice'>You finish patching damage to [target]'s [affected.name] with \the [tool].</span>")
affected.heal_damage(rand(30,50),0,1,1)
fail_step(mob/living/user, mob/living/carbon/human/target, target_zone, obj/item/tool)
var/obj/item/organ/external/affected = target.get_organ(target_zone)
user.visible_message("\red [user]'s [tool.name] slips, damaging the internal structure of [target]'s [affected.name].",
"\red Your [tool.name] slips, damaging the internal structure of [target]'s [affected.name].")
user.visible_message("<span class='warning'>[user]'s [tool.name] slips, damaging the internal structure of [target]'s [affected.name].</span>",
"<span class='warning'>Your [tool.name] slips, damaging the internal structure of [target]'s [affected.name].</span>")
target.apply_damage(rand(5,10), BURN, affected)
/datum/surgery_step/robotics/repair_burn
@@ -171,7 +171,7 @@
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 2
return SURGERY_FAILURE
C.use(3)
return 1
return 0
@@ -184,14 +184,14 @@
end_step(mob/living/user, mob/living/carbon/human/target, target_zone, obj/item/tool)
var/obj/item/organ/external/affected = target.get_organ(target_zone)
user.visible_message("\blue [user] finishes splicing cable into [target]'s [affected.name].", \
"\blue You finishes splicing new cable into [target]'s [affected.name].")
user.visible_message("<span class='notice'>[user] finishes splicing cable into [target]'s [affected.name].</span>", \
"<span class='notice'>You finishes splicing new cable into [target]'s [affected.name].</span>")
affected.heal_damage(0,rand(30,50),1,1)
fail_step(mob/living/user, mob/living/carbon/human/target, target_zone, obj/item/tool)
var/obj/item/organ/external/affected = target.get_organ(target_zone)
user.visible_message("\red [user] causes a short circuit in [target]'s [affected.name]!",
"\red You cause a short circuit in [target]'s [affected.name]!")
user.visible_message("<span class='warning'>[user] causes a short circuit in [target]'s [affected.name]!</span>",
"<span class='warning'>You cause a short circuit in [target]'s [affected.name]!</span>")
target.apply_damage(rand(5,10), BURN, affected)
/datum/surgery_step/robotics/fix_organ_robotic //For artificial organs
@@ -242,8 +242,8 @@
if(I && I.damage > 0)
if(I.robotic >= 2)
user.visible_message("\blue [user] repairs [target]'s [I.name] with [tool].", \
"\blue You repair [target]'s [I.name] with [tool]." )
user.visible_message("<span class='notice'>[user] repairs [target]'s [I.name] with [tool].</span>", \
"<span class='notice'>You repair [target]'s [I.name] with [tool].</span>" )
I.damage = 0
fail_step(mob/living/user, mob/living/carbon/human/target, target_zone, obj/item/tool)
@@ -252,8 +252,8 @@
return
var/obj/item/organ/external/affected = target.get_organ(target_zone)
user.visible_message("\red [user]'s hand slips, gumming up the mechanisms inside of [target]'s [affected.name] with \the [tool]!", \
"\red Your hand slips, gumming up the mechanisms inside of [target]'s [affected.name] with \the [tool]!")
user.visible_message("<span class='warning'>[user]'s hand slips, gumming up the mechanisms inside of [target]'s [affected.name] with \the [tool]!</span>", \
"<span class='warning'>Your hand slips, gumming up the mechanisms inside of [target]'s [affected.name] with \the [tool]!</span>")
target.adjustToxLoss(5)
affected.createwound(CUT, 5)
@@ -301,16 +301,16 @@
..()
end_step(mob/living/user, mob/living/carbon/human/target, target_zone, obj/item/tool)
user.visible_message("\blue [user] has decoupled [target]'s [target.op_stage.current_organ] with \the [tool]." , \
"\blue You have decoupled [target]'s [target.op_stage.current_organ] with \the [tool].")
user.visible_message("<span class='notice'>[user] has decoupled [target]'s [target.op_stage.current_organ] with \the [tool].</span>" , \
"<span class='notice'>You have decoupled [target]'s [target.op_stage.current_organ] with \the [tool].</span>")
var/obj/item/organ/I = target.internal_organs_by_name[target.op_stage.current_organ]
if(I && istype(I))
I.status |= ORGAN_CUT_AWAY
fail_step(mob/living/user, mob/living/carbon/human/target, target_zone, obj/item/tool)
user.visible_message("\red [user]'s hand slips, disconnecting \the [tool].", \
"\red Your hand slips, disconnecting \the [tool].")
user.visible_message("<span class='warning'>[user]'s hand slips, disconnecting \the [tool].</span>", \
"<span class='warning'>Your hand slips, disconnecting \the [tool].</span>")
/datum/surgery_step/robotics/attach_organ_robotic
allowed_tools = list(
@@ -349,16 +349,16 @@
..()
end_step(mob/living/user, mob/living/carbon/human/target, target_zone, obj/item/tool)
user.visible_message("\blue [user] has reattached [target]'s [target.op_stage.current_organ] with \the [tool]." , \
"\blue You have reattached [target]'s [target.op_stage.current_organ] with \the [tool].")
user.visible_message("<span class='notice'>[user] has reattached [target]'s [target.op_stage.current_organ] with \the [tool].</span>" , \
"<span class='notice'>You have reattached [target]'s [target.op_stage.current_organ] with \the [tool].</span>")
var/obj/item/organ/I = target.internal_organs_by_name[target.op_stage.current_organ]
if(I && istype(I))
I.status &= ~ORGAN_CUT_AWAY
fail_step(mob/living/user, mob/living/carbon/human/target, target_zone, obj/item/tool)
user.visible_message("\red [user]'s hand slips, disconnecting \the [tool].", \
"\red Your hand slips, disconnecting \the [tool].")
user.visible_message("<span class='warning'>[user]'s hand slips, disconnecting \the [tool].</span>", \
"<span class='warning'>Your hand slips, disconnecting \the [tool].</span>")
/datum/surgery_step/robotics/install_mmi
allowed_tools = list(
@@ -383,23 +383,23 @@
if(!M.brainmob || !M.brainmob.client || !M.brainmob.ckey || M.brainmob.stat >= DEAD)
user << "<span class='danger'>That brain is not usable.</span>"
return 2
return SURGERY_FAILURE
if(!(affected.status & ORGAN_ROBOT))
user << "<span class='danger'>You cannot install a computer brain into a meat skull.</span>"
return 2
return SURGERY_FAILURE
if(!target.species)
user << "<span class='danger'>You have no idea what species this person is. Report this on the bug tracker.</span>"
return 2
return SURGERY_FAILURE
if(!target.species.has_organ["brain"])
user << "<span class='danger'>You're pretty sure [target.species.name_plural] don't normally have a brain.</span>"
return 2
return SURGERY_FAILURE
if(!isnull(target.internal_organs["brain"]))
user << "<span class='danger'>Your subject already has a brain.</span>"
return 2
return SURGERY_FAILURE
return 1
@@ -411,8 +411,8 @@
end_step(mob/living/user, mob/living/carbon/human/target, target_zone, obj/item/tool)
var/obj/item/organ/external/affected = target.get_organ(target_zone)
user.visible_message("\blue [user] has installed \the [tool] into [target]'s [affected.name].", \
"\blue You have installed \the [tool] into [target]'s [affected.name].")
user.visible_message("<span class='notice'>[user] has installed \the [tool] into [target]'s [affected.name].</span>", \
"<span class='notice'>You have installed \the [tool] into [target]'s [affected.name].</span>")
var/obj/item/device/mmi/M = tool
var/obj/item/organ/mmi_holder/holder = new(target, 1)
@@ -426,5 +426,5 @@
M.brainmob.mind.transfer_to(target)
fail_step(mob/living/user, mob/living/carbon/human/target, target_zone, obj/item/tool)
user.visible_message("\red [user]'s hand slips.", \
"\red Your hand slips.")
user.visible_message("<span class='warning'>[user]'s hand slips.</span>", \
"<span class='warning'>Your hand slips.</span>")

View File

@@ -84,14 +84,14 @@ proc/do_surgery(mob/living/carbon/M, mob/living/user, obj/item/tool)
return 0
var/zone = user.zone_sel.selecting
if(zone in M.op_stage.in_progress) //Can't operate on someone repeatedly.
user << "\red You can't operate on this area while surgery is already in progress."
user << "<span class='warning'>You can't operate on this area while surgery is already in progress.</span>"
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(step_is_valid && S.is_valid_target(M))
if(step_is_valid == 2) // This is a failure that already has a message for failing.
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
@@ -101,7 +101,7 @@ proc/do_surgery(mob/living/carbon/M, mob/living/user, obj/item/tool)
else if ((tool in user.contents) && user.Adjacent(M)) //or
S.fail_step(user, M, zone, tool) //malpractice~
else // This failing silently was a pain.
user << "\red You must remain close to your patient to conduct surgery."
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.
if (ishuman(M))
var/mob/living/carbon/human/H = M
@@ -109,7 +109,7 @@ 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 << "\red You can't see any useful way to use [tool] on [M]."
user << "<span class='warning'>You can't see any useful way to use [tool] on [M].</span>"
return 1
return 0

View File

@@ -0,0 +1 @@
#undef SURGERY_FAILURE

View File

@@ -5,11 +5,11 @@
// Receiver: does whatever the subtype does. deactivate() by default calls activate(), so you will have to override in
// it in a subtype if you want it to do something.
//-------------------------------
/datum/wifi/sender/button/proc/activate(mob/living/user)
/datum/wifi/sender/button/activate(mob/living/user)
for(var/datum/wifi/receiver/button/B in connected_devices)
B.activate(user)
/datum/wifi/sender/button/proc/deactivate(mob/living/user)
/datum/wifi/sender/button/deactivate(mob/living/user)
for(var/datum/wifi/receiver/button/B in connected_devices)
B.deactivate(user)
@@ -24,32 +24,70 @@
// open at approximately the same time. Waits until all doors have finished opening before returning.
// Receiver: will try to open/close the parent door when activate/deactivate is called.
//-------------------------------
/datum/wifi/sender/door/proc/open()
// Sender procs
/datum/wifi/sender/door/activate(var/command)
if(!command)
return
var/datum/spawn_sync/S = new()
for(var/datum/wifi/receiver/button/door/D in connected_devices)
S.start_worker(D, "activate")
S.start_worker(D, command)
S.wait_until_done()
return
/datum/wifi/sender/door/proc/close()
var/datum/spawn_sync/S = new()
for(var/datum/wifi/receiver/button/door/D in connected_devices)
S.start_worker(D, "deactivate")
S.wait_until_done()
return
/datum/wifi/receiver/button/door/activate()
//Receiver procs
/datum/wifi/receiver/button/door/proc/open()
var/obj/machinery/door/D = parent
if(istype(D) && D.can_open())
D.open()
/datum/wifi/receiver/button/door/deactivate()
/datum/wifi/receiver/button/door/proc/close()
var/obj/machinery/door/D = parent
if(istype(D) && D.can_close())
D.close()
/datum/wifi/receiver/button/door/proc/lock()
var/obj/machinery/door/airlock/D = parent
if(istype(D))
D.lock()
/datum/wifi/receiver/button/door/proc/unlock()
var/obj/machinery/door/airlock/D = parent
if(istype(D))
D.unlock()
/datum/wifi/receiver/button/door/proc/enable_idscan()
var/obj/machinery/door/airlock/D = parent
if(istype(D))
D.set_idscan(1)
/datum/wifi/receiver/button/door/proc/disable_idscan()
var/obj/machinery/door/airlock/D = parent
if(istype(D))
D.set_idscan(0)
/datum/wifi/receiver/button/door/proc/enable_safeties()
var/obj/machinery/door/airlock/D = parent
if(istype(D))
D.set_safeties(1)
/datum/wifi/receiver/button/door/proc/disable_safeties()
var/obj/machinery/door/airlock/D = parent
if(istype(D))
D.set_safeties(0)
/datum/wifi/receiver/button/door/proc/electrify()
var/obj/machinery/door/airlock/D = parent
if(istype(D))
D.electrify(-1)
/datum/wifi/receiver/button/door/proc/unelectrify()
var/obj/machinery/door/airlock/D = parent
if(istype(D))
D.electrify(0)
//-------------------------------
// Emitter
// Activates/deactivates the parent emitter.
@@ -133,28 +171,25 @@
// then closes all connected doors. It will wait before continuing the sequence after opening/closing the doors.
// Receiver: Triggers the parent mass dirver to activate.
//-------------------------------
/datum/wifi/sender/mass_driver/proc/cycle()
/datum/wifi/sender/mass_driver/activate()
var/datum/spawn_sync/S = new()
//tell all doors to open
for(var/datum/wifi/receiver/button/door/D in connected_devices)
S.start_worker(D, "activate")
S.start_worker(D, "open")
S.wait_until_done()
S.reset()
//tell all mass drivers to launch
for(var/datum/wifi/receiver/button/mass_driver/M in connected_devices)
spawn()
M.activate()
sleep(20)
//tell all doors to close
S.reset()
for(var/datum/wifi/receiver/button/door/D in connected_devices)
S.start_worker(D, "deactivate")
S.start_worker(D, "close")
S.wait_until_done()
return
/datum/wifi/receiver/button/mass_driver/activate(mob/living/user)

View File

@@ -96,6 +96,11 @@
var/datum/connection_request/C = new(src, id)
wirelessProcess.add_request(C)
/datum/wifi/sender/proc/activate(mob/living/user)
return
/datum/wifi/sender/proc/deactivate(mob/living/user)
return
//-------------------------------
// Connection request

View File

@@ -306,7 +306,7 @@
return 1
/datum/gas_mixture/proc/react(atom/dump_location)
/datum/gas_mixture/proc/react()
zburn(null, force_burn=0, no_check=0) //could probably just call zburn() here with no args but I like being explicit.
@@ -442,20 +442,25 @@
total_gas[g] += gasmix.gas[g]
if(total_volume > 0)
//Average out the gases
for(var/g in total_gas)
total_gas[g] /= total_volume
var/datum/gas_mixture/combined = new(total_volume)
combined.gas = total_gas
//Calculate temperature
var/temperature = 0
if(total_heat_capacity > 0)
temperature = total_thermal_energy / total_heat_capacity
combined.temperature = total_thermal_energy / total_heat_capacity
combined.update_values()
//Allow for reactions
combined.react()
//Average out the gases
for(var/g in combined.gas)
combined.gas[g] /= total_volume
//Update individual gas_mixtures
for(var/datum/gas_mixture/gasmix in gases)
gasmix.gas = total_gas.Copy()
gasmix.temperature = temperature
gasmix.gas = combined.gas.Copy()
gasmix.temperature = combined.temperature
gasmix.multiply(gasmix.volume)
return 1