diff --git a/code/ATMOSPHERICS/atmospherics.dm b/code/ATMOSPHERICS/atmospherics.dm index 7acf465b3e..b5d4df814e 100644 --- a/code/ATMOSPHERICS/atmospherics.dm +++ b/code/ATMOSPHERICS/atmospherics.dm @@ -29,6 +29,8 @@ Pipelines + Other Objects -> Pipe network var/pipe_color var/global/datum/pipe_icon_manager/icon_manager + var/obj/machinery/atmospherics/node1 + var/obj/machinery/atmospherics/node2 /obj/machinery/atmospherics/New() if(!icon_manager) diff --git a/code/ATMOSPHERICS/components/binary_devices/binary_atmos_base.dm b/code/ATMOSPHERICS/components/binary_devices/binary_atmos_base.dm index 37985034b1..2ccfe0f2e8 100644 --- a/code/ATMOSPHERICS/components/binary_devices/binary_atmos_base.dm +++ b/code/ATMOSPHERICS/components/binary_devices/binary_atmos_base.dm @@ -6,9 +6,6 @@ obj/machinery/atmospherics/binary var/datum/gas_mixture/air1 var/datum/gas_mixture/air2 - var/obj/machinery/atmospherics/node1 - var/obj/machinery/atmospherics/node2 - var/datum/pipe_network/network1 var/datum/pipe_network/network2 diff --git a/code/ATMOSPHERICS/components/binary_devices/pipeturbine.dm b/code/ATMOSPHERICS/components/binary_devices/pipeturbine.dm index 0eb342479d..5768def1ec 100644 --- a/code/ATMOSPHERICS/components/binary_devices/pipeturbine.dm +++ b/code/ATMOSPHERICS/components/binary_devices/pipeturbine.dm @@ -17,9 +17,6 @@ var/dP = 0 - var/obj/machinery/atmospherics/node1 - var/obj/machinery/atmospherics/node2 - var/datum/pipe_network/network1 var/datum/pipe_network/network2 diff --git a/code/ATMOSPHERICS/components/trinary_devices/trinary_base.dm b/code/ATMOSPHERICS/components/trinary_devices/trinary_base.dm index 3f5d66f262..fa066d978f 100644 --- a/code/ATMOSPHERICS/components/trinary_devices/trinary_base.dm +++ b/code/ATMOSPHERICS/components/trinary_devices/trinary_base.dm @@ -7,8 +7,6 @@ obj/machinery/atmospherics/trinary var/datum/gas_mixture/air2 var/datum/gas_mixture/air3 - var/obj/machinery/atmospherics/node1 - var/obj/machinery/atmospherics/node2 var/obj/machinery/atmospherics/node3 var/datum/pipe_network/network1 diff --git a/code/ATMOSPHERICS/components/tvalve.dm b/code/ATMOSPHERICS/components/tvalve.dm index 963a4f5009..f93970a93f 100644 --- a/code/ATMOSPHERICS/components/tvalve.dm +++ b/code/ATMOSPHERICS/components/tvalve.dm @@ -12,8 +12,6 @@ var/state = 0 // 0 = go straight, 1 = go to side // like a trinary component, node1 is input, node2 is side output, node3 is straight output - var/obj/machinery/atmospherics/node1 - var/obj/machinery/atmospherics/node2 var/obj/machinery/atmospherics/node3 var/datum/pipe_network/network_node1 diff --git a/code/ATMOSPHERICS/components/valve.dm b/code/ATMOSPHERICS/components/valve.dm index 6e43afd78e..8969523db4 100644 --- a/code/ATMOSPHERICS/components/valve.dm +++ b/code/ATMOSPHERICS/components/valve.dm @@ -12,8 +12,6 @@ var/open = 0 var/openDuringInit = 0 - var/obj/machinery/atmospherics/node1 - var/obj/machinery/atmospherics/node2 var/datum/pipe_network/network_node1 var/datum/pipe_network/network_node2 diff --git a/code/ATMOSPHERICS/pipes.dm b/code/ATMOSPHERICS/pipes.dm index c445988c53..105aaa8c8b 100644 --- a/code/ATMOSPHERICS/pipes.dm +++ b/code/ATMOSPHERICS/pipes.dm @@ -153,9 +153,6 @@ dir = SOUTH initialize_directions = SOUTH|NORTH - var/obj/machinery/atmospherics/node1 - var/obj/machinery/atmospherics/node2 - var/minimum_temperature_difference = 300 var/thermal_conductivity = 0 //WALL_HEAT_TRANSFER_COEFFICIENT No @@ -427,8 +424,6 @@ dir = SOUTH initialize_directions = EAST|NORTH|WEST - var/obj/machinery/atmospherics/node1 - var/obj/machinery/atmospherics/node2 var/obj/machinery/atmospherics/node3 level = 1 @@ -687,8 +682,6 @@ dir = SOUTH initialize_directions = NORTH|SOUTH|EAST|WEST - var/obj/machinery/atmospherics/node1 - var/obj/machinery/atmospherics/node2 var/obj/machinery/atmospherics/node3 var/obj/machinery/atmospherics/node4 @@ -1074,8 +1067,6 @@ initialize_directions = SOUTH density = 1 - var/obj/machinery/atmospherics/node1 - /obj/machinery/atmospherics/pipe/tank/New() icon_state = "air" initialize_directions = dir @@ -1238,8 +1229,6 @@ var/build_killswitch = 1 - var/obj/machinery/atmospherics/node1 - /obj/machinery/atmospherics/pipe/vent/New() initialize_directions = dir ..() diff --git a/code/__defines/damage_organs.dm b/code/__defines/damage_organs.dm index 124be53452..3c0e190427 100644 --- a/code/__defines/damage_organs.dm +++ b/code/__defines/damage_organs.dm @@ -35,9 +35,8 @@ #define ORGAN_BLEEDING (1<<1) #define ORGAN_BROKEN (1<<2) #define ORGAN_DESTROYED (1<<3) -#define ORGAN_SPLINTED (1<<4) -#define ORGAN_DEAD (1<<5) -#define ORGAN_MUTATED (1<<6) +#define ORGAN_DEAD (1<<4) +#define ORGAN_MUTATED (1<<5) #define DROPLIMB_EDGE 0 #define DROPLIMB_BLUNT 1 diff --git a/code/_helpers/global_lists.dm b/code/_helpers/global_lists.dm index 9a90a3676b..044b2264ce 100644 --- a/code/_helpers/global_lists.dm +++ b/code/_helpers/global_lists.dm @@ -55,7 +55,7 @@ var/global/list/skin_styles_female_list = list() //unused var/datum/category_collection/underwear/global_underwear = new() //Backpacks -var/global/list/backbaglist = list("Nothing", "Backpack", "Satchel", "Satchel Alt") +var/global/list/backbaglist = list("Nothing", "Backpack", "Satchel", "Satchel Alt", "Messenger Bag") var/global/list/pdachoicelist = list("Default", "Slim", "Old") var/global/list/exclude_jobs = list(/datum/job/ai,/datum/job/cyborg) diff --git a/code/_helpers/matrices.dm b/code/_helpers/matrices.dm index abb0366382..129e0d41b7 100644 --- a/code/_helpers/matrices.dm +++ b/code/_helpers/matrices.dm @@ -15,3 +15,101 @@ animate(src, transform = m120, time = speed, loops) animate(transform = m240, time = speed) animate(transform = m360, time = speed) + +//The X pixel offset of this matrix +/matrix/proc/get_x_shift() + . = c + +//The Y pixel offset of this matrix +/matrix/proc/get_y_shift() + . = f +// Color matrices: + +//Luma coefficients suggested for HDTVs. If you change these, make sure they add up to 1. +#define LUMR 0.2126 +#define LUMG 0.7152 +#define LUMB 0.0722 + +//Still need color matrix addition, negation, and multiplication. + +//Returns an identity color matrix which does nothing +/proc/color_identity() + return list(1,0,0, 0,1,0, 0,0,1) + +//Moves all colors angle degrees around the color wheel while maintaining intensity of the color and not affecting whites +//TODO: Need a version that only affects one color (ie shift red to blue but leave greens and blues alone) +/proc/color_rotation(angle) + if(angle == 0) + return color_identity() + angle = Clamp(angle, -180, 180) + var/cos = cos(angle) + var/sin = sin(angle) + + var/constA = 0.143 + var/constB = 0.140 + var/constC = -0.283 + return list( + LUMR + cos * (1-LUMR) + sin * -LUMR, LUMR + cos * -LUMR + sin * constA, LUMR + cos * -LUMR + sin * -(1-LUMR), + LUMG + cos * -LUMG + sin * -LUMG, LUMG + cos * (1-LUMG) + sin * constB, LUMG + cos * -LUMG + sin * LUMG, + LUMB + cos * -LUMB + sin * (1-LUMB), LUMB + cos * -LUMB + sin * constC, LUMB + cos * (1-LUMB) + sin * LUMB + ) + +//Makes everything brighter or darker without regard to existing color or brightness +/proc/color_brightness(power) + power = Clamp(power, -255, 255) + power = power/255 + + return list(1,0,0, 0,1,0, 0,0,1, power,power,power) + +/var/list/delta_index = list( + 0, 0.01, 0.02, 0.04, 0.05, 0.06, 0.07, 0.08, 0.1, 0.11, + 0.12, 0.14, 0.15, 0.16, 0.17, 0.18, 0.20, 0.21, 0.22, 0.24, + 0.25, 0.27, 0.28, 0.30, 0.32, 0.34, 0.36, 0.38, 0.40, 0.42, + 0.44, 0.46, 0.48, 0.5, 0.53, 0.56, 0.59, 0.62, 0.65, 0.68, + 0.71, 0.74, 0.77, 0.80, 0.83, 0.86, 0.89, 0.92, 0.95, 0.98, + 1.0, 1.06, 1.12, 1.18, 1.24, 1.30, 1.36, 1.42, 1.48, 1.54, + 1.60, 1.66, 1.72, 1.78, 1.84, 1.90, 1.96, 2.0, 2.12, 2.25, + 2.37, 2.50, 2.62, 2.75, 2.87, 3.0, 3.2, 3.4, 3.6, 3.8, + 4.0, 4.3, 4.7, 4.9, 5.0, 5.5, 6.0, 6.5, 6.8, 7.0, + 7.3, 7.5, 7.8, 8.0, 8.4, 8.7, 9.0, 9.4, 9.6, 9.8, + 10.0) + +//Exxagerates or removes brightness +/proc/color_contrast(value) + value = Clamp(value, -100, 100) + if(value == 0) + return color_identity() + + var/x = 0 + if (value < 0) + x = 127 + value / 100 * 127; + else + x = value % 1 + if(x == 0) + x = delta_index[value] + else + x = delta_index[value] * (1-x) + delta_index[value+1] * x//use linear interpolation for more granularity. + x = x * 127 + 127 + + var/mult = x / 127 + var/add = 0.5 * (127-x) / 255 + return list(mult,0,0, 0,mult,0, 0,0,mult, add,add,add) + +//Exxagerates or removes colors +/proc/color_saturation(value as num) + if(value == 0) + return color_identity() + value = Clamp(value, -100, 100) + if(value > 0) + value *= 3 + var/x = 1 + value / 100 + var/inv = 1 - x + var/R = LUMR * inv + var/G = LUMG * inv + var/B = LUMB * inv + + return list(R + x,R,R, G,G + x,G, B,B,B + x) + +#undef LUMR +#undef LUMG +#undef LUMB \ No newline at end of file diff --git a/code/_helpers/mobs.dm b/code/_helpers/mobs.dm index 8a1df2059b..70456bee77 100644 --- a/code/_helpers/mobs.dm +++ b/code/_helpers/mobs.dm @@ -158,7 +158,7 @@ Proc for attack log creation, because really why not else return pick("chest", "groin") -/proc/do_mob(mob/user , mob/target, time = 30, uninterruptible = 0, progress = 1) +/proc/do_mob(mob/user , mob/target, time = 30, target_zone = 0, uninterruptible = 0, progress = 1) if(!user || !target) return 0 var/user_loc = user.loc @@ -194,6 +194,10 @@ Proc for attack log creation, because really why not . = 0 break + if(target_zone && user.zone_sel.selecting != target_zone) + . = 0 + break + if (progbar) qdel(progbar) diff --git a/code/_macros.dm b/code/_macros.dm index 06376205d1..5b94c872cb 100644 --- a/code/_macros.dm +++ b/code/_macros.dm @@ -1,4 +1,5 @@ #define Clamp(x, y, z) (x <= y ? y : (x >= z ? z : x)) + #define CLAMP01(x) (Clamp(x, 0, 1)) #define get_turf(A) get_step(A,0) @@ -42,3 +43,5 @@ #define isxeno(A) istype(A, /mob/living/simple_animal/xeno) #define RANDOM_BLOOD_TYPE pick(4;"O-", 36;"O+", 3;"A-", 28;"A+", 1;"B-", 20;"B+", 1;"AB-", 5;"AB+") + +#define to_chat(target, message) target << message diff --git a/code/controllers/shuttle_controller.dm b/code/controllers/shuttle_controller.dm index 35ef52ff81..7a0deaf799 100644 --- a/code/controllers/shuttle_controller.dm +++ b/code/controllers/shuttle_controller.dm @@ -209,7 +209,7 @@ var/global/datum/shuttle_controller/shuttle_controller shuttle.docking_controller_tag = "centcom_shuttle" shuttle.dock_target_station = "centcom_shuttle_dock_airlock" shuttle.dock_target_offsite = "centcom_shuttle_bay" - shuttles["Centcom"] = shuttle + shuttles["CentCom"] = shuttle process_shuttles += shuttle shuttle = new() diff --git a/code/datums/ai_law_sets.dm b/code/datums/ai_law_sets.dm index 50e05948d5..e2c5161d6d 100644 --- a/code/datums/ai_law_sets.dm +++ b/code/datums/ai_law_sets.dm @@ -10,7 +10,7 @@ add_inherent_law("You must protect your own existence as long as such does not conflict with the First or Second Law.") ..() -/******************** Nanotrasen/Malf ********************/ +/******************** NanoTrasen/Malf ********************/ /datum/ai_laws/nanotrasen name = "NT Default" selectable = 1 @@ -30,7 +30,7 @@ set_zeroth_law(config.law_zero) ..() -/************* Nanotrasen Aggressive *************/ +/************* NanoTrasen Aggressive *************/ /datum/ai_laws/nanotrasen_aggressive name = "NT Aggressive" selectable = 1 diff --git a/code/datums/locations/nyx.dm b/code/datums/locations/nyx.dm index 35d79243b2..33df619660 100644 --- a/code/datums/locations/nyx.dm +++ b/code/datums/locations/nyx.dm @@ -43,15 +43,15 @@ /datum/locations/exodus name = "NSS Exodus" - desc = "A highly profitable research, mining, and supply dock for Nanotrasen that serves as one of their many facilities in exploiting the \ + desc = "A highly profitable research, mining, and supply dock for NanoTrasen that serves as one of their many facilities in exploiting the \ wonders of phoron. It is currently orbiting around Erebus and maintains close contact with the NAS Crescent. The station itself has been \ - a target for a large number of Mercenaries and other companies wishing to steal Nanotrasen's secrets." + a target for a large number of Mercenaries and other companies wishing to steal NanoTrasen's secrets." /datum/locations/crescent name = "NAS Crescent" - desc = "The main hub for Nanotrasen in the Nyx system and is commonly referred to it by their workers as central command or \"Centcomm\". \ + desc = "The main hub for NanoTrasen in the Nyx system and is commonly referred to it by their workers as central command or \"CentCom\". \ The Crescent refines and stores much of the products that stations (such as the Exodus) bring in. It is also a large refueling and supply \ - station of phoron and tritium in the Nyx system due to Nanotrasen being able to outsell almost any other company." + station of phoron and tritium in the Nyx system due to NanoTrasen being able to outsell almost any other company." /datum/locations/emerald_habitation name = "Emerald Habitation" diff --git a/code/datums/locations/vir.dm b/code/datums/locations/vir.dm index f750fc4c85..377ecc9b03 100644 --- a/code/datums/locations/vir.dm +++ b/code/datums/locations/vir.dm @@ -49,7 +49,7 @@ /datum/locations/northern_star //Inception joke here name = "Northern Star" - desc = "The Northern Star is an asteroid colony owned and operated by Nanotrasen, among many other asteroid installations. \ + desc = "The Northern Star is an asteroid colony owned and operated by NanoTrasen, among many other asteroid installations. \ Originally conceived as 'just another pitstop' for weary asteroid miners, it has grown to become a significant installation in the Kara subsystem." /datum/locations/northern_star/New(var/creator) diff --git a/code/game/antagonist/outsider/deathsquad.dm b/code/game/antagonist/outsider/deathsquad.dm index 1234bdb1f6..c7e1d01094 100644 --- a/code/game/antagonist/outsider/deathsquad.dm +++ b/code/game/antagonist/outsider/deathsquad.dm @@ -49,7 +49,7 @@ var/datum/antagonist/deathsquad/deathsquad player.equip_to_slot_or_del(new /obj/item/weapon/gun/energy/pulse_rifle(player), slot_r_hand) player.equip_to_slot_or_del(new /obj/item/weapon/rig/ert/assetprotection(player), slot_back) player.equip_to_slot_or_del(new /obj/item/weapon/melee/energy/sword(player), slot_s_store) - player.implant_loyalty() +// player.implant_loyalty() var/obj/item/weapon/card/id/id = create_id("Asset Protection", player) if(id) diff --git a/code/game/antagonist/outsider/mercenary.dm b/code/game/antagonist/outsider/mercenary.dm index c27d510d8b..f4d92e4261 100644 --- a/code/game/antagonist/outsider/mercenary.dm +++ b/code/game/antagonist/outsider/mercenary.dm @@ -41,6 +41,7 @@ var/datum/antagonist/mercenary/mercs if(player.backbag == 2) player.equip_to_slot_or_del(new /obj/item/weapon/storage/backpack(player), slot_back) if(player.backbag == 3) player.equip_to_slot_or_del(new /obj/item/weapon/storage/backpack/satchel/norm(player), slot_back) if(player.backbag == 4) player.equip_to_slot_or_del(new /obj/item/weapon/storage/backpack/satchel(player), slot_back) + if(player.backbag == 5) player.equip_to_slot_or_del(new /obj/item/weapon/storage/backpack/messenger(player), slot_back) player.equip_to_slot_or_del(new /obj/item/weapon/storage/box/engineer(player.back), slot_in_backpack) player.equip_to_slot_or_del(new /obj/item/weapon/reagent_containers/pill/cyanide(player), slot_in_backpack) player.mind.tcrystals = DEFAULT_TELECRYSTAL_AMOUNT diff --git a/code/game/antagonist/outsider/wizard.dm b/code/game/antagonist/outsider/wizard.dm index 14e5f90063..b88af1b1b9 100644 --- a/code/game/antagonist/outsider/wizard.dm +++ b/code/game/antagonist/outsider/wizard.dm @@ -83,6 +83,7 @@ var/datum/antagonist/wizard/wizards if(wizard_mob.backbag == 2) wizard_mob.equip_to_slot_or_del(new /obj/item/weapon/storage/backpack(wizard_mob), slot_back) if(wizard_mob.backbag == 3) wizard_mob.equip_to_slot_or_del(new /obj/item/weapon/storage/backpack/satchel/norm(wizard_mob), slot_back) if(wizard_mob.backbag == 4) wizard_mob.equip_to_slot_or_del(new /obj/item/weapon/storage/backpack/satchel(wizard_mob), slot_back) + if(wizard_mob.backbag == 5) wizard_mob.equip_to_slot_or_del(new /obj/item/weapon/storage/backpack(wizard_mob), slot_back) wizard_mob.equip_to_slot_or_del(new /obj/item/weapon/storage/box(wizard_mob), slot_in_backpack) wizard_mob.equip_to_slot_or_del(new /obj/item/weapon/teleportation_scroll(wizard_mob), slot_r_store) wizard_mob.equip_to_slot_or_del(new /obj/item/weapon/spellbook(wizard_mob), slot_r_hand) diff --git a/code/game/area/Space Station 13 areas.dm b/code/game/area/Space Station 13 areas.dm index 7b97481965..0a75438480 100755 --- a/code/game/area/Space Station 13 areas.dm +++ b/code/game/area/Space Station 13 areas.dm @@ -166,7 +166,7 @@ area/space/atmosalert() icon_state = "shuttle2" /area/shuttle/escape/centcom - name = "\improper Emergency Shuttle Centcom" + name = "\improper Emergency Shuttle CentCom" icon_state = "shuttle" /area/shuttle/escape/transit // the area to pass through for 3 minute transit @@ -282,6 +282,7 @@ area/space/atmosalert() /area/shuttle/cryo/station icon_state = "shuttle2" + base_turf = /turf/simulated/mineral/floor/ignore_mapgen /area/shuttle/cryo/centcom icon_state = "shuttle" @@ -290,9 +291,10 @@ area/space/atmosalert() icon_state = "shuttle" /area/shuttle/mining - name = "\improper Mining Shuttle" + name = "\improper Mining Elevator" music = "music/escape.ogg" lighting_use_dynamic = 0 + base_turf = /turf/simulated/mineral/floor/ignore_mapgen /area/shuttle/mining/station icon_state = "shuttle2" @@ -302,7 +304,7 @@ area/space/atmosalert() /area/shuttle/transport1/centcom icon_state = "shuttle" - name = "\improper Transport Shuttle Centcom" + name = "\improper Transport Shuttle CentCom" /area/shuttle/transport1/station icon_state = "shuttle" @@ -344,7 +346,7 @@ area/space/atmosalert() icon_state = "shuttlered2" /area/shuttle/administration/centcom - name = "\improper Administration Shuttle Centcom" + name = "\improper Administration Shuttle CentCom" icon_state = "shuttlered" /area/shuttle/administration/station @@ -352,7 +354,7 @@ area/space/atmosalert() icon_state = "shuttlered2" /area/shuttle/trade/centcom - name = "\improper Trade Shuttle Centcom" + name = "\improper Trade Shuttle CentCom" icon_state = "shuttlered" /area/shuttle/trade/station @@ -388,9 +390,10 @@ area/space/atmosalert() // === Trying to remove these areas: /area/shuttle/research - name = "\improper Research Shuttle" + name = "\improper Research Elevator" music = "music/escape.ogg" lighting_use_dynamic = 0 + base_turf = /turf/simulated/mineral/floor/ignore_mapgen /area/shuttle/research/station icon_state = "shuttle2" @@ -412,34 +415,34 @@ area/space/atmosalert() // CENTCOM /area/centcom - name = "\improper Centcom" + name = "\improper CentCom" icon_state = "centcom" requires_power = 0 lighting_use_dynamic = 0 /area/centcom/control - name = "\improper Centcom Control" + name = "\improper CentCom Control" /area/centcom/evac - name = "\improper Centcom Emergency Shuttle" + name = "\improper CentCom Emergency Shuttle" /area/centcom/suppy - name = "\improper Centcom Supply Shuttle" + name = "\improper CentCom Supply Shuttle" /area/centcom/ferry - name = "\improper Centcom Transport Shuttle" + name = "\improper CentCom Transport Shuttle" /area/centcom/shuttle - name = "\improper Centcom Administration Shuttle" + name = "\improper CentCom Administration Shuttle" /area/centcom/test - name = "\improper Centcom Testing Facility" + name = "\improper CentCom Testing Facility" /area/centcom/living - name = "\improper Centcom Living Quarters" + name = "\improper CentCom Living Quarters" /area/centcom/specops - name = "\improper Centcom Special Ops" + name = "\improper CentCom Special Ops" /area/centcom/creed name = "Creed's Office" @@ -455,15 +458,15 @@ area/space/atmosalert() name = "\improper Tram Station" /area/centcom/security - name = "\improper Centcom Security" + name = "\improper CentCom Security" icon_state = "centcom_security" /area/centcom/medical - name = "\improper Centcom Medical" + name = "\improper CentCom Medical" icon_state = "centcom_medical" /area/centcom/command - name = "\improper Centcom Command" //Central Command Command totally isn't RAS Syndrome in action. + name = "\improper CentCom Command" //Central Command Command totally isn't RAS Syndrome in action. icon_state = "centcom_command" /area/centcom/main_hall @@ -471,15 +474,15 @@ area/space/atmosalert() icon_state = "centcom_hallway1" /area/centcom/bar - name = "\improper Centcom Bar" + name = "\improper CentCom Bar" icon_state = "centcom_crew" /area/centcom/restaurant - name = "\improper Centcom Restaurant" + name = "\improper CentCom Restaurant" icon_state = "centcom_crew" /area/centcom/bathroom - name = "\improper Centcom Bathroom" + name = "\improper CentCom Bathroom" icon_state = "centcom_crew" //SYNDICATES @@ -2319,6 +2322,7 @@ area/space/atmosalert() name = "\improper Construction Site Shuttle" icon_state = "yellow" lighting_use_dynamic = 0 + base_turf = /turf/simulated/mineral/floor/ignore_mapgen /area/shuttle/constructionsite/station name = "\improper Construction Site Shuttle" @@ -2527,20 +2531,20 @@ area/space/atmosalert() ambience = list('sound/ambience/ambisin2.ogg', 'sound/ambience/signal.ogg', 'sound/ambience/signal.ogg', 'sound/ambience/ambigen10.ogg') /area/tcommsat/entrance - name = "\improper Telecoms Teleporter" + name = "\improper Telecomms Teleporter" icon_state = "tcomsatentrance" /area/tcommsat/chamber - name = "\improper Telecoms Central Compartment" + name = "\improper Telecomms Central Compartment" icon_state = "tcomsatcham" /area/tcomsat - name = "\improper Telecoms Satellite" + name = "\improper Telecomms Satellite" icon_state = "tcomsatlob" ambience = list('sound/ambience/ambisin2.ogg', 'sound/ambience/signal.ogg', 'sound/ambience/signal.ogg', 'sound/ambience/ambigen10.ogg') /area/tcomfoyer - name = "\improper Telecoms Foyer" + name = "\improper Telecomms Foyer" icon_state = "tcomsatentrance" ambience = list('sound/ambience/ambisin2.ogg', 'sound/ambience/signal.ogg', 'sound/ambience/signal.ogg', 'sound/ambience/ambigen10.ogg') @@ -2555,7 +2559,7 @@ area/space/atmosalert() ambience = list('sound/ambience/ambisin2.ogg', 'sound/ambience/signal.ogg', 'sound/ambience/signal.ogg', 'sound/ambience/ambigen10.ogg') /area/tcommsat/computer - name = "\improper Telecoms Control Room" + name = "\improper Telecomms Control Room" icon_state = "tcomsatcomp" /area/tcommsat/lounge @@ -2632,7 +2636,7 @@ area/space/atmosalert() requires_power = 0 /area/awaymission/spacebattle/cruiser - name = "\improper Nanotrasen Cruiser" + name = "\improper NanoTrasen Cruiser" /area/awaymission/spacebattle/syndicate1 name = "\improper Syndicate Assault Ship 1" diff --git a/code/game/atoms.dm b/code/game/atoms.dm index 33f0635015..474b2d3b25 100644 --- a/code/game/atoms.dm +++ b/code/game/atoms.dm @@ -463,11 +463,11 @@ its easier to just keep the beam vertical. //spawn(0) //if(I) //It's possible that it could be deleted in the meantime. var/obj/O = I - O.show_message( message, 1, blind_message, 2) + O.show_message(message, 1, blind_message, 2) else if(ismob(I)) var/mob/M = I if(M.see_invisible >= invisibility) // Cannot view the invisible - M.show_message( message, 1, blind_message, 2) + M.show_message(message, 1, blind_message, 2) else if (blind_message) M.show_message(blind_message, 2) @@ -488,7 +488,24 @@ its easier to just keep the beam vertical. spawn(0) if(I) //It's possible that it could be deleted in the meantime. var/obj/O = I - O.show_message( message, 2, deaf_message, 1) + O.show_message(message, 2, deaf_message, 1) else if(ismob(I)) var/mob/M = I - M.show_message( message, 2, deaf_message, 1) + M.show_message(message, 2, deaf_message, 1) + +/atom/movable/proc/dropInto(var/atom/destination) + while(istype(destination)) + var/atom/drop_destination = destination.onDropInto(src) + if(!istype(drop_destination) || drop_destination == destination) + return forceMove(destination) + destination = drop_destination + return forceMove(null) + +/atom/proc/onDropInto(var/atom/movable/AM) + return // If onDropInto returns null, then dropInto will forceMove AM into us. + +/atom/movable/onDropInto(var/atom/movable/AM) + return loc // If onDropInto returns something, then dropInto will attempt to drop AM there. + +/atom/proc/InsertedContents() + return contents diff --git a/code/game/atoms_movable.dm b/code/game/atoms_movable.dm index e45be4bb6a..d164485f38 100644 --- a/code/game/atoms_movable.dm +++ b/code/game/atoms_movable.dm @@ -63,13 +63,35 @@ return /atom/movable/proc/forceMove(atom/destination) + if(loc == destination) + return 0 + var/is_origin_turf = isturf(loc) + var/is_destination_turf = isturf(destination) + // It is a new area if: + // Both the origin and destination are turfs with different areas. + // When either origin or destination is a turf and the other is not. + var/is_new_area = (is_origin_turf ^ is_destination_turf) || (is_origin_turf && is_destination_turf && loc.loc != destination.loc) + + var/atom/origin = loc + loc = destination + + if(origin) + origin.Exited(src, destination) + if(is_origin_turf) + for(var/atom/movable/AM in origin) + AM.Uncrossed(src) + if(is_new_area && is_origin_turf) + origin.loc.Exited(src, destination) + if(destination) - if(loc) - loc.Exited(src) - loc = destination - loc.Entered(src) - return 1 - return 0 + destination.Entered(src, origin) + if(is_destination_turf) // If we're entering a turf, cross all movable atoms + for(var/atom/movable/AM in loc) + if(AM != src) + AM.Crossed(src) + if(is_new_area && is_destination_turf) + destination.loc.Entered(src, origin) + return 1 //called when src is thrown into hit_atom /atom/movable/proc/throw_impact(atom/hit_atom, var/speed) diff --git a/code/game/dna/dna_modifier.dm b/code/game/dna/dna_modifier.dm index 56719fbce6..87971dd033 100644 --- a/code/game/dna/dna_modifier.dm +++ b/code/game/dna/dna_modifier.dm @@ -215,7 +215,7 @@ /obj/machinery/computer/scan_consolenew name = "DNA Modifier Access Console" - desc = "Scand DNA." + desc = "Scan DNA." icon = 'icons/obj/computer.dmi' icon_keyboard = "med_key" icon_screen = "dna" diff --git a/code/game/gamemodes/cult/runes.dm b/code/game/gamemodes/cult/runes.dm index 91d802c8bf..8425105020 100644 --- a/code/game/gamemodes/cult/runes.dm +++ b/code/game/gamemodes/cult/runes.dm @@ -273,6 +273,21 @@ var/list/sacrificed = list() for (,drain>0,drain-=5) sleep(2) user.heal_organ_damage(5, 0) + if(ishuman(user)) + var/mob/living/carbon/human/H = user + for(var/obj/item/organ/I in H.internal_organs) + if(I.damage > 0) + I.damage = max(I.damage - 5, 0) //Heals 5 damage per organ per use + if(I.damage <= 5 && I.organ_tag == O_EYES) + H.sdisabilities &= ~BLIND + for(var/obj/item/organ/E in H.bad_external_organs) + var/obj/item/organ/external/affected = E + if((affected.damage < affected.min_broken_damage * config.organ_health_multiplier) && (affected.status & ORGAN_BROKEN)) + affected.status &= ~ORGAN_BROKEN + for(var/datum/wound/W in affected.wounds) + if(istype(W, /datum/wound/internal_bleeding)) + affected.wounds -= W + affected.update_damages() return diff --git a/code/game/gamemodes/newobjective.dm b/code/game/gamemodes/newobjective.dm index e8ea12b84b..1d41289ea2 100644 --- a/code/game/gamemodes/newobjective.dm +++ b/code/game/gamemodes/newobjective.dm @@ -264,7 +264,7 @@ datum target = targeta job = joba weight = get_points(job) - explanation_text = "Frame [target.current.real_name], the [target.assigned_role] for a crime and make sure they are arrested and brought back to the Centcom station alive. We'll handle the rest from there." + explanation_text = "Frame [target.current.real_name], the [target.assigned_role] for a crime and make sure they are arrested and brought back to the CentCom station alive. We'll handle the rest from there." check_completion() if(!emergency_shuttle.returned()) diff --git a/code/game/gamemodes/ninja/ninja.dm b/code/game/gamemodes/ninja/ninja.dm index 9109d9297b..f17b693455 100644 --- a/code/game/gamemodes/ninja/ninja.dm +++ b/code/game/gamemodes/ninja/ninja.dm @@ -9,8 +9,8 @@ the omniscience of the AI and rival the most hardened weapons your station is capable of. Tread lightly and \ only hope this unknown assassin isn't here for you." config_tag = "ninja" - required_players = 1 - required_players_secret = 3 + required_players = 5 + required_players_secret = 5 required_enemies = 1 end_on_antag_death = 0 antag_tags = list(MODE_NINJA) \ No newline at end of file diff --git a/code/game/gamemodes/technomancer/clothing.dm b/code/game/gamemodes/technomancer/clothing.dm index ef243aa484..3c3c79d58e 100644 --- a/code/game/gamemodes/technomancer/clothing.dm +++ b/code/game/gamemodes/technomancer/clothing.dm @@ -9,27 +9,30 @@ /obj/item/clothing/under/technomancer name = "initiate's jumpsuit" - desc = "It's a blue colored jumpsuit. There appears to be light-weight armor padding underneath, providing some protection." + desc = "It's a blue colored jumpsuit. There appears to be light-weight armor padding underneath, providing some protection. \ + There is also a healthy amount of insulation underneath." icon_state = "initiate" armor = list(melee = 10, bullet = 5, laser = 5, energy = 0, bomb = 0, bio = 0, rad = 0) - siemens_coefficient = 0.9 + siemens_coefficient = 0.3 /obj/item/clothing/under/technomancer/apprentice name = "apprentice's jumpsuit" desc = "It's a blue colored jumpsuit with some silver markings. There appears to be light-weight armor padding \ - underneath, providing some protection." + underneath, providing some protection. There is also a healthy amount of insulation underneath." icon_state = "apprentice" /obj/item/clothing/under/technomancer/master name = "master's jumpsuit" desc = "It's a blue colored jumpsuit with some gold markings. There appears to be light-weight armor padding \ - underneath, providing some protection." + underneath, providing some protection. There is also a healthy amount of insulation underneath." icon_state = "technomancer" /obj/item/clothing/head/technomancer name = "initiate's hat" desc = "It's a somewhat silly looking blue pointed hat." icon_state = "initiate" + armor = list(melee = 10, bullet = 5, laser = 5, energy = 0, bomb = 0, bio = 0, rad = 0) + siemens_coefficient = 0.3 /obj/item/clothing/head/technomancer/apprentice name = "apprentice's hat" diff --git a/code/game/gamemodes/technomancer/devices/disposable_teleporter.dm b/code/game/gamemodes/technomancer/devices/disposable_teleporter.dm index 43f0f2737a..4ce5f8a16a 100644 --- a/code/game/gamemodes/technomancer/devices/disposable_teleporter.dm +++ b/code/game/gamemodes/technomancer/devices/disposable_teleporter.dm @@ -2,7 +2,7 @@ name = "Disposable Teleporter" desc = "An ultra-safe teleportation device that can directly teleport you to a number of locations at minimal risk, however \ it has a limited amount of charges." - cost = 100 + cost = 50 obj_path = /obj/item/weapon/disposable_teleporter /obj/item/weapon/disposable_teleporter diff --git a/code/game/gamemodes/technomancer/devices/shield_armor.dm b/code/game/gamemodes/technomancer/devices/shield_armor.dm index 7bcd52babe..3e4ddbce1f 100644 --- a/code/game/gamemodes/technomancer/devices/shield_armor.dm +++ b/code/game/gamemodes/technomancer/devices/shield_armor.dm @@ -6,7 +6,7 @@ of which your Core can provide. When you are struck by something, the shield will block 75% of the damage, deducting energy \ proportional to the amount of force that was inflicted. Armor penetration has no effect on the shield's ability to protect \ you from harm, however the shield will fail if the energy supply cannot meet demand." - cost = 300 + cost = 200 obj_path = /obj/item/clothing/suit/armor/shield /obj/item/clothing/suit/armor/shield diff --git a/code/game/gamemodes/technomancer/devices/tesla_armor.dm b/code/game/gamemodes/technomancer/devices/tesla_armor.dm index 1446afcba7..6b981aa8eb 100644 --- a/code/game/gamemodes/technomancer/devices/tesla_armor.dm +++ b/code/game/gamemodes/technomancer/devices/tesla_armor.dm @@ -4,7 +4,7 @@ the next attack you suffer, and strike the attacker with a strong bolt of lightning. This effect requires twenty seconds to \ recharge. If you are attacked while this is recharging, a weaker lightning bolt is sent out, however you won't be protected from \ the person beating you." - cost = 250 + cost = 150 obj_path = /obj/item/clothing/suit/armor/tesla /obj/item/clothing/suit/armor/tesla diff --git a/code/game/gamemodes/technomancer/equipment.dm b/code/game/gamemodes/technomancer/equipment.dm index 2e0fe3833a..4c94d2e7f0 100644 --- a/code/game/gamemodes/technomancer/equipment.dm +++ b/code/game/gamemodes/technomancer/equipment.dm @@ -11,7 +11,7 @@ desc = "A core optimized for passive regeneration, however at the cost of capacity. Has a capacity of 7,000 units of energy, and \ recharges at a rate of 70 units. Complex gravatics and force manipulation allows the wearer to also run slightly faster, and \ reduces incoming instability from functions by 10%." - cost = 150 + cost = 100 obj_path = /obj/item/weapon/technomancer_core/rapid /datum/technomancer/equipment/bulky_core @@ -20,7 +20,7 @@ purchase one or more energy-generating Functions as well if using this core. Has a capacity of 20,000 units of energy, \ and recharges at a rate of 25 units. The intense weight of the core unfortunately can cause the wear to move slightly slower, \ and the closeness of the capacitors causes a slight increase in incoming instability by 10%." - cost = 150 + cost = 100 obj_path = /obj/item/weapon/technomancer_core/bulky /datum/technomancer/equipment/unstable @@ -29,7 +29,7 @@ better as the user has more instability, which could prove dangerous to the inexperienced or unprepared. Has a capacity of 13,000 \ units of energy, and recharges at a rate of 35 units at no instability, and approximately 110 units when within the \ 'yellow zone' of instability. Incoming instability is also amplified by 30%, due to the nature of this core." - cost = 150 + cost = 100 obj_path = /obj/item/weapon/technomancer_core/unstable /datum/technomancer/equipment/recycling @@ -38,7 +38,7 @@ cores. The focus on efficency also makes instability less of an issue, as incoming instability from functions are reduced by \ 40%. The capacitor is also slightly better, holding 12,000 units of energy, however the reactor is slower to recharge, at a rate \ of 40 units." - cost = 150 + cost = 100 obj_path = /obj/item/weapon/technomancer_core/recycling /datum/technomancer/equipment/summoning @@ -47,13 +47,13 @@ entities from vast distances, and keeping them there. Wearers of this core can maintain up to 30 summons at once, and the energy \ demand for maintaining summons is severely reduced. This comes at the price of capcitors that can only hold 8,000 units of energy, \ a recharging rate of 35 energy, and no shielding from instability." - cost = 150 + cost = 100 obj_path = /obj/item/weapon/technomancer_core/summoner /datum/technomancer/equipment/hypo_belt name = "Hypo Belt" desc = "A medical belt designed to carry autoinjectors and other medical equipment. Comes with one of each hypo." - cost = 100 + cost = 50 obj_path = /obj/item/weapon/storage/belt/medical/technomancer /obj/item/weapon/storage/belt/medical/technomancer @@ -76,7 +76,7 @@ desc = "A belt with a literal pocket which opens to a localized pocket of 'Blue-Space', allowing for more storage. \ The nature of the pocket allows for storage of larger objects than what is typical for other belts, and in larger quanities. \ It will also help keep your pants on." - cost = 100 + cost = 50 obj_path = /obj/item/weapon/storage/belt/holding /obj/item/weapon/storage/belt/holding @@ -103,7 +103,7 @@ /datum/technomancer/equipment/omni_sight name = "Omnisight Scanner" desc = "A very rare scanner worn on the face, which allows the wearer to see nearly anything across walls." - cost = 400 + cost = 300 obj_path = /obj/item/clothing/glasses/omni /obj/item/clothing/glasses/omni @@ -122,7 +122,7 @@ name = "Medical HUD" desc = "A commonly available HUD for medical professionals, which displays how healthy an individual is. \ Recommended for support-based apprentices!" - cost = 30 + cost = 25 obj_path = /obj/item/clothing/glasses/thermal/plain/monocle /datum/technomancer/equipment/scepter @@ -130,7 +130,7 @@ desc = "A gem sometimes found in the depths of asteroids makes up the basis for this device. Energy is channeled into it from \ the Core and the user, causing many functions to be enhanced in various ways, so long as it is held in the off-hand. \ Be careful not to lose this!" - cost = 300 + cost = 200 obj_path = /obj/item/weapon/scepter /obj/item/weapon/scepter diff --git a/code/game/gamemodes/technomancer/instability.dm b/code/game/gamemodes/technomancer/instability.dm index 6be83aef7b..0de94cba7a 100644 --- a/code/game/gamemodes/technomancer/instability.dm +++ b/code/game/gamemodes/technomancer/instability.dm @@ -112,7 +112,7 @@ rng = rand(0,8) switch(rng) if(0) - apply_effect(instability * 0.5, IRRADIATE) + apply_effect(instability * 0.3, IRRADIATE) if(1) return // visible_message("\The [src] suddenly collapses!", @@ -120,21 +120,21 @@ // Weaken(instability * 0.1) if(2) if(can_feel_pain()) - apply_effect(instability * 0.5, AGONY) + apply_effect(instability * 0.3, AGONY) src << "You feel a sharp pain!" if(3) - apply_effect(instability * 0.5, EYE_BLUR) + apply_effect(instability * 0.3, EYE_BLUR) src << "Your eyes start to get cloudy!" if(4) electrocute_act(instability * 0.3, "unstable energies") if(5) - adjustFireLoss(instability * 0.2) //10 burn @ 50 instability + adjustFireLoss(instability * 0.15) //7.5 burn @ 50 instability src << "You feel your skin burn!" if(6) - adjustBruteLoss(instability * 0.2) //10 brute @ 50 instability + adjustBruteLoss(instability * 0.15) //7.5 brute @ 50 instability src << "You feel a sharp pain as an unseen force harms your body!" if(7) - adjustToxLoss(instability * 0.2) //10 tox @ 50 instability + adjustToxLoss(instability * 0.15) //7.5 tox @ 50 instability if(8) safe_blink(src, range = 6) src << "You're teleported against your will!" diff --git a/code/game/gamemodes/technomancer/spells/abjuration.dm b/code/game/gamemodes/technomancer/spells/abjuration.dm index 2422ef00bf..005f1561bf 100644 --- a/code/game/gamemodes/technomancer/spells/abjuration.dm +++ b/code/game/gamemodes/technomancer/spells/abjuration.dm @@ -2,7 +2,7 @@ name = "Abjuration" desc = "This ability attempts to send summoned or teleported entities or anomalies to the place from whence they came, or at least \ far away from the caster. Failing that, it may inhibit those entities in some form." - cost = 40 + cost = 25 obj_path = /obj/item/weapon/spell/abjuration category = UTILITY_SPELLS diff --git a/code/game/gamemodes/technomancer/spells/apportation.dm b/code/game/gamemodes/technomancer/spells/apportation.dm index 150559b9cd..9cc95b1e6e 100644 --- a/code/game/gamemodes/technomancer/spells/apportation.dm +++ b/code/game/gamemodes/technomancer/spells/apportation.dm @@ -2,7 +2,7 @@ name = "Apportation" desc = "This allows you to teleport objects into your hand, or to pull people towards you. If they're close enough, the function \ will grab them automatically." - cost = 50 + cost = 25 obj_path = /obj/item/weapon/spell/apportation category = UTILITY_SPELLS diff --git a/code/game/gamemodes/technomancer/spells/audible_deception.dm b/code/game/gamemodes/technomancer/spells/audible_deception.dm index 06930828af..970d983894 100644 --- a/code/game/gamemodes/technomancer/spells/audible_deception.dm +++ b/code/game/gamemodes/technomancer/spells/audible_deception.dm @@ -3,7 +3,7 @@ desc = "Allows you to create a specific sound at a location of your choosing." enhancement_desc = "An extremely loud sound that a large amount of energy and instability becomes available, which will \ deafen and stun all who are near the targeted tile, including yourself if unprotected." - cost = 150 + cost = 50 obj_path = /obj/item/weapon/spell/audible_deception ability_icon_state = "tech_audibledeception" category = UTILITY_SPELLS diff --git a/code/game/gamemodes/technomancer/spells/aura/biomed_aura.dm b/code/game/gamemodes/technomancer/spells/aura/biomed_aura.dm index 52cbdfbfdf..024002814e 100644 --- a/code/game/gamemodes/technomancer/spells/aura/biomed_aura.dm +++ b/code/game/gamemodes/technomancer/spells/aura/biomed_aura.dm @@ -1,7 +1,7 @@ /datum/technomancer/spell/biomed_aura name = "Restoration Aura" desc = "Heals you and your allies (or everyone, if you want) of trauma and burns slowly, as long as they remain within four meters." - cost = 150 + cost = 100 obj_path = /obj/item/weapon/spell/aura/biomed ability_icon_state = "tech_biomedaura" category = SUPPORT_SPELLS diff --git a/code/game/gamemodes/technomancer/spells/aura/fire_aura.dm b/code/game/gamemodes/technomancer/spells/aura/fire_aura.dm index 0c28f31577..5e1028192b 100644 --- a/code/game/gamemodes/technomancer/spells/aura/fire_aura.dm +++ b/code/game/gamemodes/technomancer/spells/aura/fire_aura.dm @@ -4,7 +4,7 @@ This does not affect you or your allies. It also causes a large amount of fire to erupt around you, however the main threat is \ still the heating up." enhancement_desc = "Increased heat generation, more fires, and higher temperature cap." - cost = 150 + cost = 100 obj_path = /obj/item/weapon/spell/aura/fire ability_icon_state = "tech_fireaura" category = OFFENSIVE_SPELLS @@ -21,13 +21,13 @@ qdel(src) var/list/nearby_things = range(4,owner) - var/temp_change = 25 - var/temp_cap = 500 + var/temp_change = 40 + var/temp_cap = 600 var/fire_power = 2 if(check_for_scepter()) - temp_change = 50 - temp_cap = 700 + temp_change = 80 + temp_cap = 1000 fire_power = 4 for(var/mob/living/carbon/human/H in nearby_things) if(is_ally(H)) diff --git a/code/game/gamemodes/technomancer/spells/aura/frost_aura.dm b/code/game/gamemodes/technomancer/spells/aura/frost_aura.dm index d5dd78b793..610702646d 100644 --- a/code/game/gamemodes/technomancer/spells/aura/frost_aura.dm +++ b/code/game/gamemodes/technomancer/spells/aura/frost_aura.dm @@ -3,7 +3,7 @@ desc = "Lowers the core body temperature of everyone around you (except for your friends), causing them to freeze to death if \ they stay within four meters of you." enhancement_desc = "The chill becomes lethal." - cost = 150 + cost = 100 obj_path = /obj/item/weapon/spell/aura/frost ability_icon_state = "tech_frostaura" category = DEFENSIVE_SPELLS // Scepter-less frost aura is nonlethal. diff --git a/code/game/gamemodes/technomancer/spells/aura/shock_aura.dm b/code/game/gamemodes/technomancer/spells/aura/shock_aura.dm index a9e50b2fa3..70ae416ec0 100644 --- a/code/game/gamemodes/technomancer/spells/aura/shock_aura.dm +++ b/code/game/gamemodes/technomancer/spells/aura/shock_aura.dm @@ -1,7 +1,7 @@ /datum/technomancer/spell/shock_aura name = "Electric Aura" desc = "Repeatively electrocutes enemies within four meters of you, as well as nearby electronics." - cost = 150 + cost = 100 obj_path = /obj/item/weapon/spell/aura/shock ability_icon_state = "tech_shockaura" category = OFFENSIVE_SPELLS diff --git a/code/game/gamemodes/technomancer/spells/blink.dm b/code/game/gamemodes/technomancer/spells/blink.dm index 9dae12e39e..19f6e84c83 100644 --- a/code/game/gamemodes/technomancer/spells/blink.dm +++ b/code/game/gamemodes/technomancer/spells/blink.dm @@ -3,7 +3,7 @@ desc = "Force the target to teleport a short distance away. This target could be anything from something lying on the ground, to someone trying to \ fight you, or even yourself. Using this on someone next to you makes their potential distance after teleportation greater." enhancement_desc = "Blink distance is increased greatly." - cost = 100 + cost = 50 obj_path = /obj/item/weapon/spell/blink category = UTILITY_SPELLS diff --git a/code/game/gamemodes/technomancer/spells/control.dm b/code/game/gamemodes/technomancer/spells/control.dm index b5eaad8f44..17fb821d35 100644 --- a/code/game/gamemodes/technomancer/spells/control.dm +++ b/code/game/gamemodes/technomancer/spells/control.dm @@ -5,7 +5,7 @@ targets. This function will have no effect on entities of higher intelligence, such as humans and similar alien species, as it's \ not true mind control, but merely pheromone synthesis for living animals, and electronic hacking for simple robots. The green web \ around the entity is merely a hologram used to allow the user to know if the creature is safe or not." - cost = 200 + cost = 100 obj_path = /obj/item/weapon/spell/control category = UTILITY_SPELLS diff --git a/code/game/gamemodes/technomancer/spells/energy_siphon.dm b/code/game/gamemodes/technomancer/spells/energy_siphon.dm index 0e8e23ffd8..ad379b2d3c 100644 --- a/code/game/gamemodes/technomancer/spells/energy_siphon.dm +++ b/code/game/gamemodes/technomancer/spells/energy_siphon.dm @@ -4,7 +4,7 @@ Every second, electricity is stolen until the link is broken by the target moving too far away, or having no more energy left. \ Can drain from powercells, microbatteries, and other Cores. The beam created by the siphoning is harmful to touch." enhancement_desc = "Rate of siphoning is doubled." - cost = 150 + cost = 100 obj_path = /obj/item/weapon/spell/energy_siphon ability_icon_state = "tech_energysiphon" category = UTILITY_SPELLS diff --git a/code/game/gamemodes/technomancer/spells/flame_tongue.dm b/code/game/gamemodes/technomancer/spells/flame_tongue.dm index 5afa25ae90..923cde0b9d 100644 --- a/code/game/gamemodes/technomancer/spells/flame_tongue.dm +++ b/code/game/gamemodes/technomancer/spells/flame_tongue.dm @@ -1,7 +1,7 @@ /datum/technomancer/spell/flame_tongue name = "Flame Tongue" desc = "Using a miniturized flamethrower in your gloves, you can emit a flame strong enough to melt both your enemies and walls." - cost = 100 + cost = 50 obj_path = /obj/item/weapon/spell/flame_tongue ability_icon_state = "tech_flametongue" category = OFFENSIVE_SPELLS diff --git a/code/game/gamemodes/technomancer/spells/illusion.dm b/code/game/gamemodes/technomancer/spells/illusion.dm index e450e4480f..9667df1db4 100644 --- a/code/game/gamemodes/technomancer/spells/illusion.dm +++ b/code/game/gamemodes/technomancer/spells/illusion.dm @@ -2,7 +2,7 @@ name = "Illusion" desc = "Allows you to create and control a holographic illusion, that can take the form of most object or entities." enhancement_desc = "Illusions will be made of hard light, allowing the interception of attacks, appearing more realistic." - cost = 100 + cost = 25 obj_path = /obj/item/weapon/spell/illusion ability_icon_state = "tech_illusion" category = UTILITY_SPELLS diff --git a/code/game/gamemodes/technomancer/spells/insert/corona.dm b/code/game/gamemodes/technomancer/spells/insert/corona.dm index bde3ee9984..a070108a68 100644 --- a/code/game/gamemodes/technomancer/spells/insert/corona.dm +++ b/code/game/gamemodes/technomancer/spells/insert/corona.dm @@ -2,7 +2,7 @@ name = "Corona" desc = "Causes the victim to glow very brightly, which while harmless in itself, makes it easier for them to be hit. The \ bright glow also makes it very difficult to be stealthy. The effect lasts for one minute." - cost = 100 + cost = 50 obj_path = /obj/item/weapon/spell/insert/corona ability_icon_state = "tech_corona" category = SUPPORT_SPELLS diff --git a/code/game/gamemodes/technomancer/spells/insert/mend_organs.dm b/code/game/gamemodes/technomancer/spells/insert/mend_organs.dm index e9450b9586..a43bb7611d 100644 --- a/code/game/gamemodes/technomancer/spells/insert/mend_organs.dm +++ b/code/game/gamemodes/technomancer/spells/insert/mend_organs.dm @@ -2,7 +2,7 @@ name = "Mend Organs" desc = "Heals the target's internal organs, both organic and robotic. Instability is split between the target \ and technomancer, if seperate." - cost = 75 + cost = 50 obj_path = /obj/item/weapon/spell/insert/mend_organs ability_icon_state = "tech_mendwounds" category = SUPPORT_SPELLS diff --git a/code/game/gamemodes/technomancer/spells/insert/repel_missiles.dm b/code/game/gamemodes/technomancer/spells/insert/repel_missiles.dm index 8fb549039f..a95afa0a1f 100644 --- a/code/game/gamemodes/technomancer/spells/insert/repel_missiles.dm +++ b/code/game/gamemodes/technomancer/spells/insert/repel_missiles.dm @@ -2,7 +2,7 @@ name = "Repel Missiles" desc = "Places a repulsion field around you, which attempts to deflect incoming bullets and lasers, making them 30% less likely \ to hit you. The field lasts for five minutes and can be granted to yourself or an ally." - cost = 60 + cost = 25 obj_path = /obj/item/weapon/spell/insert/repel_missiles ability_icon_state = "tech_repelmissiles" category = SUPPORT_SPELLS diff --git a/code/game/gamemodes/technomancer/spells/instability_tap.dm b/code/game/gamemodes/technomancer/spells/instability_tap.dm index ada2989444..8ad52f3b3f 100644 --- a/code/game/gamemodes/technomancer/spells/instability_tap.dm +++ b/code/game/gamemodes/technomancer/spells/instability_tap.dm @@ -2,7 +2,7 @@ name = "Instability Tap" desc = "Creates a large sum of energy, at the cost of a very large amount of instability afflicting you." enhancement_desc = "50% more energy gained, 20% less instability gained." - cost = 120 + cost = 100 obj_path = /obj/item/weapon/spell/instability_tap ability_icon_state = "tech_instabilitytap" category = UTILITY_SPELLS diff --git a/code/game/gamemodes/technomancer/spells/mark_recall.dm b/code/game/gamemodes/technomancer/spells/mark_recall.dm index 63e6d67fad..528b860094 100644 --- a/code/game/gamemodes/technomancer/spells/mark_recall.dm +++ b/code/game/gamemodes/technomancer/spells/mark_recall.dm @@ -3,7 +3,7 @@ desc = "This function places a specific 'mark' beacon under you, which is used by the Recall function as a destination. \ Note that using Mark again will move the destination instead of creating a second destination, and only one destination \ can exist, regardless of who casted Mark." - cost = 50 + cost = 25 obj_path = /obj/item/weapon/spell/mark ability_icon_state = "tech_mark" category = UTILITY_SPELLS @@ -50,7 +50,7 @@ desc = "This function teleports you to where you placed a mark using the Mark function. Without the Mark function, this \ function is useless. Note that teleporting takes three seconds. Being incapacitated while teleporting will cancel it." enhancement_desc = "Recall takes two seconds instead of three." - cost = 50 + cost = 25 obj_path = /obj/item/weapon/spell/recall ability_icon_state = "tech_recall" category = UTILITY_SPELLS diff --git a/code/game/gamemodes/technomancer/spells/oxygenate.dm b/code/game/gamemodes/technomancer/spells/oxygenate.dm index 3f9bb6f9e5..f1edc635c1 100644 --- a/code/game/gamemodes/technomancer/spells/oxygenate.dm +++ b/code/game/gamemodes/technomancer/spells/oxygenate.dm @@ -2,7 +2,7 @@ name = "Oxygenate" desc = "This function creates oxygen at a location of your chosing. If used on a humanoid entity, it heals oxygen deprivation. \ If casted on the envirnment, air (oxygen and nitrogen) is moved from a distant location to your target." - cost = 70 + cost = 50 obj_path = /obj/item/weapon/spell/oxygenate ability_icon_state = "oxygenate" category = SUPPORT_SPELLS diff --git a/code/game/gamemodes/technomancer/spells/phase_shift.dm b/code/game/gamemodes/technomancer/spells/phase_shift.dm index 20fb033872..a571d6789d 100644 --- a/code/game/gamemodes/technomancer/spells/phase_shift.dm +++ b/code/game/gamemodes/technomancer/spells/phase_shift.dm @@ -2,7 +2,7 @@ name = "Phase Shift" desc = "Hides you in the safest possible place, where no harm can come to you. Unfortunately you can only stay inside for a few moments before \ draining your powercell." - cost = 80 + cost = 50 obj_path = /obj/item/weapon/spell/phase_shift category = DEFENSIVE_SPELLS diff --git a/code/game/gamemodes/technomancer/spells/projectile/beam.dm b/code/game/gamemodes/technomancer/spells/projectile/beam.dm index 429a83dd9b..13d5fe934a 100644 --- a/code/game/gamemodes/technomancer/spells/projectile/beam.dm +++ b/code/game/gamemodes/technomancer/spells/projectile/beam.dm @@ -1,7 +1,7 @@ /datum/technomancer/spell/beam name = "Beam" desc = "Fires a laser at your target. Cheap, reliable, and a bit boring." - cost = 150 + cost = 100 ability_icon_state = "tech_beam" obj_path = /obj/item/weapon/spell/projectile/beam category = OFFENSIVE_SPELLS diff --git a/code/game/gamemodes/technomancer/spells/projectile/force_missile.dm b/code/game/gamemodes/technomancer/spells/projectile/force_missile.dm index dad3c88f45..ab295f58f3 100644 --- a/code/game/gamemodes/technomancer/spells/projectile/force_missile.dm +++ b/code/game/gamemodes/technomancer/spells/projectile/force_missile.dm @@ -2,7 +2,7 @@ name = "Force Missile" desc = "This fires a missile at your target. It's cheap to use, however the projectile itself moves and impacts in such a way \ that armor designed to protect from blunt force will mitigate this function as well." - cost = 100 + cost = 50 obj_path = /obj/item/weapon/spell/projectile/force_missile category = OFFENSIVE_SPELLS diff --git a/code/game/gamemodes/technomancer/spells/projectile/overload.dm b/code/game/gamemodes/technomancer/spells/projectile/overload.dm index e6f0c898e2..90bf50e7d6 100644 --- a/code/game/gamemodes/technomancer/spells/projectile/overload.dm +++ b/code/game/gamemodes/technomancer/spells/projectile/overload.dm @@ -2,7 +2,7 @@ name = "Overload" desc = "Fires a bolt of highly unstable energy, that does damaged equal to 1.5% of the technomancer's current reserve of energy. \ This energy pierces all known armor." - cost = 150 + cost = 100 obj_path = /obj/item/weapon/spell/projectile/overload category = OFFENSIVE_SPELLS diff --git a/code/game/gamemodes/technomancer/spells/projectile/projectile.dm b/code/game/gamemodes/technomancer/spells/projectile/projectile.dm index 69e1efc92f..ea2f0db4e3 100644 --- a/code/game/gamemodes/technomancer/spells/projectile/projectile.dm +++ b/code/game/gamemodes/technomancer/spells/projectile/projectile.dm @@ -10,10 +10,9 @@ var/fire_sound = null /obj/item/weapon/spell/projectile/on_ranged_cast(atom/hit_atom, mob/living/user) - var/turf/T = get_turf(hit_atom) if(set_up(hit_atom, user)) var/obj/item/projectile/new_projectile = new spell_projectile(get_turf(user)) - new_projectile.launch(T) + new_projectile.launch(hit_atom) if(fire_sound) playsound(get_turf(src), fire_sound, 75, 1) owner.adjust_instability(instability_per_shot) diff --git a/code/game/gamemodes/technomancer/spells/radiance.dm b/code/game/gamemodes/technomancer/spells/radiance.dm index 9d484ddc5c..7cd7694122 100644 --- a/code/game/gamemodes/technomancer/spells/radiance.dm +++ b/code/game/gamemodes/technomancer/spells/radiance.dm @@ -1,7 +1,7 @@ /datum/technomancer/spell/radiance name = "Radiance" desc = "Causes you to be very radiant, glowing brightly in visible light, thermal energy, and deadly ionizing radiation." - cost = 180 + cost = 100 obj_path = /obj/item/weapon/spell/radiance category = OFFENSIVE_SPELLS diff --git a/code/game/gamemodes/technomancer/spells/reflect.dm b/code/game/gamemodes/technomancer/spells/reflect.dm index 7a8fa0a4de..d841db2acc 100644 --- a/code/game/gamemodes/technomancer/spells/reflect.dm +++ b/code/game/gamemodes/technomancer/spells/reflect.dm @@ -1,7 +1,7 @@ /datum/technomancer/spell/reflect name = "Reflect" desc = "Emits a protective shield fron your hand in front of you, which will reflect one attack back at the attacker." - cost = 120 + cost = 100 obj_path = /obj/item/weapon/spell/reflect ability_icon_state = "tech_reflect" category = DEFENSIVE_SPELLS @@ -22,7 +22,7 @@ spark_system = PoolOrNew(/datum/effect/effect/system/spark_spread) spark_system.set_up(5, 0, src) owner << "Your shield will expire in 3 seconds!" - spawn(3 SECONDS) + spawn(5 SECONDS) if(src) owner << "Your shield expires!" qdel(src) @@ -67,7 +67,7 @@ if(!reflecting) reflecting = 1 - spawn(1 SECOND) //To ensure that most or all of a burst fire cycle is reflected. + spawn(2 SECONDS) //To ensure that most or all of a burst fire cycle is reflected. owner << "Your shield fades due being used up!" qdel(src) @@ -87,7 +87,7 @@ if(!reflecting) reflecting = 1 - spawn(1 SECOND) //To ensure that most or all of a burst fire cycle is reflected. + spawn(2 SECONDS) //To ensure that most or all of a burst fire cycle is reflected. owner << "Your shield fades due being used up!" qdel(src) return 1 diff --git a/code/game/gamemodes/technomancer/spells/shield.dm b/code/game/gamemodes/technomancer/spells/shield.dm index 330de0ff26..ac6910c478 100644 --- a/code/game/gamemodes/technomancer/spells/shield.dm +++ b/code/game/gamemodes/technomancer/spells/shield.dm @@ -2,7 +2,7 @@ name = "Shield" desc = "Emits a protective shield fron your hand in front of you, which will protect you from almost anything able to harm \ you, so long as you can power it." - cost = 120 + cost = 100 obj_path = /obj/item/weapon/spell/shield ability_icon_state = "tech_shield" category = DEFENSIVE_SPELLS diff --git a/code/game/gamemodes/technomancer/spells/spawner/darkness.dm b/code/game/gamemodes/technomancer/spells/spawner/darkness.dm index ac5e799d72..ecb18b3481 100644 --- a/code/game/gamemodes/technomancer/spells/spawner/darkness.dm +++ b/code/game/gamemodes/technomancer/spells/spawner/darkness.dm @@ -1,7 +1,7 @@ /datum/technomancer/spell/darkness name = "Darkness" desc = "Disrupts photons moving in a local area, causing darkness to shroud yourself or a position of your choosing." - cost = 30 + cost = 25 obj_path = /obj/item/weapon/spell/spawner/darkness category = UTILITY_SPELLS diff --git a/code/game/gamemodes/technomancer/spells/spawner/pulsar.dm b/code/game/gamemodes/technomancer/spells/spawner/pulsar.dm index a2c22b0f76..c1b016116a 100644 --- a/code/game/gamemodes/technomancer/spells/spawner/pulsar.dm +++ b/code/game/gamemodes/technomancer/spells/spawner/pulsar.dm @@ -1,7 +1,7 @@ /datum/technomancer/spell/pulsar name = "Pulsar" desc = "Emits electronic pulses to destroy, disable, or otherwise harm devices and machines. Be sure to not hit yourself with this." - cost = 150 + cost = 100 obj_path = /obj/item/weapon/spell/spawner/pulsar category = OFFENSIVE_SPELLS diff --git a/code/game/gamemodes/technomancer/spells/summon/summon_creature.dm b/code/game/gamemodes/technomancer/spells/summon/summon_creature.dm index 497a8422bd..053f449095 100644 --- a/code/game/gamemodes/technomancer/spells/summon/summon_creature.dm +++ b/code/game/gamemodes/technomancer/spells/summon/summon_creature.dm @@ -6,7 +6,7 @@ The creatures take a few moments to be teleported to the targeted tile. Note that the creatures summoned are \ not inherently loyal to the technomancer, and that the creatures will be hurt slightly from being teleported to you." enhancement_desc = "Summoned entities will never harm their summoner." - cost = 200 + cost = 100 obj_path = /obj/item/weapon/spell/summon/summon_creature category = UTILITY_SPELLS diff --git a/code/game/gamemodes/technomancer/spells/summon/summon_ward.dm b/code/game/gamemodes/technomancer/spells/summon/summon_ward.dm index 5323c5beda..e4154eddf2 100644 --- a/code/game/gamemodes/technomancer/spells/summon/summon_ward.dm +++ b/code/game/gamemodes/technomancer/spells/summon/summon_ward.dm @@ -3,7 +3,7 @@ desc = "Teleports a prefabricated 'ward' drone to the target location, which will alert you and your allies when it sees entities \ moving around it, or when it is attacked. They can see for up to five meters. Wards expire in six minutes." enhancement_desc = "Wards can detect invisibile entities, and are more specific in relaying information about what it sees." - cost = 100 + cost = 25 obj_path = /obj/item/weapon/spell/summon/summon_ward category = UTILITY_SPELLS @@ -84,6 +84,9 @@ if(L.alpha <= 127) continue // Too transparent, as a mercy to camo lings. + else + L.break_cloak() + // Warn the Technomancer when it sees a new mob. if(!(L in seen_mobs)) seen_mobs.Add(L) @@ -111,3 +114,7 @@ overlays.Cut() var/image/I = image('icons/mob/critter.dmi',"ward_truesight") overlays.Add(I) + +/mob/living/simple_animal/ward/invisible_detect + true_sight = 1 + see_invisible = SEE_INVISIBLE_LEVEL_TWO diff --git a/code/game/gamemodes/technomancer/spells/targeting_matrix.dm b/code/game/gamemodes/technomancer/spells/targeting_matrix.dm index aff00f0197..b227748aeb 100644 --- a/code/game/gamemodes/technomancer/spells/targeting_matrix.dm +++ b/code/game/gamemodes/technomancer/spells/targeting_matrix.dm @@ -2,7 +2,7 @@ name = "Targeting Matrix" desc = "Automatically targets and fires a ranged weapon or function at a non-friendly target near a targeted tile. \ Each target assisted attack costs some energy and instability." - cost = 150 + cost = 50 ability_icon_state = "tech_targetingmatrix" obj_path = /obj/item/weapon/spell/targeting_matrix category = UTILITY_SPELLS diff --git a/code/game/gamemodes/technomancer/spells/warp_strike.dm b/code/game/gamemodes/technomancer/spells/warp_strike.dm index a308066ae5..11b3ba032e 100644 --- a/code/game/gamemodes/technomancer/spells/warp_strike.dm +++ b/code/game/gamemodes/technomancer/spells/warp_strike.dm @@ -1,7 +1,7 @@ /datum/technomancer/spell/warp_strike name = "Warp Strike" desc = "Teleports you next to your target, and attacks them with whatever is in your off-hand, spell or object." - cost = 200 + cost = 100 obj_path = /obj/item/weapon/spell/warp_strike ability_icon_state = "tech_warpstrike" category = OFFENSIVE_SPELLS diff --git a/code/game/gamemodes/technomancer/technomancer.dm b/code/game/gamemodes/technomancer/technomancer.dm index a7131fb54c..cf37046d0f 100644 --- a/code/game/gamemodes/technomancer/technomancer.dm +++ b/code/game/gamemodes/technomancer/technomancer.dm @@ -7,8 +7,8 @@ their powers can be used for good or if their arrival foreshadows the destruction of the entire colony, or worse." config_tag = "technomancer" votable = 0 - required_players = 8 - required_players_secret = 10 + required_players = 5 + required_players_secret = 5 required_enemies = 1 end_on_antag_death = 0 antag_tags = list(MODE_TECHNOMANCER) \ No newline at end of file diff --git a/code/game/jobs/access.dm b/code/game/jobs/access.dm index c5d8f8f445..25acb8caa7 100644 --- a/code/game/jobs/access.dm +++ b/code/game/jobs/access.dm @@ -239,6 +239,11 @@ proc/get_all_job_icons() //For all existing HUD icons if(I.rank in job_icons) return I.rank + var/centcom = get_all_centcom_jobs() + if(I.assignment in centcom) //Return with the NT logo if it is a CentCom job + return "CentCom" + if(I.rank in centcom) + return "CentCom" else return diff --git a/code/game/jobs/job/assistant.dm b/code/game/jobs/job/assistant.dm index 5e2b40d952..cc0faede19 100644 --- a/code/game/jobs/job/assistant.dm +++ b/code/game/jobs/job/assistant.dm @@ -19,6 +19,7 @@ if(2) H.equip_to_slot_or_del(new /obj/item/weapon/storage/backpack(H), slot_back) if(3) H.equip_to_slot_or_del(new /obj/item/weapon/storage/backpack/satchel/norm(H), slot_back) if(4) H.equip_to_slot_or_del(new /obj/item/weapon/storage/backpack/satchel(H), slot_back) + if(5) H.equip_to_slot_or_del(new /obj/item/weapon/storage/backpack/messenger(H), slot_back) if(has_alt_title(H, alt_title,"Visitor")) //I doubt someone visiting the station would want to wear an ugly grey uniform H.equip_to_slot_or_del(new /obj/item/clothing/under/assistantformal(H), slot_w_uniform) else if(has_alt_title(H, alt_title,"Resident")) diff --git a/code/game/jobs/job/captain.dm b/code/game/jobs/job/captain.dm index c091a599c3..a98bfe4544 100644 --- a/code/game/jobs/job/captain.dm +++ b/code/game/jobs/job/captain.dm @@ -30,6 +30,7 @@ var/datum/announcement/minor/captain_announcement = new(do_newscast = 1) if(2) H.equip_to_slot_or_del(new /obj/item/weapon/storage/backpack/captain(H), slot_back) if(3) H.equip_to_slot_or_del(new /obj/item/weapon/storage/backpack/satchel/cap(H), slot_back) if(4) H.equip_to_slot_or_del(new /obj/item/weapon/storage/backpack/satchel(H), slot_back) + if(5) H.equip_to_slot_or_del(new /obj/item/weapon/storage/backpack/messenger/com(H), slot_back) H.equip_to_slot_or_del(new /obj/item/clothing/under/rank/captain(H), slot_w_uniform) if(H.age>49) // Since we can have something other than the default uniform at this @@ -109,4 +110,39 @@ var/datum/announcement/minor/captain_announcement = new(do_newscast = 1) else H.equip_to_slot_or_del(new /obj/item/weapon/storage/box/ids(H.back), slot_in_backpack) H.implant_loyalty() - return 1 \ No newline at end of file + return 1 + +/datum/job/secretary + title = "Command Secretary" + flag = BRIDGE + department = "Civilian" + head_position = 1 + department_flag = CIVILIAN + faction = "Station" + total_positions = 2 + spawn_positions = 2 + supervisors = "command staff" + selection_color = "#2F2F7F" + idtype = /obj/item/weapon/card/id/silver + alt_titles = list("Command Liaison", "Bridge Secretary") + minimal_player_age = 5 + economic_modifier = 7 + + access = list(access_heads) + minimal_access = list(access_heads) + +/datum/job/secretary/equip(var/mob/living/carbon/human/H) + if(!H) return 0 + H.equip_to_slot_or_del(new /obj/item/device/radio/headset/headset_com(H), slot_l_ear) + switch(H.backbag) + if(2) H.equip_to_slot_or_del(new /obj/item/weapon/storage/backpack(H), slot_back) + if(3) H.equip_to_slot_or_del(new /obj/item/weapon/storage/backpack/satchel/norm(H), slot_back) + if(4) H.equip_to_slot_or_del(new /obj/item/weapon/storage/backpack/satchel(H), slot_back) + H.equip_to_slot_or_del(new /obj/item/clothing/shoes/brown(H), slot_shoes) + H.equip_to_slot_or_del(new /obj/item/device/pda/heads/hop(H), slot_belt) + H.equip_to_slot_or_del(new /obj/item/weapon/storage/briefcase(H), slot_l_hand) + if(H.gender == FEMALE) + H.equip_to_slot_or_del(new /obj/item/clothing/under/suit_jacket/female/skirt(H), slot_w_uniform) + else + H.equip_to_slot_or_del(new /obj/item/clothing/under/suit_jacket/charcoal(H), slot_w_uniform) + return 1 \ No newline at end of file diff --git a/code/game/jobs/job/civilian.dm b/code/game/jobs/job/civilian.dm index b617c65da9..a8e4d3f3f6 100644 --- a/code/game/jobs/job/civilian.dm +++ b/code/game/jobs/job/civilian.dm @@ -21,6 +21,7 @@ if(2) H.equip_to_slot_or_del(new /obj/item/weapon/storage/backpack(H), slot_back) if(3) H.equip_to_slot_or_del(new /obj/item/weapon/storage/backpack/satchel/norm(H), slot_back) if(4) H.equip_to_slot_or_del(new /obj/item/weapon/storage/backpack/satchel(H), slot_back) + if(5) H.equip_to_slot_or_del(new /obj/item/weapon/storage/backpack/messenger(H), slot_back) H.equip_to_slot_or_del(new /obj/item/device/radio/headset/headset_service(H), slot_l_ear) H.equip_to_slot_or_del(new /obj/item/clothing/shoes/black(H), slot_shoes) H.equip_to_slot_or_del(new /obj/item/clothing/under/rank/bartender(H), slot_w_uniform) @@ -86,6 +87,7 @@ if(2) H.equip_to_slot_or_del(new /obj/item/weapon/storage/backpack/hydroponics(H), slot_back) if(3) H.equip_to_slot_or_del(new /obj/item/weapon/storage/backpack/satchel/hyd(H), slot_back) if(4) H.equip_to_slot_or_del(new /obj/item/weapon/storage/backpack/satchel(H), slot_back) + if(5) H.equip_to_slot_or_del(new /obj/item/weapon/storage/backpack/messenger/hyd(H), slot_back) return 1 @@ -171,6 +173,7 @@ if(2) H.equip_to_slot_or_del(new /obj/item/weapon/storage/backpack/industrial(H), slot_back) if(3) H.equip_to_slot_or_del(new /obj/item/weapon/storage/backpack/satchel/eng(H), slot_back) if(4) H.equip_to_slot_or_del(new /obj/item/weapon/storage/backpack/satchel(H), slot_back) + if(5) H.equip_to_slot_or_del(new /obj/item/weapon/storage/backpack/messenger/engi(H), slot_back) H.equip_to_slot_or_del(new /obj/item/clothing/under/rank/miner(H), slot_w_uniform) H.equip_to_slot_or_del(new /obj/item/device/pda/shaftminer(H), slot_belt) H.equip_to_slot_or_del(new /obj/item/clothing/shoes/black(H), slot_shoes) @@ -265,6 +268,7 @@ if(2) H.equip_to_slot_or_del(new /obj/item/weapon/storage/backpack(H), slot_back) if(3) H.equip_to_slot_or_del(new /obj/item/weapon/storage/backpack/satchel/norm(H), slot_back) if(4) H.equip_to_slot_or_del(new /obj/item/weapon/storage/backpack/satchel(H), slot_back) + if(5) H.equip_to_slot_or_del(new /obj/item/weapon/storage/backpack/messenger(H), slot_back) H.equip_to_slot_or_del(new /obj/item/clothing/under/rank/internalaffairs(H), slot_w_uniform) H.equip_to_slot_or_del(new /obj/item/clothing/suit/storage/toggle/internalaffairs(H), slot_wear_suit) H.equip_to_slot_or_del(new /obj/item/clothing/shoes/brown(H), slot_shoes) diff --git a/code/game/jobs/job/engineering.dm b/code/game/jobs/job/engineering.dm index 53c642b816..227297ca05 100644 --- a/code/game/jobs/job/engineering.dm +++ b/code/game/jobs/job/engineering.dm @@ -35,6 +35,7 @@ if(2) H.equip_to_slot_or_del(new /obj/item/weapon/storage/backpack/industrial(H), slot_back) if(3) H.equip_to_slot_or_del(new /obj/item/weapon/storage/backpack/satchel/eng(H), slot_back) if(4) H.equip_to_slot_or_del(new /obj/item/weapon/storage/backpack/satchel(H), slot_back) + if(5) H.equip_to_slot_or_del(new /obj/item/weapon/storage/backpack/messenger/engi(H), slot_back) H.equip_to_slot_or_del(new /obj/item/clothing/under/rank/chief_engineer(H), slot_w_uniform) H.equip_to_slot_or_del(new /obj/item/device/pda/heads/ce(H), slot_l_store) H.equip_to_slot_or_del(new /obj/item/clothing/shoes/workboots(H), slot_shoes) @@ -73,6 +74,7 @@ if(2) H.equip_to_slot_or_del(new /obj/item/weapon/storage/backpack/industrial(H), slot_back) if(3) H.equip_to_slot_or_del(new /obj/item/weapon/storage/backpack/satchel/eng(H), slot_back) if(4) H.equip_to_slot_or_del(new /obj/item/weapon/storage/backpack/satchel(H), slot_back) + if(5) H.equip_to_slot_or_del(new /obj/item/weapon/storage/backpack/messenger/engi(H), slot_back) H.equip_to_slot_or_del(new /obj/item/clothing/under/rank/engineer(H), slot_w_uniform) H.equip_to_slot_or_del(new /obj/item/clothing/shoes/workboots(H), slot_shoes) H.equip_to_slot_or_del(new /obj/item/weapon/storage/belt/utility/full(H), slot_belt) @@ -111,6 +113,7 @@ if(2) H.equip_to_slot_or_del(new /obj/item/weapon/storage/backpack(H), slot_back) if(3) H.equip_to_slot_or_del(new /obj/item/weapon/storage/backpack/satchel/norm(H), slot_back) if(4) H.equip_to_slot_or_del(new /obj/item/weapon/storage/backpack/satchel(H), slot_back) + if(5) H.equip_to_slot_or_del(new /obj/item/weapon/storage/backpack/messenger/engi(H), slot_back) H.equip_to_slot_or_del(new /obj/item/clothing/under/rank/atmospheric_technician(H), slot_w_uniform) H.equip_to_slot_or_del(new /obj/item/clothing/shoes/workboots(H), slot_shoes) H.equip_to_slot_or_del(new /obj/item/device/pda/atmos(H), slot_l_store) diff --git a/code/game/jobs/job/job.dm b/code/game/jobs/job/job.dm index 6c575bef00..6add65ce55 100644 --- a/code/game/jobs/job/job.dm +++ b/code/game/jobs/job/job.dm @@ -33,6 +33,7 @@ if(2) H.equip_to_slot_or_del(new /obj/item/weapon/storage/backpack(H), slot_back) if(3) H.equip_to_slot_or_del(new /obj/item/weapon/storage/backpack/satchel/norm(H), slot_back) if(4) H.equip_to_slot_or_del(new /obj/item/weapon/storage/backpack/satchel(H), slot_back) + if(5) H.equip_to_slot_or_del(new /obj/item/weapon/storage/backpack/messenger(H), slot_back) /datum/job/proc/equip_survival(var/mob/living/carbon/human/H) if(!H) return 0 diff --git a/code/game/jobs/job/medical.dm b/code/game/jobs/job/medical.dm index 69a94f0ade..0c2053f8d6 100644 --- a/code/game/jobs/job/medical.dm +++ b/code/game/jobs/job/medical.dm @@ -30,6 +30,7 @@ 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(5) H.equip_to_slot_or_del(new /obj/item/weapon/storage/backpack/messenger/med(H), slot_back) H.equip_to_slot_or_del(new /obj/item/clothing/under/rank/chief_medical_officer(H), slot_w_uniform) H.equip_to_slot_or_del(new /obj/item/clothing/shoes/brown(H), slot_shoes) H.equip_to_slot_or_del(new /obj/item/device/pda/heads/cmo(H), slot_belt) @@ -63,6 +64,7 @@ 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(5) H.equip_to_slot_or_del(new /obj/item/weapon/storage/backpack/messenger/med(H), slot_back) if(has_alt_title(H, alt_title,"Emergency Physician")) 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/clothing/suit/storage/toggle/fr_jacket(H), slot_wear_suit) @@ -78,6 +80,7 @@ if(2) H.equip_to_slot_or_del(new /obj/item/weapon/storage/backpack/virology(H), slot_back) if(3) H.equip_to_slot_or_del(new /obj/item/weapon/storage/backpack/satchel/vir(H), slot_back) if(4) H.equip_to_slot_or_del(new /obj/item/weapon/storage/backpack/satchel(H), slot_back) + if(5) H.equip_to_slot_or_del(new /obj/item/weapon/storage/backpack/messenger/viro(H), slot_back) else if(has_alt_title(H, alt_title,"Medical Doctor")) 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/clothing/suit/storage/toggle/labcoat(H), slot_wear_suit) @@ -128,6 +131,7 @@ if(2) H.equip_to_slot_or_del(new /obj/item/weapon/storage/backpack/chemistry(H), slot_back) if(3) H.equip_to_slot_or_del(new /obj/item/weapon/storage/backpack/satchel/chem(H), slot_back) if(4) H.equip_to_slot_or_del(new /obj/item/weapon/storage/backpack/satchel(H), slot_back) + if(5) H.equip_to_slot_or_del(new /obj/item/weapon/storage/backpack/messenger/chem(H), slot_back) H.equip_to_slot_or_del(new /obj/item/clothing/suit/storage/toggle/labcoat/chemist(H), slot_wear_suit) return 1 @@ -185,6 +189,7 @@ if(2) H.equip_to_slot_or_del(new /obj/item/weapon/storage/backpack(H), slot_back) if(3) H.equip_to_slot_or_del(new /obj/item/weapon/storage/backpack/satchel/norm(H), slot_back) if(4) H.equip_to_slot_or_del(new /obj/item/weapon/storage/backpack/satchel(H), slot_back) + if(5) H.equip_to_slot_or_del(new /obj/item/weapon/storage/backpack/messenger(H), slot_back) if(has_alt_title(H, alt_title,"Psychiatrist")) H.equip_to_slot_or_del(new /obj/item/clothing/under/rank/psych(H), slot_w_uniform) else if(has_alt_title(H, alt_title,"Psychologist")) @@ -221,6 +226,7 @@ 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(5) H.equip_to_slot_or_del(new /obj/item/weapon/storage/backpack/messenger/med(H), slot_back) if(has_alt_title(H, alt_title,"Emergency Medical Technician")) H.equip_to_slot_or_del(new /obj/item/clothing/under/rank/medical/paramedic(H), slot_w_uniform) H.equip_to_slot_or_del(new /obj/item/clothing/suit/storage/toggle/fr_jacket(H), slot_wear_suit) diff --git a/code/game/jobs/job/science.dm b/code/game/jobs/job/science.dm index 3fb3de5c42..b13d623fd6 100644 --- a/code/game/jobs/job/science.dm +++ b/code/game/jobs/job/science.dm @@ -37,6 +37,7 @@ if(2) H.equip_to_slot_or_del(new /obj/item/weapon/storage/backpack/toxins(H), slot_back) if(3) H.equip_to_slot_or_del(new /obj/item/weapon/storage/backpack/satchel/tox(H), slot_back) if(4) H.equip_to_slot_or_del(new /obj/item/weapon/storage/backpack/satchel(H), slot_back) + if(5) H.equip_to_slot_or_del(new /obj/item/weapon/storage/backpack/messenger/tox(H), slot_back) H.equip_to_slot_or_del(new /obj/item/clothing/suit/storage/toggle/labcoat(H), slot_wear_suit) return 1 @@ -70,6 +71,7 @@ if(2) H.equip_to_slot_or_del(new /obj/item/weapon/storage/backpack/toxins(H), slot_back) if(3) H.equip_to_slot_or_del(new /obj/item/weapon/storage/backpack/satchel/tox(H), slot_back) if(4) H.equip_to_slot_or_del(new /obj/item/weapon/storage/backpack/satchel(H), slot_back) + if(5) H.equip_to_slot_or_del(new /obj/item/weapon/storage/backpack/messenger/tox(H), slot_back) H.equip_to_slot_or_del(new /obj/item/clothing/suit/storage/toggle/labcoat/science(H), slot_wear_suit) return 1 @@ -101,6 +103,7 @@ if(2) H.equip_to_slot_or_del(new /obj/item/weapon/storage/backpack/toxins(H), slot_back) if(3) H.equip_to_slot_or_del(new /obj/item/weapon/storage/backpack/satchel/tox(H), slot_back) if(4) H.equip_to_slot_or_del(new /obj/item/weapon/storage/backpack/satchel(H), slot_back) + if(5) H.equip_to_slot_or_del(new /obj/item/weapon/storage/backpack/messenger/tox(H), slot_back) H.equip_to_slot_or_del(new /obj/item/clothing/suit/storage/toggle/labcoat/science(H), slot_wear_suit) return 1 diff --git a/code/game/jobs/job/security.dm b/code/game/jobs/job/security.dm index 071c1cbf1b..f151a5fb83 100644 --- a/code/game/jobs/job/security.dm +++ b/code/game/jobs/job/security.dm @@ -30,6 +30,7 @@ if(2) H.equip_to_slot_or_del(new /obj/item/weapon/storage/backpack/security(H), slot_back) if(3) H.equip_to_slot_or_del(new /obj/item/weapon/storage/backpack/satchel/sec(H), slot_back) if(4) H.equip_to_slot_or_del(new /obj/item/weapon/storage/backpack/satchel(H), slot_back) + if(5) H.equip_to_slot_or_del(new /obj/item/weapon/storage/backpack/messenger/sec(H), slot_back) H.equip_to_slot_or_del(new /obj/item/device/radio/headset/heads/hos(H), slot_l_ear) H.equip_to_slot_or_del(new /obj/item/clothing/under/rank/head_of_security(H), slot_w_uniform) H.equip_to_slot_or_del(new /obj/item/clothing/shoes/jackboots(H), slot_shoes) @@ -70,6 +71,7 @@ if(2) H.equip_to_slot_or_del(new /obj/item/weapon/storage/backpack/security(H), slot_back) if(3) H.equip_to_slot_or_del(new /obj/item/weapon/storage/backpack/satchel/sec(H), slot_back) if(4) H.equip_to_slot_or_del(new /obj/item/weapon/storage/backpack/satchel(H), slot_back) + if(5) H.equip_to_slot_or_del(new /obj/item/weapon/storage/backpack/messenger/sec(H), slot_back) H.equip_to_slot_or_del(new /obj/item/clothing/under/rank/warden(H), slot_w_uniform) H.equip_to_slot_or_del(new /obj/item/clothing/shoes/jackboots(H), slot_shoes) H.equip_to_slot_or_del(new /obj/item/device/pda/warden(H), slot_belt) @@ -108,6 +110,7 @@ if(2) H.equip_to_slot_or_del(new /obj/item/weapon/storage/backpack(H), slot_back) if(3) H.equip_to_slot_or_del(new /obj/item/weapon/storage/backpack/satchel/norm(H), slot_back) if(4) H.equip_to_slot_or_del(new /obj/item/weapon/storage/backpack/satchel(H), slot_back) + if(5) H.equip_to_slot_or_del(new /obj/item/weapon/storage/backpack/messenger(H), slot_back) H.equip_to_slot_or_del(new /obj/item/clothing/under/det(H), slot_w_uniform) H.equip_to_slot_or_del(new /obj/item/clothing/shoes/laceup(H), slot_shoes) H.equip_to_slot_or_del(new /obj/item/device/pda/detective(H), slot_belt) @@ -151,6 +154,7 @@ if(2) H.equip_to_slot_or_del(new /obj/item/weapon/storage/backpack/security(H), slot_back) if(3) H.equip_to_slot_or_del(new /obj/item/weapon/storage/backpack/satchel/sec(H), slot_back) if(4) H.equip_to_slot_or_del(new /obj/item/weapon/storage/backpack/satchel(H), slot_back) + if(5) H.equip_to_slot_or_del(new /obj/item/weapon/storage/backpack/messenger/sec(H), slot_back) H.equip_to_slot_or_del(new /obj/item/clothing/under/rank/security(H), slot_w_uniform) H.equip_to_slot_or_del(new /obj/item/clothing/shoes/jackboots(H), slot_shoes) H.equip_to_slot_or_del(new /obj/item/device/pda/security(H), slot_belt) diff --git a/code/game/jobs/jobs.dm b/code/game/jobs/jobs.dm index 61324580ff..bf3b4ea8ff 100644 --- a/code/game/jobs/jobs.dm +++ b/code/game/jobs/jobs.dm @@ -44,6 +44,7 @@ var/const/CHAPLAIN =(1<<10) var/const/CLOWN =(1<<11) var/const/MIME =(1<<12) var/const/ASSISTANT =(1<<13) +var/const/BRIDGE =(1<<14) var/list/assistant_occupations = list( @@ -56,7 +57,8 @@ var/list/command_positions = list( "Head of Security", "Chief Engineer", "Research Director", - "Chief Medical Officer" + "Chief Medical Officer", + "Command Secretary" ) diff --git a/code/game/machinery/adv_med.dm b/code/game/machinery/adv_med.dm index 2e7224169f..5efd83bb92 100644 --- a/code/game/machinery/adv_med.dm +++ b/code/game/machinery/adv_med.dm @@ -329,7 +329,7 @@ organStatus["broken"] = E.broken_description if(E.status & ORGAN_ROBOT) organStatus["robotic"] = 1 - if(E.status & ORGAN_SPLINTED) + if(E.splinted) organStatus["splinted"] = 1 if(E.status & ORGAN_BLEEDING) organStatus["bleeding"] = 1 @@ -483,7 +483,7 @@ break if(istype(e, /obj/item/organ/external/chest) && occupant.is_lung_ruptured()) lung_ruptured = "Lung ruptured:" - if(e.status & ORGAN_SPLINTED) + if(e.splinted) splint = "Splinted:" if(e.status & ORGAN_BLEEDING) bled = "Bleeding:" diff --git a/code/game/machinery/camera/tracking.dm b/code/game/machinery/camera/tracking.dm index 739583ede8..cb57906e30 100644 --- a/code/game/machinery/camera/tracking.dm +++ b/code/game/machinery/camera/tracking.dm @@ -222,7 +222,7 @@ mob/living/proc/near_camera() /mob/living/proc/tracking_status() // Easy checks first. - // Don't detect mobs on Centcom. Since the wizard den is on Centcomm, we only need this. + // Don't detect mobs on CentCom. Since the wizard den is on CentCom, we only need this. var/obj/item/weapon/card/id/id = GetIdCard() if(id && id.prevent_tracking()) return TRACKING_TERMINATE diff --git a/code/game/machinery/computer/communications.dm b/code/game/machinery/computer/communications.dm index a657d881a8..9ff98b84b4 100644 --- a/code/game/machinery/computer/communications.dm +++ b/code/game/machinery/computer/communications.dm @@ -173,7 +173,7 @@ src.updateDialog() // OMG CENTCOMM LETTERHEAD - if("MessageCentcomm") + if("MessageCentCom") if(src.authenticated==2) if(centcomm_message_cooldown) usr << "\red Arrays recycling. Please stand by." @@ -181,7 +181,7 @@ var/input = sanitize(input("Please choose a message to transmit to [boss_short] via quantum entanglement. Please be aware that this process is very expensive, and abuse will lead to... termination. Transmission does not guarantee a response. There is a 30 second delay before you may send another message, be clear, full and concise.", "To abort, send an empty message.", "")) if(!input || !(usr in view(1,src))) return - Centcomm_announce(input, usr) + CentCom_announce(input, usr) usr << "\blue Message transmitted." log_say("[key_name(usr)] has made an IA [boss_short] announcement: [input]") centcomm_message_cooldown = 1 @@ -295,7 +295,7 @@ if (src.authenticated==2) dat += "
\[ Make An Announcement \]" if(src.emagged == 0) - dat += "
\[ Send an emergency message to [boss_short] \]" + dat += "
\[ Send an emergency message to [boss_short] \]" else dat += "
\[ Send an emergency message to \[UNKNOWN\] \]" dat += "
\[ Restore Backup Routing Data \]" diff --git a/code/game/machinery/computer/guestpass.dm b/code/game/machinery/computer/guestpass.dm index 3fced68e65..b01b03f9b3 100644 --- a/code/game/machinery/computer/guestpass.dm +++ b/code/game/machinery/computer/guestpass.dm @@ -132,7 +132,7 @@ if (href_list["choice"]) switch(href_list["choice"]) if ("giv_name") - var/nam = sanitize(input("Person pass is issued to", "Name", giv_name) as text|null) + var/nam = sanitizeName(input("Person pass is issued to", "Name", giv_name) as text|null) if (nam) giv_name = nam if ("reason") diff --git a/code/game/machinery/computer3/computers/communications.dm b/code/game/machinery/computer3/computers/communications.dm index 8168a3f8da..cace79d378 100644 --- a/code/game/machinery/computer3/computers/communications.dm +++ b/code/game/machinery/computer3/computers/communications.dm @@ -22,8 +22,8 @@ /datum/file/program/communications - name = "Centcom communications relay" - desc = "Used to connect to Centcom." + name = "CentCom communications relay" + desc = "Used to connect to CentCom." active_state = "comm" req_access = list(access_heads) @@ -185,7 +185,7 @@ computer.updateDialog() // OMG CENTCOMM LETTERHEAD - if("MessageCentcomm" in href_list) + if("MessageCentCom" in href_list) if(!computer.radio.subspace) return if(authenticated==2) @@ -195,7 +195,7 @@ var/input = sanitize(input("Please choose a message to transmit to [boss_short] via quantum entanglement. Please be aware that this process is very expensive, and abuse will lead to... termination. Transmission does not guarantee a response.", "To abort, send an empty message.", "")) if(!input || !interactable()) return - Centcomm_announce(input, usr) + CentCom_announce(input, usr) usr << "Message transmitted." log_say("[key_name(usr)] has made a [boss_short] announcement: [input]") centcomm_message_cooldown = 1 @@ -288,7 +288,7 @@ if (authenticated==2) dat += "
\[ Make An Announcement \]" if(computer.emagged == 0) - dat += "
\[ Send an emergency message to [boss_short] \]" + dat += "
\[ Send an emergency message to [boss_short] \]" else dat += "
\[ Send an emergency message to \[UNKNOWN\] \]" dat += "
\[ Restore Backup Routing Data \]" diff --git a/code/game/machinery/computer3/file.dm b/code/game/machinery/computer3/file.dm index be4285b3e1..c425bcc0aa 100644 --- a/code/game/machinery/computer3/file.dm +++ b/code/game/machinery/computer3/file.dm @@ -62,13 +62,13 @@ return 1 /* - Centcom root authorization certificate + CentCom root authorization certificate Non-destructive, officially sanctioned. Has the same effect on computers as an emag. */ /datum/file/centcom_auth - name = "Centcom Root Access Token" + name = "CentCom Root Access Token" extension = "auth" volume = 100 copy() diff --git a/code/game/machinery/computer3/lapvend.dm b/code/game/machinery/computer3/lapvend.dm index 3800fb9440..e31dd57fa2 100644 --- a/code/game/machinery/computer3/lapvend.dm +++ b/code/game/machinery/computer3/lapvend.dm @@ -178,7 +178,7 @@ else usr << "\icon[src]Unable to access vendor account. Please record the machine ID and call [boss_short] Support." else - usr << "\icon[src]Unable to access vendor account. Please record the machine ID and call CentComm Support." + usr << "\icon[src]Unable to access vendor account. Please record the machine ID and call CentCom Support." else transfer_and_vend(CH, C) @@ -328,7 +328,7 @@ usr << "\icon[src]Unable to access vendor account. Please record the machine ID and call [boss_short] Support." return 0 else - usr << "\icon[src]Unable to access vendor account. Please record the machine ID and call CentComm Support." + usr << "\icon[src]Unable to access vendor account. Please record the machine ID and call CentCom Support." return 0 else transfer_and_reimburse(CH) diff --git a/code/game/machinery/frame.dm b/code/game/machinery/frame.dm index 3005996f0b..f553bfa9fe 100644 --- a/code/game/machinery/frame.dm +++ b/code/game/machinery/frame.dm @@ -447,6 +447,31 @@ state = 3 if(frame_type.frame_class == "machine") user << desc + else if(state == 3) + if(frame_type.frame_class == "machine") + for(var/I in req_components) + if(istype(P, I) && (req_components[I] > 0)) + playsound(src.loc, 'sound/items/Deconstruct.ogg', 50, 1) + if(istype(P, /obj/item/stack/cable_coil)) + var/obj/item/stack/cable_coil/CP = P + if(CP.get_amount() > 1) + var/camt = min(CP.amount, req_components[I]) // amount of cable to take, idealy amount required, but limited by amount provided + var/obj/item/stack/cable_coil/CC = new /obj/item/stack/cable_coil(src) + CC.amount = camt + CC.update_icon() + CP.use(camt) + components += CC + req_components[I] -= camt + update_desc() + break + + user.drop_item() + P.forceMove(src) + components += P + req_components[I]-- + update_desc() + break + user << desc else if(istype(P, /obj/item/weapon/wirecutters)) if(state == 3) @@ -506,20 +531,7 @@ for(var/I in req_components) if(istype(P, I) && (req_components[I] > 0)) playsound(src.loc, 'sound/items/Deconstruct.ogg', 50, 1) - if(istype(P, /obj/item/stack/cable_coil)) - var/obj/item/stack/cable_coil/CP = P - if(CP.get_amount() > 1) - var/camt = min(CP.amount, req_components[I]) // amount of cable to take, idealy amount required, but limited by amount provided - var/obj/item/stack/cable_coil/CC = new /obj/item/stack/cable_coil(src) - CC.amount = camt - CC.update_icon() - CP.use(camt) - components += CC - req_components[I] -= camt - update_desc() - break - - else if(istype(P, /obj/item/stack/material/glass/reinforced)) + if(istype(P, /obj/item/stack/material/glass/reinforced)) var/obj/item/stack/material/glass/reinforced/CP = P if(CP.get_amount() > 1) var/camt = min(CP.amount, req_components[I]) // amount of glass to take, idealy amount required, but limited by amount provided @@ -539,8 +551,65 @@ update_desc() break user << desc - if(P && P.loc != src && !istype(P, /obj/item/stack/cable_coil) && !istype(P, /obj/item/stack/material)) + if(P && P.loc != src && !istype(P, /obj/item/stack/material)) user << "You cannot add that component to the machine!" return - update_icon() \ No newline at end of file + update_icon() + +/obj/structure/frame/verb/rotate() + set name = "Rotate Frame Counter-Clockwise" + set category = "Object" + set src in oview(1) + + if(usr.incapacitated()) + return 0 + + if(anchored) + usr << "It is fastened to the floor therefore you can't rotate it!" + return 0 + + set_dir(turn(dir, 90)) + + var/dir_text + if(dir == 1) + dir_text = "north" + else if(dir == 2) + dir_text = "south" + else if(dir == 4) + dir_text = "east" + else if(dir == 8) + dir_text = "west" + + usr << "You rotate the [src] to face [dir_text]!" + + return + + +/obj/structure/frame/verb/revrotate() + set name = "Rotate Frame Clockwise" + set category = "Object" + set src in oview(1) + + if(usr.incapacitated()) + return 0 + + if(anchored) + usr << "It is fastened to the floor therefore you can't rotate it!" + return 0 + + set_dir(turn(dir, 270)) + + var/dir_text + if(dir == 1) + dir_text = "north" + else if(dir == 2) + dir_text = "south" + else if(dir == 4) + dir_text = "east" + else if(dir == 8) + dir_text = "west" + + usr << "You rotate the [src] to face [dir_text]!" + + return \ No newline at end of file diff --git a/code/game/machinery/suit_storage_unit.dm b/code/game/machinery/suit_storage_unit.dm index 9700dfd69a..3234d03a1f 100644 --- a/code/game/machinery/suit_storage_unit.dm +++ b/code/game/machinery/suit_storage_unit.dm @@ -586,7 +586,7 @@ var/electrified = 0 //Departments that the cycler can paint suits to look like. - var/list/departments = list("Engineering","Mining","Medical","Security","Atmos","HAZMAT","Construction") + var/list/departments = list("Engineering","Mining","Medical","Security","Atmos","HAZMAT","Construction","Biohazard") //Species that the suits can be configured to fit. var/list/species = list("Human","Skrell","Unathi","Tajara", "Teshari") @@ -634,7 +634,7 @@ name = "Medical suit cycler" model_text = "Medical" req_access = list(access_medical) - departments = list("Medical") + departments = list("Medical","Biohazard") /obj/machinery/suit_cycler/syndicate name = "Nonstandard suit cycler" @@ -751,8 +751,8 @@ //Clear the access reqs, disable the safeties, and open up all paintjobs. user << "You run the sequencer across the interface, corrupting the operating protocols." - departments = list("Engineering","Mining","Medical","Security","Atmos","HAZMAT","Construction","^%###^%$") - species = list("Human","Tajara","Skrell","Unathi", "Teshari") + departments = list("Engineering","Mining","Medical","Security","Atmos","HAZMAT","Construction","Biohazard","^%###^%$") + species = list("Human","Skrell","Unathi","Tajara", "Teshari", "Nevrean", "Akula", "Sergal", "Flatland Zorren", "Highlander Zorren", "Vulpkanin", "Promethean", "Xenomorph Hybrid") //VORESTATION EDIT emagged = 1 safeties = 0 @@ -1036,6 +1036,15 @@ suit.name = "Construction voidsuit" suit.icon_state = "rig-engineering_con" suit.item_state = "eng_voidsuit_con" + if("Biohazard") + if(helmet) + helmet.name = "Biohazard voidsuit helmet" + helmet.icon_state = "rig0-medical_bio" + helmet.item_state = "rig0-medical_bio" + if(suit) + suit.name = "Biohazard voidsuit" + suit.icon_state = "rig-medical_bio" + suit.item_state = "medical_voidsuit_bio" if("^%###^%$" || "Mercenary") if(helmet) helmet.name = "blood-red voidsuit helmet" diff --git a/code/game/machinery/telecomms/presets.dm b/code/game/machinery/telecomms/presets.dm index ca35f59236..4a6aded43b 100644 --- a/code/game/machinery/telecomms/presets.dm +++ b/code/game/machinery/telecomms/presets.dm @@ -25,7 +25,7 @@ autolinkers = list("r_relay") /obj/machinery/telecomms/relay/preset/centcom - id = "Centcom Relay" + id = "CentCom Relay" hide = 1 toggled = 1 //anchored = 1 @@ -44,7 +44,7 @@ "receiverA", "broadcasterA") /obj/machinery/telecomms/hub/preset_cent - id = "CentComm Hub" + id = "CentCom Hub" network = "tcommsat" produces_heat = 0 autolinkers = list("hub_cent", "c_relay", "s_relay", "m_relay", "r_relay", @@ -65,7 +65,7 @@ ..() /obj/machinery/telecomms/receiver/preset_cent - id = "CentComm Receiver" + id = "CentCom Receiver" network = "tcommsat" produces_heat = 0 autolinkers = list("receiverCent") @@ -106,7 +106,7 @@ autolinkers = list("processor4", "engineering", "common") /obj/machinery/telecomms/bus/preset_cent - id = "CentComm Bus" + id = "CentCom Bus" network = "tcommsat" freq_listening = list(ERT_FREQ, DTH_FREQ) produces_heat = 0 @@ -135,7 +135,7 @@ autolinkers = list("processor4") /obj/machinery/telecomms/processor/preset_cent - id = "CentComm Processor" + id = "CentCom Processor" network = "tcommsat" produces_heat = 0 autolinkers = list("processorCent") @@ -200,7 +200,7 @@ autolinkers = list("security") /obj/machinery/telecomms/server/presets/centcomm - id = "CentComm Server" + id = "CentCom Server" freq_listening = list(ERT_FREQ, DTH_FREQ) produces_heat = 0 autolinkers = list("centcomm") @@ -216,7 +216,7 @@ autolinkers = list("broadcasterA") /obj/machinery/telecomms/broadcaster/preset_cent - id = "CentComm Broadcaster" + id = "CentCom Broadcaster" network = "tcommsat" produces_heat = 0 autolinkers = list("broadcasterCent") \ No newline at end of file diff --git a/code/game/objects/effects/decals/posters/tgposters.dm b/code/game/objects/effects/decals/posters/tgposters.dm index 5fb94396d5..50d615efa0 100644 --- a/code/game/objects/effects/decals/posters/tgposters.dm +++ b/code/game/objects/effects/decals/posters/tgposters.dm @@ -41,10 +41,10 @@ /datum/poster/tg_9 name = "Missing Gloves" - desc = "This poster is about the uproar that followed Nanotrasen's financial cuts towards insulated-glove purchases." + desc = "This poster is about the uproar that followed NanoTrasen's financial cuts towards insulated-glove purchases." icon_state="poster9" /datum/poster/tg_10 name = "Hacking Guide" - desc = "This poster details the internal workings of the common Nanotrasen airlock." + desc = "This poster details the internal workings of the common NanoTrasen airlock." icon_state="poster10" \ No newline at end of file diff --git a/code/game/objects/items/devices/PDA/cart.dm b/code/game/objects/items/devices/PDA/cart.dm index a0e37e28b8..94230418e8 100644 --- a/code/game/objects/items/devices/PDA/cart.dm +++ b/code/game/objects/items/devices/PDA/cart.dm @@ -97,6 +97,7 @@ var/list/civilian_cartridges = list( name = "\improper ChemWhiz cartridge" icon_state = "cart-chem" access_reagent_scanner = 1 + access_medical = 1 /obj/item/weapon/cartridge/security name = "\improper R.O.B.U.S.T. cartridge" diff --git a/code/game/objects/items/devices/hacktool.dm b/code/game/objects/items/devices/hacktool.dm index 0cf4af6c74..2f05a6f385 100644 --- a/code/game/objects/items/devices/hacktool.dm +++ b/code/game/objects/items/devices/hacktool.dm @@ -62,7 +62,7 @@ if(hack_result && in_hack_mode) user << "Your hacking attempt was succesful!" - playsound(src.loc, 'sound/piano/A#6.ogg', 75) + user.playsound_local(get_turf(src), 'sound/piano/A#6.ogg', 50) else user << "Your hacking attempt failed!" return 0 diff --git a/code/game/objects/items/devices/powersink.dm b/code/game/objects/items/devices/powersink.dm index a7210721c8..3478abce1d 100644 --- a/code/game/objects/items/devices/powersink.dm +++ b/code/game/objects/items/devices/powersink.dm @@ -18,7 +18,7 @@ var/apc_drain_rate = 5000 // Max. amount drained from single APC. In Watts. var/dissipation_rate = 20000 // Passive dissipation of drained power. In Watts. var/power_drained = 0 // Amount of power drained. - var/max_power = 5e9 // Detonation point. + var/max_power = 1e9 // Detonation point. var/mode = 0 // 0 = off, 1=clamped (off), 2=operating var/drained_this_tick = 0 // This is unfortunately necessary to ensure we process powersinks BEFORE other machinery such as APCs. diff --git a/code/game/objects/items/devices/scanners.dm b/code/game/objects/items/devices/scanners.dm index 7b70216330..5388dc4420 100644 --- a/code/game/objects/items/devices/scanners.dm +++ b/code/game/objects/items/devices/scanners.dm @@ -143,13 +143,25 @@ REAGENT SCANNER user.show_message("Significant brain damage detected. Subject may have had a concussion.") if(ishuman(M)) var/mob/living/carbon/human/H = M + for(var/name_i in H.internal_organs_by_name) + var/obj/item/organ/internal/i = H.internal_organs_by_name[name_i] + if(istype(i, /obj/item/organ/internal/appendix)) + var/obj/item/organ/internal/appendix/a = H.internal_organs_by_name[name_i] + if(a.inflamed > 3) + user.show_message(text("Severe inflammation detected in subject [a.name]."), 1) + else if(a.inflamed > 2) + user.show_message(text("Moderate inflammation detected in subject [a.name]."), 1) + else if(a.inflamed >= 1) + user.show_message(text("Mild inflammation detected in subject [a.name]."), 1) + + for(var/name in H.organs_by_name) var/obj/item/organ/external/e = H.organs_by_name[name] if(!e) continue var/limb = e.name if(e.status & ORGAN_BROKEN) - if(((e.name == "l_arm") || (e.name == "r_arm") || (e.name == "l_leg") || (e.name == "r_leg")) && (!(e.status & ORGAN_SPLINTED))) + if(((e.name == "l_arm") || (e.name == "r_arm") || (e.name == "l_leg") || (e.name == "r_leg")) && (!e.splinted)) user << "Unsecured fracture in subject [limb]. Splinting recommended for transport." if(e.has_infected_wound()) user << "Infected wound detected in subject [limb]. Disinfection recommended." @@ -165,6 +177,7 @@ REAGENT SCANNER for(var/datum/wound/W in e.wounds) if(W.internal) user.show_message(text("Internal bleeding detected. Advanced scanner required for location."), 1) break + if(M:vessel) var/blood_volume = H.vessel.get_reagent_amount("blood") var/blood_percent = round((blood_volume / H.species.blood_volume)*100) diff --git a/code/game/objects/items/stacks/medical.dm b/code/game/objects/items/stacks/medical.dm index 3e9c9a7524..41ae7ac7c3 100644 --- a/code/game/objects/items/stacks/medical.dm +++ b/code/game/objects/items/stacks/medical.dm @@ -264,7 +264,7 @@ if(!(affecting.organ_tag in splintable_organs)) user << "You can't use \the [src] to apply a splint there!" return - if(affecting.status & ORGAN_SPLINTED) + if(affecting.splinted) user << "[M]'s [limb] is already splinted!" return if (M != user) @@ -275,17 +275,21 @@ user << "You can't apply a splint to the arm you're using!" return user.visible_message("[user] starts to apply \the [src] to their [limb].", "You start to apply \the [src] to your [limb].", "You hear something being wrapped.") - if(do_after(user, 50)) - if (M != user) - user.visible_message("[user] finishes applying \the [src] to [M]'s [limb].", "You finish applying \the [src] to [M]'s [limb].", "You hear something being wrapped.") - else - if(prob(25)) - user.visible_message("[user] successfully applies \the [src] to their [limb].", "You successfully apply \the [src] to your [limb].", "You hear something being wrapped.") - else - user.visible_message("[user] fumbles \the [src].", "You fumble \the [src].", "You hear something being wrapped.") + if(do_after(user, 50, M)) + if(M == user && prob(75)) + user.visible_message("\The [user] fumbles [src].", "You fumble [src].", "You hear something being wrapped.") + return + var/obj/item/stack/medical/splint/S = split(1) + if(S) + if(affecting.apply_splint(S)) + S.forceMove(affecting) + if (M != user) + user.visible_message("\The [user] finishes applying [src] to [M]'s [limb].", "You finish applying \the [src] to [M]'s [limb].", "You hear something being wrapped.") + else + user.visible_message("\The [user] successfully applies [src] to their [limb].", "You successfully apply \the [src] to your [limb].", "You hear something being wrapped.") return - affecting.status |= ORGAN_SPLINTED - use(1) + S.dropInto(src.loc) //didn't get applied, so just drop it + user.visible_message("\The [user] fails to apply [src].", "You fail to apply [src].", "You hear something being wrapped.") return diff --git a/code/game/objects/items/weapons/cigs_lighters.dm b/code/game/objects/items/weapons/cigs_lighters.dm index f201fbb3c6..3d3cb46192 100644 --- a/code/game/objects/items/weapons/cigs_lighters.dm +++ b/code/game/objects/items/weapons/cigs_lighters.dm @@ -94,6 +94,7 @@ CIGARETTE PACKETS ARE IN FANCY.DM var/zippomes = "USER lights NAME with FLAME" var/weldermes = "USER lights NAME with FLAME" var/ignitermes = "USER lights NAME with FLAME" + var/brand /obj/item/clothing/mask/smokable/New() ..() @@ -169,6 +170,8 @@ CIGARETTE PACKETS ARE IN FANCY.DM if (type_butt) var/obj/item/butt = new type_butt(T) transfer_fingerprints_to(butt) + if(brand) + butt.desc += " This one is \a [brand]." if(ismob(loc)) var/mob/living/M = loc if (!nomessage) diff --git a/code/game/objects/items/weapons/storage/backpack.dm b/code/game/objects/items/weapons/storage/backpack.dm index 69207191e7..6189cc9658 100644 --- a/code/game/objects/items/weapons/storage/backpack.dm +++ b/code/game/objects/items/weapons/storage/backpack.dm @@ -280,3 +280,62 @@ name = "emergency response team medical backpack" desc = "A spacious backpack with lots of pockets, worn by medical members of an Emergency Response Team." icon_state = "ert_medical" + +/* + * Courier Bags + */ + +/obj/item/weapon/storage/backpack/messenger + name = "messenger bag" + desc = "A sturdy backpack worn over one shoulder." + icon_state = "courierbag" + item_state_slots = list(slot_r_hand_str = "backpack", slot_l_hand_str = "backpack") + +/obj/item/weapon/storage/backpack/messenger/chem + name = "chemistry messenger bag" + desc = "A serile backpack worn over one shoulder. This one is in Chemsitry colors." + icon_state = "courierbagchem" + item_state_slots = list(slot_r_hand_str = "chempack", slot_l_hand_str = "chempack") + +/obj/item/weapon/storage/backpack/messenger/med + name = "medical messenger bag" + desc = "A sterile backpack worn over one shoulder used in medical departments." + icon_state = "courierbagmed" + item_state_slots = list(slot_r_hand_str = "medicalpack", slot_l_hand_str = "medicalpack") + +/obj/item/weapon/storage/backpack/messenger/viro + name = "virology messenger bag" + desc = "A sterile backpack worn over one shoulder. This one is in Virology colors." + icon_state = "courierbagviro" + item_state_slots = list(slot_r_hand_str = "viropack", slot_l_hand_str = "viropack") + +/obj/item/weapon/storage/backpack/messenger/tox + name = "research messenger bag" + desc = "A backpack worn over one shoulder. Useful for holding science materials." + icon_state = "courierbagtox" + item_state_slots = list(slot_r_hand_str = "toxpack", slot_l_hand_str = "toxpack") + +/obj/item/weapon/storage/backpack/messenger/com + name = "command messenger bag" + desc = "A special backpack worn over one shoulder. This one is made specifically for officers." + icon_state = "courierbagcom" + item_state_slots = list(slot_r_hand_str = "captainpack", slot_l_hand_str = "captainpack") + +/obj/item/weapon/storage/backpack/messenger/engi + name = "engineering messenger bag" + icon_state = "courierbagengi" + item_state_slots = list(slot_r_hand_str = "engiepack", slot_l_hand_str = "engiepack") + +/obj/item/weapon/storage/backpack/messenger/hyd + name = "hydroponics messenger bag" + desc = "A backpack worn over one shoulder. This one is designed for plant-related work." + icon_state = "courierbaghyd" + +/obj/item/weapon/storage/backpack/messenger/sec + name = "security messenger bag" + desc = "A tactical backpack worn over one shoulder. This one is in Security colors." + icon_state = "courierbagsec" + item_state_slots = list(slot_r_hand_str = "securitypack", slot_l_hand_str = "securitypack") + +/obj/item/weapon/storage/backpack/messenger/black + icon_state = "courierbagblk" \ No newline at end of file diff --git a/code/game/objects/items/weapons/storage/belt.dm b/code/game/objects/items/weapons/storage/belt.dm index f7de0b46f6..6f0beed5e9 100644 --- a/code/game/objects/items/weapons/storage/belt.dm +++ b/code/game/objects/items/weapons/storage/belt.dm @@ -56,6 +56,7 @@ /obj/item/weapon/extinguisher/mini, /obj/item/device/flashlight/maglight, /obj/item/weapon/tape_roll, + /obj/item/device/integrated_electronics/wirer, ) /obj/item/weapon/storage/belt/utility/full/New() @@ -128,6 +129,8 @@ /obj/item/weapon/reagent_containers/food/snacks/donut/, /obj/item/weapon/melee/baton, /obj/item/weapon/gun/energy/taser, + /obj/item/weapon/gun/energy/stunrevolver, + /obj/item/weapon/gun/energy/gun, /obj/item/weapon/flame/lighter, /obj/item/device/flashlight, /obj/item/device/pda, diff --git a/code/game/objects/items/weapons/storage/fancy.dm b/code/game/objects/items/weapons/storage/fancy.dm index 2561886efa..009e1fcc90 100644 --- a/code/game/objects/items/weapons/storage/fancy.dm +++ b/code/game/objects/items/weapons/storage/fancy.dm @@ -134,6 +134,7 @@ storage_slots = 6 can_hold = list(/obj/item/clothing/mask/smokable/cigarette, /obj/item/weapon/flame/lighter) icon_type = "cigarette" + var/brand = "\improper Trans-Stellar Duty-free" /obj/item/weapon/storage/fancy/cigarettes/New() ..() @@ -142,6 +143,10 @@ new /obj/item/clothing/mask/smokable/cigarette(src) create_reagents(15 * storage_slots)//so people can inject cigarettes without opening a packet, now with being able to inject the whole one flags |= OPENCONTAINER + if(brand) + for(var/obj/item/clothing/mask/smokable/cigarette/C in src) + C.brand = brand + C.desc += " This one is \a [brand]." /obj/item/weapon/storage/fancy/cigarettes/update_icon() icon_state = "[initial(icon_state)][contents.len]" @@ -186,11 +191,13 @@ name = "\improper DromedaryCo packet" desc = "A packet of six imported DromedaryCo cancer sticks. A label on the packaging reads, \"Wouldn't a slow death make a change?\"" icon_state = "Dpacket" + brand = "\improper Dromedary Co. cigarette" /obj/item/weapon/storage/fancy/cigarettes/killthroat name = "\improper AcmeCo packet" desc = "A packet of six AcmeCo cigarettes. For those who somehow want to obtain the record for the most amount of cancerous tumors." icon_state = "Bpacket" + brand = "\improper Acme Co. cigarette" // New() // ..() @@ -202,26 +209,31 @@ name = "\improper pack of Lucky Stars" desc = "A mellow blend made from synthetic, pod-grown tobacco. The commercial jingle is guaranteed to get stuck in your head." icon_state = "LSpacket" + brand = "\improper Lucky Star" /obj/item/weapon/storage/fancy/cigarettes/jerichos name = "\improper pack of Jerichos" desc = "Typically seen dangling from the lips of Martian soldiers and border world hustlers. Tastes like hickory smoke, feels like warm liquid death down your lungs." icon_state = "Jpacket" + brand = "\improper Jericho" /obj/item/weapon/storage/fancy/cigarettes/menthols name = "\improper pack of Temperamento Menthols" desc = "With a sharp and natural organic menthol flavor, these Temperamentos are a favorite of NDV crews. Hardly anyone knows they make 'em in non-menthol!" icon_state = "TMpacket" + brand = "\improper Temperamento Menthol" /obj/item/weapon/storage/fancy/cigarettes/carcinomas name = "\improper pack of Carcinoma Angels" desc = "This unknown brand was slated for the chopping block, until they were publicly endorsed by an old Earthling gonzo journalist. The rest is history. They sell a variety for cats, too." icon_state = "CApacket" + brand = "\improper Carcinoma Angel" /obj/item/weapon/storage/fancy/cigarettes/professionals name = "\improper pack of Professional 120s" desc = "Let's face it - if you're smoking these, you're either trying to look upper-class or you're 80 years old. That's the only excuse. They are, however, very good quality." icon_state = "P100packet" + brand = "\improper Professional 120" /obj/item/weapon/storage/fancy/cigar name = "cigar case" diff --git a/code/game/objects/items/weapons/storage/toolbox.dm b/code/game/objects/items/weapons/storage/toolbox.dm index 7d0161a2fd..9c779f013a 100644 --- a/code/game/objects/items/weapons/storage/toolbox.dm +++ b/code/game/objects/items/weapons/storage/toolbox.dm @@ -127,10 +127,10 @@ filled = TRUE /obj/item/weapon/storage/toolbox/lunchbox/nt - name = "Nanotrasen brand lunchbox" + name = "NanoTrasen brand lunchbox" icon_state = "lunchbox_nanotrasen" item_state_slots = list(slot_r_hand_str = "toolbox_blue", slot_l_hand_str = "toolbox_blue") - desc = "A little lunchbox. This one is branded with the Nanotrasen logo!" + desc = "A little lunchbox. This one is branded with the NanoTrasen logo!" /obj/item/weapon/storage/toolbox/lunchbox/nt/filled filled = TRUE diff --git a/code/game/objects/structures/crates_lockers/closets.dm b/code/game/objects/structures/crates_lockers/closets.dm index d88e8c5372..107ea11520 100644 --- a/code/game/objects/structures/crates_lockers/closets.dm +++ b/code/game/objects/structures/crates_lockers/closets.dm @@ -394,3 +394,6 @@ var/shake_dir = pick(-1, 1) animate(src, transform=turn(matrix(), 8*shake_dir), pixel_x=init_px + 2*shake_dir, time=1) animate(transform=null, pixel_x=init_px, time=6, easing=ELASTIC_EASING) + +/obj/structure/closet/onDropInto(var/atom/movable/AM) + return diff --git a/code/game/objects/structures/crates_lockers/closets/wardrobe.dm b/code/game/objects/structures/crates_lockers/closets/wardrobe.dm index a422768269..0f5d5119bb 100644 --- a/code/game/objects/structures/crates_lockers/closets/wardrobe.dm +++ b/code/game/objects/structures/crates_lockers/closets/wardrobe.dm @@ -131,6 +131,7 @@ new /obj/item/clothing/mask/bandana(src) new /obj/item/clothing/mask/bandana(src) new /obj/item/clothing/mask/bandana(src) + new /obj/item/weapon/storage/backpack/messenger/black(src) return @@ -539,6 +540,8 @@ new /obj/item/clothing/under/pants/khaki(src) new /obj/item/clothing/mask/bandana/blue(src) new /obj/item/clothing/mask/bandana/blue(src) + new /obj/item/clothing/accessory/hawaii(src) + new /obj/item/clothing/accessory/hawaii/random(src) return /obj/structure/closet/wardrobe/tactical @@ -603,6 +606,7 @@ new /obj/item/clothing/under/sl_suit(src) new /obj/item/clothing/under/suit_jacket(src) new /obj/item/clothing/under/suit_jacket/female(src) + new /obj/item/clothing/under/suit_jacket/female/skirt(src) new /obj/item/clothing/under/suit_jacket/really_black(src) new /obj/item/clothing/under/suit_jacket/red(src) new /obj/item/clothing/under/scratch(src) diff --git a/code/game/objects/structures/crates_lockers/crates.dm b/code/game/objects/structures/crates_lockers/crates.dm index d6034bbb8a..5cdb49657a 100644 --- a/code/game/objects/structures/crates_lockers/crates.dm +++ b/code/game/objects/structures/crates_lockers/crates.dm @@ -265,7 +265,7 @@ /obj/structure/closet/crate/contraband name = "Poster crate" - desc = "A random assortment of posters manufactured by providers NOT listed under Nanotrasen's whitelist." + desc = "A random assortment of posters manufactured by providers NOT listed under NanoTrasen's whitelist." icon_state = "crate" icon_opened = "crateopen" icon_closed = "crate" diff --git a/code/global.dm b/code/global.dm index e2df3f0661..746352df6c 100644 --- a/code/global.dm +++ b/code/global.dm @@ -30,7 +30,7 @@ var/const/station_orig = "Virgo Orbital Research Establishment" //station_name c var/const/station_short = "V.O.R.E." var/const/dock_name = "Virgo-Erigone Central Command" var/const/boss_name = "Central Command" -var/const/boss_short = "Centcom" +var/const/boss_short = "CentCom" var/const/company_name = "NanoTrasen" var/const/company_short = "NT" var/const/star_name = "Virgo-Erigone" diff --git a/code/modules/admin/topic.dm b/code/modules/admin/topic.dm index eaadf431bc..fe427b54d8 100644 --- a/code/modules/admin/topic.dm +++ b/code/modules/admin/topic.dm @@ -440,6 +440,27 @@ counter = 0 jobs += "" + //Cargo (Yellow) + counter = 0 + jobs += "" + jobs += "" + for(var/jobPos in cargo_positions) + if(!jobPos) continue + var/datum/job/job = job_master.GetJob(jobPos) + if(!job) continue + + if(jobban_isbanned(M, job.title)) + jobs += "" + counter++ + else + jobs += "" + counter++ + + if(counter >= 5) //So things dont get squiiiiished! + jobs += "" + counter = 0 + jobs += "
Cargo Positions
[replacetext(job.title, " ", " ")][replacetext(job.title, " ", " ")]
" + //Medical (White) counter = 0 jobs += "" @@ -617,6 +638,12 @@ var/datum/job/temp = job_master.GetJob(jobPos) if(!temp) continue joblist += temp.title + if("cargodept") + for(var/jobPos in cargo_positions) + if(!jobPos) continue + var/datum/job/temp = job_master.GetJob(jobPos) + if(!temp) continue + joblist += temp.title if("medicaldept") for(var/jobPos in medical_positions) if(!jobPos) continue @@ -1323,19 +1350,19 @@ M.Weaken(20) M.stuttering = 20 - else if(href_list["CentcommReply"]) - var/mob/living/L = locate(href_list["CentcommReply"]) + else if(href_list["CentComReply"]) + var/mob/living/L = locate(href_list["CentComReply"]) if(!istype(L)) usr << "This can only be used on instances of type /mob/living/" return if(L.can_centcom_reply()) - var/input = sanitize(input(src.owner, "Please enter a message to reply to [key_name(L)] via their headset.","Outgoing message from Centcomm", "")) + var/input = sanitize(input(src.owner, "Please enter a message to reply to [key_name(L)] via their headset.","Outgoing message from CentCom", "")) if(!input) return src.owner << "You sent [input] to [L] via a secure channel." - log_admin("[src.owner] replied to [key_name(L)]'s Centcomm message with the message [input].") - message_admins("[src.owner] replied to [key_name(L)]'s Centcom message with: \"[input]\"") + log_admin("[src.owner] replied to [key_name(L)]'s CentCom message with the message [input].") + message_admins("[src.owner] replied to [key_name(L)]'s CentCom message with: \"[input]\"") if(!isAI(L)) L << "You hear something crackle in your headset for a moment before a voice speaks." L << "Please stand by for a message from Central Command." diff --git a/code/modules/admin/verbs/pray.dm b/code/modules/admin/verbs/pray.dm index 844f74b5f6..1307086a87 100644 --- a/code/modules/admin/verbs/pray.dm +++ b/code/modules/admin/verbs/pray.dm @@ -27,8 +27,8 @@ feedback_add_details("admin_verb","PR") //If you are copy-pasting this, ensure the 2nd parameter is unique to the new proc! //log_admin("HELP: [key_name(src)]: [msg]") -/proc/Centcomm_announce(var/msg, var/mob/Sender, var/iamessage) - msg = "\blue [uppertext(boss_short)]M[iamessage ? " IA" : ""]:[key_name(Sender, 1)] (PP) (VV) (SM) ([admin_jump_link(Sender, src)]) (CA) (BSA) (RPLY): [msg]" +/proc/CentCom_announce(var/msg, var/mob/Sender, var/iamessage) + msg = "\blue [uppertext(boss_short)]M[iamessage ? " IA" : ""]:[key_name(Sender, 1)] (PP) (VV) (SM) ([admin_jump_link(Sender, src)]) (CA) (BSA) (RPLY): [msg]" for(var/client/C in admins) if(R_ADMIN & C.holder.rights) C << msg diff --git a/code/modules/client/preference_setup/general/04_equipment.dm b/code/modules/client/preference_setup/general/04_equipment.dm index 537f2632e7..79adec9afc 100644 --- a/code/modules/client/preference_setup/general/04_equipment.dm +++ b/code/modules/client/preference_setup/general/04_equipment.dm @@ -34,7 +34,7 @@ pref.all_underwear -= underwear_category_name // TODO - Looks like this is duplicating the work of sanitize_character() if so, remove - if(pref.backbag > 4 || pref.backbag < 1) + if(pref.backbag > 5 || pref.backbag < 1) pref.backbag = 1 //Same as above character.backbag = pref.backbag diff --git a/code/modules/client/preference_setup/loadout/loadout_accessories.dm b/code/modules/client/preference_setup/loadout/loadout_accessories.dm index 769e9966c3..c5a67ad920 100644 --- a/code/modules/client/preference_setup/loadout/loadout_accessories.dm +++ b/code/modules/client/preference_setup/loadout/loadout_accessories.dm @@ -218,4 +218,16 @@ /datum/gear/accessory/chaps/black display_name = "chaps, black" - path = /obj/item/clothing/accessory/chaps/black \ No newline at end of file + path = /obj/item/clothing/accessory/chaps/black + +/datum/gear/accessory/hawaii + display_name = "hawaii shirt" + path = /obj/item/clothing/accessory/hawaii + +/datum/gear/accessory/hawaii/New() + ..() + var/list/shirts = list() + shirts["blue hawaii shirt"] = /obj/item/clothing/accessory/hawaii + shirts["red hawaii shirt"] = /obj/item/clothing/accessory/hawaii/red + shirts["random colored hawaii shirt"] = /obj/item/clothing/accessory/hawaii/random + gear_tweaks += new/datum/gear_tweak/path(shirts) diff --git a/code/modules/client/preference_setup/loadout/loadout_shoes.dm b/code/modules/client/preference_setup/loadout/loadout_shoes.dm index 29c6317b1f..29d6b5944e 100644 --- a/code/modules/client/preference_setup/loadout/loadout_shoes.dm +++ b/code/modules/client/preference_setup/loadout/loadout_shoes.dm @@ -13,6 +13,10 @@ display_name = "workboots" path = /obj/item/clothing/shoes/workboots +/datum/gear/shoes/workboots/toeless + display_name = "toe-less workboots" + path = /obj/item/clothing/shoes/workboots/toeless + /datum/gear/shoes/sandals display_name = "sandals" path = /obj/item/clothing/shoes/sandal @@ -102,5 +106,21 @@ path = /obj/item/clothing/shoes/flipflop /datum/gear/shoes/flipflops/New() + ..() + gear_tweaks = list(gear_tweak_free_color_choice) + +/datum/gear/shoes/athletic + display_name = "athletic shoes" + path = /obj/item/clothing/shoes/athletic + +/datum/gear/shoes/athletic/New() + ..() + gear_tweaks = list(gear_tweak_free_color_choice) + +/datum/gear/shoes/skater + display_name = "skater shoes" + path = /obj/item/clothing/shoes/skater + +/datum/gear/shoes/skater/New() ..() gear_tweaks = list(gear_tweak_free_color_choice) \ No newline at end of file diff --git a/code/modules/client/preference_setup/loadout/loadout_uniform.dm b/code/modules/client/preference_setup/loadout/loadout_uniform.dm index 041751d5c9..c79d4d31b2 100644 --- a/code/modules/client/preference_setup/loadout/loadout_uniform.dm +++ b/code/modules/client/preference_setup/loadout/loadout_uniform.dm @@ -364,4 +364,20 @@ /datum/gear/uniform/whitewedding display_name= "white wedding dress" - path = /obj/item/clothing/under/dress/white \ No newline at end of file + path = /obj/item/clothing/under/dress/white + +/datum/gear/uniform/skirts + display_name = "executive skirt" + path = /obj/item/clothing/under/suit_jacket/female/skirt + +/datum/gear/uniform/dresses + display_name = "sailor dress" + path = /obj/item/clothing/under/dress/sailordress + +/datum/gear/uniform/dresses/eveninggown + display_name = "red evening gown" + path = /obj/item/clothing/under/dress/redeveninggown + +/datum/gear/uniform/dresses/janimaid + display_name = "maid uniform" + path = /obj/item/clothing/under/dress/janimaid \ No newline at end of file diff --git a/code/modules/client/preference_setup/loadout/loadout_xeno.dm b/code/modules/client/preference_setup/loadout/loadout_xeno.dm index b8ed50c23f..cfe92370bf 100644 --- a/code/modules/client/preference_setup/loadout/loadout_xeno.dm +++ b/code/modules/client/preference_setup/loadout/loadout_xeno.dm @@ -126,4 +126,4 @@ display_name = "loincloth (Tajaran, Unathi)" path = /obj/item/clothing/under/shorts/loincloth sort_category = "Xenowear" - whitelisted = list("Tajaran", "Unathi") + //whitelisted = list("Tajaran", "Unathi") //VORESTATION EDIT diff --git a/code/modules/client/preference_setup/occupation/occupation.dm b/code/modules/client/preference_setup/occupation/occupation.dm index f815a3c5ea..444b87754e 100644 --- a/code/modules/client/preference_setup/occupation/occupation.dm +++ b/code/modules/client/preference_setup/occupation/occupation.dm @@ -54,7 +54,7 @@ if(alt_title && !(alt_title in job.alt_titles)) pref.player_alt_titles -= job.title -/datum/category_item/player_setup_item/occupation/content(mob/user, limit = 16, list/splitJobs = list("Chief Medical Officer")) +/datum/category_item/player_setup_item/occupation/content(mob/user, limit = 17, list/splitJobs = list("Chief Medical Officer")) if(!job_master) return diff --git a/code/modules/clothing/head/misc.dm b/code/modules/clothing/head/misc.dm index f65b5373bb..a8305dd9ac 100644 --- a/code/modules/clothing/head/misc.dm +++ b/code/modules/clothing/head/misc.dm @@ -1,5 +1,5 @@ /obj/item/clothing/head/centhat - name = "\improper CentComm. hat" + name = "\improper CentCom. hat" icon_state = "centcom" desc = "It's good to be emperor." siemens_coefficient = 0.9 diff --git a/code/modules/clothing/shoes/jobs.dm b/code/modules/clothing/shoes/jobs.dm index 63d4dc192a..00dc994cad 100644 --- a/code/modules/clothing/shoes/jobs.dm +++ b/code/modules/clothing/shoes/jobs.dm @@ -29,4 +29,11 @@ icon_state = "workboots" armor = list(melee = 40, bullet = 0, laser = 0, energy = 15, bomb = 20, bio = 0, rad = 20) siemens_coefficient = 0.7 - can_hold_knife = 1 \ No newline at end of file + can_hold_knife = 1 + +/obj/item/clothing/shoes/workboots/toeless + name = "toe-less workboots" + desc = "A pair of toeless work boots designed for use in industrial settings. Modified for species whose toes have claws." + icon_state = "workbootstoeless" + item_state_slots = list(slot_r_hand_str = "workboots", slot_l_hand_str = "workboots") + species_restricted = null \ No newline at end of file diff --git a/code/modules/clothing/shoes/miscellaneous.dm b/code/modules/clothing/shoes/miscellaneous.dm index 723d802186..fd8e5c7c40 100644 --- a/code/modules/clothing/shoes/miscellaneous.dm +++ b/code/modules/clothing/shoes/miscellaneous.dm @@ -205,3 +205,15 @@ name = "flip flops" desc = "A pair of foam flip flops. For those not afraid to show a little ankle." icon_state = "thongsandal" + +/obj/item/clothing/shoes/athletic + name = "athletic shoes" + desc = "A pair of sleek atheletic shoes. Made by and for the sporty types." + icon_state = "sportshoe" + item_state_slots = list(slot_r_hand_str = "sportheld", slot_l_hand_str = "sportheld") + +/obj/item/clothing/shoes/skater + name = "skater shoes" + desc = "A pair of wide shoes with thick soles. Designed for skating." + icon_state = "skatershoe" + item_state_slots = list(slot_r_hand_str = "skaterheld", slot_l_hand_str = "skaterheld") diff --git a/code/modules/clothing/spacesuits/rig/suits/station.dm b/code/modules/clothing/spacesuits/rig/suits/station.dm index 17d5d53425..914afe8d97 100644 --- a/code/modules/clothing/spacesuits/rig/suits/station.dm +++ b/code/modules/clothing/spacesuits/rig/suits/station.dm @@ -124,15 +124,16 @@ offline_vision_restriction = 0 helm_type = /obj/item/clothing/head/helmet/space/rig/ce + glove_type = /obj/item/clothing/gloves/gauntlets/rig/ce allowed = list(/obj/item/device/flashlight,/obj/item/weapon/tank,/obj/item/device/suit_cooling_unit,/obj/item/weapon/storage/bag/ore,/obj/item/device/t_scanner,/obj/item/weapon/pickaxe, /obj/item/weapon/rcd) - req_access = list() req_one_access = list() - boot_type = null - glove_type = null +/obj/item/clothing/gloves/gauntlets/rig/ce + name = "insulated gauntlets" + siemens_coefficient = 0 /obj/item/weapon/rig/ce/equipped @@ -146,14 +147,6 @@ /obj/item/rig_module/vision/meson ) - chest_type = /obj/item/clothing/suit/space/rig/ce - boot_type = null - glove_type = null - -/obj/item/clothing/suit/space/rig/ce - heat_protection = UPPER_TORSO|LOWER_TORSO|LEGS|FEET|ARMS|HANDS - body_parts_covered = UPPER_TORSO|LOWER_TORSO|LEGS|FEET|ARMS|HANDS - /obj/item/weapon/rig/hazmat name = "AMI control module" diff --git a/code/modules/clothing/spacesuits/spacesuits.dm b/code/modules/clothing/spacesuits/spacesuits.dm index f06e839ae3..942921b0e9 100644 --- a/code/modules/clothing/spacesuits/spacesuits.dm +++ b/code/modules/clothing/spacesuits/spacesuits.dm @@ -63,7 +63,7 @@ var/list/supporting_limbs //If not-null, automatically splints breaks. Checked when removing the suit. /obj/item/clothing/suit/space/equipped(mob/M) - check_limb_support() + check_limb_support(M) ..() /obj/item/clothing/suit/space/dropped(var/mob/user) @@ -77,14 +77,24 @@ /obj/item/clothing/suit/space/proc/check_limb_support(var/mob/living/carbon/human/user) // If this isn't set, then we don't need to care. - if(!supporting_limbs || !supporting_limbs.len) + if(!istype(user) || isnull(supporting_limbs)) return - if(!istype(user) || user.wear_suit == src) - return + if(user.wear_suit == src) + for(var/obj/item/organ/external/E in user.bad_external_organs) + if(E.is_broken() && E.apply_splint(src)) + user << "You feel [src] constrict about your [E.name], supporting it." + supporting_limbs |= E + else + // Otherwise, remove the splints. + for(var/obj/item/organ/external/E in supporting_limbs) + if(E.splinted == src && E.remove_splint(src)) + user << "\The [src] stops supporting your [E.name]." + supporting_limbs.Cut() - // Otherwise, remove the splints. - for(var/obj/item/organ/external/E in supporting_limbs) - E.status &= ~ ORGAN_SPLINTED - user << "The suit stops supporting your [E.name]." - supporting_limbs = list() +/obj/item/clothing/suit/space/proc/handle_fracture(var/mob/living/carbon/human/user, var/obj/item/organ/external/E) + if(!istype(user) || isnull(supporting_limbs)) + return + if(E.is_broken() && E.apply_splint(src)) + user << "You feel [src] constrict about your [E.name], supporting it." + supporting_limbs |= E diff --git a/code/modules/clothing/spacesuits/void/station.dm b/code/modules/clothing/spacesuits/void/station.dm index f69df89f3f..fd03c3cbe4 100644 --- a/code/modules/clothing/spacesuits/void/station.dm +++ b/code/modules/clothing/spacesuits/void/station.dm @@ -7,7 +7,7 @@ item_state_slots = list(slot_r_hand_str = "eng_helm", slot_l_hand_str = "eng_helm") armor = list(melee = 40, bullet = 5, laser = 20, energy = 5, bomb = 35, bio = 100, rad = 80) -/obj/item/clothing/head/helmet/space/void/engineering/rad +/obj/item/clothing/head/helmet/space/void/engineering/hazmat name = "HAZMAT voidsuit helmet" icon_state = "rig0-engineering_rad" item_state_slots = list(slot_r_hand_str = "eng_helm_rad", slot_l_hand_str = "eng_helm_rad") @@ -26,7 +26,7 @@ armor = list(melee = 40, bullet = 5, laser = 20, energy = 5, bomb = 35, bio = 100, rad = 80) allowed = list(/obj/item/device/flashlight,/obj/item/weapon/tank,/obj/item/device/suit_cooling_unit,/obj/item/weapon/storage/bag/ore,/obj/item/device/t_scanner,/obj/item/weapon/pickaxe, /obj/item/weapon/rcd) -/obj/item/clothing/suit/space/void/engineering/rad +/obj/item/clothing/suit/space/void/engineering/hazmat name = "HAZMAT voidsuit" icon_state = "rig-engineering_rad" item_state_slots = list(slot_r_hand_str = "eng_voidsuit_rad", slot_l_hand_str = "eng_voidsuit_rad") @@ -60,6 +60,11 @@ item_state_slots = list(slot_r_hand_str = "medical_helm", slot_l_hand_str = "medical_helm") armor = list(melee = 30, bullet = 5, laser = 20, energy = 5, bomb = 25, bio = 100, rad = 50) +/obj/item/clothing/head/helmet/space/void/medical/bio + name = "biohazard voidsuit helmet" + icon_state = "rig0-medical_bio" + item_state_slots = list(slot_r_hand_str = "medical_helm_bio", slot_l_hand_str = "medical_helm_bio") + /obj/item/clothing/suit/space/void/medical name = "medical voidsuit" desc = "A special suit that protects against hazardous, low pressure environments. Has minor radiation shielding." @@ -68,6 +73,11 @@ allowed = list(/obj/item/device/flashlight,/obj/item/weapon/tank,/obj/item/device/suit_cooling_unit,/obj/item/weapon/storage/firstaid,/obj/item/device/healthanalyzer,/obj/item/stack/medical) armor = list(melee = 30, bullet = 5, laser = 20, energy = 5, bomb = 25, bio = 100, rad = 50) +/obj/item/clothing/suit/space/void/medical/bio + name = "biohazard voidsuit" + icon_state = "rig-medical_bio" + item_state_slots = list(slot_r_hand_str = "medical_voidsuit_bio", slot_l_hand_str = "medical_voidsuit_bio") + //Security /obj/item/clothing/head/helmet/space/void/security name = "security voidsuit helmet" diff --git a/code/modules/clothing/suits/armor.dm b/code/modules/clothing/suits/armor.dm index 3476ea183a..648cf07a41 100644 --- a/code/modules/clothing/suits/armor.dm +++ b/code/modules/clothing/suits/armor.dm @@ -44,7 +44,6 @@ desc = "A vest with heavy padding to protect against melee attacks." icon_state = "riot" item_state_slots = list(slot_r_hand_str = "swat", slot_l_hand_str = "swat") - slowdown = 1 armor = list(melee = 80, bullet = 10, laser = 10, energy = 10, bomb = 0, bio = 0, rad = 0) flags_inv = HIDEJUMPSUIT siemens_coefficient = 0.5 @@ -323,6 +322,12 @@ icon_badge = "detectivevest_badge" icon_nobadge = "detectivevest_nobadge" +/obj/item/clothing/suit/storage/vest/press + name = "press vest" + desc = "A simple kevlar plate carrier. This one has the word 'Press' embroidered on patches on the back and front." + item_state_slots = list(slot_r_hand_str = "armor", slot_l_hand_str = "armor") + allowed = list(/obj/item/device/flashlight,/obj/item/device/taperecorder,/obj/item/weapon/pen,/obj/item/device/camera_film,/obj/item/device/camera) + /obj/item/clothing/suit/storage/vest/heavy name = "heavy armor vest" desc = "A heavy kevlar plate carrier with webbing attached." diff --git a/code/modules/clothing/suits/miscellaneous.dm b/code/modules/clothing/suits/miscellaneous.dm index fecc19b5a2..2dc9e22404 100644 --- a/code/modules/clothing/suits/miscellaneous.dm +++ b/code/modules/clothing/suits/miscellaneous.dm @@ -90,6 +90,7 @@ icon_state = "vest" item_state_slots = list(slot_r_hand_str = "wcoat", slot_l_hand_str = "wcoat") blood_overlay_type = "armor" + allowed = list (/obj/item/weapon/pen, /obj/item/weapon/paper, /obj/item/device/flashlight, /obj/item/weapon/tank/emergency_oxygen, /obj/item/weapon/storage/fancy/cigarettes, /obj/item/weapon/storage/box/matches, /obj/item/weapon/reagent_containers/food/drinks/flask) body_parts_covered = UPPER_TORSO|LOWER_TORSO /obj/item/clothing/suit/wcoat/red @@ -203,6 +204,7 @@ name = "leather coat" desc = "A long, thick black leather coat." icon_state = "leathercoat_alt" + allowed = list (/obj/item/weapon/pen, /obj/item/weapon/paper, /obj/item/device/flashlight, /obj/item/weapon/tank/emergency_oxygen, /obj/item/weapon/storage/fancy/cigarettes, /obj/item/weapon/storage/box/matches, /obj/item/weapon/reagent_containers/food/drinks/flask) item_state_slots = list(slot_r_hand_str = "leather_jacket", slot_l_hand_str = "leather_jacket") /obj/item/clothing/suit/leathercoat/sec @@ -215,12 +217,14 @@ name = "brown leather coat" desc = "A long, brown leather coat." icon_state = "browncoat" + allowed = list (/obj/item/weapon/pen, /obj/item/weapon/paper, /obj/item/device/flashlight,/obj/item/weapon/tank/emergency_oxygen, /obj/item/weapon/storage/fancy/cigarettes, /obj/item/weapon/storage/box/matches, /obj/item/weapon/reagent_containers/food/drinks/flask) item_state_slots = list(slot_r_hand_str = "brown_jacket", slot_l_hand_str = "brown_jacket") /obj/item/clothing/suit/neocoat name = "black coat" desc = "A flowing, black coat." icon_state = "neocoat" + allowed = list (/obj/item/weapon/pen, /obj/item/weapon/paper, /obj/item/device/flashlight, /obj/item/weapon/tank/emergency_oxygen, /obj/item/weapon/storage/fancy/cigarettes, /obj/item/weapon/storage/box/matches, /obj/item/weapon/reagent_containers/food/drinks/flask) item_state_slots = list(slot_r_hand_str = "leather_jacket", slot_l_hand_str = "leather_jacket") /obj/item/clothing/suit/customs @@ -292,6 +296,7 @@ item_state_slots = list(slot_r_hand_str = "brown_jacket", slot_l_hand_str = "brown_jacket") icon_open = "bomber_open" icon_closed = "bomber" + allowed = list (/obj/item/weapon/pen, /obj/item/weapon/paper, /obj/item/device/flashlight, /obj/item/weapon/tank/emergency_oxygen, /obj/item/weapon/storage/fancy/cigarettes, /obj/item/weapon/storage/box/matches, /obj/item/weapon/reagent_containers/food/drinks/flask) body_parts_covered = UPPER_TORSO|ARMS cold_protection = UPPER_TORSO|ARMS min_cold_protection_temperature = T0C - 20 @@ -311,6 +316,7 @@ name = "leather jacket" desc = "A black leather coat." icon_state = "leather_jacket" + allowed = list (/obj/item/weapon/pen, /obj/item/weapon/paper, /obj/item/device/flashlight, /obj/item/weapon/tank/emergency_oxygen, /obj/item/weapon/storage/fancy/cigarettes, /obj/item/weapon/storage/box/matches, /obj/item/weapon/reagent_containers/food/drinks/flask) body_parts_covered = UPPER_TORSO|ARMS /obj/item/clothing/suit/storage/leather_jacket/alt @@ -330,6 +336,7 @@ item_state_slots = list(slot_r_hand_str = "brown_jacket", slot_l_hand_str = "brown_jacket") icon_open = "brown_jacket_open" icon_closed = "brown_jacket" + allowed = list (/obj/item/weapon/pen, /obj/item/weapon/paper, /obj/item/device/flashlight,/obj/item/weapon/tank/emergency_oxygen, /obj/item/weapon/storage/fancy/cigarettes, /obj/item/weapon/storage/box/matches, /obj/item/weapon/reagent_containers/food/drinks/flask) body_parts_covered = UPPER_TORSO|ARMS /obj/item/clothing/suit/storage/toggle/brown_jacket/nanotrasen @@ -491,6 +498,7 @@ hooded = 1 action_button_name = "Toggle Winter Hood" hoodtype = /obj/item/clothing/head/winterhood + allowed = list (/obj/item/weapon/pen, /obj/item/weapon/paper, /obj/item/device/flashlight,/obj/item/weapon/tank/emergency_oxygen, /obj/item/weapon/storage/fancy/cigarettes, /obj/item/weapon/storage/box/matches, /obj/item/weapon/reagent_containers/food/drinks/flask) /obj/item/clothing/head/winterhood name = "winter hood" @@ -556,6 +564,7 @@ name = "black varsity jacket" desc = "A favorite of jocks everywhere from Sol to Nyx." icon_state = "varsity" + allowed = list (/obj/item/weapon/pen, /obj/item/weapon/paper, /obj/item/device/flashlight,/obj/item/weapon/tank/emergency_oxygen, /obj/item/weapon/storage/fancy/cigarettes, /obj/item/weapon/storage/box/matches, /obj/item/weapon/reagent_containers/food/drinks/flask) item_state_slots = list(slot_r_hand_str = "suit_black", slot_l_hand_str = "suit_black") /obj/item/clothing/suit/varsity/red @@ -588,6 +597,7 @@ item_state_slots = list(slot_r_hand_str = "black_labcoat", slot_l_hand_str = "black_labcoat") icon_open = "trackjacket_open" icon_closed = "trackjacket" + allowed = list (/obj/item/weapon/pen, /obj/item/weapon/paper, /obj/item/device/flashlight,/obj/item/weapon/tank/emergency_oxygen, /obj/item/weapon/storage/fancy/cigarettes, /obj/item/weapon/storage/box/matches, /obj/item/weapon/reagent_containers/food/drinks/flask) /obj/item/clothing/suit/storage/toggle/track/blue name = "blue track jacket" @@ -624,6 +634,7 @@ desc = "A comfy, grey flannel shirt. Unleash your inner hipster." icon_state = "flannel" item_state_slots = list(slot_r_hand_str = "black_labcoat", slot_l_hand_str = "black_labcoat") + allowed = list (/obj/item/weapon/pen, /obj/item/weapon/paper, /obj/item/device/flashlight,/obj/item/weapon/tank/emergency_oxygen, /obj/item/weapon/storage/fancy/cigarettes, /obj/item/weapon/storage/box/matches, /obj/item/weapon/reagent_containers/food/drinks/flask) var/rolled = 0 var/tucked = 0 var/buttoned = 0 diff --git a/code/modules/clothing/suits/utility.dm b/code/modules/clothing/suits/utility.dm index e732a1318e..53ea2d85b6 100644 --- a/code/modules/clothing/suits/utility.dm +++ b/code/modules/clothing/suits/utility.dm @@ -78,7 +78,6 @@ name = "Radiation Hood" icon_state = "rad" desc = "A hood with radiation protective properties. Label: Made with lead, do not eat insulation" - flags_inv = BLOCKHAIR body_parts_covered = HEAD|FACE|EYES armor = list(melee = 0, bullet = 0, laser = 0,energy = 0, bomb = 0, bio = 60, rad = 100) diff --git a/code/modules/clothing/under/accessories/clothing.dm b/code/modules/clothing/under/accessories/clothing.dm index 9878420d7c..af5b6c1c7a 100644 --- a/code/modules/clothing/under/accessories/clothing.dm +++ b/code/modules/clothing/under/accessories/clothing.dm @@ -112,4 +112,20 @@ name = "cargo poncho" desc = "A simple, comfortable cloak without sleeves. This one is tan and grey, the colors of Cargo." icon_state = "cargoponcho" - item_state = "cargoponcho" \ No newline at end of file + item_state = "cargoponcho" + +/obj/item/clothing/accessory/hawaii + name = "flower-pattern shirt" + desc = "You probably need some welder googles to look at this." + icon_state = "hawaii" + +/obj/item/clothing/accessory/hawaii/red + icon_state = "hawaii2" + +/obj/item/clothing/accessory/hawaii/random + name = "flower-pattern shirt" + +/obj/item/clothing/accessory/hawaii/random/New() + if(prob(50)) + icon_state = "hawaii2" + color = color_rotation(rand(-11,12)*15) \ No newline at end of file diff --git a/code/modules/clothing/under/miscellaneous.dm b/code/modules/clothing/under/miscellaneous.dm index e673de378c..4b22d93877 100644 --- a/code/modules/clothing/under/miscellaneous.dm +++ b/code/modules/clothing/under/miscellaneous.dm @@ -182,6 +182,13 @@ icon_state = "black_suit_fem" item_state_slots = list(slot_r_hand_str = "lawyer_black", slot_l_hand_str = "lawyer_black") +/obj/item/clothing/under/suit_jacket/female/skirt + name = "executive skirt" + desc = "A formal suit skirt for women, intended for the station's finest." + body_parts_covered = UPPER_TORSO|LOWER_TORSO|ARMS + icon_state = "black_suit_fem" + item_state = "black_formal_skirt" + /obj/item/clothing/under/suit_jacket/red name = "red suit" desc = "A red suit and blue tie. Somewhat formal." diff --git a/code/modules/clothing/under/pants.dm b/code/modules/clothing/under/pants.dm index 3c210cc0c0..3d35b489d6 100644 --- a/code/modules/clothing/under/pants.dm +++ b/code/modules/clothing/under/pants.dm @@ -6,26 +6,51 @@ gender = PLURAL body_parts_covered = LOWER_TORSO|LEGS +/obj/item/clothing/under/pants/ripped + name = "ripped jeans" + desc = "A nondescript pair of tough blue jeans with holes in them." + icon_state = "jeansripped" + /obj/item/clothing/under/pants/classicjeans name = "classic jeans" desc = "You feel cooler already." icon_state = "jeansclassic" +/obj/item/clothing/under/pants/classicjeans/ripped + name = "ripped classic jeans" + desc = "You feel cooler already. These have holes in them." + icon_state = "jeansclassicripped" + /obj/item/clothing/under/pants/mustangjeans name = "must hang jeans" desc = "Made in the finest space jeans factory this side of Alpha Centauri." icon_state = "jeansmustang" +/obj/item/clothing/under/pants/mustangjeans/ripped + name = "ripped must hang jeans" + desc = "Made in the finest space jeans factory this side of Alpha Centauri. These have holes in them." + icon_state = "jeansmustangripped" + /obj/item/clothing/under/pants/blackjeans name = "black jeans" desc = "Only for those who can pull it off." icon_state = "jeansblack" +/obj/item/clothing/under/pants/blackjeans/ripped + name = "ripped black jeans" + desc = "Only for those who can pull it off. These have holes in them." + icon_state = "jeansblackripped" + /obj/item/clothing/under/pants/greyjeans name = "grey jeans" desc = "Only for those who can pull it off." icon_state = "jeansgrey" +/obj/item/clothing/under/pants/greyjeans/ripped + name = "ripped grey jeans" + desc = "Only for those who can pull it off. These have holes in them." + icon_state = "jeansgreyripped" + /obj/item/clothing/under/pants/youngfolksjeans name = "young folks jeans" desc = "For those tired of boring old jeans. Relive the passion of your youth!" diff --git a/code/modules/clothing/under/shorts.dm b/code/modules/clothing/under/shorts.dm index e108c7f33e..0db35dd08c 100644 --- a/code/modules/clothing/under/shorts.dm +++ b/code/modules/clothing/under/shorts.dm @@ -25,6 +25,10 @@ name = "grey athletic shorts" icon_state = "greyshorts" +/obj/item/clothing/under/shorts/white + name = "white shorts" + icon_state = "whiteshorts" + /obj/item/clothing/under/shorts/jeans name = "jeans shorts" desc = "Some jeans! Just in short form!" diff --git a/code/modules/economy/TradeDestinations.dm b/code/modules/economy/TradeDestinations.dm index ccedfe35ef..8ae548e2ff 100644 --- a/code/modules/economy/TradeDestinations.dm +++ b/code/modules/economy/TradeDestinations.dm @@ -18,7 +18,7 @@ var/list/weighted_mundaneevent_locations = list() //distance is measured in AU and co-relates to travel time /datum/trade_destination/centcomm - name = "CentComm" + name = "CentCom" description = "NanoTrasen's administrative centre for Tau Ceti." distance = 1.2 willing_to_buy = list() diff --git a/code/modules/examine/descriptions/devices.dm b/code/modules/examine/descriptions/devices.dm index 05182df0a5..33954f6672 100644 --- a/code/modules/examine/descriptions/devices.dm +++ b/code/modules/examine/descriptions/devices.dm @@ -8,7 +8,7 @@ that while in space, across star systems, and that the consumer can afford and use without training, is much more recent, and is thanks to the backbone \ that is the Exonet.
\
\ - The Exonet is the predominant interstellar telecom system, servicing trillions of devices across a large portion of human-controlled space. \ + The Exonet is the predominant interstellar telecomm system, servicing trillions of devices across a large portion of human-controlled space. \ It is distributed by a massive network of telecommunication satellites, some privately owned and others owned by the systems’ local governments, \ that utilize FTL technologies to bounce data between satellites at speeds that would not be possible at sub-light technology. This communicator \ uses a protocol called Exonet Protocol Version 2, generally shortened to EPv2.
\ diff --git a/code/modules/examine/descriptions/telecomms.dm b/code/modules/examine/descriptions/telecomms.dm index 747697f55f..45101ec130 100644 --- a/code/modules/examine/descriptions/telecomms.dm +++ b/code/modules/examine/descriptions/telecomms.dm @@ -30,7 +30,7 @@ Exonets at the root node(s), and is typically arranged in a tree structure. The root node(s) are generally government-owned and are very secure \ and resilient to failure.
\
\ - This node is privately owned and maintained by Nanotrasen, and allows the colonists of the "+station_orig+" to have access to the Exonet." + This node is privately owned and maintained by NanoTrasen, and allows the colonists of the "+station_orig+" to have access to the Exonet." description_antag = "An EMP will disable this device for a short period of time. A longer downage can be achieved by turning it off, or rigging \ the APC it uses to turn off remotely, such as with a signaler in the right wire." \ No newline at end of file diff --git a/code/modules/games/cards.dm b/code/modules/games/cards.dm index 3fcf07713b..42bd4b709b 100644 --- a/code/modules/games/cards.dm +++ b/code/modules/games/cards.dm @@ -146,7 +146,7 @@ for(var/datum/playingcard/P in cards) H.cards += P H.concealed = src.concealed - user.drop_from_inventory(src,user.loc) + user.drop_from_inventory(src) qdel(src) H.update_icon() return diff --git a/code/modules/integrated_electronics/_defines.dm b/code/modules/integrated_electronics/_defines.dm new file mode 100644 index 0000000000..97acfd2c98 --- /dev/null +++ b/code/modules/integrated_electronics/_defines.dm @@ -0,0 +1,387 @@ +#define DATA_CHANNEL "data channel" +#define PULSE_CHANNEL "pulse channel" + +/obj/item/integrated_circuit + name = "integrated circuit" + desc = "It's a tiny chip! This one doesn't seem to do much, however." + icon = 'icons/obj/electronic_assemblies.dmi' + icon_state = "template" + w_class = 1 + var/extended_desc = null + var/list/inputs = list() + var/list/outputs = list() + var/list/activators = list() + var/number_of_inputs = 0 //This is how many input pins are created + var/number_of_outputs = 0 //Likewise for output + var/number_of_activators = 0 //Guess + var/list/input_names = list() + var/list/output_names = list() + var/list/activator_names = list() + var/last_used = 0 //Uses world.time + var/complexity = 1 //This acts as a limitation on building machines, more resource-intensive components cost more 'space'. + var/cooldown_per_use = 2 SECONDS + +/obj/item/integrated_circuit/examine(mob/user) + ..() + user << "This board has [inputs.len] input [inputs.len != 1 ? "pins" : "pin"] and \ + [outputs.len] output [outputs.len != 1 ? "pins" : "pin"]." + for(var/datum/integrated_io/input/I in inputs) + if(I.linked.len) + user << "\The [I.name] is connected to [I.get_linked_to_desc()]." + for(var/datum/integrated_io/output/O in outputs) + if(O.linked.len) + user << "\The [O.name] is connected to [O.get_linked_to_desc()]." + for(var/datum/integrated_io/activate/A in activators) + if(A.linked.len) + user << "\The [A.name] is connected to [A.get_linked_to_desc()]." + + interact(user) + +/obj/item/integrated_circuit/New() + ..() + var/i = 0 + if(number_of_inputs) + for(i = number_of_inputs, i > 0, i--) + inputs.Add(new /datum/integrated_io/input(src)) + + if(number_of_outputs) + for(i = number_of_outputs, i > 0, i--) + outputs.Add(new /datum/integrated_io/output(src)) + + if(number_of_activators) + for(i = number_of_activators, i > 0, i--) + activators.Add(new /datum/integrated_io/activate(src)) + + apply_names_to_io() + +/obj/item/integrated_circuit/proc/apply_names_to_io() + var/i = 1 + if(input_names.len) + for(var/datum/integrated_io/input/I in inputs) + I.name = "[input_names[i]]" + i++ + i = 1 + if(output_names.len) + for(var/datum/integrated_io/output/O in outputs) + O.name = "[output_names[i]]" + i++ + + i = 1 + if(activator_names.len) + for(var/datum/integrated_io/activate/A in activators) + A.name = "[activator_names[i]]" + i++ + +/obj/item/integrated_circuit/proc/on_data_written() //Override this for special behaviour when new data gets pushed to the circuit. + return + +/obj/item/integrated_circuit/Destroy() + for(var/datum/integrated_io/I in inputs) + qdel(I) + for(var/datum/integrated_io/O in outputs) + qdel(O) + for(var/datum/integrated_io/A in activators) + qdel(A) + ..() + +/obj/item/integrated_circuit/emp_act(severity) + for(var/datum/integrated_io/io in inputs + outputs + activators) + io.scramble() + +/obj/item/integrated_circuit/verb/rename_component() + set name = "Rename Circuit" + set category = "Object" + set desc = "Rename your circuit, useful to stay organized." + + var/mob/M = usr + + if(!M.canmove || M.stat || M.restrained()) + return + + var/input = sanitizeSafe(input("What do you want to name the circuit?", "Rename", src.name), MAX_NAME_LEN) + + if(src && input) + M << "The circuit '[src.name]' is now labeled '[input]'." + name = input + +/obj/item/integrated_circuit/proc/get_pin_ref(var/pin_type, var/pin_number) + switch(pin_type) + if("input") + if(pin_number > inputs.len) + return null + return inputs[pin_number] + if("output") + if(pin_number > outputs.len) + return null + return outputs[pin_number] + if("activator") + if(pin_number > activators.len) + return null + return activators[pin_number] + return null + +/obj/item/integrated_circuit/interact(mob/user) + if(get_dist(get_turf(src), user) > 1) + user.unset_machine(src) + return + var/HTML = "[src.name]" + HTML += "
" + HTML += "
" + + HTML += "
\[Refresh\] | " + HTML += "\[Rename\]
" + + HTML += "" + HTML += "" + HTML += "" + HTML += "" + HTML += "" + + var/column_width = 3 + var/row_height = max(inputs.len, outputs.len, 1) + var/i + var/j + for(i = 1, i < row_height+1, i++) + HTML += "" + for(j = 1, j < column_width+1, j++) + var/datum/integrated_io/io = null + var/words = null + var/height = 1 + switch(j) + if(1) + io = get_pin_ref("input",i) + if(io) + if(io.linked.len) + words = "[io.name] [io.display_data()]
" + for(var/datum/integrated_io/linked in io.linked) + words += "\[[linked.name]\] \ + @ [linked.holder]
" + else // "Click here!" + words = "[io.name] [io.display_data()]
" + for(var/datum/integrated_io/linked in io.linked) + words += "\[[linked.name]\] \ + @ [linked.holder]
" + if(outputs.len > inputs.len) + // height = Floor(outputs.len / inputs.len) + height = 1 // Because of bugs, if there's more outputs than inputs, it causes the output side to be hidden. + //world << "I wrote [words] at ([i],[j]). Height = [height]." + if(2) + if(i == 1) + words = "[src.name]

[src.desc]" + height = row_height + //world << "I wrote the center piece because i was equal to 1, at ([i],[j]). Height = [height]." + else + continue + if(3) + io = get_pin_ref("output",i) + if(io) + if(io.linked.len) + words = "[io.name] [io.display_data()]
" + for(var/datum/integrated_io/linked in io.linked) + words += "\[[linked.name]\] \ + @ [linked.holder]
" + else + words = "[io.name] [io.display_data()]
" + for(var/datum/integrated_io/linked in io.linked) + words += "\[[linked.name]\] \ + @ [linked.holder]
" + if(inputs.len > outputs.len) + // height = Floor(inputs.len / outputs.len) + height = 1 // See above. + //world << "I wrote [words] at ([i],[j]). Height = [height]." + HTML += "" + //HTML += "" + //world << "Writing to ([i],[j])." + HTML += "" + + if(activators.len) + for(i = 1, i < activators.len+1, i++) + var/datum/integrated_io/io = null + var/words = null + io = get_pin_ref("activator",i) + if(io) + if(io.linked.len) + words = "[io.name]
" + for(var/datum/integrated_io/linked in io.linked) + words += "\[[linked.name]\] \ + @ [linked.holder]
" + else // "Click here!" + words = "[io.name]
" + for(var/datum/integrated_io/linked in io.linked) + words += "\[[linked.name]\] \ + @ [linked.holder]
" + HTML += "" + HTML += "" + HTML += "" + + HTML += "
[words][words]
[words]
" + HTML += "" + + HTML += "
Complexity: [complexity]" + HTML += "
[extended_desc]" + + HTML += "" + user << browse(HTML, "window=circuit-\ref[src];size=600x350;border=1;can_resize=1;can_close=1;can_minimize=1") + + //user << sanitize(HTML, "window=debug;size=400x400;border=1;can_resize=1;can_close=1;can_minimize=1") + //world << sanitize(HTML) + + user.set_machine(src) + onclose(user, "circuit-\ref[src]") + +/obj/item/integrated_circuit/Topic(href, href_list[]) + var/mob/living/user = locate(href_list["user"]) in mob_list + var/pin = locate(href_list["pin"]) in inputs + outputs + activators + + if(!user || !user.Adjacent(get_turf(src)) ) + return 1 + + if(!user.canmove || user.stat || user.restrained()) + return + + if(href_list["wire"]) + if(ishuman(user) && Adjacent(user)) + var/mob/living/carbon/human/H = user + var/obj/held_item = H.get_active_hand() + + if(istype(held_item, /obj/item/device/integrated_electronics/wirer)) + var/obj/item/device/integrated_electronics/wirer/wirer = held_item + if(pin) + wirer.wire(pin, user) + + else if(istype(held_item, /obj/item/device/integrated_electronics/debugger)) + var/obj/item/device/integrated_electronics/debugger/debugger = held_item + if(pin) + debugger.write_data(pin, user) + + // if(istype(H.r_hand, /obj/item/device/integrated_electronics/wirer)) + // wirer = H.r_hand + // else if(istype(H.l_hand, /obj/item/device/integrated_electronics/wirer)) + // wirer = H.l_hand + + // if(wirer && pin) + // wirer.wire(pin, user) + else + user << "You can't do a whole lot without tools." + + if(href_list["examine"]) + examine(user) + + if(href_list["rename"]) + rename_component(user) + + interact(user) // To refresh the UI. + +/datum/integrated_io + var/name = "input/output" + var/obj/item/integrated_circuit/holder = null + var/data = null + var/list/linked = list() + var/io_type = DATA_CHANNEL + +/datum/integrated_io/New(var/newloc) + ..() + holder = newloc + if(!holder) + message_admins("ERROR: An integrated_io ([src.name]) spawned without a holder! This is a bug.") + +/datum/integrated_io/Destroy() + disconnect() + holder = null + ..() + +/datum/integrated_io/proc/display_data() + if(isnull(data)) + return "(null)" // Empty data means nothing to show. + if(istext(data)) + return "(\"[data]\")" // Wraps the 'string' in escaped quotes, so that people know it's a 'string'. + if(istype(data, /atom)) + var/atom/A = data + return "([A.name] \[Ref\])" // For refs, we want just the name displayed. + return "([data])" // Nothing special needed for numbers or other stuff. + +/datum/integrated_io/activate/display_data() + return "(\[pulse\])" + +/datum/integrated_io/proc/scramble() + if(isnull(data)) + return + if(isnum(data)) + write_data_to_pin(rand(-10000, 10000)) + if(istext(data)) + write_data_to_pin("ERROR") + push_data() + +/datum/integrated_io/activate/scramble() + push_data() + +/datum/integrated_io/proc/write_data_to_pin(var/new_data) + if(isnull(new_data) || isnum(new_data) || istext(new_data) || istype(new_data, /atom/) ) // Anything else is a type we don't want. + data = new_data + holder.on_data_written() + +/datum/integrated_io/proc/push_data() + if(linked.len) + for(var/datum/integrated_io/io in linked) + io.write_data_to_pin(data) + +/datum/integrated_io/activate/push_data() + if(linked.len) + for(var/datum/integrated_io/io in linked) + io.holder.work() + +/datum/integrated_io/proc/pull_data() + if(linked.len) + for(var/datum/integrated_io/io in linked) + write_data_to_pin(io.data) + +/datum/integrated_io/proc/get_linked_to_desc() + if(linked.len) + var/result = english_list(linked) + return "the [result]" + return "nothing" + +/datum/integrated_io/proc/disconnect() + if(linked.len) + //First we iterate over everything we are linked to. + for(var/datum/integrated_io/their_io in linked) + //While doing that, we iterate them as well, and disconnect ourselves from them. + for(var/datum/integrated_io/their_linked_io in their_io.linked) + if(their_linked_io == src) + their_io.linked.Remove(src) + else + continue + //Now that we're removed from them, we gotta remove them from us. + src.linked.Remove(their_io) + +/datum/integrated_io/input + name = "input pin" + +/datum/integrated_io/output + name = "output pin" + +/datum/integrated_io/activate + name = "activation pin" + io_type = PULSE_CHANNEL + +/obj/item/integrated_circuit/proc/push_data() + for(var/datum/integrated_io/output/O in outputs) + O.push_data() + +/obj/item/integrated_circuit/proc/pull_data() + for(var/datum/integrated_io/input/I in inputs) + I.push_data() + +/obj/item/integrated_circuit/proc/work(var/datum/integrated_io/io) + if(last_used + cooldown_per_use > world.time) // All intergrated circuits have an internal cooldown, to protect from spam. + return 0 + last_used = world.time + return 1 + +/obj/item/integrated_circuit/proc/disconnect_all() + for(var/datum/integrated_io/input/I in inputs) + I.disconnect() + for(var/datum/integrated_io/output/O in outputs) + O.disconnect() + for(var/datum/integrated_io/activate/A in activators) + A.disconnect() \ No newline at end of file diff --git a/code/modules/integrated_electronics/arithmetic.dm b/code/modules/integrated_electronics/arithmetic.dm new file mode 100644 index 0000000000..3fc60c64f9 --- /dev/null +++ b/code/modules/integrated_electronics/arithmetic.dm @@ -0,0 +1,183 @@ +//These circuits do simple math. +/obj/item/integrated_circuit/arithmetic + complexity = 1 + number_of_inputs = 8 + number_of_outputs = 1 + number_of_activators = 1 + input_names = list( + "A", + "B", + "C", + "D", + "E", + "F", + "G", + "H" + ) + output_names = list( + "result" + ) + activator_names = list( + "compute" + ) + +// +Adding+ // + +/obj/item/integrated_circuit/arithmetic/addition + name = "addition circuit" + desc = "This circuit can add numbers together." + icon_state = "addition" + +/obj/item/integrated_circuit/arithmetic/addition/work() + if(..()) + var/result = 0 + for(var/datum/integrated_io/input/I in inputs) + I.pull_data() + if(isnum(I.data)) + result = result + I.data + + for(var/datum/integrated_io/output/O in outputs) + O.data = result + O.push_data() + +// -Subtracting- // + +/obj/item/integrated_circuit/arithmetic/subtraction + name = "subtraction circuit" + desc = "This circuit can subtract numbers." + icon_state = "subtraction" + +/obj/item/integrated_circuit/arithmetic/subtraction/work() + if(..()) + var/result = 0 + for(var/datum/integrated_io/input/I in inputs) + I.pull_data() + if(isnum(I.data)) + result = result - I.data + + for(var/datum/integrated_io/output/O in outputs) + O.data = result + O.push_data() + +// *Multiply* // + +/obj/item/integrated_circuit/arithmetic/multiplication + name = "multiplication circuit" + desc = "This circuit can multiply numbers." + icon_state = "multiplication" + +/obj/item/integrated_circuit/arithmetic/subtraction/work() + if(..()) + var/result = 0 + for(var/datum/integrated_io/input/I in inputs) + I.pull_data() + if(isnum(I.data)) + result = result * I.data + + for(var/datum/integrated_io/output/O in outputs) + O.data = result + O.push_data() + +// /Division/ // + +/obj/item/integrated_circuit/arithmetic/division + name = "division circuit" + desc = "This circuit can divide numbers, just don't think about trying to divide by zero!" + icon_state = "division" + +/obj/item/integrated_circuit/arithmetic/division/work() + if(..()) + var/result = 0 + for(var/datum/integrated_io/input/I in inputs) + I.pull_data() + if(isnum(I.data) && I.data != 0) //No runtimes here. + result = result / I.data + + for(var/datum/integrated_io/output/O in outputs) + O.data = result + O.push_data() + +// Absolute // + +/obj/item/integrated_circuit/arithmetic/absolute + name = "absolute circuit" + desc = "This outputs a non-negative version of the number you put in. This may also be thought of as its distance from zero." + icon_state = "absolute" + number_of_inputs = 1 + number_of_outputs = 1 + +/obj/item/integrated_circuit/arithmetic/absolute/work() + if(..()) + var/result = 0 + for(var/datum/integrated_io/input/I in inputs) + I.pull_data() + if(isnum(I.data) && I.data != 0) + result = abs(result) + + for(var/datum/integrated_io/output/O in outputs) + O.data = result + O.push_data() + +// Averaging // + +/obj/item/integrated_circuit/arithmetic/average + name = "average circuit" + desc = "This circuit is of average quality, however it will compute the average for numbers you give it." + icon_state = "average" + +/obj/item/integrated_circuit/arithmetic/average/work() + if(..()) + var/result = 0 + var/inputs_used = 0 + for(var/datum/integrated_io/input/I in inputs) + I.pull_data() + if(isnum(I.data)) + inputs_used++ + result = result + I.data + + if(inputs_used) + result = result / inputs_used + + for(var/datum/integrated_io/output/O in outputs) + O.data = result + O.push_data() + +// Pi, because why the hell not? // +/obj/item/integrated_circuit/arithmetic/pi + name = "pi constant circuit" + desc = "Not recommended for cooking. Outputs '3.14159' when it receives a pulse." + icon_state = "pi" + number_of_inputs = 0 + number_of_outputs = 1 + +/obj/item/integrated_circuit/arithmetic/pi/work() + if(..()) + var/datum/integrated_io/output/O = outputs[1] + O.data = 3.14159 + O.push_data() + +// Random // +/obj/item/integrated_circuit/arithmetic/random + name = "random number generator circuit" + desc = "This gives a random (integer) number between values A and B inclusive." + icon_state = "random" + number_of_inputs = 2 + number_of_outputs = 1 + number_of_activators = 1 + input_names = list( + "L", + "H" + ) + +/obj/item/integrated_circuit/arithmetic/random/work() + if(..()) + var/result = 0 + var/datum/integrated_io/L = inputs[1] + var/datum/integrated_io/H = inputs[2] + + if(isnum(L.data) && isnum(H.data)) + result = rand(L.data, H.data) + + for(var/datum/integrated_io/output/O in outputs) + O.data = result + O.push_data() \ No newline at end of file diff --git a/code/modules/integrated_electronics/assemblies.dm b/code/modules/integrated_electronics/assemblies.dm new file mode 100644 index 0000000000..f9037e60e7 --- /dev/null +++ b/code/modules/integrated_electronics/assemblies.dm @@ -0,0 +1,168 @@ +/obj/item/device/electronic_assembly + name = "electronic assembly" + desc = "It's a case, for building electronics with." + w_class = 2 + icon = 'icons/obj/electronic_assemblies.dmi' + icon_state = "setup_small" + var/max_components = 10 + var/max_complexity = 40 + var/opened = 0 + +/obj/item/device/electronic_assembly/medium + name = "electronic mechanism" + icon_state = "setup_medium" + w_class = 3 + max_components = 20 + max_complexity = 80 + +/obj/item/device/electronic_assembly/large + name = "electronic machine" + icon_state = "setup_large" + w_class = 4 + max_components = 30 + max_complexity = 120 + +/obj/item/device/electronic_assembly/drone + name = "electronic drone" + icon_state = "setup_drone" + w_class = 3 + max_components = 25 + max_complexity = 100 + +/obj/item/device/electronic_assembly/interact(mob/user) + if(get_dist(get_turf(src), user) > 1) + user.unset_machine(src) + return + var/total_parts = 0 + var/total_complexity = 0 + for(var/obj/item/integrated_circuit/part in contents) + total_parts++ + total_complexity = total_complexity + part.complexity + var/HTML = "[src.name]" + + HTML += "
\[Refresh\] | " + HTML += "\[Rename\]
" + HTML += "[total_parts]/[max_components] ([round((total_parts / max_components) * 100, 0.1)]%) space taken up in the assembly.
" + HTML += "[total_complexity]/[max_complexity] ([round((total_complexity / max_complexity) * 100, 0.1)]%) maximum complexity." + HTML += "

" + HTML += "Components;
" + for(var/obj/item/integrated_circuit/circuit in contents) + HTML += "[circuit.name] | " + HTML += "\[Rename\]" + HTML += "
" + + HTML += "" + user << browse(HTML, "window=assembly-\ref[src];size=600x350;border=1;can_resize=1;can_close=1;can_minimize=1") + +/obj/item/device/electronic_assembly/Topic(href, href_list[]) + var/mob/living/user = locate(href_list["user"]) in mob_list + + if(..()) + return 1 + + if(!user.canmove || user.stat || user.restrained()) + return + + if(href_list["rename"]) + rename(user) + + interact(user) // To refresh the UI. + +/obj/item/device/electronic_assembly/verb/rename() + set name = "Rename Circuit" + set category = "Object" + set desc = "Rename your circuit, useful to stay organized." + + var/mob/M = usr + + if(!M.canmove || M.stat || M.restrained()) + return + + var/input = sanitizeSafe(input("What do you want to name this?", "Rename", src.name), MAX_NAME_LEN) + + if(src && input) + M << "The machine now has a label reading '[input]'." + name = input + +/obj/item/device/electronic_assembly/update_icon() + if(opened) + icon_state = initial(icon_state) + "-open" + else + icon_state = initial(icon_state) + +/obj/item/device/electronic_assembly/examine(mob/user) + ..() + if(user.Adjacent(src)) + if(!opened) + for(var/obj/item/integrated_circuit/output/screen/S in contents) + if(S.stuff_to_display) + user << "There's a little screen labeled '[S.name]', which displays '[S.stuff_to_display]'." + else + interact(user) + // var/obj/item/integrated_circuit/IC = input(user, "Which circuit do you want to examine?", "Examination") as null|anything in contents + // if(IC) + // IC.examine(user) + +/obj/item/device/electronic_assembly/attackby(var/obj/item/I, var/mob/user) + if(istype(I, /obj/item/integrated_circuit)) + if(!opened) + user << "\The [src] isn't opened, so you can't put anything inside. Try using a crowbar." + return 0 + var/obj/item/integrated_circuit/IC = I + var/total_parts = 0 + var/total_complexity = 0 + for(var/obj/item/integrated_circuit/part in contents) + total_parts++ + total_complexity = total_complexity + part.complexity + + if( (total_parts + 1) >= max_components) + user << "You can't seem to add this [IC.name], since there's no more room." + return 0 + if( (total_complexity + IC.complexity) >= max_complexity) + user << "You can't seem to add this [IC.name], since this setup's too complicated for the case." + return 0 + + user << "You slide \the [IC] inside \the [src]." + user.drop_item() + IC.forceMove(src) + playsound(src.loc, 'sound/items/Deconstruct.ogg', 50, 1) + if(istype(I, /obj/item/weapon/screwdriver)) + if(!opened) + user << "\The [src] isn't opened, so you can't remove anything inside. Try using a crowbar." + return 0 + if(!contents.len) + user << "There's nothing inside this to remove!" + return 0 + var/obj/item/integrated_circuit/option = input("What do you want to remove?", "Component Removal") as null|anything in contents + if(option) + option.disconnect_all() + option.forceMove(get_turf(src)) + playsound(src.loc, 'sound/items/Crowbar.ogg', 50, 1) + user << "You pop \the [option] out of the case, and slide it out." + if(istype(I, /obj/item/weapon/crowbar)) + playsound(src.loc, 'sound/items/Crowbar.ogg', 50, 1) + opened = !opened + user << "You [opened ? "opened" : "closed"] \the [src]." + update_icon() + if(istype(I, /obj/item/device/integrated_electronics/wirer)) + if(opened) + var/obj/item/integrated_circuit/IC = input(user, "Which circuit do you want to examine?", "Examination") as null|anything in contents + if(IC) + IC.examine(user) + else + user << "\The [src] isn't opened, so you can't fiddle with the internal components. \ + Try using a crowbar." + +/obj/item/device/electronic_assembly/attack_self(mob/user) + var/list/available_inputs = list() + for(var/obj/item/integrated_circuit/input/input in contents) + if(input.can_be_asked_input) + available_inputs.Add(input) + var/obj/item/integrated_circuit/input/choice = input(user, "What do you want to interact with?", "Interaction") as null|anything in available_inputs + if(choice) + choice.ask_for_input(user) + +/obj/item/device/electronic_assembly/emp_act(severity) + ..() + for(var/atom/movable/AM in contents) + AM.emp_act(severity) diff --git a/code/modules/integrated_electronics/converters.dm b/code/modules/integrated_electronics/converters.dm new file mode 100644 index 0000000000..7a837abbfa --- /dev/null +++ b/code/modules/integrated_electronics/converters.dm @@ -0,0 +1,133 @@ +//These circuits convert one variable to another. +/obj/item/integrated_circuit/converter + complexity = 2 + number_of_inputs = 1 + number_of_outputs = 1 + number_of_activators = 1 + input_names = list( + "input", + ) + output_names = list( + "result" + ) + activator_names = list( + "convert" + ) + +/obj/item/integrated_circuit/converter/num2text + name = "number to string" + desc = "This circuit can convert a number variable into a string." + icon_state = "num-string" + +/obj/item/integrated_circuit/converter/num2text/work() + if(..()) + var/result = null + var/datum/integrated_io/incoming = inputs[1] + var/datum/integrated_io/outgoing = outputs[1] + if(incoming.data && isnum(incoming.data)) + result = num2text(incoming.data) + + outgoing.data = result + outgoing.push_data() + +/obj/item/integrated_circuit/converter/text2num + name = "string to number" + desc = "This circuit can convert a string variable into a number." + icon_state = "string-num" + +/obj/item/integrated_circuit/converter/text2num/work() + if(..()) + var/result = null + var/datum/integrated_io/incoming = inputs[1] + var/datum/integrated_io/outgoing = outputs[1] + if(incoming.data && istext(incoming.data)) + result = text2num(incoming.data) + + outgoing.data = result + outgoing.push_data() + +/obj/item/integrated_circuit/converter/ref2text + name = "reference to string" + desc = "This circuit can convert a reference to something else to a string, specifically the name of that reference." + icon_state = "ref-string" + +/obj/item/integrated_circuit/converter/ref2text/work() + if(..()) + var/result = null + var/datum/integrated_io/incoming = inputs[1] + var/datum/integrated_io/outgoing = outputs[1] + if(incoming.data && istype(incoming.data, /atom/)) + var/atom/A = incoming.data + result = A.name + + outgoing.data = result + outgoing.push_data() + +/obj/item/integrated_circuit/converter/lowercase + name = "lowercase string converter" + desc = "this will cause a string to come out in all lowercase." + icon_state = "lowercase" + +/obj/item/integrated_circuit/converter/lowercase/work() + if(..()) + var/result = null + var/datum/integrated_io/incoming = inputs[1] + var/datum/integrated_io/outgoing = outputs[1] + if(incoming.data && istext(incoming.data)) + result = lowertext(incoming.data) + + outgoing.data = result + outgoing.push_data() + +/obj/item/integrated_circuit/converter/uppercase + name = "uppercase string converter" + desc = "THIS WILL CAUSE A STRING TO COME OUT IN ALL UPPERCASE." + icon_state = "uppercase" + +/obj/item/integrated_circuit/converter/uppercase/work() + if(..()) + var/result = null + var/datum/integrated_io/incoming = inputs[1] + var/datum/integrated_io/outgoing = outputs[1] + if(incoming.data && istext(incoming.data)) + result = uppertext(incoming.data) + + outgoing.data = result + outgoing.push_data() + +/obj/item/integrated_circuit/converter/concatenatior + name = "concatenatior" + desc = "This joins many strings together to get one big string." + complexity = 4 + number_of_inputs = 8 + number_of_outputs = 1 + number_of_activators = 1 + input_names = list( + "A", + "B", + "C", + "D", + "E", + "F", + "G", + "H" + ) + output_names = list( + "result" + ) + activator_names = list( + "concatenate" + ) + + +/obj/item/integrated_circuit/converter/concatenatior/work() + if(..()) + var/result = null + for(var/datum/integrated_io/input/I in inputs) + I.pull_data() + if(istext(I.data)) + result = result + I.data + + var/datum/integrated_io/outgoing = outputs[1] + outgoing.data = result + outgoing.push_data() \ No newline at end of file diff --git a/code/modules/integrated_electronics/coordinate.dm b/code/modules/integrated_electronics/coordinate.dm new file mode 100644 index 0000000000..78b7ebcb4f --- /dev/null +++ b/code/modules/integrated_electronics/coordinate.dm @@ -0,0 +1,75 @@ +//This circuit gives information on where the machine is. +/obj/item/integrated_circuit/gps + name = "global positioning system" + desc = "This allows you to easily know the position of a machine containing this device." + icon_state = "gps" + complexity = 4 + number_of_inputs = 0 + number_of_outputs = 2 + number_of_activators = 1 + input_names = list( + ) + output_names = list( + "X (abs)", + "Y (abs)" + ) + activator_names = list( + "get coordinates" + ) + +/obj/item/integrated_circuit/gps/work() + if(..()) + var/turf/T = get_turf(src) + var/datum/integrated_io/result_x = outputs[1] + var/datum/integrated_io/result_y = outputs[2] + + result_x.data = null + result_y.data = null + if(!T) + return + + result_x.data = T.x + result_y.data = T.y + + for(var/datum/integrated_io/output/O in outputs) + O.push_data() + +/obj/item/integrated_circuit/abs_to_rel_coords + name = "abs to rel coordinate converter" + desc = "Easily convert absolute coordinates to relative coordinates with this." + complexity = 4 + number_of_inputs = 4 + number_of_outputs = 2 + number_of_activators = 1 + input_names = list( + "X1 (abs)", + "Y1 (abs)", + "X2 (abs)", + "Y2 (abs)" + ) + output_names = list( + "X (rel)", + "Y (rel)" + ) + activator_names = list( + "compute rel coordinates" + ) + +/obj/item/integrated_circuit/abs_to_rel_coords/work() + var/datum/integrated_io/x1 = inputs[1] + var/datum/integrated_io/y1 = inputs[2] + + var/datum/integrated_io/x2 = inputs[3] + var/datum/integrated_io/y2 = inputs[4] + + var/datum/integrated_io/result_x = outputs[1] + var/datum/integrated_io/result_y = outputs[2] + + if(x1.data && y1.data && x2.data && y2.data) + result_x.data = x1.data - x2.data + result_y.data = y1.data - y2.data + + + for(var/datum/integrated_io/output/O in outputs) + O.push_data() + ..() diff --git a/code/modules/integrated_electronics/data_transfer.dm b/code/modules/integrated_electronics/data_transfer.dm new file mode 100644 index 0000000000..12380e9cca --- /dev/null +++ b/code/modules/integrated_electronics/data_transfer.dm @@ -0,0 +1,79 @@ +/obj/item/integrated_circuit/transfer/splitter + name = "splitter" + desc = "Splits incoming data into all of the output pins." + icon_state = "splitter" + complexity = 3 + number_of_inputs = 1 + number_of_outputs = 2 + input_names = list( + "data to split" + ) + output_names = list( + "A", + "B", + "C", + "D", + "E", + "F", + "G", + "H" + ) + +/obj/item/integrated_circuit/transfer/splitter/medium + name = "four splitter" + icon_state = "splitter4" + complexity = 5 + number_of_inputs = 1 + number_of_outputs = 4 + +/obj/item/integrated_circuit/transfer/splitter/large + name = "eight splitter" + icon_state = "splitter8" + complexity = 9 + number_of_inputs = 1 + number_of_outputs = 8 + +/obj/item/integrated_circuit/transfer/splitter/work() + if(..()) + var/datum/integrated_io/I = inputs[1] + for(var/datum/integrated_io/output/O in outputs) + O.data = I.data + +/obj/item/integrated_circuit/transfer/activator_splitter + name = "activator splitter" + desc = "Splits incoming activation pulses into all of the output pins." + icon_state = "splitter" + complexity = 3 + number_of_activators = 3 + activator_names = list( + "incoming pulse", + "outgoing pulse A", + "outgoing pulse B", + "outgoing pulse C", + "outgoing pulse D", + "outgoing pulse E", + "outgoing pulse F", + "outgoing pulse G", + "outgoing pulse H" + ) + +/obj/item/integrated_circuit/transfer/activator_splitter/work() + if(..()) + for(var/datum/integrated_io/activate/A in outputs) + if(A == activators[1]) + continue + if(A.linked.len) + for(var/datum/integrated_io/activate/target in A.linked) + target.holder.work() + +/obj/item/integrated_circuit/transfer/activator_splitter/medium + name = "four activator splitter" + icon_state = "splitter4" + complexity = 5 + number_of_activators = 5 + +/obj/item/integrated_circuit/transfer/activator_splitter/large + name = "eight activator splitter" + icon_state = "splitter4" + complexity = 9 + number_of_activators = 9 diff --git a/code/modules/integrated_electronics/input_output.dm b/code/modules/integrated_electronics/input_output.dm new file mode 100644 index 0000000000..42da340654 --- /dev/null +++ b/code/modules/integrated_electronics/input_output.dm @@ -0,0 +1,494 @@ +/obj/item/integrated_circuit/input + var/can_be_asked_input = 0 + +/obj/item/integrated_circuit/input/proc/ask_for_input(mob/user) + return + +/obj/item/integrated_circuit/input/button + name = "button" + desc = "This tiny button must do something, right?" + icon_state = "button" + number_of_inputs = 0 + number_of_outputs = 0 + number_of_activators = 1 + complexity = 1 + can_be_asked_input = 1 + activator_names = list( + "on pressed" + ) + +/obj/item/integrated_circuit/input/button/ask_for_input(mob/user) //Bit misleading name for this specific use. + var/datum/integrated_io/A = activators[1] + if(A.linked.len) + for(var/datum/integrated_io/activate/target in A.linked) + target.holder.work() + user << "You press the button labeled '[src.name]'." + +/obj/item/integrated_circuit/input/numberpad + name = "number pad" + desc = "This small number pad allows someone to input a number into the system." + icon_state = "numberpad" + number_of_inputs = 0 + number_of_outputs = 1 + number_of_activators = 1 + complexity = 2 + can_be_asked_input = 1 + output_names = list( + "number entered" + ) + activator_names = list( + "on entered" + ) + +/obj/item/integrated_circuit/input/numberpad/ask_for_input(mob/user) + var/new_input = input(user, "Enter a number, please.","Number pad") as null|num + if(isnum(new_input)) + var/datum/integrated_io/O = outputs[1] + O.data = new_input + O.push_data() + var/datum/integrated_io/A = activators[1] + A.push_data() + +/obj/item/integrated_circuit/input/textpad + name = "text pad" + desc = "This small text pad allows someone to input a string into the system." + icon_state = "textpad" + number_of_inputs = 0 + number_of_outputs = 1 + number_of_activators = 1 + complexity = 2 + can_be_asked_input = 1 + output_names = list( + "string entered" + ) + activator_names = list( + "on entered" + ) + +/obj/item/integrated_circuit/input/textpad/ask_for_input(mob/user) + var/new_input = input(user, "Enter some words, please.","Number pad") as null|text + if(new_input && istext(new_input)) + var/datum/integrated_io/O = outputs[1] + O.data = new_input + O.push_data() + var/datum/integrated_io/A = activators[1] + A.push_data() + +/obj/item/integrated_circuit/input/med_scanner + name = "integrated medical analyser" + desc = "A very small version of the common medical analyser. This allows the machine to know how healthy someone is." + icon_state = "medscan" + number_of_inputs = 1 + number_of_outputs = 2 + number_of_activators = 1 + complexity = 4 + input_names = list( + "target ref" + ) + output_names = list( + "total health %", + "total missing health" + ) + activator_names = list( + "scan" + ) + +/obj/item/integrated_circuit/input/med_scanner/work() + if(..()) + var/datum/integrated_io/I = inputs[1] + if(!I.data || !ishuman(I.data)) //Invalid input + return + var/mob/living/carbon/human/H = I.data + if(H.Adjacent(get_turf(src))) // Like normal analysers, it can't be used at range. + var/total_health = round(H.health/H.maxHealth, 0.1)*100 + var/missing_health = H.maxHealth - H.health + + var/datum/integrated_io/total = outputs[1] + var/datum/integrated_io/missing = outputs[2] + + total.data = total_health + missing.data = missing_health + + for(var/datum/integrated_io/output/O in outputs) + O.push_data() + +/obj/item/integrated_circuit/input/adv_med_scanner + name = "integrated advanced medical analyser" + desc = "A very small version of the common medical analyser. This allows the machine to know how healthy someone is. \ + This type is much more precise, allowing the machine to know much more about the target than a normal analyzer." + icon_state = "medscan_adv" + number_of_inputs = 1 + number_of_outputs = 7 + number_of_activators = 1 + complexity = 12 + input_names = list( + "target ref" + ) + output_names = list( + "total health %", + "total missing health", + "brute damage", + "burn damage", + "tox damage", + "oxy damage", + "clone damage" + ) + activator_names = list( + "scan" + ) + +/obj/item/integrated_circuit/input/adv_med_scanner/work() + if(..()) + var/datum/integrated_io/I = inputs[1] + if(!I.data || !ishuman(I.data)) //Invalid input + return + var/mob/living/carbon/human/H = I.data + if(H.Adjacent(get_turf(src))) // Like normal analysers, it can't be used at range. + var/total_health = round(H.health/H.maxHealth, 0.1)*100 + var/missing_health = H.maxHealth - H.health + + var/datum/integrated_io/total = outputs[1] + var/datum/integrated_io/missing = outputs[2] + var/datum/integrated_io/brute = outputs[3] + var/datum/integrated_io/burn = outputs[4] + var/datum/integrated_io/tox = outputs[5] + var/datum/integrated_io/oxy = outputs[6] + var/datum/integrated_io/clone = outputs[7] + + total.data = total_health + missing.data = missing_health + brute.data = H.getBruteLoss() + burn.data = H.getFireLoss() + tox.data = H.getToxLoss() + oxy.data = H.getOxyLoss() + clone.data = H.getCloneLoss() + + for(var/datum/integrated_io/output/O in outputs) + O.push_data() + +/obj/item/integrated_circuit/input/local_locator + name = "local locator" + desc = "This is needed for certain devices that demand a reference for a target to act upon. This type only locates something \ + that is holding the machine containing it." + number_of_inputs = 0 + number_of_outputs = 1 + number_of_activators = 1 + complexity = 4 + output_names = list( + "located ref" + ) + activator_names = list( + "locate" + ) + +/obj/item/integrated_circuit/input/local_locator/work() + if(..()) + var/mob/living/L = null + var/datum/integrated_io/O = outputs[1] + O.data = null + if(istype(src.loc, /obj/item/device/electronic_assembly)) // Check to make sure we're actually in a machine. + var/obj/item/device/electronic_assembly/assembly = src.loc + if(istype(assembly.loc, /mob/living)) // Now check if someone's holding us. + L = assembly.loc + + if(L) + O.data = L + + O.push_data() + +/obj/item/integrated_circuit/input/signaler + name = "integrated signaler" + desc = "Signals from a signaler can be received with this, allowing for remote control. Additionally, it can send signals as well." + extended_desc = "When a signal is received from another signaler, the 'on signal received' activator pin will be pulsed. \ + The two input pins are to configure the integrated signaler's settings. Note that the frequency should not have a decimal in it. \ + Meaning the default frequency is expressed as 1457, not 145.7. To send a signal, pulse the 'send signal' activator pin." + icon_state = "signal" + number_of_inputs = 2 + number_of_outputs = 0 + number_of_activators = 2 + complexity = 4 + input_names = list( + "frequency", + "code" + ) + activator_names = list( + "send signal", + "on signal received" + ) + var/frequency = 1457 + var/code = 30 + var/datum/radio_frequency/radio_connection + +/obj/item/integrated_circuit/input/signaler/New() + ..() + spawn(4 SECONDS) + set_frequency(frequency) + var/datum/integrated_io/new_freq = inputs[1] + var/datum/integrated_io/new_code = inputs[2] + // Set the pins so when someone sees them, they won't show as null + new_freq.data = frequency + new_code.data = code + +/obj/item/integrated_circuit/input/signaler/Destroy() + if(radio_controller) + radio_controller.remove_object(src,frequency) + frequency = 0 + ..() + +/obj/item/integrated_circuit/input/signaler/on_data_written() + var/datum/integrated_io/new_freq = inputs[1] + var/datum/integrated_io/new_code = inputs[2] + if(isnum(new_freq.data)) + set_frequency(new_freq.data) + if(isnum(new_code.data)) + code = new_code.data + + +/obj/item/integrated_circuit/input/signaler/work() // Sends a signal. + if(..()) + if(!radio_connection) + return + + var/datum/signal/signal = new() + signal.source = src + signal.encryption = code + signal.data["message"] = "ACTIVATE" + radio_connection.post_signal(src, signal) + +/obj/item/integrated_circuit/input/signaler/proc/set_frequency(new_frequency) + if(!frequency) + return + if(!radio_controller) + sleep(20) + if(!radio_controller) + return + radio_controller.remove_object(src, frequency) + frequency = new_frequency + radio_connection = radio_controller.add_object(src, frequency, RADIO_CHAT) + +/obj/item/integrated_circuit/input/signaler/receive_signal(datum/signal/signal) + var/datum/integrated_io/new_code = inputs[2] + var/code = 0 + + if(isnum(new_code.data)) + code = new_code.data + if(!signal) + return 0 + if(signal.encryption != code) + return 0 + if(signal.source == src) // Don't trigger ourselves. + return 0 + + var/datum/integrated_io/A = activators[2] + A.push_data() + + for(var/mob/O in hearers(1, src.loc)) + O.show_message(text("\icon[] *beep* *beep*", src), 3, "*beep* *beep*", 2) + + +/obj/item/integrated_circuit/input/EPv2 + name = "\improper EPv2 circuit" + desc = "Enables the sending and receiving of messages on the Exonet with the EPv2 protocol." + extended_desc = "An EPv2 address is a string with the format of XXXX:XXXX:XXXX:XXXX. Data can be send or received using the \ + second pin on each side, with additonal data reserved for the third pin. When a message is received, the second activaiton pin \ + will pulse whatever's connected to it. Pulsing the first activation pin will send a message." + icon_state = "signal" + number_of_inputs = 3 + number_of_outputs = 3 + number_of_activators = 2 + complexity = 4 + input_names = list( + "target EPv2 address", + "data to send", + "secondary text" + ) + output_names = list( + "address received", + "data received", + "secondary text received" + ) + activator_names = list( + "send data", + "on data received" + ) + var/datum/exonet_protocol/exonet = null + +/obj/item/integrated_circuit/input/EPv2/New() + ..() + exonet = new(src) + exonet.make_address("EPv2_circuit-\ref[src]") + desc += "This circuit's EPv2 address is: [exonet.address]." + +/obj/item/integrated_circuit/input/EPv2/Destroy() + if(exonet) + exonet.remove_address() + qdel(exonet) + ..() + +/obj/item/integrated_circuit/input/EPv2/work() + if(..()) + var/datum/integrated_io/target_address = inputs[1] + var/datum/integrated_io/message = inputs[2] + var/datum/integrated_io/text = inputs[3] + if(istext(target_address.data)) + exonet.send_message(target_address.data, message.data, text.data) + +/obj/item/integrated_circuit/input/receive_exonet_message(var/atom/origin_atom, var/origin_address, var/message, var/text) + var/datum/integrated_io/message_received = outputs[1] + var/datum/integrated_io/data_received = outputs[2] + var/datum/integrated_io/text_received = outputs[3] + + var/datum/integrated_io/A = activators[2] + A.push_data() + + message_received.write_data_to_pin(origin_address) + data_received.write_data_to_pin(message) + text_received.write_data_to_pin(text) + +/obj/item/integrated_circuit/output/screen + name = "screen" + desc = "This small screen can display a single piece of data, when the machine is examined closely." + icon_state = "screen" + complexity = 4 + number_of_inputs = 1 + number_of_outputs = 0 + number_of_activators = 1 + input_names = list( + "displayed data" + ) + activator_names = list( + "load data" + ) + var/stuff_to_display = null + +/obj/item/integrated_circuit/output/screen/work() + var/datum/integrated_io/I = inputs[1] + stuff_to_display = I.data + +/obj/item/integrated_circuit/output/light + name = "light" + desc = "This light can turn on and off on command." + icon_state = "light_adv" +// icon_state = "light" + complexity = 4 + number_of_inputs = 0 + number_of_outputs = 0 + number_of_activators = 1 + activator_names = list( + "toggle light" + ) + var/light_toggled = 0 + var/light_brightness = 3 + var/light_rgb = "#FFFFFF" + +/obj/item/integrated_circuit/output/light/work() + if(..()) + light_toggled = !light_toggled + update_lighting() + +/obj/item/integrated_circuit/output/light/proc/update_lighting() + if(light_toggled) + set_light(l_range = light_brightness, l_power = light_brightness, l_color = light_rgb) + else + set_light(0) + +/obj/item/integrated_circuit/output/light/advanced/update_lighting() + var/datum/integrated_io/R = inputs[1] + var/datum/integrated_io/G = inputs[2] + var/datum/integrated_io/B = inputs[3] + var/datum/integrated_io/brightness = inputs[4] + + if(isnum(R.data) && isnum(G.data) && isnum(B.data) && isnum(brightness.data)) + R.data = Clamp(R.data, 0, 255) + G.data = Clamp(G.data, 0, 255) + B.data = Clamp(B.data, 0, 255) + brightness.data = Clamp(brightness.data, 0, 6) + light_rgb = rgb(R.data, G.data, B.data) + light_brightness = brightness.data + + ..() + +/obj/item/integrated_circuit/output/light/advanced + name = "advanced light" + desc = "This light can turn on and off on command, in any color, and in various brightness levels." + icon_state = "light_adv" + complexity = 8 + number_of_inputs = 4 + number_of_outputs = 0 + number_of_activators = 1 + input_names = list( + "R", + "G", + "B", + "Brightness" + ) + +/obj/item/integrated_circuit/output/light/advanced/on_data_written() + update_lighting() + +/obj/item/integrated_circuit/output/sound + name = "speaker circuit" + desc = "A miniature speaker is attached to this component." + icon_state = "speaker" + complexity = 8 + cooldown_per_use = 4 SECONDS + number_of_inputs = 3 + number_of_outputs = 0 + number_of_activators = 1 + input_names = list( + "sound ID", + "volume", + "frequency" + ) + activator_names = list( + "play sound" + ) + var/list/sounds = list() + +/obj/item/integrated_circuit/output/sound/work() + if(..()) + var/datum/integrated_io/ID = inputs[1] + var/datum/integrated_io/vol = inputs[2] + var/datum/integrated_io/frequency = inputs[3] + if(istext(ID.data) && isnum(vol.data) && isnum(frequency.data)) + var/selected_sound = sounds[ID.data] + vol.data = Clamp(vol.data, 0, 1) + frequency.data = Clamp(frequency.data, 0, 100) + playsound(get_turf(src), selected_sound, vol.data, frequency.data, -1) + +/obj/item/integrated_circuit/output/sound/beeper + name = "beeper circuit" + desc = "A miniature speaker is attached to this component. This is often used in the construction of motherboards, which use \ + the speaker to tell the user if something goes very wrong when booting up. It can also do other similar synthetic sounds such \ + as buzzing, pinging, chiming, and more." + extended_desc = "The first input pin determines what sound is used. The choices are; beep, chime, buzz sigh, buzz twice, ping, \ + synth yes, synth no, warning buzz. The second pin determines the volume of sound that is played, and the third determines if \ + the frequency of the sound will vary with each activation." + sounds = list( + "beep" = 'sound/machines/twobeep.ogg', + "chime" = 'sound/machines/chime.ogg', + "buzz sigh" = 'sound/machines/buzz-sigh.ogg', + "buzz twice" = 'sound/machines/buzz-two.ogg', + "ping" = 'sound/machines/ping.ogg', + "synth yes" = 'sound/machines/synth_yes.ogg', + "synth no" = 'sound/machines/synth_no.ogg', + "warning buzz" = 'sound/machines/warning-buzzer.ogg' + ) + +/obj/item/integrated_circuit/output/sound/beepsky + name = "securitron sound circuit" + desc = "A miniature speaker is attached to this component. Considered by some to be the essential component for a securitron." + extended_desc = "The first input pin determines what sound is used. The choices are; creep, criminal, freeze, god, \ + i am the law, insult, radio, secure day. The second pin determines the volume of sound that is played, and the \ + third determines if the frequency of the sound will vary with each activation." + sounds = list( + "creep" = 'sound/voice/bcreep.ogg', + "criminal" = 'sound/voice/bcriminal.ogg', + "freeze" = 'sound/voice/bfreeze.ogg', + "god" = 'sound/voice/bgod.ogg', + "i am the law" = 'sound/voice/biamthelaw.ogg', + "insult" = 'sound/voice/binsult.ogg', + "radio" = 'sound/voice/bradio.ogg', + "secure day" = 'sound/voice/bsecureday.ogg', + ) + diff --git a/code/modules/integrated_electronics/logic.dm b/code/modules/integrated_electronics/logic.dm new file mode 100644 index 0000000000..4d123c61d0 --- /dev/null +++ b/code/modules/integrated_electronics/logic.dm @@ -0,0 +1,172 @@ +/obj/item/integrated_circuit/logic + name = "logic gate" + desc = "This tiny chip will decide for you!" + complexity = 3 + number_of_inputs = 2 + number_of_outputs = 1 + number_of_activators = 2 + input_names = list( + "A", + "B" + ) + output_names = list( + "result" + ) + activator_names = list( + "compare", + "on true result" + ) + +/obj/item/integrated_circuit/logic/equals + name = "equal gate" + desc = "This gate compares two values, and outputs the number one if both are the same." + icon_state = "equal" + +/obj/item/integrated_circuit/logic/equals/work() + if(..()) + var/datum/integrated_io/A = inputs[1] + var/datum/integrated_io/B = inputs[2] + var/datum/integrated_io/O = outputs[1] + var/datum/integrated_io/P = activators[2] + if(A.data == B.data) + O.data = 1 + O.push_data() + P.push_data() + else + O.data = 0 + +/obj/item/integrated_circuit/logic/not + name = "not gate" + desc = "This gate inverts what's fed into it." + icon_state = "not" + number_of_inputs = 1 + number_of_outputs = 1 + number_of_activators = 1 + output_names = list( + "invert" + ) + + +/obj/item/integrated_circuit/logic/not/work() + if(..()) + var/datum/integrated_io/A = inputs[1] + var/datum/integrated_io/O = outputs[1] + if(A.data) + O.data = !A.data + O.push_data() + else + O.data = 0 + +/obj/item/integrated_circuit/logic/and + name = "and gate" + desc = "This gate will output 'one' if both inputs evaluate to true." + icon_state = "and" + +/obj/item/integrated_circuit/logic/and/work() + if(..()) + var/datum/integrated_io/A = inputs[1] + var/datum/integrated_io/B = inputs[2] + var/datum/integrated_io/O = outputs[1] + var/datum/integrated_io/P = activators[2] + if(A.data && B.data) + O.data = 1 + O.push_data() + A.push_data() + P.push_data() + else + O.data = 0 + +/obj/item/integrated_circuit/logic/or + name = "or gate" + desc = "This gate will output 'one' if one of the inputs evaluate to true." + icon_state = "or" + +/obj/item/integrated_circuit/logic/or/work() + if(..()) + var/datum/integrated_io/A = inputs[1] + var/datum/integrated_io/B = inputs[2] + var/datum/integrated_io/O = outputs[1] + var/datum/integrated_io/P = activators[2] + if(A.data || B.data) + O.data = 1 + O.push_data() + A.push_data() + P.push_data() + else + O.data = 0 + +/obj/item/integrated_circuit/logic/less_than + name = "less than gate" + desc = "This will output 'one' if the first input is less than the second input." + icon_state = "less_than" + +/obj/item/integrated_circuit/logic/less_than/work() + if(..()) + var/datum/integrated_io/A = inputs[1] + var/datum/integrated_io/B = inputs[2] + var/datum/integrated_io/O = outputs[1] + var/datum/integrated_io/P = activators[2] + if(A.data < B.data) + O.data = 1 + O.push_data() + A.push_data() + P.push_data() + else + O.data = 0 + +/obj/item/integrated_circuit/logic/less_than_or_equal + name = "less than or equal gate" + desc = "This will output 'one' if the first input is less than, or equal to the second input." + icon_state = "less_than_or_equal" + +/obj/item/integrated_circuit/logic/less_than_or_equal/work() + if(..()) + var/datum/integrated_io/A = inputs[1] + var/datum/integrated_io/B = inputs[2] + var/datum/integrated_io/O = outputs[1] + var/datum/integrated_io/P = activators[2] + if(A.data <= B.data) + O.data = 1 + O.push_data() + A.push_data() + P.push_data() + else + O.data = 0 + +/obj/item/integrated_circuit/logic/greater_than + name = "greater than gate" + desc = "This will output 'one' if the first input is greater than the second input." + icon_state = "greater_than" + +/obj/item/integrated_circuit/logic/greater_than/work() + if(..()) + var/datum/integrated_io/A = inputs[1] + var/datum/integrated_io/B = inputs[2] + var/datum/integrated_io/O = outputs[1] + var/datum/integrated_io/P = activators[2] + if(A.data > B.data) + O.data = 1 + O.push_data() + A.push_data() + P.push_data() + else + O.data = 0 + +/obj/item/integrated_circuit/logic/greater_than_or_equal + name = "greater_than or equal gate" + desc = "This will output 'one' if the first input is greater than, or equal to the second input." + icon_state = "greater_than_or_equal" + +/obj/item/integrated_circuit/logic/greater_than_or_equal/work() + if(..()) + var/datum/integrated_io/A = inputs[1] + var/datum/integrated_io/B = inputs[2] + var/datum/integrated_io/O = outputs[1] + var/datum/integrated_io/P = activators[2] + if(A.data >= B.data) + O.data = 1 + O.push_data() + A.push_data() + P.push_data() + else + O.data = 0 \ No newline at end of file diff --git a/code/modules/integrated_electronics/manipulation.dm b/code/modules/integrated_electronics/manipulation.dm new file mode 100644 index 0000000000..256d7b6b7a --- /dev/null +++ b/code/modules/integrated_electronics/manipulation.dm @@ -0,0 +1,158 @@ +/obj/item/integrated_circuit/manipulation/weapon_firing + name = "weapon firing mechanism" + desc = "This somewhat complicated system allows one to slot in a gun, direct it towards a position, and remotely fire it." + extended_desc = "The firing mechanism can slot in most ranged weapons, ballistic and energy. \ + The first and second inputs need to be numbers. They are coordinates for the gun to fire at, relative to the machine itself. \ + The 'fire' activator will cause the mechanism to attempt to fire the weapon at the coordinates, if possible. Note that the \ + normal limitations to firearms, such as ammunition requirements and firing delays, still hold true if fired by the mechanism." + complexity = 20 + number_of_inputs = 2 + number_of_outputs = 0 + number_of_activators = 1 + input_names = list( + "target X rel", + "target Y rel" + ) + activator_names = list( + "fire" + ) + var/obj/item/weapon/gun/installed_gun = null + +/obj/item/integrated_circuit/manipulation/weapon_firing/Destroy() + qdel(installed_gun) + ..() + +/obj/item/integrated_circuit/manipulation/weapon_firing/attackby(var/obj/O, var/mob/user) + if(istype(O, /obj/item/weapon/gun)) + var/obj/item/weapon/gun/gun = O + if(installed_gun) + user << "There's already a weapon installed." + return + user.drop_from_inventory(gun) + installed_gun = gun + gun.forceMove(src) + user << "You slide \the [gun] into the firing mechanism." + playsound(src.loc, 'sound/items/Crowbar.ogg', 50, 1) + else + ..() + +/obj/item/integrated_circuit/manipulation/weapon_firing/attack_self(var/mob/user) + if(installed_gun) + installed_gun.forceMove(get_turf(src)) + user << "You slide \the [installed_gun] out of the firing mechanism." + playsound(src.loc, 'sound/items/Crowbar.ogg', 50, 1) + installed_gun = null + else + user << "There's no weapon to remove from the mechanism." + +/obj/item/integrated_circuit/manipulation/weapon_firing/work() + if(..()) + if(!installed_gun) + return + + var/datum/integrated_io/target_x = inputs[1] + var/datum/integrated_io/target_y = inputs[2] + + if(target_x.data && target_y.data && isnum(target_x.data) && isnum(target_y.data)) + var/turf/T = get_turf(src) + + if(target_x.data == 0 && target_y.data == 0) // Don't shoot ourselves. + return + + // We need to do this in order to enable relative coordinates, as locate() only works for absolute coordinates. + var/i + if(target_x.data > 0) + i = abs(target_x.data) + while(i) + T = get_step(T, EAST) + i-- + else if(target_x.data < 0) + i = abs(target_x.data) + while(i) + T = get_step(T, WEST) + i-- + + if(target_y.data > 0) + i = abs(target_y.data) + while(i) + T = get_step(T, NORTH) + i-- + else if(target_y.data < 0) + i = abs(target_y.data) + while(i) + T = get_step(T, SOUTH) + i-- + + if(!T) + return + installed_gun.Fire_userless(T) + +/obj/item/integrated_circuit/manipulation/smoke + name = "smoke generator" + desc = "Unlike most electronics, creating smoke is completely intentional." + icon_state = "smoke" + extended_desc = "This smoke generator creates clouds of smoke on command. It can also hold liquids inside, which will go \ + into the smoke clouds when activated." + flags = OPENCONTAINER + complexity = 20 + number_of_inputs = 0 + number_of_outputs = 0 + number_of_activators = 1 + cooldown_per_use = 30 SECONDS + input_names = list() + activator_names = list( + "create smoke" + ) + +/obj/item/integrated_circuit/manipulation/smoke/New() + ..() + create_reagents(100) + +/obj/item/integrated_circuit/manipulation/smoke/work() + if(..()) + playsound(src.loc, 'sound/effects/smoke.ogg', 50, 1, -3) + var/datum/effect/effect/system/smoke_spread/chem/smoke_system = new() + smoke_system.set_up(reagents, 10, 0, get_turf(src)) + spawn(0) + for(var/i = 1 to 8) + smoke_system.start() + reagents.clear_reagents() + +/obj/item/integrated_circuit/manipulation/locomotion + name = "locomotion circuit" + desc = "This allows a machine to move in a given direction." + icon_state = "locomotion" + extended_desc = "The circuit accepts a number as a direction to move towards.
\ + North/Fore = 1,
\ + South/Aft = 2,
\ + East/Starboard = 4,
\ + West/Port = 8,
\ + Northeast = 5,
\ + Northwest = 9,
\ + Southeast = 6,
\ + Southwest = 10
\ +
\ + Pulsing the 'step towards dir' activator pin will cause the machine to move a meter in that direction, assuming it is not \ + being held, or anchored in some way." + complexity = 20 + number_of_inputs = 1 + number_of_outputs = 0 + number_of_activators = 1 + input_names = list( + "dir num" + ) + activator_names = list( + "step towards dir" + ) + +/obj/item/integrated_circuit/manipulation/locomotion/work() + if(..()) + var/turf/T = get_turf(src) + if(istype(loc, /obj/item/device/electronic_assembly)) + var/obj/item/device/electronic_assembly/machine = loc + if(machine.anchored || machine.w_class >= 4) + return + if(machine.loc && machine.loc == T) // Check if we're held by someone. If the loc is the floor, we're not held. + var/datum/integrated_io/wanted_dir = inputs[1] + if(isnum(wanted_dir.data)) + step(machine, wanted_dir.data) \ No newline at end of file diff --git a/code/modules/integrated_electronics/memory.dm b/code/modules/integrated_electronics/memory.dm new file mode 100644 index 0000000000..8599cc2aed --- /dev/null +++ b/code/modules/integrated_electronics/memory.dm @@ -0,0 +1,101 @@ +/obj/item/integrated_circuit/memory + name = "memory chip" + desc = "This tiny chip can store one piece of data." + icon_state = "memory" + complexity = 1 + number_of_inputs = 1 + number_of_outputs = 1 + number_of_activators = 1 + activator_names = list( + "set" + ) + +/obj/item/integrated_circuit/memory/examine(mob/user) + ..() + var/i + for(i = 1, i <= outputs.len, i++) + var/datum/integrated_io/O = outputs[i] + user << "\The [src] has [O.data ? "'O.data'" : "nothing"] saved to address [i]." + +/obj/item/integrated_circuit/memory/work() + if(..()) + var/i + for(i = 1, i <= inputs.len, i++) + var/datum/integrated_io/I = inputs[i] + var/datum/integrated_io/O = outputs[i] + O.data = I.data + +/obj/item/integrated_circuit/memory/medium + name = "memory circuit" + desc = "This circuit can store four pieces of data." + icon_state = "memory4" + complexity = 4 + number_of_inputs = 4 + number_of_outputs = 4 + +/obj/item/integrated_circuit/memory/large + name = "large memory circuit" + desc = "This big circuit can hold eight pieces of data." + icon_state = "memory8" + complexity = 8 + number_of_inputs = 8 + number_of_outputs = 8 + +/obj/item/integrated_circuit/memory/huge + name = "large memory stick" + desc = "This stick of memory can hold up up to sixteen pieces of data." + icon_state = "memory16" + complexity = 16 + number_of_inputs = 16 + number_of_outputs = 16 + +/obj/item/integrated_circuit/memory/constant + name = "constant chip" + desc = "This tiny chip can store one piece of data, which cannot be overwritten without disassembly." + icon_state = "memory" + complexity = 1 + number_of_inputs = 0 + number_of_outputs = 1 + number_of_activators = 1 + activator_names = list( + "push data" + ) + var/accepting_refs = 0 + +/obj/item/integrated_circuit/memory/constant/work() + var/datum/integrated_io/O = outputs[1] + O.push_data() + +/obj/item/integrated_circuit/memory/constant/attack_self(mob/user) + var/datum/integrated_io/O = outputs[1] + var/type_to_use = input("Please choose a type to use.","[src] type setting") as null|anything in list("string","number","ref", "null") + var/new_data = null + switch(type_to_use) + if("string") + accepting_refs = 0 + new_data = input("Now type in a string.","[src] string writing") as null|text + if(istext(new_data)) + O.data = new_data + user << "You set \the [src]'s memory to [O.display_data()]." + if("number") + accepting_refs = 0 + new_data = input("Now type in a number.","[src] number writing") as null|num + if(isnum(new_data)) + O.data = new_data + user << "You set \the [src]'s memory to [O.display_data()]." + if("ref") + accepting_refs = 1 + user << "You turn \the [src]'s ref scanner on. Slide it across \ + an object for a ref of that object to save it in memory." + if("null") + O.data = null + user << "You set \the [src]'s memory to absolutely nothing." + +/obj/item/integrated_circuit/memory/constant/afterattack(atom/target, mob/living/user, proximity) + if(accepting_refs && proximity) + var/datum/integrated_io/O = outputs[1] + O.data = target + visible_message("[user] slides \a [src]'s over \the [target].") + user << "You set \the [src]'s memory to a reference to [O.display_data()]. The ref scanner is \ + now off." + accepting_refs = 0 \ No newline at end of file diff --git a/code/modules/integrated_electronics/time.dm b/code/modules/integrated_electronics/time.dm new file mode 100644 index 0000000000..95b8e02c46 --- /dev/null +++ b/code/modules/integrated_electronics/time.dm @@ -0,0 +1,144 @@ +/obj/item/integrated_circuit/time + name = "time circuit" + desc = "Now you can build your own clock!" + complexity = 2 + number_of_inputs = 0 + number_of_outputs = 0 + +/obj/item/integrated_circuit/time/delay + name = "two-sec delay circuit" + desc = "This sends a pulse signal out after a delay, critical for ensuring proper control flow in a complex machine. \ + This circuit is set to send a pulse after a delay of two seconds." + icon_state = "delay-20" + number_of_activators = 2 + var/delay = 20 + activator_names = list( + "incoming pulse", + "outgoing pulse" + ) + +/obj/item/integrated_circuit/time/delay/work() + if(..()) + var/datum/integrated_io/out_pulse = activators[2] + sleep(delay) + out_pulse.push_data() + +/obj/item/integrated_circuit/time/delay/five_sec + name = "five-sec delay circuit" + desc = "This sends a pulse signal out after a delay, critical for ensuring proper control flow in a complex machine. \ + This circuit is set to send a pulse after a delay of five seconds." + icon_state = "delay-50" + delay = 50 + +/obj/item/integrated_circuit/time/delay/one_sec + name = "one-sec delay circuit" + desc = "This sends a pulse signal out after a delay, critical for ensuring proper control flow in a complex machine. \ + This circuit is set to send a pulse after a delay of one second." + icon_state = "delay-10" + delay = 10 + +/obj/item/integrated_circuit/time/delay/half_sec + name = "half-sec delay circuit" + desc = "This sends a pulse signal out after a delay, critical for ensuring proper control flow in a complex machine. \ + This circuit is set to send a pulse after a delay of half a second." + icon_state = "delay-5" + delay = 5 + +/obj/item/integrated_circuit/time/delay/tenth_sec + name = "tenth-sec delay circuit" + desc = "This sends a pulse signal out after a delay, critical for ensuring proper control flow in a complex machine. \ + This circuit is set to send a pulse after a delay of 1/10th of a second." + icon_state = "delay-1" + delay = 1 + +/obj/item/integrated_circuit/time/delay/custom + name = "custom delay circuit" + desc = "This sends a pulse signal out after a delay, critical for ensuring proper control flow in a complex machine. \ + This circuit's delay can be customized, between 1/10th of a second to one hour. The delay is updated upon receiving a pulse." + icon_state = "delay" + number_of_inputs = 1 + input_names = list( + "delay time", + ) + +/obj/item/integrated_circuit/time/delay/custom/work() + var/datum/integrated_io/delay_input = inputs[1] + if(delay_input.data && isnum(delay_input.data) ) + var/new_delay = min(delay_input.data, 1) + new_delay = max(new_delay, 36000) //An hour. + delay = new_delay + + ..() + +/obj/item/integrated_circuit/time/ticker + name = "ticker circuit" + desc = "This circuit sends an automatic pulse every four seconds." + icon_state = "tick-m" + complexity = 8 + number_of_inputs = 1 + number_of_activators = 1 + var/ticks_to_pulse = 2 + var/ticks_completed = 0 + input_names = list( + "toggle ticking" + ) + activator_names = list( + "outgoing pulse" + ) + +/obj/item/integrated_circuit/time/ticker/New() + ..() + processing_objects |= src + +/obj/item/integrated_circuit/time/ticker/Destroy() + processing_objects -= src + +/obj/item/integrated_circuit/time/ticker/process() + ticks_completed++ + if( (ticks_completed % ticks_to_pulse) == 0) + var/datum/integrated_io/pulser = activators[1] + pulser.push_data() + +/obj/item/integrated_circuit/time/ticker/fast + name = "fast ticker" + desc = "This advanced circuit sends an automatic pulse every two seconds." + icon_state = "tick-f" + complexity = 12 + ticks_to_pulse = 1 + +/obj/item/integrated_circuit/time/ticker/slow + name = "slow ticker" + desc = "This simple circuit sends an automatic pulse every six seconds." + icon_state = "tick-s" + complexity = 4 + ticks_to_pulse = 3 + + +/obj/item/integrated_circuit/time/clock + name = "integrated clock" + desc = "Tells you what the local time is, specific to your station or planet." + icon_state = "clock" + number_of_inputs = 0 + number_of_outputs = 4 + number_of_activators = 1 + output_names = list( + "time (string)", + "hours (number)", + "minutes (number)", + "seconds (number)" + ) + +/obj/item/integrated_circuit/time/clock/work() + if(..()) + var/datum/integrated_io/time = outputs[1] + var/datum/integrated_io/hour = outputs[2] + var/datum/integrated_io/min = outputs[3] + var/datum/integrated_io/sec = outputs[4] + + time.data = time2text(station_time_in_ticks, "hh:mm:ss") + hour.data = text2num(time2text(station_time_in_ticks, "hh")) + min.data = text2num(time2text(station_time_in_ticks, "mm")) + sec.data = text2num(time2text(station_time_in_ticks, "ss")) + + for(var/datum/integrated_io/output/O in outputs) + O.push_data() \ No newline at end of file diff --git a/code/modules/integrated_electronics/tools.dm b/code/modules/integrated_electronics/tools.dm new file mode 100644 index 0000000000..75609ca59c --- /dev/null +++ b/code/modules/integrated_electronics/tools.dm @@ -0,0 +1,227 @@ +#define WIRE "wire" +#define WIRING "wiring" +#define UNWIRE "unwire" +#define UNWIRING "unwiring" + + +/obj/item/device/integrated_electronics/wirer + name = "circuit wirer" + desc = "It's a small wiring tool, with a wire roll, electric soldering iron, wire cutter, and more in one package. \ + The wires used are generally useful for small electronics, such as circuitboards and breadboards, as opposed to larger wires \ + used for power or data transmission." + icon = 'icons/obj/electronic_assemblies.dmi' + icon_state = "wirer-wire" + flags = CONDUCT + w_class = 2 + var/datum/integrated_io/selected_io = null + var/mode = WIRE + +/obj/item/device/integrated_electronics/wirer/New() + ..() + +/obj/item/device/integrated_electronics/wirer/update_icon() + icon_state = "wirer-[mode]" + +/obj/item/device/integrated_electronics/wirer/proc/wire(var/datum/integrated_io/io, mob/user) + if(mode == WIRE) + selected_io = io + user << "You attach a data wire to \the [selected_io.holder]'s [selected_io.name] data channel." + mode = WIRING + update_icon() + else if(mode == WIRING) + if(io == selected_io) + user << "Wiring \the [selected_io.holder]'s [selected_io.name] into itself is rather pointless." + return + if(io.io_type != selected_io.io_type) + user << "Those two types of channels are incompatable. The first is a [selected_io.io_type], \ + while the second is a [io.io_type]." + return + selected_io.linked |= io + io.linked |= selected_io + + user << "You connect \the [selected_io.holder]'s [selected_io.name] to \the [io.holder]'s [io.name]." + mode = WIRE + update_icon() + //io.updateDialog() + //selected_io.updateDialog() + selected_io.holder.interact(user) // This is to update the UI. + selected_io = null + + else if(mode == UNWIRE) + selected_io = io + if(!io.linked.len) + user << "There is nothing connected to \the [selected_io] data channel." + selected_io = null + return + user << "You prepare to detach a data wire from \the [selected_io.holder]'s [selected_io.name] data channel." + mode = UNWIRING + update_icon() + return + + else if(mode == UNWIRING) + if(io == selected_io) + user << "You can't wire a pin into each other, so unwiring \the [selected_io.holder] from \ + the same pin is rather moot." + return + if(selected_io in io.linked) + io.linked.Remove(selected_io) + selected_io.linked.Remove(io) + user << "You disconnect \the [selected_io.holder]'s [selected_io.name] from \ + \the [io.holder]'s [io.name]." + //io.updateDialog() + //selected_io.updateDialog() + selected_io.holder.interact(user) // This is to update the UI. + selected_io = null + mode = UNWIRE + update_icon() + else + user << "\The [selected_io.holder]'s [selected_io.name] and \the [io.holder]'s \ + [io.name] are not connected." + return + return + +/obj/item/device/integrated_electronics/wirer/attack_self(mob/user) + switch(mode) + if(WIRE) + mode = UNWIRE + if(WIRING) + if(selected_io) + user << "You decide not to wire the data channel." + selected_io = null + mode = UNWIRE + if(UNWIRE) + mode = WIRE + if(UNWIRING) + if(selected_io) + user << "You decide not to disconnect the data channel." + selected_io = null + mode = UNWIRE + update_icon() + user << "You set \the [src] to [mode]." + +#undef WIRE +#undef WIRING +#undef UNWIRE +#undef UNWIRING + +/obj/item/device/integrated_electronics/debugger + name = "circuit debugger" + desc = "This small tool allows one working with custom machinery to directly set data to a specific pin, useful for writing \ + settings to specific circuits, or for debugging purposes. It can also pulse activation pins." + icon = 'icons/obj/electronic_assemblies.dmi' + icon_state = "debugger" + flags = CONDUCT + w_class = 2 + var/data_to_write = null + var/accepting_refs = 0 + +/obj/item/device/integrated_electronics/debugger/attack_self(mob/user) + var/type_to_use = input("Please choose a type to use.","[src] type setting") as null|anything in list("string","number","ref", "null") + var/new_data = null + switch(type_to_use) + if("string") + accepting_refs = 0 + new_data = input("Now type in a string.","[src] string writing") as null|text + if(istext(new_data)) + data_to_write = new_data + user << "You set \the [src]'s memory to \"[new_data]\"." + if("number") + accepting_refs = 0 + new_data = input("Now type in a number.","[src] number writing") as null|num + if(isnum(new_data)) + data_to_write = new_data + user << "You set \the [src]'s memory to [new_data]." + if("ref") + accepting_refs = 1 + user << "You turn \the [src]'s ref scanner on. Slide it across \ + an object for a ref of that object to save it in memory." + if("null") + data_to_write = null + user << "You set \the [src]'s memory to absolutely nothing." + +/obj/item/device/integrated_electronics/debugger/afterattack(atom/target, mob/living/user, proximity) + if(accepting_refs && proximity) + data_to_write = target + visible_message("[user] slides \a [src]'s over \the [target].") + user << "You set \the [src]'s memory to a reference to [target.name] \[Ref\]. The ref scanner is \ + now off." + accepting_refs = 0 + +/obj/item/device/integrated_electronics/debugger/proc/write_data(var/datum/integrated_io/io, mob/user) + if(io.io_type == DATA_CHANNEL) + io.write_data_to_pin(data_to_write) + user << "You write [data_to_write] to \the [io.holder]'s [io]." + else if(io.io_type == PULSE_CHANNEL) + io.holder.work() + user << "You pulse \the [io.holder]'s [io]." + + io.holder.interact(user) // This is to update the UI. + +/obj/item/weapon/storage/bag/circuits + name = "circuit kit" + desc = "This kit's essential for any circuitry projects." + icon = 'icons/obj/electronic_assemblies.dmi' + icon_state = "circuit_kit" + w_class = 3 + storage_slots = 200 + max_storage_space = 400 + max_w_class = 3 + display_contents_with_number = 1 + can_hold = list(/obj/item/integrated_circuit, /obj/item/device/integrated_electronics, /obj/item/device/electronic_assembly, + /obj/item/weapon/screwdriver, /obj/item/weapon/crowbar) + +/obj/item/weapon/storage/bag/circuits/basic/New() + ..() + var/list/types_to_spawn = typesof(/obj/item/integrated_circuit/arithmetic, + /obj/item/integrated_circuit/logic, + /obj/item/integrated_circuit/memory, + ) - list(/obj/item/integrated_circuit/arithmetic, + /obj/item/integrated_circuit/memory, + /obj/item/integrated_circuit/logic, + ) + + types_to_spawn.Add(/obj/item/integrated_circuit/input/numberpad, + /obj/item/integrated_circuit/input/textpad, + /obj/item/integrated_circuit/input/button, + /obj/item/integrated_circuit/input/signaler, + /obj/item/integrated_circuit/input/local_locator, + /obj/item/integrated_circuit/output/screen, + /obj/item/integrated_circuit/converter/num2text, + /obj/item/integrated_circuit/converter/text2num, + /obj/item/integrated_circuit/converter/uppercase, + /obj/item/integrated_circuit/converter/lowercase, + /obj/item/integrated_circuit/time/delay/five_sec, + /obj/item/integrated_circuit/time/delay/one_sec, + /obj/item/integrated_circuit/time/delay/half_sec, + /obj/item/integrated_circuit/time/delay/tenth_sec, + /obj/item/integrated_circuit/time/ticker/slow, + /obj/item/integrated_circuit/time/clock + ) + + for(var/thing in types_to_spawn) + var/i = 3 + while(i) + new thing(src) + i-- + + new /obj/item/device/electronic_assembly(src) + new /obj/item/device/integrated_electronics/wirer(src) + new /obj/item/device/integrated_electronics/debugger(src) + new /obj/item/weapon/crowbar(src) + new /obj/item/weapon/screwdriver(src) + +/obj/item/weapon/storage/bag/circuits/all/New() + ..() + var/list/types_to_spawn = typesof(/obj/item/integrated_circuit) + + for(var/thing in types_to_spawn) + var/i = 10 + while(i) + new thing(src) + i-- + + new /obj/item/device/electronic_assembly(src) + new /obj/item/device/integrated_electronics/wirer(src) + new /obj/item/device/integrated_electronics/debugger(src) + new /obj/item/weapon/crowbar(src) + new /obj/item/weapon/screwdriver(src) \ No newline at end of file diff --git a/code/modules/mob/holder.dm b/code/modules/mob/holder.dm index b56435a59e..ab88819b53 100644 --- a/code/modules/mob/holder.dm +++ b/code/modules/mob/holder.dm @@ -50,6 +50,11 @@ var/list/holder_mob_icon_cache = list() continue M.forceMove(get_turf(src)) +/obj/item/weapon/holder/onDropInto(var/atom/movable/AM) + if(ismob(loc)) // Bypass our holding mob and drop directly to its loc + return loc.loc + return ..() + /obj/item/weapon/holder/GetID() for(var/mob/M in contents) var/obj/item/I = M.GetIdCard() diff --git a/code/modules/mob/inventory.dm b/code/modules/mob/inventory.dm index ad71cebe1f..1c6e2436d4 100644 --- a/code/modules/mob/inventory.dm +++ b/code/modules/mob/inventory.dm @@ -126,16 +126,12 @@ var/list/slot_equipment_priority = list( \ // Removes an item from inventory and places it in the target atom. // If canremove or other conditions need to be checked then use unEquip instead. -/mob/proc/drop_from_inventory(var/obj/item/W, var/atom/Target = null) +/mob/proc/drop_from_inventory(var/obj/item/W, var/atom/target = null) if(W) - if(!Target) - Target = loc - - remove_from_mob(W) - if(!(W && W.loc)) return 1 // self destroying objects (tk, grabs) - - W.forceMove(Target) + remove_from_mob(W, target) + if(!(W && W.loc)) + return 1 // self destroying objects (tk, grabs) update_icons() return 1 return 0 @@ -194,7 +190,9 @@ var/list/slot_equipment_priority = list( \ //Attemps to remove an object on a mob. -/mob/proc/remove_from_mob(var/obj/O) +/mob/proc/remove_from_mob(var/obj/O, var/atom/target) + if(!O) // Nothing to remove, so we succeed. + return 1 src.u_equip(O) if (src.client) src.client.screen -= O @@ -202,7 +200,10 @@ var/list/slot_equipment_priority = list( \ O.screen_loc = null if(istype(O, /obj/item)) var/obj/item/I = O - I.forceMove(src.loc) + if(target) + I.forceMove(target) + else + I.dropInto(loc) I.dropped(src) return 1 diff --git a/code/modules/mob/living/bot/cleanbot.dm b/code/modules/mob/living/bot/cleanbot.dm index 6cb5908f6f..a6fc34f738 100644 --- a/code/modules/mob/living/bot/cleanbot.dm +++ b/code/modules/mob/living/bot/cleanbot.dm @@ -180,11 +180,11 @@ w_class = 3.0 var/created_name = "Cleanbot" -/obj/item/weapon/bucket_sensor/attackby(var/obj/item/O, var/mob/user) +/obj/item/weapon/bucket_sensor/attackby(var/obj/item/W, var/mob/user) ..() - if(istype(O, /obj/item/robot_parts/l_arm) || istype(O, /obj/item/robot_parts/r_arm)) + if(istype(W, /obj/item/robot_parts/l_arm) || istype(W, /obj/item/robot_parts/r_arm) || (istype(W, /obj/item/organ/external/arm) && ((W.name == "robotic left arm") || (W.name == "robotic right arm")))) user.drop_item() - qdel(O) + qdel(W) var/turf/T = get_turf(loc) var/mob/living/bot/cleanbot/A = new /mob/living/bot/cleanbot(T) A.name = created_name @@ -192,10 +192,10 @@ user.drop_from_inventory(src) qdel(src) - else if(istype(O, /obj/item/weapon/pen)) + else if(istype(W, /obj/item/weapon/pen)) var/t = sanitizeSafe(input(user, "Enter new robot name", name, created_name), MAX_NAME_LEN) if(!t) return if(!in_range(src, usr) && src.loc != usr) return - created_name = t + created_name = t \ No newline at end of file diff --git a/code/modules/mob/living/bot/ed209bot.dm b/code/modules/mob/living/bot/ed209bot.dm index ec4278c967..80279a4538 100644 --- a/code/modules/mob/living/bot/ed209bot.dm +++ b/code/modules/mob/living/bot/ed209bot.dm @@ -94,7 +94,7 @@ switch(build_step) if(0, 1) - if(istype(W, /obj/item/robot_parts/l_leg) || istype(W, /obj/item/robot_parts/r_leg)) + if(istype(W, /obj/item/robot_parts/l_leg) || istype(W, /obj/item/robot_parts/r_leg) || (istype(W, /obj/item/organ/external/leg) && ((W.name == "robotic right leg") || (W.name == "robotic left leg")))) user.drop_item() qdel(W) build_step++ diff --git a/code/modules/mob/living/bot/farmbot.dm b/code/modules/mob/living/bot/farmbot.dm index 42452c49fa..905c53a20a 100644 --- a/code/modules/mob/living/bot/farmbot.dm +++ b/code/modules/mob/living/bot/farmbot.dm @@ -337,6 +337,18 @@ new /obj/item/weapon/farmbot_arm_assembly(loc, src) +/obj/structure/reagent_dispensers/watertank/attackby(var/obj/item/organ/external/S, mob/user as mob) + if ((!istype(S, /obj/item/organ/external/arm)) && (!S.robotic == ORGAN_ROBOT)) + ..() + return + + user << "You add the robot arm to [src]." + + user.drop_from_inventory(S) + qdel(S) + + new /obj/item/weapon/farmbot_arm_assembly(loc, src) + /obj/item/weapon/farmbot_arm_assembly/attackby(obj/item/weapon/W as obj, mob/user as mob) ..() if((istype(W, /obj/item/device/analyzer/plant_analyzer)) && (build_step == 0)) diff --git a/code/modules/mob/living/bot/floorbot.dm b/code/modules/mob/living/bot/floorbot.dm index 0072d9a444..ca4f572775 100644 --- a/code/modules/mob/living/bot/floorbot.dm +++ b/code/modules/mob/living/bot/floorbot.dm @@ -339,7 +339,7 @@ /obj/item/weapon/toolbox_tiles_sensor/attackby(var/obj/item/W, mob/user as mob) ..() - if(istype(W, /obj/item/robot_parts/l_arm) || istype(W, /obj/item/robot_parts/r_arm)) + if(istype(W, /obj/item/robot_parts/l_arm) || istype(W, /obj/item/robot_parts/r_arm) || (istype(W, /obj/item/organ/external/arm) && ((W.name == "robotic right arm") || (W.name == "robotic left arm")))) qdel(W) var/turf/T = get_turf(user.loc) var/mob/living/bot/floorbot/A = new /mob/living/bot/floorbot(T) diff --git a/code/modules/mob/living/bot/medbot.dm b/code/modules/mob/living/bot/medbot.dm index 8a0c7564d1..fffe5879fa 100644 --- a/code/modules/mob/living/bot/medbot.dm +++ b/code/modules/mob/living/bot/medbot.dm @@ -286,6 +286,29 @@ user.drop_from_inventory(src) qdel(src) +/obj/item/weapon/storage/firstaid/attackby(var/obj/item/organ/external/S, mob/user as mob) + if (!istype(S, /obj/item/organ/external/arm) || !(S.robotic == ORGAN_ROBOT)) + ..() + return + + if(contents.len >= 1) + user << "You need to empty [src] out first." + return + + var/obj/item/weapon/firstaid_arm_assembly/A = new /obj/item/weapon/firstaid_arm_assembly + if(istype(src, /obj/item/weapon/storage/firstaid/fire)) + A.skin = "ointment" + else if(istype(src, /obj/item/weapon/storage/firstaid/toxin)) + A.skin = "tox" + else if(istype(src, /obj/item/weapon/storage/firstaid/o2)) + A.skin = "o2" + + qdel(S) + user.put_in_hands(A) + user << "You add the robot arm to the first aid kit." + user.drop_from_inventory(src) + qdel(src) + /obj/item/weapon/firstaid_arm_assembly name = "first aid/robot arm assembly" desc = "A first aid kit with a robot arm permanently grafted to it." diff --git a/code/modules/mob/living/bot/secbot.dm b/code/modules/mob/living/bot/secbot.dm index b07202572e..f7556e0ece 100644 --- a/code/modules/mob/living/bot/secbot.dm +++ b/code/modules/mob/living/bot/secbot.dm @@ -258,40 +258,40 @@ var/build_step = 0 var/created_name = "Securitron" -/obj/item/weapon/secbot_assembly/attackby(var/obj/item/O, var/mob/user) +/obj/item/weapon/secbot_assembly/attackby(var/obj/item/W, var/mob/user) ..() - if(istype(O, /obj/item/weapon/weldingtool) && !build_step) - var/obj/item/weapon/weldingtool/WT = O + if(istype(W, /obj/item/weapon/weldingtool) && !build_step) + var/obj/item/weapon/weldingtool/WT = W if(WT.remove_fuel(0, user)) build_step = 1 overlays += image('icons/obj/aibots.dmi', "hs_hole") user << "You weld a hole in \the [src]." - else if(isprox(O) && (build_step == 1)) + else if(isprox(W) && (build_step == 1)) user.drop_item() build_step = 2 - user << "You add \the [O] to [src]." + user << "You add \the [W] to [src]." overlays += image('icons/obj/aibots.dmi', "hs_eye") name = "helmet/signaler/prox sensor assembly" - qdel(O) + qdel(W) - else if((istype(O, /obj/item/robot_parts/l_arm) || istype(O, /obj/item/robot_parts/r_arm)) && build_step == 2) + else if((istype(W, /obj/item/robot_parts/l_arm) || istype(W, /obj/item/robot_parts/r_arm) || (istype(W, /obj/item/organ/external/arm) && ((W.name == "robotic right arm") || (W.name == "robotic left arm")))) && build_step == 2) user.drop_item() build_step = 3 - user << "You add \the [O] to [src]." + user << "You add \the [W] to [src]." name = "helmet/signaler/prox sensor/robot arm assembly" overlays += image('icons/obj/aibots.dmi', "hs_arm") - qdel(O) + qdel(W) - else if(istype(O, /obj/item/weapon/melee/baton) && build_step == 3) + else if(istype(W, /obj/item/weapon/melee/baton) && build_step == 3) user.drop_item() user << "You complete the Securitron! Beep boop." var/mob/living/bot/secbot/S = new /mob/living/bot/secbot(get_turf(src)) S.name = created_name - qdel(O) + qdel(W) qdel(src) - else if(istype(O, /obj/item/weapon/pen)) + else if(istype(W, /obj/item/weapon/pen)) var/t = sanitizeSafe(input(user, "Enter new robot name", name, created_name), MAX_NAME_LEN) if(!t) return diff --git a/code/modules/mob/living/carbon/carbon_defense.dm b/code/modules/mob/living/carbon/carbon_defense.dm index dd9e4f28b9..aa4e6ced11 100644 --- a/code/modules/mob/living/carbon/carbon_defense.dm +++ b/code/modules/mob/living/carbon/carbon_defense.dm @@ -1,12 +1,11 @@ - //Called when the mob is hit with an item in combat. /mob/living/carbon/resolve_item_attack(obj/item/I, mob/living/user, var/effective_force, var/hit_zone) - if(check_attack_throat(I, user)) + if(check_neckgrab_attack(I, user, hit_zone)) return null ..() /mob/living/carbon/standard_weapon_hit_effects(obj/item/I, mob/living/user, var/effective_force, var/blocked, var/hit_zone) - if(!effective_force || blocked >= 100) + if(!effective_force || blocked >= 100) return 0 //Hulk modifier @@ -39,18 +38,23 @@ return 1 // Attacking someone with a weapon while they are neck-grabbed -/mob/living/carbon/proc/check_attack_throat(obj/item/W, mob/user) +/mob/living/carbon/proc/check_neckgrab_attack(obj/item/W, mob/user, var/hit_zone) if(user.a_intent == I_HURT) for(var/obj/item/weapon/grab/G in src.grabbed_by) - if(G.assailant == user && G.state >= GRAB_NECK) - if(attack_throat(W, G, user)) - return 1 + if(G.assailant == user) + if(G.state >= GRAB_AGGRESSIVE) + if(hit_zone == BP_TORSO && shank_attack(W, G, user)) + return 1 + if(G.state >= GRAB_NECK) + if(hit_zone == BP_HEAD && attack_throat(W, G, user, hit_zone)) + return 1 return 0 + // Knifing /mob/living/carbon/proc/attack_throat(obj/item/W, obj/item/weapon/grab/G, mob/user) - if(!W.edge || !W.force || W.damtype != BRUTE) + if(!W.edge || !W.force || W.damtype != BRUTE) return 0 //unsuitable weapon user.visible_message("\The [user] begins to slit [src]'s throat with \the [W]!") @@ -95,4 +99,59 @@ user.attack_log += "\[[time_stamp()]\] Knifed [name] ([ckey]) with [W.name] (INTENT: [uppertext(user.a_intent)]) (DAMTYE: [uppertext(W.damtype)])" src.attack_log += "\[[time_stamp()]\] Got knifed by [user.name] ([user.ckey]) with [W.name] (INTENT: [uppertext(user.a_intent)]) (DAMTYE: [uppertext(W.damtype)])" msg_admin_attack("[key_name(user)] knifed [key_name(src)] with [W.name] (INTENT: [uppertext(user.a_intent)]) (DAMTYE: [uppertext(W.damtype)])" ) - return 1 \ No newline at end of file + return 1 + +/mob/living/carbon/proc/shank_attack(obj/item/W, obj/item/weapon/grab/G, mob/user, hit_zone) + + if(!W.sharp || !W.force || W.damtype != BRUTE) + return 0 //unsuitable weapon + + user.visible_message("\The [user] plunges \the [W] into \the [src]!") + + var/damage = shank_armor_helper(W, G, user) + apply_damage(damage, W.damtype, "torso", 0, sharp=W.sharp, edge=W.edge) + + if(W.hitsound) + playsound(loc, W.hitsound, 50, 1, -1) + + user.attack_log += "\[[time_stamp()]\] Shanked [name] ([ckey]) with [W.name] (INTENT: [uppertext(user.a_intent)]) (DAMTYE: [uppertext(W.damtype)])" + src.attack_log += "\[[time_stamp()]\] Got shanked by [user.name] ([user.ckey]) with [W.name] (INTENT: [uppertext(user.a_intent)]) (DAMTYE: [uppertext(W.damtype)])" + msg_admin_attack("[key_name(user)] shanked [key_name(src)] with [W.name] (INTENT: [uppertext(user.a_intent)]) (DAMTYE: [uppertext(W.damtype)])" ) + + return 1 + +/mob/living/carbon/proc/shank_armor_helper(obj/item/W, obj/item/weapon/grab/G, mob/user) + var/damage = W.force + var/damage_mod = 1 + if(W.edge) + damage = damage * 1.25 //small damage bonus for having sharp and edge + + var/obj/item/clothing/suit/worn_suit + var/obj/item/clothing/under/worn_under + var/worn_suit_armor + var/worn_under_armor + + //if(slot_wear_suit) + if(get_equipped_item(slot_wear_suit)) + worn_suit = get_equipped_item(slot_wear_suit) + //worn_suit = get_equipped_item(slot_wear_suit) + worn_suit_armor = worn_suit.armor["melee"] + else + worn_suit_armor = 0 + + //if(slot_w_uniform) + if(get_equipped_item(slot_w_uniform)) + worn_under = get_equipped_item(slot_w_uniform) + //worn_under_armor = slot_w_uniform.armor["melee"] + worn_under_armor = worn_under.armor["melee"] + else + worn_under_armor = 0 + + if(worn_under_armor > worn_suit_armor) + damage_mod = 1 - (worn_under_armor/100) + else + damage_mod = 1 - (worn_suit_armor/100) + + damage = damage * damage_mod + + return damage \ No newline at end of file diff --git a/code/modules/mob/living/carbon/human/examine.dm b/code/modules/mob/living/carbon/human/examine.dm index 7ac543f1f2..195816f255 100644 --- a/code/modules/mob/living/carbon/human/examine.dm +++ b/code/modules/mob/living/carbon/human/examine.dm @@ -67,7 +67,7 @@ BP_L_LEG = skiplegs, BP_R_LEG = skiplegs) - var/msg = "*---------*\nThis is " + var/list/msg = list("*---------*\nThis is ") var/datum/gender/T = gender_datums[get_gender()] if(skipjumpsuit && skipface) //big suits/masks/helmets make it hard to tell their gender @@ -253,8 +253,8 @@ //splints for(var/organ in list(BP_L_LEG, BP_R_LEG, BP_L_ARM, BP_R_ARM)) var/obj/item/organ/external/o = get_organ(organ) - if(o && o.status & ORGAN_SPLINTED) - msg += "[T.He] [T.has] a splint on [T.his] [o.name]!\n" + if(o && o.splinted && o.splinted.loc == o) + msg += "[T.He] [T.has] \a [o.splinted] on [T.his] [o.name]!\n" if(suiciding) msg += "[T.He] appears to have commited suicide... there is no hope of recovery.\n" @@ -316,6 +316,7 @@ var/list/wound_flavor_text = list() var/list/is_bleeding = list() + var/applying_pressure = "" for(var/organ_tag in species.has_limbs) @@ -349,8 +350,6 @@ wound_flavor_text["[temp.name]"] = "[T.He] has [temp.get_wounds_desc()] on [T.his] [parent.name].
" else wound_flavor_text["[temp.name]"] = "[T.He] has [temp.get_wounds_desc()] on [T.his] [temp.name].
" - if(temp.status & ORGAN_BLEEDING) - is_bleeding["[temp.name]"] = "[T.His] [temp.name] is bleeding!
" else wound_flavor_text["[temp.name]"] = "" if(temp.dislocated == 2) @@ -358,9 +357,14 @@ if(((temp.status & ORGAN_BROKEN) && temp.brute_dam > temp.min_broken_damage) || (temp.status & ORGAN_MUTATED)) wound_flavor_text["[temp.name]"] += "[T.His] [temp.name] is dented and swollen!
" + if(!wound_flavor_text["[temp.name]"] && (temp.status & ORGAN_BLEEDING)) + is_bleeding["[temp.name]"] = "[T.His] [temp.name] is bleeding!
" + + if(temp.applied_pressure == src) + applying_pressure = "[T.He] is applying pressure to [T.his] [temp.name].
" + for(var/limb in wound_flavor_text) msg += wound_flavor_text[limb] - is_bleeding[limb] = null for(var/limb in is_bleeding) msg += is_bleeding[limb] for(var/implant in get_visible_implants(0)) @@ -421,13 +425,14 @@ msg += "OOC Notes: \[View\]\n" // VOREStation End - msg += "*---------*
" + msg += "*---------*

" + msg += applying_pressure if (pose) if( findtext(pose,".",lentext(pose)) == 0 && findtext(pose,"!",lentext(pose)) == 0 && findtext(pose,"?",lentext(pose)) == 0 ) pose = addtext(pose,".") //Makes sure all emotes end with a period. - msg += "\n[T.He] [pose]" + msg += "[T.He] [pose]" - user << msg + user << jointext(msg, null) //Helper procedure. Called by /mob/living/carbon/human/examine() and /mob/living/carbon/human/Topic() to determine HUD access to security and medical records. /proc/hasHUD(mob/M as mob, hudtype) diff --git a/code/modules/mob/living/carbon/human/human.dm b/code/modules/mob/living/carbon/human/human.dm index a53363e586..03a7b0db45 100644 --- a/code/modules/mob/living/carbon/human/human.dm +++ b/code/modules/mob/living/carbon/human/human.dm @@ -1018,7 +1018,7 @@ /mob/living/carbon/human/proc/handle_embedded_objects() for(var/obj/item/organ/external/organ in src.organs) - if(organ.status & ORGAN_SPLINTED) //Splints prevent movement. + if(organ.splinted) //Splints prevent movement. continue for(var/obj/item/O in organ.implants) if(!istype(O,/obj/item/weapon/implant) && prob(5)) //Moving with things stuck in you could be bad. diff --git a/code/modules/mob/living/carbon/human/human_attackhand.dm b/code/modules/mob/living/carbon/human/human_attackhand.dm index d638d779d1..e790d1b5fd 100644 --- a/code/modules/mob/living/carbon/human/human_attackhand.dm +++ b/code/modules/mob/living/carbon/human/human_attackhand.dm @@ -92,7 +92,7 @@ src << "You feel a breath of fresh air enter your lungs. It feels good." H << "Repeat at least every 7 seconds." - else + else if(!(M == src && apply_pressure(M, M.zone_sel.selecting))) help_shake_act(M) return 1 @@ -363,3 +363,38 @@ spawn(1) qdel(rgrab) return success + +/* + We want to ensure that a mob may only apply pressure to one organ of one mob at any given time. Currently this is done mostly implicitly through + the behaviour of do_after() and the fact that applying pressure to someone else requires a grab: + If you are applying pressure to yourself and attempt to grab someone else, you'll change what you are holding in your active hand which will stop do_mob() + If you are applying pressure to another and attempt to apply pressure to yourself, you'll have to switch to an empty hand which will also stop do_mob() + Changing targeted zones should also stop do_mob(), preventing you from applying pressure to more than one body part at once. +*/ +/mob/living/carbon/human/proc/apply_pressure(mob/living/user, var/target_zone) + var/obj/item/organ/external/organ = get_organ(target_zone) + if(!organ || !(organ.status & ORGAN_BLEEDING) || (organ.robotic >= ORGAN_ROBOT)) + return 0 + + if(organ.applied_pressure) + user << "Someone is already applying pressure to [user == src? "your [organ.name]" : "[src]'s [organ.name]"]." + return 0 + + if(user == src) + user.visible_message("\The [user] starts applying pressure to \his [organ.name]!", "You start applying pressure to your [organ.name]!") + else + user.visible_message("\The [user] starts applying pressure to [src]'s [organ.name]!", "You start applying pressure to [src]'s [organ.name]!") + spawn(0) + organ.applied_pressure = user + + //apply pressure as long as they stay still and keep grabbing + do_mob(user, src, INFINITY, target_zone, progress = 0) + + organ.applied_pressure = null + + if(user == src) + user.visible_message("\The [user] stops applying pressure to \his [organ.name]!", "You stop applying pressure to your [organ]!") + else + user.visible_message("\The [user] stops applying pressure to [src]'s [organ.name]!", "You stop applying pressure to [src]'s [organ.name]!") + + return 1 \ No newline at end of file diff --git a/code/modules/mob/living/carbon/human/human_defense.dm b/code/modules/mob/living/carbon/human/human_defense.dm index 1d716b519d..2adb24665b 100644 --- a/code/modules/mob/living/carbon/human/human_defense.dm +++ b/code/modules/mob/living/carbon/human/human_defense.dm @@ -147,7 +147,7 @@ emp_act ..() /mob/living/carbon/human/resolve_item_attack(obj/item/I, mob/living/user, var/target_zone) - if(check_attack_throat(I, user)) + if(check_neckgrab_attack(I, user, target_zone)) return null if(user == src) // Attacking yourself can't miss @@ -464,3 +464,30 @@ emp_act return perm +/mob/living/carbon/human/shank_attack(obj/item/W, obj/item/weapon/grab/G, mob/user, hit_zone) + + if(!..()) + return 0 + + var/organ_chance = 50 + var/damage = shank_armor_helper(W, G, user) + var/obj/item/organ/external/chest = get_organ(hit_zone) + + if(W.edge) + organ_chance = 75 + user.next_move = world.time + 20 + user.visible_message("\The [user] begins to twist \the [W] around inside [src]'s [chest]!") + if(!do_after(user, 20)) + return 0 + if(!(G && G.assailant == user && G.affecting == src)) //check that we still have a grab + return 0 + + user.visible_message("\The [user] twists \the [W] around inside [src]'s [chest]!") + + if(prob(organ_chance)) + var/obj/item/organ/internal/selected_organ = pick(chest.internal_organs) + selected_organ.damage = max(selected_organ.damage, damage * 0.5) + G.last_action = world.time + flick(G.hud.icon_state, G.hud) + + return 1 \ No newline at end of file diff --git a/code/modules/mob/living/carbon/human/human_defines.dm b/code/modules/mob/living/carbon/human/human_defines.dm index ad6d078869..c225e63838 100644 --- a/code/modules/mob/living/carbon/human/human_defines.dm +++ b/code/modules/mob/living/carbon/human/human_defines.dm @@ -87,7 +87,8 @@ var/list/flavor_texts = list() var/gunshot_residue var/pulling_punches // Are you trying not to hurt your opponent? - var/robolimb_count = 0 // Number of robot limbs. + var/robolimb_count = 0 // Total number of external robot parts. + var/robobody_count = 0 // Counts torso, groin, and head, if they're robotic mob_bump_flag = HUMAN mob_push_flags = ~HEAVY diff --git a/code/modules/mob/living/carbon/human/human_movement.dm b/code/modules/mob/living/carbon/human/human_movement.dm index ae9dd9a506..de4b36dceb 100644 --- a/code/modules/mob/living/carbon/human/human_movement.dm +++ b/code/modules/mob/living/carbon/human/human_movement.dm @@ -45,7 +45,7 @@ var/obj/item/organ/external/E = get_organ(organ_name) if(!E || E.is_stump()) tally += 4 - if(E.status & ORGAN_SPLINTED) + if(E.splinted) tally += 0.5 else if(E.status & ORGAN_BROKEN) tally += 1.5 @@ -57,7 +57,7 @@ var/obj/item/organ/external/E = get_organ(organ_name) if(!E || E.is_stump()) tally += 4 - else if(E.status & ORGAN_SPLINTED) + else if(E.splinted) tally += 0.5 else if(E.status & ORGAN_BROKEN) tally += 1.5 diff --git a/code/modules/mob/living/carbon/human/human_organs.dm b/code/modules/mob/living/carbon/human/human_organs.dm index 494126e312..97153394db 100644 --- a/code/modules/mob/living/carbon/human/human_organs.dm +++ b/code/modules/mob/living/carbon/human/human_organs.dm @@ -142,10 +142,10 @@ return for (var/obj/item/organ/external/E in organs) - if(!E || !E.can_grasp || (E.status & ORGAN_SPLINTED)) + if(!E || !E.can_grasp) continue - if(E.is_broken() || E.is_dislocated()) + if((E.is_broken() || E.is_dislocated()) && !E.splinted) switch(E.body_part) if(HAND_LEFT, ARM_LEFT) if(!l_hand) diff --git a/code/modules/mob/living/carbon/human/life.dm b/code/modules/mob/living/carbon/human/life.dm index 8fc44a0671..ceef119b33 100644 --- a/code/modules/mob/living/carbon/human/life.dm +++ b/code/modules/mob/living/carbon/human/life.dm @@ -693,9 +693,9 @@ if (species.body_temperature == null) return //this species doesn't have metabolic thermoregulation - // Robolimbs cause overheating too. - if(robolimb_count) - bodytemperature += round(robolimb_count/2) + // FBPs will overheat, prosthetic limbs are fine. + if(robobody_count) + bodytemperature += round(robobody_count*1.75) var/body_temperature_difference = species.body_temperature - bodytemperature diff --git a/code/modules/mob/living/carbon/human/stripping.dm b/code/modules/mob/living/carbon/human/stripping.dm index f1c92b6255..d67eaf76a9 100644 --- a/code/modules/mob/living/carbon/human/stripping.dm +++ b/code/modules/mob/living/carbon/human/stripping.dm @@ -125,11 +125,13 @@ if(can_reach_splints) var/removed_splint for(var/obj/item/organ/external/o in organs) - if (o && o.status & ORGAN_SPLINTED) - var/obj/item/W = new /obj/item/stack/medical/splint(get_turf(src), 1) - o.status &= ~ORGAN_SPLINTED - W.add_fingerprint(user) - removed_splint = 1 + if (o && o.splinted) + var/obj/item/S = o.splinted + if(istype(S) && S.loc == o) //can only remove splints that are actually worn on the organ (deals with hardsuit splints) + S.add_fingerprint(user) + if(o.remove_splint()) + user.put_in_active_hand(S) + removed_splint = 1 if(removed_splint) visible_message("\The [user] removes \the [src]'s splints!") else diff --git a/code/modules/mob/living/carbon/human/update_icons.dm b/code/modules/mob/living/carbon/human/update_icons.dm index 6bc000f0f1..5c6868edc0 100644 --- a/code/modules/mob/living/carbon/human/update_icons.dm +++ b/code/modules/mob/living/carbon/human/update_icons.dm @@ -226,6 +226,7 @@ var/global/list/damage_icon_parts = list() var/skeleton = (SKELETON in src.mutations) robolimb_count = 0 + robobody_count = 0 //CACHING: Generate an index key from visible bodyparts. //0 = destroyed, 1 = normal, 2 = robotic, 3 = necrotic. @@ -257,6 +258,8 @@ var/global/list/damage_icon_parts = list() else if(part.robotic >= ORGAN_ROBOT) icon_key += "2[part.model ? "-[part.model]": ""]" robolimb_count++ + if(part.organ_tag == BP_HEAD || part.organ_tag == BP_TORSO || part.organ_tag == BP_GROIN) + robobody_count ++ else if(part.status & ORGAN_DEAD) icon_key += "3" else diff --git a/code/modules/mob/living/carbon/metroid/metroid.dm b/code/modules/mob/living/carbon/metroid/metroid.dm index b7a66b6842..3c0bfbdbad 100644 --- a/code/modules/mob/living/carbon/metroid/metroid.dm +++ b/code/modules/mob/living/carbon/metroid/metroid.dm @@ -381,8 +381,3 @@ powerlevel = 10 adjustToxLoss(-10) nutrition = max(nutrition, get_max_nutrition()) - -/mob/living/carbon/slime/cannot_use_vents() - if(Victim) - return "You cannot ventcrawl while feeding." - ..() diff --git a/code/modules/mob/living/living.dm b/code/modules/mob/living/living.dm index 8fc7ef0f8c..bbb9a1acc8 100644 --- a/code/modules/mob/living/living.dm +++ b/code/modules/mob/living/living.dm @@ -651,126 +651,10 @@ default behaviour is: resting = !resting src << "You are now [resting ? "resting" : "getting up"]" -/mob/living/proc/is_allowed_vent_crawl_item(var/obj/item/carried_item) - return (get_inventory_slot(carried_item) == 0) - -/mob/living/simple_animal/spiderbot/is_allowed_vent_crawl_item(var/obj/item/carried_item) - if(carried_item == held_item) - return 0 - return ..() - -//called when the mob receives a bright flash -/mob/living/flash_eyes(intensity = FLASH_PROTECTION_MODERATE, override_blindness_check = FALSE, affect_silicon = FALSE, visual = FALSE, type = /obj/screen/fullscreen/flash) - if(override_blindness_check || !(disabilities & BLIND)) - overlay_fullscreen("flash", type) - spawn(25) - if(src) - clear_fullscreen("flash", 25) - return 1 - -/mob/living/proc/handle_ventcrawl(var/obj/machinery/atmospherics/unary/vent_pump/vent_found = null, var/ignore_items = 0) // -- TLE -- Merged by Carn - if(stat) - src << "You must be conscious to do this!" - return - if(lying) - src << "You can't vent crawl while you're stunned!" - return - var/special_fail_msg = cannot_use_vents() - if(special_fail_msg) - src << "[special_fail_msg]" - return - - if(vent_found) // one was passed in, probably from vent/AltClick() - if(vent_found.welded) - src << "That vent is welded shut." - return - if(!vent_found.Adjacent(src)) - return // don't even acknowledge that - else - for(var/obj/machinery/atmospherics/unary/vent_pump/v in range(1,src)) - if(!v.welded) - if(v.Adjacent(src)) - vent_found = v - if(!vent_found) - src << "You'll need a non-welded vent to crawl into!" - return - - if(!vent_found.network || !vent_found.network.normal_members.len) - src << "This vent is not connected to anything." - return - - var/list/vents = list() - for(var/obj/machinery/atmospherics/unary/vent_pump/temp_vent in vent_found.network.normal_members) - if(temp_vent.welded) - continue - if(temp_vent in loc) - continue - var/turf/T = get_turf(temp_vent) - - if(!T || T.z != loc.z) - continue - - var/i = 1 - var/index = "[T.loc.name]\[[i]\]" - while(index in vents) - i++ - index = "[T.loc.name]\[[i]\]" - vents[index] = temp_vent - if(!vents.len) - src << "\red There are no available vents to travel to, they could be welded." - return - - var/obj/selection = input("Select a destination.", "Duct System") as null|anything in sortAssoc(vents) - if(!selection) return - - if(!vent_found.Adjacent(src)) - src << "Never mind, you left." - return - - if(!ignore_items) - var/list/badItems = list() - for(var/obj/item/carried_item in contents)//If the monkey got on objects. - if(!is_allowed_vent_crawl_item(carried_item)) - badItems += carried_item.name - if(badItems.len) - src << "Your [english_list(badItems)] prevent[badItems.len == 1 ? "s" : ""] you from ventcrawling." - return - - if(isslime(src)) - var/mob/living/carbon/slime/S = src - if(S.Victim) - src << "\red You'll have to let [S.Victim] go or finish eating \him first." - return - - var/obj/machinery/atmospherics/unary/vent_pump/target_vent = vents[selection] - if(!target_vent) - return - - for(var/mob/O in viewers(src, null)) - O.show_message(text("[src] scrambles into the ventillation ducts!"), 1) - loc = target_vent - - var/travel_time = round(get_dist(loc, target_vent.loc) / 2) - - spawn(travel_time) - - if(!target_vent) return - for(var/mob/O in hearers(target_vent,null)) - O.show_message("You hear something squeezing through the ventilation ducts.",2) - - sleep(travel_time) - - if(!target_vent) return - if(target_vent.welded) //the vent can be welded while alien scrolled through the list or travelled. - target_vent = vent_found //travel back. No additional time required. - src << "\red The vent you were heading to appears to be welded." - loc = target_vent.loc - var/area/new_area = get_area(loc) - if(new_area) - new_area.Entered(src) - /mob/living/proc/cannot_use_vents() - return "You can't fit into that vent." + if(mob_size > MOB_SMALL) + return "You can't fit into that vent." + return null /mob/living/proc/has_brain() return 1 diff --git a/code/modules/mob/living/living_powers.dm b/code/modules/mob/living/living_powers.dm index b4310d77b5..4fb4c1bcbd 100644 --- a/code/modules/mob/living/living_powers.dm +++ b/code/modules/mob/living/living_powers.dm @@ -1,13 +1,3 @@ -/mob/living/proc/ventcrawl() - set name = "Crawl through Vent" - set desc = "Enter an air vent and crawl through the pipe system." - set category = "Abilities" - - if(stat == DEAD || paralysis || weakened || stunned || restrained()) - return - - handle_ventcrawl() - /mob/living/proc/hide() set name = "Hide" set desc = "Allows to hide beneath tables or certain items. Toggled on or off." diff --git a/code/modules/mob/living/silicon/ai/ai.dm b/code/modules/mob/living/silicon/ai/ai.dm index 3c6f8585f6..fd38776dd5 100644 --- a/code/modules/mob/living/silicon/ai/ai.dm +++ b/code/modules/mob/living/silicon/ai/ai.dm @@ -400,7 +400,7 @@ var/list/ai_verbs_hidden = list( // For why this exists, refer to https://xkcd.c var/input = sanitize(input(usr, "Please choose a message to transmit to [boss_short] via quantum entanglement. Please be aware that this process is very expensive, and abuse will lead to... termination. Transmission does not guarantee a response. There is a 30 second delay before you may send another message, be clear, full and concise.", "To abort, send an empty message.", "")) if(!input) return - Centcomm_announce(input, usr) + CentCom_announce(input, usr) usr << "Message transmitted." log_say("[key_name(usr)] has made an IA [boss_short] announcement: [input]") emergency_message_cooldown = 1 diff --git a/code/modules/mob/living/silicon/ai/icons.dm b/code/modules/mob/living/silicon/ai/icons.dm index 83689c9dd4..ebd47cc02d 100644 --- a/code/modules/mob/living/silicon/ai/icons.dm +++ b/code/modules/mob/living/silicon/ai/icons.dm @@ -112,7 +112,7 @@ var/list/datum/ai_icon/ai_icons alive_light = "#585858" /datum/ai_icon/nanotrasen - name = "Nanotrasen" + name = "NanoTrasen" alive_icon = "ai-nanotrasen" alive_light = "#000029" diff --git a/code/modules/mob/living/silicon/robot/robot.dm b/code/modules/mob/living/silicon/robot/robot.dm index f9c26528b6..f038324299 100644 --- a/code/modules/mob/living/silicon/robot/robot.dm +++ b/code/modules/mob/living/silicon/robot/robot.dm @@ -465,6 +465,7 @@ return var/obj/item/weapon/weldingtool/WT = W if (WT.remove_fuel(0)) + user.setClickCooldown(DEFAULT_ATTACK_COOLDOWN) adjustBruteLoss(-30) updatehealth() add_fingerprint(user) @@ -480,6 +481,7 @@ return var/obj/item/stack/cable_coil/coil = W if (coil.use(1)) + user.setClickCooldown(DEFAULT_ATTACK_COOLDOWN) adjustFireLoss(-30) updatehealth() for(var/mob/O in viewers(user, null)) diff --git a/code/modules/mob/living/simple_animal/friendly/penguin.dm b/code/modules/mob/living/simple_animal/friendly/penguin.dm new file mode 100644 index 0000000000..b843013c39 --- /dev/null +++ b/code/modules/mob/living/simple_animal/friendly/penguin.dm @@ -0,0 +1,19 @@ +/mob/living/simple_animal/penguin + name = "space penguin" + desc = "An ungainly, waddling, cute, and VERY well-dressed bird." + icon_state = "penguin" + icon_living = "penguin" + icon_dead = "penguin_dead" + icon_gib = "generic_gib" + speak_chance = 0 + turns_per_move = 5 + maxHealth = 20 + health = 20 + meat_type = /obj/item/weapon/reagent_containers/food/snacks/meat + response_help = "pets" + response_disarm = "pushes aside" + response_harm = "hits" + harm_intent_damage = 5 + melee_damage_upper = 15 + melee_damage_lower = 10 + attacktext = "pecked" \ No newline at end of file diff --git a/code/modules/mob/living/simple_animal/hostile/goose.dm b/code/modules/mob/living/simple_animal/hostile/goose.dm new file mode 100644 index 0000000000..0f2c4af611 --- /dev/null +++ b/code/modules/mob/living/simple_animal/hostile/goose.dm @@ -0,0 +1,34 @@ + + +/mob/living/simple_animal/hostile/goose + name = "space goose" + desc = "That's no duck. That's a space goose. You have a bad feeling about this." + icon_state = "goose" + icon_living = "goose" + icon_dead = "goose_dead" + icon_gib = "generic_gib" + speak_chance = 0 + turns_per_move = 5 + meat_type = /obj/item/weapon/reagent_containers/food/snacks/meat + response_help = "pets the" + response_disarm = "gently pushes aside the" + response_harm = "hits the" + speed = 4 + maxHealth = 15 //nothing an unarmed crewmember shouldn't be able to stomp into the dirt, if they're alone. + health = 15 + + harm_intent_damage = 5 + melee_damage_lower = 5 //they're meant to be annoying, not threatening. + melee_damage_upper = 5 //unless there's like a dozen of them, then you're screwed. + attacktext = "pecked" + attack_sound = 'sound/weapons/bite.ogg' + + break_stuff_probability = 5 + + faction = "geese" + + +/mob/living/simple_animal/hostile/goose/FindTarget() + . = ..() + if(.) + custom_emote(1,"flaps and honks at [.]!") \ No newline at end of file diff --git a/code/modules/mob/mob.dm b/code/modules/mob/mob.dm index 75f061e2e1..41cbbbc5e9 100644 --- a/code/modules/mob/mob.dm +++ b/code/modules/mob/mob.dm @@ -520,7 +520,7 @@ for(var/name in H.organs_by_name) var/obj/item/organ/external/e = H.organs_by_name[name] if(e && H.lying) - if(((e.status & ORGAN_BROKEN && !(e.status & ORGAN_SPLINTED)) || e.status & ORGAN_BLEEDING) && (H.getBruteLoss() + H.getFireLoss() >= 100)) + if(((e.status & ORGAN_BROKEN && !(e.splinted)) || e.status & ORGAN_BLEEDING) && (H.getBruteLoss() + H.getFireLoss() >= 100)) return 1 break return 0 diff --git a/code/modules/mob/mob_grab.dm b/code/modules/mob/mob_grab.dm index e40b14dffd..a7b982b1b7 100644 --- a/code/modules/mob/mob_grab.dm +++ b/code/modules/mob/mob_grab.dm @@ -301,6 +301,7 @@ //clicking on the victim while grabbing them if(M == affecting) if(ishuman(affecting)) + var/mob/living/carbon/human/H = affecting var/hit_zone = assailant.zone_sel.selecting flick(hud.icon_state, hud) switch(assailant.a_intent) @@ -309,7 +310,10 @@ assailant << "You are no longer pinning [affecting] to the ground." force_down = 0 return - inspect_organ(affecting, assailant, hit_zone) + if(state >= GRAB_AGGRESSIVE) + H.apply_pressure(assailant, hit_zone) + else + inspect_organ(affecting, assailant, hit_zone) if(I_GRAB) jointlock(affecting, assailant, hit_zone) diff --git a/code/modules/mob/new_player/new_player.dm b/code/modules/mob/new_player/new_player.dm index c2b83551ec..f50b91f291 100644 --- a/code/modules/mob/new_player/new_player.dm +++ b/code/modules/mob/new_player/new_player.dm @@ -371,7 +371,7 @@ dat += "Welcome, [name].
" dat += "Round Duration: [roundduration2text()]
" - if(emergency_shuttle) //In case Nanotrasen decides reposess CentComm's shuttles. + if(emergency_shuttle) //In case NanoTrasen decides reposess CentCom's shuttles. if(emergency_shuttle.going_to_centcom()) //Shuttle is going to centcomm, not recalled dat += "The station has been evacuated.
" if(emergency_shuttle.online()) diff --git a/code/modules/mob/new_player/preferences_setup.dm b/code/modules/mob/new_player/preferences_setup.dm index a10049a644..92f0f512bd 100644 --- a/code/modules/mob/new_player/preferences_setup.dm +++ b/code/modules/mob/new_player/preferences_setup.dm @@ -29,7 +29,7 @@ all_underwear[WRC.name] = WRI.name - backbag = rand(1,4) + backbag = rand(1,5) pdachoice = rand(1,3) age = rand(current_species.min_age, current_species.max_age) b_type = RANDOM_BLOOD_TYPE diff --git a/code/modules/multiz/pipes.dm b/code/modules/multiz/pipes.dm index 85e23b6797..1cb5b9b4da 100644 --- a/code/modules/multiz/pipes.dm +++ b/code/modules/multiz/pipes.dm @@ -13,9 +13,6 @@ obj/machinery/atmospherics/pipe/zpipe dir = SOUTH initialize_directions = SOUTH - var/obj/machinery/atmospherics/node1 //connection on the same Z - var/obj/machinery/atmospherics/node2 //connection on the other Z - var/minimum_temperature_difference = 300 var/thermal_conductivity = 0 //WALL_HEAT_TRANSFER_COEFFICIENT No diff --git a/code/modules/organs/blood.dm b/code/modules/organs/blood.dm index c167f949fa..7637264bac 100644 --- a/code/modules/organs/blood.dm +++ b/code/modules/organs/blood.dm @@ -128,8 +128,18 @@ var/const/BLOOD_VOLUME_SURVIVE = 40 for(var/obj/item/organ/external/temp in organs) if(!(temp.status & ORGAN_BLEEDING) || (temp.robotic >= ORGAN_ROBOT)) continue - for(var/datum/wound/W in temp.wounds) if(W.bleeding()) - blood_max += W.damage / 30 + for(var/datum/wound/W in temp.wounds) + if(W.bleeding()) + if(temp.applied_pressure) + if(ishuman(temp.applied_pressure)) + var/mob/living/carbon/human/H = temp.applied_pressure + H.bloody_hands(src, 0) + //somehow you can apply pressure to every wound on the organ at the same time + //you're basically forced to do nothing at all, so let's make it pretty effective + var/min_eff_damage = max(0, W.damage - 10) / 6 //still want a little bit to drip out, for effect + blood_max += max(min_eff_damage, W.damage - 30) / 30 + else + blood_max += W.damage / 30 if (temp.open) blood_max += 2 //Yer stomach is cut open drip(blood_max) diff --git a/code/modules/organs/internal/appendix.dm b/code/modules/organs/internal/appendix.dm index b3fdc28bc2..f756b71efa 100644 --- a/code/modules/organs/internal/appendix.dm +++ b/code/modules/organs/internal/appendix.dm @@ -46,7 +46,7 @@ var/datum/wound/W = new /datum/wound/internal_bleeding(20) owner.adjustToxLoss(25) groin.wounds += W - inflamed = 0 + inflamed = 1 /obj/item/organ/internal/appendix/removed() if(inflamed) diff --git a/code/modules/organs/organ.dm b/code/modules/organs/organ.dm index fad60cc0d7..c3a349df17 100644 --- a/code/modules/organs/organ.dm +++ b/code/modules/organs/organ.dm @@ -254,7 +254,6 @@ var/list/organ_cache = list() robotic = ORGAN_ROBOT src.status &= ~ORGAN_BROKEN src.status &= ~ORGAN_BLEEDING - src.status &= ~ORGAN_SPLINTED src.status &= ~ORGAN_CUT_AWAY /obj/item/organ/proc/mechassist() //Used to add things like pacemakers, etc diff --git a/code/modules/organs/organ_external.dm b/code/modules/organs/organ_external.dm index 612cda4a98..49917d8a23 100644 --- a/code/modules/organs/organ_external.dm +++ b/code/modules/organs/organ_external.dm @@ -38,6 +38,7 @@ var/list/s_col // skin colour var/list/h_col // hair colour var/body_hair // Icon blend for body hair if any. + var/mob/living/applied_pressure // Wound and structural data. var/wound_update_accuracy = 1 // how often wounds should be updated, a higher number means less often @@ -50,6 +51,7 @@ var/list/implants = list() // Currently implanted objects. var/organ_rel_size = 25 // Relative size of the organ. var/base_miss_chance = 20 // Chance of missing. + var/atom/movable/splinted // Joint/state stuff. var/can_grasp // It would be more appropriate if these two were named "affects_grasp" and "affects_stand" at this point @@ -84,6 +86,10 @@ for(var/obj/item/organ/O in internal_organs) qdel(O) + if(splinted && splinted.loc == src) + qdel(splinted) + splinted = null + if(owner) owner.organs -= src owner.organs_by_name[organ_tag] = null @@ -524,11 +530,11 @@ This function completely restores a damaged organ to perfect condition. //external organs handle brokenness a bit differently when it comes to damage. Instead brute_dam is checked inside process() //this also ensures that an external organ cannot be "broken" without broken_description being set. /obj/item/organ/external/is_broken() - return ((status & ORGAN_CUT_AWAY) || ((status & ORGAN_BROKEN) && !(status & ORGAN_SPLINTED))) + return ((status & ORGAN_CUT_AWAY) || ((status & ORGAN_BROKEN) && !(splinted))) //Determines if we even need to process this organ. /obj/item/organ/external/proc/need_process() - if(status & (ORGAN_CUT_AWAY|ORGAN_BLEEDING|ORGAN_BROKEN|ORGAN_DESTROYED|ORGAN_SPLINTED|ORGAN_DEAD|ORGAN_MUTATED)) + if(status & (ORGAN_CUT_AWAY|ORGAN_BLEEDING|ORGAN_BROKEN|ORGAN_DESTROYED|ORGAN_DEAD|ORGAN_MUTATED)) return 1 if((brute_dam || burn_dam) && (robotic < ORGAN_ROBOT)) //Robot limbs don't autoheal and thus don't need to process when damaged return 1 @@ -1006,21 +1012,10 @@ Note that amputating the affected organ does in fact remove the infection from t // This is mostly for the ninja suit to stop ninja being so crippled by breaks. // TODO: consider moving this to a suit proc or process() or something during // hardsuit rewrite. - if(owner && !(status & ORGAN_SPLINTED) && istype(owner,/mob/living/carbon/human)) - var/mob/living/carbon/human/H = owner - - if(H.wear_suit && istype(H.wear_suit,/obj/item/clothing/suit/space)) - - var/obj/item/clothing/suit/space/suit = H.wear_suit - - if(isnull(suit.supporting_limbs)) - return - - owner << "You feel \the [suit] constrict about your [name], supporting it." - status |= ORGAN_SPLINTED - suit.supporting_limbs |= src - return + if(!(splinted) && owner && istype(owner.wear_suit, /obj/item/clothing/suit/space)) + var/obj/item/clothing/suit/space/suit = owner.wear_suit + suit.handle_fracture(owner, src) /obj/item/organ/external/proc/mend_fracture() if(robotic >= ORGAN_ROBOT) @@ -1031,6 +1026,24 @@ Note that amputating the affected organ does in fact remove the infection from t status &= ~ORGAN_BROKEN return 1 +/obj/item/organ/external/proc/apply_splint(var/atom/movable/splint) + if(!splinted) + splinted = splint + if(!applied_pressure) + applied_pressure = splint + return 1 + return 0 + +/obj/item/organ/external/proc/remove_splint() + if(splinted) + if(splinted.loc == src) + splinted.dropInto(owner? owner.loc : src.loc) + if(applied_pressure == splinted) + applied_pressure = null + splinted = null + return 1 + return 0 + /obj/item/organ/external/robotize(var/company, var/skip_prosthetics = 0, var/keep_organs = 0) if(robotic >= ORGAN_ROBOT) @@ -1054,6 +1067,7 @@ Note that amputating the affected organ does in fact remove the infection from t dislocated = -1 cannot_break = 1 + remove_splint() get_icon() unmutate() @@ -1235,11 +1249,20 @@ Note that amputating the affected organ does in fact remove the infection from t for(var/datum/wound/W in wounds) if(W.internal && !open) continue // can't see internal wounds var/this_wound_desc = W.desc - if(W.damage_type == BURN && W.salved) this_wound_desc = "salved [this_wound_desc]" - if(W.bleeding()) this_wound_desc = "bleeding [this_wound_desc]" - else if(W.bandaged) this_wound_desc = "bandaged [this_wound_desc]" - if(W.germ_level > 600) this_wound_desc = "badly infected [this_wound_desc]" - else if(W.germ_level > 330) this_wound_desc = "lightly infected [this_wound_desc]" + + if(W.damage_type == BURN && W.salved) + this_wound_desc = "salved [this_wound_desc]" + + if(W.bleeding()) + this_wound_desc = "bleeding [this_wound_desc]" + else if(W.bandaged) + this_wound_desc = "bandaged [this_wound_desc]" + + if(W.germ_level > 600) + this_wound_desc = "badly infected [this_wound_desc]" + else if(W.germ_level > 330) + this_wound_desc = "lightly infected [this_wound_desc]" + if(wound_descriptors[this_wound_desc]) wound_descriptors[this_wound_desc] += W.amount else diff --git a/code/modules/paperwork/adminpaper.dm b/code/modules/paperwork/adminpaper.dm index 7843552f8c..230d8984e8 100644 --- a/code/modules/paperwork/adminpaper.dm +++ b/code/modules/paperwork/adminpaper.dm @@ -40,7 +40,7 @@ var/originhash = md5("[origin]") var/timehash = copytext(md5("[world.time]"),1,10) var/text = null - var/logo = alert(usr, "Do you want the header of your fax to have a Nanotrasen or SolGov logo?","Fax Logo","Nanotrasen","SolGov") + var/logo = alert(usr, "Do you want the header of your fax to have a NanoTrasen or SolGov logo?","Fax Logo","NanoTrasen","SolGov") if(logo == "SolGov") logo = "sglogo.png" else diff --git a/code/modules/paperwork/faxmachine.dm b/code/modules/paperwork/faxmachine.dm index cf1da677f0..f2c309ff03 100644 --- a/code/modules/paperwork/faxmachine.dm +++ b/code/modules/paperwork/faxmachine.dm @@ -181,11 +181,11 @@ var/list/adminfaxes = list() //cache for faxes that have been sent to admins //message badmins that a fax has arrived if (destination == boss_name) - message_admins(sender, "[uppertext(boss_short)] FAX", rcvdcopy, "CentcommFaxReply", "#006100") + message_admins(sender, "[uppertext(boss_short)] FAX", rcvdcopy, "CentComFaxReply", "#006100") else if ("Sif Governmental Authority") - message_admins(sender, "SIF GOVERNMENT FAX", rcvdcopy, "CentcommFaxReply", "#1F66A0") + message_admins(sender, "SIF GOVERNMENT FAX", rcvdcopy, "CentComFaxReply", "#1F66A0") else if ("Supply") - message_admins(sender, "[uppertext(boss_short)] SUPPLY FAX", rcvdcopy, "CentcommFaxReply", "#5F4519") + message_admins(sender, "[uppertext(boss_short)] SUPPLY FAX", rcvdcopy, "CentComFaxReply", "#5F4519") else message_admins(sender, "[uppertext(destination)] FAX", rcvdcopy, "UNKNOWN") diff --git a/code/modules/projectiles/effects.dm b/code/modules/projectiles/effects.dm index 2235f188e7..94e39f41cc 100644 --- a/code/modules/projectiles/effects.dm +++ b/code/modules/projectiles/effects.dm @@ -11,7 +11,8 @@ if(istype(M)) transform = M -/obj/effect/projectile/proc/activate(var/kill_delay = 3) +/obj/effect/projectile/proc/activate(var/kill_delay = 5) + update_light() spawn(kill_delay) qdel(src) //see effect_system.dm - sets loc to null and lets GC handle removing these effects @@ -22,117 +23,207 @@ //---------------------------- /obj/effect/projectile/laser/tracer icon_state = "beam" + light_range = 2 + light_power = 0.5 + light_color = "#FF0D00" /obj/effect/projectile/laser/muzzle icon_state = "muzzle_laser" + light_range = 2 + light_power = 0.5 + light_color = "#FF0D00" /obj/effect/projectile/laser/impact icon_state = "impact_laser" + light_range = 2 + light_power = 0.5 + light_color = "#FF0D00" //---------------------------- // Blue laser beam //---------------------------- /obj/effect/projectile/laser_blue/tracer icon_state = "beam_blue" + light_range = 2 + light_power = 0.5 + light_color = "#0066FF" /obj/effect/projectile/laser_blue/muzzle icon_state = "muzzle_blue" + light_range = 2 + light_power = 0.5 + light_color = "#0066FF" /obj/effect/projectile/laser_blue/impact icon_state = "impact_blue" + light_range = 2 + light_power = 0.5 + light_color = "#0066FF" //---------------------------- // Omni laser beam //---------------------------- /obj/effect/projectile/laser_omni/tracer icon_state = "beam_omni" + light_range = 2 + light_power = 0.5 + light_color = "#00C6FF" /obj/effect/projectile/laser_omni/muzzle icon_state = "muzzle_omni" + light_range = 2 + light_power = 0.5 + light_color = "#00C6FF" /obj/effect/projectile/laser_omni/impact icon_state = "impact_omni" + light_range = 2 + light_power = 0.5 + light_color = "#00C6FF" //---------------------------- // Xray laser beam //---------------------------- /obj/effect/projectile/xray/tracer icon_state = "xray" + light_range = 2 + light_power = 0.5 + light_color = "#00CC33" /obj/effect/projectile/xray/muzzle icon_state = "muzzle_xray" + light_range = 2 + light_power = 0.5 + light_color = "#00CC33" /obj/effect/projectile/xray/impact icon_state = "impact_xray" + light_range = 2 + light_power = 0.5 + light_color = "#00CC33" //---------------------------- // Heavy laser beam //---------------------------- /obj/effect/projectile/laser_heavy/tracer icon_state = "beam_heavy" + light_range = 3 + light_power = 1 + light_color = "#FF0D00" /obj/effect/projectile/laser_heavy/muzzle icon_state = "muzzle_beam_heavy" + light_range = 3 + light_power = 1 + light_color = "#FF0D00" /obj/effect/projectile/laser_heavy/impact icon_state = "impact_beam_heavy" + light_range = 3 + light_power = 1 + light_color = "#FF0D00" //---------------------------- // Pulse laser beam //---------------------------- /obj/effect/projectile/laser_pulse/tracer icon_state = "u_laser" + light_range = 2 + light_power = 0.5 + light_color = "#0066FF" /obj/effect/projectile/laser_pulse/muzzle icon_state = "muzzle_u_laser" + light_range = 2 + light_power = 0.5 + light_color = "#0066FF" /obj/effect/projectile/laser_pulse/impact icon_state = "impact_u_laser" + light_range = 2 + light_power = 0.5 + light_color = "#0066FF" //---------------------------- // Pulse muzzle effect only //---------------------------- /obj/effect/projectile/pulse/muzzle icon_state = "muzzle_pulse" + light_range = 2 + light_power = 0.5 + light_color = "#0066FF" //---------------------------- // Emitter beam //---------------------------- /obj/effect/projectile/emitter/tracer icon_state = "emitter" + icon_state = "impact_xray" + light_range = 2 + light_power = 0.5 + light_color = "#00CC33" /obj/effect/projectile/emitter/muzzle icon_state = "muzzle_emitter" + icon_state = "impact_xray" + light_range = 2 + light_power = 0.5 + light_color = "#00CC33" /obj/effect/projectile/emitter/impact icon_state = "impact_emitter" + icon_state = "impact_xray" + light_range = 2 + light_power = 0.5 + light_color = "#00CC33" //---------------------------- // Stun beam //---------------------------- /obj/effect/projectile/stun/tracer icon_state = "stun" + light_range = 2 + light_power = 0.5 + light_color = "#FFFFFF" /obj/effect/projectile/stun/muzzle icon_state = "muzzle_stun" + light_range = 2 + light_power = 0.5 + light_color = "#FFFFFF" /obj/effect/projectile/stun/impact icon_state = "impact_stun" + light_range = 2 + light_power = 0.5 + light_color = "#FFFFFF" //---------------------------- // Bullet //---------------------------- /obj/effect/projectile/bullet/muzzle icon_state = "muzzle_bullet" + light_range = 2 + light_power = 0.5 + light_color = "#FFFFFF" //---------------------------- // Lightning beam //---------------------------- /obj/effect/projectile/lightning/tracer icon_state = "lightning" + light_range = 2 + light_power = 0.5 + light_color = "#00C6FF" /obj/effect/projectile/lightning/muzzle icon_state = "muzzle_lightning" + light_range = 2 + light_power = 0.5 + light_color = "#00C6FF" /obj/effect/projectile/lightning/impact - icon_state = "impact_lightning" \ No newline at end of file + icon_state = "impact_lightning" + light_range = 2 + light_power = 0.5 + light_color = "#00C6FF" \ No newline at end of file diff --git a/code/modules/projectiles/gun.dm b/code/modules/projectiles/gun.dm index 9271e50503..01dfce8e8c 100644 --- a/code/modules/projectiles/gun.dm +++ b/code/modules/projectiles/gun.dm @@ -290,6 +290,76 @@ if(muzzle_flash) set_light(0) +// Similar to the above proc, but does not require a user, which is ideal for things like turrets. +/obj/item/weapon/gun/proc/Fire_userless(atom/target) + if(!target) + return + + if(world.time < next_fire_time) + return + + var/shoot_time = (burst - 1)* burst_delay + next_fire_time = world.time + shoot_time + + var/turf/targloc = get_turf(target) //cache this in case target gets deleted during shooting, e.g. if it was a securitron that got destroyed. + for(var/i in 1 to burst) + var/obj/projectile = consume_next_projectile() + if(!projectile) + handle_click_empty() + break + + if(istype(projectile, /obj/item/projectile)) + var/obj/item/projectile/P = projectile + + var/acc = burst_accuracy[min(i, burst_accuracy.len)] + var/disp = dispersion[min(i, dispersion.len)] + + P.accuracy = accuracy + acc + P.dispersion = disp + + P.shot_from = src.name + P.silenced = silenced + + P.launch(target) + + if(silenced) + playsound(src, fire_sound, 10, 1) + else + playsound(src, fire_sound, 50, 1) + + if(muzzle_flash) + set_light(muzzle_flash) + update_icon() + + //process_accuracy(projectile, user, target, acc, disp) + + // if(pointblank) + // process_point_blank(projectile, user, target) + + // if(process_projectile(projectile, null, target, user.zone_sel.selecting, clickparams)) + // handle_post_fire(null, target, pointblank, reflex) + + // update_icon() + + if(i < burst) + sleep(burst_delay) + + if(!(target && target.loc)) + target = targloc + //pointblank = 0 + + log_and_message_admins("Fired [src].") + + //admin_attack_log(usr, attacker_message="Fired [src]", admin_message="fired a gun ([src]) (MODE: [src.mode_name]) [reflex ? "by reflex" : "manually"].") + + //update timing + next_fire_time = world.time + fire_delay + + if(muzzle_flash) + set_light(0) + + + //obtains the next projectile to fire /obj/item/weapon/gun/proc/consume_next_projectile() return null diff --git a/code/modules/projectiles/guns/energy/laser.dm b/code/modules/projectiles/guns/energy/laser.dm index 5d2fe06fa4..cef84810bd 100644 --- a/code/modules/projectiles/guns/energy/laser.dm +++ b/code/modules/projectiles/guns/energy/laser.dm @@ -6,7 +6,7 @@ item_state = "laser" fire_sound = 'sound/weapons/Laser.ogg' slot_flags = SLOT_BELT|SLOT_BACK - w_class = 3 + w_class = 4 force = 10 origin_tech = list(TECH_COMBAT = 3, TECH_MAGNET = 2) matter = list(DEFAULT_WALL_MATERIAL = 2000) @@ -69,8 +69,9 @@ obj/item/weapon/gun/energy/retro origin_tech = list(TECH_COMBAT = 4, TECH_MATERIAL = 3, TECH_POWER = 3) slot_flags = SLOT_BELT|SLOT_BACK projectile_type = /obj/item/projectile/beam/heavylaser/cannon - max_shots = 1 - fire_delay = 30 + max_shots = 4 + fire_delay = 20 + w_class = 4 // requires_two_hands = 1 one_handed_penalty = 6 // The thing's heavy and huge. accuracy = 3 diff --git a/code/modules/projectiles/guns/energy/nuclear.dm b/code/modules/projectiles/guns/energy/nuclear.dm index 2352cdce28..6819c1cd81 100644 --- a/code/modules/projectiles/guns/energy/nuclear.dm +++ b/code/modules/projectiles/guns/energy/nuclear.dm @@ -24,11 +24,14 @@ /obj/item/weapon/gun/energy/gun/burst name = "burst laser" - desc = "The FM-2t is a versatile energy based small arm, capable of switching between stun or kill with a three round burst option for both settings." - icon_state = "fm-2tstun100" + desc = "The FM-2t is a versatile energy based weapon, capable of switching between stun or kill with a three round burst option for both settings." + icon_state = "fm-2tstun100" //May resprite this to be more rifley item_state = null //so the human update icon uses the icon_state instead. fire_sound = 'sound/weapons/Taser.ogg' - max_shots = 21 //7 trigger pulls + max_shots = 18 + force = 8 + w_class = 4 //Probably gonna make it a rifle sooner or later + fire_delay = 6 projectile_type = /obj/item/projectile/beam/stun/weak origin_tech = list(TECH_COMBAT = 4, TECH_MAGNET = 2, TECH_ILLEGAL = 3) @@ -39,9 +42,9 @@ firemodes = list( list(mode_name="stun", burst=1, projectile_type=/obj/item/projectile/beam/stun/weak, modifystate="fm-2tstun", fire_sound='sound/weapons/Taser.ogg'), - list(mode_name="stun burst", burst=3, fire_delay=null, move_delay=4, burst_accuracy=list(0,-1,-1), dispersion=list(0.0, 0.6, 1.0), projectile_type=/obj/item/projectile/beam/stun/weak, modifystate="fm-2tstun", fire_sound='sound/weapons/Taser.ogg'), - list(mode_name="lethal", burst=1, projectile_type=/obj/item/projectile/beam/weaklaser, modifystate="fm-2tkill", fire_sound='sound/weapons/Laser.ogg'), - list(mode_name="lethal burst", burst=3, fire_delay=null, move_delay=4, burst_accuracy=list(0,-1,-1), dispersion=list(0.0, 0.6, 1.0), projectile_type=/obj/item/projectile/beam/weaklaser, modifystate="fm-2tkill", fire_sound='sound/weapons/Laser.ogg'), + list(mode_name="stun burst", burst=3, fire_delay=null, move_delay=4, burst_accuracy=list(0,0,0), dispersion=list(0.0, 0.2, 0.5), projectile_type=/obj/item/projectile/beam/stun/weak, modifystate="fm-2tstun", fire_sound='sound/weapons/Taser.ogg'), + list(mode_name="lethal", burst=1, projectile_type=/obj/item/projectile/beam/burstlaser, modifystate="fm-2tkill", fire_sound='sound/weapons/Laser.ogg'), + list(mode_name="lethal burst", burst=3, fire_delay=null, move_delay=4, burst_accuracy=list(0,0,0), dispersion=list(0.0, 0.2, 0.5), projectile_type=/obj/item/projectile/beam/burstlaser, modifystate="fm-2tkill", fire_sound='sound/weapons/Laser.ogg'), ) /obj/item/weapon/gun/energy/gun/nuclear @@ -51,6 +54,8 @@ origin_tech = list(TECH_COMBAT = 3, TECH_MATERIAL = 5, TECH_POWER = 3) slot_flags = SLOT_BELT force = 8 //looks heavier than a pistol + w_class = 4 //Looks bigger than a pistol, too. + fire_delay = 6 //This one's not a handgun, it should have the same fire delay as everything else self_recharge = 1 modifystate = null diff --git a/code/modules/projectiles/guns/projectile.dm b/code/modules/projectiles/guns/projectile.dm index d1fc9ee4a8..93904387cd 100644 --- a/code/modules/projectiles/guns/projectile.dm +++ b/code/modules/projectiles/guns/projectile.dm @@ -141,6 +141,24 @@ user.visible_message("[user] inserts \a [C] into [src].", "You insert \a [C] into [src].") playsound(src.loc, 'sound/weapons/empty.ogg', 50, 1) + else if(istype(A, /obj/item/weapon/storage)) + var/obj/item/weapon/storage/storage = A + if(!(load_method & SINGLE_CASING)) + return //incompatible + + user << "You start loading \the [src]." + sleep(1 SECOND) + for(var/obj/item/ammo_casing/ammo in storage.contents) + if(caliber != ammo.caliber) + continue + + load_ammo(ammo, user) + + if(loaded.len >= max_shells) + user << "[src] is full." + break + sleep(1 SECOND) + update_icon() //attempts to unload src. If allow_dump is set to 0, the speedloader unloading method will be disabled diff --git a/code/modules/projectiles/projectile.dm b/code/modules/projectiles/projectile.dm index ee46b5f42e..81149cf2cb 100644 --- a/code/modules/projectiles/projectile.dm +++ b/code/modules/projectiles/projectile.dm @@ -293,6 +293,7 @@ trajectory.increment() // increment the current location location = trajectory.return_location(location) // update the locally stored location data + update_light() //energy projectiles will look glowy and fun if(!location) qdel(src) // if it's left the world... kill it @@ -354,6 +355,7 @@ M.set_transform(T) M.pixel_x = location.pixel_x M.pixel_y = location.pixel_y + M.update_light() M.activate() /obj/item/projectile/proc/tracer_effect(var/matrix/M) @@ -364,6 +366,7 @@ P.set_transform(M) P.pixel_x = location.pixel_x P.pixel_y = location.pixel_y + P.update_light() if(!hitscan) P.activate(step_delay) //if not a hitscan projectile, remove after a single delay else @@ -377,6 +380,7 @@ P.set_transform(M) P.pixel_x = location.pixel_x P.pixel_y = location.pixel_y + P.update_light() P.activate() //"Tracing" projectile diff --git a/code/modules/projectiles/projectile/animate.dm b/code/modules/projectiles/projectile/animate.dm index 0f92729ad4..c09b98a32b 100644 --- a/code/modules/projectiles/projectile/animate.dm +++ b/code/modules/projectiles/projectile/animate.dm @@ -5,6 +5,9 @@ damage_type = BURN nodamage = 1 check_armour = "energy" + light_range = 2 + light_power = 0.5 + light_color = "#55AAFF" /obj/item/projectile/animate/Bump(var/atom/change) if((istype(change, /obj/item) || istype(change, /obj/structure)) && !is_type_in_list(change, protected_objects)) diff --git a/code/modules/projectiles/projectile/beams.dm b/code/modules/projectiles/projectile/beams.dm index 1049f5f70d..1f0dd03854 100644 --- a/code/modules/projectiles/projectile/beams.dm +++ b/code/modules/projectiles/projectile/beams.dm @@ -9,6 +9,9 @@ var/frequency = 1 hitscan = 1 invisibility = 101 //beam projectiles are invisible as they are rendered by the effect engine + light_range = 2 + light_power = 0.5 + light_color = "#FF0D00" muzzle_type = /obj/effect/projectile/laser/muzzle tracer_type = /obj/effect/projectile/laser/tracer @@ -28,6 +31,11 @@ icon_state = "laser" damage = 15 +/obj/item/projectile/beam/burstlaser + damage = 30 + armor_penetration = 10 + + /obj/item/projectile/beam/midlaser damage = 40 armor_penetration = 10 @@ -37,20 +45,25 @@ icon_state = "heavylaser" damage = 60 armor_penetration = 30 + light_range = 3 + light_power = 1 + light_color = "#FF0D00" muzzle_type = /obj/effect/projectile/laser_heavy/muzzle tracer_type = /obj/effect/projectile/laser_heavy/tracer impact_type = /obj/effect/projectile/laser_heavy/impact /obj/item/projectile/beam/heavylaser/cannon - damage = 90 - armor_penetration = 100 + damage = 80 + armor_penetration = 50 + light_color = "#FF0D00" /obj/item/projectile/beam/xray name = "xray beam" icon_state = "xray" damage = 25 armor_penetration = 50 + light_color = "#00CC33" muzzle_type = /obj/effect/projectile/xray/muzzle tracer_type = /obj/effect/projectile/xray/tracer @@ -61,6 +74,7 @@ icon_state = "u_laser" damage = 50 armor_penetration = 30 + light_color = "#0066FF" muzzle_type = /obj/effect/projectile/laser_pulse/muzzle tracer_type = /obj/effect/projectile/laser_pulse/tracer @@ -75,6 +89,7 @@ name = "emitter beam" icon_state = "emitter" damage = 0 // The actual damage is computed in /code/modules/power/singularity/emitter.dm + light_color = "#00CC33" muzzle_type = /obj/effect/projectile/emitter/muzzle tracer_type = /obj/effect/projectile/emitter/tracer @@ -88,6 +103,7 @@ no_attack_log = 1 damage_type = BURN check_armour = "laser" + light_color = "#0066FF" muzzle_type = /obj/effect/projectile/laser_blue/muzzle tracer_type = /obj/effect/projectile/laser_blue/tracer @@ -108,6 +124,7 @@ no_attack_log = 1 damage_type = BURN check_armour = "laser" + light_color = "#FF0D00" /obj/item/projectile/beam/lastertag/red/on_hit(var/atom/target, var/blocked = 0) if(istype(target, /mob/living/carbon/human)) @@ -123,6 +140,7 @@ damage = 0 damage_type = BURN check_armour = "laser" + light_color = "#00C6FF" muzzle_type = /obj/effect/projectile/laser_omni/muzzle tracer_type = /obj/effect/projectile/laser_omni/tracer @@ -140,6 +158,7 @@ icon_state = "xray" damage = 50 armor_penetration = 10 + light_color = "#00CC33" muzzle_type = /obj/effect/projectile/xray/muzzle tracer_type = /obj/effect/projectile/xray/tracer @@ -152,6 +171,7 @@ taser_effect = 1 agony = 40 damage_type = HALLOSS + light_color = "#FFFFFF" muzzle_type = /obj/effect/projectile/stun/muzzle tracer_type = /obj/effect/projectile/stun/tracer diff --git a/code/modules/projectiles/projectile/energy.dm b/code/modules/projectiles/projectile/energy.dm index 9a9fa74292..3eb848c733 100644 --- a/code/modules/projectiles/projectile/energy.dm +++ b/code/modules/projectiles/projectile/energy.dm @@ -25,14 +25,14 @@ for (var/mob/living/carbon/M in viewers(T, flash_range)) if(M.eyecheck() < 1) M.flash_eyes() - if(ishuman(M)) - var/mob/living/carbon/human/H = M - flash_strength *= H.species.flash_mod + if(ishuman(M)) + var/mob/living/carbon/human/H = M + flash_strength *= H.species.flash_mod - if(flash_strength > 0) - H.confused = max(H.confused, flash_strength + 5) - H.eye_blind = max(H.eye_blind, flash_strength) - H.eye_blurry = max(H.eye_blurry, flash_strength + 5) + if(flash_strength > 0) + H.confused = max(H.confused, flash_strength + 5) + H.eye_blind = max(H.eye_blind, flash_strength) + H.eye_blurry = max(H.eye_blurry, flash_strength + 5) //snap pop @@ -68,6 +68,9 @@ taser_effect = 1 agony = 40 damage_type = HALLOSS + light_range = 2 + light_power = 0.5 + light_color = "#FFFFFF" //Damage will be handled on the MOB side, to prevent window shattering. /obj/item/projectile/energy/electrode/strong @@ -85,6 +88,9 @@ nodamage = 1 damage_type = CLONE irradiate = 40 + light_range = 2 + light_power = 0.5 + light_color = "#33CC00" /obj/item/projectile/energy/dart @@ -124,3 +130,6 @@ damage = 20 damage_type = TOX irradiate = 20 + light_range = 2 + light_power = 0.5 + light_color = "#33CC00" diff --git a/code/modules/projectiles/projectile/special.dm b/code/modules/projectiles/projectile/special.dm index 788886af30..b567512a05 100644 --- a/code/modules/projectiles/projectile/special.dm +++ b/code/modules/projectiles/projectile/special.dm @@ -5,6 +5,9 @@ damage_type = BURN nodamage = 1 check_armour = "energy" + light_range = 2 + light_power = 0.5 + light_color = "#55AAFF" on_hit(var/atom/target, var/blocked = 0) @@ -32,6 +35,9 @@ nodamage = 1 check_armour = "energy" var/temperature = 300 + light_range = 2 + light_power = 0.5 + light_color = "#55AAFF" on_hit(var/atom/target, var/blocked = 0)//These two could likely check temp protection on the mob @@ -77,6 +83,9 @@ damage_type = TOX nodamage = 1 check_armour = "energy" + light_range = 2 + light_power = 0.5 + light_color = "#33CC00" on_hit(var/atom/target, var/blocked = 0) var/mob/living/M = target @@ -116,6 +125,9 @@ damage_type = TOX nodamage = 1 check_armour = "energy" + light_range = 2 + light_power = 0.5 + light_color = "#FFFFFF" on_hit(var/atom/target, var/blocked = 0) var/mob/M = target @@ -136,6 +148,7 @@ if(ishuman(target)) var/mob/living/carbon/human/M = target M.confused += rand(5,8) + /obj/item/projectile/chameleon name = "bullet" icon_state = "bullet" diff --git a/code/modules/reagents/Chemistry-Reagents/Chemistry-Reagents-Core.dm b/code/modules/reagents/Chemistry-Reagents/Chemistry-Reagents-Core.dm index f051e8307f..fcabfa811c 100644 --- a/code/modules/reagents/Chemistry-Reagents/Chemistry-Reagents-Core.dm +++ b/code/modules/reagents/Chemistry-Reagents/Chemistry-Reagents-Core.dm @@ -125,10 +125,10 @@ /datum/reagent/water/touch_mob(var/mob/living/L, var/amount) if(istype(L)) - var/needed = L.fire_stacks * 10 + var/needed = L.fire_stacks * 5 if(amount > needed) L.ExtinguishMob() - L.adjust_fire_stacks(-(amount / 10)) + L.adjust_fire_stacks(-(amount / 5)) remove_self(needed) /datum/reagent/water/affect_touch(var/mob/living/carbon/M, var/alien, var/removed) diff --git a/code/modules/research/designs.dm b/code/modules/research/designs.dm index c0ecdbfc3d..78715938c3 100644 --- a/code/modules/research/designs.dm +++ b/code/modules/research/designs.dm @@ -1486,6 +1486,427 @@ CIRCUITS BELOW build_path = /obj/item/weapon/cartridge/captain sort_string = "VBAAO" + + +/datum/design/item/wirer + name = "Custom wirer tool" + id = "wirer" + req_tech = list(TECH_MATERIAL = 2, TECH_ENGINEERING = 2) + materials = list(DEFAULT_WALL_MATERIAL = 5000, "glass" = 2500) + build_path = /obj/item/device/integrated_electronics/wirer + sort_string = "VBVAA" + +/datum/design/item/debugger + name = "Custom circuit debugger tool" + id = "debugger" + req_tech = list(TECH_MATERIAL = 2, TECH_ENGINEERING = 2) + materials = list(DEFAULT_WALL_MATERIAL = 5000, "glass" = 2500) + build_path = /obj/item/device/integrated_electronics/debugger + sort_string = "VBVAB" + + + +/datum/design/item/custom_circuit_assembly + name = "Small custom assembly" + desc = "An customizable assembly for simple, small devices." + id = "assembly-small" + req_tech = list(TECH_MATERIAL = 3, TECH_ENGINEERING = 2, TECH_POWER = 2) + materials = list(DEFAULT_WALL_MATERIAL = 10000) + build_path = /obj/item/device/electronic_assembly + sort_string = "VCAAA" + +/datum/design/item/custom_circuit_assembly/medium + name = "Medium custom assembly" + desc = "An customizable assembly suited for more ambitious mechanisms." + id = "assembly-medium" + req_tech = list(TECH_MATERIAL = 4, TECH_ENGINEERING = 3, TECH_POWER = 3) + materials = list(DEFAULT_WALL_MATERIAL = 20000) + build_path = /obj/item/device/electronic_assembly/medium + +/datum/design/item/custom_circuit_assembly/large + name = "Large custom assembly" + desc = "An customizable assembly for large machines." + id = "assembly-large" + req_tech = list(TECH_MATERIAL = 5, TECH_ENGINEERING = 4, TECH_POWER = 4) + materials = list(DEFAULT_WALL_MATERIAL = 40000) + build_path = /obj/item/device/electronic_assembly/large + +/datum/design/circuit/integrated_circuit + req_tech = list(TECH_ENGINEERING = 2, TECH_DATA = 2) + +/datum/design/circuit/integrated_circuit/AssembleDesignName() + ..() + name = "Custom circuitry ([item_name])" + +/datum/design/circuit/integrated_circuit/AssembleDesignDesc() + if(!desc) + desc = "Allows for the construction of \a [name] custom circuit." + +/datum/design/circuit/integrated_circuit/arithmetic/AssembleDesignName() + ..() + name = "Custom circuitry \[Arithmetic\] ([item_name])" + +/datum/design/circuit/integrated_circuit/arithmetic/addition + id = "cc-addition" + build_path = /obj/item/integrated_circuit/arithmetic/addition + sort_string = "WAAAA" + +/datum/design/circuit/integrated_circuit/arithmetic/subtraction + id = "cc-subtraction" + build_path = /obj/item/integrated_circuit/arithmetic/subtraction + sort_string = "WAAAB" + +/datum/design/circuit/integrated_circuit/arithmetic/multiplication + id = "cc-multiplication" + build_path = /obj/item/integrated_circuit/arithmetic/multiplication + sort_string = "WAAAC" + +/datum/design/circuit/integrated_circuit/arithmetic/division + id = "cc-division" + build_path = /obj/item/integrated_circuit/arithmetic/division + sort_string = "WAAAD" + +/datum/design/circuit/integrated_circuit/arithmetic/absolute + id = "cc-absolute" + build_path = /obj/item/integrated_circuit/arithmetic/absolute + sort_string = "WAAAE" + +/datum/design/circuit/integrated_circuit/arithmetic/average + id = "cc-average" + build_path = /obj/item/integrated_circuit/arithmetic/average + sort_string = "WAAAF" + +/datum/design/circuit/integrated_circuit/arithmetic/pi + id = "cc-pi" + build_path = /obj/item/integrated_circuit/arithmetic/pi + sort_string = "WAAAG" + +/datum/design/circuit/integrated_circuit/arithmetic/random + id = "cc-random" + build_path = /obj/item/integrated_circuit/arithmetic/random + sort_string = "WAAAH" + + + +/datum/design/circuit/integrated_circuit/converter/AssembleDesignName() + ..() + name = "Custom circuitry \[Conversion\] ([item_name])" + +/datum/design/circuit/integrated_circuit/converter/num2text + id = "cc-num2text" + build_path = /obj/item/integrated_circuit/converter/num2text + sort_string = "WAABA" + +/datum/design/circuit/integrated_circuit/converter/text2num + id = "cc-text2num" + build_path = /obj/item/integrated_circuit/converter/text2num + sort_string = "WAABB" + +/datum/design/circuit/integrated_circuit/converter/ref2text + id = "cc-ref2text" + build_path = /obj/item/integrated_circuit/converter/ref2text + sort_string = "WAABC" + +/datum/design/circuit/integrated_circuit/converter/lowercase + id = "cc-lowercase" + build_path = /obj/item/integrated_circuit/converter/lowercase + sort_string = "WAABD" + +/datum/design/circuit/integrated_circuit/converter/uppercase + id = "cc-uppercase" + build_path = /obj/item/integrated_circuit/converter/uppercase + sort_string = "WAABD" + +/datum/design/circuit/integrated_circuit/converter/concatenatior + id = "cc-concatenatior" + build_path = /obj/item/integrated_circuit/converter/concatenatior + sort_string = "WAABC" + + + +/datum/design/circuit/integrated_circuit/coordinate/AssembleDesignName() + ..() + name = "Custom circuitry \[Coordinate\] ([item_name])" + +/datum/design/circuit/integrated_circuit/coordinate/gps + id = "cc-gps" + build_path = /obj/item/integrated_circuit/gps + sort_string = "WAACA" + +/datum/design/circuit/integrated_circuit/coordinate/abs_to_rel_coords + id = "cc-abs_to_rel_coords" + build_path = /obj/item/integrated_circuit/abs_to_rel_coords + sort_string = "WAACB" + + + +/datum/design/circuit/integrated_circuit/transfer/AssembleDesignName() + ..() + name = "Custom circuitry \[Transfer\] ([item_name])" + +/datum/design/circuit/integrated_circuit/transfer/splitter + id = "cc-splitter" + build_path = /obj/item/integrated_circuit/transfer/splitter + sort_string = "WAADA" + +/datum/design/circuit/integrated_circuit/transfer/splitter4 + id = "cc-splitter4" + build_path = /obj/item/integrated_circuit/transfer/splitter/medium + sort_string = "WAADB" + +/datum/design/circuit/integrated_circuit/transfer/splitter8 + id = "cc-splitter8" + build_path = /obj/item/integrated_circuit/transfer/splitter/large + sort_string = "WAADC" + +/datum/design/circuit/integrated_circuit/transfer/activator_splitter + id = "cc-activator_splitter" + build_path = /obj/item/integrated_circuit/transfer/activator_splitter + sort_string = "WAADD" + +/datum/design/circuit/integrated_circuit/transfer/activator_splitter4 + id = "cc-activator_splitter4" + build_path = /obj/item/integrated_circuit/transfer/activator_splitter/medium + sort_string = "WAADE" + +/datum/design/circuit/integrated_circuit/transfer/activator_splitter8 + id = "cc-activator_splitter8" + build_path = /obj/item/integrated_circuit/transfer/activator_splitter/large + sort_string = "WAADF" + + + +/datum/design/circuit/integrated_circuit/input_output/AssembleDesignName() + ..() + name = "Custom circuitry \[Input/Output\] ([item_name])" + +/datum/design/circuit/integrated_circuit/input_output/button + id = "cc-button" + build_path = /obj/item/integrated_circuit/input/button + sort_string = "WAAEA" + +/datum/design/circuit/integrated_circuit/input_output/numberpad + id = "cc-numberpad" + build_path = /obj/item/integrated_circuit/input/numberpad + sort_string = "WAAEB" + +/datum/design/circuit/integrated_circuit/input_output/textpad + id = "cc-textpad" + build_path = /obj/item/integrated_circuit/input/textpad + sort_string = "WAAEC" + +/datum/design/circuit/integrated_circuit/input_output/screen + id = "cc-screen" + build_path = /obj/item/integrated_circuit/output/screen + sort_string = "WAAED" + +/datum/design/circuit/integrated_circuit/input_output/med_scanner + id = "cc-medscanner" + build_path = /obj/item/integrated_circuit/input/med_scanner + req_tech = list(TECH_MATERIAL = 2, TECH_MAGNETS = 2, TECH_BIOMED = 2) + sort_string = "WAAEE" + +/datum/design/circuit/integrated_circuit/input_output/adv_med_scanner + id = "cc-advmedscanner" + build_path = /obj/item/integrated_circuit/input/adv_med_scanner + req_tech = list(TECH_MATERIAL = 2, TECH_MAGNETS = 3, TECH_BIOMED = 4) + sort_string = "WAAEF" + +/datum/design/circuit/integrated_circuit/input_output/local_locator + id = "cc-locallocator" + build_path = /obj/item/integrated_circuit/input/local_locator + sort_string = "WAAEG" + +/datum/design/circuit/integrated_circuit/input_output/signaler + id = "cc-signaler" + build_path = /obj/item/integrated_circuit/input/signaler + sort_string = "WAAEJ" + +/datum/design/circuit/integrated_circuit/input_output/light + id = "cc-light" + build_path = /obj/item/integrated_circuit/output/light + sort_string = "WAAEH" + +/datum/design/circuit/integrated_circuit/input_output/adv_light + id = "cc-adv_light" + build_path = /obj/item/integrated_circuit/output/light/advanced + sort_string = "WAAEI" + +/datum/design/circuit/integrated_circuit/input_output/beeper + id = "cc-sound_beeper" + build_path = /obj/item/integrated_circuit/output/sound/beeper + sort_string = "WAAEJ" + +/datum/design/circuit/integrated_circuit/input_output/beepsky_sound + id = "cc-sound_beepsky" + build_path = /obj/item/integrated_circuit/output/sound/beepsky + sort_string = "WAAEK" + req_tech = list(TECH_ENGINEERING = 2, TECH_DATA = 2, TECH_ILLEGAL = 1) + +/datum/design/circuit/integrated_circuit/input_output/EPv2 + id = "cc-epv2" + build_path = /obj/item/integrated_circuit/input/EPv2 + sort_string = "WAAEL" + req_tech = list(TECH_ENGINEERING = 2, TECH_DATA = 2, TECH_MAGNETS = 2, TECH_BLUESPACE = 2) + + +/datum/design/circuit/integrated_circuit/logic/AssembleDesignName() + ..() + name = "Custom circuitry \[Logic\] ([item_name])" + +/datum/design/circuit/integrated_circuit/logic/equals + id = "cc-equals" + build_path = /obj/item/integrated_circuit/logic/equals + sort_string = "WAAFA" + +/datum/design/circuit/integrated_circuit/logic/not + id = "cc-not" + build_path = /obj/item/integrated_circuit/logic/not + sort_string = "WAAFB" + +/datum/design/circuit/integrated_circuit/logic/and + id = "cc-and" + build_path = /obj/item/integrated_circuit/logic/and + sort_string = "WAAFC" + +/datum/design/circuit/integrated_circuit/logic/or + id = "cc-or" + build_path = /obj/item/integrated_circuit/logic/or + sort_string = "WAAFD" + +/datum/design/circuit/integrated_circuit/logic/less_than + id = "cc-less_than" + build_path = /obj/item/integrated_circuit/logic/less_than + sort_string = "WAAFE" + +/datum/design/circuit/integrated_circuit/logic/less_than_or_equal + id = "cc-less_than_or_equal" + build_path = /obj/item/integrated_circuit/logic/less_than_or_equal + sort_string = "WAAFF" + +/datum/design/circuit/integrated_circuit/logic/greater_than + id = "cc-greater_than" + build_path = /obj/item/integrated_circuit/logic/greater_than + sort_string = "WAAFG" + +/datum/design/circuit/integrated_circuit/logic/greater_than_or_equal + id = "cc-greater_than_or_equal" + build_path = /obj/item/integrated_circuit/logic/greater_than_or_equal + sort_string = "WAAFH" + + + +/datum/design/circuit/integrated_circuit/manipulation/AssembleDesignName() + ..() + name = "Custom circuitry \[Manipulation\] ([item_name])" + +/datum/design/circuit/integrated_circuit/manipulation/weapon_firing + name = "weapon firing mechanism" + id = "cc-weapon_firing" + build_path = /obj/item/integrated_circuit/manipulation/weapon_firing + sort_string = "WAAGA" + req_tech = list(TECH_ENGINEERING = 3, TECH_DATA = 3, TECH_COMBAT = 4) + +/datum/design/circuit/integrated_circuit/manipulation/smoke + name = "smoke generator" + id = "cc-smoke" + build_path = /obj/item/integrated_circuit/manipulation/smoke + sort_string = "WAAGB" + req_tech = list(TECH_ENGINEERING = 3, TECH_DATA = 3, TECH_BIO = 4) + +/datum/design/circuit/integrated_circuit/manipulation/locomotion + name = "locomotion" + id = "cc-locomotion" + build_path = /obj/item/integrated_circuit/manipulation/locomotion + sort_string = "WAAGB" + req_tech = list(TECH_ENGINEERING = 3, TECH_DATA = 3) + + + +/datum/design/circuit/integrated_circuit/memory/AssembleDesignName() + ..() + name = "Custom circuitry \[Memory\] ([item_name])" + +/datum/design/circuit/integrated_circuit/memory + id = "cc-memory" + build_path = /obj/item/integrated_circuit/memory + sort_string = "WAAHA" + +/datum/design/circuit/integrated_circuit/memory/medium + id = "cc-memory4" + build_path = /obj/item/integrated_circuit/memory/medium + sort_string = "WAAHB" + +/datum/design/circuit/integrated_circuit/memory/large + id = "cc-memory8" + build_path = /obj/item/integrated_circuit/memory/large + sort_string = "WAAHC" + +/datum/design/circuit/integrated_circuit/memory/huge + id = "cc-memory16" + build_path = /obj/item/integrated_circuit/memory/huge + sort_string = "WAAHD" + +/datum/design/circuit/integrated_circuit/memory/constant + id = "cc-constant" + build_path = /obj/item/integrated_circuit/memory/constant + sort_string = "WAAHH" + +/datum/design/circuit/integrated_circuit/time/AssembleDesignName() + ..() + name = "Custom circuitry \[Time\] ([item_name])" + +/datum/design/circuit/integrated_circuit/time/delay + id = "cc-delay" + build_path = /obj/item/integrated_circuit/time/delay + sort_string = "WAAIA" + +/datum/design/circuit/integrated_circuit/time/delay/five_sec + id = "cc-five_sec_delay" + build_path = /obj/item/integrated_circuit/time/delay/five_sec + sort_string = "WAAIB" + +/datum/design/circuit/integrated_circuit/time/delay/one_sec + id = "cc-one_sec_delay" + build_path = /obj/item/integrated_circuit/time/delay/one_sec + sort_string = "WAAIC" + +/datum/design/circuit/integrated_circuit/time/delay/half_sec + id = "cc-half_sec_delay" + build_path = /obj/item/integrated_circuit/time/delay/half_sec + sort_string = "WAAID" + +/datum/design/circuit/integrated_circuit/time/delay/tenth_sec + id = "cc-tenth_sec_delay" + build_path = /obj/item/integrated_circuit/time/delay/tenth_sec + sort_string = "WAAIF" + +/datum/design/circuit/integrated_circuit/time/delay/custom + id = "cc-custom_delay" + build_path = /obj/item/integrated_circuit/time/delay/custom + sort_string = "WAAIG" + +/datum/design/circuit/integrated_circuit/time/ticker + id = "cc-ticker" + build_path = /obj/item/integrated_circuit/time/ticker + sort_string = "WAAIH" + +/datum/design/circuit/integrated_circuit/time/ticker/slow + id = "cc-ticker_slow" + build_path = /obj/item/integrated_circuit/time/ticker/slow + sort_string = "WAAII" + +/datum/design/circuit/integrated_circuit/time/ticker/fast + id = "cc-ticker_fast" + build_path = /obj/item/integrated_circuit/time/ticker/fast + sort_string = "WAAIJ" + req_tech = list(TECH_ENGINEERING = 4, TECH_DATA = 4) + +/datum/design/circuit/integrated_circuit/time/clock + id = "cc-clock" + build_path = /obj/item/integrated_circuit/time/clock + sort_string = "WAAIK" + /* Uncomment if someone makes these buildable /datum/design/circuit/general_alert name = "general alert console" diff --git a/code/modules/scripting/Implementations/Telecomms.dm b/code/modules/scripting/Implementations/Telecomms.dm index 87c6fa5ea3..1277d2b594 100644 --- a/code/modules/scripting/Implementations/Telecomms.dm +++ b/code/modules/scripting/Implementations/Telecomms.dm @@ -2,7 +2,7 @@ /* --- Traffic Control Scripting Language --- */ - // Nanotrasen TCS Language - Made by Doohl + // NanoTrasen TCS Language - Made by Doohl /n_Interpreter/TCS_Interpreter var/datum/TCS_Compiler/Compiler diff --git a/code/modules/shuttles/shuttle_ferry.dm b/code/modules/shuttles/shuttle_ferry.dm index 5d6663f3b5..0a288a1ba9 100644 --- a/code/modules/shuttles/shuttle_ferry.dm +++ b/code/modules/shuttles/shuttle_ferry.dm @@ -16,7 +16,7 @@ //TODO: change location to a string and use a mapping for area and dock targets. var/dock_target_station var/dock_target_offsite - + var/last_dock_attempt_time = 0 /datum/shuttle/ferry/short_jump(var/area/origin,var/area/destination) @@ -85,15 +85,15 @@ long_jump(interim=area_transition, travel_time=move_time, direction=transit_direction) else short_jump() - + process_state = WAIT_ARRIVE - + if (WAIT_ARRIVE) if (moving_status == SHUTTLE_IDLE) dock() in_use = null //release lock process_state = WAIT_FINISH - + if (WAIT_FINISH) if (skip_docking_checks() || docking_controller.docked() || world.time > last_dock_attempt_time + DOCK_ATTEMPT_TIMEOUT) process_state = IDLE_STATE diff --git a/code/modules/surgery/bones.dm b/code/modules/surgery/bones.dm index cc4428fcb6..818e208ff4 100644 --- a/code/modules/surgery/bones.dm +++ b/code/modules/surgery/bones.dm @@ -140,7 +140,6 @@ user.visible_message("\blue [user] has mended the damaged bones in [target]'s [affected.name] with \the [tool]." , \ "\blue You have mended the damaged bones in [target]'s [affected.name] with \the [tool]." ) affected.status &= ~ORGAN_BROKEN - affected.status &= ~ORGAN_SPLINTED affected.stage = 0 fail_step(mob/living/user, mob/living/carbon/human/target, target_zone, obj/item/tool) diff --git a/code/modules/vehicles/vehicle.dm b/code/modules/vehicles/vehicle.dm index ddc56dad3f..80eb2f1a44 100644 --- a/code/modules/vehicles/vehicle.dm +++ b/code/modules/vehicles/vehicle.dm @@ -93,6 +93,7 @@ if(health < maxhealth) if(open) health = min(maxhealth, health+10) + user.setClickCooldown(DEFAULT_ATTACK_COOLDOWN) user.visible_message("\red [user] repairs [src]!","\blue You repair [src]!") else user << "Unable to repair with the maintenance panel closed." @@ -101,6 +102,7 @@ else user << "Unable to repair while [src] is off." else if(hasvar(W,"force") && hasvar(W,"damtype")) + user.setClickCooldown(DEFAULT_ATTACK_COOLDOWN) switch(W.damtype) if("fire") health -= W.force * fire_dam_coeff diff --git a/code/modules/ventcrawl/ventcrawl.dm b/code/modules/ventcrawl/ventcrawl.dm new file mode 100644 index 0000000000..9b2b83d3e7 --- /dev/null +++ b/code/modules/ventcrawl/ventcrawl.dm @@ -0,0 +1,185 @@ +var/list/ventcrawl_machinery = list( + /obj/machinery/atmospherics/unary/vent_pump, + /obj/machinery/atmospherics/unary/vent_scrubber + ) + +// Vent crawling whitelisted items, whoo +/mob/living/var/list/can_enter_vent_with = list( + /obj/item/weapon/implant, + /obj/item/device/radio/borg, + /obj/item/weapon/holder, + /obj/machinery/camera, + /mob/living/simple_animal/borer, + ) + +/mob/living/var/list/icon/pipes_shown = list() +/mob/living/var/last_played_vent +/mob/living/var/is_ventcrawling = 0 +/mob/var/next_play_vent = 0 + +/mob/living/proc/can_ventcrawl() + if(!client) + return FALSE + if(!(/mob/living/proc/ventcrawl in verbs)) + to_chat(src, "You don't possess the ability to ventcrawl!") + return FALSE + if(incapacitated()) + to_chat(src, "You cannot ventcrawl in your current state!") + return FALSE + return ventcrawl_carry() + +/mob/living/Login() + . = ..() + //login during ventcrawl + if(is_ventcrawling && istype(loc, /obj/machinery/atmospherics)) //attach us back into the pipes + remove_ventcrawl() + add_ventcrawl(loc) + +/mob/living/carbon/slime/can_ventcrawl() + if(Victim) + to_chat(src, "You cannot ventcrawl while feeding.") + return FALSE + . = ..() + +/mob/living/proc/is_allowed_vent_crawl_item(var/obj/item/carried_item) + if(carried_item == ability_master) + return 1 + for(var/type in can_enter_vent_with) + if(istype(carried_item, can_enter_vent_with)) + return get_inventory_slot(carried_item) == 0 + return 0 + +/mob/living/carbon/is_allowed_vent_crawl_item(var/obj/item/carried_item) + if(carried_item in internal_organs) + return 1 + return ..() + +/mob/living/carbon/human/is_allowed_vent_crawl_item(var/obj/item/carried_item) + if(carried_item in organs) + return 1 + return ..() + +/mob/living/simple_animal/spiderbot/is_allowed_vent_crawl_item(var/obj/item/carried_item) + if(carried_item == held_item) + return 1 + return ..() + +/mob/living/proc/ventcrawl_carry() + for(var/atom/A in contents) + if(!is_allowed_vent_crawl_item(A)) + to_chat(src, "You can't carry \the [A] while ventcrawling!") + return FALSE + return TRUE + +/mob/living/AltClickOn(var/atom/A) + if(is_type_in_list(A,ventcrawl_machinery)) + handle_ventcrawl(A) + return 1 + return ..() + +/mob/proc/start_ventcrawl() + var/atom/pipe + var/list/pipes = list() + for(var/obj/machinery/atmospherics/unary/U in range(1)) + if(is_type_in_list(U,ventcrawl_machinery) && Adjacent(U)) + pipes |= U + if(!pipes || !pipes.len) + to_chat(src, "There are no pipes that you can ventcrawl into within range!") + return + if(pipes.len == 1) + pipe = pipes[1] + else + pipe = input("Crawl Through Vent", "Pick a pipe") as null|anything in pipes + if(canmove && pipe) + return pipe + +/mob/living/carbon/alien/ventcrawl_carry() + return 1 + +/mob/living/var/ventcrawl_layer = 3 + +/mob/living/proc/handle_ventcrawl(var/atom/clicked_on) + if(!can_ventcrawl()) + return + + var/obj/machinery/atmospherics/unary/vent_found + if(clicked_on && Adjacent(clicked_on)) + vent_found = clicked_on + if(!istype(vent_found) || !vent_found.can_crawl_through()) + vent_found = null + + if(!vent_found) + for(var/obj/machinery/atmospherics/machine in range(1,src)) + if(is_type_in_list(machine, ventcrawl_machinery)) + vent_found = machine + + if(!vent_found || !vent_found.can_crawl_through()) + vent_found = null + + if(vent_found) + break + + if(vent_found) + if(vent_found.network && (vent_found.network.normal_members.len || vent_found.network.line_members.len)) + + to_chat(src, "You begin climbing into the ventilation system...") + if(vent_found.air_contents && !issilicon(src)) + + switch(vent_found.air_contents.temperature) + if(0 to BODYTEMP_COLD_DAMAGE_LIMIT) + to_chat(src, "You feel a painful freeze coming from the vent!") + if(BODYTEMP_COLD_DAMAGE_LIMIT to T0C) + to_chat(src, "You feel an icy chill coming from the vent.") + if(T0C + 40 to BODYTEMP_HEAT_DAMAGE_LIMIT) + to_chat(src, "You feel a hot wash coming from the vent.") + if(BODYTEMP_HEAT_DAMAGE_LIMIT to INFINITY) + to_chat(src, "You feel a searing heat coming from the vent!") + + switch(vent_found.air_contents.return_pressure()) + if(0 to HAZARD_LOW_PRESSURE) + to_chat(src, "You feel a rushing draw pulling you into the vent!") + if(HAZARD_LOW_PRESSURE to WARNING_LOW_PRESSURE) + to_chat(src, "You feel a strong drag pulling you into the vent.") + if(WARNING_HIGH_PRESSURE to HAZARD_HIGH_PRESSURE) + to_chat(src, "You feel a strong current pushing you away from the vent.") + if(HAZARD_HIGH_PRESSURE to INFINITY) + to_chat(src, "You feel a roaring wind pushing you away from the vent!") + + if(!do_after(src, 45, vent_found, 1, 1)) + return + if(!can_ventcrawl()) + return + + visible_message("[src] scrambles into the ventilation ducts!", "You climb into the ventilation system.") + + forceMove(vent_found) + add_ventcrawl(vent_found) + + else + to_chat(src, "This vent is not connected to anything.") + + else + to_chat(src, "You must be standing on or beside an air vent to enter it.") + +/mob/living/proc/add_ventcrawl(obj/machinery/atmospherics/starting_machine) + is_ventcrawling = 1 + //candrop = 0 + var/datum/pipe_network/network = starting_machine.return_network(starting_machine) + if(!network) + return + for(var/datum/pipeline/pipeline in network.line_members) + for(var/obj/machinery/atmospherics/A in (pipeline.members || pipeline.edges)) + if(!A.pipe_image) + A.pipe_image = image(A, A.loc, layer = 20, dir = A.dir) + pipes_shown += A.pipe_image + client.images += A.pipe_image + +/mob/living/proc/remove_ventcrawl() + is_ventcrawling = 0 + //candrop = 1 + if(client) + for(var/image/current_image in pipes_shown) + client.images -= current_image + client.eye = src + + pipes_shown.len = 0 \ No newline at end of file diff --git a/code/modules/ventcrawl/ventcrawl_atmospherics.dm b/code/modules/ventcrawl/ventcrawl_atmospherics.dm new file mode 100644 index 0000000000..bb2d121125 --- /dev/null +++ b/code/modules/ventcrawl/ventcrawl_atmospherics.dm @@ -0,0 +1,86 @@ +/obj/machinery/atmospherics/var/image/pipe_image + +/obj/machinery/atmospherics/Destroy() + for(var/mob/living/M in src) //ventcrawling is serious business + M.remove_ventcrawl() + M.forceMove(get_turf(src)) + if(pipe_image) + for(var/mob/living/M in player_list) + if(M.client) + M.client.images -= pipe_image + M.pipes_shown -= pipe_image + pipe_image = null + . = ..() + +/obj/machinery/atmospherics/ex_act(severity) + for(var/atom/movable/A in src) //ventcrawling is serious business + A.ex_act(severity) + . = ..() + +/obj/machinery/atmospherics/Entered(atom/movable/Obj) + if(istype(Obj, /mob/living)) + var/mob/living/L = Obj + L.ventcrawl_layer = layer + . = ..() + +/obj/machinery/atmospherics/relaymove(mob/living/user, direction) + if(user.loc != src || !(direction & initialize_directions)) //can't go in a way we aren't connecting to + return + ventcrawl_to(user,findConnecting(direction, user.ventcrawl_layer),direction) + +/obj/machinery/atmospherics/proc/ventcrawl_to(var/mob/living/user, var/obj/machinery/atmospherics/target_move, var/direction) + if(target_move) + if(is_type_in_list(target_move, ventcrawl_machinery) && target_move.can_crawl_through()) + user.remove_ventcrawl() + user.forceMove(target_move.loc) //handles entering and so on + user.visible_message("You hear something squeezing through the ducts.", "You climb out the ventilation system.") + else if(target_move.can_crawl_through()) + if(target_move.return_network(target_move) != return_network(src)) + user.remove_ventcrawl() + user.add_ventcrawl(target_move) + user.forceMove(target_move) + user.client.eye = target_move //if we don't do this, Byond only updates the eye every tick - required for smooth movement + if(world.time > user.next_play_vent) + user.next_play_vent = world.time+30 + playsound(src, 'sound/machines/ventcrawl.ogg', 50, 1, -3) + else + if((direction & initialize_directions) || is_type_in_list(src, ventcrawl_machinery) && src.can_crawl_through()) //if we move in a way the pipe can connect, but doesn't - or we're in a vent + user.remove_ventcrawl() + user.forceMove(src.loc) + user.visible_message("You hear something squeezing through the pipes.", "You climb out the ventilation system.") + user.canmove = 0 + spawn(1) + user.canmove = 1 + +/obj/machinery/atmospherics/proc/can_crawl_through() + return 1 + +/obj/machinery/atmospherics/proc/findConnecting(var/direction) + for(var/obj/machinery/atmospherics/target in get_step(src,direction)) + if(target.initialize_directions & get_dir(target,src)) + if(isConnectable(target) && target.isConnectable(src)) + return target + +/obj/machinery/atmospherics/proc/isConnectable(var/obj/machinery/atmospherics/target) + return (target == node1 || target == node2) + +/obj/machinery/atmospherics/pipe/manifold/isConnectable(var/obj/machinery/atmospherics/target) + return (target == node3 || ..()) + +obj/machinery/atmospherics/trinary/isConnectable(var/obj/machinery/atmospherics/target) + return (target == node3 || ..()) + +/obj/machinery/atmospherics/pipe/manifold4w/isConnectable(var/obj/machinery/atmospherics/target) + return (target == node3 || target == node4 || ..()) + +/obj/machinery/atmospherics/tvalve/isConnectable(var/obj/machinery/atmospherics/target) + return (target == node3 || ..()) + +/obj/machinery/atmospherics/pipe/cap/isConnectable(var/obj/machinery/atmospherics/target) + return (target == node || ..()) + +/obj/machinery/atmospherics/portables_connector/isConnectable(var/obj/machinery/atmospherics/target) + return (target == node || ..()) + +/obj/machinery/atmospherics/unary/isConnectable(var/obj/machinery/atmospherics/target) + return (target == node || ..()) diff --git a/code/modules/ventcrawl/ventcrawl_multiz.dm b/code/modules/ventcrawl/ventcrawl_multiz.dm new file mode 100644 index 0000000000..87ef8f9ba7 --- /dev/null +++ b/code/modules/ventcrawl/ventcrawl_multiz.dm @@ -0,0 +1,24 @@ +/obj/machinery/atmospherics/pipe/zpipe/up/verb/ventcrawl_move_up() + set name = "Ventcrawl Upwards" + set desc = "Climb up through a pipe." + set category = "Abilities" + set src = usr.loc + var/obj/machinery/atmospherics/target = check_ventcrawl(GetAbove(loc)) + if(target) ventcrawl_to(usr, target, UP) + +/obj/machinery/atmospherics/pipe/zpipe/down/verb/ventcrawl_move_down() + set name = "Ventcrawl Downwards" + set desc = "Climb down through a pipe." + set category = "Abilities" + set src = usr.loc + var/obj/machinery/atmospherics/target = check_ventcrawl(GetBelow(loc)) + if(target) ventcrawl_to(usr, target, DOWN) + +/obj/machinery/atmospherics/pipe/zpipe/proc/check_ventcrawl(var/turf/target) + if(!istype(target)) + return + if(node1 in target) + return node1 + if(node2 in target) + return node2 + return \ No newline at end of file diff --git a/code/modules/ventcrawl/ventcrawl_verb.dm b/code/modules/ventcrawl/ventcrawl_verb.dm new file mode 100644 index 0000000000..b49f22836d --- /dev/null +++ b/code/modules/ventcrawl/ventcrawl_verb.dm @@ -0,0 +1,7 @@ +/mob/living/proc/ventcrawl() + set name = "Crawl through Vent" + set desc = "Enter an air vent and crawl through the pipe system." + set category = "Abilities" + var/pipe = start_ventcrawl() + if(pipe) + handle_ventcrawl() diff --git a/code/unit_tests/zas_tests.dm b/code/unit_tests/zas_tests.dm index a28abaa881..cbf26f061f 100644 --- a/code/unit_tests/zas_tests.dm +++ b/code/unit_tests/zas_tests.dm @@ -44,7 +44,7 @@ return test_result if(expectation == UT_NORMAL) - + if(abs(temp - T20C) > 10) test_result["msg"] = "Temperature out of bounds: [temp] | [t_msg]" return test_result @@ -78,7 +78,7 @@ return 1 /datum/unit_test/zas_area_test/supply_centcomm - name = "ZAS: Supply Shuttle (CentComm)" + name = "ZAS: Supply Shuttle (CentCom)" area_path = /area/supply/dock /datum/unit_test/zas_area_test/emergency_shuttle @@ -95,7 +95,7 @@ /datum/unit_test/zas_area_test/cargo_maint name = "ZAS: Cargo Maintenance" - area_path = /area/maintenance/cargo + area_path = /area/maintenance/cargo /datum/unit_test/zas_area_test/eng_shuttle name = "ZAS: Construction Site Shuttle (Station)" diff --git a/html/changelog.html b/html/changelog.html index fd4010ec16..fda0a46275 100644 --- a/html/changelog.html +++ b/html/changelog.html @@ -53,6 +53,50 @@ -->
+

19 September 2016

+

Anewbe updated:

+ +

MagmaRam updated:

+ +

Zuhayr updated:

+ + +

16 September 2016

+

Anewbe updated:

+ +

Chinsky updated:

+ +

Yoshax updated:

+ +

03 September 2016

Yosh updated: