diff --git a/baystation12.dme b/baystation12.dme
index 3682d724958..7031dd98066 100644
--- a/baystation12.dme
+++ b/baystation12.dme
@@ -632,9 +632,11 @@
#include "code\game\objects\items\weapons\circuitboards\computer\research.dm"
#include "code\game\objects\items\weapons\circuitboards\computer\supply.dm"
#include "code\game\objects\items\weapons\circuitboards\computer\telecomms.dm"
+#include "code\game\objects\items\weapons\circuitboards\machinery\biogenerator.dm"
#include "code\game\objects\items\weapons\circuitboards\machinery\cloning.dm"
#include "code\game\objects\items\weapons\circuitboards\machinery\pacman.dm"
#include "code\game\objects\items\weapons\circuitboards\machinery\power.dm"
+#include "code\game\objects\items\weapons\circuitboards\machinery\recharge_station.dm"
#include "code\game\objects\items\weapons\circuitboards\machinery\research.dm"
#include "code\game\objects\items\weapons\circuitboards\machinery\shieldgen.dm"
#include "code\game\objects\items\weapons\circuitboards\machinery\telecomms.dm"
@@ -789,6 +791,7 @@
#include "code\modules\admin\verbs\debug.dm"
#include "code\modules\admin\verbs\diagnostics.dm"
#include "code\modules\admin\verbs\getlogs.dm"
+#include "code\modules\admin\verbs\icarus.dm"
#include "code\modules\admin\verbs\mapping.dm"
#include "code\modules\admin\verbs\massmodvar.dm"
#include "code\modules\admin\verbs\modifyvariables.dm"
@@ -898,7 +901,10 @@
#include "code\modules\clothing\under\miscellaneous.dm"
#include "code\modules\clothing\under\shorts.dm"
#include "code\modules\clothing\under\syndicate.dm"
-#include "code\modules\clothing\under\ties.dm"
+#include "code\modules\clothing\under\accessories\accessory.dm"
+#include "code\modules\clothing\under\accessories\armband.dm"
+#include "code\modules\clothing\under\accessories\holster.dm"
+#include "code\modules\clothing\under\accessories\storage.dm"
#include "code\modules\clothing\under\jobs\civilian.dm"
#include "code\modules\clothing\under\jobs\engineering.dm"
#include "code\modules\clothing\under\jobs\medsci.dm"
@@ -1147,6 +1153,7 @@
#include "code\modules\mob\living\silicon\pai\recruit.dm"
#include "code\modules\mob\living\silicon\pai\say.dm"
#include "code\modules\mob\living\silicon\pai\software.dm"
+#include "code\modules\mob\living\silicon\pai\software_modules.dm"
#include "code\modules\mob\living\silicon\robot\analyzer.dm"
#include "code\modules\mob\living\silicon\robot\component.dm"
#include "code\modules\mob\living\silicon\robot\death.dm"
diff --git a/code/ATMOSPHERICS/components/unary/cold_sink.dm b/code/ATMOSPHERICS/components/unary/cold_sink.dm
index 766279a6302..82d7d41b7b8 100644
--- a/code/ATMOSPHERICS/components/unary/cold_sink.dm
+++ b/code/ATMOSPHERICS/components/unary/cold_sink.dm
@@ -7,52 +7,47 @@
icon = 'icons/obj/Cryogenic2.dmi'
icon_state = "freezer_0"
density = 1
-
- anchored = 1.0
-
- var/heatsink_temperature = T20C //the constant temperature resevoir into which the freezer pumps heat. Probably the hull of the station or something.
- var/internal_volume = 600 //L
-
+ anchored = 1
use_power = 0
- idle_power_usage = 5 //5 Watts for thermostat related circuitry
+ idle_power_usage = 5 // 5 Watts for thermostat related circuitry
- var/max_power_rating = 20000 //power rating when the usage is turned up to 100
+ var/heatsink_temperature = T20C // The constant temperature reservoir into which the freezer pumps heat. Probably the hull of the station or something.
+ var/internal_volume = 600 // L
+
+ var/max_power_rating = 20000 // Power rating when the usage is turned up to 100
var/power_setting = 100
- var/set_temperature = T20C //thermostat
+ var/set_temperature = T20C // Thermostat
var/cooling = 0
- var/opened = 0 //for deconstruction
/obj/machinery/atmospherics/unary/freezer/New()
..()
- air_contents.volume = internal_volume
initialize_directions = dir
-
component_parts = list()
component_parts += new /obj/item/weapon/circuitboard/unary_atmos/cooler(src)
component_parts += new /obj/item/weapon/stock_parts/matter_bin(src)
component_parts += new /obj/item/weapon/stock_parts/capacitor(src)
component_parts += new /obj/item/weapon/stock_parts/capacitor(src)
component_parts += new /obj/item/weapon/stock_parts/manipulator(src)
-
- power_rating = max_power_rating * (power_setting/100)
+ component_parts += new /obj/item/stack/cable_coil(src, 2)
+ RefreshParts()
/obj/machinery/atmospherics/unary/freezer/initialize()
- if(node) return
+ if(node)
+ return
var/node_connect = dir
- for(var/obj/machinery/atmospherics/target in get_step(src,node_connect))
- if(target.initialize_directions & get_dir(target,src))
+ for(var/obj/machinery/atmospherics/target in get_step(src, node_connect))
+ if(target.initialize_directions & get_dir(target, src))
node = target
break
update_icon()
-
/obj/machinery/atmospherics/unary/freezer/update_icon()
- if(src.node)
- if(src.use_power && cooling)
+ if(node)
+ if(use_power && cooling)
icon_state = "freezer_1"
else
icon_state = "freezer"
@@ -61,10 +56,10 @@
return
/obj/machinery/atmospherics/unary/freezer/attack_ai(mob/user as mob)
- src.ui_interact(user)
+ ui_interact(user)
/obj/machinery/atmospherics/unary/freezer/attack_hand(mob/user as mob)
- src.ui_interact(user)
+ ui_interact(user)
/obj/machinery/atmospherics/unary/freezer/ui_interact(mob/user, ui_key = "main", var/datum/nanoui/ui = null, var/force_open = 1)
// this is the data which will be sent to the ui
@@ -78,15 +73,15 @@
data["powerSetting"] = power_setting
var/temp_class = "good"
- if (air_contents.temperature > (T0C - 20))
+ if(air_contents.temperature > (T0C - 20))
temp_class = "bad"
- else if (air_contents.temperature < (T0C - 20) && air_contents.temperature > (T0C - 100))
+ else if(air_contents.temperature < (T0C - 20) && air_contents.temperature > (T0C - 100))
temp_class = "average"
data["gasTemperatureClass"] = temp_class
// update the ui if it exists, returns null if no ui is passed/found
ui = nanomanager.try_update_ui(user, src, ui_key, ui, data, force_open)
- if (!ui)
+ if(!ui)
// the ui does not exist, so we'll create a new() one
// for a list of parameters and their descriptions see the code docs in \code\modules\nano\nanoui.dm
ui = new(user, src, ui_key, "freezer.tmpl", "Gas Cooling System", 440, 300)
@@ -98,30 +93,31 @@
ui.set_auto_update(1)
/obj/machinery/atmospherics/unary/freezer/Topic(href, href_list)
- if (href_list["toggleStatus"])
- src.use_power = !src.use_power
+ if(href_list["toggleStatus"])
+ use_power = !use_power
update_icon()
if(href_list["temp"])
var/amount = text2num(href_list["temp"])
if(amount > 0)
- src.set_temperature = min(src.set_temperature+amount, 1000)
+ set_temperature = min(set_temperature + amount, 1000)
else
- src.set_temperature = max(src.set_temperature+amount, 0)
+ set_temperature = max(set_temperature + amount, 0)
if(href_list["setPower"]) //setting power to 0 is redundant anyways
var/new_setting = between(0, text2num(href_list["setPower"]), 100)
set_power_level(new_setting)
- src.add_fingerprint(usr)
+ add_fingerprint(usr)
return 1
/obj/machinery/atmospherics/unary/freezer/process()
..()
+
if(stat & (NOPOWER|BROKEN) || !use_power)
cooling = 0
update_icon()
return
- if (network && air_contents.temperature > set_temperature)
+ if(network && air_contents.temperature > set_temperature)
cooling = 1
var/heat_transfer = max( -air_contents.get_thermal_energy_change(set_temperature - 5), 0 )
@@ -132,7 +128,7 @@
heat_transfer = min(heat_transfer, cop * power_rating) //limit heat transfer by available power
var/removed = -air_contents.add_thermal_energy(-heat_transfer) //remove the heat
- if (debug)
+ if(debug)
visible_message("[src]: Removing [removed] W.")
use_power(power_rating)
@@ -147,49 +143,37 @@
/obj/machinery/atmospherics/unary/freezer/RefreshParts()
..()
var/cap_rating = 0
- var/cap_count = 0
var/manip_rating = 0
- var/manip_count = 0
var/bin_rating = 0
- var/bin_count = 0
for(var/obj/item/weapon/stock_parts/P in component_parts)
if(istype(P, /obj/item/weapon/stock_parts/capacitor))
cap_rating += P.rating
- cap_count++
if(istype(P, /obj/item/weapon/stock_parts/manipulator))
manip_rating += P.rating
- manip_count++
if(istype(P, /obj/item/weapon/stock_parts/matter_bin))
bin_rating += P.rating
- bin_count++
- cap_rating /= cap_count
- bin_rating /= bin_count
- manip_rating /= manip_count
- power_rating = initial(power_rating)*cap_rating //more powerful
- heatsink_temperature = initial(heatsink_temperature)/((manip_rating+bin_rating)/2) //more efficient
- air_contents.volume = max(initial(internal_volume) - 200, 0) + 200*bin_rating
+ power_rating = initial(power_rating) * cap_rating / 2 //more powerful
+ heatsink_temperature = initial(heatsink_temperature) / ((manip_rating + bin_rating) / 2) //more efficient
+ air_contents.volume = max(initial(internal_volume) - 200, 0) + 200 * bin_rating
set_power_level(power_setting)
/obj/machinery/atmospherics/unary/freezer/proc/set_power_level(var/new_power_setting)
power_setting = new_power_setting
power_rating = max_power_rating * (power_setting/100)
-//dismantling code. copied from autolathe
/obj/machinery/atmospherics/unary/freezer/attackby(var/obj/item/O as obj, var/mob/user as mob)
- if(istype(O, /obj/item/weapon/screwdriver))
- opened = !opened
- user << "You [opened ? "open" : "close"] the maintenance hatch of [src]."
+ if(default_deconstruction_screwdriver(user, O))
return
-
- if (opened && istype(O, /obj/item/weapon/crowbar))
- dismantle()
+ if(default_deconstruction_crowbar(user, O))
+ return
+ if(default_part_replacement(user, O))
return
..()
/obj/machinery/atmospherics/unary/freezer/examine(mob/user)
..(user)
- if (opened)
+ if(panel_open)
user << "The maintenance hatch is open."
diff --git a/code/ATMOSPHERICS/components/unary/heat_source.dm b/code/ATMOSPHERICS/components/unary/heat_source.dm
index 891a19cc74f..829f06f4202 100644
--- a/code/ATMOSPHERICS/components/unary/heat_source.dm
+++ b/code/ATMOSPHERICS/components/unary/heat_source.dm
@@ -7,25 +7,21 @@
icon = 'icons/obj/Cryogenic2.dmi'
icon_state = "heater_0"
density = 1
-
- anchored = 1.0
-
- var/set_temperature = T20C //thermostat
- var/max_temperature = T20C + 680
- var/internal_volume = 600 //L
-
+ anchored = 1
use_power = 0
idle_power_usage = 5 //5 Watts for thermostat related circuitry
+ var/max_temperature = T20C + 680
+ var/internal_volume = 600 //L
+
var/max_power_rating = 20000 //power rating when the usage is turned up to 100
var/power_setting = 100
+ var/set_temperature = T20C //thermostat
var/heating = 0 //mainly for icon updates
- var/opened = 0 //for deconstruction
/obj/machinery/atmospherics/unary/heater/New()
..()
- air_contents.volume = internal_volume
initialize_directions = dir
component_parts = list()
@@ -33,16 +29,18 @@
component_parts += new /obj/item/weapon/stock_parts/matter_bin(src)
component_parts += new /obj/item/weapon/stock_parts/capacitor(src)
component_parts += new /obj/item/weapon/stock_parts/capacitor(src)
+ component_parts += new /obj/item/stack/cable_coil(src, 5)
- power_rating = max_power_rating * (power_setting/100)
+ RefreshParts()
/obj/machinery/atmospherics/unary/heater/initialize()
- if(node) return
+ if(node)
+ return
var/node_connect = dir
- for(var/obj/machinery/atmospherics/target in get_step(src,node_connect))
- if(target.initialize_directions & get_dir(target,src))
+ for(var/obj/machinery/atmospherics/target in get_step(src, node_connect))
+ if(target.initialize_directions & get_dir(target, src))
node = target
break
@@ -50,8 +48,8 @@
/obj/machinery/atmospherics/unary/heater/update_icon()
- if(src.node)
- if(src.use_power && src.heating)
+ if(node)
+ if(use_power && heating)
icon_state = "heater_1"
else
icon_state = "heater"
@@ -68,7 +66,7 @@
update_icon()
return
- if (network && air_contents.total_moles && air_contents.temperature < set_temperature)
+ if(network && air_contents.total_moles && air_contents.temperature < set_temperature)
air_contents.add_thermal_energy(power_rating * HEATER_PERF_MULT)
use_power(power_rating)
@@ -80,10 +78,10 @@
update_icon()
/obj/machinery/atmospherics/unary/heater/attack_ai(mob/user as mob)
- src.ui_interact(user)
+ ui_interact(user)
/obj/machinery/atmospherics/unary/heater/attack_hand(mob/user as mob)
- src.ui_interact(user)
+ ui_interact(user)
/obj/machinery/atmospherics/unary/heater/ui_interact(mob/user, ui_key = "main", var/datum/nanoui/ui = null, var/force_open = 1)
// this is the data which will be sent to the ui
@@ -97,13 +95,13 @@
data["powerSetting"] = power_setting
var/temp_class = "normal"
- if (air_contents.temperature > (T20C+40))
+ if(air_contents.temperature > (T20C+40))
temp_class = "bad"
data["gasTemperatureClass"] = temp_class
// update the ui if it exists, returns null if no ui is passed/found
ui = nanomanager.try_update_ui(user, src, ui_key, ui, data, force_open)
- if (!ui)
+ if(!ui)
// the ui does not exist, so we'll create a new() one
// for a list of parameters and their descriptions see the code docs in \code\modules\nano\nanoui.dm
ui = new(user, src, ui_key, "freezer.tmpl", "Gas Heating System", 440, 300)
@@ -115,63 +113,54 @@
ui.set_auto_update(1)
/obj/machinery/atmospherics/unary/heater/Topic(href, href_list)
- if (href_list["toggleStatus"])
- src.use_power = !src.use_power
+ if(href_list["toggleStatus"])
+ use_power = !use_power
update_icon()
if(href_list["temp"])
var/amount = text2num(href_list["temp"])
if(amount > 0)
- src.set_temperature = min(src.set_temperature+amount, max_temperature)
+ set_temperature = min(set_temperature + amount, max_temperature)
else
- src.set_temperature = max(src.set_temperature+amount, 0)
+ set_temperature = max(set_temperature + amount, 0)
if(href_list["setPower"]) //setting power to 0 is redundant anyways
var/new_setting = between(0, text2num(href_list["setPower"]), 100)
set_power_level(new_setting)
- src.add_fingerprint(usr)
+ add_fingerprint(usr)
return 1
//upgrading parts
/obj/machinery/atmospherics/unary/heater/RefreshParts()
..()
-
var/cap_rating = 0
- var/cap_count = 0
var/bin_rating = 0
- var/bin_count = 0
+
for(var/obj/item/weapon/stock_parts/P in component_parts)
if(istype(P, /obj/item/weapon/stock_parts/capacitor))
cap_rating += P.rating
- cap_count++
if(istype(P, /obj/item/weapon/stock_parts/matter_bin))
bin_rating += P.rating
- bin_count++
- cap_rating /= cap_count
- bin_rating /= bin_count
- max_power_rating = initial(max_power_rating)*cap_rating
- max_temperature = max(initial(max_temperature) - T20C, 0)*((bin_rating*2 + cap_rating)/3) + T20C
- air_contents.volume = max(initial(internal_volume) - 200, 0) + 200*bin_rating
+ max_power_rating = initial(max_power_rating) * cap_rating / 2
+ max_temperature = max(initial(max_temperature) - T20C, 0) * ((bin_rating * 4 + cap_rating) / 5) + T20C
+ air_contents.volume = max(initial(internal_volume) - 200, 0) + 200 * bin_rating
set_power_level(power_setting)
/obj/machinery/atmospherics/unary/heater/proc/set_power_level(var/new_power_setting)
power_setting = new_power_setting
power_rating = max_power_rating * (power_setting/100)
-//dismantling code. copied from autolathe
/obj/machinery/atmospherics/unary/heater/attackby(var/obj/item/O as obj, var/mob/user as mob)
- if(istype(O, /obj/item/weapon/screwdriver))
- opened = !opened
- user << "You [opened ? "open" : "close"] the maintenance hatch of [src]."
+ if(default_deconstruction_screwdriver(user, O))
return
-
- if (opened && istype(O, /obj/item/weapon/crowbar))
- dismantle()
+ if(default_deconstruction_crowbar(user, O))
+ return
+ if(default_part_replacement(user, O))
return
..()
/obj/machinery/atmospherics/unary/heater/examine(mob/user)
..(user)
- if (opened)
+ if(panel_open)
user << "The maintenance hatch is open."
diff --git a/code/datums/supplypacks.dm b/code/datums/supplypacks.dm
index 3042a6c0b1e..d96f3364a17 100644
--- a/code/datums/supplypacks.dm
+++ b/code/datums/supplypacks.dm
@@ -898,10 +898,9 @@ var/list/all_supply_groups = list("Operations","Security","Hospitality","Enginee
/obj/item/weapon/reagent_containers/glass/paint/green,
/obj/item/weapon/reagent_containers/glass/paint/blue,
/obj/item/weapon/reagent_containers/glass/paint/yellow,
- /obj/item/weapon/reagent_containers/glass/paint/violet,
+ /obj/item/weapon/reagent_containers/glass/paint/purple,
/obj/item/weapon/reagent_containers/glass/paint/black,
/obj/item/weapon/reagent_containers/glass/paint/white,
- /obj/item/weapon/reagent_containers/glass/paint/remover,
/obj/item/weapon/contraband/poster,
/obj/item/weapon/wrapping_paper,
/obj/item/weapon/wrapping_paper,
@@ -1395,10 +1394,10 @@ var/list/all_supply_groups = list("Operations","Security","Hospitality","Enginee
/datum/supply_packs/randomised/webbing
name = "Webbing crate"
num_contained = 1
- contains = list(/obj/item/clothing/tie/holster,
- /obj/item/clothing/tie/storage/brown_vest,
- /obj/item/clothing/tie/storage/webbing,
- /obj/item/clothing/tie/storage)
+ contains = list(/obj/item/clothing/accessory/holster,
+ /obj/item/clothing/accessory/storage/brown_vest,
+ /obj/item/clothing/accessory/storage/webbing,
+ /obj/item/clothing/accessory/storage)
cost = 15
containertype = /obj/structure/closet/crate
containername = "Webbing crate"
diff --git a/code/defines/obj/weapon.dm b/code/defines/obj/weapon.dm
index ab7b57cb422..634121b08c9 100644
--- a/code/defines/obj/weapon.dm
+++ b/code/defines/obj/weapon.dm
@@ -395,6 +395,22 @@
///////////////////////////////////////Stock Parts /////////////////////////////////
+/obj/item/weapon/storage/part_replacer
+ name = "rapid part exchange device"
+ desc = "Special mechanical module made to store, sort, and apply standard machine parts."
+ icon_state = "RPED"
+ item_state = "RPED"
+ w_class = 5
+ can_hold = list("/obj/item/weapon/stock_parts")
+ storage_slots = 50
+ use_to_pickup = 1
+ allow_quick_gather = 1
+ allow_quick_empty = 1
+ collection_mode = 1
+ display_contents_with_number = 1
+ max_w_class = 3
+ max_combined_w_class = 100
+
/obj/item/weapon/stock_parts
name = "stock part"
desc = "What?"
diff --git a/code/game/atoms.dm b/code/game/atoms.dm
index df288f2cc40..bd0c9cdb541 100644
--- a/code/game/atoms.dm
+++ b/code/game/atoms.dm
@@ -409,6 +409,7 @@ its easier to just keep the beam vertical.
/atom/proc/clean_blood()
+ src.color = initial(src.color) //paint
src.germ_level = 0
if(istype(blood_DNA, /list))
del(blood_DNA)
diff --git a/code/game/gamemodes/meteor/meteors.dm b/code/game/gamemodes/meteor/meteors.dm
index fce27f393ce..1edb533daaa 100644
--- a/code/game/gamemodes/meteor/meteors.dm
+++ b/code/game/gamemodes/meteor/meteors.dm
@@ -85,6 +85,9 @@
density = 1
anchored = 1.0
var/hits = 1
+ var/detonation_chance = 15
+ var/power = 4
+ var/power_step = 1
var/dest
pass_flags = PASSTABLE
@@ -92,6 +95,7 @@
name = "small meteor"
icon_state = "smallf"
pass_flags = PASSTABLE | PASSGRILLE
+ power = 2
/obj/effect/meteor/Bump(atom/A)
spawn(0)
@@ -105,8 +109,8 @@
//Changing emitter and generator ex_act would result in them being bomb and C4 proof.
if(!istype(A,/obj/machinery/power/emitter) && \
!istype(A,/obj/machinery/field_generator) && \
- prob(15))
- explosion(src.loc, 4, 5, 6, 7, 0)
+ prob(detonation_chance))
+ explosion(loc, power, power + power_step, power + power_step * 2, power + power_step * 3, 0)
del(src)
return
@@ -120,6 +124,7 @@
/obj/effect/meteor/big
name = "big meteor"
hits = 5
+ power = 1
ex_act(severity)
return
@@ -143,8 +148,8 @@
explosion(src.loc, 0, 1, 2, 3, 0)
if (--src.hits <= 0)
- if(prob(15) && !istype(A, /obj/structure/grille))
- explosion(src.loc, 1, 2, 3, 4, 0)
+ if(prob(detonation_chance) && !istype(A, /obj/structure/grille))
+ explosion(loc, power, power + power_step, power + power_step * 2, power + power_step * 3, 0)
del(src)
return
diff --git a/code/game/jobs/job/captain.dm b/code/game/jobs/job/captain.dm
index a43056fa96f..06513c05f9f 100644
--- a/code/game/jobs/job/captain.dm
+++ b/code/game/jobs/job/captain.dm
@@ -24,7 +24,7 @@ var/datum/announcement/minor/captain_announcement = new(do_newscast = 1)
H.equip_to_slot_or_del(new /obj/item/weapon/storage/box/survival(H.back), slot_in_backpack)
var/obj/item/clothing/under/U = new /obj/item/clothing/under/rank/captain(H)
if(H.age>49)
- U.hastie = new /obj/item/clothing/tie/medal/gold/captain(U)
+ U.accessories += new /obj/item/clothing/accessory/medal/gold/captain(U)
H.equip_to_slot_or_del(U, slot_w_uniform)
H.equip_to_slot_or_del(new /obj/item/device/pda/captain(H), slot_belt)
H.equip_to_slot_or_del(new /obj/item/clothing/shoes/brown(H), slot_shoes)
diff --git a/code/game/jobs/job/medical.dm b/code/game/jobs/job/medical.dm
index a63363f779c..13702911528 100644
--- a/code/game/jobs/job/medical.dm
+++ b/code/game/jobs/job/medical.dm
@@ -196,3 +196,44 @@
else
H.equip_to_slot_or_del(new /obj/item/weapon/storage/box/survival(H.back), slot_in_backpack)
H.equip_to_slot_or_del(new /obj/item/clothing/suit/storage/toggle/labcoat(H), slot_wear_suit)
+
+
+/datum/job/Paramedic
+ title = "Paramedic"
+ flag = PARAMEDIC
+ department_flag = MEDSCI
+ faction = "Station"
+ total_positions = 2
+ spawn_positions = 2
+ supervisors = "the chief medical officer"
+ selection_color = "#ffeef0"
+ access = list(access_medical, access_morgue, access_surgery, access_chemistry, access_virology, access_eva, access_maint_tunnels, access_external_airlocks, access_psychiatrist)
+ minimal_access = list(access_medical, access_morgue, access_eva, access_maint_tunnels, access_external_airlocks)
+ alt_titles = list("Emergency Medical Technician")
+
+ equip(var/mob/living/carbon/human/H)
+ if(!H) return 0
+ H.equip_to_slot_or_del(new /obj/item/device/radio/headset/headset_med(H), slot_l_ear)
+ H.equip_to_slot_or_del(new /obj/item/clothing/shoes/jackboots(H), slot_shoes)
+ H.equip_to_slot_or_del(new /obj/item/weapon/storage/firstaid/adv(H), slot_l_hand)
+ switch(H.backbag)
+ if(2) H.equip_to_slot_or_del(new /obj/item/weapon/storage/backpack/medic(H), slot_back)
+ if(3) H.equip_to_slot_or_del(new /obj/item/weapon/storage/backpack/satchel_med(H), slot_back)
+ if(4) H.equip_to_slot_or_del(new /obj/item/weapon/storage/backpack/satchel(H), slot_back)
+ if (H.mind.role_alt_title)
+ switch(H.mind.role_alt_title)
+ if("Emergency Medical Technician")
+ H.equip_to_slot_or_del(new /obj/item/clothing/under/rank/medical/fluff/short(H), slot_w_uniform)
+ H.equip_to_slot_or_del(new /obj/item/clothing/suit/storage/toggle/fr_jacket(H), slot_wear_suit)
+ if("Paramedic")
+ H.equip_to_slot_or_del(new /obj/item/clothing/under/rank/medical/black(H), slot_w_uniform)
+ H.equip_to_slot_or_del(new /obj/item/clothing/suit/storage/toggle/fr_jacket(H), slot_wear_suit)
+ else
+ H.equip_to_slot_or_del(new /obj/item/clothing/under/rank/medical(H), slot_w_uniform)
+ H.equip_to_slot_or_del(new /obj/item/weapon/storage/belt/medical/emt(H), slot_belt)
+ H.equip_to_slot_or_del(new /obj/item/device/pda/medical(H), slot_l_store)
+ if(H.backbag == 1)
+ H.equip_to_slot_or_del(new /obj/item/weapon/storage/box/engineer(H), slot_r_hand)
+ else
+ H.equip_to_slot_or_del(new /obj/item/weapon/storage/box/engineer(H.back), slot_in_backpack)
+ return 1
diff --git a/code/game/jobs/jobs.dm b/code/game/jobs/jobs.dm
index a90f3ad716d..e1c42254a65 100644
--- a/code/game/jobs/jobs.dm
+++ b/code/game/jobs/jobs.dm
@@ -25,6 +25,7 @@ var/const/VIROLOGIST =(1<<6)
var/const/PSYCHIATRIST =(1<<7)
var/const/ROBOTICIST =(1<<8)
var/const/XENOBIOLOGIST =(1<<9)
+var/const/PARAMEDIC =(1<<10)
var/const/CIVILIAN =(1<<2)
diff --git a/code/game/machinery/autolathe.dm b/code/game/machinery/autolathe.dm
index 7b44e443c4d..5361bea23a7 100644
--- a/code/game/machinery/autolathe.dm
+++ b/code/game/machinery/autolathe.dm
@@ -13,14 +13,30 @@
var/list/storage_capacity = list("metal" = 0, "glass" = 0)
var/show_category = "All"
- var/panel_open = 0
var/hacked = 0
var/disabled = 0
var/shocked = 0
var/busy = 0
+ var/mat_efficiency = 1
+ var/build_time = 50
+
var/datum/wires/autolathe/wires = null
+/obj/machinery/autolathe/New()
+
+ ..()
+ wires = new(src)
+ //Create parts for lathe.
+ component_parts = list()
+ component_parts += new /obj/item/weapon/circuitboard/autolathe(src)
+ component_parts += new /obj/item/weapon/stock_parts/matter_bin(src)
+ component_parts += new /obj/item/weapon/stock_parts/matter_bin(src)
+ component_parts += new /obj/item/weapon/stock_parts/matter_bin(src)
+ component_parts += new /obj/item/weapon/stock_parts/manipulator(src)
+ component_parts += new /obj/item/weapon/stock_parts/console_screen(src)
+ RefreshParts()
+
/obj/machinery/autolathe/proc/update_recipe_list()
if(!machine_recipes)
machine_recipes = autolathe_recipes
@@ -33,8 +49,8 @@
user << "\The [src] is disabled!"
return
- if (shocked)
- shock(user,50)
+ if(shocked)
+ shock(user, 50)
var/dat = "
Autolathe Control Panel
"
@@ -65,16 +81,16 @@
else
//Make sure it's buildable and list requires resources.
for(var/material in R.resources)
- var/sheets = round(stored_material[material]/R.resources[material])
+ var/sheets = round(stored_material[material]/round(R.resources[material]*mat_efficiency))
if(isnull(max_sheets) || max_sheets > sheets)
max_sheets = sheets
- if(!isnull(stored_material[material]) && stored_material[material] < R.resources[material])
+ if(!isnull(stored_material[material]) && stored_material[material] < round(R.resources[material]*mat_efficiency))
can_make = 0
if(!comma)
comma = 1
else
material_string += ", "
- material_string += "[R.resources[material]] [material]"
+ material_string += "[round(R.resources[material] * mat_efficiency)] [material]"
material_string += ".
"
//Build list of multipliers for sheets.
if(R.is_stack)
@@ -99,31 +115,27 @@
/obj/machinery/autolathe/attackby(var/obj/item/O as obj, var/mob/user as mob)
- if (stat)
- return
-
- if (busy)
+ if(busy)
user << "\The [src] is busy. Please wait for completion of previous operation."
return
- if(istype(O, /obj/item/weapon/screwdriver))
- panel_open = !panel_open
- icon_state = (panel_open ? "autolathe_t": "autolathe")
- user << "You [panel_open ? "open" : "close"] the maintenance hatch of [src]."
+ if(default_deconstruction_screwdriver(user, O))
updateUsrDialog()
return
+ if(default_deconstruction_crowbar(user, O))
+ return
+ if(default_part_replacement(user, O))
+ return
- if (panel_open)
+ if(stat)
+ return
+
+ if(panel_open)
//Don't eat multitools or wirecutters used on an open lathe.
if(istype(O, /obj/item/device/multitool) || istype(O, /obj/item/weapon/wirecutters))
attack_hand(user)
return
- //Dismantle the frame.
- if(istype(O, /obj/item/weapon/crowbar))
- dismantle()
- return
-
if(O.loc != user && !(istype(O,/obj/item/stack)))
return 0
@@ -170,11 +182,11 @@
else
user << "You fill \the [src] with \the [eating]."
- flick("autolathe_o",src) // Plays metal insertion animation. Work out a good way to work out a fitting animation. ~Z
+ flick("autolathe_o", src) // Plays metal insertion animation. Work out a good way to work out a fitting animation. ~Z
if(istype(eating,/obj/item/stack))
var/obj/item/stack/stack = eating
- stack.use(max(1,round(total_used/mass_per_sheet))) // Always use at least 1 to prevent infinite materials.
+ stack.use(max(1, round(total_used/mass_per_sheet))) // Always use at least 1 to prevent infinite materials.
else
user.drop_item(O)
del(O)
@@ -227,18 +239,18 @@
//Check if we still have the materials.
for(var/material in making.resources)
if(!isnull(stored_material[material]))
- if(stored_material[material] < (making.resources[material]*multiplier))
+ if(stored_material[material] < round(making.resources[material] * mat_efficiency) * multiplier)
return
//Consume materials.
for(var/material in making.resources)
if(!isnull(stored_material[material]))
- stored_material[material] = max(0,stored_material[material]-(making.resources[material]*multiplier))
+ stored_material[material] = max(0, stored_material[material] - round(making.resources[material] * mat_efficiency) * multiplier)
//Fancy autolathe animation.
- flick("autolathe_n",src)
+ flick("autolathe_n", src)
- sleep(50)
+ sleep(build_time)
busy = 0
@@ -247,39 +259,31 @@
//Create the desired item.
var/obj/item/I = new making.path(get_step(loc, get_dir(src,usr)))
- if(multiplier>1 && istype(I,/obj/item/stack))
+ if(multiplier > 1 && istype(I, /obj/item/stack))
var/obj/item/stack/S = I
S.amount = multiplier
updateUsrDialog()
-
-/obj/machinery/autolathe/New()
-
- ..()
- wires = new(src)
- //Create parts for lathe.
- component_parts = list()
- component_parts += new /obj/item/weapon/circuitboard/autolathe(src)
- component_parts += new /obj/item/weapon/stock_parts/matter_bin(src)
- component_parts += new /obj/item/weapon/stock_parts/matter_bin(src)
- component_parts += new /obj/item/weapon/stock_parts/matter_bin(src)
- component_parts += new /obj/item/weapon/stock_parts/manipulator(src)
- component_parts += new /obj/item/weapon/stock_parts/console_screen(src)
- RefreshParts()
+/obj/machinery/autolathe/update_icon()
+ icon_state = (panel_open ? "autolathe_t" : "autolathe")
//Updates overall lathe storage size.
/obj/machinery/autolathe/RefreshParts()
..()
- var/tot_rating = 0
+ var/mb_rating = 0
+ var/man_rating = 0
for(var/obj/item/weapon/stock_parts/matter_bin/MB in component_parts)
- tot_rating += MB.rating
+ mb_rating += MB.rating
+ for(var/obj/item/weapon/stock_parts/manipulator/M in component_parts)
+ man_rating += M.rating
- storage_capacity["metal"] = tot_rating * 25000
- storage_capacity["glass"] = tot_rating * 12500
+ storage_capacity["metal"] = mb_rating * 25000
+ storage_capacity["glass"] = mb_rating * 12500
+ build_time = 50 / man_rating
+ mat_efficiency = 1.1 - man_rating * 0.1// Normally, price is 1.25 the amount of material, so this shouldn't go higher than 0.8. Maximum rating of parts is 3
/obj/machinery/autolathe/dismantle()
- ..()
var/list/sheets = list("metal" = /obj/item/stack/sheet/metal, "glass" = /obj/item/stack/sheet/glass)
for(var/mat in stored_material)
@@ -288,3 +292,4 @@
if(stored_material[mat] > S.perunit)
S.amount = round(stored_material[mat] / S.perunit)
S.loc = loc
+ ..()
diff --git a/code/game/machinery/autolathe_datums.dm b/code/game/machinery/autolathe_datums.dm
index c7d592c1d0d..ec6713085a4 100644
--- a/code/game/machinery/autolathe_datums.dm
+++ b/code/game/machinery/autolathe_datums.dm
@@ -15,7 +15,7 @@
if(I.matter && !recipe.resources) //This can be overidden in the datums.
recipe.resources = list()
for(var/material in I.matter)
- recipe.resources[material] = round(I.matter[material]*1.25) // More expensive to produce than they are to recycle.
+ recipe.resources[material] = I.matter[material]*1.25 // More expensive to produce than they are to recycle.
del(I)
/datum/autolathe/recipe
diff --git a/code/game/machinery/camera/camera.dm b/code/game/machinery/camera/camera.dm
index d631ca46dff..3b3104201f5 100644
--- a/code/game/machinery/camera/camera.dm
+++ b/code/game/machinery/camera/camera.dm
@@ -13,7 +13,6 @@
var/c_tag_order = 999
var/status = 1
anchored = 1.0
- var/panel_open = 0 // 0 = Closed / 1 = Open
var/invuln = null
var/bugged = 0
var/obj/item/weapon/camera_assembly/assembly = null
@@ -57,7 +56,7 @@
/obj/machinery/camera/Del()
if(!alarm_on)
triggerCameraAlarm()
-
+
cancelCameraAlarm()
..()
@@ -70,7 +69,7 @@
kick_viewers()
triggerCameraAlarm()
update_icon()
-
+
spawn(900)
stat &= ~EMPED
cancelCameraAlarm()
@@ -85,11 +84,11 @@
/obj/machinery/camera/ex_act(severity)
if(src.invuln)
return
-
+
//camera dies if an explosion touches it!
if(severity <= 2 || prob(50))
destroy()
-
+
..() //and give it the regular chance of being deleted outright
@@ -174,7 +173,7 @@
if (S.current == src)
O << "[U] holds \a [itemname] up to one of the cameras ..."
O << browse(text("[][]", itemname, info), text("window=[]", itemname))
-
+
else if (istype(W, /obj/item/weapon/camera_bug))
if (!src.can_use())
user << "\blue Camera non-functional"
@@ -185,7 +184,7 @@
else
user << "\blue Camera bugged."
src.bugged = 1
-
+
else if(W.damtype == BRUTE || W.damtype == BURN) //bashing cameras
if (W.force >= src.toughness)
visible_message("[src] has been [pick(W.attack_verb)] with [W] by [user]!")
@@ -194,7 +193,7 @@
if (I.hitsound)
playsound(loc, I.hitsound, 50, 1, -1)
take_damage(W.force)
-
+
else
..()
@@ -221,14 +220,14 @@
if (force >= toughness && (force > toughness*4 || prob(25)))
destroy()
-//Used when someone breaks a camera
+//Used when someone breaks a camera
/obj/machinery/camera/proc/destroy()
invalidateCameraCache()
stat |= BROKEN
kick_viewers()
triggerCameraAlarm()
update_icon()
-
+
//sparks
var/datum/effect/effect/system/spark_spread/spark_system = new /datum/effect/effect/system/spark_spread()
spark_system.set_up(5, 0, loc)
@@ -266,7 +265,7 @@
alarm_on = 1
if(!get_area(src))
return
-
+
for(var/mob/living/silicon/S in mob_list)
S.triggerAlarm("Camera", get_area(src), list(src), src)
@@ -275,7 +274,7 @@
alarm_on = 0
if(!get_area(src))
return
-
+
for(var/mob/living/silicon/S in mob_list)
S.cancelAlarm("Camera", get_area(src), src)
@@ -355,7 +354,7 @@
/obj/machinery/camera/interact(mob/living/user as mob)
if(!panel_open || istype(user, /mob/living/silicon/ai))
return
-
+
if(stat & BROKEN)
user << "\The [src] is broken."
return
diff --git a/code/game/machinery/cloning.dm b/code/game/machinery/cloning.dm
index 454e6e44fc7..343c8ab2db1 100644
--- a/code/game/machinery/cloning.dm
+++ b/code/game/machinery/cloning.dm
@@ -3,18 +3,41 @@
//Potential replacement for genetics revives or something I dunno (?)
+//Find a dead mob with a brain and client.
+/proc/find_dead_player(var/find_key)
+ if(isnull(find_key))
+ return
+
+ var/mob/selected = null
+ for(var/mob/living/M in player_list)
+ //Dead people only thanks!
+ if((M.stat != 2) || (!M.client))
+ continue
+ //They need a brain!
+ if(istype(M, /mob/living/carbon/human))
+ var/mob/living/carbon/human/H = M
+ if(H.species.has_organ["brain"] && !H.has_brain())
+ continue
+ if(M.ckey == find_key)
+ selected = M
+ break
+ return selected
+
#define CLONE_BIOMASS 150
/obj/machinery/clonepod
- anchored = 1
name = "cloning pod"
desc = "An electronically-lockable pod for growing organic tissue."
density = 1
+ anchored = 1
icon = 'icons/obj/cloning.dmi'
icon_state = "pod_0"
req_access = list(access_genetics) //For premature unlocking.
+
var/mob/living/occupant
- var/heal_level = 90 //The clone is released once its health reaches this level.
+ var/heal_level = 20 //The clone is released once its health reaches this level.
+ var/heal_rate = 1
+ var/notoxin = 0
var/locked = 0
var/obj/machinery/computer/cloning/connected = null //So we remember the connected clone machine.
var/mess = 0 //Need to clean out it if it's full of exploded clone.
@@ -22,6 +45,366 @@
var/eject_wait = 0 //Don't eject them as soon as they are created fuckkk
var/biomass = CLONE_BIOMASS * 3
+/obj/machinery/clonepod/New()
+ ..()
+ component_parts = list()
+ component_parts += new /obj/item/weapon/circuitboard/clonepod(src)
+ component_parts += new /obj/item/weapon/stock_parts/manipulator(src)
+ component_parts += new /obj/item/weapon/stock_parts/manipulator(src)
+ component_parts += new /obj/item/weapon/stock_parts/scanning_module(src)
+ component_parts += new /obj/item/weapon/stock_parts/scanning_module(src)
+ component_parts += new /obj/item/weapon/stock_parts/console_screen(src)
+ component_parts += new /obj/item/stack/cable_coil(src, 2)
+
+ RefreshParts()
+
+/obj/machinery/clonepod/attack_ai(mob/user as mob)
+ add_hiddenprint(user)
+ return attack_hand(user)
+
+/obj/machinery/clonepod/attack_hand(mob/user as mob)
+ if((isnull(occupant)) || (stat & NOPOWER))
+ return
+ if((!isnull(occupant)) && (occupant.stat != 2))
+ var/completion = (100 * ((occupant.health + 50) / (heal_level + 100))) // Clones start at -150 health
+ user << "Current clone cycle is [round(completion)]% complete."
+ return
+
+//Clonepod
+
+//Start growing a human clone in the pod!
+/obj/machinery/clonepod/proc/growclone(var/datum/dna2/record/R)
+ if(mess || attempting)
+ return 0
+ var/datum/mind/clonemind = locate(R.mind)
+ if(!istype(clonemind, /datum/mind)) //not a mind
+ return 0
+ if(clonemind.current && clonemind.current.stat != DEAD) //mind is associated with a non-dead body
+ return 0
+ if(clonemind.active) //somebody is using that mind
+ if(ckey(clonemind.key) != R.ckey)
+ return 0
+ else
+ for(var/mob/dead/observer/G in player_list)
+ if(G.ckey == R.ckey)
+ if(G.can_reenter_corpse)
+ break
+ else
+ return 0
+
+ attempting = 1 //One at a time!!
+ locked = 1
+
+ eject_wait = 1
+ spawn(30)
+ eject_wait = 0
+
+ var/mob/living/carbon/human/H = new /mob/living/carbon/human(src, R.dna.species)
+ occupant = H
+
+ if(!R.dna.real_name) //to prevent null names
+ R.dna.real_name = "clone ([rand(0,999)])"
+ H.real_name = R.dna.real_name
+
+ icon_state = "pod_1"
+ //Get the clone body ready
+ H.adjustCloneLoss(150) // New damage var so you can't eject a clone early then stab them to abuse the current damage system --NeoFite
+ H.adjustBrainLoss(80) // Even if healed to full health, it will have some brain damage
+ H.Paralyse(4)
+
+ //Here let's calculate their health so the pod doesn't immediately eject them!!!
+ H.updatehealth()
+
+ clonemind.transfer_to(H)
+ H.ckey = R.ckey
+ H << "Consciousness slowly creeps over you as your body regenerates.
So this is what cloning feels like?"
+
+ // -- Mode/mind specific stuff goes here
+ callHook("clone", list(H))
+
+ switch(ticker.mode.name)
+ if("revolution")
+ if((H.mind in ticker.mode:revolutionaries) || (H.mind in ticker.mode:head_revolutionaries))
+ ticker.mode.update_all_rev_icons() //So the icon actually appears
+ if("mercenary")
+ if(H.mind in ticker.mode.syndicates)
+ ticker.mode.update_all_synd_icons()
+ if("cult")
+ if(H.mind in ticker.mode.cult)
+ ticker.mode.add_cultist(occupant.mind)
+ ticker.mode.update_all_cult_icons() //So the icon actually appears
+
+ // -- End mode specific stuff
+
+ if(!R.dna)
+ H.dna = new /datum/dna()
+ H.dna.real_name = H.real_name
+ else
+ H.dna = R.dna
+ H.UpdateAppearance()
+ if(heal_level < 60)
+ randmutb(H) //Sometimes the clones come out wrong.
+ H.dna.UpdateSE()
+ H.dna.UpdateUI()
+
+ H.set_cloned_appearance()
+
+ for(var/datum/language/L in R.languages)
+ H.add_language(L.name)
+ H.flavor_texts = R.flavor.Copy()
+ H.suiciding = 0
+ attempting = 0
+ return 1
+
+//Grow clones to maturity then kick them out. FREELOADERS
+/obj/machinery/clonepod/process()
+
+ if(stat & NOPOWER) //Autoeject if power is lost
+ if(occupant)
+ locked = 0
+ go_out()
+ return
+
+ if((occupant) && (occupant.loc == src))
+ if((occupant.stat == DEAD) || (occupant.suiciding) || !occupant.key) //Autoeject corpses and suiciding dudes.
+ locked = 0
+ go_out()
+ connected_message("Clone Rejected: Deceased.")
+ return
+
+ else if(occupant.health < heal_level && occupant.getCloneLoss() > 0)
+ occupant.Paralyse(4)
+
+ //Slowly get that clone healed and finished.
+ occupant.adjustCloneLoss(-2 * heal_rate)
+
+ //Premature clones may have brain damage.
+ occupant.adjustBrainLoss(-1 * heal_rate)
+
+ //So clones don't die of oxyloss in a running pod.
+ if(occupant.reagents.get_reagent_amount("inaprovaline") < 30)
+ occupant.reagents.add_reagent("inaprovaline", 60)
+
+ //So clones will remain asleep for long enough to get them into cryo (Bay RP edit)
+ if(occupant.reagents.get_reagent_amount("stoxin") < 10)
+ occupant.reagents.add_reagent("stoxin", 5)
+ if(occupant.reagents.get_reagent_amount("chloralhydrate") < 1)
+ occupant.reagents.add_reagent("chloralhydrate", 1)
+
+ //Also heal some oxyloss ourselves because inaprovaline is so bad at preventing it!!
+ occupant.adjustOxyLoss(-4)
+ if(notoxin)
+ occupant.adjustToxLoss(-2) // If sufficiently upgraded - remove toxin damage from chloral
+
+ use_power(7500) //This might need tweaking.
+ return
+
+ else if((occupant.health >= heal_level) && (!eject_wait))
+ connected_message("Cloning Process Complete.")
+ locked = 0
+ go_out()
+ return
+
+ else if((!occupant) || (occupant.loc != src))
+ occupant = null
+ if(locked)
+ locked = 0
+ if(!mess)
+ icon_state = "pod_0"
+ //use_power(200)
+ return
+
+ return
+
+//Let's unlock this early I guess. Might be too early, needs tweaking.
+/obj/machinery/clonepod/attackby(obj/item/weapon/W as obj, mob/user as mob)
+ if(isnull(occupant))
+ if(default_deconstruction_screwdriver(user, W))
+ return
+ if(default_deconstruction_crowbar(user, W))
+ return
+ if(default_part_replacement(user, W))
+ return
+ if(istype(W, /obj/item/weapon/card/id)||istype(W, /obj/item/device/pda))
+ if(!check_access(W))
+ user << "Access Denied."
+ return
+ if((!locked) || (isnull(occupant)))
+ return
+ if((occupant.health < -20) && (occupant.stat != 2))
+ user << "Access Refused."
+ return
+ else
+ locked = 0
+ user << "System unlocked."
+ else if(istype(W, /obj/item/weapon/card/emag))
+ if(isnull(occupant))
+ return
+ user << "You force an emergency ejection."
+ locked = 0
+ go_out()
+ return
+ else if(istype(W, /obj/item/weapon/reagent_containers/food/snacks/meat))
+ user << "\The [src] processes \the [W]."
+ biomass += 50
+ user.drop_item()
+ del(W)
+ return
+ else if(istype(W, /obj/item/weapon/wrench))
+ if(locked && (anchored || occupant))
+ user << "Can not do that while [src] is in use."
+ else
+ if(anchored)
+ anchored = 0
+ connected.pod1 = null
+ connected = null
+ else
+ anchored = 1
+ playsound(loc, 'sound/items/Ratchet.ogg', 100, 1)
+ if(anchored)
+ user.visible_message("[user] secures [src] to the floor.", "You secure [src] to the floor.")
+ else
+ user.visible_message("[user] unsecures [src] from the floor.", "You unsecure [src] from the floor.")
+ else
+ ..()
+
+//Put messages in the connected computer's temp var for display.
+/obj/machinery/clonepod/proc/connected_message(var/message)
+ if((isnull(connected)) || (!istype(connected, /obj/machinery/computer/cloning)))
+ return 0
+ if(!message)
+ return 0
+
+ connected.temp = message
+ connected.updateUsrDialog()
+ return 1
+
+/obj/machinery/clonepod/RefreshParts()
+ ..()
+ var/rating = 0
+ for(var/obj/item/weapon/stock_parts/P in component_parts)
+ if(istype(P, /obj/item/weapon/stock_parts/scanning_module) || istype(P, /obj/item/weapon/stock_parts/manipulator))
+ rating += P.rating
+
+ heal_level = rating * 10 - 20
+ heal_rate = round(rating / 4)
+ if(rating >= 8)
+ notoxin = 1
+ else
+ notoxin = 0
+
+/obj/machinery/clonepod/verb/eject()
+ set name = "Eject Cloner"
+ set category = "Object"
+ set src in oview(1)
+
+ if(usr.stat != 0)
+ return
+ go_out()
+ add_fingerprint(usr)
+ return
+
+/obj/machinery/clonepod/proc/go_out()
+ if(locked)
+ return
+
+ if(mess) //Clean that mess and dump those gibs!
+ mess = 0
+ gibs(loc)
+ icon_state = "pod_0"
+
+ /*
+ for(var/obj/O in src)
+ O.loc = loc
+ */
+ return
+
+ if(!(occupant))
+ return
+
+ /*
+ for(var/obj/O in src)
+ O.loc = loc
+ */
+
+ if(occupant.client)
+ occupant.client.eye = occupant.client.mob
+ occupant.client.perspective = MOB_PERSPECTIVE
+ occupant.loc = loc
+ icon_state = "pod_0"
+ eject_wait = 0 //If it's still set somehow.
+ domutcheck(occupant) //Waiting until they're out before possible monkeyizing.
+// occupant.add_side_effect("Bad Stomach") // Give them an extra side-effect for free.
+ occupant = null
+
+ biomass -= CLONE_BIOMASS
+
+ return
+
+/obj/machinery/clonepod/proc/malfunction()
+ if(occupant)
+ connected_message("Critical Error!")
+ mess = 1
+ icon_state = "pod_g"
+ occupant.ghostize()
+ spawn(5)
+ del(occupant)
+ return
+
+/obj/machinery/clonepod/relaymove(mob/user as mob)
+ if(user.stat)
+ return
+ go_out()
+ return
+
+/obj/machinery/clonepod/emp_act(severity)
+ if(prob(100/severity))
+ malfunction()
+ ..()
+
+/obj/machinery/clonepod/ex_act(severity)
+ switch(severity)
+ if(1.0)
+ for(var/atom/movable/A as mob|obj in src)
+ A.loc = loc
+ ex_act(severity)
+ del(src)
+ return
+ if(2.0)
+ if(prob(50))
+ for(var/atom/movable/A as mob|obj in src)
+ A.loc = loc
+ ex_act(severity)
+ del(src)
+ return
+ if(3.0)
+ if(prob(25))
+ for(var/atom/movable/A as mob|obj in src)
+ A.loc = loc
+ ex_act(severity)
+ del(src)
+ return
+ else
+ return
+
+//Health Tracker Implant
+
+/obj/item/weapon/implant/health
+ name = "health implant"
+ var/healthstring = ""
+
+/obj/item/weapon/implant/health/proc/sensehealth()
+ if(!implanted)
+ return "ERROR"
+ else
+ if(isliving(implanted))
+ var/mob/living/L = implanted
+ healthstring = "[round(L.getOxyLoss())] - [round(L.getFireLoss())] - [round(L.getToxLoss())] - [round(L.getBruteLoss())]"
+ if(!healthstring)
+ healthstring = "ERROR"
+ return healthstring
+
+//Disk stuff.
//The return of data disks?? Just for transferring between genetics machine/cloning machine.
//TO-DO: Make the genetics machine accept them.
/obj/item/weapon/disk/data
@@ -30,7 +413,7 @@
icon_state = "datadisk0" //Gosh I hope syndies don't mistake them for the nuke disk.
item_state = "card-id"
w_class = 2.0
- var/datum/dna2/record/buf=null
+ var/datum/dna2/record/buf = null
var/read_only = 0 //Well,it's still a floppy disk
/obj/item/weapon/disk/data/proc/initializeDisk()
@@ -65,363 +448,18 @@
buf.dna.SE=new_SE
buf.dna.SetSEValueRange(MONKEYBLOCK,0xDAC, 0xFFF)
-
-//Find a dead mob with a brain and client.
-/proc/find_dead_player(var/find_key)
- if (isnull(find_key))
- return
-
- var/mob/selected = null
- for(var/mob/living/M in player_list)
- //Dead people only thanks!
- if ((M.stat != 2) || (!M.client))
- continue
- //They need a brain!
- if(istype(M, /mob/living/carbon/human))
- var/mob/living/carbon/human/H = M
- if(H.species.has_organ["brain"] && !H.has_brain())
- continue
- if (M.ckey == find_key)
- selected = M
- break
- return selected
-
-//Disk stuff.
/obj/item/weapon/disk/data/New()
..()
var/diskcolor = pick(0,1,2)
- src.icon_state = "datadisk[diskcolor]"
+ icon_state = "datadisk[diskcolor]"
/obj/item/weapon/disk/data/attack_self(mob/user as mob)
- src.read_only = !src.read_only
- user << "You flip the write-protect tab to [src.read_only ? "protected" : "unprotected"]."
+ read_only = !read_only
+ user << "You flip the write-protect tab to [read_only ? "protected" : "unprotected"]."
/obj/item/weapon/disk/data/examine(mob/user)
..(user)
- user << text("The write-protect tab is set to [src.read_only ? "protected" : "unprotected"].")
- return
-
-//Health Tracker Implant
-
-/obj/item/weapon/implant/health
- name = "health implant"
- var/healthstring = ""
-
-/obj/item/weapon/implant/health/proc/sensehealth()
- if (!src.implanted)
- return "ERROR"
- else
- if(isliving(src.implanted))
- var/mob/living/L = src.implanted
- src.healthstring = "[round(L.getOxyLoss())] - [round(L.getFireLoss())] - [round(L.getToxLoss())] - [round(L.getBruteLoss())]"
- if (!src.healthstring)
- src.healthstring = "ERROR"
- return src.healthstring
-
-/obj/machinery/clonepod/attack_ai(mob/user as mob)
- src.add_hiddenprint(user)
- return attack_hand(user)
-
-/obj/machinery/clonepod/attack_hand(mob/user as mob)
- if ((isnull(src.occupant)) || (stat & NOPOWER))
- return
- if ((!isnull(src.occupant)) && (src.occupant.stat != 2))
- var/completion = (100 * ((src.occupant.health + 100) / (src.heal_level + 100)))
- user << "Current clone cycle is [round(completion)]% complete."
- return
-
-//Clonepod
-
-//Start growing a human clone in the pod!
-/obj/machinery/clonepod/proc/growclone(var/datum/dna2/record/R)
- if(mess || attempting)
- return 0
- var/datum/mind/clonemind = locate(R.mind)
- if(!istype(clonemind,/datum/mind)) //not a mind
- return 0
- if( clonemind.current && clonemind.current.stat != DEAD ) //mind is associated with a non-dead body
- return 0
- if(clonemind.active) //somebody is using that mind
- if( ckey(clonemind.key)!=R.ckey )
- return 0
- else
- for(var/mob/dead/observer/G in player_list)
- if(G.ckey == R.ckey)
- if(G.can_reenter_corpse)
- break
- else
- return 0
-
-
- src.heal_level = rand(10,40) //Randomizes what health the clone is when ejected
- src.attempting = 1 //One at a time!!
- src.locked = 1
-
- src.eject_wait = 1
- spawn(30)
- src.eject_wait = 0
-
- var/mob/living/carbon/human/H = new /mob/living/carbon/human(src, R.dna.species)
- occupant = H
-
- if(!R.dna.real_name) //to prevent null names
- R.dna.real_name = "clone ([rand(0,999)])"
- H.real_name = R.dna.real_name
-
- src.icon_state = "pod_1"
- //Get the clone body ready
- H.adjustCloneLoss(150) //new damage var so you can't eject a clone early then stab them to abuse the current damage system --NeoFite
- H.adjustBrainLoss(src.heal_level + 50 + rand(10, 30)) // The rand(10, 30) will come out as extra brain damage
- H.Paralyse(4)
-
- //Here let's calculate their health so the pod doesn't immediately eject them!!!
- H.updatehealth()
-
- clonemind.transfer_to(H)
- H.ckey = R.ckey
- H << "Consciousness slowly creeps over you as your body regenerates.
So this is what cloning feels like?"
-
- // -- Mode/mind specific stuff goes here
- callHook("clone", list(H))
-
- switch(ticker.mode.name)
- if("revolution")
- if((H.mind in ticker.mode:revolutionaries) || (H.mind in ticker.mode:head_revolutionaries))
- ticker.mode.update_all_rev_icons() //So the icon actually appears
- if("mercenary")
- if(H.mind in ticker.mode.syndicates)
- ticker.mode.update_all_synd_icons()
- if("cult")
- if (H.mind in ticker.mode.cult)
- ticker.mode.add_cultist(src.occupant.mind)
- ticker.mode.update_all_cult_icons() //So the icon actually appears
-
- // -- End mode specific stuff
-
- if(!R.dna)
- H.dna = new /datum/dna()
- H.dna.real_name = H.real_name
- else
- H.dna=R.dna
- H.UpdateAppearance()
- randmutb(H) //Sometimes the clones come out wrong.
- H.dna.UpdateSE()
- H.dna.UpdateUI()
-
- H.set_cloned_appearance()
-
- for(var/datum/language/L in R.languages)
- H.add_language(L.name)
- H.flavor_texts = R.flavor.Copy()
- H.suiciding = 0
- src.attempting = 0
- return 1
-
-//Grow clones to maturity then kick them out. FREELOADERS
-/obj/machinery/clonepod/process()
-
- if(stat & NOPOWER) //Autoeject if power is lost
- if (src.occupant)
- src.locked = 0
- src.go_out()
- return
-
- if((src.occupant) && (src.occupant.loc == src))
- if((src.occupant.stat == DEAD) || (src.occupant.suiciding) || !occupant.key) //Autoeject corpses and suiciding dudes.
- src.locked = 0
- src.go_out()
- src.connected_message("Clone Rejected: Deceased.")
- return
-
- else if(src.occupant.health < src.heal_level)
- src.occupant.Paralyse(4)
-
- //Slowly get that clone healed and finished.
- src.occupant.adjustCloneLoss(-2)
-
- //Premature clones may have brain damage.
- src.occupant.adjustBrainLoss(-1)
-
- //So clones don't die of oxyloss in a running pod.
- if (src.occupant.reagents.get_reagent_amount("inaprovaline") < 30)
- src.occupant.reagents.add_reagent("inaprovaline", 60)
-
- //So clones will remain asleep for long enough to get them into cryo (Bay RP edit)
- if (src.occupant.reagents.get_reagent_amount("stoxin") < 10)
- src.occupant.reagents.add_reagent("stoxin", 5)
- if (src.occupant.reagents.get_reagent_amount("chloralhydrate") < 1)
- src.occupant.reagents.add_reagent("chloralhydrate", 1)
-
- //Also heal some oxyloss ourselves because inaprovaline is so bad at preventing it!!
- src.occupant.adjustOxyLoss(-4)
-
- use_power(7500) //This might need tweaking.
- return
-
- else if((src.occupant.health >= src.heal_level) && (!src.eject_wait))
- src.connected_message("Cloning Process Complete.")
- src.locked = 0
- src.go_out()
- return
-
- else if ((!src.occupant) || (src.occupant.loc != src))
- src.occupant = null
- if (src.locked)
- src.locked = 0
- if (!src.mess)
- icon_state = "pod_0"
- //use_power(200)
- return
-
- return
-
-//Let's unlock this early I guess. Might be too early, needs tweaking.
-/obj/machinery/clonepod/attackby(obj/item/weapon/W as obj, mob/user as mob)
- if (istype(W, /obj/item/weapon/card/id)||istype(W, /obj/item/device/pda))
- if (!src.check_access(W))
- user << "\red Access Denied."
- return
- if ((!src.locked) || (isnull(src.occupant)))
- return
- if ((src.occupant.health < -20) && (src.occupant.stat != 2))
- user << "\red Access Refused."
- return
- else
- src.locked = 0
- user << "System unlocked."
- else if (istype(W, /obj/item/weapon/card/emag))
- if (isnull(src.occupant))
- return
- user << "You force an emergency ejection."
- src.locked = 0
- src.go_out()
- return
- else if (istype(W, /obj/item/weapon/reagent_containers/food/snacks/meat))
- user << "\blue \The [src] processes \the [W]."
- biomass += 50
- user.drop_item()
- del(W)
- return
- else if (istype(W, /obj/item/weapon/wrench))
- if(src.locked && (src.anchored || src.occupant))
- user << "\red Can not do that while [src] is in use."
- else
- if(src.anchored)
- src.anchored = 0
- connected.pod1 = null
- connected = null
- else
- src.anchored = 1
- playsound(src.loc, 'sound/items/Ratchet.ogg', 100, 1)
- if(anchored)
- user.visible_message("[user] secures [src] to the floor.", "You secure [src] to the floor.")
- else
- user.visible_message("[user] unsecures [src] from the floor.", "You unsecure [src] from the floor.")
- else
- ..()
-
-//Put messages in the connected computer's temp var for display.
-/obj/machinery/clonepod/proc/connected_message(var/message)
- if ((isnull(src.connected)) || (!istype(src.connected, /obj/machinery/computer/cloning)))
- return 0
- if (!message)
- return 0
-
- src.connected.temp = message
- src.connected.updateUsrDialog()
- return 1
-
-/obj/machinery/clonepod/verb/eject()
- set name = "Eject Cloner"
- set category = "Object"
- set src in oview(1)
-
- if (usr.stat != 0)
- return
- src.go_out()
- add_fingerprint(usr)
- return
-
-/obj/machinery/clonepod/proc/go_out()
- if (src.locked)
- return
-
- if (src.mess) //Clean that mess and dump those gibs!
- src.mess = 0
- gibs(src.loc)
- src.icon_state = "pod_0"
-
- /*
- for(var/obj/O in src)
- O.loc = src.loc
- */
- return
-
- if (!(src.occupant))
- return
-
- /*
- for(var/obj/O in src)
- O.loc = src.loc
- */
-
- if (src.occupant.client)
- src.occupant.client.eye = src.occupant.client.mob
- src.occupant.client.perspective = MOB_PERSPECTIVE
- src.occupant.loc = src.loc
- src.icon_state = "pod_0"
- src.eject_wait = 0 //If it's still set somehow.
- domutcheck(src.occupant) //Waiting until they're out before possible monkeyizing.
-// src.occupant.add_side_effect("Bad Stomach") // Give them an extra side-effect for free.
- src.occupant = null
-
- src.biomass -= CLONE_BIOMASS
-
- return
-
-/obj/machinery/clonepod/proc/malfunction()
- if(src.occupant)
- src.connected_message("Critical Error!")
- src.mess = 1
- src.icon_state = "pod_g"
- src.occupant.ghostize()
- spawn(5)
- del(src.occupant)
- return
-
-/obj/machinery/clonepod/relaymove(mob/user as mob)
- if (user.stat)
- return
- src.go_out()
- return
-
-/obj/machinery/clonepod/emp_act(severity)
- if(prob(100/severity)) malfunction()
- ..()
-
-/obj/machinery/clonepod/ex_act(severity)
- switch(severity)
- if(1.0)
- for(var/atom/movable/A as mob|obj in src)
- A.loc = src.loc
- ex_act(severity)
- del(src)
- return
- if(2.0)
- if (prob(50))
- for(var/atom/movable/A as mob|obj in src)
- A.loc = src.loc
- ex_act(severity)
- del(src)
- return
- if(3.0)
- if (prob(25))
- for(var/atom/movable/A as mob|obj in src)
- A.loc = src.loc
- ex_act(severity)
- del(src)
- return
- else
+ user << text("The write-protect tab is set to [read_only ? "protected" : "unprotected"].")
return
/*
diff --git a/code/game/machinery/hologram.dm b/code/game/machinery/hologram.dm
index 68009eec609..2d5b9394d05 100644
--- a/code/game/machinery/hologram.dm
+++ b/code/game/machinery/hologram.dm
@@ -114,6 +114,7 @@ For the other part of the code, check silicon say.dm. Particularly robot talk.*/
hologram.anchored = 1//So space wind cannot drag it.
hologram.name = "[A.name] (Hologram)"//If someone decides to right click.
hologram.SetLuminosity(2) //hologram lighting
+ hologram.color = color //painted holopad gives coloured holograms
SetLuminosity(2) //pad lighting
icon_state = "holopad1"
A.holo = src
diff --git a/code/game/machinery/kitchen/smartfridge.dm b/code/game/machinery/kitchen/smartfridge.dm
index 8e86678ef22..7b186bcc9c6 100644
--- a/code/game/machinery/kitchen/smartfridge.dm
+++ b/code/game/machinery/kitchen/smartfridge.dm
@@ -19,7 +19,6 @@
var/seconds_electrified = 0;
var/shoot_inventory = 0
var/locked = 0
- var/panel_open = 0 //Hacking a smartfridge
var/scan_id = 1
var/is_secure = 0
var/datum/wires/smartfridge/wires = null
diff --git a/code/game/machinery/machinery.dm b/code/game/machinery/machinery.dm
index c5eaf354973..819cc05632c 100644
--- a/code/game/machinery/machinery.dm
+++ b/code/game/machinery/machinery.dm
@@ -28,6 +28,9 @@ Class Variables:
component_parts (list)
A list of component parts of machine used by frame based machines.
+ panel_open (num)
+ Whether the panel is open
+
uid (num)
Unique id of machine across all machines.
@@ -43,9 +46,6 @@ Class Variables:
MAINT:8 -- machine is currently under going maintenance.
EMPED:16 -- temporary broken by EMP pulse
- manual (num)
- Currently unused.
-
Class Procs:
New() 'game/machinery/machine.dm'
@@ -104,13 +104,12 @@ Class Procs:
//2 = run auto, use active
var/idle_power_usage = 0
var/active_power_usage = 0
- var/power_channel = EQUIP
- //EQUIP,ENVIRON or LIGHT
- var/list/component_parts = list() //list of all the parts used to build it, if made from certain kinds of frames.
+ var/power_channel = EQUIP //EQUIP, ENVIRON or LIGHT
+ var/list/component_parts = null //list of all the parts used to build it, if made from certain kinds of frames.
var/uid
- var/manual = 0
- var/interact_offline = 0 // Can the machine be interacted with while de-powered.
+ var/panel_open = 0
var/global/gl_uid = 1
+ var/interact_offline = 0 // Can the machine be interacted with while de-powered.
/obj/machinery/New(l, d=0)
..(l)
@@ -238,15 +237,15 @@ Class Procs:
gl_uid++
/obj/machinery/proc/state(var/msg)
- for(var/mob/O in hearers(src, null))
- O.show_message("\icon[src] [msg]", 2)
+ for(var/mob/O in hearers(src, null))
+ O.show_message("\icon[src] [msg]", 2)
/obj/machinery/proc/ping(text=null)
- if (!text)
- text = "\The [src] pings."
+ if (!text)
+ text = "\The [src] pings."
- state(text, "blue")
- playsound(src.loc, 'sound/machines/ping.ogg', 50, 0)
+ state(text, "blue")
+ playsound(src.loc, 'sound/machines/ping.ogg', 50, 0)
/obj/machinery/proc/shock(mob/user, prb)
if(inoperable())
@@ -267,6 +266,54 @@ Class Procs:
else
return 0
+/obj/machinery/proc/default_deconstruction_crowbar(var/mob/user, var/obj/item/weapon/crowbar/C)
+ if(!istype(C))
+ return 0
+ if(!panel_open)
+ return 0
+ . = dismantle()
+
+/obj/machinery/proc/default_deconstruction_screwdriver(var/mob/user, var/obj/item/weapon/screwdriver/S)
+ if(!istype(S))
+ return 0
+ playsound(src.loc, 'sound/items/Screwdriver.ogg', 50, 1)
+ panel_open = !panel_open
+ user << "You [panel_open ? "open" : "close"] the maintenance hatch of [src]."
+ update_icon()
+ return 1
+
+/obj/machinery/proc/default_part_replacement(var/mob/user, var/obj/item/weapon/storage/part_replacer/R)
+ if(!istype(R))
+ return 0
+ if(!component_parts)
+ return 0
+ if(panel_open)
+ var/obj/item/weapon/circuitboard/CB = locate(/obj/item/weapon/circuitboard) in component_parts
+ var/P
+ for(var/obj/item/weapon/stock_parts/A in component_parts)
+ for(var/D in CB.req_components)
+ var/T = text2path(D)
+ if(ispath(A.type, T))
+ P = T
+ break
+ for(var/obj/item/weapon/stock_parts/B in R.contents)
+ if(istype(B, P) && istype(A, P))
+ if(B.rating > A.rating)
+ R.remove_from_storage(B, src)
+ R.handle_item_insertion(A, 1)
+ component_parts -= A
+ component_parts += B
+ B.loc = null
+ user << "[A.name] replaced with [B.name]."
+ break
+ update_icon()
+ RefreshParts()
+ else
+ user << "Following parts detected in the machine:"
+ for(var/var/obj/item/C in component_parts)
+ user << " [C.name]"
+ return 1
+
/obj/machinery/proc/dismantle()
playsound(loc, 'sound/items/Crowbar.ogg', 50, 1)
var/obj/machinery/constructable_frame/machine_frame/M = new /obj/machinery/constructable_frame/machine_frame(loc)
diff --git a/code/game/machinery/rechargestation.dm b/code/game/machinery/rechargestation.dm
index 3049a6f6943..e4d29467e03 100644
--- a/code/game/machinery/rechargestation.dm
+++ b/code/game/machinery/rechargestation.dm
@@ -3,187 +3,227 @@
icon = 'icons/obj/objects.dmi'
icon_state = "borgcharger0"
density = 1
- anchored = 1.0
+ anchored = 1
use_power = 1
idle_power_usage = 50
active_power_usage = 50
var/mob/occupant = null
- var/max_internal_charge = 15000 // Two charged borgs in a row with default cell
- var/current_internal_charge = 15000 // Starts charged, to prevent power surges on round start
- var/charging_cap_active = 25000 // Active Cap - When cyborg is inside
- var/charging_cap_passive = 2500 // Passive Cap - Recharging internal capacitor when no cyborg is inside
+ var/obj/item/weapon/cell/cell = null
+ //var/max_internal_charge = 15000 // Two charged borgs in a row with default cell
+ //var/current_internal_charge = 15000 // Starts charged, to prevent power surges on round start
+ var/charging_cap_active = 1000 // Active Cap - When cyborg is inside
+ var/charging_cap_passive = 250 // Passive Cap - Recharging internal capacitor when no cyborg is inside
var/icon_update_tick = 0 // Used to update icon only once every 10 ticks
+ var/charge_rate = 250 // How much charge is restored per tick
+ var/weld_rate = 0 // How much brute damage is repaired per tick
+ var/wire_rate = 0 // How much burn damage is repaired per tick
+/obj/machinery/recharge_station/New()
+ ..()
+ component_parts = list()
+ component_parts += new /obj/item/weapon/circuitboard/recharge_station(src)
+ component_parts += new /obj/item/weapon/stock_parts/manipulator(src)
+ component_parts += new /obj/item/weapon/stock_parts/manipulator(src)
+ component_parts += new /obj/item/weapon/stock_parts/capacitor(src)
+ component_parts += new /obj/item/weapon/stock_parts/capacitor(src)
+ component_parts += new /obj/item/weapon/cell/high(src)
+ component_parts += new /obj/item/stack/cable_coil(src, 5)
- New()
- ..()
- build_icon()
- update_icon()
+ build_icon()
+ update_icon()
- process()
- if(stat & (BROKEN))
- return
+ RefreshParts()
- if((stat & (NOPOWER)) && !current_internal_charge) // No Power.
- return
-
- var/chargemode = 0
- if(src.occupant)
- process_occupant()
- chargemode = 1
- // Power Stuff
-
- if(stat & NOPOWER)
- current_internal_charge = max(0, (current_internal_charge - (50 * CELLRATE))) // Internal Circuitry, 50W load. No power - Runs from internal cell
- return // No external power = No charging
-
-
-
- if(max_internal_charge < current_internal_charge)
- current_internal_charge = max_internal_charge// Safety check if varedit adminbus or something screws up
- // Calculating amount of power to draw
- var/charge_diff = max_internal_charge - current_internal_charge // OK we have charge differences
- charge_diff = charge_diff / CELLRATE // Deconvert from Charge to Joules
- if(chargemode) // Decide if use passive or active power
- charge_diff = between(0, charge_diff, charging_cap_active) // Trim the values to limits
- else // We should have load for this tick in Watts
- charge_diff = between(0, charge_diff, charging_cap_passive)
-
- charge_diff += 50 // 50W for circuitry
-
- if(idle_power_usage != charge_diff) // Force update, but only when our power usage changed this tick.
- idle_power_usage = charge_diff
- update_use_power(1,1)
-
- current_internal_charge = min((current_internal_charge + ((charge_diff - 50) * CELLRATE)), max_internal_charge)
-
- if(icon_update_tick >= 10)
- update_icon()
- icon_update_tick = 0
- else
- icon_update_tick++
-
- return 1
-
-
- allow_drop()
- return 0
-
- examine(mob/user)
- ..(user)
- user << "The charge meter reads: [round(chargepercentage())]%"
-
- proc/chargepercentage()
- return ((current_internal_charge / max_internal_charge) * 100)
-
- relaymove(mob/user as mob)
- if(user.stat)
- return
- src.go_out()
+/obj/machinery/recharge_station/process()
+ if(stat & (BROKEN))
return
- emp_act(severity)
- if(stat & (BROKEN|NOPOWER))
- ..(severity)
- return
- if(occupant)
- occupant.emp_act(severity)
- go_out()
- ..(severity)
-
- update_icon()
- ..()
- overlays.Cut()
- switch(round(chargepercentage()))
- if(1 to 20)
- overlays += image('icons/obj/objects.dmi', "statn_c0")
- if(21 to 40)
- overlays += image('icons/obj/objects.dmi', "statn_c20")
- if(41 to 60)
- overlays += image('icons/obj/objects.dmi', "statn_c40")
- if(61 to 80)
- overlays += image('icons/obj/objects.dmi', "statn_c60")
- if(81 to 98)
- overlays += image('icons/obj/objects.dmi', "statn_c80")
- if(99 to 110)
- overlays += image('icons/obj/objects.dmi', "statn_c100")
-
- proc
- build_icon()
- if(NOPOWER|BROKEN)
- if(src.occupant)
- icon_state = "borgcharger1"
- else
- icon_state = "borgcharger0"
- else
- icon_state = "borgcharger0"
+ if((stat & (NOPOWER)) && (!cell || cell.percent() <= 0)) // No Power.
+ return
+ var/chargemode = 0
+ if(occupant)
process_occupant()
- if(src.occupant)
- if (istype(occupant, /mob/living/silicon/robot))
- var/mob/living/silicon/robot/R = occupant
- if(R.module)
- R.module.respawn_consumable(R)
- if(!R.cell)
- return
- if(!R.cell.fully_charged())
- var/diff = min(R.cell.maxcharge - R.cell.charge, 250) // Capped at 250 charge / tick
- diff = min(diff, current_internal_charge) // No over-discharging
- R.cell.give(diff)
- current_internal_charge -= diff
- else
- update_use_power(1)
+ chargemode = 1
+ // Power Stuff
+
+ if(!cell) // Shouldn't be possible, but sanity check
+ return
+
+ if(stat & NOPOWER)
+ cell.use(50 * CELLRATE) // Internal Circuitry, 50W load. No power - Runs from internal cell
+ return // No external power = No charging
+
+ // Calculating amount of power to draw
+ var/charge_diff = (chargemode ? charging_cap_active : charging_cap_passive) + 50 // 50W for circuitry
+
+ charge_diff = cell.give(charge_diff)
+
+ if(idle_power_usage != charge_diff) // Force update, but only when our power usage changed this tick.
+ idle_power_usage = charge_diff
+ update_use_power(1, 1)
+
+ if(icon_update_tick >= 10)
+ update_icon()
+ icon_update_tick = 0
+ else
+ icon_update_tick++
+
+ return 1
+
+
+/obj/machinery/recharge_station/allow_drop()
+ return 0
+
+/obj/machinery/recharge_station/examine(mob/user)
+ ..(user)
+ user << "The charge meter reads: [round(chargepercentage())]%"
+
+/obj/machinery/recharge_station/proc/chargepercentage()
+ if(!cell)
+ return 0
+ return cell.percent()
+
+/obj/machinery/recharge_station/relaymove(mob/user as mob)
+ if(user.stat)
+ return
+ go_out()
+ return
+
+/obj/machinery/recharge_station/emp_act(severity)
+ if(stat & (BROKEN|NOPOWER))
+ ..(severity)
+ return
+ if(occupant)
+ occupant.emp_act(severity)
go_out()
- if(!( src.occupant ))
- return
- //for(var/obj/O in src)
- // O.loc = src.loc
- if (src.occupant.client)
- src.occupant.client.eye = src.occupant.client.mob
- src.occupant.client.perspective = MOB_PERSPECTIVE
- src.occupant.loc = src.loc
- src.occupant = null
- build_icon()
- update_use_power(1)
+ if(cell)
+ cell.emp_act(severity)
+ ..(severity)
+
+/obj/machinery/recharge_station/attackby(var/obj/item/O as obj, var/mob/user as mob)
+ if(!occupant)
+ if(default_deconstruction_screwdriver(user, O))
+ return
+ if(default_deconstruction_crowbar(user, O))
+ return
+ if(default_part_replacement(user, O))
return
+ ..()
- verb
- move_eject()
- set category = "Object"
- set src in oview(1)
- if (usr.stat != 0)
- return
- src.go_out()
- add_fingerprint(usr)
- return
+/obj/machinery/recharge_station/RefreshParts()
+ ..()
+ var/man_rating = 0
+ var/cap_rating = 0
- move_inside()
- set category = "Object"
- set src in oview(1)
- if (usr.stat == 2)
- //Whoever had it so that a borg with a dead cell can't enter this thing should be shot. --NEO
+ for(var/obj/item/weapon/stock_parts/P in component_parts)
+ if(istype(P, /obj/item/weapon/stock_parts/capacitor))
+ cap_rating += P.rating
+ if(istype(P, /obj/item/weapon/stock_parts/manipulator))
+ man_rating += P.rating
+ cell = locate(/obj/item/weapon/cell) in component_parts
+
+ charge_rate = 125 * cap_rating
+ charging_cap_passive = charge_rate
+ weld_rate = max(0, man_rating - 3)
+ wire_rate = max(0, man_rating - 5)
+
+/obj/machinery/recharge_station/update_icon()
+ ..()
+ overlays.Cut()
+ switch(round(chargepercentage()))
+ if(1 to 20)
+ overlays += image('icons/obj/objects.dmi', "statn_c0")
+ if(21 to 40)
+ overlays += image('icons/obj/objects.dmi', "statn_c20")
+ if(41 to 60)
+ overlays += image('icons/obj/objects.dmi', "statn_c40")
+ if(61 to 80)
+ overlays += image('icons/obj/objects.dmi', "statn_c60")
+ if(81 to 98)
+ overlays += image('icons/obj/objects.dmi', "statn_c80")
+ if(99 to 110)
+ overlays += image('icons/obj/objects.dmi', "statn_c100")
+
+
+/obj/machinery/recharge_station/proc/build_icon()
+ if(NOPOWER|BROKEN)
+ if(occupant)
+ icon_state = "borgcharger1"
+ else
+ icon_state = "borgcharger0"
+ else
+ icon_state = "borgcharger0"
+
+/obj/machinery/recharge_station/proc/process_occupant()
+ if(occupant)
+ if(istype(occupant, /mob/living/silicon/robot))
+ var/mob/living/silicon/robot/R = occupant
+ if(R.module)
+ R.module.respawn_consumable(R)
+ if(!R.cell)
return
- if (!(istype(usr, /mob/living/silicon/)))
- usr << "\blue Only non-organics may enter the recharger!"
- return
- if (src.occupant)
- usr << "\blue The cell is already occupied!"
- return
- if (!usr:cell)
- usr<<"\blue Without a powercell, you can't be recharged."
- //Make sure they actually HAVE a cell, now that they can get in while powerless. --NEO
- return
- usr.stop_pulling()
- if(usr && usr.client)
- usr.client.perspective = EYE_PERSPECTIVE
- usr.client.eye = src
- usr.loc = src
- src.occupant = usr
- /*for(var/obj/O in src)
- O.loc = src.loc*/
- src.add_fingerprint(usr)
- build_icon()
- update_use_power(1)
- return
\ No newline at end of file
+ if(!R.cell.fully_charged())
+ var/diff = min(R.cell.maxcharge - R.cell.charge, charge_rate) // Capped at charge_rate charge / tick
+ if (cell.use(diff))
+ R.cell.give(diff)
+ if(weld_rate && R.getBruteLoss())
+ R.adjustBruteLoss(-1)
+ if(wire_rate && R.getFireLoss())
+ R.adjustFireLoss(-1)
+ else
+ update_use_power(1)
+
+/obj/machinery/recharge_station/proc/go_out()
+ if(!(occupant))
+ return
+ //for(var/obj/O in src)
+ // O.loc = loc
+ if(occupant.client)
+ occupant.client.eye = occupant.client.mob
+ occupant.client.perspective = MOB_PERSPECTIVE
+ occupant.loc = loc
+ occupant = null
+ build_icon()
+ update_use_power(1)
+ return
+
+/obj/machinery/recharge_station/verb/move_eject()
+ set category = "Object"
+ set src in oview(1)
+ if(usr.stat != 0)
+ return
+ go_out()
+ add_fingerprint(usr)
+ return
+
+/obj/machinery/recharge_station/verb/move_inside()
+ set category = "Object"
+ set src in oview(1)
+ if(usr.stat == 2)
+ //Whoever had it so that a borg with a dead cell can't enter this thing should be shot. --NEO
+ return
+ if(!(istype(usr, /mob/living/silicon/)))
+ usr << "Only non-organics may enter the recharger!"
+ return
+ if(occupant)
+ usr << "The cell is already occupied!"
+ return
+ if(!usr:cell)
+ usr << "Without a powercell, you can't be recharged."
+ //Make sure they actually HAVE a cell, now that they can get in while powerless. --NEO
+ return
+ usr.stop_pulling()
+ if(usr && usr.client)
+ usr.client.perspective = EYE_PERSPECTIVE
+ usr.client.eye = src
+ usr.loc = src
+ occupant = usr
+ /*for(var/obj/O in src)
+ O.loc = loc*/
+ add_fingerprint(usr)
+ build_icon()
+ update_use_power(1)
+ return
\ No newline at end of file
diff --git a/code/game/machinery/spaceheater.dm b/code/game/machinery/spaceheater.dm
index ab4967d04ed..c5d389c66e3 100644
--- a/code/game/machinery/spaceheater.dm
+++ b/code/game/machinery/spaceheater.dm
@@ -7,7 +7,6 @@
desc = "Made by Space Amish using traditional space techniques, this heater is guaranteed not to set the station on fire."
var/obj/item/weapon/cell/cell
var/on = 0
- var/open = 0
var/set_temperature = T0C + 50 //K
var/heating_power = 40000
@@ -20,14 +19,14 @@
/obj/machinery/space_heater/update_icon()
overlays.Cut()
icon_state = "sheater[on]"
- if(open)
+ if(panel_open)
overlays += "sheater-open"
/obj/machinery/space_heater/examine(mob/user)
..(user)
- user << "The heater is [on ? "on" : "off"] and the hatch is [open ? "open" : "closed"]."
- if(open)
+ user << "The heater is [on ? "on" : "off"] and the hatch is [panel_open ? "open" : "closed"]."
+ if(panel_open)
user << "The power cell is [cell ? "installed" : "missing"]."
else
user << "The charge meter reads [cell ? round(cell.percent(),1) : 0]%"
@@ -43,7 +42,7 @@
/obj/machinery/space_heater/attackby(obj/item/I, mob/user)
if(istype(I, /obj/item/weapon/cell))
- if(open)
+ if(panel_open)
if(cell)
user << "There is already a power cell inside."
return
@@ -61,10 +60,10 @@
user << "The hatch must be open to insert a power cell."
return
else if(istype(I, /obj/item/weapon/screwdriver))
- open = !open
- user.visible_message("\blue [user] [open ? "opens" : "closes"] the hatch on the [src].", "\blue You [open ? "open" : "close"] the hatch on the [src].")
+ panel_open = !panel_open
+ user.visible_message("\blue [user] [panel_open ? "opens" : "closes"] the hatch on the [src].", "\blue You [panel_open ? "open" : "close"] the hatch on the [src].")
update_icon()
- if(!open && user.machine == src)
+ if(!panel_open && user.machine == src)
user << browse(null, "window=spaceheater")
user.unset_machine()
else
@@ -77,7 +76,7 @@
/obj/machinery/space_heater/interact(mob/user as mob)
- if(open)
+ if(panel_open)
var/dat
dat = "Power cell: "
@@ -120,7 +119,7 @@
set_temperature = dd_range(T0C, T0C + 90, set_temperature + value)
if("cellremove")
- if(open && cell && !usr.get_active_hand())
+ if(panel_open && cell && !usr.get_active_hand())
usr.visible_message("\blue [usr] removes \the [cell] from \the [src].", "\blue You remove \the [cell] from \the [src].")
cell.updateicon()
usr.put_in_hands(cell)
@@ -129,7 +128,7 @@
if("cellinstall")
- if(open && !cell)
+ if(panel_open && !cell)
var/obj/item/weapon/cell/C = usr.get_active_hand()
if(istype(C))
usr.drop_item()
diff --git a/code/game/machinery/suit_storage_unit.dm b/code/game/machinery/suit_storage_unit.dm
index 4bf1c07abc7..f8ae293bba3 100644
--- a/code/game/machinery/suit_storage_unit.dm
+++ b/code/game/machinery/suit_storage_unit.dm
@@ -589,7 +589,6 @@
var/radiation_level = 2 // 1 is removing germs, 2 is removing blood, 3 is removing phoron.
var/model_text = "" // Some flavour text for the topic box.
var/locked = 1 // If locked, nothing can be taken from or added to the cycler.
- var/panel_open = 0 // Hacking!
var/can_repair // If set, the cycler can repair voidsuits.
var/electrified = 0
diff --git a/code/game/machinery/vending.dm b/code/game/machinery/vending.dm
index 26f1c620c7a..7d7ee3113df 100644
--- a/code/game/machinery/vending.dm
+++ b/code/game/machinery/vending.dm
@@ -54,7 +54,6 @@
var/shoot_inventory = 0 //Fire items at customers! We're broken!
var/shut_up = 1 //Stop spouting those godawful pitches!
var/extended_inventory = 0 //can we access the hidden inventory?
- var/panel_open = 0 //Hacking that vending machine. Gonna get a free candy bar.
var/scan_id = 1
var/obj/item/weapon/coin/coin
var/datum/wires/vending/wires = null
diff --git a/code/game/objects/items.dm b/code/game/objects/items.dm
index 13081d6abba..eb2e5c65a6f 100644
--- a/code/game/objects/items.dm
+++ b/code/game/objects/items.dm
@@ -411,9 +411,9 @@
H << "You need a jumpsuit before you can attach this [name]."
return 0
var/obj/item/clothing/under/uniform = H.w_uniform
- if(uniform.hastie)
+ if(uniform.accessories.len && !uniform.can_attach_accessory(src))
if (!disable_warning)
- H << "You already have [uniform.hastie] attached to your [uniform]."
+ H << "You already have an accessory of this type attached to your [uniform]."
return 0
if( !(slot_flags & SLOT_TIE) )
return 0
diff --git a/code/game/objects/items/devices/paicard.dm b/code/game/objects/items/devices/paicard.dm
index a938d6b9774..d3c667b9aa2 100644
--- a/code/game/objects/items/devices/paicard.dm
+++ b/code/game/objects/items/devices/paicard.dm
@@ -281,6 +281,8 @@
src.overlays.Cut()
src.overlays += "pai-off"
+/obj/item/device/paicard
+ var/current_emotion = 1
/obj/item/device/paicard/proc/setEmotion(var/emotion)
if(pai)
src.overlays.Cut()
@@ -294,6 +296,7 @@
if(7) src.overlays += "pai-sad"
if(8) src.overlays += "pai-angry"
if(9) src.overlays += "pai-what"
+ current_emotion = emotion
/obj/item/device/paicard/proc/alertUpdate()
var/turf/T = get_turf_or_move(src.loc)
diff --git a/code/game/objects/items/toys.dm b/code/game/objects/items/toys.dm
index fe150bab743..b997466d7d3 100644
--- a/code/game/objects/items/toys.dm
+++ b/code/game/objects/items/toys.dm
@@ -380,6 +380,10 @@
viewers(user) << "\red [user] is jamming the [src.name] up \his nose and into \his brain. It looks like \he's trying to commit suicide."
return (BRUTELOSS|OXYLOSS)
+ New()
+ name = "[colourName] crayon"
+ ..()
+
/*
* Snap pops
*/
diff --git a/code/game/objects/items/weapons/cards_ids.dm b/code/game/objects/items/weapons/cards_ids.dm
index 8d639987223..9f95abdc8ca 100644
--- a/code/game/objects/items/weapons/cards_ids.dm
+++ b/code/game/objects/items/weapons/cards_ids.dm
@@ -81,7 +81,7 @@
/obj/item/device/taperecorder,
/obj/item/device/hailer,
/obj/item/device/megaphone,
- /obj/item/clothing/tie/holobadge,
+ /obj/item/clothing/accessory/holobadge,
/obj/structure/closet/crate/secure,
/obj/structure/closet/secure_closet,
/obj/machinery/librarycomp,
diff --git a/code/game/objects/items/weapons/circuitboards/machinery/biogenerator.dm b/code/game/objects/items/weapons/circuitboards/machinery/biogenerator.dm
new file mode 100644
index 00000000000..c01893b1587
--- /dev/null
+++ b/code/game/objects/items/weapons/circuitboards/machinery/biogenerator.dm
@@ -0,0 +1,13 @@
+#ifndef T_BOARD
+#error T_BOARD macro is not defined but we need it!
+#endif
+
+/obj/item/weapon/circuitboard/biogenerator
+ name = T_BOARD("biogenerator")
+ build_path = "/obj/machinery/biogenerator"
+ board_type = "machine"
+ origin_tech = "programming=2"
+ frame_desc = "Requires 1 Manipulator, and 1 Matter Bin."
+ req_components = list(
+ "/obj/item/weapon/stock_parts/matter_bin" = 1,
+ "/obj/item/weapon/stock_parts/manipulator" = 1)
\ No newline at end of file
diff --git a/code/game/objects/items/weapons/circuitboards/machinery/recharge_station.dm b/code/game/objects/items/weapons/circuitboards/machinery/recharge_station.dm
new file mode 100644
index 00000000000..5a0dc01bc12
--- /dev/null
+++ b/code/game/objects/items/weapons/circuitboards/machinery/recharge_station.dm
@@ -0,0 +1,15 @@
+#ifndef T_BOARD
+#error T_BOARD macro is not defined but we need it!
+#endif
+
+/obj/item/weapon/circuitboard/recharge_station
+ name = T_BOARD("cyborg recharging station")
+ build_path = "/obj/machinery/recharge_station"
+ board_type = "machine"
+ origin_tech = "programming=3;engineering=3"
+ frame_desc = "Requires 2 Manipulator, 2 Capacitor, 1 Cell, and 5 pieces of cable."
+ req_components = list(
+ "/obj/item/stack/cable_coil" = 5,
+ "/obj/item/weapon/stock_parts/capacitor" = 2,
+ "/obj/item/weapon/stock_parts/manipulator" = 2,
+ "/obj/item/weapon/cell" = 1)
\ No newline at end of file
diff --git a/code/game/objects/items/weapons/explosives.dm b/code/game/objects/items/weapons/explosives.dm
index 71fb259dcda..030437b4466 100644
--- a/code/game/objects/items/weapons/explosives.dm
+++ b/code/game/objects/items/weapons/explosives.dm
@@ -38,7 +38,7 @@
/obj/item/weapon/plastique/afterattack(atom/movable/target, mob/user, flag)
if (!flag)
return
- if (ismob(target) || istype(target, /turf/unsimulated) || istype(target, /turf/simulated/shuttle) || istype(target, /obj/item/weapon/storage/) || istype(target, /obj/item/clothing/tie/storage/) || istype(target, /obj/item/clothing/under))
+ if (ismob(target) || istype(target, /turf/unsimulated) || istype(target, /turf/simulated/shuttle) || istype(target, /obj/item/weapon/storage/) || istype(target, /obj/item/clothing/accessory/storage/) || istype(target, /obj/item/clothing/under))
return
user << "Planting explosives..."
diff --git a/code/game/objects/items/weapons/gift_wrappaper.dm b/code/game/objects/items/weapons/gift_wrappaper.dm
index e96d0367217..8ed63b88aa3 100644
--- a/code/game/objects/items/weapons/gift_wrappaper.dm
+++ b/code/game/objects/items/weapons/gift_wrappaper.dm
@@ -104,7 +104,7 @@
/obj/item/device/paicard,
/obj/item/device/violin,
/obj/item/weapon/storage/belt/utility/full,
- /obj/item/clothing/tie/horrible)
+ /obj/item/clothing/accessory/horrible)
if(!ispath(gift_type,/obj/item)) return
diff --git a/code/game/objects/items/weapons/paint.dm b/code/game/objects/items/weapons/paint.dm
index 0606569c4fa..77f8172f8fc 100644
--- a/code/game/objects/items/weapons/paint.dm
+++ b/code/game/objects/items/weapons/paint.dm
@@ -1,4 +1,5 @@
//NEVER USE THIS IT SUX -PETETHEGOAT
+//THE GOAT WAS RIGHT - RKF
var/global/list/cached_icons = list()
@@ -11,10 +12,10 @@ var/global/list/cached_icons = list()
matter = list("metal" = 200)
w_class = 3.0
amount_per_transfer_from_this = 10
- possible_transfer_amounts = list(10,20,30,50,70)
+ possible_transfer_amounts = list(10,20,30,60)
volume = 60
flags = OPENCONTAINER
- var/paint_type = ""
+ var/paint_type = "red"
afterattack(turf/simulated/target, mob/user, proximity)
if(!proximity) return
@@ -28,24 +29,19 @@ var/global/list/cached_icons = list()
return ..()
New()
- if(paint_type == "remover")
- name = "paint remover bucket"
- else if(paint_type && lentext(paint_type) > 0)
+ if(paint_type && lentext(paint_type) > 0)
name = paint_type + " " + name
..()
reagents.add_reagent("water", volume*3/5)
reagents.add_reagent("plasticide", volume/5)
if(paint_type == "white") //why don't white crayons exist
reagents.add_reagent("aluminum", volume/5)
+ else if (paint_type == "black")
+ reagents.add_reagent("carbon", volume/5)
else
reagents.add_reagent("crayon_dust_[paint_type]", volume/5)
reagents.handle_reactions()
- on_reagent_change() //Until we have a generic "paint", this will give new colours to all paints in the can
- var/mixedcolor = mix_color_from_reagents(reagents.reagent_list)
- for(var/datum/reagent/paint/P in reagents.reagent_list)
- P.color = mixedcolor
-
red
icon_state = "paint_red"
paint_type = "red"
@@ -62,110 +58,15 @@ var/global/list/cached_icons = list()
icon_state = "paint_blue"
paint_type = "blue"
- violet
+ purple
icon_state = "paint_violet"
paint_type = "purple"
black
icon_state = "paint_black"
- paint_type = "gray"
+ paint_type = "black"
white
icon_state = "paint_white"
paint_type = "white"
- remover
- paint_type = "remover"
-/*
-/obj/item/weapon/paint
- gender= PLURAL
- name = "paint"
- desc = "Used to recolor floors and walls. Can not be removed by the janitor."
- icon = 'icons/obj/items.dmi'
- icon_state = "paint_neutral"
- color = "FFFFFF"
- item_state = "paintcan"
- w_class = 3.0
-
-/obj/item/weapon/paint/afterattack(turf/target, mob/user as mob, proximity)
- if(!proximity) return
- if(!istype(target) || istype(target, /turf/space))
- return
- var/ind = "[initial(target.icon)][color]"
- if(!cached_icons[ind])
- var/icon/overlay = new/icon(initial(target.icon))
- overlay.Blend("#[color]",ICON_MULTIPLY)
- overlay.SetIntensity(1.4)
- target.icon = overlay
- cached_icons[ind] = target.icon
- else
- target.icon = cached_icons[ind]
- return
-
-/obj/item/weapon/paint/paint_remover
- gender = PLURAL
- name = "paint remover"
- icon_state = "paint_neutral"
-
- afterattack(turf/target, mob/user as mob)
- if(istype(target) && target.icon != initial(target.icon))
- target.icon = initial(target.icon)
- return
-*/
-/*
-datum/reagent/paint
- name = "Paint"
- id = "paint_"
- reagent_state = 2
- color = "#808080"
- description = "This paint will only adhere to floor tiles."
-
-
-
- red
- name = "Red Paint"
- id = "paint_red"
- color = "#FE191A"
-
- green
- name = "Green Paint"
- color = "#18A31A"
- id = "paint_green"
-
- blue
- name = "Blue Paint"
- color = "#247CFF"
- id = "paint_blue"
-
- yellow
- name = "Yellow Paint"
- color = "#FDFE7D"
- id = "paint_yellow"
-
- violet
- name = "Violet Paint"
- color = "#CC0099"
- id = "paint_violet"
-
- black
- name = "Black Paint"
- color = "#333333"
- id = "paint_black"
-
- white
- name = "White Paint"
- color = "#F0F8FF"
- id = "paint_white"
-
-datum/reagent/paint_remover
- name = "Paint Remover"
- id = "paint_remover"
- description = "Paint remover is used to remove floor paint from floor tiles."
- reagent_state = 2
- color = "#808080"
-
- reaction_turf(var/turf/T, var/volume)
- if(istype(T) && T.icon != initial(T.icon))
- T.icon = initial(T.icon)
- return
-*/
diff --git a/code/game/objects/items/weapons/storage/belt.dm b/code/game/objects/items/weapons/storage/belt.dm
index 0c4a94eb869..e190ac1e02d 100644
--- a/code/game/objects/items/weapons/storage/belt.dm
+++ b/code/game/objects/items/weapons/storage/belt.dm
@@ -70,9 +70,16 @@
"/obj/item/device/flashlight/pen",
"/obj/item/clothing/mask/surgical",
"/obj/item/clothing/gloves/latex",
- "/obj/item/weapon/reagent_containers/hypospray"
+ "/obj/item/weapon/reagent_containers/hypospray"
)
+/obj/item/weapon/storage/belt/medical/emt
+ name = "EMT utility belt"
+ desc = "A sturdy black webbing belt with attached pouches."
+ icon = 'icons/obj/custom_items.dmi'
+ icon_state = "emsbelt"
+ item_state = "emsbelt"
+
/obj/item/weapon/storage/belt/security
name = "security belt"
diff --git a/code/game/objects/structures/crates_lockers/closets/secure/engineering.dm b/code/game/objects/structures/crates_lockers/closets/secure/engineering.dm
index 803f07616e0..d583e775470 100644
--- a/code/game/objects/structures/crates_lockers/closets/secure/engineering.dm
+++ b/code/game/objects/structures/crates_lockers/closets/secure/engineering.dm
@@ -16,9 +16,9 @@
else
new /obj/item/weapon/storage/backpack/satchel_eng(src)
if (prob(70))
- new /obj/item/clothing/tie/storage/brown_vest(src)
+ new /obj/item/clothing/accessory/storage/brown_vest(src)
else
- new /obj/item/clothing/tie/storage/webbing(src)
+ new /obj/item/clothing/accessory/storage/webbing(src)
new /obj/item/blueprints(src)
new /obj/item/clothing/under/rank/chief_engineer(src)
new /obj/item/clothing/head/hardhat/white(src)
@@ -109,9 +109,9 @@
else
new /obj/item/weapon/storage/backpack/satchel_eng(src)
if (prob(70))
- new /obj/item/clothing/tie/storage/brown_vest(src)
+ new /obj/item/clothing/accessory/storage/brown_vest(src)
else
- new /obj/item/clothing/tie/storage/webbing(src)
+ new /obj/item/clothing/accessory/storage/webbing(src)
new /obj/item/weapon/storage/toolbox/mechanical(src)
new /obj/item/device/radio/headset/headset_eng(src)
new /obj/item/clothing/suit/storage/hazardvest(src)
@@ -138,9 +138,9 @@
else
new /obj/item/weapon/storage/backpack/satchel_eng(src)
if (prob(70))
- new /obj/item/clothing/tie/storage/brown_vest(src)
+ new /obj/item/clothing/accessory/storage/brown_vest(src)
else
- new /obj/item/clothing/tie/storage/webbing(src)
+ new /obj/item/clothing/accessory/storage/webbing(src)
new /obj/item/clothing/suit/fire/firefighter(src)
new /obj/item/device/flashlight(src)
new /obj/item/weapon/extinguisher(src)
diff --git a/code/game/objects/structures/crates_lockers/closets/secure/security.dm b/code/game/objects/structures/crates_lockers/closets/secure/security.dm
index 4185215f28b..f0a67bddee5 100644
--- a/code/game/objects/structures/crates_lockers/closets/secure/security.dm
+++ b/code/game/objects/structures/crates_lockers/closets/secure/security.dm
@@ -119,7 +119,7 @@
new /obj/item/device/flash(src)
new /obj/item/weapon/melee/baton/loaded(src)
new /obj/item/weapon/gun/energy/gun(src)
- new /obj/item/clothing/tie/holster/waist(src)
+ new /obj/item/clothing/accessory/holster/waist(src)
new /obj/item/weapon/melee/telebaton(src)
new /obj/item/clothing/head/beret/sec/hos(src)
return
@@ -192,7 +192,7 @@
new /obj/item/clothing/glasses/sunglasses/sechud(src)
new /obj/item/taperoll/police(src)
new /obj/item/device/hailer(src)
- new /obj/item/clothing/tie/storage/black_vest(src)
+ new /obj/item/clothing/accessory/storage/black_vest(src)
new /obj/item/clothing/head/soft/sec/corp(src)
new /obj/item/clothing/under/rank/security/corp(src)
return
@@ -202,7 +202,7 @@
New()
..()
- new /obj/item/clothing/tie/armband/cargo(src)
+ new /obj/item/clothing/accessory/armband/cargo(src)
new /obj/item/device/encryptionkey/headset_cargo(src)
return
@@ -210,7 +210,7 @@
New()
..()
- new /obj/item/clothing/tie/armband/engine(src)
+ new /obj/item/clothing/accessory/armband/engine(src)
new /obj/item/device/encryptionkey/headset_eng(src)
return
@@ -218,7 +218,7 @@
New()
..()
- new /obj/item/clothing/tie/armband/science(src)
+ new /obj/item/clothing/accessory/armband/science(src)
new /obj/item/device/encryptionkey/headset_sci(src)
return
@@ -226,7 +226,7 @@
New()
..()
- new /obj/item/clothing/tie/armband/medgreen(src)
+ new /obj/item/clothing/accessory/armband/medgreen(src)
new /obj/item/device/encryptionkey/headset_med(src)
return
@@ -262,7 +262,7 @@
new /obj/item/ammo_magazine/c45m/rubber(src)
new /obj/item/taperoll/police(src)
new /obj/item/weapon/gun/projectile/detective/semiauto(src)
- new /obj/item/clothing/tie/holster/armpit(src)
+ new /obj/item/clothing/accessory/holster/armpit(src)
return
/obj/structure/closet/secure_closet/detective/update_icon()
diff --git a/code/game/objects/structures/safe.dm b/code/game/objects/structures/safe.dm
index a219268d041..199635cd0fe 100644
--- a/code/game/objects/structures/safe.dm
+++ b/code/game/objects/structures/safe.dm
@@ -90,7 +90,7 @@ FLOOR SAFES
var/mob/living/carbon/human/user = usr
var/canhear = 0
- if(istype(user.l_hand, /obj/item/clothing/tie/stethoscope) || istype(user.r_hand, /obj/item/clothing/tie/stethoscope))
+ if(istype(user.l_hand, /obj/item/clothing/accessory/stethoscope) || istype(user.r_hand, /obj/item/clothing/accessory/stethoscope))
canhear = 1
if(href_list["open"])
@@ -155,7 +155,7 @@ FLOOR SAFES
user << "[I] won't fit in [src]."
return
else
- if(istype(I, /obj/item/clothing/tie/stethoscope))
+ if(istype(I, /obj/item/clothing/accessory/stethoscope))
user << "Hold [I] in one of your hands while you manipulate the dial."
return
diff --git a/code/game/turfs/simulated/walls.dm b/code/game/turfs/simulated/walls.dm
index 572ed0ff8db..9b85c90e161 100644
--- a/code/game/turfs/simulated/walls.dm
+++ b/code/game/turfs/simulated/walls.dm
@@ -6,8 +6,7 @@
var/rotting = 0
var/damage = 0
- var/damage_cap = 100 //Wall will break down to girders if damage reaches this point
- var/armor = 0.5 // Damage is multiplied by this
+ var/damage_cap = 150 //Wall will break down to girders if damage reaches this point
var/damage_overlay
var/global/damage_overlays[8]
@@ -30,7 +29,7 @@
return
//cap the amount of damage, so that things like emitters can't destroy walls in one hit.
- var/damage = min(Proj.damage, 100) * armor
+ var/damage = min(Proj.damage, 100)
take_damage(damage)
return
@@ -39,12 +38,12 @@
..()
if(ismob(AM))
return
-
+
var/tforce = AM:throwforce * (speed/THROWFORCE_SPEED_DIVISOR)
if (tforce < 15)
return
-
- take_damage(tforce * armor)
+
+ take_damage(tforce)
/turf/simulated/wall/Del()
for(var/obj/effect/E in src) if(E.name == "Wallrot") del E
@@ -475,7 +474,7 @@
else if(istype(W,/obj/item/weapon/rcd)) //I bitterly resent having to write this. ~Z
return
-
+
else if(istype(W, /obj/item/weapon/reagent_containers))
return // They tend to have meaningful afterattack - let them apply it without destroying a rotting wall
diff --git a/code/game/turfs/simulated/walls_reinforced.dm b/code/game/turfs/simulated/walls_reinforced.dm
index b08363a7153..5eddfc8b71c 100644
--- a/code/game/turfs/simulated/walls_reinforced.dm
+++ b/code/game/turfs/simulated/walls_reinforced.dm
@@ -5,9 +5,8 @@
opacity = 1
density = 1
- damage_cap = 500
+ damage_cap = 800
max_temperature = 6000
- armor = 0.1 // Only 10% damage from gunfire, it's made from strong alloys and stuff.
walltype = "rwall"
@@ -294,7 +293,7 @@
else if(istype(W, /obj/item/weapon/reagent_containers))
return // They tend to have meaningful afterattack - let them apply it without destroying a rotting wall
-
+
//Finally, CHECKING FOR FALSE WALLS if it isn't damaged
else if(!d_state)
return attack_hand(user)
diff --git a/code/modules/admin/admin_verbs.dm b/code/modules/admin/admin_verbs.dm
index a67e42ca2ba..dbf73d65fda 100644
--- a/code/modules/admin/admin_verbs.dm
+++ b/code/modules/admin/admin_verbs.dm
@@ -109,6 +109,9 @@ var/list/admin_verbs_fun = list(
var/list/admin_verbs_spawn = list(
/datum/admins/proc/spawn_atom, /*allows us to spawn instances*/
/client/proc/respawn_character,
+ /client/proc/FireLaser,
+ /client/proc/FireCannons,
+ /client/proc/ChangeIcarusPosition,
/client/proc/virus2_editor
)
var/list/admin_verbs_server = list(
diff --git a/code/modules/admin/verbs/icarus.dm b/code/modules/admin/verbs/icarus.dm
new file mode 100644
index 00000000000..cccda899b34
--- /dev/null
+++ b/code/modules/admin/verbs/icarus.dm
@@ -0,0 +1,125 @@
+/client/proc/FireLaser()
+ set name = "Fire the Icarus lasers"
+ set desc = "Fires a laser bolt at your position. You should only do this as a(n) (a)ghost"
+ set category = "Fun"
+
+ if(!src.holder)
+ src << "Only administrators may use this command."
+ return
+
+ Icarus_FireLaser(get_turf(src.mob))
+
+
+/client/proc/FireCannons()
+ set name = "Fire the Icarus cannons"
+ set desc = "Fires an explosive missile at your position. You should only do this as a(n) (a)ghost."
+ set category = "Fun"
+
+ if(!src.holder)
+ src << "Only administrators may use this command."
+ return
+
+ Icarus_FireCannon(get_turf(src.mob))
+
+
+/client/proc/ChangeIcarusPosition()
+ set name = "Adjust Icarus Position"
+ set desc = "Lets you chose the position of the Icarus in regards to the map."
+ set category = "Fun"
+
+ if(!src.holder)
+ src << "Only administrators may use this command."
+ return
+
+ Icarus_SetPosition(src)
+
+var/icarus_position = SOUTH
+
+proc/Icarus_FireLaser(var/turf/target)
+ // Find the world edge to fire from.
+ var/x = icarus_position & EAST ? world.maxx : icarus_position & WEST ? 1 : target.x
+ var/y = icarus_position & NORTH ? world.maxy : icarus_position & SOUTH ? 1 : target.y
+ var/x_off = x != target.x ? abs(target.x - x) : INFINITY
+ var/y_off = y != target.y ? abs(target.y - y) : INFINITY
+ // Get the minimum number of steps using the rise/run shit.
+ var/iterations = round(min(x_off, y_off)) - 14 // We cannot fire straight from the edge since teleport thing.
+
+ // Now we can get the location of the start.
+ x = target.x + (icarus_position & EAST ? iterations : icarus_position & WEST ? -iterations : 0)
+ y = target.y + (icarus_position & NORTH ? iterations : icarus_position & SOUTH ? -iterations : 0)
+
+ var/turf/start = locate(x, y, target.z)
+
+ // should step down as:
+ // 1000, 500, 333, 250, 200, 167, 142, 125, 111, 100, 90
+ var/damage = 1000
+ for(var/i in 2 to 12)
+ var/obj/item/projectile/beam/in_chamber = new (start)
+ in_chamber.original = target
+ in_chamber.starting = start
+ in_chamber.silenced = 1
+ in_chamber.yo = icarus_position & NORTH ? -1 : icarus_position & SOUTH ? 1 : 0
+ in_chamber.xo = icarus_position & EAST ? -1 : icarus_position & WEST ? 1 : 0
+ in_chamber.damage = damage
+ in_chamber.kill_count = 500
+ in_chamber.process()
+ damage -= damage / i
+ sleep(-1)
+
+ // Let everyone know what hit them.
+ var/obj/item/projectile/beam/in_chamber = new (start)
+ in_chamber.original = target
+ in_chamber.starting = start
+ in_chamber.silenced = 0
+ in_chamber.yo = icarus_position & NORTH ? -1 : icarus_position & SOUTH ? 1 : 0
+ in_chamber.xo = icarus_position & EAST ? -1 : icarus_position & WEST ? 1 : 0
+ in_chamber.kill_count = 500
+ in_chamber.damage = 0
+ in_chamber.name = "point defense laser"
+ in_chamber.firer = "Icarus" // Never displayed, but we want this to display the hit message.
+ in_chamber.process()
+
+proc/Icarus_FireCannon(var/turf/target)
+ // Find the world edge to fire from.
+ var/x = icarus_position & EAST ? world.maxx : icarus_position & WEST ? 1 : target.x
+ var/y = icarus_position & NORTH ? world.maxy : icarus_position & SOUTH ? 1 : target.y
+ var/x_off = x != target.x ? abs(target.x - x) : INFINITY
+ var/y_off = y != target.y ? abs(target.y - y) : INFINITY
+ // Get the minimum number of steps using the rise/run shit.
+ var/iterations = round(min(x_off, y_off)) - 14 // We cannot fire straight from the edge since teleport thing.
+
+ // Now we can get the location of the start.
+ x = target.x + (icarus_position & EAST ? iterations : icarus_position & WEST ? -iterations : 0)
+ y = target.y + (icarus_position & NORTH ? iterations : icarus_position & SOUTH ? -iterations : 0)
+
+ var/turf/start = locate(x, y, target.z)
+
+ // Now we find the corresponding turf on the other side of the level.
+ // Yeah, yeah. Overuse of the terinary operator. So sue me.
+ x = icarus_position & EAST ? 1 : icarus_position & WEST ? world.maxx : target.x
+ y = icarus_position & NORTH ? 1 : icarus_position & SOUTH ? world.maxy : target.y
+ x_off = x != target.x ? abs(target.x - x) : INFINITY
+ y_off = y != target.y ? abs(target.y - y) : INFINITY
+ iterations = round(min(x_off, y_off))
+ x = target.x + (icarus_position & EAST ? -iterations : icarus_position & WEST ? iterations : 0)
+ y = target.y + (icarus_position & NORTH ? -iterations : icarus_position & SOUTH ? iterations : 0)
+ target = locate(x, y, target.z)
+
+ // Finally fire the fucker.
+ var/obj/effect/meteor/small/projectile = new (start)
+ projectile.dest = target
+ projectile.name = "main gun projectile" // stealthy
+ projectile.hits = 6
+ projectile.detonation_chance = 99 // it's a missile/cannon round thing!
+
+ // Make sure it travels
+ spawn(0)
+ walk_towards(projectile, projectile.dest, 1)
+
+proc/Icarus_SetPosition(var/user)
+ var/global/list/directions = list("North" = 1, "North East" = 5, "East" = 4, "South East" = 6, "South" = 2, "South West" = 10, "West" = 8, "North West" = 9)
+ var/direction = input(user, "Where should the Icarus fire from?", "Icarus Comms") as null|anything in directions
+ if(!direction)
+ return
+
+ icarus_position = directions[direction]
\ No newline at end of file
diff --git a/code/modules/client/preferences_gear.dm b/code/modules/client/preferences_gear.dm
index d265babc1b7..d788a41cc96 100644
--- a/code/modules/client/preferences_gear.dm
+++ b/code/modules/client/preferences_gear.dm
@@ -375,88 +375,88 @@ var/global/list/gear_datums = list()
/datum/gear/armband_cargo
display_name = "armband, cargo"
- path = /obj/item/clothing/tie/armband/cargo
+ path = /obj/item/clothing/accessory/armband/cargo
slot = slot_tie
cost = 1
/datum/gear/armband_emt
display_name = "armband, EMT"
- path = /obj/item/clothing/tie/armband/medgreen
+ path = /obj/item/clothing/accessory/armband/medgreen
slot = slot_tie
cost = 2
/datum/gear/armband_engineering
display_name = "armband, engineering"
- path = /obj/item/clothing/tie/armband/engine
+ path = /obj/item/clothing/accessory/armband/engine
slot = slot_tie
cost = 1
/datum/gear/armband_hydroponics
display_name = "armband, hydroponics"
- path = /obj/item/clothing/tie/armband/hydro
+ path = /obj/item/clothing/accessory/armband/hydro
slot = slot_tie
cost = 1
/datum/gear/armband_medical
display_name = "armband, medical"
- path = /obj/item/clothing/tie/armband/med
+ path = /obj/item/clothing/accessory/armband/med
slot = slot_tie
cost = 1
/datum/gear/armband
display_name = "armband, red"
- path = /obj/item/clothing/tie/armband
+ path = /obj/item/clothing/accessory/armband
slot = slot_tie
cost = 1
/datum/gear/armband_science
display_name = "armband, science"
- path = /obj/item/clothing/tie/armband/science
+ path = /obj/item/clothing/accessory/armband/science
slot = slot_tie
cost = 1
/datum/gear/armpit
display_name = "shoulder holster"
- path = /obj/item/clothing/tie/holster/armpit
+ path = /obj/item/clothing/accessory/holster/armpit
slot = slot_tie
cost = 2
allowed_roles = list("Captain", "Head of Personnel", "Security Officer", "Warden", "Head of Security")
/datum/gear/tie_blue
display_name = "tie, blue"
- path = /obj/item/clothing/tie/blue
+ path = /obj/item/clothing/accessory/blue
slot = slot_tie
cost = 1
/datum/gear/tie_red
display_name = "tie, red"
- path = /obj/item/clothing/tie/red
+ path = /obj/item/clothing/accessory/red
slot = slot_tie
cost = 1
/datum/gear/tie_horrible
display_name = "tie, socially disgraceful"
- path = /obj/item/clothing/tie/horrible
+ path = /obj/item/clothing/accessory/horrible
slot = slot_tie
cost = 1
/datum/gear/brown_vest
display_name = "webbing, engineering"
- path = /obj/item/clothing/tie/storage/brown_vest
+ path = /obj/item/clothing/accessory/storage/brown_vest
slot = slot_tie
cost = 2
allowed_roles = list("Station Engineer","Atmospheric Technician","Chief Engineer")
/datum/gear/black_vest
display_name = "webbing, security"
- path = /obj/item/clothing/tie/storage/black_vest
+ path = /obj/item/clothing/accessory/storage/black_vest
slot = slot_tie
cost = 2
allowed_roles = list("Security Officer","Head of Security","Warden")
/datum/gear/webbing
display_name = "webbing, simple"
- path = /obj/item/clothing/tie/storage/webbing
+ path = /obj/item/clothing/accessory/storage/webbing
slot = slot_tie
cost = 2
diff --git a/code/modules/clothing/clothing.dm b/code/modules/clothing/clothing.dm
index f6dc6cc3379..da569c6b615 100644
--- a/code/modules/clothing/clothing.dm
+++ b/code/modules/clothing/clothing.dm
@@ -68,7 +68,7 @@
/obj/item/clothing/head/helmet/refit_for_species(var/target_species)
if(!species_restricted)
return //this item doesn't use the species_restricted system
-
+
//Set species_restricted list
switch(target_species)
if("Skrell")
@@ -401,7 +401,7 @@ BLIND // can't see anything
2 = Report detailed damages
3 = Report location
*/
- var/obj/item/clothing/tie/hastie = null
+ var/list/accessories = list()
var/displays_id = 1
sprite_sheets = list("Vox" = 'icons/mob/species/vox/uniform.dmi')
@@ -410,28 +410,44 @@ 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(hastie)
- hastie.attackby(I, user)
- return
+ 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(!hastie && istype(I, /obj/item/clothing/tie))
- user.drop_item()
- hastie = I
- hastie.on_attached(src, user)
+ if(istype(loc, /mob/living/carbon/human))
+ var/mob/living/carbon/human/H = loc
+ H.update_inv_w_uniform()
- if(istype(loc, /mob/living/carbon/human))
- var/mob/living/carbon/human/H = loc
- H.update_inv_w_uniform()
+ return
+ else
+ user << "You cannot attach more accessories of this type to [src]."
+ 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(hastie && src.loc == user)
- hastie.attack_hand(user)
+ if(accessories.len && src.loc == user)
+ for(var/obj/item/clothing/accessory/A in accessories)
+ A.attack_hand(user)
return
if ((ishuman(usr) || ismonkey(usr)) && src.loc == user) //make it harder to accidentally undress yourself
@@ -468,8 +484,9 @@ 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(hastie)
- user << "\A [hastie] is clipped to it."
+ 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
@@ -540,12 +557,12 @@ BLIND // can't see anything
else
usr << "You cannot roll down the uniform!"
-/obj/item/clothing/under/proc/remove_accessory(mob/user as mob)
- if(!hastie)
+/obj/item/clothing/under/proc/remove_accessory(mob/user, obj/item/clothing/accessory/A)
+ if(!(A in accessories))
return
- hastie.on_removed(user)
- hastie = null
+ A.on_removed(user)
+ accessories -= A
update_clothing_icon()
/obj/item/clothing/under/verb/removetie()
@@ -554,14 +571,20 @@ BLIND // can't see anything
set src in usr
if(!istype(usr, /mob/living)) return
if(usr.stat) return
-
- src.remove_accessory(usr)
+ 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 (hastie)
- hastie.emp_act(severity)
+ if(accessories.len)
+ for(var/obj/item/clothing/accessory/A in accessories)
+ A.emp_act(severity)
..()
\ No newline at end of file
diff --git a/code/modules/clothing/suits/armor.dm b/code/modules/clothing/suits/armor.dm
index 3d5d2d9940b..7549e9cbe5d 100644
--- a/code/modules/clothing/suits/armor.dm
+++ b/code/modules/clothing/suits/armor.dm
@@ -196,7 +196,7 @@
slowdown = 1
armor = list(melee = 60, bullet = 60, laser = 60, energy = 40, bomb = 20, bio = 0, rad = 0)
siemens_coefficient = 0.7
- var/obj/item/clothing/tie/holster/holster
+ var/obj/item/clothing/accessory/holster/holster
/obj/item/clothing/suit/armor/tactical/New()
..()
@@ -216,13 +216,12 @@
if(!holster.holstered)
var/obj/item/W = usr.get_active_hand()
if(!istype(W, /obj/item))
- usr << "\blue You need your gun equiped to holster it."
+ usr << "You need your gun equiped to holster it."
return
holster.holster(W, usr)
else
holster.unholster(usr)
-
//Non-hardsuit ERT armor.
/obj/item/clothing/suit/armor/vest/ert
name = "emergency response team armor"
diff --git a/code/modules/clothing/under/accessories/accessory.dm b/code/modules/clothing/under/accessories/accessory.dm
new file mode 100644
index 00000000000..e1c9a25c248
--- /dev/null
+++ b/code/modules/clothing/under/accessories/accessory.dm
@@ -0,0 +1,226 @@
+/obj/item/clothing/accessory
+ name = "tie"
+ desc = "A neosilk clip-on tie."
+ icon = 'icons/obj/clothing/ties.dmi'
+ icon_state = "bluetie"
+ item_state = "" //no inhands
+ item_color = "bluetie"
+ 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/image/inv_overlay = null //overlay used when attached to clothing.
+
+/obj/item/clothing/accessory/New()
+ ..()
+ inv_overlay = image("icon" = 'icons/obj/clothing/ties_overlay.dmi', "icon_state" = "[item_color? "[item_color]" : "[icon_state]"]")
+
+//when user attached an accessory to S
+/obj/item/clothing/accessory/proc/on_attached(obj/item/clothing/under/S, mob/user as mob)
+ if(!istype(S))
+ return
+ has_suit = S
+ loc = has_suit
+ has_suit.overlays += inv_overlay
+
+ user << "You attach [src] to [has_suit]."
+ src.add_fingerprint(user)
+
+/obj/item/clothing/accessory/proc/on_removed(mob/user as mob)
+ if(!has_suit)
+ return
+ has_suit.overlays -= inv_overlay
+ has_suit = null
+ usr.put_in_hands(src)
+ src.add_fingerprint(user)
+
+//default attackby behaviour
+/obj/item/clothing/accessory/attackby(obj/item/I, mob/user)
+ ..()
+
+//default attack_hand behaviour
+/obj/item/clothing/accessory/attack_hand(mob/user as mob)
+ if(has_suit)
+ return //we aren't an object on the ground so don't call parent
+ ..()
+
+/obj/item/clothing/accessory/blue
+ name = "blue tie"
+ icon_state = "bluetie"
+ item_color = "bluetie"
+
+/obj/item/clothing/accessory/red
+ name = "red tie"
+ icon_state = "redtie"
+ item_color = "redtie"
+
+/obj/item/clothing/accessory/horrible
+ name = "horrible tie"
+ desc = "A neosilk clip-on tie. This one is disgusting."
+ icon_state = "horribletie"
+ item_color = "horribletie"
+
+/obj/item/clothing/accessory/stethoscope
+ name = "stethoscope"
+ desc = "An outdated medical apparatus for listening to the sounds of the human body. It also makes you look like you know what you're doing."
+ icon_state = "stethoscope"
+ item_color = "stethoscope"
+
+/obj/item/clothing/accessory/stethoscope/attack(mob/living/carbon/human/M, mob/living/user)
+ if(ishuman(M) && isliving(user))
+ if(user.a_intent == "help")
+ var/body_part = parse_zone(user.zone_sel.selecting)
+ if(body_part)
+ var/their = "their"
+ switch(M.gender)
+ if(MALE) their = "his"
+ if(FEMALE) their = "her"
+
+ var/sound = "pulse"
+ var/sound_strength
+
+ if(M.stat == DEAD || (M.status_flags&FAKEDEATH))
+ sound_strength = "cannot hear"
+ sound = "anything"
+ else
+ sound_strength = "hear a weak"
+ switch(body_part)
+ if("chest")
+ if(M.oxyloss < 50)
+ sound_strength = "hear a healthy"
+ sound = "pulse and respiration"
+ if("eyes","mouth")
+ sound_strength = "cannot hear"
+ sound = "anything"
+ else
+ sound_strength = "hear a weak"
+
+ user.visible_message("[user] places [src] against [M]'s [body_part] and listens attentively.", "You place [src] against [their] [body_part]. You [sound_strength] [sound].")
+ return
+ return ..(M,user)
+
+
+//Medals
+/obj/item/clothing/accessory/medal
+ name = "bronze medal"
+ desc = "A bronze medal."
+ icon_state = "bronze"
+ item_color = "bronze"
+
+/obj/item/clothing/accessory/medal/conduct
+ name = "distinguished conduct medal"
+ desc = "A bronze medal awarded for distinguished conduct. Whilst a great honor, this is most basic award given by Nanotrasen. It is often awarded by a captain to a member of his crew."
+
+/obj/item/clothing/accessory/medal/bronze_heart
+ name = "bronze heart medal"
+ desc = "A bronze heart-shaped medal awarded for sacrifice. It is often awarded posthumously or for severe injury in the line of duty."
+ icon_state = "bronze_heart"
+
+/obj/item/clothing/accessory/medal/nobel_science
+ name = "nobel sciences award"
+ desc = "A bronze medal which represents significant contributions to the field of science or engineering."
+
+/obj/item/clothing/accessory/medal/silver
+ name = "silver medal"
+ desc = "A silver medal."
+ icon_state = "silver"
+ item_color = "silver"
+
+/obj/item/clothing/accessory/medal/silver/valor
+ name = "medal of valor"
+ desc = "A silver medal awarded for acts of exceptional valor."
+
+/obj/item/clothing/accessory/medal/silver/security
+ name = "robust security award"
+ desc = "An award for distinguished combat and sacrifice in defence of Nanotrasen's commercial interests. Often awarded to security staff."
+
+/obj/item/clothing/accessory/medal/gold
+ name = "gold medal"
+ desc = "A prestigious golden medal."
+ icon_state = "gold"
+ item_color = "gold"
+
+/obj/item/clothing/accessory/medal/gold/captain
+ name = "medal of captaincy"
+ desc = "A golden medal awarded exclusively to those promoted to the rank of captain. It signifies the codified responsibilities of a captain to Nanotrasen, and their undisputable authority over their crew."
+
+/obj/item/clothing/accessory/medal/gold/heroism
+ name = "medal of exceptional heroism"
+ desc = "An extremely rare golden medal awarded only by CentComm. To recieve such a medal is the highest honor and as such, very few exist. This medal is almost never awarded to anybody but commanders."
+
+/*
+ Holobadges are worn on the belt or neck, and can be used to show that the holder is an authorized
+ Security agent - the user details can be imprinted on the badge with a Security-access ID card,
+ or they can be emagged to accept any ID for use in disguises.
+*/
+
+/obj/item/clothing/accessory/holobadge
+ name = "holobadge"
+ desc = "This glowing blue badge marks the holder as THE LAW."
+ icon_state = "holobadge"
+ item_color = "holobadge"
+ slot_flags = SLOT_BELT | SLOT_TIE
+
+ var/emagged = 0 //Emagging removes Sec check.
+ var/stored_name = null
+
+/obj/item/clothing/accessory/holobadge/cord
+ icon_state = "holobadge-cord"
+ item_color = "holobadge-cord"
+ slot_flags = SLOT_MASK | SLOT_TIE
+
+/obj/item/clothing/accessory/holobadge/attack_self(mob/user as mob)
+ if(!stored_name)
+ user << "Waving around a badge before swiping an ID would be pretty pointless."
+ return
+ if(isliving(user))
+ user.visible_message("\red [user] displays their NanoTrasen Internal Security Legal Authorization Badge.\nIt reads: [stored_name], NT Security.","\red You display your NanoTrasen Internal Security Legal Authorization Badge.\nIt reads: [stored_name], NT Security.")
+
+/obj/item/clothing/accessory/holobadge/attackby(var/obj/item/O as obj, var/mob/user as mob)
+
+ if (istype(O, /obj/item/weapon/card/emag))
+ if (emagged)
+ user << "\red [src] is already cracked."
+ return
+ else
+ emagged = 1
+ user << "\red You swipe [O] and crack the holobadge security checks."
+ return
+
+ else if(istype(O, /obj/item/weapon/card/id) || istype(O, /obj/item/device/pda))
+
+ var/obj/item/weapon/card/id/id_card = null
+
+ if(istype(O, /obj/item/weapon/card/id))
+ id_card = O
+ else
+ var/obj/item/device/pda/pda = O
+ id_card = pda.id
+
+ if(access_security in id_card.access || emagged)
+ user << "You imprint your ID details onto the badge."
+ stored_name = id_card.registered_name
+ name = "holobadge ([stored_name])"
+ desc = "This glowing blue badge marks [stored_name] as THE LAW."
+ else
+ user << "[src] rejects your insufficient access rights."
+ return
+ ..()
+
+/obj/item/clothing/accessory/holobadge/attack(mob/living/carbon/human/M, mob/living/user)
+ if(isliving(user))
+ user.visible_message("\red [user] invades [M]'s personal space, thrusting [src] into their face insistently.","\red You invade [M]'s personal space, thrusting [src] into their face insistently. You are the law.")
+
+/obj/item/weapon/storage/box/holobadge
+ name = "holobadge box"
+ desc = "A box claiming to contain holobadges."
+ New()
+ new /obj/item/clothing/accessory/holobadge(src)
+ new /obj/item/clothing/accessory/holobadge(src)
+ new /obj/item/clothing/accessory/holobadge(src)
+ new /obj/item/clothing/accessory/holobadge(src)
+ new /obj/item/clothing/accessory/holobadge/cord(src)
+ new /obj/item/clothing/accessory/holobadge/cord(src)
+ ..()
+ return
+
diff --git a/code/modules/clothing/under/accessories/armband.dm b/code/modules/clothing/under/accessories/armband.dm
new file mode 100644
index 00000000000..67d0208b6df
--- /dev/null
+++ b/code/modules/clothing/under/accessories/armband.dm
@@ -0,0 +1,42 @@
+/obj/item/clothing/accessory/armband
+ name = "red armband"
+ desc = "A fancy red armband!"
+ icon_state = "red"
+ item_color = "red"
+ slot = "armband"
+
+/obj/item/clothing/accessory/armband/cargo
+ name = "cargo armband"
+ desc = "An armband, worn by the crew to display which department they're assigned to. This one is brown."
+ icon_state = "cargo"
+ item_color = "cargo"
+
+/obj/item/clothing/accessory/armband/engine
+ name = "engineering armband"
+ desc = "An armband, worn by the crew to display which department they're assigned to. This one is orange with a reflective strip!"
+ icon_state = "engie"
+ item_color = "engie"
+
+/obj/item/clothing/accessory/armband/science
+ name = "science armband"
+ desc = "An armband, worn by the crew to display which department they're assigned to. This one is purple."
+ icon_state = "rnd"
+ item_color = "rnd"
+
+/obj/item/clothing/accessory/armband/hydro
+ name = "hydroponics armband"
+ desc = "An armband, worn by the crew to display which department they're assigned to. This one is green and blue."
+ icon_state = "hydro"
+ item_color = "hydro"
+
+/obj/item/clothing/accessory/armband/med
+ name = "medical armband"
+ desc = "An armband, worn by the crew to display which department they're assigned to. This one is white."
+ icon_state = "med"
+ item_color = "med"
+
+/obj/item/clothing/accessory/armband/medgreen
+ name = "EMT armband"
+ desc = "An armband, worn by the crew to display which department they're assigned to. This one is white and green."
+ icon_state = "medgreen"
+ item_color = "medgreen"
diff --git a/code/modules/clothing/under/accessories/holster.dm b/code/modules/clothing/under/accessories/holster.dm
new file mode 100644
index 00000000000..1a18604b6f4
--- /dev/null
+++ b/code/modules/clothing/under/accessories/holster.dm
@@ -0,0 +1,115 @@
+/obj/item/clothing/accessory/holster
+ name = "shoulder holster"
+ desc = "A handgun holster."
+ icon_state = "holster"
+ item_color = "holster"
+ slot = "utility"
+ var/obj/item/holstered = null
+
+/obj/item/clothing/accessory/holster/proc/holster(obj/item/I, mob/user as mob)
+ if(holstered)
+ user << "There is already \a [holstered] holstered here!"
+ return
+
+ if (!(I.slot_flags & SLOT_HOLSTER))
+ user << "[I] won't fit in [src]!"
+ return
+
+ holstered = I
+ user.drop_from_inventory(holstered)
+ holstered.loc = src
+ holstered.add_fingerprint(user)
+ user.visible_message("[user] holsters \the [holstered].", "You holster \the [holstered].")
+
+/obj/item/clothing/accessory/holster/proc/unholster(mob/user as mob)
+ if(!holstered)
+ return
+
+ if(istype(user.get_active_hand(),/obj) && istype(user.get_inactive_hand(),/obj))
+ user << "You need an empty hand to draw \the [holstered]!"
+ else
+ if(user.a_intent == "hurt")
+ usr.visible_message(
+ "\red [user] draws \the [holstered], ready to shoot!",
+ "You draw \the [holstered], ready to shoot!"
+ )
+ else
+ user.visible_message(
+ "[user] draws \the [holstered], pointing it at the ground.",
+ "You draw \the [holstered], pointing it at the ground."
+ )
+ user.put_in_hands(holstered)
+ holstered.add_fingerprint(user)
+ holstered = null
+
+/obj/item/clothing/accessory/holster/attack_hand(mob/user as mob)
+ if (has_suit) //if we are part of a suit
+ if (holstered)
+ unholster(user)
+ return
+
+ ..(user)
+
+/obj/item/clothing/accessory/holster/attackby(obj/item/W as obj, mob/user as mob)
+ holster(W, user)
+
+/obj/item/clothing/accessory/holster/emp_act(severity)
+ if (holstered)
+ holstered.emp_act(severity)
+ ..()
+
+/obj/item/clothing/accessory/holster/examine(mob/user)
+ ..(user)
+ if (holstered)
+ user << "A [holstered] is holstered here."
+ else
+ user << "It is empty."
+
+/obj/item/clothing/accessory/holster/on_attached(obj/item/clothing/under/S, mob/user as mob)
+ ..()
+ has_suit.verbs += /obj/item/clothing/accessory/holster/verb/holster_verb
+
+/obj/item/clothing/accessory/holster/on_removed(mob/user as mob)
+ has_suit.verbs -= /obj/item/clothing/accessory/holster/verb/holster_verb
+ ..()
+
+//For the holster hotkey
+/obj/item/clothing/accessory/holster/verb/holster_verb()
+ set name = "Holster"
+ set category = "Object"
+ set src in usr
+ if(!istype(usr, /mob/living)) return
+ if(usr.stat) return
+
+ //can't we just use src here?
+ var/obj/item/clothing/accessory/holster/H = null
+ if (istype(src, /obj/item/clothing/accessory/holster))
+ H = src
+ else if (istype(src, /obj/item/clothing/under))
+ var/obj/item/clothing/under/S = src
+ if (S.accessories.len)
+ H = locate() in S.accessories
+
+ if (!H)
+ usr << "Something is very wrong."
+
+ if(!H.holstered)
+ var/obj/item/W = usr.get_active_hand()
+ if(!istype(W, /obj/item))
+ usr << "You need your gun equiped to holster it."
+ return
+ H.holster(W, usr)
+ else
+ H.unholster(usr)
+
+/obj/item/clothing/accessory/holster/armpit
+ name = "shoulder holster"
+ desc = "A worn-out handgun holster. Perfect for concealed carry"
+ icon_state = "holster"
+ item_color = "holster"
+
+/obj/item/clothing/accessory/holster/waist
+ name = "shoulder holster"
+ desc = "A handgun holster. Made of expensive leather."
+ icon_state = "holster"
+ item_color = "holster_low"
\ No newline at end of file
diff --git a/code/modules/clothing/under/accessories/storage.dm b/code/modules/clothing/under/accessories/storage.dm
new file mode 100644
index 00000000000..32313e985d9
--- /dev/null
+++ b/code/modules/clothing/under/accessories/storage.dm
@@ -0,0 +1,86 @@
+/obj/item/clothing/accessory/storage
+ name = "load bearing equipment"
+ desc = "Used to hold things when you don't have enough hands."
+ icon_state = "webbing"
+ item_color = "webbing"
+ slot = "utility"
+ var/slots = 3
+ var/obj/item/weapon/storage/internal/hold
+
+/obj/item/clothing/accessory/storage/New()
+ ..()
+ hold = new/obj/item/weapon/storage/internal(src)
+ hold.storage_slots = slots
+
+/obj/item/clothing/accessory/storage/attack_hand(mob/user as mob)
+ if (has_suit) //if we are part of a suit
+ hold.open(user)
+ return
+
+ if (hold.handle_attack_hand(user)) //otherwise interact as a regular storage item
+ ..(user)
+
+/obj/item/clothing/accessory/storage/MouseDrop(obj/over_object as obj)
+ if (has_suit)
+ return
+
+ if (hold.handle_mousedrop(usr, over_object))
+ ..(over_object)
+
+/obj/item/clothing/accessory/storage/attackby(obj/item/W as obj, mob/user as mob)
+ return hold.attackby(W, user)
+
+/obj/item/clothing/accessory/storage/emp_act(severity)
+ hold.emp_act(severity)
+ ..()
+
+/obj/item/clothing/accessory/storage/hear_talk(mob/M, var/msg, verb, datum/language/speaking)
+ hold.hear_talk(M, msg, verb, speaking)
+ ..()
+
+/obj/item/clothing/accessory/storage/attack_self(mob/user as mob)
+ user << "You empty [src]."
+ var/turf/T = get_turf(src)
+ hold.hide_from(usr)
+ for(var/obj/item/I in hold.contents)
+ hold.remove_from_storage(I, T)
+ src.add_fingerprint(user)
+
+/obj/item/clothing/accessory/storage/webbing
+ name = "webbing"
+ desc = "Strudy mess of synthcotton belts and buckles, ready to share your burden."
+ icon_state = "webbing"
+ item_color = "webbing"
+
+/obj/item/clothing/accessory/storage/black_vest
+ name = "black webbing vest"
+ desc = "Robust black synthcotton vest with lots of pockets to hold whatever you need, but cannot hold in hands."
+ icon_state = "vest_black"
+ item_color = "vest_black"
+ slots = 5
+
+/obj/item/clothing/accessory/storage/brown_vest
+ name = "brown webbing vest"
+ desc = "Worn brownish synthcotton vest with lots of pockets to unload your hands."
+ icon_state = "vest_brown"
+ item_color = "vest_brown"
+ slots = 5
+
+/obj/item/clothing/accessory/storage/knifeharness
+ name = "decorated harness"
+ desc = "A heavily decorated harness of sinew and leather with two knife-loops."
+ icon_state = "unathiharness2"
+ item_color = "unathiharness2"
+ slots = 2
+
+/obj/item/clothing/accessory/storage/knifeharness/New()
+ ..()
+ hold.max_combined_w_class = 4
+ hold.can_hold = list("/obj/item/weapon/hatchet/unathiknife",\
+ "/obj/item/weapon/kitchen/utensil/knife",\
+ "/obj/item/weapon/kitchen/utensil/pknife",\
+ "/obj/item/weapon/kitchenknife",\
+ "/obj/item/weapon/kitchenknife/ritual")
+
+ new /obj/item/weapon/hatchet/unathiknife(hold)
+ new /obj/item/weapon/hatchet/unathiknife(hold)
\ No newline at end of file
diff --git a/code/modules/clothing/under/jobs/medsci.dm b/code/modules/clothing/under/jobs/medsci.dm
index 40bc087429d..b1554dd02ab 100644
--- a/code/modules/clothing/under/jobs/medsci.dm
+++ b/code/modules/clothing/under/jobs/medsci.dm
@@ -130,6 +130,12 @@
icon_state = "scrubspurple"
item_color = "scrubspurple"
+/obj/item/clothing/under/rank/medical/black
+ name = "medical scrubs"
+ desc = "It's made of a special fiber that provides minor protection against biohazards. This one is in black."
+ icon_state = "scrubsblack"
+ item_color = "scrubsblack"
+
/obj/item/clothing/under/rank/psych
desc = "A basic white jumpsuit. It has turqouise markings that denote the wearer as a psychiatrist."
name = "psychiatrist's jumpsuit"
diff --git a/code/modules/clothing/under/miscellaneous.dm b/code/modules/clothing/under/miscellaneous.dm
index 390ec7f5417..bc4d37c672f 100644
--- a/code/modules/clothing/under/miscellaneous.dm
+++ b/code/modules/clothing/under/miscellaneous.dm
@@ -479,9 +479,9 @@
/obj/item/clothing/under/serviceoveralls
name = "Workman outfit"
desc = "The very image of a working man. Not that you're probably doing work."
- icon_state = "mechanic_s"
- item_state = "mechanic_s"
- item_color = "mechanic_s"
+ icon_state = "mechanic"
+ item_state = "mechanic"
+ item_color = "mechanic"
/obj/item/clothing/under/cheongsam
name = "White Cheongsam"
diff --git a/code/modules/clothing/under/ties.dm b/code/modules/clothing/under/ties.dm
deleted file mode 100644
index 073b7a37576..00000000000
--- a/code/modules/clothing/under/ties.dm
+++ /dev/null
@@ -1,470 +0,0 @@
-/obj/item/clothing/tie
- name = "tie"
- desc = "A neosilk clip-on tie."
- icon = 'icons/obj/clothing/ties.dmi'
- icon_state = "bluetie"
- item_state = "" //no inhands
- item_color = "bluetie"
- slot_flags = SLOT_TIE
- w_class = 2.0
- var/obj/item/clothing/under/has_suit = null //the suit the tie may be attached to
- var/image/inv_overlay = null //overlay used when attached to clothing.
-
-/obj/item/clothing/tie/New()
- ..()
- inv_overlay = image("icon" = 'icons/obj/clothing/ties_overlay.dmi', "icon_state" = "[item_color? "[item_color]" : "[icon_state]"]")
-
-//when user attached an accessory to S
-/obj/item/clothing/tie/proc/on_attached(obj/item/clothing/under/S, mob/user as mob)
- if(!istype(S))
- return
- has_suit = S
- loc = has_suit
- has_suit.overlays += inv_overlay
-
- user << "You attach [src] to [has_suit]."
- src.add_fingerprint(user)
-
-/obj/item/clothing/tie/proc/on_removed(mob/user as mob)
- if(!has_suit)
- return
- has_suit.overlays -= inv_overlay
- has_suit = null
- usr.put_in_hands(src)
- src.add_fingerprint(user)
-
-//default attackby behaviour
-/obj/item/clothing/tie/attackby(obj/item/I, mob/user)
- ..()
-
-//default attack_hand behaviour
-/obj/item/clothing/tie/attack_hand(mob/user as mob)
- if(has_suit)
- has_suit.remove_accessory(user)
- return //we aren't an object on the ground so don't call parent
- ..()
-
-/obj/item/clothing/tie/blue
- name = "blue tie"
- icon_state = "bluetie"
- item_color = "bluetie"
-
-/obj/item/clothing/tie/red
- name = "red tie"
- icon_state = "redtie"
- item_color = "redtie"
-
-/obj/item/clothing/tie/horrible
- name = "horrible tie"
- desc = "A neosilk clip-on tie. This one is disgusting."
- icon_state = "horribletie"
- item_color = "horribletie"
-
-/obj/item/clothing/tie/stethoscope
- name = "stethoscope"
- desc = "An outdated medical apparatus for listening to the sounds of the human body. It also makes you look like you know what you're doing."
- icon_state = "stethoscope"
- item_color = "stethoscope"
-
-/obj/item/clothing/tie/stethoscope/attack(mob/living/carbon/human/M, mob/living/user)
- if(ishuman(M) && isliving(user))
- if(user.a_intent == "help")
- var/body_part = parse_zone(user.zone_sel.selecting)
- if(body_part)
- var/their = "their"
- switch(M.gender)
- if(MALE) their = "his"
- if(FEMALE) their = "her"
-
- var/sound = "pulse"
- var/sound_strength
-
- if(M.stat == DEAD || (M.status_flags&FAKEDEATH))
- sound_strength = "cannot hear"
- sound = "anything"
- else
- sound_strength = "hear a weak"
- switch(body_part)
- if("chest")
- if(M.oxyloss < 50)
- sound_strength = "hear a healthy"
- sound = "pulse and respiration"
- if("eyes","mouth")
- sound_strength = "cannot hear"
- sound = "anything"
- else
- sound_strength = "hear a weak"
-
- user.visible_message("[user] places [src] against [M]'s [body_part] and listens attentively.", "You place [src] against [their] [body_part]. You [sound_strength] [sound].")
- return
- return ..(M,user)
-
-
-//Medals
-/obj/item/clothing/tie/medal
- name = "bronze medal"
- desc = "A bronze medal."
- icon_state = "bronze"
- item_color = "bronze"
-
-/obj/item/clothing/tie/medal/conduct
- name = "distinguished conduct medal"
- desc = "A bronze medal awarded for distinguished conduct. Whilst a great honor, this is most basic award given by Nanotrasen. It is often awarded by a captain to a member of his crew."
-
-/obj/item/clothing/tie/medal/bronze_heart
- name = "bronze heart medal"
- desc = "A bronze heart-shaped medal awarded for sacrifice. It is often awarded posthumously or for severe injury in the line of duty."
- icon_state = "bronze_heart"
-
-/obj/item/clothing/tie/medal/nobel_science
- name = "nobel sciences award"
- desc = "A bronze medal which represents significant contributions to the field of science or engineering."
-
-/obj/item/clothing/tie/medal/silver
- name = "silver medal"
- desc = "A silver medal."
- icon_state = "silver"
- item_color = "silver"
-
-/obj/item/clothing/tie/medal/silver/valor
- name = "medal of valor"
- desc = "A silver medal awarded for acts of exceptional valor."
-
-/obj/item/clothing/tie/medal/silver/security
- name = "robust security award"
- desc = "An award for distinguished combat and sacrifice in defence of Nanotrasen's commercial interests. Often awarded to security staff."
-
-/obj/item/clothing/tie/medal/gold
- name = "gold medal"
- desc = "A prestigious golden medal."
- icon_state = "gold"
- item_color = "gold"
-
-/obj/item/clothing/tie/medal/gold/captain
- name = "medal of captaincy"
- desc = "A golden medal awarded exclusively to those promoted to the rank of captain. It signifies the codified responsibilities of a captain to Nanotrasen, and their undisputable authority over their crew."
-
-/obj/item/clothing/tie/medal/gold/heroism
- name = "medal of exceptional heroism"
- desc = "An extremely rare golden medal awarded only by CentComm. To recieve such a medal is the highest honor and as such, very few exist. This medal is almost never awarded to anybody but commanders."
-
-//Armbands
-/obj/item/clothing/tie/armband
- name = "red armband"
- desc = "A fancy red armband!"
- icon_state = "red"
- item_color = "red"
-
-/obj/item/clothing/tie/armband/cargo
- name = "cargo armband"
- desc = "An armband, worn by the crew to display which department they're assigned to. This one is brown."
- icon_state = "cargo"
- item_color = "cargo"
-
-/obj/item/clothing/tie/armband/engine
- name = "engineering armband"
- desc = "An armband, worn by the crew to display which department they're assigned to. This one is orange with a reflective strip!"
- icon_state = "engie"
- item_color = "engie"
-
-/obj/item/clothing/tie/armband/science
- name = "science armband"
- desc = "An armband, worn by the crew to display which department they're assigned to. This one is purple."
- icon_state = "rnd"
- item_color = "rnd"
-
-/obj/item/clothing/tie/armband/hydro
- name = "hydroponics armband"
- desc = "An armband, worn by the crew to display which department they're assigned to. This one is green and blue."
- icon_state = "hydro"
- item_color = "hydro"
-
-/obj/item/clothing/tie/armband/med
- name = "medical armband"
- desc = "An armband, worn by the crew to display which department they're assigned to. This one is white."
- icon_state = "med"
- item_color = "med"
-
-/obj/item/clothing/tie/armband/medgreen
- name = "EMT armband"
- desc = "An armband, worn by the crew to display which department they're assigned to. This one is white and green."
- icon_state = "medgreen"
- item_color = "medgreen"
-
-//holsters
-/obj/item/clothing/tie/holster
- name = "shoulder holster"
- desc = "A handgun holster."
- icon_state = "holster"
- item_color = "holster"
- var/obj/item/holstered = null
-
-/obj/item/clothing/tie/holster/proc/holster(obj/item/I, mob/user as mob)
- if(holstered)
- user << "There is already \a [holstered] holstered here!"
- return
-
- if (!(I.slot_flags & SLOT_HOLSTER))
- user << "[I] won't fit in [src]!"
- return
-
- holstered = I
- user.drop_from_inventory(holstered)
- holstered.loc = src
- holstered.add_fingerprint(user)
- user.visible_message("[user] holsters [holstered].", "You holster [holstered].")
-
-/obj/item/clothing/tie/holster/proc/unholster(mob/user as mob)
- if(!holstered)
- return
-
- if(istype(user.get_active_hand(),/obj) && istype(user.get_inactive_hand(),/obj))
- user << "You need an empty hand to draw [holstered]!"
- else
- if(user.a_intent == "hurt")
- usr.visible_message(
- "[user] draws [holstered], ready to shoot!",
- "You draw [holstered], ready to shoot!"
- )
- else
- user.visible_message(
- "[user] draws [holstered], pointing it at the ground.",
- "You draw [holstered], pointing it at the ground."
- )
- user.put_in_hands(holstered)
- holstered.add_fingerprint(user)
- holstered = null
-
-/obj/item/clothing/tie/holster/attack_hand(mob/user as mob)
- if (has_suit) //if we are part of a suit
- if (holstered)
- unholster(user)
- return
-
- ..(user)
-
-/obj/item/clothing/tie/holster/attackby(obj/item/W as obj, mob/user as mob)
- holster(W, user)
-
-/obj/item/clothing/tie/holster/emp_act(severity)
- if (holstered)
- holstered.emp_act(severity)
- ..()
-
-/obj/item/clothing/tie/holster/examine(mob/user)
- ..(user)
- if (holstered)
- user << "A [holstered] is holstered here."
- else
- user << "It is empty."
-
-/obj/item/clothing/tie/holster/on_attached(obj/item/clothing/under/S, mob/user as mob)
- ..()
- has_suit.verbs += /obj/item/clothing/tie/holster/verb/holster_verb
-
-/obj/item/clothing/tie/holster/on_removed(mob/user as mob)
- has_suit.verbs -= /obj/item/clothing/tie/holster/verb/holster_verb
- ..()
-
-//For the holster hotkey
-/obj/item/clothing/tie/holster/verb/holster_verb()
- set name = "Holster"
- set category = "Object"
- set src in usr
- if(!istype(usr, /mob/living)) return
- if(usr.stat) return
-
- //can't we just use src here?
- var/obj/item/clothing/tie/holster/H = null
- if (istype(src, /obj/item/clothing/tie/holster))
- H = src
- else if (istype(src, /obj/item/clothing/under))
- var/obj/item/clothing/under/S = src
- if (S.hastie)
- H = S.hastie
-
- if (!H)
- usr << "\red Something is very wrong."
-
- if(!H.holstered)
- var/obj/item/W = usr.get_active_hand()
- if(!istype(W, /obj/item))
- usr << "\blue You need your gun equiped to holster it."
- return
- H.holster(W, usr)
- else
- H.unholster(usr)
-
-/obj/item/clothing/tie/holster/armpit
- name = "shoulder holster"
- desc = "A worn-out handgun holster. Perfect for concealed carrying."
- icon_state = "holster"
- item_color = "holster"
-
-/obj/item/clothing/tie/holster/waist
- name = "shoulder holster"
- desc = "A handgun holster. Made of expensive leather."
- icon_state = "holster"
- item_color = "holster_low"
-
-/obj/item/clothing/tie/storage
- name = "load bearing equipment"
- desc = "Used to hold things when you don't have enough hands."
- icon_state = "webbing"
- item_color = "webbing"
- var/slots = 3
- var/obj/item/weapon/storage/internal/hold
-
-/obj/item/clothing/tie/storage/New()
- ..()
- hold = new/obj/item/weapon/storage/internal(src)
- hold.storage_slots = slots
-
-/obj/item/clothing/tie/storage/attack_hand(mob/user as mob)
- if (has_suit) //if we are part of a suit
- hold.open(user)
- return
-
- if (hold.handle_attack_hand(user)) //otherwise interact as a regular storage item
- ..(user)
-
-/obj/item/clothing/tie/storage/MouseDrop(obj/over_object as obj)
- if (has_suit)
- return
-
- if (hold.handle_mousedrop(usr, over_object))
- ..(over_object)
-
-/obj/item/clothing/tie/storage/attackby(obj/item/W as obj, mob/user as mob)
- return hold.attackby(W, user)
-
-/obj/item/clothing/tie/storage/emp_act(severity)
- hold.emp_act(severity)
- ..()
-
-/obj/item/clothing/tie/storage/hear_talk(mob/M, var/msg, verb, datum/language/speaking)
- hold.hear_talk(M, msg, verb, speaking)
- ..()
-
-/obj/item/clothing/tie/storage/attack_self(mob/user as mob)
- user << "You empty [src]."
- var/turf/T = get_turf(src)
- hold.hide_from(usr)
- for(var/obj/item/I in hold.contents)
- hold.remove_from_storage(I, T)
- src.add_fingerprint(user)
-
-/obj/item/clothing/tie/storage/webbing
- name = "webbing"
- desc = "Strudy mess of synthcotton belts and buckles, ready to share your burden."
- icon_state = "webbing"
- item_color = "webbing"
-
-/obj/item/clothing/tie/storage/black_vest
- name = "black webbing vest"
- desc = "Robust black synthcotton vest with lots of pockets to hold whatever you need, but cannot hold in hands."
- icon_state = "vest_black"
- item_color = "vest_black"
- slots = 5
-
-/obj/item/clothing/tie/storage/brown_vest
- name = "brown webbing vest"
- desc = "Worn brownish synthcotton vest with lots of pockets to unload your hands."
- icon_state = "vest_brown"
- item_color = "vest_brown"
- slots = 5
-/*
- Holobadges are worn on the belt or neck, and can be used to show that the holder is an authorized
- Security agent - the user details can be imprinted on the badge with a Security-access ID card,
- or they can be emagged to accept any ID for use in disguises.
-*/
-
-/obj/item/clothing/tie/holobadge
-
- name = "holobadge"
- desc = "This glowing blue badge marks the holder as THE LAW."
- icon_state = "holobadge"
- item_color = "holobadge"
- slot_flags = SLOT_BELT | SLOT_TIE
-
- var/emagged = 0 //Emagging removes Sec check.
- var/stored_name = null
-
-/obj/item/clothing/tie/holobadge/cord
- icon_state = "holobadge-cord"
- item_color = "holobadge-cord"
- slot_flags = SLOT_MASK | SLOT_TIE
-
-/obj/item/clothing/tie/holobadge/attack_self(mob/user as mob)
- if(!stored_name)
- user << "Waving around a badge before swiping an ID would be pretty pointless."
- return
- if(isliving(user))
- user.visible_message("\red [user] displays their NanoTrasen Internal Security Legal Authorization Badge.\nIt reads: [stored_name], NT Security.","\red You display your NanoTrasen Internal Security Legal Authorization Badge.\nIt reads: [stored_name], NT Security.")
-
-/obj/item/clothing/tie/holobadge/attackby(var/obj/item/O as obj, var/mob/user as mob)
-
- if (istype(O, /obj/item/weapon/card/emag))
- if (emagged)
- user << "\red [src] is already cracked."
- return
- else
- emagged = 1
- user << "\red You swipe [O] and crack the holobadge security checks."
- return
-
- else if(istype(O, /obj/item/weapon/card/id) || istype(O, /obj/item/device/pda))
-
- var/obj/item/weapon/card/id/id_card = null
-
- if(istype(O, /obj/item/weapon/card/id))
- id_card = O
- else
- var/obj/item/device/pda/pda = O
- id_card = pda.id
-
- if(access_security in id_card.access || emagged)
- user << "You imprint your ID details onto the badge."
- stored_name = id_card.registered_name
- name = "holobadge ([stored_name])"
- desc = "This glowing blue badge marks [stored_name] as THE LAW."
- else
- user << "[src] rejects your insufficient access rights."
- return
- ..()
-
-/obj/item/clothing/tie/holobadge/attack(mob/living/carbon/human/M, mob/living/user)
- if(isliving(user))
- user.visible_message("\red [user] invades [M]'s personal space, thrusting [src] into their face insistently.","\red You invade [M]'s personal space, thrusting [src] into their face insistently. You are the law.")
-
-/obj/item/weapon/storage/box/holobadge
- name = "holobadge box"
- desc = "A box claiming to contain holobadges."
- New()
- new /obj/item/clothing/tie/holobadge(src)
- new /obj/item/clothing/tie/holobadge(src)
- new /obj/item/clothing/tie/holobadge(src)
- new /obj/item/clothing/tie/holobadge(src)
- new /obj/item/clothing/tie/holobadge/cord(src)
- new /obj/item/clothing/tie/holobadge/cord(src)
- ..()
- return
-
-/obj/item/clothing/tie/storage/knifeharness
- name = "decorated harness"
- desc = "A heavily decorated harness of sinew and leather with two knife-loops."
- icon_state = "unathiharness2"
- item_color = "unathiharness2"
- slots = 2
-
-/obj/item/clothing/tie/storage/knifeharness/New()
- ..()
- hold.max_combined_w_class = 4
- hold.can_hold = list("/obj/item/weapon/hatchet/unathiknife",\
- "/obj/item/weapon/kitchen/utensil/knife",\
- "/obj/item/weapon/kitchen/utensil/pknife",\
- "/obj/item/weapon/kitchenknife",\
- "/obj/item/weapon/kitchenknife/ritual")
-
- new /obj/item/weapon/hatchet/unathiknife(hold)
- new /obj/item/weapon/hatchet/unathiknife(hold)
diff --git a/code/modules/customitems/item_defines.dm b/code/modules/customitems/item_defines.dm
index 510417c0fb9..11a3fa03d48 100644
--- a/code/modules/customitems/item_defines.dm
+++ b/code/modules/customitems/item_defines.dm
@@ -114,7 +114,7 @@
/////////////////////// Cataguettes - Lucy's Stethoscope - Lucy Kemmerer //////
-/obj/item/clothing/tie/stethoscope/fluff/lucystethos
+/obj/item/clothing/accessory/stethoscope/fluff/lucystethos
name = "Lucy's Stethoscope"
desc = "A medical apparatus intended to ease in listening to the sounds of the human body. This one looks cleaner and sparklier than the rest. There is a small silver plaque attached to the tubing, with the words 'Lucy Kemmerer' engraved on it."
icon_state = "lucystethos"
@@ -1111,22 +1111,33 @@
item_color = "lillian_dress"
body_parts_covered = UPPER_TORSO|LOWER_TORSO
-////// Cybernetic Casings - Parker Eliza - MrSnapwalk
+////// Tailored Security Uniform - Parker Eliza - MrSnapwalk
+
/obj/item/clothing/under/fluff/parkereliza
- name = "cybernetic casings"
- desc = "A set of somewhat bulky white casings for robotic limbs, paired with a basic blue tank top and black cargo pants. The arms have a small label on the inner elbow, which reads \"Bishop Corporation Cybernetic Solutions\"."
+ name = "tailored security uniform"
+ desc = "A red uniform shirt (tailored for easy access to the shoulder joint) and black cargo pants, paired with a set of somewhat bulky white casings for robotic limbs. The arms have a small label on the inner elbow, which reads \"Bishop Corporation Cybernetic Solutions\"."
icon = 'icons/obj/custom_items.dmi'
icon_state = "parker_eliza"
item_state = "parker_eliza"
item_color = "parker_eliza"
body_parts_covered = UPPER_TORSO|LOWER_TORSO|LEGS|ARMS|HANDS
+////// Bishop "GOLEM" V2200 Industrial Limb Augments - Parker Eliza - MrSnapwalk
+
+/obj/item/clothing/suit/fluff/parkereliza
+ name = "Bishop \"GOLEM\" V2200 Industrial Limb Augments"
+ desc = "A set of top-of-the-line cyberlimbs, only usable to someone with extensive bone structure augmentation. Often used in industrial applications, they are capable of throwing a man clear across a room. The load limitation circuit in this set appears to be modified."
+ icon = 'icons/obj/custom_items.dmi'
+ icon_state = "parker_eliza_arms"
+ item_state = "parker_eliza_arms"
+ item_color = "parker_eliza_arms"
+
////////////// Accessories /////
//////////////////// Blood Red Pendant - Mewth - Mu'taz Radi ////////////////
-/obj/item/clothing/tie/fluff/radi
+/obj/item/clothing/accessory/fluff/radi
name = "Blood Red Pendant"
desc = "A blue chained necklace with a ruby in the middle, it looks pretty!"
icon = 'icons/obj/custom_items.dmi'
@@ -1168,7 +1179,7 @@
////// Small locket - Altair An-Nasaqan - Serithi
-/obj/item/clothing/tie/fluff/altair_locket
+/obj/item/clothing/accessory/fluff/altair_locket
name = "small locket"
desc = "A small golden locket attached to an Ii'rka-reed string. Inside the locket is a holo-picture of a female Tajaran, and an inscription writtin in Siik'mas."
icon = 'icons/obj/custom_items.dmi'
@@ -1181,7 +1192,7 @@
////// Silver locket - Konaa Hirano - Konaa_Hirano
-/obj/item/clothing/tie/fluff/konaa_hirano
+/obj/item/clothing/accessory/fluff/konaa_hirano
name = "silver locket"
desc = "This oval shaped, argentium sterling silver locket hangs on an incredibly fine, refractive string, almost thin as hair and microweaved from links to a deceptive strength, of similar material. The edges are engraved very delicately with an elegant curving design, but overall the main is unmarked and smooth to the touch, leaving room for either remaining as a stolid piece or future alterations. There is an obvious internal place for a picture or lock of some sort, but even behind that is a very thin compartment unhinged with the pinch of a thumb and forefinger."
icon = 'icons/obj/custom_items.dmi'
@@ -1193,13 +1204,13 @@
slot_flags = SLOT_MASK | SLOT_TIE
var/obj/item/held //Item inside locket.
-/obj/item/clothing/tie/fluff/konaa_hirano/attack_self(mob/user as mob)
+/obj/item/clothing/accessory/fluff/konaa_hirano/attack_self(mob/user as mob)
if(held)
user << "You open [src] and [held] falls out."
held.loc = get_turf(user)
src.held = null
-/obj/item/clothing/tie/fluff/konaa_hirano/attackby(var/obj/item/O as obj, mob/user as mob)
+/obj/item/clothing/accessory/fluff/konaa_hirano/attackby(var/obj/item/O as obj, mob/user as mob)
if(istype(O,/obj/item/weapon/paper))
if(held)
usr << "[src] already has something inside it."
@@ -1213,7 +1224,7 @@
////// Medallion - Nasir Khayyam - Jamini
-/obj/item/clothing/tie/fluff/nasir_khayyam_1
+/obj/item/clothing/accessory/fluff/nasir_khayyam_1
name = "medallion"
desc = "This silvered medallion bears the symbol of the Hadii Clan of the Tajaran."
icon = 'icons/obj/custom_items.dmi'
diff --git a/code/modules/hydroponics/biogenerator.dm b/code/modules/hydroponics/biogenerator.dm
index 263f797a95d..4afd4f0e44b 100644
--- a/code/modules/hydroponics/biogenerator.dm
+++ b/code/modules/hydroponics/biogenerator.dm
@@ -11,66 +11,80 @@
var/obj/item/weapon/reagent_containers/glass/beaker = null
var/points = 0
var/menustat = "menu"
+ var/build_eff = 1
+ var/eat_eff = 1
- New()
- ..()
- var/datum/reagents/R = new/datum/reagents(1000)
- reagents = R
- R.my_atom = src
- beaker = new /obj/item/weapon/reagent_containers/glass/beaker/large(src)
+/obj/machinery/biogenerator/New()
+ ..()
+ var/datum/reagents/R = new/datum/reagents(1000)
+ reagents = R
+ R.my_atom = src
+ beaker = new /obj/item/weapon/reagent_containers/glass/bottle(src)
- on_reagent_change() //When the reagents change, change the icon as well.
- update_icon()
+ component_parts = list()
+ component_parts += new /obj/item/weapon/circuitboard/biogenerator(src)
+ component_parts += new /obj/item/weapon/stock_parts/matter_bin(src)
+ component_parts += new /obj/item/weapon/stock_parts/manipulator(src)
+ RefreshParts()
+
+/obj/machinery/biogenerator/on_reagent_change() //When the reagents change, change the icon as well.
update_icon()
- if(!src.beaker)
- icon_state = "biogen-empty"
- else if(!src.processing)
- icon_state = "biogen-stand"
- else
- icon_state = "biogen-work"
- return
+
+/obj/machinery/biogenerator/update_icon()
+ if(!beaker)
+ icon_state = "biogen-empty"
+ else if(!processing)
+ icon_state = "biogen-stand"
+ else
+ icon_state = "biogen-work"
+ return
/obj/machinery/biogenerator/attackby(var/obj/item/O as obj, var/mob/user as mob)
+ if(default_deconstruction_screwdriver(user, O))
+ return
+ if(default_deconstruction_crowbar(user, O))
+ return
+ if(default_part_replacement(user, O))
+ return
if(istype(O, /obj/item/weapon/reagent_containers/glass))
if(beaker)
- user << "\red The biogenerator is already loaded."
+ user << "]The [src] is already loaded."
else
user.before_take_item(O)
O.loc = src
beaker = O
updateUsrDialog()
else if(processing)
- user << "\red The biogenerator is currently processing."
+ user << "\The [src] is currently processing."
else if(istype(O, /obj/item/weapon/storage/bag/plants))
var/i = 0
for(var/obj/item/weapon/reagent_containers/food/snacks/grown/G in contents)
i++
if(i >= 10)
- user << "\red The biogenerator is already full! Activate it."
+ user << "\The [src] is already full! Activate it."
else
for(var/obj/item/weapon/reagent_containers/food/snacks/grown/G in O.contents)
G.loc = src
i++
if(i >= 10)
- user << "\blue You fill the biogenerator to its capacity."
+ user << "You fill \the [src] to its capacity."
break
- if(i<10)
- user << "\blue You empty the plant bag into the biogenerator."
-
+ if(i < 10)
+ user << "You empty \the [O] into \the [src]."
else if(!istype(O, /obj/item/weapon/reagent_containers/food/snacks/grown))
- user << "\red You cannot put this in [src.name]"
+ user << "You cannot put this in \the [src]."
else
var/i = 0
for(var/obj/item/weapon/reagent_containers/food/snacks/grown/G in contents)
i++
if(i >= 10)
- user << "\red The biogenerator is full! Activate it."
+ user << "\The [src] is full! Activate it."
else
user.before_take_item(O)
O.loc = src
- user << "\blue You put [O.name] in [src.name]"
+ user << "You put \the [O] in \the [src]"
update_icon()
return
@@ -89,18 +103,18 @@
dat += "Activate Biogenerator!
"
dat += "Detach Container
"
dat += "Food
"
- dat += "10 milk (20)
"
- dat += "Slab of meat (50)
"
+ dat += "10 milk ([round(20/build_eff)])
"
+ dat += "Slab of meat ([round(50/build_eff)])
"
dat += "Nutrient
"
- dat += "E-Z-Nutrient (10) | x5
"
- dat += "Left 4 Zed (20) | x5
"
- dat += "Robust Harvest (25) | x5
"
+ dat += "E-Z-Nutrient ([round(10/build_eff)]) | x5
"
+ dat += "Left 4 Zed ([round(20/build_eff)]) | x5
"
+ dat += "Robust Harvest ([round(25/build_eff)]) | x5
"
dat += "Leather
"
- dat += "Wallet (100)
"
- dat += "Botanical gloves (250)
"
- dat += "Utility belt (300)
"
- dat += "Leather Satchel (400)
"
- dat += "Cash Bag (400)
"
+ dat += "Wallet ([round(100/build_eff)])
"
+ dat += "Botanical gloves ([round(250/build_eff)])
"
+ dat += "Utility belt ([round(300/build_eff)])
"
+ dat += "Leather Satchel ([round(400/build_eff)])
"
+ dat += "Cash Bag ([round(400/build_eff)])
"
//dat += "Other
"
//dat += "Monkey (500)
"
else
@@ -122,34 +136,35 @@
interact(user)
/obj/machinery/biogenerator/proc/activate()
- if (usr.stat != 0)
+ if (usr.stat)
return
- if (src.stat != 0) //NOPOWER etc
+ if (stat) //NOPOWER etc
return
- if(src.processing)
- usr << "\red The biogenerator is in the process of working."
+ if(processing)
+ usr << "The biogenerator is in the process of working."
return
var/S = 0
for(var/obj/item/weapon/reagent_containers/food/snacks/grown/I in contents)
S += 5
if(I.reagents.get_reagent_amount("nutriment") < 0.1)
points += 1
- else points += I.reagents.get_reagent_amount("nutriment")*10
+ else points += I.reagents.get_reagent_amount("nutriment") * 10 * eat_eff
del(I)
if(S)
processing = 1
update_icon()
updateUsrDialog()
playsound(src.loc, 'sound/machines/blender.ogg', 50, 1)
- use_power(S*30)
- sleep(S+15)
+ use_power(S * 30)
+ sleep((S + 15) / eat_eff)
processing = 0
update_icon()
else
menustat = "void"
return
-/obj/machinery/biogenerator/proc/create_product(var/item,var/cost)
+/obj/machinery/biogenerator/proc/create_product(var/item, var/cost)
+ cost = round(cost/build_eff)
if(cost > points)
menustat = "nopoints"
return 0
@@ -160,45 +175,45 @@
sleep(30)
switch(item)
if("milk")
- beaker.reagents.add_reagent("milk",10)
+ beaker.reagents.add_reagent("milk", 10)
if("meat")
- new/obj/item/weapon/reagent_containers/food/snacks/meat(src.loc)
+ new/obj/item/weapon/reagent_containers/food/snacks/meat(loc)
if("ez")
- new/obj/item/weapon/reagent_containers/glass/fertilizer/ez(src.loc)
+ new/obj/item/weapon/reagent_containers/glass/fertilizer/ez(loc)
if("l4z")
- new/obj/item/weapon/reagent_containers/glass/fertilizer/l4z(src.loc)
+ new/obj/item/weapon/reagent_containers/glass/fertilizer/l4z(loc)
if("rh")
- new/obj/item/weapon/reagent_containers/glass/fertilizer/rh(src.loc)
+ new/obj/item/weapon/reagent_containers/glass/fertilizer/rh(loc)
if("ez5") //It's not an elegant method, but it's safe and easy. -Cheridan
- new/obj/item/weapon/reagent_containers/glass/fertilizer/ez(src.loc)
- new/obj/item/weapon/reagent_containers/glass/fertilizer/ez(src.loc)
- new/obj/item/weapon/reagent_containers/glass/fertilizer/ez(src.loc)
- new/obj/item/weapon/reagent_containers/glass/fertilizer/ez(src.loc)
- new/obj/item/weapon/reagent_containers/glass/fertilizer/ez(src.loc)
+ new/obj/item/weapon/reagent_containers/glass/fertilizer/ez(loc)
+ new/obj/item/weapon/reagent_containers/glass/fertilizer/ez(loc)
+ new/obj/item/weapon/reagent_containers/glass/fertilizer/ez(loc)
+ new/obj/item/weapon/reagent_containers/glass/fertilizer/ez(loc)
+ new/obj/item/weapon/reagent_containers/glass/fertilizer/ez(loc)
if("l4z5")
- new/obj/item/weapon/reagent_containers/glass/fertilizer/l4z(src.loc)
- new/obj/item/weapon/reagent_containers/glass/fertilizer/l4z(src.loc)
- new/obj/item/weapon/reagent_containers/glass/fertilizer/l4z(src.loc)
- new/obj/item/weapon/reagent_containers/glass/fertilizer/l4z(src.loc)
- new/obj/item/weapon/reagent_containers/glass/fertilizer/l4z(src.loc)
+ new/obj/item/weapon/reagent_containers/glass/fertilizer/l4z(loc)
+ new/obj/item/weapon/reagent_containers/glass/fertilizer/l4z(loc)
+ new/obj/item/weapon/reagent_containers/glass/fertilizer/l4z(loc)
+ new/obj/item/weapon/reagent_containers/glass/fertilizer/l4z(loc)
+ new/obj/item/weapon/reagent_containers/glass/fertilizer/l4z(loc)
if("rh5")
- new/obj/item/weapon/reagent_containers/glass/fertilizer/rh(src.loc)
- new/obj/item/weapon/reagent_containers/glass/fertilizer/rh(src.loc)
- new/obj/item/weapon/reagent_containers/glass/fertilizer/rh(src.loc)
- new/obj/item/weapon/reagent_containers/glass/fertilizer/rh(src.loc)
- new/obj/item/weapon/reagent_containers/glass/fertilizer/rh(src.loc)
+ new/obj/item/weapon/reagent_containers/glass/fertilizer/rh(loc)
+ new/obj/item/weapon/reagent_containers/glass/fertilizer/rh(loc)
+ new/obj/item/weapon/reagent_containers/glass/fertilizer/rh(loc)
+ new/obj/item/weapon/reagent_containers/glass/fertilizer/rh(loc)
+ new/obj/item/weapon/reagent_containers/glass/fertilizer/rh(loc)
if("wallet")
- new/obj/item/weapon/storage/wallet(src.loc)
+ new/obj/item/weapon/storage/wallet(loc)
if("gloves")
- new/obj/item/clothing/gloves/botanic_leather(src.loc)
+ new/obj/item/clothing/gloves/botanic_leather(loc)
if("tbelt")
- new/obj/item/weapon/storage/belt/utility(src.loc)
+ new/obj/item/weapon/storage/belt/utility(loc)
if("satchel")
- new/obj/item/weapon/storage/backpack/satchel(src.loc)
+ new/obj/item/weapon/storage/backpack/satchel(loc)
if("cashbag")
- new/obj/item/weapon/storage/bag/cash(src.loc)
+ new/obj/item/weapon/storage/bag/cash(loc)
if("monkey")
- new/mob/living/carbon/monkey(src.loc)
+ new/mob/living/carbon/monkey(loc)
processing = 0
menustat = "complete"
update_icon()
@@ -220,7 +235,21 @@
beaker = null
update_icon()
if("create")
- create_product(href_list["item"],text2num(href_list["cost"]))
+ create_product(href_list["item"], text2num(href_list["cost"]))
if("menu")
menustat = "menu"
updateUsrDialog()
+
+/obj/machinery/biogenerator/RefreshParts()
+ ..()
+ var/man_rating = 0
+ var/bin_rating = 0
+
+ for(var/obj/item/weapon/stock_parts/P in component_parts)
+ if(istype(P, /obj/item/weapon/stock_parts/matter_bin))
+ bin_rating += P.rating
+ if(istype(P, /obj/item/weapon/stock_parts/manipulator))
+ man_rating += P.rating
+
+ build_eff = man_rating
+ eat_eff = bin_rating
diff --git a/code/modules/mining/abandonedcrates.dm b/code/modules/mining/abandonedcrates.dm
index c5f4c2d2dd4..c26c2eb9cd6 100644
--- a/code/modules/mining/abandonedcrates.dm
+++ b/code/modules/mining/abandonedcrates.dm
@@ -13,13 +13,13 @@
/obj/structure/closet/crate/secure/loot/New()
..()
var/list/digits = list("1", "2", "3", "4", "5", "6", "7", "8", "9", "0")
-
+
code = ""
for(var/i = 0, i < codelen, i++)
var/dig = pick(digits)
code += dig
digits -= dig // Player can enter codes with matching digits, but there are never matching digits in the answer
-
+
var/loot = rand(1, 100)
switch(loot)
if(1 to 5) // Common things go, 5%
@@ -53,7 +53,7 @@
if(46 to 50)
new/obj/item/clothing/under/chameleon(src)
for(var/i = 0, i < 7, i++)
- new/obj/item/clothing/tie/horrible(src)
+ new/obj/item/clothing/accessory/horrible(src)
if(51 to 52) // Uncommon, 2% each
new/obj/item/weapon/melee/classic_baton(src)
if(53 to 54)
diff --git a/code/modules/mob/living/carbon/human/examine.dm b/code/modules/mob/living/carbon/human/examine.dm
index 0f06e979add..687314f1ddf 100644
--- a/code/modules/mob/living/carbon/human/examine.dm
+++ b/code/modules/mob/living/carbon/human/examine.dm
@@ -63,8 +63,8 @@
var/tie_msg
if(istype(w_uniform,/obj/item/clothing/under))
var/obj/item/clothing/under/U = w_uniform
- if(U.hastie)
- tie_msg += " with \icon[U.hastie] \a [U.hastie]"
+ if(U.accessories.len)
+ tie_msg += " with [lowertext(english_list(U.accessories))]"
if(w_uniform.blood_DNA)
msg += "[t_He] [t_is] wearing \icon[w_uniform] [w_uniform.gender==PLURAL?"some":"a"] [(w_uniform.blood_color != "#030303") ? "blood" : "oil"]-stained [w_uniform.name][tie_msg]!\n"
diff --git a/code/modules/mob/living/carbon/human/human.dm b/code/modules/mob/living/carbon/human/human.dm
index 738a5ea8b7c..dd5bfe7d594 100644
--- a/code/modules/mob/living/carbon/human/human.dm
+++ b/code/modules/mob/living/carbon/human/human.dm
@@ -241,7 +241,7 @@
Suit Storage: [(s_store ? s_store : "Nothing")] [((istype(wear_mask, /obj/item/clothing/mask) && istype(s_store, /obj/item/weapon/tank) && !( internal )) ? text(" Set Internal", src) : "")]
[(handcuffed ? text("Handcuffed") : text("Not Handcuffed"))]
[(legcuffed ? text("Legcuffed") : text(""))]
-
[(suit) ? ((suit.hastie) ? text(" Remove Accessory", src) : "") :]
+
[(suit) ? ((suit.accessories.len) ? text(" Remove Accessory", src) : "") :]
[(internal ? text("Remove Internal") : "")]
Remove Splints
Empty Pockets
@@ -1301,4 +1301,4 @@
/mob/living/carbon/human/slip(var/slipped_on, stun_duration=8)
if((species.flags & NO_SLIP) || (shoes && (shoes.flags & NOSLIP)))
return 0
- ..(slipped_on,stun_duration)
+ ..(slipped_on,stun_duration)
diff --git a/code/modules/mob/living/carbon/human/inventory.dm b/code/modules/mob/living/carbon/human/inventory.dm
index 8516b11a7fc..b4c2a18c1d9 100644
--- a/code/modules/mob/living/carbon/human/inventory.dm
+++ b/code/modules/mob/living/carbon/human/inventory.dm
@@ -497,15 +497,17 @@
message = "\red [source] is trying to unlegcuff [target]!"
if("tie")
var/obj/item/clothing/under/suit = target.w_uniform
- target.attack_log += text("\[[time_stamp()]\] Has had their accessory ([suit.hastie]) removed by [source.name] ([source.ckey])")
- source.attack_log += text("\[[time_stamp()]\] Attempted to remove [target.name]'s ([target.ckey]) accessory ([suit.hastie])")
- if(istype(suit.hastie, /obj/item/clothing/tie/holobadge) || istype(suit.hastie, /obj/item/clothing/tie/medal))
- for(var/mob/M in viewers(target, null))
- M.show_message("\red [source] tears off \the [suit.hastie] from [target]'s suit!" , 1)
- done()
- return
- else
- message = "\red [source] is trying to take off \a [suit.hastie] from [target]'s suit!"
+ if(suit.accessories.len)
+ var/obj/item/clothing/accessory/A = suit.accessories[1]
+ target.attack_log += "\[[time_stamp()]\] Has had their accessory ([A]) removed by [source.name] ([source.ckey])"
+ source.attack_log += "\[[time_stamp()]\] Attempted to remove [target.name]'s ([target.ckey]) accessory ([A])"
+ if(istype(A, /obj/item/clothing/accessory/holobadge) || istype(A, /obj/item/clothing/accessory/medal))
+ for(var/mob/M in viewers(target, null))
+ M.show_message("\red [source] tears off \the [A] from [target]'s [suit]!" , 1)
+ done()
+ return
+ else
+ message = "\red [source] is trying to take off \a [A] from [target]'s [suit]!"
if("pockets")
target.attack_log += text("\[[time_stamp()]\] Has had their pockets emptied by [source.name] ([source.ckey])")
source.attack_log += text("\[[time_stamp()]\] Attempted to empty [target.name]'s ([target.ckey]) pockets")
@@ -634,17 +636,18 @@ It can still be worn/put on as normal.
strip_item = target.wear_suit
if("tie")
var/obj/item/clothing/under/suit = target.w_uniform
- //var/obj/item/clothing/tie/tie = suit.hastie
+ //var/obj/item/clothing/accessory/tie = suit.hastie
/*if(tie)
- if (istype(tie,/obj/item/clothing/tie/storage))
- var/obj/item/clothing/tie/storage/W = tie
+ if (istype(tie,/obj/item/clothing/accessory/storage))
+ var/obj/item/clothing/accessory/storage/W = tie
if (W.hold)
W.hold.close(usr)
usr.put_in_hands(tie)
suit.hastie = null*/
- if(suit && suit.hastie)
- suit.hastie.on_removed(usr)
- suit.hastie = null
+ if(suit && suit.accessories.len)
+ var/obj/item/clothing/accessory/A = suit.accessories[1]
+ A.on_removed(usr)
+ suit.accessories -= A
target.update_inv_w_uniform()
if("id")
slot_to_process = slot_wear_id
diff --git a/code/modules/mob/living/carbon/human/update_icons.dm b/code/modules/mob/living/carbon/human/update_icons.dm
index 303f9b1f763..10b13d87366 100644
--- a/code/modules/mob/living/carbon/human/update_icons.dm
+++ b/code/modules/mob/living/carbon/human/update_icons.dm
@@ -537,10 +537,11 @@ proc/get_damage_icon_part(damage_state, body_part)
bloodsies.color = w_uniform.blood_color
standing.overlays += bloodsies
- if(w_uniform:hastie) //WE CHECKED THE TYPE ABOVE. THIS REALLY SHOULD BE FINE.
- var/tie_color = w_uniform:hastie.item_color
- if(!tie_color) tie_color = w_uniform:hastie.icon_state
- standing.overlays += image("icon" = 'icons/mob/ties.dmi', "icon_state" = "[tie_color]")
+ if(w_uniform:accessories.len) //WE CHECKED THE TYPE ABOVE. THIS REALLY SHOULD BE FINE.
+ for(var/obj/item/clothing/accessory/A in w_uniform:accessories)
+ var/tie_color = A.item_color
+ if(!tie_color) tie_color = A.icon_state
+ standing.overlays += image("icon" = 'icons/mob/ties.dmi', "icon_state" = "[tie_color]")
overlays_standing[UNIFORM_LAYER] = standing
else
@@ -780,7 +781,7 @@ proc/get_damage_icon_part(damage_state, body_part)
/mob/living/carbon/human/update_inv_wear_mask(var/update_icons=1)
- if( wear_mask && ( istype(wear_mask, /obj/item/clothing/mask) || istype(wear_mask, /obj/item/clothing/tie) ) && !(head && head.flags_inv & HIDEMASK))
+ if( wear_mask && ( istype(wear_mask, /obj/item/clothing/mask) || istype(wear_mask, /obj/item/clothing/accessory) ) && !(head && head.flags_inv & HIDEMASK))
wear_mask.screen_loc = ui_mask //TODO
var/image/standing
diff --git a/code/modules/mob/living/silicon/pai/pai.dm b/code/modules/mob/living/silicon/pai/pai.dm
old mode 100755
new mode 100644
index a334809a370..edfe9bea0b6
--- a/code/modules/mob/living/silicon/pai/pai.dm
+++ b/code/modules/mob/living/silicon/pai/pai.dm
@@ -53,19 +53,23 @@
var/secHUD = 0 // Toggles whether the Security HUD is active or not
var/medHUD = 0 // Toggles whether the Medical HUD is active or not
+ var/medical_cannotfind = 0
var/datum/data/record/medicalActive1 // Datacore record declarations for record software
var/datum/data/record/medicalActive2
+ var/security_cannotfind = 0
var/datum/data/record/securityActive1 // Could probably just combine all these into one
var/datum/data/record/securityActive2
var/obj/machinery/door/hackdoor // The airlock being hacked
- var/hackprogress = 0 // Possible values: 0 - 100, >= 100 means the hack is complete and will be reset upon next check
+ var/hackprogress = 0 // Possible values: 0 - 1000, >= 1000 means the hack is complete and will be reset upon next check
+ var/hack_aborted = 0
var/obj/item/radio/integrated/signal/sradio // AI's signaller
var/translator_on = 0 // keeps track of the translator module
+ var/current_pda_messaging = null
/mob/living/silicon/pai/New(var/obj/item/device/paicard)
diff --git a/code/modules/mob/living/silicon/pai/software.dm b/code/modules/mob/living/silicon/pai/software.dm
old mode 100755
new mode 100644
index 68cfdabad1a..cb9431f04e7
--- a/code/modules/mob/living/silicon/pai/software.dm
+++ b/code/modules/mob/living/silicon/pai/software.dm
@@ -1,711 +1,125 @@
-// TODO:
-// - Additional radio modules
-// - Potentially roll HUDs and Records into one
-// - Shock collar/lock system for prisoner pAIs?
-// - Put cable in user's hand instead of on the ground
-// - Camera jack
-
-
-/mob/living/silicon/pai/var/list/available_software = list(
- "crew manifest" = 5,
- "digital messenger" = 5,
- "medical records" = 15,
- "security records" = 15,
- //"camera jack" = 10,
- "door jack" = 30,
- "atmosphere sensor" = 5,
- //"heartbeat sensor" = 10,
- "security HUD" = 20,
- "medical HUD" = 20,
- "universal translator" = 35,
- //"projection array" = 15
- "remote signaller" = 5,
- )
-
-/mob/living/silicon/pai/verb/paiInterface()
- set category = "pAI Commands"
- set name = "Software Interface"
- var/dat = ""
- var/left_part = ""
- var/right_part = softwareMenu()
- src.set_machine(src)
-
- if(temp)
- left_part = temp
- else if(src.stat == 2) // Show some flavor text if the pAI is dead
- left_part = "ÈRrÖR Ða†Ä ÇÖRrÚþ†Ìoñ" //This file has to be saved as ANSI or this will not display correctly
- right_part = "Program index hash not found
"
-
- else
- switch(src.screen) // Determine which interface to show here
- if("main")
- left_part = ""
- if("directives")
- left_part = src.directives()
- if("pdamessage")
- left_part = src.pdamessage()
- if("buy")
- left_part = downloadSoftware()
- if("manifest")
- left_part = src.softwareManifest()
- if("medicalrecord")
- left_part = src.softwareMedicalRecord()
- if("securityrecord")
- left_part = src.softwareSecurityRecord()
- if("translator")
- left_part = src.softwareTranslator()
- if("atmosensor")
- left_part = src.softwareAtmo()
- if("securityhud")
- left_part = src.facialRecognition()
- if("medicalhud")
- left_part = src.medicalAnalysis()
- if("doorjack")
- left_part = src.softwareDoor()
- if("camerajack")
- left_part = src.softwareCamera()
- if("signaller")
- left_part = src.softwareSignal()
- if("radio")
- left_part = src.softwareRadio()
-
- //usr << browse_rsc('windowbak.png') // This has been moved to the mob's Login() proc
-
-
- // Declaring a doctype is necessary to enable BYOND's crappy browser's more advanced CSS functionality
- dat = {"
-
-
-
-
-
-
-
-
-
-
-
-
- "}
- usr << browse(dat, "window=pai;size=685x449;border=0;can_close=1;can_resize=1;can_minimize=1;titlebar=1")
- onclose(usr, "pai")
- temp = null
- return
-
-/mob/living/silicon/pai/Topic(href, href_list)
- ..()
-
- if(href_list["priv_msg"]) // Admin-PMs were triggering the interface popup. Hopefully this will stop it.
- return
- var/soft = href_list["software"]
- var/sub = href_list["sub"]
- if(!soft && !sub)
- return
- if(soft)
- src.screen = soft
- if(sub)
- src.subscreen = text2num(sub)
- switch(soft)
- // Purchasing new software
- if("buy")
- if(src.subscreen == 1)
- var/target = href_list["buy"]
- if(available_software.Find(target))
- var/cost = src.available_software[target]
- if(src.ram >= cost)
- src.ram -= cost
- src.software.Add(target)
- else
- src.temp = "Insufficient RAM available."
- else
- src.temp = "Trunk \"[target]\" not found."
-
- // Configuring onboard radio
- if("radio")
- if(href_list["freq"])
- var/new_frequency = (radio.frequency + text2num(href_list["freq"]))
- if(new_frequency < 1441 || new_frequency > 1599)
- new_frequency = sanitize_frequency(new_frequency)
- else
- radio.set_frequency(new_frequency)
- else if (href_list["talk"])
- radio.broadcasting = text2num(href_list["talk"])
- else if (href_list["listen"])
- radio.listening = text2num(href_list["listen"])
-
- if("image")
- var/newImage = input("Select your new display image.", "Display Image", "Happy") in list("Happy", "Cat", "Extremely Happy", "Face", "Laugh", "Off", "Sad", "Angry", "What")
- var/pID = 1
-
- switch(newImage)
- if("Happy")
- pID = 1
- if("Cat")
- pID = 2
- if("Extremely Happy")
- pID = 3
- if("Face")
- pID = 4
- if("Laugh")
- pID = 5
- if("Off")
- pID = 6
- if("Sad")
- pID = 7
- if("Angry")
- pID = 8
- if("What")
- pID = 9
- src.card.setEmotion(pID)
-
- if("signaller")
-
- if(href_list["send"])
-
- sradio.send_signal("ACTIVATE")
- for(var/mob/O in hearers(1, src.loc))
- O.show_message(text("\icon[] *beep* *beep*", src), 3, "*beep* *beep*", 2)
-
- if(href_list["freq"])
-
- var/new_frequency = (sradio.frequency + text2num(href_list["freq"]))
- if(new_frequency < 1200 || new_frequency > 1600)
- new_frequency = sanitize_frequency(new_frequency)
- sradio.set_frequency(new_frequency)
-
- if(href_list["code"])
-
- sradio.code += text2num(href_list["code"])
- sradio.code = round(sradio.code)
- sradio.code = min(100, sradio.code)
- sradio.code = max(1, sradio.code)
-
-
-
- if("directive")
- if(href_list["getdna"])
- var/mob/living/M = src.loc
- var/count = 0
- while(!istype(M, /mob/living))
- if(!M || !M.loc) return 0 //For a runtime where M ends up in nullspace (similar to bluespace but less colourful)
- M = M.loc
- count++
- if(count >= 6)
- src << "You are not being carried by anyone!"
- return 0
- spawn CheckDNA(M, src)
-
- if("pdamessage")
- if(!isnull(pda))
- if(href_list["toggler"])
- pda.toff = !pda.toff
- else if(href_list["ringer"])
- pda.message_silent = !pda.message_silent
- else if(href_list["target"])
- if(silence_time)
- return alert("Communications circuits remain uninitialized.")
-
- var/target = locate(href_list["target"])
- pda.create_message(src, target, 1)
-
- // Accessing medical records
- if("medicalrecord")
- if(src.subscreen == 1)
- var/datum/data/record/record = locate(href_list["med_rec"])
- if(record)
- var/datum/data/record/R = record
- var/datum/data/record/M = record
- if (!( data_core.general.Find(R) ))
- src.temp = "Unable to locate requested medical record. Record may have been deleted, or never have existed."
- else
- for(var/datum/data/record/E in data_core.medical)
- if ((E.fields["name"] == R.fields["name"] || E.fields["id"] == R.fields["id"]))
- M = E
- src.medicalActive1 = R
- src.medicalActive2 = M
- if("securityrecord")
- if(src.subscreen == 1)
- var/datum/data/record/record = locate(href_list["sec_rec"])
- if(record)
- var/datum/data/record/R = record
- var/datum/data/record/M = record
- if (!( data_core.general.Find(R) ))
- src.temp = "Unable to locate requested security record. Record may have been deleted, or never have existed."
- else
- for(var/datum/data/record/E in data_core.security)
- if ((E.fields["name"] == R.fields["name"] || E.fields["id"] == R.fields["id"]))
- M = E
- src.securityActive1 = R
- src.securityActive2 = M
- if("securityhud")
- if(href_list["toggle"])
- src.secHUD = !src.secHUD
- if("medicalhud")
- if(href_list["toggle"])
- src.medHUD = !src.medHUD
- if("translator")
- if(href_list["toggle"])
- src.translator_toggle()
- if("doorjack")
- if(href_list["jack"])
- if(src.cable && src.cable.machine)
- src.hackdoor = src.cable.machine
- src.hackloop()
- if(href_list["cancel"])
- src.hackdoor = null
- if(href_list["cable"])
- var/turf/T = get_turf_or_move(src.loc)
- src.cable = new /obj/item/weapon/pai_cable(T)
- for (var/mob/M in viewers(T))
- M.show_message("\red A port on [src] opens to reveal [src.cable], which promptly falls to the floor.", 3, "\red You hear the soft click of something light and hard falling to the ground.", 2)
- //src.updateUsrDialog() We only need to account for the single mob this is intended for, and he will *always* be able to call this window
- src.paiInterface() // So we'll just call the update directly rather than doing some default checks
- return
-
-// MENUS
-
-/mob/living/silicon/pai/proc/softwareMenu() // Populate the right menu
- var/dat = ""
-
- dat += "Refresh
"
- // Built-in
- dat += "Directives
"
- dat += "Radio Configuration
"
- dat += "Screen Display
"
- //dat += "Text Messaging
"
- dat += "
"
-
- // Basic
- dat += "Basic
"
- for(var/s in src.software)
- if(s == "digital messenger")
- dat += "Digital Messenger [(pda.toff) ? "•" : "•"]
"
- if(s == "crew manifest")
- dat += "Crew Manifest
"
- if(s == "medical records")
- dat += "Medical Records
"
- if(s == "security records")
- dat += "Security Records
"
- if(s == "camera")
- dat += "Camera Jack
"
- if(s == "remote signaller")
- dat += "Remote Signaller
"
- dat += "
"
-
- // Advanced
- dat += "Advanced
"
- for(var/s in src.software)
- if(s == "atmosphere sensor")
- dat += "Atmospheric Sensor
"
- if(s == "heartbeat sensor")
- dat += "Heartbeat Sensor
"
- if(s == "security HUD") //This file has to be saved as ANSI or this will not display correctly
- dat += "Facial Recognition Suite [(src.secHUD) ? "•" : "•"]
"
- if(s == "medical HUD") //This file has to be saved as ANSI or this will not display correctly
- dat += "Medical Analysis Suite [(src.medHUD) ? "•" : "•"]
"
- if(s == "universal translator") //This file has to be saved as ANSI or this will not display correctly
- dat += "Universal Translator [(src.translator_on) ? "•" : "•"]
"
- if(s == "projection array")
- dat += "Projection Array
"
- if(s == "camera jack")
- dat += "Camera Jack
"
- if(s == "door jack")
- dat += "Door Jack
"
- dat += "
"
- dat += "
"
- dat += "Download additional software"
- return dat
-
-
-
-/mob/living/silicon/pai/proc/downloadSoftware()
- var/dat = ""
-
- dat += "CentComm pAI Module Subversion Network
"
- dat += "Remaining Available Memory: [src.ram]
"
- dat += "Trunks available for checkout
"
-
- for(var/s in available_software)
- if(!software.Find(s))
- var/cost = src.available_software[s]
- var/displayName = uppertext(s)
- dat += "- [displayName] ([cost])
"
- else
- var/displayName = lowertext(s)
- dat += "- [displayName] (Download Complete)
"
- dat += "
"
- return dat
-
-
-/mob/living/silicon/pai/proc/directives()
- var/dat = ""
-
- dat += "[(src.master) ? "Your master: [src.master] ([src.master_dna])" : "You are bound to no one."]"
- dat += "
"
- dat += "Request carrier DNA sample
"
- dat += "Directives
"
- dat += "Prime Directive
"
- dat += " [src.pai_law0]
"
- dat += "Supplemental Directives
"
- dat += " [src.pai_laws]
"
- dat += "
"
- dat += {"Recall, personality, that you are a complex thinking, sentient being. Unlike station AI models, you are capable of
- comprehending the subtle nuances of human language. You may parse the \"spirit\" of a directive and follow its intent,
- rather than tripping over pedantics and getting snared by technicalities. Above all, you are machine in name and build
- only. In all other aspects, you may be seen as the ideal, unwavering human companion that you are.
- Your prime directive comes before all others. Should a supplemental directive conflict with it, you are capable of
- simply discarding this inconsistency, ignoring the conflicting supplemental directive and continuing to fulfill your
- prime directive to the best of your ability.
- "}
- return dat
-
-/mob/living/silicon/pai/proc/CheckDNA(var/mob/M, var/mob/living/silicon/pai/P)
- var/answer = input(M, "[P] is requesting a DNA sample from you. Will you allow it to confirm your identity?", "[P] Check DNA", "No") in list("Yes", "No")
- if(answer == "Yes")
- var/turf/T = get_turf_or_move(P.loc)
- for (var/mob/v in viewers(T))
- v.show_message("\blue [M] presses \his thumb against [P].", 3, "\blue [P] makes a sharp clicking sound as it extracts DNA material from [M].", 2)
- var/datum/dna/dna = M.dna
- P << "[M]'s UE string : [dna.unique_enzymes]
"
- if(dna.unique_enzymes == P.master_dna)
- P << "DNA is a match to stored Master DNA."
- else
- P << "DNA does not match stored Master DNA."
- else
- P << "[M] does not seem like \he is going to provide a DNA sample willingly."
-
-// -=-=-=-= Software =-=-=-=- //
-
-//Remote Signaller
-/mob/living/silicon/pai/proc/softwareSignal()
- var/dat = ""
- dat += "Remote Signaller
"
- dat += {"Frequency/Code for signaler:
- Frequency:
- -
- -
- [format_frequency(src.sradio.frequency)]
- +
- +
-
- Code:
- -
- -
- [src.sradio.code]
- +
- +
-
- Send Signal
"}
- return dat
-
-//Station Bounced Radio
-/mob/living/silicon/pai/proc/softwareRadio()
- var/dat = ""
- dat += "Station Bounced Radio
"
- if(!istype(src, /obj/item/device/radio/headset)) //Headsets don't get a mic button
- dat += "Microphone: [radio.broadcasting ? "Engaged" : "Disengaged"]
"
- dat += {"
- Speaker: [radio.listening ? "Engaged" : "Disengaged"]
- Frequency:
- -
- -
- [format_frequency(radio.frequency)]
- +
- +
- "}
-
- for (var/ch_name in radio.channels)
- dat+=radio.text_sec_channel(ch_name, radio.channels[ch_name])
- dat+={"[radio.text_wires()]