Merge remote-tracking branch 'upstream/dev' into 151117-MultitoolPower

Conflicts:
	code/modules/nano/nanoui.dm
This commit is contained in:
PsiOmegaDelta
2015-12-06 12:10:33 +01:00
64 changed files with 747 additions and 438 deletions
+1 -1
View File
@@ -5,7 +5,7 @@ sudo: false
env:
BYOND_MAJOR="508"
BYOND_MINOR="1293"
MACRO_COUNT=1129
MACRO_COUNT=1061
cache:
directories:
+3
View File
@@ -979,6 +979,7 @@
#include "code\modules\blob\blob.dm"
#include "code\modules\client\client defines.dm"
#include "code\modules\client\client procs.dm"
#include "code\modules\client\movement.dm"
#include "code\modules\client\preferences.dm"
#include "code\modules\client\preferences_factions.dm"
#include "code\modules\client\preferences_gear.dm"
@@ -1814,6 +1815,7 @@
#include "code\modules\spells\targeted\projectile\magic_missile.dm"
#include "code\modules\spells\targeted\projectile\projectile.dm"
#include "code\modules\supermatter\supermatter.dm"
#include "code\modules\surgery\_defines.dm"
#include "code\modules\surgery\bones.dm"
#include "code\modules\surgery\encased.dm"
#include "code\modules\surgery\face.dm"
@@ -1825,6 +1827,7 @@
#include "code\modules\surgery\robotics.dm"
#include "code\modules\surgery\slimes.dm"
#include "code\modules\surgery\surgery.dm"
#include "code\modules\surgery\~defines.dm"
#include "code\modules\tables\flipping.dm"
#include "code\modules\tables\interactions.dm"
#include "code\modules\tables\presets.dm"
-3
View File
@@ -28,9 +28,6 @@ datum/pipeline
if(!member.check_pressure(pressure))
break //Only delete 1 pipe per process
//Allow for reactions
//air.react() //Should be handled by pipe_network now
proc/temporarily_store_air()
//Update individual gas_mixtures by volume ratio
+9 -9
View File
@@ -30,15 +30,15 @@
#define AIR_DAMAGE_MODIFIER 2.025 // More means less damage from hot air scalding lungs, less = more damage. (default 2.025)
// Organ defines.
#define ORGAN_CUT_AWAY 1<<0
#define ORGAN_BLEEDING 1<<1
#define ORGAN_BROKEN 1<<2
#define ORGAN_DESTROYED 1<<3
#define ORGAN_ROBOT 1<<4
#define ORGAN_SPLINTED 1<<5
#define ORGAN_DEAD 1<<6
#define ORGAN_MUTATED 1<<7
#define ORGAN_ASSISTED 1<<8
#define ORGAN_CUT_AWAY (1<<0)
#define ORGAN_BLEEDING (1<<1)
#define ORGAN_BROKEN (1<<2)
#define ORGAN_DESTROYED (1<<3)
#define ORGAN_ROBOT (1<<4)
#define ORGAN_SPLINTED (1<<5)
#define ORGAN_DEAD (1<<6)
#define ORGAN_MUTATED (1<<7)
#define ORGAN_ASSISTED (1<<8)
#define DROPLIMB_EDGE 0
#define DROPLIMB_BLUNT 1
+47 -3
View File
@@ -1,3 +1,4 @@
//////////////////////////
//Movable Screen Objects//
// By RemieRichards //
@@ -30,9 +31,10 @@
//Split X+Pixel_X up into list(X, Pixel_X)
var/list/screen_loc_X = text2list(screen_loc_params[1],":")
screen_loc_X[1] = encode_screen_X(text2num(screen_loc_X[1]))
//Split Y+Pixel_Y up into list(Y, Pixel_Y)
var/list/screen_loc_Y = text2list(screen_loc_params[2],":")
screen_loc_Y[1] = encode_screen_Y(text2num(screen_loc_Y[1]))
if(snap2grid) //Discard Pixel Values
screen_loc = "[screen_loc_X[1]],[screen_loc_Y[1]]"
@@ -42,8 +44,50 @@
var/pix_Y = text2num(screen_loc_Y[2]) - 16
screen_loc = "[screen_loc_X[1]]:[pix_X],[screen_loc_Y[1]]:[pix_Y]"
moved = TRUE
/obj/screen/movable/proc/encode_screen_X(X)
if(X > usr.client.view+1)
. = "EAST-[usr.client.view*2 + 1-X]"
else if(X < usr.client.view+1)
. = "WEST+[X-1]"
else
. = "CENTER"
/obj/screen/movable/proc/decode_screen_X(X)
//Find EAST/WEST implementations
if(findtext(X,"EAST-"))
var/num = text2num(copytext(X,6)) //Trim EAST-
if(!num)
num = 0
. = usr.client.view*2 + 1 - num
else if(findtext(X,"WEST+"))
var/num = text2num(copytext(X,6)) //Trim WEST+
if(!num)
num = 0
. = num+1
else if(findtext(X,"CENTER"))
. = usr.client.view+1
/obj/screen/movable/proc/encode_screen_Y(Y)
if(Y > usr.client.view+1)
. = "NORTH-[usr.client.view*2 + 1-Y]"
else if(Y < usr.client.view+1)
. = "SOUTH+[Y-1]"
else
. = "CENTER"
/obj/screen/movable/proc/decode_screen_Y(Y)
if(findtext(Y,"NORTH-"))
var/num = text2num(copytext(Y,7)) //Trim NORTH-
if(!num)
num = 0
. = usr.client.view*2 + 1 - num
else if(findtext(Y,"SOUTH+"))
var/num = text2num(copytext(Y,7)) //Time SOUTH+
if(!num)
num = 0
. = num+1
else if(findtext(Y,"CENTER"))
. = usr.client.view+1
//Debug procs
/client/proc/test_movable_UI()
@@ -81,4 +125,4 @@
S.screen_loc = screen_l
screen += S
screen += S
+34 -18
View File
@@ -19,9 +19,12 @@
spell_objects.Cut()
if(spell_holder)
spell_holder.spell_masters -= src
if(spell_holder.client && spell_holder.client.screen)
spell_holder.client.screen -= src
spell_holder = null
/obj/screen/movable/spell_master/ResetVars()
..("spell_objects")
..("spell_objects", args)
spell_objects = list()
/obj/screen/movable/spell_master/MouseDrop()
@@ -47,25 +50,34 @@
overlays.len = 0
overlays.Add(closed_state)
else if(forced_state != 1)
var/temp_loc = screen_loc
var/x_position = text2num(copytext(temp_loc, 1, findtext(temp_loc, ":")))
var/x_pix = text2num(copytext(temp_loc, findtext(temp_loc, ":") + 1, findtext(temp_loc, ",")))
temp_loc = copytext(temp_loc, findtext(temp_loc, ",") + 1)
var/y_position = text2num(copytext(temp_loc, 1, findtext(temp_loc, ":")))
var/y_pix = text2num(copytext(temp_loc, findtext(temp_loc, ":")+1))
for(var/i = 1; i <= spell_objects.len; i++)
var/obj/screen/spell/S = spell_objects[i]
S.screen_loc = "[x_position + (x_position < 8 ? 1 : -1)*(i%7)]:[x_pix],[y_position + (y_position < 8 ? round(i/7) : -round(i/7))]:[y_pix]"
if(spell_holder && spell_holder.client)
spell_holder.client.screen += S
S.handle_icon_updates = 1
open_spellmaster()
update_spells(1)
showing = 1
overlays.len = 0
overlays.Add(open_state)
/obj/screen/movable/spell_master/proc/open_spellmaster()
var/list/screen_loc_xy = text2list(screen_loc,",")
//Create list of X offsets
var/list/screen_loc_X = text2list(screen_loc_xy[1],":")
var/x_position = decode_screen_X(screen_loc_X[1])
var/x_pix = screen_loc_X[2]
//Create list of Y offsets
var/list/screen_loc_Y = text2list(screen_loc_xy[2],":")
var/y_position = decode_screen_Y(screen_loc_Y[1])
var/y_pix = screen_loc_Y[2]
for(var/i = 1; i <= spell_objects.len; i++)
var/obj/screen/spell/S = spell_objects[i]
var/xpos = x_position + (x_position < 8 ? 1 : -1)*(i%7)
var/ypos = y_position + (y_position < 8 ? round(i/7) : -round(i/7))
S.screen_loc = "[encode_screen_X(xpos)]:[x_pix],[encode_screen_Y(ypos)]:[y_pix]"
if(spell_holder && spell_holder.client)
spell_holder.client.screen += S
S.handle_icon_updates = 1
/obj/screen/movable/spell_master/proc/add_spell(var/spell/spell)
if(!spell) return
@@ -74,13 +86,14 @@
return
else
spell_objects.Add(spell.connected_button)
toggle_open(2)
if(spell_holder.client)
toggle_open(2)
return
if(spell.spell_flags & NO_BUTTON) //no button to add if we don't get one
return
var/obj/screen/spell/newscreen = new /obj/screen/spell
var/obj/screen/spell/newscreen = PoolOrNew(/obj/screen/spell)
newscreen.spellmaster = src
newscreen.spell = spell
@@ -96,7 +109,8 @@
newscreen.name = spell.name
newscreen.update_charge(1)
spell_objects.Add(newscreen)
toggle_open(2) //forces the icons to refresh on screen
if(spell_holder.client)
toggle_open(2) //forces the icons to refresh on screen
/obj/screen/movable/spell_master/proc/remove_spell(var/spell/spell)
qdel(spell.connected_button)
@@ -151,6 +165,8 @@
last_charged_icon = null
if(spellmaster)
spellmaster.spell_objects -= src
if(spellmaster.spell_holder && spellmaster.spell_holder.client)
spellmaster.spell_holder.client.screen -= src
if(spellmaster && !spellmaster.spell_objects.len)
qdel(spellmaster)
spellmaster = null
+4 -1
View File
@@ -166,7 +166,7 @@
if(H.mind && !player_is_antag(H.mind, only_offstation_roles = 1))
var/assignment = GetAssignment(H)
var/id = add_zero(num2hex(rand(1, 1.6777215E7)), 6) //this was the best they could come up with? A large random number? *sigh*
var/id = generate_record_id()
//General Record
var/datum/data/record/G = CreateGeneralRecord(H, id)
G.fields["name"] = H.real_name
@@ -222,6 +222,9 @@
locked += L
return
/proc/generate_record_id()
return add_zero(num2hex(rand(1, 65535)), 4) //no point generating higher numbers because of the limitations of num2hex
proc/get_id_photo(var/mob/living/carbon/human/H, var/assigned_role)
var/icon/preview_icon = null
+89 -17
View File
@@ -11,13 +11,13 @@
idle_power_usage = 2
active_power_usage = 4
var/_wifi_id
var/datum/wifi/sender/button/wifi_sender
var/datum/wifi/sender/wifi_sender
/obj/machinery/button/initialize()
..()
update_icon()
if(_wifi_id)
wifi_sender = new(_wifi_id, src)
if(_wifi_id && !wifi_sender)
wifi_sender = new/datum/wifi/sender/button(_wifi_id, src)
/obj/machinery/button/Destroy()
qdel(wifi_sender)
@@ -31,7 +31,7 @@
return attack_hand(user)
/obj/machinery/button/attack_hand(mob/living/user)
..()
if(..()) return 1
activate(user)
/obj/machinery/button/proc/activate(mob/living/user)
@@ -55,13 +55,24 @@
icon_state = "launcherbtt"
//alternate button with the same functionality, except has a lightswitch sprite instead
/obj/machinery/button/alternate
/obj/machinery/button/switch
icon = 'icons/obj/power.dmi'
icon_state = "light0"
/obj/machinery/button/alternate/update_icon()
/obj/machinery/button/switch/update_icon()
icon_state = "light[active]"
//alternate button with the same functionality, except has a door control sprite instead
/obj/machinery/button/alternate
icon = 'icons/obj/stationobjs.dmi'
icon_state = "doorctrl0"
/obj/machinery/button/alternate/update_icon()
if(active)
icon_state = "doorctrl0"
else
icon_state = "doorctrl2"
//Toggle button with two states (on and off) and calls seperate procs for each state
/obj/machinery/button/toggle/activate(mob/living/user)
if(operating || !istype(wifi_sender))
@@ -77,55 +88,116 @@
update_icon()
operating = 0
/obj/machinery/button/toggle/alternate
//alternate button with the same toggle functionality, except has a lightswitch sprite instead
/obj/machinery/button/toggle/switch
icon = 'icons/obj/power.dmi'
icon_state = "light0"
/obj/machinery/button/toggle/alternate/update_icon()
/obj/machinery/button/toggle/switch/update_icon()
icon_state = "light[active]"
//alternate button with the same toggle functionality, except has a door control sprite instead
/obj/machinery/button/toggle/alternate
icon = 'icons/obj/stationobjs.dmi'
icon_state = "doorctrl0"
/obj/machinery/button/toggle/alternate/update_icon()
if(active)
icon_state = "doorctrl0"
else
icon_state = "doorctrl2"
//-------------------------------
// Mass Driver Button
// Passes the activate call to a mass driver wifi sender
//-------------------------------
/obj/machinery/button/mass_driver
var/datum/wifi/sender/mass_driver/sender
name = "mass driver button"
/obj/machinery/button/mass_driver/initialize()
if(_wifi_id)
wifi_sender = new/datum/wifi/sender/mass_driver(_wifi_id, src)
..()
sender = new(_wifi_id, src)
/obj/machinery/button/mass_driver/activate(mob/living/user)
if(active || !istype(wifi_sender))
return
active = 1
use_power(5)
update_icon()
sender.cycle()
wifi_sender.activate()
active = 0
update_icon()
//-------------------------------
// Door Button
//-------------------------------
// Bitmasks for door switches.
#define OPEN 0x1
#define IDSCAN 0x2
#define BOLTS 0x4
#define SHOCK 0x8
#define SAFE 0x10
/obj/machinery/button/toggle/door
var/datum/wifi/sender/door/sender
icon = 'icons/obj/stationobjs.dmi'
icon_state = "doorctrl0"
var/_door_functions = 1
/* Bitflag, 1 = open
2 = idscan
4 = bolts
8 = shock
16 = door safties */
/obj/machinery/button/toggle/door/update_icon()
if(active)
icon_state = "doorctrl0"
else
icon_state = "doorctrl2"
/obj/machinery/button/toggle/door/initialize()
if(_wifi_id)
wifi_sender = new/datum/wifi/sender/door(_wifi_id, src)
..()
sender = new(_wifi_id, src)
/obj/machinery/button/toggle/door/activate(mob/living/user)
if(operating || !istype(sender))
if(operating || !istype(wifi_sender))
return
operating = 1
active = !active
use_power(5)
update_icon()
if(!active)
sender.open()
if(active)
if(_door_functions & IDSCAN)
wifi_sender.activate("enable_idscan")
if(_door_functions & SHOCK)
wifi_sender.activate("electrify")
if(_door_functions & SAFE)
wifi_sender.activate("enable_safeties")
if(_door_functions & BOLTS)
wifi_sender.activate("unlock")
if(_door_functions & OPEN)
wifi_sender.activate("open")
else
sender.close()
if(_door_functions & IDSCAN)
wifi_sender.activate("disable_idscan")
if(_door_functions & SHOCK)
wifi_sender.activate("unelectrify")
if(_door_functions & SAFE)
wifi_sender.activate("disable_safeties")
if(_door_functions & OPEN)
wifi_sender.activate("close")
if(_door_functions & BOLTS)
wifi_sender.activate("lock")
operating = 0
#undef OPEN
#undef IDSCAN
#undef BOLTS
#undef SHOCK
#undef SAFE
+12 -2
View File
@@ -136,9 +136,19 @@
if(weld(W, user))
if(assembly)
assembly.loc = src.loc
assembly.state = 1
assembly.anchored = 1
assembly.camera_name = c_tag
assembly.camera_network = english_list(network, "Exodus", ",", ",")
assembly.update_icon()
assembly.dir = src.dir
assembly = null //so qdel doesn't eat it.
new /obj/item/stack/cable_coil(src.loc, length=2)
if(stat & BROKEN)
assembly.state = 2
user << "<span class='notice'>You repaired \the [src] frame.</span>"
else
assembly.state = 1
user << "<span class='notice'>You cut \the [src] free from the wall.</span>"
new /obj/item/stack/cable_coil(src.loc, length=2)
qdel(src)
// OTHER
@@ -11,6 +11,8 @@
// Motion, EMP-Proof, X-Ray
var/list/obj/item/possible_upgrades = list(/obj/item/device/assembly/prox_sensor, /obj/item/stack/material/osmium, /obj/item/weapon/stock_parts/scanning_module)
var/list/upgrades = list()
var/camera_name
var/camera_network
var/state = 0
var/busy = 0
/*
@@ -47,7 +49,7 @@
else if(iswrench(W))
playsound(src.loc, 'sound/items/Ratchet.ogg', 50, 1)
user << "You unattach the assembly from it's place."
user << "You unattach the assembly from its place."
anchored = 0
update_icon()
state = 0
@@ -67,7 +69,7 @@
else if(iswelder(W))
if(weld(W, user))
user << "You unweld the assembly from it's place."
user << "You unweld the assembly from its place."
state = 1
anchored = 1
return
@@ -78,7 +80,7 @@
if(isscrewdriver(W))
playsound(src.loc, 'sound/items/Screwdriver.ogg', 50, 1)
var/input = sanitize(input(usr, "Which networks would you like to connect this camera to? Separate networks with a comma. No Spaces!\nFor example: Exodus,Security,Secret ", "Set Network", NETWORK_EXODUS))
var/input = sanitize(input(usr, "Which networks would you like to connect this camera to? Separate networks with a comma. No Spaces!\nFor example: Exodus,Security,Secret", "Set Network", camera_network ? camera_network : NETWORK_EXODUS))
if(!input)
usr << "No input found please hang up and try your call again."
return
@@ -90,7 +92,7 @@
var/area/camera_area = get_area(src)
var/temptag = "[sanitize(camera_area.name)] ([rand(1, 999)])"
input = sanitizeSafe(input(usr, "How would you like to name the camera?", "Set Camera Name", temptag), MAX_NAME_LEN)
input = sanitizeSafe(input(usr, "How would you like to name the camera?", "Set Camera Name", camera_name ? camera_name : temptag), MAX_NAME_LEN)
state = 4
var/obj/machinery/camera/C = new(src.loc)
+1 -4
View File
@@ -1039,10 +1039,7 @@ About the new airlock wires panel:
if(A.closeOtherId == src.closeOtherId && A != src)
src.closeOther = A
break
//wireless connection
if(_wifi_id)
wifi_receiver = new(_wifi_id, src)
..()
/obj/machinery/door/airlock/Destroy()
qdel(wires)
+5 -1
View File
@@ -130,11 +130,15 @@ obj/machinery/door/airlock/proc/set_frequency(new_frequency)
obj/machinery/door/airlock/initialize()
..()
if(frequency)
set_frequency(frequency)
update_icon()
//wireless connection
if(_wifi_id)
wifi_receiver = new(_wifi_id, src)
update_icon()
obj/machinery/door/airlock/New()
..()
+26 -12
View File
@@ -88,7 +88,7 @@
//Processes the occupant, drawing from the internal power cell if needed.
/obj/machinery/recharge_station/proc/process_occupant()
if(istype(occupant, /mob/living/silicon/robot))
if(isrobot(occupant))
var/mob/living/silicon/robot/R = occupant
if(R.module)
@@ -103,6 +103,12 @@
R.adjustBruteLoss(-weld_rate)
if(wire_rate && R.getFireLoss() && cell.checked_use(wire_power_use * wire_rate * CELLRATE))
R.adjustFireLoss(-wire_rate)
else if(ishuman(occupant))
var/mob/living/carbon/human/H = occupant
if(!isnull(H.internal_organs_by_name["cell"]) && H.nutrition < 450)
H.nutrition = min(H.nutrition+10, 450)
cell.use(7000/450*10)
/obj/machinery/recharge_station/examine(mob/user)
..(user)
@@ -199,24 +205,30 @@
/obj/machinery/recharge_station/Bumped(var/mob/living/silicon/robot/R)
go_in(R)
/obj/machinery/recharge_station/proc/go_in(var/mob/living/silicon/robot/R)
if(!istype(R))
return
/obj/machinery/recharge_station/proc/go_in(var/mob/M)
if(occupant)
return
if(R.incapacitated())
return
if(!R.cell)
if(!hascell(M))
return
add_fingerprint(R)
R.reset_view(src)
R.forceMove(src)
occupant = R
add_fingerprint(M)
M.reset_view(src)
M.forceMove(src)
occupant = M
update_icon()
return 1
/obj/machinery/recharge_station/proc/hascell(var/mob/M)
if(isrobot(M))
var/mob/living/silicon/robot/R = M
if(R.cell)
return 1
if(ishuman(M))
var/mob/living/carbon/human/H = M
if(!isnull(H.internal_organs_by_name["cell"]))
return 1
return 0
/obj/machinery/recharge_station/proc/go_out()
if(!occupant)
return
@@ -243,4 +255,6 @@
set name = "Enter Recharger"
set src in oview(1)
if(!usr.incapacitated())
return
go_in(usr)
+1 -1
View File
@@ -88,7 +88,7 @@ obj/machinery/scanner/attack_hand(mob/living/carbon/human/user)
G.fields["rank"] = "Unassigned"
G.fields["real_rank"] = G.fields["rank"]
G.fields["name"] = mname
G.fields["id"] = text("[]", add_zero(num2hex(rand(1, 1.6777215E7)), 6))
G.fields["id"] = generate_record_id()
M.fields["name"] = G.fields["name"]
M.fields["id"] = G.fields["id"]
S.fields["name"] = G.fields["name"]
+3
View File
@@ -248,6 +248,9 @@
// for items that can be placed in multiple slots
// note this isn't called during the initial dressing of a player
/obj/item/proc/equipped(var/mob/user, var/slot)
layer = 20
if(user.client) user.client.screen |= src
if(user.pulling == src) user.stop_pulling()
return
//Defines which slots correspond to which slot flags
@@ -18,9 +18,11 @@
/obj/item/device/chameleon/dropped()
disrupt()
..()
/obj/item/device/chameleon/equipped()
disrupt()
..()
/obj/item/device/chameleon/attack_self()
toggle()
@@ -35,7 +35,7 @@
else
user << "<span class='warning'>Access Denied</span>"
else if(istype(W, /obj/item/weapon/melee/energy/blade))
if(emag_act(INFINITY, user, "The locker has been sliced open by [user] with an energy blade!", "You hear metal being sliced and sparks flying."))
if(emag_act(INFINITY, user, W, "The locker has been sliced open by [user] with an energy blade!", "You hear metal being sliced and sparks flying."))
var/datum/effect/effect/system/spark_spread/spark_system = new /datum/effect/effect/system/spark_spread()
spark_system.set_up(5, 0, src.loc)
spark_system.start()
@@ -55,7 +55,7 @@
..()
return
/obj/item/weapon/storage/lockbox/emag_act(var/remaining_charges, var/mob/user, var/visual_feedback = "", var/audible_feedback = "")
/obj/item/weapon/storage/lockbox/emag_act(var/remaining_charges, var/mob/user, var/emag_source, var/visual_feedback = "", var/audible_feedback = "")
if(!broken)
if(visual_feedback)
visual_feedback = "<span class='warning'>[visual_feedback]</span>"
@@ -165,19 +165,18 @@
if(1)
for(var/atom/movable/A as mob|obj in src)//pulls everything out of the locker and hits it with an explosion
A.forceMove(src.loc)
A.ex_act(severity++)
A.ex_act(severity + 1)
qdel(src)
if(2)
if(prob(50))
for (var/atom/movable/A as mob|obj in src)
A.forceMove(src.loc)
A.ex_act(severity++)
A.ex_act(severity + 1)
qdel(src)
if(3)
if(prob(5))
for(var/atom/movable/A as mob|obj in src)
A.forceMove(src.loc)
A.ex_act(severity++)
qdel(src)
/obj/structure/closet/proc/damage(var/damage)
@@ -92,7 +92,7 @@
else
togglelock(user)
/obj/structure/closet/secure_closet/attack_hand(var/remaining_charges, var/mob/user, var/visual_feedback, var/audible_feedback)
/obj/structure/closet/secure_closet/emag_act(var/remaining_charges, var/mob/user, var/emag_source, var/visual_feedback = "", var/audible_feedback = "")
if(!broken)
broken = 1
locked = 0
@@ -102,8 +102,11 @@
if(visual_feedback)
visible_message(visual_feedback, audible_feedback)
else if(user && emag_source)
visible_message("<span class='warning'>\The [src] has been broken by \the [user] with \an [emag_source]!</span>", "You hear a faint electrical spark.")
else
visible_message("<span class='warning'>The locker has been broken by [user] with an electromagnetic card!</span>", "You hear a faint electrical spark.")
visible_message("<span class='warning'>\The [src] sparks and breaks open!</span>", "You hear a faint electrical spark.")
return 1
/obj/structure/closet/secure_closet/attack_hand(mob/user as mob)
src.add_fingerprint(user)
+2 -1
View File
@@ -31,6 +31,7 @@
if(held_item)
var/damagetype = held_item.suicide_act(src)
if(damagetype)
log_and_message_admins("[key_name(src)] commited suicide using \a [held_item]")
var/damage_mod = 1
switch(damagetype) //Sorry about the magic numbers.
//brute = 1, burn = 2, tox = 4, oxy = 8
@@ -70,7 +71,7 @@
updatehealth()
return
log_and_message_admins("[key_name(src)] commited suicide")
viewers(src) << pick("<span class='danger'>[src] is attempting to bite \his tongue off! It looks like \he's trying to commit suicide.</span>", \
"<span class='danger'>[src] is jamming \his thumbs into \his eye sockets! It looks like \he's trying to commit suicide.</span>", \
"<span class='danger'>[src] is twisting \his own neck! It looks like \he's trying to commit suicide.</span>", \
+15
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)
+26 -23
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")
@@ -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
+13 -43
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.
+2 -5
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"
+5 -1
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)
+35 -47
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>")
@@ -1389,6 +1389,48 @@
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."
@@ -1398,3 +1440,4 @@
pulling_punches = !pulling_punches
src << "<span class='notice'>You are now [pulling_punches ? "pulling your punches" : "not pulling your punches"].</span>"
return
@@ -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"
@@ -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
@@ -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)
@@ -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)
+3
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>"
@@ -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()
@@ -304,7 +307,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
@@ -417,7 +421,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()
@@ -449,7 +454,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()
@@ -492,7 +498,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()
@@ -534,7 +541,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()
@@ -562,7 +570,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)
@@ -585,7 +594,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()
+1 -1
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"] )
+2 -2
View File
@@ -140,8 +140,8 @@ nanoui is used to open and update nano browser uis
* @return nothing
*/
/datum/nanoui/proc/update_status(var/push_update = 0)
var/datum/host = src_object.nano_host()
var/new_status = host.CanUseTopic(user, state)
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)
+5 -6
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
+3 -2
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
+2 -1
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)
+1 -1
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)
+1 -1
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
@@ -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
+1
View File
@@ -0,0 +1 @@
#define SURGERY_FAILURE -1
+31 -31
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)
//////////////////////////////////////////////////////////////////
+42 -42
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>")
+4 -4
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
+1
View File
@@ -0,0 +1 @@
#undef SURGERY_FAILURE
+55 -20
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)
+5
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
+14 -9
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
+32
View File
@@ -56,6 +56,38 @@
-->
<div class="commit sansserif">
<h2 class="date">06 December 2015</h2>
<h3 class="author">Hubblenaut updated:</h3>
<ul class="changes bgimages16">
<li class="bugfix">Welding a broken camera will use the correct icon.</li>
<li class="tweak">Camera assemblies remember their tag and network from previous usage.</li>
<li class="tweak">Mobs on help intent will not push others that aren't.</li>
</ul>
<h3 class="author">Loganbacca updated:</h3>
<ul class="changes bgimages16">
<li class="rscadd">Added a backend (wireless) system for communication between machinery and other devices.</li>
</ul>
<h3 class="author">Neerti updated:</h3>
<ul class="changes bgimages16">
<li class="rscadd">The AI can now toggle whether its hologram will move towards the center of its view using the 'Toggle Hologram Movement' verb.</li>
</ul>
<h3 class="author">PsiOmegaDelta updated:</h3>
<ul class="changes bgimages16">
<li class="tweak">Helmet cameras are no longer enabled by clicking the helmet, instead there is a 'Toggle Helmet Camera' verb.</li>
</ul>
<h3 class="author">Raptor1628 updated:</h3>
<ul class="changes bgimages16">
<li class="tweak">Armory layout changed, weapons returned to static amounts.</li>
<li class="rscadd">New security armor and helmet sprites added.</li>
</ul>
<h3 class="author">Zuhayr updated:</h3>
<ul class="changes bgimages16">
<li class="tweak">Backend change: allowed accessories to be placed on any clothing item with the appropriate variables set.</li>
<li class="rscadd">Drones can now pull a variety of things (such as scrubbers). This came with a pulling refactor so please report any strangeness with pulling in general.</li>
<li class="rscadd">Drones (and any mob that can be picked up) can be bashed against airlocks and such to use their internal access, so long as the person using them does not have an ID card equipped.</li>
<li class="tweak">Rewrote fireaxe cabinets. Click with a multitool to unlock or loc, click with a hand to open or close, smash with anything that does damage, and drag onto your icon to remove the fireaxe.</li>
</ul>
<h2 class="date">22 November 2015</h2>
<h3 class="author">PsiOmegaDelta updated:</h3>
<ul class="changes bgimages16">
+28
View File
@@ -2393,3 +2393,31 @@ DO NOT EDIT THIS FILE BY HAND! AUTOMATICALLY GENERATED BY ss13_genchangelog.py.
- bugfix: Laptop Vendors now accept ID Containers (PDA, Wallet, etc).
- bugfix: Personal Lockers now accept ID Containers (PDA, Wallet, etc).
- experiment: Add /tg/-like attack overlays.
2015-12-06:
Hubblenaut:
- bugfix: Welding a broken camera will use the correct icon.
- tweak: Camera assemblies remember their tag and network from previous usage.
- tweak: Mobs on help intent will not push others that aren't.
Loganbacca:
- rscadd: Added a backend (wireless) system for communication between machinery
and other devices.
Neerti:
- rscadd: The AI can now toggle whether its hologram will move towards the center
of its view using the 'Toggle Hologram Movement' verb.
PsiOmegaDelta:
- tweak: Helmet cameras are no longer enabled by clicking the helmet, instead there
is a 'Toggle Helmet Camera' verb.
Raptor1628:
- tweak: Armory layout changed, weapons returned to static amounts.
- rscadd: New security armor and helmet sprites added.
Zuhayr:
- tweak: 'Backend change: allowed accessories to be placed on any clothing item
with the appropriate variables set.'
- rscadd: Drones can now pull a variety of things (such as scrubbers). This came
with a pulling refactor so please report any strangeness with pulling in general.
- rscadd: Drones (and any mob that can be picked up) can be bashed against airlocks
and such to use their internal access, so long as the person using them does
not have an ID card equipped.
- tweak: Rewrote fireaxe cabinets. Click with a multitool to unlock or loc, click
with a hand to open or close, smash with anything that does damage, and drag
onto your icon to remove the fireaxe.
-4
View File
@@ -1,4 +0,0 @@
author: Loganbacca
delete-after: True
changes:
- rscadd: "Added a backend (wireless) system for communication between machinery and other devices."
@@ -1,4 +0,0 @@
author: PsiOmegaDelta
delete-after: True
changes:
- tweak: "Helmet cameras are no longer enabled by clicking the helmet, instead there is a 'Toggle Helmet Camera' verb."
@@ -1,4 +0,0 @@
author: Neerti
delete-after: True
changes:
- rscadd: "The AI can now toggle whether its hologram will move towards the center of its view using the 'Toggle Hologram Movement' verb."
-5
View File
@@ -1,5 +0,0 @@
author: Raptor1628
delete-after: True
changes:
- tweak: "Armory layout changed, weapons returned to static amounts."
- rscadd: "New security armor and helmet sprites added."
-5
View File
@@ -1,5 +0,0 @@
author: Zuhayr
delete-after: True
changes:
- tweak: "Backend change: allowed accessories to be placed on any clothing item with the appropriate variables set."
-5
View File
@@ -1,5 +0,0 @@
author: Zuhayr
delete-after: True
changes:
- rscadd: Drones can now pull a variety of things (such as scrubbers). This came with a pulling refactor so please report any strangeness with pulling in general.
- rscadd: Drones (and any mob that can be picked up) can be bashed against airlocks and such to use their internal access, so long as the person using them does not have an ID card equipped.
-4
View File
@@ -1,4 +0,0 @@
author: Zuhayr
delete-after: True
changes:
- tweak: "Rewrote fireaxe cabinets. Click with a multitool to unlock or loc, click with a hand to open or close, smash with anything that does damage, and drag onto your icon to remove the fireaxe."
Binary file not shown.

Before

Width:  |  Height:  |  Size: 166 KiB

After

Width:  |  Height:  |  Size: 184 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 94 KiB

After

Width:  |  Height:  |  Size: 96 KiB

+10 -6
View File
@@ -3,29 +3,33 @@
# Four arguments, password host channel and message.
# EG: "ircbot_message.py hunter2 example.com #adminchannel ADMINHELP, people are killing me!"
import sys,cPickle,socket,HTMLParser
import sys
import cPickle
import socket
import HTMLParser
def pack():
ht = HTMLParser.HTMLParser()
passwd = sys.argv[1]
ip = sys.argv[3]
try:
data = []
for in_data in sys.argv[4:]: #The rest of the arguments is data
for in_data in sys.argv[4:]: #The rest of the arguments is data
data += {ht.unescape(in_data)}
except:
data = "NO DATA SPECIFIED"
dictionary = {"ip":ip,"data":[passwd] + data}
dictionary = {"ip": ip, "data": [passwd] + data}
pickled = cPickle.dumps(dictionary)
nudge(pickled)
def nudge(data):
HOST = sys.argv[2]
PORT = 45678
s = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
s.connect((HOST,PORT))
s.connect((HOST, PORT))
s.send(data)
s.close()
if __name__ == "__main__" and len(sys.argv) > 1: # If not imported and more than one argument
if __name__ == "__main__" and len(sys.argv) > 1: # If not imported and more than one argument
pack()
+39 -26
View File
@@ -26,7 +26,13 @@ THE SOFTWARE.
'''
from __future__ import print_function
import yaml, os, glob, sys, re, time, argparse
import yaml
import os
import glob
import sys
import re
import time
import argparse
from datetime import datetime, date
from time import time
@@ -58,6 +64,7 @@ validPrefixes = [
'experiment'
]
def dictToTuples(inp):
return [(k, v) for k, v in inp.items()]
@@ -69,7 +76,7 @@ if os.path.isfile(changelog_cache):
with open(changelog_cache) as f:
(_, all_changelog_entries) = yaml.load_all(f)
failed_cache_read = False
# Convert old timestamps to newer format.
new_entries = {}
for _date in all_changelog_entries.keys():
@@ -85,26 +92,26 @@ if os.path.isfile(changelog_cache):
except Exception as e:
print("Failed to read cache:")
print(e, file=sys.stderr)
if args.dryRun:
if args.dryRun:
changelog_cache = os.path.join(args.ymlDir, '.dry_changelog.yml')
if failed_cache_read and os.path.isfile(args.targetFile):
from bs4 import BeautifulSoup
from bs4.element import NavigableString
print(' Generating cache...')
with open(args.targetFile, 'r') as f:
soup = BeautifulSoup(f)
for e in soup.find_all('div', {'class':'commit'}):
for e in soup.find_all('div', {'class': 'commit'}):
entry = {}
date = datetime.strptime(e.h2.string.strip(), dateformat).date() # key
for authorT in e.find_all('h3', {'class':'author'}):
for authorT in e.find_all('h3', {'class': 'author'}):
author = authorT.string
# Strip suffix
if author.endswith('updated:'):
author = author[:-8]
author = author.strip()
# Find <ul>
ulT = authorT.next_sibling
while(ulT.name != 'ul'):
@@ -112,26 +119,29 @@ if failed_cache_read and os.path.isfile(args.targetFile):
changes = []
for changeT in ulT.children:
if changeT.name != 'li': continue
if changeT.name != 'li':
continue
val = changeT.decode_contents(formatter="html")
newdat = {changeT['class'][0] + '': val + ''}
if newdat not in changes:
changes += [newdat]
if len(changes) > 0:
entry[author] = changes
if date in all_changelog_entries:
all_changelog_entries[date].update(entry)
else:
all_changelog_entries[date] = entry
del_after = []
errors = False
print('Reading changelogs...')
for fileName in glob.glob(os.path.join(args.ymlDir, "*.yml")):
name, ext = os.path.splitext(os.path.basename(fileName))
if name.startswith('.'): continue
if name == 'example': continue
if name.startswith('.'):
continue
if name == 'example':
continue
fileName = os.path.abspath(fileName)
print(' Reading {}...'.format(fileName))
cl = {}
@@ -151,54 +161,57 @@ for fileName in glob.glob(os.path.join(args.ymlDir, "*.yml")):
print(' {0}: Invalid prefix {1}'.format(fileName, change_type), file=sys.stderr)
author_entries += [change]
new += 1
all_changelog_entries[today][cl['author']] = author_entries
all_changelog_entries[today][cl['author']] = author_entries
if new > 0:
print(' Added {0} new changelog entries.'.format(new))
if cl.get('delete-after', False):
if os.path.isfile(fileName):
if args.dryRun:
print(' Would delete {0} (delete-after set)...'.format(fileName))
else:
del_after += [fileName]
if args.dryRun: continue
if args.dryRun:
continue
cl['changes'] = []
with open(fileName, 'w') as f:
yaml.dump(cl, f, default_flow_style=False)
yaml.dump(cl, f, default_flow_style=False)
targetDir = os.path.dirname(args.targetFile)
with open(args.targetFile.replace('.htm', '.dry.htm') if args.dryRun else args.targetFile, 'w') as changelog:
with open(os.path.join(targetDir, 'templates', 'header.html'), 'r') as h:
for line in h:
changelog.write(line)
for _date in reversed(sorted(all_changelog_entries.keys())):
entry_htm = '\n'
entry_htm += '\t\t\t<h2 class="date">{date}</h2>\n'.format(date=_date.strftime(dateformat))
write_entry = False
for author in sorted(all_changelog_entries[_date].keys()):
if len(all_changelog_entries[_date]) == 0: continue
if len(all_changelog_entries[_date]) == 0:
continue
author_htm = '\t\t\t<h3 class="author">{author} updated:</h3>\n'.format(author=author)
author_htm += '\t\t\t<ul class="changes bgimages16">\n'
changes_added = []
for (css_class, change) in (dictToTuples(e)[0] for e in all_changelog_entries[_date][author]):
if change in changes_added: continue
if change in changes_added:
continue
write_entry = True
changes_added += [change]
changes_added += [change]
author_htm += '\t\t\t\t<li class="{css_class}">{change}</li>\n'.format(css_class=css_class, change=change.strip())
author_htm += '\t\t\t</ul>\n'
if len(changes_added) > 0:
entry_htm += author_htm
if write_entry:
changelog.write(entry_htm)
with open(os.path.join(targetDir, 'templates', 'footer.html'), 'r') as h:
for line in h:
changelog.write(line)
with open(changelog_cache, 'w') as f:
cache_head = 'DO NOT EDIT THIS FILE BY HAND! AUTOMATICALLY GENERATED BY ss13_genchangelog.py.'
+38 -22
View File
@@ -7,50 +7,56 @@ from subprocess import Popen, PIPE
_JAVA_PATH = ["java"]
_DMITOOL_CMD = ["-jar", "dmitool.jar"]
def _dmitool_call(*dmitool_args, **popen_args):
return Popen(_JAVA_PATH + _DMITOOL_CMD + [str(arg) for arg in dmitool_args], **popen_args)
def _safe_parse(dict, key, deferred_value):
try:
dict[key] = deferred_value()
except Exception as e:
print "Could not parse property '%s': %s"%(key, e)
print "Could not parse property '%s': %s" % (key, e)
return e
return False
def version():
""" Returns the version as a string. """
stdout, stderr = _dmitool_call("version", stdout=PIPE).communicate()
return str(stdout).strip()
def help():
""" Returns the help text as a string. """
stdout, stderr = _dmitool_call("help", stdout=PIPE).communicate()
return str(stdout).strip()
def info(filepath):
""" Totally not a hack that parses the output from dmitool into a dictionary.
May break at any moment.
"""
subproc = _dmitool_call("info", filepath, stdout=PIPE)
stdout, stderr = subproc.communicate()
result = {}
data = stdout.split(os.linesep)[1:]
#for s in data: print s
#parse header line
# for s in data: print s
# parse header line
if len(data) > 0:
header = data.pop(0).split(",")
#don't need to parse states, it's redundant
# don't need to parse states, it's redundant
_safe_parse(result, "images", lambda: int(header[0].split()[0].strip()))
_safe_parse(result, "size", lambda: header[2].split()[1].strip())
#parse state information
# parse state information
states = []
for item in data:
if not len(item): continue
if not len(item):
continue
stateinfo = {}
item = item.split(",", 3)
_safe_parse(stateinfo, "name", lambda: item[0].split()[1].strip(" \""))
@@ -58,37 +64,47 @@ def info(filepath):
_safe_parse(stateinfo, "frames", lambda: int(item[2].split()[0].strip()))
if len(item) > 3:
stateinfo["misc"] = item[3]
states.append(stateinfo)
result["states"] = states
return result
def extract_state(input_path, output_path, icon_state, direction=None, frame=None):
""" Extracts an icon state as a png to a given path.
If provided direction should be a string, one of S, N, E, W, SE, SW, NE, NW.
If provided frame should be a frame number or a string of two frame number separated by a dash.
"""
args = ["extract", input_path, icon_state, output_path]
if direction is not None: args.extend(("direction" , str(direction)))
if frame is not None: args.extend(("frame" , str(frame)))
if direction is not None:
args.extend(("direction", str(direction)))
if frame is not None:
args.extend(("frame", str(frame)))
return _dmitool_call(*args)
def import_state(target_path, input_path, icon_state, replace=False, delays=None, rewind=False, loop=None, ismovement=False, direction=None, frame=None):
""" Inserts an input png given by the input_path into the target_path.
"""
args = ["import", target_path, icon_state, input_path]
if replace: args.append("nodup")
if rewind: args.append("rewind")
if ismovement: args.append("movement")
if delays: args.extend(("delays", ",".join(delays)))
if direction is not None: args.extend(("direction", direction))
if frame is not None: args.extend(("frame", frame))
if replace:
args.append("nodup")
if rewind:
args.append("rewind")
if ismovement:
args.append("movement")
if delays:
args.extend(("delays", ",".join(delays)))
if direction is not None:
args.extend(("direction", direction))
if frame is not None:
args.extend(("frame", frame))
if loop in ("inf", "infinity"):
args.append("loop")
elif loop:
args.extend(("loopn", loop))
return _dmitool_call(*args)