diff --git a/.github/ISSUE_TEMPLATE/bug_report.md b/.github/ISSUE_TEMPLATE/bug_report.md new file mode 100644 index 00000000000..2b4c3586bf9 --- /dev/null +++ b/.github/ISSUE_TEMPLATE/bug_report.md @@ -0,0 +1,35 @@ +--- +name: Bug report +about: Create a report to help us improve +title: '' +labels: '' +assignees: '' + +--- + +**Issue Description**: + + + +**What did you expect to happen**: + + + +**What happened instead**: + + + +**Why is this bad/What are the consequences**: + + + +**Steps to reproduce the problem**: + + + +**When did the problem start happening**: + + + +**Extra information**: + diff --git a/.github/ISSUE_TEMPLATE/feature_request.md b/.github/ISSUE_TEMPLATE/feature_request.md new file mode 100644 index 00000000000..2f58d4e9ebb --- /dev/null +++ b/.github/ISSUE_TEMPLATE/feature_request.md @@ -0,0 +1,10 @@ +--- +name: Feature request +about: Suggest an idea for this project +title: '' +labels: '' +assignees: '' + +--- + +Please place all features requests here: https://nanotrasen.se/forum/60-suggestions/ diff --git a/SQL/paradise_schema.sql b/SQL/paradise_schema.sql index ed4fb787b8d..1e4692b7e3b 100644 --- a/SQL/paradise_schema.sql +++ b/SQL/paradise_schema.sql @@ -269,6 +269,7 @@ CREATE TABLE `player` ( `fuid` bigint(20) NULL DEFAULT NULL, `fupdate` smallint(4) NULL DEFAULT '0', `afk_watch` tinyint(1) NOT NULL DEFAULT '0', + `parallax` tinyint(1) DEFAULT '8', PRIMARY KEY (`id`), UNIQUE KEY `ckey` (`ckey`) ) ENGINE=InnoDB AUTO_INCREMENT=32446 DEFAULT CHARSET=latin1; diff --git a/SQL/paradise_schema_prefixed.sql b/SQL/paradise_schema_prefixed.sql index b0f7bbc5c82..aa5d5895e56 100644 --- a/SQL/paradise_schema_prefixed.sql +++ b/SQL/paradise_schema_prefixed.sql @@ -268,6 +268,7 @@ CREATE TABLE `SS13_player` ( `fuid` bigint(20) NULL DEFAULT NULL, `fupdate` smallint(4) NULL DEFAULT '0', `afk_watch` tinyint(1) NOT NULL DEFAULT '0', + `parallax` tinyint(1) DEFAULT '8', PRIMARY KEY (`id`), UNIQUE KEY `ckey` (`ckey`) ) ENGINE=InnoDB AUTO_INCREMENT=32446 DEFAULT CHARSET=latin1; diff --git a/SQL/updates/8-9.sql b/SQL/updates/8-9.sql new file mode 100644 index 00000000000..d7f0fd19ab3 --- /dev/null +++ b/SQL/updates/8-9.sql @@ -0,0 +1,4 @@ +#Updating the SQL from version 8 to version 9. -affectedarc07 +#Adding new column to contain the parallax value. +ALTER TABLE `player` + ADD `parallax` tinyint(1) DEFAULT '8' AFTER `fupdate`; diff --git a/_maps/map_files/Delta/delta.dmm b/_maps/map_files/Delta/delta.dmm index 447889d17a1..37231b29651 100644 --- a/_maps/map_files/Delta/delta.dmm +++ b/_maps/map_files/Delta/delta.dmm @@ -694,7 +694,6 @@ /obj/structure/rack, /obj/item/clothing/suit/space/hardsuit/medical, /obj/item/clothing/mask/breath, -/obj/item/clothing/head/helmet/space/hardsuit/medical, /turf/simulated/shuttle/floor{ icon_state = "floor3" }, @@ -3304,7 +3303,6 @@ /obj/item/tank/oxygen, /obj/item/clothing/suit/space/hardsuit/security, /obj/item/clothing/mask/breath, -/obj/item/clothing/head/helmet/space/hardsuit/security, /obj/item/clothing/shoes/magboots, /obj/item/tank/jetpack/oxygen, /obj/item/radio/intercom{ @@ -27867,11 +27865,6 @@ /obj/effect/decal/warning_stripes/northwest, /turf/simulated/floor/plasteel, /area/atmos) -"bat" = ( -/obj/machinery/pipedispenser, -/obj/effect/decal/warning_stripes/east, -/turf/simulated/floor/plasteel, -/area/atmos) "bau" = ( /obj/machinery/atmospherics/pipe/manifold/hidden/supply{ dir = 8; @@ -28742,11 +28735,6 @@ /obj/effect/decal/warning_stripes/west, /turf/simulated/floor/plasteel, /area/atmos) -"bbU" = ( -/obj/machinery/pipedispenser/disposal, -/obj/effect/decal/warning_stripes/east, -/turf/simulated/floor/plasteel, -/area/atmos) "bbV" = ( /obj/structure/cable{ d1 = 1; @@ -31407,6 +31395,7 @@ id_tag = "s_docking_airlock"; req_access_txt = "48" }, +/obj/structure/fans/tiny, /turf/simulated/shuttle/floor, /area/shuttle/mining) "bgZ" = ( @@ -31431,6 +31420,7 @@ name = "mining shuttle bay"; width = 7 }, +/obj/structure/fans/tiny, /turf/simulated/shuttle/floor, /area/shuttle/mining) "bha" = ( @@ -34038,6 +34028,7 @@ name = "Mining Dock Airlock"; req_access_txt = "48" }, +/obj/structure/fans/tiny, /turf/simulated/floor/plasteel, /area/quartermaster/miningdock) "blH" = ( @@ -38843,6 +38834,7 @@ name = "Labor Shuttle Airlock"; req_access_txt = "2" }, +/obj/structure/fans/tiny, /turf/simulated/shuttle/floor{ icon_state = "floor4" }, @@ -38864,6 +38856,7 @@ name = "Labor Camp Airlock"; req_access_txt = "2" }, +/obj/structure/fans/tiny, /turf/simulated/floor/plasteel, /area/security/prisonershuttle) "btT" = ( @@ -41958,6 +41951,7 @@ name = "fore bay 1"; width = 9 }, +/obj/structure/fans/tiny, /turf/simulated/shuttle/floor, /area/shuttle/siberia) "bzg" = ( @@ -49658,8 +49652,8 @@ /obj/item/radio/intercom{ pixel_y = 28 }, -/obj/machinery/deployable/barrier, -/obj/machinery/deployable/barrier, +/obj/item/grenade/barrier, +/obj/item/grenade/barrier, /turf/simulated/floor/plasteel{ icon_state = "vault"; dir = 8 @@ -49679,8 +49673,8 @@ }, /area/security/armoury) "bLK" = ( -/obj/machinery/deployable/barrier, -/obj/machinery/deployable/barrier, +/obj/item/grenade/barrier, +/obj/item/grenade/barrier, /turf/simulated/floor/plasteel{ icon_state = "vault"; dir = 8 @@ -142582,9 +142576,9 @@ aUd aVM aXq aYI -bat -bbU -bat +bhp +bhp +bhp beO aXn bhk diff --git a/_maps/map_files/MetaStation/MetaStation.v41A.II.dmm b/_maps/map_files/MetaStation/MetaStation.v41A.II.dmm index 8bf89da81b2..ccfadc2ab79 100644 --- a/_maps/map_files/MetaStation/MetaStation.v41A.II.dmm +++ b/_maps/map_files/MetaStation/MetaStation.v41A.II.dmm @@ -1650,7 +1650,6 @@ name = "EXTERNAL AIRLOCK"; pixel_y = 32 }, -/obj/effect/decal/warning_stripes/east, /turf/simulated/floor/plating, /area/security/permabrig) "adl" = ( @@ -1887,7 +1886,6 @@ network = list("SS13") }, /obj/item/clothing/suit/space/hardsuit/security, -/obj/item/clothing/head/helmet/space/hardsuit/security, /turf/simulated/floor/plasteel{ icon_state = "dark" }, @@ -2037,6 +2035,9 @@ /area/security/permabrig) "adW" = ( /obj/effect/decal/warning_stripes/east, +/obj/machinery/atmospherics/pipe/simple/visible{ + dir = 5 + }, /turf/simulated/floor/plating, /area/security/permabrig) "adX" = ( @@ -2062,13 +2063,6 @@ icon_state = "dark" }, /area/security/permabrig) -"adZ" = ( -/obj/machinery/door/airlock/external{ - name = "Security External Airlock"; - req_access_txt = "1" - }, -/turf/simulated/floor/plating, -/area/security/permabrig) "aea" = ( /obj/machinery/atmospherics/unary/vent_scrubber{ dir = 4; @@ -3850,12 +3844,20 @@ /turf/simulated/floor/plating, /area/maintenance/auxsolarport) "agY" = ( -/obj/vehicle/secway, -/obj/item/key/security, +/obj/structure/rack, +/obj/item/storage/box/buck{ + pixel_x = -3; + pixel_y = 3 + }, +/obj/item/storage/box/buck, +/obj/item/storage/box/buck{ + pixel_x = 3; + pixel_y = -3 + }, /turf/simulated/floor/plasteel{ - tag = "icon-vault (WEST)"; + dir = 8; icon_state = "vault"; - dir = 8 + tag = "icon-vault (WEST)" }, /area/security/armoury) "agZ" = ( @@ -4310,7 +4312,6 @@ /obj/structure/rack, /obj/item/clothing/suit/space/hardsuit/security, /obj/item/clothing/mask/gas/sechailer, -/obj/item/clothing/head/helmet/space/hardsuit/security, /turf/simulated/floor/plasteel{ icon_state = "dark" }, @@ -4794,10 +4795,10 @@ /obj/structure/reagent_dispensers/peppertank{ pixel_y = 29 }, -/obj/machinery/deployable/barrier, -/obj/machinery/deployable/barrier, -/obj/machinery/deployable/barrier, -/obj/machinery/deployable/barrier, +/obj/item/grenade/barrier, +/obj/item/grenade/barrier, +/obj/item/grenade/barrier, +/obj/item/grenade/barrier, /turf/simulated/floor/plasteel{ tag = "icon-vault (WEST)"; icon_state = "vault"; @@ -5439,7 +5440,6 @@ /obj/item/clothing/shoes/magboots, /obj/item/clothing/suit/space/hardsuit/security, /obj/item/clothing/mask/gas/sechailer, -/obj/item/clothing/head/helmet/space/hardsuit/security, /turf/simulated/floor/plasteel{ icon_state = "vault"; dir = 4 @@ -5635,11 +5635,6 @@ }, /area/security/armoury) "ajN" = ( -/obj/machinery/door/airlock/external{ - name = "Solar Maintenance"; - req_access = null; - req_access_txt = "10; 13" - }, /obj/structure/cable{ d1 = 1; d2 = 2; @@ -5657,7 +5652,6 @@ /obj/item/clothing/shoes/magboots, /obj/item/clothing/suit/space/hardsuit/security, /obj/item/clothing/mask/gas/sechailer, -/obj/item/clothing/head/helmet/space/hardsuit/security, /turf/simulated/floor/plasteel{ icon_state = "vault"; dir = 1 @@ -5922,7 +5916,6 @@ req_access_txt = "3" }, /obj/machinery/atmospherics/pipe/simple/hidden/supply, -/obj/effect/decal/warning_stripes/yellow, /turf/simulated/floor/plasteel, /area/security/armoury) "aks" = ( @@ -6192,15 +6185,6 @@ icon_state = "dark" }, /area/security/podbay) -"akP" = ( -/obj/structure/cable{ - d1 = 1; - d2 = 2; - icon_state = "1-2" - }, -/obj/effect/decal/warning_stripes/north, -/turf/simulated/floor/plating, -/area/maintenance/auxsolarport) "akQ" = ( /obj/structure/disposalpipe/segment{ dir = 4 @@ -6503,15 +6487,15 @@ d2 = 8; icon_state = "4-8" }, -/obj/effect/decal/warning_stripes/yellow, /turf/simulated/floor/plasteel, /area/security/armoury) "alo" = ( +/obj/structure/fans/tiny, /obj/machinery/door/poddoor{ id_tag = "trash"; - name = "disposal bay door" + name = "disposal bay door"; + protected = 0 }, -/obj/structure/fans/tiny, /turf/simulated/floor/plating, /area/maintenance/disposal) "alp" = ( @@ -6796,19 +6780,6 @@ }, /turf/simulated/floor/plating, /area/security/main) -"alQ" = ( -/obj/structure/cable{ - d1 = 1; - d2 = 2; - icon_state = "1-2" - }, -/obj/machinery/door/airlock/external{ - name = "Solar Maintenance"; - req_access = null; - req_access_txt = "10; 13" - }, -/turf/simulated/floor/plating, -/area/maintenance/auxsolarport) "alR" = ( /obj/machinery/door/firedoor, /obj/structure/cable/yellow{ @@ -7019,7 +6990,7 @@ /area/maintenance/disposal) "amn" = ( /obj/machinery/door_control{ - id = "trash"; + id = "Disposal Exit"; name = "Disposal Vent Control"; pixel_x = -25; pixel_y = 4; @@ -7557,11 +7528,7 @@ /obj/machinery/atmospherics/pipe/simple/hidden/supply{ dir = 4 }, -/turf/simulated/floor/plasteel{ - tag = "icon-vault (WEST)"; - icon_state = "vault"; - dir = 8 - }, +/turf/simulated/floor/plasteel, /area/security/armoury) "anb" = ( /obj/machinery/atmospherics/pipe/simple/hidden/supply{ @@ -7679,6 +7646,10 @@ name = "EXTERNAL AIRLOCK"; pixel_x = 32 }, +/obj/machinery/portable_atmospherics/canister/air, +/obj/machinery/atmospherics/unary/portables_connector{ + dir = 8 + }, /turf/simulated/floor/plating, /area/maintenance/auxsolarport) "ann" = ( @@ -7754,25 +7725,11 @@ /obj/structure/window/reinforced, /turf/simulated/floor/plating, /area/maintenance/disposal) -"anx" = ( -/obj/structure/disposalpipe/segment{ - dir = 4 - }, -/obj/effect/decal/warning_stripes/south, -/turf/simulated/floor/plating, -/area/maintenance/disposal) "any" = ( -/obj/structure/disposalpipe/segment{ - dir = 4; - icon_state = "pipe-c" - }, /obj/effect/decal/warning_stripes/south, /turf/simulated/floor/plating, /area/maintenance/disposal) "anz" = ( -/obj/structure/disposalpipe/segment{ - dir = 4 - }, /obj/machinery/atmospherics/pipe/simple/hidden/supply{ dir = 5 }, @@ -7780,9 +7737,6 @@ /turf/simulated/floor/plating, /area/maintenance/disposal) "anA" = ( -/obj/structure/disposalpipe/segment{ - dir = 4 - }, /obj/machinery/atmospherics/pipe/simple/hidden/supply{ dir = 4 }, @@ -7804,9 +7758,6 @@ d2 = 8; icon_state = "4-8" }, -/obj/structure/disposalpipe/segment{ - dir = 4 - }, /obj/machinery/atmospherics/pipe/simple/hidden/supply{ dir = 4 }, @@ -7820,9 +7771,6 @@ d2 = 8; icon_state = "4-8" }, -/obj/structure/disposalpipe/segment{ - dir = 4 - }, /obj/machinery/atmospherics/pipe/simple/hidden/supply{ dir = 4 }, @@ -7842,10 +7790,6 @@ d2 = 8; icon_state = "2-8" }, -/obj/structure/disposalpipe/segment{ - dir = 2; - icon_state = "pipe-c" - }, /obj/machinery/atmospherics/pipe/manifold/hidden/supply{ dir = 4 }, @@ -7939,6 +7883,9 @@ icon_state = "1-8" }, /obj/effect/decal/warning_stripes/north, +/obj/machinery/atmospherics/pipe/simple/visible{ + dir = 5 + }, /turf/simulated/floor/plating, /area/maintenance/auxsolarport) "anL" = ( @@ -8084,6 +8031,10 @@ /obj/item/reagent_containers/glass/bottle/morphine, /obj/machinery/light/small, /obj/effect/decal/warning_stripes/yellow/hollow, +/obj/item/storage/toolbox/mechanical{ + pixel_x = -4; + pixel_y = 4 + }, /turf/simulated/floor/plasteel, /area/security/armoury) "aoa" = ( @@ -8092,16 +8043,9 @@ /turf/simulated/floor/plating, /area/security/armoury) "aob" = ( -/obj/structure/rack, -/obj/item/storage/toolbox/mechanical{ - pixel_x = -4; - pixel_y = 4 - }, -/obj/item/storage/toolbox/emergency{ - pixel_x = 2; - pixel_y = -3 - }, /obj/effect/decal/warning_stripes/yellow/hollow, +/obj/vehicle/secway, +/obj/item/key/security, /turf/simulated/floor/plasteel, /area/security/armoury) "aoc" = ( @@ -8544,10 +8488,8 @@ icon_state = "right"; layer = 3 }, -/obj/structure/disposalpipe/trunk{ - dir = 1 - }, /obj/effect/decal/warning_stripes/east, +/obj/structure/disposalpipe/trunk, /turf/simulated/floor/plating, /area/maintenance/disposal) "aoU" = ( @@ -8560,13 +8502,16 @@ /turf/simulated/floor/plating, /area/maintenance/disposal) "aoV" = ( -/obj/machinery/mineral/stacking_machine, /obj/structure/window/reinforced{ dir = 4 }, /obj/structure/window/reinforced{ dir = 1 }, +/obj/machinery/mineral/stacking_machine{ + input_dir = 2; + stack_amt = 10 + }, /turf/simulated/floor/plating, /area/maintenance/disposal) "aoW" = ( @@ -8640,7 +8585,9 @@ name = "Danger: Conveyor Access"; req_access_txt = "12" }, -/obj/machinery/conveyor/east, +/obj/machinery/conveyor/west{ + id = "garbage" + }, /turf/simulated/floor/plating, /area/maintenance/disposal) "apd" = ( @@ -9017,13 +8964,6 @@ }, /turf/simulated/floor/plating, /area/maintenance/fore) -"apP" = ( -/obj/machinery/light/small{ - dir = 8 - }, -/obj/effect/decal/warning_stripes/southeast, -/turf/simulated/floor/plating, -/area/maintenance/starboard) "apQ" = ( /obj/machinery/sleeper{ icon_state = "sleeper-open"; @@ -9147,13 +9087,6 @@ dir = 4 }, /area/security/brig) -"aqe" = ( -/obj/machinery/door/airlock/external{ - req_access_txt = "0"; - req_one_access_txt = "13,8" - }, -/turf/simulated/floor/plating, -/area/maintenance/starboard) "aqf" = ( /obj/machinery/atmospherics/pipe/simple/hidden/supply{ dir = 6 @@ -9309,18 +9242,6 @@ }, /turf/simulated/floor/plating, /area/maintenance/fore) -"aqv" = ( -/obj/structure/cable/yellow{ - d1 = 1; - d2 = 2; - icon_state = "1-2" - }, -/obj/machinery/atmospherics/pipe/simple/hidden/supply, -/obj/structure/disposalpipe/segment, -/turf/simulated/floor/plating, -/area/maintenance/fpmaint2{ - name = "Port Maintenance" - }) "aqw" = ( /obj/structure/closet/crate, /obj/item/bodybag, @@ -9424,7 +9345,6 @@ /turf/simulated/floor/plating, /area/security/brig) "aqG" = ( -/obj/effect/decal/warning_stripes/yellow/hollow, /turf/simulated/floor/plasteel, /area/security/armoury) "aqH" = ( @@ -9876,7 +9796,9 @@ dir = 2; icon_state = "pipe-c" }, -/obj/machinery/conveyor/east, +/obj/machinery/conveyor/east{ + id = "garbage" + }, /turf/simulated/floor/plating, /area/maintenance/disposal) "art" = ( @@ -9942,11 +9864,6 @@ d2 = 2; icon_state = "1-2" }, -/obj/machinery/door/airlock/external{ - name = "Solar Maintenance"; - req_access = null; - req_access_txt = "10; 13" - }, /turf/simulated/floor/plating, /area/maintenance/auxsolarstarboard) "arD" = ( @@ -9961,7 +9878,9 @@ /area/maintenance/disposal) "arE" = ( /obj/machinery/recycler, -/obj/machinery/conveyor/east, +/obj/machinery/conveyor/east{ + id = "garbage" + }, /turf/simulated/floor/plating, /area/maintenance/disposal) "arF" = ( @@ -9969,7 +9888,10 @@ dir = 2; on = 1 }, -/obj/machinery/conveyor/east, +/obj/machinery/conveyor/east{ + id = "garbage" + }, +/obj/structure/disposalpipe/segment, /turf/simulated/floor/plating, /area/maintenance/disposal) "arG" = ( @@ -10704,15 +10626,6 @@ icon_state = "dark" }, /area/engine/gravitygenerator) -"asL" = ( -/obj/structure/cable{ - d1 = 1; - d2 = 2; - icon_state = "1-2" - }, -/obj/effect/decal/warning_stripes/north, -/turf/simulated/floor/plating, -/area/maintenance/auxsolarstarboard) "asM" = ( /obj/machinery/atmospherics/pipe/simple/hidden/scrubbers, /obj/machinery/atmospherics/pipe/simple/hidden/supply{ @@ -10905,6 +10818,7 @@ req_access_txt = "12" }, /obj/machinery/atmospherics/pipe/simple/hidden/supply, +/obj/structure/disposalpipe/segment, /turf/simulated/floor/plating, /area/maintenance/disposal) "atd" = ( @@ -10926,7 +10840,6 @@ d2 = 2; icon_state = "1-2" }, -/obj/structure/disposalpipe/segment, /turf/simulated/floor/plating, /area/maintenance/fpmaint2{ name = "Port Maintenance" @@ -11031,7 +10944,6 @@ d2 = 2; icon_state = "1-2" }, -/obj/structure/disposalpipe/segment, /obj/machinery/atmospherics/pipe/manifold/hidden/supply{ dir = 8 }, @@ -11345,26 +11257,9 @@ name = "\improper Recreation Area" }) "atU" = ( -/obj/structure/table, -/obj/item/tank/emergency_oxygen{ - pixel_x = -8 - }, -/obj/item/tank/emergency_oxygen{ - pixel_x = -8 - }, -/obj/item/clothing/mask/breath{ - pixel_x = 4 - }, -/obj/item/clothing/mask/breath{ - pixel_x = 4 - }, -/obj/effect/decal/cleanable/cobweb, -/obj/structure/sign/securearea{ - desc = "A warning sign which reads 'EXTERNAL AIRLOCK'"; - icon_state = "space"; - layer = 4; - name = "EXTERNAL AIRLOCK"; - pixel_y = 32 +/obj/machinery/portable_atmospherics/canister/air, +/obj/machinery/atmospherics/unary/portables_connector{ + dir = 8 }, /turf/simulated/floor/plating, /area/maintenance/starboard) @@ -11380,6 +11275,9 @@ icon_state = "1-8" }, /obj/effect/decal/warning_stripes/north, +/obj/machinery/atmospherics/pipe/simple/visible{ + dir = 5 + }, /turf/simulated/floor/plating, /area/maintenance/auxsolarstarboard) "atW" = ( @@ -11401,6 +11299,10 @@ pixel_x = 32 }, /obj/effect/decal/cleanable/cobweb2, +/obj/machinery/atmospherics/unary/portables_connector{ + dir = 8 + }, +/obj/machinery/portable_atmospherics/canister/air, /turf/simulated/floor/plating, /area/maintenance/auxsolarstarboard) "atY" = ( @@ -11660,6 +11562,7 @@ "aux" = ( /obj/machinery/atmospherics/pipe/simple/hidden/supply, /obj/effect/decal/warning_stripes/north, +/obj/structure/disposalpipe/segment, /turf/simulated/floor/plating, /area/maintenance/fpmaint2{ name = "Port Maintenance" @@ -11722,6 +11625,7 @@ name = "Labor Camp Shuttle Airlock"; req_access_txt = "2" }, +/obj/structure/fans/tiny, /turf/simulated/floor/plasteel{ icon_state = "dark" }, @@ -13120,12 +13024,6 @@ dir = 1 }, /area/security/processing) -"axg" = ( -/obj/machinery/door/airlock/external{ - req_access_txt = "13" - }, -/turf/simulated/floor/plating, -/area/maintenance/starboard) "axh" = ( /turf/simulated/wall/r_wall, /area/maintenance/starboard) @@ -13235,7 +13133,6 @@ icon_state = "1-2" }, /obj/machinery/atmospherics/pipe/simple/hidden/supply, -/obj/structure/disposalpipe/segment, /obj/effect/decal/cleanable/dirt, /turf/simulated/floor/plating, /area/maintenance/fpmaint2{ @@ -13954,20 +13851,6 @@ /obj/machinery/atmospherics/pipe/simple/hidden/supply, /obj/structure/disposalpipe/segment, /turf/simulated/floor/plating, -/area/maintenance/fpmaint2{ - name = "Port Maintenance" - }) -"ayE" = ( -/obj/structure/cable/yellow{ - d1 = 1; - d2 = 2; - icon_state = "1-2" - }, -/obj/structure/disposalpipe/segment{ - dir = 1; - icon_state = "pipe-c" - }, -/turf/simulated/floor/plating, /area/maintenance/fpmaint2{ name = "Port Maintenance" }) @@ -13978,9 +13861,6 @@ max_integrity = 120; reinf = 0 }, -/obj/structure/disposalpipe/segment{ - dir = 4 - }, /turf/simulated/floor/plating, /area/maintenance/fore) "ayG" = ( @@ -13988,17 +13868,13 @@ /turf/simulated/floor/plating, /area/maintenance/fore) "ayH" = ( -/obj/structure/disposalpipe/junction{ - tag = "icon-pipe-j2 (NORTH)"; - icon_state = "pipe-j2"; - dir = 1 - }, /obj/machinery/atmospherics/pipe/simple/hidden/supply, /obj/structure/cable/yellow{ d1 = 1; d2 = 2; icon_state = "1-2" }, +/obj/structure/disposalpipe/segment, /turf/simulated/floor/plating, /area/maintenance/fore) "ayI" = ( @@ -14268,7 +14144,6 @@ }, /area/security/brig) "azf" = ( -/obj/structure/closet/emcloset, /obj/structure/sign/securearea{ desc = "A warning sign which reads 'EXTERNAL AIRLOCK'"; icon_state = "space"; @@ -14276,6 +14151,8 @@ name = "EXTERNAL AIRLOCK"; pixel_y = 32 }, +/obj/machinery/portable_atmospherics/canister/air, +/obj/machinery/atmospherics/unary/portables_connector, /turf/simulated/floor/plating, /area/maintenance/starboard) "azg" = ( @@ -14296,22 +14173,8 @@ /turf/simulated/floor/wood, /area/crew_quarters/mrchangs) "azi" = ( -/obj/structure/closet/crate{ - icon_state = "crateopen"; - opened = 1 - }, -/obj/structure/sign/securearea{ - desc = "A warning sign which reads 'EXTERNAL AIRLOCK'"; - icon_state = "space"; - layer = 4; - name = "EXTERNAL AIRLOCK"; - pixel_y = 32 - }, -/obj/effect/decal/cleanable/cobweb, -/obj/effect/spawner/lootdrop/maintenance{ - lootcount = 3; - name = "3maintenance loot spawner" - }, +/obj/machinery/portable_atmospherics/canister/air, +/obj/machinery/atmospherics/unary/portables_connector, /turf/simulated/floor/plating, /area/maintenance/fpmaint2{ name = "Port Maintenance" @@ -14439,13 +14302,6 @@ /obj/effect/spawner/lootdrop/maintenance, /turf/simulated/floor/plating, /area/maintenance/starboard) -"azv" = ( -/obj/structure/rack, -/obj/item/clothing/mask/gas, -/obj/item/clothing/glasses/sunglasses, -/obj/effect/spawner/lootdrop/maintenance, -/turf/simulated/floor/plating, -/area/maintenance/starboard) "azw" = ( /obj/effect/spawner/window/reinforced, /obj/structure/cable/yellow{ @@ -14603,12 +14459,6 @@ }, /turf/simulated/floor/plating/airless, /area/space/nearstation) -"azJ" = ( -/obj/machinery/door/airlock/external, -/turf/simulated/floor/plating, -/area/maintenance/fpmaint2{ - name = "Port Maintenance" - }) "azK" = ( /obj/machinery/atmospherics/pipe/simple/hidden/supply{ dir = 4 @@ -14666,6 +14516,7 @@ icon_state = "2-4" }, /obj/effect/decal/warning_stripes/south, +/obj/structure/disposalpipe/segment, /turf/simulated/floor/plating, /area/maintenance/fpmaint2{ name = "Port Maintenance" @@ -14728,6 +14579,7 @@ name = "Mining Office"; req_access_txt = "48" }, +/obj/structure/disposalpipe/segment, /turf/simulated/floor/plasteel, /area/quartermaster/miningdock{ name = "\improper Mining Office" @@ -14760,6 +14612,7 @@ id_tag = "s_docking_airlock"; name = "Labor Shuttle Airlock" }, +/obj/structure/fans/tiny, /turf/simulated/shuttle/floor{ icon_state = "floor4" }, @@ -14769,6 +14622,7 @@ id_tag = "laborcamp_home"; name = "Labor Camp Shuttle Airlock" }, +/obj/structure/fans/tiny, /turf/simulated/floor/plasteel{ icon_state = "dark" }, @@ -15229,17 +15083,6 @@ icon_state = "red" }, /area/security/brig) -"aAO" = ( -/obj/structure/sign/securearea{ - desc = "A warning sign which reads 'EXTERNAL AIRLOCK'"; - icon_state = "space"; - layer = 4; - name = "EXTERNAL AIRLOCK"; - pixel_y = -32 - }, -/obj/effect/decal/warning_stripes/east, -/turf/simulated/floor/plating, -/area/maintenance/starboard) "aAP" = ( /obj/structure/closet, /obj/effect/spawner/lootdrop/maintenance, @@ -15287,19 +15130,6 @@ /obj/effect/decal/warning_stripes/south, /turf/simulated/floor/plating, /area/maintenance/fore) -"aAW" = ( -/obj/structure/sign/securearea{ - desc = "A warning sign which reads 'EXTERNAL AIRLOCK'"; - icon_state = "space"; - layer = 4; - name = "EXTERNAL AIRLOCK"; - pixel_y = 32 - }, -/obj/effect/decal/warning_stripes/west, -/turf/simulated/floor/plating, -/area/maintenance/fpmaint2{ - name = "Port Maintenance" - }) "aAX" = ( /obj/structure/closet/crate, /obj/item/coin/silver, @@ -15638,6 +15468,7 @@ pixel_y = -25; req_access_txt = "2" }, +/obj/structure/fans/tiny, /turf/simulated/floor/plasteel{ icon_state = "dark" }, @@ -16118,6 +15949,8 @@ d2 = 2; icon_state = "1-2" }, +/obj/structure/disposalpipe/segment, +/obj/structure/disposalpipe/segment, /turf/simulated/floor/plating, /area/quartermaster/miningdock{ name = "\improper Mining Office" @@ -16347,6 +16180,10 @@ name = "Brig"; req_access_txt = "63" }, +/obj/effect/mapping_helpers/airlock/unres{ + icon_state = "airlock_unres_helper"; + dir = 1 + }, /turf/simulated/floor/plasteel{ icon_state = "red" }, @@ -16369,6 +16206,10 @@ name = "Brig"; req_access_txt = "63" }, +/obj/effect/mapping_helpers/airlock/unres{ + icon_state = "airlock_unres_helper"; + dir = 1 + }, /turf/simulated/floor/plasteel{ icon_state = "red" }, @@ -16764,6 +16605,7 @@ d2 = 8; icon_state = "1-8" }, +/obj/structure/disposalpipe/segment, /turf/simulated/floor/plasteel{ dir = 1; icon_state = "brown" @@ -17546,6 +17388,7 @@ name = "mining shuttle bay"; width = 7 }, +/obj/structure/fans/tiny, /turf/simulated/shuttle/plating, /area/shuttle/mining) "aEJ" = ( @@ -17554,6 +17397,7 @@ req_access = null; req_access_txt = "0" }, +/obj/structure/fans/tiny, /turf/simulated/floor/plating, /area/quartermaster/miningdock{ name = "\improper Mining Office" @@ -17568,6 +17412,7 @@ name = "Mining Dock"; req_access_txt = "48" }, +/obj/structure/fans/tiny, /turf/simulated/floor/plasteel, /area/quartermaster/miningdock{ name = "\improper Mining Office" @@ -17608,6 +17453,7 @@ /obj/effect/landmark/start{ name = "Shaft Miner" }, +/obj/structure/disposalpipe/segment, /turf/simulated/floor/plasteel, /area/quartermaster/miningdock{ name = "\improper Mining Office" @@ -17814,6 +17660,7 @@ id_tag = "s_docking_airlock"; name = "Labor Shuttle Airlock" }, +/obj/structure/fans/tiny, /turf/simulated/shuttle/floor, /area/shuttle/siberia) "aFe" = ( @@ -17821,6 +17668,7 @@ id_tag = "laborcamp_home"; name = "Labor Camp Shuttle Airlock" }, +/obj/structure/fans/tiny, /turf/simulated/floor/plasteel{ icon_state = "dark" }, @@ -18413,6 +18261,7 @@ d2 = 2; icon_state = "1-2" }, +/obj/structure/disposalpipe/segment, /turf/simulated/floor/plasteel, /area/quartermaster/miningdock{ name = "\improper Mining Office" @@ -18457,7 +18306,6 @@ d2 = 2; icon_state = "1-2" }, -/obj/structure/disposalpipe/segment, /obj/effect/decal/cleanable/dirt, /turf/simulated/floor/plating, /area/maintenance/fpmaint2{ @@ -18621,6 +18469,10 @@ name = "Brig"; req_access_txt = "63" }, +/obj/effect/mapping_helpers/airlock/unres{ + icon_state = "airlock_unres_helper"; + dir = 1 + }, /turf/simulated/floor/plasteel{ icon_state = "red"; dir = 1 @@ -18662,6 +18514,10 @@ name = "Brig"; req_access_txt = "63" }, +/obj/effect/mapping_helpers/airlock/unres{ + icon_state = "airlock_unres_helper"; + dir = 1 + }, /turf/simulated/floor/plasteel{ icon_state = "red"; dir = 1 @@ -18908,9 +18764,8 @@ layer = 2.9 }, /obj/item/clothing/shoes/magboots, -/obj/item/clothing/suit/space/hardsuit/engineering, +/obj/item/clothing/suit/space/hardsuit/engine, /obj/item/clothing/mask/breath, -/obj/item/clothing/head/helmet/space/hardsuit/engineering, /obj/effect/decal/warning_stripes/yellow/hollow, /turf/simulated/floor/plasteel, /area/engine/engineering) @@ -19039,10 +18894,6 @@ "aHk" = ( /turf/simulated/wall, /area/construction) -"aHl" = ( -/obj/machinery/door/airlock/external, -/turf/simulated/floor/plating, -/area/construction) "aHm" = ( /obj/structure/closet/crate, /obj/item/coin/silver, @@ -19134,18 +18985,6 @@ /obj/machinery/atmospherics/pipe/simple/hidden/supply, /obj/effect/decal/cleanable/dirt, /turf/simulated/floor/plating, -/area/maintenance/fpmaint2{ - name = "Port Maintenance" - }) -"aHw" = ( -/obj/structure/cable/yellow{ - d1 = 1; - d2 = 2; - icon_state = "1-2" - }, -/obj/structure/disposalpipe/segment, -/obj/effect/decal/cleanable/dirt, -/turf/simulated/floor/plating, /area/maintenance/fpmaint2{ name = "Port Maintenance" }) @@ -19698,9 +19537,8 @@ layer = 2.9 }, /obj/item/clothing/shoes/magboots, -/obj/item/clothing/suit/space/hardsuit/engineering, +/obj/item/clothing/suit/space/hardsuit/engine, /obj/item/clothing/mask/breath, -/obj/item/clothing/head/helmet/space/hardsuit/engineering, /obj/effect/decal/warning_stripes/yellow/hollow, /turf/simulated/floor/plasteel, /area/engine/engineering) @@ -19942,6 +19780,7 @@ /obj/machinery/atmospherics/pipe/simple/hidden/supply{ dir = 10 }, +/obj/structure/disposalpipe/segment, /turf/simulated/floor/plasteel, /area/quartermaster/miningdock{ name = "\improper Mining Office" @@ -19995,6 +19834,9 @@ "aIU" = ( /obj/effect/decal/warning_stripes/west, /obj/effect/decal/cleanable/dirt, +/obj/machinery/atmospherics/pipe/simple/visible{ + dir = 9 + }, /turf/simulated/floor/plating, /area/maintenance/fpmaint2{ name = "Port Maintenance" @@ -20496,17 +20338,6 @@ }, /turf/simulated/floor/plating/airless, /area/space/nearstation) -"aJK" = ( -/obj/structure/sign/securearea{ - desc = "A warning sign which reads 'EXTERNAL AIRLOCK'"; - icon_state = "space"; - layer = 4; - name = "EXTERNAL AIRLOCK"; - pixel_x = 32 - }, -/obj/effect/decal/warning_stripes/north, -/turf/simulated/floor/plating, -/area/construction) "aJL" = ( /obj/effect/decal/warning_stripes/southwest, /turf/simulated/floor/plasteel, @@ -20711,6 +20542,7 @@ /obj/machinery/atmospherics/pipe/simple/hidden/supply{ req_access_txt = 1 }, +/obj/structure/disposalpipe/segment, /turf/simulated/floor/plasteel{ dir = 2; icon_state = "brown" @@ -22277,6 +22109,7 @@ d2 = 4; icon_state = "1-4" }, +/obj/structure/disposalpipe/segment, /turf/simulated/floor/plasteel, /area/quartermaster/storage) "aMT" = ( @@ -23822,6 +23655,7 @@ dir = 4; on = 1 }, +/obj/structure/disposalpipe/segment, /turf/simulated/floor/plasteel, /area/quartermaster/storage) "aPK" = ( @@ -25313,6 +25147,7 @@ /obj/effect/landmark/start{ name = "Cargo Technician" }, +/obj/structure/disposalpipe/segment, /turf/simulated/floor/plasteel, /area/quartermaster/storage) "aSA" = ( @@ -29954,9 +29789,8 @@ layer = 2.9 }, /obj/item/clothing/shoes/magboots, -/obj/item/clothing/suit/space/hardsuit/engineering, +/obj/item/clothing/suit/space/hardsuit/engine, /obj/item/clothing/mask/breath, -/obj/item/clothing/head/helmet/space/hardsuit/engineering, /obj/effect/decal/warning_stripes/west, /turf/simulated/floor/plasteel, /area/engine/engineering) @@ -30850,9 +30684,8 @@ layer = 2.9 }, /obj/item/clothing/shoes/magboots, -/obj/item/clothing/suit/space/hardsuit/engineering, +/obj/item/clothing/suit/space/hardsuit/engine, /obj/item/clothing/mask/breath, -/obj/item/clothing/head/helmet/space/hardsuit/engineering, /obj/effect/decal/warning_stripes/southwest, /turf/simulated/floor/plasteel, /area/engine/engineering) @@ -30984,6 +30817,7 @@ /area/engine/engineering) "bcs" = ( /obj/machinery/hologram/holopad, +/obj/structure/disposalpipe/segment, /turf/simulated/floor/plasteel, /area/quartermaster/storage) "bct" = ( @@ -31330,6 +31164,7 @@ maxcharge = 15000 }, /obj/effect/decal/warning_stripes/northwest, +/obj/item/rcs, /turf/simulated/floor/plasteel, /area/quartermaster/storage) "bcW" = ( @@ -32774,6 +32609,10 @@ d2 = 8; icon_state = "4-8" }, +/obj/structure/disposalpipe/segment{ + dir = 4; + icon_state = "pipe-c" + }, /turf/simulated/floor/plating, /area/quartermaster/storage) "bfp" = ( @@ -33597,6 +33436,10 @@ }) "bgC" = ( /obj/effect/decal/warning_stripes/south, +/obj/machinery/telepad, +/obj/structure/disposalpipe/segment{ + dir = 4 + }, /turf/simulated/floor/plasteel, /area/quartermaster/storage) "bgD" = ( @@ -33686,14 +33529,11 @@ icon_state = "1-8" }, /obj/effect/decal/warning_stripes/southwest, +/obj/structure/disposalpipe/segment{ + dir = 4 + }, /turf/simulated/floor/plasteel, /area/quartermaster/storage) -"bgL" = ( -/obj/machinery/door/airlock/external{ - req_access_txt = "13" - }, -/turf/simulated/floor/plating, -/area/engine/engineering) "bgM" = ( /obj/structure/window/reinforced{ dir = 4 @@ -33813,6 +33653,10 @@ pixel_y = -2 }, /obj/effect/decal/warning_stripes/south, +/obj/structure/disposalpipe/segment{ + dir = 8; + icon_state = "pipe-c" + }, /turf/simulated/floor/plasteel, /area/quartermaster/storage) "bgW" = ( @@ -34764,15 +34608,19 @@ dir = 4 }, /obj/machinery/space_heater, +/obj/structure/disposalpipe/segment{ + dir = 4; + icon_state = "pipe-c" + }, /turf/simulated/floor/plating, /area/maintenance/fpmaint2{ name = "Port Maintenance" }) "biD" = ( /obj/structure/disposalpipe/segment{ - dir = 4; - icon_state = "pipe-c" + dir = 4 }, +/obj/structure/disposalpipe/segment, /turf/simulated/wall, /area/quartermaster/office{ name = "\improper Cargo Office" @@ -35619,6 +35467,9 @@ pixel_y = 32 }, /obj/effect/decal/warning_stripes/east, +/obj/machinery/atmospherics/pipe/simple/visible{ + dir = 4 + }, /turf/simulated/floor/plating, /area/engine/engineering) "bjU" = ( @@ -35904,6 +35755,7 @@ req_access_txt = "50" }, /obj/structure/disposalpipe/segment, +/obj/structure/disposalpipe/segment, /turf/simulated/floor/plating, /area/quartermaster/office{ name = "\improper Cargo Office" @@ -36854,13 +36706,18 @@ /obj/machinery/atmospherics/pipe/simple/hidden/supply{ dir = 10 }, +/obj/structure/disposalpipe/wrapsortjunction{ + dir = 1 + }, /turf/simulated/floor/plating, /area/maintenance/fpmaint2{ name = "Port Maintenance" }) "bmf" = ( -/obj/structure/disposalpipe/wrapsortjunction{ - dir = 1 +/obj/structure/disposalpipe/junction{ + dir = 4; + icon_state = "pipe-j2"; + tag = "icon-pipe-j1 (WEST)" }, /turf/simulated/wall, /area/quartermaster/office{ @@ -37920,9 +37777,8 @@ layer = 2.9 }, /obj/item/clothing/shoes/magboots/advance, -/obj/item/clothing/suit/space/hardsuit/elite, +/obj/item/clothing/suit/space/hardsuit/engine/elite, /obj/item/clothing/mask/breath, -/obj/item/clothing/head/helmet/space/hardsuit/elite, /turf/simulated/floor/plasteel{ icon_state = "vault"; dir = 5 @@ -37992,45 +37848,7 @@ }, /turf/simulated/floor/bluegrid, /area/turret_protected/ai) -"bnR" = ( -/obj/machinery/door/airlock/external{ - name = "MiniSat External Access"; - req_access = null; - req_access_txt = "75;13" - }, -/turf/simulated/floor/plasteel{ - icon_state = "vault"; - dir = 8 - }, -/area/construction/hallway{ - name = "\improper MiniSat Exterior" - }) -"bnS" = ( -/obj/machinery/atmospherics/pipe/simple/hidden/supply{ - dir = 4; - level = 1 - }, -/obj/machinery/door/window/eastright{ - base_state = "left"; - dir = 4; - icon_state = "left"; - name = "MiniSat Walkway Access"; - req_access_txt = "13;75" - }, -/turf/simulated/floor/plasteel{ - icon_state = "vault"; - dir = 8 - }, -/area/construction/hallway{ - name = "\improper MiniSat Exterior" - }) "bnT" = ( -/obj/machinery/atmospherics/unary/vent_pump{ - dir = 4; - external_pressure_bound = 101; - on = 1; - pressure_checks = 1 - }, /obj/machinery/light/small{ dir = 1 }, @@ -38041,21 +37859,6 @@ /area/construction/hallway{ name = "\improper MiniSat Exterior" }) -"bnU" = ( -/obj/structure/window/reinforced{ - dir = 4 - }, -/obj/machinery/atmospherics/pipe/manifold/hidden/supply{ - dir = 4; - initialize_directions = 11; - level = 1 - }, -/turf/simulated/floor/plasteel{ - icon_state = "dark" - }, -/area/construction/hallway{ - name = "\improper MiniSat Exterior" - }) "bnV" = ( /obj/effect/landmark{ name = "Observer-Start" @@ -38139,6 +37942,7 @@ name = "blobstart" }, /obj/effect/decal/warning_stripes/east, +/obj/structure/disposalpipe/segment, /turf/simulated/floor/plating, /area/maintenance/fpmaint2{ name = "Port Maintenance" @@ -38162,6 +37966,7 @@ }) "boe" = ( /obj/machinery/atmospherics/pipe/simple/hidden/supply, +/obj/structure/disposalpipe/segment, /turf/simulated/wall, /area/maintenance/fpmaint2{ name = "Port Maintenance" @@ -38236,6 +38041,7 @@ /obj/machinery/light_switch{ pixel_x = 27 }, +/obj/item/rcs, /turf/simulated/floor/plasteel{ icon_state = "arrival"; dir = 4 @@ -39114,6 +38920,7 @@ icon_state = "map-left-MS"; pixel_y = 32 }, +/obj/structure/disposalpipe/segment, /turf/simulated/floor/plasteel{ icon_state = "neutral"; dir = 1 @@ -40044,19 +39851,6 @@ /area/construction/hallway{ name = "\improper MiniSat Exterior" }) -"brg" = ( -/obj/machinery/door/window/eastright{ - dir = 4; - name = "MiniSat Walkway Access"; - req_access_txt = "13;75" - }, -/turf/simulated/floor/plasteel{ - icon_state = "vault"; - dir = 8 - }, -/area/construction/hallway{ - name = "\improper MiniSat Exterior" - }) "brh" = ( /obj/structure/window/reinforced{ dir = 4 @@ -40305,6 +40099,7 @@ /obj/machinery/atmospherics/pipe/simple/hidden/scrubbers{ dir = 10 }, +/obj/structure/disposalpipe/segment, /turf/simulated/floor/plasteel{ dir = 8; icon_state = "neutralcorner" @@ -40312,7 +40107,6 @@ /area/hallway/primary/port) "brF" = ( /obj/machinery/atmospherics/pipe/simple/hidden/supply, -/obj/structure/disposalpipe/segment, /turf/simulated/floor/plasteel{ icon_state = "neutral"; dir = 4 @@ -41354,9 +41148,10 @@ icon_state = "1-2" }, /obj/machinery/atmospherics/pipe/simple/hidden/scrubbers, -/obj/structure/disposalpipe/segment{ - dir = 4; - icon_state = "pipe-c" +/obj/structure/disposalpipe/junction{ + dir = 1; + icon_state = "pipe-j1"; + tag = "icon-pipe-j1 (EAST)" }, /turf/simulated/floor/plasteel{ icon_state = "neutral"; @@ -41364,14 +41159,13 @@ }, /area/hallway/primary/port) "btt" = ( -/obj/structure/disposalpipe/junction{ - dir = 1; - icon_state = "pipe-j2"; - tag = "icon-pipe-j1 (WEST)" - }, /obj/machinery/atmospherics/pipe/simple/hidden/supply{ dir = 5 }, +/obj/structure/disposalpipe/segment{ + dir = 2; + icon_state = "pipe-c" + }, /turf/simulated/floor/plasteel{ dir = 4; icon_state = "neutralcorner" @@ -41581,7 +41375,6 @@ /obj/structure/extinguisher_cabinet{ pixel_x = 30 }, -/obj/structure/disposalpipe/segment, /obj/machinery/atmospherics/pipe/simple/hidden/supply{ dir = 10 }, @@ -59958,8 +59751,7 @@ /obj/structure/rack, /obj/item/clothing/shoes/magboots, /obj/item/clothing/mask/breath, -/obj/item/clothing/suit/space/hardsuit/atmos, -/obj/item/clothing/head/helmet/space/hardsuit/atmos, +/obj/item/clothing/suit/space/hardsuit/engine/atmos, /obj/effect/decal/warning_stripes/west, /turf/simulated/floor/plasteel, /area/atmos) @@ -61905,7 +61697,6 @@ name = "Station Intercom (General)"; pixel_y = 28 }, -/obj/machinery/pipedispenser/disposal, /obj/effect/decal/warning_stripes/southeast, /turf/simulated/floor/plasteel, /area/atmos) @@ -62048,8 +61839,7 @@ /obj/structure/rack, /obj/item/clothing/shoes/magboots, /obj/item/clothing/mask/breath, -/obj/item/clothing/suit/space/hardsuit/atmos, -/obj/item/clothing/head/helmet/space/hardsuit/atmos, +/obj/item/clothing/suit/space/hardsuit/engine/atmos, /turf/simulated/floor/plasteel{ dir = 9; icon_state = "caution" @@ -62062,8 +61852,7 @@ /obj/structure/rack, /obj/item/clothing/shoes/magboots, /obj/item/clothing/mask/breath, -/obj/item/clothing/suit/space/hardsuit/atmos, -/obj/item/clothing/head/helmet/space/hardsuit/atmos, +/obj/item/clothing/suit/space/hardsuit/engine/atmos, /turf/simulated/floor/plasteel{ dir = 1; icon_state = "caution" @@ -62855,7 +62644,6 @@ /turf/simulated/floor/plating, /area/maintenance/starboard) "cdq" = ( -/obj/machinery/pipedispenser, /obj/effect/decal/warning_stripes/southwest, /turf/simulated/floor/plasteel, /area/atmos) @@ -63755,6 +63543,10 @@ name = "EXTERNAL AIRLOCK"; pixel_x = 32 }, +/obj/machinery/atmospherics/unary/portables_connector{ + dir = 8 + }, +/obj/machinery/portable_atmospherics/canister/air, /turf/simulated/floor/plating, /area/maintenance/portsolar) "ceX" = ( @@ -63857,6 +63649,10 @@ icon_state = "2-8" }, /obj/effect/decal/warning_stripes/south, +/obj/machinery/atmospherics/pipe/simple/visible{ + dir = 6; + level = 2 + }, /turf/simulated/floor/plating, /area/maintenance/portsolar) "cff" = ( @@ -63961,11 +63757,6 @@ d2 = 2; icon_state = "1-2" }, -/obj/machinery/door/airlock/external{ - name = "Solar Maintenance"; - req_access = null; - req_access_txt = "10; 13" - }, /turf/simulated/floor/plating, /area/maintenance/portsolar) "cfm" = ( @@ -65992,17 +65783,9 @@ }, /area/maintenance/incinerator) "ciI" = ( -/obj/structure/sign/securearea{ - desc = "A warning sign which reads 'EXTERNAL AIRLOCK'"; - icon_state = "space"; - layer = 4; - name = "EXTERNAL AIRLOCK"; - pixel_y = -32 - }, /obj/machinery/light/small{ dir = 1 }, -/obj/effect/decal/warning_stripes/east, /turf/simulated/floor/plating, /area/atmos) "ciJ" = ( @@ -66228,13 +66011,6 @@ /area/security/checkpoint/science{ name = "Security Post - Research Division" }) -"ciY" = ( -/obj/machinery/door/airlock/external{ - req_access_txt = "24"; - req_one_access_txt = "0" - }, -/turf/simulated/floor/plating, -/area/atmos) "ciZ" = ( /obj/machinery/disposal{ pixel_x = -2; @@ -66787,19 +66563,6 @@ /area/security/checkpoint/science{ name = "Security Post - Research Division" }) -"cjT" = ( -/obj/structure/sign/securearea{ - desc = "A warning sign which reads 'EXTERNAL AIRLOCK'"; - icon_state = "space"; - layer = 4; - name = "EXTERNAL AIRLOCK"; - pixel_y = 32 - }, -/obj/effect/decal/warning_stripes/west, -/turf/simulated/floor/plating, -/area/maintenance/aft{ - name = "Aft Maintenance" - }) "cjU" = ( /obj/machinery/atmospherics/pipe/simple/hidden/supply{ req_access_txt = 1 @@ -67052,14 +66815,6 @@ /area/medical/research{ name = "Research Division" }) -"ckt" = ( -/obj/machinery/door/airlock/external{ - req_access_txt = "13" - }, -/turf/simulated/floor/plating, -/area/maintenance/aft{ - name = "Aft Maintenance" - }) "cku" = ( /obj/machinery/firealarm{ dir = 1; @@ -69196,13 +68951,6 @@ /obj/effect/decal/warning_stripes/west, /turf/simulated/floor/plating, /area/maintenance/starboard) -"cnS" = ( -/obj/structure/closet/emcloset, -/obj/effect/decal/warning_stripes/north, -/turf/simulated/floor/plating, -/area/maintenance/aft{ - name = "Aft Maintenance" - }) "cnT" = ( /obj/machinery/chem_heater{ pixel_x = -4; @@ -70317,6 +70065,7 @@ name = "Medbay"; req_access_txt = "5" }, +/obj/effect/mapping_helpers/airlock/unres, /turf/simulated/floor/plasteel{ icon_state = "whitebluefull" }, @@ -70329,6 +70078,7 @@ name = "Medbay"; req_access_txt = "5" }, +/obj/effect/mapping_helpers/airlock/unres, /turf/simulated/floor/plasteel{ icon_state = "whitebluefull" }, @@ -73975,7 +73725,7 @@ /obj/machinery/door/firedoor, /obj/machinery/door/airlock/research{ name = "Research and Development Lab"; - req_access_txt = "7" + req_access_txt = "47" }, /turf/simulated/floor/plasteel{ dir = 4; @@ -78196,15 +77946,6 @@ icon_state = "white" }, /area/medical/surgeryobs) -"cCe" = ( -/obj/structure/closet/crate, -/obj/item/coin/silver, -/obj/item/flashlight/seclite, -/obj/effect/spawner/lootdrop/maintenance, -/turf/simulated/floor/plating, -/area/maintenance/aft{ - name = "Aft Maintenance" - }) "cCf" = ( /obj/structure/cable{ d1 = 1; @@ -79072,7 +78813,6 @@ /obj/item/clothing/shoes/magboots, /obj/item/clothing/suit/space/hardsuit/medical, /obj/item/clothing/mask/breath, -/obj/item/clothing/head/helmet/space/hardsuit/medical, /obj/item/radio/intercom{ dir = 1; name = "Station Intercom (General)"; @@ -79238,9 +78978,8 @@ }, /area/crew_quarters/hor) "cDM" = ( -/obj/machinery/door/airlock/external{ - req_access_txt = "0"; - req_one_access_txt = "13,8" +/obj/machinery/atmospherics/pipe/simple/visible{ + dir = 5 }, /turf/simulated/floor/plating, /area/maintenance/aft{ @@ -79366,6 +79105,10 @@ req_access_txt = "0"; req_one_access_txt = "5" }, +/obj/effect/mapping_helpers/airlock/unres{ + icon_state = "airlock_unres_helper"; + dir = 4 + }, /turf/simulated/floor/plasteel{ icon_state = "whitebluefull" }, @@ -79990,13 +79733,6 @@ /obj/machinery/light/small{ dir = 1 }, -/obj/structure/sign/securearea{ - desc = "A warning sign which reads 'EXTERNAL AIRLOCK'"; - icon_state = "space"; - layer = 4; - name = "EXTERNAL AIRLOCK"; - pixel_y = 32 - }, /turf/simulated/floor/plating, /area/maintenance/aft{ name = "Aft Maintenance" @@ -80138,22 +79874,6 @@ icon_state = "gcircuit" }, /area/assembly/chargebay) -"cFp" = ( -/obj/structure/sign/securearea{ - desc = "A warning sign which reads 'EXTERNAL AIRLOCK'"; - icon_state = "space"; - layer = 4; - name = "EXTERNAL AIRLOCK"; - pixel_y = 32 - }, -/obj/machinery/light/small{ - dir = 1 - }, -/obj/effect/decal/warning_stripes/east, -/turf/simulated/floor/plating, -/area/maintenance/aft{ - name = "Aft Maintenance" - }) "cFq" = ( /obj/machinery/door/window/westleft{ base_state = "right"; @@ -84411,20 +84131,8 @@ d2 = 2; icon_state = "0-2" }, -/obj/structure/table, -/obj/item/paper_bin{ - pixel_x = -2; - pixel_y = 4 - }, -/obj/item/assembly/prox_sensor{ - pixel_x = -8; - pixel_y = 4 - }, -/obj/item/assembly/prox_sensor{ - pixel_x = -8; - pixel_y = 4 - }, /obj/effect/decal/warning_stripes/yellow, +/obj/machinery/photocopier, /turf/simulated/floor/plasteel, /area/assembly/robotics) "cMo" = ( @@ -84995,6 +84703,14 @@ pixel_x = 32 }, /obj/effect/decal/warning_stripes/yellow, +/obj/item/assembly/prox_sensor{ + pixel_x = -8; + pixel_y = 4 + }, +/obj/item/assembly/prox_sensor{ + pixel_x = -8; + pixel_y = 4 + }, /turf/simulated/floor/plasteel, /area/assembly/robotics) "cMY" = ( @@ -85252,6 +84968,11 @@ pixel_x = -27 }, /obj/effect/decal/warning_stripes/west, +/obj/item/paper_bin{ + pixel_x = -2; + pixel_y = 4 + }, +/obj/structure/table, /turf/simulated/floor/plasteel, /area/assembly/robotics) "cNv" = ( @@ -85624,10 +85345,9 @@ pixel_x = 4; pixel_y = -4 }, -/obj/item/radio/headset/headset_sci{ - pixel_x = -3 - }, /obj/effect/decal/warning_stripes/yellow, +/obj/item/storage/firstaid/machine, +/obj/item/storage/firstaid/machine, /turf/simulated/floor/plasteel, /area/assembly/robotics) "cNZ" = ( @@ -85955,10 +85675,8 @@ name = "Aft Maintenance" }) "cOx" = ( -/obj/structure/rack, -/obj/item/clothing/mask/gas, -/obj/item/clothing/glasses/sunglasses, -/obj/effect/spawner/lootdrop/maintenance, +/obj/machinery/portable_atmospherics/canister/air, +/obj/machinery/atmospherics/unary/portables_connector, /turf/simulated/floor/plating, /area/maintenance/aft{ name = "Aft Maintenance" @@ -86209,6 +85927,7 @@ /obj/item/razor{ pixel_y = 5 }, +/obj/item/bonegel, /turf/simulated/floor/plasteel{ dir = 4; icon_state = "whitehall" @@ -86253,13 +85972,10 @@ /obj/structure/window/reinforced{ dir = 8 }, -/obj/structure/table, -/obj/item/storage/box/bodybags{ - pixel_x = 2; - pixel_y = 2 - }, -/obj/item/borg/upgrade/rename, /obj/effect/decal/warning_stripes/yellow, +/obj/structure/closet/secure_closet/roboticist{ + pixel_x = 2 + }, /turf/simulated/floor/plasteel, /area/assembly/robotics) "cOX" = ( @@ -86818,6 +86534,12 @@ name = "Station Intercom (General)"; pixel_x = -29 }, +/obj/item/cautery, +/obj/item/bonesetter, +/obj/item/reagent_containers/spray/cleaner{ + desc = "Someone has crossed out the Space from Space Cleaner and written in Surgery. 'Do not remove under punishment of death!!!' is scrawled on the back."; + name = "Surgery Cleaner" + }, /turf/simulated/floor/plasteel{ dir = 4; icon_state = "whitecorner" @@ -86832,12 +86554,16 @@ dir = 1; pixel_y = 1 }, -/obj/item/robotanalyzer, /obj/item/storage/box/gloves, /obj/item/storage/box/masks{ pixel_x = 6; pixel_y = 6 }, +/obj/item/storage/box/bodybags{ + pixel_x = 2; + pixel_y = 2 + }, +/obj/item/robotanalyzer, /obj/item/robotanalyzer, /turf/simulated/floor/plasteel{ dir = 8; @@ -87168,24 +86894,6 @@ /area/toxins/server{ name = "\improper Research Division Server Room" }) -"cQr" = ( -/obj/structure/sign/securearea{ - desc = "A warning sign which reads 'EXTERNAL AIRLOCK'"; - icon_state = "space"; - layer = 4; - name = "EXTERNAL AIRLOCK"; - pixel_y = -32 - }, -/obj/structure/cable/yellow{ - d1 = 4; - d2 = 8; - icon_state = "4-8" - }, -/obj/effect/decal/warning_stripes/east, -/turf/simulated/floor/plating, -/area/maintenance/aft{ - name = "Aft Maintenance" - }) "cQs" = ( /obj/machinery/atmospherics/pipe/simple/hidden/supply, /turf/simulated/floor/plasteel{ @@ -87338,6 +87046,9 @@ icon_state = "4-8" }, /obj/effect/decal/warning_stripes/east, +/obj/machinery/atmospherics/pipe/simple/visible{ + dir = 5 + }, /turf/simulated/floor/plating, /area/maintenance/aft{ name = "Aft Maintenance" @@ -88519,6 +88230,8 @@ dir = 1; network = list("SS13","RD") }, +/obj/item/tank/anesthetic, +/obj/item/clothing/mask/breath/medical, /turf/simulated/floor/plasteel{ dir = 1; icon_state = "whitehall" @@ -88983,14 +88696,6 @@ /area/hallway/secondary/exit{ name = "\improper Departure Lounge" }) -"cTj" = ( -/obj/machinery/door/airlock/external{ - name = "Auxiliary Escape Airlock" - }, -/turf/simulated/floor/plating, -/area/maintenance/aft{ - name = "Aft Maintenance" - }) "cTk" = ( /obj/structure/sign/biohazard, /turf/simulated/wall, @@ -89096,16 +88801,12 @@ name = "\improper Departure Lounge" }) "cTu" = ( -/obj/machinery/power/solar_control{ - id = "aftstarboard"; - name = "Aft Starboard Solar Control"; - track = 0 - }, /obj/structure/cable{ - icon_state = "0-4"; - d2 = 4 + d1 = 1; + d2 = 2; + icon_state = "1-2" }, -/obj/structure/cable, +/obj/structure/chair/stool, /turf/simulated/floor/plating, /area/maintenance/starboardsolar) "cTv" = ( @@ -89294,14 +88995,10 @@ }, /area/chapel/main) "cTN" = ( -/obj/machinery/power/apc{ - cell_type = 5000; - dir = 2; - name = "Aft Maintenance APC"; - pixel_y = -24 +/obj/machinery/atmospherics/unary/portables_connector{ + dir = 8 }, -/obj/structure/cable/yellow, -/obj/effect/decal/warning_stripes/south, +/obj/machinery/portable_atmospherics/canister/air, /turf/simulated/floor/plating, /area/maintenance/aft{ name = "Aft Maintenance" @@ -89486,7 +89183,6 @@ name = "Aft Maintenance" }) "cUd" = ( -/obj/structure/chair/stool, /obj/structure/cable{ d1 = 2; d2 = 4; @@ -90002,13 +89698,8 @@ }, /area/chapel/office) "cUQ" = ( -/obj/structure/sign/securearea{ - desc = "A warning sign which reads 'EXTERNAL AIRLOCK'"; - icon_state = "space"; - layer = 4; - name = "EXTERNAL AIRLOCK"; - pixel_x = 32 - }, +/obj/machinery/portable_atmospherics/canister/air, +/obj/machinery/atmospherics/unary/portables_connector, /turf/simulated/floor/plating, /area/maintenance/starboardsolar) "cUR" = ( @@ -90306,12 +89997,6 @@ name = "Aft Maintenance" }) "cVr" = ( -/obj/structure/cable{ - d1 = 2; - d2 = 8; - icon_state = "2-8" - }, -/obj/effect/decal/warning_stripes/south, /turf/simulated/floor/plating, /area/maintenance/starboardsolar) "cVs" = ( @@ -90651,15 +90336,6 @@ icon_state = "chapel" }, /area/chapel/main) -"cVY" = ( -/obj/structure/sign/vacuum{ - pixel_x = 32 - }, -/obj/effect/decal/warning_stripes/south, -/turf/simulated/floor/plating, -/area/maintenance/aft{ - name = "Aft Maintenance" - }) "cVZ" = ( /obj/machinery/atmospherics/pipe/simple/hidden/supply{ dir = 6 @@ -90973,15 +90649,6 @@ /area/hallway/secondary/exit{ name = "\improper Departure Lounge" }) -"cWC" = ( -/obj/structure/cable{ - d1 = 1; - d2 = 4; - icon_state = "1-4" - }, -/obj/effect/decal/warning_stripes/south, -/turf/simulated/floor/plating, -/area/maintenance/starboardsolar) "cWD" = ( /obj/structure/chair{ dir = 8 @@ -91096,14 +90763,9 @@ }) "cWK" = ( /obj/structure/cable{ - d1 = 1; - d2 = 2; - icon_state = "1-2" - }, -/obj/machinery/door/airlock/external{ - name = "Solar Maintenance"; - req_access = null; - req_access_txt = "10; 13" + d1 = 4; + d2 = 8; + icon_state = "4-8" }, /turf/simulated/floor/plating, /area/maintenance/starboardsolar) @@ -91620,19 +91282,6 @@ /area/hallway/secondary/exit{ name = "\improper Departure Lounge" }) -"cXC" = ( -/obj/machinery/door/airlock/external{ - name = "Solar Maintenance"; - req_access = null; - req_access_txt = "10; 13" - }, -/obj/structure/cable{ - d1 = 4; - d2 = 8; - icon_state = "4-8" - }, -/turf/simulated/floor/plating, -/area/maintenance/starboardsolar) "cXD" = ( /obj/structure/chair, /obj/effect/landmark/start{ @@ -91664,25 +91313,6 @@ icon_state = "dark" }, /area/chapel/main) -"cXG" = ( -/obj/structure/cable/yellow{ - d1 = 4; - d2 = 8; - icon_state = "4-8" - }, -/obj/machinery/atmospherics/pipe/simple/hidden/supply{ - dir = 4 - }, -/obj/structure/cable/yellow{ - d1 = 2; - d2 = 4; - icon_state = "2-4" - }, -/obj/effect/decal/warning_stripes/north, -/turf/simulated/floor/plating, -/area/maintenance/aft{ - name = "Aft Maintenance" - }) "cXH" = ( /obj/structure/cable/yellow{ d1 = 1; @@ -91750,13 +91380,9 @@ name = "\improper Departure Lounge" }) "cXN" = ( -/obj/structure/cable{ - d1 = 4; - d2 = 8; - icon_state = "4-8" - }, -/obj/structure/lattice/catwalk, -/turf/space, +/obj/effect/spawner/window/reinforced, +/obj/effect/spawner/airlock/w_to_e, +/turf/simulated/floor/plating, /area/solar/starboard) "cXO" = ( /obj/machinery/atmospherics/pipe/simple/hidden/supply{ @@ -92016,12 +91642,12 @@ }, /area/chapel/main) "cYi" = ( -/obj/structure/cable{ - d1 = 2; - d2 = 8; - icon_state = "2-8" - }, /obj/structure/lattice/catwalk, +/obj/structure/cable{ + d1 = 1; + d2 = 2; + icon_state = "1-2" + }, /turf/space, /area/solar/starboard) "cYj" = ( @@ -97506,12 +97132,401 @@ }, /turf/simulated/floor/plating, /area/maintenance/fore) +"djL" = ( +/obj/machinery/atmospherics/unary/portables_connector, +/obj/machinery/portable_atmospherics/canister/air, +/turf/simulated/floor/plating, +/area/security/permabrig) +"dAH" = ( +/obj/machinery/atmospherics/pipe/simple/visible{ + dir = 5 + }, +/turf/simulated/floor/plating, +/area/maintenance/starboard) +"dMV" = ( +/obj/machinery/atmospherics/pipe/manifold/visible/cyan{ + dir = 8; + initialize_directions = 11 + }, +/turf/simulated/floor/plasteel{ + icon_state = "dark" + }, +/area/atmos) +"elK" = ( +/obj/effect/spawner/airlock/w_to_e, +/turf/simulated/wall/r_wall, +/area/security/permabrig) +"eSt" = ( +/obj/structure/window/reinforced{ + dir = 1 + }, +/obj/effect/spawner/airlock/e_to_w/long/square, +/turf/space, +/area/space/nearstation) +"fmg" = ( +/obj/effect/spawner/window/reinforced, +/obj/effect/spawner/airlock, +/turf/simulated/floor/plating, +/area/maintenance/portsolar) +"fnC" = ( +/turf/space, +/area/space/nearstation) +"frX" = ( +/obj/machinery/atmospherics/pipe/simple/hidden/supply{ + dir = 4 + }, +/obj/structure/disposalpipe/segment{ + dir = 4 + }, +/obj/structure/disposalpipe/segment, +/turf/simulated/floor/plating, +/area/maintenance/fpmaint2{ + name = "Port Maintenance" + }) +"fBB" = ( +/obj/structure/lattice, +/turf/space, +/area/space) +"gRw" = ( +/obj/effect/spawner/window/reinforced, +/obj/effect/spawner/airlock/s_to_n, +/turf/simulated/floor/plating, +/area/maintenance/auxsolarstarboard) +"hLL" = ( +/obj/structure/lattice, +/turf/simulated/wall, +/area/space/nearstation) +"iDw" = ( +/obj/machinery/atmospherics/unary/portables_connector, +/obj/machinery/portable_atmospherics/canister/air, +/turf/simulated/floor/plating, +/area/maintenance/aft{ + name = "Aft Maintenance" + }) +"iTR" = ( +/obj/effect/decal/warning_stripes/south, +/obj/machinery/atmospherics/pipe/simple/visible{ + dir = 6; + level = 2 + }, +/turf/simulated/floor/plating, +/area/maintenance/aft{ + name = "Aft Maintenance" + }) +"jap" = ( +/obj/structure/disposalpipe/segment, +/turf/simulated/floor/plating, +/area/maintenance/fpmaint2{ + name = "Port Maintenance" + }) +"kBq" = ( +/obj/structure/window/reinforced, +/obj/structure/window/reinforced{ + dir = 4 + }, +/obj/structure/window/reinforced{ + dir = 1 + }, +/turf/space, +/area/space/nearstation) +"kSC" = ( +/obj/machinery/atmospherics/unary/portables_connector{ + dir = 4 + }, +/obj/machinery/portable_atmospherics/canister/air, +/turf/simulated/floor/plasteel, +/area/construction) +"kWU" = ( +/obj/machinery/atmospherics/pipe/simple/visible{ + dir = 6; + level = 2 + }, +/turf/simulated/floor/plating, +/area/engine/engineering) +"lcL" = ( +/obj/machinery/portable_atmospherics/canister/air, +/obj/machinery/atmospherics/unary/portables_connector{ + dir = 1 + }, +/turf/simulated/floor/plating, +/area/maintenance/aft{ + name = "Aft Maintenance" + }) +"lCt" = ( +/obj/structure/window/reinforced{ + dir = 4 + }, +/obj/machinery/atmospherics/pipe/simple/hidden/supply, +/obj/machinery/atmospherics/pipe/simple/visible{ + dir = 10 + }, +/turf/simulated/floor/plasteel{ + icon_state = "dark" + }, +/area/construction/hallway{ + name = "\improper MiniSat Exterior" + }) +"nbO" = ( +/obj/effect/spawner/airlock/s_to_n, +/turf/simulated/wall, +/area/construction) +"nig" = ( +/obj/effect/decal/warning_stripes/south, +/obj/structure/disposalpipe/segment{ + dir = 4 + }, +/turf/simulated/floor/plasteel, +/area/quartermaster/storage) +"onG" = ( +/obj/effect/spawner/window/reinforced, +/obj/effect/spawner/airlock/s_to_n, +/turf/simulated/floor/plating, +/area/maintenance/auxsolarport) +"oAG" = ( +/obj/effect/spawner/airlock/w_to_e, +/turf/simulated/wall, +/area/engine/engineering) +"pep" = ( +/obj/effect/spawner/airlock/s_to_n, +/turf/simulated/wall, +/area/maintenance/starboard) +"pMx" = ( +/obj/effect/spawner/airlock/w_to_e, +/turf/simulated/wall, +/area/maintenance/aft{ + name = "Aft Maintenance" + }) +"pQx" = ( +/obj/structure/cable/yellow{ + d1 = 4; + d2 = 8; + icon_state = "4-8" + }, +/obj/machinery/atmospherics/pipe/simple/hidden/supply{ + dir = 4 + }, +/obj/effect/decal/warning_stripes/east, +/obj/structure/cable/yellow{ + d1 = 2; + d2 = 4; + icon_state = "2-4" + }, +/turf/simulated/floor/plating, +/area/maintenance/aft{ + name = "Aft Maintenance" + }) +"pVq" = ( +/obj/machinery/atmospherics/pipe/simple/hidden/scrubbers{ + dir = 4 + }, +/obj/structure/disposalpipe/segment, +/turf/simulated/floor/plasteel, +/area/quartermaster/storage) +"qaM" = ( +/obj/structure/cable/yellow{ + d1 = 4; + d2 = 8; + icon_state = "4-8" + }, +/obj/structure/disposalpipe/segment, +/turf/simulated/floor/plasteel, +/area/quartermaster/storage) +"qbl" = ( +/obj/effect/spawner/airlock, +/turf/simulated/wall, +/area/maintenance/aft{ + name = "Aft Maintenance" + }) +"qcE" = ( +/obj/machinery/atmospherics/pipe/simple/visible, +/turf/simulated/floor/plating, +/area/construction) +"qhx" = ( +/obj/effect/spawner/airlock/w_to_e, +/turf/simulated/wall/r_wall, +/area/atmos) +"qFg" = ( +/obj/machinery/space_heater, +/obj/machinery/power/apc{ + cell_type = 5000; + dir = 2; + name = "Aft Maintenance APC"; + pixel_y = -24 + }, +/obj/structure/cable/yellow, +/turf/simulated/floor/plating, +/area/maintenance/aft{ + name = "Aft Maintenance" + }) +"rpg" = ( +/obj/structure/lattice/catwalk, +/obj/structure/cable{ + d1 = 2; + d2 = 8; + icon_state = "2-8" + }, +/turf/space, +/area/solar/starboard) +"rzO" = ( +/obj/machinery/portable_atmospherics/canister/air, +/obj/machinery/atmospherics/unary/portables_connector{ + dir = 1 + }, +/turf/simulated/floor/plating, +/area/engine/engineering) +"rIq" = ( +/obj/structure/table, +/obj/item/clothing/mask/breath{ + pixel_x = 4 + }, +/obj/item/tank/emergency_oxygen{ + pixel_x = -8 + }, +/turf/simulated/floor/plating, +/area/maintenance/starboard) +"rOZ" = ( +/obj/structure/lattice/catwalk, +/obj/structure/cable{ + d1 = 4; + d2 = 8; + icon_state = "4-8" + }, +/turf/space, +/area/solar/starboard) +"sjF" = ( +/obj/structure/window/reinforced{ + dir = 1 + }, +/obj/structure/window/reinforced, +/obj/machinery/atmospherics/unary/portables_connector{ + dir = 4 + }, +/obj/machinery/portable_atmospherics/canister/air, +/turf/simulated/floor/plasteel{ + icon_state = "dark" + }, +/area/space/nearstation) +"sJe" = ( +/obj/structure/window/reinforced{ + dir = 4 + }, +/obj/machinery/atmospherics/pipe/simple/hidden/supply, +/obj/machinery/atmospherics/pipe/simple/visible{ + dir = 9 + }, +/turf/simulated/floor/plasteel{ + icon_state = "dark" + }, +/area/construction/hallway{ + name = "\improper MiniSat Exterior" + }) +"sJs" = ( +/obj/effect/spawner/window/reinforced, +/turf/space, +/area/engine/engineering) +"sRB" = ( +/obj/machinery/atmospherics/pipe/simple/visible{ + dir = 10 + }, +/turf/simulated/floor/plating, +/area/maintenance/aft{ + name = "Aft Maintenance" + }) +"tlh" = ( +/obj/machinery/atmospherics/pipe/simple/visible{ + dir = 9 + }, +/turf/simulated/floor/plasteel, +/area/construction) +"twD" = ( +/obj/structure/disposalpipe/segment{ + dir = 2; + icon_state = "pipe-c" + }, +/turf/simulated/floor/plating, +/area/maintenance/fpmaint2{ + name = "Port Maintenance" + }) +"tWl" = ( +/obj/effect/spawner/window/reinforced, +/obj/effect/spawner/airlock/e_to_w, +/turf/simulated/floor/plating, +/area/maintenance/aft{ + name = "Aft Maintenance" + }) "tXL" = ( /obj/structure/chair/comfy/shuttle{ dir = 8 }, /turf/simulated/shuttle/floor4/vox, /area/shuttle/vox) +"uJn" = ( +/obj/effect/spawner/airlock/w_to_e, +/turf/simulated/wall/r_wall, +/area/maintenance/starboard) +"uKm" = ( +/obj/effect/spawner/airlock/e_to_w, +/turf/simulated/wall, +/area/maintenance/fpmaint2{ + name = "Port Maintenance" + }) +"vtP" = ( +/obj/machinery/conveyor/west{ + id = "garbage" + }, +/obj/structure/disposalpipe/segment, +/turf/simulated/floor/plating, +/area/maintenance/disposal) +"vZo" = ( +/turf/simulated/floor/plating, +/area/space/nearstation) +"wvK" = ( +/obj/structure/cable{ + d1 = 1; + d2 = 4; + icon_state = "1-4"; + tag = "90Curve" + }, +/obj/machinery/power/solar_control{ + id = "aftstarboard"; + name = "Aft Starboard Solar Control"; + track = 0 + }, +/obj/structure/cable, +/turf/simulated/floor/plating, +/area/maintenance/starboardsolar) +"wJQ" = ( +/obj/effect/decal/warning_stripes/north, +/obj/machinery/atmospherics/pipe/simple/visible{ + dir = 5 + }, +/turf/simulated/floor/plating, +/area/maintenance/starboard) +"xrG" = ( +/obj/machinery/atmospherics/pipe/simple/visible{ + dir = 5 + }, +/obj/structure/cable{ + d1 = 4; + d2 = 8; + icon_state = "4-8" + }, +/turf/simulated/floor/plating, +/area/maintenance/starboardsolar) +"xuA" = ( +/obj/machinery/atmospherics/pipe/simple/hidden/supply, +/obj/structure/disposalpipe/segment{ + dir = 1; + icon_state = "pipe-c" + }, +/turf/simulated/floor/plating, +/area/maintenance/fpmaint2{ + name = "Port Maintenance" + }) +"xZq" = ( +/obj/effect/spawner/window/reinforced, +/turf/simulated/floor/plating, +/area/solar/starboard) (1,1,1) = {" aaa @@ -107891,9 +107906,9 @@ arA arA aHk aHk +nbO aHk -aHk -aML +kSC aOk aPA aLB @@ -108146,11 +108161,11 @@ arA arA abq arA -aHl -aJK -aHl aLB -aML +aLB +aLB +qcE +tlh aLB aLB aLB @@ -109939,8 +109954,8 @@ aaa aaa abq apf -azJ -apf +apd +uKm abq aaa abq @@ -110196,7 +110211,7 @@ aaa abq abq apf -aAW +apd apf abq abq @@ -110453,7 +110468,7 @@ aaa abq apf apf -azJ +apd apf aAA alL @@ -111023,7 +111038,7 @@ cdj cdC bTY bTY -bTY +fmg aaa aaa abq @@ -112309,9 +112324,9 @@ apd apf aaa aaa -aaa -aef -aaa +cmi +chy +tWl bZU bZU cmi @@ -112566,9 +112581,9 @@ cdG apf aaa aaa -bZU -ckt -bZU +cmi +chy +cmi bZU cpu cqY @@ -112823,9 +112838,9 @@ apf apf aaa aaa -bZU -cjT -cnS +cmi +chy +cmi bZU cpv cqZ @@ -113080,9 +113095,9 @@ cdH bZU bZU bZU -bZU -clJ -bZU +cmi +sRB +lcL bZU cpw cra @@ -114075,11 +114090,11 @@ aZt aZt aZt bfo -bfw +bhc biD bku bmf -bhc +bfw btL brF btt @@ -114815,11 +114830,11 @@ amm amn any aoT -aqq +vtP arF atc aux -atk +xuA axn ayB apf @@ -114845,7 +114860,7 @@ aSm aSm bdm bdZ -bgC +nig bkE biG bpp @@ -115070,16 +115085,16 @@ aaa akI aoY alr -anx +any apc aqq arE aug aoX -apd -axo -apd -apd +twD +frX +jap +jap azO aCt aDx @@ -115090,18 +115105,18 @@ aIQ aKe azT aMS -aOr +pVq aPJ -aRo +aOu aSz -aRo -aRo -aRo +aOu +aOu +aOu aPJ -aRo -aRo +aOu +aOu bcs -bdZ +qaM bgV aXi biF @@ -116093,7 +116108,7 @@ aaa abq agX agX -agX +onG ajC akv ajE @@ -116349,8 +116364,8 @@ aiR abA abA ajN -akP -alQ +ajN +ajN anK akw alv @@ -116358,12 +116373,12 @@ amr anD ato axp -aqv +bFu ate aGj -aHw -aHw -ayE +cJU +cJU +bgY azK aAX aCu @@ -122246,7 +122261,7 @@ acw acH acH adg -adv +djL adW abB aeU @@ -122504,8 +122519,8 @@ acJ acN acN acN -adZ -abB +adv +elK adI afz aga @@ -123018,7 +123033,7 @@ abq abq abq acN -adZ +adv abB abB acs @@ -126737,7 +126752,7 @@ cXx bZU bZU bZU -bZU +qbl bZU abq abq @@ -126991,10 +127006,10 @@ cOW cPV cIx cmY -cEB -cTj -cVY -cTj +iTR +chy +chy +chy aef aef abq @@ -127247,7 +127262,7 @@ cQD cLr cLr cQP -cXG +cXx cTN bZU bZU @@ -127504,8 +127519,8 @@ cOV cPo cQO crU -cQi -cfZ +pQx +qFg bZU abq abq @@ -132647,9 +132662,9 @@ cQW cRQ cUd cTu +wvK cOy -cOy -cOy +aaa aaa aaa aaa @@ -132905,7 +132920,6 @@ cTp cUf cVr cWK -cWC cOy aaa aaa @@ -132936,6 +132950,7 @@ aaa aaa aaa aaa +aaa aaD aaa aaa @@ -133161,9 +133176,9 @@ cSQ cRS cSy cUQ +xrG cOy -cXC -cOy +aaa aaa aaa aaa @@ -133412,13 +133427,13 @@ abq abq bZU bZU -clJ -bZU -cQW -cQW +bgZ +pMx cQW cQW cQW +cOy +cWK cXN abq abq @@ -133669,14 +133684,14 @@ abq aaa abq bZU -cQr +bgZ bZU aaa abq aaa -aaa -aaa -cXN +cOy +cWK +xZq aaa abq abq @@ -133926,14 +133941,14 @@ abq aaa abq bZU -clJ +bgZ bZU aaa abq abq -abq -abq -cXN +cOy +cWK +xZq abq abq aaa @@ -134169,8 +134184,8 @@ cxf bZU cAe cEb -chy bZU +iDw cDM bZU cFJ @@ -134189,8 +134204,8 @@ aaa abq aaa aaa +rOZ aaa -cXN aaa abq aaa @@ -134426,10 +134441,10 @@ cyT cPT cfY cvW -cCe bZU -cFp bZU +cFe +pMx cFM cBN cBN @@ -134446,8 +134461,8 @@ aaa abq aaa aaa -abq -cXN +rOZ +aaa aaa abq aaa @@ -134685,7 +134700,7 @@ bZU cmi bZU bZU -cDM +chy bZU abq abq @@ -134703,8 +134718,8 @@ abq abq aaa aaa -abq -cXN +rOZ +aaa abq abq abq @@ -134941,9 +134956,9 @@ bZU aaa abq aaa -abq -aef -abq +hLL +vZo +hLL abq aaa abq @@ -134960,8 +134975,8 @@ abq abq aaa aaa +rOZ aaa -cXN abq aaa aaa @@ -135217,8 +135232,8 @@ aaa abq aaa aaa +rOZ aaa -cXN aaa aaa aaa @@ -135474,7 +135489,7 @@ aaa abq aaa aaa -abq +rpg cYi cYA cYA @@ -137688,7 +137703,7 @@ aeN aeN aoG aoG -aoG +pep aoG aoG aoG @@ -137941,12 +137956,12 @@ abq aaa aaa aaa -aaa -abq -ape -apP -aqe -aqt +aef +aef +asJ +ayx +asJ +wJQ asJ avA avz @@ -138201,7 +138216,7 @@ abq abq abq aoG -aqe +ape aoG atU asJ @@ -138458,7 +138473,7 @@ abq aaa abq aaa -aef +aaa aoG aou asJ @@ -138715,9 +138730,9 @@ abq abq abq abq -aef +abq ape -asJ +rIq asJ asJ asJ @@ -141543,7 +141558,7 @@ abq ano apg apg -apg +gRw asU auj arT @@ -141799,7 +141814,7 @@ aee aee auv arC -asL +arC arC atV auk @@ -141863,7 +141878,7 @@ bSU ceK bRi bRi -bRi +dMV ckn bCM abq @@ -142120,8 +142135,8 @@ bIt bCM bCM bCM -ciY -bCM +cja +qhx bCM abq aaa @@ -142576,7 +142591,7 @@ awM asJ asJ aoG -azv +cbX asJ arr axh @@ -142634,7 +142649,7 @@ bMk bGL abq bCM -ciY +cja bCM abq aaa @@ -142858,9 +142873,9 @@ aDi aDf aCg aCg -aOd -aDL -aaa +kWU +rzO +sJs aaa aaa aaa @@ -143091,7 +143106,7 @@ bnG aWG axh azf -asJ +dAH axh aCD aFk @@ -143117,7 +143132,7 @@ bdG aCg bjT aFR -aaa +aFR aaa aaa aaa @@ -143348,8 +143363,8 @@ blA avN aoG aoG -axg -axh +asJ +uJn aDf aWz aEG @@ -143372,9 +143387,9 @@ aDi aDi aDf aCg -bgL -aFR -aFR +aOd +oAG +aaa aaa aaa aaa @@ -143605,7 +143620,7 @@ awD avN bpl aoG -aAO +asJ axh aDl aDj @@ -143629,11 +143644,11 @@ baG bbU bhA aCg -bjT -aTR -bgL -aef -aef +aOd +aFR +aaa +fnC +fnC abq abq aaa @@ -143862,7 +143877,7 @@ blB bnH aaa aoG -axg +asJ axh aDf aDi @@ -143886,12 +143901,12 @@ aDi aDi aDf aCg -bgL -aFR +aOd aFR aaa aaa aaa +aaa abq aaa bwY @@ -144147,8 +144162,8 @@ aef abq abq abq -aaa -aaa +fBB +fBB abq aaa bwY @@ -148772,9 +148787,9 @@ abq aaa aaa aUU -bnR -bnR -bsd +blE +blE +eSt bsS buO bxq @@ -149543,10 +149558,10 @@ abd abd aaa aXN -bnS -brg -bse -aXN +blE +blE +sjF +kBq buP bxs bBc @@ -149800,9 +149815,9 @@ aXH aXH bgM bmH -bnU brh -bsf +lCt +sJe bsf buS bxv diff --git a/_maps/map_files/MetaStation/z2.dmm b/_maps/map_files/MetaStation/z2.dmm index f27926e04f9..e2ed24880f1 100644 --- a/_maps/map_files/MetaStation/z2.dmm +++ b/_maps/map_files/MetaStation/z2.dmm @@ -10,6 +10,15 @@ dir = 8 }, /area/space) +"ad" = ( +/obj/structure/flora/ausbushes/brflowers, +/turf/simulated/floor/holofloor/grass, +/turf/simulated/floor/holofloor{ + tag = "icon-wood_siding2 (EAST)"; + icon_state = "wood_siding2"; + dir = 4 + }, +/area/holodeck/source_picnicarea) "ae" = ( /turf/unsimulated/wall{ tag = "icon-iron6"; @@ -245,12 +254,12 @@ /turf/simulated/floor/holofloor/grass, /area/holodeck/source_picnicarea) "aM" = ( -/obj/structure/flora/ausbushes/brflowers, +/obj/structure/flora/ausbushes/grassybush, /turf/simulated/floor/holofloor/grass, /turf/simulated/floor/holofloor{ - tag = "icon-wood_siding2 (EAST)"; - icon_state = "wood_siding2"; - dir = 4 + tag = "icon-wood_siding5"; + icon_state = "wood_siding5"; + dir = 2 }, /area/holodeck/source_picnicarea) "aN" = ( @@ -315,8 +324,8 @@ /obj/structure/flora/ausbushes/grassybush, /turf/simulated/floor/holofloor/grass, /turf/simulated/floor/holofloor{ - tag = "icon-wood_siding5"; - icon_state = "wood_siding5"; + tag = "icon-wood_siding9"; + icon_state = "wood_siding9"; dir = 2 }, /area/holodeck/source_picnicarea) @@ -336,8 +345,8 @@ /obj/structure/flora/ausbushes/grassybush, /turf/simulated/floor/holofloor/grass, /turf/simulated/floor/holofloor{ - tag = "icon-wood_siding9"; - icon_state = "wood_siding9"; + tag = "icon-wood_siding6"; + icon_state = "wood_siding6"; dir = 2 }, /area/holodeck/source_picnicarea) @@ -388,17 +397,17 @@ /obj/structure/flora/ausbushes/grassybush, /turf/simulated/floor/holofloor/grass, /turf/simulated/floor/holofloor{ - tag = "icon-wood_siding6"; - icon_state = "wood_siding6"; + tag = "icon-wood_siding10"; + icon_state = "wood_siding10"; dir = 2 }, /area/holodeck/source_picnicarea) "bg" = ( -/obj/structure/flora/ausbushes/grassybush, +/obj/structure/flora/ausbushes/brflowers, /turf/simulated/floor/holofloor/grass, /turf/simulated/floor/holofloor{ - tag = "icon-wood_siding10"; - icon_state = "wood_siding10"; + tag = "icon-wood_siding1"; + icon_state = "wood_siding1"; dir = 2 }, /area/holodeck/source_picnicarea) @@ -458,14 +467,16 @@ }, /area/holodeck/source_picnicarea) "bp" = ( -/obj/structure/flora/ausbushes/brflowers, -/turf/simulated/floor/holofloor/grass, -/turf/simulated/floor/holofloor{ - tag = "icon-wood_siding1"; - icon_state = "wood_siding1"; - dir = 2 +/obj/structure/flora/tree/pine{ + pixel_x = 1 }, -/area/holodeck/source_picnicarea) +/turf/unsimulated/floor/snow, +/turf/unsimulated/floor/snow{ + tag = "icon-gravsnow_corner (WEST)"; + icon_state = "gravsnow_corner"; + dir = 8 + }, +/area/syndicate_mothership) "bq" = ( /turf/simulated/floor/holofloor{ tag = "icon-carpet3-0 (EAST)"; @@ -864,14 +875,14 @@ }, /area/holodeck/source_meetinghall) "cq" = ( -/obj/structure/flora/tree/pine{ - pixel_x = 1 +/obj/effect/light_emitter{ + light_power = 1 }, -/turf/unsimulated/floor/snow, -/turf/unsimulated/floor/snow{ - icon_state = "gravsnow_corner" +/turf/unsimulated/floor{ + tag = "icon-cult"; + icon_state = "cult" }, -/area/syndicate_mothership) +/area/wizard_station) "cr" = ( /obj/structure/chair/stool, /turf/simulated/floor/holofloor{ @@ -1771,6 +1782,15 @@ /obj/structure/grille, /turf/simulated/shuttle/plating, /area/centcom/evac) +"eP" = ( +/obj/structure/flora/grass/brown, +/turf/unsimulated/floor/snow, +/turf/unsimulated/floor/snow{ + tag = "icon-gravsnow_corner (SOUTHWEST)"; + icon_state = "gravsnow_corner"; + dir = 10 + }, +/area/syndicate_mothership) "eQ" = ( /obj/structure/closet/secure_closet/cargotech, /turf/unsimulated/floor{ @@ -3614,9 +3634,7 @@ }, /turf/unsimulated/floor/snow, /turf/unsimulated/floor/snow{ - tag = "icon-gravsnow_corner (WEST)"; - icon_state = "gravsnow_corner"; - dir = 8 + icon_state = "gravsnow_corner" }, /area/syndicate_mothership) "ka" = ( @@ -3747,10 +3765,12 @@ /turf/simulated/shuttle/plating, /area/wizard_station) "kr" = ( -/obj/structure/flora/tree/pine, +/obj/structure/flora/grass/brown, /turf/unsimulated/floor/snow, /turf/unsimulated/floor/snow{ - icon_state = "gravsnow_corner" + tag = "icon-gravsnow_corner (EAST)"; + icon_state = "gravsnow_corner"; + dir = 4 }, /area/syndicate_mothership) "ks" = ( @@ -3762,12 +3782,18 @@ /turf/simulated/shuttle/plating, /area/wizard_station) "kt" = ( -/obj/structure/flora/grass/brown, -/turf/unsimulated/floor/snow, -/turf/unsimulated/floor/snow{ - icon_state = "gravsnow_corner" +/obj/structure/cult/talisman{ + desc = "A altar dedicated to the Wizard's Federation" }, -/area/syndicate_mothership) +/obj/item/kitchen/knife/ritual, +/obj/effect/light_emitter{ + light_power = 1 + }, +/turf/unsimulated/floor{ + tag = "icon-cult"; + icon_state = "cult" + }, +/area/wizard_station) "ku" = ( /obj/effect/forcefield, /turf/unsimulated/floor{ @@ -3951,14 +3977,15 @@ /turf/unsimulated/wall, /area/tdome/tdomeobserve) "kW" = ( -/obj/structure/flora/grass/brown, -/turf/unsimulated/floor/snow, -/turf/unsimulated/floor/snow{ - tag = "icon-gravsnow_corner (SOUTHWEST)"; - icon_state = "gravsnow_corner"; - dir = 10 +/obj/effect/decal/cleanable/blood/splatter, +/obj/effect/decal/remains/human, +/obj/effect/light_emitter{ + light_power = 1 }, -/area/syndicate_mothership) +/turf/unsimulated/floor{ + icon_state = "floor" + }, +/area/wizard_station) "kX" = ( /turf/unsimulated/wall{ tag = "icon-uranium8"; @@ -4165,7 +4192,6 @@ /area/wizard_station) "lC" = ( /obj/structure/rack, -/obj/item/clothing/head/helmet/space/hardsuit/wizard, /turf/unsimulated/floor{ tag = "icon-cult"; icon_state = "cult" @@ -4497,14 +4523,14 @@ /turf/unsimulated/floor/abductor, /area/abductor_ship) "mB" = ( -/obj/structure/flora/grass/brown, -/turf/unsimulated/floor/snow, -/turf/unsimulated/floor/snow{ - tag = "icon-gravsnow_corner (EAST)"; - icon_state = "gravsnow_corner"; - dir = 4 +/obj/machinery/porta_turret/syndicate/pod, +/turf/simulated/floor/pod, +/turf/space, +/turf/simulated/shuttle/wall{ + dir = 8; + icon_state = "diagonalWall3" }, -/area/syndicate_mothership) +/area/shuttle/assault_pod) "mC" = ( /obj/structure/noticeboard{ pixel_x = -32 @@ -4583,15 +4609,14 @@ }, /area/wizard_station) "mL" = ( -/obj/structure/cult/talisman{ - desc = "A altar dedicated to the Wizard's Federation" +/obj/machinery/porta_turret/syndicate/pod, +/turf/simulated/floor/pod, +/turf/space, +/turf/simulated/shuttle/wall{ + dir = 1; + icon_state = "diagonalWall3" }, -/obj/item/kitchen/knife/ritual, -/turf/unsimulated/floor{ - tag = "icon-cult"; - icon_state = "cult" - }, -/area/wizard_station) +/area/shuttle/assault_pod) "mM" = ( /obj/item/clothing/shoes/sandal/marisa, /obj/item/clothing/suit/wizrobe/marisa, @@ -4791,14 +4816,14 @@ }, /area/syndicate_mothership) "nh" = ( -/obj/machinery/porta_turret/syndicate/pod, -/turf/simulated/floor/pod, -/turf/space, -/turf/simulated/shuttle/wall{ - dir = 8; - icon_state = "diagonalWall3" +/obj/structure/flora/grass/brown, +/turf/unsimulated/floor/snow, +/turf/unsimulated/floor/snow{ + tag = "icon-gravsnow_corner (WEST)"; + icon_state = "gravsnow_corner"; + dir = 8 }, -/area/shuttle/assault_pod) +/area/syndicate_mothership) "ni" = ( /obj/machinery/door/airlock/centcom{ aiControlDisabled = 1; @@ -4813,8 +4838,9 @@ /turf/simulated/floor/pod, /turf/space, /turf/simulated/shuttle/wall{ - dir = 1; - icon_state = "diagonalWall3" + tag = "icon-diagonalWall3"; + icon_state = "diagonalWall3"; + dir = 2 }, /area/shuttle/assault_pod) "nk" = ( @@ -5089,14 +5115,14 @@ /turf/unsimulated/floor/snow, /area/syndicate_mothership) "nP" = ( -/obj/structure/flora/grass/brown, -/turf/unsimulated/floor/snow, -/turf/unsimulated/floor/snow{ - tag = "icon-gravsnow_corner (WEST)"; - icon_state = "gravsnow_corner"; - dir = 8 +/obj/machinery/porta_turret/syndicate/pod, +/turf/simulated/floor/pod, +/turf/space, +/turf/simulated/shuttle/wall{ + dir = 4; + icon_state = "diagonalWall3" }, -/area/syndicate_mothership) +/area/shuttle/assault_pod) "nQ" = ( /obj/item/radio/intercom/syndicate{ pixel_x = -28 @@ -5191,24 +5217,25 @@ }, /area/syndicate_mothership) "oa" = ( -/obj/machinery/porta_turret/syndicate/pod, -/turf/simulated/floor/pod, -/turf/space, -/turf/simulated/shuttle/wall{ - tag = "icon-diagonalWall3"; - icon_state = "diagonalWall3"; +/obj/structure/flora/bush, +/turf/unsimulated/floor/snow, +/turf/unsimulated/floor/snow{ + tag = "icon-gravsnow_corner (NORTH)"; + icon_state = "gravsnow_corner"; + dir = 1 + }, +/area/syndicate_mothership) +"ob" = ( +/obj/structure/bed, +/obj/item/bedsheet/wiz, +/obj/effect/light_emitter{ + light_power = 1 + }, +/turf/unsimulated/floor{ + icon_state = "carpet"; dir = 2 }, -/area/shuttle/assault_pod) -"ob" = ( -/obj/machinery/porta_turret/syndicate/pod, -/turf/simulated/floor/pod, -/turf/space, -/turf/simulated/shuttle/wall{ - dir = 4; - icon_state = "diagonalWall3" - }, -/area/shuttle/assault_pod) +/area/wizard_station) "oc" = ( /turf/unsimulated/floor{ icon_state = "redbluefull"; @@ -5329,12 +5356,10 @@ }, /area/syndicate_mothership) "os" = ( -/obj/structure/flora/bush, +/obj/structure/flora/tree/pine, /turf/unsimulated/floor/snow, /turf/unsimulated/floor/snow{ - tag = "icon-gravsnow_corner (NORTH)"; - icon_state = "gravsnow_corner"; - dir = 1 + icon_state = "gravsnow_corner" }, /area/syndicate_mothership) "ot" = ( @@ -5354,13 +5379,12 @@ }, /area/syndicate_mothership) "ov" = ( -/obj/structure/bed, -/obj/item/bedsheet/wiz, -/turf/unsimulated/floor{ - icon_state = "carpet"; - dir = 2 +/obj/structure/flora/grass/brown, +/turf/unsimulated/floor/snow, +/turf/unsimulated/floor/snow{ + icon_state = "gravsnow_corner" }, -/area/wizard_station) +/area/syndicate_mothership) "ow" = ( /turf/unsimulated/floor{ dir = 8; @@ -5878,13 +5902,6 @@ /obj/effect/decal/cleanable/blood/gibs/body, /turf/simulated/floor/plating/airless, /area/wizard_station) -"ru" = ( -/obj/effect/decal/cleanable/blood/splatter, -/obj/effect/decal/remains/human, -/turf/unsimulated/floor{ - icon_state = "floor" - }, -/area/wizard_station) "rv" = ( /obj/effect/decal/cleanable/blood/splatter, /obj/effect/decal/cleanable/blood/gibs/body, @@ -6285,6 +6302,13 @@ icon_state = "floor4" }, /area/shuttle/assault_pod) +"Gs" = ( +/obj/effect/light_emitter, +/turf/unsimulated/floor{ + tag = "icon-cultdamage3"; + icon_state = "cultdamage3" + }, +/area/wizard_station) "Gw" = ( /obj/structure/chair/sofa/left, /turf/simulated/shuttle/floor{ @@ -11411,7 +11435,7 @@ ko kZ jv jv -jv +cq jv jv nu @@ -13199,18 +13223,18 @@ aa aa je js -jC +Gs jF ka kf km -jv +cq jv jC ln jv jv -mL +kt mX jC nw @@ -13219,11 +13243,11 @@ nN jT oe ol -ov +ob oF kb oQ -jv +cq jv oZ pc @@ -15009,7 +15033,7 @@ aa aa ko kz -ru +kW mw np mH @@ -21948,7 +21972,7 @@ ab ab ab ab -kW +eP nc nq oD @@ -22458,7 +22482,7 @@ jx jY kx at -jZ +bp jn jn am @@ -22981,7 +23005,7 @@ jY oq jY am -nP +nh jn jI ab @@ -23233,7 +23257,7 @@ am am au am -cq +jZ jY oq jY @@ -23489,7 +23513,7 @@ am at jo jo -mB +kr jJ jX oq @@ -24528,7 +24552,7 @@ nV iS kx am -kr +os iS iS iS @@ -24783,9 +24807,9 @@ nH nS nY iS -os +oa am -kt +ov iS ab ab @@ -25536,13 +25560,13 @@ am am am am -jZ +bp jn jn jn -jZ +bp jn -kW +eP iS lR jx @@ -26056,7 +26080,7 @@ am av at am -cq +jZ iS iS mF @@ -26570,7 +26594,7 @@ am at am am -cq +jZ iS lZ mG @@ -27861,11 +27885,11 @@ ab iS gC hi -nh +mB hj ni hj -oa +nj hU hV iS @@ -28117,13 +28141,13 @@ ab ab iS gE -nh +mB hj FV hy FV hj -oa +nj ig iS ab @@ -29145,13 +29169,13 @@ ab ab iS gE -nj +mL hj FW hy hy hj -ob +nP ig iS ab @@ -29403,11 +29427,11 @@ ab iS gK hm -nj +mL hj ni hj -ob +nP id ie iS @@ -62636,12 +62660,12 @@ ab af aK bb +ad +aP aM +aX aP -aU -bf -aP -bp +bg bb aK bF @@ -63150,12 +63174,12 @@ ab af aK bb -aM +ad aP aW aW aP -bp +bg bb aK bF @@ -63664,12 +63688,12 @@ ab af aK bb -aM +ad +aP +aU +bf aP -aX bg -aP -bp bb aK bF diff --git a/_maps/map_files/RandomRuins/LavaRuins/lavaland_biodome_clown_planet.dmm b/_maps/map_files/RandomRuins/LavaRuins/lavaland_biodome_clown_planet.dmm new file mode 100644 index 00000000000..41d298fffb1 --- /dev/null +++ b/_maps/map_files/RandomRuins/LavaRuins/lavaland_biodome_clown_planet.dmm @@ -0,0 +1,2238 @@ +//MAP CONVERTED BY dmm2tgm.py THIS HEADER COMMENT PREVENTS RECONVERSION, DO NOT REMOVE +"aa" = ( +/turf/template_noop, +/area/template_noop) +"ab" = ( +/obj/structure/disposalpipe/segment{ + dir = 4; + icon_state = "pipe-c" + }, +/turf/simulated/wall/r_wall, +/area/ruin/powered/clownplanet) +"ac" = ( +/obj/structure/disposalpipe/segment{ + dir = 2; + icon_state = "pipe-c" + }, +/turf/simulated/wall/r_wall, +/area/ruin/powered/clownplanet) +"ad" = ( +/obj/structure/disposalpipe/segment{ + dir = 4; + icon_state = "pipe-c" + }, +/turf/simulated/floor/plating, +/area/ruin/powered/clownplanet) +"ae" = ( +/obj/structure/disposalpipe/segment{ + dir = 2; + icon_state = "pipe-c" + }, +/turf/simulated/floor/plating, +/area/ruin/powered/clownplanet) +"af" = ( +/obj/structure/disposalpipe/segment{ + invisibility = 101 + }, +/obj/effect/turf_decal/tile/yellow, +/obj/effect/turf_decal/tile/yellow{ + dir = 1 + }, +/obj/effect/turf_decal/tile/yellow{ + dir = 8 + }, +/obj/effect/turf_decal/tile/yellow{ + dir = 4 + }, +/turf/simulated/floor/lubed, +/area/ruin/powered/clownplanet) +"ag" = ( +/obj/effect/mob_spawn/human/corpse/damaged, +/obj/effect/decal/cleanable/blood/old, +/obj/structure/disposalpipe/segment{ + invisibility = 101 + }, +/obj/effect/turf_decal/tile/yellow, +/obj/effect/turf_decal/tile/yellow{ + dir = 1 + }, +/obj/effect/turf_decal/tile/yellow{ + dir = 8 + }, +/obj/effect/turf_decal/tile/yellow{ + dir = 4 + }, +/turf/simulated/floor/lubed, +/area/ruin/powered/clownplanet) +"ah" = ( +/obj/effect/turf_decal/tile/yellow, +/obj/effect/turf_decal/tile/yellow{ + dir = 1 + }, +/obj/effect/turf_decal/tile/yellow{ + dir = 8 + }, +/obj/effect/turf_decal/tile/yellow{ + dir = 4 + }, +/obj/structure/disposalpipe/segment{ + dir = 4; + icon_state = "pipe-c" + }, +/turf/simulated/floor/lubed, +/area/ruin/powered/clownplanet) +"ai" = ( +/obj/structure/disposalpipe/sortjunction{ + dir = 1 + }, +/turf/simulated/wall/r_wall, +/area/ruin/powered/clownplanet) +"aj" = ( +/obj/effect/decal/cleanable/pie_smudge, +/obj/structure/disposalpipe/segment{ + invisibility = 101 + }, +/obj/effect/turf_decal/tile/yellow, +/obj/effect/turf_decal/tile/yellow{ + dir = 1 + }, +/obj/effect/turf_decal/tile/yellow{ + dir = 8 + }, +/obj/effect/turf_decal/tile/yellow{ + dir = 4 + }, +/turf/simulated/floor/lubed, +/area/ruin/powered/clownplanet) +"ak" = ( +/obj/structure/disposalpipe/segment{ + invisibility = 101 + }, +/obj/machinery/light/small{ + dir = 1 + }, +/obj/effect/turf_decal/tile/yellow, +/obj/effect/turf_decal/tile/yellow{ + dir = 1 + }, +/obj/effect/turf_decal/tile/yellow{ + dir = 8 + }, +/obj/effect/turf_decal/tile/yellow{ + dir = 4 + }, +/turf/simulated/floor/lubed, +/area/ruin/powered/clownplanet) +"al" = ( +/obj/effect/decal/cleanable/dirt, +/obj/effect/turf_decal/tile/yellow, +/obj/effect/turf_decal/tile/yellow{ + dir = 1 + }, +/obj/effect/turf_decal/tile/yellow{ + dir = 8 + }, +/obj/effect/turf_decal/tile/yellow{ + dir = 4 + }, +/obj/structure/disposalpipe/segment{ + dir = 1; + icon_state = "pipe-c" + }, +/turf/simulated/floor/lubed, +/area/ruin/powered/clownplanet) +"am" = ( +/obj/structure/disposalpipe/segment{ + dir = 4; + invisibility = 101 + }, +/obj/effect/decal/cleanable/dirt, +/obj/effect/turf_decal/tile/yellow, +/obj/effect/turf_decal/tile/yellow{ + dir = 1 + }, +/obj/effect/turf_decal/tile/yellow{ + dir = 8 + }, +/obj/effect/turf_decal/tile/yellow{ + dir = 4 + }, +/turf/simulated/floor/lubed, +/area/ruin/powered/clownplanet) +"an" = ( +/obj/structure/disposalpipe/segment{ + dir = 4; + invisibility = 101 + }, +/obj/effect/turf_decal/tile/yellow, +/obj/effect/turf_decal/tile/yellow{ + dir = 1 + }, +/obj/effect/turf_decal/tile/yellow{ + dir = 8 + }, +/obj/effect/turf_decal/tile/yellow{ + dir = 4 + }, +/turf/simulated/floor/lubed, +/area/ruin/powered/clownplanet) +"ao" = ( +/obj/structure/window/reinforced, +/obj/structure/disposalpipe/segment{ + dir = 8; + icon_state = "pipe-c" + }, +/turf/simulated/floor/plating, +/area/ruin/powered/clownplanet) +"ap" = ( +/obj/effect/turf_decal/tile/yellow, +/obj/effect/turf_decal/tile/yellow{ + dir = 1 + }, +/obj/effect/turf_decal/tile/yellow{ + dir = 8 + }, +/obj/effect/turf_decal/tile/yellow{ + dir = 4 + }, +/obj/structure/disposalpipe/segment{ + dir = 8; + icon_state = "pipe-c" + }, +/turf/simulated/floor/lubed, +/area/ruin/powered/clownplanet) +"aq" = ( +/obj/structure/disposalpipe/trunk, +/obj/structure/disposaloutlet{ + dir = 1 + }, +/turf/simulated/floor/plating, +/area/ruin/powered/clownplanet) +"ar" = ( +/obj/effect/turf_decal/tile/yellow, +/obj/effect/turf_decal/tile/yellow{ + dir = 1 + }, +/obj/effect/turf_decal/tile/yellow{ + dir = 8 + }, +/obj/effect/turf_decal/tile/yellow{ + dir = 4 + }, +/turf/simulated/floor/lubed, +/area/ruin/powered/clownplanet) +"as" = ( +/obj/effect/decal/cleanable/dirt, +/obj/effect/turf_decal/tile/yellow, +/obj/effect/turf_decal/tile/yellow{ + dir = 1 + }, +/obj/effect/turf_decal/tile/yellow{ + dir = 8 + }, +/obj/effect/turf_decal/tile/yellow{ + dir = 4 + }, +/turf/simulated/floor/lubed, +/area/ruin/powered/clownplanet) +"at" = ( +/obj/structure/disposalpipe/segment{ + dir = 4; + invisibility = 101 + }, +/obj/effect/decal/cleanable/cobweb, +/obj/effect/turf_decal/tile/yellow, +/obj/effect/turf_decal/tile/yellow{ + dir = 1 + }, +/obj/effect/turf_decal/tile/yellow{ + dir = 8 + }, +/obj/effect/turf_decal/tile/yellow{ + dir = 4 + }, +/turf/simulated/floor/lubed, +/area/ruin/powered/clownplanet) +"au" = ( +/obj/structure/disposalpipe/segment{ + invisibility = 101 + }, +/turf/simulated/floor/plating, +/area/ruin/powered/clownplanet) +"av" = ( +/obj/effect/turf_decal/tile/yellow, +/obj/effect/turf_decal/tile/yellow{ + dir = 1 + }, +/obj/effect/turf_decal/tile/yellow{ + dir = 8 + }, +/obj/effect/turf_decal/tile/yellow{ + dir = 4 + }, +/obj/structure/disposalpipe/segment{ + dir = 1; + icon_state = "pipe-c" + }, +/turf/simulated/floor/lubed, +/area/ruin/powered/clownplanet) +"aw" = ( +/obj/machinery/light/small{ + dir = 1 + }, +/obj/effect/turf_decal/tile/yellow, +/obj/effect/turf_decal/tile/yellow{ + dir = 1 + }, +/obj/effect/turf_decal/tile/yellow{ + dir = 8 + }, +/obj/effect/turf_decal/tile/yellow{ + dir = 4 + }, +/turf/simulated/floor/lubed, +/area/ruin/powered/clownplanet) +"ay" = ( +/obj/effect/decal/cleanable/dirt, +/obj/effect/turf_decal/tile/yellow, +/obj/effect/turf_decal/tile/yellow{ + dir = 1 + }, +/obj/effect/turf_decal/tile/yellow{ + dir = 8 + }, +/obj/effect/turf_decal/tile/yellow{ + dir = 4 + }, +/obj/structure/disposalpipe/segment{ + dir = 8; + icon_state = "pipe-c" + }, +/turf/simulated/floor/lubed, +/area/ruin/powered/clownplanet) +"az" = ( +/obj/item/bikehorn, +/obj/effect/turf_decal/tile/yellow, +/obj/effect/turf_decal/tile/yellow{ + dir = 1 + }, +/obj/effect/turf_decal/tile/yellow{ + dir = 8 + }, +/obj/effect/turf_decal/tile/yellow{ + dir = 4 + }, +/obj/structure/disposalpipe/segment{ + dir = 1; + icon_state = "pipe-c" + }, +/turf/simulated/floor/lubed, +/area/ruin/powered/clownplanet) +"aA" = ( +/obj/structure/disposalpipe/segment{ + dir = 1; + icon_state = "pipe-c" + }, +/turf/simulated/wall/r_wall, +/area/ruin/powered/clownplanet) +"aB" = ( +/obj/structure/disposalpipe/segment{ + dir = 4; + invisibility = 101 + }, +/obj/effect/decal/cleanable/pie_smudge, +/obj/effect/turf_decal/tile/yellow, +/obj/effect/turf_decal/tile/yellow{ + dir = 1 + }, +/obj/effect/turf_decal/tile/yellow{ + dir = 8 + }, +/obj/effect/turf_decal/tile/yellow{ + dir = 4 + }, +/turf/simulated/floor/lubed, +/area/ruin/powered/clownplanet) +"aC" = ( +/obj/effect/turf_decal/tile/yellow, +/obj/effect/turf_decal/tile/yellow{ + dir = 1 + }, +/obj/effect/turf_decal/tile/yellow{ + dir = 8 + }, +/obj/effect/turf_decal/tile/yellow{ + dir = 4 + }, +/obj/structure/disposalpipe/segment{ + dir = 2; + icon_state = "pipe-c" + }, +/turf/simulated/floor/lubed, +/area/ruin/powered/clownplanet) +"aD" = ( +/obj/item/bikehorn, +/obj/structure/disposalpipe/segment{ + dir = 4; + invisibility = 101 + }, +/obj/effect/turf_decal/tile/yellow, +/obj/effect/turf_decal/tile/yellow{ + dir = 1 + }, +/obj/effect/turf_decal/tile/yellow{ + dir = 8 + }, +/obj/effect/turf_decal/tile/yellow{ + dir = 4 + }, +/turf/simulated/floor/lubed, +/area/ruin/powered/clownplanet) +"aE" = ( +/obj/structure/disposalpipe/segment{ + dir = 8; + icon_state = "pipe-c" + }, +/turf/simulated/floor/plating, +/area/ruin/powered/clownplanet) +"aF" = ( +/obj/effect/decal/cleanable/dirt, +/obj/structure/disposalpipe/segment{ + invisibility = 101 + }, +/obj/effect/turf_decal/tile/yellow, +/obj/effect/turf_decal/tile/yellow{ + dir = 1 + }, +/obj/effect/turf_decal/tile/yellow{ + dir = 8 + }, +/obj/effect/turf_decal/tile/yellow{ + dir = 4 + }, +/turf/simulated/floor/lubed, +/area/ruin/powered/clownplanet) +"aG" = ( +/obj/machinery/light/small{ + dir = 4 + }, +/obj/effect/turf_decal/tile/yellow, +/obj/effect/turf_decal/tile/yellow{ + dir = 1 + }, +/obj/effect/turf_decal/tile/yellow{ + dir = 8 + }, +/obj/effect/turf_decal/tile/yellow{ + dir = 4 + }, +/obj/structure/disposalpipe/segment{ + dir = 2; + icon_state = "pipe-c" + }, +/turf/simulated/floor/lubed, +/area/ruin/powered/clownplanet) +"aH" = ( +/obj/effect/decal/cleanable/dirt, +/obj/machinery/light/small{ + dir = 8 + }, +/obj/effect/turf_decal/tile/yellow, +/obj/effect/turf_decal/tile/yellow{ + dir = 1 + }, +/obj/effect/turf_decal/tile/yellow{ + dir = 8 + }, +/obj/effect/turf_decal/tile/yellow{ + dir = 4 + }, +/obj/structure/disposalpipe/segment{ + dir = 2; + icon_state = "pipe-c" + }, +/turf/simulated/floor/lubed, +/area/ruin/powered/clownplanet) +"aI" = ( +/obj/item/bikehorn, +/obj/effect/decal/cleanable/dirt, +/obj/structure/disposalpipe/segment{ + invisibility = 101 + }, +/obj/effect/turf_decal/tile/yellow, +/obj/effect/turf_decal/tile/yellow{ + dir = 1 + }, +/obj/effect/turf_decal/tile/yellow{ + dir = 8 + }, +/obj/effect/turf_decal/tile/yellow{ + dir = 4 + }, +/turf/simulated/floor/lubed, +/area/ruin/powered/clownplanet) +"aJ" = ( +/obj/item/bikehorn, +/obj/structure/disposalpipe/segment{ + invisibility = 101 + }, +/obj/effect/turf_decal/tile/yellow, +/obj/effect/turf_decal/tile/yellow{ + dir = 1 + }, +/obj/effect/turf_decal/tile/yellow{ + dir = 8 + }, +/obj/effect/turf_decal/tile/yellow{ + dir = 4 + }, +/turf/simulated/floor/lubed, +/area/ruin/powered/clownplanet) +"aK" = ( +/obj/structure/disposalpipe/segment{ + dir = 4; + invisibility = 101 + }, +/obj/effect/turf_decal/tile/red, +/obj/effect/turf_decal/tile/red{ + dir = 8 + }, +/obj/effect/turf_decal/tile/red{ + dir = 4 + }, +/obj/effect/turf_decal/tile/red{ + dir = 1 + }, +/turf/simulated/floor/plasteel, +/area/ruin/powered/clownplanet) +"aL" = ( +/obj/structure/disposalpipe/segment{ + dir = 4; + invisibility = 101 + }, +/turf/simulated/wall/r_wall, +/area/ruin/powered/clownplanet) +"aM" = ( +/obj/effect/decal/cleanable/pie_smudge, +/obj/effect/turf_decal/tile/yellow, +/obj/effect/turf_decal/tile/yellow{ + dir = 1 + }, +/obj/effect/turf_decal/tile/yellow{ + dir = 8 + }, +/obj/effect/turf_decal/tile/yellow{ + dir = 4 + }, +/turf/simulated/floor/lubed, +/area/ruin/powered/clownplanet) +"aN" = ( +/obj/structure/disposalpipe/segment{ + dir = 4; + invisibility = 101 + }, +/turf/simulated/floor/plasteel{ + dir = 4; + icon_state = "white" + }, +/area/ruin/powered/clownplanet) +"aO" = ( +/obj/effect/decal/cleanable/dirt, +/obj/effect/turf_decal/tile/yellow, +/obj/effect/turf_decal/tile/yellow{ + dir = 1 + }, +/obj/effect/turf_decal/tile/yellow{ + dir = 8 + }, +/obj/effect/turf_decal/tile/yellow{ + dir = 4 + }, +/obj/structure/disposalpipe/segment{ + dir = 4; + icon_state = "pipe-c" + }, +/turf/simulated/floor/lubed, +/area/ruin/powered/clownplanet) +"aP" = ( +/obj/structure/disposalpipe/segment{ + dir = 4; + invisibility = 101 + }, +/turf/simulated/floor/plating, +/area/ruin/powered/clownplanet) +"aQ" = ( +/obj/structure/disposalpipe/segment{ + dir = 4; + invisibility = 101 + }, +/obj/structure/table, +/obj/item/paper/crumpled/bloody/ruins/lavaland/clown_planet/escape, +/obj/item/pen/multi, +/turf/simulated/floor/plasteel{ + dir = 4; + icon_state = "white" + }, +/area/ruin/powered/clownplanet) +"aR" = ( +/obj/structure/disposalpipe/segment{ + dir = 4; + invisibility = 101 + }, +/obj/structure/table, +/obj/item/flashlight/lamp/bananalamp, +/turf/simulated/floor/plasteel{ + dir = 4; + icon_state = "white" + }, +/area/ruin/powered/clownplanet) +"aS" = ( +/obj/effect/decal/cleanable/pie_smudge, +/obj/effect/turf_decal/tile/yellow, +/obj/effect/turf_decal/tile/yellow{ + dir = 1 + }, +/obj/effect/turf_decal/tile/yellow{ + dir = 8 + }, +/obj/effect/turf_decal/tile/yellow{ + dir = 4 + }, +/obj/structure/disposalpipe/segment{ + dir = 2; + icon_state = "pipe-c" + }, +/turf/simulated/floor/lubed, +/area/ruin/powered/clownplanet) +"aT" = ( +/obj/structure/disposalpipe/segment{ + dir = 4; + invisibility = 101 + }, +/obj/item/pickaxe, +/turf/simulated/floor/plasteel{ + dir = 4; + icon_state = "white" + }, +/area/ruin/powered/clownplanet) +"aU" = ( +/obj/effect/spawner/window/reinforced, +/turf/simulated/floor/plating, +/area/ruin/powered/clownplanet) +"aV" = ( +/obj/structure/disposalpipe/segment{ + dir = 4; + icon_state = "pipe-c" + }, +/turf/simulated/floor/plasteel{ + dir = 4; + icon_state = "white" + }, +/area/ruin/powered/clownplanet) +"aW" = ( +/obj/structure/disposalpipe/segment{ + dir = 2; + icon_state = "pipe-c" + }, +/turf/simulated/floor/plasteel{ + dir = 4; + icon_state = "white" + }, +/area/ruin/powered/clownplanet) +"aX" = ( +/obj/structure/disposalpipe/trunk{ + dir = 4 + }, +/obj/structure/disposaloutlet{ + dir = 8 + }, +/turf/simulated/floor/plating, +/area/ruin/powered/clownplanet) +"aY" = ( +/obj/structure/disposalpipe/segment{ + dir = 4; + invisibility = 101 + }, +/obj/machinery/light/small{ + dir = 8 + }, +/turf/simulated/floor/plasteel{ + dir = 4; + icon_state = "white" + }, +/area/ruin/powered/clownplanet) +"aZ" = ( +/obj/structure/disposalpipe/segment{ + dir = 4; + invisibility = 101 + }, +/turf/simulated/floor/light, +/area/ruin/powered/clownplanet) +"ba" = ( +/obj/structure/disposalpipe/segment{ + dir = 4; + invisibility = 101 + }, +/obj/machinery/light/small{ + dir = 4 + }, +/turf/simulated/floor/plasteel{ + dir = 4; + icon_state = "white" + }, +/area/ruin/powered/clownplanet) +"bb" = ( +/obj/structure/disposalpipe/segment{ + invisibility = 101 + }, +/obj/machinery/light/small{ + dir = 8 + }, +/turf/simulated/floor/plasteel{ + dir = 4; + icon_state = "white" + }, +/area/ruin/powered/clownplanet) +"bc" = ( +/turf/simulated/floor/light, +/area/ruin/powered/clownplanet) +"bd" = ( +/obj/structure/disposalpipe/segment{ + dir = 1; + icon_state = "pipe-c" + }, +/turf/simulated/floor/plasteel{ + dir = 4; + icon_state = "white" + }, +/area/ruin/powered/clownplanet) +"be" = ( +/obj/machinery/light/small{ + dir = 4 + }, +/obj/structure/disposalpipe/segment{ + dir = 8; + icon_state = "pipe-c" + }, +/turf/simulated/floor/plasteel{ + dir = 4; + icon_state = "white" + }, +/area/ruin/powered/clownplanet) +"bf" = ( +/turf/simulated/mineral/clown/volcanic, +/area/ruin/powered/clownplanet) +"bg" = ( +/obj/item/pickaxe, +/turf/simulated/floor/plasteel{ + dir = 4; + icon_state = "white" + }, +/area/ruin/powered/clownplanet) +"bh" = ( +/turf/simulated/floor/plasteel{ + dir = 4; + icon_state = "white" + }, +/area/ruin/powered/clownplanet) +"bi" = ( +/obj/effect/turf_decal/tile/red, +/obj/effect/turf_decal/tile/red{ + dir = 8 + }, +/obj/effect/turf_decal/tile/red{ + dir = 4 + }, +/obj/effect/turf_decal/tile/red{ + dir = 1 + }, +/obj/structure/disposalpipe/segment{ + dir = 4; + icon_state = "pipe-c" + }, +/turf/simulated/floor/plasteel, +/area/ruin/powered/clownplanet) +"bj" = ( +/obj/effect/decal/cleanable/dirt, +/obj/effect/turf_decal/tile/yellow, +/obj/effect/turf_decal/tile/yellow{ + dir = 1 + }, +/obj/effect/turf_decal/tile/yellow{ + dir = 8 + }, +/obj/effect/turf_decal/tile/yellow{ + dir = 4 + }, +/obj/structure/disposalpipe/segment{ + dir = 2; + icon_state = "pipe-c" + }, +/turf/simulated/floor/lubed, +/area/ruin/powered/clownplanet) +"bk" = ( +/obj/structure/disposalpipe/segment{ + dir = 1; + icon_state = "pipe-c" + }, +/turf/simulated/floor/plating, +/area/ruin/powered/clownplanet) +"bl" = ( +/obj/item/bikehorn, +/obj/effect/turf_decal/tile/yellow, +/obj/effect/turf_decal/tile/yellow{ + dir = 1 + }, +/obj/effect/turf_decal/tile/yellow{ + dir = 8 + }, +/obj/effect/turf_decal/tile/yellow{ + dir = 4 + }, +/obj/structure/disposalpipe/segment{ + dir = 2; + icon_state = "pipe-c" + }, +/turf/simulated/floor/lubed, +/area/ruin/powered/clownplanet) +"bm" = ( +/obj/structure/disposalpipe/segment{ + dir = 8; + icon_state = "pipe-c" + }, +/turf/simulated/floor/plasteel{ + dir = 4; + icon_state = "white" + }, +/area/ruin/powered/clownplanet) +"bn" = ( +/obj/effect/decal/cleanable/cobweb, +/obj/effect/turf_decal/tile/red, +/obj/effect/turf_decal/tile/red{ + dir = 8 + }, +/obj/effect/turf_decal/tile/red{ + dir = 4 + }, +/obj/effect/turf_decal/tile/red{ + dir = 1 + }, +/turf/simulated/floor/plasteel, +/area/ruin/powered/clownplanet) +"bo" = ( +/obj/structure/disposalpipe/segment, +/obj/effect/turf_decal/tile/yellow, +/obj/effect/turf_decal/tile/yellow{ + dir = 1 + }, +/obj/effect/turf_decal/tile/yellow{ + dir = 8 + }, +/obj/effect/turf_decal/tile/yellow{ + dir = 4 + }, +/turf/simulated/floor/lubed, +/area/ruin/powered/clownplanet) +"bp" = ( +/obj/effect/decal/cleanable/pie_smudge, +/obj/effect/turf_decal/tile/yellow{ + dir = 4 + }, +/obj/effect/turf_decal/tile/yellow{ + dir = 8 + }, +/obj/effect/turf_decal/tile/yellow{ + dir = 1 + }, +/obj/effect/turf_decal/tile/yellow, +/turf/simulated/floor/lubed, +/area/ruin/powered/clownplanet) +"bq" = ( +/obj/machinery/disposal/deliveryChute{ + dir = 1 + }, +/obj/structure/disposalpipe/trunk, +/turf/simulated/floor/plasteel{ + dir = 4; + icon_state = "white" + }, +/area/ruin/powered/clownplanet) +"br" = ( +/obj/effect/turf_decal/tile/red, +/obj/effect/turf_decal/tile/red{ + dir = 8 + }, +/obj/effect/turf_decal/tile/red{ + dir = 4 + }, +/obj/effect/turf_decal/tile/red{ + dir = 1 + }, +/turf/simulated/floor/plasteel, +/area/ruin/powered/clownplanet) +"bs" = ( +/obj/machinery/light{ + dir = 1 + }, +/obj/effect/turf_decal/tile/red, +/obj/effect/turf_decal/tile/red{ + dir = 8 + }, +/obj/effect/turf_decal/tile/red{ + dir = 4 + }, +/obj/effect/turf_decal/tile/red{ + dir = 1 + }, +/turf/simulated/floor/plasteel, +/area/ruin/powered/clownplanet) +"bt" = ( +/obj/effect/decal/cleanable/dirt, +/obj/effect/turf_decal/tile/yellow, +/obj/effect/turf_decal/tile/yellow{ + dir = 1 + }, +/obj/effect/turf_decal/tile/yellow{ + dir = 8 + }, +/obj/effect/turf_decal/tile/yellow{ + dir = 4 + }, +/obj/structure/disposalpipe/junction{ + dir = 1; + icon_state = "pipe-y" + }, +/turf/simulated/floor/lubed, +/area/ruin/powered/clownplanet) +"bu" = ( +/obj/effect/decal/cleanable/blood/oil, +/obj/structure/disposalpipe/segment{ + dir = 2; + icon_state = "pipe-c" + }, +/turf/simulated/floor/plating, +/area/ruin/powered/clownplanet) +"bv" = ( +/obj/effect/mob_spawn/human/corpse/damaged, +/obj/effect/decal/cleanable/blood/old, +/obj/effect/turf_decal/tile/yellow{ + dir = 8 + }, +/obj/effect/turf_decal/tile/yellow{ + dir = 1 + }, +/obj/effect/turf_decal/tile/yellow, +/obj/effect/turf_decal/tile/yellow{ + dir = 4 + }, +/turf/simulated/floor/lubed, +/area/ruin/powered/clownplanet) +"bw" = ( +/obj/effect/turf_decal/tile/red, +/obj/effect/turf_decal/tile/red{ + dir = 8 + }, +/obj/effect/turf_decal/tile/red{ + dir = 4 + }, +/obj/effect/turf_decal/tile/red{ + dir = 1 + }, +/obj/structure/disposalpipe/segment{ + dir = 8; + icon_state = "pipe-c" + }, +/turf/simulated/floor/plasteel, +/area/ruin/powered/clownplanet) +"bx" = ( +/obj/effect/decal/cleanable/dirt, +/obj/effect/turf_decal/tile/yellow, +/obj/effect/turf_decal/tile/yellow{ + dir = 1 + }, +/obj/effect/turf_decal/tile/yellow{ + dir = 8 + }, +/obj/effect/turf_decal/tile/yellow{ + dir = 4 + }, +/obj/effect/baseturf_helper/lava_land/surface, +/turf/simulated/floor/lubed, +/area/ruin/powered/clownplanet) +"by" = ( +/obj/structure/table/glass, +/obj/item/gun/magic/staff/slipping, +/turf/simulated/floor/carpet, +/area/ruin/powered/clownplanet) +"bB" = ( +/turf/simulated/floor/mineral/bananium/lubed, +/area/ruin/powered/clownplanet) +"bD" = ( +/obj/effect/decal/mecha_wreckage/honker, +/obj/structure/disposalpipe/segment{ + dir = 4; + invisibility = 101 + }, +/turf/simulated/floor/plating, +/area/ruin/powered/clownplanet) +"bH" = ( +/obj/effect/decal/cleanable/dirt, +/turf/simulated/floor/mineral/bananium/lubed, +/area/ruin/powered/clownplanet) +"bL" = ( +/obj/item/reagent_containers/food/drinks/trophy/gold_cup, +/obj/structure/table/glass, +/turf/simulated/floor/carpet, +/area/ruin/powered/clownplanet) +"bM" = ( +/turf/simulated/floor/carpet, +/area/ruin/powered/clownplanet) +"bN" = ( +/obj/machinery/disposal/deliveryChute, +/obj/structure/disposalpipe/trunk{ + dir = 1 + }, +/turf/simulated/floor/carpet, +/area/ruin/powered/clownplanet) +"bO" = ( +/obj/effect/decal/cleanable/cobweb, +/turf/simulated/floor/mineral/bananium/lubed, +/area/ruin/powered/clownplanet) +"bP" = ( +/obj/structure/statue/bananium/clown, +/turf/simulated/floor/carpet, +/area/ruin/powered/clownplanet) +"bQ" = ( +/obj/structure/table/glass, +/obj/item/grown/bananapeel/bluespace, +/turf/simulated/floor/carpet, +/area/ruin/powered/clownplanet) +"bR" = ( +/obj/structure/table/glass, +/obj/item/clothing/shoes/magboots/clown, +/turf/simulated/floor/carpet, +/area/ruin/powered/clownplanet) +"bS" = ( +/obj/item/coin/clown, +/obj/item/coin/clown, +/obj/item/coin/clown, +/obj/item/coin/clown, +/obj/machinery/light/small{ + dir = 8 + }, +/turf/simulated/floor/carpet, +/area/ruin/powered/clownplanet) +"bT" = ( +/obj/item/slime_extract/rainbow, +/obj/structure/table/glass, +/turf/simulated/floor/carpet, +/area/ruin/powered/clownplanet) +"bU" = ( +/obj/item/bikehorn/airhorn, +/turf/simulated/floor/carpet, +/area/ruin/powered/clownplanet) +"bW" = ( +/obj/item/bikehorn, +/turf/simulated/floor/mineral/bananium/lubed, +/area/ruin/powered/clownplanet) +"bY" = ( +/obj/effect/mob_spawn/human/corpse/damaged, +/obj/effect/decal/cleanable/blood/old, +/turf/simulated/floor/mineral/bananium/lubed, +/area/ruin/powered/clownplanet) +"bZ" = ( +/obj/machinery/door/airlock/bananium, +/turf/simulated/floor/mineral/bananium/lubed, +/area/ruin/powered/clownplanet) +"ca" = ( +/obj/item/bikehorn, +/obj/effect/decal/cleanable/dirt, +/turf/simulated/floor/mineral/bananium/lubed, +/area/ruin/powered/clownplanet) +"cc" = ( +/turf/simulated/wall/r_wall, +/area/ruin/powered/clownplanet) +"ch" = ( +/obj/structure/disposalpipe/segment{ + invisibility = 101 + }, +/turf/simulated/wall/r_wall, +/area/ruin/powered/clownplanet) +"cu" = ( +/turf/simulated/floor/plating, +/area/ruin/powered/clownplanet) +"dK" = ( +/obj/machinery/light/small{ + dir = 1 + }, +/turf/simulated/floor/carpet, +/area/ruin/powered/clownplanet) +"dL" = ( +/obj/item/coin/clown, +/obj/item/coin/clown, +/obj/item/coin/clown, +/obj/item/coin/clown, +/obj/machinery/light/small{ + dir = 4 + }, +/turf/simulated/floor/carpet, +/area/ruin/powered/clownplanet) +"dM" = ( +/obj/machinery/light{ + dir = 1 + }, +/turf/simulated/floor/mineral/bananium/lubed, +/area/ruin/powered/clownplanet) +"dO" = ( +/obj/machinery/light, +/turf/simulated/floor/mineral/bananium/lubed, +/area/ruin/powered/clownplanet) +"eX" = ( +/obj/effect/mapping_helpers/no_lava, +/turf/simulated/floor/noslip/lavaland, +/area/lavaland/surface/outdoors/explored) +"gX" = ( +/obj/effect/mapping_helpers/no_lava, +/turf/simulated/floor/chasm/straight_down/lava_land_surface, +/area/lavaland/surface/outdoors/explored) +"hY" = ( +/obj/machinery/light, +/obj/effect/mapping_helpers/no_lava, +/turf/simulated/floor/plating/asteroid/basalt/lava_land_surface, +/area/ruin/powered/clownplanet) +"pv" = ( +/obj/machinery/light{ + dir = 4 + }, +/turf/simulated/floor/plating/asteroid/basalt/lava_land_surface, +/area/ruin/powered/clownplanet) +"ye" = ( +/turf/simulated/floor/plating/lava/smooth, +/area/ruin/powered/clownplanet) +"CB" = ( +/obj/item/paper/crumpled/bloody/ruins/lavaland/clown_planet/hope, +/obj/effect/decal/cleanable/blood/old, +/obj/effect/mapping_helpers/no_lava, +/turf/simulated/floor/noslip/lavaland, +/area/lavaland/surface/outdoors/explored) +"KX" = ( +/obj/item/grown/bananapeel{ + color = "#2F3000"; + name = "stealth banana peel" + }, +/obj/effect/mapping_helpers/no_lava, +/turf/simulated/floor/plating/asteroid/basalt/lava_land_surface, +/area/lavaland/surface/outdoors/explored) +"LH" = ( +/obj/machinery/disposal/deliveryChute{ + desc = "The following is engraved upon the chute: A FATE WORSE THAN DEATH LIES WITHIN"; + dir = 1; + name = "THE TRIAL OF HONKITUDE" + }, +/obj/structure/disposalpipe/trunk, +/obj/effect/mapping_helpers/no_lava, +/turf/simulated/floor/noslip/lavaland, +/area/ruin/powered/clownplanet) +"Mv" = ( +/obj/effect/mapping_helpers/no_lava, +/mob/living/simple_animal/hostile/retaliate/clown, +/turf/simulated/floor/plating/asteroid/basalt/lava_land_surface, +/area/lavaland/surface/outdoors/explored) +"MR" = ( +/obj/machinery/light{ + dir = 8 + }, +/obj/effect/mapping_helpers/no_lava, +/turf/simulated/floor/plating/asteroid/basalt/lava_land_surface, +/area/ruin/powered/clownplanet) +"TD" = ( +/obj/structure/disposalpipe/trunk, +/obj/structure/disposaloutlet{ + dir = 1 + }, +/obj/effect/mapping_helpers/no_lava, +/turf/simulated/floor/noslip/lavaland, +/area/ruin/powered/clownplanet) +"VH" = ( +/obj/structure/disposalpipe/segment{ + dir = 8; + icon_state = "pipe-c" + }, +/turf/simulated/wall/r_wall, +/area/ruin/powered/clownplanet) +"Xm" = ( +/obj/item/clothing/head/cone, +/obj/effect/mapping_helpers/no_lava, +/turf/simulated/floor/noslip/lavaland, +/area/lavaland/surface/outdoors/explored) +"XO" = ( +/obj/effect/mapping_helpers/no_lava, +/turf/simulated/floor/plating/asteroid/basalt/lava_land_surface, +/area/lavaland/surface/outdoors/explored) +"Yf" = ( +/obj/machinery/light{ + dir = 1 + }, +/obj/effect/mapping_helpers/no_lava, +/turf/simulated/floor/plating/asteroid/basalt/lava_land_surface, +/area/ruin/powered/clownplanet) +"YI" = ( +/obj/machinery/light/small, +/obj/effect/mapping_helpers/no_lava, +/turf/simulated/floor/noslip/lavaland, +/area/ruin/powered/clownplanet) + +(1,1,1) = {" +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +XO +XO +XO +XO +XO +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +"} +(2,1,1) = {" +aa +aa +aa +aa +aa +aa +aa +cc +cc +cc +cc +cc +cc +cc +pv +XO +gX +XO +XO +gX +pv +cc +cc +cc +cc +cc +aa +aa +aa +aa +aa +aa +"} +(3,1,1) = {" +aa +aa +aa +aa +aa +cc +cc +cc +ye +ye +ye +ye +ye +cc +cc +gX +gX +KX +gX +gX +cc +cc +ye +ye +ye +cc +cc +cc +aa +aa +aa +aa +"} +(4,1,1) = {" +aa +aa +aa +aa +cc +cc +ye +ye +ye +ab +aA +ab +aA +ye +cc +cc +gX +gX +gX +cc +cc +ye +ye +aU +cu +ye +ye +cc +cc +aa +aa +aa +"} +(5,1,1) = {" +aa +aa +aa +cc +cc +ye +ye +ab +ch +VH +aH +ay +aS +aA +ye +cc +cc +cc +cc +cc +bO +bB +aU +ye +ye +ye +ye +ye +cc +cc +aa +aa +"} +(6,1,1) = {" +aa +aa +aa +cc +ye +ye +cc +at +ah +af +aI +af +av +aL +ye +cc +bB +bH +bB +cc +bB +bH +bY +bB +aU +ye +aU +ye +ye +cc +Yf +aa +"} +(7,1,1) = {" +aa +aa +cc +cc +ye +ab +aj +ap +am +ah +af +aA +aL +aL +cc +bn +br +bB +bH +bH +bB +bH +bB +bB +bB +cc +ye +cu +ye +cc +cc +aa +"} +(8,1,1) = {" +aa +aa +cc +ye +ye +ae +af +av +am +aL +aX +aL +aN +aY +bf +cc +bs +br +bB +cc +cc +bH +cc +bB +bB +bB +aU +ye +ye +ye +cc +aa +"} +(9,1,1) = {" +aa +aa +cc +ye +ab +af +af +ay +an +an +aL +aN +aN +aN +bg +bf +cc +cc +br +bB +bB +bH +bB +bB +ca +bH +dO +cc +ye +ye +cc +aa +"} +(10,1,1) = {" +aa +Mv +cc +ye +ac +ag +af +av +aL +am +aL +aN +aN +aZ +bc +bh +br +br +br +bB +cc +bB +bB +bH +bH +bB +bB +ye +aU +ye +cc +cc +"} +(11,1,1) = {" +aa +hY +cc +ye +ad +ch +ak +ay +am +am +aL +aN +aT +aZ +bc +bf +cc +br +br +bB +bB +cc +bB +bB +bB +bB +bH +ye +aU +ye +ye +cc +"} +(12,1,1) = {" +aa +Mv +cc +ye +ae +af +af +az +am +ac +ap +aL +aN +ba +bh +cc +cc +br +bB +bB +cc +cc +bB +bB +cc +bB +bH +ye +cu +aU +ye +cc +"} +(13,1,1) = {" +XO +Mv +cc +ye +cc +ah +af +ap +aC +aj +af +ap +aL +aL +bi +ch +aA +cc +cc +cc +bP +bS +cc +dM +bB +bH +ca +bB +ye +aU +ye +cc +"} +(14,1,1) = {" +XO +Xm +cc +cc +ye +ac +af +af +af +af +aJ +af +ay +an +bj +al +am +cc +cc +bL +bM +bM +bM +cc +bB +bH +bH +bB +ye +aU +ye +cc +"} +(15,1,1) = {" +eX +eX +LH +ch +ch +au +af +ch +af +aF +ch +aj +af +ay +as +an +aC +av +cc +dK +bQ +bT +bM +cc +cc +bH +bB +bB +ye +aU +ye +cc +"} +(16,1,1) = {" +eX +CB +YI +cc +ye +cu +ah +aA +ah +av +ah +af +af +au +bk +aC +av +bj +ch +bN +bM +bU +bM +bZ +bB +bH +bB +cc +ye +aU +ye +cc +"} +(17,1,1) = {" +eX +eX +TD +ch +ch +ai +ay +an +an +aL +an +aO +af +av +bl +bo +bt +bx +cc +bM +bR +by +bM +cc +bB +bB +bB +bB +ye +aU +ye +cc +"} +(18,1,1) = {" +XO +eX +cc +cc +ye +aL +as +am +am +an +an +an +ar +aC +av +bp +aL +bv +cc +bL +bM +bM +bM +cc +bB +bB +bB +bB +ye +aU +ye +cc +"} +(19,1,1) = {" +XO +Mv +cc +ye +ye +aL +as +am +aD +an +an +aL +cc +cc +aK +cc +bD +cc +bB +cc +bP +dL +cc +dM +bB +bH +bH +bB +ye +aU +ye +cc +"} +(20,1,1) = {" +aa +Mv +cc +ye +cc +aL +ar +an +an +am +an +aL +aV +bb +bm +cc +bu +aA +bB +bB +cc +cc +bY +bB +bB +bH +bB +ye +aU +cu +ye +cc +"} +(21,1,1) = {" +aa +hY +cc +ye +cc +aL +aw +aB +aL +am +aL +aQ +aN +bc +bc +bf +cc +aK +br +bB +bB +cc +bB +bH +bB +bB +bB +ye +aU +ye +ye +cc +"} +(22,1,1) = {" +aa +Mv +cc +ye +aq +ao +ar +aL +aP +am +aL +aR +aN +bc +bc +bq +ch +bw +cc +bB +bB +bH +bH +bH +bB +bW +dO +cc +aU +ye +cc +cc +"} +(23,1,1) = {" +aa +aa +cc +ye +cc +cc +ar +an +an +aD +aK +aN +aW +bd +bh +bf +cc +br +br +bB +bB +bH +bH +bB +bB +cc +cc +ye +cu +ye +cc +aa +"} +(24,1,1) = {" +aa +aa +cc +ye +cc +cc +as +an +aL +an +aL +aL +aV +be +bf +cc +bs +br +bB +bB +bB +bB +bB +cc +bB +bB +ye +cu +ye +ye +cc +aa +"} +(25,1,1) = {" +aa +aa +cc +ye +ye +cc +ar +an +an +an +aC +ap +aL +cc +cc +br +br +bB +bB +bB +bH +bW +bB +bB +bB +cc +ye +aU +ye +cc +cc +aa +"} +(26,1,1) = {" +aa +aa +cc +cc +ye +cc +cc +aC +ap +aG +af +af +aE +cc +ye +cc +bO +bB +bB +cc +bB +bB +cc +bB +bB +ye +cu +ye +ye +cc +Yf +aa +"} +(27,1,1) = {" +aa +aa +aa +cc +cc +ye +ye +cc +cu +cc +aM +ar +cu +cc +ye +cc +cc +cc +cc +cc +bB +bB +bB +ye +ye +ye +ye +ye +cc +cc +aa +aa +"} +(28,1,1) = {" +aa +aa +aa +aa +cc +cc +ye +ye +ye +aU +aU +aU +cc +ye +cc +cc +gX +gX +gX +cc +cc +ye +ye +cu +aU +ye +ye +cc +cc +aa +aa +aa +"} +(29,1,1) = {" +aa +aa +aa +aa +aa +cc +cc +cc +ye +ye +ye +ye +ye +cc +cc +gX +gX +KX +gX +gX +cc +cc +ye +ye +ye +cc +cc +cc +aa +aa +aa +aa +"} +(30,1,1) = {" +aa +aa +aa +aa +aa +aa +aa +cc +cc +cc +cc +cc +cc +cc +MR +XO +XO +XO +XO +gX +MR +cc +cc +cc +cc +cc +aa +aa +aa +aa +aa +aa +"} +(31,1,1) = {" +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +XO +gX +XO +XO +XO +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +"} diff --git a/_maps/map_files/RandomRuins/LavaRuins/lavaland_biodome_winter.dmm b/_maps/map_files/RandomRuins/LavaRuins/lavaland_biodome_winter.dmm new file mode 100644 index 00000000000..01797b0ea59 --- /dev/null +++ b/_maps/map_files/RandomRuins/LavaRuins/lavaland_biodome_winter.dmm @@ -0,0 +1,1364 @@ +//MAP CONVERTED BY dmm2tgm.py THIS HEADER COMMENT PREVENTS RECONVERSION, DO NOT REMOVE +"aa" = ( +/turf/template_noop, +/area/template_noop) +"ab" = ( +/obj/effect/baseturf_helper/lava_land/surface, +/turf/simulated/floor/plating/asteroid/snow/atmosphere, +/area/ruin/powered/snow_biodome) +"ac" = ( +/obj/item/stack/medical/ointment, +/obj/structure/table, +/obj/item/stack/medical/bruise_pack, +/turf/simulated/floor/plating, +/area/ruin/powered/snow_biodome) +"ad" = ( +/obj/structure/table, +/obj/item/stack/medical/bruise_pack, +/obj/item/stack/medical/bruise_pack, +/obj/machinery/light/small{ + dir = 1 + }, +/turf/simulated/floor/plating, +/area/ruin/powered/snow_biodome) +"ae" = ( +/obj/machinery/power/smes, +/turf/simulated/floor/plating, +/area/ruin/powered/snow_biodome) +"af" = ( +/turf/simulated/floor/plating, +/area/ruin/powered/snow_biodome) +"ag" = ( +/obj/structure/reagent_dispensers/beerkeg, +/obj/machinery/light/small{ + dir = 1 + }, +/turf/simulated/floor/plating, +/area/ruin/powered/snow_biodome) +"ah" = ( +/obj/item/reagent_containers/food/drinks/mug, +/turf/simulated/floor/plating, +/area/ruin/powered/snow_biodome) +"ai" = ( +/obj/machinery/shower, +/turf/simulated/floor/plating, +/area/ruin/powered/snow_biodome) +"aj" = ( +/obj/structure/sink, +/obj/machinery/light/small{ + dir = 1 + }, +/turf/simulated/floor/plating, +/area/ruin/powered/snow_biodome) +"ak" = ( +/turf/simulated/floor/plating/asteroid/snow/atmosphere, +/area/ruin/powered/snow_biodome) +"al" = ( +/obj/effect/decal/cleanable/blood/oil, +/turf/simulated/floor/plating, +/area/ruin/powered/snow_biodome) +"am" = ( +/obj/machinery/door/airlock/hatch, +/turf/simulated/floor/plating, +/area/ruin/powered/snow_biodome) +"an" = ( +/obj/structure/toilet{ + dir = 8 + }, +/turf/simulated/floor/plating, +/area/ruin/powered/snow_biodome) +"ao" = ( +/turf/simulated/floor/plating/ice/smooth, +/area/ruin/powered/snow_biodome) +"ap" = ( +/obj/structure/flora/rock/icy, +/turf/simulated/floor/plating/asteroid/snow/atmosphere, +/area/ruin/powered/snow_biodome) +"aq" = ( +/turf/simulated/wall/mineral/wood, +/area/ruin/powered/snow_cabin) +"ar" = ( +/obj/machinery/door/airlock/wood, +/turf/simulated/floor/plating, +/area/ruin/powered/snow_cabin) +"as" = ( +/obj/structure/fans, +/turf/simulated/wall/mineral/wood, +/area/ruin/powered/snow_cabin) +"at" = ( +/turf/simulated/floor/wood, +/area/ruin/powered/snow_cabin) +"au" = ( +/obj/structure/bed, +/obj/item/bedsheet/blue, +/turf/simulated/floor/wood, +/area/ruin/powered/snow_cabin) +"av" = ( +/obj/structure/bookcase/random, +/turf/simulated/floor/wood, +/area/ruin/powered/snow_cabin) +"aw" = ( +/obj/structure/table/wood, +/turf/simulated/floor/wood, +/area/ruin/powered/snow_cabin) +"ax" = ( +/obj/structure/table/wood, +/obj/item/reagent_containers/food/snacks/beans, +/turf/simulated/floor/wood, +/area/ruin/powered/snow_cabin) +"ay" = ( +/obj/structure/closet/crate/trashcart, +/obj/item/trash/semki, +/obj/item/trash/candy, +/turf/simulated/floor/plating/asteroid/snow/atmosphere, +/area/ruin/powered/snow_biodome) +"az" = ( +/obj/structure/flora/tree/pine, +/turf/simulated/floor/plating/asteroid/snow/atmosphere, +/area/ruin/powered/snow_biodome) +"aA" = ( +/obj/structure/chair/comfy/brown{ + dir = 4 + }, +/turf/simulated/floor/wood, +/area/ruin/powered/snow_cabin) +"aB" = ( +/obj/structure/flora/rock/pile/icy, +/turf/simulated/floor/plating/asteroid/snow/atmosphere, +/area/ruin/powered/snow_biodome) +"aC" = ( +/obj/structure/flora/tree/dead, +/turf/simulated/floor/plating/asteroid/snow/atmosphere, +/area/ruin/powered/snow_biodome) +"aD" = ( +/obj/machinery/door/airlock/wood, +/turf/simulated/floor/wood, +/area/ruin/powered/snow_cabin) +"aE" = ( +/obj/structure/extinguisher_cabinet, +/turf/simulated/wall/mineral/wood, +/area/ruin/powered/snow_cabin) +"aF" = ( +/obj/structure/table/wood, +/obj/item/reagent_containers/food/drinks/h_chocolate, +/turf/simulated/floor/wood, +/area/ruin/powered/snow_cabin) +"aG" = ( +/obj/structure/chair/comfy/brown{ + dir = 8 + }, +/turf/simulated/floor/wood, +/area/ruin/powered/snow_cabin) +"aH" = ( +/mob/living/simple_animal/hostile/skeleton/eskimo, +/turf/simulated/floor/wood, +/area/ruin/powered/snow_cabin) +"aI" = ( +/obj/structure/flora/bush, +/turf/simulated/floor/plating/asteroid/snow/atmosphere, +/area/ruin/powered/snow_biodome) +"aJ" = ( +/obj/vehicle/atv, +/turf/simulated/floor/plating/asteroid/snow/atmosphere, +/area/ruin/powered/snow_biodome) +"aK" = ( +/obj/structure/table/wood, +/obj/item/key/snowmobile, +/turf/simulated/floor/wood, +/area/ruin/powered/snow_cabin) +"aL" = ( +/obj/structure/displaycase/lavaland_winter, +/turf/simulated/floor/wood, +/area/ruin/powered/snow_cabin) +"aM" = ( +/turf/simulated/floor/carpet, +/area/ruin/powered/snow_cabin) +"aN" = ( +/obj/structure/bed/dogbed, +/turf/simulated/floor/wood, +/area/ruin/powered/snow_cabin) +"aO" = ( +/obj/machinery/door/airlock/multi_tile/glass, +/obj/structure/fans/tiny, +/turf/simulated/floor/pod/dark, +/area/ruin/powered/snow_biodome) +"aP" = ( +/obj/structure/fans/tiny, +/turf/simulated/floor/pod/dark, +/area/ruin/powered/snow_biodome) +"aQ" = ( +/obj/structure/flora/grass/both, +/turf/simulated/floor/plating/asteroid/snow/atmosphere, +/area/ruin/powered/snow_biodome) +"aR" = ( +/obj/structure/flora/tree/pine/xmas, +/turf/simulated/floor/plating/asteroid/snow/atmosphere, +/area/ruin/powered/snow_biodome) +"bi" = ( +/obj/structure/fans/tiny, +/turf/simulated/floor/pod/dark, +/area/ruin/powered/snow_cabin) +"bl" = ( +/turf/simulated/floor/wood/cold, +/area/ruin/powered/snow_biodome) +"bv" = ( +/obj/machinery/light{ + dir = 1 + }, +/turf/simulated/floor/plating/ice/smooth, +/area/ruin/powered/snow_biodome) +"bw" = ( +/obj/machinery/light/small{ + dir = 8 + }, +/turf/simulated/floor/wood, +/area/ruin/powered/snow_cabin) +"bx" = ( +/obj/machinery/light{ + dir = 4 + }, +/turf/simulated/floor/wood, +/area/ruin/powered/snow_cabin) +"by" = ( +/obj/machinery/light{ + dir = 8 + }, +/turf/simulated/floor/plating/asteroid/snow/atmosphere, +/area/ruin/powered/snow_biodome) +"bz" = ( +/obj/machinery/light, +/turf/simulated/floor/wood, +/area/ruin/powered/snow_cabin) +"bB" = ( +/obj/machinery/light{ + dir = 4 + }, +/turf/simulated/floor/plating/asteroid/snow/atmosphere, +/area/ruin/powered/snow_biodome) +"bD" = ( +/obj/machinery/light{ + dir = 1 + }, +/turf/simulated/floor/plating/asteroid/snow/atmosphere, +/area/ruin/powered/snow_biodome) +"bM" = ( +/obj/machinery/light, +/turf/simulated/floor/plating/asteroid/snow/atmosphere, +/area/ruin/powered/snow_biodome) +"bN" = ( +/obj/machinery/light, +/turf/simulated/floor/plating/ice/smooth, +/area/ruin/powered/snow_biodome) +"dS" = ( +/obj/machinery/light/small, +/turf/simulated/floor/pod/dark, +/area/ruin/powered/snow_biodome) +"eb" = ( +/obj/machinery/light/small{ + dir = 4 + }, +/turf/simulated/floor/pod/dark, +/area/ruin/powered/snow_biodome) +"eg" = ( +/obj/machinery/vending/coffee, +/turf/simulated/floor/pod/dark, +/area/ruin/powered/snow_biodome) +"gh" = ( +/obj/machinery/light/small{ + dir = 8 + }, +/turf/simulated/floor/pod/dark, +/area/ruin/powered/snow_biodome) +"gz" = ( +/obj/structure/chair/stool, +/turf/simulated/floor/pod/dark, +/area/ruin/powered/snow_biodome) +"hA" = ( +/obj/machinery/light/built{ + dir = 1 + }, +/obj/effect/mapping_helpers/no_lava, +/turf/simulated/floor/pod/dark, +/area/ruin/powered/snow_biodome) +"qt" = ( +/obj/machinery/door/airlock/silver, +/obj/structure/fans/tiny, +/turf/simulated/floor/pod/dark, +/area/ruin/powered/snow_biodome) +"tb" = ( +/obj/effect/mapping_helpers/no_lava, +/turf/simulated/floor/plating/asteroid/basalt/lava_land_surface, +/area/lavaland/surface/outdoors/explored) +"tl" = ( +/turf/simulated/floor/pod/light, +/area/ruin/powered/snow_biodome) +"vf" = ( +/obj/machinery/door/airlock/multi_tile/glass, +/obj/structure/fans/tiny, +/turf/simulated/floor/pod/dark, +/area/ruin/powered/snow_cabin) +"xU" = ( +/obj/item/storage/toolbox/mechanical, +/turf/simulated/floor/pod/dark, +/area/ruin/powered/snow_biodome) +"zT" = ( +/obj/machinery/door/airlock/silver, +/obj/structure/fans/tiny, +/turf/simulated/floor/plating, +/area/ruin/powered/snow_biodome) +"AM" = ( +/obj/structure/table, +/obj/item/pen, +/obj/item/paper, +/turf/simulated/floor/pod/dark, +/area/ruin/powered/snow_biodome) +"Dd" = ( +/obj/structure/rack, +/obj/item/clothing/suit/hooded/wintercoat/science, +/obj/item/clothing/shoes/winterboots, +/obj/item/clothing/gloves/fingerless, +/turf/simulated/floor/pod/dark, +/area/ruin/powered/snow_biodome) +"Ef" = ( +/obj/structure/reagent_dispensers/fueltank, +/turf/simulated/floor/pod/dark, +/area/ruin/powered/snow_biodome) +"Ez" = ( +/obj/structure/fans/tiny, +/obj/machinery/door/airlock/multi_tile/glass, +/turf/simulated/floor/pod/dark, +/area/ruin/powered/snow_biodome) +"HP" = ( +/turf/simulated/floor/pod/dark, +/area/ruin/powered/snow_biodome) +"HR" = ( +/obj/structure/closet/secure_closet/freezer/fridge/open, +/turf/simulated/floor/pod/dark, +/area/ruin/powered/snow_biodome) +"JZ" = ( +/obj/structure/table, +/obj/machinery/microwave, +/turf/simulated/floor/pod/dark, +/area/ruin/powered/snow_biodome) +"KS" = ( +/obj/structure/closet, +/obj/machinery/light/small{ + dir = 4 + }, +/obj/item/twohanded/required/chainsaw, +/turf/simulated/floor/pod/dark, +/area/ruin/powered/snow_biodome) +"Mp" = ( +/obj/item/clothing/mask/balaclava, +/turf/simulated/floor/pod/dark, +/area/ruin/powered/snow_biodome) +"Oj" = ( +/obj/structure/table, +/turf/simulated/floor/pod/dark, +/area/ruin/powered/snow_biodome) +"PD" = ( +/obj/machinery/door/airlock/hatch, +/obj/structure/fans/tiny, +/turf/simulated/floor/pod/dark, +/area/ruin/powered/snow_biodome) +"PK" = ( +/obj/structure/table, +/obj/item/pen, +/obj/item/paper_bin, +/turf/simulated/floor/pod/dark, +/area/ruin/powered/snow_biodome) +"Qa" = ( +/obj/effect/mapping_helpers/no_lava, +/obj/effect/mapping_helpers/no_lava, +/turf/simulated/floor/plating/asteroid/basalt/lava_land_surface, +/area/lavaland/surface/outdoors/explored) +"QI" = ( +/turf/simulated/floor/plating/asteroid/basalt/lava_land_surface, +/area/lavaland/surface/outdoors/explored) +"QK" = ( +/obj/structure/table, +/obj/item/storage/fancy/cigarettes/cigpack_carp, +/turf/simulated/floor/pod/dark, +/area/ruin/powered/snow_biodome) +"QN" = ( +/obj/effect/spawner/window, +/turf/simulated/floor/plating, +/area/ruin/powered/snow_biodome) +"Sj" = ( +/obj/effect/decal/cleanable/blood/oil, +/turf/simulated/floor/pod/dark, +/area/ruin/powered/snow_biodome) +"Ub" = ( +/obj/structure/filingcabinet, +/turf/simulated/floor/pod/dark, +/area/ruin/powered/snow_biodome) +"UM" = ( +/obj/machinery/computer/monitor/secret{ + dir = 1 + }, +/turf/simulated/floor/pod/dark, +/area/ruin/powered/snow_biodome) +"Wg" = ( +/turf/simulated/wall/r_wall, +/area/ruin/powered/snow_biodome) + +(1,1,1) = {" +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +Wg +Wg +Wg +Wg +PD +Wg +Wg +Wg +Wg +Wg +Wg +aa +aa +aa +aa +aa +aa +aa +aa +aa +"} +(2,1,1) = {" +aa +aa +aa +aa +aa +aa +Wg +Wg +Wg +Wg +Wg +Dd +gh +HP +tl +gh +HP +Ub +Wg +Wg +Wg +Wg +Wg +aa +aa +aa +aa +aa +aa +aa +"} +(3,1,1) = {" +aa +aa +aa +aa +Wg +Wg +Wg +ak +by +ak +Wg +Dd +HP +HP +tl +PK +gz +UM +Wg +ak +ak +ak +Wg +Wg +Wg +QI +QI +aa +aa +aa +"} +(4,1,1) = {" +aa +aa +aa +Wg +Wg +ak +aC +ak +ak +ak +Wg +QN +QN +QN +qt +QN +QN +QN +Wg +ak +ak +ak +ak +ak +Wg +Wg +QI +QI +aa +aa +"} +(5,1,1) = {" +aa +aa +Wg +Wg +ao +ao +ak +aI +ak +ak +by +az +ak +aB +ak +ak +ak +aI +by +ak +ak +ak +ak +ak +ak +Wg +Wg +QI +tb +aa +"} +(6,1,1) = {" +aa +aa +Wg +bv +ao +ao +ao +ao +ak +aI +ak +ak +ak +ak +ak +ak +ak +ak +ak +aQ +ak +ak +ak +az +ak +ak +Wg +QI +tb +aa +"} +(7,1,1) = {" +aa +Wg +Wg +ap +ak +ao +ao +ao +ao +ak +ak +ak +ak +ak +az +ak +aC +ak +ak +aI +aI +ak +ak +ak +ak +bM +Wg +Wg +tb +aa +"} +(8,1,1) = {" +aa +Wg +ak +ak +ak +ak +ak +ao +ao +ao +ao +ak +ak +ak +ak +ak +ak +ak +ap +aI +ak +aQ +ak +ak +ak +az +ak +Wg +tb +tb +"} +(9,1,1) = {" +aa +Wg +Wg +Wg +ak +az +ak +ak +ao +ao +ao +ao +ao +ak +ak +ak +ak +ak +ak +ak +ak +aC +ak +ak +ak +ak +ak +Wg +hA +tb +"} +(10,1,1) = {" +Wg +Wg +af +Wg +ak +ak +ak +ak +ak +ak +ak +ao +ao +ao +ao +ak +aI +az +ak +ak +ak +ak +ak +aI +ak +ak +ak +Wg +tb +tb +"} +(11,1,1) = {" +Wg +ac +af +aq +aq +aq +aq +aq +aq +aq +bD +ao +ao +ao +ao +ao +ak +ak +bl +bl +ak +aI +ak +ak +ak +Wg +Wg +Wg +Wg +tb +"} +(12,1,1) = {" +Wg +ad +af +ar +bw +at +aD +at +aL +aq +ak +az +ak +ao +ao +ao +ao +ao +bl +bl +ak +ak +ak +az +bM +Wg +Dd +Dd +Wg +tb +"} +(13,1,1) = {" +Wg +ae +af +aq +au +au +aq +at +bz +aq +ak +ak +ak +ao +ao +ao +ao +ao +bl +bl +ao +ak +ak +ak +aI +Wg +Mp +dS +Wg +tb +"} +(14,1,1) = {" +Wg +af +al +aq +aq +aq +aE +at +at +aq +ak +ak +aC +ak +ao +ak +ao +ao +bl +bl +ao +ao +aI +ak +ak +Wg +tl +tl +Wg +tb +"} +(15,1,1) = {" +Wg +ae +af +aq +av +at +at +aH +aM +vf +ap +ak +ak +ak +ak +ak +ak +ao +bl +bl +ao +ao +ak +ak +ak +aO +tl +tl +Ez +Qa +"} +(16,1,1) = {" +Wg +ag +ah +as +aw +aA +aA +at +aM +bi +ak +ak +aQ +ak +ak +az +ak +ak +bl +bl +ak +ao +ao +ak +ak +aP +tl +tl +aP +Qa +"} +(17,1,1) = {" +Wg +ah +af +aq +ax +aK +aF +at +at +aq +ak +aI +ak +ak +ak +ak +ak +ak +ak +ak +ak +ao +ao +ao +ak +Wg +tl +tl +Wg +tb +"} +(18,1,1) = {" +Wg +Wg +am +aq +av +at +aG +at +bz +aq +aR +ak +ak +ak +ak +ab +ak +ak +aC +ak +ak +ak +ao +ao +ao +Wg +HP +dS +Wg +tb +"} +(19,1,1) = {" +Wg +ai +af +aq +av +bx +aH +at +aN +aq +ak +ak +ak +az +ak +ak +ak +ak +ak +ak +ak +ak +ak +ao +bN +Wg +QK +AM +Wg +tb +"} +(20,1,1) = {" +Wg +aj +af +aq +aq +aq +aq +aq +aq +aq +bD +ak +ak +ak +ak +aI +ak +az +ak +ak +ak +ak +az +ak +ao +Wg +Wg +Wg +Wg +tb +"} +(21,1,1) = {" +Wg +Wg +an +Wg +ay +ak +ak +ak +ak +ak +ak +ak +ak +ak +aC +ak +ak +ak +ak +ap +ak +ak +ak +ak +ak +ak +ak +Wg +tb +tb +"} +(22,1,1) = {" +aa +Wg +Wg +Wg +ak +ak +aI +ak +ap +ak +ak +ak +ak +ak +ak +ak +ak +ak +ak +ak +aI +ak +ak +aQ +ak +ak +ak +Wg +hA +tb +"} +(23,1,1) = {" +aa +Wg +ak +ak +az +ak +aJ +ak +ak +ak +ak +ak +ak +az +ak +aQ +ak +aC +ak +aI +ak +az +aI +aI +ak +ak +ak +Wg +tb +tb +"} +(24,1,1) = {" +aa +Wg +Wg +ak +ak +aB +ak +ak +aC +ak +ak +ak +ak +aI +ak +ap +ak +ak +ak +ak +ak +ak +aI +aI +ak +bM +Wg +Wg +tb +aa +"} +(25,1,1) = {" +aa +aa +Wg +ap +ak +ak +ak +ak +ak +aQ +ak +ak +ak +aI +ak +ak +ak +ak +aQ +ak +ak +aB +ak +ak +aC +ak +Wg +QI +tb +aa +"} +(26,1,1) = {" +aa +aa +Wg +Wg +ak +ak +az +ak +ak +ak +bB +ak +ak +ak +ak +ak +az +ak +bB +ak +ak +az +ak +ak +ak +Wg +Wg +QI +aa +aa +"} +(27,1,1) = {" +aa +aa +aa +Wg +Wg +ak +ak +ak +ak +ak +Wg +QN +QN +QN +zT +QN +QN +QN +Wg +ak +ak +ak +ak +ak +Wg +Wg +QI +QI +aa +aa +"} +(28,1,1) = {" +aa +aa +aa +aa +Wg +Wg +Wg +ak +bB +ak +Wg +eg +HP +tl +tl +tl +Sj +xU +Wg +ak +bB +ak +Wg +Wg +Wg +QI +QI +aa +aa +aa +"} +(29,1,1) = {" +aa +aa +aa +aa +aa +aa +Wg +Wg +Wg +Wg +Wg +HR +eb +gz +Oj +JZ +KS +Ef +Wg +Wg +Wg +Wg +Wg +aa +aa +aa +aa +aa +aa +aa +"} +(30,1,1) = {" +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +Wg +Wg +Wg +Wg +Wg +Wg +Wg +Wg +Wg +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +"} diff --git a/_maps/map_files/RandomRuins/LavaRuins/lavaland_surface_syndicate_base1.dmm b/_maps/map_files/RandomRuins/LavaRuins/lavaland_surface_syndicate_base1.dmm index 421f2e62b53..279afa9713d 100644 --- a/_maps/map_files/RandomRuins/LavaRuins/lavaland_surface_syndicate_base1.dmm +++ b/_maps/map_files/RandomRuins/LavaRuins/lavaland_surface_syndicate_base1.dmm @@ -1611,15 +1611,6 @@ pixel_x = 1; pixel_y = -1 }, -/obj/item/radio/headset/syndicate/alt{ - pixel_x = -3; - pixel_y = 3 - }, -/obj/item/radio/headset/syndicate/alt, -/obj/item/radio/headset/syndicate/alt{ - pixel_x = 3; - pixel_y = -3 - }, /obj/effect/decal/cleanable/dirt, /turf/simulated/floor/plasteel/dark, /area/ruin/unpowered/syndicate_lava_base/cargo) @@ -3538,6 +3529,10 @@ /obj/machinery/alarm/syndicate{ pixel_y = 24 }, +/obj/item/radio/headset/syndicate/alt{ + pixel_x = -3; + pixel_y = 3 + }, /turf/simulated/floor/plasteel/grimy, /area/ruin/unpowered/syndicate_lava_base/dormitories) "hN" = ( @@ -3563,6 +3558,10 @@ /obj/machinery/alarm/syndicate{ pixel_y = 24 }, +/obj/item/radio/headset/syndicate/alt{ + pixel_x = -3; + pixel_y = 3 + }, /turf/simulated/floor/plasteel/grimy, /area/ruin/unpowered/syndicate_lava_base/dormitories) "hR" = ( @@ -4480,6 +4479,10 @@ /obj/structure/table/wood, /obj/item/ammo_box/magazine/m10mm, /obj/item/ammo_box/magazine/sniper_rounds, +/obj/item/radio/headset/syndicate/alt{ + pixel_x = -3; + pixel_y = 3 + }, /turf/simulated/floor/plasteel/grimy, /area/ruin/unpowered/syndicate_lava_base/dormitories) "jB" = ( @@ -6068,6 +6071,13 @@ /obj/structure/sign/fire, /turf/simulated/wall/mineral/plastitanium/coated, /area/ruin/unpowered/syndicate_lava_base/engineering) +"ng" = ( +/obj/structure/table, +/obj/machinery/photocopier/faxmachine/longrange/syndie{ + department = "Syndicate Bioweapon Research Outpost" + }, +/turf/simulated/floor/plasteel/dark, +/area/ruin/unpowered/syndicate_lava_base/telecomms) "nh" = ( /obj/machinery/telecomms/relay/preset/ruskie{ use_power = 0 @@ -7337,7 +7347,7 @@ ab ab ab mp -mP +ng nk nI oi diff --git a/_maps/map_files/RandomRuins/SpaceRuins/abandonedzoo.dmm b/_maps/map_files/RandomRuins/SpaceRuins/abandonedzoo.dmm index 805f97b6784..62a22425926 100644 --- a/_maps/map_files/RandomRuins/SpaceRuins/abandonedzoo.dmm +++ b/_maps/map_files/RandomRuins/SpaceRuins/abandonedzoo.dmm @@ -397,7 +397,6 @@ /obj/structure/rack, /obj/item/clothing/suit/space/hardsuit/medical, /obj/item/tank/emergency_oxygen/double, -/obj/item/clothing/head/helmet/space/hardsuit/medical, /turf/simulated/floor/plasteel{ icon_state = "dark" }, diff --git a/_maps/map_files/RandomRuins/SpaceRuins/oldstation.dmm b/_maps/map_files/RandomRuins/SpaceRuins/oldstation.dmm index 3ba27975660..58eae91a94f 100644 --- a/_maps/map_files/RandomRuins/SpaceRuins/oldstation.dmm +++ b/_maps/map_files/RandomRuins/SpaceRuins/oldstation.dmm @@ -4168,7 +4168,6 @@ "jB" = ( /obj/structure/table/reinforced, /obj/item/clothing/suit/space/hardsuit/ancient, -/obj/item/clothing/head/helmet/space/hardsuit/ancient, /obj/effect/decal/cleanable/dirt, /turf/simulated/floor/plasteel{ icon_state = "white" diff --git a/_maps/map_files/RandomRuins/SpaceRuins/onehalf.dmm b/_maps/map_files/RandomRuins/SpaceRuins/onehalf.dmm index 8f19d1cc390..fa38a1a647b 100644 --- a/_maps/map_files/RandomRuins/SpaceRuins/onehalf.dmm +++ b/_maps/map_files/RandomRuins/SpaceRuins/onehalf.dmm @@ -1132,7 +1132,6 @@ /obj/item/reagent_containers/food/drinks/bottle/rum, /obj/item/reagent_containers/food/drinks/bottle/rum, /obj/item/folder/syndicate/blue, -/obj/item/clothing/head/helmet/space/hardsuit/syndi, /turf/simulated/floor/plating, /area/ruin/onehalf/bridge) "cN" = ( diff --git a/_maps/map_files/RandomZLevels/academy.dmm b/_maps/map_files/RandomZLevels/academy.dmm index 5d22afc5fcd..2f37e69604e 100644 --- a/_maps/map_files/RandomZLevels/academy.dmm +++ b/_maps/map_files/RandomZLevels/academy.dmm @@ -243,7 +243,6 @@ /obj/item/stack/sheet/mineral/silver{ amount = 20 }, -/obj/item/clothing/head/helmet/space/hardsuit/wizard, /turf/simulated/floor/wood, /area/awaymission/academy/headmaster) "aM" = ( diff --git a/_maps/map_files/RandomZLevels/beach.dmm b/_maps/map_files/RandomZLevels/beach.dmm index 2931d7175b7..fe4060ad52d 100644 --- a/_maps/map_files/RandomZLevels/beach.dmm +++ b/_maps/map_files/RandomZLevels/beach.dmm @@ -13,7 +13,7 @@ /turf/unsimulated/beach/water/deep/rock_wall, /area/awaymission/undersea) "ae" = ( -/obj/structure/ladder/dive_point/anchor{ +/obj/structure/ladder/unbreakable/dive_point/anchor{ id = "pirate" }, /turf/unsimulated/beach/water/deep/sand_floor, @@ -217,7 +217,7 @@ /turf/unsimulated/beach/water/deep/wood_floor, /area/awaymission/undersea) "aU" = ( -/obj/structure/ladder/dive_point/anchor, +/obj/structure/ladder/unbreakable/dive_point/anchor, /turf/unsimulated/beach/water/deep/sand_floor, /area/awaymission/undersea) "aV" = ( @@ -1113,7 +1113,7 @@ /turf/unsimulated/beach/water/deep, /area/awaymission/beach) "dv" = ( -/obj/structure/ladder/dive_point/buoy, +/obj/structure/ladder/unbreakable/dive_point/buoy, /turf/unsimulated/beach/water/deep, /area/awaymission/beach) "dw" = ( @@ -1306,7 +1306,7 @@ }, /area/awaymission/beach) "dW" = ( -/obj/structure/ladder/dive_point/buoy{ +/obj/structure/ladder/unbreakable/dive_point/buoy{ id = "pirate" }, /turf/unsimulated/beach/water, diff --git a/_maps/map_files/RandomZLevels/example.dmm b/_maps/map_files/RandomZLevels/example.dmm index fd85d240c36..779a0bede34 100644 --- a/_maps/map_files/RandomZLevels/example.dmm +++ b/_maps/map_files/RandomZLevels/example.dmm @@ -261,7 +261,7 @@ /turf/simulated/floor/plasteel, /area/awaymission/example) "aH" = ( -/obj/structure/ladder{ +/obj/structure/ladder/unbreakable{ height = 1; id = "example" }, @@ -782,7 +782,7 @@ /turf/simulated/floor/plasteel, /area/awaymission/example) "ca" = ( -/obj/structure/ladder{ +/obj/structure/ladder/unbreakable{ id = "example" }, /turf/simulated/floor/plating, diff --git a/_maps/map_files/RandomZLevels/spacebattle.dmm b/_maps/map_files/RandomZLevels/spacebattle.dmm index 17341581c9a..2525d05730f 100644 --- a/_maps/map_files/RandomZLevels/spacebattle.dmm +++ b/_maps/map_files/RandomZLevels/spacebattle.dmm @@ -406,7 +406,6 @@ /area/awaymission/spacebattle/syndicate3) "bg" = ( /obj/structure/table/reinforced, -/obj/item/clothing/head/helmet/space/hardsuit/syndi, /turf/simulated/shuttle/floor{ icon_state = "floor4" }, @@ -2261,7 +2260,6 @@ "hl" = ( /obj/structure/rack, /obj/item/clothing/suit/space/hardsuit, -/obj/item/clothing/head/helmet/space/hardsuit, /turf/simulated/floor/plasteel, /area/awaymission/spacebattle/cruiser) "hn" = ( diff --git a/_maps/map_files/RandomZLevels/spacehotel.dmm b/_maps/map_files/RandomZLevels/spacehotel.dmm index 8394ca1b635..4b45711ff3d 100644 --- a/_maps/map_files/RandomZLevels/spacehotel.dmm +++ b/_maps/map_files/RandomZLevels/spacehotel.dmm @@ -540,7 +540,7 @@ requires_power = 0 }) "aZ" = ( -/obj/structure/ladder/dive_point/anchor{ +/obj/structure/ladder/unbreakable/dive_point/anchor{ id = "weirddive"; layer = 4.5 }, @@ -1996,7 +1996,7 @@ requires_power = 0 }) "dA" = ( -/obj/structure/ladder/dive_point/anchor{ +/obj/structure/ladder/unbreakable/dive_point/anchor{ layer = 4.5 }, /turf/unsimulated/beach/water/deep/wood_floor{ @@ -2721,8 +2721,8 @@ /turf/unsimulated/beach/water/drop, /area/awaymission/spacehotel) "fC" = ( -/obj/structure/ladder/dive_point/buoy, -/obj/structure/ladder/dive_point/buoy{ +/obj/structure/ladder/unbreakable/dive_point/buoy, +/obj/structure/ladder/unbreakable/dive_point/buoy{ id = "weirddive"; invisibility = 101 }, @@ -3465,7 +3465,7 @@ }, /area/awaymission/spacehotel) "hG" = ( -/obj/structure/ladder{ +/obj/structure/ladder/unbreakable{ height = 1; icon_state = "ladder10"; id = "service" @@ -3525,7 +3525,7 @@ /area/awaymission/spacehotel) "hN" = ( /obj/effect/decal/cleanable/blood/old, -/obj/structure/ladder{ +/obj/structure/ladder/unbreakable{ height = 2; icon_state = "ladder01"; id = "service" diff --git a/_maps/map_files/cyberiad/cyberiad.dmm b/_maps/map_files/cyberiad/cyberiad.dmm index f57aa9bae01..7fdecb976a1 100644 --- a/_maps/map_files/cyberiad/cyberiad.dmm +++ b/_maps/map_files/cyberiad/cyberiad.dmm @@ -547,7 +547,6 @@ /obj/structure/rack, /obj/item/clothing/suit/space/hardsuit/medical, /obj/item/clothing/mask/breath, -/obj/item/clothing/head/helmet/space/hardsuit/medical, /turf/simulated/shuttle/floor{ icon_state = "floor3" }, @@ -2225,6 +2224,7 @@ icon_state = "1-2"; pixel_y = 0 }, +/obj/structure/fans/tiny, /turf/simulated/floor/plating, /area/security/prisonershuttle) "aeG" = ( @@ -4055,7 +4055,7 @@ /turf/simulated/floor/plasteel, /area/security/armoury) "ahH" = ( -/obj/machinery/deployable/barrier, +/obj/item/grenade/barrier, /obj/structure/window/reinforced{ dir = 8 }, @@ -4155,7 +4155,7 @@ }, /area/security/brig) "ahR" = ( -/obj/machinery/deployable/barrier, +/obj/item/grenade/barrier, /obj/structure/window/reinforced{ dir = 4 }, @@ -4324,7 +4324,7 @@ }, /area/security/brig) "aif" = ( -/obj/machinery/deployable/barrier, +/obj/item/grenade/barrier, /obj/structure/window/reinforced{ dir = 8 }, @@ -4370,7 +4370,7 @@ }, /area/security/brig) "aij" = ( -/obj/machinery/deployable/barrier, +/obj/item/grenade/barrier, /obj/structure/window/reinforced{ dir = 4 }, @@ -11418,10 +11418,6 @@ id_tag = "secmaintdorm1"; name = "Room 1" }, -/obj/effect/mapping_helpers/airlock/unres{ - icon_state = "airlock_unres_helper"; - dir = 1 - }, /turf/simulated/floor/plating, /area/maintenance/fsmaint) "ats" = ( @@ -11429,10 +11425,6 @@ id_tag = "secmaintdorm2"; name = "Room 2" }, -/obj/effect/mapping_helpers/airlock/unres{ - icon_state = "airlock_unres_helper"; - dir = 1 - }, /turf/simulated/floor/plating, /area/maintenance/fsmaint) "att" = ( @@ -12166,6 +12158,7 @@ name = "Labor Camp Airlock"; req_access_txt = "2" }, +/obj/structure/fans/tiny, /turf/simulated/floor/plating, /area/security/prisonershuttle) "auz" = ( @@ -12174,6 +12167,7 @@ name = "Labor Shuttle Airlock"; req_access_txt = "2" }, +/obj/structure/fans/tiny, /turf/simulated/shuttle/floor{ icon_state = "floor4" }, @@ -13181,16 +13175,6 @@ }, /turf/simulated/floor/plasteel, /area/security/lobby) -"avU" = ( -/obj/machinery/door/airlock/maintenance{ - req_access_txt = "12" - }, -/obj/effect/mapping_helpers/airlock/unres{ - icon_state = "airlock_unres_helper"; - dir = 4 - }, -/turf/simulated/floor/plating, -/area/maintenance/fsmaint) "avV" = ( /obj/machinery/atmospherics/pipe/simple/hidden/supply{ dir = 10 @@ -13214,10 +13198,6 @@ dir = 4; level = 1 }, -/obj/effect/mapping_helpers/airlock/unres{ - icon_state = "airlock_unres_helper"; - dir = 8 - }, /turf/simulated/floor/plasteel{ tag = "icon-cult"; icon_state = "cult"; @@ -14352,16 +14332,6 @@ icon_state = "darkredcorners" }, /area/security/prison/cell_block/A) -"axN" = ( -/obj/machinery/door/airlock/maintenance{ - req_access_txt = "12" - }, -/obj/effect/mapping_helpers/airlock/unres{ - icon_state = "airlock_unres_helper"; - dir = 1 - }, -/turf/simulated/floor/plating, -/area/maintenance/fsmaint) "axO" = ( /obj/structure/cable{ d1 = 1; @@ -14558,6 +14528,7 @@ name = "fore bay 1"; width = 9 }, +/obj/structure/fans/tiny, /turf/simulated/shuttle/floor, /area/shuttle/siberia) "ayi" = ( @@ -17788,10 +17759,6 @@ req_access_txt = "12" }, /obj/effect/decal/cleanable/dirt, -/obj/effect/mapping_helpers/airlock/unres{ - icon_state = "airlock_unres_helper"; - dir = 4 - }, /turf/simulated/floor/plasteel{ icon_state = "floorgrime" }, @@ -19009,13 +18976,6 @@ /obj/item/twohanded/required/kirbyplants, /turf/simulated/floor/wood, /area/crew_quarters/courtroom) -"aGv" = ( -/obj/machinery/door/airlock/maintenance{ - req_access_txt = "12" - }, -/obj/effect/mapping_helpers/airlock/unres, -/turf/simulated/floor/plating, -/area/maintenance/fsmaint) "aGw" = ( /obj/structure/disposalpipe/junction{ dir = 1; @@ -20068,10 +20028,6 @@ name = "Magistrate's Office"; req_access_txt = "74" }, -/obj/effect/mapping_helpers/airlock/unres{ - icon_state = "airlock_unres_helper"; - dir = 4 - }, /turf/simulated/floor/plasteel{ tag = "icon-cult"; icon_state = "cult"; @@ -20160,10 +20116,6 @@ /obj/machinery/door/airlock/maintenance{ req_access_txt = "12" }, -/obj/effect/mapping_helpers/airlock/unres{ - icon_state = "airlock_unres_helper"; - dir = 1 - }, /turf/simulated/floor/plating, /area/maintenance/fsmaint) "aIZ" = ( @@ -20743,16 +20695,6 @@ }, /turf/simulated/floor/plasteel, /area/hallway/primary/fore) -"aKp" = ( -/obj/machinery/door/airlock/maintenance{ - req_access_txt = "12" - }, -/obj/effect/mapping_helpers/airlock/unres{ - icon_state = "airlock_unres_helper"; - dir = 4 - }, -/turf/simulated/floor/plating, -/area/maintenance/fsmaint2) "aKq" = ( /obj/machinery/atmospherics/pipe/simple/hidden/scrubbers{ dir = 4 @@ -20826,10 +20768,6 @@ d2 = 2; icon_state = "1-2" }, -/obj/effect/mapping_helpers/airlock/unres{ - icon_state = "airlock_unres_helper"; - dir = 1 - }, /turf/simulated/floor/plasteel{ tag = "icon-cult"; icon_state = "cult"; @@ -21150,10 +21088,6 @@ req_access = null; req_access_txt = "4" }, -/obj/effect/mapping_helpers/airlock/unres{ - icon_state = "airlock_unres_helper"; - dir = 4 - }, /turf/simulated/floor/plasteel{ icon_state = "grimy" }, @@ -21192,10 +21126,6 @@ /obj/machinery/door/airlock/maintenance{ req_access_txt = "12" }, -/obj/effect/mapping_helpers/airlock/unres{ - icon_state = "airlock_unres_helper"; - dir = 4 - }, /turf/simulated/floor/plating, /area/maintenance/fpmaint2) "aLl" = ( @@ -21234,10 +21164,6 @@ req_access_txt = "12" }, /obj/effect/decal/cleanable/dirt, -/obj/effect/mapping_helpers/airlock/unres{ - icon_state = "airlock_unres_helper"; - dir = 8 - }, /turf/simulated/floor/wood{ tag = "icon-wood-broken3"; icon_state = "wood-broken3" @@ -22079,16 +22005,6 @@ }, /turf/simulated/floor/carpet, /area/crew_quarters/courtroom) -"aNe" = ( -/obj/machinery/door/airlock/maintenance{ - req_access_txt = "12" - }, -/obj/effect/mapping_helpers/airlock/unres{ - icon_state = "airlock_unres_helper"; - dir = 1 - }, -/turf/simulated/floor/plating, -/area/maintenance/fsmaint2) "aNf" = ( /obj/machinery/access_button{ command = "cycle_interior"; @@ -22464,10 +22380,6 @@ name = "Courtroom Privacy Shutters"; opacity = 0 }, -/obj/effect/mapping_helpers/airlock/unres{ - icon_state = "airlock_unres_helper"; - dir = 8 - }, /turf/simulated/floor/wood, /area/crew_quarters/courtroom) "aNT" = ( @@ -22567,16 +22479,6 @@ icon_state = "barber" }, /area/civilian/barber) -"aOa" = ( -/obj/machinery/door/airlock/maintenance{ - req_access_txt = "12" - }, -/obj/effect/mapping_helpers/airlock/unres{ - icon_state = "airlock_unres_helper"; - dir = 8 - }, -/turf/simulated/floor/plating, -/area/maintenance/fsmaint2) "aOb" = ( /obj/machinery/prize_counter, /obj/machinery/light{ @@ -22895,10 +22797,6 @@ icon_state = "1-2" }, /obj/machinery/atmospherics/pipe/simple/visible/purple, -/obj/effect/mapping_helpers/airlock/unres{ - icon_state = "airlock_unres_helper"; - dir = 1 - }, /turf/simulated/floor/plating, /area/maintenance/fpmaint2) "aOO" = ( @@ -22926,10 +22824,6 @@ name = "Courtroom Privacy Shutters"; opacity = 0 }, -/obj/effect/mapping_helpers/airlock/unres{ - icon_state = "airlock_unres_helper"; - dir = 8 - }, /turf/simulated/floor/wood, /area/crew_quarters/courtroom) "aOP" = ( @@ -23025,10 +22919,6 @@ /obj/machinery/atmospherics/pipe/simple/hidden/scrubbers{ dir = 4 }, -/obj/effect/mapping_helpers/airlock/unres{ - icon_state = "airlock_unres_helper"; - dir = 4 - }, /turf/simulated/floor/plating, /area/maintenance/fsmaint) "aPc" = ( @@ -23036,6 +22926,9 @@ /turf/simulated/wall, /area/maintenance/fpmaint2) "aPd" = ( +/obj/machinery/light_switch{ + pixel_y = 27 + }, /turf/simulated/floor/plasteel{ dir = 4; icon_state = "yellowcorner" @@ -23105,10 +22998,6 @@ /obj/machinery/atmospherics/pipe/simple/visible/purple{ dir = 4 }, -/obj/effect/mapping_helpers/airlock/unres{ - icon_state = "airlock_unres_helper"; - dir = 4 - }, /turf/simulated/floor/plating, /area/maintenance/fpmaint2) "aPi" = ( @@ -23418,10 +23307,6 @@ d2 = 2; icon_state = "1-2" }, -/obj/effect/mapping_helpers/airlock/unres{ - icon_state = "airlock_unres_helper"; - dir = 1 - }, /turf/simulated/floor/plating, /area/maintenance/fsmaint) "aPQ" = ( @@ -23476,10 +23361,6 @@ req_access_txt = "12" }, /obj/machinery/atmospherics/pipe/simple/hidden/supply, -/obj/effect/mapping_helpers/airlock/unres{ - icon_state = "airlock_unres_helper"; - dir = 1 - }, /turf/simulated/floor/plating, /area/maintenance/fsmaint) "aPV" = ( @@ -25238,10 +25119,6 @@ /obj/machinery/atmospherics/pipe/simple/hidden/supply{ dir = 4 }, -/obj/effect/mapping_helpers/airlock/unres{ - icon_state = "airlock_unres_helper"; - dir = 8 - }, /turf/simulated/floor/plating, /area/maintenance/fsmaint2) "aTt" = ( @@ -26043,7 +25920,6 @@ d2 = 2; icon_state = "1-2" }, -/obj/effect/mapping_helpers/airlock/unres, /turf/simulated/floor/plating, /area/maintenance/fpmaint) "aVc" = ( @@ -26512,10 +26388,6 @@ }, /obj/machinery/atmospherics/pipe/simple/hidden/supply, /obj/machinery/atmospherics/pipe/simple/hidden/scrubbers, -/obj/effect/mapping_helpers/airlock/unres{ - icon_state = "airlock_unres_helper"; - dir = 1 - }, /turf/simulated/floor/plating, /area/maintenance/fpmaint2) "aVM" = ( @@ -27629,13 +27501,6 @@ /obj/machinery/lapvend, /turf/simulated/floor/plasteel, /area/storage/primary) -"aXT" = ( -/obj/machinery/door/airlock/maintenance{ - req_access_txt = "12" - }, -/obj/effect/mapping_helpers/airlock/unres, -/turf/simulated/floor/plating, -/area/maintenance/fsmaint2) "aXU" = ( /obj/item/flag/mime, /obj/machinery/power/apc{ @@ -27956,6 +27821,9 @@ /obj/item/storage/fancy/cigarettes, /obj/item/lighter/zippo, /obj/item/pen/multi, +/obj/item/enginepicker{ + layer = 3.1 + }, /turf/simulated/floor/plasteel{ dir = 8; icon_state = "neutralfull" @@ -29493,16 +29361,6 @@ dir = 2 }, /area/crew_quarters/dorms) -"bbx" = ( -/obj/machinery/door/airlock/maintenance{ - req_access_txt = "12" - }, -/obj/effect/mapping_helpers/airlock/unres{ - icon_state = "airlock_unres_helper"; - dir = 8 - }, -/turf/simulated/floor/plating, -/area/maintenance/fpmaint2) "bby" = ( /obj/machinery/camera{ c_tag = "Medbay Morgue"; @@ -30065,10 +29923,6 @@ /obj/machinery/door/airlock/maintenance{ req_access_txt = "12" }, -/obj/effect/mapping_helpers/airlock/unres{ - icon_state = "airlock_unres_helper"; - dir = 4 - }, /turf/simulated/floor/plating, /area/maintenance/fpmaint) "bcw" = ( @@ -31207,10 +31061,6 @@ icon_state = "4-8"; tag = "" }, -/obj/effect/mapping_helpers/airlock/unres{ - icon_state = "airlock_unres_helper"; - dir = 8 - }, /turf/simulated/floor/plating, /area/maintenance/fpmaint) "bex" = ( @@ -31510,10 +31360,6 @@ name = "Mime's Office"; req_access_txt = "46" }, -/obj/effect/mapping_helpers/airlock/unres{ - icon_state = "airlock_unres_helper"; - dir = 4 - }, /turf/simulated/floor/plasteel{ icon_state = "tranquillite"; dir = 4; @@ -31584,10 +31430,6 @@ }, /obj/machinery/atmospherics/pipe/simple/hidden/supply, /obj/machinery/atmospherics/pipe/simple/hidden/scrubbers, -/obj/effect/mapping_helpers/airlock/unres{ - icon_state = "airlock_unres_helper"; - dir = 1 - }, /turf/simulated/floor/plating, /area/maintenance/fpmaint2) "bfg" = ( @@ -33022,8 +32864,8 @@ /obj/machinery/light{ dir = 1 }, -/obj/structure/reagent_dispensers/watertank/high, -/obj/item/reagent_containers/glass/bucket, +/obj/structure/table, +/obj/machinery/smartfridge/disks, /turf/simulated/floor/plasteel{ icon_state = "dark" }, @@ -33841,7 +33683,6 @@ name = "Clown's Office"; req_access_txt = "46" }, -/obj/effect/mapping_helpers/airlock/unres, /turf/simulated/floor/wood, /area/clownoffice) "bjf" = ( @@ -33855,10 +33696,6 @@ }, /obj/machinery/atmospherics/pipe/simple/hidden/supply, /obj/machinery/atmospherics/pipe/simple/hidden/scrubbers, -/obj/effect/mapping_helpers/airlock/unres{ - icon_state = "airlock_unres_helper"; - dir = 1 - }, /turf/simulated/floor/plating, /area/maintenance/fsmaint2) "bjh" = ( @@ -33872,10 +33709,6 @@ }, /obj/machinery/atmospherics/pipe/simple/hidden/scrubbers, /obj/machinery/atmospherics/pipe/simple/hidden/supply, -/obj/effect/mapping_helpers/airlock/unres{ - icon_state = "airlock_unres_helper"; - dir = 1 - }, /turf/simulated/floor/plating, /area/maintenance/fpmaint2) "bji" = ( @@ -36505,6 +36338,7 @@ /turf/simulated/floor/carpet, /area/crew_quarters/bar) "bou" = ( +/obj/item/reagent_containers/glass/bucket, /obj/structure/sink{ icon_state = "sink"; dir = 8; @@ -37143,7 +36977,6 @@ /obj/structure/disposalpipe/segment, /obj/machinery/atmospherics/pipe/simple/hidden/scrubbers, /obj/machinery/atmospherics/pipe/simple/hidden/supply, -/obj/effect/mapping_helpers/airlock/unres, /turf/simulated/floor/plating, /area/maintenance/fsmaint2) "bpF" = ( @@ -37423,10 +37256,6 @@ }, /obj/machinery/atmospherics/pipe/simple/hidden/supply, /obj/machinery/atmospherics/pipe/simple/hidden/scrubbers, -/obj/effect/mapping_helpers/airlock/unres{ - icon_state = "airlock_unres_helper"; - dir = 1 - }, /turf/simulated/floor/plating, /area/maintenance/fsmaint2) "bqk" = ( @@ -40030,10 +39859,6 @@ name = "Chapel Office"; req_access_txt = "22" }, -/obj/effect/mapping_helpers/airlock/unres{ - icon_state = "airlock_unres_helper"; - dir = 8 - }, /turf/simulated/floor/plasteel{ icon_state = "dark" }, @@ -40310,10 +40135,6 @@ name = "Bar Office"; req_access_txt = "25" }, -/obj/effect/mapping_helpers/airlock/unres{ - icon_state = "airlock_unres_helper"; - dir = 1 - }, /turf/simulated/floor/wood, /area/crew_quarters/bar) "bwm" = ( @@ -40716,10 +40537,6 @@ }, /obj/machinery/atmospherics/pipe/simple/hidden/scrubbers, /obj/machinery/atmospherics/pipe/simple/hidden/supply, -/obj/effect/mapping_helpers/airlock/unres{ - icon_state = "airlock_unres_helper"; - dir = 1 - }, /turf/simulated/floor/plating, /area/maintenance/fsmaint2) "bwY" = ( @@ -41513,10 +41330,6 @@ }, /obj/machinery/atmospherics/pipe/simple/hidden/supply, /obj/machinery/atmospherics/pipe/simple/hidden/scrubbers, -/obj/effect/mapping_helpers/airlock/unres{ - icon_state = "airlock_unres_helper"; - dir = 1 - }, /turf/simulated/floor/plating, /area/maintenance/fpmaint) "byt" = ( @@ -43421,10 +43234,6 @@ /obj/machinery/door/airlock/maintenance{ req_access_txt = "12" }, -/obj/effect/mapping_helpers/airlock/unres{ - icon_state = "airlock_unres_helper"; - dir = 1 - }, /turf/simulated/floor/plating, /area/maintenance/fpmaint) "bCr" = ( @@ -48798,20 +48607,6 @@ icon_state = "brown" }, /area/quartermaster/office) -"bMz" = ( -/obj/machinery/door/firedoor, -/obj/machinery/door/airlock/glass{ - name = "Chapel Office"; - req_access_txt = "22" - }, -/obj/effect/mapping_helpers/airlock/unres{ - icon_state = "airlock_unres_helper"; - dir = 1 - }, -/turf/simulated/floor/plasteel{ - icon_state = "dark" - }, -/area/chapel/office) "bMA" = ( /obj/machinery/mineral/ore_redemption, /turf/simulated/floor/plasteel, @@ -48856,10 +48651,6 @@ }, /obj/machinery/atmospherics/pipe/simple/hidden/supply, /obj/machinery/atmospherics/pipe/simple/hidden/scrubbers, -/obj/effect/mapping_helpers/airlock/unres{ - icon_state = "airlock_unres_helper"; - dir = 1 - }, /turf/simulated/floor/plasteel{ icon_state = "showroomfloor" }, @@ -49725,7 +49516,6 @@ }, /obj/structure/disposalpipe/segment, /obj/machinery/atmospherics/pipe/simple/hidden/supply, -/obj/effect/mapping_helpers/airlock/unres, /turf/simulated/floor/plating, /area/maintenance/port) "bNQ" = ( @@ -50007,7 +49797,6 @@ }, /obj/machinery/atmospherics/pipe/simple/hidden/supply, /obj/machinery/atmospherics/pipe/simple/hidden/scrubbers, -/obj/effect/mapping_helpers/airlock/unres, /turf/simulated/floor/plating, /area/maintenance/port) "bOo" = ( @@ -50668,7 +50457,6 @@ icon_state = "1-2"; tag = "" }, -/obj/effect/mapping_helpers/airlock/unres, /turf/simulated/floor/plating, /area/storage/emergency2) "bPs" = ( @@ -50727,10 +50515,6 @@ }, /obj/machinery/atmospherics/pipe/simple/hidden/scrubbers, /obj/machinery/atmospherics/pipe/simple/hidden/supply, -/obj/effect/mapping_helpers/airlock/unres{ - icon_state = "airlock_unres_helper"; - dir = 1 - }, /turf/simulated/floor/plating, /area/maintenance/fsmaint2) "bPy" = ( @@ -50925,10 +50709,6 @@ name = "Kitchen"; req_access_txt = "28" }, -/obj/effect/mapping_helpers/airlock/unres{ - icon_state = "airlock_unres_helper"; - dir = 4 - }, /turf/simulated/floor/plasteel{ dir = 2; icon_state = "cafeteria"; @@ -52143,10 +51923,6 @@ /obj/machinery/atmospherics/pipe/simple/hidden/scrubbers{ dir = 4 }, -/obj/effect/mapping_helpers/airlock/unres{ - icon_state = "airlock_unres_helper"; - dir = 4 - }, /turf/simulated/floor/plating, /area/maintenance/port) "bRI" = ( @@ -52629,7 +52405,6 @@ }, /obj/machinery/atmospherics/pipe/simple/hidden/supply, /obj/machinery/atmospherics/pipe/simple/hidden/scrubbers, -/obj/effect/mapping_helpers/airlock/unres, /turf/simulated/floor/plasteel{ icon_state = "white" }, @@ -52655,10 +52430,6 @@ /obj/machinery/atmospherics/pipe/simple/hidden/supply{ dir = 4 }, -/obj/effect/mapping_helpers/airlock/unres{ - icon_state = "airlock_unres_helper"; - dir = 8 - }, /turf/simulated/floor/plating, /area/maintenance/port) "bSB" = ( @@ -54252,10 +54023,6 @@ /obj/machinery/atmospherics/pipe/simple/hidden/scrubbers{ dir = 4 }, -/obj/effect/mapping_helpers/airlock/unres{ - icon_state = "airlock_unres_helper"; - dir = 8 - }, /turf/simulated/floor/plasteel, /area/quartermaster/office) "bVl" = ( @@ -54270,10 +54037,6 @@ icon_state = "4-8"; pixel_x = 0 }, -/obj/effect/mapping_helpers/airlock/unres{ - icon_state = "airlock_unres_helper"; - dir = 8 - }, /turf/simulated/floor/plasteel, /area/quartermaster/storage) "bVm" = ( @@ -54542,10 +54305,6 @@ name = "Delivery Office"; req_access_txt = "50" }, -/obj/effect/mapping_helpers/airlock/unres{ - icon_state = "airlock_unres_helper"; - dir = 1 - }, /turf/simulated/floor/plasteel, /area/quartermaster/office) "bVI" = ( @@ -55259,10 +55018,6 @@ /obj/machinery/atmospherics/pipe/simple/hidden/scrubbers{ dir = 4 }, -/obj/effect/mapping_helpers/airlock/unres{ - icon_state = "airlock_unres_helper"; - dir = 8 - }, /turf/simulated/floor/plasteel, /area/quartermaster/storage) "bWP" = ( @@ -55483,7 +55238,6 @@ }, /obj/machinery/atmospherics/pipe/simple/hidden/supply, /obj/machinery/atmospherics/pipe/simple/hidden/scrubbers, -/obj/effect/mapping_helpers/airlock/unres, /turf/simulated/floor/plating, /area/maintenance/asmaint2) "bXj" = ( @@ -56533,9 +56287,6 @@ /area/server) "bYV" = ( /obj/structure/table, -/obj/machinery/photocopier/faxmachine{ - department = "Head of Personnel's Office" - }, /obj/machinery/firealarm{ dir = 1; pixel_y = -24 @@ -56548,6 +56299,9 @@ pixel_y = 16; req_access_txt = "57" }, +/obj/machinery/photocopier/faxmachine/longrange{ + department = "Head of Personnel's Office" + }, /turf/simulated/floor/plasteel, /area/crew_quarters/heads) "bYW" = ( @@ -57302,7 +57056,7 @@ name = "Biohazard Shutter Control"; pixel_x = -4; pixel_y = 6; - req_access_txt = "47" + req_access_txt = "30" }, /obj/item/folder/white{ pixel_x = 4 @@ -57318,7 +57072,7 @@ normaldoorcontrol = 1; pixel_x = -4; pixel_y = -4; - req_access_txt = "20" + req_access_txt = "30" }, /turf/simulated/floor/plasteel{ dir = 2; @@ -58284,10 +58038,6 @@ d2 = 2; icon_state = "1-2" }, -/obj/effect/mapping_helpers/airlock/unres{ - icon_state = "airlock_unres_helper"; - dir = 1 - }, /turf/simulated/floor/plasteel{ tag = "icon-whitebluefull"; icon_state = "whitebluefull" @@ -58365,10 +58115,6 @@ name = "Medical Supplies"; req_access_txt = "5" }, -/obj/effect/mapping_helpers/airlock/unres{ - icon_state = "airlock_unres_helper"; - dir = 1 - }, /turf/simulated/floor/plasteel{ tag = "icon-whitebluefull"; icon_state = "whitebluefull" @@ -58386,10 +58132,6 @@ /obj/machinery/atmospherics/pipe/simple/hidden/scrubbers{ dir = 4 }, -/obj/effect/mapping_helpers/airlock/unres{ - icon_state = "airlock_unres_helper"; - dir = 8 - }, /turf/simulated/floor/plasteel, /area/quartermaster/office) "cbA" = ( @@ -63283,10 +63025,6 @@ /obj/machinery/door/airlock/maintenance{ req_access_txt = "12" }, -/obj/effect/mapping_helpers/airlock/unres{ - icon_state = "airlock_unres_helper"; - dir = 8 - }, /turf/simulated/floor/plating, /area/maintenance/asmaint2) "cjB" = ( @@ -63338,7 +63076,6 @@ tag = "" }, /obj/machinery/atmospherics/pipe/simple/hidden/supply, -/obj/effect/mapping_helpers/airlock/unres, /turf/simulated/floor/plating, /area/maintenance/apmaint) "cjE" = ( @@ -63725,6 +63462,7 @@ name = "mining shuttle bay"; width = 7 }, +/obj/structure/fans/tiny, /turf/simulated/shuttle/floor, /area/shuttle/mining) "ckl" = ( @@ -63733,6 +63471,7 @@ name = "Mining Dock Airlock"; req_access_txt = "48" }, +/obj/structure/fans/tiny, /turf/simulated/floor/plating, /area/quartermaster/miningdock) "ckm" = ( @@ -63741,6 +63480,7 @@ name = "Mining Dock Airlock"; req_access_txt = "48" }, +/obj/structure/fans/tiny, /turf/simulated/floor/plasteel, /area/quartermaster/miningdock) "ckn" = ( @@ -64003,7 +63743,6 @@ }, /obj/machinery/atmospherics/pipe/simple/hidden/supply, /obj/machinery/atmospherics/pipe/simple/hidden/scrubbers, -/obj/effect/mapping_helpers/airlock/unres, /turf/simulated/floor/wood, /area/blueshield) "ckJ" = ( @@ -64047,7 +63786,6 @@ }, /obj/machinery/atmospherics/pipe/simple/hidden/supply, /obj/machinery/atmospherics/pipe/simple/hidden/scrubbers, -/obj/effect/mapping_helpers/airlock/unres, /turf/simulated/floor/wood, /area/ntrep) "ckO" = ( @@ -64063,7 +63801,6 @@ req_access_txt = "26" }, /obj/structure/disposalpipe/segment, -/obj/effect/mapping_helpers/airlock/unres, /turf/simulated/floor/plasteel, /area/janitor) "ckQ" = ( @@ -64097,7 +63834,6 @@ }, /obj/machinery/atmospherics/pipe/simple/hidden/scrubbers, /obj/machinery/atmospherics/pipe/simple/hidden/supply, -/obj/effect/mapping_helpers/airlock/unres, /turf/simulated/floor/plating, /area/maintenance/asmaint) "ckU" = ( @@ -64185,7 +63921,6 @@ }, /obj/machinery/atmospherics/pipe/simple/hidden/scrubbers, /obj/machinery/atmospherics/pipe/simple/hidden/supply, -/obj/effect/mapping_helpers/airlock/unres, /turf/simulated/floor/plating, /area/maintenance/asmaint2) "clb" = ( @@ -64961,10 +64696,6 @@ /obj/machinery/door/airlock/maintenance{ req_access_txt = "12" }, -/obj/effect/mapping_helpers/airlock/unres{ - icon_state = "airlock_unres_helper"; - dir = 1 - }, /turf/simulated/floor/plating, /area/maintenance/asmaint) "cmu" = ( @@ -65384,7 +65115,7 @@ /turf/simulated/wall, /area/toxins/test_area) "cnl" = ( -/obj/structure/closet/wardrobe/miner/lavaland, +/obj/structure/closet/wardrobe/miner, /turf/simulated/floor/plasteel{ dir = 2; icon_state = "brown" @@ -66667,10 +66398,6 @@ /obj/machinery/door/airlock/maintenance{ req_access_txt = "12" }, -/obj/effect/mapping_helpers/airlock/unres{ - icon_state = "airlock_unres_helper"; - dir = 4 - }, /turf/simulated/floor/plating, /area/maintenance/asmaint) "cpl" = ( @@ -67408,10 +67135,6 @@ /obj/machinery/holosign/surgery{ id = "surgery1" }, -/obj/effect/mapping_helpers/airlock/unres{ - icon_state = "airlock_unres_helper"; - dir = 8 - }, /turf/simulated/floor/plasteel{ icon_state = "dark" }, @@ -67595,10 +67318,6 @@ /obj/machinery/holosign/surgery{ id = "surgery2" }, -/obj/effect/mapping_helpers/airlock/unres{ - icon_state = "airlock_unres_helper"; - dir = 4 - }, /turf/simulated/floor/plasteel{ icon_state = "dark" }, @@ -67680,7 +67399,6 @@ /obj/machinery/door/airlock/maintenance{ req_access_txt = "12" }, -/obj/effect/mapping_helpers/airlock/unres, /turf/simulated/floor/plating, /area/maintenance/apmaint) "cqG" = ( @@ -69558,13 +69276,6 @@ /area/medical/research{ name = "Research Division" }) -"ctD" = ( -/obj/machinery/door/airlock/maintenance{ - req_access_txt = "12" - }, -/obj/effect/mapping_helpers/airlock/unres, -/turf/simulated/floor/plating, -/area/maintenance/asmaint) "ctE" = ( /obj/machinery/hologram/holopad, /turf/simulated/floor/plasteel{ @@ -69648,16 +69359,6 @@ /obj/effect/decal/warning_stripes/yellow, /turf/simulated/floor/plasteel, /area/engine/controlroom) -"ctK" = ( -/obj/machinery/door/airlock/maintenance{ - req_access_txt = "12" - }, -/obj/effect/mapping_helpers/airlock/unres{ - icon_state = "airlock_unres_helper"; - dir = 1 - }, -/turf/simulated/floor/plating, -/area/maintenance/apmaint) "ctL" = ( /obj/machinery/light{ dir = 4; @@ -71182,7 +70883,6 @@ /obj/item/clothing/shoes/magboots, /obj/item/clothing/suit/space/hardsuit/medical, /obj/item/clothing/mask/gas, -/obj/item/clothing/head/helmet/space/hardsuit/medical, /obj/machinery/door/window/westright{ name = "Emergency Hardsuits"; req_access_txt = "40" @@ -71264,7 +70964,6 @@ /obj/item/clothing/shoes/magboots, /obj/item/clothing/suit/space/hardsuit/medical, /obj/item/clothing/mask/gas, -/obj/item/clothing/head/helmet/space/hardsuit/medical, /obj/machinery/door/window/westleft{ name = "Emergency Hardsuits"; req_access_txt = "40" @@ -71699,10 +71398,6 @@ req_access_txt = "5"; req_one_access_txt = "0" }, -/obj/effect/mapping_helpers/airlock/unres{ - icon_state = "airlock_unres_helper"; - dir = 4 - }, /turf/simulated/floor/plasteel{ dir = 2; icon_state = "cafeteria"; @@ -72356,16 +72051,6 @@ }, /turf/simulated/floor/plasteel, /area/storage/tech) -"cyu" = ( -/obj/machinery/door/airlock/maintenance{ - req_access_txt = "12" - }, -/obj/effect/mapping_helpers/airlock/unres{ - icon_state = "airlock_unres_helper"; - dir = 4 - }, -/turf/simulated/floor/plating, -/area/maintenance/asmaint) "cyv" = ( /obj/structure/sign/securearea{ desc = "A warning sign which reads 'HIGH VOLTAGE'"; @@ -72502,10 +72187,6 @@ name = "Medbay Maintenance"; req_access_txt = "5" }, -/obj/effect/mapping_helpers/airlock/unres{ - icon_state = "airlock_unres_helper"; - dir = 1 - }, /turf/simulated/floor/plating, /area/maintenance/genetics) "cyF" = ( @@ -72643,10 +72324,6 @@ /obj/structure/disposalpipe/segment, /obj/machinery/atmospherics/pipe/simple/hidden/supply, /obj/machinery/atmospherics/pipe/simple/hidden/scrubbers, -/obj/effect/mapping_helpers/airlock/unres{ - icon_state = "airlock_unres_helper"; - dir = 1 - }, /turf/simulated/floor/plasteel{ icon_state = "white" }, @@ -72953,10 +72630,6 @@ /obj/machinery/atmospherics/pipe/simple/hidden/scrubbers{ dir = 4 }, -/obj/effect/mapping_helpers/airlock/unres{ - icon_state = "airlock_unres_helper"; - dir = 8 - }, /turf/simulated/floor/plating, /area/maintenance/asmaint) "czy" = ( @@ -73657,10 +73330,6 @@ /obj/machinery/atmospherics/pipe/simple/hidden/supply{ dir = 4 }, -/obj/effect/mapping_helpers/airlock/unres{ - icon_state = "airlock_unres_helper"; - dir = 8 - }, /turf/simulated/floor/plating, /area/maintenance/asmaint2) "cAH" = ( @@ -74103,10 +73772,6 @@ /obj/machinery/door/airlock/maintenance{ req_access_txt = "12" }, -/obj/effect/mapping_helpers/airlock/unres{ - icon_state = "airlock_unres_helper"; - dir = 4 - }, /turf/simulated/floor/plating, /area/maintenance/asmaint2) "cBy" = ( @@ -74704,16 +74369,6 @@ }, /turf/simulated/floor/plating, /area/maintenance/apmaint) -"cCF" = ( -/obj/machinery/door/airlock/maintenance{ - req_access_txt = "12" - }, -/obj/effect/mapping_helpers/airlock/unres{ - icon_state = "airlock_unres_helper"; - dir = 4 - }, -/turf/simulated/floor/plating, -/area/maintenance/apmaint) "cCG" = ( /obj/structure/cable{ d1 = 2; @@ -74752,10 +74407,6 @@ /obj/machinery/atmospherics/pipe/simple/hidden/scrubbers{ dir = 4 }, -/obj/effect/mapping_helpers/airlock/unres{ - icon_state = "airlock_unres_helper"; - dir = 8 - }, /turf/simulated/floor/plating, /area/storage/tech) "cCJ" = ( @@ -75088,6 +74739,10 @@ /obj/machinery/light_switch{ pixel_y = 27 }, +/obj/machinery/alarm{ + frequency = 1439; + pixel_y = 23 + }, /turf/simulated/floor/plasteel{ dir = 1; icon_state = "yellowcorner" @@ -75213,7 +74868,6 @@ /obj/structure/disposalpipe/segment, /obj/machinery/atmospherics/pipe/simple/hidden/scrubbers, /obj/machinery/atmospherics/pipe/simple/hidden/supply, -/obj/effect/mapping_helpers/airlock/unres, /turf/simulated/floor/plasteel{ icon_state = "white" }, @@ -76075,10 +75729,6 @@ name = "Alternate Construction Area"; req_access_txt = "12" }, -/obj/effect/mapping_helpers/airlock/unres{ - icon_state = "airlock_unres_helper"; - dir = 8 - }, /turf/simulated/floor/plating, /area/maintenance/apmaint) "cFf" = ( @@ -76612,10 +76262,6 @@ name = "Alternate Construction Area"; req_access_txt = "12" }, -/obj/effect/mapping_helpers/airlock/unres{ - icon_state = "airlock_unres_helper"; - dir = 8 - }, /turf/simulated/floor/plating, /area/maintenance/consarea) "cFU" = ( @@ -77113,7 +76759,6 @@ /obj/machinery/atmospherics/pipe/simple/hidden/scrubbers, /obj/structure/disposalpipe/segment, /obj/machinery/atmospherics/pipe/simple/hidden/supply, -/obj/effect/mapping_helpers/airlock/unres, /turf/simulated/floor/wood, /area/medical/psych) "cGM" = ( @@ -77620,10 +77265,6 @@ /obj/machinery/door/airlock/maintenance{ req_access_txt = "12" }, -/obj/effect/mapping_helpers/airlock/unres{ - icon_state = "airlock_unres_helper"; - dir = 1 - }, /turf/simulated/floor/plating, /area/maintenance/apmaint) "cHF" = ( @@ -77776,10 +77417,6 @@ }, /obj/machinery/atmospherics/pipe/simple/hidden/scrubbers, /obj/machinery/atmospherics/pipe/simple/hidden/supply, -/obj/effect/mapping_helpers/airlock/unres{ - icon_state = "airlock_unres_helper"; - dir = 1 - }, /turf/simulated/floor/plating, /area/maintenance/apmaint) "cHS" = ( @@ -79005,10 +78642,6 @@ /obj/machinery/atmospherics/pipe/simple/hidden/scrubbers{ dir = 4 }, -/obj/effect/mapping_helpers/airlock/unres{ - icon_state = "airlock_unres_helper"; - dir = 8 - }, /turf/simulated/floor/plasteel{ icon_state = "dark" }, @@ -80228,10 +79861,6 @@ /obj/machinery/door/airlock/maintenance{ req_access_txt = "12" }, -/obj/effect/mapping_helpers/airlock/unres{ - icon_state = "airlock_unres_helper"; - dir = 1 - }, /turf/simulated/floor/plating, /area/maintenance/aft) "cMr" = ( @@ -80359,7 +79988,7 @@ "cMF" = ( /obj/machinery/door/airlock/engineering{ name = "Engineering Checkpoint"; - req_access_txt = "11" + req_one_access_txt = "11;24" }, /obj/machinery/atmospherics/pipe/simple/hidden/scrubbers{ dir = 4 @@ -81301,7 +80930,6 @@ }, /obj/machinery/atmospherics/pipe/simple/hidden/supply, /obj/machinery/atmospherics/pipe/simple/hidden/scrubbers, -/obj/effect/mapping_helpers/airlock/unres, /turf/simulated/floor/plating, /area/maintenance/aft) "cOt" = ( @@ -82087,12 +81715,6 @@ }, /turf/simulated/floor/plasteel, /area/atmos) -"cPR" = ( -/obj/machinery/atmospherics/pipe/simple/hidden/scrubbers{ - dir = 4 - }, -/turf/simulated/floor/plasteel, -/area/atmos) "cPS" = ( /obj/machinery/atmospherics/pipe/manifold/hidden/supply{ dir = 4; @@ -82204,14 +81826,6 @@ /obj/effect/decal/warning_stripes/northeast, /turf/simulated/floor/plasteel, /area/engine/engineering) -"cQd" = ( -/obj/machinery/alarm{ - frequency = 1439; - pixel_y = 23 - }, -/obj/machinery/pipedispenser, -/turf/simulated/floor/plasteel, -/area/atmos) "cQe" = ( /obj/machinery/atmospherics/pipe/simple/visible/green{ dir = 4; @@ -82621,10 +82235,6 @@ }, /turf/simulated/floor/plasteel, /area/engine/equipmentstorage) -"cQQ" = ( -/obj/machinery/pipedispenser/disposal, -/turf/simulated/floor/plasteel, -/area/atmos) "cQR" = ( /obj/machinery/firealarm{ dir = 1; @@ -83448,10 +83058,6 @@ "cSd" = ( /turf/simulated/floor/plasteel, /area/atmos) -"cSe" = ( -/obj/structure/closet/wardrobe/atmospherics_yellow, -/turf/simulated/floor/plasteel, -/area/atmos) "cSf" = ( /obj/machinery/atmospherics/pipe/simple/hidden/scrubbers{ dir = 5 @@ -84375,10 +83981,6 @@ /obj/machinery/atmospherics/pipe/simple/hidden/scrubbers{ dir = 4 }, -/obj/effect/mapping_helpers/airlock/unres{ - icon_state = "airlock_unres_helper"; - dir = 4 - }, /turf/simulated/floor/plasteel, /area/engine/break_room) "cTH" = ( @@ -86811,7 +86413,6 @@ /obj/machinery/light{ dir = 8 }, -/obj/machinery/suit_storage_unit/atmos, /turf/simulated/floor/plasteel, /area/atmos) "cXP" = ( @@ -88570,7 +88171,6 @@ /obj/machinery/door/airlock/maintenance{ req_access_txt = "12" }, -/obj/effect/mapping_helpers/airlock/unres, /turf/simulated/floor/plating, /area/maintenance/aft) "dbi" = ( @@ -88636,7 +88236,6 @@ tag = "" }, /obj/structure/disposalpipe/segment, -/obj/effect/mapping_helpers/airlock/unres, /turf/simulated/floor/plating, /area/maintenance/aft) "dbq" = ( @@ -89107,10 +88706,6 @@ /area/maintenance/asmaint) "dci" = ( /obj/machinery/door/airlock/maintenance, -/obj/effect/mapping_helpers/airlock/unres{ - icon_state = "airlock_unres_helper"; - dir = 4 - }, /turf/simulated/floor/plating, /area/maintenance/genetics) "dcj" = ( @@ -89447,6 +89042,7 @@ req_access_txt = "0"; req_one_access_txt = "10;24" }, +/obj/structure/fans/tiny, /turf/simulated/floor/plating, /area/maintenance/engi_shuttle) "dcV" = ( @@ -89963,7 +89559,6 @@ /obj/structure/disposalpipe/segment, /obj/machinery/atmospherics/pipe/simple/hidden/supply, /obj/machinery/atmospherics/pipe/simple/hidden/scrubbers, -/obj/effect/mapping_helpers/airlock/unres, /turf/simulated/floor/plating, /area/maintenance/engi_shuttle) "ddX" = ( @@ -89979,13 +89574,6 @@ /obj/structure/lattice/catwalk, /turf/space, /area/space/nearstation) -"ddY" = ( -/obj/machinery/door/airlock/maintenance{ - req_access_txt = "12" - }, -/obj/effect/mapping_helpers/airlock/unres, -/turf/simulated/floor/plating, -/area/maintenance/asmaint2) "ddZ" = ( /obj/structure/reagent_dispensers/watertank, /obj/structure/cable{ @@ -90159,10 +89747,6 @@ d2 = 8; icon_state = "4-8" }, -/obj/effect/mapping_helpers/airlock/unres{ - icon_state = "airlock_unres_helper"; - dir = 8 - }, /turf/simulated/floor/plating, /area/maintenance/asmaint) "dep" = ( @@ -90173,7 +89757,6 @@ icon_state = "1-2"; tag = "" }, -/obj/effect/mapping_helpers/airlock/unres, /turf/simulated/floor/plating, /area/maintenance/genetics) "deq" = ( @@ -90575,10 +90158,6 @@ icon_state = "4-8"; pixel_x = 0 }, -/obj/effect/mapping_helpers/airlock/unres{ - icon_state = "airlock_unres_helper"; - dir = 8 - }, /turf/simulated/floor/plating, /area/maintenance/asmaint2) "dfg" = ( @@ -91015,16 +90594,6 @@ "dfV" = ( /turf/simulated/floor/plating, /area/storage/secure) -"dfW" = ( -/obj/machinery/door/airlock/maintenance{ - req_access_txt = "12" - }, -/obj/effect/mapping_helpers/airlock/unres{ - icon_state = "airlock_unres_helper"; - dir = 1 - }, -/turf/simulated/floor/plating, -/area/maintenance/asmaint2) "dfX" = ( /turf/space, /turf/simulated/shuttle/wall{ @@ -91063,6 +90632,7 @@ name = "engineering dock"; width = 7 }, +/obj/structure/fans/tiny, /turf/simulated/floor/plating, /area/shuttle/constructionsite) "dga" = ( @@ -91095,15 +90665,10 @@ req_access_txt = "12" }, /obj/machinery/atmospherics/pipe/simple/hidden/scrubbers, -/obj/effect/mapping_helpers/airlock/unres, /turf/simulated/floor/plating, /area/maintenance/asmaint) "dgf" = ( /obj/machinery/door/airlock/maintenance, -/obj/effect/mapping_helpers/airlock/unres{ - icon_state = "airlock_unres_helper"; - dir = 8 - }, /turf/simulated/floor/plating, /area/maintenance/asmaint2) "dgg" = ( @@ -93695,20 +93260,15 @@ name = "\improper AI Satellite Service" }) "dle" = ( -/obj/machinery/the_singularitygen{ - anchored = 1 - }, /obj/effect/decal/warning_stripes/west, -/turf/simulated/floor/plating/airless, -/area/space/nearstation) -"dlf" = ( /obj/item/wrench, /turf/simulated/floor/plating/airless, /area/space/nearstation) +"dlf" = ( +/obj/item/radio/beacon/engine/tesling, +/turf/simulated/floor/plating/airless, +/area/space/nearstation) "dlg" = ( -/obj/machinery/the_singularitygen/tesla{ - anchored = 1 - }, /obj/effect/decal/warning_stripes/east, /turf/simulated/floor/plating/airless, /area/space/nearstation) @@ -96733,19 +96293,7 @@ /obj/machinery/atmospherics/pipe/simple/visible/universal{ dir = 4 }, -/obj/structure/table, -/obj/item/clothing/glasses/welding, -/obj/item/clothing/glasses/welding, -/obj/item/clothing/gloves/color/black, -/obj/item/clothing/gloves/color/black, -/obj/item/clothing/gloves/color/black, -/obj/machinery/alarm{ - dir = 4; - icon_state = "alarm0"; - pixel_x = -22 - }, -/obj/item/pipe_painter, -/obj/item/pipe_painter, +/obj/structure/closet/wardrobe/atmospherics_yellow, /turf/simulated/floor/plasteel, /area/atmos) "dtk" = ( @@ -96970,6 +96518,14 @@ /obj/structure/lattice, /turf/space, /area/space/nearstation) +"lLC" = ( +/obj/machinery/alarm{ + dir = 4; + icon_state = "alarm0"; + pixel_x = -22 + }, +/turf/simulated/floor/plasteel, +/area/atmos) "mMw" = ( /obj/structure/chair/comfy/shuttle{ dir = 8 @@ -97097,6 +96653,17 @@ icon_state = "floor2" }, /area/shuttle/constructionsite) +"wOS" = ( +/obj/structure/table, +/obj/item/clothing/gloves/color/black, +/obj/item/clothing/gloves/color/black, +/obj/item/clothing/gloves/color/black, +/obj/item/pipe_painter, +/obj/item/pipe_painter, +/obj/item/clothing/glasses/welding, +/obj/item/clothing/glasses/welding, +/turf/simulated/floor/plasteel, +/area/atmos) "wVD" = ( /obj/effect/landmark/start{ name = "Shaft Miner" @@ -114520,7 +114087,7 @@ aaa cng coL coL -ctK +cqF coL cvk cwx @@ -115241,7 +114808,7 @@ aGn aGn aGn aGn -bbx +aLk aGn aGn aUy @@ -115291,7 +114858,7 @@ aaa cng coL coL -ctK +cqF coL coL cwx @@ -117095,7 +116662,7 @@ ctU cgQ cgQ cgQ -cCF +cqF cgQ cgQ cgQ @@ -118377,7 +117944,7 @@ cam aab cgQ ctU -ctK +cqF coL coL coL @@ -121982,7 +121549,7 @@ czN cyg cCH coL -ctK +cqF cEQ cGj cJZ @@ -126808,7 +126375,7 @@ avq avq avq avq -axN +aHp aRx aUw aDN @@ -128911,7 +128478,7 @@ cPd cos cPd cqY -ctD +cmt csL csL cvI @@ -129452,7 +129019,7 @@ cSd cOF cTk dfF -dtn +wOS dcq dcq dcq @@ -129709,8 +129276,8 @@ cSd cSd cWT cXQ -dtn -dtn +cSd +lLC cXO dbK dct @@ -130218,7 +129785,7 @@ cGK cDi cSd cSd -cPR +cPT cQS cEr cTq @@ -130472,10 +130039,10 @@ cJc cJN csK cZS -cQd -cQQ -cSe -cPT +dtn +dtn +dtn +dtn cFG cVJ cWO @@ -130712,7 +130279,7 @@ csL cqD csL chf -cyu +cmt chf chf chf @@ -132960,7 +132527,7 @@ aIq avq aAc aBt -aGv +aHp aCh aEw aFI @@ -133725,7 +133292,7 @@ ajb awl arR awl -avU +aHp aqc aya awl @@ -135271,7 +134838,7 @@ avb aAQ awF aye -axN +aHp avq aAS atG @@ -137342,7 +136909,7 @@ aFJ aPq aRv aTb -aXT +aMn aGY aGY aGY @@ -139906,7 +139473,7 @@ aGX aHc aIv aGX -aOa +aMn aGX aGX aGX @@ -140419,10 +139986,10 @@ aCy aMf aNf aGY -aNe +aMn aGY aGY -aNe +aMn aGY aGY aPK @@ -140935,7 +140502,7 @@ aJI aGY aGX aGX -aKp +aMn aGX aGX aGY @@ -142472,14 +142039,14 @@ aab aAf aAf aAf -aKp +aMn aAf aHb aMz aMz aIE aGX -aKp +aMn aMz aGX aOG @@ -143522,7 +143089,7 @@ bcu ber bga bis -bMz +bvN bcD bld blw @@ -147196,7 +146763,7 @@ bGH bGG dgy bGG -dfW +cjA dia cuQ djQ @@ -148472,7 +148039,7 @@ aab bGH bGG bGG -ddY +cjA bGG dcJ ddJ @@ -148737,7 +148304,7 @@ cuQ dfc bGG bGG -ddY +cjA bGG bGG bGH diff --git a/_maps/map_files/cyberiad/z2.dmm b/_maps/map_files/cyberiad/z2.dmm index d3417ba50f3..7c7b0403547 100644 --- a/_maps/map_files/cyberiad/z2.dmm +++ b/_maps/map_files/cyberiad/z2.dmm @@ -3248,8 +3248,6 @@ /area/shuttle/assault_pod) "iw" = ( /obj/structure/rack, -/obj/item/clothing/suit/space/eva/plasmaman/wizard, -/obj/item/clothing/head/helmet/space/eva/plasmaman/wizard, /obj/item/clothing/mask/breath, /obj/item/clothing/mask/breath/vox, /obj/item/tank/plasma/plasmaman, @@ -8555,11 +8553,6 @@ /area/admin) "uJ" = ( /obj/structure/rack, -/obj/item/clothing/head/helmet/space/hardsuit/wizard{ - pixel_x = -3; - pixel_y = 3 - }, -/obj/item/clothing/head/helmet/space/hardsuit/syndi, /obj/item/clothing/head/helmet/space/santahat{ pixel_x = 3; pixel_y = -3 @@ -8749,7 +8742,7 @@ pixel_x = -3; pixel_y = 3 }, -/obj/item/clothing/glasses/hud/health/health_advanced, +/obj/item/clothing/glasses/hud/health/sunglasses, /obj/item/clothing/glasses/hud/security/sunglasses, /turf/unsimulated/floor{ tag = "icon-floor"; @@ -11644,8 +11637,8 @@ /area/admin) "AL" = ( /obj/structure/rack, -/obj/item/storage/box/syndie_kit/hardsuit, -/obj/item/storage/box/syndie_kit/elite_hardsuit{ +/obj/item/clothing/suit/space/hardsuit/syndi, +/obj/item/clothing/suit/space/hardsuit/syndi/elite{ pixel_x = -6; pixel_y = 6 }, diff --git a/_maps/map_files/cyberiad/z4.dmm b/_maps/map_files/cyberiad/z4.dmm index 08d56927445..bd20066c0a4 100644 --- a/_maps/map_files/cyberiad/z4.dmm +++ b/_maps/map_files/cyberiad/z4.dmm @@ -2571,6 +2571,7 @@ req_access_txt = "0"; req_one_access_txt = "10;24" }, +/obj/structure/fans/tiny, /turf/simulated/floor/plating, /area/engiestation) "gs" = ( diff --git a/_maps/test_all_maps.dm b/_maps/test_all_maps.dm index 064bf8defaf..55cb0ff946b 100644 --- a/_maps/test_all_maps.dm +++ b/_maps/test_all_maps.dm @@ -19,6 +19,8 @@ // Lavaland Ruins #include "map_files\RandomRuins\LavaRuins\lavaland_biodome_beach.dmm" + #include "map_files\RandomRuins\LavaRuins\lavaland_biodome_clown_planet.dmm" + #include "map_files\RandomRuins\LavaRuins\lavaland_biodome_winter.dmm" #include "map_files\RandomRuins\LavaRuins\lavaland_surface_animal_hospital.dmm" #include "map_files\RandomRuins\LavaRuins\lavaland_surface_ash_walker1.dmm" #include "map_files\RandomRuins\LavaRuins\lavaland_surface_blooddrunk1.dmm" @@ -44,7 +46,7 @@ #include "map_files\RandomRuins\LavaRuins\lavaland_surface_syndicate_base1.dmm" #include "map_files\RandomRuins\LavaRuins\lavaland_surface_ufo_crash.dmm" #include "map_files\RandomRuins\LavaRuins\lavaland_surface_xeno_nest.dmm" - + // Space Ruins #include "map_files\RandomRuins\SpaceRuins\abandonedzoo.dmm" diff --git a/code/__DEFINES/atmospherics.dm b/code/__DEFINES/atmospherics.dm index 67eea12291a..2f296960622 100644 --- a/code/__DEFINES/atmospherics.dm +++ b/code/__DEFINES/atmospherics.dm @@ -123,8 +123,12 @@ #define TANK_RUPTURE_PRESSURE (40.*ONE_ATMOSPHERE) //Tank spills all contents into atmosphere #define TANK_FRAGMENT_PRESSURE (50.*ONE_ATMOSPHERE) //Boom 3x3 base explosion #define TANK_FRAGMENT_SCALE (10.*ONE_ATMOSPHERE) //+1 for each SCALE kPa aboe threshold +#define TANK_DEFAULT_RELEASE_PRESSURE 16 // Atmos alarm defines #define ATMOS_ALARM_NONE 0 #define ATMOS_ALARM_WARNING 1 #define ATMOS_ALARM_DANGER 2 + +//LAVALAND +#define LAVALAND_EQUIPMENT_EFFECT_PRESSURE 50 //what pressure you have to be under to increase the effect of equipment meant for lavaland \ No newline at end of file diff --git a/code/__DEFINES/combat.dm b/code/__DEFINES/combat.dm index fbc28695ebf..d8e051e600e 100644 --- a/code/__DEFINES/combat.dm +++ b/code/__DEFINES/combat.dm @@ -106,9 +106,10 @@ #define SAWN_INTACT 0 #define SAWN_OFF 1 -#define WEAPON_LIGHT 0 -#define WEAPON_MEDIUM 1 -#define WEAPON_HEAVY 2 +#define WEAPON_DUAL_WIELD 0 +#define WEAPON_LIGHT 1 +#define WEAPON_MEDIUM 2 +#define WEAPON_HEAVY 3 #define EXPLODE_NONE 0 //Don't even ask me why we need this. #define EXPLODE_DEVASTATE 1 diff --git a/code/__DEFINES/crafting.dm b/code/__DEFINES/crafting.dm index 4b783490568..6acaea463f9 100644 --- a/code/__DEFINES/crafting.dm +++ b/code/__DEFINES/crafting.dm @@ -5,6 +5,7 @@ #define CAT_FOOD "Food" #define CAT_MISC "Misc" #define CAT_PRIMAL "Tribal" +#define CAT_CLOTHING "Clothing" #define RECIPE_MICROWAVE "Microwave" #define RECIPE_OVEN "Oven" diff --git a/code/__DEFINES/genetics.dm b/code/__DEFINES/genetics.dm index 0fb9253a083..7213ecc3118 100644 --- a/code/__DEFINES/genetics.dm +++ b/code/__DEFINES/genetics.dm @@ -105,6 +105,9 @@ #define NUTRITION_LEVEL_STARVING 150 #define NUTRITION_LEVEL_CURSED 0 +//Used as an upper limit for species that continuously gain nutriment +#define NUTRITION_LEVEL_ALMOST_FULL 535 + //Blood levels #define BLOOD_VOLUME_MAXIMUM 2000 #define BLOOD_VOLUME_NORMAL 560 diff --git a/code/__DEFINES/misc.dm b/code/__DEFINES/misc.dm index 049f2541bc1..4eb11963eff 100644 --- a/code/__DEFINES/misc.dm +++ b/code/__DEFINES/misc.dm @@ -353,6 +353,8 @@ #define TRIGGER_GUARD_NONE 0 #define TRIGGER_GUARD_NORMAL 1 +#define CLIENT_FROM_VAR(I) (ismob(I) ? I:client : (istype(I, /client) ? I : (istype(I, /datum/mind) ? I:current?:client : null))) + // Macro to get the current elapsed round time, rather than total world runtime #define ROUND_TIME (SSticker.round_start_time ? (world.time - SSticker.round_start_time) : 0) @@ -388,6 +390,8 @@ #define BLOODY_FOOTPRINT_BASE_ALPHA 150 #define BLOOD_GAIN_PER_STEP 100 #define BLOOD_LOSS_PER_STEP 5 +#define BLOOD_LOSS_IN_SPREAD 20 +#define BLOOD_AMOUNT_PER_DECAL 20 //Bloody shoe blood states #define BLOOD_STATE_HUMAN "blood" @@ -403,7 +407,7 @@ #define INVESTIGATE_BOMB "bombs" // The SQL version required by this version of the code -#define SQL_VERSION 8 +#define SQL_VERSION 9 // Vending machine stuff #define CAT_NORMAL 1 @@ -483,6 +487,21 @@ // Cult summon possibilities #define SUMMON_POSSIBILITIES 3 +// Dice rigged options. #define DICE_NOT_RIGGED 1 #define DICE_BASICALLY_RIGGED 2 -#define DICE_TOTALLY_RIGGED 3 \ No newline at end of file +#define DICE_TOTALLY_RIGGED 3 + +// Water temperature +#define COLD_WATER_TEMPERATURE 283.15 // 10 degrees celsius + +// Parallax +#define PARALLAX_DELAY_DEFAULT world.tick_lag +#define PARALLAX_DELAY_MED 1 +#define PARALLAX_DELAY_LOW 2 +#define PARALLAX_LOOP_TIME 25 + +// Engine types +#define ENGTYPE_SING "Singularity" +#define ENGTYPE_SM "Supermatter" +#define ENGTYPE_TESLA "Tesla" diff --git a/code/__DEFINES/mobs.dm b/code/__DEFINES/mobs.dm index 284b0e4d745..608fcfcce20 100644 --- a/code/__DEFINES/mobs.dm +++ b/code/__DEFINES/mobs.dm @@ -187,6 +187,7 @@ #define isswarmer(A) (istype((A), /mob/living/simple_animal/hostile/swarmer)) #define isguardian(A) (istype((A), /mob/living/simple_animal/hostile/guardian)) #define isnymph(A) (istype((A), /mob/living/simple_animal/diona)) +#define ishostile(A) (istype(A, /mob/living/simple_animal/hostile)) #define issilicon(A) (istype((A), /mob/living/silicon)) #define isAI(A) (istype((A), /mob/living/silicon/ai)) diff --git a/code/__DEFINES/preferences.dm b/code/__DEFINES/preferences.dm index 9582fddccfe..54fd59307f4 100644 --- a/code/__DEFINES/preferences.dm +++ b/code/__DEFINES/preferences.dm @@ -7,8 +7,9 @@ #define SOUND_BUZZ 64 #define SOUND_INSTRUMENTS 128 #define SOUND_MENTORHELP 256 +#define SOUND_DISCO 512 -#define SOUND_DEFAULT (SOUND_ADMINHELP|SOUND_MIDI|SOUND_AMBIENCE|SOUND_LOBBY|SOUND_HEARTBEAT|SOUND_BUZZ|SOUND_INSTRUMENTS|SOUND_MENTORHELP) +#define SOUND_DEFAULT (SOUND_ADMINHELP|SOUND_MIDI|SOUND_AMBIENCE|SOUND_LOBBY|SOUND_HEARTBEAT|SOUND_BUZZ|SOUND_INSTRUMENTS|SOUND_MENTORHELP|SOUND_DISCO) #define CHAT_OOC 1 #define CHAT_DEAD 2 @@ -34,7 +35,7 @@ #define AMBIENT_OCCLUSION 2097152 #define CHAT_GHOSTPDA 4194304 #define NUMPAD_TARGET 8388608 -#define TOGGLES_TOTAL 16777215 // If you add or remove a preference toggle above, make sure you update this define with the total value of the toggles combined. +#define TOGGLES_TOTAL 16777215 // If you add or remove a preference toggle above, make sure you update this define with the total value of the toggles combined. #define TOGGLES_DEFAULT (CHAT_OOC|CHAT_DEAD|CHAT_GHOSTEARS|CHAT_GHOSTSIGHT|CHAT_PRAYER|CHAT_RADIO|CHAT_LOOC|MEMBER_PUBLIC|DONATOR_PUBLIC|AMBIENT_OCCLUSION|CHAT_GHOSTPDA|NUMPAD_TARGET) @@ -63,3 +64,12 @@ #define EXP_TYPE_WHITELIST "Whitelist" #define EXP_DEPT_TYPE_LIST list(EXP_TYPE_SERVICE, EXP_TYPE_MEDICAL, EXP_TYPE_ENGINEERING, EXP_TYPE_SCIENCE, EXP_TYPE_SECURITY, EXP_TYPE_COMMAND, EXP_TYPE_SILICON, EXP_TYPE_SPECIAL) + +// Defines just for parallax because its levels make storing it in the regular prefs a pain in the ass +// These dont need to be bitflags because there isnt going to be more than one at a time of these active +// But its gonna piss off my OCD if it isnt bitflags, so deal with it, -affected +#define PARALLAX_DISABLE 1 +#define PARALLAX_LOW 2 +#define PARALLAX_MED 4 +#define PARALLAX_HIGH 8 +#define PARALLAX_INSANE 16 diff --git a/code/__DEFINES/sight.dm b/code/__DEFINES/sight.dm index 54162cd0f96..58f557c4b75 100644 --- a/code/__DEFINES/sight.dm +++ b/code/__DEFINES/sight.dm @@ -32,3 +32,10 @@ #define SECHUD 1 #define MEDHUD 2 #define ANTAGHUD 3 + +//for clothing visor toggles, these determine which vars to toggle +#define VISOR_FLASHPROTECT (1<<0) +#define VISOR_TINT (1<<1) +#define VISOR_VISIONFLAGS (1<<2) //all following flags only matter for glasses +#define VISOR_DARKNESSVIEW (1<<3) +#define VISOR_INVISVIEW (1<<4) \ No newline at end of file diff --git a/code/__DEFINES/stat.dm b/code/__DEFINES/stat.dm index b38018c0382..b0a74b6c702 100644 --- a/code/__DEFINES/stat.dm +++ b/code/__DEFINES/stat.dm @@ -34,13 +34,14 @@ #define WAIT_FINISH 3 //shuttle mode defines -#define SHUTTLE_IDLE 0 -#define SHUTTLE_RECALL 1 -#define SHUTTLE_CALL 2 -#define SHUTTLE_DOCKED 3 -#define SHUTTLE_STRANDED 4 -#define SHUTTLE_ESCAPE 5 -#define SHUTTLE_ENDGAME 6 +#define SHUTTLE_IGNITING 0 +#define SHUTTLE_IDLE 1 +#define SHUTTLE_RECALL 2 +#define SHUTTLE_CALL 3 +#define SHUTTLE_DOCKED 4 +#define SHUTTLE_STRANDED 5 +#define SHUTTLE_ESCAPE 6 +#define SHUTTLE_ENDGAME 7 // Shuttle return values #define SHUTTLE_CAN_DOCK "can_dock" diff --git a/code/__DEFINES/status_effects.dm b/code/__DEFINES/status_effects.dm index e5d5bb723c1..f451a34a8b7 100644 --- a/code/__DEFINES/status_effects.dm +++ b/code/__DEFINES/status_effects.dm @@ -26,7 +26,7 @@ //#define STATUS_EFFECT_WISH_GRANTERS_GIFT /datum/status_effect/wish_granters_gift //If you're currently resurrecting with the Wish Granter -//#define STATUS_EFFECT_BLOODDRUNK /datum/status_effect/blooddrunk //Stun immunity and greatly reduced damage taken +#define STATUS_EFFECT_BLOODDRUNK /datum/status_effect/blooddrunk //Stun immunity and greatly reduced damage taken ///////////// // DEBUFFS // @@ -52,7 +52,7 @@ #define STATUS_EFFECT_SUMMONEDGHOST /datum/status_effect/cultghost //is a cult ghost and can't use manifest runes -//#define STATUS_EFFECT_CRUSHERMARK /datum/status_effect/crusher_mark //if struck with a proto-kinetic crusher, takes a ton of damage +#define STATUS_EFFECT_CRUSHERMARK /datum/status_effect/crusher_mark //if struck with a proto-kinetic crusher, takes a ton of damage #define STATUS_EFFECT_SAWBLEED /datum/status_effect/saw_bleed //if the bleed builds up enough, takes a ton of damage @@ -74,6 +74,6 @@ //#define STATUS_EFFECT_SIGILMARK /datum/status_effect/sigil_mark -//#define STATUS_EFFECT_CRUSHERDAMAGETRACKING /datum/status_effect/crusher_damage //tracks total kinetic crusher damage on a target +#define STATUS_EFFECT_CRUSHERDAMAGETRACKING /datum/status_effect/crusher_damage //tracks total kinetic crusher damage on a target -//#define STATUS_EFFECT_SYPHONMARK /datum/status_effect/syphon_mark //tracks kills for the KA death syphon module \ No newline at end of file +#define STATUS_EFFECT_SYPHONMARK /datum/status_effect/syphon_mark //tracks kills for the KA death syphon module \ No newline at end of file diff --git a/code/__DEFINES/subsystems.dm b/code/__DEFINES/subsystems.dm index 29a93ae94f9..c55fec2cd87 100644 --- a/code/__DEFINES/subsystems.dm +++ b/code/__DEFINES/subsystems.dm @@ -79,7 +79,8 @@ #define INIT_ORDER_NANOMOB -23 #define INIT_ORDER_SQUEAK -40 #define INIT_ORDER_PATH -50 -#define INIT_ORDER_PERSISTENCE -100 +#define INIT_ORDER_PERSISTENCE -95 +#define INIT_ORDER_CHAT -100 //Should be last to ensure chat remains smooth during init. // Subsystem fire priority, from lowest to highest priority // If the subsystem isn't listed here it's either DEFAULT or PROCESS (if it's a processing subsystem child) @@ -111,6 +112,7 @@ #define FIRE_PRIORITY_MOBS 100 #define FIRE_PRIORITY_NANOUI 110 #define FIRE_PRIORITY_TICKER 200 +#define FIRE_PRIORITY_CHAT 400 #define FIRE_PRIORITY_OVERLAYS 500 #define FIRE_PRIORITY_INPUT 1000 // This must always always be the max highest priority. Player input must never be lost. diff --git a/code/__HELPERS/game.dm b/code/__HELPERS/game.dm index abd9aeb5a03..3bb6b742a04 100644 --- a/code/__HELPERS/game.dm +++ b/code/__HELPERS/game.dm @@ -435,6 +435,17 @@ /proc/GetBluePart(const/hexa) return hex2num(copytext(hexa, 6, 8)) +/proc/lavaland_equipment_pressure_check(turf/T) + . = FALSE + if(!istype(T)) + return + var/datum/gas_mixture/environment = T.return_air() + if(!istype(environment)) + return + var/pressure = environment.return_pressure() + if(pressure <= LAVALAND_EQUIPMENT_EFFECT_PRESSURE) + . = TRUE + /proc/GetHexColors(const/hexa) return list( GetRedPart(hexa), diff --git a/code/__HELPERS/icon_smoothing.dm b/code/__HELPERS/icon_smoothing.dm index 11c86940b75..acf202f0eee 100644 --- a/code/__HELPERS/icon_smoothing.dm +++ b/code/__HELPERS/icon_smoothing.dm @@ -153,29 +153,33 @@ /turf/simulated/wall/diagonal_smooth(adjacencies) adjacencies = reverse_ndir(..()) if(adjacencies) - var/list/U = list() + var/mutable_appearance/underlay_appearance = mutable_appearance(layer = TURF_LAYER, plane = FLOOR_PLANE) + var/list/U = list(underlay_appearance) if(fixed_underlay) if(fixed_underlay["space"]) - U += image('icons/turf/space.dmi', SPACE_ICON_STATE, layer=TURF_LAYER) + underlay_appearance.icon = 'icons/turf/space.dmi' + underlay_appearance.icon_state = SPACE_ICON_STATE + underlay_appearance.plane = PLANE_SPACE else - U += image(fixed_underlay["icon"], fixed_underlay["icon_state"], layer=TURF_LAYER) + underlay_appearance.icon = fixed_underlay["icon"] + underlay_appearance.icon_state = fixed_underlay["icon_state"] else - var/turf/T = get_step(src, turn(adjacencies, 180)) - if(T && (T.density || T.smooth)) + var/turned_adjacency = turn(adjacencies, 180) + var/turf/T = get_step(src, turned_adjacency) + if(!T.get_smooth_underlay_icon(underlay_appearance, src, turned_adjacency)) T = get_step(src, turn(adjacencies, 135)) - if(T && (T.density || T.smooth)) + if(!T.get_smooth_underlay_icon(underlay_appearance, src, turned_adjacency)) T = get_step(src, turn(adjacencies, 225)) - - if(istype(T, /turf/space) && !istype(T, /turf/space/transit)) - U += image('icons/turf/space.dmi', SPACE_ICON_STATE, layer=TURF_LAYER) - else if(T && !T.density && !T.smooth) - U += T - else if(baseturf && !initial(baseturf.density) && !initial(baseturf.smooth)) - U += image(initial(baseturf.icon), initial(baseturf.icon_state), layer=TURF_LAYER) - else - U += DEFAULT_UNDERLAY_IMAGE + //if all else fails, ask our own turf + if(!T.get_smooth_underlay_icon(underlay_appearance, src, turned_adjacency) && !get_smooth_underlay_icon(underlay_appearance, src, turned_adjacency)) + underlay_appearance.icon = DEFAULT_UNDERLAY_ICON + underlay_appearance.icon_state = DEFAULT_UNDERLAY_ICON_STATE underlays = U + // Drop posters which were previously placed on this wall. + for(var/obj/structure/sign/poster/P in src) + P.roll_and_drop(src) + /proc/cardinal_smooth(atom/A, adjacencies) //NW CORNER var/nw = "1-i" diff --git a/code/__HELPERS/icons.dm b/code/__HELPERS/icons.dm index ed4f3242c4d..0b37872decd 100644 --- a/code/__HELPERS/icons.dm +++ b/code/__HELPERS/icons.dm @@ -948,10 +948,16 @@ The _flatIcons list is a cache for generated icon files. return "#[color]" //Imagine removing pixels from the main icon that are covered by pixels from the mask icon. -/proc/get_icon_difference(var/icon/main, var/icon/mask) +//Standard behaviour is to cut pixels from the main icon that are covered by pixels from the mask icon unless passed mask_ready, see below. +/proc/get_icon_difference(var/icon/main, var/icon/mask, var/mask_ready) + /*You should skip prep if the mask is already sprited properly. This significantly improves performance by eliminating most of the realtime icon work. + e.g. A 'ready' mask is a mask where the part you want cut out is missing (no pixels, 0 alpha) from the sprite, and everything else is solid white.*/ + if(istype(main) && istype(mask)) - mask.Blend(rgb(255,255,255), ICON_SUBTRACT) //Make all pixels on the mask as black as possible. - mask.Opaque(rgb(255,255,255)) //Make the transparent pixels (background) white. - mask.BecomeAlphaMask() //Make all the black pixels vanish (fully transparent), leaving only the white pixels. + if(!mask_ready) //Prep the mask if we're using a regular old sprite and not a special-made mask. + mask.Blend(rgb(255,255,255), ICON_SUBTRACT) //Make all pixels on the mask as black as possible. + mask.Opaque(rgb(255,255,255)) //Make the transparent pixels (background) white. + mask.BecomeAlphaMask() //Make all the black pixels vanish (fully transparent), leaving only the white background pixels. + main.AddAlphaMask(mask) //Make the pixels in the main icon that are in the transparent zone of the mask icon also vanish (fully transparent). - return main + return main \ No newline at end of file diff --git a/code/_globalvars/lists/objects.dm b/code/_globalvars/lists/objects.dm index 5ff132a7ee6..ad3798a010e 100644 --- a/code/_globalvars/lists/objects.dm +++ b/code/_globalvars/lists/objects.dm @@ -42,9 +42,12 @@ GLOBAL_LIST_INIT(global_radios, list()) //list of all radios, across all z-le GLOBAL_LIST_INIT(meteor_list, list()) //list of all meteors GLOBAL_LIST_INIT(poi_list, list()) //list of points of interest for observe/follow GLOBAL_LIST_INIT(active_jammers, list()) // List of active radio jammers +GLOBAL_LIST_EMPTY(ladders) GLOBAL_LIST_INIT(active_diseases, list()) //List of Active disease in all mobs; purely for quick referencing. GLOBAL_LIST_EMPTY(mob_spawners) // All mob_spawn objects -GLOBAL_LIST_EMPTY(explosive_walls) \ No newline at end of file +GLOBAL_LIST_EMPTY(explosive_walls) + +GLOBAL_LIST_EMPTY(engine_beacon_list) \ No newline at end of file diff --git a/code/_onclick/ai.dm b/code/_onclick/ai.dm index 22921f5228d..ca8f32f2599 100644 --- a/code/_onclick/ai.dm +++ b/code/_onclick/ai.dm @@ -209,11 +209,13 @@ /atom/proc/AIMiddleClick() return -/obj/machinery/door/airlock/AIMiddleClick() // Toggles door bolt lights. - if(!src.lights) - Topic(src, list("src" = UID(), "command"="lights", "activate" = "1"), 1) // 1 meaning no window (consistency!) +/obj/machinery/door/airlock/AIMiddleClick() // Toggles door safety. + if(safe) + Topic(src, list("src" = UID(), "command"="safeties", "activate" = "1"), 1) // 1 meaning no window (consistency!) + to_chat(usr, "The door safeties have been overridden.") else - Topic(src, list("src" = UID(), "command"="lights", "activate" = "0"), 1) + Topic(src, list("src" = UID(), "command"="safeties", "activate" = "0"), 1) + to_chat(usr, "The door safeties have been reset.") return /obj/machinery/ai_slipper/AICtrlClick() //Turns liquid dispenser on or off diff --git a/code/_onclick/hud/blob_overmind.dm b/code/_onclick/hud/blob_overmind.dm index 1e8f99814df..c1f14fc625d 100644 --- a/code/_onclick/hud/blob_overmind.dm +++ b/code/_onclick/hud/blob_overmind.dm @@ -49,8 +49,8 @@ /obj/screen/blob/Blobbernaut icon_state = "ui_blobbernaut" - name = "Produce Blobbernaut (20)" - desc = "Produces a strong, but dumb blobbernaut from a factory blob for 20 resources.
The factory blob will be destroyed in the process." + name = "Produce Blobbernaut (60)" + desc = "Produces a strong, intelligent blobbernaut from a factory blob for 60 resources.
The factory blob will be destroyed in the process." /obj/screen/blob/Blobbernaut/Click() if(isovermind(usr)) diff --git a/code/_onclick/hud/ghost.dm b/code/_onclick/hud/ghost.dm index 4e92395f4cc..600c1105e8e 100644 --- a/code/_onclick/hud/ghost.dm +++ b/code/_onclick/hud/ghost.dm @@ -59,3 +59,8 @@ using = new /obj/screen/ghost/teleport() using.screen_loc = ui_ghost_teleport static_inventory += using + +/datum/hud/ghost/show_hud() + mymob.client.screen = list() + mymob.client.screen += static_inventory + ..() diff --git a/code/_onclick/hud/hud.dm b/code/_onclick/hud/hud.dm index 0063feae9cf..e93b3b121e6 100644 --- a/code/_onclick/hud/hud.dm +++ b/code/_onclick/hud/hud.dm @@ -99,6 +99,7 @@ /datum/hud/proc/show_hud(version = 0) if(!ismob(mymob)) return FALSE + if(!mymob.client) return FALSE @@ -172,6 +173,7 @@ mymob.update_action_buttons(1) reorganize_alerts() reload_fullscreen() + update_parallax_pref(mymob) plane_masters_update() /datum/hud/proc/plane_masters_update() diff --git a/code/_onclick/hud/parallax.dm b/code/_onclick/hud/parallax.dm new file mode 100644 index 00000000000..e60200b967a --- /dev/null +++ b/code/_onclick/hud/parallax.dm @@ -0,0 +1,319 @@ +/client + var/list/parallax_layers + var/list/parallax_layers_cached + var/static/list/parallax_static_layers_tail = newlist(/obj/screen/parallax_pmaster, /obj/screen/parallax_space_whitifier) + var/atom/movable/movingmob + var/turf/previous_turf + var/dont_animate_parallax //world.time of when we can state animate()ing parallax again + var/last_parallax_shift //world.time of last update + var/parallax_throttle = 0 //ds between updates + var/parallax_movedir = 0 + var/parallax_layers_max = 3 + var/parallax_animate_timer + +/datum/hud/proc/create_parallax() + var/client/C = mymob.client + if(!apply_parallax_pref()) + return + + if(!length(C.parallax_layers_cached)) + C.parallax_layers_cached = list() + C.parallax_layers_cached += new /obj/screen/parallax_layer/layer_1(null, C.view) + C.parallax_layers_cached += new /obj/screen/parallax_layer/layer_2(null, C.view) + C.parallax_layers_cached += new /obj/screen/parallax_layer/planet(null, C.view) + C.parallax_layers_cached += new /obj/screen/parallax_layer/layer_3(null, C.view) + + C.parallax_layers = C.parallax_layers_cached.Copy() + + if(length(C.parallax_layers) > C.parallax_layers_max) + C.parallax_layers.len = C.parallax_layers_max + + C.screen |= (C.parallax_layers + C.parallax_static_layers_tail) + +/datum/hud/proc/remove_parallax() + var/client/C = mymob.client + C.screen -= (C.parallax_layers_cached + C.parallax_static_layers_tail) + C.parallax_layers = null + +/datum/hud/proc/apply_parallax_pref() + var/client/C = mymob.client + if(C.prefs) + var/pref = C.prefs.parallax + if (isnull(pref)) + pref = PARALLAX_HIGH + switch(C.prefs.parallax) + if (PARALLAX_INSANE) + C.parallax_throttle = FALSE + C.parallax_layers_max = 4 + return TRUE + + if (PARALLAX_MED) + C.parallax_throttle = PARALLAX_DELAY_MED + C.parallax_layers_max = 2 + return TRUE + + if (PARALLAX_LOW) + C.parallax_throttle = PARALLAX_DELAY_LOW + C.parallax_layers_max = 1 + return TRUE + + if (PARALLAX_DISABLE) + return FALSE + + C.parallax_throttle = PARALLAX_DELAY_DEFAULT + C.parallax_layers_max = 3 + return TRUE + +/datum/hud/proc/update_parallax_pref() + remove_parallax() + create_parallax() + update_parallax() + +// This sets which way the current shuttle is moving (returns true if the shuttle has stopped moving so the caller can append their animation) +// Well, it would if our shuttle code had dynamic areas +/datum/hud/proc/set_parallax_movedir(new_parallax_movedir, skip_windups) + . = FALSE + var/client/C = mymob.client + if(new_parallax_movedir == C.parallax_movedir) + return + var/animatedir = new_parallax_movedir + if(new_parallax_movedir == FALSE) + var/animate_time = 0 + for(var/thing in C.parallax_layers) + var/obj/screen/parallax_layer/L = thing + L.icon_state = initial(L.icon_state) + L.update_o(C.view) + var/T = PARALLAX_LOOP_TIME / L.speed + if(T > animate_time) + animate_time = T + C.dont_animate_parallax = world.time + min(animate_time, PARALLAX_LOOP_TIME) + animatedir = C.parallax_movedir + + var/matrix/newtransform + switch(animatedir) + if(NORTH) + newtransform = matrix(1, 0, 0, 0, 1, 480) + if(SOUTH) + newtransform = matrix(1, 0, 0, 0, 1,-480) + if(EAST) + newtransform = matrix(1, 0, 480, 0, 1, 0) + if(WEST) + newtransform = matrix(1, 0,-480, 0, 1, 0) + + var/shortesttimer + for(var/thing in C.parallax_layers) + var/obj/screen/parallax_layer/L = thing + + var/T = PARALLAX_LOOP_TIME / L.speed + if(isnull(shortesttimer)) + shortesttimer = T + if(T < shortesttimer) + shortesttimer = T + L.transform = newtransform + animate(L, transform = matrix(), time = T, easing = QUAD_EASING | (new_parallax_movedir ? EASE_IN : EASE_OUT), flags = ANIMATION_END_NOW) + if(new_parallax_movedir) + L.transform = newtransform + animate(transform = matrix(), time = T) //queue up another animate so lag doesn't create a shutter + + C.parallax_movedir = new_parallax_movedir + if(C.parallax_animate_timer) + deltimer(C.parallax_animate_timer) + var/datum/callback/CB = CALLBACK(src, .proc/update_parallax_motionblur, C, animatedir, new_parallax_movedir, newtransform) + if(skip_windups) + CB.Invoke() + else + C.parallax_animate_timer = addtimer(CB, min(shortesttimer, PARALLAX_LOOP_TIME), TIMER_CLIENT_TIME|TIMER_STOPPABLE) + +/datum/hud/proc/update_parallax_motionblur(client/C, animatedir, new_parallax_movedir, matrix/newtransform) + C.parallax_animate_timer = FALSE + for(var/thing in C.parallax_layers) + var/obj/screen/parallax_layer/L = thing + if(!new_parallax_movedir) + animate(L) + continue + + var/newstate = initial(L.icon_state) + if(animatedir) + if(animatedir == NORTH || animatedir == SOUTH) + newstate += "_vertical" + else + newstate += "_horizontal" + + var/T = PARALLAX_LOOP_TIME / L.speed + + if(newstate in icon_states(L.icon)) + L.icon_state = newstate + L.update_o(C.view) + + L.transform = newtransform + + animate(L, transform = matrix(), time = T, loop = -1, flags = ANIMATION_END_NOW) + +/datum/hud/proc/update_parallax() + var/client/C = mymob.client + var/turf/posobj = get_turf(C.eye) + if(!posobj) + return + var/area/areaobj = posobj.loc + + // Update the movement direction of the parallax if necessary (for shuttles) + var/area/shuttle/SA = areaobj + if(!SA || !SA.moving) + set_parallax_movedir(0) + else + set_parallax_movedir(SA.parallax_movedir) + + var/force + if(!C.previous_turf || (C.previous_turf.z != posobj.z)) + C.previous_turf = posobj + force = TRUE + + if(!force && world.time < C.last_parallax_shift+C.parallax_throttle) + return + + //Doing it this way prevents parallax layers from "jumping" when you change Z-Levels. + var/offset_x = posobj.x - C.previous_turf.x + var/offset_y = posobj.y - C.previous_turf.y + + if(!offset_x && !offset_y && !force) + return + + var/last_delay = world.time - C.last_parallax_shift + last_delay = min(last_delay, C.parallax_throttle) + C.previous_turf = posobj + C.last_parallax_shift = world.time + + for(var/thing in C.parallax_layers) + var/obj/screen/parallax_layer/L = thing + L.update_status(mymob) + if(L.view_sized != C.view) + L.update_o(C.view) + + var/change_x + var/change_y + + if(L.absolute) + L.offset_x = -(posobj.x - SSparallax.planet_x_offset) * L.speed + L.offset_y = -(posobj.y - SSparallax.planet_y_offset) * L.speed + else + change_x = offset_x * L.speed + L.offset_x -= change_x + change_y = offset_y * L.speed + L.offset_y -= change_y + + if(L.offset_x > 240) + L.offset_x -= 480 + if(L.offset_x < -240) + L.offset_x += 480 + if(L.offset_y > 240) + L.offset_y -= 480 + if(L.offset_y < -240) + L.offset_y += 480 + + if(!(areaobj.parallax_movedir && areaobj.moving) && C.dont_animate_parallax <= world.time && (offset_x || offset_y) && abs(offset_x) <= max(C.parallax_throttle/world.tick_lag+1,1) && abs(offset_y) <= max(C.parallax_throttle/world.tick_lag+1,1) && (round(abs(change_x)) > 1 || round(abs(change_y)) > 1)) + L.transform = matrix(1, 0, offset_x*L.speed, 0, 1, offset_y*L.speed) + animate(L, transform=matrix(), time = last_delay) + + L.screen_loc = "CENTER-7:[round(L.offset_x,1)],CENTER-7:[round(L.offset_y,1)]" + +/atom/movable/proc/update_parallax_contents() + if(length(client_mobs_in_contents)) + for(var/thing in client_mobs_in_contents) + var/mob/M = thing + if(M && M.client && M.hud_used && length(M.client.parallax_layers)) + M.hud_used.update_parallax() + +/obj/screen/parallax_layer + icon = 'icons/effects/parallax.dmi' + var/speed = 1 + var/offset_x = 0 + var/offset_y = 0 + var/view_sized + var/absolute = FALSE + blend_mode = BLEND_ADD + plane = PLANE_SPACE_PARALLAX + screen_loc = "CENTER-7,CENTER-7" + mouse_opacity = 0 + + +/obj/screen/parallax_layer/New(view) + ..() + if(!view) + view = world.view + update_o(view) + +/obj/screen/parallax_layer/proc/update_o(view) + if(!view) + view = world.view + var/list/new_overlays = list() + var/count = Ceiling(view/(480/world.icon_size))+1 + for(var/x in -count to count) + for(var/y in -count to count) + if(x == 0 && y == 0) + continue + var/mutable_appearance/texture_overlay = mutable_appearance(icon, icon_state) + texture_overlay.transform = matrix(1, 0, x*480, 0, 1, y*480) + new_overlays += texture_overlay + + overlays = new_overlays + view_sized = view + +/obj/screen/parallax_layer/proc/update_status(mob/M) + return + +/obj/screen/parallax_layer/layer_1 + icon_state = "layer1" + speed = 0.6 + layer = 1 + +/obj/screen/parallax_layer/layer_2 + icon_state = "layer2" + speed = 1 + layer = 2 + +/obj/screen/parallax_layer/layer_3 + icon_state = "layer3" + speed = 1.4 + layer = 3 + +/obj/screen/parallax_layer/planet + icon_state = "planet" + blend_mode = BLEND_OVERLAY + absolute = TRUE //Status of seperation + speed = 3 + layer = 30 + +/obj/screen/parallax_layer/planet/update_status(mob/M) + var/turf/T = get_turf(M) + if(is_station_level(T.z)) + invisibility = 0 + else + invisibility = INVISIBILITY_ABSTRACT + +/obj/screen/parallax_layer/planet/update_o() + return //Shit wont move + +/obj/screen/parallax_pmaster + appearance_flags = PLANE_MASTER + plane = PLANE_SPACE_PARALLAX + blend_mode = BLEND_MULTIPLY + mouse_opacity = FALSE + screen_loc = "CENTER-7,CENTER-7" + +/obj/screen/parallax_space_whitifier + appearance_flags = PLANE_MASTER + plane = PLANE_SPACE + color = list( + 0, 0, 0, 0, + 0, 0, 0, 0, + 0, 0, 0, 0, + 1, 1, 1, 1, + 0, 0, 0, 0 + ) + screen_loc = "CENTER-7,CENTER-7" + + +#undef LOOP_NONE +#undef LOOP_NORMAL +#undef LOOP_REVERSE +#undef LOOP_TIME \ No newline at end of file diff --git a/code/_onclick/observer.dm b/code/_onclick/observer.dm index 797384b8336..5f0c94ecee6 100644 --- a/code/_onclick/observer.dm +++ b/code/_onclick/observer.dm @@ -17,6 +17,7 @@ else following = null forceMove(get_turf(A)) + update_parallax_contents() /mob/dead/observer/ClickOn(var/atom/A, var/params) if(client.click_intercept) @@ -58,6 +59,14 @@ /atom/proc/attack_ghost(mob/user as mob) return +// health + cyborg analyzer for ghosts +/mob/living/attack_ghost(mob/dead/observer/user) + if(user.client && user.health_scan) + if(issilicon(src) || ismachine(src)) + robot_healthscan(user, src) + else if(ishuman(src)) + healthscan(user, src, 1, TRUE) + // --------------------------------------- // And here are some good things for free: // Now you can click through portals, wormholes, gateways, and teleporters while observing. -Sayu diff --git a/code/controllers/subsystem/chat.dm b/code/controllers/subsystem/chat.dm new file mode 100644 index 00000000000..a90e14d0ab4 --- /dev/null +++ b/code/controllers/subsystem/chat.dm @@ -0,0 +1,65 @@ +SUBSYSTEM_DEF(chat) + name = "Chat" + flags = SS_TICKER|SS_NO_INIT + wait = 1 + priority = FIRE_PRIORITY_CHAT + init_order = INIT_ORDER_CHAT + + var/list/payload = list() + + +/datum/controller/subsystem/chat/fire() + for(var/i in payload) + var/client/C = i + C << output(payload[C], "browseroutput:output") + payload -= C + + if(MC_TICK_CHECK) + return + + +/datum/controller/subsystem/chat/proc/queue(target, message, flag) + if(!target || !message) + return + + if(!istext(message)) + stack_trace("to_chat called with invalid input type") + return + + if(target == world) + target = GLOB.clients + + //Some macros remain in the string even after parsing and fuck up the eventual output + message = replacetext(message, "\improper", "") + message = replacetext(message, "\proper", "") + message += "
" + + + //url_encode it TWICE, this way any UTF-8 characters are able to be decoded by the Javascript. + //Do the double-encoding here to save nanoseconds + var/twiceEncoded = url_encode(url_encode(message)) + + if(islist(target)) + for(var/I in target) + var/client/C = CLIENT_FROM_VAR(I) //Grab us a client if possible + + if(!C?.chatOutput || C.chatOutput.broken) //A player who hasn't updated his skin file. + continue + + if(!C.chatOutput.loaded) //Client still loading, put their messages in a queue + C.chatOutput.messageQueue += message + continue + + payload[C] += twiceEncoded + + else + var/client/C = CLIENT_FROM_VAR(target) //Grab us a client if possible + + if(!C?.chatOutput || C.chatOutput.broken) //A player who hasn't updated his skin file. + return + + if(!C.chatOutput.loaded) //Client still loading, put their messages in a queue + C.chatOutput.messageQueue += message + return + + payload[C] += twiceEncoded \ No newline at end of file diff --git a/code/controllers/subsystem/parallax.dm b/code/controllers/subsystem/parallax.dm new file mode 100644 index 00000000000..039b6d2b008 --- /dev/null +++ b/code/controllers/subsystem/parallax.dm @@ -0,0 +1,44 @@ +SUBSYSTEM_DEF(parallax) + name = "Parallax" + wait = 2 + flags = SS_POST_FIRE_TIMING | SS_BACKGROUND + priority = FIRE_PRIORITY_PARALLAX + runlevels = RUNLEVEL_LOBBY | RUNLEVELS_DEFAULT + var/list/currentrun + var/planet_x_offset = 128 + var/planet_y_offset = 128 + +/datum/controller/subsystem/parallax/Initialize(timeofday) + . = ..() + planet_y_offset = rand(100, 160) + planet_x_offset = rand(100, 160) + +/datum/controller/subsystem/parallax/fire(resumed = 0) + if(!resumed) + src.currentrun = GLOB.clients.Copy() + + //cache for sanic speed (lists are references anyways) + var/list/currentrun = src.currentrun + + while(length(currentrun)) + var/client/C = currentrun[currentrun.len] + currentrun.len-- + if(!C || !C.eye) + if(MC_TICK_CHECK) + return + continue + var/atom/movable/A = C.eye + if(!istype(A)) + continue + for (A; isloc(A.loc) && !isturf(A.loc); A = A.loc); + + if(A != C.movingmob) + if(C.movingmob != null) + C.movingmob.client_mobs_in_contents -= C.mob + UNSETEMPTY(C.movingmob.client_mobs_in_contents) + LAZYINITLIST(A.client_mobs_in_contents) + A.client_mobs_in_contents += C.mob + C.movingmob = A + if(MC_TICK_CHECK) + return + currentrun = null diff --git a/code/controllers/subsystem/ticker.dm b/code/controllers/subsystem/ticker.dm index 4aa30657778..f9528f2b2b9 100644 --- a/code/controllers/subsystem/ticker.dm +++ b/code/controllers/subsystem/ticker.dm @@ -68,8 +68,14 @@ SUBSYSTEM_DEF(ticker) current_state = GAME_STATE_PREGAME fire() // TG says this is a good idea if(GAME_STATE_PREGAME) + if(!going) + return + // This is so we dont have sleeps in controllers, because that is a bad, bad thing - pregame_timeleft = max(0,round_start_time - world.time) + if(!delay_end) + pregame_timeleft = max(0,round_start_time - world.time) // Normal lobby countdown when roundstart was not delayed + else + pregame_timeleft = max(0,pregame_timeleft - 20) // If roundstart was delayed, we should resume the countdown where it left off if(pregame_timeleft <= 600 && !tipped) // 60 seconds send_tip_of_the_round() @@ -83,6 +89,7 @@ SUBSYSTEM_DEF(ticker) current_state = GAME_STATE_STARTUP Master.SetRunLevel(RUNLEVEL_LOBBY) if(GAME_STATE_PLAYING) + delay_end = 0 // reset this in case round start was delayed mode.process() mode.process_job_tasks() var/game_finished = SSshuttle.emergency.mode >= SHUTTLE_ENDGAME || mode.station_was_nuked diff --git a/code/datums/action.dm b/code/datums/action.dm index a5f63cc6fe4..6a2f02c2562 100644 --- a/code/datums/action.dm +++ b/code/datums/action.dm @@ -196,6 +196,14 @@ /datum/action/item_action/toggle_helmet_light name = "Toggle Helmet Light" +/datum/action/item_action/toggle_welding_screen/plasmaman + name = "Toggle Welding Screen" + +/datum/action/item_action/toggle_welding_screen/plasmaman/Trigger() + var/obj/item/clothing/head/helmet/space/plasmaman/H = target + if(istype(H)) + H.toggle_welding_screen(owner) + /datum/action/item_action/toggle_helmet_mode name = "Toggle Helmet Mode" diff --git a/code/datums/components/paintable.dm b/code/datums/components/paintable.dm new file mode 100644 index 00000000000..ef9a2923cc6 --- /dev/null +++ b/code/datums/components/paintable.dm @@ -0,0 +1,31 @@ +/datum/component/spraycan_paintable + var/current_paint + +/datum/component/spraycan_paintable/Initialize() + RegisterSignal(parent, COMSIG_PARENT_ATTACKBY, .proc/Repaint) + +/datum/component/spraycan_paintable/Destroy() + RemoveCurrentCoat() + return ..() + +/datum/component/spraycan_paintable/proc/RemoveCurrentCoat() + var/atom/A = parent + A.remove_atom_colour(FIXED_COLOUR_PRIORITY, current_paint) + +/datum/component/spraycan_paintable/proc/Repaint(datum/source, obj/item/toy/crayon/spraycan/spraycan, mob/living/user) + if(!istype(spraycan) || user.a_intent == INTENT_HARM) + return + . = COMPONENT_NO_AFTERATTACK + if(spraycan.capped) + to_chat(user, "Take the cap off first!") + return + if(spraycan.uses < 2) + to_chat(user, "There is not enough paint in the can!") + return + RemoveCurrentCoat() + var/colour = spraycan.colour + current_paint = colour + var/atom/A = parent + A.add_atom_colour(colour, FIXED_COLOUR_PRIORITY) + playsound(spraycan, 'sound/effects/spray.ogg', 5, 1, 5) + to_chat(user, "You spray [spraycan] on [A], painting it.") diff --git a/code/datums/datumvars.dm b/code/datums/datumvars.dm index adb3167d8e4..e8339f81945 100644 --- a/code/datums/datumvars.dm +++ b/code/datums/datumvars.dm @@ -1269,7 +1269,12 @@ return src.debug_variables(DAT) - return + if(href_list["copyoutfit"]) + if(!check_rights(R_EVENT)) + return + var/mob/living/carbon/human/H = locateUID(href_list["copyoutfit"]) + if(istype(H)) + H.copy_outfit() /client/proc/view_var_Topic_list(href, href_list, hsrc) if(href_list["VarsList"]) diff --git a/code/datums/diseases/advance/symptoms/shivering.dm b/code/datums/diseases/advance/symptoms/shivering.dm index d52a0a02256..30d1084ba0e 100644 --- a/code/datums/diseases/advance/symptoms/shivering.dm +++ b/code/datums/diseases/advance/symptoms/shivering.dm @@ -30,11 +30,11 @@ Bonus if(prob(SYMPTOM_ACTIVATION_PROB)) var/mob/living/carbon/M = A.affected_mob to_chat(M, "[pick("You feel cold.", "You start shivering.")]") - if(M.bodytemperature < BODYTEMP_COLD_DAMAGE_LIMIT) + if(M.bodytemperature > BODYTEMP_COLD_DAMAGE_LIMIT) Chill(M, A) return /datum/symptom/shivering/proc/Chill(mob/living/M, datum/disease/advance/A) var/get_cold = (sqrtor0(16+A.totalStealth()*2))+(sqrtor0(21+A.totalResistance()*2)) - M.bodytemperature = min(M.bodytemperature - (get_cold * A.stage), BODYTEMP_COLD_DAMAGE_LIMIT + 1) - return 1 \ No newline at end of file + M.bodytemperature = max(M.bodytemperature - (get_cold * A.stage), BODYTEMP_COLD_DAMAGE_LIMIT + 1) + return 1 diff --git a/code/datums/mind.dm b/code/datums/mind.dm index 0ab0453cb95..3f4a0cb6b26 100644 --- a/code/datums/mind.dm +++ b/code/datums/mind.dm @@ -1151,7 +1151,7 @@ A.set_zeroth_law("") A.show_laws() A.verbs -= /mob/living/silicon/ai/proc/choose_modules - A.malf_picker.remove_verbs(A) + A.malf_picker.remove_malf_verbs(A) qdel(A.malf_picker) SSticker.mode.update_traitor_icons_removed(src) diff --git a/code/datums/outfits/outfit.dm b/code/datums/outfits/outfit.dm index 184f1155da2..db5cca6e9ec 100644 --- a/code/datums/outfits/outfit.dm +++ b/code/datums/outfits/outfit.dm @@ -19,14 +19,20 @@ var/suit_store = null var/l_hand = null var/r_hand = null + /// Should the toggle helmet proc be called on the helmet during equip + var/toggle_helmet = TRUE var/pda = null var/internals_slot = null //ID of slot containing a gas tank var/list/backpack_contents = list() // In the list(path=count,otherpath=count) format - var/list/implants = null - var/list/cybernetic_implants = null + var/box // Internals box. Will be inserted at the start of backpack_contents + var/list/implants = list() + var/list/cybernetic_implants = list() + var/list/accessories = list() var/list/chameleon_extras //extra types for chameleon outfit changes, mostly guns + var/can_be_admin_equipped = TRUE // Set to FALSE if your outfit requires runtime parameters + /datum/outfit/proc/pre_equip(mob/living/carbon/human/H, visualsOnly = FALSE) //to be overriden for customization depending on client prefs,species etc return @@ -82,12 +88,24 @@ if(pda) equip_item(H, pda, slot_wear_pda) + if(uniform) + for(var/path in accessories) + var/obj/item/clothing/accessory/A = new path() + var/obj/item/clothing/under/U = uniform + U.attach_accessory(A, H) + if(!visualsOnly) // Items in pockets or backpack don't show up on mob's icon. if(l_pocket) equip_item(H, l_pocket, slot_l_store) if(r_pocket) equip_item(H, r_pocket, slot_r_store) + if(box) + if(!backpack_contents) + backpack_contents = list() + backpack_contents.Insert(1, box) + backpack_contents[box] = 1 + for(var/path in backpack_contents) var/number = backpack_contents[path] for(var/i in 1 to number) @@ -97,6 +115,10 @@ var/obj/item/organ/internal/O = new path(H) O.insert(H) + if(!H.head && toggle_helmet && istype(H.wear_suit, /obj/item/clothing/suit/space/hardsuit)) + var/obj/item/clothing/suit/space/hardsuit/HS = H.wear_suit + HS.ToggleHelmet() + post_equip(H, visualsOnly) if(!visualsOnly) @@ -159,3 +181,97 @@ types += chameleon_extras listclearnulls(types) return types + +/datum/outfit/proc/save_to_file(mob/admin) + var/stored_data = get_json_data() + var/json = json_encode(stored_data) + // Kinda annoying but as far as I can tell you need to make actual file. + var/f = file("data/TempOutfitUpload") + fdel(f) + WRITE_FILE(f, json) + admin << ftp(f, "[name].json") + +/datum/outfit/proc/load_from(list/outfit_data) + // This could probably use more strict validation. + name = outfit_data["name"] + uniform = text2path(outfit_data["uniform"]) + suit = text2path(outfit_data["suit"]) + toggle_helmet = text2path(outfit_data["toggle_helmet"]) + back = text2path(outfit_data["back"]) + belt = text2path(outfit_data["belt"]) + gloves = text2path(outfit_data["gloves"]) + shoes = text2path(outfit_data["shoes"]) + head = text2path(outfit_data["head"]) + mask = text2path(outfit_data["mask"]) + l_ear = text2path(outfit_data["l_ear"]) + r_ear = text2path(outfit_data["r_ear"]) + glasses = text2path(outfit_data["glasses"]) + id = text2path(outfit_data["id"]) + pda = text2path(outfit_data["pda"]) + l_pocket = text2path(outfit_data["l_pocket"]) + r_pocket = text2path(outfit_data["r_pocket"]) + suit_store = text2path(outfit_data["suit_store"]) + r_hand = text2path(outfit_data["r_hand"]) + l_hand = text2path(outfit_data["l_hand"]) + internals_slot = text2path(outfit_data["internals_slot"]) + + var/list/backpack = outfit_data["backpack_contents"] + backpack_contents = list() + for(var/item in backpack) + var/itype = text2path(item) + if(itype) + backpack_contents[itype] = backpack[item] + box = text2path(outfit_data["box"]) + + var/list/impl = outfit_data["implants"] + implants = list() + for(var/I in impl) + var/imptype = text2path(I) + if(imptype) + implants += imptype + + var/list/cybernetic_impl = outfit_data["cybernetic_implants"] + cybernetic_implants = list() + for(var/I in cybernetic_impl) + var/cybtype = text2path(I) + if(cybtype) + cybernetic_implants += cybtype + + var/list/accessories = outfit_data["accessories"] + accessories = list() + for(var/A in accessories) + var/accessorytype = text2path(A) + if(accessorytype) + accessories += accessorytype + + return TRUE + +/datum/outfit/proc/get_json_data() + . = list() + .["outfit_type"] = type + .["name"] = name + .["uniform"] = uniform + .["suit"] = suit + .["toggle_helmet"] = toggle_helmet + .["back"] = back + .["belt"] = belt + .["gloves"] = gloves + .["shoes"] = shoes + .["head"] = head + .["mask"] = mask + .["l_ear"] = l_ear + .["r_ear"] = r_ear + .["glasses"] = glasses + .["id"] = id + .["pda"] = pda + .["l_pocket"] = l_pocket + .["r_pocket"] = r_pocket + .["suit_store"] = suit_store + .["r_hand"] = r_hand + .["l_hand"] = l_hand + .["internals_slot"] = internals_slot + .["backpack_contents"] = backpack_contents + .["box"] = box + .["implants"] = implants + .["cybernetic_implants"] = cybernetic_implants + .["accessories"] = accessories diff --git a/code/datums/outfits/outfit_admin.dm b/code/datums/outfits/outfit_admin.dm index 40205ca715b..ff8a93d3df0 100644 --- a/code/datums/outfits/outfit_admin.dm +++ b/code/datums/outfits/outfit_admin.dm @@ -78,7 +78,6 @@ suit = /obj/item/clothing/suit/space/hardsuit/syndi belt = /obj/item/storage/belt/military - head = /obj/item/clothing/head/helmet/space/hardsuit/syndi mask = /obj/item/clothing/mask/gas/syndicate l_ear = /obj/item/radio/headset/syndicate/alt glasses = /obj/item/clothing/glasses/night @@ -110,7 +109,6 @@ /datum/outfit/admin/syndicate/operative/freedom name = "Syndicate Freedom Operative" suit = /obj/item/clothing/suit/space/hardsuit/syndi/freedom - head = /obj/item/clothing/head/helmet/space/hardsuit/syndi/freedom /datum/outfit/admin/syndicate_strike_team @@ -794,41 +792,34 @@ /datum/outfit/admin/hardsuit/engineer name = "Engineer Hardsuit" - suit = /obj/item/clothing/suit/space/hardsuit - head = /obj/item/clothing/head/helmet/space/hardsuit + suit = /obj/item/clothing/suit/space/hardsuit/engine /datum/outfit/admin/hardsuit/ce name = "CE Hardsuit" - suit = /obj/item/clothing/suit/space/hardsuit/elite - head = /obj/item/clothing/head/helmet/space/hardsuit/elite + suit = /obj/item/clothing/suit/space/hardsuit/engine/elite shoes = /obj/item/clothing/shoes/magboots/advance /datum/outfit/admin/hardsuit/mining name = "Mining Hardsuit" suit = /obj/item/clothing/suit/space/hardsuit/mining - head = /obj/item/clothing/head/helmet/space/hardsuit/mining /datum/outfit/admin/hardsuit/syndi name = "Syndi Hardsuit" suit = /obj/item/clothing/suit/space/hardsuit/syndi - head = /obj/item/clothing/head/helmet/space/hardsuit/syndi shoes = /obj/item/clothing/shoes/magboots/syndie /datum/outfit/admin/hardsuit/wizard name = "Wizard Hardsuit" suit = /obj/item/clothing/suit/space/hardsuit/wizard - head = /obj/item/clothing/head/helmet/space/hardsuit/wizard shoes = /obj/item/clothing/shoes/magboots /datum/outfit/admin/hardsuit/medical name = "Medical Hardsuit" suit = /obj/item/clothing/suit/space/hardsuit/medical - head = /obj/item/clothing/head/helmet/space/hardsuit/medical /datum/outfit/admin/hardsuit/atmos name = "Atmos Hardsuit" - suit = /obj/item/clothing/suit/space/hardsuit/atmos - head = /obj/item/clothing/head/helmet/space/hardsuit/atmos + suit = /obj/item/clothing/suit/space/hardsuit/engine/atmos /datum/outfit/admin/tournament @@ -963,7 +954,6 @@ belt = /obj/item/claymore/ceremonial gloves = /obj/item/clothing/gloves/combat shoes = /obj/item/clothing/shoes/magboots - head = /obj/item/clothing/head/helmet/space/hardsuit/singuloth mask = /obj/item/clothing/mask/breath l_ear = /obj/item/radio/headset/ert glasses = /obj/item/clothing/glasses/meson/cyber @@ -1111,7 +1101,6 @@ backpack_contents = list( /obj/item/storage/box/engineer = 1, /obj/item/clothing/suit/space/hardsuit/wizard = 1, - /obj/item/clothing/head/helmet/space/hardsuit/wizard = 1, /obj/item/clothing/shoes/magboots = 1, /obj/item/kitchen/knife/ritual = 1, /obj/item/clothing/suit/wizrobe/red = 1, diff --git a/code/datums/outfits/plasmamen.dm b/code/datums/outfits/plasmamen.dm new file mode 100644 index 00000000000..c14eafd08f2 --- /dev/null +++ b/code/datums/outfits/plasmamen.dm @@ -0,0 +1,178 @@ +/datum/outfit/plasmaman + name = "Plasmaman" + + head = /obj/item/clothing/head/helmet/space/plasmaman + uniform = /obj/item/clothing/under/plasmaman + r_hand = /obj/item/tank/plasma/plasmaman/belt/full + mask = /obj/item/clothing/mask/breath + +/datum/outfit/plasmaman/bar + name = "Bartender Plasmaman" + + head = /obj/item/clothing/head/helmet/space/plasmaman/white + uniform = /obj/item/clothing/under/plasmaman/enviroslacks + +/datum/outfit/plasmaman/chef + name = "Chef Plasmaman" + + head = /obj/item/clothing/head/helmet/space/plasmaman/chef + uniform = /obj/item/clothing/under/plasmaman/chef + +/datum/outfit/plasmaman/botany + name = "Botany Plasmaman" + + head = /obj/item/clothing/head/helmet/space/plasmaman/botany + uniform = /obj/item/clothing/under/plasmaman/botany + +/datum/outfit/plasmaman/librarian + name = "Librarian Plasmaman" + + head = /obj/item/clothing/head/helmet/space/plasmaman/librarian + uniform = /obj/item/clothing/under/plasmaman/librarian + +/datum/outfit/plasmaman/chaplain + name = "Chaplain Plasmaman" + + head = /obj/item/clothing/head/helmet/space/plasmaman/chaplain + uniform = /obj/item/clothing/under/plasmaman/chaplain + +/datum/outfit/plasmaman/janitor + name = "Janitor Plasmaman" + + head = /obj/item/clothing/head/helmet/space/plasmaman/janitor + uniform = /obj/item/clothing/under/plasmaman/janitor + +/datum/outfit/plasmaman/security + name = "Security Plasmaman" + + head = /obj/item/clothing/head/helmet/space/plasmaman/security + uniform = /obj/item/clothing/under/plasmaman/security + +/datum/outfit/plasmaman/detective + name = "Detective Plasmaman" + + head = /obj/item/clothing/head/helmet/space/plasmaman/white + uniform = /obj/item/clothing/under/plasmaman/enviroslacks + l_ear = /obj/item/radio/headset/headset_sec + +/datum/outfit/plasmaman/warden + name = "Warden Plasmaman" + + head = /obj/item/clothing/head/helmet/space/plasmaman/security/warden + uniform = /obj/item/clothing/under/plasmaman/security/warden + +/datum/outfit/plasmaman/hos + name = "Head of Security Plasmaman" + + head = /obj/item/clothing/head/helmet/space/plasmaman/security/hos + uniform = /obj/item/clothing/under/plasmaman/security/hos + +/datum/outfit/plasmaman/cargo + name = "Cargo Plasmaman" + + head = /obj/item/clothing/head/helmet/space/plasmaman/cargo + uniform = /obj/item/clothing/under/plasmaman/cargo + +/datum/outfit/plasmaman/mining + name = "Mining Plasmaman" + + head = /obj/item/clothing/head/helmet/space/plasmaman/mining + uniform = /obj/item/clothing/under/plasmaman/mining + +/datum/outfit/plasmaman/medical + name = "Medical Plasmaman" + + head = /obj/item/clothing/head/helmet/space/plasmaman/medical + uniform = /obj/item/clothing/under/plasmaman/medical + +/datum/outfit/plasmaman/cmo + name = "Chief Medical Officer Plasmaman" + + head = /obj/item/clothing/head/helmet/space/plasmaman/cmo + uniform = /obj/item/clothing/under/plasmaman/cmo + +/datum/outfit/plasmaman/viro + name = "Virology Plasmaman" + + head = /obj/item/clothing/head/helmet/space/plasmaman/viro + uniform = /obj/item/clothing/under/plasmaman/viro + +/datum/outfit/plasmaman/chemist + name = "Chemist Plasmaman" + + head = /obj/item/clothing/head/helmet/space/plasmaman/chemist + uniform = /obj/item/clothing/under/plasmaman/chemist + +/datum/outfit/plasmaman/genetics + name = "Genetics Plasmaman" + + head = /obj/item/clothing/head/helmet/space/plasmaman/genetics + uniform = /obj/item/clothing/under/plasmaman/genetics + +/datum/outfit/plasmaman/science + name = "Science Plasmaman" + + head = /obj/item/clothing/head/helmet/space/plasmaman/science + uniform = /obj/item/clothing/under/plasmaman/science + +/datum/outfit/plasmaman/rd + name = "Research Director Plasmaman" + + head = /obj/item/clothing/head/helmet/space/plasmaman/rd + uniform = /obj/item/clothing/under/plasmaman/rd + +/datum/outfit/plasmaman/robotics + name = "Robotics Plasmaman" + + head = /obj/item/clothing/head/helmet/space/plasmaman/robotics + uniform = /obj/item/clothing/under/plasmaman/robotics + +/datum/outfit/plasmaman/engineering + name = "Engineering Plasmaman" + + head = /obj/item/clothing/head/helmet/space/plasmaman/engineering + uniform = /obj/item/clothing/under/plasmaman/engineering + +/datum/outfit/plasmaman/ce + name = "Chief Engineer Plasmaman" + + head = /obj/item/clothing/head/helmet/space/plasmaman/engineering/ce + uniform = /obj/item/clothing/under/plasmaman/engineering/ce + +/datum/outfit/plasmaman/atmospherics + name = "Atmospherics Plasmaman" + + head = /obj/item/clothing/head/helmet/space/plasmaman/atmospherics + uniform = /obj/item/clothing/under/plasmaman/atmospherics + +/datum/outfit/plasmaman/mime + name = "Plasmamime" + + head = /obj/item/clothing/head/helmet/space/plasmaman/mime + uniform = /obj/item/clothing/under/plasmaman/mime + mask = /obj/item/clothing/mask/gas/mime + +/datum/outfit/plasmaman/clown + name = "Plasmaclown" + + head = /obj/item/clothing/head/helmet/space/plasmaman/clown + uniform = /obj/item/clothing/under/plasmaman/clown + mask = /obj/item/clothing/mask/gas/clown_hat + +/datum/outfit/plasmaman/hop + name = "Head of Personnel Plasmaman" + + head = /obj/item/clothing/head/helmet/space/plasmaman/hop + uniform = /obj/item/clothing/under/plasmaman/hop + +/datum/outfit/plasmaman/captain + name = "Captain Plasmaman" + + head = /obj/item/clothing/head/helmet/space/plasmaman/captain + uniform = /obj/item/clothing/under/plasmaman/captain + +/datum/outfit/plasmaman/blueshield + name = "Blueshield Plasmaman" + + head = /obj/item/clothing/head/helmet/space/plasmaman/blueshield + uniform = /obj/item/clothing/under/plasmaman/blueshield \ No newline at end of file diff --git a/code/datums/outfits/vv_outfit.dm b/code/datums/outfits/vv_outfit.dm new file mode 100644 index 00000000000..7a07b087ae8 --- /dev/null +++ b/code/datums/outfits/vv_outfit.dm @@ -0,0 +1,190 @@ +// This outfit preserves varedits made on the items +// Created from admin helpers. +/datum/outfit/varedit + var/list/vv_values + var/list/stored_access + var/update_id_name = FALSE //If the name of the human is same as the name on the id they're wearing we'll update provided id when equipping + +/datum/outfit/varedit/pre_equip(mob/living/carbon/human/H, visualsOnly) + H.delete_equipment() //Applying VV to wrong objects is not reccomended. + . = ..() + +/datum/outfit/varedit/proc/set_equipment_by_slot(slot, item_path) + switch(slot) + if(slot_w_uniform) + uniform = item_path + if(slot_back) + back = item_path + if(slot_wear_suit) + suit = item_path + if(slot_belt) + belt = item_path + if(slot_gloves) + gloves = item_path + if(slot_shoes) + shoes = item_path + if(slot_head) + head = item_path + if(slot_wear_mask) + mask = item_path + if(slot_l_ear) + l_ear = item_path + if(slot_r_ear) + r_ear = item_path + if(slot_glasses) + glasses = item_path + if(slot_wear_id) + id = item_path + if(slot_wear_pda) + pda = item_path + if(slot_s_store) + suit_store = item_path + if(slot_l_store) + l_pocket = item_path + if(slot_r_store) + r_pocket = item_path + + +/proc/collect_vv(obj/item/I) + //Temporary/Internal stuff, do not copy these. + var/static/list/ignored_vars = list("vars","x","y","z","plane","layer","override","animate_movement","pixel_step_size","screen_loc","fingerprintslast","tip_timer") + + if(istype(I)) + var/list/vedits = list() + for(var/varname in I.vars) + if(!I.can_vv_get(varname)) + continue + if(varname in ignored_vars) + continue + var/vval = I.vars[varname] + //Does it even work ? + if(vval == initial(I.vars[varname])) + continue + //Only text/numbers and icons variables to make it less weirdness prone. + if(!istext(vval) && !isnum(vval) && !isicon(vval)) + continue + vedits[varname] = I.vars[varname] + return vedits + +/mob/living/carbon/human/proc/copy_outfit() + var/datum/outfit/varedit/O = new + + //Copy equipment + var/list/result = list() + var/list/slots_to_check = list(slot_w_uniform, slot_back, slot_wear_suit, slot_belt, slot_gloves, slot_shoes, slot_head, slot_wear_mask, slot_l_ear, slot_r_ear, slot_glasses, slot_wear_id, slot_wear_pda, slot_s_store, slot_l_store, slot_r_store) + for(var/s in slots_to_check) + var/obj/item/I = get_item_by_slot(s) + var/vedits = collect_vv(I) + if(vedits) + result["[s]"] = vedits + if(istype(I)) + O.set_equipment_by_slot(s, I.type) + + //Copy access + O.stored_access = list() + var/obj/item/id_slot = get_item_by_slot(slot_wear_id) + if(id_slot) + O.stored_access |= id_slot.GetAccess() + var/obj/item/card/id/ID = id_slot.GetID() + if(ID && ID.registered_name == real_name) + O.update_id_name = TRUE + + //Copy hands + if(l_hand || r_hand) //Not in the mood to let outfits transfer amputees + var/obj/item/left_hand = l_hand + var/obj/item/right_hand = r_hand + if(istype(left_hand)) + O.l_hand = left_hand.type + var/vedits = collect_vv(left_hand) + if(vedits) + result["LHAND"] = vedits + if(istype(right_hand)) + O.r_hand = right_hand.type + var/vedits = collect_vv(left_hand) + if(vedits) + result["RHAND"] = vedits + O.vv_values = result + + //Copy backpack contents if exist. + var/obj/item/backpack = get_item_by_slot(slot_back) + if(istype(backpack) && LAZYLEN(backpack.contents) > 0) + var/list/typecounts = list() + for(var/obj/item/I in backpack) + if(typecounts[I.type]) + typecounts[I.type] += 1 + else + typecounts[I.type] = 1 + O.backpack_contents = typecounts + //TODO : Copy varedits from backpack stuff too. + + //Copy implants + O.implants = list() + for(var/obj/item/implant/I in contents) + if(istype(I)) + O.implants |= I.type + + // Copy cybernetic implants + O.cybernetic_implants = list() + for(var/obj/item/organ/internal/CI in contents) + if(istype(CI)) + O.cybernetic_implants |= CI.type + + // Copy accessories + var/obj/item/clothing/under/uniform_slot = get_item_by_slot(slot_w_uniform) + if(uniform_slot) + O.accessories = list() + for(var/obj/item/clothing/accessory/A in uniform_slot.accessories) + if(istype(A)) + O.accessories |= A + + //Copy to outfit cache + var/outfit_name = stripped_input(usr, "Enter the outfit name") + O.name = outfit_name + GLOB.custom_outfits += O + to_chat(usr, "Outfit registered, use select equipment to equip it.") + +/datum/outfit/varedit/post_equip(mob/living/carbon/human/H, visualsOnly) + . = ..() + //Apply VV + for(var/slot in vv_values) + var/list/edits = vv_values[slot] + var/obj/item/I + switch(slot) + if("LHAND") + I = H.l_hand + if("RHAND") + I = H.r_hand + else + I = H.get_item_by_slot(text2num(slot)) + for(var/vname in edits) + I.vv_edit_var(vname,edits[vname]) + //Apply access + var/obj/item/id_slot = H.get_item_by_slot(slot_wear_id) + if(id_slot) + var/obj/item/card/id/card = id_slot.GetID() + if(istype(card)) + card.access |= stored_access + if(update_id_name) + card.registered_name = H.real_name + card.update_label() + +/datum/outfit/varedit/get_json_data() + . = .. () + .["stored_access"] = stored_access + .["update_id_name"] = update_id_name + var/list/stripped_vv = list() + for(var/slot in vv_values) + var/list/vedits = vv_values[slot] + var/list/stripped_edits = list() + for(var/edit in vedits) + if(istext(vedits[edit]) || isnum(vedits[edit]) || isnull(vedits[edit])) + stripped_edits[edit] = vedits[edit] + if(stripped_edits.len) + stripped_vv[slot] = stripped_edits + .["vv_values"] = stripped_vv + +/datum/outfit/varedit/load_from(list/outfit_data) + . = ..() + stored_access = outfit_data["stored_access"] + vv_values = outfit_data["vv_values"] + update_id_name = outfit_data["update_id_name"] \ No newline at end of file diff --git a/code/datums/pipe_datums.dm b/code/datums/pipe_datums.dm index cf2ec79fe85..83b77425447 100644 --- a/code/datums/pipe_datums.dm +++ b/code/datums/pipe_datums.dm @@ -337,6 +337,13 @@ GLOBAL_LIST_EMPTY(rpd_pipe_list) //Some pipes we don't want to be dispensable pipe_icon = "intake" rpd_dispensable = TRUE +/datum/pipes/disposal/sortjunction + pipe_name = "disposals sort junction" + pipe_id = PIPE_DISPOSALS_SORT_RIGHT + orientations = 4 + pipe_icon = "pipe-j1s" + rpd_dispensable = TRUE + //Pipes the RPD can't dispense. Since these don't use an interface, we don't need to bother with setting an icon. We do, however, want to name these for other purposes /datum/pipes/atmospheric/circulator @@ -363,12 +370,8 @@ GLOBAL_LIST_EMPTY(rpd_pipe_list) //Some pipes we don't want to be dispensable pipe_name = "bent insulated pipe" pipe_id = PIPE_INSULATED_BENT -/datum/pipes/disposal/sortjunction - pipe_name = "disposals sort junction" - pipe_id = PIPE_DISPOSALS_SORT_RIGHT - pipe_icon = "pipe-j1s" - -/datum/pipes/disposal/sortjunction/left +/datum/pipes/disposal/left_sortjunction + pipe_name = "disposals sort junction left" pipe_id = PIPE_DISPOSALS_SORT_LEFT pipe_icon = "pipe-j2s" diff --git a/code/datums/ruins/lavaland.dm b/code/datums/ruins/lavaland.dm index 67e5438656e..7fe8ad7248e 100644 --- a/code/datums/ruins/lavaland.dm +++ b/code/datums/ruins/lavaland.dm @@ -12,6 +12,19 @@ Comes with a rustic wooden bar and suicidal bartender." suffix = "lavaland_biodome_beach.dmm" +/datum/map_template/ruin/lavaland/biodome/winter + name = "Biodome Winter" + id = "biodome-winter" + description = "For those getaways where you want to get back to nature, but you don't want to leave the fortified military compound where you spend your days. \ + Includes a unique(*) laser pistol display case, and the recently introduced I.C.E(tm)." + suffix = "lavaland_biodome_winter.dmm" + +/datum/map_template/ruin/lavaland/biodome/clown + name = "Biodome Clown Planet" + id = "biodome-clown" + description = "WELCOME TO CLOWN PLANET! HONK HONK HONK etc.!" + suffix = "lavaland_biodome_clown_planet.dmm" + /datum/map_template/ruin/lavaland/cube name = "The Wishgranter Cube" id = "wishgranter-cube" diff --git a/code/datums/spells/charge.dm b/code/datums/spells/charge.dm index 5dd054f67ed..46cdbff7f94 100644 --- a/code/datums/spells/charge.dm +++ b/code/datums/spells/charge.dm @@ -1,7 +1,6 @@ /obj/effect/proc_holder/spell/targeted/charge name = "Charge" desc = "This spell can be used to recharge a variety of things in your hands, from magical artifacts to electrical components. A creative wizard can even use it to grant magical power to a fellow magic user." - school = "transmutation" charge_max = 600 clothes_req = 0 @@ -10,7 +9,7 @@ range = -1 cooldown_min = 400 //50 deciseconds reduction per rank include_user = 1 - + action_icon_state = "charge" /obj/effect/proc_holder/spell/targeted/charge/cast(list/targets,mob/user = usr) for(var/mob/living/L in targets) diff --git a/code/datums/spells/horsemask.dm b/code/datums/spells/horsemask.dm index 7b880f00e42..f536041e807 100644 --- a/code/datums/spells/horsemask.dm +++ b/code/datums/spells/horsemask.dm @@ -36,7 +36,7 @@ return var/obj/item/clothing/mask/horsehead/magichead = new /obj/item/clothing/mask/horsehead - magichead.flags |= NODROP //curses! + magichead.flags |= NODROP | DROPDEL //curses! magichead.flags_inv = null //so you can still see their face magichead.voicechange = 1 //NEEEEIIGHH target.visible_message( "[target]'s face lights up in fire, and after the event a horse's head takes its place!", \ diff --git a/code/datums/spells/infinite_guns.dm b/code/datums/spells/infinite_guns.dm index 83cafb88666..35699d4634a 100644 --- a/code/datums/spells/infinite_guns.dm +++ b/code/datums/spells/infinite_guns.dm @@ -11,8 +11,6 @@ cooldown_min = 10 //Gun wizard action_icon_state = "bolt_action" - - /obj/effect/proc_holder/spell/targeted/infinite_guns/cast(list/targets, mob/user = usr) for(var/mob/living/carbon/C in targets) C.drop_item() diff --git a/code/datums/spells/wizard.dm b/code/datums/spells/wizard.dm index 7b648bb72c1..739a03d92c5 100644 --- a/code/datums/spells/wizard.dm +++ b/code/datums/spells/wizard.dm @@ -72,6 +72,7 @@ /obj/effect/proc_holder/spell/noclothes name = "No Clothes" desc = "This always-on spell allows you to cast magic without your garments." + action_icon_state = "no_clothes" /obj/effect/proc_holder/spell/targeted/genetic/mutate name = "Mutate" diff --git a/code/datums/status_effects/buffs.dm b/code/datums/status_effects/buffs.dm index 387cc70f992..0573f3b90ca 100644 --- a/code/datums/status_effects/buffs.dm +++ b/code/datums/status_effects/buffs.dm @@ -40,6 +40,49 @@ playsound(owner, 'sound/weapons/bite.ogg', 50, 1) owner.adjustBruteLoss(3) +/datum/status_effect/blooddrunk + id = "blooddrunk" + duration = 10 + tick_interval = 0 + alert_type = /obj/screen/alert/status_effect/blooddrunk + +/obj/screen/alert/status_effect/blooddrunk + name = "Blood-Drunk" + desc = "You are drunk on blood! Your pulse thunders in your ears! Nothing can harm you!" //not true, and the item description mentions its actual effect + icon_state = "blooddrunk" + +/datum/status_effect/blooddrunk/on_apply() + . = ..() + if(.) + if(ishuman(owner)) + var/mob/living/carbon/human/H = owner + for(var/X in H.bodyparts) + var/obj/item/organ/external/BP = X + BP.brute_mod *= 0.1 + BP.burn_mod *= 0.1 + H.dna.species.tox_mod *= 0.1 + H.dna.species.oxy_mod *= 0.1 + H.dna.species.clone_mod *= 0.1 + H.dna.species.stamina_mod *= 0.1 + add_attack_logs(owner, owner, "gained blood-drunk stun immunity") + var/status = CANSTUN | CANWEAKEN | CANPARALYSE | IGNORESLOWDOWN + owner.status_flags &= ~status + owner.playsound_local(get_turf(owner), 'sound/effects/singlebeat.ogg', 40, 1) + +/datum/status_effect/blooddrunk/on_remove() + if(ishuman(owner)) + var/mob/living/carbon/human/H = owner + for(var/X in H.bodyparts) + var/obj/item/organ/external/BP = X + BP.brute_mod *= 10 + BP.burn_mod *= 10 + H.dna.species.tox_mod *= 10 + H.dna.species.oxy_mod *= 10 + H.dna.species.clone_mod *= 10 + H.dna.species.stamina_mod *= 10 + add_attack_logs(owner, owner, "lost blood-drunk stun immunity") + owner.status_flags |= CANSTUN | CANWEAKEN | CANPARALYSE | IGNORESLOWDOWN + /datum/status_effect/exercised id = "Exercised" duration = 1200 diff --git a/code/datums/status_effects/debuffs.dm b/code/datums/status_effects/debuffs.dm index 6e809b32606..3ce68f85250 100644 --- a/code/datums/status_effects/debuffs.dm +++ b/code/datums/status_effects/debuffs.dm @@ -9,6 +9,39 @@ if(owner.reagents) owner.reagents.del_reagent("holywater") //can't be deconverted +/datum/status_effect/crusher_mark + id = "crusher_mark" + duration = 300 //if you leave for 30 seconds you lose the mark, deal with it + status_type = STATUS_EFFECT_REPLACE + alert_type = null + var/mutable_appearance/marked_underlay + var/obj/item/twohanded/kinetic_crusher/hammer_synced + +/datum/status_effect/crusher_mark/on_creation(mob/living/new_owner, obj/item/twohanded/kinetic_crusher/new_hammer_synced) + . = ..() + if(.) + hammer_synced = new_hammer_synced + +/datum/status_effect/crusher_mark/on_apply() + if(owner.mob_size >= MOB_SIZE_LARGE) + marked_underlay = mutable_appearance('icons/effects/effects.dmi', "shield2") + marked_underlay.pixel_x = -owner.pixel_x + marked_underlay.pixel_y = -owner.pixel_y + owner.underlays += marked_underlay + return TRUE + return FALSE + +/datum/status_effect/crusher_mark/Destroy() + hammer_synced = null + if(owner) + owner.underlays -= marked_underlay + QDEL_NULL(marked_underlay) + return ..() + +/datum/status_effect/crusher_mark/be_replaced() + owner.underlays -= marked_underlay //if this is being called, we should have an owner at this point. + ..() + /datum/status_effect/saw_bleed id = "saw_bleed" duration = -1 //removed under specific conditions diff --git a/code/datums/status_effects/neutral.dm b/code/datums/status_effects/neutral.dm index eaa14c4d0b0..8f5023e4a74 100644 --- a/code/datums/status_effects/neutral.dm +++ b/code/datums/status_effects/neutral.dm @@ -1,5 +1,43 @@ //entirely neutral or internal status effects go here +/datum/status_effect/crusher_damage //tracks the damage dealt to this mob by kinetic crushers + id = "crusher_damage" + duration = -1 + status_type = STATUS_EFFECT_UNIQUE + alert_type = null + var/total_damage = 0 + +/datum/status_effect/syphon_mark + id = "syphon_mark" + duration = 50 + status_type = STATUS_EFFECT_MULTIPLE + alert_type = null + on_remove_on_mob_delete = TRUE + var/obj/item/borg/upgrade/modkit/bounty/reward_target + +/datum/status_effect/syphon_mark/on_creation(mob/living/new_owner, obj/item/borg/upgrade/modkit/bounty/new_reward_target) + . = ..() + if(.) + reward_target = new_reward_target + +/datum/status_effect/syphon_mark/on_apply() + if(owner.stat == DEAD) + return FALSE + return ..() + +/datum/status_effect/syphon_mark/proc/get_kill() + if(!QDELETED(reward_target)) + reward_target.get_kill(owner) + +/datum/status_effect/syphon_mark/tick() + if(owner.stat == DEAD) + get_kill() + qdel(src) + +/datum/status_effect/syphon_mark/on_remove() + get_kill() + . = ..() + /datum/status_effect/high_five id = "high_five" duration = 40 diff --git a/code/datums/supplypacks.dm b/code/datums/supplypacks.dm index 7a63fa1571f..494379aa821 100644 --- a/code/datums/supplypacks.dm +++ b/code/datums/supplypacks.dm @@ -160,12 +160,16 @@ var/list/all_supply_groups = list(supply_emergency,supply_security,supply_engine containername = "vox life support supplies crate" /datum/supply_packs/emergency/plasmamansupport - name = "Plasmaman Life Support Supplies" - contains = list(/obj/item/clothing/mask/breath, - /obj/item/tank/emergency_oxygen/plasma, - /obj/item/clothing/suit/space/eva/plasmaman, - /obj/item/clothing/head/helmet/space/eva/plasmaman) - cost = 75 + name = "Plasmaman Supply Kit" + contains = list(/obj/item/clothing/under/plasmaman, + /obj/item/clothing/under/plasmaman, + /obj/item/tank/plasma/plasmaman/belt/full, + /obj/item/tank/plasma/plasmaman/belt/full, + /obj/item/clothing/mask/breath, + /obj/item/clothing/mask/breath, + /obj/item/clothing/head/helmet/space/plasmaman, + /obj/item/clothing/head/helmet/space/plasmaman) + cost = 20 containertype = /obj/structure/closet/crate/secure/plasma containername = "plasmaman life support supplies crate" access = access_eva @@ -478,10 +482,10 @@ var/list/all_supply_groups = list(supply_emergency,supply_security,supply_engine /datum/supply_packs/security/securitybarriers name = "Security Barriers Crate" - contains = list(/obj/machinery/deployable/barrier, - /obj/machinery/deployable/barrier, - /obj/machinery/deployable/barrier, - /obj/machinery/deployable/barrier) + contains = list(/obj/item/grenade/barrier, + /obj/item/grenade/barrier, + /obj/item/grenade/barrier, + /obj/item/grenade/barrier) cost = 20 containername = "security barriers crate" @@ -1169,6 +1173,7 @@ var/list/all_supply_groups = list(supply_emergency,supply_security,supply_engine /datum/supply_packs/organic/hydroponics/seeds name = "Seeds Crate" contains = list(/obj/item/seeds/chili, + /obj/item/seeds/cotton, /obj/item/seeds/berry, /obj/item/seeds/corn, /obj/item/seeds/eggplant, diff --git a/code/datums/uplink_item.dm b/code/datums/uplink_item.dm index 4c1fb437046..354543e2b85 100644 --- a/code/datums/uplink_item.dm +++ b/code/datums/uplink_item.dm @@ -207,6 +207,14 @@ GLOBAL_LIST_INIT(uplink_items, subtypesof(/datum/uplink_item)) cost = 10 job = list("Mime") +/datum/uplink_item/jobspecific/pressure_mod + name = "Kinetic Accelerator Pressure Mod" + desc = "A modification kit which allows Kinetic Accelerators to do greatly increased damage while indoors. Occupies 35% mod capacity." + reference = "KPM" + item = /obj/item/borg/upgrade/modkit/indoors + cost = 5 //you need two for full damage, so total of 10 for maximum damage + job = list("Shaft Miner") + //Chef /datum/uplink_item/jobspecific/specialsauce name = "Chef Excellence's Special Sauce" @@ -892,6 +900,13 @@ GLOBAL_LIST_INIT(uplink_items, subtypesof(/datum/uplink_item)) cost = 3 surplus = 10 +/datum/uplink_item/stealthy_weapons/false_briefcase + name = "False Bottomed Briefcase" + desc = "A modified briefcase capable of storing and firing a gun under a false bottom. Use a screwdriver to pry away the false bottom and make modifications. Distinguishable upon close examination due to the added weight." + reference = "FBBC" + item = /obj/item/storage/briefcase/false_bottomed + cost = 3 + /datum/uplink_item/stealthy_weapons/soap name = "Syndicate Soap" desc = "A sinister-looking surfactant used to clean blood stains to hide murders and prevent DNA analysis. You can also drop it underfoot to slip people." @@ -1305,7 +1320,7 @@ GLOBAL_LIST_INIT(uplink_items, subtypesof(/datum/uplink_item)) /datum/uplink_item/suits/hardsuit/elite name = "Elite Syndicate Hardsuit" desc = "An advanced hardsuit with superior armor and mobility to the standard Syndicate Hardsuit." - item = /obj/item/storage/box/syndie_kit/elite_hardsuit + item = /obj/item/clothing/suit/space/hardsuit/syndi/elite cost = 8 reference = "ESHS" excludefrom = list() @@ -1314,7 +1329,7 @@ GLOBAL_LIST_INIT(uplink_items, subtypesof(/datum/uplink_item)) /datum/uplink_item/suits/hardsuit/shielded name = "Shielded Hardsuit" desc = "An advanced hardsuit with built in energy shielding. The shields will rapidly recharge when not under fire." - item = /obj/item/storage/box/syndie_kit/shielded_hardsuit + item = /obj/item/clothing/suit/space/hardsuit/shielded/syndi cost = 30 reference = "SHS" excludefrom = list() diff --git a/code/game/area/Space Station 13 areas.dm b/code/game/area/Space Station 13 areas.dm index d5b4faef17c..d6a531950c5 100644 --- a/code/game/area/Space Station 13 areas.dm +++ b/code/game/area/Space Station 13 areas.dm @@ -100,9 +100,11 @@ var/list/ghostteleportlocs = list() requires_power = FALSE valid_territory = FALSE dynamic_lighting = DYNAMIC_LIGHTING_FORCED + parallax_movedir = NORTH /area/shuttle/arrival name = "\improper Arrival Shuttle" + parallax_movedir = EAST /area/shuttle/arrival/pre_game icon_state = "shuttle2" @@ -136,12 +138,14 @@ var/list/ghostteleportlocs = list() music = "music/escape.ogg" icon_state = "shuttle" nad_allowed = TRUE + parallax_movedir = EAST /area/shuttle/pod_4 name = "\improper Escape Pod Four" music = "music/escape.ogg" icon_state = "shuttle" nad_allowed = TRUE + parallax_movedir = EAST /area/shuttle/escape_pod1 name = "\improper Escape Pod One" @@ -207,6 +211,7 @@ var/list/ghostteleportlocs = list() /area/shuttle/transport icon_state = "shuttle" name = "\improper Transport Shuttle" + parallax_movedir = EAST /area/shuttle/transport1 icon_state = "shuttle" @@ -247,6 +252,7 @@ var/list/ghostteleportlocs = list() /area/shuttle/specops name = "\improper Special Ops Shuttle" icon_state = "shuttlered" + parallax_movedir = EAST /area/shuttle/specops/centcom name = "\improper Special Ops Shuttle" @@ -260,6 +266,7 @@ var/list/ghostteleportlocs = list() name = "\improper Syndicate Elite Shuttle" icon_state = "shuttlered" nad_allowed = TRUE + parallax_movedir = SOUTH /area/shuttle/syndicate_elite/mothership name = "\improper Syndicate Elite Shuttle" @@ -273,6 +280,7 @@ var/list/ghostteleportlocs = list() name = "\improper Syndicate SIT Shuttle" icon_state = "shuttlered" nad_allowed = TRUE + parallax_movedir = SOUTH /area/shuttle/assault_pod name = "Steel Rain" @@ -281,6 +289,7 @@ var/list/ghostteleportlocs = list() /area/shuttle/administration name = "\improper Nanotrasen Vessel" icon_state = "shuttlered" + parallax_movedir = EAST /area/shuttle/administration/centcom name = "\improper Nanotrasen Vessel Centcom" @@ -380,6 +389,7 @@ var/list/ghostteleportlocs = list() /area/shuttle/salvage/abandoned_ship name = "\improper Abandoned Ship" icon_state = "yellow" + parallax_movedir = WEST /area/shuttle/salvage/clown_asteroid name = "\improper Clown Asteroid" @@ -412,6 +422,7 @@ var/list/ghostteleportlocs = list() /area/shuttle/trade/sol name = "Sol Freighter" + parallax_movedir = EAST /area/shuttle/freegolem name = "Free Golem Ship" @@ -1859,6 +1870,7 @@ var/list/ghostteleportlocs = list() /area/shuttle/constructionsite name = "\improper Construction Site Shuttle" icon_state = "yellow" + parallax_movedir = EAST /area/shuttle/constructionsite/station name = "\improper Construction Site Shuttle" diff --git a/code/game/area/areas.dm b/code/game/area/areas.dm index 2e7448ec5c8..26dc6ddbf56 100644 --- a/code/game/area/areas.dm +++ b/code/game/area/areas.dm @@ -67,6 +67,9 @@ var/can_get_auto_cryod = TRUE var/hide_attacklogs = FALSE // For areas such as thunderdome, lavaland syndiebase, etc which generate a lot of spammy attacklogs. Reduces log priority. + var/parallax_movedir = 0 + var/moving = FALSE + /area/Initialize(mapload) GLOB.all_areas += src icon_state = "" diff --git a/code/game/area/areas/ruins/lavaland.dm b/code/game/area/areas/ruins/lavaland.dm index d72c6cc0406..ac4c41b0c42 100644 --- a/code/game/area/areas/ruins/lavaland.dm +++ b/code/game/area/areas/ruins/lavaland.dm @@ -12,6 +12,9 @@ /area/ruin/powered/snow_biodome icon_state = "dk_yellow" +/area/ruin/powered/snow_cabin + icon_state = "bar" + /area/ruin/powered/gluttony icon_state = "dk_yellow" diff --git a/code/game/atoms_movable.dm b/code/game/atoms_movable.dm index 1a23dc71070..0a22c19770b 100644 --- a/code/game/atoms_movable.dm +++ b/code/game/atoms_movable.dm @@ -26,7 +26,7 @@ var/inertia_move_delay = 5 var/moving_diagonally = 0 //0: not doing a diagonal move. 1 and 2: doing the first/second step of the diagonal move - + var/list/client_mobs_in_contents var/area/areaMaster /atom/movable/New() @@ -215,6 +215,8 @@ if(!inertia_moving) inertia_next_move = world.time + inertia_move_delay newtonian_move(Dir) + if(length(client_mobs_in_contents)) + update_parallax_contents() return TRUE // Previously known as HasEntered() diff --git a/code/game/gamemodes/blob/blobs/blob_mobs.dm b/code/game/gamemodes/blob/blobs/blob_mobs.dm index bf2143b9784..f15f1dc742c 100644 --- a/code/game/gamemodes/blob/blobs/blob_mobs.dm +++ b/code/game/gamemodes/blob/blobs/blob_mobs.dm @@ -163,10 +163,10 @@ icon_state = "blobbernaut" icon_living = "blobbernaut" icon_dead = "blobbernaut_dead" - health = 240 - maxHealth = 240 - melee_damage_lower = 20 - melee_damage_upper = 20 + health = 200 + maxHealth = 200 + melee_damage_lower = 10 + melee_damage_upper = 15 obj_damage = 60 attacktext = "hits" attack_sound = 'sound/effects/blobattack.ogg' @@ -175,18 +175,48 @@ maxbodytemp = 360 force_threshold = 10 mob_size = MOB_SIZE_LARGE - environment_smash = ENVIRONMENT_SMASH_RWALLS + environment_smash = ENVIRONMENT_SMASH_STRUCTURES pressure_resistance = 100 //100 kPa difference required to push throw_pressure_limit = 120 //120 kPa difference required to throw see_in_dark = 8 lighting_alpha = LIGHTING_PLANE_ALPHA_MOSTLY_INVISIBLE +/mob/living/simple_animal/hostile/blob/blobbernaut/Life(seconds, times_fired) + if(stat != DEAD && (getBruteLoss() || getFireLoss())) // Heal on blob structures + if(locate(/obj/structure/blob) in get_turf(src)) + adjustBruteLoss(-0.25) + adjustFireLoss(-0.25) + else + adjustBruteLoss(0.2) // If you are at full health, you won't lose health. You'll need it. However the moment anybody sneezes on you, the decaying will begin. + adjustFireLoss(0.2) + /mob/living/simple_animal/hostile/blob/blobbernaut/blob_act() return +/mob/living/simple_animal/hostile/blob/blobbernaut/New() + ..() + if(name == "blobbernaut") + name = text("blobbernaut ([rand(1, 1000)])") + /mob/living/simple_animal/hostile/blob/blobbernaut/death(gibbed) // Only execute the below if we successfully died . = ..() if(!.) return FALSE flick("blobbernaut_death", src) + +/mob/living/simple_animal/hostile/blob/blobbernaut/verb/communicate_overmind() + set category = "Blobbernaut" + set name = "Blob Telepathy" + set desc = "Send a message to the Overmind" + + if(stat != DEAD) + blob_talk() + +/mob/living/simple_animal/hostile/blob/blobbernaut/proc/blob_talk() + var/message = input(src, "Announce to the overmind", "Blob Telepathy") + var/rendered = "Blob Telepathy, [name]([overmind]) states, \"[message]\"" + if(message) + for(var/mob/M in GLOB.mob_list) + if(isovermind(M) || isobserver(M) || istype((M), /mob/living/simple_animal/hostile/blob/blobbernaut)) + M.show_message(rendered, 2) \ No newline at end of file diff --git a/code/game/gamemodes/blob/overmind.dm b/code/game/gamemodes/blob/overmind.dm index 4489aaf707b..d4d9dc15c58 100644 --- a/code/game/gamemodes/blob/overmind.dm +++ b/code/game/gamemodes/blob/overmind.dm @@ -84,7 +84,7 @@ var/rendered = "Blob Telepathy, [name]([blob_reagent_datum.name]) [verb] \"[message]\"" for(var/mob/M in GLOB.mob_list) - if(isovermind(M) || isobserver(M)) + if(isovermind(M) || isobserver(M) || istype((M), /mob/living/simple_animal/hostile/blob/blobbernaut)) M.show_message(rendered, 2) /mob/camera/blob/emote(act, m_type = 1, message = null, force) diff --git a/code/game/gamemodes/blob/powers.dm b/code/game/gamemodes/blob/powers.dm index d6d4a91cf19..dfe28336631 100644 --- a/code/game/gamemodes/blob/powers.dm +++ b/code/game/gamemodes/blob/powers.dm @@ -208,7 +208,7 @@ /mob/camera/blob/verb/create_blobbernaut() set category = "Blob" - set name = "Create Blobbernaut (20)" + set name = "Create Blobbernaut (60)" set desc = "Create a powerful blob-being, a Blobbernaut" var/turf/T = get_turf(src) @@ -225,7 +225,7 @@ to_chat(src, "Unable to use this blob, find a factory blob.") return - if(!can_buy(20)) + if(!can_buy(60)) return var/mob/living/simple_animal/hostile/blob/blobbernaut/blobber = new /mob/living/simple_animal/hostile/blob/blobbernaut (get_turf(B)) @@ -234,6 +234,18 @@ blobber.color = blob_reagent_datum.complementary_color blobber.overmind = src blob_mobs.Add(blobber) + blobber.AIStatus = AI_OFF + blobber.LoseTarget() + spawn() + var/list/candidates = pollCandidates("Do you want to play as a blobbernaut?", ROLE_BLOB, 1, 100) + if(candidates.len) + var/mob/C = pick(candidates) + if(C) + blobber.key = C.key + to_chat(blobber, "You are a blobbernaut! You must assist all blob lifeforms in their mission to consume everything!") + to_chat(blobber, "You heal while standing on blob structures, however you will decay slowly if you are damaged outside of the blob.") + if(!blobber.ckey) + blobber.AIStatus = AI_ON return diff --git a/code/game/gamemodes/changeling/changeling.dm b/code/game/gamemodes/changeling/changeling.dm index 038f331f924..713779af241 100644 --- a/code/game/gamemodes/changeling/changeling.dm +++ b/code/game/gamemodes/changeling/changeling.dm @@ -303,7 +303,7 @@ var/list/possible_changeling_IDs = list("Alpha","Beta","Gamma","Delta","Epsilon" /datum/changeling/proc/can_absorb_dna(mob/living/carbon/user, mob/living/carbon/target) if(using_stale_dna(user))//If our current DNA is the stalest, we gotta ditch it. - to_chat(user, "We have reached our capacity to store genetic information! We must transform before absorbing more.") + to_chat(user, "The DNA we are wearing is stale. Transform and try again.") return if(!target || !target.dna) diff --git a/code/game/gamemodes/changeling/powers/headcrab.dm b/code/game/gamemodes/changeling/powers/headslug.dm similarity index 88% rename from code/game/gamemodes/changeling/powers/headcrab.dm rename to code/game/gamemodes/changeling/powers/headslug.dm index b39a2bba0d5..f29ec02db54 100644 --- a/code/game/gamemodes/changeling/powers/headcrab.dm +++ b/code/game/gamemodes/changeling/powers/headslug.dm @@ -1,4 +1,4 @@ -/datum/action/changeling/headcrab +/datum/action/changeling/headslug name = "Last Resort" desc = "We sacrifice our current body in a moment of need, placing us in control of a vessel that can plant our likeness in a new host. Costs 20 chemicals." helptext = "We will be placed in control of a small, fragile creature. We may attack a corpse like this to plant an egg which will slowly mature into a new form for us." @@ -7,12 +7,12 @@ dna_cost = 1 req_human = 1 -/datum/action/changeling/headcrab/try_to_sting(mob/user, mob/target) +/datum/action/changeling/headslug/try_to_sting(mob/user, mob/target) if(alert("Are you sure you wish to do this? This action cannot be undone.",,"Yes","No")=="No") return ..() -/datum/action/changeling/headcrab/sting_action(mob/user) +/datum/action/changeling/headslug/sting_action(mob/user) var/datum/mind/M = user.mind var/list/organs = user.get_organs_zone("head", 1) @@ -33,7 +33,7 @@ S.Weaken(3) var/new_location = user.drop_location() spawn(5) // So it's not killed in explosion - var/mob/living/simple_animal/hostile/headcrab/crab = new(new_location) + var/mob/living/simple_animal/hostile/headslug/crab = new(new_location) for(var/obj/item/organ/internal/I in organs) I.loc = crab crab.origin = M diff --git a/code/game/gamemodes/cult/cult_items.dm b/code/game/gamemodes/cult/cult_items.dm index db0145bb51b..a1bec7a2a83 100644 --- a/code/game/gamemodes/cult/cult_items.dm +++ b/code/game/gamemodes/cult/cult_items.dm @@ -343,21 +343,6 @@ else to_chat(C, "The veil cannot be torn here!") -/obj/item/clothing/suit/space/eva/plasmaman/cultist - name = "plasmaman cultist armor" - icon_state = "plasmaman_cult" - item_state = "plasmaman_cult" - desc = "A bulky suit of armour, menacing with red energy. It looks like it would fit a plasmaman." - slowdown = 1 - armor = list(melee = 60, bullet = 50, laser = 30,energy = 15, bomb = 30, bio = 30, rad = 30) - -/obj/item/clothing/head/helmet/space/eva/plasmaman/cultist - name = "plasmaman cultist helmet" - icon_state = "plasmamanCult_helmet0" - base_state = "plasmamanCult_helmet" - desc = "A helmet designed by cultists. It glows menacingly with unearthly flames." - armor = list(melee = 60, bullet = 50, laser = 30,energy = 15, bomb = 30, bio = 30, rad = 30) - /obj/item/melee/cultblade/ghost name = "eldritch sword" force = 15 diff --git a/code/game/gamemodes/cult/talisman.dm b/code/game/gamemodes/cult/talisman.dm index 08633ef92f4..179425d320d 100644 --- a/code/game/gamemodes/cult/talisman.dm +++ b/code/game/gamemodes/cult/talisman.dm @@ -291,11 +291,8 @@ var/mob/living/carbon/human/H = user user.visible_message("Otherworldly armor suddenly appears on [user]!", \ "You speak the words of the talisman, arming yourself!") - if(isplasmaman(H)) - H.equip_to_slot(new /obj/item/clothing/suit/space/eva/plasmaman/cultist(H), slot_wear_suit) - H.equip_to_slot(new /obj/item/clothing/head/helmet/space/eva/plasmaman/cultist(H), slot_head) - else - H.equip_to_slot_or_del(new /obj/item/clothing/suit/hooded/cultrobes/alt(user), slot_wear_suit) + + H.equip_to_slot_or_del(new /obj/item/clothing/suit/hooded/cultrobes/alt(user), slot_wear_suit) H.equip_to_slot_or_del(new /obj/item/storage/backpack/cultpack(user), slot_back) H.equip_to_slot_or_del(new /obj/item/clothing/shoes/cult(user), slot_shoes) H.put_in_hands(new /obj/item/melee/cultblade(user)) diff --git a/code/game/gamemodes/malfunction/Malf_Modules.dm b/code/game/gamemodes/malfunction/Malf_Modules.dm index 8eeee9e4f2a..9a40cb58881 100644 --- a/code/game/gamemodes/malfunction/Malf_Modules.dm +++ b/code/game/gamemodes/malfunction/Malf_Modules.dm @@ -1,46 +1,243 @@ +//The malf AI action subtype. All malf actions are subtypes of this. +/datum/action/innate/ai + name = "AI Action" + desc = "You aren't entirely sure what this does, but it's very beepy and boopy." + background_icon_state = "bg_tech_blue" + var/mob/living/silicon/ai/owner_AI //The owner AI, so we don't have to typecast every time + var/uses //If we have multiple uses of the same power + var/auto_use_uses = TRUE //If we automatically use up uses on each activation + var/cooldown_period //If applicable, the time in deciseconds we have to wait before using any more modules + +/datum/action/innate/ai/Grant(mob/living/L) + . = ..() + if(!isAI(owner)) + WARNING("AI action [name] attempted to grant itself to non-AI mob [L.real_name] ([L.key])!") + qdel(src) + else + owner_AI = owner + +/datum/action/innate/ai/IsAvailable() + . = ..() + if(owner_AI && owner_AI.malf_cooldown > world.time) + return + +/datum/action/innate/ai/Trigger() + . = ..() + if(auto_use_uses) + adjust_uses(-1) + if(cooldown_period) + owner_AI.malf_cooldown = world.time + cooldown_period + +/datum/action/innate/ai/proc/adjust_uses(amt, silent) + uses += amt + if(!silent && uses) + to_chat(owner, "[name] now has [uses] use[uses > 1 ? "s" : ""] remaining.") + if(!uses) + if(initial(uses) > 1) //no need to tell 'em if it was one-use anyway! + to_chat(owner, "[name] has run out of uses!") + qdel(src) + +//Framework for ranged abilities that can have different effects by left-clicking stuff. +/datum/action/innate/ai/ranged + name = "Ranged AI Action" + auto_use_uses = FALSE //This is so we can do the thing and disable/enable freely without having to constantly add uses + var/obj/effect/proc_holder/ranged_ai/linked_ability //The linked proc holder that contains the actual ability code + var/linked_ability_type //The path of our linked ability + +/datum/action/innate/ai/ranged/New() + if(!linked_ability_type) + WARNING("Ranged AI action [name] attempted to spawn without a linked ability!") + qdel(src) //uh oh! + return + linked_ability = new linked_ability_type() + linked_ability.attached_action = src + ..() + +/datum/action/innate/ai/ranged/adjust_uses(amt, silent) + uses += amt + if(!silent && uses) + to_chat(owner, "[name] now has [uses] use[uses > 1 ? "s" : ""] remaining.") + if(!uses) + if(initial(uses) > 1) //no need to tell 'em if it was one-use anyway! + to_chat(owner, "[name] has run out of uses!") + Remove(owner) + QDEL_IN(src, 100) //let any active timers on us finish up + +/datum/action/innate/ai/ranged/Destroy() + QDEL_NULL(linked_ability) + return ..() + +/datum/action/innate/ai/ranged/Activate() + linked_ability.toggle(owner) + return TRUE + +//The actual ranged proc holder. +/obj/effect/proc_holder/ranged_ai + var/enable_text = "Hello World!" //Appears when the user activates the ability + var/disable_text = "Goodbye Cruel World!" //Context clues! + var/datum/action/innate/ai/ranged/attached_action + +/obj/effect/proc_holder/ranged_ai/Destroy() + QDEL_NULL(attached_action) + return ..() + +/obj/effect/proc_holder/ranged_ai/proc/toggle(mob/user) + if(active) + remove_ranged_ability(disable_text) + else + add_ranged_ability(user, enable_text) + +//The datum and interface for the malf unlock menu, which lets them choose actions to unlock. +/datum/module_picker + var/temp + var/processing_time = 50 + var/list/possible_modules + +/datum/module_picker/New() + possible_modules = list() + for(var/type in typesof(/datum/AI_Module)) + var/datum/AI_Module/AM = new type + if((AM.power_type && AM.power_type != /datum/action/innate/ai) || AM.upgrade) + possible_modules += AM + +/datum/module_picker/proc/remove_malf_verbs(mob/living/silicon/ai/AI) //Removes all malfunction-related abilities from the target AI. + for(var/datum/AI_Module/AM in possible_modules) + for(var/datum/action/A in AI.actions) + if(istype(A, initial(AM.power_type))) + qdel(A) + +/datum/module_picker/proc/use(user as mob) + var/dat + dat += {"Select use of processing time: (currently #[processing_time] left.)
+
+ Install Module:
+ The number afterwards is the amount of processing time it consumes.
"} + for(var/datum/AI_Module/large/module in possible_modules) + dat += "[module.module_name]\[?\] ([module.cost])
" + for(var/datum/AI_Module/small/module in possible_modules) + dat += "[module.module_name]\[?\] ([module.cost])
" + dat += "
" + if(temp) + dat += "[temp]" + var/datum/browser/popup = new(user, "modpicker", "Malf Module Menu", 400, 500) + popup.set_content(dat) + popup.open() + return + +/datum/module_picker/Topic(href, href_list) + ..() + + if(!isAI(usr)) + return + var/mob/living/silicon/ai/A = usr + + if(A.stat == DEAD) + to_chat(A, "You are already dead!") + return + + for(var/datum/AI_Module/AM in possible_modules) + if (href_list[AM.mod_pick_name]) + + // Cost check + if(AM.cost > processing_time) + temp = "You cannot afford this module." + break + + var/datum/action/innate/ai/action = locate(AM.power_type) in A.actions + + // Give the power and take away the money. + if(AM.upgrade) //upgrade and upgrade() are separate, be careful! + AM.upgrade(A) + possible_modules -= AM + to_chat(A, AM.unlock_text) + A.playsound_local(A, AM.unlock_sound, 50, 0) + else + if(AM.power_type) + if(!action) //Unlocking for the first time + var/datum/action/AC = new AM.power_type + AC.Grant(A) + A.current_modules += new AM.type + temp = AM.description + if(AM.one_purchase) + possible_modules -= AM + if(AM.unlock_text) + to_chat(A, AM.unlock_text) + if(AM.unlock_sound) + A.playsound_local(A, AM.unlock_sound, 50, 0) + else //Adding uses to an existing module + action.uses += initial(action.uses) + action.desc = "[initial(action.desc)] It has [action.uses] use\s remaining." + action.UpdateButtonIcon() + temp = "Additional use[action.uses > 1 ? "s" : ""] added to [action.name]!" + processing_time -= AM.cost + + if(href_list["showdesc"]) + if(AM.mod_pick_name == href_list["showdesc"]) + temp = AM.description + use(usr) + +//The base module type, which holds info about each ability. /datum/AI_Module - var/uses = 0 var/module_name var/mod_pick_name var/description = "" var/engaged = 0 var/cost = 5 - var/one_time = 0 + var/one_purchase = FALSE //If this module can only be purchased once. This always applies to upgrades, even if the variable is set to false. + var/power_type = /datum/action/innate/ai //If the module gives an active ability, use this. Mutually exclusive with upgrade. + var/upgrade //If the module gives a passive upgrade, use this. Mutually exclusive with power_type. + var/unlock_text = "Hello World!" //Text shown when an ability is unlocked + var/unlock_sound //Sound played when an ability is unlocked - var/power_type +/datum/AI_Module/proc/upgrade(mob/living/silicon/AI/AI) //Apply upgrades! + return -/datum/AI_Module/large/ - uses = 1 - -/datum/AI_Module/small/ - uses = 5 +/datum/AI_Module/large //Big, powerful stuff that can only be used once. +/datum/AI_Module/small //Weak, usually localized stuff with multiple uses. +//Doomsday Device: Starts the self-destruct timer. It can only be stopped by killing the AI completely. /datum/AI_Module/large/nuke_station module_name = "Doomsday Device" mod_pick_name = "nukestation" - description = "Activate a weapon that will disintegrate all organic life on the station after a 450 second delay." + description = "Activate a weapon that will disintegrate all organic life on the station after a 450 second delay. Can only be used while on the station, will fail if your core is moved off station or destroyed." cost = 130 - one_time = 1 + one_purchase = TRUE + power_type = /datum/action/innate/ai/nuke_station + unlock_text = "You slowly, carefully, establish a connection with the on-station self-destruct. You can now activate it at any time." + unlock_sound = 'sound/items/timer.ogg' - power_type = /mob/living/silicon/ai/proc/nuke_station +/datum/action/innate/ai/nuke_station + name = "Doomsday Device" + desc = "Activates the doomsday device. This is not reversible." + button_icon_state = "doomsday_device" + auto_use_uses = FALSE -/mob/living/silicon/ai/proc/nuke_station() - set category = "Malfunction" - set name = "Doomsday Device" +/datum/action/innate/ai/nuke_station/Activate() + var/turf/T = get_turf(owner) + if(!istype(T) || !is_station_level(T.z)) + to_chat(owner, "You cannot activate the doomsday device while off-station!") + return + if(alert(owner, "Send arming signal? (true = arm, false = cancel)", "purge_all_life()", "confirm = TRUE;", "confirm = FALSE;") != "confirm = TRUE;") + return + if(active) + return //prevent the AI from activating an already active doomsday + active = TRUE + set_us_up_the_bomb() - to_chat(src, "Nuclear device armed.") +/datum/action/innate/ai/nuke_station/proc/set_us_up_the_bomb() + to_chat(owner_AI, "Nuclear device armed.") event_announcement.Announce("Hostile runtimes detected in all station systems, please deactivate your AI to prevent possible damage to its morality core.", "Anomaly Alert", new_sound = 'sound/AI/aimalf.ogg') set_security_level("delta") - nuking = 1 - var/obj/machinery/doomsday_device/DOOM = new /obj/machinery/doomsday_device(src) - doomsday_device = DOOM - doomsday_device.start() - verbs -= /mob/living/silicon/ai/proc/nuke_station + owner_AI.nuking = TRUE + var/obj/machinery/doomsday_device/DOOM = new /obj/machinery/doomsday_device(owner_AI) + owner_AI.doomsday_device = DOOM + owner_AI.doomsday_device.start() for(var/obj/item/pinpointer/point in GLOB.pinpointer_list) for(var/mob/living/silicon/ai/A in ai_list) if((A.stat != DEAD) && A.nuking) point.the_disk = A //The pinpointer now tracks the AI core + qdel(src) /obj/machinery/doomsday_device icon = 'icons/obj/machines/nuke_terminal.dmi' @@ -113,49 +310,42 @@ to_chat(world, "The AI cleansed the station of life with the doomsday device!") SSticker.force_ending = 1 - +//AI Turret Upgrade: Increases the health and damage of all turrets. /datum/AI_Module/large/upgrade_turrets module_name = "AI Turret Upgrade" mod_pick_name = "turret" description = "Improves the power and health of all AI turrets. This effect is permanent." cost = 30 - one_time = 1 + upgrade = TRUE + unlock_text = "You establish a power diversion to your turrets, upgrading their health and damage." + unlock_sound = 'sound/items/rped.ogg' - power_type = /mob/living/silicon/ai/proc/upgrade_turrets - -/mob/living/silicon/ai/proc/upgrade_turrets() - set category = "Malfunction" - set name = "Upgrade Turrets" - - if(stat) - return - - src.verbs -= /mob/living/silicon/ai/proc/upgrade_turrets +/datum/AI_Module/large/upgrade_turrets/upgrade(mob/living/silicon/AI/AI) for(var/obj/machinery/porta_turret/turret in GLOB.machines) var/turf/T = get_turf(turret) if(is_station_level(T.z)) turret.health += 30 turret.eprojectile = /obj/item/projectile/beam/laser/heavylaser //Once you see it, you will know what it means to FEAR. turret.eshot_sound = 'sound/weapons/lasercannonfire.ogg' - to_chat(src, "Turrets upgraded.") - +//Hostile Station Lockdown: Locks, bolts, and electrifies every airlock on the station. After 90 seconds, the doors reset. /datum/AI_Module/large/lockdown module_name = "Hostile Station Lockdown" mod_pick_name = "lockdown" - description = "Overload the airlock, blast door and fire control networks, locking them down. Caution! This command also electrifies all airlocks. The networks will automatically reset after 90 seconds." + description = "Overload the airlock, blast door and fire control networks, locking them down. Caution! This command also electrifies all airlocks. The networks will automatically reset after 90 seconds, briefly \ + opening all doors on the station." cost = 30 - one_time = 1 + one_purchase = TRUE + power_type = /datum/action/innate/ai/lockdown + unlock_text = "You upload a sleeper trojan into the door control systems. You can send a signal to set it off at any time." - power_type = /mob/living/silicon/ai/proc/lockdown - -/mob/living/silicon/ai/proc/lockdown() - set category = "Malfunction" - set name = "Initiate Hostile Lockdown" - - if(stat) - return +/datum/action/innate/ai/lockdown + name = "Lockdown" + desc = "Closes, bolts, and depowers every airlock, firelock, and blast door on the station. After 90 seconds, they will reset themselves." + button_icon_state = "lockdown" + uses = 1 +/datum/action/innate/ai/lockdown/Activate() for(var/obj/machinery/door/D in GLOB.airlocks) if(!is_station_level(D.z)) continue @@ -164,342 +354,360 @@ post_status("alert", "lockdown") - verbs -= /mob/living/silicon/ai/proc/lockdown minor_announcement.Announce("Hostile runtime detected in door controllers. Isolation lockdown protocols are now in effect. Please remain calm.", "Network Alert") - to_chat(src, "Lockdown Initiated. Network reset in 90 seconds.") + to_chat(owner, "Lockdown Initiated. Network reset in 90 seconds.") spawn(900) minor_announcement.Announce("Automatic system reboot complete. Have a secure day.","Network reset:") - +//Destroy RCDs: Detonates all non-cyborg RCDs on the station. /datum/AI_Module/large/destroy_rcd module_name = "Destroy RCDs" mod_pick_name = "rcd" description = "Send a specialised pulse to detonate all hand-held and exosuit Rapid Construction Devices on the station." cost = 25 - one_time = 1 + one_purchase = TRUE + power_type = /datum/action/innate/ai/destroy_rcds + unlock_text = "After some improvisation, you rig your onboard radio to be able to send a signal to detonate all RCDs." - power_type = /mob/living/silicon/ai/proc/disable_rcd - -/mob/living/silicon/ai/proc/disable_rcd() - set category = "Malfunction" - set name = "Destroy RCDs" - set desc = "Detonate all RCDs on the station, while sparing onboard cyborg RCDs." - - if(stat || malf_cooldown > world.time) - return +/datum/action/innate/ai/destroy_rcds + name = "Destroy RCDs" + desc = "Detonate all non-cyborg RCDs on the station." + button_icon_state = "detonate_rcds" + uses = 1 + cooldown_period = 100 +/datum/action/innate/ai/destroy_rcds/Activate() for(var/obj/item/rcd/RCD in GLOB.rcd_list) if(!istype(RCD, /obj/item/rcd/borg)) //Ensures that cyborg RCDs are spared. RCD.detonate_pulse() - to_chat(src, "RCD detonation pulse emitted.") - malf_cooldown = world.time + 100 - + to_chat(owner, "RCD detonation pulse emitted.") + owner.playsound_local(owner, 'sound/machines/twobeep.ogg', 50, 0) +//Unlock Mech Domination: Unlocks the ability to dominate mechs. Big shocker, right? /datum/AI_Module/large/mecha_domination - module_name = "Viral Mech Domination" + module_name = "Unlock Mech Domination" mod_pick_name = "mechjack" - description = "Hack into a mech's onboard computer, shunting all processes into it and ejecting any occupants. Once uploaded to the mech, it is impossible to leave. \ + description = "Allows you to hack into a mech's onboard computer, shunting all processes into it and ejecting any occupants. Once uploaded to the mech, it is impossible to leave.\ Do not allow the mech to leave the station's vicinity or allow it to be destroyed." cost = 30 - one_time = 1 - - power_type = /mob/living/silicon/ai/proc/mech_takeover - -/mob/living/silicon/ai/proc/mech_takeover() - set name = "Compile Mecha Virus" - set category = "Malfunction" - set desc = "Target a mech by clicking it. Click the appropriate command when ready." - - if(stat) - return - - can_dominate_mechs = 1 //Yep. This is all it does. Honk! - to_chat(src, "Virus package compiled. Select a target mech at any time. You must remain on the station at all times. Loss of signal will result in total system lockout.") - - verbs -= /mob/living/silicon/ai/proc/mech_takeover + upgrade = TRUE + unlock_text = "Virus package compiled. Select a target mech at any time. You must remain on the station at all times. Loss of signal will result in total system lockout." + unlock_sound = 'sound/mecha/nominal.ogg' +/datum/AI_Module/large/mecha_domination/upgrade(mob/living/silicon/ai/AI) + AI.can_dominate_mechs = TRUE //Yep. This is all it does. Honk! +//Thermal Sensor Override: Unlocks the ability to disable all fire alarms from doing their job. /datum/AI_Module/large/break_fire_alarms module_name = "Thermal Sensor Override" mod_pick_name = "burnpigs" description = "Gives you the ability to override the thermal sensors on all fire alarms. This will remove their ability to scan for fire and thus their ability to alert. \ Anyone can check the fire alarm's interface and may be tipped off by its status." - one_time = 1 + one_purchase = TRUE cost = 25 + power_type = /datum/action/innate/ai/break_fire_alarms + unlock_text = "You replace the thermal sensing capabilities of all fire alarms with a manual override, allowing you to turn them off at will." - power_type = /mob/living/silicon/ai/proc/break_fire_alarms - -/mob/living/silicon/ai/proc/break_fire_alarms() - set name = "Override Thermal Sensors" - set category = "Malfunction" - - if(stat) - return +/datum/action/innate/ai/break_fire_alarms + name = "Override Thermal Sensors" + desc = "Disables the automatic temperature sensing on all fire alarms, making them effectively useless." + button_icon_state = "break_fire_alarms" + uses = 1 +/datum/action/innate/ai/break_fire_alarms/Activate() for(var/obj/machinery/firealarm/F in GLOB.machines) if(!is_station_level(F.z)) continue - F.emagged = 1 - to_chat(src, "All thermal sensors on the station have been disabled. Fire alerts will no longer be recognized.") - verbs -= /mob/living/silicon/ai/proc/break_fire_alarms - + F.emagged = TRUE + to_chat(owner, "All thermal sensors on the station have been disabled. Fire alerts will no longer be recognized.") + owner.playsound_local(owner, 'sound/machines/terminal_off.ogg', 50, 0) +//Air Alarm Safety Override: Unlocks the ability to enable flooding on all air alarms. /datum/AI_Module/large/break_air_alarms module_name = "Air Alarm Safety Override" mod_pick_name = "allow_flooding" description = "Gives you the ability to disable safeties on all air alarms. This will allow you to use the environmental mode Flood, which disables scrubbers as well as pressure checks on vents. \ Anyone can check the air alarm's interface and may be tipped off by their nonfunctionality." - one_time = 1 + one_purchase = TRUE cost = 50 + power_type = /datum/action/innate/ai/break_air_alarms + unlock_text = "You remove the safety overrides on all air alarms, but you leave the confirm prompts open. You can hit 'Yes' at any time... you bastard." - power_type = /mob/living/silicon/ai/proc/break_air_alarms - -/mob/living/silicon/ai/proc/break_air_alarms() - set name = "Disable Air Alarm Safeties" - set category = "Malfunction" - - if(stat) - return +/datum/action/innate/ai/break_air_alarms + name = "Override Air Alarm Safeties" + desc = "Enables the Flood setting on all air alarms." + button_icon_state = "break_air_alarms" + uses = 1 +/datum/action/innate/ai/break_air_alarms/Activate() for(var/obj/machinery/alarm/AA in GLOB.machines) if(!is_station_level(AA.z)) continue - AA.emagged = 1 - to_chat(src, "All air alarm safeties on the station have been overriden. Air alarms may now use the Flood environmental mode.") - verbs -= /mob/living/silicon/ai/proc/break_air_alarms - + AA.emagged = TRUE + to_chat(owner, "All air alarm safeties on the station have been overriden. Air alarms may now use the Flood environmental mode.") + owner.playsound_local(owner, 'sound/machines/terminal_off.ogg', 50, 0) +//Overload Machine: Allows the AI to overload a machine, detonating it after a delay. Two uses per purchase. /datum/AI_Module/small/overload_machine module_name = "Machine Overload" mod_pick_name = "overload" - description = "Overloads an electrical machine, causing a small explosion. 2 uses." - uses = 2 + description = "Overheats an electrical machine, causing a small explosion and destroying it. Two uses per purchase." cost = 20 + power_type = /datum/action/innate/ai/overload_machine + unlock_text = "You enable the ability for the station's APCs to direct intense energy into machinery." - power_type = /mob/living/silicon/ai/proc/overload_machine +/datum/action/innate/ai/overload_machine + name = "Overload Machine" + desc = "Overheats a machine, causing a small explosion after a short time." + button_icon_state = "overload_machine" + uses = 2 + auto_use_uses = FALSE -/mob/living/silicon/ai/proc/overload_machine(obj/machinery/M in GLOB.machines) - set name = "Overload Machine" - set category = "Malfunction" +/datum/action/innate/ai/overload_machine/New() + ..() + desc = "[desc] It has [uses] use\s remaining." + button.desc = desc - if(stat) +/datum/action/innate/ai/overload_machine/Activate() + var/select = input("Choose a device to overload", "Overload Machine", null, null) as null|anything in GLOB.machines + if(!select) return + var/obj/machinery/M = select if(istype(M, /obj/machinery)) - for(var/datum/AI_Module/small/overload_machine/overload in current_modules) - if(overload.uses > 0) - overload.uses -- - audible_message("You hear a loud electrical buzzing sound!") - to_chat(src, "Overloading machine circuitry...") - spawn(50) - if(M) - explosion(get_turf(M), 0,1,1,0) - qdel(M) - else - to_chat(src, "Out of uses.") + if(uses > 0) + adjust_uses(-1) + if(src && uses) //Not sure if not having src here would cause a runtime, so it's here to be safe + desc = "[initial(desc)] It has [uses] use\s remaining." + UpdateButtonIcon() + M.audible_message("You hear a loud electrical buzzing sound!") + to_chat(owner, "Overloading machine circuitry...") + spawn(50) + if(M) + explosion(get_turf(M), 0,1,1,0) + qdel(M) + else + to_chat(owner, "Out of uses.") else - to_chat(src, "That's not a machine.") - + to_chat(owner, "That's not a machine.") + return +//Override Machine: Allows the AI to override a machine, animating it into an angry, living version of itself. /datum/AI_Module/small/override_machine module_name = "Machine Override" mod_pick_name = "override" - description = "Overrides a machine's programming, causing it to rise up and attack everyone except other machines. 4 uses." - uses = 4 + description = "Overrides a machine's programming, causing it to rise up and attack everyone except other machines. Four uses." cost = 30 + power_type = /datum/action/innate/ai/override_machine + unlock_text = "You procure a virus from the Space Dark Web and prepare to distribute it to the station's machines." - power_type = /mob/living/silicon/ai/proc/override_machine +/datum/action/innate/ai/override_machine + name = "Override Machine" + desc = "Animates a targeted machine, causing it to attack anyone nearby." + button_icon_state = "override_machine" + uses = 4 + auto_use_uses = FALSE +/datum/action/innate/ai/override_machine/New() + ..() + desc = "[desc] It has [uses] use\s remaining." + button.desc = desc -/mob/living/silicon/ai/proc/override_machine(obj/machinery/M in GLOB.machines) - set name = "Override Machine" - set category = "Malfunction" - - if(stat) +/datum/action/innate/ai/override_machine/Activate() + var/select = input("Choose a device to override", "Override Machine", null, null) as null|anything in GLOB.machines + if(!select) return - if (istype(M, /obj/machinery)) + var/obj/machinery/M = select + if(istype(M, /obj/machinery)) if(!M.can_be_overridden()) - to_chat(src, "Can't override this device.") - for(var/datum/AI_Module/small/override_machine/override in current_modules) - if(override.uses > 0) - override.uses -- - audible_message("You hear a loud electrical buzzing sound!") - to_chat(src, "Reprogramming machine behaviour...") - spawn(50) - if(M && !QDELETED(M)) - new /mob/living/simple_animal/hostile/mimic/copy/machine(get_turf(M), M, src, 1) - else - to_chat(src, "Out of uses.") + to_chat(owner, "Can't override this device.") + return + else if(uses > 0) + adjust_uses(-1) + if(src && uses) //Not sure if not having src here would cause a runtime, so it's here to be safe + desc = "[initial(desc)] It has [uses] use\s remaining." + UpdateButtonIcon() + M.audible_message("You hear a loud electrical buzzing sound!") + to_chat(owner, "Reprogramming machine behaviour...") + spawn(50) + if(M && !QDELETED(M)) + new /mob/living/simple_animal/hostile/mimic/copy/machine(get_turf(M), M, src, 1) + else + to_chat(owner, "Out of uses.") else - to_chat(src, "That's not a machine.") - + to_chat(owner, "That's not a machine.") + return +//Robotic Factory: Places a large machine that converts humans that go through it into cyborgs. Unlocking this ability removes shunting. /datum/AI_Module/large/place_cyborg_transformer module_name = "Robotic Factory (Removes Shunting)" mod_pick_name = "cyborgtransformer" description = "Build a machine anywhere, using expensive nanomachines, that can convert a living human into a loyal cyborg slave when placed inside." cost = 100 - power_type = /mob/living/silicon/ai/proc/place_transformer - var/list/turfOverlays = list() + one_purchase = TRUE + power_type = /datum/action/innate/ai/place_transformer + unlock_text = "You prepare a robotics factory for deployment." + unlock_sound = 'sound/machines/ping.ogg' -/datum/AI_Module/large/place_cyborg_transformer/New() - for(var/i=0;i<3;i++) - var/image/I = image("icon"='icons/turf/overlays.dmi') - turfOverlays += I +/datum/action/innate/ai/place_transformer + name = "Place Robotics Factory" + desc = "Places a machine that converts humans into cyborgs. Conveyor belts included!" + button_icon_state = "robotic_factory" + uses = 1 + auto_use_uses = FALSE //So we can attempt multiple times + var/list/turfOverlays + +/datum/action/innate/ai/place_transformer/New() ..() + for(var/i in 1 to 3) + var/image/I = image("icon"='icons/turf/overlays.dmi') + LAZYADD(turfOverlays, I) -/mob/living/silicon/ai/proc/place_transformer() - set name = "Place Robotic Factory" - set category = "Malfunction" - - if(!canPlaceTransformer()) +/datum/action/innate/ai/place_transformer/Activate() + if(!owner_AI.can_place_transformer(src)) return - - var/sure = alert(src, "Are you sure you want to place the machine here?", "Are you sure?", "Yes", "No") - if(sure == "Yes") - if(!canPlaceTransformer()) - return - var/turf/T = get_turf(eyeobj) - new /obj/machinery/transformer/conveyor(T) - playsound(T, 'sound/effects/phasein.ogg', 100, 1) - var/datum/AI_Module/large/place_cyborg_transformer/PCT = locate() in current_modules - PCT.uses -- - can_shunt = 0 - to_chat(src, "You cannot shunt anymore.") - -/mob/living/silicon/ai/proc/canPlaceTransformer() - if(!eyeobj || !isturf(src.loc)) + active = TRUE + if(alert(owner, "Are you sure you want to place the machine here?", "Are you sure?", "Yes", "No") == "No") + active = FALSE return - var/datum/AI_Module/large/place_cyborg_transformer/PCT = locate() in current_modules - if(!PCT || PCT.uses < 1) - alert(src, "Out of uses.") + if(!owner_AI.can_place_transformer(src)) + active = FALSE + return + var/turf/T = get_turf(owner_AI.eyeobj) + new /obj/machinery/transformer/conveyor(T) + playsound(T, 'sound/effects/phasein.ogg', 100, 1) + owner_AI.can_shunt = FALSE + to_chat(owner, "You are no longer able to shunt your core to APCs.") + adjust_uses(-1) + +/mob/living/silicon/ai/proc/remove_transformer_image(client/C, image/I, turf/T) + if(C && I.loc == T) + C.images -= I + +/mob/living/silicon/ai/proc/can_place_transformer(datum/action/innate/ai/place_transformer/action) + if(!eyeobj || !isturf(loc) || incapacitated() || !action) return var/turf/middle = get_turf(eyeobj) var/list/turfs = list(middle, locate(middle.x - 1, middle.y, middle.z), locate(middle.x + 1, middle.y, middle.z)) - var/alert_msg = "There isn't enough room. Make sure you are placing the machine in a clear area and on a floor." - var/success = 1 - if(turfs.len == 3) - for(var/n=1;n<4,n++) - var/fail - var/turf/T = turfs[n] - if(!istype(T, /turf/simulated/floor)) - fail = 1 - var/datum/camerachunk/C = cameranet.getCameraChunk(T.x, T.y, T.z) - if(!C.visibleTurfs[T]) - alert_msg = "We cannot get camera vision of this location." - fail = 1 - for(var/atom/movable/AM in T.contents) - if(AM.density) - fail = 1 - var/image/I = PCT.turfOverlays[n] - I.loc = T - client.images += I - if(fail) - success = 0 - I.icon_state = "redOverlay" - else - I.icon_state = "greenOverlay" - spawn(30) - if(client && (I.loc == T)) - client.images -= I - if(success) - return 1 - alert(src, alert_msg) - + var/alert_msg = "There isn't enough room! Make sure you are placing the machine in a clear area and on a floor." + var/success = TRUE + for(var/n in 1 to 3) //We have to do this instead of iterating normally because of how overlay images are handled + var/turf/T = turfs[n] + if(!isfloorturf(T)) + success = FALSE + var/datum/camerachunk/C = cameranet.getCameraChunk(T.x, T.y, T.z) + if(!C.visibleTurfs[T]) + alert_msg = "You don't have camera vision of this location!" + success = FALSE + for(var/atom/movable/AM in T.contents) + if(AM.density) + alert_msg = "That area must be clear of objects!" + success = FALSE + var/image/I = action.turfOverlays[n] + I.loc = T + client.images += I + I.icon_state = "[success ? "green" : "red"]Overlay" //greenOverlay and redOverlay for success and failure respectively + addtimer(CALLBACK(src, .proc/remove_transformer_image, client, I, T), 30) + if(!success) + to_chat(src, "[alert_msg]") + return success +//Blackout: Overloads a random number of lights across the station. Three uses. /datum/AI_Module/small/blackout module_name = "Blackout" mod_pick_name = "blackout" - description = "Attempts to overload the lighting circuits on the station, destroying some bulbs. 3 uses." - uses = 3 + description = "Attempts to overload the lighting circuits on the station, destroying some bulbs. Three uses." cost = 15 + power_type = /datum/action/innate/ai/blackout + unlock_text = "You hook into the powernet and route bonus power towards the station's lighting." - power_type = /mob/living/silicon/ai/proc/blackout +/datum/action/innate/ai/blackout + name = "Blackout" + desc = "Overloads random lights across the station." + button_icon_state = "blackout" + uses = 3 + auto_use_uses = FALSE -/mob/living/silicon/ai/proc/blackout() - set category = "Malfunction" - set name = "Blackout" +/datum/action/innate/ai/blackout/New() + ..() + desc = "[desc] It has [uses] use\s remaining." + button.desc = desc - if(stat) - return - - for(var/datum/AI_Module/small/blackout/blackout in current_modules) - if(blackout.uses > 0) - blackout.uses -- - for(var/obj/machinery/power/apc/apc in GLOB.apcs) - if(prob(30*apc.overload)) - apc.overload_lighting() - else - apc.overload++ - to_chat(src, "Overcurrent applied to the powernet.") +/datum/action/innate/ai/blackout/Activate() + for(var/obj/machinery/power/apc/apc in GLOB.apcs) + if(prob(30 * apc.overload)) + apc.overload_lighting() else - to_chat(src, "Out of uses.") - + apc.overload++ + to_chat(owner, "Overcurrent applied to the powernet.") + owner.playsound_local(owner, "sparks", 50, 0) + adjust_uses(-1) + if(src && uses) //Not sure if not having src here would cause a runtime, so it's here to be safe + desc = "[initial(desc)] It has [uses] use\s remaining." + UpdateButtonIcon() +//Reactivate Camera Network: Reactivates up to 30 cameras across the station. /datum/AI_Module/small/reactivate_cameras module_name = "Reactivate Camera Network" mod_pick_name = "recam" description = "Runs a network-wide diagnostic on the camera network, resetting focus and re-routing power to failed cameras. Can be used to repair up to 30 cameras." - uses = 30 cost = 10 - one_time = 1 + one_purchase = TRUE + power_type = /datum/action/innate/ai/reactivate_cameras + unlock_text = "You deploy nanomachines to the cameranet." - power_type = /mob/living/silicon/ai/proc/reactivate_cameras +/datum/action/innate/ai/reactivate_cameras + name = "Reactivate Cameras" + desc = "Reactivates disabled cameras across the station; remaining uses can be used later." + button_icon_state = "reactivate_cameras" + uses = 30 + auto_use_uses = FALSE + cooldown_period = 30 -/mob/living/silicon/ai/proc/reactivate_cameras() - set name = "Reactivate Cameranet" - set category = "Malfunction" - - if(stat || malf_cooldown > world.time) - return - var/fixedcams = 0 //Tells the AI how many cams it fixed. Stats are fun. - - for(var/datum/AI_Module/small/reactivate_cameras/camera in current_modules) - for(var/obj/machinery/camera/C in cameranet.cameras) - var/initial_range = initial(C.view_range) //To prevent calling the proc twice - if(camera.uses > 0) - if(!C.status) - C.toggle_cam(src, 1) //Reactivates the camera based on status. Badly named proc. - fixedcams++ - camera.uses-- - if(C.view_range != initial_range) - C.view_range = initial_range //Fixes cameras with bad focus. - camera.uses-- - fixedcams++ - //If a camera is both deactivated and has bad focus, it will cost two uses to fully fix! - else - to_chat(src, "Out of uses.") - verbs -= /mob/living/silicon/ai/proc/reactivate_cameras //It is useless now, clean it up. - break - to_chat(src, "Diagnostic complete! Operations completed: [fixedcams].") - - malf_cooldown = world.time + 30 +/datum/action/innate/ai/reactivate_cameras/New() + ..() + desc = "[desc] It has [uses] use\s remaining." + button.desc = desc +/datum/action/innate/ai/reactivate_cameras/Activate() + var/fixed_cameras = 0 + for(var/V in cameranet.cameras) + if(!uses) + break + var/obj/machinery/camera/C = V + if(!C.status || C.view_range != initial(C.view_range)) + C.toggle_cam(owner_AI, 0) //Reactivates the camera based on status. Badly named proc. + C.view_range = initial(C.view_range) + fixed_cameras++ + uses-- //Not adjust_uses() so it doesn't automatically delete or show a message + to_chat(owner, "Diagnostic complete! Cameras reactivated: [fixed_cameras]. Reactivations remaining: [uses].") + owner.playsound_local(owner, 'sound/items/wirecutter.ogg', 50, 0) + adjust_uses(0, TRUE) //Checks the uses remaining + if(src && uses) //Not sure if not having src here would cause a runtime, so it's here to be safe + desc = "[initial(desc)] It has [uses] use\s remaining." + UpdateButtonIcon() +//Upgrade Camera Network: EMP-proofs all cameras, in addition to giving them X-ray vision. /datum/AI_Module/large/upgrade_cameras module_name = "Upgrade Camera Network" mod_pick_name = "upgradecam" - description = "Install broad-spectrum scanning and electrical redundancy firmware to the camera network, enabling EMP-Proofing and light-amplified X-ray vision." //I <3 pointless technobabble + description = "Install broad-spectrum scanning and electrical redundancy firmware to the camera network, enabling EMP-proofing and light-amplified X-ray vision." //I <3 pointless technobabble //This used to have motion sensing as well, but testing quickly revealed that giving it to the whole cameranet is PURE HORROR. - one_time = 1 + one_purchase = TRUE cost = 35 //Decent price for omniscience! + upgrade = TRUE + unlock_text = "OTA firmware distribution complete! Cameras upgraded: CAMSUPGRADED. Light amplification system online." + unlock_sound = 'sound/items/rped.ogg' - power_type = /mob/living/silicon/ai/proc/upgrade_cameras +/datum/AI_Module/large/upgrade_cameras/upgrade(mob/living/silicon/ai/AI) + AI.lighting_alpha = LIGHTING_PLANE_ALPHA_MOSTLY_INVISIBLE //Night-vision, without which X-ray would be very limited in power. + AI.update_sight() + var/upgraded_cameras = 0 -/mob/living/silicon/ai/proc/upgrade_cameras() - set name = "Upgrade Cameranet" - set category = "Malfunction" - - if(stat) - return - - var/upgradedcams = 0 - RegisterSignal(src, COMSIG_MOB_UPDATE_SIGHT, .proc/update_upgraded_cameras_sight) //Makes sure the AI has night vision, without which X-ray would be very limited in power. - update_sight() - - for(var/obj/machinery/camera/C in cameranet.cameras) + for(var/V in cameranet.cameras) + var/obj/machinery/camera/C = V if(C.assembly) var/upgraded = FALSE @@ -514,107 +722,21 @@ upgraded = TRUE if(upgraded) - upgradedcams++ + upgraded_cameras++ - to_chat(src, "OTA firmware distribution complete! Cameras upgraded: [upgradedcams]. Light amplification system online.") - verbs -= /mob/living/silicon/ai/proc/upgrade_cameras - -/mob/living/silicon/ai/proc/update_upgraded_cameras_sight() - lighting_alpha = LIGHTING_PLANE_ALPHA_MOSTLY_INVISIBLE + unlock_text = replacetext(unlock_text, "CAMSUPGRADED", "[upgraded_cameras]") //This works, since unlock text is called after upgrade() /datum/AI_Module/large/eavesdrop module_name = "Enhanced Surveillance" mod_pick_name = "eavesdrop" description = "Via a combination of hidden microphones and lip reading software, you are able to use your cameras to listen in on conversations." cost = 30 - one_time = 1 + one_purchase = TRUE + upgrade = TRUE + unlock_text = "OTA firmware distribution complete! Cameras upgraded: Enhanced surveillance package online." + unlock_sound = 'sound/items/rped.ogg' - power_type = /mob/living/silicon/ai/proc/surveillance +/datum/AI_Module/large/eavesdrop/upgrade(mob/living/silicon/ai/AI) + if(AI.eyeobj) + AI.eyeobj.relay_speech = TRUE -/mob/living/silicon/ai/proc/surveillance() - set category = "Malfunction" - set name = "Enhanced Surveillance" - - if(eyeobj) - eyeobj.relay_speech = 1 - to_chat(src, "OTA firmware distribution complete! Cameras upgraded: Enhanced surveillance package online.") - verbs -= /mob/living/silicon/ai/proc/surveillance - - -/datum/module_picker - var/temp = null - var/processing_time = 50 - var/list/possible_modules = list() - -/datum/module_picker/New() - for(var/type in subtypesof(/datum/AI_Module)) - var/datum/AI_Module/AM = new type - if(AM.power_type != null) - src.possible_modules += AM - -/datum/module_picker/proc/remove_verbs(var/mob/living/silicon/ai/A) - - for(var/datum/AI_Module/AM in possible_modules) - A.verbs.Remove(AM.power_type) - - -/datum/module_picker/proc/use(user as mob) - var/dat - dat += {"Select use of processing time: (currently #[src.processing_time] left.)
-
- Install Module:
- The number afterwards is the amount of processing time it consumes.
"} - for(var/datum/AI_Module/large/module in src.possible_modules) - dat += "[module.module_name]\[?\] ([module.cost])
" - for(var/datum/AI_Module/small/module in src.possible_modules) - dat += "[module.module_name]\[?\] ([module.cost])
" - dat += "
" - if(src.temp) - dat += "[src.temp]" - var/datum/browser/popup = new(user, "modpicker", "Malf Module Menu") - popup.set_content(dat) - popup.open() - return - -/datum/module_picker/Topic(href, href_list) - ..() - - if(!isAI(usr)) - return - var/mob/living/silicon/ai/A = usr - - if(A.stat == DEAD) - to_chat(A, "You are already dead!") //Omae Wa Mou Shindeiru - return - - for(var/datum/AI_Module/AM in possible_modules) - if(href_list[AM.mod_pick_name]) - - // Cost check - if(AM.cost > src.processing_time) - temp = "You cannot afford this module." - break - - // Add new uses if we can, and it is allowed. - var/datum/AI_Module/already_AM = locate(AM.type) in A.current_modules - if(already_AM) - if(!AM.one_time) - already_AM.uses += AM.uses - src.processing_time -= AM.cost - temp = "Additional use added to [already_AM.module_name]" - break - else - temp = "This module is only needed once." - break - - // Give the power and take away the money. - A.view_core() //A BYOND bug requires you to be viewing your core before your verbs update - A.verbs += AM.power_type - A.current_modules += new AM.type - temp = AM.description - src.processing_time -= AM.cost - - if(href_list["showdesc"]) - if(AM.mod_pick_name == href_list["showdesc"]) - temp = AM.description - use(usr) diff --git a/code/game/gamemodes/miniantags/slaughter/slaughter.dm b/code/game/gamemodes/miniantags/slaughter/slaughter.dm index 09d5fecb8a2..4a8f215ee47 100644 --- a/code/game/gamemodes/miniantags/slaughter/slaughter.dm +++ b/code/game/gamemodes/miniantags/slaughter/slaughter.dm @@ -290,10 +290,10 @@ emote_hear = list("gaffaws", "laughs") response_help = "hugs" attacktext = "wildly tickles" - maxHealth = 150 - health = 150 - melee_damage_lower = 20 - melee_damage_upper = 20 + maxHealth = 175 + health = 175 + melee_damage_lower = 25 + melee_damage_upper = 25 attack_sound = 'sound/items/bikehorn.ogg' feast_sound = 'sound/spookoween/scary_horn2.ogg' diff --git a/code/game/gamemodes/nuclear/nuclear.dm b/code/game/gamemodes/nuclear/nuclear.dm index cf808f3709d..2d7c9cff015 100644 --- a/code/game/gamemodes/nuclear/nuclear.dm +++ b/code/game/gamemodes/nuclear/nuclear.dm @@ -291,11 +291,9 @@ proc/issyndicate(mob/living/M as mob) if("Plasmaman") synd_mob.equip_to_slot_or_del(new /obj/item/clothing/mask/gas/syndicate(synd_mob), slot_wear_mask) - synd_mob.equip_to_slot(new /obj/item/clothing/suit/space/eva/plasmaman/nuclear(synd_mob), slot_wear_suit) - synd_mob.equip_to_slot(new /obj/item/clothing/head/helmet/space/eva/plasmaman/nuclear(synd_mob), slot_head) synd_mob.equip_or_collect(new /obj/item/tank/plasma/plasmaman(synd_mob), slot_s_store) - synd_mob.equip_or_collect(new /obj/item/plasmensuit_cartridge(synd_mob), slot_in_backpack) - synd_mob.equip_or_collect(new /obj/item/plasmensuit_cartridge(synd_mob), slot_in_backpack) + synd_mob.equip_or_collect(new /obj/item/extinguisher_refill(synd_mob), slot_in_backpack) + synd_mob.equip_or_collect(new /obj/item/extinguisher_refill(synd_mob), slot_in_backpack) synd_mob.internal = synd_mob.get_item_by_slot(slot_s_store) synd_mob.update_action_buttons_icon() diff --git a/code/game/gamemodes/nuclear/nuclearbomb.dm b/code/game/gamemodes/nuclear/nuclearbomb.dm index 09de3f917bd..b11c43299ad 100644 --- a/code/game/gamemodes/nuclear/nuclearbomb.dm +++ b/code/game/gamemodes/nuclear/nuclearbomb.dm @@ -76,14 +76,19 @@ var/bomb_set if(panel_open && (istype(O, /obj/item/multitool) || istype(O, /obj/item/wirecutters))) return attack_hand(user) - - if(extended) - if(istype(O, /obj/item/disk/nuclear)) - usr.drop_item() - O.loc = src + + if(istype(O, /obj/item/disk/nuclear)) + if(extended) + if(!user.drop_item()) + to_chat(user, "\The [O] is stuck to your hand!") + return + O.forceMove(src) auth = O add_fingerprint(user) return attack_hand(user) + else + to_chat(user, "You need to deploy \the [src] first. Right click on the sprite, select 'Make Deployable' then click on \the [src] with an empty hand.") + return if(anchored) switch(removal_stage) diff --git a/code/game/gamemodes/vampire/vampire.dm b/code/game/gamemodes/vampire/vampire.dm index 5fc01686200..d696543cbdf 100644 --- a/code/game/gamemodes/vampire/vampire.dm +++ b/code/game/gamemodes/vampire/vampire.dm @@ -297,23 +297,23 @@ You are weak to holy things and starlight. Don't go into space and avoid the Cha to_chat(owner, "They've got no blood left to give.") break if(H.stat < DEAD) - if(!issmall(H) || H.ckey) + if(H.ckey || H.player_ghosted) //Requires ckey regardless if monkey or humanoid, or the body has been ghosted before it died blood = min(20, H.blood_volume) // if they have less than 20 blood, give them the remnant else they get 20 blood bloodtotal += blood / 2 //divide by 2 to counted the double suction since removing cloneloss -Melandor0 bloodusable += blood / 2 else - if(!issmall(H) || H.ckey) + if(H.ckey || H.player_ghosted) blood = min(5, H.blood_volume) // The dead only give 5 blood bloodtotal += blood if(old_bloodtotal != bloodtotal) - if(!issmall(H) || H.ckey) // not small OR has a ckey, monkeys with ckeys can be sucked, humanized monkeys can be sucked monkeys without ckeys cannot be sucked + if(H.ckey || H.player_ghosted) // Requires ckey regardless if monkey or human, and has not ghosted, otherwise no power to_chat(owner, "You have accumulated [bloodtotal] [bloodtotal > 1 ? "units" : "unit"] of blood[bloodusable != old_bloodusable ? ", and have [bloodusable] left to use" : ""].") check_vampire_upgrade() H.blood_volume = max(H.blood_volume - 25, 0) if(ishuman(owner)) var/mob/living/carbon/human/V = owner - if(issmall(H) && !H.ckey) - to_chat(V, "Feeding on [H] reduces your hunger, but you get no usable blood from it.") + if(!H.ckey && !H.player_ghosted)//Only runs if there is no ckey and the body has not being ghosted while alive + to_chat(V, "Feeding on [H] reduces your thirst, but you get no usable blood from them.") V.nutrition = min(NUTRITION_LEVEL_WELL_FED, V.nutrition + 5) else V.nutrition = min(NUTRITION_LEVEL_WELL_FED, V.nutrition + (blood / 2)) @@ -402,7 +402,14 @@ You are weak to holy things and starlight. Don't go into space and avoid the Cha if(T.density) return - vamp_burn(1) + if(bloodusable >= 10) //burn through your blood to tank the light for a little while + to_chat(owner, "The starlight saps your strength!") + bloodusable -= 10 + vamp_burn(10) + else //You're in trouble, get out of the sun NOW + to_chat(owner, "Your body is turning to ash, get out of the light now!") + owner.adjustCloneLoss(10) //I'm melting! + vamp_burn(85) /datum/vampire/proc/handle_vampire() if(owner.hud_used) @@ -419,7 +426,7 @@ You are weak to holy things and starlight. Don't go into space and avoid the Cha if(istype(owner.loc, /turf/space)) check_sun() if(istype(owner.loc.loc, /area/chapel) && !get_ability(/datum/vampire_passive/full)) - vamp_burn(0) + vamp_burn(7) nullified = max(0, nullified - 1) /datum/vampire/proc/handle_vampire_cloak() @@ -442,8 +449,7 @@ You are weak to holy things and starlight. Don't go into space and avoid the Cha else owner.alpha = round((255 * 0.80)) -/datum/vampire/proc/vamp_burn(severe_burn) - var/burn_chance = severe_burn ? 35 : 8 +/datum/vampire/proc/vamp_burn(burn_chance) if(prob(burn_chance) && owner.health >= 50) switch(owner.health) if(75 to 100) diff --git a/code/game/gamemodes/wizard/rightandwrong.dm b/code/game/gamemodes/wizard/rightandwrong.dm index deb054f6d3e..e69a4b7ec79 100644 --- a/code/game/gamemodes/wizard/rightandwrong.dm +++ b/code/game/gamemodes/wizard/rightandwrong.dm @@ -139,7 +139,6 @@ new /obj/item/gun/magic/staff/door(get_turf(H)) if("armor") new /obj/item/clothing/suit/space/hardsuit/wizard(get_turf(H)) - new /obj/item/clothing/head/helmet/space/hardsuit/wizard(get_turf(H)) if("scrying") new /obj/item/scrying(get_turf(H)) if(!(XRAY in H.mutations)) diff --git a/code/game/gamemodes/wizard/spellbook.dm b/code/game/gamemodes/wizard/spellbook.dm index 6f96d4c22e2..50a427ae70c 100644 --- a/code/game/gamemodes/wizard/spellbook.dm +++ b/code/game/gamemodes/wizard/spellbook.dm @@ -12,7 +12,7 @@ var/buy_word = "Learn" var/limit //used to prevent a spellbook_entry from being bought more than X times with one wizard spellbook -/datum/spellbook_entry/proc/IsAvailible() // For config prefs / gamemode restrictions - these are round applied +/datum/spellbook_entry/proc/IsSpellAvailable() // For config prefs / gamemode restrictions - these are round applied return 1 /datum/spellbook_entry/proc/CanBuy(var/mob/living/carbon/human/user,var/obj/item/spellbook/book) // Specific circumstances if(book.uses" return dat -/datum/spellbook_entry/noclothes - name = "Remove Clothes Requirement" - spell_type = /obj/effect/proc_holder/spell/noclothes - log_name = "NC" - category = "Defensive" +//Main category - Spells +//Offensive +/datum/spellbook_entry/blind + name = "Blind" + spell_type = /obj/effect/proc_holder/spell/targeted/trigger/blind + log_name = "BD" + category = "Offensive" + cost = 1 -/datum/spellbook_entry/fireball - name = "Fireball" - spell_type = /obj/effect/proc_holder/spell/fireball - log_name = "FB" +/datum/spellbook_entry/lightningbolt + name = "Lightning Bolt" + spell_type = /obj/effect/proc_holder/spell/targeted/lightning + log_name = "LB" + category = "Offensive" + cost = 1 -/datum/spellbook_entry/rod_form - name = "Rod Form" - spell_type = /obj/effect/proc_holder/spell/targeted/rod_form - log_name = "RF" +/datum/spellbook_entry/cluwne + name = "Curse of the Cluwne" + spell_type = /obj/effect/proc_holder/spell/targeted/touch/cluwne + log_name = "CC" + category = "Offensive" -/datum/spellbook_entry/magicm - name = "Magic Missile" - spell_type = /obj/effect/proc_holder/spell/targeted/projectile/magic_missile - log_name = "MM" - category = "Defensive" +/datum/spellbook_entry/horseman + name = "Curse of the Horseman" + spell_type = /obj/effect/proc_holder/spell/targeted/horsemask + log_name = "HH" + category = "Offensive" /datum/spellbook_entry/disintegrate name = "Disintegrate" spell_type = /obj/effect/proc_holder/spell/targeted/touch/disintegrate log_name = "DG" + category = "Offensive" +/datum/spellbook_entry/fireball + name = "Fireball" + spell_type = /obj/effect/proc_holder/spell/fireball + log_name = "FB" + category = "Offensive" + +/datum/spellbook_entry/fleshtostone + name = "Flesh to Stone" + spell_type = /obj/effect/proc_holder/spell/targeted/touch/flesh_to_stone + log_name = "FS" + category = "Offensive" + +/datum/spellbook_entry/mutate + name = "Mutate" + spell_type = /obj/effect/proc_holder/spell/targeted/genetic/mutate + log_name = "MU" + category = "Offensive" + +/datum/spellbook_entry/rod_form + name = "Rod Form" + spell_type = /obj/effect/proc_holder/spell/targeted/rod_form + log_name = "RF" + category = "Offensive" + +/datum/spellbook_entry/infinite_guns + name = "Lesser Summon Guns" + spell_type = /obj/effect/proc_holder/spell/targeted/infinite_guns + log_name = "IG" + category = "Offensive" + cost = 4 + +//Defensive /datum/spellbook_entry/disabletech name = "Disable Tech" spell_type = /obj/effect/proc_holder/spell/targeted/emplosion/disable_tech @@ -128,37 +167,6 @@ category = "Defensive" cost = 1 -/datum/spellbook_entry/repulse - name = "Repulse" - spell_type = /obj/effect/proc_holder/spell/aoe_turf/repulse - log_name = "RP" - category = "Defensive" - -/datum/spellbook_entry/timestop - name = "Time Stop" - spell_type = /obj/effect/proc_holder/spell/aoe_turf/conjure/timestop - log_name = "TS" - category = "Defensive" - -/datum/spellbook_entry/smoke - name = "Smoke" - spell_type = /obj/effect/proc_holder/spell/targeted/smoke - log_name = "SM" - category = "Defensive" - cost = 1 - -/datum/spellbook_entry/blind - name = "Blind" - spell_type = /obj/effect/proc_holder/spell/targeted/trigger/blind - log_name = "BD" - cost = 1 - -/datum/spellbook_entry/mindswap - name = "Mindswap" - spell_type = /obj/effect/proc_holder/spell/targeted/mind_transfer - log_name = "MT" - category = "Mobility" - /datum/spellbook_entry/forcewall name = "Force Wall" spell_type = /obj/effect/proc_holder/spell/targeted/forcewall @@ -173,54 +181,18 @@ category = "Defensive" cost = 1 -/datum/spellbook_entry/blink - name = "Blink" - spell_type = /obj/effect/proc_holder/spell/targeted/turf_teleport/blink - log_name = "BL" - category = "Mobility" - -/datum/spellbook_entry/teleport - name = "Teleport" - spell_type = /obj/effect/proc_holder/spell/targeted/area_teleport/teleport - log_name = "TP" - category = "Mobility" - -/datum/spellbook_entry/mutate - name = "Mutate" - spell_type = /obj/effect/proc_holder/spell/targeted/genetic/mutate - log_name = "MU" - -/datum/spellbook_entry/jaunt - name = "Ethereal Jaunt" - spell_type = /obj/effect/proc_holder/spell/targeted/ethereal_jaunt - log_name = "EJ" - category = "Mobility" - -/datum/spellbook_entry/knock - name = "Knock" - spell_type = /obj/effect/proc_holder/spell/aoe_turf/knock - log_name = "KN" - category = "Mobility" +/datum/spellbook_entry/repulse + name = "Repulse" + spell_type = /obj/effect/proc_holder/spell/aoe_turf/repulse + log_name = "RP" + category = "Defensive" cost = 1 -/datum/spellbook_entry/greaterknock - name = "Greater Knock" - spell_type = /obj/effect/proc_holder/spell/aoe_turf/knock/greater - log_name = "GK" - category = "Mobility" - cost = 2 - refundable = 0 //global effect on cast - -/datum/spellbook_entry/fleshtostone - name = "Flesh to Stone" - spell_type = /obj/effect/proc_holder/spell/targeted/touch/flesh_to_stone - log_name = "FS" - -/datum/spellbook_entry/summonitem - name = "Summon Item" - spell_type = /obj/effect/proc_holder/spell/targeted/summonitem - log_name = "IS" - category = "Assistance" +/datum/spellbook_entry/smoke + name = "Smoke" + spell_type = /obj/effect/proc_holder/spell/targeted/smoke + log_name = "SM" + category = "Defensive" cost = 1 /datum/spellbook_entry/lichdom @@ -229,28 +201,64 @@ log_name = "LD" category = "Defensive" -/datum/spellbook_entry/lichdom/IsAvailible() +/datum/spellbook_entry/lichdom/IsSpellAvailable() if(SSticker.mode.name == "ragin' mages") return FALSE else return TRUE -/datum/spellbook_entry/lightningbolt - name = "Lightning Bolt" - spell_type = /obj/effect/proc_holder/spell/targeted/lightning - log_name = "LB" +/datum/spellbook_entry/magicm + name = "Magic Missile" + spell_type = /obj/effect/proc_holder/spell/targeted/projectile/magic_missile + log_name = "MM" + category = "Defensive" -/datum/spellbook_entry/infinite_guns - name = "Lesser Summon Guns" - spell_type = /obj/effect/proc_holder/spell/targeted/infinite_guns - log_name = "IG" - cost = 4 +/datum/spellbook_entry/timestop + name = "Time Stop" + spell_type = /obj/effect/proc_holder/spell/aoe_turf/conjure/timestop + log_name = "TS" + category = "Defensive" -/datum/spellbook_entry/horseman - name = "Curse of The Horseman" - spell_type = /obj/effect/proc_holder/spell/targeted/horsemask - log_name = "HH" +//Mobility +/datum/spellbook_entry/knock + name = "Knock" + spell_type = /obj/effect/proc_holder/spell/aoe_turf/knock + log_name = "KN" + category = "Mobility" + cost = 1 +/datum/spellbook_entry/blink + name = "Blink" + spell_type = /obj/effect/proc_holder/spell/targeted/turf_teleport/blink + log_name = "BL" + category = "Mobility" + +/datum/spellbook_entry/jaunt + name = "Ethereal Jaunt" + spell_type = /obj/effect/proc_holder/spell/targeted/ethereal_jaunt + log_name = "EJ" + category = "Mobility" + +/datum/spellbook_entry/greaterknock + name = "Greater Knock" + spell_type = /obj/effect/proc_holder/spell/aoe_turf/knock/greater + log_name = "GK" + category = "Mobility" + refundable = 0 //global effect on cast + +/datum/spellbook_entry/mindswap + name = "Mindswap" + spell_type = /obj/effect/proc_holder/spell/targeted/mind_transfer + log_name = "MT" + category = "Mobility" + +/datum/spellbook_entry/teleport + name = "Teleport" + spell_type = /obj/effect/proc_holder/spell/targeted/area_teleport/teleport + log_name = "TP" + category = "Mobility" + +//Assistance /datum/spellbook_entry/charge name = "Charge" spell_type = /obj/effect/proc_holder/spell/targeted/charge @@ -258,193 +266,20 @@ category = "Assistance" cost = 1 -/datum/spellbook_entry/cluwne - name = "Curse of the Cluwne" - spell_type = /obj/effect/proc_holder/spell/targeted/touch/cluwne - log_name = "CC" - -/datum/spellbook_entry/item - name = "Buy Item" - refundable = 0 - buy_word = "Summon" - var/item_path= null - - -/datum/spellbook_entry/item/Buy(var/mob/living/carbon/human/user,var/obj/item/spellbook/book) - new item_path(get_turf(user)) - feedback_add_details("wizard_spell_learned",log_name) - return 1 - -/datum/spellbook_entry/item/GetInfo() - var/dat ="" - dat += "[name]" - dat += " Cost:[cost]
" - dat += "[desc]
" - if(surplus>=0) - dat += "[surplus] left.
" - return dat - -/datum/spellbook_entry/item/staffchange - name = "Staff of Change" - desc = "An artefact that spits bolts of coruscating energy which cause the target's very form to reshape itself." - item_path = /obj/item/gun/magic/staff/change - log_name = "ST" - -/datum/spellbook_entry/item/staffanimation - name = "Staff of Animation" - desc = "An arcane staff capable of shooting bolts of eldritch energy which cause inanimate objects to come to life. This magic doesn't affect machines." - item_path = /obj/item/gun/magic/staff/animate - log_name = "SA" +/datum/spellbook_entry/summonitem + name = "Summon Item" + spell_type = /obj/effect/proc_holder/spell/targeted/summonitem + log_name = "IS" category = "Assistance" - -/datum/spellbook_entry/item/staffchaos - name = "Staff of Chaos" - desc = "A caprious tool that can fire all sorts of magic without any rhyme or reason. Using it on people you care about is not recommended." - item_path = /obj/item/gun/magic/staff/chaos - log_name = "SC" - -/datum/spellbook_entry/item/staffslipping - name = "Staff of Slipping" - desc = "A staff that shoots magical bananas. These bananas will either slip or stun the target when hit. Surprisingly reliable!" - item_path = /obj/item/gun/magic/staff/slipping - log_name = "SL" cost = 1 -/datum/spellbook_entry/item/staffdoor - name = "Staff of Door Creation" - desc = "A particular staff that can mold solid metal into ornate wooden doors. Useful for getting around in the absence of other transportation. Does not work on glass." - item_path = /obj/item/gun/magic/staff/door - log_name = "SD" - cost = 1 - category = "Mobility" - -/datum/spellbook_entry/item/staffhealing - name = "Staff of Healing" - desc = "An altruistic staff that can heal the lame and raise the dead." - item_path = /obj/item/gun/magic/staff/healing - log_name = "SH" - cost = 1 - category = "Defensive" - -/datum/spellbook_entry/item/scryingorb - name = "Scrying Orb" - desc = "An incandescent orb of crackling energy, using it will allow you to ghost while alive, allowing you to spy upon the station with ease. In addition, buying it will permanently grant you x-ray vision." - item_path = /obj/item/scrying - log_name = "SO" - category = "Defensive" - -/datum/spellbook_entry/item/scryingorb/Buy(var/mob/living/carbon/human/user,var/obj/item/spellbook/book) - if(..()) - if(!(XRAY in user.mutations)) - user.mutations.Add(XRAY) - user.sight |= (SEE_MOBS|SEE_OBJS|SEE_TURFS) - user.see_in_dark = 8 - user.lighting_alpha = LIGHTING_PLANE_ALPHA_MOSTLY_INVISIBLE - to_chat(user, "The walls suddenly disappear.") - return 1 - - -/datum/spellbook_entry/item/soulstones - name = "Six Soul Stone Shards and the spell Artificer" - desc = "Soul Stone Shards are ancient tools capable of capturing and harnessing the spirits of the dead and dying. The spell Artificer allows you to create arcane machines for the captured souls to pilot." - item_path = /obj/item/storage/belt/soulstone/full - log_name = "SS" +/datum/spellbook_entry/noclothes + name = "Remove Clothes Requirement" + spell_type = /obj/effect/proc_holder/spell/noclothes + log_name = "NC" category = "Assistance" -/datum/spellbook_entry/item/soulstones/Buy(var/mob/living/carbon/human/user,var/obj/item/spellbook/book) - . =..() - if(.) - user.mind.AddSpell(new /obj/effect/proc_holder/spell/aoe_turf/conjure/construct(null)) - return . - -/datum/spellbook_entry/item/necrostone - name = "A Necromantic Stone" - desc = "A Necromantic stone is able to resurrect three dead individuals as skeletal thralls for you to command." - item_path = /obj/item/necromantic_stone - log_name = "NS" - category = "Assistance" - -/datum/spellbook_entry/item/wands - name = "Wand Assortment" - desc = "A collection of wands that allow for a wide variety of utility. Wands do not recharge, so be conservative in use. Comes in a handy belt." - item_path = /obj/item/storage/belt/wands/full - log_name = "WA" - category = "Defensive" - -/datum/spellbook_entry/item/armor - name = "Mastercrafted Armor Set" - desc = "An artefact suit of armor that allows you to cast spells while providing more protection against attacks and the void of space. Comes bundled with Boots of Gripping." - item_path = /obj/item/clothing/suit/space/hardsuit/wizard - log_name = "HS" - category = "Defensive" - -/datum/spellbook_entry/item/armor/Buy(var/mob/living/carbon/human/user,var/obj/item/spellbook/book) - . = ..() - if(.) - new /obj/item/clothing/shoes/magboots/wizard(get_turf(user)) - new /obj/item/clothing/gloves/color/purple(get_turf(user))//To complete the outfit - new /obj/item/clothing/head/helmet/space/hardsuit/wizard(get_turf(user)) - -/datum/spellbook_entry/item/contract - name = "Contract of Apprenticeship" - desc = "A magical contract binding an apprentice wizard to your service, using it will summon them to your side." - item_path = /obj/item/contract - log_name = "CT" - category = "Assistance" - -/datum/spellbook_entry/item/bloodbottle - name = "Bottle of Blood" - desc = "A bottle of magically infused blood, the smell of which will attract extradimensional beings when broken. Be careful though, the kinds of creatures summoned by blood magic are indiscriminate in their killing, and you yourself may become a victim." - item_path = /obj/item/antag_spawner/slaughter_demon - log_name = "BB" - limit = 3 - category = "Assistance" - -/datum/spellbook_entry/item/hugbottle - name = "Bottle of Tickles" - desc = "A bottle of magically infused fun, the smell of which will \ - attract adorable extradimensional beings when broken. These beings \ - are similar to slaughter demons, but are a little weaker and they do not permamently \ - kill their victims, instead putting them in an extradimensional hugspace, \ - to be released on the demon's death. Chaotic, but not ultimately \ - damaging. The crew's reaction to the other hand could be very \ - destructive." - item_path = /obj/item/antag_spawner/slaughter_demon/laughter - cost = 1 //non-destructive; it's just a jape, sibling! - log_name = "HB" - limit = 3 - category = "Assistance" - -/datum/spellbook_entry/item/oozebottle - name = "Bottle of Ooze" - desc = "A bottle of magically infused ooze, which will awake an all-consuming Morph, capable of cunningly disguising itself as any object it comes in contact with and even casting some very basic spells. Be careful though, as Morph diet includes Wizards." - item_path = /obj/item/antag_spawner/morph - cost = 1 - log_name = "BO" - limit = 3 - category = "Assistance" - -/datum/spellbook_entry/item/tarotdeck - name = "Guardian Deck" - desc = "A deck of guardian tarot cards, capable of binding a personal guardian to your body. There are multiple types of guardian available, but all of them will transfer some amount of damage to you. \ - It would be wise to avoid buying these with anything capable of causing you to swap bodies with others." - item_path = /obj/item/guardiancreator - log_name = "TD" - limit = 1 - category = "Assistance" - -/datum/spellbook_entry/item/mjolnir - name = "Mjolnir" - desc = "A mighty hammer on loan from Thor, God of Thunder. It crackles with barely contained power." - item_path = /obj/item/twohanded/mjollnir - log_name = "MJ" - -/datum/spellbook_entry/item/singularity_hammer - name = "Singularity Hammer" - desc = "A hammer that creates an intensely powerful field of gravity where it strikes, pulling everthing nearby to the point of impact." - item_path = /obj/item/twohanded/singularityhammer - log_name = "SI" - +//Rituals /datum/spellbook_entry/summon name = "Summon Stuff" category = "Rituals" @@ -473,7 +308,7 @@ cost = 0 log_name = "SGH" -/datum/spellbook_entry/summon/ghosts/IsAvailible() +/datum/spellbook_entry/summon/ghosts/IsSpellAvailable() if(!SSticker.mode) // In case spellbook is placed on map return FALSE if(SSticker.mode.name == "ragin' mages") @@ -494,7 +329,7 @@ cost = 0 log_name = "SG" -/datum/spellbook_entry/summon/guns/IsAvailible() +/datum/spellbook_entry/summon/guns/IsSpellAvailable() if(!SSticker.mode) // In case spellbook is placed on map return FALSE if(SSticker.mode.name == "ragin' mages") @@ -503,7 +338,7 @@ return TRUE /datum/spellbook_entry/summon/guns/Buy(var/mob/living/carbon/human/user,var/obj/item/spellbook/book) - feedback_add_details("wizard_spell_learned",log_name) + feedback_add_details("wizard_spell_learned", log_name) user.rightandwrong(0) book.uses += 1 active = 1 @@ -516,7 +351,7 @@ cost = 0 log_name = "SU" -/datum/spellbook_entry/summon/magic/IsAvailible() +/datum/spellbook_entry/summon/magic/IsSpellAvailable() if(!SSticker.mode) // In case spellbook is placed on map return FALSE if(SSticker.mode.name == "ragin' mages") @@ -525,18 +360,207 @@ return TRUE /datum/spellbook_entry/summon/magic/Buy(var/mob/living/carbon/human/user,var/obj/item/spellbook/book) - feedback_add_details("wizard_spell_learned",log_name) + feedback_add_details("wizard_spell_learned", log_name) user.rightandwrong(1) book.uses += 1 active = 1 to_chat(user, "You have cast summon magic and gained an extra charge for your spellbook.") return 1 +//Main category - Magical Items +/datum/spellbook_entry/item + name = "Buy Item" + refundable = 0 + buy_word = "Summon" + var/item_path = null + +/datum/spellbook_entry/item/Buy(var/mob/living/carbon/human/user,var/obj/item/spellbook/book) + new item_path(get_turf(user)) + feedback_add_details("wizard_spell_learned", log_name) + return 1 + +/datum/spellbook_entry/item/GetInfo() + var/dat ="" + dat += "[name]" + dat += " Cost:[cost]
" + dat += "[desc]
" + if(surplus>=0) + dat += "[surplus] left.
" + return dat + +//Artefacts +/datum/spellbook_entry/item/necrostone + name = "A Necromantic Stone" + desc = "A Necromantic stone is able to resurrect three dead individuals as skeletal thralls for you to command." + item_path = /obj/item/necromantic_stone + log_name = "NS" + category = "Artefacts" + +/datum/spellbook_entry/item/scryingorb + name = "Scrying Orb" + desc = "An incandescent orb of crackling energy, using it will allow you to ghost while alive, allowing you to spy upon the station with ease. In addition, buying it will permanently grant you x-ray vision." + item_path = /obj/item/scrying + log_name = "SO" + category = "Artefacts" + +/datum/spellbook_entry/item/scryingorb/Buy(var/mob/living/carbon/human/user,var/obj/item/spellbook/book) + if(..()) + if(!(XRAY in user.mutations)) + user.mutations.Add(XRAY) + user.sight |= (SEE_MOBS|SEE_OBJS|SEE_TURFS) + user.see_in_dark = 8 + user.lighting_alpha = LIGHTING_PLANE_ALPHA_MOSTLY_INVISIBLE + to_chat(user, "The walls suddenly disappear.") + return TRUE + +/datum/spellbook_entry/item/soulstones + name = "Six Soul Stone Shards and the spell Artificer" + desc = "Soul Stone Shards are ancient tools capable of capturing and harnessing the spirits of the dead and dying. The spell Artificer allows you to create arcane machines for the captured souls to pilot." + item_path = /obj/item/storage/belt/soulstone/full + log_name = "SS" + category = "Artefacts" + +/datum/spellbook_entry/item/soulstones/Buy(var/mob/living/carbon/human/user,var/obj/item/spellbook/book) + . = ..() + if(.) + user.mind.AddSpell(new /obj/effect/proc_holder/spell/aoe_turf/conjure/construct(null)) + return . + +/datum/spellbook_entry/item/wands + name = "Wand Assortment" + desc = "A collection of wands that allow for a wide variety of utility. Wands do not recharge, so be conservative in use. Comes in a handy belt." + item_path = /obj/item/storage/belt/wands/full + log_name = "WA" + category = "Artefacts" + +//Weapons and Armors +/datum/spellbook_entry/item/armor + name = "Mastercrafted Armor Set" + desc = "An artefact suit of armor that allows you to cast spells while providing more protection against attacks and the void of space. Comes bundled with Boots of Gripping." + item_path = /obj/item/clothing/suit/space/hardsuit/wizard + log_name = "HS" + category = "Weapons and Armors" + +/datum/spellbook_entry/item/armor/Buy(var/mob/living/carbon/human/user,var/obj/item/spellbook/book) + . = ..() + if(.) + new /obj/item/clothing/shoes/magboots/wizard(get_turf(user)) + new /obj/item/clothing/gloves/color/purple(get_turf(user)) // To complete the outfit + +/datum/spellbook_entry/item/mjolnir + name = "Mjolnir" + desc = "A mighty hammer on loan from Thor, God of Thunder. It crackles with barely contained power." + item_path = /obj/item/twohanded/mjollnir + log_name = "MJ" + category = "Weapons and Armors" + +/datum/spellbook_entry/item/singularity_hammer + name = "Singularity Hammer" + desc = "A hammer that creates an intensely powerful field of gravity where it strikes, pulling everthing nearby to the point of impact." + item_path = /obj/item/twohanded/singularityhammer + log_name = "SI" + category = "Weapons and Armors" + +//Staves +/datum/spellbook_entry/item/staffdoor + name = "Staff of Door Creation" + desc = "A particular staff that can mold solid metal into ornate wooden doors. Useful for getting around in the absence of other transportation. Does not work on glass." + item_path = /obj/item/gun/magic/staff/door + log_name = "SD" + category = "Staves" + cost = 1 + +/datum/spellbook_entry/item/staffhealing + name = "Staff of Healing" + desc = "An altruistic staff that can heal the lame and raise the dead." + item_path = /obj/item/gun/magic/staff/healing + log_name = "SH" + category = "Staves" + cost = 1 + +/datum/spellbook_entry/item/staffslipping + name = "Staff of Slipping" + desc = "A staff that shoots magical bananas. These bananas will either slip or stun the target when hit. Surprisingly reliable!" + item_path = /obj/item/gun/magic/staff/slipping + log_name = "SL" + category = "Staves" + cost = 1 + +/datum/spellbook_entry/item/staffanimation + name = "Staff of Animation" + desc = "An arcane staff capable of shooting bolts of eldritch energy which cause inanimate objects to come to life. This magic doesn't affect machines." + item_path = /obj/item/gun/magic/staff/animate + log_name = "SA" + category = "Staves" + +/datum/spellbook_entry/item/staffchange + name = "Staff of Change" + desc = "An artefact that spits bolts of coruscating energy which cause the target's very form to reshape itself." + item_path = /obj/item/gun/magic/staff/change + log_name = "ST" + category = "Staves" + +/datum/spellbook_entry/item/staffchaos + name = "Staff of Chaos" + desc = "A caprious tool that can fire all sorts of magic without any rhyme or reason. Using it on people you care about is not recommended." + item_path = /obj/item/gun/magic/staff/chaos + log_name = "SC" + category = "Staves" + +//Summons +/datum/spellbook_entry/item/oozebottle + name = "Bottle of Ooze" + desc = "A bottle of magically infused ooze, which will awake an all-consuming Morph, capable of cunningly disguising itself as any object it comes in contact with and even casting some very basic spells. Be careful though, as Morph diet includes Wizards." + item_path = /obj/item/antag_spawner/morph + log_name = "BO" + category = "Summons" + limit = 3 + cost = 1 + +/datum/spellbook_entry/item/hugbottle + name = "Bottle of Tickles" + desc = "A bottle of magically infused fun, the smell of which will \ + attract adorable extradimensional beings when broken. These beings \ + are similar to slaughter demons, but are a little weaker and they do not permamently \ + kill their victims, instead putting them in an extradimensional hugspace, \ + to be released on the demon's death. Chaotic, but not ultimately \ + damaging. The crew's reaction to the other hand could be very \ + destructive." + item_path = /obj/item/antag_spawner/slaughter_demon/laughter + log_name = "HB" + category = "Summons" + limit = 3 + cost = 1 // Non-destructive; it's just a jape, sibling! + +/datum/spellbook_entry/item/bloodbottle + name = "Bottle of Blood" + desc = "A bottle of magically infused blood, the smell of which will attract extradimensional beings when broken. Be careful though, the kinds of creatures summoned by blood magic are indiscriminate in their killing, and you yourself may become a victim." + item_path = /obj/item/antag_spawner/slaughter_demon + log_name = "BB" + category = "Summons" + limit = 3 + +/datum/spellbook_entry/item/contract + name = "Contract of Apprenticeship" + desc = "A magical contract binding an apprentice wizard to your service, using it will summon them to your side." + item_path = /obj/item/contract + log_name = "CT" + category = "Summons" + +/datum/spellbook_entry/item/tarotdeck + name = "Guardian Deck" + desc = "A deck of guardian tarot cards, capable of binding a personal guardian to your body. There are multiple types of guardian available, but all of them will transfer some amount of damage to you. \ + It would be wise to avoid buying these with anything capable of causing you to swap bodies with others." + item_path = /obj/item/guardiancreator + log_name = "TD" + category = "Summons" + limit = 1 + /obj/item/spellbook name = "spell book" desc = "The legendary book of spells of the wizard." icon = 'icons/obj/library.dmi' - icon_state ="book" + icon_state = "spellbook" throw_speed = 2 throw_range = 5 w_class = WEIGHT_CLASS_TINY @@ -544,19 +568,24 @@ var/temp = null var/op = 1 var/tab = null + var/main_tab = null var/mob/living/carbon/human/owner var/list/datum/spellbook_entry/entries = list() var/list/categories = list() + var/list/main_categories = list("Spells", "Magical Items") + var/list/spell_categories = list("Offensive", "Defensive", "Mobility", "Assistance", "Rituals") + var/list/item_categories = list("Artefacts", "Weapons and Armors", "Staves", "Summons") /obj/item/spellbook/proc/initialize() var/entry_types = subtypesof(/datum/spellbook_entry) - /datum/spellbook_entry/item - /datum/spellbook_entry/summon for(var/T in entry_types) var/datum/spellbook_entry/E = new T - if(E.IsAvailible()) + if(E.IsSpellAvailable()) entries |= E categories |= E.category else qdel(E) + main_tab = main_categories[1] tab = categories[1] /obj/item/spellbook/New() @@ -570,48 +599,64 @@ to_chat(user, "The contract has been used, you can't get your points back now!") else to_chat(user, "You feed the contract back into the spellbook, refunding your points.") - uses+=2 - qdel(O) if(istype(O, /obj/item/antag_spawner/slaughter_demon)) to_chat(user, "On second thought, maybe summoning a demon is a bad idea. You refund your points.") - if(istype(O, /obj/item/antag_spawner/slaughter_demon/laughter)) uses += 1 + for(var/datum/spellbook_entry/item/hugbottle/HB in entries) + if(!isnull(HB.limit)) + HB.limit++ else uses += 2 - for(var/datum/spellbook_entry/item/bloodbottle/BB in entries) - if(!isnull(BB.limit)) - BB.limit++ + for(var/datum/spellbook_entry/item/bloodbottle/BB in entries) + if(!isnull(BB.limit)) + BB.limit++ + qdel(O) + + if(istype(O, /obj/item/antag_spawner/morph)) + to_chat(user, "On second thought, maybe awakening a morph is a bad idea. You refund your points.") + uses += 1 + for(var/datum/spellbook_entry/item/oozebottle/OB in entries) + if(!isnull(OB.limit)) + OB.limit++ qdel(O) /obj/item/spellbook/proc/GetCategoryHeader(var/category) var/dat = "" switch(category) if("Offensive") - dat += "Spells and items geared towards debilitating and destroying.

" - dat += "Items are not bound to you and can be stolen. Additionaly they cannot typically be returned once purchased.
" + dat += "Spells geared towards debilitating and destroying.

" dat += "For spells: the number after the spell name is the cooldown time.
" dat += "You can reduce this number by spending more points on the spell.
" if("Defensive") - dat += "Spells and items geared towards improving your survivabilty or reducing foes ability to attack.

" - dat += "Items are not bound to you and can be stolen. Additionaly they cannot typically be returned once purchased.
" + dat += "Spells geared towards improving your survivabilty or reducing foes ability to attack.

" dat += "For spells: the number after the spell name is the cooldown time.
" dat += "You can reduce this number by spending more points on the spell.
" if("Mobility") - dat += "Spells and items geared towards improving your ability to move. It is a good idea to take at least one.

" - dat += "Items are not bound to you and can be stolen. Additionaly they cannot typically be returned once purchased.
" + dat += "Spells geared towards improving your ability to move. It is a good idea to take at least one.

" dat += "For spells: the number after the spell name is the cooldown time.
" dat += "You can reduce this number by spending more points on the spell.
" if("Assistance") - dat += "Spells and items geared towards bringing in outside forces to aid you or improving upon your other items and abilties.

" - dat += "Items are not bound to you and can be stolen. Additionaly they cannot typically be returned once purchased.
" + dat += "Spells geared towards improving your other items and abilities.

" dat += "For spells: the number after the spell name is the cooldown time.
" dat += "You can reduce this number by spending more points on the spell.
" if("Rituals") - dat += "These powerful spells change the very fabric of reality. Not always in your favour.
" + dat += "These powerful spells are capable of changing the very fabric of reality. Not always in your favour.
" + if("Weapons and Armors") + dat += "Various weapons and armors to crush your enemies and protect you from harm.

" + dat += "Items are not bound to you and can be stolen. Additionaly they cannot typically be returned once purchased.
" + if("Staves") + dat += "Various staves granting you their power, which they slowly recharge over time.

" + dat += "Items are not bound to you and can be stolen. Additionaly they cannot typically be returned once purchased.
" + if("Artefacts") + dat += "Various magical artefacts to aid you.

" + dat += "Items are not bound to you and can be stolen. Additionaly they cannot typically be returned once purchased.
" + if("Summons") + dat += "Magical items geared towards bringing in outside forces to aid you.

" + dat += "Items are not bound to you and can be stolen. Additionaly they cannot typically be returned once purchased.
" return dat /obj/item/spellbook/proc/wrap(var/content) @@ -621,11 +666,16 @@ @@ -645,13 +695,29 @@ user.set_machine(src) var/dat = "" - dat += "
    " + dat += "
      " var/list/cat_dat = list() - for(var/category in categories) - cat_dat[category] = "
      " - dat += "
    • [category]
    • " - - dat += "
    • Points remaining : [uses]
    • " + for(var/main_category in main_categories) + cat_dat[main_category] = "
      " + dat += "
    • [main_category]
    • " + dat += "
    " + switch(main_tab) + if("Spells") + dat += "
      " + for(var/category in categories) + if(category in item_categories) + continue + cat_dat[category] = "
      " + dat += "
    • [category]
    • " + dat += "
    • Points remaining : [uses]
    • " + if("Magical Items") + dat += "" var/datum/spellbook_entry/E @@ -675,7 +741,7 @@ dat += cat_dat[category] dat += "" - user << browse(wrap(dat), "window=spellbook;size=700x500") + user << browse(wrap(dat), "window=spellbook;size=800x600") onclose(user, "spellbook") return @@ -709,13 +775,19 @@ if(!isnull(E.limit)) E.limit += result uses += result + else if(href_list["mainpage"]) + main_tab = sanitize(href_list["mainpage"]) + tab = sanitize(href_list["page"]) + if(main_tab == "Spells") + tab = spell_categories[1] + else if(main_tab == "Magical Items") + tab = item_categories[1] else if(href_list["page"]) tab = sanitize(href_list["page"]) attack_self(H) return 1 -//Single Use Spellbooks// - +//Single Use Spellbooks /obj/item/spellbook/oneuse var/spell = /obj/effect/proc_holder/spell/targeted/projectile/magic_missile //just a placeholder to avoid runtimes if someone spawned the generic var/spellname = "sandbox" @@ -749,7 +821,6 @@ user.create_attack_log("[key_name(user)] learned the spell [spellname] ([S]).") onlearned(user) - /obj/item/spellbook/oneuse/proc/recoil(mob/user) user.visible_message("[src] glows in a black light!") @@ -763,7 +834,7 @@ /obj/item/spellbook/oneuse/fireball spell = /obj/effect/proc_holder/spell/fireball spellname = "fireball" - icon_state ="bookfireball" + icon_state = "bookfireball" desc = "This book feels warm to the touch." /obj/item/spellbook/oneuse/fireball/recoil(mob/user as mob) @@ -774,7 +845,7 @@ /obj/item/spellbook/oneuse/smoke spell = /obj/effect/proc_holder/spell/targeted/smoke spellname = "smoke" - icon_state ="booksmoke" + icon_state = "booksmoke" desc = "This book is overflowing with the dank arts." /obj/item/spellbook/oneuse/smoke/recoil(mob/user as mob) @@ -788,7 +859,7 @@ /obj/item/spellbook/oneuse/blind spell = /obj/effect/proc_holder/spell/targeted/trigger/blind spellname = "blind" - icon_state ="bookblind" + icon_state = "bookblind" desc = "This book looks blurry, no matter how you look at it." /obj/item/spellbook/oneuse/blind/recoil(mob/user as mob) @@ -799,7 +870,7 @@ /obj/item/spellbook/oneuse/mindswap spell = /obj/effect/proc_holder/spell/targeted/mind_transfer spellname = "mindswap" - icon_state ="bookmindswap" + icon_state = "bookmindswap" desc = "This book's cover is pristine, though its pages look ragged and torn." var/mob/stored_swap = null //Used in used book recoils to store an identity for mindswaps @@ -831,7 +902,7 @@ /obj/item/spellbook/oneuse/forcewall spell = /obj/effect/proc_holder/spell/targeted/forcewall spellname = "forcewall" - icon_state ="bookforcewall" + icon_state = "bookforcewall" desc = "This book has a dedication to mimes everywhere inside the front cover." /obj/item/spellbook/oneuse/forcewall/recoil(mob/user as mob) @@ -841,11 +912,10 @@ S.timer = 30 user.drop_item() - /obj/item/spellbook/oneuse/knock spell = /obj/effect/proc_holder/spell/aoe_turf/knock spellname = "knock" - icon_state ="bookknock" + icon_state = "bookknock" desc = "This book is hard to hold closed properly." /obj/item/spellbook/oneuse/knock/recoil(mob/user as mob) @@ -856,14 +926,14 @@ /obj/item/spellbook/oneuse/horsemask spell = /obj/effect/proc_holder/spell/targeted/horsemask spellname = "horses" - icon_state ="bookhorses" + icon_state = "bookhorses" desc = "This book is more horse than your mind has room for." /obj/item/spellbook/oneuse/horsemask/recoil(mob/living/carbon/user as mob) if(istype(user, /mob/living/carbon/human)) to_chat(user, "HOR-SIE HAS RISEN") var/obj/item/clothing/mask/horsehead/magichead = new /obj/item/clothing/mask/horsehead - magichead.flags |= NODROP //curses! + magichead.flags |= NODROP | DROPDEL //curses! magichead.flags_inv = null //so you can still see their face magichead.voicechange = 1 //NEEEEIIGHH if(!user.unEquip(user.wear_mask)) @@ -876,7 +946,7 @@ /obj/item/spellbook/oneuse/charge spell = /obj/effect/proc_holder/spell/targeted/charge spellname = "charging" - icon_state ="bookcharge" + icon_state = "bookcharge" desc = "This book is made of 100% post-consumer wizard." /obj/item/spellbook/oneuse/charge/recoil(mob/user as mob) @@ -887,7 +957,7 @@ /obj/item/spellbook/oneuse/summonitem spell = /obj/effect/proc_holder/spell/targeted/summonitem spellname = "instant summons" - icon_state ="booksummons" + icon_state = "booksummons" desc = "This book is bright and garish, very hard to miss." /obj/item/spellbook/oneuse/summonitem/recoil(mob/user as mob) @@ -898,13 +968,13 @@ /obj/item/spellbook/oneuse/fake_gib spell = /obj/effect/proc_holder/spell/targeted/touch/fake_disintegrate spellname = "disintegrate" - icon_state ="bookfireball" + icon_state = "bookfireball" desc = "This book feels like it will rip stuff apart." /obj/item/spellbook/oneuse/sacredflame spell = /obj/effect/proc_holder/spell/targeted/sacred_flame spellname = "sacred flame" - icon_state ="booksacredflame" + icon_state = "booksacredflame" desc = "Become one with the flames that burn within... and invite others to do so as well." /obj/item/spellbook/oneuse/random diff --git a/code/game/jobs/job/job.dm b/code/game/jobs/job/job.dm index eebe4f2e9e4..9def19d2970 100644 --- a/code/game/jobs/job/job.dm +++ b/code/game/jobs/job/job.dm @@ -146,7 +146,7 @@ var/backpack = /obj/item/storage/backpack var/satchel = /obj/item/storage/backpack/satchel_norm var/dufflebag = /obj/item/storage/backpack/duffel - var/box = /obj/item/storage/box/survival + box = /obj/item/storage/box/survival var/tmp/list/gear_leftovers = list() @@ -168,12 +168,8 @@ else back = backpack //Department backpack - if(box) - var/spawnbox = box - if(H.dna.species.speciesbox) - spawnbox = H.dna.species.speciesbox - backpack_contents.Insert(1, spawnbox) // Box always takes a first slot in backpack - backpack_contents[spawnbox] = 1 + if(box && H.dna.species.speciesbox) + box = H.dna.species.speciesbox if(allow_loadout && H.client && (H.client.prefs.gear && H.client.prefs.gear.len)) for(var/gear in H.client.prefs.gear) diff --git a/code/game/jobs/job/security.dm b/code/game/jobs/job/security.dm index 407393eb489..0dfd0876817 100644 --- a/code/game/jobs/job/security.dm +++ b/code/game/jobs/job/security.dm @@ -214,7 +214,7 @@ suit = /obj/item/clothing/suit/storage/fr_jacket shoes = /obj/item/clothing/shoes/white l_ear = /obj/item/radio/headset/headset_sec/alt - glasses = /obj/item/clothing/glasses/hud/health/health_advanced + glasses = /obj/item/clothing/glasses/hud/health/sunglasses id = /obj/item/card/id/security suit_store = /obj/item/flashlight/pen l_hand = /obj/item/storage/firstaid/adv diff --git a/code/game/jobs/job/supervisor.dm b/code/game/jobs/job/supervisor.dm index 3208e9d3533..849f54169f5 100644 --- a/code/game/jobs/job/supervisor.dm +++ b/code/game/jobs/job/supervisor.dm @@ -175,7 +175,7 @@ var/datum/announcement/minor/captain_announcement = new(do_newscast = 0) gloves = /obj/item/clothing/gloves/combat shoes = /obj/item/clothing/shoes/jackboots l_ear = /obj/item/radio/headset/heads/blueshield/alt - glasses = /obj/item/clothing/glasses/hud/health/health_advanced + glasses = /obj/item/clothing/glasses/hud/health/sunglasses id = /obj/item/card/id/nanotrasen pda = /obj/item/pda/heads/blueshield backpack_contents = list( diff --git a/code/game/jobs/job/support.dm b/code/game/jobs/job/support.dm index 22c2d47e3b9..a247fa6810b 100644 --- a/code/game/jobs/job/support.dm +++ b/code/game/jobs/job/support.dm @@ -66,6 +66,12 @@ l_ear = /obj/item/radio/headset/headset_service pda = /obj/item/pda/chef +/datum/outfit/job/chef/post_equip(mob/living/carbon/human/H, visualsOnly = FALSE) + ..() + if(visualsOnly) + return + var/datum/martial_art/cqc/under_siege/justacook = new + justacook.teach(H) /datum/job/hydro @@ -175,23 +181,24 @@ name = "Shaft Miner" jobtype = /datum/job/mining - uniform = /obj/item/clothing/under/rank/miner/lavaland - gloves = /obj/item/clothing/gloves/color/black - shoes = /obj/item/clothing/shoes/workboots/mining l_ear = /obj/item/radio/headset/headset_cargo/mining - id = /obj/item/card/id/supply + shoes = /obj/item/clothing/shoes/workboots/mining + gloves = /obj/item/clothing/gloves/color/black + uniform = /obj/item/clothing/under/rank/miner/lavaland l_pocket = /obj/item/reagent_containers/hypospray/autoinjector/survival - r_pocket = /obj/item/flashlight/seclite + r_pocket = /obj/item/storage/bag/ore + id = /obj/item/card/id/supply pda = /obj/item/pda/shaftminer backpack_contents = list( - /obj/item/storage/bag/ore=1,\ + /obj/item/flashlight/seclite=1,\ /obj/item/kitchen/knife/combat/survival=1,\ /obj/item/mining_voucher=1,\ /obj/item/stack/marker_beacon/ten=1 ) - + backpack = /obj/item/storage/backpack/explorer - satchel = /obj/item/storage/backpack/explorer + satchel = /obj/item/storage/backpack/satchel/explorer + box = /obj/item/storage/box/survival_mining /datum/outfit/job/mining/equipped name = "Shaft Miner" @@ -210,9 +217,6 @@ /obj/item/stack/marker_beacon/ten=1 ) - backpack = /obj/item/storage/backpack/explorer - satchel = /obj/item/storage/backpack/explorer - /datum/outfit/job/miner/equipped/post_equip(mob/living/carbon/human/H, visualsOnly = FALSE) ..() if(visualsOnly) diff --git a/code/game/machinery/cell_charger.dm b/code/game/machinery/cell_charger.dm index d85a89606ea..0d4455399b0 100644 --- a/code/game/machinery/cell_charger.dm +++ b/code/game/machinery/cell_charger.dm @@ -8,6 +8,7 @@ idle_power_usage = 5 active_power_usage = 60 power_channel = EQUIP + pass_flags = PASSTABLE var/obj/item/stock_parts/cell/charging = null var/chargelevel = -1 diff --git a/code/game/machinery/cloning.dm b/code/game/machinery/cloning.dm index 1d05204e381..1ce0bcd97e7 100644 --- a/code/game/machinery/cloning.dm +++ b/code/game/machinery/cloning.dm @@ -178,6 +178,12 @@ if(occupant && occupant.stat != DEAD) to_chat(user, "Current clone cycle is [round(get_completion())]% complete.") +/obj/machinery/clonepod/return_air() //non-reactive air + var/datum/gas_mixture/GM = new + GM.nitrogen = MOLES_O2STANDARD + MOLES_N2STANDARD + GM.temperature = T20C + return GM + /obj/machinery/clonepod/proc/get_completion() . = (100 * ((occupant.health + 100) / (heal_level + 100))) diff --git a/code/game/machinery/computer/HolodeckControl.dm b/code/game/machinery/computer/HolodeckControl.dm index 604ac3f02f3..d3edc588e2d 100644 --- a/code/game/machinery/computer/HolodeckControl.dm +++ b/code/game/machinery/computer/HolodeckControl.dm @@ -460,6 +460,12 @@ desc = "Here's your chance, do your dance at the Space Jam." w_class = WEIGHT_CLASS_BULKY //Stops people from hiding it in their bags/pockets +/obj/item/beach_ball/holoball/baseball + icon_state = "baseball" + name = "baseball" + item_state = "baseball" + desc = "Take me out to the ball game." + /obj/structure/holohoop name = "basketball hoop" desc = "Boom, Shakalaka!" diff --git a/code/game/machinery/constructable_frame.dm b/code/game/machinery/constructable_frame.dm index 9e91e254950..8cb3301e40c 100644 --- a/code/game/machinery/constructable_frame.dm +++ b/code/game/machinery/constructable_frame.dm @@ -330,6 +330,14 @@ to destroy them and players will be able to make replacements. name = "circuit board (Freezer)" to_chat(user, "You set the board to cooling.") +/obj/item/circuitboard/recharger + name = "circuit board (Recharger)" + build_path = /obj/machinery/recharger + board_type = "machine" + origin_tech = "powerstorage=3;materials=2" + frame_desc = "Requires 1 Capacitor" + req_components = list(/obj/item/stock_parts/capacitor = 1) + /obj/item/circuitboard/snow_machine name = "circuit board (snow machine)" build_path = /obj/machinery/snow_machine @@ -591,6 +599,16 @@ to destroy them and players will be able to make replacements. /obj/item/stock_parts/micro_laser = 1, /obj/item/stock_parts/console_screen = 1) +/obj/item/circuitboard/reagentgrinder + name = "circuit board (All-In-One Grinder)" + build_path = /obj/machinery/reagentgrinder/empty + board_type = "machine" + origin_tech = "materials=2;engineering=2;biotech=2" + frame_desc = "Requires 2 Manipulators and 1 Matter Bin." + req_components = list( + /obj/item/stock_parts/manipulator = 2, + /obj/item/stock_parts/matter_bin = 1) + //Almost the same recipe as destructive analyzer to give people choices. /obj/item/circuitboard/experimentor name = "circuit board (E.X.P.E.R.I-MENTOR)" diff --git a/code/game/machinery/dance_machine.dm b/code/game/machinery/dance_machine.dm index 75c4e466a79..a0c0d2234af 100644 --- a/code/game/machinery/dance_machine.dm +++ b/code/game/machinery/dance_machine.dm @@ -322,6 +322,9 @@ /obj/machinery/disco/proc/dance(mob/living/M) //Show your moves set waitfor = FALSE + if(M.client && !(M.client.prefs.sound & SOUND_DISCO)) //We have a client that doesn't want to dance. + rangers -= M //Doing that here as it'll be checked less often than in processing. + return switch(rand(0,9)) if(0 to 1) dance2(M) @@ -460,17 +463,18 @@ var/sound/song_played = sound(selection.song_path) for(var/mob/M in range(10,src)) - if(!(M in rangers)) - rangers[M] = TRUE - M.playsound_local(get_turf(M), null, 100, channel = CHANNEL_JUKEBOX, S = song_played) - if(prob(5+(allowed(M) * 4)) && M.canmove && isliving(M)) - dance(M) + if(!M.client || M.client.prefs.sound & SOUND_DISCO) + if(!(M in rangers)) + rangers[M] = TRUE + M.playsound_local(get_turf(M), null, 100, channel = CHANNEL_JUKEBOX, S = song_played) for(var/mob/L in rangers) if(get_dist(src, L) > 10) rangers -= L if(!L || !L.client) continue L.stop_sound_channel(CHANNEL_JUKEBOX) + else if(prob(9) && L.canmove && isliving(L)) + dance(L) else if(active) active = FALSE STOP_PROCESSING(SSobj, src) diff --git a/code/game/machinery/deployable.dm b/code/game/machinery/deployable.dm index e0fb65787cd..6785c5ed8ff 100644 --- a/code/game/machinery/deployable.dm +++ b/code/game/machinery/deployable.dm @@ -1,144 +1,231 @@ -/* -CONTAINS: +#define SINGLE "single" +#define VERTICAL "vertical" +#define HORIZONTAL "horizontal" -Deployable items -Barricades +#define METAL 1 +#define WOOD 2 +#define SAND 3 -for reference: +//Barricades/cover - access_security = 1 - access_brig = 2 - access_armory = 3 - access_forensics_lockers= 4 - access_medical = 5 - access_morgue = 6 - access_tox = 7 - access_tox_storage = 8 - access_genetics = 9 - access_engine = 10 - access_engine_equip= 11 - access_maint_tunnels = 12 - access_external_airlocks = 13 - access_emergency_storage = 14 - access_change_ids = 15 - access_ai_upload = 16 - access_teleporter = 17 - access_eva = 18 - access_heads = 19 - access_captain = 20 - access_all_personal_lockers = 21 - access_chapel_office = 22 - access_tech_storage = 23 - access_atmospherics = 24 - access_bar = 25 - access_janitor = 26 - access_crematorium = 27 - access_kitchen = 28 - access_robotics = 29 - access_rd = 30 - access_cargo = 31 - access_construction = 32 - access_chemistry = 33 - access_cargo_bot = 34 - access_hydroponics = 35 - access_manufacturing = 36 - access_library = 37 - access_lawyer = 38 - access_virology = 39 - access_cmo = 40 - access_qm = 41 - access_court = 42 - access_clown = 43 - access_mime = 44 - -*/ - - -//Barricades, maybe there will be a metal one later... /obj/structure/barricade - anchored = 1.0 - density = 1.0 - var/health = 100.0 - var/maxhealth = 100.0 + name = "chest high wall" + desc = "Looks like this would make good cover." + anchored = TRUE + density = TRUE + max_integrity = 100 + var/proj_pass_rate = 50 //How many projectiles will pass the cover. Lower means stronger cover + var/bar_material = METAL + var/drop_amount = 3 var/stacktype = /obj/item/stack/sheet/metal -/obj/structure/barricade/attackby(obj/item/W as obj, mob/user as mob, params) - if(istype(W, stacktype)) - if(src.health < src.maxhealth) - visible_message("[user] begins to repair the [src]!") - if(do_after(user, 20 * W.toolspeed, target = src)) - src.health = src.maxhealth - W:use(1) - visible_message("[user] repairs the [src]!") - return - else - return - return - else if(istype(W, /obj/item/crowbar)) - user.changeNext_move(CLICK_CD_MELEE) - user.visible_message("[user] is prying apart \the [src].", "You begin to pry apart \the [src].") - playsound(src, W.usesound, 200, 1) +/obj/structure/barricade/blob_act(obj/structure/blob/B) //TO-DO-OBJECT-DAMAGE: Kill off when everything is damageable + take_damage(400, BRUTE, "melee", 0, get_dir(src, B)) - if(do_after(user, 300 * W.toolspeed, target = src) && !QDELETED(src)) - user.visible_message("[user] pries apart \the [src].", "You pry apart \the [src].") - dismantle() +/obj/structure/barricade/ex_act(severity) //TO-DO-OBJECT-DAMAGE: Kill off when everything is damageable + if(resistance_flags & INDESTRUCTIBLE) return - else - switch(W.damtype) - if("fire") - src.health -= W.force * 1 - if("brute") - src.health -= W.force * 0.75 - else - if(src.health <= 0) - visible_message("\The [src] is smashed apart!") - dismantle() - ..() - -/obj/structure/barricade/ex_act(severity) switch(severity) - if(1.0) - visible_message("\The [src] is blown apart!") + if(1) + obj_integrity = 0 qdel(src) - return - if(2.0) - src.health -= 25 - if(src.health <= 0) - visible_message("\The [src] is blown apart!") - dismantle() - return + if(2) + take_damage(rand(100, 250), BRUTE, "bomb", 0) + if(3) + take_damage(rand(10, 90), BRUTE, "bomb", 0) -/obj/structure/barricade/blob_act() - src.health -= 25 - if(src.health <= 0) - visible_message("The blob eats through \the [src]!") - qdel(src) - return - -/obj/structure/barricade/CanPass(atom/movable/mover, turf/target, height=0)//So bullets will fly over and stuff. - if(height==0) - return 1 - if(istype(mover) && mover.checkpass(PASSTABLE)) - return 1 +/obj/structure/barricade/mech_melee_attack(obj/mecha/M) //TO-DO-OBJECT-DAMAGE: Kill off when everything is damageable + M.do_attack_animation(src) + var/play_soundeffect = 0 + var/mech_damtype = M.damtype + if(M.selected) + mech_damtype = M.selected.damtype + play_soundeffect = 1 else - return 0 + switch(M.damtype) + if(BRUTE) + playsound(src, 'sound/weapons/punch4.ogg', 50, 1) + if(BURN) + playsound(src, 'sound/items/welder.ogg', 50, 1) + if(TOX) + playsound(src, 'sound/effects/spray2.ogg', 50, 1) + return 0 + else + return 0 + visible_message("[M.name] has hit [src].") + return take_damage(M.force*3, mech_damtype, "melee", play_soundeffect, get_dir(src, M)) // multiplied by 3 so we can hit objs hard but not be overpowered against mobs. -/obj/structure/barricade/proc/dismantle() - if(stacktype) - new stacktype(get_turf(src)) - new stacktype(get_turf(src)) - new stacktype(get_turf(src)) +/obj/structure/barricade/deconstruct(disassembled = TRUE) + make_debris() qdel(src) +/obj/structure/barricade/proc/make_debris() + if(stacktype) + new stacktype(get_turf(src), drop_amount) + +/obj/structure/barricade/attackby(obj/item/I, mob/user, params) + if(iswelder(I) && user.a_intent != INTENT_HARM && bar_material == METAL) + var/obj/item/weldingtool/WT = I + if(obj_integrity < max_integrity) + if(WT.remove_fuel(0, user)) + to_chat(user, "You begin repairing [src]...") + playsound(loc, WT.usesound, 40, 1) + if(do_after(user, 40 * I.toolspeed, target = src)) + obj_integrity = Clamp(obj_integrity + 20, 0, max_integrity) + else + return ..() + +/obj/structure/barricade/CanPass(atom/movable/mover, turf/target)//So bullets will fly over and stuff. + if(locate(/obj/structure/barricade) in get_turf(mover)) + return TRUE + else if(istype(mover, /obj/item/projectile)) + if(!anchored) + return TRUE + var/obj/item/projectile/proj = mover + if(proj.firer && Adjacent(proj.firer)) + return TRUE + if(prob(proj_pass_rate)) + return TRUE + return FALSE + else + return !density + + + +/////BARRICADE TYPES/////// + /obj/structure/barricade/wooden name = "wooden barricade" desc = "This space is blocked off by a wooden barricade." icon = 'icons/obj/structures.dmi' icon_state = "woodenbarricade" + bar_material = WOOD stacktype = /obj/item/stack/sheet/wood burn_state = FLAMMABLE burntime = 25 +/obj/structure/barricade/wooden/attackby(obj/item/I, mob/user) + if(istype(I,/obj/item/stack/sheet/wood)) + var/obj/item/stack/sheet/wood/W = I + if(W.amount < 5) + to_chat(user, "You need at least five wooden planks to make a wall!") + return + else + to_chat(user, "You start adding [I] to [src]...") + if(do_after(user, 50, target = src)) + W.use(5) + new /turf/simulated/wall/mineral/wood/nonmetal(get_turf(src)) + qdel(src) + return + return ..() + +/obj/structure/barricade/wooden/crude + name = "crude plank barricade" + desc = "This space is blocked off by a crude assortment of planks." + icon_state = "woodenbarricade-old" + drop_amount = 1 + max_integrity = 50 + proj_pass_rate = 65 + +/obj/structure/barricade/wooden/crude/snow + desc = "This space is blocked off by a crude assortment of planks. It seems to be covered in a layer of snow." + icon_state = "woodenbarricade-snow-old" + max_integrity = 75 + +/obj/structure/barricade/sandbags + name = "sandbags" + desc = "Bags of sand. Self explanatory." + icon = 'icons/obj/smooth_structures/sandbags.dmi' + icon_state = "sandbags" + max_integrity = 280 + proj_pass_rate = 20 + pass_flags = LETPASSTHROW + bar_material = SAND + climbable = TRUE + smooth = SMOOTH_TRUE + canSmoothWith = list(/obj/structure/barricade/sandbags, /turf/simulated/wall, /turf/simulated/wall/r_wall, /obj/structure/falsewall, /obj/structure/falsewall/reinforced, /turf/simulated/wall/rust, /turf/simulated/wall/r_wall/rust, /obj/structure/barricade/security) + stacktype = null + +/obj/structure/barricade/security + name = "security barrier" + desc = "A deployable barrier. Provides good cover in fire fights." + icon = 'icons/obj/objects.dmi' + icon_state = "barrier0" + density = FALSE + anchored = FALSE + max_integrity = 180 + proj_pass_rate = 20 + armor = list(melee = 10, bullet = 50, laser = 50, energy = 50, bomb = 10, bio = 100, rad = 100) + stacktype = null + var/deploy_time = 40 + var/deploy_message = TRUE + +/obj/structure/barricade/security/New() + ..() + addtimer(CALLBACK(src, .proc/deploy), deploy_time) + +/obj/structure/barricade/security/proc/deploy() + icon_state = "barrier1" + density = TRUE + anchored = TRUE + if(deploy_message) + visible_message("[src] deploys!") + + +/obj/item/grenade/barrier + name = "barrier grenade" + desc = "Instant cover." + icon = 'icons/obj/grenade.dmi' + icon_state = "flashbang" + item_state = "flashbang" + actions_types = list(/datum/action/item_action/toggle_barrier_spread) + var/mode = SINGLE + +/obj/item/grenade/barrier/examine(mob/user) + . = ..() + to_chat(user, "Alt-click to toggle modes.") + +/obj/item/grenade/barrier/AltClick(mob/living/carbon/user) + if(!istype(user) || !user.Adjacent(src) || user.incapacitated()) + return + toggle_mode(user) + +/obj/item/grenade/barrier/proc/toggle_mode(mob/user) + switch(mode) + if(SINGLE) + mode = VERTICAL + if(VERTICAL) + mode = HORIZONTAL + if(HORIZONTAL) + mode = SINGLE + + to_chat(user, "[src] is now in [mode] mode.") + +/obj/item/grenade/barrier/prime() + new /obj/structure/barricade/security(get_turf(loc)) + switch(mode) + if(VERTICAL) + var/target_turf = get_step(src, NORTH) + if(!(is_blocked_turf(target_turf))) + new /obj/structure/barricade/security(target_turf) + + var/target_turf2 = get_step(src, SOUTH) + if(!(is_blocked_turf(target_turf2))) + new /obj/structure/barricade/security(target_turf2) + if(HORIZONTAL) + var/target_turf = get_step(src, EAST) + if(!(is_blocked_turf(target_turf))) + new /obj/structure/barricade/security(target_turf) + + var/target_turf2 = get_step(src, WEST) + if(!(is_blocked_turf(target_turf2))) + new /obj/structure/barricade/security(target_turf2) + qdel(src) + +/obj/item/grenade/barrier/ui_action_click(mob/user) + toggle_mode(user) + + /obj/structure/barricade/mime name = "floor" desc = "Is... this a floor?" @@ -149,128 +236,10 @@ for reference: /obj/structure/barricade/mime/mrcd stacktype = null -//Actual Deployable machinery stuff +#undef SINGLE +#undef VERTICAL +#undef HORIZONTAL -/obj/machinery/deployable - name = "deployable" - desc = "deployable" - icon = 'icons/obj/objects.dmi' - req_access = list(access_security)//I'm changing this until these are properly tested./N - -/obj/machinery/deployable/barrier - name = "deployable barrier" - desc = "A deployable barrier. Swipe your ID card to lock/unlock it." - icon = 'icons/obj/objects.dmi' - anchored = 0.0 - density = 1.0 - icon_state = "barrier0" - var/health = 100.0 - var/maxhealth = 100.0 - var/locked = 0.0 -// req_access = list(access_maint_tunnels) - -/obj/machinery/deployable/barrier/New() - ..() - - src.icon_state = "barrier[src.locked]" - -/obj/machinery/deployable/barrier/attackby(obj/item/W as obj, mob/user as mob, params) - if(istype(W, /obj/item/card/id)) - if(src.allowed(user)) - if(src.emagged < 2.0) - src.locked = !src.locked - src.anchored = !src.anchored - src.icon_state = "barrier[src.locked]" - if((src.locked == 1.0) && (src.emagged < 2.0)) - to_chat(user, "Barrier lock toggled on.") - return - else if((src.locked == 0.0) && (src.emagged < 2.0)) - to_chat(user, "Barrier lock toggled off.") - return - else - do_sparks(2, 1, src) - visible_message("BZZzZZzZZzZT") - return - return - else if(istype(W, /obj/item/wrench)) - if(src.health < src.maxhealth) - src.health = src.maxhealth - src.emagged = 0 - src.req_access = list(access_security) - visible_message("[user] repairs the [src]!") - return - else if(src.emagged > 0) - src.emagged = 0 - src.req_access = list(access_security) - visible_message("[user] repairs the [src]!") - return - return - else - switch(W.damtype) - if("fire") - src.health -= W.force * 0.75 - if("brute") - src.health -= W.force * 0.5 - else - if(src.health <= 0) - src.explode() - ..() - -/obj/machinery/deployable/barrier/emag_act(user as mob) - if(!emagged) - emagged = 1 - req_access = null - to_chat(user, "You break the ID authentication lock on the [src].") - do_sparks(2, 1, src) - visible_message("BZZzZZzZZzZT") - else if(src.emagged == 1) - src.emagged = 2 - to_chat(user, "You short out the anchoring mechanism on the [src].") - do_sparks(2, 1, src) - visible_message("BZZzZZzZZzZT") - -/obj/machinery/deployable/barrier/ex_act(severity) - switch(severity) - if(1.0) - src.explode() - return - if(2.0) - src.health -= 25 - if(src.health <= 0) - src.explode() - return - -/obj/machinery/deployable/barrier/emp_act(severity) - if(stat & (BROKEN|NOPOWER)) - return - if(prob(50/severity)) - locked = !locked - anchored = !anchored - icon_state = "barrier[src.locked]" - -/obj/machinery/deployable/barrier/blob_act() - src.health -= 25 - if(src.health <= 0) - src.explode() - return - -/obj/machinery/deployable/barrier/CanPass(atom/movable/mover, turf/target, height=0)//So bullets will fly over and stuff. - if(height==0) - return 1 - if(istype(mover) && mover.checkpass(PASSTABLE)) - return 1 - else - return 0 - -/obj/machinery/deployable/barrier/proc/explode() - visible_message("[src] blows apart!") - var/turf/Tsec = get_turf(src) - -/* var/obj/item/stack/rods/ =*/ - new /obj/item/stack/rods(Tsec) - - do_sparks(3, 1, src) - - explosion(src.loc,-1,-1,0) - if(src) - qdel(src) +#undef METAL +#undef WOOD +#undef SAND \ No newline at end of file diff --git a/code/game/machinery/doors/airlock.dm b/code/game/machinery/doors/airlock.dm index 17b6f9e55c8..1284a9a485c 100644 --- a/code/game/machinery/doors/airlock.dm +++ b/code/game/machinery/doors/airlock.dm @@ -181,12 +181,6 @@ About the new airlock wires panel: /obj/machinery/door/airlock/bumpopen(mob/living/simple_animal/user) ..(user) -/obj/machinery/door/airlock/autoclose() - autoclose_timer = 0 - if(!QDELETED(src) && !density && !operating && !locked && !welded && autoclose) - close() - return - /obj/machinery/door/airlock/proc/isElectrified() if(electrified_until != 0) return 1 @@ -516,6 +510,7 @@ About the new airlock wires panel: else to_chat(user, "There's a [note.name] pinned to the front...") note.examine(user) + to_chat(user, "Use an empty hand on the airlock on grab mode to remove [note.name].") if(panel_open) switch(security_level) @@ -645,7 +640,7 @@ About the new airlock wires panel: add_overlay(I) else set_light(0) - + /obj/machinery/door/airlock/CanPass(atom/movable/mover, turf/target, height=0) if(isElectrified() && density && istype(mover, /obj/item)) var/obj/item/I = mover @@ -1103,6 +1098,10 @@ About the new airlock wires panel: playsound(loc, doorOpen, 30, 1) if(closeOther != null && istype(closeOther, /obj/machinery/door/airlock/) && !closeOther.density) closeOther.close() + + if(autoclose) + autoclose_in(normalspeed ? auto_close_time : auto_close_time_dangerous) + if(!density) return TRUE operating = TRUE @@ -1117,10 +1116,6 @@ About the new airlock wires panel: layer = OPEN_DOOR_LAYER update_icon(AIRLOCK_OPEN, 1) operating = FALSE - - // The `addtimer` system has the advantage of being cancelable - if(autoclose) - autoclose_timer = addtimer(CALLBACK(src, .proc/autoclose), normalspeed ? auto_close_time : auto_close_time_dangerous, TIMER_UNIQUE | TIMER_STOPPABLE) return TRUE /obj/machinery/door/airlock/close(forced=0, override = 0) @@ -1137,7 +1132,8 @@ About the new airlock wires panel: for(var/turf/turf in locs) for(var/atom/movable/M in turf) if(M.density && M != src) //something is blocking the door - addtimer(CALLBACK(src, .proc/autoclose), 60) + autoclose_in(60) + return use_power(360) //360 W seems much more appropriate for an actuator moving an industrial door capable of crushing people if(forced) diff --git a/code/game/machinery/doors/door.dm b/code/game/machinery/doors/door.dm index fdfaae71477..65854bb1412 100644 --- a/code/game/machinery/doors/door.dm +++ b/code/game/machinery/doors/door.dm @@ -14,14 +14,13 @@ var/visible = 1 var/operating = FALSE var/autoclose = 0 - var/autoclose_timer var/safe = TRUE //whether the door detects things and mobs in its way and reopen or crushes them. var/locked = FALSE //whether the door is bolted or not. var/glass = FALSE var/welded = FALSE var/normalspeed = 1 var/auto_close_time = 150 - var/auto_close_time_dangerous = 5 + var/auto_close_time_dangerous = 15 var/assemblytype //the type of door frame to drop during deconstruction var/datum/effect_system/spark_spread/spark_system var/damage_deflection = 10 @@ -77,9 +76,6 @@ air_update_turf(1) update_freelook_sight() GLOB.airlocks -= src - if(autoclose_timer) - deltimer(autoclose_timer) - autoclose_timer = 0 QDEL_NULL(spark_system) return ..() @@ -187,7 +183,7 @@ /obj/machinery/door/proc/unrestricted_side(mob/M) //Allows for specific side of airlocks to be unrestrected (IE, can exit maint freely, but need access to enter) return get_dir(src, M) & unres_sides - + /obj/machinery/door/proc/try_to_weld(obj/item/weldingtool/W, mob/user) return @@ -282,11 +278,8 @@ operating = FALSE air_update_turf(1) update_freelook_sight() - - // The `addtimer` system has the advantage of being cancelable if(autoclose) - autoclose_timer = addtimer(CALLBACK(src, .proc/autoclose), normalspeed ? auto_close_time : auto_close_time_dangerous, TIMER_UNIQUE | TIMER_STOPPABLE) - + autoclose_in(normalspeed ? auto_close_time : auto_close_time_dangerous) return TRUE /obj/machinery/door/proc/close() @@ -295,18 +288,15 @@ if(operating || welded) return if(safe) - for(var/atom/movable/M in get_turf(src)) - if(M.density && M != src) //something is blocking the door - if(autoclose) - addtimer(CALLBACK(src, .proc/autoclose), 60) - return + for(var/turf/turf in locs) + for(var/atom/movable/M in turf) + if(M.density && M != src) //something is blocking the door + if(autoclose) + autoclose_in(60) + return operating = TRUE - if(autoclose_timer) - deltimer(autoclose_timer) - autoclose_timer = 0 - do_animate("closing") layer = closingLayer sleep(5) @@ -354,10 +344,12 @@ return !(stat & NOPOWER) /obj/machinery/door/proc/autoclose() - autoclose_timer = 0 if(!QDELETED(src) && !density && !operating && !locked && !welded && autoclose) close() +/obj/machinery/door/proc/autoclose_in(wait) + addtimer(CALLBACK(src, .proc/autoclose), wait, TIMER_UNIQUE | TIMER_NO_HASH_WAIT | TIMER_OVERRIDE) + /obj/machinery/door/proc/update_freelook_sight() if(!glass && cameranet) cameranet.updateVisibility(src, 0) diff --git a/code/game/machinery/mass_driver.dm b/code/game/machinery/mass_driver.dm index 8bc5976d638..de14dce7d5b 100644 --- a/code/game/machinery/mass_driver.dm +++ b/code/game/machinery/mass_driver.dm @@ -160,8 +160,8 @@ var/obj/item/stack/cable_coil/C = W to_chat(user, "You start adding cables to \the [src]...") playsound(get_turf(src), C.usesound, 50, 1) - if(do_after(user, 20 * C.toolspeed, target = src) && (C.amount >= 3) && (build == 2)) - C.use(3) + if(do_after(user, 20 * C.toolspeed, target = src) && (C.amount >= 2) && (build == 2)) + C.use(2) to_chat(user, "You've added cables to \the [src].") build++ update_icon() @@ -169,7 +169,7 @@ if(istype(W, /obj/item/wirecutters)) to_chat(user, "You begin to remove the wiring from \the [src].") if(do_after(user, 10 * W.toolspeed, target = src) && (build == 3)) - new /obj/item/stack/cable_coil(loc,3) + new /obj/item/stack/cable_coil(loc,2) playsound(get_turf(src), W.usesound, 50, 1) to_chat(user, "You've removed the cables from \the [src].") build-- @@ -179,8 +179,8 @@ var/obj/item/stack/rods/R = W to_chat(user, "You begin to complete \the [src]...") playsound(get_turf(src), R.usesound, 50, 1) - if(do_after(user, 20 * R.toolspeed, target = src) && (R.amount >= 3) && (build == 3)) - R.use(3) + if(do_after(user, 20 * R.toolspeed, target = src) && (R.amount >= 2) && (build == 3)) + R.use(2) to_chat(user, "You've added the grille to \the [src].") build++ update_icon() diff --git a/code/game/machinery/recharger.dm b/code/game/machinery/recharger.dm index b8f2d153d9f..5abfc313047 100644 --- a/code/game/machinery/recharger.dm +++ b/code/game/machinery/recharger.dm @@ -6,7 +6,8 @@ anchored = 1 use_power = IDLE_POWER_USE idle_power_usage = 4 - active_power_usage = 250 + active_power_usage = 200 + pass_flags = PASSTABLE var/obj/item/charging = null var/using_power = FALSE var/list/allowed_devices = list(/obj/item/gun/energy, /obj/item/melee/baton, /obj/item/modular_computer, /obj/item/rcs, /obj/item/bodyanalyzer) @@ -14,6 +15,18 @@ var/icon_state_charged = "recharger2" var/icon_state_charging = "recharger1" var/icon_state_idle = "recharger0" + var/recharge_coeff = 1 + +/obj/machinery/recharger/New() + ..() + component_parts = list() + component_parts += new /obj/item/circuitboard/recharger(null) + component_parts += new /obj/item/stock_parts/capacitor(null) + RefreshParts() + +/obj/machinery/recharger/RefreshParts() + for(var/obj/item/stock_parts/capacitor/C in component_parts) + recharge_coeff = C.rating /obj/machinery/recharger/attackby(obj/item/G, mob/user, params) if(iswrench(G)) @@ -54,8 +67,16 @@ else to_chat(user, "[src] isn't connected to anything!") return 1 - else - return ..() + + if(anchored && !charging) + if(default_deconstruction_screwdriver(user, "rechargeropen", "recharger0", G)) + return + + if(panel_open && istype(G, /obj/item/crowbar)) + default_deconstruction_crowbar(G) + return + + return ..() /obj/machinery/recharger/attack_hand(mob/user) if(issilicon(user)) @@ -87,10 +108,12 @@ if(istype(charging, /obj/item/gun/energy)) var/obj/item/gun/energy/E = charging if(E.power_supply.charge < E.power_supply.maxcharge) - E.power_supply.give(E.power_supply.chargerate) + E.power_supply.give(E.power_supply.chargerate * recharge_coeff) + E.on_recharge() use_power(250) using_power = TRUE + if(istype(charging, /obj/item/melee/baton)) var/obj/item/melee/baton/B = charging if(B.bcell) diff --git a/code/game/machinery/rechargestation.dm b/code/game/machinery/rechargestation.dm index 1532eeaccbd..c15aed3b757 100644 --- a/code/game/machinery/rechargestation.dm +++ b/code/game/machinery/rechargestation.dm @@ -203,6 +203,7 @@ if(D.power_supply.charge < D.power_supply.maxcharge) var/obj/item/ammo_casing/energy/E = D.ammo_type[D.select] D.power_supply.give(E.e_cost) + D.on_recharge() D.update_icon() else D.charge_tick = 0 diff --git a/code/game/machinery/suit_storage_unit.dm b/code/game/machinery/suit_storage_unit.dm index 3776e18e450..671a7d1caff 100644 --- a/code/game/machinery/suit_storage_unit.dm +++ b/code/game/machinery/suit_storage_unit.dm @@ -62,8 +62,7 @@ /obj/machinery/suit_storage_unit/engine name = "engineering suit storage unit" - suit_type = /obj/item/clothing/suit/space/hardsuit/engineering - helmet_type = /obj/item/clothing/head/helmet/space/hardsuit/engineering + suit_type = /obj/item/clothing/suit/space/hardsuit/engine mask_type = /obj/item/clothing/mask/breath magboots_type = /obj/item/clothing/shoes/magboots req_access = list(access_engine_equip) @@ -73,8 +72,7 @@ /obj/machinery/suit_storage_unit/ce name = "chief engineer's suit storage unit" - suit_type = /obj/item/clothing/suit/space/hardsuit/elite - helmet_type = /obj/item/clothing/head/helmet/space/hardsuit/elite + suit_type = /obj/item/clothing/suit/space/hardsuit/engine/elite mask_type = /obj/item/clothing/mask/gas magboots_type = /obj/item/clothing/shoes/magboots/advance req_access = list(access_ce) @@ -85,7 +83,6 @@ /obj/machinery/suit_storage_unit/security name = "security suit storage unit" suit_type = /obj/item/clothing/suit/space/hardsuit/security - helmet_type = /obj/item/clothing/head/helmet/space/hardsuit/security mask_type = /obj/item/clothing/mask/gas/sechailer magboots_type = /obj/item/clothing/shoes/magboots req_access = list(access_security) @@ -98,8 +95,7 @@ /obj/machinery/suit_storage_unit/atmos name = "atmospherics suit storage unit" - suit_type = /obj/item/clothing/suit/space/hardsuit/atmos - helmet_type = /obj/item/clothing/head/helmet/space/hardsuit/atmos + suit_type = /obj/item/clothing/suit/space/hardsuit/engine/atmos mask_type = /obj/item/clothing/mask/gas magboots_type = /obj/item/clothing/shoes/magboots req_access = list(access_atmospherics) @@ -110,7 +106,6 @@ /obj/machinery/suit_storage_unit/mining name = "mining suit storage unit" suit_type = /obj/item/clothing/suit/space/hardsuit/mining - helmet_type = /obj/item/clothing/head/helmet/space/hardsuit/mining mask_type = /obj/item/clothing/mask/breath req_access = list(access_mining_station) @@ -125,7 +120,6 @@ /obj/machinery/suit_storage_unit/cmo suit_type = /obj/item/clothing/suit/space/hardsuit/medical - helmet_type = /obj/item/clothing/head/helmet/space/hardsuit/medical mask_type = /obj/item/clothing/mask/breath req_access = list(access_cmo) @@ -159,7 +153,6 @@ /obj/machinery/suit_storage_unit/syndicate name = "syndicate suit storage unit" suit_type = /obj/item/clothing/suit/space/hardsuit/syndi - helmet_type = /obj/item/clothing/head/helmet/space/hardsuit/syndi mask_type = /obj/item/clothing/mask/gas/syndicate magboots_type = /obj/item/clothing/shoes/magboots/syndie storage_type = /obj/item/tank/jetpack/oxygen/harness @@ -174,7 +167,6 @@ /obj/machinery/suit_storage_unit/ert/command suit_type = /obj/item/clothing/suit/space/hardsuit/ert/commander - helmet_type = /obj/item/clothing/head/helmet/space/hardsuit/ert/commander mask_type = /obj/item/clothing/mask/breath storage_type = /obj/item/tank/emergency_oxygen/double @@ -183,7 +175,6 @@ /obj/machinery/suit_storage_unit/ert/security suit_type = /obj/item/clothing/suit/space/hardsuit/ert/security - helmet_type = /obj/item/clothing/head/helmet/space/hardsuit/ert/security mask_type = /obj/item/clothing/mask/breath storage_type = /obj/item/tank/emergency_oxygen/double @@ -192,7 +183,6 @@ /obj/machinery/suit_storage_unit/ert/engineer suit_type = /obj/item/clothing/suit/space/hardsuit/ert/engineer - helmet_type = /obj/item/clothing/head/helmet/space/hardsuit/ert/engineer mask_type = /obj/item/clothing/mask/breath storage_type = /obj/item/tank/emergency_oxygen/double @@ -201,7 +191,6 @@ /obj/machinery/suit_storage_unit/ert/medical suit_type = /obj/item/clothing/suit/space/hardsuit/ert/medical - helmet_type = /obj/item/clothing/head/helmet/space/hardsuit/ert/medical mask_type = /obj/item/clothing/mask/breath storage_type = /obj/item/tank/emergency_oxygen/double @@ -699,7 +688,7 @@ else mask.forceMove(loc) mask = null - + /obj/machinery/suit_storage_unit/proc/dispense_magboots(mob/user as mob) if(!magboots) return diff --git a/code/game/machinery/syndicatebomb.dm b/code/game/machinery/syndicatebomb.dm index bc2af073fc6..3630beb1f6c 100644 --- a/code/game/machinery/syndicatebomb.dm +++ b/code/game/machinery/syndicatebomb.dm @@ -201,6 +201,9 @@ return FALSE if(!Adjacent(user)) return FALSE + if(!allowed(user)) + to_chat(user, "Access denied!") + return FALSE return TRUE /obj/machinery/syndicatebomb/proc/activate() @@ -273,6 +276,7 @@ /obj/machinery/syndicatebomb/self_destruct name = "self destruct device" desc = "Do not taunt. Warranty invalid if exposed to high temperature. Not suitable for agents under 3 years of age." + req_access = list(access_syndicate) payload = /obj/item/bombcore/large can_unanchor = FALSE var/explosive_wall_group = EXPLOSIVE_WALL_GROUP_SYNDICATE_BASE // If set, this bomb will also cause explosive walls in the same group to explode diff --git a/code/game/machinery/vending.dm b/code/game/machinery/vending.dm index cf7937474c8..dd5772149a0 100644 --- a/code/game/machinery/vending.dm +++ b/code/game/machinery/vending.dm @@ -1191,7 +1191,7 @@ product_slogans = "THIS'S WHERE TH' SEEDS LIVE! GIT YOU SOME!;Hands down the best seed selection on the station!;Also certain mushroom varieties available, more for experts! Get certified today!" product_ads = "We like plants!;Grow some crops!;Grow, baby, growww!;Aw h'yeah son!" icon_state = "seeds" - products = list(/obj/item/seeds/aloe =3, /obj/item/seeds/ambrosia = 3, /obj/item/seeds/apple = 3, /obj/item/seeds/banana = 3, /obj/item/seeds/berry = 3, + products = list(/obj/item/seeds/aloe =3, /obj/item/seeds/ambrosia = 3, /obj/item/seeds/apple = 3, /obj/item/seeds/cotton = 3, /obj/item/seeds/banana = 3, /obj/item/seeds/berry = 3, /obj/item/seeds/cabbage = 3, /obj/item/seeds/carrot = 3, /obj/item/seeds/cherry = 3, /obj/item/seeds/chanter = 3, /obj/item/seeds/chili = 3, /obj/item/seeds/cocoapod = 3, /obj/item/seeds/coffee = 3, /obj/item/seeds/comfrey =3, /obj/item/seeds/corn = 3, /obj/item/seeds/nymph =3, /obj/item/seeds/eggplant = 3, /obj/item/seeds/grape = 3, /obj/item/seeds/grass = 3, /obj/item/seeds/lemon = 3, @@ -1355,7 +1355,7 @@ desc = "Spare tool vending. What? Did you expect some witty description?" icon_state = "engivend" icon_deny = "engivend-deny" - req_access_txt = "11" //Engineering Equipment access + req_one_access_txt = "11;24" // Engineers and atmos techs can use this products = list(/obj/item/clothing/glasses/meson = 2,/obj/item/multitool = 4,/obj/item/airlock_electronics = 10,/obj/item/firelock_electronics = 10,/obj/item/firealarm_electronics = 10,/obj/item/apc_electronics = 10,/obj/item/airalarm_electronics = 10,/obj/item/stock_parts/cell/high = 10,/obj/item/camera_assembly = 10) contraband = list(/obj/item/stock_parts/cell/potato = 3) premium = list(/obj/item/storage/belt/utility = 3) @@ -1470,24 +1470,90 @@ product_slogans = "Dress for success!;Prepare to look swagalicious!;Look at all this free swag!;Why leave style up to fate? Use the ClothesMate!" vend_delay = 15 vend_reply = "Thank you for using the ClothesMate!" - products = list(/obj/item/clothing/head/that=2,/obj/item/clothing/head/fedora=1,/obj/item/clothing/glasses/monocle=1, - /obj/item/clothing/under/suit_jacket/navy=2,/obj/item/clothing/under/kilt=1,/obj/item/clothing/under/overalls=1, - /obj/item/clothing/under/suit_jacket/really_black=2,/obj/item/clothing/suit/storage/lawyer/blackjacket=2,/obj/item/clothing/under/pants/jeans=3,/obj/item/clothing/under/pants/classicjeans=2, - /obj/item/clothing/under/pants/camo = 1,/obj/item/clothing/under/pants/blackjeans=2,/obj/item/clothing/under/pants/khaki=2, - /obj/item/clothing/under/pants/white=2,/obj/item/clothing/under/pants/red=1,/obj/item/clothing/under/pants/black=2, - /obj/item/clothing/under/pants/tan=2,/obj/item/clothing/under/pants/blue=1,/obj/item/clothing/under/pants/track=1,/obj/item/clothing/suit/jacket/miljacket = 1, - /obj/item/clothing/accessory/scarf/red=1,/obj/item/clothing/accessory/scarf/green=1,/obj/item/clothing/accessory/scarf/darkblue=1, - /obj/item/clothing/accessory/scarf/purple=1,/obj/item/clothing/accessory/scarf/yellow=1,/obj/item/clothing/accessory/scarf/orange=1, - /obj/item/clothing/accessory/scarf/lightblue=1,/obj/item/clothing/accessory/scarf/white=1,/obj/item/clothing/accessory/scarf/black=1, - /obj/item/clothing/accessory/scarf/zebra=1,/obj/item/clothing/accessory/scarf/christmas=1,/obj/item/clothing/accessory/stripedredscarf=1, - /obj/item/clothing/accessory/stripedbluescarf=1,/obj/item/clothing/accessory/stripedgreenscarf=1,/obj/item/clothing/accessory/waistcoat=1, - /obj/item/clothing/under/sundress=2,/obj/item/clothing/under/stripeddress = 1, /obj/item/clothing/under/sailordress = 1, /obj/item/clothing/under/redeveninggown = 1, /obj/item/clothing/under/blacktango=1,/obj/item/clothing/suit/jacket=3, - /obj/item/clothing/glasses/regular=2,/obj/item/clothing/glasses/sunglasses/fake=2,/obj/item/clothing/head/sombrero=1,/obj/item/clothing/suit/poncho=1, - /obj/item/clothing/suit/ianshirt=1,/obj/item/clothing/shoes/laceup=2,/obj/item/clothing/shoes/black=4, - /obj/item/clothing/shoes/sandal=1, /obj/item/clothing/gloves/fingerless=2, - /obj/item/storage/belt/fannypack=1, /obj/item/storage/belt/fannypack/blue=1, /obj/item/storage/belt/fannypack/red=1, /obj/item/clothing/suit/mantle = 2, /obj/item/clothing/suit/mantle/old = 1, /obj/item/clothing/suit/mantle/regal = 2) - contraband = list(/obj/item/clothing/under/syndicate/tacticool=1,/obj/item/clothing/mask/balaclava=1,/obj/item/clothing/head/ushanka=1,/obj/item/clothing/under/soviet=1,/obj/item/storage/belt/fannypack/black=1) - premium = list(/obj/item/clothing/under/suit_jacket/checkered=1,/obj/item/clothing/head/mailman=1,/obj/item/clothing/under/rank/mailman=1,/obj/item/clothing/suit/jacket/leather=1,/obj/item/clothing/under/pants/mustangjeans=1) + products = list(/obj/item/clothing/head/that = 2, + /obj/item/clothing/head/fedora = 1, + /obj/item/clothing/glasses/monocle = 1, + /obj/item/clothing/under/suit_jacket/navy = 2, + /obj/item/clothing/under/kilt = 1, + /obj/item/clothing/under/overalls = 1, + /obj/item/clothing/under/suit_jacket/really_black = 2, + /obj/item/clothing/suit/storage/lawyer/blackjacket = 2, + /obj/item/clothing/under/pants/jeans = 3, + /obj/item/clothing/under/pants/classicjeans = 2, + /obj/item/clothing/under/pants/camo = 1, + /obj/item/clothing/under/pants/blackjeans = 2, + /obj/item/clothing/under/pants/khaki = 2, + /obj/item/clothing/under/pants/white = 2, + /obj/item/clothing/under/pants/red = 1, + /obj/item/clothing/under/pants/black = 2, + /obj/item/clothing/under/pants/tan = 2, + /obj/item/clothing/under/pants/blue = 1, + /obj/item/clothing/under/pants/track = 1, + /obj/item/clothing/suit/jacket/miljacket = 1, + /obj/item/clothing/head/beanie = 3, + /obj/item/clothing/head/beanie/black = 3, + /obj/item/clothing/head/beanie/red = 3, + /obj/item/clothing/head/beanie/green = 3, + /obj/item/clothing/head/beanie/darkblue = 3, + /obj/item/clothing/head/beanie/purple = 3, + /obj/item/clothing/head/beanie/yellow = 3, + /obj/item/clothing/head/beanie/orange = 3, + /obj/item/clothing/head/beanie/cyan = 3, + /obj/item/clothing/head/beanie/christmas = 3, + /obj/item/clothing/head/beanie/striped = 3, + /obj/item/clothing/head/beanie/stripedred = 3, + /obj/item/clothing/head/beanie/stripedblue = 3, + /obj/item/clothing/head/beanie/stripedgreen = 3, + /obj/item/clothing/head/beanie/rasta = 3, + /obj/item/clothing/accessory/scarf/red = 1, + /obj/item/clothing/accessory/scarf/green = 1, + /obj/item/clothing/accessory/scarf/darkblue = 1, + /obj/item/clothing/accessory/scarf/purple = 1, + /obj/item/clothing/accessory/scarf/yellow = 1, + /obj/item/clothing/accessory/scarf/orange = 1, + /obj/item/clothing/accessory/scarf/lightblue = 1, + /obj/item/clothing/accessory/scarf/white = 1, + /obj/item/clothing/accessory/scarf/black = 1, + /obj/item/clothing/accessory/scarf/zebra = 1, + /obj/item/clothing/accessory/scarf/christmas = 1, + /obj/item/clothing/accessory/stripedredscarf = 1, + /obj/item/clothing/accessory/stripedbluescarf = 1, + /obj/item/clothing/accessory/stripedgreenscarf = 1, + /obj/item/clothing/accessory/waistcoat = 1, + /obj/item/clothing/under/sundress = 2, + /obj/item/clothing/under/stripeddress = 1, + /obj/item/clothing/under/sailordress = 1, + /obj/item/clothing/under/redeveninggown = 1, + /obj/item/clothing/under/blacktango = 1, + /obj/item/clothing/suit/jacket = 3, + /obj/item/clothing/glasses/regular = 2, + /obj/item/clothing/glasses/sunglasses_fake = 2, + /obj/item/clothing/head/sombrero = 1, + /obj/item/clothing/suit/poncho = 1, + /obj/item/clothing/suit/ianshirt = 1, + /obj/item/clothing/shoes/laceup = 2, + /obj/item/clothing/shoes/black = 4, + /obj/item/clothing/shoes/sandal = 1, + /obj/item/clothing/gloves/fingerless = 2, + /obj/item/storage/belt/fannypack = 1, + /obj/item/storage/belt/fannypack/blue = 1, + /obj/item/storage/belt/fannypack/red = 1, + /obj/item/clothing/suit/mantle = 2, + /obj/item/clothing/suit/mantle/old = 1, + /obj/item/clothing/suit/mantle/regal = 2) + + contraband = list(/obj/item/clothing/under/syndicate/tacticool = 1, + /obj/item/clothing/mask/balaclava = 1, + /obj/item/clothing/head/ushanka = 1, + /obj/item/clothing/under/soviet = 1, + /obj/item/storage/belt/fannypack/black = 1) + + premium = list(/obj/item/clothing/under/suit_jacket/checkered = 1, + /obj/item/clothing/head/mailman = 1, + /obj/item/clothing/under/rank/mailman = 1, + /obj/item/clothing/suit/jacket/leather = 1, + /obj/item/clothing/under/pants/mustangjeans = 1) + refill_canister = /obj/item/vending_refill/clothing /obj/machinery/vending/clothing/New() diff --git a/code/game/mecha/working/ripley.dm b/code/game/mecha/working/ripley.dm index 5b4a8143bef..8cce6cdcdfc 100644 --- a/code/game/mecha/working/ripley.dm +++ b/code/game/mecha/working/ripley.dm @@ -171,10 +171,8 @@ /obj/mecha/working/ripley/proc/update_pressure() var/turf/T = get_turf(loc) - var/datum/gas_mixture/environment = T.return_air() - var/pressure = environment.return_pressure() - if(pressure < 20) + if(lavaland_equipment_pressure_check(T)) step_in = 3 for(var/obj/item/mecha_parts/mecha_equipment/drill/drill in equipment) drill.equip_cooldown = initial(drill.equip_cooldown)/2 diff --git a/code/game/objects/effects/decals/Cleanable/aliens.dm b/code/game/objects/effects/decals/Cleanable/aliens.dm index c788e934b45..f4ca5cf613a 100644 --- a/code/game/objects/effects/decals/Cleanable/aliens.dm +++ b/code/game/objects/effects/decals/Cleanable/aliens.dm @@ -3,7 +3,7 @@ desc = "It's green and acidic. It looks like... blood?" icon = 'icons/effects/blood.dmi' basecolor = "#05EE05" - bloodiness = MAX_SHOE_BLOODINESS + bloodiness = BLOOD_AMOUNT_PER_DECAL blood_state = BLOOD_STATE_XENO /obj/effect/decal/cleanable/blood/xeno/splatter diff --git a/code/game/objects/effects/decals/Cleanable/fuel.dm b/code/game/objects/effects/decals/Cleanable/fuel.dm index c4c903474ef..6c7ea8f3247 100644 --- a/code/game/objects/effects/decals/Cleanable/fuel.dm +++ b/code/game/objects/effects/decals/Cleanable/fuel.dm @@ -6,18 +6,18 @@ anchored = TRUE var/amount = 1 //Basically moles. -/obj/effect/decal/cleanable/liquid_fuel/Initialize(newLoc, amt = 1) +/obj/effect/decal/cleanable/liquid_fuel/Initialize(mapload, amt = 1) + . = ..() amount = amt //Be absorbed by any other liquid fuel in the tile. - for(var/obj/effect/decal/cleanable/liquid_fuel/other in newLoc) + for(var/obj/effect/decal/cleanable/liquid_fuel/other in loc) if(other != src) other.amount += amount spawn other.Spread() qdel(src) Spread() - . = ..() /obj/effect/decal/cleanable/liquid_fuel/proc/Spread() //Allows liquid fuels to sometimes flow into other tiles. diff --git a/code/game/objects/effects/decals/Cleanable/humans.dm b/code/game/objects/effects/decals/Cleanable/humans.dm index c410a9130a0..d282e1264e2 100644 --- a/code/game/objects/effects/decals/Cleanable/humans.dm +++ b/code/game/objects/effects/decals/Cleanable/humans.dm @@ -11,19 +11,30 @@ var/global/list/image/splatter_cache = list() density = FALSE anchored = TRUE layer = TURF_LAYER + plane = GAME_PLANE icon = 'icons/effects/blood.dmi' icon_state = "mfloor1" random_icon_states = list("mfloor1", "mfloor2", "mfloor3", "mfloor4", "mfloor5", "mfloor6", "mfloor7") blood_DNA = list() var/base_icon = 'icons/effects/blood.dmi' var/blood_state = BLOOD_STATE_HUMAN - var/bloodiness = MAX_SHOE_BLOODINESS + bloodiness = BLOOD_AMOUNT_PER_DECAL var/basecolor = "#A10808" // Color when wet. var/amount = 5 var/dry_timer = 0 var/off_floor = FALSE -/obj/effect/decal/cleanable/blood/Initialize() + +/obj/effect/decal/cleanable/blood/replace_decal(obj/effect/decal/cleanable/blood/C) + if(C.blood_DNA) + blood_DNA |= C.blood_DNA.Copy() + if(bloodiness) + if(C.bloodiness < MAX_SHOE_BLOODINESS) + C.bloodiness += bloodiness + return ..() + + +/obj/effect/decal/cleanable/blood/Initialize(mapload) . = ..() update_icon() if(GAMEMODE_IS_CULT) @@ -87,46 +98,6 @@ var/global/list/image/splatter_cache = list() /obj/effect/decal/cleanable/blood/can_bloodcrawl_in() return TRUE -//Add "bloodiness" of this blood's type, to the human's shoes -/obj/effect/decal/cleanable/blood/Crossed(atom/movable/O, oldloc) - if(!off_floor && ishuman(O)) - var/mob/living/carbon/human/H = O - var/obj/item/organ/external/l_foot = H.get_organ("l_foot") - var/obj/item/organ/external/r_foot = H.get_organ("r_foot") - var/hasfeet = TRUE - if(!l_foot && !r_foot) - hasfeet = FALSE - if(H.shoes && blood_state && bloodiness) - var/obj/item/clothing/shoes/S = H.shoes - var/add_blood = 0 - if(bloodiness >= BLOOD_GAIN_PER_STEP) - add_blood = BLOOD_GAIN_PER_STEP - else - add_blood = bloodiness - bloodiness -= add_blood - S.bloody_shoes[blood_state] = min(MAX_SHOE_BLOODINESS, S.bloody_shoes[blood_state] + add_blood) - if(blood_DNA && blood_DNA.len) - S.add_blood(H.blood_DNA, basecolor) - S.blood_state = blood_state - S.blood_color = basecolor - update_icon() - H.update_inv_shoes() - else if(hasfeet && blood_state && bloodiness)//Or feet - var/add_blood = 0 - if(bloodiness >= BLOOD_GAIN_PER_STEP) - add_blood = BLOOD_GAIN_PER_STEP - else - add_blood = bloodiness - bloodiness -= add_blood - H.bloody_feet[blood_state] = min(MAX_SHOE_BLOODINESS, H.bloody_feet[blood_state] + add_blood) - if(!H.feet_blood_DNA) - H.feet_blood_DNA = list() - H.blood_state = blood_state - H.feet_blood_DNA |= blood_DNA.Copy() - H.feet_blood_color = basecolor - update_icon() - H.update_inv_shoes() - /obj/effect/decal/cleanable/blood/splatter random_icon_states = list("mgibbl1", "mgibbl2", "mgibbl3", "mgibbl4", "mgibbl5") amount = 2 @@ -167,7 +138,7 @@ var/global/list/image/splatter_cache = list() amount = 0 var/message -/obj/effect/decal/cleanable/blood/writing/Initialize() +/obj/effect/decal/cleanable/blood/writing/Initialize(mapload) . = ..() if(random_icon_states.len) for(var/obj/effect/decal/cleanable/blood/writing/W in loc) @@ -191,6 +162,8 @@ var/global/list/image/splatter_cache = list() icon_state = "gibbl5" random_icon_states = list("gib1", "gib2", "gib3", "gib4", "gib5", "gib6") no_clear = TRUE + mergeable_decal = FALSE + var/fleshcolor = "#FFFFFF" /obj/effect/decal/cleanable/blood/gibs/update_icon() @@ -238,7 +211,7 @@ var/global/list/image/splatter_cache = list() break -/obj/effect/decal/cleanable/blood/old/Initialize() +/obj/effect/decal/cleanable/blood/old/Initialize(mapload) . = ..() bloodiness = 0 dry() @@ -246,7 +219,7 @@ var/global/list/image/splatter_cache = list() /obj/effect/decal/cleanable/blood/old/can_bloodcrawl_in() return FALSE -/obj/effect/decal/cleanable/blood/gibs/old/Initialize() +/obj/effect/decal/cleanable/blood/gibs/old/Initialize(mapload) . = ..() bloodiness = 0 dry() diff --git a/code/game/objects/effects/decals/Cleanable/misc.dm b/code/game/objects/effects/decals/Cleanable/misc.dm index d1ba3204bd0..349b8039d92 100644 --- a/code/game/objects/effects/decals/Cleanable/misc.dm +++ b/code/game/objects/effects/decals/Cleanable/misc.dm @@ -16,6 +16,7 @@ icon_state = "ash" anchored = TRUE scoop_reagents = list("ash" = 10) + mergeable_decal = FALSE /obj/effect/decal/cleanable/dirt name = "dirt" @@ -30,8 +31,8 @@ smooth = SMOOTH_MORE mouse_opacity = FALSE -/obj/effect/decal/cleanable/dirt/Initialize() - ..() +/obj/effect/decal/cleanable/dirt/Initialize(mapload) + . = ..() icon_state = "" /obj/effect/decal/cleanable/dirt/blackpowder @@ -55,7 +56,7 @@ desc = "It's foam." color = "#EBEBEB" -/obj/effect/decal/cleanable/flour/foam/Initialize() +/obj/effect/decal/cleanable/flour/foam/Initialize(mapload) . = ..() QDEL_IN(src, 15 SECONDS) @@ -97,6 +98,7 @@ gender = NEUTER icon = 'icons/effects/effects.dmi' icon_state = "molten" + mergeable_decal = FALSE /obj/effect/decal/cleanable/molten_object/large name = "big gooey grey mass" @@ -173,6 +175,7 @@ density = FALSE anchored = TRUE layer = TURF_LAYER + plane = GAME_PLANE icon = 'icons/effects/effects.dmi' icon_state = "flour" color = "#D5820B" diff --git a/code/game/objects/effects/decals/Cleanable/robots.dm b/code/game/objects/effects/decals/Cleanable/robots.dm index 1c8ad706dc8..5193436295e 100644 --- a/code/game/objects/effects/decals/Cleanable/robots.dm +++ b/code/game/objects/effects/decals/Cleanable/robots.dm @@ -5,7 +5,8 @@ icon_state = "gib1" basecolor = "#030303" random_icon_states = list("gib1", "gib2", "gib3", "gib4", "gib5", "gib6", "gib7") - bloodiness = MAX_SHOE_BLOODINESS + bloodiness = BLOOD_AMOUNT_PER_DECAL + mergeable_decal = FALSE /obj/effect/decal/cleanable/blood/gibs/robot/can_bloodcrawl_in() return FALSE diff --git a/code/game/objects/effects/decals/Cleanable/tracks.dm b/code/game/objects/effects/decals/Cleanable/tracks.dm index 1e45c2aa4cf..08b9b402cda 100644 --- a/code/game/objects/effects/decals/Cleanable/tracks.dm +++ b/code/game/objects/effects/decals/Cleanable/tracks.dm @@ -30,6 +30,7 @@ var/global/list/image/fluidtrack_cache = list() /obj/effect/decal/cleanable/blood/footprints/Crossed(atom/movable/O, oldloc) + ..() if(ishuman(O)) var/mob/living/carbon/human/H = O var/obj/item/clothing/shoes/S = H.shoes @@ -40,19 +41,22 @@ var/global/list/image/fluidtrack_cache = list() hasfeet = FALSE if(S && S.bloody_shoes[blood_state] && S.blood_color == basecolor) S.bloody_shoes[blood_state] = max(S.bloody_shoes[blood_state] - BLOOD_LOSS_PER_STEP, 0) - entered_dirs |= H.dir if(!S.blood_DNA) S.blood_DNA = list() S.blood_DNA |= blood_DNA.Copy() + if(!(entered_dirs & H.dir)) + entered_dirs |= H.dir + update_icon() else if(hasfeet && H.bloody_feet[blood_state] && H.feet_blood_color == basecolor)//Or feet //This will need to be changed. H.bloody_feet[blood_state] = max(H.bloody_feet[blood_state] - BLOOD_LOSS_PER_STEP, 0) - entered_dirs |= H.dir if(!H.feet_blood_DNA) H.feet_blood_DNA = list() H.feet_blood_DNA |= blood_DNA.Copy() - update_icon() - + if(!(entered_dirs & H.dir)) + entered_dirs |= H.dir + update_icon() /obj/effect/decal/cleanable/blood/footprints/Uncrossed(atom/movable/O) + ..() if(ishuman(O)) var/mob/living/carbon/human/H = O var/obj/item/clothing/shoes/S = H.shoes @@ -63,17 +67,20 @@ var/global/list/image/fluidtrack_cache = list() hasfeet = FALSE if(S && S.bloody_shoes[blood_state] && S.blood_color == basecolor) S.bloody_shoes[blood_state] = max(S.bloody_shoes[blood_state] - BLOOD_LOSS_PER_STEP, 0) - exited_dirs |= H.dir if(!S.blood_DNA) S.blood_DNA = list() S.blood_DNA |= blood_DNA.Copy() + if(!(exited_dirs & H.dir)) + exited_dirs |= H.dir + update_icon() else if(hasfeet && H.bloody_feet[blood_state] && H.feet_blood_color == basecolor)//Or feet H.bloody_feet[blood_state] = max(H.bloody_feet[blood_state] - BLOOD_LOSS_PER_STEP, 0) - exited_dirs |= H.dir if(!H.feet_blood_DNA) H.feet_blood_DNA = list() H.feet_blood_DNA |= blood_DNA.Copy() - update_icon() + if(!(exited_dirs & H.dir)) + exited_dirs |= H.dir + update_icon() /obj/effect/decal/cleanable/blood/footprints/update_icon() @@ -108,14 +115,14 @@ var/global/list/image/fluidtrack_cache = list() if(ishuman(A)) var/mob/living/carbon/human/H = A FP.blood_state = H.blood_state - FP.bloodiness = H.bloody_feet[H.blood_state] + FP.bloodiness = H.bloody_feet[H.blood_state] - BLOOD_LOSS_IN_SPREAD FP.basecolor = H.feet_blood_color if(H.blood_DNA) FP.blood_DNA = H.blood_DNA.Copy() else if(istype(A, /obj/item/clothing/shoes)) var/obj/item/clothing/shoes/S = A FP.blood_state = S.blood_state - FP.bloodiness = S.bloody_shoes[S.blood_state] + FP.bloodiness = S.bloody_shoes[S.blood_state] - BLOOD_LOSS_IN_SPREAD FP.basecolor = S.blood_color if(S.blood_DNA) FP.blood_DNA = S.blood_DNA.Copy() @@ -123,3 +130,8 @@ var/global/list/image/fluidtrack_cache = list() FP.update_icon() return FP + +/obj/effect/decal/cleanable/blood/footprints/replace_decal(obj/effect/decal/cleanable/blood/footprints/C) + if(blood_state != C.blood_state) //We only replace footprints of the same type as us + return + ..() \ No newline at end of file diff --git a/code/game/objects/effects/decals/cleanable.dm b/code/game/objects/effects/decals/cleanable.dm index 461273bccdb..3f50a9e3bb7 100644 --- a/code/game/objects/effects/decals/cleanable.dm +++ b/code/game/objects/effects/decals/cleanable.dm @@ -1,17 +1,70 @@ /obj/effect/decal/cleanable anchored = TRUE var/list/random_icon_states = list() + var/bloodiness = 0 //0-100, amount of blood in this decal, used for making footprints and affecting the alpha of bloody footprints + var/mergeable_decal = TRUE //when two of these are on a same tile or do we need to merge them into just one? + +/obj/effect/decal/cleanable/proc/replace_decal(obj/effect/decal/cleanable/C) // Returns true if we should give up in favor of the pre-existing decal + if(mergeable_decal) + return TRUE + +//Add "bloodiness" of this blood's type, to the human's shoes +//This is on /cleanable because fuck this ancient mess +/obj/effect/decal/cleanable/blood/Crossed(atom/movable/O) + ..() + if(!off_floor && ishuman(O)) + var/mob/living/carbon/human/H = O + var/obj/item/organ/external/l_foot = H.get_organ("l_foot") + var/obj/item/organ/external/r_foot = H.get_organ("r_foot") + var/hasfeet = TRUE + if(!l_foot && !r_foot) + hasfeet = FALSE + if(H.shoes && blood_state && bloodiness) + var/obj/item/clothing/shoes/S = H.shoes + var/add_blood = 0 + if(bloodiness >= BLOOD_GAIN_PER_STEP) + add_blood = BLOOD_GAIN_PER_STEP + else + add_blood = bloodiness + bloodiness -= add_blood + S.bloody_shoes[blood_state] = min(MAX_SHOE_BLOODINESS, S.bloody_shoes[blood_state] + add_blood) + if(blood_DNA && blood_DNA.len) + S.add_blood(H.blood_DNA, basecolor) + S.blood_state = blood_state + S.blood_color = basecolor + update_icon() + H.update_inv_shoes() + else if(hasfeet && blood_state && bloodiness)//Or feet + var/add_blood = 0 + if(bloodiness >= BLOOD_GAIN_PER_STEP) + add_blood = BLOOD_GAIN_PER_STEP + else + add_blood = bloodiness + bloodiness -= add_blood + H.bloody_feet[blood_state] = min(MAX_SHOE_BLOODINESS, H.bloody_feet[blood_state] + add_blood) + if(!H.feet_blood_DNA) + H.feet_blood_DNA = list() + H.blood_state = blood_state + H.feet_blood_DNA |= blood_DNA.Copy() + H.feet_blood_color = basecolor + update_icon() + H.update_inv_shoes() /obj/effect/decal/cleanable/proc/can_bloodcrawl_in() return FALSE -/obj/effect/decal/cleanable/New() +/obj/effect/decal/cleanable/Initialize(mapload) + . = ..() + if(loc && isturf(loc)) + for(var/obj/effect/decal/cleanable/C in loc) + if(C != src && C.type == type && !QDELETED(C)) + if(replace_decal(C)) + return INITIALIZE_HINT_QDEL if(random_icon_states && length(src.random_icon_states) > 0) src.icon_state = pick(src.random_icon_states) if(smooth) queue_smooth(src) queue_smooth_neighbors(src) - ..() /obj/effect/decal/cleanable/Destroy() if(smooth) diff --git a/code/game/objects/effects/decals/crayon.dm b/code/game/objects/effects/decals/crayon.dm index ac0007e42ae..06243b1db8a 100644 --- a/code/game/objects/effects/decals/crayon.dm +++ b/code/game/objects/effects/decals/crayon.dm @@ -4,12 +4,12 @@ icon = 'icons/effects/crayondecal.dmi' icon_state = "rune1" layer = MID_TURF_LAYER + plane = GAME_PLANE //makes the graffiti visible over a wall. anchored = TRUE -/obj/effect/decal/cleanable/crayon/New(location, main = "#FFFFFF", var/type = "rune1", var/e_name = "rune") - ..() - loc = location +/obj/effect/decal/cleanable/crayon/Initialize(mapload, main = "#FFFFFF", var/type = "rune1", var/e_name = "rune") + . = ..() name = e_name desc = "A [name] drawn in crayon." diff --git a/code/game/objects/effects/effect_system.dm b/code/game/objects/effects/effect_system.dm index 8bb117b832c..a145fcea1d4 100644 --- a/code/game/objects/effects/effect_system.dm +++ b/code/game/objects/effects/effect_system.dm @@ -79,7 +79,7 @@ would spawn and follow the beaker, even if it is carried or thrown. reagents.reaction(A) if(istype(A,/atom/movable)) var/atom/movable/AM = A - AM.water_act(life, 310.15, src) + AM.water_act(life, COLD_WATER_TEMPERATURE, src) return ..() diff --git a/code/game/objects/effects/effect_system/effects_water.dm b/code/game/objects/effects/effect_system/effects_water.dm index c4009516f92..12fc9732bb5 100644 --- a/code/game/objects/effects/effect_system/effects_water.dm +++ b/code/game/objects/effects/effect_system/effects_water.dm @@ -21,7 +21,7 @@ reagents.reaction(A) if(istype(A,/atom/movable)) var/atom/movable/AM = A - AM.water_act(life, 310.15, src) + AM.water_act(life, COLD_WATER_TEMPERATURE, src) return ..() ///////////////////////////////////////////// diff --git a/code/game/objects/effects/mines.dm b/code/game/objects/effects/mines.dm index 76e28f013a1..a9ef27c4e01 100644 --- a/code/game/objects/effects/mines.dm +++ b/code/game/objects/effects/mines.dm @@ -141,7 +141,7 @@ new /obj/effect/hallucination/delusion(victim.loc, victim, force_kind = "demon", duration = duration, skip_nearby = 0) var/obj/item/twohanded/required/chainsaw/doomslayer/chainsaw = new(victim.loc) - chainsaw.flags |= NODROP + chainsaw.flags |= NODROP | DROPDEL victim.drop_l_hand() victim.drop_r_hand() victim.put_in_hands(chainsaw) diff --git a/code/game/objects/effects/temporary_visuals/miscellaneous.dm b/code/game/objects/effects/temporary_visuals/miscellaneous.dm index 8fd1c061c32..7f1683ba415 100644 --- a/code/game/objects/effects/temporary_visuals/miscellaneous.dm +++ b/code/game/objects/effects/temporary_visuals/miscellaneous.dm @@ -140,6 +140,20 @@ ..() animate(src, alpha = 0, time = duration) +/obj/effect/temp_visual/fire + icon = 'icons/goonstation/effects/fire.dmi' + icon_state = "3" + light_range = LIGHT_RANGE_FIRE + light_color = LIGHT_COLOR_FIRE + duration = 10 + layer = MASSIVE_OBJ_LAYER + alpha = 250 + blend_mode = BLEND_ADD + +/obj/effect/temp_visual/fire/New(loc) + color = heat2color(FIRE_MINIMUM_TEMPERATURE_TO_EXIST) + ..() + /obj/effect/temp_visual/revenant name = "spooky lights" icon_state = "purplesparkles" @@ -289,4 +303,33 @@ /obj/effect/temp_visual/dir_setting/firing_effect/magic icon_state = "shieldsparkles" - duration = 3 \ No newline at end of file + duration = 3 + +/obj/effect/temp_visual/impact_effect + icon_state = "impact_bullet" + duration = 5 + +/obj/effect/temp_visual/impact_effect/Initialize(mapload, x, y) + pixel_x = x + pixel_y = y + return ..() + +/obj/effect/temp_visual/impact_effect/red_laser + icon_state = "impact_laser" + duration = 4 + +/obj/effect/temp_visual/impact_effect/blue_laser + icon_state = "impact_laser_blue" + duration = 4 + +/obj/effect/temp_visual/impact_effect/green_laser + icon_state = "impact_laser_green" + duration = 4 + +/obj/effect/temp_visual/impact_effect/purple_laser + icon_state = "impact_laser_purple" + duration = 4 + +/obj/effect/temp_visual/impact_effect/ion + icon_state = "shieldsparkles" + duration = 6 \ No newline at end of file diff --git a/code/game/objects/items.dm b/code/game/objects/items.dm index 9dbb02553ca..935c587fa57 100644 --- a/code/game/objects/items.dm +++ b/code/game/objects/items.dm @@ -87,6 +87,7 @@ var/global/image/fire_overlay = image("icon" = 'icons/goonstation/effects/fire.d If index term exists and icon_override is not set, this sprite sheet will be used. */ var/list/sprite_sheets = null + var/list/sprite_sheets_inhand = null //Used to override inhand items. Use a single .dmi and suffix the icon states inside with _l and _r for each hand. var/icon_override = null //Used to override hardcoded clothing dmis in human clothing proc. var/sprite_sheets_obj = null //Used to override hardcoded clothing inventory object dmis in human clothing proc. @@ -331,7 +332,7 @@ var/global/image/fire_overlay = image("icon" = 'icons/goonstation/effects/fire.d else return ..() -/obj/item/proc/hit_reaction(mob/living/carbon/human/owner, attack_text = "the attack", final_block_chance = 0, damage = 0, attack_type = MELEE_ATTACK) +/obj/item/proc/hit_reaction(mob/living/carbon/human/owner, attack_text = "the attack", final_block_chance = 0, damage = 0, attack_type = MELEE_ATTACK, atom/movable/AM) SEND_SIGNAL(src, COMSIG_ITEM_HIT_REACT, args) if(prob(final_block_chance)) owner.visible_message("[owner] blocks [attack_text] with [src]!") @@ -347,6 +348,8 @@ var/global/image/fire_overlay = image("icon" = 'icons/goonstation/effects/fire.d A.Remove(user) if(flags & DROPDEL) qdel(src) + if((flags & NODROP) && !(initial(flags) & NODROP)) //Remove NODROP is dropped + flags &= ~NODROP in_inventory = FALSE SEND_SIGNAL(src, COMSIG_ITEM_DROPPED,user) diff --git a/code/game/objects/items/devices/enginepicker.dm b/code/game/objects/items/devices/enginepicker.dm new file mode 100644 index 00000000000..e28b5b3bef5 --- /dev/null +++ b/code/game/objects/items/devices/enginepicker.dm @@ -0,0 +1,96 @@ +/* +////////// + Item meant to spawn one of the three (Tesla / Singularity / Supermatter) engines on-station at round-start. + Should be found in the CE's office. Not access-restricted. +////////// +*/ + +/obj/item/enginepicker + name = "Bluespace Engine Delivery Device" + desc = "A per-station bluespace-based delivery system for a unique engine Engineering Department's choice. Only one option can be chosen. Device self-destructs on use." + icon = 'icons/obj/device.dmi' + icon_state = "enginepicker" + + var/list/list_enginebeacons = list() + var/isactive = FALSE + +/obj/item/enginepicker/attack_self(mob/living/carbon/user) + if(usr.stat || !usr.canmove || usr.restrained()) + return + + if(!isactive) + isactive = TRUE //Self-attack spam exploit prevention + else + return + + locatebeacons() + var/default = null + var/E = input("Select the station's Engine:", "[src]", default) as null|anything in list_enginebeacons + if(E) + processchoice(E, user) + else + isactive = FALSE + return + +//This proc re-assigns all of engine beacons in the global list to a local list. +/obj/item/enginepicker/proc/locatebeacons() + LAZYCLEARLIST(list_enginebeacons) + for(var/obj/item/radio/beacon/engine/B in GLOB.engine_beacon_list) + if(B && !QDELETED(B)) //This ensures that the input pop-up won't have any qdeleted beacons + list_enginebeacons += B + +//Spawns and logs / announces the appropriate engine based on the choice made +/obj/item/enginepicker/proc/processchoice(var/obj/item/radio/beacon/engine/choice, mob/living/carbon/user) + var/issuccessful = FALSE //Check for a successful choice + var/engtype //Engine type + var/G //Generator that will be spawned + var/turf/T = get_turf(choice) + + if(choice.enginetype.len > 1) //If the beacon has multiple engine types + var/default = null + var/E = input("You have selected a combined beacon, which option would you prefer?", "[src]", default) as null|anything in choice.enginetype + if(E) + engtype = E + issuccessful = TRUE + else + isactive = FALSE + return + + if(!engtype) //If it has only one type + engtype = DEFAULTPICK(choice.enginetype, null) //This should(?) account for a possibly scrambled list with a single entry + switch(engtype) + if(ENGTYPE_TESLA) + G = /obj/machinery/the_singularitygen/tesla + if(ENGTYPE_SING) + G = /obj/machinery/the_singularitygen + + if(G) //This can only be not-null if the switch operation was successful + issuccessful = TRUE + + if(issuccessful) + clearturf(T) //qdels all items / gibs all mobs on the turf. Let's not have an SM shard spawn on top of a poor sod. + new G(T) //Spawns the switch-selected engine on the chosen beacon's turf + + var/ailist[] = list() + for(var/mob/living/silicon/ai/A in GLOB.living_mob_list) + ailist += A + if(ailist.len) + var/mob/living/silicon/ai/announcer = pick(ailist) + announcer.say(";Engine delivery detected. Type: [engtype].") //Let's announce the terrible choice to everyone + + visible_message("\The [src] begins to violently vibrate and hiss, then promptly disintegrates!") + qdel(src) //Self-destructs to prevent crew from spawning multiple engines. + else + visible_message("\The [src] buzzes! No beacon found or selected!") + isactive = FALSE + return + +//Deletes objects and mobs from the beacon's turf. +/obj/item/enginepicker/proc/clearturf(var/turf/T) + for(var/obj/item/I in T) + I.visible_message("\The [I] gets crushed to dust!") + qdel(I) + + for(var/mob/living/M in T) + M.visible_message("\The [M] gets obliterated!") + M.gib() \ No newline at end of file diff --git a/code/game/objects/items/devices/radio/beacon.dm b/code/game/objects/items/devices/radio/beacon.dm index d45bcfa2ff4..041b21ede10 100644 --- a/code/game/objects/items/devices/radio/beacon.dm +++ b/code/game/objects/items/devices/radio/beacon.dm @@ -49,8 +49,7 @@ /obj/item/radio/beacon/bacon //Probably a better way of doing this, I'm lazy. /obj/item/radio/beacon/bacon/proc/digest_delay() - spawn(600) - qdel(src) + QDEL_IN(src, 600) // SINGULO BEACON SPAWNER /obj/item/radio/beacon/syndicate @@ -85,3 +84,23 @@ playsound(src, 'sound/effects/pop.ogg', 100, 1, 1) qdel(src) return + +/obj/item/radio/beacon/engine + desc = "A label on it reads: Warning: This device is used for transportation of high-density objects used for high-yield power generation. Stay away!." + anchored = 1 //Let's not move these around. Some folk might get the idea to use these for assassinations + var/list/enginetype = list() + +/obj/item/radio/beacon/engine/Initialize() + LAZYADD(GLOB.engine_beacon_list, src) + +/obj/item/radio/beacon/engine/tesling + name = "Engine Beacon for Tesla and Singularity" + enginetype = list(ENGTYPE_TESLA, ENGTYPE_SING) + +/obj/item/radio/beacon/engine/tesla + name = "Engine Beacon for Tesla" + enginetype = list(ENGTYPE_TESLA) + +/obj/item/radio/beacon/engine/sing + name = "Engine Beacon for Singularity" + enginetype = list(ENGTYPE_SING) \ No newline at end of file diff --git a/code/game/objects/items/devices/radio/headset.dm b/code/game/objects/items/devices/radio/headset.dm index 610c257b03f..27d27b11a9b 100644 --- a/code/game/objects/items/devices/radio/headset.dm +++ b/code/game/objects/items/devices/radio/headset.dm @@ -4,6 +4,10 @@ var/radio_desc = "" icon_state = "headset" item_state = "headset" + sprite_sheets = list( + "Vox" = 'icons/mob/species/vox/ears.dmi', + "Vox Armalis" = 'icons/mob/species/armalis/ears.dmi' + ) //We read you loud and skree-er. materials = list(MAT_METAL=75) subspace_transmission = TRUE canhear_range = 0 // can't hear headsets from very far away diff --git a/code/game/objects/items/devices/scanners.dm b/code/game/objects/items/devices/scanners.dm index cad4ae25ac8..d838fe7ec0d 100644 --- a/code/game/objects/items/devices/scanners.dm +++ b/code/game/objects/items/devices/scanners.dm @@ -135,8 +135,13 @@ REAGENT SCANNER user.show_message("Key: Suffocation/Toxin/Burns/Brute", 1) user.show_message("Body Temperature: ???", 1) return - user.visible_message("[user] has analyzed [M]'s vitals."," You have analyzed [M]'s vitals.") + user.visible_message("[user] has analyzed [M]'s vitals."," You have analyzed [M]'s vitals.") + healthscan(user, M, mode, upgraded) + add_fingerprint(user) + + +proc/healthscan(mob/user, mob/living/M, mode = 1, upgraded = FALSE) if(!ishuman(M) || M.isSynthetic()) //these sensors are designed for organic life user.show_message("Analyzing Results for ERROR:\n\t Overall Status: ERROR") @@ -271,8 +276,9 @@ REAGENT SCANNER user.show_message("Subject's genes are showing minor signs of instability.") else user.show_message("Subject's genes are stable.") - add_fingerprint(user) +/obj/item/healthanalyzer/attack_self(mob/user) + toggle_mode() /obj/item/healthanalyzer/verb/toggle_mode() set name = "Switch Verbosity" diff --git a/code/game/objects/items/random_items.dm b/code/game/objects/items/random_items.dm index e51bac10005..65f00e98781 100644 --- a/code/game/objects/items/random_items.dm +++ b/code/game/objects/items/random_items.dm @@ -18,8 +18,8 @@ /obj/effect/decal/cleanable/random name = "Random Mess" -/obj/effect/decal/cleanable/random/New() - ..() +/obj/effect/decal/cleanable/random/Initialize(mapload) + . = ..() var/list/list = subtypesof(/obj/effect/decal/cleanable) - list(/obj/effect/decal/cleanable/random,/obj/effect/decal/cleanable/cobweb,/obj/effect/decal/cleanable/cobweb2) var/T = pick(list) new T(loc) diff --git a/code/game/objects/items/stacks/medical.dm b/code/game/objects/items/stacks/medical.dm index 0e95f509463..d021c0254a8 100644 --- a/code/game/objects/items/stacks/medical.dm +++ b/code/game/objects/items/stacks/medical.dm @@ -123,6 +123,19 @@ origin_tech = "biotech=2" stop_bleeding = 1800 +/obj/item/stack/medical/bruise_pack/attackby(obj/item/I, mob/user, params) + if(I.sharp) + if(get_amount() < 2) + to_chat(user, "You need at least two gauzes to do this!") + return + new /obj/item/stack/sheet/cloth(user.drop_location()) + user.visible_message("[user] cuts [src] into pieces of cloth with [I].", \ + "You cut [src] into pieces of cloth with [I].", \ + "You hear cutting.") + use(2) + else + return ..() + /obj/item/stack/medical/bruise_pack/attack(mob/living/M, mob/user) if(..()) return 1 @@ -145,6 +158,11 @@ else to_chat(user, "[affecting] is cut open, you'll need more than a bandage!") +/obj/item/stack/medical/bruise_pack/improvised + name = "improvised gauze" + singular_name = "improvised gauze" + desc = "A roll of cloth roughly cut from something that can stop bleeding, but does not heal wounds." + stop_bleeding = 900 /obj/item/stack/medical/bruise_pack/advanced name = "advanced trauma kit" diff --git a/code/game/objects/items/stacks/sheets/leather.dm b/code/game/objects/items/stacks/sheets/leather.dm index db7c08b1863..aebe5097174 100644 --- a/code/game/objects/items/stacks/sheets/leather.dm +++ b/code/game/objects/items/stacks/sheets/leather.dm @@ -133,12 +133,9 @@ var/global/list/datum/stack_recipe/sinew_recipes = list ( \ can_strengthen_clothing = typecacheof(list( /obj/item/clothing/suit/space/hardsuit/mining, /obj/item/clothing/head/helmet/space/hardsuit/mining, - /obj/item/clothing/suit/space/eva/plasmaman/miner, - /obj/item/clothing/head/helmet/space/eva/plasmaman/miner, /obj/item/clothing/suit/hooded/explorer, /obj/item/clothing/head/hooded/explorer, - /obj/item/clothing/suit/space/eva/plasmaman/explorer, - /obj/item/clothing/head/helmet/space/eva/plasmaman/explorer + /obj/item/clothing/head/helmet/space/plasmaman/mining )) /obj/item/stack/sheet/animalhide/goliath_hide/afterattack(atom/target, mob/user, proximity_flag) diff --git a/code/game/objects/items/stacks/sheets/mineral.dm b/code/game/objects/items/stacks/sheets/mineral.dm index 8c60bcefa11..c9099d6d38b 100644 --- a/code/game/objects/items/stacks/sheets/mineral.dm +++ b/code/game/objects/items/stacks/sheets/mineral.dm @@ -137,6 +137,44 @@ var/global/list/datum/stack_recipe/snow_recipes = list( ..() recipes = sandstone_recipes +/* + * Sandbags + */ + +/obj/item/stack/sheet/mineral/sandbags + name = "sandbags" + icon_state = "sandbags" + singular_name = "sandbag" + layer = LOW_ITEM_LAYER + merge_type = /obj/item/stack/sheet/mineral/sandbags + +GLOBAL_LIST_INIT(sandbag_recipes, list ( \ + new/datum/stack_recipe("sandbags", /obj/structure/barricade/sandbags, 1, time = 25, one_per_turf = 1, on_floor = 1), \ + )) + +/obj/item/stack/sheet/mineral/sandbags/New() + recipes = GLOB.sandbag_recipes + ..() + +/obj/item/emptysandbag + name = "empty sandbag" + desc = "A bag to be filled with sand." + icon = 'icons/obj/items.dmi' + icon_state = "sandbag" + w_class = WEIGHT_CLASS_TINY + +/obj/item/emptysandbag/attackby(obj/item/I, mob/user, params) + if(istype(I, /obj/item/stack/ore/glass)) + var/obj/item/stack/ore/glass/G = I + to_chat(user, "You fill the sandbag.") + var/obj/item/stack/sheet/mineral/sandbags/S = new /obj/item/stack/sheet/mineral/sandbags(drop_location()) + qdel(src) + if(Adjacent(user) && !issilicon(user)) + user.put_in_hands(S) + G.use(1) + else + return ..() + /obj/item/stack/sheet/mineral/diamond name = "diamond" icon_state = "sheet-diamond" diff --git a/code/game/objects/items/stacks/sheets/sheet_types.dm b/code/game/objects/items/stacks/sheets/sheet_types.dm index 9ec921fef92..8698a4a2bbe 100644 --- a/code/game/objects/items/stacks/sheets/sheet_types.dm +++ b/code/game/objects/items/stacks/sheets/sheet_types.dm @@ -178,8 +178,13 @@ var/global/list/datum/stack_recipe/wood_recipes = list( new /datum/stack_recipe("wooden buckler", /obj/item/shield/riot/buckler, 20, time = 40), new /datum/stack_recipe("apiary", /obj/structure/beebox, 40, time = 50), new /datum/stack_recipe("honey frame", /obj/item/honey_frame, 5, time = 10), + new /datum/stack_recipe("wooden bucket", /obj/item/reagent_containers/glass/bucket/wooden, 3, time = 10), + new /datum/stack_recipe("rake", /obj/item/cultivator/rake, 5, time = 10), + new /datum/stack_recipe("ore box", /obj/structure/ore_box, 4, time = 50, one_per_turf = TRUE, on_floor = TRUE), new /datum/stack_recipe("baseball bat", /obj/item/melee/baseball_bat, 5, time = 15), - new /datum/stack_recipe("fermenting barrel", /obj/structure/fermenting_barrel, 30, time = 50) + new /datum/stack_recipe("loom", /obj/structure/loom, 10, time = 15, one_per_turf = TRUE, on_floor = TRUE), \ + new /datum/stack_recipe("fermenting barrel", /obj/structure/fermenting_barrel, 30, time = 50), + new /datum/stack_recipe("firebrand", /obj/item/match/firebrand, 2, time = 100) ) /obj/item/stack/sheet/wood @@ -200,8 +205,9 @@ var/global/list/datum/stack_recipe/wood_recipes = list( * Cloth */ var/global/list/datum/stack_recipe/cloth_recipes = list ( \ - new/datum/stack_recipe("grey jumpsuit", /obj/item/clothing/under/color/grey, 3), \ - new/datum/stack_recipe("black shoes", /obj/item/clothing/shoes/black, 2), \ + new/datum/stack_recipe("white jumpsuit", /obj/item/clothing/under/color/white, 3), \ + new/datum/stack_recipe("white shoes", /obj/item/clothing/shoes/white, 2), \ + new/datum/stack_recipe("white scarf", /obj/item/clothing/accessory/scarf/white, 1), \ null, \ new/datum/stack_recipe("backpack", /obj/item/storage/backpack, 4), \ new/datum/stack_recipe("dufflebag", /obj/item/storage/backpack/duffel, 6), \ @@ -212,11 +218,15 @@ var/global/list/datum/stack_recipe/cloth_recipes = list ( \ new/datum/stack_recipe("chemistry bag", /obj/item/storage/bag/chemistry, 4), \ new/datum/stack_recipe("bio bag", /obj/item/storage/bag/bio, 4), \ null, \ + new/datum/stack_recipe("improvised gauze", /obj/item/stack/medical/bruise_pack/improvised, 1, 2, 6), \ new/datum/stack_recipe("rag", /obj/item/reagent_containers/glass/rag, 1), \ new/datum/stack_recipe("bedsheet", /obj/item/bedsheet, 3), \ + new/datum/stack_recipe("empty sandbag", /obj/item/emptysandbag, 4), \ null, \ new/datum/stack_recipe("fingerless gloves", /obj/item/clothing/gloves/fingerless, 1), \ - new/datum/stack_recipe("black gloves", /obj/item/clothing/gloves/color/black, 3), \ + new/datum/stack_recipe("white gloves", /obj/item/clothing/gloves/color/white, 3), \ + new/datum/stack_recipe("white softcap", /obj/item/clothing/head/soft/mime, 2), \ + new/datum/stack_recipe("white beanie", /obj/item/clothing/head/beanie, 2), \ null, \ new/datum/stack_recipe("blindfold", /obj/item/clothing/glasses/sunglasses/blindfold, 3), \ ) @@ -239,6 +249,49 @@ var/global/list/datum/stack_recipe/cloth_recipes = list ( \ /obj/item/stack/sheet/cloth/ten amount = 10 +GLOBAL_LIST_INIT(durathread_recipes, list ( \ + new/datum/stack_recipe("durathread jumpsuit", /obj/item/clothing/under/misc/durathread, 4, time = 40), + new/datum/stack_recipe("durathread beret", /obj/item/clothing/head/beret/durathread, 2, time = 40), \ + new/datum/stack_recipe("durathread beanie", /obj/item/clothing/head/beanie/durathread, 2, time = 40), \ + new/datum/stack_recipe("durathread bandana", /obj/item/clothing/mask/bandana/durathread, 1, time = 25), \ + )) + +/obj/item/stack/sheet/durathread + name = "durathread" + desc = "A fabric sown from incredibly durable threads, known for its usefulness in armor production." + singular_name = "durathread roll" + icon_state = "sheet-durathread" + item_state = "sheet-cloth" + resistance_flags = FLAMMABLE + force = 0 + throwforce = 0 + merge_type = /obj/item/stack/sheet/durathread + +/obj/item/stack/sheet/durathread/Initialize(mapload, new_amount, merge = TRUE) + recipes = GLOB.durathread_recipes + return ..() + +/obj/item/stack/sheet/cotton + name = "raw cotton bundle" + desc = "A bundle of raw cotton ready to be spun on the loom." + singular_name = "raw cotton ball" + icon_state = "sheet-cotton" + resistance_flags = FLAMMABLE + force = 0 + throwforce = 0 + merge_type = /obj/item/stack/sheet/cotton + var/pull_effort = 30 + var/loom_result = /obj/item/stack/sheet/cloth + +/obj/item/stack/sheet/cotton/durathread + name = "raw durathread bundle" + desc = "A bundle of raw durathread ready to be spun on the loom." + singular_name = "raw durathread ball" + icon_state = "sheet-durathreadraw" + merge_type = /obj/item/stack/sheet/cotton/durathread + pull_effort = 70 + loom_result = /obj/item/stack/sheet/durathread + /* * Cardboard */ diff --git a/code/game/objects/items/toys.dm b/code/game/objects/items/toys.dm index a8ddcf6d315..eda3088199e 100644 --- a/code/game/objects/items/toys.dm +++ b/code/game/objects/items/toys.dm @@ -299,7 +299,7 @@ /obj/effect/decal/cleanable/ash/snappop_phoenix var/respawn_time = 300 -/obj/effect/decal/cleanable/ash/snappop_phoenix/New() +/obj/effect/decal/cleanable/ash/snappop_phoenix/Initialize(mapload) . = ..() addtimer(CALLBACK(src, .proc/respawn), respawn_time) diff --git a/code/game/objects/items/weapons/defib.dm b/code/game/objects/items/weapons/defib.dm index fbdc403d758..45309b381c0 100644 --- a/code/game/objects/items/weapons/defib.dm +++ b/code/game/objects/items/weapons/defib.dm @@ -45,7 +45,7 @@ /obj/item/defibrillator/examine(mob/user) ..(user) - to_chat(user,"Ctrl-click to remove the paddles from the defibrillator.") + to_chat(user, "Ctrl-click to remove the paddles from the defibrillator.") /obj/item/defibrillator/proc/update_power() if(bcell) diff --git a/code/game/objects/items/weapons/kitchen.dm b/code/game/objects/items/weapons/kitchen.dm index 4f94a6b8a1b..21161c2642a 100644 --- a/code/game/objects/items/weapons/kitchen.dm +++ b/code/game/objects/items/weapons/kitchen.dm @@ -115,7 +115,8 @@ throw_range = 6 materials = list(MAT_METAL=12000) attack_verb = list("slashed", "stabbed", "sliced", "torn", "ripped", "diced", "cut") - sharp = 1 + sharp = TRUE + var/bayonet = FALSE //Can this be attached to a gun? /obj/item/kitchen/knife/suicide_act(mob/user) user.visible_message(pick("[user] is slitting [user.p_their()] wrists with the [src.name]! It looks like [user.p_theyre()] trying to commit suicide.", \ @@ -164,6 +165,7 @@ throwforce = 20 origin_tech = "materials=3;combat=4" attack_verb = list("slashed", "stabbed", "sliced", "torn", "ripped", "cut") + bayonet = TRUE /obj/item/kitchen/knife/combat/survival name = "survival knife" diff --git a/code/game/objects/items/weapons/lighters.dm b/code/game/objects/items/weapons/lighters.dm index ab946de5f0f..56d237c4eda 100644 --- a/code/game/objects/items/weapons/lighters.dm +++ b/code/game/objects/items/weapons/lighters.dm @@ -224,3 +224,13 @@ var/mask_item = M.get_item_by_slot(slot_wear_mask) if(istype(mask_item, /obj/item/clothing/mask/cigarette)) return mask_item + + +/obj/item/match/firebrand + name = "firebrand" + desc = "An unlit firebrand. It makes you wonder why it's not just called a stick." + smoketime = 20 //40 seconds + +/obj/item/match/firebrand/New() + ..() + matchignite() \ No newline at end of file diff --git a/code/game/objects/items/weapons/storage/backpack.dm b/code/game/objects/items/weapons/storage/backpack.dm index 3f638d44918..ddae7d87f85 100644 --- a/code/game/objects/items/weapons/storage/backpack.dm +++ b/code/game/objects/items/weapons/storage/backpack.dm @@ -18,8 +18,10 @@ burn_state = FLAMMABLE burntime = 20 sprite_sheets = list( - "Vox" = 'icons/mob/species/vox/back.dmi' - ) + "Vox" = 'icons/mob/species/vox/back.dmi', + "Vox Armalis" = 'icons/mob/species/armalis/back.dmi', + "Grey" = 'icons/mob/species/grey/back.dmi' + ) //For Armalis anything but this and the nitrogen tank will use the default backpack icon. /obj/item/storage/backpack/attackby(obj/item/W as obj, mob/user as mob, params) playsound(src.loc, "rustle", 50, 1, -5) diff --git a/code/game/objects/items/weapons/storage/boxes.dm b/code/game/objects/items/weapons/storage/boxes.dm index e7342774619..d4e1ed2d7f1 100644 --- a/code/game/objects/items/weapons/storage/boxes.dm +++ b/code/game/objects/items/weapons/storage/boxes.dm @@ -113,7 +113,7 @@ New() ..() contents = list() - new /obj/item/clothing/mask/breath(src) + new /obj/item/clothing/mask/gas/explorer(src) new /obj/item/tank/emergency_oxygen/engi(src) new /obj/item/crowbar/red(src) new /obj/item/reagent_containers/hypospray/autoinjector(src) @@ -372,6 +372,20 @@ new /obj/item/implantpad(src) new /obj/item/locator(src) +/obj/item/storage/box/minertracker + name = "boxed tracking implant kit" + desc = "For finding those who have died on the accursed lavaworld." + icon_state = "implant" + +/obj/item/storage/box/minertracker/New() + ..() + new /obj/item/implantcase/tracking(src) + new /obj/item/implantcase/tracking(src) + new /obj/item/implantcase/tracking(src) + new /obj/item/implanter(src) + new /obj/item/implantpad(src) + new /obj/item/locator(src) + /obj/item/storage/box/chemimp name = "chemical implant kit" desc = "Box of stuff used to implant chemicals." @@ -1045,6 +1059,15 @@ desc = "A colorful cardboard box for the clown" icon_state = "box_clown" +/obj/item/storage/box/emptysandbags + name = "box of empty sandbags" + +/obj/item/storage/box/emptysandbags/New() + ..() + contents = list() + for(var/i in 1 to 7) + new /obj/item/emptysandbag(src) + /obj/item/storage/box/rndboards name = "the Liberator's legacy" desc = "A box containing a gift for worthy golems." @@ -1082,15 +1105,6 @@ new /obj/item/stock_parts/micro_laser/quadultra(src) new /obj/item/stock_parts/matter_bin/bluespace(src) -/obj/item/storage/box/mininghardsuit - name = "Boxed Mining Hardsuit" - desc = "Contains a mining hardsuit and helmet. For mining." - -/obj/item/storage/box/mininghardsuit/New() - ..() - new /obj/item/clothing/suit/space/hardsuit/mining(src) - new /obj/item/clothing/head/helmet/space/hardsuit/mining(src) - /obj/item/storage/box/hug name = "box of hugs" desc = "A special box for sensitive people." diff --git a/code/game/objects/items/weapons/storage/briefcase.dm b/code/game/objects/items/weapons/storage/briefcase.dm index 2450648cded..0a2a8bcfbbc 100644 --- a/code/game/objects/items/weapons/storage/briefcase.dm +++ b/code/game/objects/items/weapons/storage/briefcase.dm @@ -5,7 +5,7 @@ item_state = "briefcase" flags = CONDUCT hitsound = "swing_hit" - force = 8.0 + force = 8 throw_speed = 2 throw_range = 4 w_class = WEIGHT_CLASS_BULKY @@ -20,10 +20,69 @@ force = 10 /obj/item/storage/briefcase/sniperbundle/New() - ..() + ..() new /obj/item/gun/projectile/automatic/sniper_rifle/syndicate(src) new /obj/item/clothing/accessory/red(src) new /obj/item/clothing/under/syndicate/sniper(src) new /obj/item/ammo_box/magazine/sniper_rounds/soporific(src) new /obj/item/ammo_box/magazine/sniper_rounds/soporific(src) - new /obj/item/suppressor/specialoffer(src) \ No newline at end of file + new /obj/item/suppressor/specialoffer(src) + +/obj/item/storage/briefcase/false_bottomed + max_w_class = WEIGHT_CLASS_SMALL + max_combined_w_class = 10 + + var/busy_hunting = FALSE + var/bottom_open = FALSE //is the false bottom open? + var/obj/item/stored_item = null //what's in the false bottom. If it's a gun, we can fire it + +/obj/item/storage/briefcase/false_bottomed/Destroy() + if(stored_item)//since the stored_item isn't in the briefcase' contents we gotta remind the game to delete it here. + QDEL_NULL(stored_item) + return ..() + +/obj/item/storage/briefcase/false_bottomed/afterattack(atom/A, mob/user, flag, params) + ..() + if(stored_item && istype(stored_item, /obj/item/gun) && !Adjacent(A)) + var/obj/item/gun/stored_gun = stored_item + stored_gun.afterattack(A, user, flag, params) + +/obj/item/storage/briefcase/false_bottomed/attackby(var/obj/item/I, mob/user) + if(isscrewdriver(I)) + if(!bottom_open && !busy_hunting) + to_chat(user, "You begin to hunt around the rim of the [src]...") + busy_hunting = TRUE + if(do_after(user, 20, target = src)) + if(user) + to_chat(user, "You pry open the false bottom!") + bottom_open = TRUE + busy_hunting = FALSE + else if(bottom_open) + to_chat(user, "You push the false bottom down and close it with a click[stored_item ? ", with the [stored_item] snugly inside." : "."]") + bottom_open = FALSE + else if(bottom_open) + if(stored_item) + to_chat(user, "There's already something in the false bottom!") + return + if(I.w_class > WEIGHT_CLASS_NORMAL) + to_chat(user, "The [I] is too big to fit in the false bottom!") + return + if(!user.drop_item(I)) + user << "The [I] is stuck to your hands!" + return + + stored_item = I + max_w_class = WEIGHT_CLASS_NORMAL - stored_item.w_class + I.forceMove(null) //null space here we go - to stop it showing up in the briefcase + to_chat(user, "You place the [I] into the false bottom of the briefcase.") + else + return ..() + +/obj/item/storage/briefcase/false_bottomed/attack_hand(mob/user) + if(bottom_open && stored_item) + user.put_in_hands(stored_item) + to_chat(user, "You pull out the [stored_item] from the [src]'s false bottom.") + stored_item = null + max_w_class = initial(max_w_class) + else + return ..() diff --git a/code/game/objects/items/weapons/storage/uplink_kits.dm b/code/game/objects/items/weapons/storage/uplink_kits.dm index 3736d93f3f6..a8f0af13b98 100644 --- a/code/game/objects/items/weapons/storage/uplink_kits.dm +++ b/code/game/objects/items/weapons/storage/uplink_kits.dm @@ -136,36 +136,14 @@ /obj/item/storage/box/syndie_kit/hardsuit name = "Boxed Blood Red Suit and Helmet" - can_hold = list(/obj/item/clothing/suit/space/hardsuit/syndi, /obj/item/clothing/head/helmet/space/hardsuit/syndi, /obj/item/tank/emergency_oxygen/syndi, /obj/item/clothing/mask/gas/syndicate) + can_hold = list(/obj/item/clothing/suit/space/hardsuit/syndi, /obj/item/tank/emergency_oxygen/syndi, /obj/item/clothing/mask/gas/syndicate) max_w_class = WEIGHT_CLASS_NORMAL /obj/item/storage/box/syndie_kit/hardsuit/New() ..() new /obj/item/clothing/suit/space/hardsuit/syndi(src) - new /obj/item/clothing/head/helmet/space/hardsuit/syndi(src) new /obj/item/clothing/mask/gas/syndicate(src) new /obj/item/tank/emergency_oxygen/syndi(src) - return - -/obj/item/storage/box/syndie_kit/elite_hardsuit - name = "Boxed Elite Syndicate Hardsuit and Helmet" - can_hold = list(/obj/item/clothing/suit/space/hardsuit/syndi/elite, /obj/item/clothing/head/helmet/space/hardsuit/syndi/elite) - max_w_class = WEIGHT_CLASS_NORMAL - -/obj/item/storage/box/syndie_kit/elite_hardsuit/New() - ..() - new /obj/item/clothing/suit/space/hardsuit/syndi/elite(src) - new /obj/item/clothing/head/helmet/space/hardsuit/syndi/elite(src) - -/obj/item/storage/box/syndie_kit/shielded_hardsuit - name = "Boxed Shielded Syndicate Hardsuit and Helmet" - can_hold = list(/obj/item/clothing/suit/space/hardsuit/shielded/syndi, /obj/item/clothing/head/helmet/space/hardsuit/shielded/syndi) - max_w_class = WEIGHT_CLASS_BULKY - -/obj/item/storage/box/syndie_kit/shielded_hardsuit/New() - ..() - new /obj/item/clothing/suit/space/hardsuit/shielded/syndi(src) - new /obj/item/clothing/head/helmet/space/hardsuit/shielded/syndi(src) /obj/item/storage/box/syndie_kit/conversion name = "box (CK)" diff --git a/code/game/objects/items/weapons/tanks/jetpack.dm b/code/game/objects/items/weapons/tanks/jetpack.dm index c047fc82abd..21f43073b73 100644 --- a/code/game/objects/items/weapons/tanks/jetpack.dm +++ b/code/game/objects/items/weapons/tanks/jetpack.dm @@ -48,38 +48,38 @@ return if(!on) - turn_on() + turn_on(user) to_chat(user, "You turn the jetpack on.") else - turn_off() + turn_off(user) to_chat(user, "You turn the jetpack off.") for(var/X in actions) var/datum/action/A = X A.UpdateButtonIcon() -/obj/item/tank/jetpack/proc/turn_on() +/obj/item/tank/jetpack/proc/turn_on(mob/user) on = TRUE icon_state = "[initial(icon_state)]-on" ion_trail.start() -/obj/item/tank/jetpack/proc/turn_off() +/obj/item/tank/jetpack/proc/turn_off(mob/user) on = FALSE stabilizers = FALSE icon_state = initial(icon_state) ion_trail.stop() -/obj/item/tank/jetpack/proc/allow_thrust(num, mob/living/user as mob) +/obj/item/tank/jetpack/proc/allow_thrust(num, mob/living/user) if(!on) return 0 if((num < 0.005 || air_contents.total_moles() < num)) - turn_off() + turn_off(user) return 0 var/datum/gas_mixture/removed = air_contents.remove(num) if(removed.total_moles() < 0.005) - turn_off() + turn_off(user) return 0 var/turf/T = get_turf(user) @@ -163,6 +163,65 @@ to_chat(user, "The meter on [src] indicates you are almost out of air!") playsound(user, 'sound/effects/alert.ogg', 50, 1) +/obj/item/tank/jetpack/suit + name = "hardsuit jetpack upgrade" + desc = "A modular, compact set of thrusters designed to integrate with a hardsuit. It is fueled by a tank inserted into the suit's storage compartment." + icon_state = "jetpack-mining" + item_state = "jetpack-black" + origin_tech = "materials=4;magnets=4;engineering=5" + w_class = WEIGHT_CLASS_NORMAL + actions_types = list(/datum/action/item_action/toggle_jetpack, /datum/action/item_action/jetpack_stabilization) + volume = 1 + slot_flags = null + var/datum/gas_mixture/temp_air_contents + var/obj/item/tank/tank = null + var/mob/living/carbon/human/cur_user + +/obj/item/tank/jetpack/suit/New() + ..() + STOP_PROCESSING(SSobj, src) + temp_air_contents = air_contents + +/obj/item/tank/jetpack/suit/attack_self() + return + +/obj/item/tank/jetpack/suit/cycle(mob/user) + if(!istype(loc, /obj/item/clothing/suit/space/hardsuit)) + to_chat(user, "[src] must be connected to a hardsuit!") + return + + var/mob/living/carbon/human/H = user + if(!istype(H.s_store, /obj/item/tank)) + to_chat(user, "You need a tank in your suit storage!") + return + ..() + +/obj/item/tank/jetpack/suit/turn_on(mob/user) + if(!istype(loc, /obj/item/clothing/suit/space/hardsuit) || !ishuman(loc.loc) || loc.loc != user) + return + var/mob/living/carbon/human/H = user + tank = H.s_store + air_contents = tank.air_contents + START_PROCESSING(SSobj, src) + cur_user = user + ..() + +/obj/item/tank/jetpack/suit/turn_off(mob/user) + tank = null + air_contents = temp_air_contents + STOP_PROCESSING(SSobj, src) + cur_user = null + ..() + +/obj/item/tank/jetpack/suit/process() + if(!istype(loc, /obj/item/clothing/suit/space/hardsuit) || !ishuman(loc.loc)) + turn_off(cur_user) + return + var/mob/living/carbon/human/H = loc.loc + if(!tank || tank != H.s_store) + turn_off(cur_user) + return + ..() /obj/item/tank/jetpack/rig name = "jetpack" @@ -173,7 +232,7 @@ to_chat(usr, "It's a jetpack. If you can see this, report it on the bug tracker.") return 0 -/obj/item/tank/jetpack/rig/allow_thrust(num, mob/living/user as mob) +/obj/item/tank/jetpack/rig/allow_thrust(num, mob/living/user) if(!on) return 0 @@ -182,7 +241,7 @@ var/datum/gas_mixture/removed = holder.air_supply.air_contents.remove(num) if(removed.total_moles() < 0.005) - turn_off() + turn_off(user) return 0 var/turf/T = get_turf(user) diff --git a/code/game/objects/items/weapons/tanks/tank_types.dm b/code/game/objects/items/weapons/tanks/tank_types.dm index d3814b1af98..ea178aa3345 100644 --- a/code/game/objects/items/weapons/tanks/tank_types.dm +++ b/code/game/objects/items/weapons/tanks/tank_types.dm @@ -110,9 +110,12 @@ obj/item/tank/oxygen/empty/New() air_contents.toxins = (10*ONE_ATMOSPHERE)*volume/(R_IDEAL_GAS_EQUATION*T20C) /obj/item/tank/plasma/plasmaman - desc = "The lifeblood of plasmamen. Warning: Extremely flammable, do not inhale (unless you're a plasman)." - icon_state = "plasma_fr" - distribute_pressure = ONE_ATMOSPHERE*O2STANDARD + name = "plasma internals tank" + desc = "A tank of plasma gas designed specifically for use as internals, particularly for plasma-based lifeforms. If you're not a Plasmaman, you probably shouldn't use this." + icon_state = "plasmaman_tank" + item_state = "plasmaman_tank" + force = 10 + distribute_pressure = TANK_DEFAULT_RELEASE_PRESSURE /obj/item/tank/plasma/plasmaman/examine(mob/user) if(..(user, 0)) @@ -120,6 +123,19 @@ obj/item/tank/oxygen/empty/New() to_chat(user, text("The meter on the [src.name] indicates you are almost out of plasma!")) user << sound('sound/effects/alert.ogg') + +/obj/item/tank/plasma/plasmaman/belt + icon_state = "plasmaman_tank_belt" + item_state = "plasmaman_tank_belt" + slot_flags = SLOT_BELT + force = 5 + volume = 25 + w_class = WEIGHT_CLASS_SMALL + +/obj/item/tank/plasma/plasmaman/belt/full/New() + ..() + air_contents.toxins = (10 * ONE_ATMOSPHERE) * volume / (R_IDEAL_GAS_EQUATION * T20C) + /* * Emergency Oxygen */ @@ -189,7 +205,7 @@ obj/item/tank/emergency_oxygen/double/empty/New() desc = "A tank of nitrogen." icon_state = "oxygen_fr" distribute_pressure = ONE_ATMOSPHERE*O2STANDARD - + sprite_sheets = list("Vox Armalis" = 'icons/mob/species/armalis/back.dmi') //Do it for Big Bird. /obj/item/tank/nitrogen/New() ..() @@ -206,6 +222,7 @@ obj/item/tank/emergency_oxygen/double/empty/New() desc = "A high-tech nitrogen tank designed specifically for Vox." icon_state = "emergency_vox" volume = 25 + sprite_sheets = list("Vox Armalis" = 'icons/mob/species/armalis/belt.dmi') //Do it for Big Bird. /obj/item/tank/emergency_oxygen/vox/New() ..() diff --git a/code/game/objects/items/weapons/weaponry.dm b/code/game/objects/items/weapons/weaponry.dm index b759139dba6..501f1780a0b 100644 --- a/code/game/objects/items/weapons/weaponry.dm +++ b/code/game/objects/items/weapons/weaponry.dm @@ -157,6 +157,8 @@ icon = 'icons/obj/items.dmi' icon_state = "baseball_bat" item_state = "baseball_bat" + var/deflectmode = FALSE // deflect small/medium thrown objects + var/lastdeflect force = 10 throwforce = 12 attack_verb = list("beat", "smacked") @@ -169,14 +171,54 @@ desc = "This thing looks dangerous... Dangerously good at baseball, that is." homerun_able = 1 +/obj/item/melee/baseball_bat/hit_reaction(mob/living/carbon/human/owner, attack_text, final_block_chance, damage, attack_type, atom/movable/AM) + . = ..() + if(!istype(AM, /obj/item) || attack_type != THROWN_PROJECTILE_ATTACK) + return FALSE + var/obj/item/I = AM + if(I.w_class <= WEIGHT_CLASS_NORMAL || istype(I, /obj/item/beach_ball)) // baseball bat deflecting + if(deflectmode) + if(prob(10)) + visible_message("[owner] Deflects [I] directly back at the thrower! It's a home run!", "You deflect the [I] directly back at the thrower! It's a home run!") + playsound(get_turf(owner), 'sound/weapons/homerun.ogg', 100, 1) + do_attack_animation(I, ATTACK_EFFECT_DISARM) + I.throw_at(I.thrownby, 20, 20, owner) + deflectmode = FALSE + if(!istype(I, /obj/item/beach_ball)) + lastdeflect = world.time + 3000 + return TRUE + else if(prob(30)) + visible_message("[owner] swings! And [p_they()] miss[p_es()]! How embarassing.", "You swing! You miss! Oh no!") + playsound(get_turf(owner), 'sound/weapons/thudswoosh.ogg', 50, 1, -1) + do_attack_animation(get_step(owner, pick(alldirs)), ATTACK_EFFECT_DISARM) + deflectmode = FALSE + if(!istype(I, /obj/item/beach_ball)) + lastdeflect = world.time + 3000 + return FALSE + else + visible_message("[owner] swings and deflects [I]!", "You swing and deflect the [I]!") + playsound(get_turf(owner), 'sound/weapons/baseball_hit.ogg', 50, 1, -1) + do_attack_animation(I, ATTACK_EFFECT_DISARM) + I.throw_at(get_edge_target_turf(owner, pick(cardinal)), rand(8,10), 14, owner) + deflectmode = FALSE + if(!istype(I, /obj/item/beach_ball)) + lastdeflect = world.time + 3000 + return TRUE + /obj/item/melee/baseball_bat/attack_self(mob/user) if(!homerun_able) - ..() - return + if(!deflectmode && world.time >= lastdeflect) + to_chat(user, "You prepare to deflect objects thrown at you. You cannot attack during this time.") + deflectmode = TRUE + else if(deflectmode && world.time >= lastdeflect) + to_chat(user, "You no longer deflect objects thrown at you. You can attack during this time") + deflectmode = FALSE + else + to_chat(user, "You need to wait until you can deflect again. The ability will be ready in [time2text(lastdeflect - world.time, "m:ss")]") + return ..() if(homerun_ready) to_chat(user, "You're already ready to do a home run!") - ..() - return + return ..() to_chat(user, "You begin gathering strength...") playsound(get_turf(src), 'sound/magic/lightning_chargeup.ogg', 65, 1) if(do_after(user, 90, target = user)) @@ -185,6 +227,9 @@ ..() /obj/item/melee/baseball_bat/attack(mob/living/target, mob/living/user) + if(deflectmode) + to_chat(user, "You cannot attack in deflect mode!") + return . = ..() var/atom/throw_target = get_edge_target_turf(target, user.dir) if(homerun_ready) @@ -194,7 +239,7 @@ playsound(get_turf(src), 'sound/weapons/homerun.ogg', 100, 1) homerun_ready = 0 return - else + else if(!target.anchored) target.throw_at(throw_target, rand(1,2), 7, user) /obj/item/melee/baseball_bat/ablative diff --git a/code/game/objects/structures/bedsheet_bin.dm b/code/game/objects/structures/bedsheet_bin.dm index 43f45647985..d7900d82e38 100644 --- a/code/game/objects/structures/bedsheet_bin.dm +++ b/code/game/objects/structures/bedsheet_bin.dm @@ -34,6 +34,15 @@ LINEN BINS add_fingerprint(user) return +/obj/item/bedsheet/attackby(obj/item/I, mob/user, params) + if(I.sharp) + var/obj/item/stack/sheet/cloth/C = new (get_turf(src), 3) + transfer_fingerprints_to(C) + C.add_fingerprint(user) + qdel(src) + to_chat(user, "You tear [src] up.") + else + return ..() /obj/item/bedsheet/blue icon_state = "sheetblue" diff --git a/code/game/objects/structures/crates_lockers/closets.dm b/code/game/objects/structures/crates_lockers/closets.dm index 2037293d734..dba81195e6e 100644 --- a/code/game/objects/structures/crates_lockers/closets.dm +++ b/code/game/objects/structures/crates_lockers/closets.dm @@ -105,7 +105,7 @@ continue if(istype(M, /mob/living/simple_animal/bot/mulebot)) continue - if(M.buckled) + if(M.buckled || M.anchored) continue M.forceMove(src) diff --git a/code/game/objects/structures/crates_lockers/closets/cardboardbox.dm b/code/game/objects/structures/crates_lockers/closets/cardboardbox.dm index 19e08c15bde..f642960e52e 100644 --- a/code/game/objects/structures/crates_lockers/closets/cardboardbox.dm +++ b/code/game/objects/structures/crates_lockers/closets/cardboardbox.dm @@ -15,15 +15,19 @@ var/move_delay = 0 var/egged = 0 -/obj/structure/closet/cardboard/relaymove(mob/user, direction) - if(opened || move_delay || user.stat || user.stunned || user.weakened || user.paralysis || !isturf(loc) || !has_gravity(loc)) +/obj/structure/closet/cardboard/relaymove(mob/living/user, direction) + if(!istype(user) || opened || move_delay || user.incapacitated() || !isturf(loc) || !has_gravity(loc)) return - move_delay = 1 - if(step(src, direction)) - spawn(config.walk_speed) - move_delay = 0 + move_delay = TRUE + var/oldloc = loc + step(src, direction) + if(oldloc != loc) + addtimer(CALLBACK(src, .proc/ResetMoveDelay), config.walk_speed) else - move_delay = 0 + move_delay = FALSE + +/obj/structure/closet/cardboard/proc/ResetMoveDelay() + move_delay = FALSE /obj/structure/closet/cardboard/open() if(opened || !can_open()) diff --git a/code/game/objects/structures/crates_lockers/closets/fireaxe.dm b/code/game/objects/structures/crates_lockers/closets/fireaxe.dm index acedb317bb3..d22f0a59a61 100644 --- a/code/game/objects/structures/crates_lockers/closets/fireaxe.dm +++ b/code/game/objects/structures/crates_lockers/closets/fireaxe.dm @@ -6,203 +6,194 @@ icon_state = "fireaxe1000" icon_closed = "fireaxe1000" icon_opened = "fireaxe1100" - anchored = 1 - density = 0 + anchored = TRUE + density = FALSE armor = list(melee = 50, bullet = 50, laser = 50, energy = 100, bomb = 10, bio = 100, rad = 100) - var/localopened = 0 //Setting this to keep it from behaviouring like a normal closet and obstructing movement in the map. -Agouri - opened = 1 - var/hitstaken = 0 - locked = 1 - var/smashed = 0 + var/localopened = FALSE //Setting this to keep it from behaviouring like a normal closet and obstructing movement in the map. -Agouri + opened = TRUE + var/hitstaken = FALSE + locked = TRUE + var/smashed = FALSE - attackby(var/obj/item/O as obj, var/mob/living/user as mob) //Marker -Agouri - //..() //That's very useful, Erro +/obj/structure/closet/fireaxecabinet/examine(mob/user) + . = ..() + to_chat(user, "Use a multitool to lock/unlock it.") - var/hasaxe = 0 //gonna come in handy later~ - if(fireaxe) - hasaxe = 1 - - if(isrobot(user) || src.locked) - if(istype(O, /obj/item/multitool)) - to_chat(user, "Resetting circuitry...") - playsound(user, 'sound/machines/lockreset.ogg', 50, 1) - if(do_after(user, 20 * O.toolspeed, target = src)) - src.locked = 0 - to_chat(user, " You disable the locking modules.") - update_icon() - return - else if(istype(O, /obj/item)) - user.changeNext_move(CLICK_CD_MELEE) - var/obj/item/W = O - if(src.smashed || src.localopened) - if(localopened) - localopened = 0 - icon_state = text("fireaxe[][][][]closing",hasaxe,src.localopened,src.hitstaken,src.smashed) - spawn(10) update_icon() - return - else - user.do_attack_animation(src) - playsound(user, 'sound/effects/Glasshit.ogg', 100, 1) //We don't want this playing every time - if(W.force < 15) - to_chat(user, "The cabinet's protective glass glances off the hit.") - else - src.hitstaken++ - if(src.hitstaken == 4) - playsound(user, 'sound/effects/glassbr3.ogg', 100, 1) //Break cabinet, receive goodies. Cabinet's fucked for life after that. - src.smashed = 1 - src.locked = 0 - src.localopened = 1 +/obj/structure/closet/fireaxecabinet/attackby(var/obj/item/O as obj, var/mob/living/user as mob) //Marker -Agouri + if(isrobot(user) || locked) + if(istype(O, /obj/item/multitool)) + to_chat(user, "Resetting circuitry...") + playsound(user, 'sound/machines/lockreset.ogg', 50, 1) + if(do_after(user, 20 * O.toolspeed, target = src)) + locked = FALSE + to_chat(user, " You disable the locking modules.") update_icon() return - if(istype(O, /obj/item/twohanded/fireaxe) && src.localopened) - if(!fireaxe) - if(O:wielded) - to_chat(user, "Unwield the axe first.") - return - fireaxe = O - user.drop_item(O) - src.contents += O - to_chat(user, "You place the fire axe back in the [src.name].") - update_icon() - else - if(src.smashed) - return - else - localopened = !localopened - if(localopened) - icon_state = text("fireaxe[][][][]opening",hasaxe,src.localopened,src.hitstaken,src.smashed) - spawn(10) update_icon() - else - icon_state = text("fireaxe[][][][]closing",hasaxe,src.localopened,src.hitstaken,src.smashed) - spawn(10) update_icon() - else - if(src.smashed) - return - if(istype(O, /obj/item/multitool)) + else if(istype(O, /obj/item)) + user.changeNext_move(CLICK_CD_MELEE) + var/obj/item/W = O + if(smashed || localopened) if(localopened) - localopened = 0 - icon_state = text("fireaxe[][][][]closing",hasaxe,src.localopened,src.hitstaken,src.smashed) - spawn(10) update_icon() - return - else - to_chat(user, "Resetting circuitry...") - sleep(50) - src.locked = 1 - to_chat(user, "You re-enable the locking modules.") - playsound(user, 'sound/machines/lockenable.ogg', 50, 1) - if(do_after(user, 20 * O.toolspeed, target = src)) - src.locked = 1 - to_chat(user, " You re-enable the locking modules.") - return + localopened = FALSE + update_icon_closing() + return + else + user.do_attack_animation(src) + playsound(user, 'sound/effects/Glasshit.ogg', 100, 1) //We don't want this playing every time + if(W.force < 15) + to_chat(user, "The cabinet's protective glass glances off the hit.") + else + hitstaken++ + if(hitstaken == 4) + playsound(user, 'sound/effects/glassbr3.ogg', 100, 1) //Break cabinet, receive goodies. Cabinet's fucked for life after that. + smashed = TRUE + locked = FALSE + localopened = TRUE + update_icon() + return + if(istype(O, /obj/item/twohanded/fireaxe) && localopened) + if(!fireaxe) + var/obj/item/twohanded/fireaxe/F = O + if(F.wielded) + to_chat(user, "Unwield \the [F] first.") + return + if(!user.unEquip(F, FALSE)) + to_chat(user, "\The [F] stays stuck to your hands!") + return + fireaxe = F + contents += F + to_chat(user, "You place \the [F] back in the [name].") + update_icon() + else + if(smashed) + return else localopened = !localopened if(localopened) - icon_state = text("fireaxe[][][][]opening",hasaxe,src.localopened,src.hitstaken,src.smashed) - spawn(10) update_icon() + update_icon_opening() else - icon_state = text("fireaxe[][][][]closing",hasaxe,src.localopened,src.hitstaken,src.smashed) - spawn(10) update_icon() - - - - - attack_hand(mob/user as mob) - - var/hasaxe = 0 - if(fireaxe) - hasaxe = 1 - - if(src.locked) - to_chat(user, "The cabinet won't budge!") + update_icon_closing() + else + if(smashed) return - if(localopened) - if(fireaxe) - user.put_in_hands(fireaxe) - fireaxe = null - to_chat(user, "You take the fire axe from the [name].") - src.add_fingerprint(user) - update_icon() - else - if(src.smashed) - return - else - localopened = !localopened - if(localopened) - src.icon_state = text("fireaxe[][][][]opening",hasaxe,src.localopened,src.hitstaken,src.smashed) - spawn(10) update_icon() - else - src.icon_state = text("fireaxe[][][][]closing",hasaxe,src.localopened,src.hitstaken,src.smashed) - spawn(10) update_icon() - - else - localopened = !localopened //I'm pretty sure we don't need an if(src.smashed) in here. In case I'm wrong and it fucks up teh cabinet, **MARKER**. -Agouri + if(istype(O, /obj/item/multitool)) if(localopened) - src.icon_state = text("fireaxe[][][][]opening",hasaxe,src.localopened,src.hitstaken,src.smashed) - spawn(10) update_icon() + localopened = FALSE + update_icon_closing() + return else - src.icon_state = text("fireaxe[][][][]closing",hasaxe,src.localopened,src.hitstaken,src.smashed) - spawn(10) update_icon() - - attack_tk(mob/user as mob) - if(localopened && fireaxe) - fireaxe.forceMove(loc) - to_chat(user, "You telekinetically remove the fire axe.") - fireaxe = null - update_icon() - return - attack_hand(user) - - verb/toggle_openness() //nice name, huh? HUH?! -Erro //YEAH -Agouri - set name = "Open/Close" - set category = "Object" - - if(isrobot(usr) || src.locked || src.smashed) - if(src.locked) - to_chat(usr, "The cabinet won't budge!") - else if(src.smashed) - to_chat(usr, "The protective glass is broken!") - return - - localopened = !localopened - update_icon() - - verb/remove_fire_axe() - set name = "Remove Fire Axe" - set category = "Object" - - if(isrobot(usr)) - return - - if(localopened) - if(fireaxe) - usr.put_in_hands(fireaxe) - fireaxe = null - to_chat(usr, "You take the Fire axe from the [name].") - else - to_chat(usr, "The [src.name] is empty.") + to_chat(user, "Resetting circuitry...") + playsound(user, 'sound/machines/lockenable.ogg', 50, 1) + if(do_after(user, 20 * O.toolspeed, target = src)) + locked = TRUE + to_chat(user, " You re-enable the locking modules.") + return else - to_chat(usr, "The [src.name] is closed.") - update_icon() - - attack_ai(mob/user as mob) - if(src.smashed) - to_chat(user, "The security of the cabinet is compromised.") - return - else - locked = !locked - if(locked) - to_chat(user, "Cabinet locked.") + localopened = !localopened + if(localopened) + update_icon_opening() else - to_chat(user, "Cabinet unlocked.") + update_icon_closing() - update_icon() //Template: fireaxe[has fireaxe][is opened][hits taken][is smashed]. If you want the opening or closing animations, add "opening" or "closing" right after the numbers - var/hasaxe = 0 +/obj/structure/closet/fireaxecabinet/attack_hand(mob/user as mob) + if(locked) + to_chat(user, "The cabinet won't budge!") + return + if(localopened) if(fireaxe) - hasaxe = 1 - icon_state = text("fireaxe[][][][]",hasaxe,src.localopened,src.hitstaken,src.smashed) + user.put_in_hands(fireaxe) + to_chat(user, "You take \the [fireaxe] from the [src].") + fireaxe = null + + add_fingerprint(user) + update_icon() + else + if(smashed) + return + else + localopened = !localopened + if(localopened) + update_icon_opening() + else + update_icon_closing() - open() + else + localopened = !localopened //I'm pretty sure we don't need an if(smashed) in here. In case I'm wrong and it fucks up teh cabinet, **MARKER**. -Agouri + if(localopened) + update_icon_opening() + else + update_icon_closing() + +/obj/structure/closet/fireaxecabinet/attack_tk(mob/user as mob) + if(localopened && fireaxe) + fireaxe.forceMove(loc) + to_chat(user, "You telekinetically remove \the [fireaxe].") + fireaxe = null + update_icon() + return + attack_hand(user) + +/obj/structure/closet/fireaxecabinet/verb/toggle_openness() //nice name, huh? HUH?! -Erro //YEAH -Agouri + set name = "Open/Close" + set category = "Object" + + if(isrobot(usr) || locked || smashed) + if(locked) + to_chat(usr, "The cabinet won't budge!") + else if(smashed) + to_chat(usr, "The protective glass is broken!") return - close() - return \ No newline at end of file + localopened = !localopened + update_icon() + +/obj/structure/closet/fireaxecabinet/verb/remove_fire_axe() + set name = "Remove Fire Axe" + set category = "Object" + + if(isrobot(usr)) + return + + if(localopened) + if(fireaxe) + usr.put_in_hands(fireaxe) + to_chat(usr, "You take \the [fireaxe] from the [src].") + fireaxe = null + else + to_chat(usr, "The [src] is empty.") + else + to_chat(usr, "The [src] is closed.") + update_icon() + +/obj/structure/closet/fireaxecabinet/attack_ai(mob/user as mob) + if(smashed) + to_chat(user, "The security of the cabinet is compromised.") + return + else + locked = !locked + if(locked) + to_chat(user, "Cabinet locked.") + else + to_chat(user, "Cabinet unlocked.") + +/obj/structure/closet/fireaxecabinet/proc/update_icon_opening() + var/hasaxe = fireaxe != null + icon_state = "fireaxe[hasaxe][localopened][hitstaken][smashed]opening" + spawn(10) + update_icon() + +/obj/structure/closet/fireaxecabinet/proc/update_icon_closing() + var/hasaxe = fireaxe != null + icon_state = "fireaxe[hasaxe][localopened][hitstaken][smashed]closing" + spawn(10) + update_icon() + +/obj/structure/closet/fireaxecabinet/update_icon() //Template: fireaxe[has fireaxe][is opened][hits taken][is smashed]. If you want the opening or closing animations, add "opening" or "closing" right after the numbers + var/hasaxe = fireaxe != null + icon_state = "fireaxe[hasaxe][localopened][hitstaken][smashed]" + +/obj/structure/closet/fireaxecabinet/open() + return + +/obj/structure/closet/fireaxecabinet/close() + return \ No newline at end of file diff --git a/code/game/objects/structures/crates_lockers/closets/secure/engineering.dm b/code/game/objects/structures/crates_lockers/closets/secure/engineering.dm index 0cd6e541398..0608eb64cbb 100644 --- a/code/game/objects/structures/crates_lockers/closets/secure/engineering.dm +++ b/code/game/objects/structures/crates_lockers/closets/secure/engineering.dm @@ -25,6 +25,7 @@ new /obj/item/clothing/glasses/welding/superior(src) new /obj/item/clothing/gloves/color/yellow(src) new /obj/item/clothing/shoes/brown(src) + new /obj/item/tank/jetpack/suit(src) new /obj/item/cartridge/ce(src) new /obj/item/radio/headset/heads/ce(src) new /obj/item/storage/toolbox/mechanical(src) @@ -147,3 +148,4 @@ new /obj/item/clothing/suit/fire/atmos(src) new /obj/item/clothing/head/hardhat/atmos(src) new /obj/item/rpd(src) + new /obj/item/destTagger(src) diff --git a/code/game/objects/structures/crates_lockers/closets/secure/medical.dm b/code/game/objects/structures/crates_lockers/closets/secure/medical.dm index 189cbc5893d..73dbc88487a 100644 --- a/code/game/objects/structures/crates_lockers/closets/secure/medical.dm +++ b/code/game/objects/structures/crates_lockers/closets/secure/medical.dm @@ -273,6 +273,7 @@ new /obj/item/key/ambulance(src) new /obj/item/pinpointer/crew(src) new /obj/item/clothing/shoes/magboots(src) + new /obj/item/handheld_defibrillator(src) /obj/structure/closet/secure_closet/reagents name = "chemical storage closet" diff --git a/code/game/objects/structures/crates_lockers/closets/secure/miscjobs.dm b/code/game/objects/structures/crates_lockers/closets/secure/miscjobs.dm index 37669a47938..a1e4cd03239 100644 --- a/code/game/objects/structures/crates_lockers/closets/secure/miscjobs.dm +++ b/code/game/objects/structures/crates_lockers/closets/secure/miscjobs.dm @@ -54,7 +54,7 @@ /obj/structure/closet/secure_closet/syndicate_officer/New() ..() - new /obj/item/storage/box/syndie_kit/elite_hardsuit(src) + new /obj/item/clothing/suit/space/hardsuit/syndi/elite(src) new /obj/item/gun/projectile/automatic/sniper_rifle/syndicate(src) new /obj/item/ammo_box/magazine/sniper_rounds/penetrator(src) new /obj/item/ammo_box/magazine/sniper_rounds/penetrator(src) diff --git a/code/game/objects/structures/crates_lockers/closets/secure/security.dm b/code/game/objects/structures/crates_lockers/closets/secure/security.dm index fe6b0082207..2501c32c2a6 100644 --- a/code/game/objects/structures/crates_lockers/closets/secure/security.dm +++ b/code/game/objects/structures/crates_lockers/closets/secure/security.dm @@ -251,7 +251,7 @@ new /obj/item/melee/baton/loaded(src) new /obj/item/clothing/glasses/sunglasses(src) new /obj/item/clothing/glasses/hud/security/sunglasses/read_only(src) - new /obj/item/clothing/glasses/hud/health/health_advanced + new /obj/item/clothing/glasses/hud/health/sunglasses new /obj/item/clothing/head/beret/centcom/officer(src) new /obj/item/clothing/head/beret/centcom/officer/navy(src) new /obj/item/clothing/suit/armor/vest/blueshield(src) diff --git a/code/game/objects/structures/crates_lockers/closets/syndicate.dm b/code/game/objects/structures/crates_lockers/closets/syndicate.dm index 493554ea25d..3c3ea235b58 100644 --- a/code/game/objects/structures/crates_lockers/closets/syndicate.dm +++ b/code/game/objects/structures/crates_lockers/closets/syndicate.dm @@ -23,7 +23,6 @@ /obj/structure/closet/syndicate/suits/New() ..() - new /obj/item/clothing/head/helmet/space/hardsuit/syndi(src) new /obj/item/clothing/mask/gas/syndicate(src) new /obj/item/clothing/suit/space/hardsuit/syndi(src) new /obj/item/tank/jetpack/oxygen/harness(src) @@ -61,7 +60,6 @@ new /obj/item/clothing/glasses/thermal(src) new /obj/item/clothing/shoes/magboots/syndie/advance(src) new /obj/item/clothing/mask/gas/syndicate(src) - new /obj/item/clothing/head/helmet/space/hardsuit/syndi/elite/sst(src) new /obj/item/clothing/suit/space/hardsuit/syndi/elite/sst(src) /obj/structure/closet/syndicate/resources/ diff --git a/code/game/objects/structures/crates_lockers/crates.dm b/code/game/objects/structures/crates_lockers/crates.dm index d44ec20c515..4a2dadffcc7 100644 --- a/code/game/objects/structures/crates_lockers/crates.dm +++ b/code/game/objects/structures/crates_lockers/crates.dm @@ -5,9 +5,9 @@ icon_state = "crate" icon_opened = "crateopen" icon_closed = "crate" - climbable = 1 + climbable = TRUE // mouse_drag_pointer = MOUSE_ACTIVE_POINTER //??? - var/rigged = 0 + var/rigged = FALSE var/obj/item/paper/manifest/manifest // A list of beacon names that the crate will announce the arrival of, when delivered. var/list/announce_beacons = list() @@ -23,16 +23,16 @@ overlays += "manifest" /obj/structure/closet/crate/can_open() - return 1 + return TRUE /obj/structure/closet/crate/can_close() - return 1 + return TRUE /obj/structure/closet/crate/open() if(src.opened) - return 0 + return FALSE if(!src.can_open()) - return 0 + return FALSE if(rigged && locate(/obj/item/radio/electropack) in src) if(isliving(usr)) @@ -47,18 +47,18 @@ for(var/mob/M in src) //Mobs M.forceMove(loc) icon_state = icon_opened - src.opened = 1 + src.opened = TRUE if(climbable) structure_shaken() - return 1 + return TRUE /obj/structure/closet/crate/close() if(!src.opened) - return 0 + return FALSE if(!src.can_close()) - return 0 + return FALSE playsound(src.loc, 'sound/machines/click.ogg', 15, 1, -3) var/itemcount = 0 @@ -75,8 +75,8 @@ itemcount++ icon_state = icon_closed - src.opened = 0 - return 1 + src.opened = FALSE + return TRUE /obj/structure/closet/crate/attackby(obj/item/W, mob/user, params) if(istype(W, /obj/item/rcs) && !src.opened) @@ -105,7 +105,7 @@ return playsound(E.loc, E.usesound, 50, 1) to_chat(user, "Teleporting [src.name]...") - E.teleporting = 1 + E.teleporting = TRUE if(!do_after(user, 50 * E.toolspeed, target = src)) E.teleporting = 0 return @@ -127,9 +127,9 @@ return playsound(E.loc, E.usesound, 50, 1) to_chat(user, "Teleporting [src.name]...") - E.teleporting = 1 + E.teleporting = TRUE if(!do_after(user, 50 * E.toolspeed, target = src)) - E.teleporting = 0 + E.teleporting = FALSE return E.teleporting = 0 if(!(E.rcell && E.rcell.use(E.chargecost))) @@ -154,14 +154,16 @@ else if(istype(W, /obj/item/stack/packageWrap)) return else if(istype(W, /obj/item/stack/cable_coil)) + var/obj/item/stack/cable_coil/C = W if(rigged) to_chat(user, "[src] is already rigged!") return - to_chat(user, "You rig [src].") - user.drop_item() - qdel(W) - rigged = 1 - return + if(C.use(15)) + to_chat(user, "You rig [src].") + rigged = TRUE + else + to_chat(user, "You need atleast 15 wires to rig [src]!") + return else if(istype(W, /obj/item/radio/electropack)) if(rigged) to_chat(user, "You attach [W] to [src].") @@ -172,7 +174,7 @@ if(rigged) to_chat(user, "You cut away the wiring.") playsound(loc, W.usesound, 100, 1) - rigged = 0 + rigged = FALSE return else return attack_hand(user) @@ -653,4 +655,4 @@ new /obj/item/storage/bag/ore(src) new /obj/item/clothing/glasses/meson(src) new /obj/item/card/id/golem(src) - new /obj/item/flashlight/lantern(src) \ No newline at end of file + new /obj/item/flashlight/lantern(src) diff --git a/code/game/objects/structures/displaycase.dm b/code/game/objects/structures/displaycase.dm index c03b9694cfa..497644a1926 100644 --- a/code/game/objects/structures/displaycase.dm +++ b/code/game/objects/structures/displaycase.dm @@ -6,7 +6,7 @@ GLOBAL_LIST_INIT(captain_display_cases, list()) /proc/updateDisplaycase(mob/living/carbon/human/captain) if(!GLOB.captain_display_cases.len) - return + return var/fingerprint = captain.get_full_print() for(var/item in GLOB.captain_display_cases) var/obj/structure/displaycase/CASE = item @@ -113,6 +113,11 @@ GLOBAL_LIST_INIT(captain_display_cases, list()) occupant = new start_showpiece_type(src) update_icon() +/obj/structure/displaycase/Destroy() + dump() + QDEL_NULL(circuit) + return ..() + /obj/structure/displaycase/captains_laser name = "captain's display case" desc = "A display case for the captain's antique laser gun. Hooked up with an anti-theft system." @@ -125,6 +130,16 @@ GLOBAL_LIST_INIT(captain_display_cases, list()) . = ..() GLOB.captain_display_cases += src +/obj/structure/displaycase/captains_laser/Destroy() + GLOB.captain_display_cases -= src + return ..() + +/obj/structure/displaycase/lavaland_winter + burglar_alarm = TRUE + locked = TRUE + req_access = list(access_cent_specops) + start_showpiece_type = /obj/item/gun/energy/laser/captain + /obj/structure/displaycase/stechkin name = "officer's display case" desc = "A display case containing a humble stechkin pistol. Never forget your roots." @@ -132,15 +147,6 @@ GLOBAL_LIST_INIT(captain_display_cases, list()) req_access = list(access_syndicate_command) start_showpiece_type = /obj/item/gun/projectile/automatic/pistol -/obj/structure/displaycase/Destroy() - dump() - QDEL_NULL(circuit) - return ..() - -/obj/structure/displaycase/captains_laser/Destroy() - GLOB.captain_display_cases -= src - return ..() - /obj/structure/displaycase/examine(mob/user) ..(user) to_chat(user, "Peering through the glass, you see that it contains:") diff --git a/code/game/objects/structures/false_walls.dm b/code/game/objects/structures/false_walls.dm index 4a70729d7e9..9f3829a8277 100644 --- a/code/game/objects/structures/false_walls.dm +++ b/code/game/objects/structures/false_walls.dm @@ -97,12 +97,9 @@ else icon_state = "fwall_open" -/obj/structure/falsewall/proc/ChangeToWall(delete = 1) +/obj/structure/falsewall/proc/ChangeToWall(delete = TRUE) var/turf/T = get_turf(src) - if(!walltype || walltype == "metal") - T.ChangeTurf(/turf/simulated/wall) - else - T.ChangeTurf(text2path("/turf/simulated/wall/mineral/[walltype]")) + T.ChangeTurf(walltype) if(delete) qdel(src) return T diff --git a/code/game/objects/structures/flora.dm b/code/game/objects/structures/flora.dm index bd97d611576..9c51cc0d451 100644 --- a/code/game/objects/structures/flora.dm +++ b/code/game/objects/structures/flora.dm @@ -260,6 +260,14 @@ ..() icon_state = "rockpile[rand(1,5)]" +/obj/structure/flora/rock/icy + name = "icy rock" + color = "#cce9eb" + +/obj/structure/flora/rock/pile/icy + name = "icy rocks" + color = "#cce9eb" + /obj/structure/flora/corn_stalk name = "corn stalk" icon = 'icons/obj/flora/plants.dmi' diff --git a/code/game/objects/structures/ladders.dm b/code/game/objects/structures/ladders.dm index 97bd986ceb9..14ee2765d02 100644 --- a/code/game/objects/structures/ladders.dm +++ b/code/game/objects/structures/ladders.dm @@ -1,33 +1,59 @@ +// Basic ladder. By default links to the z-level above/below. /obj/structure/ladder name = "ladder" desc = "A sturdy metal ladder." icon = 'icons/obj/structures.dmi' icon_state = "ladder11" - anchored = 1 - var/id = null - var/height = 0 //the 'height' of the ladder. higher numbers are considered physically higher - var/obj/structure/ladder/down = null //the ladder below this one - var/obj/structure/ladder/up = null //the ladder above this one - var/use_verb = "climbs" + anchored = TRUE + var/obj/structure/ladder/down //the ladder below this one + var/obj/structure/ladder/up //the ladder above this one + var/use_verb = "climb" -/obj/structure/ladder/New() - spawn(8) - for(var/obj/structure/ladder/L in world) - if(L.id == id) - if(L.height == (height - 1)) - down = L - if(isnull(L.up)) - L.up = src - continue - if(L.height == (height + 1)) - up = L - if(isnull(L.down)) - L.down = src - continue +/obj/structure/ladder/Initialize(mapload, obj/structure/ladder/up, obj/structure/ladder/down) + . = ..() + if (up) + src.up = up + up.down = src + up.update_icon() + if (down) + src.down = down + down.up = src + down.update_icon() + return INITIALIZE_HINT_LATELOAD - if(up && down) //if both our connections are filled - break - update_icon() +/obj/structure/ladder/Destroy(force) + if((resistance_flags & INDESTRUCTIBLE) && !force) + return QDEL_HINT_LETMELIVE + disconnect() + return ..() + +/obj/structure/ladder/LateInitialize() + // By default, discover ladders above and below us vertically + var/turf/T = get_turf(src) + + if(!down) + for(var/obj/structure/ladder/L in locate(T.x, T.y, T.z - 1)) + down = L + L.up = src // Don't waste effort looping the other way + L.update_icon() + break + if(!up) + for (var/obj/structure/ladder/L in locate(T.x, T.y, T.z + 1)) + up = L + L.down = src // Don't waste effort looping the other way + L.update_icon() + break + + update_icon() + +/obj/structure/ladder/proc/disconnect() + if(up && up.down == src) + up.down = null + up.update_icon() + if(down && down.up == src) + down.up = null + down.update_icon() + up = down = null /obj/structure/ladder/update_icon() if(up && down) @@ -42,61 +68,134 @@ else //wtf make your ladders properly assholes icon_state = "ladder00" -/obj/structure/ladder/attack_hand(mob/user as mob) +/obj/structure/ladder/singularity_pull() + if(!(resistance_flags & INDESTRUCTIBLE)) + visible_message("[src] is torn to pieces by the gravitational pull!") + qdel(src) + +/obj/structure/ladder/proc/travel(going_up, mob/user, is_ghost, obj/structure/ladder/ladder) + if(!is_ghost) + show_fluff_message(going_up, user) + ladder.add_fingerprint(user) + + var/turf/T = get_turf(ladder) + var/atom/movable/AM + if(user.pulling) + AM = user.pulling + AM.forceMove(T) + user.forceMove(T) + if(AM) + user.start_pulling(AM) + +/obj/structure/ladder/proc/use(mob/user, is_ghost = FALSE) + if(!is_ghost && !in_range(src, user)) + return + if(up && down) - switch( alert("Go up or down the ladder?", "Ladder", "Up", "Down", "Cancel") ) + var/result = alert("Go up or down [src]?", "[name]", "Up", "Down", "Cancel") + if (!is_ghost && !in_range(src, user)) + return // nice try + switch(result) if("Up") - user.visible_message("[user] climbs up \the [src]!", \ - "You climb up \the [src]!") - user.forceMove(get_turf(up)) - up.add_fingerprint(user) + travel(TRUE, user, is_ghost, up) if("Down") - user.visible_message("[user] climbs down \the [src]!", \ - "You climb down \the [src]!") - user.forceMove(get_turf(down)) - down.add_fingerprint(user) + travel(FALSE, user, is_ghost, down) if("Cancel") return - else if(up) - user.visible_message("[user] climbs up \the [src]!", \ - "You climb up \the [src]!") - user.forceMove(get_turf(up)) - up.add_fingerprint(user) - + travel(TRUE, user, is_ghost, up) else if(down) - user.visible_message("[user] climbs down \the [src]!", \ - "You climb down \the [src]!") - user.forceMove(get_turf(down)) - down.add_fingerprint(user) + travel(FALSE, user, is_ghost, down) + else + to_chat(user, "[src] doesn't seem to lead anywhere!") - add_fingerprint(user) + if(!is_ghost) + add_fingerprint(user) -/obj/structure/ladder/attackby(obj/item/W, mob/user as mob, params) - return attack_hand(user) +/obj/structure/ladder/attack_hand(mob/user) + use(user) -/obj/structure/ladder/dive_point/buoy +/obj/structure/ladder/attackby(obj/item/W, mob/user, params) + return use(user) + +/obj/structure/ladder/attack_robot(mob/living/silicon/robot/R) + if(R.Adjacent(src)) + return use(R) + +//ATTACK GHOST IGNORING PARENT RETURN VALUE +/obj/structure/ladder/attack_ghost(mob/dead/observer/user) + use(user, TRUE) + +/obj/structure/ladder/proc/show_fluff_message(going_up, mob/user) + if(going_up) + user.visible_message("[user] climbs up [src].","You [use_verb] up [src].") + else + user.visible_message("[user] climbs down [src].","You [use_verb] down [src].") + + +// Indestructible away mission ladders which link based on a mapped ID and height value rather than X/Y/Z. +/obj/structure/ladder/unbreakable + name = "sturdy ladder" + desc = "An extremely sturdy metal ladder." + resistance_flags = INDESTRUCTIBLE + var/id + var/height = 0 // higher numbers are considered physically higher + +/obj/structure/ladder/unbreakable/Initialize(mapload) + GLOB.ladders += src + return ..() + +/obj/structure/ladder/unbreakable/Destroy() + . = ..() + if(. != QDEL_HINT_LETMELIVE) + GLOB.ladders -= src + +/obj/structure/ladder/unbreakable/LateInitialize() + // Override the parent to find ladders based on being height-linked + if(!id || (up && down)) + update_icon() + return + + for(var/O in GLOB.ladders) + var/obj/structure/ladder/unbreakable/L = O + if(L.id != id) + continue // not one of our pals + if(!down && L.height == height - 1) + down = L + L.up = src + L.update_icon() + if (up) + break // break if both our connections are filled + else if(!up && L.height == height + 1) + up = L + L.down = src + L.update_icon() + if (down) + break // break if both our connections are filled + + update_icon() + +/obj/structure/ladder/unbreakable/dive_point/buoy name = "diving point buoy" desc = "A buoy marking the location of an underwater dive area." icon = 'icons/misc/beach.dmi' icon_state = "buoy" id = "dive" height = 2 - use_verb = "dives" + use_verb = "swim" layer = MOB_LAYER + 0.2 //0.1 higher than the water overlay, this also means people can "swim" behind/under it -/obj/structure/ladder/dive_point/anchor +/obj/structure/ladder/unbreakable/dive_point/anchor name = "diving point anchor" desc = "An anchor tethered to the buoy at the surface, to keep the dive area marked." icon = 'icons/misc/beach.dmi' icon_state = "anchor" id = "dive" height = 1 - use_verb = "ascends" light_range = 5 -/obj/structure/ladder/dive_point/New() - ..() +/obj/structure/ladder/dive_point/Initialize(mapload) + . = ..() set_light(light_range, light_power) //magical glowing anchor /obj/structure/ladder/dive_point/update_icon() diff --git a/code/game/objects/structures/loom.dm b/code/game/objects/structures/loom.dm new file mode 100644 index 00000000000..26bd4136c2a --- /dev/null +++ b/code/game/objects/structures/loom.dm @@ -0,0 +1,38 @@ +#define FABRIC_PER_SHEET 4 + + +///This is a loom. It's usually made out of wood and used to weave fabric like durathread or cotton into their respective cloth types. +/obj/structure/loom + name = "loom" + desc = "A simple device used to weave cloth and other thread-based fabrics together into usable material." + icon = 'icons/obj/hydroponics/equipment.dmi' + icon_state = "loom" + density = TRUE + anchored = TRUE + +/obj/structure/loom/attackby(obj/item/I, mob/user) + if(default_unfasten_wrench(user, I, 5)) + return + if(weave(I, user)) + return + return ..() + +///Handles the weaving. +/obj/structure/loom/proc/weave(obj/item/stack/sheet/cotton/W, mob/user) + if(!istype(W)) + return FALSE + if(!anchored) + user.show_message("The loom needs to be wrenched down.", 1) + return FALSE + if(W.amount < FABRIC_PER_SHEET) + user.show_message("You need at least [FABRIC_PER_SHEET] units of fabric before using this.", 1) + return FALSE + user.show_message("You start weaving \the [W.name] through the loom..", 1) + if(do_after(user, W.pull_effort, target = src)) + if(W.amount >= FABRIC_PER_SHEET) + new W.loom_result(drop_location()) + W.use(FABRIC_PER_SHEET) + user.show_message("You weave \the [W.name] into a workable fabric.", 1) + return TRUE + +#undef FABRIC_PER_SHEET \ No newline at end of file diff --git a/code/game/objects/structures/signs.dm b/code/game/objects/structures/signs.dm index 345d35cb4aa..6d41209aa94 100644 --- a/code/game/objects/structures/signs.dm +++ b/code/game/objects/structures/signs.dm @@ -145,6 +145,12 @@ name = "\improper RADIOACTIVE AREA" desc = "A warning sign which reads 'RADIOACTIVE AREA'." +/obj/structure/sign/xeno_warning_mining + name = "DANGEROUS ALIEN LIFE" + desc = "A sign that warns would be travellers of hostile alien life in the vicinity." + icon = 'icons/obj/mining.dmi' + icon_state = "xeno_warning" + /obj/structure/sign/redcross name = "medbay" desc = "The Intergalactic symbol of Medical institutions. You'll probably get help here.'" @@ -210,7 +216,7 @@ desc = "A glowing dragon invites you in." icon_state = "chinese" -/obj/structure/sign/science +/obj/structure/sign/science name = "\improper SCIENCE!" desc = "A warning sign which reads 'SCIENCE!'" icon_state = "science1" diff --git a/code/game/objects/structures/tables_racks.dm b/code/game/objects/structures/tables_racks.dm index ac013ebcf93..93b2e30b6d9 100644 --- a/code/game/objects/structures/tables_racks.dm +++ b/code/game/objects/structures/tables_racks.dm @@ -91,6 +91,12 @@ if(climber) climber.Weaken(2) climber.visible_message("[climber.name] has been knocked off the table", "You've been knocked off the table", "You see [climber.name] get knocked off the table") + else if(user.pulling.pass_flags & PASSTABLE) + user.Move_Pulled(src) + if (user.pulling.loc == loc) + user.visible_message("[user] places [user.pulling] onto [src].", + "You place [user.pulling] onto [src].") + user.stop_pulling() /obj/structure/table/attack_tk() // no telehulk sorry return diff --git a/code/game/objects/structures/watercloset.dm b/code/game/objects/structures/watercloset.dm index ada70921c99..0958f3cc0e0 100644 --- a/code/game/objects/structures/watercloset.dm +++ b/code/game/objects/structures/watercloset.dm @@ -600,7 +600,7 @@ wateract = (W.wash(user, src)) busy = 0 if(wateract) - W.water_act(20, 310.15, src) + W.water_act(20, COLD_WATER_TEMPERATURE, src) if("Disconnect") user.visible_message("[user] starts disconnecting [src].", "You begin disconnecting [src]...") if(do_after(user, 40 * O.toolspeed, target = src)) @@ -633,7 +633,7 @@ wateract = (O.wash(user, src)) busy = 0 if(wateract) - O.water_act(20, 310.15, src) + O.water_act(20, COLD_WATER_TEMPERATURE, src) /obj/structure/sink/update_icon() ..() diff --git a/code/game/turfs/simulated.dm b/code/game/turfs/simulated.dm index f54e28defb1..c67d61770ac 100644 --- a/code/game/turfs/simulated.dm +++ b/code/game/turfs/simulated.dm @@ -25,7 +25,7 @@ /turf/simulated/water_act(volume, temperature, source) . = ..() - + if(volume >= 3) MakeSlippery() @@ -37,7 +37,7 @@ assume_air(lowertemp) qdel(hotspot) -/turf/simulated/proc/MakeSlippery(wet_setting = TURF_WET_WATER) // 1 = Water, 2 = Lube, 3 = Ice, 4 = Permafrost +/turf/simulated/proc/MakeSlippery(wet_setting = TURF_WET_WATER, infinite = FALSE) // 1 = Water, 2 = Lube, 3 = Ice, 4 = Permafrost if(wet >= wet_setting) return wet = wet_setting @@ -57,11 +57,11 @@ else wet_overlay = image('icons/effects/water.dmi', src, "wet_static") overlays += wet_overlay - - spawn(rand(790, 820)) // Purely so for visual effect - if(!istype(src, /turf/simulated)) //Because turfs don't get deleted, they change, adapt, transform, evolve and deform. they are one and they are all. - return - MakeDry(wet_setting) + if(!infinite) + spawn(rand(790, 820)) // Purely so for visual effect + if(!istype(src, /turf/simulated)) //Because turfs don't get deleted, they change, adapt, transform, evolve and deform. they are one and they are all. + return + MakeDry(wet_setting) /turf/simulated/proc/MakeDry(wet_setting = TURF_WET_WATER) if(wet > wet_setting) diff --git a/code/game/turfs/simulated/floor/asteroid.dm b/code/game/turfs/simulated/floor/asteroid.dm index 5f2ad4b629c..04ac165fc56 100644 --- a/code/game/turfs/simulated/floor/asteroid.dm +++ b/code/game/turfs/simulated/floor/asteroid.dm @@ -5,6 +5,7 @@ baseturf = /turf/simulated/floor/plating/asteroid icon_state = "asteroid" icon_plating = "asteroid" + footstep_sounds = list() var/environment_type = "asteroid" var/turf_type = /turf/simulated/floor/plating/asteroid //Because caves do whacky shit to revert to normal var/dug = 0 //0 = has not yet been dug, 1 = has already been dug diff --git a/code/game/turfs/simulated/floor/chasm.dm b/code/game/turfs/simulated/floor/chasm.dm index 6a213400d04..17807bd255b 100644 --- a/code/game/turfs/simulated/floor/chasm.dm +++ b/code/game/turfs/simulated/floor/chasm.dm @@ -22,6 +22,11 @@ if(!drop_stuff()) STOP_PROCESSING(SSprocessing, src) +/turf/open/chasm/get_smooth_underlay_icon(mutable_appearance/underlay_appearance, turf/asking_turf, adjacency_dir) + underlay_appearance.icon = 'icons/turf/floors.dmi' + underlay_appearance.icon_state = "basalt" + return TRUE + /turf/simulated/floor/chasm/attackby(obj/item/C, mob/user, params, area/area_restriction) ..() if(istype(C, /obj/item/stack/rods)) diff --git a/code/game/turfs/simulated/floor/fancy_floor.dm b/code/game/turfs/simulated/floor/fancy_floor.dm index 97065cd9711..b326f93fe27 100644 --- a/code/game/turfs/simulated/floor/fancy_floor.dm +++ b/code/game/turfs/simulated/floor/fancy_floor.dm @@ -53,6 +53,11 @@ to_chat(user, "You forcefully pry off the planks, destroying them in the process.") return make_plating() +/turf/simulated/floor/wood/cold + oxygen = 22 + nitrogen = 82 + temperature = 180 + /turf/simulated/floor/grass name = "grass patch" icon_state = "grass1" @@ -117,6 +122,9 @@ burnt = 1 update_icon() +/turf/open/floor/carpet/get_smooth_underlay_icon(mutable_appearance/underlay_appearance, turf/asking_turf, adjacency_dir) + return FALSE + /turf/simulated/floor/carpet/black icon = 'icons/turf/floors/carpet_black.dmi' floor_tile = /obj/item/stack/tile/carpet/black @@ -127,6 +135,7 @@ icon_state = "0" floor_tile = /obj/item/stack/tile/fakespace broken_states = list("damaged") + plane = PLANE_SPACE /turf/simulated/floor/fakespace/New() ..() @@ -137,3 +146,9 @@ icon_state = "arcade" floor_tile = /obj/item/stack/tile/arcade_carpet smooth = SMOOTH_FALSE + +/turf/open/floor/fakespace/get_smooth_underlay_icon(mutable_appearance/underlay_appearance, turf/asking_turf, adjacency_dir) + underlay_appearance.icon = 'icons/turf/space.dmi' + underlay_appearance.icon_state = SPACE_ICON_STATE + underlay_appearance.plane = PLANE_SPACE + return TRUE diff --git a/code/game/turfs/simulated/floor/indestructible.dm b/code/game/turfs/simulated/floor/indestructible.dm index 6c1679776e6..3705e24eea0 100644 --- a/code/game/turfs/simulated/floor/indestructible.dm +++ b/code/game/turfs/simulated/floor/indestructible.dm @@ -81,5 +81,8 @@ planetary_atmos = TRUE desc = "A floor with a square pattern. It's faintly cool to the touch." +/turf/open/indestructible/hierophant/get_smooth_underlay_icon(mutable_appearance/underlay_appearance, turf/asking_turf, adjacency_dir) + return FALSE + /turf/simulated/floor/indestructible/hierophant/two icon_state = "hierophant2" diff --git a/code/game/turfs/simulated/floor/lava.dm b/code/game/turfs/simulated/floor/lava.dm index 0882bb18766..66d7eaca83d 100644 --- a/code/game/turfs/simulated/floor/lava.dm +++ b/code/game/turfs/simulated/floor/lava.dm @@ -41,6 +41,11 @@ /turf/simulated/floor/plating/lava/remove_plating() return +/turf/open/lava/get_smooth_underlay_icon(mutable_appearance/underlay_appearance, turf/asking_turf, adjacency_dir) + underlay_appearance.icon = 'icons/turf/floors.dmi' + underlay_appearance.icon_state = "basalt" + return TRUE + /turf/simulated/floor/plating/lava/proc/is_safe() var/static/list/lava_safeties_typecache = typecacheof(list(/obj/structure/lattice/catwalk, /obj/structure/stone_tile)) var/list/found_safeties = typecache_filter_list(contents, lava_safeties_typecache) diff --git a/code/game/turfs/simulated/floor/mineral.dm b/code/game/turfs/simulated/floor/mineral.dm index a801fd450c5..9031a0a350c 100644 --- a/code/game/turfs/simulated/floor/mineral.dm +++ b/code/game/turfs/simulated/floor/mineral.dm @@ -173,6 +173,18 @@ nitrogen = 0.01 temperature = TCMB + +/turf/simulated/floor/mineral/bananium/lubed/Initialize(mapload) + . = ..() + MakeSlippery(TURF_WET_LUBE, TRUE) + +/turf/simulated/floor/mineral/bananium/lubed/pry_tile(obj/item/C, mob/user, silent = FALSE) //I want to get off Mr Honk's Wild Ride + if(ishuman(user)) + var/mob/living/carbon/human/H = user + to_chat(H, "You lose your footing trying to pry off the tile!") + H.slip("the floor", 0, 5, tilesSlipped = 4, walkSafely = 0, slipAny = 1) + return + //TRANQUILLITE /turf/simulated/floor/mineral/tranquillite name = "silent floor" diff --git a/code/game/turfs/simulated/floor/misc_floor.dm b/code/game/turfs/simulated/floor/misc_floor.dm index 5c8f2022189..5a097b5fe5b 100644 --- a/code/game/turfs/simulated/floor/misc_floor.dm +++ b/code/game/turfs/simulated/floor/misc_floor.dm @@ -43,7 +43,7 @@ name = "beach" icon = 'icons/misc/beach.dmi' -/turf/simulated/floor/beach/pry_tile(obj/item/C, mob/user, silent = FALSE) +/turf/simulated/floor/beach/pry_tile(obj/item/C, mob/user, silent = FALSE) return /turf/simulated/floor/beach/sand @@ -79,7 +79,7 @@ /turf/simulated/floor/beach/water/Entered(atom/movable/AM, atom/OldLoc) . = ..() if(!linkedcontroller) - return + return if(ismob(AM)) linkedcontroller.mobinpool += AM @@ -107,6 +107,26 @@ /turf/simulated/floor/noslip/MakeSlippery() return +/turf/simulated/floor/noslip/lavaland + oxygen = 14 + nitrogen = 23 + temperature = 300 + +/turf/simulated/floor/lubed + name = "slippery floor" + icon_state = "floor" + +/turf/simulated/floor/lubed/Initialize(mapload) + . = ..() + MakeSlippery(TURF_WET_LUBE, TRUE) + +/turf/simulated/floor/lubed/pry_tile(obj/item/C, mob/user, silent = FALSE) //I want to get off Mr Honk's Wild Ride + if(ishuman(user)) + var/mob/living/carbon/human/H = user + to_chat(H, "You lose your footing trying to pry off the tile!") + H.slip("the floor", 0, 5, tilesSlipped = 4, walkSafely = 0, slipAny = 1) + return + //Clockwork floor: Slowly heals toxin damage on nearby servants. /turf/simulated/floor/clockwork name = "clockwork floor" @@ -124,7 +144,7 @@ new /obj/effect/temp_visual/ratvar/beam(src) realappearence = new /obj/effect/clockwork/overlay/floor(src) realappearence.linked = src - + /turf/simulated/floor/clockwork/Destroy() if(uses_overlay && realappearence) QDEL_NULL(realappearence) diff --git a/code/game/turfs/simulated/floor/plating.dm b/code/game/turfs/simulated/floor/plating.dm index 2ef4602d268..819f6a07ef3 100644 --- a/code/game/turfs/simulated/floor/plating.dm +++ b/code/game/turfs/simulated/floor/plating.dm @@ -7,6 +7,8 @@ broken_states = list("damaged1", "damaged2", "damaged3", "damaged4", "damaged5") burnt_states = list("floorscorched1", "floorscorched2") + var/unfastened = FALSE + footstep_sounds = list( "human" = list('sound/effects/footstep/plating_human.ogg'), "xeno" = list('sound/effects/footstep/plating_xeno.ogg') @@ -31,6 +33,12 @@ if(!broken && !burnt) icon_state = icon_plating //Because asteroids are 'platings' too. +/turf/simulated/floor/plating/examine(mob/user) + . = ..() + + if(unfastened) + to_chat(user, "It has been unfastened.") + /turf/simulated/floor/plating/attackby(obj/item/C, mob/user, params) if(..()) return TRUE @@ -64,6 +72,15 @@ to_chat(user, "This section is too damaged to support a tile! Use a welder to fix the damage.") return TRUE + else if(isscrewdriver(C)) + var/obj/item/screwdriver/screwdriver = C + to_chat(user, "You start [unfastened ? "fastening" : "unfastening"] [src].") + playsound(src, screwdriver.usesound, 50, 1) + if(do_after(user, 20 * screwdriver.toolspeed, target = src) && screwdriver) + to_chat(user, "You [unfastened ? "fasten" : "unfasten"] [src].") + unfastened = !unfastened + return TRUE + else if(iswelder(C)) var/obj/item/weldingtool/welder = C if(welder.isOn()) @@ -79,7 +96,7 @@ burnt = FALSE broken = FALSE update_icon() - else + if(unfastened) to_chat(user, "You start removing [src].") playsound(src, welder.usesound, 100, 1) if(do_after(user, 50 * welder.toolspeed, target = src) && welder && welder.isOn()) @@ -168,7 +185,7 @@ /turf/simulated/floor/engine/blob_act() if(prob(25)) ChangeTurf(baseturf) - + /turf/simulated/floor/engine/cult name = "engraved floor" icon_state = "cult" @@ -318,3 +335,28 @@ /turf/simulated/floor/plating/abductor/New() ..() icon_state = "alienpod[rand(1,9)]" + +/turf/simulated/floor/plating/ice + name = "ice sheet" + desc = "A sheet of solid ice. Looks slippery." + icon = 'icons/turf/floors/ice_turfs.dmi' + icon_state = "unsmooth" + oxygen = 22 + nitrogen = 82 + temperature = 180 + baseturf = /turf/simulated/floor/plating/ice + slowdown = TRUE + smooth = SMOOTH_TRUE + canSmoothWith = list(/turf/simulated/floor/plating/ice/smooth, /turf/simulated/floor/plating/ice) + +/turf/simulated/floor/plating/ice/Initialize(mapload) + . = ..() + MakeSlippery(TURF_WET_PERMAFROST, TRUE) + +/turf/simulated/floor/plating/ice/try_replace_tile(obj/item/stack/tile/T, mob/user, params) + return + +/turf/simulated/floor/plating/ice/smooth + icon_state = "smooth" + smooth = SMOOTH_MORE | SMOOTH_BORDER + canSmoothWith = list(/turf/simulated/floor/plating/ice/smooth, /turf/simulated/floor/plating/ice) diff --git a/code/game/turfs/simulated/minerals.dm b/code/game/turfs/simulated/minerals.dm index 119f0b000d9..aee23831050 100644 --- a/code/game/turfs/simulated/minerals.dm +++ b/code/game/turfs/simulated/minerals.dm @@ -48,6 +48,13 @@ setDir(angle2dir(rotation + dir2angle(dir))) queue_smooth(src) +/turf/simulated/mineral/get_smooth_underlay_icon(mutable_appearance/underlay_appearance, turf/asking_turf, adjacency_dir) + if(turf_type) + underlay_appearance.icon = initial(turf_type.icon) + underlay_appearance.icon_state = initial(turf_type.icon_state) + return TRUE + return ..() + /turf/simulated/mineral/attackby(var/obj/item/pickaxe/P as obj, mob/user as mob, params) if(!user.IsAdvancedToolUser()) to_chat(usr, "You don't have the dexterity to do this!") diff --git a/code/game/turfs/simulated/walls.dm b/code/game/turfs/simulated/walls.dm index 5a8f842307e..26b79c9e9f4 100644 --- a/code/game/turfs/simulated/walls.dm +++ b/code/game/turfs/simulated/walls.dm @@ -1,3 +1,7 @@ +#define WALL_DENT_HIT 1 +#define WALL_DENT_SHOT 2 +#define MAX_DENT_DECALS 15 + /turf/simulated/wall name = "wall" desc = "A huge chunk of metal used to seperate rooms." @@ -25,7 +29,7 @@ var/slicing_duration = 100 var/engraving //engraving on the wall var/engraving_quality - + var/list/dent_decals var/sheet_type = /obj/item/stack/sheet/metal var/sheet_amount = 2 var/girder_type = /obj/structure/girder @@ -167,6 +171,8 @@ /turf/simulated/wall/blob_act() if(prob(50)) dismantle_wall() + else + add_dent(WALL_DENT_HIT) /turf/simulated/wall/rpd_act(mob/user, obj/item/rpd/our_rpd) if(our_rpd.mode == RPD_ATMOS_MODE) @@ -191,6 +197,8 @@ M.occupant_message("You smash through the wall.") visible_message("[src.name] smashes through the wall!") playsound(src, 'sound/effects/meteorimpact.ogg', 100, 1) + else + add_dent(WALL_DENT_HIT) // Wall-rot effect, a nasty fungus that destroys walls. /turf/simulated/wall/proc/rot() @@ -260,6 +268,7 @@ dismantle_wall(TRUE) else playsound(src, 'sound/effects/bang.ogg', 50, 1) + add_dent(WALL_DENT_HIT) to_chat(user, text("You punch the wall.")) return TRUE @@ -296,7 +305,6 @@ if(try_wallmount(I, user, params)) return - // The magnetic gripper does a separate attackby, so bail from this one if(istype(I, /obj/item/gripper)) return @@ -327,7 +335,7 @@ return TRUE // this means "don't continue trying to find alternative uses in attackby", not "decon succeeded" var/response = "Dismantle" - if(damage) + if(damage || LAZYLEN(dent_decals)) response = alert(user, "Would you like to repair or dismantle [src]?", "[src]", "Repair", "Dismantle") switch(response) @@ -336,6 +344,8 @@ playsound(src, WT.usesound, 100, 1) if(do_after(user, max(5, damage / 5) * WT.toolspeed, target = src) && WT && WT.isOn()) to_chat(user, "You finish repairing the damage to [src].") + cut_overlay(dent_decals) + dent_decals.Cut() take_damage(-damage) else to_chat(user, "You begin slicing through the outer plating.") @@ -435,3 +445,27 @@ /turf/simulated/wall/narsie_act() if(prob(20)) ChangeTurf(/turf/simulated/wall/cult) + +/turf/simulated/wall/proc/add_dent(denttype, x=rand(-8, 8), y=rand(-8, 8)) + if(LAZYLEN(dent_decals) >= MAX_DENT_DECALS) + return + + var/mutable_appearance/decal = mutable_appearance('icons/effects/effects.dmi', "", BULLET_HOLE_LAYER) + switch(denttype) + if(WALL_DENT_SHOT) + decal.icon_state = "bullet_hole" + if(WALL_DENT_HIT) + decal.icon_state = "impact[rand(1, 3)]" + + decal.pixel_x = x + decal.pixel_y = y + + if(LAZYLEN(dent_decals)) + cut_overlay(dent_decals) + dent_decals += decal + else + dent_decals = list(decal) + + add_overlay(dent_decals) + +#undef MAX_DENT_DECALS \ No newline at end of file diff --git a/code/game/turfs/simulated/walls_mineral.dm b/code/game/turfs/simulated/walls_mineral.dm index 74d0e216614..6bae5a79d94 100644 --- a/code/game/turfs/simulated/walls_mineral.dm +++ b/code/game/turfs/simulated/walls_mineral.dm @@ -140,7 +140,23 @@ sheet_type = /obj/item/stack/sheet/wood hardness = 70 explosion_block = 0 - canSmoothWith = list(/turf/simulated/wall/mineral/wood, /obj/structure/falsewall/wood) + canSmoothWith = list(/turf/simulated/wall/mineral/wood, /obj/structure/falsewall/wood, /turf/simulated/wall/mineral/wood/nonmetal) + +/turf/simulated/wall/mineral/wood/attackby(obj/item/W, mob/user) + if(W.sharp && W.force) + var/duration = (48 / W.force) * 2 //In seconds, for now. + if(istype(W, /obj/item/hatchet) || istype(W, /obj/item/twohanded/fireaxe)) + duration /= 4 //Much better with hatchets and axes. + if(do_after(user, duration * 10, target = src)) //Into deciseconds. + dismantle_wall(FALSE, FALSE) + return + return ..() + +/turf/simulated/wall/mineral/wood/nonmetal + desc = "A solidly wooden wall. It's a bit weaker than a wall made with metal." + girder_type = /obj/structure/barricade/wooden + hardness = 50 + canSmoothWith = list(/turf/simulated/wall/mineral/wood, /obj/structure/falsewall/wood, /turf/simulated/wall/mineral/wood/nonmetal) /turf/simulated/wall/mineral/iron name = "rough metal wall" diff --git a/code/game/turfs/space/space.dm b/code/game/turfs/space/space.dm index 0d6428b10a2..40c0d83272e 100644 --- a/code/game/turfs/space/space.dm +++ b/code/game/turfs/space/space.dm @@ -16,6 +16,7 @@ var/destination_z var/destination_x var/destination_y + plane = PLANE_SPACE /turf/space/Initialize(mapload) if(!istype(src, /turf/space/transit)) @@ -262,4 +263,10 @@ /turf/space/attack_ghost(mob/dead/observer/user) if(destination_z) var/turf/T = locate(destination_x, destination_y, destination_z) - user.forceMove(T) \ No newline at end of file + user.forceMove(T) + +/turf/space/get_smooth_underlay_icon(mutable_appearance/underlay_appearance, turf/asking_turf, adjacency_dir) + underlay_appearance.icon = 'icons/turf/space.dmi' + underlay_appearance.icon_state = SPACE_ICON_STATE + underlay_appearance.plane = PLANE_SPACE + return TRUE diff --git a/code/game/turfs/space/transit.dm b/code/game/turfs/space/transit.dm index 79bf171ce1f..15c553b3f95 100644 --- a/code/game/turfs/space/transit.dm +++ b/code/game/turfs/space/transit.dm @@ -1,5 +1,6 @@ /turf/space/transit var/pushdirection // push things that get caught in the transit tile this direction + plane = PLANE_SPACE //Overwrite because we dont want people building rods in space. /turf/space/transit/attackby(obj/O as obj, mob/user as mob, params) @@ -151,3 +152,9 @@ icon_state = "speedspace_ns_[state]" transform = turn(matrix(), angle) + +/turf/space/transit/get_smooth_underlay_icon(mutable_appearance/underlay_appearance, turf/asking_turf, adjacency_dir) + underlay_appearance.icon = 'icons/turf/space.dmi' + underlay_appearance.icon_state = SPACE_ICON_STATE + underlay_appearance.plane = PLANE_SPACE + return TRUE diff --git a/code/game/turfs/turf.dm b/code/game/turfs/turf.dm index e315ad26ad0..0ab9ccbef15 100644 --- a/code/game/turfs/turf.dm +++ b/code/game/turfs/turf.dm @@ -470,6 +470,12 @@ if(ismob(A) || .) A.ratvar_act() +/turf/proc/get_smooth_underlay_icon(mutable_appearance/underlay_appearance, turf/asking_turf, adjacency_dir) + underlay_appearance.icon = icon + underlay_appearance.icon_state = icon_state + underlay_appearance.dir = adjacency_dir + return TRUE + /turf/proc/add_blueprints(atom/movable/AM) var/image/I = new I.appearance = AM.appearance @@ -510,6 +516,5 @@ /turf/AllowDrop() return TRUE -/turf/proc/water_act(volume, temperature, source) - for(var/mob/living/carbon/slime/M in src) - M.apply_water() +/turf/proc/water_act(volume, temperature, source) + return FALSE diff --git a/code/game/verbs/ooc.dm b/code/game/verbs/ooc.dm index 5a2807e8379..df2f588753f 100644 --- a/code/game/verbs/ooc.dm +++ b/code/game/verbs/ooc.dm @@ -41,6 +41,9 @@ var/global/admin_ooc_colour = "#b82e00" return if(!check_rights(R_ADMIN|R_MOD,0)) + if(!config.ooc_allowed) + to_chat(src, "OOC is globally muted.") + return if(handle_spam_prevention(msg, MUTE_OOC, OOC_COOLDOWN)) return if(findtext(msg, "byond://")) diff --git a/code/modules/admin/admin.dm b/code/modules/admin/admin.dm index a6f186dad73..d32a05eb312 100644 --- a/code/modules/admin/admin.dm +++ b/code/modules/admin/admin.dm @@ -784,11 +784,13 @@ var/global/nologevent = 0 log_admin("[key_name(usr)] [SSticker.delay_end ? "delayed the round end" : "has made the round end normally"].") message_admins("[key_name(usr)] [SSticker.delay_end ? "delayed the round end" : "has made the round end normally"].", 1) return //alert("Round end delayed", null, null, null, null, null) - going = !( going ) - if(!( going )) + if(going) + going = FALSE + SSticker.delay_end = TRUE to_chat(world, "The game start has been delayed.") log_admin("[key_name(usr)] delayed the game.") else + going = TRUE to_chat(world, "The game will start soon.") log_admin("[key_name(usr)] removed the delay.") feedback_add_details("admin_verb","DELAY") //If you are copy-pasting this, ensure the 2nd parameter is unique to the new proc! diff --git a/code/modules/admin/admin_verbs.dm b/code/modules/admin/admin_verbs.dm index 1176e733dde..b66f83543dd 100644 --- a/code/modules/admin/admin_verbs.dm +++ b/code/modules/admin/admin_verbs.dm @@ -120,7 +120,8 @@ var/list/admin_verbs_event = list( /client/proc/cmd_admin_create_centcom_report, /client/proc/fax_panel, /client/proc/event_manager_panel, - /client/proc/modify_goals + /client/proc/modify_goals, + /client/proc/outfit_manager ) var/list/admin_verbs_spawn = list( diff --git a/code/modules/admin/outfits.dm b/code/modules/admin/outfits.dm new file mode 100644 index 00000000000..336edc89c88 --- /dev/null +++ b/code/modules/admin/outfits.dm @@ -0,0 +1,262 @@ +GLOBAL_LIST_EMPTY(custom_outfits) //Admin created outfits + +/client/proc/outfit_manager() + set category = "Event" + set name = "Outfit Manager" + + if(!check_rights(R_EVENT)) + return + holder.outfit_manager(usr) + +/datum/admins/proc/outfit_manager(mob/admin) + var/list/dat = list("
        ") + for(var/datum/outfit/O in GLOB.custom_outfits) + var/vv = FALSE + var/datum/outfit/varedit/VO = O + if(istype(VO)) + vv = length(VO.vv_values) + dat += "
      • [O.name][vv ? "(VV)" : ""]
      • Save Delete" + dat += "
      " + dat += "Create
      " + dat += "Load from file" + admin << browse(dat.Join(),"window=outfitmanager") + +/datum/admins/proc/save_outfit(mob/admin,datum/outfit/O) + O.save_to_file(admin) + outfit_manager(admin) + +/datum/admins/proc/delete_outfit(mob/admin,datum/outfit/O) + GLOB.custom_outfits -= O + qdel(O) + to_chat(admin,"Outfit deleted.") + outfit_manager(admin) + +/datum/admins/proc/load_outfit(mob/admin) + var/outfit_file = input("Pick outfit json file:", "File") as null|file + if(!outfit_file) + return + var/filedata = file2text(outfit_file) + var/json = json_decode(filedata) + if(!json) + to_chat(admin,"JSON decode error.") + return + var/otype = text2path(json["outfit_type"]) + if(!ispath(otype,/datum/outfit)) + to_chat(admin,"Malformed/Outdated file.") + return + var/datum/outfit/O = new otype + if(!O.load_from(json)) + to_chat(admin,"Malformed/Outdated file.") + return + GLOB.custom_outfits += O + outfit_manager(admin) + +/datum/admins/proc/create_outfit(mob/admin) + var/list/uniforms = typesof(/obj/item/clothing/under) + var/list/suits = typesof(/obj/item/clothing/suit) + var/list/gloves = typesof(/obj/item/clothing/gloves) + var/list/shoes = typesof(/obj/item/clothing/shoes) + var/list/headwear = typesof(/obj/item/clothing/head) + var/list/glasses = typesof(/obj/item/clothing/glasses) + var/list/masks = typesof(/obj/item/clothing/mask) + var/list/pdas = typesof(/obj/item/pda) + var/list/ids = typesof(/obj/item/card/id) + + var/uniform_select = "" + + var/suit_select = "" + + var/gloves_select = "" + + var/shoes_select = "" + + var/head_select = "" + + var/glasses_select = "" + + var/mask_select = "" + + var/id_select = "" + + var/pda_select = "" + + var/dat = {" + Create Outfit +
      + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
      Name: + +
      Uniform: + [uniform_select] +
      Suit: + [suit_select] +
      Back: + +
      Belt: + +
      Gloves: + [gloves_select] +
      Shoes: + [shoes_select] +
      Head: + [head_select] +
      Mask: + [mask_select] +
      Left Ear: + +
      Right Ear: + +
      Glasses: + [glasses_select] +
      ID: + [id_select] +
      PDA: + [pda_select] +
      Left Pocket: + +
      Right Pocket: + +
      Suit Store: + +
      Right Hand: + +
      Left Hand: + +
      +
      + +
      + "} + admin << browse(dat, "window=dressup;size=550x600") + + +/datum/admins/proc/create_outfit_finalize(mob/admin, list/href_list) + var/datum/outfit/O = new + + O.name = href_list["outfit_name"] + O.uniform = text2path(href_list["outfit_uniform"]) + O.shoes = text2path(href_list["outfit_shoes"]) + O.gloves = text2path(href_list["outfit_gloves"]) + O.suit = text2path(href_list["outfit_suit"]) + O.head = text2path(href_list["outfit_head"]) + O.back = text2path(href_list["outfit_back"]) + O.mask = text2path(href_list["outfit_mask"]) + O.glasses = text2path(href_list["outfit_glasses"]) + O.r_hand = text2path(href_list["outfit_r_hand"]) + O.l_hand = text2path(href_list["outfit_l_hand"]) + O.suit_store = text2path(href_list["outfit_s_store"]) + O.l_pocket = text2path(href_list["outfit_l_pocket"]) + O.r_pocket = text2path(href_list["outfit_r_pocket"]) + O.id = text2path(href_list["outfit_id"]) + O.pda = text2path(href_list["outfit_pda"]) + O.belt = text2path(href_list["outfit_belt"]) + O.l_ear = text2path(href_list["outfit_l_ear"]) + O.r_ear = text2path(href_list["outfit_r_ear"]) + + GLOB.custom_outfits.Add(O) + message_admins("[key_name_admin(usr)] created \"[O.name]\" outfit.") diff --git a/code/modules/admin/topic.dm b/code/modules/admin/topic.dm index be136204739..cb10ba4d335 100644 --- a/code/modules/admin/topic.dm +++ b/code/modules/admin/topic.dm @@ -341,9 +341,6 @@ if("Cancel") return if("Yes") delmob = 1 - log_admin("[key_name(usr)] has used rudimentary transformation on [key_name(M)]. Transforming to [href_list["simplemake"]]; deletemob=[delmob]") - message_admins("[key_name_admin(usr)] has used rudimentary transformation on [key_name_admin(M)]. Transforming to [href_list["simplemake"]]; deletemob=[delmob]", 1) - switch(href_list["simplemake"]) if("observer") M.change_mob_type( /mob/dead/observer , null, null, delmob, 1 ) if("drone") M.change_mob_type( /mob/living/carbon/alien/humanoid/drone , null, null, delmob, 1 ) @@ -351,7 +348,11 @@ if("queen") M.change_mob_type( /mob/living/carbon/alien/humanoid/queen/large , null, null, delmob, 1 ) if("sentinel") M.change_mob_type( /mob/living/carbon/alien/humanoid/sentinel , null, null, delmob, 1 ) if("larva") M.change_mob_type( /mob/living/carbon/alien/larva , null, null, delmob, 1 ) - if("human") M.change_mob_type( /mob/living/carbon/human, null, null, delmob, 1 ) + if("human") + var/posttransformoutfit = usr.client.robust_dress_shop() + var/mob/living/carbon/human/newmob = M.change_mob_type(/mob/living/carbon/human, null, null, delmob, 1) + if(posttransformoutfit && istype(newmob)) + newmob.equipOutfit(posttransformoutfit) if("slime") M.change_mob_type( /mob/living/carbon/slime , null, null, delmob, 1 ) if("monkey") M.change_mob_type( /mob/living/carbon/human/monkey , null, null, delmob, 1 ) if("robot") M.change_mob_type( /mob/living/silicon/robot , null, null, delmob, 1 ) @@ -368,6 +369,9 @@ if("constructwraith") M.change_mob_type( /mob/living/simple_animal/hostile/construct/wraith , null, null, delmob, 1 ) if("shade") M.change_mob_type( /mob/living/simple_animal/shade , null, null, delmob, 1 ) + log_admin("[key_name(usr)] has used rudimentary transformation on [key_name(M)]. Transforming to [href_list["simplemake"]]; deletemob=[delmob]") + message_admins("[key_name_admin(usr)] has used rudimentary transformation on [key_name_admin(M)]. Transforming to [href_list["simplemake"]]; deletemob=[delmob]", 1) + /////////////////////////////////////new ban stuff else if(href_list["unbanf"]) @@ -1510,14 +1514,22 @@ usr.client.cmd_admin_animalize(M) else if(href_list["incarn_ghost"]) - if(!check_rights(R_SPAWN)) return + if(!check_rights(R_SPAWN)) + return var/mob/dead/observer/G = locateUID(href_list["incarn_ghost"]) if(!istype(G)) to_chat(usr, "This will only work on /mob/dead/observer") - log_admin("[key_name(G)] was incarnated by [key_name(src.owner)]") - message_admins("[key_name_admin(G)] was incarnated by [key_name_admin(src.owner)]") - G.incarnate_ghost() + + var/posttransformoutfit = usr.client.robust_dress_shop() + + var/mob/living/carbon/human/H = G.incarnate_ghost() + + if(posttransformoutfit && istype(H)) + H.equipOutfit(posttransformoutfit) + + log_admin("[key_name(G)] was incarnated by [key_name(owner)]") + message_admins("[key_name_admin(G)] was incarnated by [key_name_admin(owner)]") else if(href_list["togmutate"]) if(!check_rights(R_SPAWN)) return @@ -1930,7 +1942,7 @@ evilcookie.reagents.add_reagent("mutagen", 10) evilcookie.desc = "It has a faint green glow." evilcookie.bitesize = 100 - evilcookie.flags = NODROP + evilcookie.flags = NODROP | DROPDEL H.drop_l_hand() H.equip_to_slot_or_del(evilcookie, slot_l_hand) logmsg = "a mutagen cookie." @@ -1939,7 +1951,7 @@ evilcookie.reagents.add_reagent("hell_water", 25) evilcookie.desc = "Sulphur-flavored." evilcookie.bitesize = 100 - evilcookie.flags = NODROP + evilcookie.flags = NODROP | DROPDEL H.drop_l_hand() H.equip_to_slot_or_del(evilcookie, slot_l_hand) logmsg = "a hellwater cookie." @@ -2171,7 +2183,7 @@ var/obj/item/paper/P = new /obj/item/paper(null) //hopefully the null loc won't cause trouble for us if(!fax) - var/list/departmentoptions = alldepartments + "All Departments" + var/list/departmentoptions = alldepartments + hidden_departments + "All Departments" destination = input(usr, "To which department?", "Choose a department", "") as null|anything in departmentoptions if(!destination) qdel(P) @@ -3373,6 +3385,29 @@ message_admins("[key_name_admin(usr)] forcefully unlinked the discord account belonging to [target_ckey]") log_admin("[key_name_admin(usr)] forcefully unlinked the discord account belonging to [target_ckey]") + else if(href_list["create_outfit_finalize"]) + if(!check_rights(R_EVENT)) + return + create_outfit_finalize(usr,href_list) + else if(href_list["load_outfit"]) + if(!check_rights(R_EVENT)) + return + load_outfit(usr) + else if(href_list["create_outfit_menu"]) + if(!check_rights(R_EVENT)) + return + create_outfit(usr) + else if(href_list["delete_outfit"]) + if(!check_rights(R_EVENT)) + return + var/datum/outfit/O = locate(href_list["chosen_outfit"]) in GLOB.custom_outfits + delete_outfit(usr,O) + else if(href_list["save_outfit"]) + if(!check_rights(R_EVENT)) + return + var/datum/outfit/O = locate(href_list["chosen_outfit"]) in GLOB.custom_outfits + save_outfit(usr,O) + /client/proc/create_eventmob_for(var/mob/living/carbon/human/H, var/killthem = 0) if(!check_rights(R_EVENT)) return diff --git a/code/modules/admin/verbs/adminpm.dm b/code/modules/admin/verbs/adminpm.dm index e2482c54d7c..1069e981c37 100644 --- a/code/modules/admin/verbs/adminpm.dm +++ b/code/modules/admin/verbs/adminpm.dm @@ -161,7 +161,9 @@ var/emoji_msg = "[msg]" recieve_message = "[type] from-[recieve_pm_type][C.holder ? key_name(src, TRUE, type) : key_name_hidden(src, TRUE, type)]: [emoji_msg]" to_chat(C, recieve_message) - to_chat(src, "[send_pm_type][type] to-[holder ? key_name(C, TRUE, type) : key_name_hidden(C, TRUE, type)]: [emoji_msg]") + var/ping_link = check_rights(R_ADMIN, 0, mob) ? "(PING)" : "" + var/window_link = "(WINDOW)" + to_chat(src, "[send_pm_type][type] to-[holder ? key_name(C, TRUE, type) : key_name_hidden(C, TRUE, type)]: [emoji_msg] [ping_link] [window_link]") /*if(holder && !C.holder) C.last_pm_recieved = world.time @@ -380,7 +382,6 @@ window_flash(C) C.pm_tracker.show_ui(C.mob) to_chat(usr, "Forced open [C]'s messages window.") - show_ui(usr) return if(href_list["reply"]) diff --git a/code/modules/admin/verbs/debug.dm b/code/modules/admin/verbs/debug.dm index 008eaa4a910..11664349274 100644 --- a/code/modules/admin/verbs/debug.dm +++ b/code/modules/admin/verbs/debug.dm @@ -576,109 +576,79 @@ But you can call procs that are of type /mob/living/carbon/human/proc/ for that if(!check_rights(R_EVENT)) return - if(!ishuman(M)) + if(!ishuman(M) && !isobserver(M)) alert("Invalid mob") return - var/list/choices = list( - "strip", - "as job...", - "emergency response team member", - "emergency response team leader" + var/dresscode = robust_dress_shop() + + if(!dresscode) + return + + var/delete_pocket + var/mob/living/carbon/human/H + if(isobserver(M)) + H = M.change_mob_type(/mob/living/carbon/human, null, null, TRUE) + else + H = M + if(H.l_store || H.r_store || H.s_store) //saves a lot of time for admins and coders alike + if(alert("Should the items in their pockets be dropped? Selecting \"No\" will delete them.", "Robust quick dress shop", "Yes", "No") == "No") + delete_pocket = TRUE + + for (var/obj/item/I in H.get_equipped_items(delete_pocket)) + qdel(I) + if(dresscode != "Naked") + H.equipOutfit(dresscode) + + H.regenerate_icons() + + feedback_add_details("admin_verb", "SE") //If you are copy-pasting this, ensure the 2nd parameter is unique to the new proc! + log_admin("[key_name(usr)] changed the equipment of [key_name(M)] to [dresscode].") + message_admins("[key_name_admin(usr)] changed the equipment of [key_name_admin(M)] to [dresscode].", 1) + +/client/proc/robust_dress_shop() + var/list/outfits = list( + "Naked", + "As Job...", + "Custom..." ) - var/admin_outfits = subtypesof(/datum/outfit/admin) - for(var/type in admin_outfits) - var/datum/outfit/O = type - var/name = initial(O.name) - if(name != "Naked") - choices[initial(O.name)] = type + var/list/paths = subtypesof(/datum/outfit) - typesof(/datum/outfit/job) + for(var/path in paths) + var/datum/outfit/O = path //not much to initalize here but whatever + if(initial(O.can_be_admin_equipped)) + outfits[initial(O.name)] = path - var/dostrip = 0 - switch(alert("Strip [M] before dressing?", "Strip?", "Yes", "No", "Cancel")) - if("Yes") - dostrip = 1 - if("Cancel") - return - - var/dresscode = input("Select dress for [M]", "Robust quick dress shop") as null|anything in choices + var/dresscode = input("Select outfit", "Robust quick dress shop") as null|anything in outfits if(isnull(dresscode)) return - var/datum/outfit/O - if(!(dresscode in list("strip", "as job...", "emergency response team member", "emergency response team leader"))) - O = choices[dresscode] + if(outfits[dresscode]) + dresscode = outfits[dresscode] - var/datum/job/jobdatum - if(dresscode == "as job...") - var/jobname = input("Select job", "Robust quick dress shop") as null|anything in get_all_jobs() - jobdatum = SSjobs.GetJob(jobname) + if(dresscode == "As Job...") + var/list/job_paths = subtypesof(/datum/outfit/job) + var/list/job_outfits = list() + for(var/path in job_paths) + var/datum/outfit/O = path + if(initial(O.can_be_admin_equipped)) + job_outfits[initial(O.name)] = path - feedback_add_details("admin_verb", "SEQ") //If you are copy-pasting this, ensure the 2nd parameter is unique to the new proc! - if(dostrip) - for(var/obj/item/I in M) - if(istype(I, /obj/item/implant)) - continue - if(istype(I, /obj/item/organ)) - continue - qdel(I) + dresscode = input("Select job equipment", "Robust quick dress shop") as null|anything in job_outfits + dresscode = job_outfits[dresscode] + if(isnull(dresscode)) + return + if(dresscode == "Custom...") + var/list/custom_names = list() + for(var/datum/outfit/D in GLOB.custom_outfits) + custom_names[D.name] = D + var/selected_name = input("Select outfit", "Robust quick dress shop") as null|anything in custom_names + dresscode = custom_names[selected_name] + if(isnull(dresscode)) + return - switch(dresscode) - if("strip") - //do nothing - - // god is dead - if("as job...") - if(jobdatum) - dresscode = "[jobdatum.title]" - jobdatum.equip(M) - - if("emergency response team member", "emergency response team leader") - var/datum/response_team/equip_team = null - switch(alert("Level", "Emergency Response Team", "Amber", "Red", "Gamma")) - if("Amber") - equip_team = new /datum/response_team/amber - if("Red") - equip_team = new /datum/response_team/red - if("Gamma") - equip_team = new /datum/response_team/gamma - if(!equip_team) - return - if(dresscode == "emergency response team leader") - equip_team.equip_officer("Commander", M) - else - var/list/ert_outfits = list("Security", "Engineer", "Medic", "Janitor", "Paranormal") - var/echoice = input("Loadout Type", "Emergency Response Team") as null|anything in ert_outfits - if(!echoice) - return - switch(echoice) - if("Commander") - equip_team.equip_officer("Commander", M) - if("Security") - equip_team.equip_officer("Security", M) - if("Engineer") - equip_team.equip_officer("Engineer", M) - if("Medic") - equip_team.equip_officer("Medic", M) - if("Janitor") - equip_team.equip_officer("Janitor", M) - if("Paranormal") - equip_team.equip_officer("Paranormal", M) - else - to_chat(src, "Invalid ERT Loadout selected") - - - else // outfit datum - if(O) - M.equipOutfit(O, FALSE) - - M.regenerate_icons() - - log_admin("[key_name(usr)] changed the equipment of [key_name(M)] to [dresscode].") - message_admins("[key_name_admin(usr)] changed the equipment of [key_name_admin(M)] to [dresscode].", 1) - return - + return dresscode /client/proc/startSinglo() set category = "Debug" diff --git a/code/modules/admin/verbs/striketeam_syndicate.dm b/code/modules/admin/verbs/striketeam_syndicate.dm index 7e77fe17df7..611dbcfd97a 100644 --- a/code/modules/admin/verbs/striketeam_syndicate.dm +++ b/code/modules/admin/verbs/striketeam_syndicate.dm @@ -147,7 +147,6 @@ var/global/sent_syndicate_strike_team = 0 equip_to_slot_or_del(new /obj/item/melee/energy/sword/saber/red(src), slot_l_store) if(full_gear) - equip_to_slot_or_del(new /obj/item/clothing/head/helmet/space/hardsuit/syndi/elite/sst(src), slot_head) equip_to_slot_or_del(new /obj/item/clothing/mask/gas/syndicate(src), slot_wear_mask) equip_to_slot_or_del(new /obj/item/clothing/suit/space/hardsuit/syndi/elite/sst(src), slot_wear_suit) equip_to_slot_or_del(new /obj/item/clothing/glasses/thermal(src), slot_glasses) diff --git a/code/modules/antagonists/_common/antag_spawner.dm b/code/modules/antagonists/_common/antag_spawner.dm index d52507bee1d..d57c3124f61 100644 --- a/code/modules/antagonists/_common/antag_spawner.dm +++ b/code/modules/antagonists/_common/antag_spawner.dm @@ -210,6 +210,7 @@ var/datum/objective/KillDaCrew = new /datum/objective KillDaCrew.owner = S.mind KillDaCrew.explanation_text = "[objective_verb] everyone else while you're at it." + KillDaCrew.completed = TRUE S.mind.objectives += KillDaCrew to_chat(S, "Objective #[1]: [KillDaWiz.explanation_text]") to_chat(S, "Objective #[2]: [KillDaCrew.explanation_text]") @@ -219,7 +220,8 @@ desc = "A magically infused bottle of clown love, distilled from \ countless hugging attacks. Used in funny rituals to attract \ adorable creatures." - color = "#FF69B4" // HOT PINK + icon = 'icons/obj/wizard.dmi' + icon_state = "vialtickles" veil_msg = "You sense an adorable presence \ lurking just beyond the veil..." objective_verb = "Hug and tickle" @@ -278,6 +280,7 @@ var/datum/objective/KillDaCrew = new /datum/objective KillDaCrew.owner = M.mind KillDaCrew.explanation_text = "[objective_verb] everyone and everything else while you're at it." + KillDaCrew.completed = TRUE M.mind.objectives += KillDaCrew to_chat(M, "Objective #[1]: [KillDaWiz.explanation_text]") to_chat(M, "Objective #[2]: [KillDaCrew.explanation_text]") diff --git a/code/modules/awaymissions/corpse.dm b/code/modules/awaymissions/corpse.dm index 92a6a2b1d86..ce2afbd13c4 100644 --- a/code/modules/awaymissions/corpse.dm +++ b/code/modules/awaymissions/corpse.dm @@ -341,9 +341,8 @@ uniform = /obj/item/clothing/under/rank/engineer belt = /obj/item/storage/belt/utility/full - suit = /obj/item/clothing/suit/space/hardsuit + suit = /obj/item/clothing/suit/space/hardsuit/engine shoes = /obj/item/clothing/shoes/workboots - head = /obj/item/clothing/head/helmet/space/hardsuit mask = /obj/item/clothing/mask/breath id = /obj/item/card/id/engineering l_pocket = /obj/item/t_scanner @@ -423,7 +422,6 @@ /datum/outfit/job/mining/suit name = "Shaft Miner" suit = /obj/item/clothing/suit/space/hardsuit/mining - head = /obj/item/clothing/head/helmet/space/hardsuit/mining uniform = /obj/item/clothing/under/rank/miner gloves = /obj/item/clothing/gloves/fingerless shoes = /obj/item/clothing/shoes/workboots diff --git a/code/modules/awaymissions/mission_code/ghost_role_spawners/golems.dm b/code/modules/awaymissions/mission_code/ghost_role_spawners/golems.dm index 60cedb281fa..9a5bf275abc 100644 --- a/code/modules/awaymissions/mission_code/ghost_role_spawners/golems.dm +++ b/code/modules/awaymissions/mission_code/ghost_role_spawners/golems.dm @@ -104,6 +104,11 @@ H.rename_character(null, H.dna.species.get_random_name()) else H.rename_character(null, name) + if(is_species(H, /datum/species/golem/tranquillite) && H.mind) + H.mind.AddSpell(new /obj/effect/proc_holder/spell/aoe_turf/conjure/mime_wall(null)) + H.mind.AddSpell(new /obj/effect/proc_holder/spell/targeted/mime/speak(null)) + H.mind.miming = TRUE + if(has_owner) new_spawn.mind.assigned_role = "Servant Golem" else diff --git a/code/modules/awaymissions/mission_code/ruins/oldstation.dm b/code/modules/awaymissions/mission_code/ruins/oldstation.dm index 7150d0c74c4..83cdfd8ac5c 100644 --- a/code/modules/awaymissions/mission_code/ruins/oldstation.dm +++ b/code/modules/awaymissions/mission_code/ruins/oldstation.dm @@ -161,6 +161,7 @@ armor = list("melee" = 30, "bullet" = 5, "laser" = 5, "energy" = 0, "bomb" = 50, "bio" = 100, "rad" = 100, "fire" = 100, "acid" = 75) item_color = "ancient" resistance_flags = FIRE_PROOF + sprite_sheets = null /obj/item/clothing/suit/space/hardsuit/ancient name = "prototype RIG hardsuit" @@ -170,6 +171,8 @@ armor = list("melee" = 30, "bullet" = 5, "laser" = 5, "energy" = 0, "bomb" = 50, "bio" = 100, "rad" = 100, "fire" = 100, "acid" = 75) slowdown = 3 resistance_flags = FIRE_PROOF + sprite_sheets = null + helmettype = /obj/item/clothing/head/helmet/space/hardsuit/ancient var/footstep = 1 /obj/item/clothing/suit/space/hardsuit/ancient/on_mob_move() diff --git a/code/modules/client/asset_cache.dm b/code/modules/client/asset_cache.dm index 300443714ab..57a6df32ab6 100644 --- a/code/modules/client/asset_cache.dm +++ b/code/modules/client/asset_cache.dm @@ -318,7 +318,7 @@ You can set verify to TRUE if you want send() to sleep until the client has the for(var/D in cardinal) assets["[state]-[dir2text(D)].png"] = icon('icons/obj/pipe-item.dmi', state, D) for(var/state in icon_states('icons/obj/pipes/disposal.dmi')) - if(!(state in list("pipe-c", "pipe-j1", "pipe-s", "pipe-t", "pipe-y", "intake", "outlet"))) //Pipes we want sprites for + if(!(state in list("pipe-c", "pipe-j1", "pipe-s", "pipe-t", "pipe-y", "intake", "outlet", "pipe-j1s"))) //Pipes we want sprites for continue for(var/D in cardinal) assets["[state]-[dir2text(D)].png"] = icon('icons/obj/pipes/disposal.dmi', state, D) diff --git a/code/modules/client/client procs.dm b/code/modules/client/client procs.dm index 95f6c16ba97..744cb44ea63 100644 --- a/code/modules/client/client procs.dm +++ b/code/modules/client/client procs.dm @@ -143,7 +143,7 @@ if("5") karma_purchase(karma,45,"species","Slime People") if("6") - karma_purchase(karma,100,"species","Plasmaman") + karma_purchase(karma,45,"species","Plasmaman") if("7") karma_purchase(karma,30,"species","Drask") if(href_list["KarmaRefund"]) @@ -401,7 +401,7 @@ if(!winexists(src, "asset_cache_browser")) // The client is using a custom skin, tell them. to_chat(src, "Unable to access asset cache browser, if you are using a custom skin file, please allow DS to download the updated version, if you are not, then make a bug report. This is not a critical issue but can cause issues with resource downloading, as it is impossible to know when extra resources arrived to you.") - + //This is down here because of the browse() calls in tooltip/New() if(!tooltips) tooltips = new /datum/tooltip(src) @@ -433,6 +433,9 @@ GLOB.admins -= src GLOB.directory -= ckey GLOB.clients -= src + if(movingmob) + movingmob.client_mobs_in_contents -= mob + UNSETEMPTY(movingmob.client_mobs_in_contents) Master.UpdateTickRate() return ..() diff --git a/code/modules/client/preference/loadout/loadout_cosmetics.dm b/code/modules/client/preference/loadout/loadout_cosmetics.dm index aa7f5f02576..b7ac6c39493 100644 --- a/code/modules/client/preference/loadout/loadout_cosmetics.dm +++ b/code/modules/client/preference/loadout/loadout_cosmetics.dm @@ -21,12 +21,4 @@ /datum/gear/lipstick/lime display_name = "lipstick, lime" - path = /obj/item/lipstick/lime - -/datum/gear/monocle - display_name = "monocle" - path = /obj/item/clothing/glasses/monocle - -/datum/gear/sunglasses - display_name = "cheap sunglasses" - path = /obj/item/clothing/glasses/sunglasses/fake \ No newline at end of file + path = /obj/item/lipstick/lime \ No newline at end of file diff --git a/code/modules/client/preference/loadout/loadout_donor.dm b/code/modules/client/preference/loadout/loadout_donor.dm index 5558a988209..830b10b7055 100644 --- a/code/modules/client/preference/loadout/loadout_donor.dm +++ b/code/modules/client/preference/loadout/loadout_donor.dm @@ -18,12 +18,10 @@ /datum/gear/donor/furcape display_name = "Fur Cape" path = /obj/item/clothing/suit/furcape - cost = 2 /datum/gear/donor/furcoat display_name = "Fur Coat" path = /obj/item/clothing/suit/furcoat - cost = 2 /datum/gear/donor/kamina display_name = "Spiky Orange-tinted Shades" @@ -33,10 +31,6 @@ display_name = "Spiky Green-tinted Shades" path = /obj/item/clothing/glasses/fluff/kamina/green -/datum/gear/donor/hipster - display_name = "Hipster Glasses" - path = /obj/item/clothing/glasses/regular/hipster - /datum/gear/donor/threedglasses display_name = "Threed Glasses" path = /obj/item/clothing/glasses/threedglasses diff --git a/code/modules/client/preference/loadout/loadout_glasses.dm b/code/modules/client/preference/loadout/loadout_glasses.dm new file mode 100644 index 00000000000..94f2555bdba --- /dev/null +++ b/code/modules/client/preference/loadout/loadout_glasses.dm @@ -0,0 +1,24 @@ +/datum/gear/glasses + subtype_path = /datum/gear/glasses + slot = slot_glasses + sort_category = "Glasses" + +/datum/gear/glasses/sunglasses + display_name = "cheap sunglasses" + path = /obj/item/clothing/glasses/sunglasses_fake + +/datum/gear/glasses/eyepatch + display_name = "Eyepatch" + path = /obj/item/clothing/glasses/eyepatch + +/datum/gear/glasses/hipster + display_name = "Hipster glasses" + path = /obj/item/clothing/glasses/regular/hipster + +/datum/gear/glasses/monocle + display_name = "Monocle" + path = /obj/item/clothing/glasses/monocle + +/datum/gear/glasses/prescription + display_name = "Prescription glasses" + path = /obj/item/clothing/glasses/regular \ No newline at end of file diff --git a/code/modules/client/preference/loadout/loadout_gloves.dm b/code/modules/client/preference/loadout/loadout_gloves.dm new file mode 100644 index 00000000000..cd8d5a7c8e1 --- /dev/null +++ b/code/modules/client/preference/loadout/loadout_gloves.dm @@ -0,0 +1,8 @@ +/datum/gear/gloves + subtype_path = /datum/gear/gloves + slot = slot_gloves + sort_category = "Gloves" + +/datum/gear/gloves/fingerless + display_name = "Fingerless Gloves" + path = /obj/item/clothing/gloves/fingerless \ No newline at end of file diff --git a/code/modules/client/preference/loadout/loadout_shoes.dm b/code/modules/client/preference/loadout/loadout_shoes.dm index 519cadcc044..5031f4333fb 100644 --- a/code/modules/client/preference/loadout/loadout_shoes.dm +++ b/code/modules/client/preference/loadout/loadout_shoes.dm @@ -27,25 +27,32 @@ /datum/gear/shoes/cowboyboots display_name = "cowboy boots, brown" - cost = 1 - path = /obj/item/clothing/shoes/cowboyboots + path = /obj/item/clothing/shoes/cowboy /datum/gear/shoes/cowboyboots_black display_name = "cowboy boots, black" - cost = 1 - path = /obj/item/clothing/shoes/cowboyboots/black + path = /obj/item/clothing/shoes/cowboy/black /datum/gear/shoes/cowboyboots/white display_name = "cowboy boots, white" - cost = 1 - path = /obj/item/clothing/shoes/cowboyboots/white + path = /obj/item/clothing/shoes/cowboy/white /datum/gear/shoes/cowboyboots/pink display_name = "cowboy boots, pink" - cost = 1 - path = /obj/item/clothing/shoes/cowboyboots/pink - + path = /obj/item/clothing/shoes/cowboy/pink + /datum/gear/shoes/laceup display_name = "laceup shoes" - cost = 1 path = /obj/item/clothing/shoes/laceup + +/datum/gear/shoes/blackshoes + display_name = "Black shoes" + path = /obj/item/clothing/shoes/black + +/datum/gear/shoes/brownshoes + display_name = "Brown shoes" + path = /obj/item/clothing/shoes/brown + +/datum/gear/shoes/whiteshoes + display_name = "White shoes" + path = /obj/item/clothing/shoes/white \ No newline at end of file diff --git a/code/modules/client/preference/loadout/loadout_suit.dm b/code/modules/client/preference/loadout/loadout_suit.dm index 3d6b5ded994..32a9bae99e7 100644 --- a/code/modules/client/preference/loadout/loadout_suit.dm +++ b/code/modules/client/preference/loadout/loadout_suit.dm @@ -1,7 +1,6 @@ /datum/gear/suit subtype_path = /datum/gear/suit slot = slot_wear_suit - cost = 2 sort_category = "External Wear" //WINTER COATS @@ -105,6 +104,10 @@ path = /obj/item/clothing/suit/armor/secjacket allowed_roles = list("Head of Security", "Warden", "Detective", "Security Officer", "Security Pod Pilot") +/datum/gear/suit/ianshirt + display_name = "Ian Shirt" + path = /obj/item/clothing/suit/ianshirt + /datum/gear/suit/poncho display_name = "poncho, classic" path = /obj/item/clothing/suit/poncho diff --git a/code/modules/client/preference/loadout/loadout_uniform.dm b/code/modules/client/preference/loadout/loadout_uniform.dm index f4a5c465aba..eb5264a0975 100644 --- a/code/modules/client/preference/loadout/loadout_uniform.dm +++ b/code/modules/client/preference/loadout/loadout_uniform.dm @@ -2,7 +2,6 @@ /datum/gear/uniform subtype_path = /datum/gear/uniform slot = slot_w_uniform - cost = 2 sort_category = "Uniforms and Casual Dress" /datum/gear/uniform/skirt diff --git a/code/modules/client/preference/preferences.dm b/code/modules/client/preference/preferences.dm index 97f9ddc6169..7fce23b9e4c 100644 --- a/code/modules/client/preference/preferences.dm +++ b/code/modules/client/preference/preferences.dm @@ -201,6 +201,8 @@ var/global/list/special_role_times = list( //minimum age (in days) for accounts //Gear stuff var/list/gear = list() var/gear_tab = "General" + // Parallax + var/parallax = PARALLAX_HIGH /datum/preferences/New(client/C) parent = C @@ -462,6 +464,19 @@ var/global/list/special_role_times = list( //minimum age (in days) for accounts dat += "OOC Color:     Change
      " if(config.allow_Metadata) dat += "OOC Notes: Edit
      " + dat += "Parallax (Fancy Space): " + switch (parallax) + if(PARALLAX_LOW) + dat += "Low" + if(PARALLAX_MED) + dat += "Medium" + if(PARALLAX_INSANE) + dat += "Insane" + if(PARALLAX_DISABLE) + dat += "Disabled" + else + dat += "High" + dat += "
      " dat += "Play Admin MIDIs: [(sound & SOUND_MIDI) ? "Yes" : "No"]
      " dat += "Play Lobby Music: [(sound & SOUND_LOBBY) ? "Yes" : "No"]
      " dat += "Randomized Character Slot: [randomslot ? "Yes" : "No"]
      " @@ -2072,6 +2087,7 @@ var/global/list/special_role_times = list( //minimum age (in days) for accounts if(href_list["tab"]) current_tab = text2num(href_list["tab"]) + if("ambientocclusion") toggles ^= AMBIENT_OCCLUSION if(parent && parent.screen && parent.screen.len) @@ -2080,6 +2096,19 @@ var/global/list/special_role_times = list( //minimum age (in days) for accounts if(toggles & AMBIENT_OCCLUSION) PM.filters += FILTER_AMBIENT_OCCLUSION + if("parallax") + var/parallax_styles = list( + "Off" = PARALLAX_DISABLE, + "Low" = PARALLAX_LOW, + "Medium" = PARALLAX_MED, + "High" = PARALLAX_HIGH, + "Insane" = PARALLAX_INSANE + ) + parallax = parallax_styles[input(user, "Pick a parallax style", "Parallax Style") as null|anything in parallax_styles] + if(parent && parent.mob && parent.mob.hud_used) + parent.mob.hud_used.update_parallax_pref() + + ShowChoices(user) return 1 diff --git a/code/modules/client/preference/preferences_mysql.dm b/code/modules/client/preference/preferences_mysql.dm index cdbfe2afb2f..6090538f2b3 100644 --- a/code/modules/client/preference/preferences_mysql.dm +++ b/code/modules/client/preference/preferences_mysql.dm @@ -20,7 +20,8 @@ clientfps, atklog, fuid, - afk_watch + afk_watch, + parallax FROM [format_table_name("player")] WHERE ckey='[C.ckey]'"} ) @@ -54,6 +55,7 @@ atklog = text2num(query.item[18]) fuid = text2num(query.item[19]) afk_watch = text2num(query.item[20]) + parallax = text2num(query.item[21]) //Sanitize ooccolor = sanitize_hexcolor(ooccolor, initial(ooccolor)) @@ -75,6 +77,7 @@ atklog = sanitize_integer(atklog, 0, 100, initial(atklog)) fuid = sanitize_integer(fuid, 0, 10000000, initial(fuid)) afk_watch = sanitize_integer(afk_watch, 0, 1, initial(afk_watch)) + parallax = sanitize_integer(parallax, 0, 16, initial(parallax)) return 1 /datum/preferences/proc/save_preferences(client/C) @@ -105,7 +108,8 @@ ghost_anonsay='[ghost_anonsay]', clientfps='[clientfps]', atklog='[atklog]', - afk_watch='[afk_watch]' + afk_watch='[afk_watch]', + parallax='[parallax]' WHERE ckey='[C.ckey]'"} ) diff --git a/code/modules/client/preference/preferences_toggles.dm b/code/modules/client/preference/preferences_toggles.dm index e164a2ab843..c1ad8d6d103 100644 --- a/code/modules/client/preference/preferences_toggles.dm +++ b/code/modules/client/preference/preferences_toggles.dm @@ -201,6 +201,19 @@ to_chat(src, "You will no longer hear musical instruments.") feedback_add_details("admin_verb","TInstru") //If you are copy-pasting this, ensure the 2nd parameter is unique to the new proc! +/client/verb/Toggle_disco() //to toggle off the disco machine locally, in case it gets too annoying + set name = "Hear/Silence Dance Machine" + set category = "Preferences" + set desc = "Toggles hearing and dancing to the radiant dance machine" + prefs.sound ^= SOUND_DISCO + prefs.save_preferences(src) + if(prefs.sound & SOUND_DISCO) + to_chat(src, "You will now hear and dance to the radiant dance machine.") + else + to_chat(src, "You will no longer hear or dance to the radiant dance machine.") + usr.stop_sound_channel(CHANNEL_JUKEBOX) + feedback_add_details("admin_verb","Tdd") //If you are copy-pasting this, ensure the 2nd parameter is unique to the new proc! + /client/verb/setup_character() set name = "Game Preferences" set category = "Preferences" diff --git a/code/modules/clothing/chameleon.dm b/code/modules/clothing/chameleon.dm index e62fc3c2814..f2e9e639dd6 100644 --- a/code/modules/clothing/chameleon.dm +++ b/code/modules/clothing/chameleon.dm @@ -15,7 +15,8 @@ standard_outfit_options = list() for(var/path in subtypesof(/datum/outfit/job)) var/datum/outfit/O = path - standard_outfit_options[initial(O.name)] = path + if(initial(O.can_be_admin_equipped)) + standard_outfit_options[initial(O.name)] = path sortTim(standard_outfit_options, /proc/cmp_text_asc) outfit_options = standard_outfit_options diff --git a/code/modules/clothing/clothing.dm b/code/modules/clothing/clothing.dm index 4bbf68b4b7f..96cff51ec4d 100644 --- a/code/modules/clothing/clothing.dm +++ b/code/modules/clothing/clothing.dm @@ -2,7 +2,6 @@ name = "clothing" burn_state = FLAMMABLE var/list/species_restricted = null //Only these species can wear this kit. - var/hardsuit_restrict_helmet = 0 // Stops the user from equipping a hardsuit helmet without attaching it to the suit first. var/scan_reagents = 0 //Can the wearer see reagents while it's equipped? /* @@ -18,8 +17,10 @@ var/flash_protect = 0 //What level of bright light protection item has. 1 = Flashers, Flashes, & Flashbangs | 2 = Welding | -1 = OH GOD WELDING BURNT OUT MY RETINAS var/tint = 0 //Sets the item's level of visual impairment tint, normally set to the same as flash_protect var/up = 0 //but seperated to allow items to protect but not impair vision, like space helmets + var/visor_flags = 0 //flags that are added/removed when an item is adjusted up/down var/visor_flags_inv = 0 //same as visor_flags, but for flags_inv + var/visor_vars_to_toggle = VISOR_FLASHPROTECT | VISOR_TINT | VISOR_VISIONFLAGS | VISOR_DARKNESSVIEW | VISOR_INVISVIEW //what to toggle when toggled with weldingvisortoggle() var/toggle_message = null var/alt_toggle_message = null @@ -30,6 +31,39 @@ var/species_disguise = null var/magical = FALSE +/obj/item/clothing/proc/weldingvisortoggle(mob/user) //proc to toggle welding visors on helmets, masks, goggles, etc. + if(!can_use(user)) + return FALSE + + visor_toggling() + + to_chat(user, "You adjust \the [src] [up ? "up" : "down"].") + + if(iscarbon(user)) + var/mob/living/carbon/C = user + C.head_update(src, forced = 1) + for(var/X in actions) + var/datum/action/A = X + A.UpdateButtonIcon() + return TRUE + +/obj/item/clothing/proc/visor_toggling() //handles all the actual toggling of flags + up = !up + flags ^= visor_flags + flags_inv ^= visor_flags_inv + flags_cover ^= initial(flags_cover) + icon_state = "[initial(icon_state)][up ? "up" : ""]" + if(visor_vars_to_toggle & VISOR_FLASHPROTECT) + flash_protect ^= initial(flash_protect) + if(visor_vars_to_toggle & VISOR_TINT) + tint ^= initial(tint) + +/obj/item/clothing/proc/can_use(mob/user) + if(user && ismob(user)) + if(!user.incapacitated()) + return TRUE + return FALSE + //BS12: Species-restricted clothing check. /obj/item/clothing/mob_can_equip(M as mob, slot) @@ -90,6 +124,10 @@ throwforce = 2 slot_flags = SLOT_EARS burn_state = FIRE_PROOF + sprite_sheets = list( + "Vox" = 'icons/mob/species/vox/ears.dmi', + "Vox Armalis" = 'icons/mob/species/armalis/ears.dmi' + ) //We read you loud and skree-er. /obj/item/clothing/ears/attack_hand(mob/user) if(!user) @@ -406,7 +444,8 @@ BLIND // can't see anything slowdown = SHOES_SLOWDOWN sprite_sheets = list( - "Vox" = 'icons/mob/species/vox/shoes.dmi' + "Vox" = 'icons/mob/species/vox/shoes.dmi', + "Drask" = 'icons/mob/species/drask/shoes.dmi' ) /obj/item/clothing/shoes/attackby(obj/item/I, mob/user, params) @@ -469,6 +508,7 @@ BLIND // can't see anything armor = list(melee = 0, bullet = 0, laser = 0, energy = 0, bomb = 0, bio = 0, rad = 0) slot_flags = SLOT_OCLOTHING var/blood_overlay_type = "suit" + var/suittoggled = FALSE var/suit_adjusted = 0 var/ignore_suitadjust = 1 var/adjust_flavour = null @@ -556,7 +596,7 @@ BLIND // can't see anything min_cold_protection_temperature = SPACE_HELM_MIN_TEMP_PROTECT heat_protection = HEAD max_heat_protection_temperature = SPACE_HELM_MAX_TEMP_PROTECT - species_restricted = list("exclude","Diona","Vox","Wryn") + species_restricted = list("exclude","Vox","Wryn") flash_protect = 2 strip_delay = 50 put_on_delay = 50 @@ -584,7 +624,7 @@ BLIND // can't see anything put_on_delay = 80 burn_state = FIRE_PROOF hide_tail_by_species = null - species_restricted = list("exclude","Diona","Vox","Wryn") + species_restricted = list("exclude","Vox","Wryn") //Under clothing /obj/item/clothing/under @@ -625,38 +665,45 @@ BLIND // can't see anything /obj/item/clothing/under/proc/can_attach_accessory(obj/item/clothing/accessory/A) if(istype(A)) - . = 1 + . = TRUE else - return 0 + return FALSE + if(accessories.len) for(var/obj/item/clothing/accessory/AC in accessories) if((A.slot in list(ACCESSORY_SLOT_UTILITY, ACCESSORY_SLOT_ARMBAND)) && AC.slot == A.slot) - return 0 + return FALSE if(!A.allow_duplicates && AC.type == A.type) - return 0 + return FALSE /obj/item/clothing/under/attackby(obj/item/I, mob/user, params) if(istype(I, /obj/item/clothing/accessory)) - var/obj/item/clothing/accessory/A = I - if(can_attach_accessory(A)) - user.unEquip(I) // Make absolutely sure this accessory is removed from hands - accessories += A - A.on_attached(src, user) - - if(istype(loc, /mob/living/carbon/human)) - var/mob/living/carbon/human/H = loc - H.update_inv_w_uniform() - - return - else - to_chat(user, "You cannot attach more accessories of this type to [src].") + attach_accessory(I, user, TRUE) if(accessories.len) for(var/obj/item/clothing/accessory/A in accessories) A.attackby(I, user, params) - return + return TRUE - ..() + . = ..() + +/obj/item/clothing/under/proc/attach_accessory(obj/item/clothing/accessory/A, mob/user, unequip = FALSE) + if(can_attach_accessory(A)) + if(unequip && !user.unEquip(A)) // Make absolutely sure this accessory is removed from hands + return FALSE + + accessories += A + A.on_attached(src, user) + + if(ishuman(loc)) + var/mob/living/carbon/human/H = loc + H.update_inv_w_uniform() + + return TRUE + else + to_chat(user, "You cannot attach more accessories of this type to [src].") + + return FALSE /obj/item/clothing/under/examine(mob/user) ..(user) diff --git a/code/modules/clothing/ears/ears.dm b/code/modules/clothing/ears/ears.dm index 2e3a1d40bda..74164f0e245 100644 --- a/code/modules/clothing/ears/ears.dm +++ b/code/modules/clothing/ears/ears.dm @@ -14,7 +14,7 @@ desc = "Unce unce unce unce." var/on = 0 icon_state = "headphones0" - item_state = "earmuffs" + item_state = null actions_types = list(/datum/action/item_action/toggle_headphones) burn_state = FLAMMABLE diff --git a/code/modules/clothing/glasses/glasses.dm b/code/modules/clothing/glasses/glasses.dm index 0f1aad16814..81ab79adbc4 100644 --- a/code/modules/clothing/glasses/glasses.dm +++ b/code/modules/clothing/glasses/glasses.dm @@ -30,6 +30,21 @@ return return ..() +/obj/item/clothing/glasses/visor_toggling() + ..() + if(visor_vars_to_toggle & VISOR_VISIONFLAGS) + vision_flags ^= initial(vision_flags) + if(visor_vars_to_toggle & VISOR_DARKNESSVIEW) + see_in_dark ^= initial(see_in_dark) + if(visor_vars_to_toggle & VISOR_INVISVIEW) + invis_view ^= initial(invis_view) + +/obj/item/clothing/glasses/weldingvisortoggle(mob/user) + . = ..() + if(. && user) + user.update_sight() + user.update_inv_glasses() + /obj/item/clothing/glasses/meson name = "Optical Meson Scanner" desc = "Used for seeing walls, floors, and stuff through anything." @@ -43,7 +58,8 @@ sprite_sheets = list( "Vox" = 'icons/mob/species/vox/eyes.dmi', "Drask" = 'icons/mob/species/drask/eyes.dmi', - "Grey" = 'icons/mob/species/grey/eyes.dmi' + "Grey" = 'icons/mob/species/grey/eyes.dmi', + "Drask" = 'icons/mob/species/drask/eyes.dmi' ) /obj/item/clothing/glasses/meson/night @@ -91,7 +107,8 @@ sprite_sheets = list( "Vox" = 'icons/mob/species/vox/eyes.dmi', - "Grey" = 'icons/mob/species/grey/eyes.dmi' + "Grey" = 'icons/mob/species/grey/eyes.dmi', + "Drask" = 'icons/mob/species/drask/eyes.dmi' ) actions_types = list(/datum/action/item_action/toggle_research_scanner) @@ -140,7 +157,8 @@ sprite_sheets = list( "Vox" = 'icons/mob/species/vox/eyes.dmi', - "Grey" = 'icons/mob/species/grey/eyes.dmi' + "Grey" = 'icons/mob/species/grey/eyes.dmi', + "Drask" = 'icons/mob/species/drask/eyes.dmi' ) /obj/item/clothing/glasses/monocle @@ -196,7 +214,8 @@ sprite_sheets = list( "Vox" = 'icons/mob/species/vox/eyes.dmi', - "Grey" = 'icons/mob/species/grey/eyes.dmi' + "Grey" = 'icons/mob/species/grey/eyes.dmi', + "Drask" = 'icons/mob/species/drask/eyes.dmi' ) /obj/item/clothing/glasses/regular/hipster @@ -213,7 +232,8 @@ sprite_sheets = list( "Vox" = 'icons/mob/species/vox/eyes.dmi', - "Grey" = 'icons/mob/species/grey/eyes.dmi' + "Grey" = 'icons/mob/species/grey/eyes.dmi', + "Drask" = 'icons/mob/species/drask/eyes.dmi' ) /obj/item/clothing/glasses/gglasses @@ -224,7 +244,8 @@ sprite_sheets = list( "Vox" = 'icons/mob/species/vox/eyes.dmi', - "Grey" = 'icons/mob/species/grey/eyes.dmi' + "Grey" = 'icons/mob/species/grey/eyes.dmi', + "Drask" = 'icons/mob/species/drask/eyes.dmi' ) prescription_upgradable = 1 @@ -244,9 +265,11 @@ "Grey" = 'icons/mob/species/grey/eyes.dmi' ) -/obj/item/clothing/glasses/sunglasses/fake +/obj/item/clothing/glasses/sunglasses_fake desc = "Cheap, plastic sunglasses. They don't even have UV protection." name = "cheap sunglasses" + icon_state = "sun" + item_state = "sunglasses" see_in_dark = 0 flash_protect = 0 tint = 0 @@ -324,40 +347,15 @@ actions_types = list(/datum/action/item_action/toggle) flash_protect = 2 tint = 2 - + visor_vars_to_toggle = VISOR_FLASHPROTECT | VISOR_TINT sprite_sheets = list( "Vox" = 'icons/mob/species/vox/eyes.dmi', "Drask" = 'icons/mob/species/drask/eyes.dmi', "Grey" = 'icons/mob/species/grey/eyes.dmi' ) -/obj/item/clothing/glasses/welding/attack_self() - toggle() - -/obj/item/clothing/glasses/welding/proc/toggle() - if(up) - up = !up - flags_cover |= GLASSESCOVERSEYES - flags_inv |= HIDEEYES - icon_state = initial(icon_state) - to_chat(usr, "You flip the [src] down to protect your eyes.") - flash_protect = 2 - tint = initial(tint) //better than istype - else - up = !up - flags_cover &= ~GLASSESCOVERSEYES - flags_inv &= ~HIDEEYES - icon_state = "[initial(icon_state)]up" - to_chat(usr, "You push the [src] up out of your face.") - flash_protect = 0 - tint = 0 - var/mob/living/carbon/user = usr - user.update_tint() - user.update_inv_glasses() - - for(var/X in actions) - var/datum/action/A = X - A.UpdateButtonIcon() +/obj/item/clothing/glasses/welding/attack_self(mob/user) + weldingvisortoggle(user) /obj/item/clothing/glasses/welding/superior name = "superior welding goggles" @@ -397,7 +395,8 @@ sprite_sheets = list( "Vox" = 'icons/mob/species/vox/eyes.dmi', - "Grey" = 'icons/mob/species/grey/eyes.dmi' + "Grey" = 'icons/mob/species/grey/eyes.dmi', + "Drask" = 'icons/mob/species/drask/eyes.dmi' ) /obj/item/clothing/glasses/thermal/emp_act(severity) @@ -438,6 +437,7 @@ item_state = "eyepatch" flags = NODROP + /obj/item/clothing/glasses/godeye name = "eye of god" desc = "A strange eye, said to have been torn from an omniscient creature that used to roam the wastes." @@ -450,6 +450,12 @@ flags_cover = null lighting_alpha = LIGHTING_PLANE_ALPHA_MOSTLY_INVISIBLE + sprite_sheets = list( + "Vox" = 'icons/mob/species/vox/eyes.dmi', + "Grey" = 'icons/mob/species/grey/eyes.dmi', + "Drask" = 'icons/mob/species/drask/eyes.dmi' + ) + /obj/item/clothing/glasses/godeye/attackby(obj/item/W as obj, mob/user as mob, params) if(istype(W, src) && W != src && W.loc == user) if(W.icon_state == "godeye") @@ -475,7 +481,9 @@ tint = 0 sprite_sheets = list( - "Vox" = 'icons/mob/species/vox/eyes.dmi' + "Vox" = 'icons/mob/species/vox/eyes.dmi', + "Grey" = 'icons/mob/species/grey/eyes.dmi', + "Drask" = 'icons/mob/species/drask/eyes.dmi' ) /obj/item/clothing/glasses/tajblind/eng diff --git a/code/modules/clothing/glasses/hud.dm b/code/modules/clothing/glasses/hud.dm index 049710bbe3e..27cd78afad3 100644 --- a/code/modules/clothing/glasses/hud.dm +++ b/code/modules/clothing/glasses/hud.dm @@ -38,12 +38,6 @@ "Grey" = 'icons/mob/species/grey/eyes.dmi' ) -/obj/item/clothing/glasses/hud/health/health_advanced - name = "\improper Advanced Health Scanner HUD" - desc = "A heads-up display that scans the humans in view and provides accurate data about their health status. Includes anti-flash filter." - icon_state = "advmedhud" - flash_protect = 1 - /obj/item/clothing/glasses/hud/health/night name = "\improper Night Vision Health Scanner HUD" desc = "An advanced medical head-up display that allows doctors to find patients in complete darkness." @@ -54,6 +48,14 @@ lighting_alpha = LIGHTING_PLANE_ALPHA_MOSTLY_VISIBLE prescription_upgradable = 0 +/obj/item/clothing/glasses/hud/health/sunglasses + name = "medical HUDSunglasses" + desc = "Sunglasses with a medical HUD." + icon_state = "sunhudmed" + see_in_dark = 1 + flash_protect = 1 + tint = 1 + /obj/item/clothing/glasses/hud/diagnostic name = "Diagnostic HUD" desc = "A heads-up display capable of analyzing the integrity and status of robotics and exosuits." @@ -63,6 +65,7 @@ sprite_sheets = list( "Vox" = 'icons/mob/species/vox/eyes.dmi', + "Drask" = 'icons/mob/species/drask/eyes.dmi', "Grey" = 'icons/mob/species/grey/eyes.dmi' ) @@ -76,6 +79,14 @@ lighting_alpha = LIGHTING_PLANE_ALPHA_MOSTLY_VISIBLE prescription_upgradable = 0 +/obj/item/clothing/glasses/hud/diagnostic/sunglasses + name = "diagnostic sunglasses" + desc = "Sunglasses with a diagnostic HUD." + icon_state = "sunhuddiag" + item_state = "glasses" + flash_protect = 1 + tint = 1 + /obj/item/clothing/glasses/hud/security name = "\improper Security HUD" desc = "A heads-up display that scans the humans in view and provides accurate data about their ID status and security records." @@ -91,6 +102,7 @@ "Grey" = 'icons/mob/species/grey/eyes.dmi' ) + /obj/item/clothing/glasses/hud/security/sunglasses/jensenshades name = "augmented shades" desc = "Polarized bioneural eyewear, designed to augment your vision." @@ -138,6 +150,7 @@ sprite_sheets = list( "Vox" = 'icons/mob/species/vox/eyes.dmi', + "Drask" = 'icons/mob/species/drask/eyes.dmi', "Grey" = 'icons/mob/species/grey/eyes.dmi' ) @@ -176,7 +189,9 @@ up = 0 sprite_sheets = list( - "Vox" = 'icons/mob/species/vox/eyes.dmi' + "Vox" = 'icons/mob/species/vox/eyes.dmi', + "Grey" = 'icons/mob/species/grey/eyes.dmi', + "Drask" = 'icons/mob/species/drask/eyes.dmi' ) /obj/item/clothing/glasses/hud/health/tajblind/attack_self() diff --git a/code/modules/clothing/gloves/miscellaneous.dm b/code/modules/clothing/gloves/miscellaneous.dm index 8e5e658e31a..a06b01de65d 100644 --- a/code/modules/clothing/gloves/miscellaneous.dm +++ b/code/modules/clothing/gloves/miscellaneous.dm @@ -38,6 +38,21 @@ max_heat_protection_temperature = GLOVES_MAX_TEMP_PROTECT burn_state = FIRE_PROOF +/obj/item/clothing/gloves/bracer + name = "bone bracers" + desc = "For when you're expecting to get slapped on the wrist. Offers modest protection to your arms." + icon_state = "bracers" + item_state = "bracers" + item_color = null //So they don't wash. + transfer_prints = TRUE + strip_delay = 40 + body_parts_covered = ARMS + cold_protection = ARMS + min_cold_protection_temperature = GLOVES_MIN_TEMP_PROTECT + max_heat_protection_temperature = GLOVES_MAX_TEMP_PROTECT + resistance_flags = NONE + armor = list(melee = 15, bullet = 25, laser = 15, energy = 15, bomb = 20, bio = 10, rad = 0) + /obj/item/clothing/gloves/botanic_leather desc = "These leather gloves protect against thorns, barbs, prickles, spikes and other harmful objects of floral origin." name = "botanist's leather gloves" diff --git a/code/modules/clothing/head/beanie.dm b/code/modules/clothing/head/beanie.dm new file mode 100644 index 00000000000..af7e805b232 --- /dev/null +++ b/code/modules/clothing/head/beanie.dm @@ -0,0 +1,96 @@ + +//BeanieStation13 Redux + +//Plus a bobble hat, lets be inclusive!! + +/obj/item/clothing/head/beanie //Default is white, this is meant to be seen + name = "white beanie" + desc = "A stylish beanie. The perfect winter accessory for those with a keen fashion sense, and those who just can't handle a cold breeze on their heads." + icon_state = "beanie" //Default white + item_color = "beanie" + +/obj/item/clothing/head/beanie/black + name = "black beanie" + icon_state = "beanie" + color = "#4A4A4B" //Grey but it looks black + +/obj/item/clothing/head/beanie/red + name = "red beanie" + icon_state = "beanie" + color = "#D91414" //Red + +/obj/item/clothing/head/beanie/green + name = "green beanie" + icon_state = "beanie" + color = "#5C9E54" //Green + +/obj/item/clothing/head/beanie/darkblue + name = "dark blue beanie" + icon_state = "beanie" + color = "#1E85BC" //Blue + +/obj/item/clothing/head/beanie/purple + name = "purple beanie" + icon_state = "beanie" + color = "#9557C5" //purple + +/obj/item/clothing/head/beanie/yellow + name = "yellow beanie" + icon_state = "beanie" + color = "#E0C14F" //Yellow + +/obj/item/clothing/head/beanie/orange + name = "orange beanie" + icon_state = "beanie" + color = "#C67A4B" //orange + +/obj/item/clothing/head/beanie/cyan + name = "cyan beanie" + icon_state = "beanie" + color = "#54A3CE" //Cyan (Or close to it) + +//Striped Beanies have unique sprites + +/obj/item/clothing/head/beanie/christmas + name = "christmas beanie" + icon_state = "beaniechristmas" + item_color = "beaniechristmas" + +/obj/item/clothing/head/beanie/striped + name = "striped beanie" + icon_state = "beaniestriped" + item_color = "beaniestriped" + +/obj/item/clothing/head/beanie/stripedred + name = "red striped beanie" + icon_state = "beaniestripedred" + item_color = "beaniestripedred" + +/obj/item/clothing/head/beanie/stripedblue + name = "blue striped beanie" + icon_state = "beaniestripedblue" + item_color = "beaniestripedblue" + +/obj/item/clothing/head/beanie/stripedgreen + name = "green striped beanie" + icon_state = "beaniestripedgreen" + item_color = "beaniestripedgreen" + +/obj/item/clothing/head/beanie/durathread + name = "durathread beanie" + desc = "A beanie made from durathread, its resilient fibres provide some protection to the wearer." + icon_state = "beaniedurathread" + item_color = null + armor = list(melee = 15, bullet = 5, laser = 15, energy = 5, bomb = 10, bio = 0, rad = 0) + +/obj/item/clothing/head/beanie/waldo + name = "red striped bobble hat" + desc = "If you're going on a worldwide hike, you'll need some cold protection." + icon_state = "waldo_hat" + item_color = "waldo_hat" + +/obj/item/clothing/head/beanie/rasta + name = "rastacap" + desc = "Perfect for tucking in those dreadlocks." + icon_state = "beanierasta" + item_color = "beanierasta" \ No newline at end of file diff --git a/code/modules/clothing/head/helmet.dm b/code/modules/clothing/head/helmet.dm index 4c915e5fc9c..13826e53ea1 100644 --- a/code/modules/clothing/head/helmet.dm +++ b/code/modules/clothing/head/helmet.dm @@ -227,6 +227,24 @@ obj/item/clothing/head/blob item_state = "knight_templar" armor = list(melee = 20, bullet = 7, laser = 2, energy = 2, bomb = 2, bio = 2, rad = 0) +/obj/item/clothing/head/helmet/skull + name = "skull helmet" + desc = "An intimidating tribal helmet, it doesn't look very comfortable." + flags_inv = HIDEMASK|HIDEEARS|HIDEEYES|HIDEFACE + flags_cover = HEADCOVERSEYES + armor = list(melee = 25, bullet = 25, laser = 25, energy = 10, bomb = 10, bio = 5, rad = 20) + icon_state = "skull" + item_state = "skull" + strip_delay = 100 + +/obj/item/clothing/head/helmet/durathread + name = "durathread helmet" + desc = "A helmet made from durathread and leather." + icon_state = "durathread" + item_state = "durathread" + armor = list(melee = 25, bullet = 10, laser = 20, energy = 10, bomb = 30, bio = 15, rad = 20) + strip_delay = 60 + //Commander /obj/item/clothing/head/helmet/ert/command name = "emergency response team commander helmet" diff --git a/code/modules/clothing/head/jobs.dm b/code/modules/clothing/head/jobs.dm index c31ab1ad2e4..9c96cbae961 100644 --- a/code/modules/clothing/head/jobs.dm +++ b/code/modules/clothing/head/jobs.dm @@ -82,6 +82,13 @@ desc = "A beret, an artists favorite headwear." icon_state = "beret" +/obj/item/clothing/head/beret/durathread + name = "durathread beret" + desc = "A beret made from durathread, its resilient fibres provide some protection to the wearer." + icon_state = "beretdurathread" + item_color = null + armor = list(melee = 15, bullet = 5, laser = 15, energy = 5, bomb = 10, bio = 0, rad = 0) + //Security /obj/item/clothing/head/HoS name = "head of security cap" diff --git a/code/modules/clothing/head/misc_special.dm b/code/modules/clothing/head/misc_special.dm index 35f346402f9..0501171d650 100644 --- a/code/modules/clothing/head/misc_special.dm +++ b/code/modules/clothing/head/misc_special.dm @@ -24,6 +24,7 @@ armor = list(melee = 10, bullet = 0, laser = 0, energy = 0, bomb = 0, bio = 0, rad = 0) flags_inv = (HIDEMASK|HIDEEARS|HIDEEYES|HIDEFACE) actions_types = list(/datum/action/item_action/toggle) + visor_flags_inv = HIDEMASK|HIDEEARS|HIDEEYES|HIDEFACE burn_state = FIRE_PROOF sprite_sheets = list( @@ -34,6 +35,9 @@ "Grey" = 'icons/mob/species/grey/helmet.dmi' ) +/obj/item/clothing/head/welding/attack_self(mob/user) + weldingvisortoggle(user) + /obj/item/clothing/head/welding/flamedecal name = "flame decal welding helmet" desc = "A welding helmet adorned with flame decals, and several cryptic slogans of varying degrees of legibility." diff --git a/code/modules/clothing/masks/breath.dm b/code/modules/clothing/masks/breath.dm index df229f5b9c3..638aa3c2c84 100644 --- a/code/modules/clothing/masks/breath.dm +++ b/code/modules/clothing/masks/breath.dm @@ -12,6 +12,7 @@ burn_state = FIRE_PROOF sprite_sheets = list( "Vox" = 'icons/mob/species/vox/mask.dmi', + "Vox Armalis" = 'icons/mob/species/armalis/mask.dmi', "Unathi" = 'icons/mob/species/unathi/mask.dmi', "Tajaran" = 'icons/mob/species/tajaran/mask.dmi', "Vulpkanin" = 'icons/mob/species/vulpkanin/mask.dmi', @@ -43,7 +44,7 @@ icon_state = "voxmask" item_state = "voxmask" permeability_coefficient = 0.01 - species_restricted = list("Vox") + species_restricted = list("Vox", "Vox Armalis") //These should fit the "Mega Vox" just fine. actions_types = list() /obj/item/clothing/mask/breath/vox/attack_self(var/mob/user) diff --git a/code/modules/clothing/masks/gasmask.dm b/code/modules/clothing/masks/gasmask.dm index 289250befac..db7295809b1 100644 --- a/code/modules/clothing/masks/gasmask.dm +++ b/code/modules/clothing/masks/gasmask.dm @@ -33,34 +33,12 @@ armor = list(melee = 10, bullet = 0, laser = 0, energy = 0, bomb = 0, bio = 0, rad = 0) origin_tech = "materials=2;engineering=3" actions_types = list(/datum/action/item_action/toggle) + flags_inv = HIDEEARS|HIDEEYES|HIDEFACE + flags_cover = MASKCOVERSEYES + visor_flags_inv = HIDEEYES -/obj/item/clothing/mask/gas/welding/attack_self() - toggle() - -/obj/item/clothing/mask/gas/welding/proc/toggle() - if(up) - up = !src.up - flags_cover |= (MASKCOVERSEYES) - flags_inv |= (HIDEEYES) - icon_state = initial(icon_state) - to_chat(usr, "You flip the [src] down to protect your eyes.") - flash_protect = 2 - tint = 2 - else - up = !up - flags_cover &= ~(MASKCOVERSEYES) - flags_inv &= ~(HIDEEYES) - icon_state = "[initial(icon_state)]up" - to_chat(usr, "You push the [src] up out of your face.") - flash_protect = 0 - tint = 0 - var/mob/living/carbon/user = usr - user.update_tint() - user.update_inv_wear_mask() //so our mob-overlays update - - for(var/X in actions) - var/datum/action/A = X - A.UpdateButtonIcon() +/obj/item/clothing/mask/gas/welding/attack_self(mob/user) + weldingvisortoggle(user) /obj/item/clothing/mask/gas/explorer name = "explorer gas mask" diff --git a/code/modules/clothing/masks/miscellaneous.dm b/code/modules/clothing/masks/miscellaneous.dm index b11dfd45d68..a60e4b2c2a6 100644 --- a/code/modules/clothing/masks/miscellaneous.dm +++ b/code/modules/clothing/masks/miscellaneous.dm @@ -214,7 +214,8 @@ "Unathi" = 'icons/mob/species/unathi/mask.dmi', "Tajaran" = 'icons/mob/species/tajaran/mask.dmi', "Vulpkanin" = 'icons/mob/species/vulpkanin/mask.dmi', - "Grey" = 'icons/mob/species/grey/mask.dmi' + "Grey" = 'icons/mob/species/grey/mask.dmi', + "Drask" = 'icons/mob/species/drask/eyes.dmi' ) @@ -233,7 +234,8 @@ "Unathi" = 'icons/mob/species/unathi/mask.dmi', "Tajaran" = 'icons/mob/species/tajaran/mask.dmi', "Vulpkanin" = 'icons/mob/species/vulpkanin/mask.dmi', - "Grey" = 'icons/mob/species/grey/mask.dmi' + "Grey" = 'icons/mob/species/grey/mask.dmi', + "Drask" = 'icons/mob/species/drask/mask.dmi' ) /obj/item/clothing/mask/fakemoustache/attack_self(mob/user) @@ -308,7 +310,8 @@ var/originalname = "" sprite_sheets = list( - "Grey" = 'icons/mob/species/grey/mask.dmi' + "Grey" = 'icons/mob/species/grey/mask.dmi', + "Drask" = 'icons/mob/species/drask/mask.dmi' ) /obj/item/clothing/mask/horsehead/equipped(mob/user, slot) @@ -420,7 +423,8 @@ "Unathi" = 'icons/mob/species/unathi/mask.dmi', "Tajaran" = 'icons/mob/species/tajaran/mask.dmi', "Vulpkanin" = 'icons/mob/species/vulpkanin/mask.dmi', - "Grey" = 'icons/mob/species/grey/mask.dmi' + "Grey" = 'icons/mob/species/grey/mask.dmi', + "Drask" = 'icons/mob/species/drask/mask.dmi' ) actions_types = list(/datum/action/item_action/adjust) @@ -479,6 +483,11 @@ item_color = "black" desc = "It's a black bandana." +/obj/item/clothing/mask/bandana/durathread + name = "durathread bandana" + desc = "A bandana made from durathread, you wish it would provide some protection to its wearer, but it's far too thin..." + icon_state = "banddurathread" + /obj/item/clothing/mask/cursedclown name = "cursed clown mask" desc = "This is a very, very odd looking mask." diff --git a/code/modules/clothing/shoes/miscellaneous.dm b/code/modules/clothing/shoes/miscellaneous.dm index bca650a30b1..3a94118e538 100644 --- a/code/modules/clothing/shoes/miscellaneous.dm +++ b/code/modules/clothing/shoes/miscellaneous.dm @@ -243,30 +243,55 @@ icon_state = "bsing" put_on_delay = 50 -/obj/item/clothing/shoes/cowboyboots +/obj/item/clothing/shoes/cowboy name = "cowboy boots" desc = "A pair a' brown boots." - icon_state = "cowboyboots" - item_color = "cowboyboots" + icon_state = "cowboy_brown" + item_color = "cowboy_brown" -/obj/item/clothing/shoes/cowboyboots/black +/obj/item/clothing/shoes/cowboy/black name = "black cowboy boots" desc = "A pair a' black rustlers' boots" - icon_state = "cowboyboots_black" - item_color = "cowboyboots_black" + icon_state = "cowboy_black" + item_color = "cowboy_black" -/obj/item/clothing/shoes/cowboyboots/white +/obj/item/clothing/shoes/cowboy/white name = "white cowboy boots" desc = "For the rancher in us all." - icon_state = "cowboyboots_white" - item_color = "cowboyboots_white" + icon_state = "cowboy_white" + item_color = "cowboy_white" -/obj/item/clothing/shoes/cowboyboots/pink +/obj/item/clothing/shoes/cowboy/fancy + name = "bilton wrangler boots" + desc = "A pair of authentic haute couture boots from Japanifornia. You doubt they have ever been close to cattle." + icon_state = "cowboy_fancy" + item_color = "cowboy_fancy" + +/obj/item/clothing/shoes/cowboy/pink name = "pink cowgirl boots" desc = "For a Rustlin' tustlin' cowgirl." icon_state = "cowboyboots_pink" item_color = "cowboyboots_pink" +/obj/item/clothing/shoes/cowboy/lizard + name = "lizard skin boots" + desc = "You can hear a faint hissing from inside the boots; you hope it is just a mournful ghost." + icon_state = "lizardboots_green" + +/obj/item/clothing/shoes/cowboy/lizardmasterwork + name = "\improper Hugs-The-Feet lizard skin boots" + desc = "A pair of masterfully crafted lizard skin boots. Finally a good application for the station's most bothersome inhabitants." + icon_state = "lizardboots_blue" + +/obj/effect/spawner/lootdrop/lizardboots + name = "random lizard boot quality" + desc = "Which ever gets picked, the lizard race loses" + icon = 'icons/obj/clothing/shoes.dmi' + icon_state = "lizardboots_green" + loot = list( + /obj/item/clothing/shoes/cowboy/lizard = 7, + /obj/item/clothing/shoes/cowboy/lizardmasterwork = 1) + /obj/item/clothing/shoes/footwraps name = "cloth footwraps" desc = "A roll of treated canvas used for wrapping claws or paws." diff --git a/code/modules/clothing/spacesuits/ert.dm b/code/modules/clothing/spacesuits/ert.dm index 099b46a10b9..60523d6c0e8 100644 --- a/code/modules/clothing/spacesuits/ert.dm +++ b/code/modules/clothing/spacesuits/ert.dm @@ -4,8 +4,8 @@ desc = "A helmet worn by members of the Nanotrasen Emergency Response Team. Armoured and space ready." icon_state = "hardsuit0-ert_commander" item_state = "helm-command" + item_color = "ert_commander" armor = list(melee = 45, bullet = 25, laser = 30, energy = 10, bomb = 25, bio = 100, rad = 50) - hardsuit_restrict_helmet = 0 // ERT helmets can be taken on and off at will. var/obj/machinery/camera/camera var/has_camera = TRUE strip_delay = 130 @@ -41,6 +41,7 @@ /obj/item/screwdriver, /obj/item/weldingtool, /obj/item/wirecutters, /obj/item/wrench, /obj/item/multitool, \ /obj/item/radio, /obj/item/analyzer, /obj/item/gun/energy/laser, /obj/item/gun/energy/pulse, \ /obj/item/gun/energy/gun/advtaser, /obj/item/melee/baton, /obj/item/gun/energy/gun, /obj/item/gun/projectile/automatic/lasercarbine, /obj/item/gun/energy/gun/blueshield, /obj/item/gun/energy/immolator/multi) + helmettype = /obj/item/clothing/head/helmet/space/hardsuit/ert strip_delay = 130 sprite_sheets = list( @@ -67,11 +68,13 @@ desc = "A suit worn by the commander of a Nanotrasen Emergency Response Team. Has blue highlights. Armoured, space ready, and fire resistant." icon_state = "ert_commander" item_state = "suit-command" + helmettype = /obj/item/clothing/head/helmet/space/hardsuit/ert/commander /obj/item/clothing/suit/space/hardsuit/ert/commander/gamma name = "elite emergency response team commander suit" max_heat_protection_temperature = FIRE_IMMUNITY_MAX_TEMP_PROTECT icon_state = "ert_gcommander" + helmettype = /obj/item/clothing/head/helmet/space/hardsuit/ert/commander/gamma //Security /obj/item/clothing/head/helmet/space/hardsuit/ert/security @@ -92,11 +95,13 @@ desc = "A suit worn by security members of a Nanotrasen Emergency Response Team. Has red highlights. Armoured, space ready, and fire resistant." icon_state = "ert_security" item_state = "syndicate-black-red" + helmettype = /obj/item/clothing/head/helmet/space/hardsuit/ert/security /obj/item/clothing/suit/space/hardsuit/ert/security/gamma name = "elite emergency response team security suit" max_heat_protection_temperature = FIRE_IMMUNITY_MAX_TEMP_PROTECT icon_state = "ert_gsecurity" + helmettype = /obj/item/clothing/head/helmet/space/hardsuit/ert/security/gamma //Engineer /obj/item/clothing/head/helmet/space/hardsuit/ert/engineer @@ -118,11 +123,13 @@ desc = "A suit worn by the engineers of a Nanotrasen Emergency Response Team. Has yellow highlights. Armoured, space ready, and fire resistant." icon_state = "ert_engineer" item_state = "suit-orange" + helmettype = /obj/item/clothing/head/helmet/space/hardsuit/ert/engineer /obj/item/clothing/suit/space/hardsuit/ert/engineer/gamma name = "elite emergency response team engineer suit" max_heat_protection_temperature = FIRE_IMMUNITY_MAX_TEMP_PROTECT icon_state = "ert_gengineer" + helmettype = /obj/item/clothing/head/helmet/space/hardsuit/ert/engineer/gamma //Medical /obj/item/clothing/head/helmet/space/hardsuit/ert/medical @@ -141,11 +148,13 @@ name = "emergency response team medical suit" desc = "A suit worn by medical members of a Nanotrasen Emergency Response Team. Has white highlights. Armoured and space ready." icon_state = "ert_medical" + helmettype = /obj/item/clothing/head/helmet/space/hardsuit/ert/medical /obj/item/clothing/suit/space/hardsuit/ert/medical/gamma name = "elite emergency response team medical suit" max_heat_protection_temperature = FIRE_IMMUNITY_MAX_TEMP_PROTECT icon_state = "ert_gmedical" + helmettype = /obj/item/clothing/head/helmet/space/hardsuit/ert/medical/gamma //Janitor /obj/item/clothing/head/helmet/space/hardsuit/ert/janitor @@ -159,15 +168,18 @@ max_heat_protection_temperature = FIRE_IMMUNITY_MAX_TEMP_PROTECT icon_state = "hardsuit0-gammajanitor" item_color = "gammajanitor" + /obj/item/clothing/suit/space/hardsuit/ert/janitor name = "emergency response team janitor suit" desc = "A suit worn by the janitorial of a Nanotrasen Emergency Response Team. Has purple highlights. Armoured, space ready, and fire resistant." icon_state = "ert_janitor" + helmettype = /obj/item/clothing/head/helmet/space/hardsuit/ert/janitor /obj/item/clothing/suit/space/hardsuit/ert/janitor/gamma name = "elite emergency response team janitor suit" max_heat_protection_temperature = FIRE_IMMUNITY_MAX_TEMP_PROTECT icon_state = "ert_gjanitor" + helmettype = /obj/item/clothing/head/helmet/space/hardsuit/ert/janitor/gamma //Paranormal /obj/item/clothing/head/helmet/space/hardsuit/ert/paranormal @@ -178,7 +190,7 @@ max_heat_protection_temperature = FIRE_IMMUNITY_MAX_TEMP_PROTECT sprite_sheets = null actions_types = list() - has_camera = 0 + has_camera = FALSE /obj/item/clothing/suit/space/hardsuit/ert/paranormal name = "paranormal response team suit" @@ -186,7 +198,7 @@ icon_state = "hardsuit-paranormal" max_heat_protection_temperature = FIRE_IMMUNITY_MAX_TEMP_PROTECT sprite_sheets = null - actions_types = list() + helmettype = /obj/item/clothing/head/helmet/space/hardsuit/ert/paranormal /obj/item/clothing/suit/space/hardsuit/ert/paranormal/New() ..() @@ -196,18 +208,26 @@ name = "inquisitor's helmet" icon_state = "hardsuit0-inquisitor" item_color = "inquisitor" + armor = list(melee = 65, bullet = 50, laser = 50, energy = 50, bomb = 50, bio = 100, rad = 100) /obj/item/clothing/suit/space/hardsuit/ert/paranormal/inquisitor name = "inquisitor's hardsuit" icon_state = "hardsuit-inquisitor" + helmettype = /obj/item/clothing/head/helmet/space/hardsuit/ert/paranormal/inquisitor + armor = list(melee = 65, bullet = 50, laser = 50, energy = 50, bomb = 50, bio = 100, rad = 100) + slowdown = 0 /obj/item/clothing/head/helmet/space/hardsuit/ert/paranormal/berserker name = "champion's helmet" desc = "Peering into the eyes of the helmet is enough to seal damnation." icon_state = "hardsuit0-berserker" item_color = "berserker" + armor = list(melee = 65, bullet = 50, laser = 50, energy = 50, bomb = 50, bio = 100, rad = 100) /obj/item/clothing/suit/space/hardsuit/ert/paranormal/berserker name = "champion's hardsuit" desc = "Voices echo from the hardsuit, driving the user insane." icon_state = "hardsuit-berserker" + helmettype = /obj/item/clothing/head/helmet/space/hardsuit/ert/paranormal/berserker + armor = list(melee = 65, bullet = 50, laser = 50, energy = 50, bomb = 50, bio = 100, rad = 100) + slowdown = 0 \ No newline at end of file diff --git a/code/modules/clothing/spacesuits/hardsuit.dm b/code/modules/clothing/spacesuits/hardsuit.dm index ead2c04016d..466fb2fc2fd 100644 --- a/code/modules/clothing/spacesuits/hardsuit.dm +++ b/code/modules/clothing/spacesuits/hardsuit.dm @@ -4,16 +4,17 @@ desc = "A special helmet designed for work in a hazardous, low-pressure environment." icon_state = "hardsuit0-engineering" item_state = "eng_helm" - hardsuit_restrict_helmet = 1 armor = list(melee = 10, bullet = 5, laser = 10, energy = 5, bomb = 10, bio = 100, rad = 75) + var/basestate = "hardsuit" allowed = list(/obj/item/flashlight) var/brightness_on = 4 //luminosity when on - var/on = 0 + var/on = FALSE + var/obj/item/clothing/suit/space/hardsuit/suit item_color = "engineering" //Determines used sprites: hardsuit[on]-[color] and hardsuit[on]-[color]2 (lying down sprite) actions_types = list(/datum/action/item_action/toggle_helmet_light) //Species-specific stuff. - species_restricted = list("exclude","Diona","Wryn") + species_restricted = list("exclude","Wryn") sprite_sheets = list( "Unathi" = 'icons/mob/species/unathi/helmet.dmi', "Tajaran" = 'icons/mob/species/tajaran/helmet.dmi', @@ -31,28 +32,21 @@ "Vulpkanin" = 'icons/obj/clothing/species/vulpkanin/hats.dmi' ) -/obj/item/clothing/head/helmet/space/hardsuit/equip_to_best_slot(mob/M) - if(hardsuit_restrict_helmet) - to_chat(M, "You must fasten the helmet to a hardsuit first. (Target the head and use on a hardsuit)") // Stop hardsuit helmet equipping - return 0 - ..() - /obj/item/clothing/head/helmet/space/hardsuit/attack_self(mob/user) toggle_light(user) /obj/item/clothing/head/helmet/space/hardsuit/proc/toggle_light(mob/user) on = !on - icon_state = "hardsuit[on]-[item_color]" - - if(on) - set_light(brightness_on) - else - set_light(0) + icon_state = "[basestate][on]-[item_color]" if(istype(user,/mob/living/carbon/human)) var/mob/living/carbon/human/H = user H.update_inv_head() + if(on) + set_light(brightness_on) + else + set_light(0) for(var/X in actions) var/datum/action/A = X A.UpdateButtonIcon() @@ -62,10 +56,32 @@ toggle_light() visible_message("[src]'s light fades and turns off.") +/obj/item/clothing/head/helmet/space/hardsuit/dropped(mob/user) + ..() + if(suit) + suit.RemoveHelmet() + /obj/item/clothing/head/helmet/space/hardsuit/item_action_slot_check(slot) if(slot == slot_head) return 1 +/obj/item/clothing/head/helmet/space/hardsuit/equipped(mob/user, slot) + ..() + if(slot != slot_head) + if(suit) + suit.RemoveHelmet() + else + qdel(src) + +/obj/item/clothing/head/helmet/space/hardsuit/proc/display_visor_message(var/msg) + var/mob/wearer = loc + if(msg && ishuman(wearer)) + wearer.show_message("[msg]", 1) + +/obj/item/clothing/head/helmet/space/hardsuit/emp_act(severity) + ..() + display_visor_message("[severity > 1 ? "Light" : "Strong"] electromagnetic pulse detected!") + /obj/item/clothing/suit/space/hardsuit name = "hardsuit" desc = "A special space suit for environments that might pose hazards beyond just the vacuum of space. Provides more protection than a standard space suit." @@ -74,10 +90,13 @@ armor = list(melee = 10, bullet = 5, laser = 10, energy = 5, bomb = 10, bio = 100, rad = 75) allowed = list(/obj/item/flashlight,/obj/item/tank,/obj/item/t_scanner, /obj/item/rcd, /obj/item/rpd) siemens_coefficient = 0 + var/obj/item/clothing/head/helmet/space/hardsuit/helmet actions_types = list(/datum/action/item_action/toggle_helmet) + var/helmettype = /obj/item/clothing/head/helmet/space/hardsuit + var/obj/item/tank/jetpack/suit/jetpack = null hide_tail_by_species = list("Vox" , "Vulpkanin" , "Unathi" , "Tajaran") - species_restricted = list("exclude","Diona","Wryn") + species_restricted = list("exclude", "Wryn") sprite_sheets = list( "Unathi" = 'icons/mob/species/unathi/suit.dmi', "Tajaran" = 'icons/mob/species/tajaran/suit.dmi', @@ -94,206 +113,113 @@ "Vulpkanin" = 'icons/obj/clothing/species/vulpkanin/suits.dmi' ) - //Breach thresholds, should ideally be inherited by most (if not all) hardsuits. - breach_threshold = 18 - can_breach = 0 - - //Component/device holders. - var/obj/item/stock_parts/gloves = null // Basic capacitor allows insulation, upgrades allow shock gloves etc. - - var/attached_boots = 1 // Can't wear boots if some are attached - var/obj/item/clothing/shoes/magboots/boots = null // Deployable boots, if any. - var/attached_helmet = 1 // Can't wear a helmet if one is deployable. - var/obj/item/clothing/head/helmet/helmet = null // Deployable helmet, if any. - - var/list/max_mounted_devices = 0 // Maximum devices. Easy. - var/list/can_mount = null // Types of device that can be hardpoint mounted. - var/list/mounted_devices = null // Holder for the above device. - var/obj/item/active_device = null // Currently deployed device, if any. - -/obj/item/clothing/suit/space/hardsuit/equipped(mob/M) +/obj/item/clothing/suit/space/hardsuit/New() + if(jetpack && ispath(jetpack)) + jetpack = new jetpack(src) ..() - var/mob/living/carbon/human/H = M - - if(!istype(H)) return - - spawn(1) //to ensure the slot is set before we continue - if(H.wear_suit != src) - return - - if(attached_helmet && helmet) - if(H.head) - to_chat(M, "You are unable to deploy your suit's helmet as \the [H.head] is in the way.") - else - to_chat(M, "Your suit's helmet deploys with a hiss.") - //TODO: Species check, skull damage for forcing an unfitting helmet on? - helmet.forceMove(H) - H.equip_to_slot(helmet, slot_head) - helmet.flags |= NODROP - - if(attached_boots && boots) - if(H.shoes) - to_chat(M, "You are unable to deploy your suit's magboots as \the [H.shoes] are in the way.") - else - to_chat(M, "Your suit's boots deploy with a hiss.") - boots.forceMove(H) - H.equip_to_slot(boots, slot_shoes) - boots.flags |= NODROP - -/obj/item/clothing/suit/space/hardsuit/dropped() +/obj/item/clothing/suit/space/hardsuit/attack_self(mob/user) + user.changeNext_move(CLICK_CD_MELEE) ..() - var/mob/living/carbon/human/H +/obj/item/clothing/suit/space/hardsuit/attackby(obj/item/I, mob/user, params) + if(istype(I, /obj/item/tank/jetpack/suit)) + if(jetpack) + to_chat(user, "[src] already has a jetpack installed.") + return + if(src == user.get_item_by_slot(slot_wear_suit)) //Make sure the player is not wearing the suit before applying the upgrade. + to_chat(user, "You cannot install the upgrade to [src] while wearing it.") + return - if(helmet) - H = helmet.loc - if(istype(H)) - if(helmet && H.head == helmet) - helmet.flags &= ~NODROP - H.unEquip(helmet) - helmet.forceMove(src) + if(user.unEquip(I)) + I.forceMove(src) + jetpack = I + to_chat(user, "You successfully install the jetpack into [src].") + return + else if(isscrewdriver(I)) + if(!jetpack) + to_chat(user, "[src] has no jetpack installed.") + return + if(src == user.get_item_by_slot(slot_wear_suit)) + to_chat(user, "You cannot remove the jetpack from [src] while wearing it.") + return - if(boots) - H = boots.loc - if(istype(H)) - if(boots && H.shoes == boots) - boots.flags &= ~NODROP - H.unEquip(boots) - boots.forceMove(src) + jetpack.turn_off(user) + jetpack.forceMove(drop_location()) + jetpack = null + to_chat(user, "You successfully remove the jetpack from [src].") + return + return ..() -/obj/item/clothing/suit/space/hardsuit/ui_action_click() +/obj/item/clothing/suit/space/hardsuit/equipped(mob/user, slot) ..() - toggle_helmet() - -/obj/item/clothing/suit/space/hardsuit/verb/toggle_helmet() - set name = "Toggle Helmet" - set category = "Object" - set src in usr - - if(!isliving(usr)) - return - - if(!helmet) - to_chat(usr, "There is no helmet installed.") - return - - var/mob/living/carbon/human/H = usr - - if(!istype(H)) return - if(H.stat) return - if(H.wear_suit != src) return - - if(H.head == helmet) - helmet.flags &= ~NODROP - H.unEquip(helmet) - helmet.loc = src - to_chat(H, "You retract your hardsuit helmet.") - else - if(H.head) - to_chat(H, "You cannot deploy your helmet while wearing another helmet.") - return - //TODO: Species check, skull damage for forcing an unfitting helmet on? - helmet.loc = H - helmet.pickup(H) - H.equip_to_slot(helmet, slot_head) - helmet.flags |= NODROP - to_chat(H, "You deploy your hardsuit helmet, sealing you off from the world.") - H.update_inv_head() - -/obj/item/clothing/suit/space/hardsuit/attackby(obj/item/W, mob/user, params) - if(!isliving(user)) - return - - if(istype(W,/obj/item/screwdriver) && can_modify(user)) - if(!helmet) - to_chat(user, "\The [src] does not have a helmet installed.") - else - to_chat(user, "You detach \the [helmet] from \the [src]'s helmet mount.") - helmet.loc = get_turf(src) - if(istype(helmet,/obj/item/clothing/head/helmet/space/hardsuit/syndi)) - var/obj/item/clothing/head/helmet/space/hardsuit/syndi/S = helmet - S.linkedsuit = null - src.helmet = null - return - if(!boots) - to_chat(user, "\The [src] does not have any boots installed.") - else - to_chat(user, "You detach \the [boots] from \the [src]'s boot mounts.") - boots.loc = get_turf(src) - boots = null - return - - else if(istype(W,/obj/item/clothing/head/helmet/space) && can_modify(user)) - if(!attached_helmet) - to_chat(user, "\The [src] does not have a helmet mount.") - return - if(helmet) - to_chat(user, "\The [src] already has a helmet installed.") - else - to_chat(user, "You attach \the [W] to \the [src]'s helmet mount.") - user.drop_item() - W.loc = src - helmet = W - if(istype(helmet,/obj/item/clothing/head/helmet/space/hardsuit/syndi)) - var/obj/item/clothing/head/helmet/space/hardsuit/syndi/S = W - S.forceMove(src) - helmet = S - S.link_suit() - return - - else if(istype(W,/obj/item/clothing/shoes/magboots) && can_modify(user)) - if(!attached_boots) - to_chat(user, "\The [src] does not have boot mounts.") - return - - if(boots) - to_chat(user, "\The [src] already has magboots installed.") - else - to_chat(user, "You attach \the [W] to \the [src]'s boot mounts.") - user.drop_item() - W.loc = src - boots = W - else - return ..() + if(jetpack) + if(slot == slot_wear_suit) + for(var/X in jetpack.actions) + var/datum/action/A = X + A.Grant(user) +/obj/item/clothing/suit/space/hardsuit/dropped(mob/user) ..() + if(jetpack) + for(var/X in jetpack.actions) + var/datum/action/A = X + A.Remove(user) -/obj/item/clothing/suit/space/hardsuit/proc/can_modify(mob/living/user) - if(isliving(loc)) - to_chat(user, "You can not modify the hardsuit while it is being worn.") - return 0 - - return 1 +/obj/item/clothing/suit/space/hardsuit/item_action_slot_check(slot) + if(slot == slot_wear_suit) //we only give the mob the ability to toggle the helmet if he's wearing the hardsuit. + return 1 //Engineering hardsuit -/obj/item/clothing/head/helmet/space/hardsuit/engineering +/obj/item/clothing/head/helmet/space/hardsuit/engine name = "engineering hardsuit helmet" desc = "A special helmet designed for work in a hazardous, low-pressure environment. Has radiation shielding." icon_state = "hardsuit0-engineering" item_state = "eng_helm" - armor = list(melee = 10, bullet = 5, laser = 10, energy = 5, bomb = 10, bio = 100, rad = 75) + armor = list(melee = 30, bullet = 5, laser = 10, energy = 5, bomb = 10, bio = 100, rad = 75) + item_color = "engineering" -/obj/item/clothing/suit/space/hardsuit/engineering +/obj/item/clothing/suit/space/hardsuit/engine name = "engineering hardsuit" desc = "A special suit that protects against hazardous, low pressure environments. Has radiation shielding." icon_state = "hardsuit-engineering" item_state = "eng_hardsuit" - armor = list(melee = 10, bullet = 5, laser = 10, energy = 5, bomb = 10, bio = 100, rad = 75) - allowed = list(/obj/item/flashlight,/obj/item/tank,/obj/item/t_scanner, /obj/item/rcd) + armor = list(melee = 30, bullet = 5, laser = 10, energy = 5, bomb = 10, bio = 100, rad = 75) + helmettype = /obj/item/clothing/head/helmet/space/hardsuit/engine + +//Atmospherics +/obj/item/clothing/head/helmet/space/hardsuit/engine/atmos + name = "atmospherics hardsuit helmet" + desc = "A special helmet designed for work in a hazardous, low-pressure environment. Has thermal shielding." + icon_state = "hardsuit0-atmos" + item_state = "atmos_helm" + item_color = "atmos" + armor = list(melee = 30, bullet = 5, laser = 10, energy = 5, bomb = 10, bio = 100, rad = 25) + heat_protection = HEAD //Uncomment to enable firesuit protection + max_heat_protection_temperature = FIRE_IMMUNITY_MAX_TEMP_PROTECT + +/obj/item/clothing/suit/space/hardsuit/engine/atmos + name = "atmospherics hardsuit" + desc = "A special suit that protects against hazardous, low pressure environments. Has thermal shielding." + icon_state = "hardsuit-atmos" + item_state = "atmo_hardsuit" + armor = list(melee = 30, bullet = 5, laser = 10, energy = 5, bomb = 10, bio = 100, rad = 25) + heat_protection = UPPER_TORSO|LOWER_TORSO|LEGS|FEET|ARMS|HANDS //Uncomment to enable firesuit protection + max_heat_protection_temperature = FIRE_IMMUNITY_MAX_TEMP_PROTECT + helmettype = /obj/item/clothing/head/helmet/space/hardsuit/engine/atmos //Chief Engineer's hardsuit -/obj/item/clothing/head/helmet/space/hardsuit/elite +/obj/item/clothing/head/helmet/space/hardsuit/engine/elite name = "advanced hardsuit helmet" desc = "An advanced helmet designed for work in a hazardous, low pressure environment. Shines with a high polish." icon_state = "hardsuit0-white" item_state = "ce_helm" item_color = "white" - armor = list(melee = 40, bullet = 5, laser = 10, energy = 5, bomb = 50, bio = 100, rad = 90) + armor = list(melee = 40, bullet = 5, laser = 10, energy = 5, bomb = 50, bio = 100, rad = 100) heat_protection = HEAD //Uncomment to enable firesuit protection max_heat_protection_temperature = FIRE_IMMUNITY_MAX_TEMP_PROTECT -/obj/item/clothing/suit/space/hardsuit/elite +/obj/item/clothing/suit/space/hardsuit/engine/elite icon_state = "hardsuit-white" name = "advanced hardsuit" desc = "An advanced suit that protects against hazardous, low pressure environments. Shines with a high polish." @@ -301,6 +227,8 @@ armor = list(melee = 40, bullet = 5, laser = 10, energy = 5, bomb = 50, bio = 100, rad = 90) heat_protection = UPPER_TORSO|LOWER_TORSO|LEGS|FEET|ARMS|HANDS //Uncomment to enable firesuit protection max_heat_protection_temperature = FIRE_IMMUNITY_MAX_TEMP_PROTECT + helmettype = /obj/item/clothing/head/helmet/space/hardsuit/engine/elite + jetpack = /obj/item/tank/jetpack/suit //Mining hardsuit /obj/item/clothing/head/helmet/space/hardsuit/mining @@ -309,16 +237,21 @@ icon_state = "hardsuit0-mining" item_state = "mining_helm" item_color = "mining" + max_heat_protection_temperature = FIRE_SUIT_MAX_TEMP_PROTECT + heat_protection = HEAD armor = list(melee = 30, bullet = 5, laser = 10, energy = 5, bomb = 50, bio = 100, rad = 50) + brightness_on = 7 /obj/item/clothing/suit/space/hardsuit/mining icon_state = "hardsuit-mining" name = "mining hardsuit" desc = "A special suit that protects against hazardous, low pressure environments. Has reinforced plating." item_state = "mining_hardsuit" + max_heat_protection_temperature = FIRE_SUIT_MAX_TEMP_PROTECT armor = list(melee = 30, bullet = 5, laser = 10, energy = 5, bomb = 50, bio = 100, rad = 50) - allowed = list(/obj/item/flashlight,/obj/item/tank,/obj/item/storage/bag/ore,/obj/item/pickaxe) - + allowed = list(/obj/item/flashlight, /obj/item/tank, /obj/item/storage/bag/ore, /obj/item/pickaxe, /obj/item/resonator, /obj/item/mining_scanner, /obj/item/t_scanner/adv_mining_scanner, /obj/item/gun/energy/kinetic_accelerator) + helmettype = /obj/item/clothing/head/helmet/space/hardsuit/mining + heat_protection = UPPER_TORSO|LOWER_TORSO|LEGS|FEET|ARMS|HANDS //Syndicate hardsuit /obj/item/clothing/head/helmet/space/hardsuit/syndi @@ -332,48 +265,47 @@ on = 1 var/obj/item/clothing/suit/space/hardsuit/syndi/linkedsuit = null actions_types = list(/datum/action/item_action/toggle_helmet_mode) - flags = BLOCKHAIR | STOPSPRESSUREDMAGE | THICKMATERIAL visor_flags_inv = HIDEMASK|HIDEEYES|HIDEFACE|HIDETAIL + visor_flags = STOPSPRESSUREDMAGE /obj/item/clothing/head/helmet/space/hardsuit/syndi/update_icon() icon_state = "hardsuit[on]-[item_color]" -/obj/item/clothing/head/helmet/space/hardsuit/syndi/proc/link_suit() - . = ..() - if(istype(loc,/obj/item/clothing/suit/space/hardsuit/syndi)) +/obj/item/clothing/head/helmet/space/hardsuit/syndi/New() + ..() + if(istype(loc, /obj/item/clothing/suit/space/hardsuit/syndi)) linkedsuit = loc -/obj/item/clothing/head/helmet/space/hardsuit/syndi/attack_self(mob/user) - - if(!linkedsuit) - to_chat(user, "You must attach the helmet to a syndicate hardsuit to toggle combat mode!") +/obj/item/clothing/head/helmet/space/hardsuit/syndi/attack_self(mob/user) //Toggle Helmet + if(!isturf(user.loc)) + to_chat(user, "You cannot toggle your helmet while in this [user.loc]!" ) return - on = !on if(on) - to_chat(user, "You switch your helmet to travel mode. It will allow you to stand in zero pressure environments, at the cost of speed.") + to_chat(user, "You switch your hardsuit to EVA mode, sacrificing speed for space protection.") name = initial(name) desc = initial(desc) set_light(brightness_on) - flags = BLOCKHAIR | STOPSPRESSUREDMAGE | THICKMATERIAL | NODROP + flags |= visor_flags flags_cover |= HEADCOVERSEYES | HEADCOVERSMOUTH flags_inv |= visor_flags_inv cold_protection |= HEAD else - to_chat(user, "You switch your helmet to combat mode. You will take damage in zero pressure environments, but you are more suited for a fight.") - name = "blood-red hardsuit helmet (combat)" + to_chat(user, "You switch your hardsuit to combat mode and can now run at full speed.") + name += " (combat)" desc = alt_desc set_light(0) - flags = BLOCKHAIR | THICKMATERIAL | NODROP + flags &= ~visor_flags flags_cover &= ~(HEADCOVERSEYES | HEADCOVERSMOUTH) flags_inv &= ~visor_flags_inv cold_protection &= ~HEAD - update_icon() playsound(src.loc, 'sound/mecha/mechmove03.ogg', 50, 1) toggle_hardsuit_mode(user) user.update_inv_head() - + if(iscarbon(user)) + var/mob/living/carbon/C = user + C.head_update(src, forced = 1) for(var/X in actions) var/datum/action/A = X A.UpdateButtonIcon() @@ -384,34 +316,19 @@ linkedsuit.name = initial(linkedsuit.name) linkedsuit.desc = initial(linkedsuit.desc) linkedsuit.slowdown = 1 - linkedsuit.flags |= STOPSPRESSUREDMAGE | THICKMATERIAL - linkedsuit.flags_inv = HIDEGLOVES|HIDESHOES|HIDEJUMPSUIT|HIDETAIL + linkedsuit.flags |= STOPSPRESSUREDMAGE linkedsuit.cold_protection |= UPPER_TORSO | LOWER_TORSO | LEGS | FEET | ARMS | HANDS else linkedsuit.name += " (combat)" linkedsuit.desc = linkedsuit.alt_desc linkedsuit.slowdown = 0 - linkedsuit.flags = THICKMATERIAL + linkedsuit.flags &= ~STOPSPRESSUREDMAGE linkedsuit.cold_protection &= ~(UPPER_TORSO | LOWER_TORSO | LEGS | FEET | ARMS | HANDS) - linkedsuit.flags_inv &= ~(HIDEGLOVES|HIDESHOES|HIDEJUMPSUIT|HIDETAIL) linkedsuit.update_icon() user.update_inv_wear_suit() user.update_inv_w_uniform() - for(var/X in actions) - var/datum/action/A = X - A.UpdateButtonIcon() - -/obj/item/clothing/head/helmet/space/hardsuit/syndi/freedom - name = "eagle helmet" - desc = "An advanced, space-proof helmet. It appears to be modeled after an old-world eagle." - icon_state = "griffinhat" - item_state = "griffinhat" - -/obj/item/clothing/head/helmet/space/hardsuit/syndi/freedom/update_icon() - return - /obj/item/clothing/suit/space/hardsuit/syndi name = "blood-red hardsuit" desc = "A dual-mode advanced hardsuit designed for work in special operations. It is in travel mode. Property of Gorlex Marauders." @@ -423,7 +340,9 @@ var/on = 1 actions_types = list(/datum/action/item_action/toggle_hardsuit_mode) armor = list(melee = 40, bullet = 50, laser = 30, energy = 15, bomb = 35, bio = 100, rad = 50) - allowed = list(/obj/item/gun,/obj/item/ammo_box,/obj/item/ammo_casing,/obj/item/melee/baton,/obj/item/melee/energy/sword/saber,/obj/item/restraints/handcuffs,/obj/item/tank) + allowed = list(/obj/item/gun, /obj/item/ammo_box,/obj/item/ammo_casing, /obj/item/melee/baton, /obj/item/melee/energy/sword, /obj/item/restraints/handcuffs, /obj/item/tank) + helmettype = /obj/item/clothing/head/helmet/space/hardsuit/syndi + jetpack = /obj/item/tank/jetpack/suit /obj/item/clothing/suit/space/hardsuit/syndi/update_icon() icon_state = "hardsuit[on]-[item_color]" @@ -437,36 +356,21 @@ armor = list(melee = 60, bullet = 60, laser = 50, energy = 25, bomb = 55, bio = 100, rad = 70) heat_protection = HEAD max_heat_protection_temperature = FIRE_IMMUNITY_MAX_TEMP_PROTECT + unacidable = TRUE sprite_sheets = null -/obj/item/clothing/head/helmet/space/hardsuit/syndi/elite/attack_self(mob/user) - ..() - if(on) - name = "elite syndicate hardsuit helmet" - desc = "An elite version of the syndicate helmet, with improved armour and fire shielding. It is in travel mode. Property of Gorlex Marauders." - else - name = "elite syndicate hardsuit helmet (combat)" - desc = "An elite version of the syndicate helmet, with improved armour and fire shielding. It is in combat mode. Property of Gorlex Marauders." - /obj/item/clothing/suit/space/hardsuit/syndi/elite name = "elite syndicate hardsuit" desc = "An elite version of the syndicate hardsuit, with improved armour and fire shielding. It is in travel mode." icon_state = "hardsuit0-syndielite" item_color = "syndielite" + helmettype = /obj/item/clothing/head/helmet/space/hardsuit/syndi/elite armor = list(melee = 60, bullet = 60, laser = 50, energy = 25, bomb = 55, bio = 100, rad = 70) heat_protection = UPPER_TORSO|LOWER_TORSO|LEGS|FEET|ARMS|HANDS max_heat_protection_temperature = FIRE_IMMUNITY_MAX_TEMP_PROTECT + unacidable = TRUE sprite_sheets = null -/obj/item/clothing/suit/space/hardsuit/syndi/elite/attack_self(mob/user) - ..() - if(on) - name = "elite syndicate hardsuit" - desc = "An elite version of the syndicate hardsuit, with improved armour and fire shielding. It is in travel mode. Property of Gorlex Marauders." - else - name = "elite syndicate hardsuit (combat)" - desc = "An elite version of the syndicate hardsuit, with improved armour and fire shielding. It is in combat mode. Property of Gorlex Marauders." - //Strike team hardsuits /obj/item/clothing/head/helmet/space/hardsuit/syndi/elite/sst armor = list(melee = 70, bullet = 70, laser = 50, energy = 40, bomb = 80, bio = 100, rad = 100) //Almost as good as DS gear, but unlike DS can switch to combat for mobility @@ -477,16 +381,29 @@ armor = list(melee = 70, bullet = 70, laser = 50, energy = 40, bomb = 80, bio = 100, rad = 100) icon_state = "hardsuit0-sst" item_color = "sst" + helmettype = /obj/item/clothing/head/helmet/space/hardsuit/syndi/elite/sst /obj/item/clothing/suit/space/hardsuit/syndi/freedom name = "eagle suit" desc = "An advanced, light suit, fabricated from a mixture of synthetic feathers and space-resistant material. A gun holster appears to be integrated into the suit." icon_state = "freedom" item_state = "freedom" + helmettype = /obj/item/clothing/head/helmet/space/hardsuit/syndi/freedom + sprite_sheets = null /obj/item/clothing/suit/space/hardsuit/syndi/freedom/update_icon() return +/obj/item/clothing/head/helmet/space/hardsuit/syndi/freedom + name = "eagle helmet" + desc = "An advanced, space-proof helmet. It appears to be modeled after an old-world eagle." + icon_state = "griffinhat" + item_state = "griffinhat" + sprite_sheets = null + +/obj/item/clothing/head/helmet/space/hardsuit/syndi/freedom/update_icon() + return + //Wizard hardsuit /obj/item/clothing/head/helmet/space/hardsuit/wizard name = "gem-encrusted hardsuit helmet" @@ -515,6 +432,7 @@ allowed = list(/obj/item/teleportation_scroll,/obj/item/tank) heat_protection = UPPER_TORSO|LOWER_TORSO|LEGS|FEET|ARMS|HANDS //Uncomment to enable firesuit protection max_heat_protection_temperature = FIRE_IMMUNITY_MAX_TEMP_PROTECT + helmettype = /obj/item/clothing/head/helmet/space/hardsuit/wizard sprite_sheets = null magical = TRUE @@ -525,9 +443,9 @@ icon_state = "hardsuit0-medical" item_state = "medical_helm" item_color = "medical" - flags_inv = HIDEMASK|HIDEEARS|HIDEEYES - armor = list(melee = 10, bullet = 5, laser = 10, energy = 5, bomb = 10, bio = 100, rad = 50) flash_protect = 0 + armor = list(melee = 30, bullet = 5, laser = 10, energy = 5, bomb = 10, bio = 100, rad = 50) + flags = STOPSPRESSUREDMAGE | THICKMATERIAL scan_reagents = 1 //Generally worn by the CMO, so they'd get utility off of seeing reagents /obj/item/clothing/suit/space/hardsuit/medical @@ -536,7 +454,9 @@ desc = "A special helmet designed for work in a hazardous, low pressure environment. Built with lightweight materials for extra comfort." item_state = "medical_hardsuit" allowed = list(/obj/item/flashlight,/obj/item/tank,/obj/item/storage/firstaid,/obj/item/healthanalyzer,/obj/item/stack/medical,/obj/item/rad_laser) - armor = list(melee = 10, bullet = 5, laser = 10, energy = 5, bomb = 10, bio = 100, rad = 50) + armor = list(melee = 30, bullet = 5, laser = 10, energy = 5, bomb = 10, bio = 100, rad = 50) + helmettype = /obj/item/clothing/head/helmet/space/hardsuit/medical + slowdown = 0.5 //Security /obj/item/clothing/head/helmet/space/hardsuit/security @@ -545,36 +465,33 @@ icon_state = "hardsuit0-sec" item_state = "sec_helm" item_color = "sec" - armor = list(melee = 30, bullet = 15, laser = 30, energy = 10, bomb = 10, bio = 100, rad = 50) + armor = list(melee = 35, bullet = 15, laser = 30, energy = 10, bomb = 10, bio = 100, rad = 50) /obj/item/clothing/suit/space/hardsuit/security icon_state = "hardsuit-sec" name = "security hardsuit" desc = "A special suit that protects against hazardous, low pressure environments. Has an additional layer of armor." item_state = "sec_hardsuit" - armor = list(melee = 30, bullet = 15, laser = 30, energy = 10, bomb = 10, bio = 100, rad = 50) + armor = list(melee = 35, bullet = 15, laser = 30, energy = 10, bomb = 10, bio = 100, rad = 50) allowed = list(/obj/item/gun,/obj/item/flashlight,/obj/item/tank,/obj/item/melee/baton,/obj/item/reagent_containers/spray/pepper,/obj/item/ammo_box,/obj/item/ammo_casing,/obj/item/restraints/handcuffs) + helmettype = /obj/item/clothing/head/helmet/space/hardsuit/security +/obj/item/clothing/head/helmet/space/hardsuit/security/hos + name = "head of security's hardsuit helmet" + desc = "a special bulky helmet designed for work in a hazardous, low pressure environment. Has an additional layer of armor." + icon_state = "hardsuit0-hos" + item_color = "hos" + armor = list(melee = 45, bullet = 25, laser = 30,energy = 10, bomb = 25, bio = 100, rad = 50) + sprite_sheets = null -//Atmospherics hardsuit (BS12) -/obj/item/clothing/head/helmet/space/hardsuit/atmos - desc = "A special helmet designed for work in a hazardous, low pressure environments. Has improved thermal protection and minor radiation shielding." - name = "atmospherics hardsuit helmet" - icon_state = "hardsuit0-atmos" - item_state = "atmos_helm" - item_color = "atmos" - armor = list(melee = 10, bullet = 5, laser = 10, energy = 5, bomb = 10, bio = 100, rad = 0) - heat_protection = HEAD //Uncomment to enable firesuit protection - max_heat_protection_temperature = FIRE_IMMUNITY_MAX_TEMP_PROTECT - -/obj/item/clothing/suit/space/hardsuit/atmos - desc = "A special suit that protects against hazardous, low pressure environments. Has improved thermal protection and minor radiation shielding." - icon_state = "hardsuit-atmos" - name = "atmos hardsuit" - item_state = "atmos_hardsuit" - armor = list(melee = 10, bullet = 5, laser = 10, energy = 5, bomb = 10, bio = 100, rad = 0) - heat_protection = UPPER_TORSO|LOWER_TORSO|LEGS|FEET|ARMS|HANDS //Uncomment to enable firesuit protection - max_heat_protection_temperature = FIRE_IMMUNITY_MAX_TEMP_PROTECT +/obj/item/clothing/suit/space/hardsuit/security/hos + name = "head of security's hardsuit" + desc = "A special bulky suit that protects against hazardous, low pressure environments. Has an additional layer of armor." + icon_state = "hardsuit-hos" + armor = list(melee = 45, bullet = 25, laser = 30, energy = 10, bomb = 25, bio = 100, rad = 50) + helmettype = /obj/item/clothing/head/helmet/space/hardsuit/security/hos + jetpack = /obj/item/tank/jetpack/suit + sprite_sheets = null //Singuloth armor /obj/item/clothing/head/helmet/space/hardsuit/singuloth @@ -584,6 +501,7 @@ item_state = "singuloth_helm" item_color = "singuloth" armor = list(melee = 40, bullet = 5, laser = 20, energy = 5, bomb = 25, bio = 100, rad = 100) + sprite_sheets = null /obj/item/clothing/suit/space/hardsuit/singuloth icon_state = "hardsuit-singuloth" @@ -591,22 +509,8 @@ desc = "This is a ceremonial armor from the chapter of the Singuloth Knights. It's made of pure forged adamantium." item_state = "singuloth_hardsuit" flags = STOPSPRESSUREDMAGE - armor = list(melee = 40, bullet = 5, laser = 20, energy = 5, bomb = 25, bio = 100, rad = 100) - - -/obj/item/clothing/head/helmet/space/hardsuit/security/hos - name = "head of security's hardsuit helmet" - desc = "a special bulky helmet designed for work in a hazardous, low pressure environment. Has an additional layer of armor." - icon_state = "hardsuit0-hos" - item_color = "hos" - armor = list(melee = 45, bullet = 25, laser = 30,energy = 10, bomb = 25, bio = 100, rad = 50) - - -/obj/item/clothing/suit/space/hardsuit/security/hos - icon_state = "hardsuit-hos" - name = "head of security's hardsuit" - desc = "A special bulky suit that protects against hazardous, low pressure environments. Has an additional layer of armor." - armor = list(melee = 45, bullet = 25, laser = 30, energy = 10, bomb = 25, bio = 100, rad = 50) + armor = list(melee = 45, bullet = 25, laser = 30, energy = 10, bomb = 25, bio = 100, rad = 100) + helmettype = /obj/item/clothing/head/helmet/space/hardsuit/singuloth sprite_sheets = null @@ -616,6 +520,7 @@ name = "shielded hardsuit" desc = "A hardsuit with built in energy shielding. Will rapidly recharge when not under fire." icon_state = "hardsuit-hos" + helmettype = /obj/item/clothing/head/helmet/space/hardsuit/security/hos allowed = list(/obj/item/flashlight,/obj/item/tank, /obj/item/gun,/obj/item/reagent_containers/spray/pepper,/obj/item/ammo_box,/obj/item/ammo_casing,/obj/item/melee/baton,/obj/item/restraints/handcuffs) armor = list(melee = 30, bullet = 15, laser = 30, energy = 10, bomb = 10, bio = 100, rad = 50) var/current_charges = 3 @@ -669,6 +574,8 @@ armor = list(melee = 40, bullet = 50, laser = 30, energy = 15, bomb = 35, bio = 100, rad = 50) allowed = list(/obj/item/gun,/obj/item/ammo_box,/obj/item/ammo_casing,/obj/item/melee/baton,/obj/item/melee/energy/sword/saber,/obj/item/restraints/handcuffs,/obj/item/tank) slowdown = 0 + helmettype = /obj/item/clothing/head/helmet/space/hardsuit/shielded/syndi + jetpack = /obj/item/tank/jetpack/suit sprite_sheets = list( "Unathi" = 'icons/mob/species/unathi/suit.dmi', "Tajaran" = 'icons/mob/species/tajaran/suit.dmi', diff --git a/code/modules/clothing/spacesuits/miscellaneous.dm b/code/modules/clothing/spacesuits/miscellaneous.dm index 9706b254fa8..1e5c9ad6dcb 100644 --- a/code/modules/clothing/spacesuits/miscellaneous.dm +++ b/code/modules/clothing/spacesuits/miscellaneous.dm @@ -7,7 +7,7 @@ flags_inv = HIDEFACE permeability_coefficient = 0.01 armor = list(melee = 40, bullet = 50, laser = 50, energy = 25, bomb = 50, bio = 100, rad = 50) - species_restricted = list("exclude", "Diona", "Wryn") + species_restricted = list("exclude", "Wryn") sprite_sheets = list( "Vox" = 'icons/mob/species/vox/helmet.dmi', @@ -31,7 +31,7 @@ w_class = WEIGHT_CLASS_BULKY allowed = list(/obj/item/tank, /obj/item/flashlight,/obj/item/gun/energy, /obj/item/gun/projectile, /obj/item/ammo_box, /obj/item/ammo_casing, /obj/item/melee/baton,/obj/item/restraints/handcuffs) armor = list(melee = 40, bullet = 50, laser = 50, energy = 25, bomb = 50, bio = 100, rad = 50) - species_restricted = list("exclude", "Diona", "Wryn") + species_restricted = list("exclude", "Wryn") sprite_sheets = list( "Vox" = 'icons/mob/species/vox/suit.dmi' @@ -72,7 +72,7 @@ allowed = list(/obj/item/gun,/obj/item/ammo_box,/obj/item/ammo_casing,/obj/item/melee/baton,/obj/item/restraints/handcuffs,/obj/item/tank,/obj/item/kitchen/knife/combat) armor = list(melee = 40, bullet = 30, laser = 30, energy = 30, bomb = 50, bio = 90, rad = 20) strip_delay = 120 - species_restricted = list("exclude", "Diona", "Wryn") + species_restricted = list("exclude", "Wryn") sprite_sheets = list( "Vox" = 'icons/mob/species/vox/suit.dmi' @@ -159,7 +159,7 @@ icon_state = "paramedic-eva-helmet" item_state = "paramedic-eva-helmet" armor = list(melee = 0, bullet = 0, laser = 0, energy = 0, bomb = 0, bio = 100, rad = 20) - species_restricted = list("exclude", "Diona", "Wryn") + species_restricted = list("exclude", "Wryn") sprite_sheets = list( "Vox" = 'icons/mob/species/vox/helmet.dmi', @@ -180,7 +180,7 @@ item_state = "paramedic-eva" desc = "A brand new paramedic EVA suit. The nitrile seems a bit too thin to be space proof. Used for retrieving bodies in space." armor = list(melee = 0, bullet = 0, laser = 0, energy = 0, bomb = 0, bio = 100, rad = 20) - species_restricted = list("exclude", "Diona", "Wryn") + species_restricted = list("exclude", "Wryn") sprite_sheets = list( "Vox" = 'icons/mob/species/vox/suit.dmi', @@ -200,7 +200,7 @@ item_state = "s_suit" desc = "A lightweight space suit with the basic ability to protect the wearer from the vacuum of space during emergencies." armor = list(melee = 0, bullet = 0, laser = 0, energy = 0, bomb = 0, bio = 100, rad = 20) - species_restricted = list("exclude", "Diona", "Wryn") + species_restricted = list("exclude", "Wryn") sprite_sheets = list( "Tajaran" = 'icons/mob/species/tajaran/suit.dmi', @@ -223,7 +223,7 @@ flags_inv = HIDEMASK|HIDEEARS|HIDEEYES armor = list(melee = 0, bullet = 0, laser = 0, energy = 0, bomb = 0, bio = 100, rad = 20) flash_protect = 0 - species_restricted = list("exclude", "Diona", "Wryn") + species_restricted = list("exclude", "Wryn") sprite_sheets = list( "Tajaran" = 'icons/mob/species/tajaran/helmet.dmi', @@ -244,7 +244,7 @@ desc = ". . ." icon_state = "spacemimehelmet" item_state = "spacemimehelmet" - species_restricted = list("exclude","Diona","Vox","Wryn") + species_restricted = list("exclude","Vox","Wryn") sprite_sheets = null sprite_sheets_obj = null @@ -254,7 +254,7 @@ desc = ". . ." icon_state = "spacemime_suit" item_state = "spacemime_items" - species_restricted = list("exclude","Diona","Vox","Wryn") + species_restricted = list("exclude","Vox","Wryn") sprite_sheets = null sprite_sheets_obj = null @@ -264,7 +264,7 @@ desc = "An EVA helmet specifically designed for the clown. SPESSHONK!" icon_state = "clownhelmet" item_state = "clownhelmet" - species_restricted = list("exclude","Diona","Vox","Wryn") + species_restricted = list("exclude","Vox","Wryn") sprite_sheets = null sprite_sheets_obj = null @@ -274,7 +274,6 @@ desc = "An EVA suit specifically designed for the clown. SPESSHONK!" icon_state = "spaceclown_suit" item_state = "spaceclown_items" - species_restricted = list("exclude","Diona","Vox","Wryn") + species_restricted = list("exclude","Vox","Wryn") sprite_sheets = null sprite_sheets_obj = null - \ No newline at end of file diff --git a/code/modules/clothing/spacesuits/plasmamen.dm b/code/modules/clothing/spacesuits/plasmamen.dm index e355aead650..fef732ed01b 100644 --- a/code/modules/clothing/spacesuits/plasmamen.dm +++ b/code/modules/clothing/spacesuits/plasmamen.dm @@ -1,427 +1,250 @@ -// PLASMEN SHIT -// CAN'T WEAR UNLESS YOU'RE A PINK SKELETON -/obj/item/clothing/suit/space/eva/plasmaman - name = "plasmaman suit" - desc = "A special containment suit designed to protect a plasmaman's volatile body from outside exposure and quickly extinguish it in emergencies." - allowed = list(/obj/item/gun,/obj/item/ammo_casing,/obj/item/ammo_casing,/obj/item/melee/baton,/obj/item/melee/energy/sword/saber,/obj/item/restraints/handcuffs,/obj/item/tank) - slowdown = 0 - armor = list(melee = 0, bullet = 0, laser = 0, energy = 0, bomb = 0, bio = 100, rad = 20) - heat_protection = UPPER_TORSO|LOWER_TORSO|LEGS|FEET|ARMS|HANDS - body_parts_covered = UPPER_TORSO|LOWER_TORSO|LEGS|FEET|ARMS|HANDS - flags_inv = HIDEGLOVES|HIDESHOES - max_heat_protection_temperature = SPACE_SUIT_MAX_TEMP_PROTECT - icon = 'icons/obj/clothing/species/plasmaman/suits.dmi' - species_restricted = list("Plasmaman") - sprite_sheets = list( - "Plasmaman" = 'icons/mob/species/plasmaman/suit.dmi' - ) - flags = STOPSPRESSUREDMAGE - icon_state = "plasmaman_suit" - item_state = "plasmaman_suit" - - var/next_extinguish = 0 - var/extinguish_cooldown = 10 SECONDS - var/max_extinguishes = 5 - var/extinguishes_left = 5 // Yeah yeah, reagents, blah blah blah. This should be simple. - -/obj/item/clothing/suit/space/eva/plasmaman/proc/Extinguish(var/mob/user) - var/mob/living/carbon/human/H=user - if(extinguishes_left) - if(next_extinguish > world.time) - return - - next_extinguish = world.time + extinguish_cooldown - extinguishes_left-- - to_chat(user, "You hear a soft click and a hiss from your suit as it automatically extinguishes the fire.") - if(!extinguishes_left) - to_chat(user, "Onboard auto-extinguisher depleted, refill with a cartridge.") - playsound(src.loc, 'sound/effects/spray.ogg', 10, 1, -3) - H.ExtinguishMob() - -/obj/item/clothing/suit/space/eva/plasmaman/attackby(var/obj/item/A as obj, mob/user as mob, params) - ..() - if(istype(A, /obj/item/plasmensuit_cartridge)) //This suit can only be reloaded by the appropriate cartridges, and only if it's got no more extinguishes left. - if(!extinguishes_left) - extinguishes_left = max_extinguishes //Full replenishment from the cartridge. - to_chat(user, "You replenish \the [src] with the cartridge.") - qdel(A) - else - to_chat(user, "The suit must be depleted before it can be refilled.") - -/obj/item/clothing/suit/space/eva/plasmaman/examine(mob/user) - ..(user) - to_chat(user, "There are [extinguishes_left] extinguisher canisters left in this suit.") - -/obj/item/plasmensuit_cartridge //Can be used to refill Plasmaman suits when they run out of autoextinguishes. - name = "auto-extinguisher cartridge" - desc = "A tiny and light fibreglass-framed auto-extinguisher cartridge." - icon = 'icons/obj/items.dmi' - icon_state = "miniFE0" - item_state = "miniFE" - hitsound = null //Ultralight and - flags = null //non-conductive - force = 0 - throwforce = 0 - w_class = WEIGHT_CLASS_SMALL //Fits in boxes. - materials = list() - attack_verb = list("tapped") - -/obj/item/clothing/head/helmet/space/eva/plasmaman - name = "plasmaman helmet" - desc = "A special containment helmet designed to protect a plasmaman's volatile body from outside exposure and quickly extinguish it in emergencies." - flags = STOPSPRESSUREDMAGE +//I just want the light feature of the hardsuit helmet +/obj/item/clothing/head/helmet/space/plasmaman + name = "plasma envirosuit helmet" + desc = "A special containment helmet that allows plasma-based lifeforms to exist safely in an oxygenated environment. It is space-worthy, and may be worn in tandem with other EVA gear." + icon_state = "plasmaman-helm" + item_state = "plasmaman-helm" + strip_delay = 80 + flash_protect = 2 + tint = 2 + armor = list(melee = 0, bullet = 0, laser = 0, energy = 0, bomb = 0, bio = 100, rad = 0) + resistance_flags = FIRE_PROOF + var/brightness_on = 4 //luminosity when the light is on + var/on = FALSE + var/smile = FALSE + var/smile_color = "#FF0000" + var/visor_icon = "envisor" + var/smile_state = "envirohelm_smile" + actions_types = list(/datum/action/item_action/toggle_helmet_light, /datum/action/item_action/toggle_welding_screen/plasmaman) + visor_vars_to_toggle = VISOR_FLASHPROTECT | VISOR_TINT + flags_inv = HIDEMASK|HIDEEARS|HIDEEYES|HIDEFACE + flags_cover = HEADCOVERSMOUTH|HEADCOVERSEYES + visor_flags_inv = HIDEEYES|HIDEFACE icon = 'icons/obj/clothing/species/plasmaman/hats.dmi' species_restricted = list("Plasmaman") - sprite_sheets = list( - "Plasmaman" = 'icons/mob/species/plasmaman/helmet.dmi' - ) - icon_state = "plasmaman_helmet0" - item_state = "plasmaman_helmet0" - var/base_state = "plasmaman_helmet" - var/brightness_on = 4 //luminosity when on - var/on = 0 + sprite_sheets = list("Plasmaman" = 'icons/mob/species/plasmaman/helmet.dmi') + +/obj/item/clothing/head/helmet/space/plasmaman/New() + ..() + visor_toggling() + update_icon() + cut_overlays() + +/obj/item/clothing/head/helmet/space/plasmaman/AltClick(mob/user) + if(!user.incapacitated() && Adjacent(user)) + toggle_welding_screen(user) + +/obj/item/clothing/head/helmet/space/plasmaman/visor_toggling() //handles all the actual toggling of flags + up = !up + flags ^= visor_flags + flags_inv ^= visor_flags_inv + icon_state = "[initial(icon_state)]" + if(visor_vars_to_toggle & VISOR_FLASHPROTECT) + flash_protect ^= initial(flash_protect) + if(visor_vars_to_toggle & VISOR_TINT) + tint ^= initial(tint) + +/obj/item/clothing/head/helmet/space/plasmaman/proc/toggle_welding_screen(mob/living/user) + if(weldingvisortoggle(user)) + if(on) + to_chat(user, "Your helmet's torch can't pass through your welding visor!") + on = FALSE + playsound(src, 'sound/mecha/mechmove03.ogg', 50, 1) //Visors don't just come from nothing + update_icon() + else + playsound(src, 'sound/mecha/mechmove03.ogg', 50, 1) //Visors don't just come from nothing + update_icon() + +/obj/item/clothing/head/helmet/space/plasmaman/update_icon() + cut_overlays() + add_overlay(visor_icon) + ..() actions_types = list(/datum/action/item_action/toggle_helmet_light) -/obj/item/clothing/head/helmet/space/eva/plasmaman/attack_self(mob/user) - toggle_light(user) - -/obj/item/clothing/head/helmet/space/eva/plasmaman/proc/toggle_light(mob/user) +/obj/item/clothing/head/helmet/space/plasmaman/attack_self(mob/user) on = !on - icon_state = "[base_state][on]" + icon_state = "[initial(icon_state)][on ? "-light":""]" + item_state = icon_state + user.update_inv_head() //So the mob overlay updates if(on) - set_light(brightness_on) + if(!up) + to_chat(user, "Your helmet's torch can't pass through your welding visor!") + set_light(0) + else + set_light(brightness_on) else set_light(0) - if(istype(user,/mob/living/carbon/human)) - var/mob/living/carbon/human/H = user - H.update_inv_head() - for(var/X in actions) - var/datum/action/A = X + var/datum/action/A=X A.UpdateButtonIcon() -/obj/item/clothing/head/helmet/space/eva/plasmaman/extinguish_light() - if(on) - toggle_light() - visible_message("[src]'s light fades and turns off.") - -// ENGINEERING -/obj/item/clothing/suit/space/eva/plasmaman/atmostech - name = "plasmaman atmospheric suit" - icon_state = "plasmamanAtmos_suit" - armor = list(melee = 10, bullet = 5, laser = 10, energy = 5, bomb = 10, bio = 100, rad = 0) - max_heat_protection_temperature = FIRE_IMMUNITY_MAX_TEMP_PROTECT - -/obj/item/clothing/head/helmet/space/eva/plasmaman/atmostech - name = "plasmaman atmospheric helmet" - icon_state = "plasmamanAtmos_helmet0" - base_state = "plasmamanAtmos_helmet" - armor = list(melee = 10, bullet = 5, laser = 10, energy = 5, bomb = 10, bio = 100, rad = 0) - max_heat_protection_temperature = FIRE_IMMUNITY_MAX_TEMP_PROTECT - flash_protect = 2 - -/obj/item/clothing/suit/space/eva/plasmaman/engineer - name = "plasmaman engineer suit" - icon_state = "plasmamanEngineer_suit" - armor = list(melee = 10, bullet = 5, laser = 10, energy = 5, bomb = 10, bio = 100, rad = 75) - -/obj/item/clothing/head/helmet/space/eva/plasmaman/engineer - name = "plasmaman engineer helmet" - icon_state = "plasmamanEngineer_helmet0" - base_state = "plasmamanEngineer_helmet" - armor = list(melee = 10, bullet = 5, laser = 10, energy = 5, bomb = 10, bio = 100, rad = 75) - flash_protect = 2 - -/obj/item/clothing/suit/space/eva/plasmaman/engineer/ce - name = "plasmaman chief engineer suit" - icon_state = "plasmaman_CE" - max_heat_protection_temperature = FIRE_IMMUNITY_MAX_TEMP_PROTECT - - -/obj/item/clothing/head/helmet/space/eva/plasmaman/engineer/ce - name = "plasmaman chief engineer helmet" - icon_state = "plasmaman_CE_helmet0" - base_state = "plasmaman_CE_helmet" - max_heat_protection_temperature = FIRE_IMMUNITY_MAX_TEMP_PROTECT - flash_protect = 2 - -//SERVICE -/obj/item/clothing/suit/space/eva/plasmaman/assistant - name = "plasmaman assistant suit" - icon_state = "plasmamanAssistant_suit" - -/obj/item/clothing/head/helmet/space/eva/plasmaman/assistant - name = "plasmaman assistant helmet" - icon_state = "plasmamanAssistant_helmet0" - base_state = "plasmamanAssistant_helmet" - -/obj/item/clothing/suit/space/eva/plasmaman/botanist - name = "plasmaman botanist suit" - icon_state = "plasmamanBotanist_suit" - -/obj/item/clothing/head/helmet/space/eva/plasmaman/botanist - name = "plasmaman botanist helmet" - icon_state = "plasmamanBotanist_helmet0" - base_state = "plasmamanBotanist_helmet" - -/obj/item/clothing/suit/space/eva/plasmaman/chaplain - name = "plasmaman chaplain suit" - icon_state = "plasmamanChaplain_suit" - -/obj/item/clothing/head/helmet/space/eva/plasmaman/chaplain - name = "plasmaman chaplain helmet" - icon_state = "plasmamanChaplain_helmet0" - base_state = "plasmamanChaplain_helmet" - -/obj/item/clothing/suit/space/eva/plasmaman/clown - name = "plasmaman clown suit" - icon_state = "plasmaman_Clown" - -/obj/item/clothing/head/helmet/space/eva/plasmaman/clown - name = "plasmaman clown helmet" - icon_state = "plasmaman_Clown_helmet0" - base_state = "plasmaman_Clown_helmet" - -/obj/item/clothing/suit/space/eva/plasmaman/mime - name = "plasmaman mime suit" - icon_state = "plasmaman_Mime" - -/obj/item/clothing/head/helmet/space/eva/plasmaman/mime - name = "plasmaman mime helmet" - icon_state = "plasmaman_Mime_helmet0" - base_state = "plasmaman_Mime_helmet" - -/obj/item/clothing/suit/space/eva/plasmaman/service - name = "plasmaman service suit" - icon_state = "plasmamanService_suit" - -/obj/item/clothing/head/helmet/space/eva/plasmaman/service - name = "plasmaman service helmet" - icon_state = "plasmamanService_helmet0" - base_state = "plasmamanService_helmet" - -/obj/item/clothing/suit/space/eva/plasmaman/janitor - name = "plasmaman janitor suit" - icon_state = "plasmamanJanitor_suit" - -/obj/item/clothing/head/helmet/space/eva/plasmaman/janitor - name = "plasmaman janitor helmet" - icon_state = "plasmamanJanitor_helmet0" - base_state = "plasmamanJanitor_helmet" - - -//CARGO - -/obj/item/clothing/suit/space/eva/plasmaman/cargo - name = "plasmaman cargo suit" - icon_state = "plasmamanCargo_suit" - -/obj/item/clothing/head/helmet/space/eva/plasmaman/cargo - name = "plasmaman cargo helmet" - icon_state = "plasmamanCargo_helmet0" - base_state = "plasmamanCargo_helmet" - -/obj/item/clothing/suit/space/eva/plasmaman/miner - name = "plasmaman miner suit" - icon_state = "plasmamanMiner_suit" - armor = list(melee = 30, bullet = 5, laser = 10, energy = 5, bomb = 50, bio = 100, rad = 50) - slowdown = 1 - -/obj/item/clothing/head/helmet/space/eva/plasmaman/miner - name = "plasmaman miner helmet" - icon_state = "plasmamanMiner_helmet0" - base_state = "plasmamanMiner_helmet" - armor = list(melee = 30, bullet = 5, laser = 10, energy = 5, bomb = 50, bio = 100, rad = 50) - -/obj/item/clothing/suit/space/eva/plasmaman/explorer - name = "plasmaman explorer suit" - icon_state = "plasmamanExplorer_suit" - armor = list(melee = 30, bullet = 20, laser = 20, energy = 20, bomb = 50, bio = 100, rad = 50, fire = 50, acid = 50) - -/obj/item/clothing/head/helmet/space/eva/plasmaman/explorer - name = "plasmaman explorer helmet" - icon_state = "plasmamanExplorer_helmet0" - base_state = "plasmamanExplorer_helmet" - armor = list(melee = 30, bullet = 20, laser = 20, energy = 20, bomb = 50, bio = 100, rad = 50, fire = 50, acid = 50) - -// MEDSCI - -/obj/item/clothing/suit/space/eva/plasmaman/medical - name = "plasmaman medical suit" - icon_state = "plasmamanMedical_suit" - -/obj/item/clothing/head/helmet/space/eva/plasmaman/medical - name = "plasmaman medical helmet" - icon_state = "plasmamanMedical_helmet0" - base_state = "plasmamanMedical_helmet" - -/obj/item/clothing/suit/space/eva/plasmaman/medical/paramedic - name = "plasmaman paramedic suit" - icon_state = "plasmaman_Paramedic" - -/obj/item/clothing/head/helmet/space/eva/plasmaman/medical/paramedic - name = "plasmaman paramedic helmet" - icon_state = "plasmaman_Paramedic_helmet0" - base_state = "plasmaman_Paramedic_helmet" - -/obj/item/clothing/suit/space/eva/plasmaman/medical/chemist - name = "plasmaman chemist suit" - icon_state = "plasmaman_Chemist" - -/obj/item/clothing/head/helmet/space/eva/plasmaman/medical/chemist - name = "plasmaman chemist helmet" - icon_state = "plasmaman_Chemist_helmet0" - base_state = "plasmaman_Chemist_helmet" - -/obj/item/clothing/suit/space/eva/plasmaman/medical/cmo - name = "plasmaman chief medical officer suit" - icon_state = "plasmaman_CMO" - -/obj/item/clothing/head/helmet/space/eva/plasmaman/medical/cmo - name = "plasmaman chief medical officer helmet" - icon_state = "plasmaman_CMO_helmet0" - base_state = "plasmaman_CMO_helmet" - -/obj/item/clothing/suit/space/eva/plasmaman/medical/coroner - name = "plasmaman coroner suit" - icon_state = "plasmaman_Coroner" - -/obj/item/clothing/head/helmet/space/eva/plasmaman/medical/coroner - name = "plasmaman coroner helmet" - icon_state = "plasmaman_Coroner_helmet0" - base_state = "plasmaman_Coroner_helmet" - -/obj/item/clothing/suit/space/eva/plasmaman/medical/virologist - name = "plasmaman virologist suit" - icon_state = "plasmaman_Virologist" - -/obj/item/clothing/head/helmet/space/eva/plasmaman/medical/virologist - name = "plasmaman virologist helmet" - icon_state = "plasmaman_Virologist_helmet0" - base_state = "plasmaman_Virologist_helmet" - -/obj/item/clothing/suit/space/eva/plasmaman/science - name = "plasmaman scientist suit" - icon_state = "plasmamanScience_suit" - -/obj/item/clothing/head/helmet/space/eva/plasmaman/science - name = "plasmaman scientist helmet" - icon_state = "plasmamanScience_helmet0" - base_state = "plasmamanScience_helmet" - -/obj/item/clothing/suit/space/eva/plasmaman/science/geneticist - name = "plasmaman geneticist suit" - icon_state = "plasmaman_Geneticist" - -/obj/item/clothing/head/helmet/space/eva/plasmaman/science/geneticist - name = "plasmaman geneticist helmet" - icon_state = "plasmaman_Geneticist_helmet0" - base_state = "plasmaman_Geneticist_helmet" - -/obj/item/clothing/suit/space/eva/plasmaman/science/rd - name = "plasmaman research director suit" - icon_state = "plasmaman_RD" - -/obj/item/clothing/head/helmet/space/eva/plasmaman/science/rd - name = "plasmaman research director helmet" - icon_state = "plasmaman_RD_helmet0" - base_state = "plasmaman_RD_helmet" - -//MAGISTRATE -/obj/item/clothing/suit/space/eva/plasmaman/magistrate - name = "plasmaman magistrate suit" - icon_state = "plasmaman_HoS" - -/obj/item/clothing/head/helmet/space/eva/plasmaman/magistrate - name = "plasmaman magistrate helmet" - icon_state = "plasmaman_HoS_helmet0" - base_state = "plasmaman_HoS_helmet" - -//NT REP -/obj/item/clothing/suit/space/eva/plasmaman/nt_rep - name = "plasmaman NT representative suit" - icon_state = "plasmaman_rep" - -/obj/item/clothing/head/helmet/space/eva/plasmaman/nt_rep - name = "plasmaman NT representative helmet" - icon_state = "plasmaman_rep_helmet0" - base_state = "plasmaman_rep_helmet" - -//SECURITY - -/obj/item/clothing/suit/space/eva/plasmaman/security - name = "plasmaman security suit" - icon_state = "plasmamanSecurity_suit" - armor = list(melee = 15, bullet = 15, laser = 15, energy = 10, bomb = 10, bio = 100, rad = 50) - -/obj/item/clothing/head/helmet/space/eva/plasmaman/security - name = "plasmaman security helmet" - icon_state = "plasmamanSecurity_helmet0" - base_state = "plasmamanSecurity_helmet" - armor = list(melee = 15, bullet = 15, laser = 15, energy = 10, bomb = 10, bio = 100, rad = 50) - -/obj/item/clothing/suit/space/eva/plasmaman/security/hos - name = "plasmaman head of security suit" - icon_state = "plasmaman_HoS" - -/obj/item/clothing/head/helmet/space/eva/plasmaman/security/hos - name = "plasmaman head of security helmet" - icon_state = "plasmaman_HoS_helmet0" - base_state = "plasmaman_HoS_helmet" - -/obj/item/clothing/suit/space/eva/plasmaman/security/hop - name = "plasmaman head of personnel suit" - icon_state = "plasmaman_HoP" - -/obj/item/clothing/head/helmet/space/eva/plasmaman/security/hop - name = "plasmaman head of personnel helmet" - icon_state = "plasmaman_HoP_helmet0" - base_state = "plasmaman_HoP_helmet" - -/obj/item/clothing/suit/space/eva/plasmaman/security/captain - name = "plasmaman captain suit" - icon_state = "plasmaman_Captain" - -/obj/item/clothing/head/helmet/space/eva/plasmaman/security/captain - name = "plasmaman captain helmet" - icon_state = "plasmaman_Captain_helmet0" - base_state = "plasmaman_Captain_helmet" - - -//IAA/LAWYER -/obj/item/clothing/suit/space/eva/plasmaman/lawyer - name = "plasmaman lawyer suit" - icon_state = "plasmamanlawyer_suit" - -/obj/item/clothing/head/helmet/space/eva/plasmaman/lawyer - name = "plasmaman lawyer helmet" - icon_state = "plasmamanlawyer_helmet0" - base_state = "plasmamanlawyer_helmet" - -//NUKEOPS - -/obj/item/clothing/suit/space/eva/plasmaman/nuclear - name = "blood red plasmaman suit" - icon_state = "plasmaman_Nukeops" - armor = list(melee = 60, bullet = 50, laser = 30, energy = 15, bomb = 35, bio = 100, rad = 50) - allowed = list(/obj/item/flashlight,/obj/item/tank,/obj/item/gun,/obj/item/ammo_casing,/obj/item/ammo_casing,/obj/item/melee/baton,/obj/item/melee/energy/sword/saber,/obj/item/restraints/handcuffs) - -/obj/item/clothing/head/helmet/space/eva/plasmaman/nuclear - name = "blood red plasmaman helmet" - icon_state = "plasmaman_Nukeops_helmet0" - base_state = "plasmaman_Nukeops_helmet" - armor = list(melee = 60, bullet = 50, laser = 30, energy = 15, bomb = 35, bio = 100, rad = 50) - -//WIZARD -/obj/item/clothing/suit/space/eva/plasmaman/wizard - name = "robed plasmaman suit" - icon_state = "plasmamanWizardBlue_suit" - magical = TRUE - -/obj/item/clothing/head/helmet/space/eva/plasmaman/wizard - name = "wizard hat" - icon_state = "plasmamanWizardBlue_helmet0" - base_state = "plasmamanWizardBlue_helmet" - magical = TRUE +/obj/item/clothing/head/helmet/space/plasmaman/security + name = "security plasma envirosuit helmet" + desc = "A plasmaman containment helmet designed for security officers, protecting them from being flashed and burning alive, along-side other undesirables." + icon_state = "security_envirohelm" + item_state = "security_envirohelm" + armor = list(melee = 10, bullet = 0, laser = 0, energy = 0, bomb = 0, bio = 100, rad = 0) + +/obj/item/clothing/head/helmet/space/plasmaman/security/warden + name = "warden's plasma envirosuit helmet" + desc = "A plasmaman containment helmet designed for the warden, a pair of white stripes being added to differeciate them from other members of security." + icon_state = "warden_envirohelm" + item_state = "warden_envirohelm" + +/obj/item/clothing/head/helmet/space/plasmaman/security/hos + name = "security plasma envirosuit helmet" + desc = "A plasmaman containment helmet designed for the head of security." + icon_state = "hos_envirohelm" + item_state = "hos_envirohelm" + +/obj/item/clothing/head/helmet/space/plasmaman/medical + name = "medical's plasma envirosuit helmet" + desc = "An envriohelmet designed for plasmaman medical doctors, having two stripes down it's length to denote as much" + icon_state = "doctor_envirohelm" + item_state = "doctor_envirohelm" + +/obj/item/clothing/head/helmet/space/plasmaman/cmo + name = "chief medical officer's plasma envirosuit helmet" + desc = "An envriohelmet designed for plasmaman employed as the cheif medical officer." + icon_state = "cmo_envirohelm" + item_state = "cmo_envirohelm" + +/obj/item/clothing/head/helmet/space/plasmaman/genetics + name = "geneticist's plasma envirosuit helmet" + desc = "A plasmaman envirohelmet designed for geneticists." + icon_state = "geneticist_envirohelm" + item_state = "geneticist_envirohelm" + +/obj/item/clothing/head/helmet/space/plasmaman/viro + name = "virology plasma envirosuit helmet" + desc = "The helmet worn by the safest people on the station, those who are completely immune to the monstrosities they create." + icon_state = "virologist_envirohelm" + item_state = "virologist_envirohelm" + +/obj/item/clothing/head/helmet/space/plasmaman/chemist + name = "chemistry plasma envirosuit helmet" + desc = "A plasmaman envirosuit designed for chemists, two orange stripes going down it's face." + icon_state = "chemist_envirohelm" + item_state = "chemist_envirohelm" + +/obj/item/clothing/head/helmet/space/plasmaman/science + name = "science plasma envirosuit helmet" + desc = "A plasmaman envirohelmet designed for scientists." + icon_state = "scientist_envirohelm" + item_state = "scientist_envirohelm" + +/obj/item/clothing/head/helmet/space/plasmaman/rd + name = "research director plasma envirosuit helmet" + desc = "A plasmaman envirohelmet designed for the research director." + icon_state = "rd_envirohelm" + item_state = "rd_envirohelm" + +/obj/item/clothing/head/helmet/space/plasmaman/robotics + name = "robotics plasma envirosuit helmet" + desc = "A plasmaman envirohelmet designed for roboticists." + icon_state = "roboticist_envirohelm" + item_state = "roboticist_envirohelm" + +/obj/item/clothing/head/helmet/space/plasmaman/engineering + name = "engineering plasma envirosuit helmet" + desc = "A space-worthy helmet specially designed for engineer plasmamen, the usual purple stripes being replaced by engineering's orange." + icon_state = "engineer_envirohelm" + item_state = "engineer_envirohelm" + armor = list(melee = 0, bullet = 0, laser = 0, energy = 0, bomb = 0, bio = 100, rad = 10) + +/obj/item/clothing/head/helmet/space/plasmaman/engineering/ce + name = "chief engineer's plasma envirosuit helmet" + desc = "A space-worthy helmet specially designed for chief engineer employed plasmamen." + icon_state = "ce_envirohelm" + item_state = "ce_envirohelm" + +/obj/item/clothing/head/helmet/space/plasmaman/atmospherics + name = "atmospherics plasma envirosuit helmet" + desc = "A space-worthy helmet specially designed for atmos technician plasmamen, the usual purple stripes being replaced by engineering's blue." + icon_state = "atmos_envirohelm" + item_state = "atmos_envirohelm" + +/obj/item/clothing/head/helmet/space/plasmaman/cargo + name = "cargo plasma envirosuit helmet" + desc = "An plasmaman envirohelmet designed for cargo techs and quartermasters." + icon_state = "cargo_envirohelm" + item_state = "cargo_envirohelm" + +/obj/item/clothing/head/helmet/space/plasmaman/mining + name = "mining plasma envirosuit helmet" + desc = "A khaki helmet given to plasmamen miners operating on lavaland." + icon_state = "explorer_envirohelm" + item_state = "explorer_envirohelm" + visor_icon = "explorer_envisor" + +/obj/item/clothing/head/helmet/space/plasmaman/chaplain + name = "chaplain's plasma envirosuit helmet" + desc = "An envirohelmet specially designed for only the most pious of plasmamen." + icon_state = "chap_envirohelm" + item_state = "chap_envirohelm" + +/obj/item/clothing/head/helmet/space/plasmaman/white + name = "white plasma envirosuit helmet" + desc = "A generic white envirohelm." + icon_state = "white_envirohelm" + item_state = "white_envirohelm" + +/obj/item/clothing/head/helmet/space/plasmaman/chef + name = "chef plasma envirosuit helmet" + desc = "An envirohelm designed for plasmamen chefs." + icon_state = "chef_envirohelm" + item_state = "chef_envirohelm" + +/obj/item/clothing/head/helmet/space/plasmaman/librarian + name = "librarian's plasma envirosuit helmet" + desc = "A slight modification on a tradiational voidsuit helmet, this helmet was Nano-Trasen's first solution to the *logistical problems* that come with employing plasmamen. Despite their limitations, these helmets still see use by historian and old-styled plasmamen alike." + icon_state = "prototype_envirohelm" + item_state = "prototype_envirohelm" + actions_types = list(/datum/action/item_action/toggle_welding_screen/plasmaman) + visor_icon = "prototype_envisor" + +/obj/item/clothing/head/helmet/space/plasmaman/botany + name = "botany plasma envirosuit helmet" + desc = "A green and blue envirohelmet designating it's wearer as a botanist. While not specially designed for it, it would protect against minor planet-related injuries." + icon_state = "botany_envirohelm" + item_state = "botany_envirohelm" + +/obj/item/clothing/head/helmet/space/plasmaman/janitor + name = "janitor's plasma envirosuit helmet" + desc = "A grey helmet bearing a pair of purple stripes, designating the wearer as a janitor." + icon_state = "janitor_envirohelm" + item_state = "janitor_envirohelm" + +/obj/item/clothing/head/helmet/space/plasmaman/mime + name = "mime envirosuit helmet" + desc = "The make-up is painted on, it's a miracle it doesn't chip. It's not very colourful." + icon_state = "mime_envirohelm" + item_state = "mime_envirohelm" + visor_icon = "mime_envisor" + +/obj/item/clothing/head/helmet/space/plasmaman/clown + name = "clown envirosuit helmet" + desc = "The make-up is painted on, it's a miracle it doesn't chip. 'HONK!'" + icon_state = "clown_envirohelm" + item_state = "clown_envirohelm" + visor_icon = "clown_envisor" + +/obj/item/clothing/head/helmet/space/plasmaman/hop + name = "head of personnel envirosuit helmet" + desc = "A plasmaman envirohelm that reeks of bureaucracy." + icon_state = "hop_envirohelm" + item_state = "hop_envirohelm" + +/obj/item/clothing/head/helmet/space/plasmaman/captain + name = "captain envirosuit helmet" + desc = "A plasmaman envirohelm designed with the insignia and markings befitting a captain." + icon_state = "cap_envirohelm" + item_state = "cap_envirohelm" + +/obj/item/clothing/head/helmet/space/plasmaman/blueshield + name = "blueshield envirosuit helmet" + desc = "A plasmaman envirohelm designed for the blueshield." + icon_state = "bs_envirohelm" + item_state = "bs_envirohelm" \ No newline at end of file diff --git a/code/modules/clothing/spacesuits/rig/modules/utility.dm b/code/modules/clothing/spacesuits/rig/modules/utility.dm index bfb326eae1d..e87e35a0dea 100644 --- a/code/modules/clothing/spacesuits/rig/modules/utility.dm +++ b/code/modules/clothing/spacesuits/rig/modules/utility.dm @@ -56,7 +56,7 @@ interface_desc = "A diamond-tipped industrial drill." suit_overlay_active = "mounted-drill" suit_overlay_inactive = "mounted-drill" - device_type = /obj/item/pickaxe/diamonddrill + device_type = /obj/item/pickaxe/drill/diamonddrill /obj/item/rig_module/device/orescanner name = "ore scanner module" diff --git a/code/modules/clothing/suits/armor.dm b/code/modules/clothing/suits/armor.dm index 96c2ed46f7a..e27b3b8ef1f 100644 --- a/code/modules/clothing/suits/armor.dm +++ b/code/modules/clothing/suits/armor.dm @@ -209,6 +209,15 @@ allowed = list(/obj/item/nullrod/claymore) armor = list(melee = 25, bullet = 5, laser = 5, energy = 5, bomb = 0, bio = 0, rad = 0) +/obj/item/clothing/suit/armor/vest/durathread + name = "durathread vest" + desc = "A vest made of durathread with strips of leather acting as trauma plates." + icon_state = "durathread" + item_state = "durathread" + strip_delay = 60 + burn_state = FLAMMABLE + armor = list(melee = 20, bullet = 10, laser = 30, energy = 5, bomb = 15, bio = 0, rad = 0) + /obj/item/clothing/suit/armor/bulletproof name = "Bulletproof Vest" desc = "A bulletproof vest that excels in protecting the wearer against traditional projectile weaponry and explosives to a minor extent." @@ -527,14 +536,5 @@ icon_state = "bonearmor" item_state = "bonearmor" blood_overlay_type = "armor" - armor = list("melee" = 35, "bullet" = 25, "laser" = 25, "energy" = 10, "bomb" = 25, "bio" = 0, "rad" = 0, "fire" = 50, "acid" = 50) - body_parts_covered = UPPER_TORSO|LOWER_TORSO|LEGS|FEET|ARMS - -/obj/item/clothing/head/skullhelmet - name = "skull helmet" - desc = "An intimidating tribal helmet, it doesn't look very comfortable." - flags = BLOCKHAIR - flags_cover = HEADCOVERSEYES - armor = list("melee" = 25, "bullet" = 25, "laser" = 25, "energy" = 10, "bomb" = 10, "bio" = 5, "rad" = 20, "fire" = 40, "acid" = 20) - icon_state = "skull" - item_state = "skull" \ No newline at end of file + armor = list(melee = 35, bullet = 25, laser = 25, energy = 10, bomb = 25, bio = 0, rad = 0) + body_parts_covered = UPPER_TORSO|LOWER_TORSO|LEGS|FEET|ARMS \ No newline at end of file diff --git a/code/modules/clothing/suits/toggles.dm b/code/modules/clothing/suits/toggles.dm new file mode 100644 index 00000000000..576b3e6c552 --- /dev/null +++ b/code/modules/clothing/suits/toggles.dm @@ -0,0 +1,77 @@ +//Hardsuit toggle code +/obj/item/clothing/suit/space/hardsuit/New() + MakeHelmet() + ..() + +/obj/item/clothing/suit/space/hardsuit/Destroy() + if(helmet) + helmet.suit = null + QDEL_NULL(helmet) + QDEL_NULL(jetpack) + return ..() + +/obj/item/clothing/head/helmet/space/hardsuit/Destroy() + if(suit) + suit.helmet = null + return ..() + +/obj/item/clothing/suit/space/hardsuit/proc/MakeHelmet() + if(!helmettype) + return + if(!helmet) + var/obj/item/clothing/head/helmet/space/hardsuit/W = new helmettype(src) + W.suit = src + helmet = W + +/obj/item/clothing/suit/space/hardsuit/ui_action_click() + ..() + ToggleHelmet() + +/obj/item/clothing/suit/space/hardsuit/equipped(mob/user, slot) + if(!helmettype) + return + if(slot != slot_wear_suit) + RemoveHelmet() + ..() + +/obj/item/clothing/suit/space/hardsuit/proc/RemoveHelmet() + if(!helmet) + return + suittoggled = FALSE + if(ishuman(helmet.loc)) + var/mob/living/carbon/H = helmet.loc + if(helmet.on) + helmet.attack_self(H) + H.unEquip(helmet, TRUE) + helmet.forceMove(src) + H.update_inv_wear_suit() + to_chat(H, "The helmet on the hardsuit disengages.") + playsound(src.loc, 'sound/mecha/mechmove03.ogg', 50, 1) + else + helmet.forceMove(src) + +/obj/item/clothing/suit/space/hardsuit/dropped() + ..() + RemoveHelmet() + +/obj/item/clothing/suit/space/hardsuit/proc/ToggleHelmet() + var/mob/living/carbon/human/H = src.loc + if(!helmettype) + return + if(!helmet) + return + if(!suittoggled) + if(ishuman(src.loc)) + if(H.wear_suit != src) + to_chat(H, "You must be wearing [src] to engage the helmet!") + return + if(H.head) + to_chat(H, "You're already wearing something on your head!") + return + else if(H.equip_to_slot_if_possible(helmet, slot_head, 0 ,0, 1)) + to_chat(H, "You engage the helmet on the hardsuit.") + suittoggled = TRUE + H.update_inv_wear_suit() + playsound(src.loc, 'sound/mecha/mechmove03.ogg', 50, 1) + else + RemoveHelmet() \ No newline at end of file diff --git a/code/modules/clothing/under/jobs/plasmamen/_plasmamen.dm b/code/modules/clothing/under/jobs/plasmamen/_plasmamen.dm new file mode 100644 index 00000000000..5c38361e0b2 --- /dev/null +++ b/code/modules/clothing/under/jobs/plasmamen/_plasmamen.dm @@ -0,0 +1,55 @@ +/obj/item/clothing/under/plasmaman + name = "plasma envirosuit" + desc = "A special containment suit that allows plasma-based lifeforms to exist safely in an oxygenated environment, and automatically extinguishes them in a crisis. Despite being airtight, it's not spaceworthy." + armor = list(melee = 0, bullet = 0, laser = 0, energy = 0, bomb = 0, bio = 100, rad = 0) + body_parts_covered = UPPER_TORSO|LOWER_TORSO|LEGS|FEET|ARMS|HANDS + strip_delay = 80 + var/next_extinguish = 0 + var/extinguish_cooldown = 100 + var/extinguishes_left = 5 + icon = 'icons/obj/clothing/species/plasmaman/uniform.dmi' + species_restricted = list("Plasmaman") + sprite_sheets = list("Plasmaman" = 'icons/mob/species/plasmaman/uniform.dmi') + icon_state = "plasmaman" + item_state = "plasmaman" + item_color = "plasmaman" + +/obj/item/clothing/under/plasmaman/examine(mob/user) + ..() + to_chat(user, "There are [extinguishes_left] extinguisher charges left in this suit.") + +/obj/item/clothing/under/plasmaman/proc/Extinguish(mob/living/carbon/human/H) + if(!istype(H)) + return + + if(H.on_fire) + if(extinguishes_left) + if(next_extinguish > world.time) + return + next_extinguish = world.time + extinguish_cooldown + extinguishes_left-- + H.visible_message("[H]'s suit automatically extinguishes [H.p_them()]!","Your suit automatically extinguishes you.") + if(!extinguishes_left) + to_chat(H, "Onboard auto-extinguisher depleted, refill with a cartridge.") + playsound(H.loc, 'sound/effects/spray.ogg', 10, 1, -3) + H.ExtinguishMob() + new /obj/effect/particle_effect/water(get_turf(H)) + return FALSE + +/obj/item/clothing/under/plasmaman/attackby(obj/item/E, mob/user, params) + if (istype(E, /obj/item/extinguisher_refill)) + if (extinguishes_left == 5) + to_chat(user, "The inbuilt extinguisher is full.") + return + else + extinguishes_left = 5 + to_chat(user, "You refill the suit's built-in extinguisher, using up the cartridge.") + qdel(E) + else + return ..() + +/obj/item/extinguisher_refill + name = "envirosuit extinguisher cartridge" + desc = "A cartridge loaded with a compressed extinguisher mix, used to refill the automatic extinguisher on plasma envirosuits." + icon_state = "plasmarefill" + icon = 'icons/obj/device.dmi' \ No newline at end of file diff --git a/code/modules/clothing/under/jobs/plasmamen/civilian_service.dm b/code/modules/clothing/under/jobs/plasmamen/civilian_service.dm new file mode 100644 index 00000000000..69697d3be6f --- /dev/null +++ b/code/modules/clothing/under/jobs/plasmamen/civilian_service.dm @@ -0,0 +1,107 @@ +/obj/item/clothing/under/plasmaman/cargo + name = "cargo plasma envirosuit" + desc = "A joint envirosuit used by plasmamen quartermasters and cargo techs alike, due to the logistical problems of differenciating the two with the length of their pant legs." + icon_state = "cargo_envirosuit" + item_state = "cargo_envirosuit" + item_color = "cargo_envirosuit" + +/obj/item/clothing/under/plasmaman/mining + name = "mining plasma envirosuit" + desc = "An air-tight khaki suit designed for operations on lavaland by plasmamen." + icon_state = "explorer_envirosuit" + item_state = "explorer_envirosuit" + item_color = "explorer_envirosuit" + + +/obj/item/clothing/under/plasmaman/chef + name = "chef's plasma envirosuit" + desc = "A white plasmaman envirosuit designed for cullinary practices. One might question why a member of a species that doesn't need to eat would become a chef." + icon_state = "chef_envirosuit" + item_state = "chef_envirosuit" + item_color = "chef_envirosuit" + +/obj/item/clothing/under/plasmaman/enviroslacks + name = "enviroslacks" + desc = "The pet project of a particularly posh plasmaman, this custom suit was quickly appropriated by Nano-Trasen for it's detectives, lawyers, and bar-tenders alike." + icon_state = "enviroslacks" + item_state = "enviroslacks" + item_color = "enviroslacks" + +/obj/item/clothing/under/plasmaman/chaplain + name = "chaplain's plasma envirosuit" + desc = "An envirosuit specially designed for only the most pious of plasmamen." + icon_state = "chap_envirosuit" + item_state = "chap_envirosuit" + item_color = "chap_envirosuit" + +/obj/item/clothing/under/plasmaman/librarian + name = "librarian's plasma envirosuit" + desc = "Made out of a modified voidsuit, this suit was Nano-Trasen's first solution to the *logistical problems* that come with employing plasmamen. Due to the modifications, the suit is no longer space-worthy. Despite their limitations, these suits are still in used by historian and old-styled plasmamen alike." + icon_state = "prototype_envirosuit" + item_state = "prototype_envirosuit" + item_color = "prototype_envirosuit" + +/obj/item/clothing/under/plasmaman/janitor + name = "janitor's plasma envirosuit" + desc = "A grey and purple envirosuit designated for plasmamen janitors." + icon_state = "janitor_envirosuit" + item_state = "janitor_envirosuit" + item_color = "janitor_envirosuit" + +/obj/item/clothing/under/plasmaman/botany + name = "botany envirosuit" + desc = "A green and blue envirosuit designed to protect plasmamen from minor plant-related injuries." + icon_state = "botany_envirosuit" + item_state = "botany_envirosuit" + item_color = "botany_envirosuit" + + +/obj/item/clothing/under/plasmaman/mime + name = "mime envirosuit" + desc = "It's not very colourful." + icon_state = "mime_envirosuit" + item_state = "mime_envirosuit" + item_color = "mime_envirosuit" + +/obj/item/clothing/under/plasmaman/clown + name = "clown envirosuit" + desc = "'HONK!'" + icon_state = "clown_envirosuit" + item_state = "clown_envirosuit" + item_color = "clown_envirosuit" + +/obj/item/clothing/under/plasmaman/clown/Extinguish(mob/living/carbon/human/H) + if(!istype(H)) + return + + if(H.on_fire) + if(extinguishes_left) + if(next_extinguish > world.time) + return + next_extinguish = world.time + extinguish_cooldown + extinguishes_left-- + H.visible_message("[H]'s suit spews out a tonne of space lube!", "Your suit spews out a tonne of space lube!") + H.ExtinguishMob() + new /obj/effect/particle_effect/foam(loc) //Truely terrifying. + return FALSE + +/obj/item/clothing/under/plasmaman/hop + name = "head of personnel envirosuit" + desc = "An envirosuit designed for plasmamen employed as the head of personnel." + icon_state = "hop_envirosuit" + item_state = "hop_envirosuit" + item_color = "hop_envirosuit" + +/obj/item/clothing/under/plasmaman/captain + name = "captain envirosuit" + desc = "An envirosuit designed for plasmamen employed as the captain." + icon_state = "cap_envirosuit" + item_state = "cap_envirosuit" + item_color = "cap_envirosuit" + +/obj/item/clothing/under/plasmaman/blueshield + name = "blueshield envirosuit" + desc = "An envirosuit designed for plasmamen employed as the blueshield." + icon_state = "bs_envirosuit" + item_state = "bs_envirosuit" + item_color = "bs_envirosuit" \ No newline at end of file diff --git a/code/modules/clothing/under/jobs/plasmamen/engineering.dm b/code/modules/clothing/under/jobs/plasmamen/engineering.dm new file mode 100644 index 00000000000..e83eef2917c --- /dev/null +++ b/code/modules/clothing/under/jobs/plasmamen/engineering.dm @@ -0,0 +1,22 @@ +/obj/item/clothing/under/plasmaman/engineering + name = "engineering plasma envirosuit" + desc = "An air-tight suit designed to be used by plasmamen exployed as engineers, the usual purple stripes being replaced by engineer's orange. It protects the user from fire and acid damage." + icon_state = "engineer_envirosuit" + item_state = "engineer_envirosuit" + item_color = "engineer_envirosuit" + armor = list(melee = 0, bullet = 0, laser = 0, energy = 0, bomb = 0, bio = 100, rad = 10) + +/obj/item/clothing/under/plasmaman/engineering/ce + name = "chief engineer plasma envirosuit" + desc = "An air-tight suit designed to be used by plasmamen exployed as the chief engineer" + icon_state = "ce_envirosuit" + item_state = "ce_envirosuit" + item_color = "ce_envirosuit" + +/obj/item/clothing/under/plasmaman/atmospherics + name = "atmospherics plasma envirosuit" + desc = "An air-tight suit designed to be used by plasmamen exployed as atmos technicians, the usual purple stripes being replaced by atmos's blue." + icon_state = "atmos_envirosuit" + item_state = "atmos_envirosuit" + item_color = "atmos_envirosuit" + diff --git a/code/modules/clothing/under/jobs/plasmamen/medsci.dm b/code/modules/clothing/under/jobs/plasmamen/medsci.dm new file mode 100644 index 00000000000..69e14c0e878 --- /dev/null +++ b/code/modules/clothing/under/jobs/plasmamen/medsci.dm @@ -0,0 +1,55 @@ +/obj/item/clothing/under/plasmaman/medical + name = "medical plasma envirosuit" + desc = "A suit designed for the station's more plasma-based doctors." + icon_state = "doctor_envirosuit" + item_state = "doctor_envirosuit" + item_color = "doctor_envirosuit" + +/obj/item/clothing/under/plasmaman/cmo + name = "cmo plasma envirosuit" + desc = "A suit designed for the station's more plasma-based chief medical officer." + icon_state = "cmo_envirosuit" + item_state = "cmo_envirosuit" + item_color = "cmo_envirosuit" + +/obj/item/clothing/under/plasmaman/science + name = "science plasma envirosuit" + desc = "A plasmaman envirosuit designed for scientists." + icon_state = "scientist_envirosuit" + item_state = "scientist_envirosuit" + item_color = "scientist_envirosuit" + +/obj/item/clothing/under/plasmaman/rd + name = "science plasma envirosuit" + desc = "A plasmaman envirosuit designed for the research director." + icon_state = "rd_envirosuit" + item_state = "rd_envirosuit" + item_color = "rd_envirosuit" + +/obj/item/clothing/under/plasmaman/robotics + name = "robotics plasma envirosuit" + desc = "A plasmaman envirosuit designed for roboticists." + icon_state = "roboticist_envirosuit" + item_state = "roboticist_envirosuit" + item_color = "roboticist_envirosuit" + +/obj/item/clothing/under/plasmaman/viro + name = "virology plasma envirosuit" + desc = "The suit worn by the safest people on the station, those who are completely immune to the monstrosities they create." + icon_state = "virologist_envirosuit" + item_state = "virologist_envirosuit" + item_color = "virologist_envirosuit" + +/obj/item/clothing/under/plasmaman/genetics + name = "genetics plasma envirosuit" + desc = "A plasmaman envirosuit designed for geneticists." + icon_state = "geneticist_envirosuit" + item_state = "geneticist_envirosuit" + item_color = "geneticist_envirosuit" + +/obj/item/clothing/under/plasmaman/chemist + name = "chemistry plasma envirosuit" + desc = "A plasmaman envirosuit designed for chemists." + icon_state = "chemist_envirosuit" + item_state = "chemist_envirosuit" + item_color = "chemist_envirosuit" diff --git a/code/modules/clothing/under/jobs/plasmamen/security.dm b/code/modules/clothing/under/jobs/plasmamen/security.dm new file mode 100644 index 00000000000..d6f85da06f7 --- /dev/null +++ b/code/modules/clothing/under/jobs/plasmamen/security.dm @@ -0,0 +1,21 @@ +/obj/item/clothing/under/plasmaman/security + name = "security plasma envirosuit" + desc = "A plasmaman containment suit designed for security officers, offering a limited amount of extra protection." + icon_state = "security_envirosuit" + item_state = "security_envirosuit" + item_color = "security_envirosuit" + armor = list(melee = 10, bullet = 0, laser = 0, energy = 0, bomb = 0, bio = 100, rad = 0) + +/obj/item/clothing/under/plasmaman/security/warden + name = "warden plasma envirosuit" + desc = "A plasmaman containment suit designed for the warden, white stripes being added to differeciate them from other members of security." + icon_state = "warden_envirosuit" + item_state = "warden_envirosuit" + item_color = "warden_envirosuit" + +/obj/item/clothing/under/plasmaman/security/hos + name = "head of security plasma envirosuit" + desc = "A plasmaman containment suit designed for the head of security." + icon_state = "hos_envirosuit" + item_state = "hos_envirosuit" + item_color = "hos_envirosuit" \ No newline at end of file diff --git a/code/modules/clothing/under/miscellaneous.dm b/code/modules/clothing/under/miscellaneous.dm index 91527f2dd19..c277345a440 100644 --- a/code/modules/clothing/under/miscellaneous.dm +++ b/code/modules/clothing/under/miscellaneous.dm @@ -890,3 +890,10 @@ item_color = "hawaiianblue" flags_size = ONESIZEFITSALL +/obj/item/clothing/under/misc/durathread + name = "durathread jumpsuit" + desc = "A jumpsuit made from durathread, its resilient fibres provide some protection to the wearer." + icon_state = "durathread" + item_state = "durathread" + item_color = "durathread" + armor = list(melee = 10, bullet = 0, laser = 10, energy = 0, bomb = 5, bio = 0, rad = 0) \ No newline at end of file diff --git a/code/modules/crafting/craft.dm b/code/modules/crafting/craft.dm index ea5e4a652aa..77cef31ed55 100644 --- a/code/modules/crafting/craft.dm +++ b/code/modules/crafting/craft.dm @@ -1,7 +1,7 @@ /datum/personal_crafting var/busy var/viewing_category = 1 //typical powergamer starting on the Weapons tab - var/list/categories = list(CAT_WEAPON,CAT_AMMO,CAT_ROBOT,CAT_FOOD,CAT_MISC,CAT_PRIMAL) + var/list/categories = list(CAT_WEAPON,CAT_AMMO,CAT_ROBOT,CAT_FOOD,CAT_CLOTHING,CAT_MISC,CAT_PRIMAL) var/display_craftable_only = FALSE var/display_compact = TRUE diff --git a/code/modules/crafting/recipes.dm b/code/modules/crafting/recipes.dm index 1520e19dcfc..58338efea61 100644 --- a/code/modules/crafting/recipes.dm +++ b/code/modules/crafting/recipes.dm @@ -385,42 +385,11 @@ ) category = CAT_WEAPON -/datum/crafting_recipe/bonfire - name = "Bonfire" - time = 60 - reqs = list(/obj/item/grown/log = 5) - result = /obj/structure/bonfire - category = CAT_PRIMAL - -/datum/crafting_recipe/boneaxe - name = "Bone Axe" - result = /obj/item/twohanded/fireaxe/boneaxe - time = 50 - reqs = list(/obj/item/stack/sheet/bone = 6, - /obj/item/stack/sheet/sinew = 3) - category = CAT_PRIMAL - -/datum/crafting_recipe/bonespear - name = "Bone Spear" - result = /obj/item/twohanded/spear/bonespear +/datum/crafting_recipe/bonearmor + name = "Bone Armor" + result = /obj/item/clothing/suit/armor/bone time = 30 - reqs = list(/obj/item/stack/sheet/bone = 4, - /obj/item/stack/sheet/sinew = 1) - category = CAT_PRIMAL - -/datum/crafting_recipe/bonedagger - name = "Bone Dagger" - result = /obj/item/kitchen/knife/combat/survival/bone - time = 20 - reqs = list(/obj/item/stack/sheet/bone = 2) - category = CAT_PRIMAL - -/datum/crafting_recipe/bonecodpiece - name = "Skull Codpiece" - result = /obj/item/clothing/accessory/necklace/skullcodpiece - time = 20 - reqs = list(/obj/item/stack/sheet/bone = 2, - /obj/item/stack/sheet/animalhide/goliath_hide = 1) + reqs = list(/obj/item/stack/sheet/bone = 6) category = CAT_PRIMAL /datum/crafting_recipe/bonetalisman @@ -431,16 +400,25 @@ /obj/item/stack/sheet/sinew = 1) category = CAT_PRIMAL -/datum/crafting_recipe/bonearmor - name = "Bone Armor" - result = /obj/item/clothing/suit/armor/bone - time = 30 - reqs = list(/obj/item/stack/sheet/bone = 6) +/datum/crafting_recipe/bonecodpiece + name = "Skull Codpiece" + result = /obj/item/clothing/accessory/necklace/skullcodpiece + time = 20 + reqs = list(/obj/item/stack/sheet/bone = 2, + /obj/item/stack/sheet/animalhide/goliath_hide = 1) + category = CAT_PRIMAL + +/datum/crafting_recipe/bracers + name = "Bone Bracers" + result = /obj/item/clothing/gloves/bracer + time = 20 + reqs = list(/obj/item/stack/sheet/bone = 2, + /obj/item/stack/sheet/sinew = 1) category = CAT_PRIMAL /datum/crafting_recipe/skullhelm name = "Skull Helmet" - result = /obj/item/clothing/head/skullhelmet + result = /obj/item/clothing/head/helmet/skull time = 30 reqs = list(/obj/item/stack/sheet/bone = 4) category = CAT_PRIMAL @@ -463,6 +441,13 @@ /obj/item/stack/sheet/animalhide/ashdrake = 5) category = CAT_PRIMAL +/datum/crafting_recipe/firebrand + name = "Firebrand" + result = /obj/item/match/firebrand + time = 100 //Long construction time. Making fire is hard work. + reqs = list(/obj/item/stack/sheet/wood = 2) + category = CAT_PRIMAL + /datum/crafting_recipe/tribal_splint name = "Tribal Splint" time = 20 @@ -471,6 +456,50 @@ result = /obj/item/stack/medical/splint/tribal category = CAT_PRIMAL +/datum/crafting_recipe/bonedagger + name = "Bone Dagger" + result = /obj/item/kitchen/knife/combat/survival/bone + time = 20 + reqs = list(/obj/item/stack/sheet/bone = 2) + category = CAT_PRIMAL + +/datum/crafting_recipe/bonespear + name = "Bone Spear" + result = /obj/item/twohanded/spear/bonespear + time = 30 + reqs = list(/obj/item/stack/sheet/bone = 4, + /obj/item/stack/sheet/sinew = 1) + category = CAT_PRIMAL + +/datum/crafting_recipe/boneaxe + name = "Bone Axe" + result = /obj/item/twohanded/fireaxe/boneaxe + time = 50 + reqs = list(/obj/item/stack/sheet/bone = 6, + /obj/item/stack/sheet/sinew = 3) + category = CAT_PRIMAL + +/datum/crafting_recipe/bonfire + name = "Bonfire" + time = 60 + reqs = list(/obj/item/grown/log = 5) + result = /obj/structure/bonfire + category = CAT_PRIMAL + +/datum/crafting_recipe/rake //Category resorting incoming + name = "Rake" + time = 30 + reqs = list(/obj/item/stack/sheet/wood = 5) + result = /obj/item/cultivator/rake + category = CAT_PRIMAL + +/datum/crafting_recipe/woodbucket + name = "Wooden Bucket" + time = 30 + reqs = list(/obj/item/stack/sheet/wood = 3) + result = /obj/item/reagent_containers/glass/bucket/wooden + category = CAT_PRIMAL + /datum/crafting_recipe/guillotine name = "Guillotine" result = /obj/structure/guillotine diff --git a/code/modules/crafting/tailoring.dm b/code/modules/crafting/tailoring.dm new file mode 100644 index 00000000000..a46e509001c --- /dev/null +++ b/code/modules/crafting/tailoring.dm @@ -0,0 +1,145 @@ +/datum/crafting_recipe/durathread_vest + name = "Durathread Vest" + result = /obj/item/clothing/suit/armor/vest/durathread + reqs = list(/obj/item/stack/sheet/durathread = 5, + /obj/item/stack/sheet/leather = 4) + time = 50 + category = CAT_CLOTHING + +/datum/crafting_recipe/durathread_helmet + name = "Durathread Helmet" + result = /obj/item/clothing/head/helmet/durathread + reqs = list(/obj/item/stack/sheet/durathread = 4, + /obj/item/stack/sheet/leather = 5) + time = 40 + category = CAT_CLOTHING + +/datum/crafting_recipe/durathread_jumpsuit + name = "Durathread Jumpsuit" + result = /obj/item/clothing/under/misc/durathread + reqs = list(/obj/item/stack/sheet/durathread = 4) + time = 40 + category = CAT_CLOTHING + +/datum/crafting_recipe/durathread_beret + name = "Durathread Beret" + result = /obj/item/clothing/head/beret/durathread + reqs = list(/obj/item/stack/sheet/durathread = 2) + time = 40 + category = CAT_CLOTHING + +/datum/crafting_recipe/durathread_beanie + name = "Durathread Beanie" + result = /obj/item/clothing/head/beanie/durathread + reqs = list(/obj/item/stack/sheet/durathread = 2) + time = 40 + category = CAT_CLOTHING + +/datum/crafting_recipe/durathread_bandana + name = "Durathread Bandana" + result = /obj/item/clothing/mask/bandana/durathread + reqs = list(/obj/item/stack/sheet/durathread = 1) + time = 25 + category = CAT_CLOTHING + +/datum/crafting_recipe/fannypack + name = "Fannypack" + result = /obj/item/storage/belt/fannypack + reqs = list(/obj/item/stack/sheet/cloth = 2, + /obj/item/stack/sheet/leather = 1) + time = 20 + category = CAT_CLOTHING + +/datum/crafting_recipe/hudsunsec + name = "Security HUDsunglasses" + result = /obj/item/clothing/glasses/hud/security/sunglasses + time = 20 + tools = list(/obj/item/screwdriver, /obj/item/wirecutters) + reqs = list(/obj/item/clothing/glasses/hud/security = 1, + /obj/item/clothing/glasses/sunglasses = 1, + /obj/item/stack/cable_coil = 5) + category = CAT_CLOTHING + +/datum/crafting_recipe/hudsunsecremoval + name = "Security HUD removal" + result = /obj/item/clothing/glasses/sunglasses + time = 20 + tools = list(/obj/item/screwdriver, /obj/item/wirecutters) + reqs = list(/obj/item/clothing/glasses/hud/security/sunglasses = 1) + category = CAT_CLOTHING + +/datum/crafting_recipe/hudsunmed + name = "Medical HUDsunglasses" + result = /obj/item/clothing/glasses/hud/health/sunglasses + time = 20 + tools = list(/obj/item/screwdriver, /obj/item/wirecutters) + reqs = list(/obj/item/clothing/glasses/hud/health = 1, + /obj/item/clothing/glasses/sunglasses = 1, + /obj/item/stack/cable_coil = 5) + category = CAT_CLOTHING + +/datum/crafting_recipe/hudsunmedremoval + name = "Medical HUD removal" + result = /obj/item/clothing/glasses/sunglasses + time = 20 + tools = list(/obj/item/screwdriver, /obj/item/wirecutters) + reqs = list(/obj/item/clothing/glasses/hud/health/sunglasses = 1) + category = CAT_CLOTHING + +/datum/crafting_recipe/hudsundiag + name = "Diagnostic HUDsunglasses" + result = /obj/item/clothing/glasses/hud/diagnostic/sunglasses + time = 20 + tools = list(/obj/item/screwdriver, /obj/item/wirecutters) + reqs = list(/obj/item/clothing/glasses/hud/diagnostic = 1, + /obj/item/clothing/glasses/sunglasses = 1, + /obj/item/stack/cable_coil = 5) + category = CAT_CLOTHING + +/datum/crafting_recipe/hudsundiagremoval + name = "Diagnostic HUD removal" + result = /obj/item/clothing/glasses/sunglasses + time = 20 + tools = list(/obj/item/screwdriver, /obj/item/wirecutters) + reqs = list(/obj/item/clothing/glasses/hud/diagnostic/sunglasses = 1) + category = CAT_CLOTHING + +/datum/crafting_recipe/beergoggles + name = "Beer Goggles" + result = /obj/item/clothing/glasses/sunglasses/reagent + time = 20 + tools = list(/obj/item/screwdriver, /obj/item/wirecutters) + reqs = list(/obj/item/clothing/glasses/science = 1, + /obj/item/clothing/glasses/sunglasses = 1, + /obj/item/stack/cable_coil = 5) + category = CAT_CLOTHING + +/datum/crafting_recipe/beergogglesremoval + name = "Beer Goggles removal" + result = /obj/item/clothing/glasses/sunglasses + time = 20 + tools = list(/obj/item/screwdriver, /obj/item/wirecutters) + reqs = list(/obj/item/clothing/glasses/sunglasses/reagent = 1) + category = CAT_CLOTHING + +/datum/crafting_recipe/ghostsheet + name = "Ghost Sheet" + result = /obj/item/clothing/suit/ghost_sheet + time = 5 + tools = list(/obj/item/wirecutters) + reqs = list(/obj/item/bedsheet = 1) + category = CAT_CLOTHING + +/datum/crafting_recipe/cowboyboots + name = "Cowboy Boots" + result = /obj/item/clothing/shoes/cowboy + reqs = list(/obj/item/stack/sheet/leather = 2) + time = 45 + category = CAT_CLOTHING + +/datum/crafting_recipe/lizardboots + name = "Lizard Skin Boots" + result = /obj/effect/spawner/lootdrop/lizardboots + reqs = list(/obj/item/stack/sheet/animalhide/lizard = 1, /obj/item/stack/sheet/leather = 1) + time = 60 + category = CAT_CLOTHING diff --git a/code/modules/customitems/item_defines.dm b/code/modules/customitems/item_defines.dm index 3be36b0282e..c1acd1e3d38 100644 --- a/code/modules/customitems/item_defines.dm +++ b/code/modules/customitems/item_defines.dm @@ -10,6 +10,9 @@ ////////// Usable Items ////////// ////////////////////////////////// +#define USED_MOD_HELM 1 +#define USED_MOD_SUIT 2 + /obj/item/fluff var/used = 0 @@ -175,7 +178,7 @@ icon = 'icons/obj/custom_items.dmi' icon_state = "book_berner_1" -/obj/item/clothing/glasses/sunglasses/fake/fluff/kaki //Rapidvalj: Kakicharakiti +/obj/item/clothing/glasses/sunglasses_fake/fluff/kaki //Rapidvalj: Kakicharakiti name = "broken thermonocle" desc = "A weathered Vox thermonocle, doesn't seem to work anymore." icon_state = "thermoncle" @@ -401,118 +404,6 @@ return to_chat(user, "You can't modify [target]!") -#define USED_MOD_HELM 1 -#define USED_MOD_SUIT 2 - -/obj/item/fluff/shadey_plasman_modkit - name = "plasmaman suit modkit" - desc = "A kit containing nanites that are able to modify the look of a plasmaman suit and helmet without exposing the wearer to hostile environments." - icon_state = "modkit" - w_class = WEIGHT_CLASS_SMALL - force = 0 - throwforce = 0 - -/obj/item/fluff/shadey_plasman_modkit/afterattack(atom/target, mob/user, proximity) - if(!proximity || !ishuman(user) || user.incapacitated()) - return - var/mob/living/carbon/human/H = user - - if(istype(target, /obj/item/clothing/head/helmet/space/eva/plasmaman)) - if(used & USED_MOD_HELM) - to_chat(H, "The kit's helmet modifier has already been used.") - return - to_chat(H, "You modify the appearance of [target].") - used |= USED_MOD_HELM - - var/obj/item/clothing/head/helmet/space/eva/plasmaman/P = target - P.name = "plasma containment helmet" - P.desc = "A purpose-built containment helmet designed to keep plasma in, and everything else out." - P.icon_state = "plasmaman_halo_helmet[P.on]" - P.base_state = "plasmaman_halo_helmet" - - if(P == H.head) - H.update_inv_head() - return - if(istype(target, /obj/item/clothing/suit/space/eva/plasmaman)) - if(used & USED_MOD_SUIT) - to_chat(user, "The kit's suit modifier has already been used.") - return - to_chat(H, "You modify the appearance of [target].") - used |= USED_MOD_SUIT - - var/obj/item/clothing/suit/space/eva/plasmaman/P = target - P.name = "plasma containment suit" - P.desc = "A feminine containment suit designed to keep plasma in, and everything else out. It's even got an overskirt." - P.icon_state = "plasmaman_halo" - - if(P == H.wear_suit) - H.update_inv_wear_suit() - return - to_chat(user, "You can't modify [target]!") - -/obj/item/fluff/lighty_plasman_modkit // LightFire53: Ikelos - name = "plasmaman suit modkit" - desc = "A kit containing nanites that are able to modify the look of a plasmaman suit and helmet without exposing the wearer to hostile environments." - icon_state = "modkit" - w_class = 2 - force = 0 - throwforce = 0 - var/picked_color = null - var/list/helmets = list( - "Blue" = "plasmaman_ikelosdefault_helmet", - "Gold" = "plasmaman_ikelosgold_helmet", - "Red" = "plasmaman_ikelossecurity_helmet") - var/list/suits = list( - "Blue" = "plasmaman_ikelosdefault", - "Gold" = "plasmaman_ikelosgold", - "Red" = "plasmaman_ikelossecurity") - -/obj/item/fluff/lighty_plasman_modkit/afterattack(atom/target, mob/user, proximity) - if(!proximity || !ishuman(user) || user.incapacitated()) - return - var/mob/living/carbon/human/H = user - - if(istype(target, /obj/item/clothing/head/helmet/space/eva/plasmaman)) - if(used & USED_MOD_HELM) - to_chat(H, "The kit's helmet modifier has already been used.") - return - - picked_color = input(H, "Which color would you like to paint [target]?", "Recolor") as null|anything in helmets - var/obj/item/clothing/head/helmet/space/eva/plasmaman/P = target - - if(!picked_color) - return - P.icon_state = helmets[picked_color] + "[P.on]" - P.base_state = helmets[picked_color] - - to_chat(H, "You modify the appearance of [target].") - P.icon = 'icons/obj/custom_items.dmi' - used |= USED_MOD_HELM - - if(P == H.head) - H.update_inv_head() - return - if(istype(target, /obj/item/clothing/suit/space/eva/plasmaman)) - if(used & USED_MOD_SUIT) - to_chat(user, "The kit's suit modifier has already been used.") - return - picked_color = input(H, "Which color would you like to paint [target]?", "Recolor") as null|anything in suits - var/obj/item/clothing/suit/space/eva/plasmaman/P = target - - if(!picked_color) - return - P.icon_state = suits[picked_color] - - to_chat(H, "You modify the appearance of [target].") - P.icon = 'icons/obj/custom_items.dmi' - used |= USED_MOD_SUIT - - if(P == H.wear_suit) - H.update_inv_wear_suit() - return - to_chat(user, "You can't modify [target]!") - - /obj/item/fluff/merchant_sallet_modkit //Travelling Merchant: Trav Noble. This is what they spawn in with name = "SG Helmet modkit" desc = "A modkit that can make most helmets look like a Shellguard Helmet." @@ -1321,16 +1212,16 @@ //////////// Sets //////////// // Fox P McCloud: Fox McCloud -/obj/item/clothing/suit/jacket/fluff/fox +/obj/item/clothing/suit/storage/fox name = "Aeronautics Jacket" desc = "An aviator styled jacket made from a peculiar material; this one seems very old." icon = 'icons/obj/custom_items.dmi' icon_state = "fox_jacket" item_state = "fox_jacket" - ignore_suitadjust = TRUE - actions_types = list() - adjust_flavour = null - sprite_sheets = null + allowed = list(/obj/item/flashlight, /obj/item/tank/emergency_oxygen, /obj/item/toy, /obj/item/storage/fancy/cigarettes, /obj/item/lighter, /obj/item/gun/projectile/automatic/pistol, /obj/item/gun/projectile/revolver, /obj/item/gun/projectile/revolver/detective) + body_parts_covered = UPPER_TORSO|LOWER_TORSO|ARMS + cold_protection = UPPER_TORSO|LOWER_TORSO|ARMS + min_cold_protection_temperature = FIRE_SUIT_MIN_TEMP_PROTECT /obj/item/clothing/under/fluff/fox name = "Aeronautics Jumpsuit" @@ -1341,6 +1232,12 @@ item_color = "fox_suit" displays_id = FALSE //still appears on examine; this is pure fluff. +/obj/item/clothing/suit/storage/fox/miljacket_desert + name = "rugged military jacket" + desc = "A rugged brown military jacket with a stylized 'A' embroidered on the back. It seems very old, yet is in near mint condition. Has a tag on the inside collar signed 'Fox McCloud'." + icon_state = "fox_coat" + item_color = "fox_coat" + /obj/item/toy/plushie/fluff/fox name = "orange fox plushie" desc = "A cute, soft, fuzzy, fluffy, and cuddly plushie. This has a small tag on it that is signed 'Fox McCloud'." @@ -1371,12 +1268,6 @@ /obj/item/toy/plushie/fluff/fox/ui_action_click() change_color() -/obj/item/clothing/suit/jacket/miljacket/desert/fox - name = "rugged military jacket" - desc = "A rugged brown military jacket with a stylized 'A' embroidered on the back. It seems very old, yet is in near mint condition. Has a tag on the inside collar signed 'Fox McCloud'." - icon = 'icons/obj/custom_items.dmi' - icon_state = "fox_coat" - item_color = "fox_coat" // TheFlagbearer: Willow Walker /obj/item/clothing/under/fluff/arachno_suit diff --git a/code/modules/events/alien_infestation.dm b/code/modules/events/alien_infestation.dm index 590ff374ad6..2d3cb8465c9 100644 --- a/code/modules/events/alien_infestation.dm +++ b/code/modules/events/alien_infestation.dm @@ -26,6 +26,7 @@ if(C) GLOB.respawnable_list -= C.client var/mob/living/carbon/alien/larva/new_xeno = new(vent.loc) + new_xeno.amount_grown += (0.75 * new_xeno.max_grown) //event spawned larva start off almost ready to evolve. new_xeno.key = C.key if(SSticker && SSticker.mode) SSticker.mode.xenos += new_xeno.mind diff --git a/code/modules/events/grid_check.dm b/code/modules/events/grid_check.dm index d8d1f46ad9b..8467c709f5e 100644 --- a/code/modules/events/grid_check.dm +++ b/code/modules/events/grid_check.dm @@ -1,6 +1,6 @@ /datum/event/grid_check //NOTE: Times are measured in master controller ticks! announceWhen = 5 - + /datum/event/grid_check/setup() endWhen = rand(30,120) @@ -12,7 +12,7 @@ if(!M.client || !is_station_level(T.z)) continue SEND_SOUND(M, S) - + /datum/event/grid_check/announce() event_announcement.Announce("Abnormal activity detected in [station_name()]'s powernet. As a precautionary measure, the station's power will be shut off for an indeterminate duration.", "Automated Grid Check", new_sound = 'sound/AI/poweroff.ogg') diff --git a/code/modules/events/headcrabs.dm b/code/modules/events/headcrabs.dm new file mode 100644 index 00000000000..3c02212a40f --- /dev/null +++ b/code/modules/events/headcrabs.dm @@ -0,0 +1,146 @@ +#define LOC_ATMOS_CONTROL 0 +#define LOC_FPMAINT 1 +#define LOC_FPMAINT2 2 +#define LOC_FSMAINT 3 +#define LOC_FSMAINT2 4 +#define LOC_ASMAINT 5 +#define LOC_ASMAINT2 6 +#define LOC_APMAINT 7 +#define LOC_MAINTCENTRAL 8 +#define LOC_FORE 9 +#define LOC_STARBOARD 10 +#define LOC_PORT 11 +#define LOC_AFT 12 +#define LOC_STORAGE 13 +#define LOC_DISPOSAL 14 +#define LOC_GENETICS 15 +#define LOC_ELECTRICAL 16 +#define LOC_ABANDONEDBAR 17 +#define LOC_ELECTRICAL_SHOP 18 +#define LOC_GAMBLING_DEN 19 + +#define HEADCRAB_NORMAL 0 +/*#define HEADCRAB_SPECIAL 1 +#define HEADCRAB_CLOWN 2 */ //Planned for the future + +/datum/event/headcrabs + announceWhen = 10 + endWhen = 11 + var/location + var/locstring + var/headcrab + +/datum/event/headcrabs/start() + + location = rand(0,19) + var/list/turf/simulated/floor/turfs = list() + var/spawn_area_type + switch(location) + if(LOC_ATMOS_CONTROL) + spawn_area_type = /area/maintenance/atmos_control + locstring = "Atmospherics Maintenance" + if(LOC_FPMAINT) + spawn_area_type = /area/maintenance/fpmaint + locstring = "EVA Maintenance" + if(LOC_FPMAINT2) + spawn_area_type = /area/maintenance/fpmaint2 + locstring = "Arrivals North Maintenance" + if(LOC_FSMAINT) + spawn_area_type = /area/maintenance/fsmaint + locstring = "Dormitory Maintenance" + if(LOC_FSMAINT2) + spawn_area_type = /area/maintenance/fsmaint2 + locstring = "Bar Maintenance" + if(LOC_ASMAINT) + spawn_area_type = /area/maintenance/asmaint + locstring = "Medbay Maintenance" + if(LOC_ASMAINT2) + spawn_area_type = /area/maintenance/asmaint2 + locstring = "Science Maintenance" + if(LOC_APMAINT) + spawn_area_type = /area/maintenance/apmaint + locstring = "Cargo Maintenance" + if(LOC_MAINTCENTRAL) + spawn_area_type = /area/maintenance/maintcentral + locstring = "Bridge Maintenance" + if(LOC_FORE) + spawn_area_type = /area/maintenance/fore + locstring = "Fore Maintenance" + if(LOC_STARBOARD) + spawn_area_type = /area/maintenance/starboard + locstring = "Starboard Maintenance" + if(LOC_PORT) + spawn_area_type = /area/maintenance/port + locstring = "Locker Room Maintenance" + if(LOC_AFT) + spawn_area_type = /area/maintenance/aft + locstring = "Engineering Maintenance" + if(LOC_STORAGE) + spawn_area_type = /area/maintenance/storage + locstring = "Atmospherics Maintenance" + if(LOC_DISPOSAL) + spawn_area_type = /area/maintenance/disposal + locstring = "Waste Disposal" + if(LOC_GENETICS) + spawn_area_type = /area/maintenance/genetics + locstring = "Genetics Maintenance" + if(LOC_ELECTRICAL) + spawn_area_type = /area/maintenance/electrical + locstring = "Electrical Maintenance" + if(LOC_ABANDONEDBAR) + spawn_area_type = /area/maintenance/abandonedbar + locstring = "Maintenance Bar" + if(LOC_ELECTRICAL_SHOP) + spawn_area_type = /area/maintenance/electrical_shop + locstring ="Electronics Den" + if(LOC_GAMBLING_DEN) + spawn_area_type = /area/maintenance/gambling_den + locstring = "Gambling Den" + for(var/areapath in typesof(spawn_area_type)) + var/area/A = locate(areapath) + for(var/turf/simulated/floor/F in A.contents) + if(turf_clear(F)) + turfs += F + + var/list/spawn_types = list() + var/max_number + headcrab = 0 //rand(0,x) for the future + switch(headcrab) //Switch is for the future + if(HEADCRAB_NORMAL) + spawn_types = list(/mob/living/simple_animal/hostile/headcrab) + max_number = 6 + + var/num = rand(2,max_number) + while(turfs.len > 0 && num > 0) + var/turf/simulated/floor/T = pick(turfs) + turfs.Remove(T) + num-- + var/spawn_type = pick(spawn_types) + new spawn_type(T) + + +/datum/event/headcrabs/announce() + event_announcement.Announce("Bioscans indicate that creatures have been breeding in [locstring]. Clear them out, before this starts to affect productivity", "Lifesign Alert") + +#undef LOC_ATMOS_CONTROL +#undef LOC_FPMAINT +#undef LOC_FPMAINT2 +#undef LOC_FSMAINT +#undef LOC_FSMAINT2 +#undef LOC_ASMAINT +#undef LOC_ASMAINT2 +#undef LOC_APMAINT +#undef LOC_MAINTCENTRAL +#undef LOC_FORE +#undef LOC_STARBOARD +#undef LOC_PORT +#undef LOC_AFT +#undef LOC_STORAGE +#undef LOC_DISPOSAL +#undef LOC_GENETICS +#undef LOC_ELECTRICAL +#undef LOC_ABANDONEDBAR +#undef LOC_ELECTRICAL_SHOP +#undef LOC_GAMBLING_DEN + +#undef HEADCRAB_NORMAL diff --git a/code/modules/food_and_drinks/food/foods/candy.dm b/code/modules/food_and_drinks/food/foods/candy.dm index fb5ea043839..299b60cc8fa 100644 --- a/code/modules/food_and_drinks/food/foods/candy.dm +++ b/code/modules/food_and_drinks/food/foods/candy.dm @@ -258,7 +258,7 @@ /obj/item/reagent_containers/food/snacks/candy/gummybear/wtf name = "gummy bear" desc = "A small bear. Wait... what?" - icon_state = "gbear_wtf" + icon_state = "gbear_rainbow" filling_color = "#60A584" list_reagents = list("sugar" = 10, "space_drugs" = 2) @@ -318,7 +318,7 @@ /obj/item/reagent_containers/food/snacks/candy/gummyworm/wtf name = "gummy worm" desc = "An edible worm. Did it just move?" - icon_state = "gworm_wtf" + icon_state = "gworm_rainbow" filling_color = "#60A584" list_reagents = list("sugar" = 10, "space_drugs" = 2) @@ -413,7 +413,7 @@ /obj/item/reagent_containers/food/snacks/candy/jellybean/wtf name = "jelly bean" desc = "A candy bean, guarenteed to not give you gas. You aren't sure what color it is." - icon_state = "jbean_wtf" + icon_state = "jbean_rainbow" filling_color = "#60A584" list_reagents = list("sugar" = 10, "space_drugs" = 2) diff --git a/code/modules/food_and_drinks/food/foods/meat.dm b/code/modules/food_and_drinks/food/foods/meat.dm index eb9569ad356..d19a88fcea8 100644 --- a/code/modules/food_and_drinks/food/foods/meat.dm +++ b/code/modules/food_and_drinks/food/foods/meat.dm @@ -152,7 +152,7 @@ /obj/item/reagent_containers/food/snacks/bacon name = "bacon" desc = "It looks crispy and tastes amazing! Mmm... Bacon." - icon_state = "bacon2" + icon_state = "bacon" list_reagents = list("nutriment" = 4, "porktonium" = 10, "msg" = 4) /obj/item/reagent_containers/food/snacks/telebacon @@ -168,8 +168,9 @@ /obj/item/reagent_containers/food/snacks/telebacon/On_Consume(mob/M, mob/user) if(!reagents.total_volume) - baconbeacon.loc = user + baconbeacon.forceMove(user) baconbeacon.digest_delay() + baconbeacon = null /obj/item/reagent_containers/food/snacks/meatball name = "meatball" diff --git a/code/modules/food_and_drinks/kitchen_machinery/microwave.dm b/code/modules/food_and_drinks/kitchen_machinery/microwave.dm index 446e919a4a4..c5cf20ce10f 100644 --- a/code/modules/food_and_drinks/kitchen_machinery/microwave.dm +++ b/code/modules/food_and_drinks/kitchen_machinery/microwave.dm @@ -11,6 +11,7 @@ broken_icon = "mwb" dirty_icon = "mwbloody" open_icon = "mw-o" + pass_flags = PASSTABLE // see code/modules/food/recipes_microwave.dm for recipes diff --git a/code/modules/hydroponics/gene_modder.dm b/code/modules/hydroponics/gene_modder.dm index a9511b00fcd..10e135f5fe6 100644 --- a/code/modules/hydroponics/gene_modder.dm +++ b/code/modules/hydroponics/gene_modder.dm @@ -2,6 +2,7 @@ name = "plant DNA manipulator" desc = "An advanced device designed to manipulate plant genetic makeup." icon = 'icons/obj/hydroponics/equipment.dmi' + pass_flags = PASSTABLE icon_state = "dnamod" density = 1 anchored = 1 diff --git a/code/modules/hydroponics/grown/cotton.dm b/code/modules/hydroponics/grown/cotton.dm new file mode 100644 index 00000000000..3fa4247f578 --- /dev/null +++ b/code/modules/hydroponics/grown/cotton.dm @@ -0,0 +1,79 @@ +/obj/item/seeds/cotton + name = "pack of cotton seeds" + desc = "A pack of seeds that'll grow into a cotton plant. Assistants make good free labor if neccesary." + icon_state = "seed-cotton" + species = "cotton" + plantname = "Cotton" + icon_harvest = "cotton-harvest" + product = /obj/item/grown/cotton + lifespan = 35 + endurance = 25 + maturation = 15 + production = 1 + yield = 2 + potency = 50 + growthstages = 3 + growing_icon = 'icons/obj/hydroponics/growing.dmi' + icon_dead = "cotton-dead" + mutatelist = list(/obj/item/seeds/cotton/durathread) + +/obj/item/grown/cotton + seed = /obj/item/seeds/cotton + name = "cotton bundle" + desc = "A fluffy bundle of cotton." + icon_state = "cotton" + force = 0 + throwforce = 0 + w_class = WEIGHT_CLASS_TINY + throw_speed = 2 + throw_range = 3 + attack_verb = list("pomfed") + var/cotton_type = /obj/item/stack/sheet/cotton + var/cotton_name = "raw cotton" + +/obj/item/grown/cotton/attack_self(mob/user) + user.show_message("You pull some [cotton_name] out of the [name]!", 1) + var/seed_modifier = 0 + if(seed) + seed_modifier = round(seed.potency / 25) + var/obj/item/stack/cotton = new cotton_type(user.loc, 1 + seed_modifier) + var/old_cotton_amount = cotton.amount + for(var/obj/item/stack/ST in user.loc) + if(ST != cotton && istype(ST, cotton_type) && ST.amount < ST.max_amount) + ST.attackby(cotton, user) + if(cotton.amount > old_cotton_amount) + to_chat(user, "You add the newly-formed [cotton_name] to the stack. It now contains [cotton.amount] [cotton_name].") + qdel(src) + +//reinforced mutated variant +/obj/item/seeds/cotton/durathread + name = "pack of durathread seeds" + desc = "A pack of seeds that'll grow into an extremely durable thread that could easily rival plasteel if woven properly." + icon_state = "seed-durathread" + species = "durathread" + plantname = "Durathread" + icon_harvest = "durathread-harvest" + product = /obj/item/grown/cotton/durathread + lifespan = 80 + endurance = 50 + maturation = 15 + production = 1 + yield = 2 + potency = 50 + growthstages = 3 + growing_icon = 'icons/obj/hydroponics/growing.dmi' + icon_dead = "cotton-dead" + +/obj/item/grown/cotton/durathread + seed = /obj/item/seeds/cotton/durathread + name = "durathread bundle" + desc = "A tough bundle of durathread, good luck unraveling this." + icon_state = "durathread" + force = 5 + throwforce = 5 + w_class = WEIGHT_CLASS_NORMAL + throw_speed = 2 + throw_range = 3 + attack_verb = list("bashed", "battered", "bludgeoned", "whacked") + cotton_type = /obj/item/stack/sheet/cotton/durathread + cotton_name = "raw durathread" \ No newline at end of file diff --git a/code/modules/hydroponics/grown/replicapod.dm b/code/modules/hydroponics/grown/replicapod.dm index c8145033545..3aaa8d87041 100644 --- a/code/modules/hydroponics/grown/replicapod.dm +++ b/code/modules/hydroponics/grown/replicapod.dm @@ -88,7 +88,7 @@ make_podman = 0 if(make_podman) //all conditions met! - var/mob/living/carbon/human/diona/podman = new /mob/living/carbon/human/diona(parent.loc) + var/mob/living/carbon/human/pod_diona/podman = new /mob/living/carbon/human/pod_diona(parent.loc) if(realName) podman.real_name = realName mind.transfer_to(podman) diff --git a/code/modules/hydroponics/hydroitemdefines.dm b/code/modules/hydroponics/hydroitemdefines.dm index 14080c62bba..899146f160d 100644 --- a/code/modules/hydroponics/hydroitemdefines.dm +++ b/code/modules/hydroponics/hydroitemdefines.dm @@ -72,6 +72,16 @@ attack_verb = list("slashed", "sliced", "cut", "clawed") hitsound = 'sound/weapons/bladeslice.ogg' +/obj/item/cultivator/rake + name = "rake" + icon_state = "rake" + w_class = WEIGHT_CLASS_NORMAL + attack_verb = list("slashed", "sliced", "bashed", "clawed") + hitsound = null + materials = null + flags = NONE + burn_state = FLAMMABLE + /obj/item/hatchet name = "hatchet" desc = "A very sharp axe blade upon a short fibremetal handle. It has a long history of chopping things, but now it is used for chopping wood." diff --git a/code/modules/karma/karma.dm b/code/modules/karma/karma.dm index 57063b0d743..ebcf10f7868 100644 --- a/code/modules/karma/karma.dm +++ b/code/modules/karma/karma.dm @@ -222,7 +222,7 @@ var/list/karma_spenders = list() Unlock Drask -- 30KP
      Unlock Vox -- 45KP
      Unlock Slime People -- 45KP
      - Unlock Plasmaman -- 100KP
      + Unlock Plasmaman -- 45KP
      "} if(2) // Karma Refunds diff --git a/code/modules/mining/abandonedcrates.dm b/code/modules/mining/abandonedcrates.dm index e96fd0e867b..3e4d4d143ec 100644 --- a/code/modules/mining/abandonedcrates.dm +++ b/code/modules/mining/abandonedcrates.dm @@ -40,9 +40,11 @@ if(21 to 25) for(var/i in 1 to 5) new /obj/item/poster/random_contraband(src) - if(26 to 35) + if(26 to 30) for(var/i in 1 to 3) new /obj/item/reagent_containers/glass/beaker/noreact(src) + if(31 to 35) + new /obj/item/seeds/firelemon(src) if(36 to 40) new /obj/item/melee/baton(src) if(41 to 45) @@ -109,7 +111,7 @@ if(90) new /obj/item/organ/internal/heart(src) if(91) - new /obj/item/soulstone(src) + new /obj/item/soulstone/anybody(src) if(92) new /obj/item/katana(src) if(93) diff --git a/code/modules/mining/coins.dm b/code/modules/mining/coins.dm deleted file mode 100644 index 70d920cd38f..00000000000 --- a/code/modules/mining/coins.dm +++ /dev/null @@ -1,153 +0,0 @@ -/*****************************Coin********************************/ - -/obj/item/coin - icon = 'icons/obj/economy.dmi' - name = "coin" - icon_state = "coin__heads" - flags = CONDUCT - force = 1 - throwforce = 2 - w_class = WEIGHT_CLASS_TINY - var/string_attached - var/list/sideslist = list("heads","tails") - var/cmineral = null - var/cooldown = 0 - var/credits = 10 - -/obj/item/coin/New() - pixel_x = rand(0,16)-8 - pixel_y = rand(0,8)-8 - - icon_state = "coin_[cmineral]_[sideslist[1]]" - if(cmineral) - name = "[cmineral] coin" - -/obj/item/coin/gold - cmineral = "gold" - icon_state = "coin_gold_heads" - materials = list(MAT_GOLD = 400) - credits = 160 - -/obj/item/coin/silver - cmineral = "silver" - icon_state = "coin_silver_heads" - materials = list(MAT_SILVER = 400) - credits = 40 - -/obj/item/coin/diamond - cmineral = "diamond" - icon_state = "coin_diamond_heads" - materials = list(MAT_DIAMOND = 400) - credits = 120 - -/obj/item/coin/iron - cmineral = "iron" - icon_state = "coin_iron_heads" - materials = list(MAT_METAL = 400) - credits = 20 - -/obj/item/coin/plasma - cmineral = "plasma" - icon_state = "coin_plasma_heads" - materials = list(MAT_PLASMA = 400) - credits = 80 - -/obj/item/coin/uranium - cmineral = "uranium" - icon_state = "coin_uranium_heads" - materials = list(MAT_URANIUM = 400) - credits = 160 - -/obj/item/coin/clown - cmineral = "bananium" - icon_state = "coin_bananium_heads" - materials = list(MAT_BANANIUM = 400) - credits = 600 //makes the clown cri - -/obj/item/coin/mime - cmineral = "tranquillite" - icon_state = "coin_tranquillite_heads" - materials = list(MAT_TRANQUILLITE = 400) - credits = 600 //makes the mime cri - -/obj/item/coin/adamantine - cmineral = "adamantine" - icon_state = "coin_adamantine_heads" - credits = 400 - -/obj/item/coin/mythril - cmineral = "mythril" - icon_state = "coin_mythril_heads" - credits = 400 - -/obj/item/coin/twoheaded - cmineral = "iron" - icon_state = "coin_iron_heads" - desc = "Hey, this coin's the same on both sides!" - sideslist = list("heads") - credits = 20 - -/obj/item/coin/antagtoken - name = "antag token" - icon_state = "coin_valid_valid" - cmineral = "valid" - desc = "A novelty coin that helps the heart know what hard evidence cannot prove." - sideslist = list("valid", "salad") - credits = 20 - -/obj/item/coin/antagtoken/syndicate - name = "syndicate coin" - credits = 160 - -/obj/item/coin/attackby(obj/item/W as obj, mob/user as mob, params) - if(istype(W, /obj/item/stack/cable_coil)) - var/obj/item/stack/cable_coil/CC = W - if(string_attached) - to_chat(user, "There already is a string attached to this coin.") - return - - if(CC.use(1)) - overlays += image('icons/obj/economy.dmi',"coin_string_overlay") - string_attached = 1 - to_chat(user, "You attach a string to the coin.") - else - to_chat(user, "You need one length of cable to attach a string to the coin.") - return - - else if(istype(W,/obj/item/wirecutters)) - if(!string_attached) - ..() - return - - var/obj/item/stack/cable_coil/CC = new/obj/item/stack/cable_coil(user.loc) - CC.amount = 1 - CC.update_icon() - overlays = list() - string_attached = null - to_chat(user, "You detach the string from the coin.") - else if(istype(W,/obj/item/weldingtool)) - var/obj/item/weldingtool/WT = W - if(WT.welding && WT.remove_fuel(0, user)) - var/typelist = list("iron" = /obj/item/clothing/gloves/ring, - "silver" = /obj/item/clothing/gloves/ring/silver, - "gold" = /obj/item/clothing/gloves/ring/gold, - "plasma" = /obj/item/clothing/gloves/ring/plasma, - "uranium" = /obj/item/clothing/gloves/ring/uranium) - var/typekey = typelist[cmineral] - if(ispath(typekey)) - to_chat(user, "You make [src] into a ring.") - new typekey(get_turf(loc)) - qdel(src) - else ..() - -/obj/item/coin/attack_self(mob/user as mob) - if(cooldown < world.time - 15) - var/coinflip = pick(sideslist) - cooldown = world.time - flick("coin_[cmineral]_flip", src) - icon_state = "coin_[cmineral]_[coinflip]" - playsound(user.loc, 'sound/items/coinflip.ogg', 50, 1) - if(do_after(user, 15, target = src)) - user.visible_message("[user] has flipped [src]. It lands on [coinflip].", \ - "You flip [src]. It lands on [coinflip].", \ - "You hear the clattering of loose change.") diff --git a/code/modules/mining/equipment/explorer_gear.dm b/code/modules/mining/equipment/explorer_gear.dm new file mode 100644 index 00000000000..566694d480d --- /dev/null +++ b/code/modules/mining/equipment/explorer_gear.dm @@ -0,0 +1,97 @@ +/****************Explorer's Suit and Mask****************/ +/obj/item/clothing/suit/hooded/explorer + name = "explorer suit" + desc = "An armoured suit for exploring harsh environments." + icon_state = "explorer" + item_state = "explorer" + body_parts_covered = UPPER_TORSO|LOWER_TORSO|LEGS|ARMS + min_cold_protection_temperature = FIRE_SUIT_MIN_TEMP_PROTECT + cold_protection = UPPER_TORSO|LOWER_TORSO|LEGS|ARMS + max_heat_protection_temperature = FIRE_SUIT_MAX_TEMP_PROTECT + heat_protection = UPPER_TORSO|LOWER_TORSO|LEGS|ARMS + hoodtype = /obj/item/clothing/head/hooded/explorer + armor = list("melee" = 30, "bullet" = 20, "laser" = 20, "energy" = 20, "bomb" = 50, "bio" = 100, "rad" = 50, "fire" = 50, "acid" = 50) + allowed = list(/obj/item/flashlight, /obj/item/tank, /obj/item/resonator, /obj/item/mining_scanner, /obj/item/t_scanner/adv_mining_scanner, /obj/item/gun/energy/kinetic_accelerator, /obj/item/pickaxe) + resistance_flags = FIRE_PROOF + hide_tail_by_species = list("Vox" , "Vulpkanin" , "Unathi" , "Tajaran") + + sprite_sheets = list( + "Vox" = 'icons/mob/species/vox/suit.dmi', + "Drask" = 'icons/mob/species/drask/suit.dmi', + "Tajaran" = 'icons/mob/species/tajaran/suit.dmi', + "Unathi" = 'icons/mob/species/unathi/suit.dmi', + "Vulpkanin" = 'icons/mob/species/vulpkanin/suit.dmi' + ) + +/obj/item/clothing/head/hooded/explorer + name = "explorer hood" + desc = "An armoured hood for exploring harsh environments." + icon_state = "explorer" + item_state = "explorer" + body_parts_covered = HEAD + flags = BLOCKHAIR | NODROP + flags_cover = HEADCOVERSEYES + min_cold_protection_temperature = FIRE_HELM_MIN_TEMP_PROTECT + max_heat_protection_temperature = FIRE_HELM_MAX_TEMP_PROTECT + armor = list("melee" = 30, "bullet" = 20, "laser" = 20, "energy" = 20, "bomb" = 50, "bio" = 100, "rad" = 50, "fire" = 50, "acid" = 50) + resistance_flags = FIRE_PROOF + + sprite_sheets = list( + "Vox" = 'icons/mob/species/vox/head.dmi', + "Drask" = 'icons/mob/species/drask/head.dmi', + "Grey" = 'icons/mob/species/grey/head.dmi', + "Skrell" = 'icons/mob/species/skrell/head.dmi' + ) + +/obj/item/clothing/suit/space/hostile_environment + name = "H.E.C.K. suit" + desc = "Hostile Environment Cross-Kinetic Suit: A suit designed to withstand the wide variety of hazards from Lavaland. It wasn't enough for its last owner." + icon_state = "hostile_env" + item_state = "hostile_env" + flags = THICKMATERIAL //not spaceproof + max_heat_protection_temperature = FIRE_IMMUNITY_MAX_TEMP_PROTECT + burn_state = FIRE_PROOF | LAVA_PROOF + slowdown = 0 + armor = list(melee = 70, bullet = 40, laser = 10, energy = 10, bomb = 50, bio = 100, rad = 100) + allowed = list(/obj/item/flashlight, /obj/item/tank, /obj/item/resonator, /obj/item/mining_scanner, /obj/item/t_scanner/adv_mining_scanner, /obj/item/gun/energy/kinetic_accelerator, /obj/item/pickaxe) + +/obj/item/clothing/suit/space/hostile_environment/New() + ..() + AddComponent(/datum/component/spraycan_paintable) + START_PROCESSING(SSobj, src) + +/obj/item/clothing/suit/space/hostile_environment/Destroy() + STOP_PROCESSING(SSobj, src) + return ..() + +/obj/item/clothing/suit/space/hostile_environment/process() + var/mob/living/carbon/C = loc + if(istype(C) && prob(2)) //cursed by bubblegum + if(prob(15)) + new /obj/effect/hallucination/oh_yeah(get_turf(C), C) + to_chat(C, "[pick("I AM IMMORTAL.","I SHALL TAKE BACK WHAT'S MINE.","I SEE YOU.","YOU CANNOT ESCAPE ME FOREVER.","DEATH CANNOT HOLD ME.")]") + else + to_chat(C, "[pick("You hear faint whispers.","You smell ash.","You feel hot.","You hear a roar in the distance.")]") + +/obj/item/clothing/head/helmet/space/hostile_environment + name = "H.E.C.K. helmet" + desc = "Hostile Environiment Cross-Kinetic Helmet: A helmet designed to withstand the wide variety of hazards from Lavaland. It wasn't enough for its last owner." + icon_state = "hostile_env" + item_state = "hostile_env" + w_class = WEIGHT_CLASS_NORMAL + max_heat_protection_temperature = FIRE_IMMUNITY_MAX_TEMP_PROTECT + flags = THICKMATERIAL // no space protection + armor = list(melee = 70, bullet = 40, laser = 10, energy = 10, bomb = 50, bio = 100, rad = 100) + burn_state = FIRE_PROOF | LAVA_PROOF + +/obj/item/clothing/head/helmet/space/hostile_environment/New() + ..() + AddComponent(/datum/component/spraycan_paintable) + update_icon() + +/obj/item/clothing/head/helmet/space/hostile_environment/update_icon() + ..() + cut_overlays() + var/mutable_appearance/glass_overlay = mutable_appearance(icon, "hostile_env_glass") + glass_overlay.appearance_flags = RESET_COLOR + add_overlay(glass_overlay) \ No newline at end of file diff --git a/code/modules/mining/equipment/kinetic_crusher.dm b/code/modules/mining/equipment/kinetic_crusher.dm new file mode 100644 index 00000000000..d340e6069cc --- /dev/null +++ b/code/modules/mining/equipment/kinetic_crusher.dm @@ -0,0 +1,439 @@ +/*********************Mining Hammer****************/ +/obj/item/twohanded/kinetic_crusher + icon = 'icons/obj/mining.dmi' + icon_state = "crusher" + item_state = "crusher0" + name = "proto-kinetic crusher" + desc = "An early design of the proto-kinetic accelerator, it is little more than a combination of various mining tools cobbled together, forming a high-tech club. \ + While it is an effective mining tool, it did little to aid any but the most skilled and/or suicidal miners against local fauna." + force = 0 //You can't hit stuff unless wielded + w_class = WEIGHT_CLASS_BULKY + slot_flags = SLOT_BACK + force_unwielded = 0 + force_wielded = 20 + throwforce = 5 + throw_speed = 4 + armour_penetration = 10 + materials = list(MAT_METAL = 1150, MAT_GLASS = 2075) + hitsound = 'sound/weapons/bladeslice.ogg' + attack_verb = list("smashed", "crushed", "cleaved", "chopped", "pulped") + sharp = TRUE + actions_types = list(/datum/action/item_action/toggle_light) + var/list/trophies = list() + var/charged = TRUE + var/charge_time = 15 + var/detonation_damage = 50 + var/backstab_bonus = 30 + var/light_on = FALSE + var/brightness_on = 5 + +/obj/item/twohanded/kinetic_crusher/Destroy() + QDEL_LIST(trophies) + return ..() + +/obj/item/twohanded/kinetic_crusher/examine(mob/living/user) + ..() + to_chat(user, "Mark a large creature with the destabilizing force, then hit them in melee to do [force + detonation_damage] damage.") + to_chat(user, "Does [force + detonation_damage + backstab_bonus] damage if the target is backstabbed, instead of [force + detonation_damage].") + for(var/t in trophies) + var/obj/item/crusher_trophy/T = t + to_chat(user, "It has \a [T] attached, which causes [T.effect_desc()].") + +/obj/item/twohanded/kinetic_crusher/attackby(obj/item/I, mob/living/user) + if(iscrowbar(I)) + if(LAZYLEN(trophies)) + to_chat(user, "You remove [src]'s trophies.") + playsound(loc, I.usesound, 100, 1) + for(var/t in trophies) + var/obj/item/crusher_trophy/T = t + T.remove_from(src, user) + else + to_chat(user, "There are no trophies on [src].") + else if(istype(I, /obj/item/crusher_trophy)) + var/obj/item/crusher_trophy/T = I + T.add_to(src, user) + else + return ..() + +/obj/item/twohanded/kinetic_crusher/attack(mob/living/target, mob/living/carbon/user) + if(!wielded) + to_chat(user, "[src] is too heavy to use with one hand. You fumble and drop everything.") + user.drop_r_hand() + user.drop_l_hand() + return + var/datum/status_effect/crusher_damage/C = target.has_status_effect(STATUS_EFFECT_CRUSHERDAMAGETRACKING) + var/target_health = target.health + ..() + for(var/t in trophies) + if(!QDELETED(target)) + var/obj/item/crusher_trophy/T = t + T.on_melee_hit(target, user) + if(!QDELETED(C) && !QDELETED(target)) + C.total_damage += target_health - target.health //we did some damage, but let's not assume how much we did + +/obj/item/twohanded/kinetic_crusher/afterattack(atom/target, mob/living/user, proximity_flag, clickparams) + . = ..() + if(!wielded) + return + if(!proximity_flag && charged)//Mark a target, or mine a tile. + var/turf/proj_turf = user.loc + if(!isturf(proj_turf)) + return + var/obj/item/projectile/destabilizer/D = new /obj/item/projectile/destabilizer(proj_turf) + for(var/t in trophies) + var/obj/item/crusher_trophy/T = t + T.on_projectile_fire(D, user) + D.preparePixelProjectile(target, get_turf(target), user, clickparams) + D.firer = user + D.hammer_synced = src + playsound(user, 'sound/weapons/plasma_cutter.ogg', 100, 1) + D.fire() + charged = FALSE + update_icon() + addtimer(CALLBACK(src, .proc/Recharge), charge_time) + return + if(proximity_flag && isliving(target)) + var/mob/living/L = target + var/datum/status_effect/crusher_mark/CM = L.has_status_effect(STATUS_EFFECT_CRUSHERMARK) + if(!CM || CM.hammer_synced != src || !L.remove_status_effect(STATUS_EFFECT_CRUSHERMARK)) + return + var/datum/status_effect/crusher_damage/C = L.has_status_effect(STATUS_EFFECT_CRUSHERDAMAGETRACKING) + var/target_health = L.health + for(var/t in trophies) + var/obj/item/crusher_trophy/T = t + T.on_mark_detonation(target, user) + if(!QDELETED(L)) + if(!QDELETED(C)) + C.total_damage += target_health - L.health //we did some damage, but let's not assume how much we did + new /obj/effect/temp_visual/kinetic_blast(get_turf(L)) + var/backstab_dir = get_dir(user, L) + var/def_check = L.getarmor(type = "bomb") + if((user.dir & backstab_dir) && (L.dir & backstab_dir)) + if(!QDELETED(C)) + C.total_damage += detonation_damage + backstab_bonus //cheat a little and add the total before killing it, so certain mobs don't have much lower chances of giving an item + L.apply_damage(detonation_damage + backstab_bonus, BRUTE, blocked = def_check) + playsound(user, 'sound/weapons/kenetic_accel.ogg', 100, 1) //Seriously who spelled it wrong + else + if(!QDELETED(C)) + C.total_damage += detonation_damage + L.apply_damage(detonation_damage, BRUTE, blocked = def_check) + +/obj/item/twohanded/kinetic_crusher/proc/Recharge() + if(!charged) + charged = TRUE + update_icon() + playsound(src.loc, 'sound/weapons/kenetic_reload.ogg', 60, 1) + +/obj/item/twohanded/kinetic_crusher/ui_action_click(mob/user, actiontype) + light_on = !light_on + playsound(user, 'sound/weapons/empty.ogg', 100, TRUE) + update_brightness(user) + update_icon() + +/obj/item/twohanded/kinetic_crusher/proc/update_brightness(mob/user = null) + if(light_on) + set_light(brightness_on) + else + set_light(0) + +/obj/item/twohanded/kinetic_crusher/update_icon() + ..() + cut_overlays() + if(!charged) + add_overlay("[icon_state]_uncharged") + if(light_on) + add_overlay("[icon_state]_lit") + spawn(1) + for(var/X in actions) + var/datum/action/A = X + A.UpdateButtonIcon() + item_state = "crusher[wielded]" + +//destablizing force +/obj/item/projectile/destabilizer + name = "destabilizing force" + icon_state = "pulse1" + nodamage = TRUE + damage = 0 //We're just here to mark people. This is still a melee weapon. + damage_type = BRUTE + flag = "bomb" + range = 6 + log_override = TRUE + var/obj/item/twohanded/kinetic_crusher/hammer_synced + +/obj/item/projectile/destabilizer/Destroy() + hammer_synced = null + return ..() + +/obj/item/projectile/destabilizer/on_hit(atom/target, blocked = FALSE) + if(isliving(target)) + var/mob/living/L = target + var/had_effect = (L.has_status_effect(STATUS_EFFECT_CRUSHERMARK)) //used as a boolean + var/datum/status_effect/crusher_mark/CM = L.apply_status_effect(STATUS_EFFECT_CRUSHERMARK, hammer_synced) + if(hammer_synced) + for(var/t in hammer_synced.trophies) + var/obj/item/crusher_trophy/T = t + T.on_mark_application(target, CM, had_effect) + var/target_turf = get_turf(target) + if(ismineralturf(target_turf)) + var/turf/simulated/mineral/M = target_turf + new /obj/effect/temp_visual/kinetic_blast(M) + M.gets_drilled(firer) + ..() + +//trophies +/obj/item/crusher_trophy + name = "tail spike" + desc = "A strange spike with no usage." + icon = 'icons/obj/lavaland/artefacts.dmi' + icon_state = "tail_spike" + var/bonus_value = 10 //if it has a bonus effect, this is how much that effect is + var/denied_type = /obj/item/crusher_trophy + +/obj/item/crusher_trophy/examine(mob/living/user) + ..() + to_chat(user, "Causes [effect_desc()] when attached to a kinetic crusher.") + +/obj/item/crusher_trophy/proc/effect_desc() + return "errors" + +/obj/item/crusher_trophy/attackby(obj/item/A, mob/living/user) + if(istype(A, /obj/item/twohanded/kinetic_crusher)) + add_to(A, user) + else + ..() + +/obj/item/crusher_trophy/proc/add_to(obj/item/twohanded/kinetic_crusher/H, mob/living/user) + for(var/t in H.trophies) + var/obj/item/crusher_trophy/T = t + if(istype(T, denied_type) || istype(src, T.denied_type)) + to_chat(user, "You can't seem to attach [src] to [H]. Maybe remove a few trophies?") + return FALSE + if(!user.unEquip(src)) + return + forceMove(H) + H.trophies += src + to_chat(user, "You attach [src] to [H].") + return TRUE + +/obj/item/crusher_trophy/proc/remove_from(obj/item/twohanded/kinetic_crusher/H, mob/living/user) + forceMove(get_turf(H)) + H.trophies -= src + return TRUE + +/obj/item/crusher_trophy/proc/on_melee_hit(mob/living/target, mob/living/user) //the target and the user + +/obj/item/crusher_trophy/proc/on_projectile_fire(obj/item/projectile/destabilizer/marker, mob/living/user) //the projectile fired and the user + +/obj/item/crusher_trophy/proc/on_mark_application(mob/living/target, datum/status_effect/crusher_mark/mark, had_mark) //the target, the mark applied, and if the target had a mark before + +/obj/item/crusher_trophy/proc/on_mark_detonation(mob/living/target, mob/living/user) //the target and the user + +//goliath +/obj/item/crusher_trophy/goliath_tentacle + name = "goliath tentacle" + desc = "A sliced-off goliath tentacle. Suitable as a trophy for a kinetic crusher." + icon_state = "goliath_tentacle" + denied_type = /obj/item/crusher_trophy/goliath_tentacle + bonus_value = 2 + var/missing_health_ratio = 0.1 + var/missing_health_desc = 10 + +/obj/item/crusher_trophy/goliath_tentacle/effect_desc() + return "mark detonation to do [bonus_value] more damage for every [missing_health_desc] health you are missing" + +/obj/item/crusher_trophy/goliath_tentacle/on_mark_detonation(mob/living/target, mob/living/user) + var/missing_health = user.health - user.maxHealth + missing_health *= missing_health_ratio //bonus is active at all times, even if you're above 90 health + missing_health *= bonus_value //multiply the remaining amount by bonus_value + if(missing_health > 0) + target.adjustBruteLoss(missing_health) //and do that much damage + +//watcher +/obj/item/crusher_trophy/watcher_wing + name = "watcher wing" + desc = "A wing ripped from a watcher. Suitable as a trophy for a kinetic crusher." + icon_state = "watcher_wing" + denied_type = /obj/item/crusher_trophy/watcher_wing + bonus_value = 5 + +/obj/item/crusher_trophy/watcher_wing/effect_desc() + return "mark detonation to prevent certain creatures from using certain attacks for [bonus_value*0.1] second\s" + +/obj/item/crusher_trophy/watcher_wing/on_mark_detonation(mob/living/target, mob/living/user) + if(ishostile(target)) + var/mob/living/simple_animal/hostile/H = target + if(H.ranged) //briefly delay ranged attacks + if(H.ranged_cooldown >= world.time) + H.ranged_cooldown += bonus_value + else + H.ranged_cooldown = bonus_value + world.time + +//magmawing watcher +/obj/item/crusher_trophy/blaster_tubes/magma_wing + name = "magmawing watcher wing" + desc = "A still-searing wing from a magmawing watcher. Suitable as a trophy for a kinetic crusher." + icon_state = "magma_wing" + gender = NEUTER + bonus_value = 5 + +/obj/item/crusher_trophy/blaster_tubes/magma_wing/effect_desc() + return "mark detonation to make the next destabilizer shot deal [bonus_value] damage" + +/obj/item/crusher_trophy/blaster_tubes/magma_wing/on_projectile_fire(obj/item/projectile/destabilizer/marker, mob/living/user) + if(deadly_shot) + marker.name = "heated [marker.name]" + marker.icon_state = "lava" + marker.damage = bonus_value + marker.nodamage = FALSE + deadly_shot = FALSE + +//icewing watcher +/obj/item/crusher_trophy/watcher_wing/ice_wing + name = "icewing watcher wing" + desc = "A carefully preserved frozen wing from an icewing watcher. Suitable as a trophy for a kinetic crusher." + icon_state = "ice_wing" + bonus_value = 8 + +//legion +/obj/item/crusher_trophy/legion_skull + name = "legion skull" + desc = "A dead and lifeless legion skull. Suitable as a trophy for a kinetic crusher." + icon_state = "legion_skull" + denied_type = /obj/item/crusher_trophy/legion_skull + bonus_value = 3 + +/obj/item/crusher_trophy/legion_skull/effect_desc() + return "a kinetic crusher to recharge [bonus_value*0.1] second\s faster" + +/obj/item/crusher_trophy/legion_skull/add_to(obj/item/twohanded/kinetic_crusher/H, mob/living/user) + . = ..() + if(.) + H.charge_time -= bonus_value + +/obj/item/crusher_trophy/legion_skull/remove_from(obj/item/twohanded/kinetic_crusher/H, mob/living/user) + . = ..() + if(.) + H.charge_time += bonus_value + +//blood-drunk hunter +/obj/item/crusher_trophy/miner_eye + name = "eye of a blood-drunk hunter" + desc = "Its pupil is collapsed and turned to mush. Suitable as a trophy for a kinetic crusher." + icon_state = "hunter_eye" + denied_type = /obj/item/crusher_trophy/miner_eye + +/obj/item/crusher_trophy/miner_eye/effect_desc() + return "mark detonation to grant stun immunity and 90% damage reduction for 1 second" + +/obj/item/crusher_trophy/miner_eye/on_mark_detonation(mob/living/target, mob/living/user) + user.apply_status_effect(STATUS_EFFECT_BLOODDRUNK) + +//ash drake +/obj/item/crusher_trophy/tail_spike + desc = "A spike taken from an ash drake's tail. Suitable as a trophy for a kinetic crusher." + denied_type = /obj/item/crusher_trophy/tail_spike + bonus_value = 5 + +/obj/item/crusher_trophy/tail_spike/effect_desc() + return "mark detonation to do [bonus_value] damage to nearby creatures and push them back" + +/obj/item/crusher_trophy/tail_spike/on_mark_detonation(mob/living/target, mob/living/user) + for(var/mob/living/L in oview(2, user)) + if(L.stat == DEAD) + continue + playsound(L, 'sound/magic/fireball.ogg', 20, 1) + new /obj/effect/temp_visual/fire(L.loc) + addtimer(CALLBACK(src, .proc/pushback, L, user), 1) //no free backstabs, we push AFTER module stuff is done + L.adjustFireLoss(bonus_value) + +/obj/item/crusher_trophy/tail_spike/proc/pushback(mob/living/target, mob/living/user) + if(!QDELETED(target) && !QDELETED(user) && (!target.anchored || ismegafauna(target))) //megafauna will always be pushed + step(target, get_dir(user, target)) + +//bubblegum +/obj/item/crusher_trophy/demon_claws + name = "demon claws" + desc = "A set of blood-drenched claws from a massive demon's hand. Suitable as a trophy for a kinetic crusher." + icon_state = "demon_claws" + gender = PLURAL + denied_type = /obj/item/crusher_trophy/demon_claws + bonus_value = 10 + var/static/list/damage_heal_order = list(BRUTE, BURN, OXY) + +/obj/item/crusher_trophy/demon_claws/effect_desc() + return "melee hits to do [bonus_value * 0.2] more damage and heal you for [bonus_value * 0.1], with 5X effect on mark detonation" + +/obj/item/crusher_trophy/demon_claws/add_to(obj/item/twohanded/kinetic_crusher/H, mob/living/user) + . = ..() + if(.) + H.force += bonus_value * 0.2 + H.force_unwielded += bonus_value * 0.2 + H.force_wielded += bonus_value * 0.2 + H.detonation_damage += bonus_value * 0.8 + +/obj/item/crusher_trophy/demon_claws/remove_from(obj/item/twohanded/kinetic_crusher/H, mob/living/user) + . = ..() + if(.) + H.force -= bonus_value * 0.2 + H.force_unwielded -= bonus_value * 0.2 + H.force_wielded -= bonus_value * 0.2 + H.detonation_damage -= bonus_value * 0.8 + +/obj/item/crusher_trophy/demon_claws/on_melee_hit(mob/living/target, mob/living/user) + user.heal_ordered_damage(bonus_value * 0.1, damage_heal_order) + +/obj/item/crusher_trophy/demon_claws/on_mark_detonation(mob/living/target, mob/living/user) + user.heal_ordered_damage(bonus_value * 0.4, damage_heal_order) + +//colossus +/obj/item/crusher_trophy/blaster_tubes + name = "blaster tubes" + desc = "The blaster tubes from a colossus's arm. Suitable as a trophy for a kinetic crusher." + icon_state = "blaster_tubes" + gender = PLURAL + denied_type = /obj/item/crusher_trophy/blaster_tubes + bonus_value = 15 + var/deadly_shot = FALSE + +/obj/item/crusher_trophy/blaster_tubes/effect_desc() + return "mark detonation to make the next destabilizer shot deal [bonus_value] damage but move slower" + +/obj/item/crusher_trophy/blaster_tubes/on_projectile_fire(obj/item/projectile/destabilizer/marker, mob/living/user) + if(deadly_shot) + marker.name = "deadly [marker.name]" + marker.icon_state = "chronobolt" + marker.damage = bonus_value + marker.nodamage = FALSE + marker.speed = 2 + deadly_shot = FALSE + +/obj/item/crusher_trophy/blaster_tubes/on_mark_detonation(mob/living/target, mob/living/user) + deadly_shot = TRUE + addtimer(CALLBACK(src, .proc/reset_deadly_shot), 300, TIMER_UNIQUE|TIMER_OVERRIDE) + +/obj/item/crusher_trophy/blaster_tubes/proc/reset_deadly_shot() + deadly_shot = FALSE + +//hierophant +/obj/item/crusher_trophy/vortex_talisman + name = "vortex talisman" + desc = "A glowing trinket that was originally the Hierophant's beacon. Suitable as a trophy for a kinetic crusher." + icon_state = "vortex_talisman" + denied_type = /obj/item/crusher_trophy/vortex_talisman + +/obj/item/crusher_trophy/vortex_talisman/effect_desc() + return "mark detonation to create a barrier you can pass" + +/obj/item/crusher_trophy/vortex_talisman/on_mark_detonation(mob/living/target, mob/living/user) + var/turf/T = get_turf(user) + new /obj/effect/temp_visual/hierophant/wall/crusher(T, user) //a wall only you can pass! + var/turf/otherT = get_step(T, turn(user.dir, 90)) + if(otherT) + new /obj/effect/temp_visual/hierophant/wall/crusher(otherT, user) + otherT = get_step(T, turn(user.dir, -90)) + if(otherT) + new /obj/effect/temp_visual/hierophant/wall/crusher(otherT, user) + +/obj/effect/temp_visual/hierophant/wall/crusher + duration = 75 \ No newline at end of file diff --git a/code/modules/mining/equipment/lazarus_injector.dm b/code/modules/mining/equipment/lazarus_injector.dm new file mode 100644 index 00000000000..0f174ff748f --- /dev/null +++ b/code/modules/mining/equipment/lazarus_injector.dm @@ -0,0 +1,122 @@ +/**********************Lazarus Injector**********************/ +/obj/item/lazarus_injector + name = "lazarus injector" + desc = "An injector with a cocktail of nanomachines and chemicals, this device can seemingly raise animals from the dead, making them become friendly to the user. Unfortunately, the process is useless on higher forms of life and incredibly costly, so these were hidden in storage until an executive thought they'd be great motivation for some of their employees." + icon = 'icons/obj/hypo.dmi' + icon_state = "lazarus_hypo" + item_state = "hypo" + origin_tech = "biotech=4;magnets=6" + throwforce = 0 + w_class = WEIGHT_CLASS_SMALL + throw_speed = 3 + throw_range = 5 + var/loaded = 1 + var/malfunctioning = 0 + var/revive_type = SENTIENCE_ORGANIC //So you can't revive boss monsters or robots with it + +/obj/item/lazarus_injector/afterattack(atom/target, mob/user, proximity_flag) + if(!loaded) + return + if(istype(target, /mob/living) && proximity_flag) + if(istype(target, /mob/living/simple_animal)) + var/mob/living/simple_animal/M = target + if(M.sentience_type != revive_type) + to_chat(user, "[src] does not work on this sort of creature.") + return + if(M.stat == DEAD) + M.faction = list("neutral") + M.revive() + M.can_collar = 1 + if(istype(target, /mob/living/simple_animal/hostile)) + var/mob/living/simple_animal/hostile/H = M + if(malfunctioning) + H.faction |= list("lazarus", "\ref[user]") + H.robust_searching = 1 + H.friends += user + H.attack_same = 1 + log_game("[user] has revived hostile mob [target] with a malfunctioning lazarus injector") + else + H.attack_same = 0 + loaded = 0 + user.visible_message("[user] injects [M] with [src], reviving it.") + playsound(src,'sound/effects/refill.ogg',50,1) + icon_state = "lazarus_empty" + return + else + to_chat(user, "[src] is only effective on the dead.") + return + else + to_chat(user, "[src] is only effective on lesser beings.") + return + +/obj/item/lazarus_injector/emag_act(mob/user) + if(!malfunctioning) + malfunctioning = 1 + to_chat(user, "You override [src]'s safety protocols.") + +/obj/item/lazarus_injector/emp_act() + if(!malfunctioning) + malfunctioning = 1 + +/obj/item/lazarus_injector/examine(mob/user) + ..(user) + if(!loaded) + to_chat(user, "[src] is empty.") + if(malfunctioning) + to_chat(user, "The display on [src] seems to be flickering.") + +/*********************Mob Capsule*************************/ + +/obj/item/mobcapsule + name = "lazarus capsule" + desc = "It allows you to store and deploy lazarus-injected creatures easier." + icon = 'icons/obj/mobcap.dmi' + icon_state = "mobcap0" + w_class = WEIGHT_CLASS_TINY + throw_range = 7 + var/mob/living/simple_animal/captured = null + var/colorindex = 0 + var/capture_type = SENTIENCE_ORGANIC //So you can't capture boss monsters or robots with it + +/obj/item/mobcapsule/Destroy() + if(captured) + captured.ghostize() + QDEL_NULL(captured) + return ..() + +/obj/item/mobcapsule/attack(mob/living/simple_animal/S, mob/user, prox_flag) + if(istype(S) && S.sentience_type == capture_type) + capture(S, user) + return TRUE + return ..() + +/obj/item/mobcapsule/proc/capture(mob/living/simple_animal/S, mob/living/M) + if(captured) + to_chat(M, "Capture failed!: The capsule already has a mob registered to it!") + else + if("neutral" in S.faction) + S.forceMove(src) + S.name = "[M.name]'s [initial(S.name)]" + S.cancel_camera() + name = "Lazarus Capsule: [initial(S.name)]" + to_chat(M, "You placed a [S.name] inside the Lazarus Capsule!") + captured = S + else + to_chat(M, "You can't capture that mob!") + +/obj/item/mobcapsule/throw_impact(atom/A, mob/user) + ..() + if(captured) + dump_contents(user) + +/obj/item/mobcapsule/proc/dump_contents(mob/user) + if(captured) + captured.forceMove(get_turf(src)) + captured = null + +/obj/item/mobcapsule/attack_self(mob/user) + colorindex += 1 + if(colorindex >= 6) + colorindex = 0 + icon_state = "mobcap[colorindex]" + update_icon() \ No newline at end of file diff --git a/code/modules/mining/equipment/mineral_scanner.dm b/code/modules/mining/equipment/mineral_scanner.dm new file mode 100644 index 00000000000..6a706ca523f --- /dev/null +++ b/code/modules/mining/equipment/mineral_scanner.dm @@ -0,0 +1,116 @@ +/**********************Mining Scanner**********************/ +/obj/item/mining_scanner + desc = "A scanner that checks surrounding rock for useful minerals; it can also be used to stop gibtonite detonations. Wear material scanners for optimal results." + name = "manual mining scanner" + icon = 'icons/obj/device.dmi' + icon_state = "mining1" + item_state = "analyzer" + w_class = WEIGHT_CLASS_SMALL + flags = CONDUCT + slot_flags = SLOT_BELT + var/cooldown = 0 + origin_tech = "engineering=1;magnets=1" + +/obj/item/mining_scanner/attack_self(mob/user) + if(!user.client) + return + if(!cooldown) + cooldown = 1 + spawn(40) + cooldown = 0 + var/list/mobs = list() + mobs |= user + mineral_scan_pulse(mobs, get_turf(user)) + + +//Debug item to identify all ore spread quickly +/obj/item/mining_scanner/admin + +/obj/item/mining_scanner/admin/attack_self(mob/user) + for(var/turf/simulated/mineral/M in world) + if(M.scan_state) + M.icon_state = M.scan_state + qdel(src) + +/obj/item/t_scanner/adv_mining_scanner + desc = "A scanner that automatically checks surrounding rock for useful minerals; it can also be used to stop gibtonite detonations. Wear meson scanners for optimal results. This one has an extended range." + name = "advanced automatic mining scanner" + icon_state = "mining0" + item_state = "analyzer" + w_class = WEIGHT_CLASS_SMALL + flags = CONDUCT + slot_flags = SLOT_BELT + var/cooldown = 35 + var/on_cooldown = 0 + var/range = 7 + var/meson = TRUE + origin_tech = "engineering=3;magnets=3" + +/obj/item/t_scanner/adv_mining_scanner/cyborg + flags = CONDUCT | NODROP + +/obj/item/t_scanner/adv_mining_scanner/material + meson = FALSE + desc = "A scanner that automatically checks surrounding rock for useful minerals; it can also be used to stop gibtonite detonations. Wear material scanners for optimal results. This one has an extended range." + +/obj/item/t_scanner/adv_mining_scanner/lesser + name = "automatic mining scanner" + desc = "A scanner that automatically checks surrounding rock for useful minerals; it can also be used to stop gibtonite detonations. Wear meson scanners for optimal results." + range = 4 + cooldown = 50 + +/obj/item/t_scanner/adv_mining_scanner/lesser/material + desc = "A scanner that automatically checks surrounding rock for useful minerals; it can also be used to stop gibtonite detonations. Wear material scanners for optimal results." + meson = FALSE + +/obj/item/t_scanner/adv_mining_scanner/scan() + if(!on_cooldown) + on_cooldown = 1 + spawn(cooldown) + on_cooldown = 0 + var/turf/t = get_turf(src) + var/list/mobs = recursive_mob_check(t, client_check = 1, sight_check = 0, include_radio = 0) + if(!mobs.len) + return + if(meson) + mineral_scan_pulse(mobs, t, range) + else + mineral_scan_pulse_material(mobs, t, range) + +//For use with mesons +/proc/mineral_scan_pulse(list/mobs, turf/T, range = world.view) + var/list/minerals = list() + for(var/turf/simulated/mineral/M in range(range, T)) + if(M.scan_state) + minerals += M + if(minerals.len) + for(var/mob/user in mobs) + if(user.client) + var/client/C = user.client + for(var/turf/simulated/mineral/M in minerals) + var/turf/F = get_turf(M) + var/image/I = image('icons/turf/mining.dmi', loc = F, icon_state = M.scan_state, layer = 18) + C.images += I + spawn(30) + if(C) + C.images -= I + +//For use with material scanners +/proc/mineral_scan_pulse_material(list/mobs, turf/T, range = world.view) + var/list/minerals = list() + for(var/turf/simulated/mineral/M in range(range, T)) + if(M.scan_state) + minerals += M + if(minerals.len) + for(var/turf/simulated/mineral/M in minerals) + var/obj/effect/temp_visual/mining_overlay/C = new/obj/effect/temp_visual/mining_overlay(M) + C.icon_state = M.scan_state + +/obj/effect/temp_visual/mining_overlay + layer = 18 + icon = 'icons/turf/mining.dmi' + anchored = 1 + mouse_opacity = MOUSE_OPACITY_TRANSPARENT + duration = 30 + pixel_x = -4 + pixel_y = -4 \ No newline at end of file diff --git a/code/modules/mining/equipment/mining_tools.dm b/code/modules/mining/equipment/mining_tools.dm new file mode 100644 index 00000000000..4d47f88e065 --- /dev/null +++ b/code/modules/mining/equipment/mining_tools.dm @@ -0,0 +1,142 @@ +/*****************Pickaxes & Drills & Shovels****************/ +/obj/item/pickaxe + name = "pickaxe" + icon = 'icons/obj/items.dmi' + icon_state = "pickaxe" + flags = CONDUCT + slot_flags = SLOT_BELT + force = 15 + throwforce = 10 + item_state = "pickaxe" + w_class = WEIGHT_CLASS_BULKY + materials = list(MAT_METAL=2000) //one sheet, but where can you make them? + origin_tech = "materials=2;engineering=3" + attack_verb = list("hit", "pierced", "sliced", "attacked") + var/list/digsound = list('sound/effects/picaxe1.ogg','sound/effects/picaxe2.ogg','sound/effects/picaxe3.ogg') + var/drill_verb = "picking" + sharp = 1 + var/excavation_amount = 100 + usesound = 'sound/effects/picaxe1.ogg' + toolspeed = 1 + +/obj/item/pickaxe/proc/playDigSound() + playsound(src, pick(digsound),20,1) + +/obj/item/pickaxe/emergency + name = "emergency disembarkation tool" + desc = "For extracting yourself from rough landings." + +/obj/item/pickaxe/safety + name = "safety pickaxe" + desc = "A pickaxe designed to be only effective at digging rock and ore, very ineffective as a weapon." + force = 1 + throwforce = 1 + attack_verb = list("ineffectively hit") + +/obj/item/pickaxe/mini + name = "compact pickaxe" + desc = "A smaller, compact version of the standard pickaxe." + icon_state = "minipick" + force = 10 + throwforce = 7 + w_class = WEIGHT_CLASS_NORMAL + materials = list(MAT_METAL = 1000) + +/obj/item/pickaxe/silver + name = "silver-plated pickaxe" + icon_state = "spickaxe" + item_state = "spickaxe" + origin_tech = "materials=3;engineering=4" + toolspeed = 0.5 //mines faster than a normal pickaxe, bought from mining vendor + desc = "A silver-plated pickaxe that mines slightly faster than standard-issue." + force = 17 + +/obj/item/pickaxe/gold + name = "golden pickaxe" + icon_state = "gpickaxe" + item_state = "gpickaxe" + origin_tech = "materials=4;engineering=4" + toolspeed = 0.4 + desc = "A gold-plated pickaxe that mines faster than standard-issue." + force = 18 + +/obj/item/pickaxe/diamond + name = "diamond-tipped pickaxe" + icon_state = "dpickaxe" + item_state = "dpickaxe" + origin_tech = "materials=5;engineering=4" + toolspeed = 0.3 + desc = "A pickaxe with a diamond pick head. Extremely robust at cracking rock walls and digging up dirt." + force = 19 + +/obj/item/pickaxe/drill + name = "mining drill" + icon_state = "handdrill" + item_state = "jackhammer" + digsound = list('sound/weapons/drill.ogg') + toolspeed = 0.6 //available from roundstart, faster than a pickaxe. + hitsound = 'sound/weapons/drill.ogg' + usesound = 'sound/weapons/drill.ogg' + origin_tech = "materials=2;powerstorage=2;engineering=3" + desc = "An electric mining drill for the especially scrawny." + +/obj/item/pickaxe/drill/cyborg + name = "cyborg mining drill" + desc = "An integrated electric mining drill." + flags = NODROP + +/obj/item/pickaxe/drill/diamonddrill + name = "diamond-tipped mining drill" + icon_state = "diamonddrill" + origin_tech = "materials=6;powerstorage=4;engineering=4" + desc = "Yours is the drill that will pierce the heavens!" + toolspeed = 0.2 + +/obj/item/pickaxe/drill/cyborg/diamond //This is the BORG version! + name = "diamond-tipped cyborg mining drill" //To inherit the NODROP flag, and easier to change borg specific drill mechanics. + icon_state = "diamonddrill" + toolspeed = 0.2 + +/obj/item/pickaxe/drill/jackhammer + name = "sonic jackhammer" + icon_state = "jackhammer" + item_state = "jackhammer" + origin_tech = "materials=6;powerstorage=4;engineering=5;magnets=4" + digsound = list('sound/weapons/sonic_jackhammer.ogg') + hitsound = 'sound/weapons/sonic_jackhammer.ogg' + usesound = 'sound/weapons/sonic_jackhammer.ogg' + desc = "Cracks rocks with sonic blasts, and doubles as a demolition power tool for smashing walls." + toolspeed = 0.1 //the epitome of powertools. extremely fast mining, laughs at puny walls + +/obj/item/shovel + name = "shovel" + desc = "A large tool for digging and moving dirt." + icon = 'icons/obj/items.dmi' + icon_state = "shovel" + flags = CONDUCT + slot_flags = SLOT_BELT + force = 8 + throwforce = 4 + item_state = "shovel" + w_class = WEIGHT_CLASS_NORMAL + materials = list(MAT_METAL=50) + origin_tech = "materials=2;engineering=2" + attack_verb = list("bashed", "bludgeoned", "thrashed", "whacked") + usesound = 'sound/effects/shovel_dig.ogg' + toolspeed = 1 + +/obj/item/shovel/spade + name = "spade" + desc = "A small tool for digging and moving dirt." + icon_state = "spade" + item_state = "spade" + force = 5 + throwforce = 7 + w_class = WEIGHT_CLASS_SMALL + +/obj/item/shovel/safety + name = "safety shovel" + desc = "A large tool for digging and moving dirt. Was modified with extra safety, making it ineffective as a weapon." + force = 1 + throwforce = 1 + attack_verb = list("ineffectively hit") \ No newline at end of file diff --git a/code/modules/mining/equipment/regenerative_core.dm b/code/modules/mining/equipment/regenerative_core.dm new file mode 100644 index 00000000000..2d96c46d161 --- /dev/null +++ b/code/modules/mining/equipment/regenerative_core.dm @@ -0,0 +1,139 @@ +/*********************Hivelord stabilizer****************/ +/obj/item/hivelordstabilizer + name = "hivelord stabilizer" + icon = 'icons/obj/chemical.dmi' + icon_state = "bottle19" + desc = "Inject a hivelord core with this stabilizer to preserve its healing powers indefinitely." + w_class = WEIGHT_CLASS_TINY + origin_tech = "biotech=3" + +/obj/item/hivelordstabilizer/afterattack(obj/item/organ/internal/M, mob/user) + . = ..() + var/obj/item/organ/internal/hivelord_core/C = M + if(!istype(C, /obj/item/organ/internal/hivelord_core)) + to_chat(user, "The stabilizer only works on certain types of monster organs, generally regenerative in nature.") + return ..() + + C.preserved() + to_chat(user, "You inject the [M] with the stabilizer. It will no longer go inert.") + qdel(src) + +/************************Hivelord core*******************/ +/obj/item/organ/internal/hivelord_core + name = "hivelord remains" + desc = "All that remains of a hivelord. It can be used to help keep your body going, but it will rapidly decay into uselessness." + icon_state = "roro core 2" + flags = NOBLUDGEON + slot = "hivecore" + force = 0 + actions_types = list(/datum/action/item_action/organ_action/use) + var/inert = 0 + var/preserved = 0 + +/obj/item/organ/internal/hivelord_core/New() + ..() + addtimer(CALLBACK(src, .proc/inert_check), 2400) + +/obj/item/organ/internal/hivelord_core/proc/inert_check() + if(!preserved) + go_inert() + +/obj/item/organ/internal/hivelord_core/proc/preserved(implanted = 0) + inert = FALSE + preserved = TRUE + update_icon() + desc = "All that remains of a hivelord. It is preserved, allowing you to use it to heal completely without danger of decay." + if(implanted) + feedback_add_details("hivelord_core", "[type]|implanted") + else + feedback_add_details("hivelord_core", "[type]|stabilizer") + +/obj/item/organ/internal/hivelord_core/proc/go_inert() + inert = TRUE + name = "decayed regenerative core" + desc = "All that remains of a hivelord. It has decayed, and is completely useless." + feedback_add_details("hivelord_core", "[src.type]|inert") + update_icon() + +/obj/item/organ/internal/hivelord_core/ui_action_click() + if(inert) + to_chat(owner, "[src] breaks down as it tries to activate.") + else + owner.revive() + qdel(src) + +/obj/item/organ/internal/hivelord_core/on_life() + ..() + if(owner.health < HEALTH_THRESHOLD_CRIT) + ui_action_click() + +///Handles applying the core, logging and status/mood events. +/obj/item/organ/internal/hivelord_core/proc/applyto(atom/target, mob/user) + if(ishuman(target)) + var/mob/living/carbon/human/H = target + if(inert) + to_chat(user, "[src] has decayed and can no longer be used to heal.") + return + else + if(H.stat == DEAD) + to_chat(user, "[src] is useless on the dead.") + return + if(H != user) + H.visible_message("[user] forces [H] to apply [src]... Black tendrils entangle and reinforce [H.p_them()]!") + feedback_add_details("hivelord_core","[src.type]|used|other") + else + to_chat(user, "You start to smear [src] on yourself. Disgusting tendrils hold you together and allow you to keep moving, but for how long?") + feedback_add_details("hivelord_core","[src.type]|used|self") + H.revive() + user.drop_item() + qdel(src) + +/obj/item/organ/internal/hivelord_core/afterattack(atom/target, mob/user, proximity_flag) + . = ..() + if(proximity_flag) + applyto(target, user) + +/obj/item/organ/internal/hivelord_core/attack_self(mob/user) + applyto(user, user) + +/obj/item/organ/internal/hivelord_core/insert(mob/living/carbon/M, special = 0) + ..() + if(!preserved && !inert) + preserved(TRUE) + owner.visible_message("[src] stabilizes as it's inserted.") + +/obj/item/organ/internal/hivelord_core/remove(mob/living/carbon/M, special = 0) + if(!inert && !special) + owner.visible_message("[src] rapidly decays as it's removed.") + go_inert() + return ..() + +/obj/item/organ/internal/hivelord_core/prepare_eat() + return null + +/*************************Legion core********************/ +/obj/item/organ/internal/hivelord_core/legion + name = "legion's soul" + desc = "A strange rock that crackles with power. It can be used to heal completely, but it will rapidly decay into uselessness." + icon_state = "legion_soul" + +/obj/item/organ/internal/hivelord_core/legion/New() + ..() + update_icon() + +/obj/item/organ/internal/hivelord_core/legion/update_icon() + icon_state = inert ? "legion_soul_inert" : "legion_soul" + cut_overlays() + if(!inert && !preserved) + add_overlay("legion_soul_crackle") + for(var/X in actions) + var/datum/action/A = X + A.UpdateButtonIcon() + +/obj/item/organ/internal/hivelord_core/legion/go_inert() + ..() + desc = "[src] has become inert. It has decayed, and is completely useless." + +/obj/item/organ/internal/hivelord_core/legion/preserved(implanted = 0) + ..() + desc = "[src] has been stabilized. It is preserved, allowing you to use it to heal completely without danger of decay." \ No newline at end of file diff --git a/code/modules/mining/equipment/resonator.dm b/code/modules/mining/equipment/resonator.dm new file mode 100644 index 00000000000..4c7c4e599ef --- /dev/null +++ b/code/modules/mining/equipment/resonator.dm @@ -0,0 +1,116 @@ +/**********************Resonator**********************/ +/obj/item/resonator + name = "resonator" + icon = 'icons/obj/items.dmi' + icon_state = "resonator" + item_state = "resonator" + origin_tech = "magnets=3;engineering=3" + desc = "A handheld device that creates small fields of energy that resonate until they detonate, crushing rock. It can also be activated without a target to create a field at the user's location, to act as a delayed time trap. It's more effective in a vaccuum." + w_class = WEIGHT_CLASS_NORMAL + force = 15 + throwforce = 10 + var/burst_time = 30 + var/fieldlimit = 4 + var/list/fields = list() + var/quick_burst_mod = 0.8 + +/obj/item/resonator/upgraded + name = "upgraded resonator" + desc = "An upgraded version of the resonator that can produce more fields at once." + icon_state = "resonator_u" + origin_tech = "materials=4;powerstorage=3;engineering=3;magnets=3" + fieldlimit = 6 + quick_burst_mod = 1 + +/obj/item/resonator/attack_self(mob/user) + if(burst_time == 50) + burst_time = 30 + to_chat(user, "You set the resonator's fields to detonate after 3 seconds.") + else + burst_time = 50 + to_chat(user, "You set the resonator's fields to detonate after 5 seconds.") + +/obj/item/resonator/proc/CreateResonance(target, mob/user) + var/turf/T = get_turf(target) + var/obj/effect/temp_visual/resonance/R = locate(/obj/effect/temp_visual/resonance) in T + if(R) + R.damage_multiplier = quick_burst_mod + R.burst() + return + if(LAZYLEN(fields) < fieldlimit) + new /obj/effect/temp_visual/resonance(T, user, src, burst_time) + user.changeNext_move(CLICK_CD_MELEE) + +/obj/item/resonator/pre_attackby(atom/target, mob/user, params) + if(check_allowed_items(target, 1)) + CreateResonance(target, user) + return TRUE + +//resonance field, crushes rock, damages mobs +/obj/effect/temp_visual/resonance + name = "resonance field" + desc = "A resonating field that significantly damages anything inside of it when the field eventually ruptures. More damaging in low pressure environments." + icon = 'icons/effects/effects.dmi' + icon_state = "shield1" + layer = ABOVE_ALL_MOB_LAYER + duration = 50 + var/resonance_damage = 20 + var/damage_multiplier = 1 + var/creator + var/obj/item/resonator/res + +/obj/effect/temp_visual/resonance/New(loc, set_creator, set_resonator, set_duration) + duration = set_duration + . = ..() + creator = set_creator + res = set_resonator + if(res) + res.fields += src + playsound(src,'sound/weapons/resonator_fire.ogg',50,1) + transform = matrix() * 0.75 + animate(src, transform = matrix() * 1.5, time = duration) + deltimer(timerid) + timerid = addtimer(CALLBACK(src, .proc/burst), duration, TIMER_STOPPABLE) + +/obj/effect/temp_visual/resonance/Destroy() + if(res) + res.fields -= src + res = null + creator = null + return ..() + +/obj/effect/temp_visual/resonance/proc/check_pressure(turf/proj_turf) + if(!proj_turf) + proj_turf = get_turf(src) + resonance_damage = initial(resonance_damage) + if(lavaland_equipment_pressure_check(proj_turf)) + name = "strong [initial(name)]" + resonance_damage *= 3 + else + name = initial(name) + resonance_damage *= damage_multiplier + +/obj/effect/temp_visual/resonance/proc/burst() + var/turf/T = get_turf(src) + new /obj/effect/temp_visual/resonance_crush(T) + if(ismineralturf(T)) + var/turf/simulated/mineral/M = T + M.gets_drilled(creator) + check_pressure(T) + playsound(T,'sound/weapons/resonator_blast.ogg',50,1) + for(var/mob/living/L in T) + if(creator) + add_attack_logs(creator, L, "Resonance field'ed") + to_chat(L, "[src] ruptured with you in it!") + L.apply_damage(resonance_damage, BRUTE) + qdel(src) + +/obj/effect/temp_visual/resonance_crush + icon_state = "shield1" + layer = ABOVE_ALL_MOB_LAYER + duration = 4 + +/obj/effect/temp_visual/resonance_crush/New() + ..() + transform = matrix()*1.5 + animate(src, transform = matrix() * 0.1, alpha = 50, time = 4) \ No newline at end of file diff --git a/code/modules/mining/equipment/vendor_items.dm b/code/modules/mining/equipment/vendor_items.dm new file mode 100644 index 00000000000..8868d4655b5 --- /dev/null +++ b/code/modules/mining/equipment/vendor_items.dm @@ -0,0 +1,14 @@ +/**********************Mining Equipment Vendor Items**************************/ +//misc stuff you can buy from the vendor that has special code but doesn't really need its own file + +/**********************Facehugger toy**********************/ +/obj/item/clothing/mask/facehugger/toy + item_state = "facehugger_inactive" + desc = "A toy often used to play pranks on other miners by putting it in their beds. It takes a bit to recharge after latching onto something." + throwforce = 0 + real = 0 + sterile = 1 + tint = 3 //Makes it feel more authentic when it latches on + +/obj/item/clothing/mask/facehugger/toy/Die() + return diff --git a/code/modules/mining/equipment/wormhole_jaunter.dm b/code/modules/mining/equipment/wormhole_jaunter.dm new file mode 100644 index 00000000000..7ab7276bb9e --- /dev/null +++ b/code/modules/mining/equipment/wormhole_jaunter.dm @@ -0,0 +1,77 @@ +/**********************Jaunter**********************/ +/obj/item/wormhole_jaunter + name = "wormhole jaunter" + desc = "A single use device harnessing outdated wormhole technology, Nanotrasen has since turned its eyes to bluespace for more accurate teleportation. The wormholes it creates are unpleasant to travel through, to say the least.\nThanks to modifications provided by the Free Golems, this jaunter can be worn on the belt to provide protection from chasms." + icon = 'icons/obj/items.dmi' + icon_state = "Jaunter" + item_state = "electronic" + throwforce = 0 + w_class = WEIGHT_CLASS_SMALL + throw_speed = 3 + throw_range = 5 + origin_tech = "bluespace=2" + slot_flags = SLOT_BELT + +/obj/item/wormhole_jaunter/attack_self(mob/user) + user.visible_message("[user.name] activates the [name]!") + activate(user, TRUE) + +/obj/item/wormhole_jaunter/proc/turf_check(mob/user) + var/turf/device_turf = get_turf(user) + if(!device_turf || !is_teleport_allowed(device_turf.z)) + to_chat(user, "You're having difficulties getting the [name] to work.") + return FALSE + return TRUE + +/obj/item/wormhole_jaunter/proc/get_destinations(mob/user) + var/list/destinations = list() + + for(var/obj/item/radio/beacon/B in world) + var/turf/T = get_turf(B) + if(is_station_level(T.z)) + destinations += B + + return destinations + +/obj/item/wormhole_jaunter/proc/activate(mob/user, adjacent) + if(!turf_check(user)) + return + + var/list/L = get_destinations(user) + if(!L.len) + to_chat(user, "The [name] found no beacons in the world to anchor a wormhole to.") + return + var/chosen_beacon = pick(L) + var/obj/effect/portal/jaunt_tunnel/J = new(get_turf(src), get_turf(chosen_beacon), src, 100) + if(adjacent) + try_move_adjacent(J) + else + J.teleport(user) + playsound(src,'sound/effects/sparks4.ogg',50,1) + qdel(src) + +/obj/item/wormhole_jaunter/proc/chasm_react(mob/user) + if(user.get_item_by_slot(slot_belt) == src) + to_chat(user, "Your [name] activates, saving you from the chasm!") + activate(user, FALSE) + else + to_chat(user, "[src] is not attached to your belt, preventing it from saving you from the chasm. RIP.
      ") + +/obj/effect/portal/jaunt_tunnel + name = "jaunt tunnel" + icon = 'icons/effects/effects.dmi' + icon_state = "bhole3" + desc = "A stable hole in the universe made by a wormhole jaunter. Turbulent doesn't even begin to describe how rough passage through one of these is, but at least it will always get you somewhere near a beacon." + failchance = 0 + +/obj/effect/portal/jaunt_tunnel/teleport(atom/movable/M) + . = ..() + if(.) + // KERPLUNK + playsound(M,'sound/weapons/resonator_blast.ogg', 50, 1) + if(iscarbon(M)) + var/mob/living/carbon/L = M + L.Weaken(6) + if(ishuman(L)) + shake_camera(L, 20, 1) + addtimer(CALLBACK(L, /mob/living/carbon.proc/vomit), 20) \ No newline at end of file diff --git a/code/modules/mining/equipment_locker.dm b/code/modules/mining/equipment_locker.dm deleted file mode 100644 index 1001a2aa514..00000000000 --- a/code/modules/mining/equipment_locker.dm +++ /dev/null @@ -1,1215 +0,0 @@ -/**********************Ore Redemption Unit**************************/ -//Turns all the various mining machines into a single unit to speed up mining and establish a point system - -/obj/machinery/mineral/ore_redemption - name = "ore redemption machine" - desc = "A machine that accepts ore and instantly transforms it into workable material sheets. Points for ore are generated based on type and can be redeemed at a mining equipment vendor." - icon = 'icons/obj/machines/mining_machines.dmi' - icon_state = "ore_redemption" - density = TRUE - anchored = TRUE - input_dir = NORTH - output_dir = SOUTH - req_access = list(access_mineral_storeroom) - speed_process = TRUE - layer = BELOW_OBJ_LAYER - var/req_access_reclaim = access_mining_station - var/obj/item/card/id/inserted_id - var/points = 0 - var/ore_pickup_rate = 15 - var/sheet_per_ore = 1 - var/point_upgrade = 1 - var/list/ore_values = list("sand" = 1, "iron" = 1, "plasma" = 15, "silver" = 16, "gold" = 18, "titanium" = 30, "uranium" = 30, "diamond" = 50, "bluespace crystal" = 50, "bananium" = 60, "tranquillite" = 60) - var/message_sent = FALSE - var/list/ore_buffer = list() - var/datum/research/files - var/obj/item/disk/design_disk/inserted_disk - var/list/supply_consoles = list("Science", "Robotics", "Research Director's Desk", "Mechanic", "Engineering" = list("metal", "glass", "plasma"), "Chief Engineer's Desk" = list("metal", "glass", "plasma"), "Atmospherics" = list("metal", "glass", "plasma"), "Bar" = list("uranium", "plasma"), "Virology" = list("plasma", "uranium", "gold")) - -/obj/machinery/mineral/ore_redemption/New() - ..() - AddComponent(/datum/component/material_container, list(MAT_METAL, MAT_GLASS, MAT_SILVER, MAT_GOLD, MAT_DIAMOND, MAT_PLASMA, MAT_URANIUM, MAT_BANANIUM, MAT_TRANQUILLITE, MAT_TITANIUM, MAT_BLUESPACE), INFINITY, FALSE, /obj/item/stack) - files = new /datum/research/smelter(src) - component_parts = list() - component_parts += new /obj/item/circuitboard/ore_redemption(null) - component_parts += new /obj/item/stock_parts/matter_bin(null) - component_parts += new /obj/item/stock_parts/manipulator(null) - component_parts += new /obj/item/stock_parts/micro_laser(null) - component_parts += new /obj/item/assembly/igniter(null) - component_parts += new /obj/item/stock_parts/console_screen(null) - RefreshParts() - -/obj/machinery/mineral/ore_redemption/upgraded/New() - ..() - component_parts = list() - component_parts += new /obj/item/circuitboard/ore_redemption(null) - component_parts += new /obj/item/stock_parts/matter_bin/super(null) - component_parts += new /obj/item/stock_parts/manipulator/pico(null) - component_parts += new /obj/item/stock_parts/micro_laser/ultra(null) - component_parts += new /obj/item/assembly/igniter(null) - component_parts += new /obj/item/stock_parts/console_screen(null) - RefreshParts() - -/obj/machinery/mineral/ore_redemption/golem - req_access = list(access_free_golems) - req_access_reclaim = access_free_golems - -/obj/machinery/mineral/ore_redemption/golem/New() - ..() - component_parts = list() - component_parts += new /obj/item/circuitboard/ore_redemption/golem(null) - component_parts += new /obj/item/stock_parts/matter_bin(null) - component_parts += new /obj/item/stock_parts/manipulator(null) - component_parts += new /obj/item/stock_parts/micro_laser(null) - component_parts += new /obj/item/assembly/igniter(null) - component_parts += new /obj/item/stock_parts/console_screen(null) - RefreshParts() - -/obj/machinery/mineral/ore_redemption/Destroy() - QDEL_NULL(files) - GET_COMPONENT(materials, /datum/component/material_container) - materials.retrieve_all() - return ..() - -/obj/machinery/mineral/ore_redemption/RefreshParts() - var/ore_pickup_rate_temp = 15 - var/point_upgrade_temp = 1 - var/sheet_per_ore_temp = 1 - for(var/obj/item/stock_parts/matter_bin/B in component_parts) - sheet_per_ore_temp = 0.65 + (0.35 * B.rating) - for(var/obj/item/stock_parts/manipulator/M in component_parts) - ore_pickup_rate_temp = 15 * M.rating - for(var/obj/item/stock_parts/micro_laser/L in component_parts) - point_upgrade_temp = 0.65 + (0.35 * L.rating) - ore_pickup_rate = ore_pickup_rate_temp - point_upgrade = point_upgrade_temp - sheet_per_ore = sheet_per_ore_temp - -/obj/machinery/mineral/ore_redemption/proc/smelt_ore(obj/item/stack/ore/O) - - ore_buffer -= O - - if(O && O.refined_type) - points += O.points * point_upgrade * O.amount - - GET_COMPONENT(materials, /datum/component/material_container) - var/material_amount = materials.get_item_material_amount(O) - - if(!material_amount) - qdel(O) //no materials, incinerate it - - else if(!materials.has_space(material_amount * sheet_per_ore * O.amount)) //if there is no space, eject it - unload_mineral(O) - - else - materials.insert_item(O, sheet_per_ore) //insert it - qdel(O) - -/obj/machinery/mineral/ore_redemption/proc/can_smelt_alloy(datum/design/D) - if(D.make_reagents.len) - return FALSE - - var/build_amount = 0 - - GET_COMPONENT(materials, /datum/component/material_container) - for(var/mat_id in D.materials) - var/M = D.materials[mat_id] - var/datum/material/redemption_mat = materials.materials[mat_id] - - if(!M || !redemption_mat) - return FALSE - - var/smeltable_sheets = round(redemption_mat.amount / M) - - if(!smeltable_sheets) - return FALSE - - if(!build_amount) - build_amount = smeltable_sheets - - build_amount = min(build_amount, smeltable_sheets) - - return build_amount - -/obj/machinery/mineral/ore_redemption/proc/process_ores(list/ores_to_process) - var/current_amount = 0 - for(var/ore in ores_to_process) - if(current_amount >= ore_pickup_rate) - break - smelt_ore(ore) - -/obj/machinery/mineral/ore_redemption/proc/send_console_message() - if(!is_station_level(z)) - return - message_sent = TRUE - var/area/A = get_area(src) - var/msg = "Now available in [A]:
      " - - var/has_minerals = FALSE - var/mineral_name = null - GET_COMPONENT(materials, /datum/component/material_container) - for(var/mat_id in materials.materials) - var/datum/material/M = materials.materials[mat_id] - var/mineral_amount = M.amount / MINERAL_MATERIAL_AMOUNT - mineral_name = capitalize(M.name) - if(mineral_amount) - has_minerals = TRUE - msg += "[mineral_name]: [mineral_amount] sheets
      " - - if(!has_minerals) - return - - for(var/obj/machinery/requests_console/D in allConsoles) - if(D.department in src.supply_consoles) - if(supply_consoles[D.department] == null || (mineral_name in supply_consoles[D.department])) - D.createMessage("Ore Redemption Machine", "New Minerals Available!", msg, 1) - -/obj/machinery/mineral/ore_redemption/process() - if(panel_open || !powered()) - return - var/atom/input = get_step(src, input_dir) - var/obj/structure/ore_box/OB = locate() in input - if(OB) - input = OB - - for(var/obj/item/stack/ore/O in input) - if(QDELETED(O)) - continue - ore_buffer |= O - O.forceMove(src) - CHECK_TICK - - if(LAZYLEN(ore_buffer)) - message_sent = FALSE - process_ores(ore_buffer) - else if(!message_sent) - send_console_message() - -/obj/machinery/mineral/ore_redemption/attackby(obj/item/W, mob/user, params) - if(exchange_parts(user, W)) - return - if(default_unfasten_wrench(user, W)) - return - if(default_deconstruction_screwdriver(user, "ore_redemption-open", "ore_redemption", W)) - updateUsrDialog() - return - if(default_deconstruction_crowbar(W)) - return - - if(!powered()) - return - if(istype(W, /obj/item/card/id)) - var/obj/item/card/id/I = user.get_active_hand() - if(istype(I) && !istype(inserted_id)) - if(!user.drop_item()) - return - I.forceMove(src) - inserted_id = I - interact(user) - return - - if(ismultitool(W) && panel_open) - input_dir = turn(input_dir, -90) - output_dir = turn(output_dir, -90) - to_chat(user, "You change [src]'s I/O settings, setting the input to [dir2text(input_dir)] and the output to [dir2text(output_dir)].") - return - - if(istype(W, /obj/item/disk/design_disk)) - if(user.drop_item()) - W.forceMove(src) - inserted_disk = W - interact(user) - return TRUE - - return ..() - -/obj/machinery/mineral/ore_redemption/attack_hand(mob/user) - if(..()) - return - interact(user) - -/obj/machinery/mineral/ore_redemption/interact(mob/user) - var/dat = "This machine only accepts ore. Gibtonite and Slag are not accepted.

      " - dat += "Current unclaimed points: [points]
      " - - if(inserted_id) - dat += "You have [inserted_id.mining_points] mining points collected. Eject ID.
      " - dat += "Claim points.

      " - else - dat += "No ID inserted. Insert ID.

      " - - GET_COMPONENT(materials, /datum/component/material_container) - for(var/mat_id in materials.materials) - var/datum/material/M = materials.materials[mat_id] - if(M.amount) - var/sheet_amount = M.amount / MINERAL_MATERIAL_AMOUNT - dat += "[capitalize(M.name)]: [sheet_amount] " - if(sheet_amount >= 1) - dat += "Release
      " - else - dat += "Release
      " - - dat += "
      Alloys:
      " - - for(var/v in files.known_designs) - var/datum/design/D = files.known_designs[v] - if(can_smelt_alloy(D)) - dat += "[D.name]: Smelt
      " - else - dat += "[D.name]: Smelt
      " - - dat += "
      Mineral Value List:
      [get_ore_values()]
      " - - if(inserted_disk) - dat += "Eject disk
      " - dat += "
      Uploadable designs:
      " - - if(inserted_disk.blueprint) - var/datum/design/D = inserted_disk.blueprint - if(D.build_type & SMELTER) - dat += "Name: [D.name] Upload to smelter" - - dat += "

      " - else - dat += "Insert design disk

      " - - var/datum/browser/popup = new(user, "ore_redemption_machine", "Ore Redemption Machine", 400, 500) - popup.set_content(dat) - popup.open() - return - -/obj/machinery/mineral/ore_redemption/proc/get_ore_values() - var/dat = "" - for(var/ore in ore_values) - var/value = ore_values[ore] - dat += "" - dat += "
      [capitalize(ore)][value * point_upgrade]
      " - return dat - -/obj/machinery/mineral/ore_redemption/Topic(href, href_list) - if(..()) - return - GET_COMPONENT(materials, /datum/component/material_container) - if(href_list["eject_id"]) - usr.put_in_hands(inserted_id) - inserted_id = null - if(href_list["claim"]) - if(inserted_id) - if(req_access_reclaim in inserted_id.access) - inserted_id.mining_points += points - points = 0 - else - to_chat(usr, "Required access not found.") - else if(href_list["insert_id"]) - var/obj/item/card/id/I = usr.get_active_hand() - if(istype(I)) - if(!usr.drop_item()) - return - I.forceMove(src) - inserted_id = I - else - to_chat(usr, "Not a valid ID!") - if(href_list["eject_disk"]) - if(inserted_disk) - inserted_disk.forceMove(loc) - inserted_disk = null - if(href_list["insert_disk"]) - var/obj/item/disk/design_disk/D = usr.get_active_hand() - if(istype(D)) - if(!usr.drop_item()) - return - D.forceMove(src) - inserted_disk = D - if(href_list["upload"]) - if(inserted_disk && inserted_disk.blueprint) - files.AddDesign2Known(inserted_disk.blueprint) - - if(href_list["release"]) - if(check_access(inserted_id) || allowed(usr)) //Check the ID inside, otherwise check the user - var/mat_id = href_list["release"] - if(!materials.materials[mat_id]) - return - - var/datum/material/mat = materials.materials[mat_id] - var/stored_amount = mat.amount / MINERAL_MATERIAL_AMOUNT - - if(!stored_amount) - return - - var/desired = input("How many sheets?", "How many sheets to eject?", 1) as null|num - var/sheets_to_remove = round(min(desired,50,stored_amount)) - - var/out = get_step(src, output_dir) - materials.retrieve_sheets(sheets_to_remove, mat_id, out) - - else - to_chat(usr, "Required access not found.") - - if(href_list["alloy"]) - var/alloy_id = href_list["alloy"] - var/datum/design/alloy = files.FindDesignByID(alloy_id) - if((check_access(inserted_id) || allowed(usr)) && alloy) - var/desired = input("How many sheets?", "How many sheets would you like to smelt?", 1) as null|num - if(desired < 1) // Stops an exploit that lets you build negative alloys and get free materials - return - var/smelt_amount = can_smelt_alloy(alloy) - var/amount = round(min(desired,50,smelt_amount)) - materials.use_amount(alloy.materials, amount) - - var/output = new alloy.build_path(src) - if(istype(output, /obj/item/stack/sheet)) - var/obj/item/stack/sheet/mineral/produced_alloy = output - produced_alloy.amount = amount - unload_mineral(produced_alloy) - else - unload_mineral(output) - - else - to_chat(usr, "Required access not found.") - updateUsrDialog() - -/obj/machinery/mineral/ore_redemption/ex_act(severity, target) - do_sparks(5, 1, src) - if(severity == 1) - if(prob(50)) - qdel(src) - else if(severity == 2) - if(prob(25)) - qdel(src) - -/obj/machinery/mineral/ore_redemption/power_change() - ..() - update_icon() - if(inserted_id && !powered()) - visible_message("The ID slot indicator light flickers on [src] as it spits out a card before powering down.") - inserted_id.forceMove(loc) - -/obj/machinery/mineral/ore_redemption/update_icon() - if(powered()) - icon_state = initial(icon_state) - else - icon_state = "[initial(icon_state)]-off" - -/**********************Mining Equipment Locker**************************/ - -/obj/machinery/mineral/equipment_vendor - name = "mining equipment vendor" - desc = "An equipment vendor for miners, points collected at an ore redemption machine can be spent here." - icon = 'icons/obj/machines/mining_machines.dmi' - icon_state = "mining" - density = 1 - anchored = 1.0 - var/obj/item/card/id/inserted_id - var/list/prize_list = list( - new /datum/data/mining_equipment("Stimpack", /obj/item/reagent_containers/hypospray/autoinjector/stimpack, 50), - new /datum/data/mining_equipment("Teporone MediPen", /obj/item/reagent_containers/hypospray/autoinjector/teporone, 50), - new /datum/data/mining_equipment("MediPen Bundle", /obj/item/storage/box/autoinjector/utility, 200), - new /datum/data/mining_equipment("Whiskey", /obj/item/reagent_containers/food/drinks/bottle/whiskey, 100), - new /datum/data/mining_equipment("Cigar", /obj/item/clothing/mask/cigarette/cigar/havana, 150), - new /datum/data/mining_equipment("Soap", /obj/item/soap/nanotrasen, 200), - new /datum/data/mining_equipment("Laser Pointer", /obj/item/laser_pointer, 300), - new /datum/data/mining_equipment("Alien Toy", /obj/item/clothing/mask/facehugger/toy, 300), - new /datum/data/mining_equipment("Advanced Scanner", /obj/item/t_scanner/adv_mining_scanner, 400), - new /datum/data/mining_equipment("Hivelord Stabilizer", /obj/item/hivelordstabilizer, 400), - new /datum/data/mining_equipment("Mining Drone", /obj/item/mining_drone_cube, 500), - new /datum/data/mining_equipment("Drone Melee Upgrade", /obj/item/mine_bot_upgrade, 400), - new /datum/data/mining_equipment("Drone Health Upgrade", /obj/item/mine_bot_upgrade/health, 400), - new /datum/data/mining_equipment("Drone Ranged Upgrade", /obj/item/mine_bot_upgrade/cooldown, 600), - new /datum/data/mining_equipment("Kinetic Crusher", /obj/item/twohanded/required/kinetic_crusher, 750), - new /datum/data/mining_equipment("Shelter Capsule", /obj/item/survivalcapsule, 400), - new /datum/data/mining_equipment("Luxury Shelter Capsule", /obj/item/survivalcapsule/luxury, 3000), - new /datum/data/mining_equipment("Explorer\'s Webbing", /obj/item/storage/belt/mining, 500), - new /datum/data/mining_equipment("Drone AI Upgrade", /obj/item/slimepotion/sentience/mining, 1000), - new /datum/data/mining_equipment("GAR mesons", /obj/item/clothing/glasses/meson/gar, 500), - new /datum/data/mining_equipment("Brute First-Aid Kit", /obj/item/storage/firstaid/brute, 600), - new /datum/data/mining_equipment("Jaunter", /obj/item/wormhole_jaunter, 600), - new /datum/data/mining_equipment("Kinetic Accelerator", /obj/item/gun/energy/kinetic_accelerator, 750), - new /datum/data/mining_equipment("Resonator", /obj/item/resonator, 800), - new /datum/data/mining_equipment("Lazarus Injector", /obj/item/lazarus_injector, 1000), - new /datum/data/mining_equipment("Silver Pickaxe", /obj/item/pickaxe/silver, 1000), - new /datum/data/mining_equipment("Lazarus Capsule", /obj/item/mobcapsule, 800), - new /datum/data/mining_equipment("Lazarus Capsule belt", /obj/item/storage/belt/lazarus, 200), - new /datum/data/mining_equipment("Jetpack", /obj/item/tank/jetpack/carbondioxide/mining, 2000), - new /datum/data/mining_equipment("Space Cash", /obj/item/stack/spacecash/c1000, 2000), - new /datum/data/mining_equipment("Diamond Pickaxe", /obj/item/pickaxe/diamond, 2000), - new /datum/data/mining_equipment("Super Resonator", /obj/item/resonator/upgraded, 2500), - new /datum/data/mining_equipment("Jump Boots", /obj/item/clothing/shoes/bhop, 2500), - new /datum/data/mining_equipment("Mining Hardsuit", /obj/item/storage/box/mininghardsuit, 2000), - new /datum/data/mining_equipment("1 Marker Beacon", /obj/item/stack/marker_beacon, 10), - new /datum/data/mining_equipment("10 Marker Beacons", /obj/item/stack/marker_beacon/ten, 100), - new /datum/data/mining_equipment("30 Marker Beacons", /obj/item/stack/marker_beacon/thirty, 300), - new /datum/data/mining_equipment("KA White Tracer Rounds", /obj/item/borg/upgrade/modkit/tracer, 100), - new /datum/data/mining_equipment("KA Adjustable Tracer Rounds", /obj/item/borg/upgrade/modkit/tracer/adjustable, 150), - new /datum/data/mining_equipment("KA Super Chassis", /obj/item/borg/upgrade/modkit/chassis_mod, 250), - new /datum/data/mining_equipment("KA Hyper Chassis", /obj/item/borg/upgrade/modkit/chassis_mod/orange, 300), - new /datum/data/mining_equipment("KA Range Increase", /obj/item/borg/upgrade/modkit/range, 1000), - new /datum/data/mining_equipment("KA Damage Increase", /obj/item/borg/upgrade/modkit/damage, 1000), - new /datum/data/mining_equipment("KA Cooldown Decrease", /obj/item/borg/upgrade/modkit/cooldown, 1000), - new /datum/data/mining_equipment("KA AoE Damage", /obj/item/borg/upgrade/modkit/aoe/mobs, 2000), - new /datum/data/mining_equipment("Point Transfer Card", /obj/item/card/mining_point_card, 500), - new /datum/data/mining_equipment("Mining Conscription Kit", /obj/item/storage/backpack/duffel/mining_conscript, 1000), - ) - -/obj/machinery/mineral/equipment_vendor/golem - name = "golem ship equipment vendor" - -/obj/machinery/mineral/equipment_vendor/golem/New() - ..() - component_parts = list() - component_parts += new /obj/item/circuitboard/mining_equipment_vendor/golem(null) - component_parts += new /obj/item/stock_parts/matter_bin(null) - component_parts += new /obj/item/stock_parts/matter_bin(null) - component_parts += new /obj/item/stock_parts/matter_bin(null) - component_parts += new /obj/item/stock_parts/console_screen(null) - RefreshParts() - -/obj/machinery/mineral/equipment_vendor/golem/Initialize() - . = ..() - desc += "\nIt seems a few selections have been added." - prize_list += list( - new /datum/data/mining_equipment("Extra Id", /obj/item/card/id/golem, 250), - new /datum/data/mining_equipment("Science Backpack", /obj/item/storage/backpack/science, 250), - new /datum/data/mining_equipment("Full Toolbelt", /obj/item/storage/belt/utility/full/multitool, 250), - new /datum/data/mining_equipment("Monkey Cube", /obj/item/reagent_containers/food/snacks/monkeycube, 250), - new /datum/data/mining_equipment("Royal Cape of the Liberator", /obj/item/bedsheet/rd/royal_cape, 500), - new /datum/data/mining_equipment("Grey Slime Extract", /obj/item/slime_extract/grey, 1000), - new /datum/data/mining_equipment("KA Trigger Modification Kit", /obj/item/borg/upgrade/modkit/trigger_guard, 1000), - new /datum/data/mining_equipment("Shuttle Console Board", /obj/item/circuitboard/shuttle/golem_ship, 2000), - new /datum/data/mining_equipment("The Liberator's Legacy", /obj/item/storage/box/rndboards, 2000) - - ) - -/datum/data/mining_equipment - var/equipment_name = "generic" - var/equipment_path = null - var/cost = 0 - -/datum/data/mining_equipment/New(name, path, equipment_cost) - equipment_name = name - equipment_path = path - cost = equipment_cost - -/obj/machinery/mineral/equipment_vendor/New() - ..() - component_parts = list() - component_parts += new /obj/item/circuitboard/mining_equipment_vendor(null) - component_parts += new /obj/item/stock_parts/matter_bin(null) - component_parts += new /obj/item/stock_parts/matter_bin(null) - component_parts += new /obj/item/stock_parts/matter_bin(null) - component_parts += new /obj/item/stock_parts/console_screen(null) - RefreshParts() - -/obj/machinery/mineral/equipment_vendor/power_change() - ..() - update_icon() - if(inserted_id && !powered()) - visible_message("The ID slot indicator light flickers on \the [src] as it spits out a card before powering down.") - inserted_id.forceMove(loc) - -/obj/machinery/mineral/equipment_vendor/update_icon() - if(powered()) - icon_state = initial(icon_state) - else - icon_state = "[initial(icon_state)]-off" - -/obj/machinery/mineral/equipment_vendor/attack_hand(mob/user) - if(..()) - return - interact(user) - -/obj/machinery/mineral/equipment_vendor/attack_ghost(mob/user) - interact(user) - -/obj/machinery/mineral/equipment_vendor/interact(mob/user) - user.set_machine(src) - - var/dat - dat +="
      " - if(istype(inserted_id)) - dat += "You have [inserted_id.mining_points] mining points collected. Eject ID.
      " - else - dat += "No ID inserted. Insert ID.
      " - dat += "
      " - dat += "
      Equipment point cost list:
      " - for(var/datum/data/mining_equipment/prize in prize_list) - dat += "" - dat += "
      [prize.equipment_name][prize.cost]Purchase
      " - var/datum/browser/popup = new(user, "miningvendor", "Mining Equipment Vendor", 400, 350) - popup.set_content(dat) - popup.open() - -/obj/machinery/mineral/equipment_vendor/Topic(href, href_list) - if(..()) - return 1 - - if(href_list["choice"]) - if(istype(inserted_id)) - if(href_list["choice"] == "eject") - inserted_id.loc = loc - inserted_id.verb_pickup() - inserted_id = null - else if(href_list["choice"] == "insert") - var/obj/item/card/id/I = usr.get_active_hand() - if(istype(I)) - if(!usr.drop_item()) - return - I.loc = src - inserted_id = I - else - to_chat(usr, "No valid ID.") - - if(href_list["purchase"]) - if(istype(inserted_id)) - var/datum/data/mining_equipment/prize = locate(href_list["purchase"]) - if(!prize || !(prize in prize_list) || prize.cost > inserted_id.mining_points) - return - - inserted_id.mining_points -= prize.cost - new prize.equipment_path(src.loc) - updateUsrDialog() - -/obj/machinery/mineral/equipment_vendor/attackby(obj/item/I, mob/user, params) - if(default_deconstruction_screwdriver(user, "mining-open", "mining", I)) - updateUsrDialog() - return - if(panel_open) - if(istype(I, /obj/item/crowbar)) - if(inserted_id) - inserted_id.forceMove(loc) //Prevents deconstructing the ORM from deleting whatever ID was inside it. - default_deconstruction_crowbar(I) - return 1 - if(istype(I, /obj/item/mining_voucher)) - if(!powered()) - return - else - RedeemVoucher(I, user) - return - if(istype(I,/obj/item/card/id)) - if(!powered()) - return - else - var/obj/item/card/id/C = usr.get_active_hand() - if(istype(C) && !istype(inserted_id)) - if(!usr.drop_item()) - return - C.forceMove(src) - inserted_id = C - interact(user) - return - ..() - -/obj/machinery/mineral/equipment_vendor/proc/RedeemVoucher(obj/item/mining_voucher/voucher, mob/redeemer) - var/items = list("Kinetic Accelerator", "Survival Capsule and Explorer's Webbing", "Resonator Kit", "Minebot Kit", "Crusher Kit", "Mining Conscription Kit", "Advanced Scanner") - - var/selection = input(redeemer, "Pick your equipment", "Mining Voucher Redemption") as null|anything in items - if(!selection || !Adjacent(redeemer) || QDELETED(voucher) || voucher.loc != redeemer) - return - - var/drop_location = loc - switch(selection) - if("Kinetic Accelerator") - new /obj/item/gun/energy/kinetic_accelerator(drop_location) - if("Survival Capsule and Explorer's Webbing") - new /obj/item/storage/belt/mining(drop_location) - if("Resonator Kit") - new /obj/item/extinguisher/mini(drop_location) - new /obj/item/resonator(drop_location) - if("Minebot Kit") - new /obj/item/mining_drone_cube(drop_location) - new /obj/item/weldingtool/hugetank(drop_location) - new /obj/item/clothing/head/welding(drop_location) - if("Crusher Kit") - new /obj/item/extinguisher/mini(drop_location) - new /obj/item/twohanded/required/kinetic_crusher(drop_location) - if("Mining Conscription Kit") - new /obj/item/storage/backpack/duffel/mining_conscript(drop_location) - if("Advanced Scanner") - new /obj/item/t_scanner/adv_mining_scanner(drop_location) - - qdel(voucher) - -/obj/machinery/mineral/equipment_vendor/ex_act(severity, target) - do_sparks(5, 1, src) - if(prob(50 / severity) && severity < 3) - qdel(src) - -/**********************Mining Equipment Locker Items**************************/ - -/**********************Mining Equipment Voucher**********************/ - -/obj/item/mining_voucher - name = "mining voucher" - desc = "A token to redeem a piece of equipment. Use it on a mining equipment vendor." - icon = 'icons/obj/items.dmi' - icon_state = "mining_voucher" - w_class = WEIGHT_CLASS_TINY - -/**********************Mining Point Card**********************/ - -/obj/item/card/mining_point_card - name = "mining point card" - desc = "A small card preloaded with mining points. Swipe your ID card over it to transfer the points, then discard." - icon_state = "data" - var/points = 500 - -/obj/item/card/mining_point_card/attackby(obj/item/I, mob/user, params) - if(istype(I, /obj/item/card/id)) - if(points) - var/obj/item/card/id/C = I - C.mining_points += points - to_chat(user, "You transfer [points] points to [C].") - points = 0 - else - to_chat(user, "There's no points left on [src].") - ..() - -/obj/item/card/mining_point_card/examine(mob/user) - ..(user) - to_chat(user, "There's [points] points on the card.") - -/**********************Conscription Kit**********************/ - -/obj/item/card/id/mining_access_card - name = "mining access card" - desc = "A small card, that when used on any ID, will add mining access." - icon_state = "data_1" - -/obj/item/card/id/mining_access_card/afterattack(atom/movable/AM, mob/user, proximity) - . = ..() - if(istype(AM, /obj/item/card/id) && proximity) - var/obj/item/card/id/I = AM - I.access |= list(access_mining, access_mining_station, access_mineral_storeroom, access_cargo) - to_chat(user, "You upgrade [I] with mining access.") - qdel(src) - -/obj/item/storage/backpack/duffel/mining_conscript - name = "mining conscription kit" - desc = "A kit containing everything a crewmember needs to support a shaft miner in the field." - -/obj/item/storage/backpack/duffel/mining_conscript/New() - ..() - new /obj/item/pickaxe(src) - new /obj/item/clothing/glasses/meson(src) - new /obj/item/t_scanner/adv_mining_scanner/lesser(src) - new /obj/item/storage/bag/ore(src) - new /obj/item/clothing/under/rank/miner/lavaland(src) - new /obj/item/encryptionkey/headset_cargo(src) - new /obj/item/clothing/mask/gas(src) - new /obj/item/card/id/mining_access_card(src) - -/**********************Jaunter**********************/ - -/obj/item/wormhole_jaunter - name = "wormhole jaunter" - desc = "A single use device harnessing outdated wormhole technology, Nanotrasen has since turned its eyes to bluespace for more accurate teleportation. The wormholes it creates are unpleasant to travel through, to say the least.\nThanks to modifications provided by the Free Golems, this jaunter can be worn on the belt to provide protection from chasms." - icon = 'icons/obj/items.dmi' - icon_state = "Jaunter" - item_state = "electronic" - throwforce = 0 - w_class = WEIGHT_CLASS_SMALL - throw_speed = 3 - throw_range = 5 - origin_tech = "bluespace=2" - slot_flags = SLOT_BELT - -/obj/item/wormhole_jaunter/attack_self(mob/user) - user.visible_message("[user.name] activates the [name]!") - activate(user, TRUE) - -/obj/item/wormhole_jaunter/proc/turf_check(mob/user) - var/turf/device_turf = get_turf(user) - if(!device_turf || !is_teleport_allowed(device_turf.z)) - to_chat(user, "You're having difficulties getting the [name] to work.") - return FALSE - return TRUE - -/obj/item/wormhole_jaunter/proc/get_destinations(mob/user) - var/list/destinations = list() - - for(var/obj/item/radio/beacon/B in world) - var/turf/T = get_turf(B) - if(is_station_level(T.z)) - destinations += B - - return destinations - -/obj/item/wormhole_jaunter/proc/activate(mob/user, adjacent) - if(!turf_check(user)) - return - - var/list/L = get_destinations(user) - if(!L.len) - to_chat(user, "The [name] found no beacons in the world to anchor a wormhole to.") - return - var/chosen_beacon = pick(L) - var/obj/effect/portal/jaunt_tunnel/J = new(get_turf(src), get_turf(chosen_beacon), src, 100) - if(adjacent) - try_move_adjacent(J) - else - J.teleport(user) - playsound(src,'sound/effects/sparks4.ogg',50,1) - qdel(src) - -/obj/item/wormhole_jaunter/proc/chasm_react(mob/user) - if(user.get_item_by_slot(slot_belt) == src) - to_chat(user, "Your [name] activates, saving you from the chasm!") - activate(user, FALSE) - else - to_chat(user, "[src] is not attached to your belt, preventing it from saving you from the chasm. RIP.") - -/obj/effect/portal/jaunt_tunnel - name = "jaunt tunnel" - icon = 'icons/effects/effects.dmi' - icon_state = "bhole3" - desc = "A stable hole in the universe made by a wormhole jaunter. Turbulent doesn't even begin to describe how rough passage through one of these is, but at least it will always get you somewhere near a beacon." - failchance = 0 - -/obj/effect/portal/jaunt_tunnel/teleport(atom/movable/M) - . = ..() - if(.) - // KERPLUNK - playsound(M,'sound/weapons/resonator_blast.ogg', 50, 1) - if(iscarbon(M)) - var/mob/living/carbon/L = M - L.Weaken(6) - if(ishuman(L)) - shake_camera(L, 20, 1) - addtimer(CALLBACK(L, /mob/living/carbon.proc/vomit), 20) - -/**********************Resonator**********************/ - -/obj/item/resonator - name = "resonator" - icon = 'icons/obj/items.dmi' - icon_state = "resonator" - item_state = "resonator" - origin_tech = "magnets=3;engineering=3" - desc = "A handheld device that creates small fields of energy that resonate until they detonate, crushing rock. It can also be activated without a target to create a field at the user's location, to act as a delayed time trap. It's more effective in a vaccuum." - w_class = WEIGHT_CLASS_NORMAL - force = 8 - throwforce = 10 - var/cooldown = 0 - var/fieldsactive = 0 - var/burst_time = 50 - var/fieldlimit = 3 - -/obj/item/resonator/upgraded - name = "upgraded resonator" - desc = "An upgraded version of the resonator that can produce more fields at once." - icon_state = "resonator_u" - origin_tech = "materials=4;powerstorage=3;engineering=3;magnets=3" - fieldlimit = 5 - -/obj/item/resonator/proc/CreateResonance(var/target, var/creator) - var/turf/T = get_turf(target) - if(locate(/obj/effect/resonance) in T) - return - if(fieldsactive < fieldlimit) - playsound(src,'sound/weapons/resonator_fire.ogg',50,1) - new /obj/effect/resonance(T, creator, burst_time) - fieldsactive++ - spawn(burst_time) - fieldsactive-- - -/obj/item/resonator/attack_self(mob/user) - if(burst_time == 50) - burst_time = 30 - to_chat(user, "You set the resonator's fields to detonate after 3 seconds.") - else - burst_time = 50 - to_chat(user, "You set the resonator's fields to detonate after 5 seconds.") - -/obj/item/resonator/afterattack(atom/target, mob/user, proximity_flag) - if(proximity_flag) - if(!check_allowed_items(target, 1)) return - CreateResonance(target, user) - -/obj/effect/resonance - name = "resonance field" - desc = "A resonating field that significantly damages anything inside of it when the field eventually ruptures." - icon = 'icons/effects/effects.dmi' - icon_state = "shield1" - layer = 4.1 - mouse_opacity = MOUSE_OPACITY_TRANSPARENT - var/resonance_damage = 20 - -/obj/effect/resonance/New(loc, var/creator = null, var/timetoburst) - var/turf/proj_turf = get_turf(src) - if(!istype(proj_turf)) - return - if(istype(proj_turf, /turf/simulated/mineral)) - var/turf/simulated/mineral/M = proj_turf - spawn(timetoburst) - playsound(src,'sound/weapons/resonator_blast.ogg',50,1) - M.gets_drilled(creator) - qdel(src) - else - var/datum/gas_mixture/environment = proj_turf.return_air() - var/pressure = environment.return_pressure() - if(pressure < 50) - name = "strong resonance field" - resonance_damage = 50 - spawn(timetoburst) - playsound(src,'sound/weapons/resonator_blast.ogg',50,1) - if(creator) - for(var/mob/living/L in src.loc) - add_attack_logs(creator, L, "Resonance field'ed") - to_chat(L, "The [src.name] ruptured with you in it!") - L.adjustBruteLoss(resonance_damage) - else - for(var/mob/living/L in src.loc) - to_chat(L, "The [src.name] ruptured with you in it!") - L.adjustBruteLoss(resonance_damage) - qdel(src) - -/**********************Facehugger toy**********************/ - -/obj/item/clothing/mask/facehugger/toy - item_state = "facehugger_inactive" - desc = "A toy often used to play pranks on other miners by putting it in their beds. It takes a bit to recharge after latching onto something." - throwforce = 0 - real = 0 - sterile = 1 - tint = 3 //Makes it feel more authentic when it latches on - -/obj/item/clothing/mask/facehugger/toy/Die() - return - - -/**********************Mining drone cube**********************/ - -/obj/item/mining_drone_cube - name = "mining drone cube" - desc = "Compressed mining drone, ready for deployment. Just press the button to activate!" - w_class = WEIGHT_CLASS_SMALL - icon = 'icons/obj/aibots.dmi' - icon_state = "minedronecube" - item_state = "electronic" - -/obj/item/mining_drone_cube/attack_self(mob/user) - user.visible_message("\The [src] suddenly expands into a fully functional mining drone!", \ - "You press center button on \the [src]. The device suddenly expands into a fully functional mining drone!") - new /mob/living/simple_animal/hostile/mining_drone(get_turf(src)) - qdel(src) - -/**********************Lazarus Injector**********************/ - -/obj/item/lazarus_injector - name = "lazarus injector" - desc = "An injector with a cocktail of nanomachines and chemicals, this device can seemingly raise animals from the dead, making them become friendly to the user. Unfortunately, the process is useless on higher forms of life and incredibly costly, so these were hidden in storage until an executive thought they'd be great motivation for some of their employees." - icon = 'icons/obj/hypo.dmi' - icon_state = "lazarus_hypo" - item_state = "hypo" - origin_tech = "biotech=4;magnets=6" - throwforce = 0 - w_class = WEIGHT_CLASS_SMALL - throw_speed = 3 - throw_range = 5 - var/loaded = 1 - var/malfunctioning = 0 - var/revive_type = SENTIENCE_ORGANIC //So you can't revive boss monsters or robots with it - -/obj/item/lazarus_injector/afterattack(atom/target, mob/user, proximity_flag) - if(!loaded) - return - if(istype(target, /mob/living) && proximity_flag) - if(istype(target, /mob/living/simple_animal)) - var/mob/living/simple_animal/M = target - if(M.sentience_type != revive_type) - to_chat(user, "[src] does not work on this sort of creature.") - return - if(M.stat == DEAD) - M.faction = list("neutral") - M.revive() - M.can_collar = 1 - if(istype(target, /mob/living/simple_animal/hostile)) - var/mob/living/simple_animal/hostile/H = M - if(malfunctioning) - H.faction |= list("lazarus", "\ref[user]") - H.robust_searching = 1 - H.friends += user - H.attack_same = 1 - log_game("[user] has revived hostile mob [target] with a malfunctioning lazarus injector") - else - H.attack_same = 0 - loaded = 0 - user.visible_message("[user] injects [M] with [src], reviving it.") - playsound(src,'sound/effects/refill.ogg',50,1) - icon_state = "lazarus_empty" - return - else - to_chat(user, "[src] is only effective on the dead.") - return - else - to_chat(user, "[src] is only effective on lesser beings.") - return - -/obj/item/lazarus_injector/emag_act(mob/user) - if(!malfunctioning) - malfunctioning = 1 - to_chat(user, "You override [src]'s safety protocols.") - -/obj/item/lazarus_injector/emp_act() - if(!malfunctioning) - malfunctioning = 1 - -/obj/item/lazarus_injector/examine(mob/user) - ..(user) - if(!loaded) - to_chat(user, "[src] is empty.") - if(malfunctioning) - to_chat(user, "The display on [src] seems to be flickering.") - -/**********************Mining Scanner**********************/ - -/obj/item/mining_scanner - desc = "A scanner that checks surrounding rock for useful minerals; it can also be used to stop gibtonite detonations. Wear material scanners for optimal results." - name = "manual mining scanner" - icon = 'icons/obj/device.dmi' - icon_state = "mining1" - item_state = "analyzer" - w_class = WEIGHT_CLASS_SMALL - flags = CONDUCT - slot_flags = SLOT_BELT - var/cooldown = 0 - origin_tech = "engineering=1;magnets=1" - -/obj/item/mining_scanner/attack_self(mob/user) - if(!user.client) - return - if(!cooldown) - cooldown = 1 - spawn(40) - cooldown = 0 - var/list/mobs = list() - mobs |= user - mineral_scan_pulse(mobs, get_turf(user)) - - -//Debug item to identify all ore spread quickly -/obj/item/mining_scanner/admin - -/obj/item/mining_scanner/admin/attack_self(mob/user) - for(var/turf/simulated/mineral/M in world) - if(M.scan_state) - M.icon_state = M.scan_state - qdel(src) - -/obj/item/t_scanner/adv_mining_scanner - desc = "A scanner that automatically checks surrounding rock for useful minerals; it can also be used to stop gibtonite detonations. Wear meson scanners for optimal results. This one has an extended range." - name = "advanced automatic mining scanner" - icon_state = "mining0" - item_state = "analyzer" - w_class = WEIGHT_CLASS_SMALL - flags = CONDUCT - slot_flags = SLOT_BELT - var/cooldown = 35 - var/on_cooldown = 0 - var/range = 7 - var/meson = TRUE - origin_tech = "engineering=3;magnets=3" - -/obj/item/t_scanner/adv_mining_scanner/cyborg - flags = CONDUCT | NODROP - -/obj/item/t_scanner/adv_mining_scanner/material - meson = FALSE - desc = "A scanner that automatically checks surrounding rock for useful minerals; it can also be used to stop gibtonite detonations. Wear material scanners for optimal results. This one has an extended range." - -/obj/item/t_scanner/adv_mining_scanner/lesser - name = "automatic mining scanner" - desc = "A scanner that automatically checks surrounding rock for useful minerals; it can also be used to stop gibtonite detonations. Wear meson scanners for optimal results." - range = 4 - cooldown = 50 - -/obj/item/t_scanner/adv_mining_scanner/lesser/material - desc = "A scanner that automatically checks surrounding rock for useful minerals; it can also be used to stop gibtonite detonations. Wear material scanners for optimal results." - meson = FALSE - -/obj/item/t_scanner/adv_mining_scanner/scan() - if(!on_cooldown) - on_cooldown = 1 - spawn(cooldown) - on_cooldown = 0 - var/turf/t = get_turf(src) - var/list/mobs = recursive_mob_check(t, client_check = 1, sight_check = 0, include_radio = 0) - if(!mobs.len) - return - if(meson) - mineral_scan_pulse(mobs, t, range) - else - mineral_scan_pulse_material(mobs, t, range) - -//For use with mesons -/proc/mineral_scan_pulse(list/mobs, turf/T, range = world.view) - var/list/minerals = list() - for(var/turf/simulated/mineral/M in range(range, T)) - if(M.scan_state) - minerals += M - if(minerals.len) - for(var/mob/user in mobs) - if(user.client) - var/client/C = user.client - for(var/turf/simulated/mineral/M in minerals) - var/turf/F = get_turf(M) - var/image/I = image('icons/turf/mining.dmi', loc = F, icon_state = M.scan_state, layer = 18) - C.images += I - spawn(30) - if(C) - C.images -= I - -//For use with material scanners -/proc/mineral_scan_pulse_material(list/mobs, turf/T, range = world.view) - var/list/minerals = list() - for(var/turf/simulated/mineral/M in range(range, T)) - if(M.scan_state) - minerals += M - if(minerals.len) - for(var/turf/simulated/mineral/M in minerals) - var/obj/effect/temp_visual/mining_overlay/C = new/obj/effect/temp_visual/mining_overlay(M) - C.icon_state = M.scan_state - -/obj/effect/temp_visual/mining_overlay - layer = 18 - icon = 'icons/turf/mining.dmi' - anchored = 1 - mouse_opacity = MOUSE_OPACITY_TRANSPARENT - duration = 30 - pixel_x = -4 - pixel_y = -4 - -/**********************Xeno Warning Sign**********************/ -/obj/structure/sign/xeno_warning_mining - name = "DANGEROUS ALIEN LIFE" - desc = "A sign that warns would be travellers of hostile alien life in the vicinity." - icon = 'icons/obj/mining.dmi' - icon_state = "xeno_warning" - -/**********************Mining Jetpack**********************/ -/obj/item/tank/jetpack/carbondioxide/mining - name = "mining jetpack" - icon_state = "jetpack-mining" - item_state = "jetpack-mining" - origin_tech = "materials=4;magnets=4;engineering=5" - desc = "A tank of compressed carbon dioxide for miners to use as propulsion in local space. The compact size allows for easy storage at the cost of capacity." - volume = 40 - throw_range = 7 - w_class = WEIGHT_CLASS_NORMAL //same as syndie harness - -/*********************Hivelord stabilizer****************/ - -/obj/item/hivelordstabilizer - name = "hivelord stabilizer" - icon = 'icons/obj/chemical.dmi' - icon_state = "bottle19" - desc = "Inject a hivelord core with this stabilizer to preserve its healing powers indefinitely." - w_class = WEIGHT_CLASS_TINY - origin_tech = "biotech=3" - -/obj/item/hivelordstabilizer/afterattack(obj/item/organ/internal/M, mob/user) - var/obj/item/organ/internal/hivelord_core/C = M - if(!istype(C, /obj/item/organ/internal/hivelord_core)) - to_chat(user, "The stabilizer only works on hivelord cores.") - return ..() - C.preserved = 1 - to_chat(user, "You inject the hivelord core with the stabilizer. It will no longer go inert.") - qdel(src) - -/*********************Mining Hammer****************/ -/obj/item/twohanded/required/kinetic_crusher - icon = 'icons/obj/mining.dmi' - icon_state = "mining_hammer1" - item_state = "mining_hammer1" - name = "proto-kinetic crusher" - desc = "An early design of the proto-kinetic accelerator, it is little more than an combination of various mining tools cobbled together, forming a high-tech club.\ - While it is an effective mining tool, it did little to aid any but the most skilled and/or suicidal miners against local fauna. \ - \nMark a mob with the destabilizing force, then hit them in melee to activate it for extra damage. Extra damage if backstabbed in this fashion. \ - This weapon is only particularly effective against large creatures." - force = 20 //As much as a bone spear, but this is significantly more annoying to carry around due to requiring the use of both hands at all times - w_class = WEIGHT_CLASS_BULKY - slot_flags = SLOT_BACK - force_unwielded = 20 //It's never not wielded so these are the same - force_wielded = 20 - throwforce = 5 - throw_speed = 4 - light_range = 4 - armour_penetration = 10 - materials = list(MAT_METAL=1150, MAT_GLASS=2075) - hitsound = 'sound/weapons/bladeslice.ogg' - attack_verb = list("smashes", "crushes", "cleaves", "chops", "pulps") - sharp = 1 - var/charged = 1 - var/charge_time = 16 - var/atom/mark = null - var/marked_image = null - -/obj/item/projectile/destabilizer - name = "destabilizing force" - icon_state = "pulse1" - damage = 0 //We're just here to mark people. This is still a melee weapon. - damage_type = BRUTE - flag = "bomb" - range = 6 - var/obj/item/twohanded/required/kinetic_crusher/hammer_synced = null - -/obj/item/projectile/destabilizer/on_hit(atom/target, blocked = 0, hit_zone) - if(hammer_synced) - if(hammer_synced.mark == target) - return ..() - if(isliving(target)) - if(hammer_synced.mark && hammer_synced.marked_image) - hammer_synced.mark.underlays -= hammer_synced.marked_image - hammer_synced.marked_image = null - var/mob/living/L = target - if(L.mob_size >= MOB_SIZE_LARGE) - hammer_synced.mark = L - var/image/I = image('icons/effects/effects.dmi', loc = L, icon_state = "shield2",pixel_y = (-L.pixel_y),pixel_x = (-L.pixel_x)) - L.underlays += I - hammer_synced.marked_image = I - var/target_turf = get_turf(target) - if(istype(target_turf, /turf/simulated/mineral)) - var/turf/simulated/mineral/M = target_turf - new /obj/effect/temp_visual/kinetic_blast(M) - M.gets_drilled(firer) - ..() - -/obj/item/twohanded/required/kinetic_crusher/afterattack(atom/target, mob/user, proximity_flag) - if(!proximity_flag && charged)//Mark a target, or mine a tile. - var/turf/proj_turf = get_turf(src) - if(!istype(proj_turf, /turf)) - return - var/datum/gas_mixture/environment = proj_turf.return_air() - var/pressure = environment.return_pressure() - if(pressure > 50) - playsound(user, 'sound/weapons/empty.ogg', 100, 1) - return - var/obj/item/projectile/destabilizer/D = new /obj/item/projectile/destabilizer(user.loc) - D.preparePixelProjectile(target,get_turf(target), user) - D.hammer_synced = src - playsound(user, 'sound/weapons/plasma_cutter.ogg', 100, 1) - D.fire() - charged = 0 - icon_state = "mining_hammer1_uncharged" - spawn(charge_time) - Recharge() - return - if(proximity_flag && target == mark && isliving(target)) - var/mob/living/L = target - new /obj/effect/temp_visual/kinetic_blast(get_turf(L)) - mark = 0 - if(L.mob_size >= MOB_SIZE_LARGE) - L.underlays -= marked_image - QDEL_NULL(marked_image) - var/backstab = check_target_facings(user, L) - var/def_check = L.getarmor(type = "bomb") - if(backstab == FACING_INIT_FACING_TARGET_TARGET_FACING_PERPENDICULAR || backstab == FACING_SAME_DIR) - L.apply_damage(80, BRUTE, blocked = def_check) - playsound(user, 'sound/weapons/kenetic_accel.ogg', 100, 1) //Seriously who spelled it wrong - else - L.apply_damage(50, BRUTE, blocked = def_check) - -/obj/item/twohanded/required/kinetic_crusher/proc/Recharge() - if(!charged) - charged = 1 - icon_state = "mining_hammer1" - playsound(loc, 'sound/weapons/kenetic_reload.ogg', 60, 1) diff --git a/code/modules/mining/explorer_gear.dm b/code/modules/mining/explorer_gear.dm deleted file mode 100644 index a9464efe959..00000000000 --- a/code/modules/mining/explorer_gear.dm +++ /dev/null @@ -1,44 +0,0 @@ -/****************Explorer's Suit and Mask****************/ -/obj/item/clothing/suit/hooded/explorer - name = "explorer suit" - desc = "An armoured suit for exploring harsh environments." - icon_state = "explorer" - item_state = "explorer" - body_parts_covered = UPPER_TORSO|LOWER_TORSO|LEGS|ARMS - min_cold_protection_temperature = FIRE_SUIT_MIN_TEMP_PROTECT - cold_protection = UPPER_TORSO|LOWER_TORSO|LEGS|ARMS - max_heat_protection_temperature = FIRE_SUIT_MAX_TEMP_PROTECT - heat_protection = UPPER_TORSO|LOWER_TORSO|LEGS|ARMS - hoodtype = /obj/item/clothing/head/hooded/explorer - armor = list("melee" = 30, "bullet" = 20, "laser" = 20, "energy" = 20, "bomb" = 50, "bio" = 100, "rad" = 50, "fire" = 50, "acid" = 50) - allowed = list(/obj/item/flashlight, /obj/item/tank, /obj/item/resonator, /obj/item/mining_scanner, /obj/item/t_scanner/adv_mining_scanner, /obj/item/gun/energy/kinetic_accelerator, /obj/item/pickaxe) - resistance_flags = FIRE_PROOF - hide_tail_by_species = list("Vox" , "Vulpkanin" , "Unathi" , "Tajaran") - - sprite_sheets = list( - "Vox" = 'icons/mob/species/vox/suit.dmi', - "Drask" = 'icons/mob/species/drask/suit.dmi', - "Tajaran" = 'icons/mob/species/tajaran/suit.dmi', - "Unathi" = 'icons/mob/species/unathi/suit.dmi', - "Vulpkanin" = 'icons/mob/species/vulpkanin/suit.dmi' - ) - -/obj/item/clothing/head/hooded/explorer - name = "explorer hood" - desc = "An armoured hood for exploring harsh environments." - icon_state = "explorer" - item_state = "explorer" - body_parts_covered = HEAD - flags = BLOCKHAIR | NODROP - flags_cover = HEADCOVERSEYES - min_cold_protection_temperature = FIRE_HELM_MIN_TEMP_PROTECT - max_heat_protection_temperature = FIRE_HELM_MAX_TEMP_PROTECT - armor = list("melee" = 30, "bullet" = 20, "laser" = 20, "energy" = 20, "bomb" = 50, "bio" = 100, "rad" = 50, "fire" = 50, "acid" = 50) - resistance_flags = FIRE_PROOF - - sprite_sheets = list( - "Vox" = 'icons/mob/species/vox/head.dmi', - "Drask" = 'icons/mob/species/drask/head.dmi', - "Grey" = 'icons/mob/species/grey/head.dmi', - "Skrell" = 'icons/mob/species/skrell/head.dmi' - ) \ No newline at end of file diff --git a/code/modules/mining/fulton.dm b/code/modules/mining/fulton.dm new file mode 100644 index 00000000000..2d09c6a8e7a --- /dev/null +++ b/code/modules/mining/fulton.dm @@ -0,0 +1,195 @@ +GLOBAL_LIST_EMPTY(total_extraction_beacons) + +/obj/item/extraction_pack + name = "fulton extraction pack" + desc = "A balloon that can be used to extract equipment or personnel to a Fulton Recovery Beacon. Anything not bolted down can be moved. Link the pack to a beacon by using the pack in hand." + icon = 'icons/obj/fulton.dmi' + icon_state = "extraction_pack" + w_class = WEIGHT_CLASS_NORMAL + var/obj/structure/extraction_point/beacon + var/list/beacon_networks = list("station") + var/uses_left = 3 + var/can_use_indoors + var/safe_for_living_creatures = TRUE + var/max_force_fulton = MOVE_FORCE_STRONG + +/obj/item/extraction_pack/examine(mob/user) + ..() + to_chat(user, "It has [uses_left] use\s remaining.") + +/obj/item/extraction_pack/attack_self(mob/user) + var/list/possible_beacons = list() + for(var/B in GLOB.total_extraction_beacons) + var/obj/structure/extraction_point/EP = B + if(EP.beacon_network in beacon_networks) + possible_beacons += EP + + if(!possible_beacons.len) + to_chat(user, "There are no extraction beacons in existence!") + return + + else + var/A + + A = input("Select a beacon to connect to", "Balloon Extraction Pack", A) as null|anything in possible_beacons + + if(!A) + return + beacon = A + to_chat(user, "You link the extraction pack to the beacon system.") + +/obj/item/extraction_pack/afterattack(atom/movable/A, mob/living/carbon/human/user, flag, params) + . = ..() + if(!beacon) + to_chat(user, "[src] is not linked to a beacon, and cannot be used!") + return + if(!can_use_indoors) + var/area/area = get_area(A) + if(!area.outdoors) + to_chat(user, "[src] can only be used on things that are outdoors!") + return + if(!flag) + return + if(!istype(A)) + return + else + if(!safe_for_living_creatures && check_for_living_mobs(A)) + to_chat(user, "[src] is not safe for use with living creatures, they wouldn't survive the trip back!") + return + if(!isturf(A.loc)) // no extracting stuff inside other stuff + return + if(A.anchored || (A.move_resist > max_force_fulton)) + return + to_chat(user, "You start attaching the pack to [A]...") + if(do_after(user, 50, target = A)) + to_chat(user, "You attach the pack to [A] and activate it.") + if(loc == user && istype(user.back, /obj/item/storage/backpack)) + var/obj/item/storage/backpack/B = user.back + if(B.can_be_inserted(src, stop_messages = TRUE)) + B.handle_item_insertion(src) + uses_left-- + if(uses_left <= 0) + user.drop_item(src) + forceMove(A) + var/mutable_appearance/balloon + var/mutable_appearance/balloon2 + var/mutable_appearance/balloon3 + if(isliving(A)) + var/mob/living/M = A + M.Weaken(16) // Keep them from moving during the duration of the extraction + M.buckled = 0 // Unbuckle them to prevent anchoring problems + else + A.anchored = TRUE + A.density = FALSE + var/obj/effect/extraction_holder/holder_obj = new(A.loc) + holder_obj.appearance = A.appearance + A.forceMove(holder_obj) + balloon2 = mutable_appearance('icons/obj/fulton_balloon.dmi', "fulton_expand") + balloon2.pixel_y = 10 + balloon2.appearance_flags = RESET_COLOR | RESET_ALPHA | RESET_TRANSFORM + holder_obj.add_overlay(balloon2) + sleep(4) + balloon = mutable_appearance('icons/obj/fulton_balloon.dmi', "fulton_balloon") + balloon.pixel_y = 10 + balloon.appearance_flags = RESET_COLOR | RESET_ALPHA | RESET_TRANSFORM + holder_obj.cut_overlay(balloon2) + holder_obj.add_overlay(balloon) + playsound(holder_obj.loc, 'sound/items/fultext_deploy.ogg', 50, 1, -3) + animate(holder_obj, pixel_z = 10, time = 20) + sleep(20) + animate(holder_obj, pixel_z = 15, time = 10) + sleep(10) + animate(holder_obj, pixel_z = 10, time = 10) + sleep(10) + animate(holder_obj, pixel_z = 15, time = 10) + sleep(10) + animate(holder_obj, pixel_z = 10, time = 10) + sleep(10) + playsound(holder_obj.loc, 'sound/items/fultext_launch.ogg', 50, 1, -3) + animate(holder_obj, pixel_z = 1000, time = 30) + if(ishuman(A)) + var/mob/living/carbon/human/L = A + L.SetParalysis(0) + L.drowsyness = 0 + L.SetSleeping(0) + sleep(30) + var/list/flooring_near_beacon = list() + for(var/turf/floor in orange(1, beacon)) + if(floor.density) + continue + flooring_near_beacon += floor + holder_obj.forceMove(pick(flooring_near_beacon)) + animate(holder_obj, pixel_z = 10, time = 50) + sleep(50) + animate(holder_obj, pixel_z = 15, time = 10) + sleep(10) + animate(holder_obj, pixel_z = 10, time = 10) + sleep(10) + balloon3 = mutable_appearance('icons/obj/fulton_balloon.dmi', "fulton_retract") + balloon3.pixel_y = 10 + balloon3.appearance_flags = RESET_COLOR | RESET_ALPHA | RESET_TRANSFORM + holder_obj.cut_overlay(balloon) + holder_obj.add_overlay(balloon3) + sleep(4) + holder_obj.cut_overlay(balloon3) + A.anchored = FALSE // An item has to be unanchored to be extracted in the first place. + A.density = initial(A.density) + animate(holder_obj, pixel_z = 0, time = 5) + sleep(5) + A.forceMove(holder_obj.loc) + qdel(holder_obj) + if(uses_left <= 0) + qdel(src) + + +/obj/item/fulton_core + name = "extraction beacon signaller" + desc = "Emits a signal which fulton recovery devices can lock onto. Activate in hand to create a beacon." + icon = 'icons/obj/stock_parts.dmi' + icon_state = "subspace_amplifier" + +/obj/item/fulton_core/attack_self(mob/user) + if(do_after(user, 15, target = user) && !QDELETED(src)) + new /obj/structure/extraction_point(get_turf(user)) + qdel(src) + +/obj/structure/extraction_point + name = "fulton recovery beacon" + desc = "A beacon for the fulton recovery system. Activate a pack in your hand to link it to a beacon." + icon = 'icons/obj/fulton.dmi' + icon_state = "extraction_point" + anchored = TRUE + density = FALSE + var/beacon_network = "station" + +/obj/structure/extraction_point/New() + ..() + name += " ([rand(100,999)]) ([get_location_name(src)])" + GLOB.total_extraction_beacons += src + +/obj/structure/extraction_point/Destroy() + GLOB.total_extraction_beacons -= src + return ..() + +/obj/effect/extraction_holder + name = "extraction holder" + desc = "you shouldnt see this" + var/atom/movable/stored_obj + +/obj/item/extraction_pack/proc/check_for_living_mobs(atom/A) + if(isliving(A)) + var/mob/living/L = A + if(L.stat != DEAD) + return TRUE + for(var/thing in A.GetAllContents()) + if(isliving(A)) + var/mob/living/L = A + if(L.stat != DEAD) + return TRUE + return FALSE + +/obj/effect/extraction_holder/singularity_pull() + return + +/obj/effect/extraction_holder/singularity_pull() + return \ No newline at end of file diff --git a/code/modules/mining/lavaland/loot/ashdragon_loot.dm b/code/modules/mining/lavaland/loot/ashdragon_loot.dm index 4f8f01498d0..6a30c565547 100644 --- a/code/modules/mining/lavaland/loot/ashdragon_loot.dm +++ b/code/modules/mining/lavaland/loot/ashdragon_loot.dm @@ -15,6 +15,15 @@ if(4) new /obj/item/dragons_blood(src) + +/obj/structure/closet/crate/necropolis/dragon/crusher + name = "firey dragon chest" + +/obj/structure/closet/crate/necropolis/dragon/crusher/New() + ..() + new /obj/item/crusher_trophy/tail_spike(src) + + // Spectral Blade /obj/item/melee/ghost_sword diff --git a/code/modules/mining/lavaland/loot/bubblegum_loot.dm b/code/modules/mining/lavaland/loot/bubblegum_loot.dm index bb0031ea77d..6cc33e1ad92 100644 --- a/code/modules/mining/lavaland/loot/bubblegum_loot.dm +++ b/code/modules/mining/lavaland/loot/bubblegum_loot.dm @@ -3,6 +3,8 @@ /obj/structure/closet/crate/necropolis/bubblegum/New() ..() + new /obj/item/clothing/suit/space/hostile_environment(src) + new /obj/item/clothing/head/helmet/space/hostile_environment(src) var/loot = rand(1,3) switch(loot) if(1) @@ -12,6 +14,13 @@ if(3) new /obj/item/gun/magic/staff/spellblade(src) +/obj/structure/closet/crate/necropolis/bubblegum/crusher + name = "bloody bubblegum chest" + +/obj/structure/closet/crate/necropolis/bubblegum/crusher/New() + ..() + new /obj/item/crusher_trophy/demon_claws(src) + // Mayhem /obj/item/mayhem diff --git a/code/modules/mining/lavaland/loot/colossus_loot.dm b/code/modules/mining/lavaland/loot/colossus_loot.dm index 2490f6f48db..9b6bd8c5893 100644 --- a/code/modules/mining/lavaland/loot/colossus_loot.dm +++ b/code/modules/mining/lavaland/loot/colossus_loot.dm @@ -1,3 +1,22 @@ +//Colossus +/obj/structure/closet/crate/necropolis/colossus + name = "colossus chest" + +/obj/structure/closet/crate/necropolis/colossus/New() + ..() + var/list/choices = subtypesof(/obj/machinery/anomalous_crystal) + var/random_crystal = pick(choices) + new random_crystal(src) + new /obj/item/organ/internal/vocal_cords/colossus(src) + +/obj/structure/closet/crate/necropolis/colossus/crusher + name = "angelic colossus chest" + +/obj/structure/closet/crate/necropolis/colossus/crusher/New() + ..() + new /obj/item/crusher_trophy/blaster_tubes(src) + + //Black Box /obj/machinery/smartfridge/black_box diff --git a/code/modules/mining/lavaland/loot/tendril_loot.dm b/code/modules/mining/lavaland/loot/tendril_loot.dm index c8579fbec65..3727c103a64 100644 --- a/code/modules/mining/lavaland/loot/tendril_loot.dm +++ b/code/modules/mining/lavaland/loot/tendril_loot.dm @@ -77,6 +77,21 @@ add_fingerprint(M) +//Book of Babel + +/obj/item/book_of_babel + name = "Book of Babel" + desc = "An ancient tome written in countless tongues." + icon = 'icons/obj/library.dmi' + icon_state = "book1" + w_class = 2 + +/obj/item/book_of_babel/attack_self(mob/user) + to_chat(user, "You flip through the pages of the book, quickly and conveniently learning every language in existence. Somewhat less conveniently, the aging book crumbles to dust in the process. Whoops.") + user.grant_all_languages() + new /obj/effect/decal/cleanable/ash(get_turf(user)) + qdel(src) + //Potion of Flight: as we do not have the "Angel" species this currently does not work. /obj/item/reagent_containers/glass/bottle/potion @@ -117,6 +132,30 @@ H.emote("scream") ..()*/ +/obj/item/jacobs_ladder + name = "jacob's ladder" + desc = "A celestial ladder that violates the laws of physics." + icon = 'icons/obj/structures.dmi' + icon_state = "ladder00" + +/obj/item/jacobs_ladder/attack_self(mob/user) + var/turf/T = get_turf(src) + var/ladder_x = T.x + var/ladder_y = T.y + to_chat(user, "You unfold the ladder. It extends much farther than you were expecting.") + var/last_ladder = null + for(var/i in 1 to world.maxz) + if(is_admin_level(i) || is_away_level(i)) + continue + var/turf/T2 = locate(ladder_x, ladder_y, i) + last_ladder = new /obj/structure/ladder/unbreakable/jacob(T2, null, last_ladder) + qdel(src) + +// Inherit from unbreakable but don't set ID, to suppress the default Z linkage +/obj/structure/ladder/unbreakable/jacob + name = "jacob's ladder" + desc = "An indestructible celestial ladder that violates the laws of physics." + //Boat /obj/vehicle/lavaboat diff --git a/code/modules/mining/lavaland/necropolis_chests.dm b/code/modules/mining/lavaland/necropolis_chests.dm index 7eed5577aeb..1a0a063e33f 100644 --- a/code/modules/mining/lavaland/necropolis_chests.dm +++ b/code/modules/mining/lavaland/necropolis_chests.dm @@ -8,18 +8,18 @@ icon_closed = "necrocrate" burn_state = LAVA_PROOF | FIRE_PROOF unacidable = 1 - + /obj/structure/closet/crate/necropolis/tendril desc = "It's watching you suspiciously." /obj/structure/closet/crate/necropolis/tendril/New(add_loot = TRUE) ..() - + if(!add_loot) return - var/loot = rand(1,24) - switch(loot) + var/loot = rand(1, 26) + switch(loot) if(1) new /obj/item/shared_storage/red(src) if(2) @@ -37,16 +37,18 @@ new /obj/item/clothing/suit/hooded/cultrobes(src) new /obj/item/bedsheet/cult(src) if(8) - new /obj/item/organ/internal/brain/xeno(src) + if(prob(50)) + new /obj/item/disk/design_disk/modkit_disc/resonator_blast(src) + else + new /obj/item/disk/design_disk/modkit_disc/rapid_repeater(src) if(9) new /obj/item/organ/internal/heart/cursed/wizard(src) if(10) new /obj/item/ship_in_a_bottle(src) if(11) - new /obj/item/clothing/head/helmet/space/hardsuit/ert/paranormal/berserker(src) new /obj/item/clothing/suit/space/hardsuit/ert/paranormal/berserker(src) if(12) - new /obj/item/sord(src) + new /obj/item/jacobs_ladder(src) if(13) new /obj/item/nullrod/scythe/talking(src) if(14) @@ -54,7 +56,10 @@ if(15) new /obj/item/guardiancreator(src) if(16) - new /obj/item/borg/upgrade/modkit/aoe/turfs/andmobs(src) + if(prob(50)) + new /obj/item/disk/design_disk/modkit_disc/mob_and_turf_aoe(src) + else + new /obj/item/disk/design_disk/modkit_disc/bounty(src) if(17) new /obj/item/warp_cube/red(src) if(18) @@ -69,10 +74,14 @@ new /obj/item/grenade/clusterbuster/inferno(src) if(23) new /obj/item/reagent_containers/food/drinks/bottle/holywater/hell(src) - new /obj/item/clothing/head/helmet/space/hardsuit/ert/paranormal/inquisitor(src) new /obj/item/clothing/suit/space/hardsuit/ert/paranormal/inquisitor(src) if(24) new /obj/item/spellbook/oneuse/summonitem(src) + if(25) + new /obj/item/book_of_babel(src) + if(26) + new /obj/item/borg/upgrade/modkit/lifesteal(src) + new /obj/item/bedsheet/cult(src) /obj/structure/closet/crate/necropolis/puzzle name = "puzzling chest" @@ -88,3 +97,63 @@ new /obj/item/wisp_lantern(src) if(3) new /obj/item/prisoncube(src) + +//KA modkit design discs +/obj/item/disk/design_disk/modkit_disc + name = "KA Mod Disk" + desc = "A design disc containing the design for a unique kinetic accelerator modkit. It's compatible with a research console." + icon_state = "datadisk1" + var/modkit_design = /datum/design/unique_modkit + +/obj/item/disk/design_disk/modkit_disc/New() + . = ..() + blueprint = new modkit_design + +/obj/item/disk/design_disk/modkit_disc/mob_and_turf_aoe + name = "Offensive Mining Explosion Mod Disk" + modkit_design = /datum/design/unique_modkit/offensive_turf_aoe + +/obj/item/disk/design_disk/modkit_disc/rapid_repeater + name = "Rapid Repeater Mod Disk" + modkit_design = /datum/design/unique_modkit/rapid_repeater + +/obj/item/disk/design_disk/modkit_disc/resonator_blast + name = "Resonator Blast Mod Disk" + modkit_design = /datum/design/unique_modkit/resonator_blast + +/obj/item/disk/design_disk/modkit_disc/bounty + name = "Death Syphon Mod Disk" + modkit_design = /datum/design/unique_modkit/bounty + +/datum/design/unique_modkit + category = list("Mining", "Cyborg Upgrade Modules") //can't be normally obtained + build_type = PROTOLATHE | MECHFAB + +/datum/design/unique_modkit/offensive_turf_aoe + name = "Kinetic Accelerator Offensive Mining Explosion Mod" + desc = "A device which causes kinetic accelerators to fire AoE blasts that destroy rock and damage creatures." + id = "hyperaoemod" + materials = list(MAT_METAL = 7000, MAT_GLASS = 3000, MAT_SILVER= 3000, MAT_GOLD = 3000, MAT_DIAMOND = 4000) + build_path = /obj/item/borg/upgrade/modkit/aoe/turfs/andmobs + +/datum/design/unique_modkit/rapid_repeater + name = "Kinetic Accelerator Rapid Repeater Mod" + desc = "A device which greatly reduces a kinetic accelerator's cooldown on striking a living target or rock, but greatly increases its base cooldown." + id = "repeatermod" + materials = list(MAT_METAL = 5000, MAT_GLASS = 5000, MAT_URANIUM = 8000, MAT_BLUESPACE = 2000) + build_path = /obj/item/borg/upgrade/modkit/cooldown/repeater + +/datum/design/unique_modkit/resonator_blast + name = "Kinetic Accelerator Resonator Blast Mod" + desc = "A device which causes kinetic accelerators to fire shots that leave and detonate resonator blasts." + id = "resonatormod" + materials = list(MAT_METAL = 5000, MAT_GLASS = 5000, MAT_SILVER= 5000, MAT_URANIUM = 5000) + build_path = /obj/item/borg/upgrade/modkit/resonator_blasts + +/datum/design/unique_modkit/bounty + name = "Kinetic Accelerator Death Syphon Mod" + desc = "A device which causes kinetic accelerators to permanently gain damage against creature types killed with it." + id = "bountymod" + materials = list(MAT_METAL = 4000, MAT_SILVER = 4000, MAT_GOLD = 4000, MAT_BLUESPACE = 4000) + reagents_list = list("blood" = 40) + build_path = /obj/item/borg/upgrade/modkit/bounty \ No newline at end of file diff --git a/code/modules/mining/machine_processing.dm b/code/modules/mining/machine_processing.dm index 03b8404b1f0..46daf596f8c 100644 --- a/code/modules/mining/machine_processing.dm +++ b/code/modules/mining/machine_processing.dm @@ -7,7 +7,7 @@ var/output_dir = SOUTH /obj/machinery/mineral/proc/unload_mineral(atom/movable/S) - S.forceMove(loc) + S.forceMove(drop_location()) var/turf/T = get_step(src,output_dir) if(T) S.forceMove(T) diff --git a/code/modules/mining/machine_redemption.dm b/code/modules/mining/machine_redemption.dm new file mode 100644 index 00000000000..696be4c6bfb --- /dev/null +++ b/code/modules/mining/machine_redemption.dm @@ -0,0 +1,391 @@ +/**********************Ore Redemption Unit**************************/ +//Turns all the various mining machines into a single unit to speed up mining and establish a point system + +/obj/machinery/mineral/ore_redemption + name = "ore redemption machine" + desc = "A machine that accepts ore and instantly transforms it into workable material sheets. Points for ore are generated based on type and can be redeemed at a mining equipment vendor." + icon = 'icons/obj/machines/mining_machines.dmi' + icon_state = "ore_redemption" + density = TRUE + anchored = TRUE + input_dir = NORTH + output_dir = SOUTH + req_access = list(access_mineral_storeroom) + speed_process = TRUE + layer = BELOW_OBJ_LAYER + var/req_access_reclaim = access_mining_station + var/obj/item/card/id/inserted_id + var/points = 0 + var/ore_pickup_rate = 15 + var/sheet_per_ore = 1 + var/point_upgrade = 1 + var/list/ore_values = list("sand" = 1, "iron" = 1, "plasma" = 15, "silver" = 16, "gold" = 18, "titanium" = 30, "uranium" = 30, "diamond" = 50, "bluespace crystal" = 50, "bananium" = 60, "tranquillite" = 60) + var/message_sent = FALSE + var/list/ore_buffer = list() + var/datum/research/files + var/obj/item/disk/design_disk/inserted_disk + var/list/supply_consoles = list("Science", "Robotics", "Research Director's Desk", "Mechanic", "Engineering" = list("metal", "glass", "plasma"), "Chief Engineer's Desk" = list("metal", "glass", "plasma"), "Atmospherics" = list("metal", "glass", "plasma"), "Bar" = list("uranium", "plasma"), "Virology" = list("plasma", "uranium", "gold")) + +/obj/machinery/mineral/ore_redemption/New() + ..() + AddComponent(/datum/component/material_container, list(MAT_METAL, MAT_GLASS, MAT_SILVER, MAT_GOLD, MAT_DIAMOND, MAT_PLASMA, MAT_URANIUM, MAT_BANANIUM, MAT_TRANQUILLITE, MAT_TITANIUM, MAT_BLUESPACE), INFINITY, FALSE, /obj/item/stack) + files = new /datum/research/smelter(src) + component_parts = list() + component_parts += new /obj/item/circuitboard/ore_redemption(null) + component_parts += new /obj/item/stock_parts/matter_bin(null) + component_parts += new /obj/item/stock_parts/manipulator(null) + component_parts += new /obj/item/stock_parts/micro_laser(null) + component_parts += new /obj/item/assembly/igniter(null) + component_parts += new /obj/item/stock_parts/console_screen(null) + RefreshParts() + +/obj/machinery/mineral/ore_redemption/upgraded/New() + ..() + component_parts = list() + component_parts += new /obj/item/circuitboard/ore_redemption(null) + component_parts += new /obj/item/stock_parts/matter_bin/super(null) + component_parts += new /obj/item/stock_parts/manipulator/pico(null) + component_parts += new /obj/item/stock_parts/micro_laser/ultra(null) + component_parts += new /obj/item/assembly/igniter(null) + component_parts += new /obj/item/stock_parts/console_screen(null) + RefreshParts() + +/obj/machinery/mineral/ore_redemption/golem + req_access = list(access_free_golems) + req_access_reclaim = access_free_golems + +/obj/machinery/mineral/ore_redemption/golem/New() + ..() + component_parts = list() + component_parts += new /obj/item/circuitboard/ore_redemption/golem(null) + component_parts += new /obj/item/stock_parts/matter_bin(null) + component_parts += new /obj/item/stock_parts/manipulator(null) + component_parts += new /obj/item/stock_parts/micro_laser(null) + component_parts += new /obj/item/assembly/igniter(null) + component_parts += new /obj/item/stock_parts/console_screen(null) + RefreshParts() + +/obj/machinery/mineral/ore_redemption/Destroy() + QDEL_NULL(files) + GET_COMPONENT(materials, /datum/component/material_container) + materials.retrieve_all() + return ..() + +/obj/machinery/mineral/ore_redemption/RefreshParts() + var/ore_pickup_rate_temp = 15 + var/point_upgrade_temp = 1 + var/sheet_per_ore_temp = 1 + for(var/obj/item/stock_parts/matter_bin/B in component_parts) + sheet_per_ore_temp = 0.65 + (0.35 * B.rating) + for(var/obj/item/stock_parts/manipulator/M in component_parts) + ore_pickup_rate_temp = 15 * M.rating + for(var/obj/item/stock_parts/micro_laser/L in component_parts) + point_upgrade_temp = 0.65 + (0.35 * L.rating) + ore_pickup_rate = ore_pickup_rate_temp + point_upgrade = point_upgrade_temp + sheet_per_ore = sheet_per_ore_temp + +/obj/machinery/mineral/ore_redemption/proc/smelt_ore(obj/item/stack/ore/O) + + ore_buffer -= O + + if(O && O.refined_type) + points += O.points * point_upgrade * O.amount + + GET_COMPONENT(materials, /datum/component/material_container) + var/material_amount = materials.get_item_material_amount(O) + + if(!material_amount) + qdel(O) //no materials, incinerate it + + else if(!materials.has_space(material_amount * sheet_per_ore * O.amount)) //if there is no space, eject it + unload_mineral(O) + + else + materials.insert_item(O, sheet_per_ore) //insert it + qdel(O) + +/obj/machinery/mineral/ore_redemption/proc/can_smelt_alloy(datum/design/D) + if(D.make_reagents.len) + return FALSE + + var/build_amount = 0 + + GET_COMPONENT(materials, /datum/component/material_container) + for(var/mat_id in D.materials) + var/M = D.materials[mat_id] + var/datum/material/redemption_mat = materials.materials[mat_id] + + if(!M || !redemption_mat) + return FALSE + + var/smeltable_sheets = round(redemption_mat.amount / M) + + if(!smeltable_sheets) + return FALSE + + if(!build_amount) + build_amount = smeltable_sheets + + build_amount = min(build_amount, smeltable_sheets) + + return build_amount + +/obj/machinery/mineral/ore_redemption/proc/process_ores(list/ores_to_process) + var/current_amount = 0 + for(var/ore in ores_to_process) + if(current_amount >= ore_pickup_rate) + break + smelt_ore(ore) + +/obj/machinery/mineral/ore_redemption/proc/send_console_message() + if(!is_station_level(z)) + return + message_sent = TRUE + var/area/A = get_area(src) + var/msg = "Now available in [A]:
      " + + var/has_minerals = FALSE + var/mineral_name = null + GET_COMPONENT(materials, /datum/component/material_container) + for(var/mat_id in materials.materials) + var/datum/material/M = materials.materials[mat_id] + var/mineral_amount = M.amount / MINERAL_MATERIAL_AMOUNT + mineral_name = capitalize(M.name) + if(mineral_amount) + has_minerals = TRUE + msg += "[mineral_name]: [mineral_amount] sheets
      " + + if(!has_minerals) + return + + for(var/obj/machinery/requests_console/D in allConsoles) + if(D.department in src.supply_consoles) + if(supply_consoles[D.department] == null || (mineral_name in supply_consoles[D.department])) + D.createMessage("Ore Redemption Machine", "New Minerals Available!", msg, 1) + +/obj/machinery/mineral/ore_redemption/process() + if(panel_open || !powered()) + return + var/atom/input = get_step(src, input_dir) + var/obj/structure/ore_box/OB = locate() in input + if(OB) + input = OB + + for(var/obj/item/stack/ore/O in input) + if(QDELETED(O)) + continue + ore_buffer |= O + O.forceMove(src) + CHECK_TICK + + if(LAZYLEN(ore_buffer)) + message_sent = FALSE + process_ores(ore_buffer) + else if(!message_sent) + send_console_message() + +/obj/machinery/mineral/ore_redemption/attackby(obj/item/W, mob/user, params) + if(exchange_parts(user, W)) + return + if(default_unfasten_wrench(user, W)) + return + if(default_deconstruction_screwdriver(user, "ore_redemption-open", "ore_redemption", W)) + updateUsrDialog() + return + if(default_deconstruction_crowbar(W)) + return + + if(!powered()) + return + if(istype(W, /obj/item/card/id)) + var/obj/item/card/id/I = user.get_active_hand() + if(istype(I) && !istype(inserted_id)) + if(!user.drop_item()) + return + I.forceMove(src) + inserted_id = I + interact(user) + return + + if(ismultitool(W) && panel_open) + input_dir = turn(input_dir, -90) + output_dir = turn(output_dir, -90) + to_chat(user, "You change [src]'s I/O settings, setting the input to [dir2text(input_dir)] and the output to [dir2text(output_dir)].") + return + + if(istype(W, /obj/item/disk/design_disk)) + if(user.drop_item()) + W.forceMove(src) + inserted_disk = W + interact(user) + return TRUE + + return ..() + +/obj/machinery/mineral/ore_redemption/attack_hand(mob/user) + if(..()) + return + interact(user) + +/obj/machinery/mineral/ore_redemption/interact(mob/user) + var/dat = "This machine only accepts ore. Gibtonite and Slag are not accepted.

      " + dat += "Current unclaimed points: [points]
      " + + if(inserted_id) + dat += "You have [inserted_id.mining_points] mining points collected. Eject ID.
      " + dat += "Claim points.

      " + else + dat += "No ID inserted. Insert ID.

      " + + GET_COMPONENT(materials, /datum/component/material_container) + for(var/mat_id in materials.materials) + var/datum/material/M = materials.materials[mat_id] + if(M.amount) + var/sheet_amount = M.amount / MINERAL_MATERIAL_AMOUNT + dat += "[capitalize(M.name)]: [sheet_amount] " + if(sheet_amount >= 1) + dat += "Release
      " + else + dat += "Release
      " + + dat += "
      Alloys:
      " + + for(var/v in files.known_designs) + var/datum/design/D = files.known_designs[v] + if(can_smelt_alloy(D)) + dat += "[D.name]: Smelt
      " + else + dat += "[D.name]: Smelt
      " + + dat += "
      Mineral Value List:
      [get_ore_values()]
      " + + if(inserted_disk) + dat += "Eject disk
      " + dat += "
      Uploadable designs:
      " + + if(inserted_disk.blueprint) + var/datum/design/D = inserted_disk.blueprint + if(D.build_type & SMELTER) + dat += "Name: [D.name] Upload to smelter" + + dat += "

      " + else + dat += "Insert design disk

      " + + var/datum/browser/popup = new(user, "ore_redemption_machine", "Ore Redemption Machine", 400, 500) + popup.set_content(dat) + popup.open() + return + +/obj/machinery/mineral/ore_redemption/proc/get_ore_values() + var/dat = "" + for(var/ore in ore_values) + var/value = ore_values[ore] + dat += "" + dat += "
      [capitalize(ore)][value * point_upgrade]
      " + return dat + +/obj/machinery/mineral/ore_redemption/Topic(href, href_list) + if(..()) + return + GET_COMPONENT(materials, /datum/component/material_container) + if(href_list["eject_id"]) + usr.put_in_hands(inserted_id) + inserted_id = null + if(href_list["claim"]) + if(inserted_id) + if(req_access_reclaim in inserted_id.access) + inserted_id.mining_points += points + points = 0 + else + to_chat(usr, "Required access not found.") + else if(href_list["insert_id"]) + var/obj/item/card/id/I = usr.get_active_hand() + if(istype(I)) + if(!usr.drop_item()) + return + I.forceMove(src) + inserted_id = I + else + to_chat(usr, "Not a valid ID!") + if(href_list["eject_disk"]) + if(inserted_disk) + inserted_disk.forceMove(loc) + inserted_disk = null + if(href_list["insert_disk"]) + var/obj/item/disk/design_disk/D = usr.get_active_hand() + if(istype(D)) + if(!usr.drop_item()) + return + D.forceMove(src) + inserted_disk = D + if(href_list["upload"]) + if(inserted_disk && inserted_disk.blueprint) + files.AddDesign2Known(inserted_disk.blueprint) + + if(href_list["release"]) + if(check_access(inserted_id) || allowed(usr)) //Check the ID inside, otherwise check the user + var/mat_id = href_list["release"] + if(!materials.materials[mat_id]) + return + + var/datum/material/mat = materials.materials[mat_id] + var/stored_amount = mat.amount / MINERAL_MATERIAL_AMOUNT + + if(!stored_amount) + return + + var/desired = input("How many sheets?", "How many sheets to eject?", 1) as null|num + var/sheets_to_remove = round(min(desired,50,stored_amount)) + + var/out = get_step(src, output_dir) + materials.retrieve_sheets(sheets_to_remove, mat_id, out) + + else + to_chat(usr, "Required access not found.") + + if(href_list["alloy"]) + var/alloy_id = href_list["alloy"] + var/datum/design/alloy = files.FindDesignByID(alloy_id) + if((check_access(inserted_id) || allowed(usr)) && alloy) + var/desired = input("How many sheets?", "How many sheets would you like to smelt?", 1) as null|num + if(desired < 1) // Stops an exploit that lets you build negative alloys and get free materials + return + var/smelt_amount = can_smelt_alloy(alloy) + var/amount = round(min(desired,50,smelt_amount)) + materials.use_amount(alloy.materials, amount) + + var/output = new alloy.build_path(src) + if(istype(output, /obj/item/stack/sheet)) + var/obj/item/stack/sheet/mineral/produced_alloy = output + produced_alloy.amount = amount + unload_mineral(produced_alloy) + else + unload_mineral(output) + + else + to_chat(usr, "Required access not found.") + updateUsrDialog() + +/obj/machinery/mineral/ore_redemption/ex_act(severity, target) + do_sparks(5, 1, src) + if(severity == 1) + if(prob(50)) + qdel(src) + else if(severity == 2) + if(prob(25)) + qdel(src) + +/obj/machinery/mineral/ore_redemption/power_change() + ..() + update_icon() + if(inserted_id && !powered()) + visible_message("The ID slot indicator light flickers on [src] as it spits out a card before powering down.") + inserted_id.forceMove(loc) + +/obj/machinery/mineral/ore_redemption/update_icon() + if(powered()) + icon_state = initial(icon_state) + else + icon_state = "[initial(icon_state)]-off" \ No newline at end of file diff --git a/code/modules/mining/machine_vending.dm b/code/modules/mining/machine_vending.dm new file mode 100644 index 00000000000..4de84bb70c4 --- /dev/null +++ b/code/modules/mining/machine_vending.dm @@ -0,0 +1,311 @@ +/**********************Mining Equipment Locker**************************/ + +/obj/machinery/mineral/equipment_vendor + name = "mining equipment vendor" + desc = "An equipment vendor for miners, points collected at an ore redemption machine can be spent here." + icon = 'icons/obj/machines/mining_machines.dmi' + icon_state = "mining" + density = 1 + anchored = 1.0 + var/obj/item/card/id/inserted_id + var/list/prize_list = list( //if you add something to this, please, for the love of god, sort it by price/type. use tabs and not spaces. + new /datum/data/mining_equipment("1 Marker Beacon", /obj/item/stack/marker_beacon, 10), + new /datum/data/mining_equipment("10 Marker Beacons", /obj/item/stack/marker_beacon/ten, 100), + new /datum/data/mining_equipment("30 Marker Beacons", /obj/item/stack/marker_beacon/thirty, 300), + new /datum/data/mining_equipment("Whiskey", /obj/item/reagent_containers/food/drinks/bottle/whiskey, 100), + new /datum/data/mining_equipment("Absinthe", /obj/item/reagent_containers/food/drinks/bottle/absinthe/premium, 100), + new /datum/data/mining_equipment("Cigar", /obj/item/clothing/mask/cigarette/cigar/havana, 150), + new /datum/data/mining_equipment("Soap", /obj/item/soap/nanotrasen, 200), + new /datum/data/mining_equipment("Laser Pointer", /obj/item/laser_pointer, 300), + new /datum/data/mining_equipment("Alien Toy", /obj/item/clothing/mask/facehugger/toy, 300), + new /datum/data/mining_equipment("Stabilizing Serum", /obj/item/hivelordstabilizer, 400), + new /datum/data/mining_equipment("Space Cash", /obj/item/stack/spacecash/c1000, 2000), + new /datum/data/mining_equipment("Point Transfer Card", /obj/item/card/mining_point_card, 500), + new /datum/data/mining_equipment("Fulton Beacon", /obj/item/fulton_core, 400), + new /datum/data/mining_equipment("Shelter Capsule", /obj/item/survivalcapsule, 400), + new /datum/data/mining_equipment("GAR Meson Scanners", /obj/item/clothing/glasses/meson/gar, 500), + new /datum/data/mining_equipment("Explorer's Webbing", /obj/item/storage/belt/mining, 500), + new /datum/data/mining_equipment("Survival Medipen", /obj/item/reagent_containers/hypospray/autoinjector/survival, 500), + new /datum/data/mining_equipment("Brute First-Aid Kit", /obj/item/storage/firstaid/brute, 600), + new /datum/data/mining_equipment("Tracking Implant Kit", /obj/item/storage/box/minertracker, 600), + new /datum/data/mining_equipment("Jaunter", /obj/item/wormhole_jaunter, 750), + new /datum/data/mining_equipment("Kinetic Crusher", /obj/item/twohanded/kinetic_crusher, 750), + new /datum/data/mining_equipment("Kinetic Accelerator", /obj/item/gun/energy/kinetic_accelerator, 750), + new /datum/data/mining_equipment("Advanced Scanner", /obj/item/t_scanner/adv_mining_scanner, 800), + new /datum/data/mining_equipment("Resonator", /obj/item/resonator, 800), + new /datum/data/mining_equipment("Fulton Pack", /obj/item/extraction_pack, 1000), + new /datum/data/mining_equipment("Lazarus Injector", /obj/item/lazarus_injector, 1000), + new /datum/data/mining_equipment("Silver Pickaxe", /obj/item/pickaxe/silver, 1000), + new /datum/data/mining_equipment("Mining Conscription Kit", /obj/item/storage/backpack/duffel/mining_conscript, 1500), + new /datum/data/mining_equipment("Jetpack Upgrade", /obj/item/tank/jetpack/suit, 2000), + new /datum/data/mining_equipment("Mining Hardsuit", /obj/item/clothing/suit/space/hardsuit/mining, 2000), + new /datum/data/mining_equipment("Diamond Pickaxe", /obj/item/pickaxe/diamond, 2000), + new /datum/data/mining_equipment("Super Resonator", /obj/item/resonator/upgraded, 2500), + new /datum/data/mining_equipment("Jump Boots", /obj/item/clothing/shoes/bhop, 2500), + new /datum/data/mining_equipment("Luxury Shelter Capsule", /obj/item/survivalcapsule/luxury, 3000), + new /datum/data/mining_equipment("Nanotrasen Minebot", /obj/item/mining_drone_cube, 800), + new /datum/data/mining_equipment("Minebot Melee Upgrade", /obj/item/mine_bot_upgrade, 400), + new /datum/data/mining_equipment("Minebot Armor Upgrade", /obj/item/mine_bot_upgrade/health, 400), + new /datum/data/mining_equipment("Minebot Cooldown Upgrade", /obj/item/borg/upgrade/modkit/cooldown/minebot, 600), + new /datum/data/mining_equipment("Minebot AI Upgrade", /obj/item/slimepotion/sentience/mining, 1000), + new /datum/data/mining_equipment("KA Minebot Passthrough", /obj/item/borg/upgrade/modkit/minebot_passthrough, 100), + new /datum/data/mining_equipment("Lazarus Capsule", /obj/item/mobcapsule, 800), + new /datum/data/mining_equipment("Lazarus Capsule belt", /obj/item/storage/belt/lazarus, 200), + new /datum/data/mining_equipment("KA White Tracer Rounds", /obj/item/borg/upgrade/modkit/tracer, 100), + new /datum/data/mining_equipment("KA Adjustable Tracer Rounds", /obj/item/borg/upgrade/modkit/tracer/adjustable, 150), + new /datum/data/mining_equipment("KA Super Chassis", /obj/item/borg/upgrade/modkit/chassis_mod, 250), + new /datum/data/mining_equipment("KA Hyper Chassis", /obj/item/borg/upgrade/modkit/chassis_mod/orange, 300), + new /datum/data/mining_equipment("KA Range Increase", /obj/item/borg/upgrade/modkit/range, 1000), + new /datum/data/mining_equipment("KA Damage Increase", /obj/item/borg/upgrade/modkit/damage, 1000), + new /datum/data/mining_equipment("KA Cooldown Decrease", /obj/item/borg/upgrade/modkit/cooldown, 1000), + new /datum/data/mining_equipment("KA AoE Damage", /obj/item/borg/upgrade/modkit/aoe/mobs, 2000) + ) + +/obj/machinery/mineral/equipment_vendor/golem + name = "golem ship equipment vendor" + +/obj/machinery/mineral/equipment_vendor/golem/New() + ..() + component_parts = list() + component_parts += new /obj/item/circuitboard/mining_equipment_vendor/golem(null) + component_parts += new /obj/item/stock_parts/matter_bin(null) + component_parts += new /obj/item/stock_parts/matter_bin(null) + component_parts += new /obj/item/stock_parts/matter_bin(null) + component_parts += new /obj/item/stock_parts/console_screen(null) + RefreshParts() + +/obj/machinery/mineral/equipment_vendor/golem/Initialize() + . = ..() + desc += "\nIt seems a few selections have been added." + prize_list += list( + new /datum/data/mining_equipment("Extra Id", /obj/item/card/id/golem, 250), + new /datum/data/mining_equipment("Science Backpack", /obj/item/storage/backpack/science, 250), + new /datum/data/mining_equipment("Full Toolbelt", /obj/item/storage/belt/utility/full/multitool, 250), + new /datum/data/mining_equipment("Monkey Cube", /obj/item/reagent_containers/food/snacks/monkeycube, 250), + new /datum/data/mining_equipment("Royal Cape of the Liberator", /obj/item/bedsheet/rd/royal_cape, 500), + new /datum/data/mining_equipment("Grey Slime Extract", /obj/item/slime_extract/grey, 1000), + new /datum/data/mining_equipment("KA Trigger Modification Kit", /obj/item/borg/upgrade/modkit/trigger_guard, 1000), + new /datum/data/mining_equipment("Shuttle Console Board", /obj/item/circuitboard/shuttle/golem_ship, 2000), + new /datum/data/mining_equipment("The Liberator's Legacy", /obj/item/storage/box/rndboards, 2000) + + ) + +/datum/data/mining_equipment + var/equipment_name = "generic" + var/equipment_path = null + var/cost = 0 + +/datum/data/mining_equipment/New(name, path, equipment_cost) + equipment_name = name + equipment_path = path + cost = equipment_cost + +/obj/machinery/mineral/equipment_vendor/New() + ..() + component_parts = list() + component_parts += new /obj/item/circuitboard/mining_equipment_vendor(null) + component_parts += new /obj/item/stock_parts/matter_bin(null) + component_parts += new /obj/item/stock_parts/matter_bin(null) + component_parts += new /obj/item/stock_parts/matter_bin(null) + component_parts += new /obj/item/stock_parts/console_screen(null) + RefreshParts() + +/obj/machinery/mineral/equipment_vendor/power_change() + ..() + update_icon() + if(inserted_id && !powered()) + visible_message("The ID slot indicator light flickers on \the [src] as it spits out a card before powering down.") + inserted_id.forceMove(loc) + +/obj/machinery/mineral/equipment_vendor/update_icon() + if(powered()) + icon_state = initial(icon_state) + else + icon_state = "[initial(icon_state)]-off" + +/obj/machinery/mineral/equipment_vendor/attack_hand(mob/user) + if(..()) + return + interact(user) + +/obj/machinery/mineral/equipment_vendor/attack_ghost(mob/user) + interact(user) + +/obj/machinery/mineral/equipment_vendor/interact(mob/user) + user.set_machine(src) + + var/dat + dat +="
      " + if(istype(inserted_id)) + dat += "You have [inserted_id.mining_points] mining points collected. Eject ID.
      " + else + dat += "No ID inserted. Insert ID.
      " + dat += "
      " + dat += "
      Equipment point cost list:
      " + for(var/datum/data/mining_equipment/prize in prize_list) + dat += "" + dat += "
      [prize.equipment_name][prize.cost]Purchase
      " + var/datum/browser/popup = new(user, "miningvendor", "Mining Equipment Vendor", 400, 350) + popup.set_content(dat) + popup.open() + +/obj/machinery/mineral/equipment_vendor/Topic(href, href_list) + if(..()) + return 1 + + if(href_list["choice"]) + if(istype(inserted_id)) + if(href_list["choice"] == "eject") + inserted_id.loc = loc + inserted_id.verb_pickup() + inserted_id = null + else if(href_list["choice"] == "insert") + var/obj/item/card/id/I = usr.get_active_hand() + if(istype(I)) + if(!usr.drop_item()) + return + I.loc = src + inserted_id = I + else + to_chat(usr, "No valid ID.") + + if(href_list["purchase"]) + if(istype(inserted_id)) + var/datum/data/mining_equipment/prize = locate(href_list["purchase"]) + if(!prize || !(prize in prize_list) || prize.cost > inserted_id.mining_points) + return + + inserted_id.mining_points -= prize.cost + new prize.equipment_path(src.loc) + updateUsrDialog() + +/obj/machinery/mineral/equipment_vendor/attackby(obj/item/I, mob/user, params) + if(default_deconstruction_screwdriver(user, "mining-open", "mining", I)) + updateUsrDialog() + return + if(panel_open) + if(istype(I, /obj/item/crowbar)) + if(inserted_id) + inserted_id.forceMove(loc) //Prevents deconstructing the ORM from deleting whatever ID was inside it. + default_deconstruction_crowbar(I) + return 1 + if(istype(I, /obj/item/mining_voucher)) + if(!powered()) + return + else + RedeemVoucher(I, user) + return + if(istype(I,/obj/item/card/id)) + if(!powered()) + return + else + var/obj/item/card/id/C = usr.get_active_hand() + if(istype(C) && !istype(inserted_id)) + if(!usr.drop_item()) + return + C.forceMove(src) + inserted_id = C + interact(user) + return + ..() + +/obj/machinery/mineral/equipment_vendor/proc/RedeemVoucher(obj/item/mining_voucher/voucher, mob/redeemer) + var/items = list("Survival Capsule and Explorer's Webbing", "Resonator Kit", "Minebot Kit", "Extraction and Rescue Kit", "Crusher Kit", "Mining Conscription Kit") + + var/selection = input(redeemer, "Pick your equipment", "Mining Voucher Redemption") as null|anything in items + if(!selection || !Adjacent(redeemer) || QDELETED(voucher) || voucher.loc != redeemer) + return + + var/drop_location = drop_location() + switch(selection) + if("Survival Capsule and Explorer's Webbing") + new /obj/item/storage/belt/mining(drop_location) + if("Resonator Kit") + new /obj/item/extinguisher/mini(drop_location) + new /obj/item/resonator(drop_location) + if("Minebot Kit") + new /obj/item/mining_drone_cube(drop_location) + new /obj/item/weldingtool/hugetank(drop_location) + new /obj/item/clothing/head/welding(drop_location) + if("Extraction and Rescue Kit") + new /obj/item/extraction_pack(drop_location) + new /obj/item/fulton_core(drop_location) + new /obj/item/stack/marker_beacon/thirty(drop_location) + if("Crusher Kit") + new /obj/item/extinguisher/mini(drop_location) + new /obj/item/twohanded/kinetic_crusher(drop_location) + if("Mining Conscription Kit") + new /obj/item/storage/backpack/duffel/mining_conscript(drop_location) + + qdel(voucher) + +/obj/machinery/mineral/equipment_vendor/ex_act(severity, target) + do_sparks(5, 1, src) + if(prob(50 / severity) && severity < 3) + qdel(src) + +/**********************Mining Equipment Locker Items**************************/ + +/**********************Mining Equipment Voucher**********************/ + +/obj/item/mining_voucher + name = "mining voucher" + desc = "A token to redeem a piece of equipment. Use it on a mining equipment vendor." + icon = 'icons/obj/items.dmi' + icon_state = "mining_voucher" + w_class = WEIGHT_CLASS_TINY + +/**********************Mining Point Card**********************/ + +/obj/item/card/mining_point_card + name = "mining point card" + desc = "A small card preloaded with mining points. Swipe your ID card over it to transfer the points, then discard." + icon_state = "data" + var/points = 500 + +/obj/item/card/mining_point_card/attackby(obj/item/I, mob/user, params) + if(istype(I, /obj/item/card/id)) + if(points) + var/obj/item/card/id/C = I + C.mining_points += points + to_chat(user, "You transfer [points] points to [C].") + points = 0 + else + to_chat(user, "There's no points left on [src].") + ..() + +/obj/item/card/mining_point_card/examine(mob/user) + ..(user) + to_chat(user, "There's [points] points on the card.") + +/**********************Conscription Kit**********************/ + +/obj/item/card/id/mining_access_card + name = "mining access card" + desc = "A small card, that when used on any ID, will add mining access." + icon_state = "data_1" + +/obj/item/card/id/mining_access_card/afterattack(atom/movable/AM, mob/user, proximity) + . = ..() + if(istype(AM, /obj/item/card/id) && proximity) + var/obj/item/card/id/I = AM + I.access |= list(access_mining, access_mining_station, access_mineral_storeroom, access_cargo) + to_chat(user, "You upgrade [I] with mining access.") + qdel(src) + +/obj/item/storage/backpack/duffel/mining_conscript + name = "mining conscription kit" + desc = "A kit containing everything a crewmember needs to support a shaft miner in the field." + +/obj/item/storage/backpack/duffel/mining_conscript/New() + ..() + new /obj/item/clothing/glasses/meson(src) + new /obj/item/t_scanner/adv_mining_scanner/lesser(src) + new /obj/item/storage/bag/ore(src) + new /obj/item/clothing/suit/hooded/explorer(src) + new /obj/item/encryptionkey/headset_cargo(src) + new /obj/item/clothing/mask/gas/explorer(src) + new /obj/item/card/id/mining_access_card(src) + new /obj/item/gun/energy/kinetic_accelerator(src) + new /obj/item/kitchen/knife/combat/survival(src) + new /obj/item/flashlight/seclite(src) \ No newline at end of file diff --git a/code/modules/mining/mine_items.dm b/code/modules/mining/mine_items.dm index f10b78dc526..b85db884ef5 100644 --- a/code/modules/mining/mine_items.dm +++ b/code/modules/mining/mine_items.dm @@ -17,35 +17,20 @@ icon_closed = "mixed" /obj/structure/closet/wardrobe/miner/New() - ..() - contents = list() - new /obj/item/storage/backpack/duffel(src) - new /obj/item/storage/backpack/industrial(src) - new /obj/item/storage/backpack/satchel_eng(src) - new /obj/item/clothing/under/rank/miner(src) - new /obj/item/clothing/under/rank/miner(src) - new /obj/item/clothing/under/rank/miner(src) - new /obj/item/clothing/shoes/workboots(src) - new /obj/item/clothing/shoes/workboots(src) - new /obj/item/clothing/shoes/workboots(src) - new /obj/item/clothing/gloves/fingerless(src) - new /obj/item/clothing/gloves/fingerless(src) - new /obj/item/clothing/gloves/fingerless(src) - -/obj/structure/closet/wardrobe/miner/lavaland - -/obj/structure/closet/wardrobe/miner/lavaland/New() ..() contents = list() new /obj/item/storage/backpack/duffel(src) new /obj/item/storage/backpack/explorer(src) - new /obj/item/storage/backpack/explorer(src) + new /obj/item/storage/backpack/satchel/explorer(src) new /obj/item/clothing/under/rank/miner/lavaland(src) new /obj/item/clothing/under/rank/miner/lavaland(src) new /obj/item/clothing/under/rank/miner/lavaland(src) new /obj/item/clothing/shoes/workboots/mining(src) new /obj/item/clothing/shoes/workboots/mining(src) new /obj/item/clothing/shoes/workboots/mining(src) + new /obj/item/clothing/gloves/color/black(src) + new /obj/item/clothing/gloves/color/black(src) + new /obj/item/clothing/gloves/color/black(src) /obj/structure/closet/secure_closet/miner name = "miner's equipment" @@ -59,14 +44,18 @@ /obj/structure/closet/secure_closet/miner/New() ..() + new /obj/item/stack/sheet/mineral/sandbags(src, 5) + new /obj/item/storage/box/emptysandbags(src) new /obj/item/shovel(src) - new /obj/item/pickaxe(src) + new /obj/item/pickaxe/mini(src) new /obj/item/radio/headset/headset_cargo/mining(src) - new /obj/item/t_scanner/adv_mining_scanner/lesser(src) + new /obj/item/flashlight/seclite(src) + new /obj/item/storage/bag/plants(src) new /obj/item/storage/bag/ore(src) + new /obj/item/t_scanner/adv_mining_scanner/lesser(src) + new /obj/item/gun/energy/kinetic_accelerator(src) new /obj/item/clothing/glasses/meson(src) new /obj/item/survivalcapsule(src) - new /obj/item/stack/marker_beacon/ten /**********************Shuttle Computer**************************/ @@ -86,148 +75,6 @@ desc = "A mining lantern." brightness_on = 6 // luminosity when on -/*****************************Pickaxe********************************/ - -/obj/item/pickaxe - name = "pickaxe" - icon = 'icons/obj/items.dmi' - icon_state = "pickaxe" - flags = CONDUCT - slot_flags = SLOT_BELT - force = 15 - throwforce = 10 - item_state = "pickaxe" - w_class = WEIGHT_CLASS_BULKY - materials = list(MAT_METAL=2000) //one sheet, but where can you make them? - origin_tech = "materials=2;engineering=3" - attack_verb = list("hit", "pierced", "sliced", "attacked") - var/list/digsound = list('sound/effects/picaxe1.ogg','sound/effects/picaxe2.ogg','sound/effects/picaxe3.ogg') - var/drill_verb = "picking" - sharp = 1 - var/excavation_amount = 100 - usesound = 'sound/effects/picaxe1.ogg' - toolspeed = 1 - -/obj/item/pickaxe/proc/playDigSound() - playsound(src, pick(digsound),20,1) - -/obj/item/pickaxe/emergency - name = "emergency disembarkation tool" - desc = "For extracting yourself from rough landings." - -/obj/item/pickaxe/safety - name = "safety pickaxe" - desc = "A pickaxe designed to be only effective at digging rock and ore, very ineffective as a weapon." - force = 1 - throwforce = 1 - attack_verb = list("ineffectively hit") - -/obj/item/pickaxe/silver - name = "silver-plated pickaxe" - icon_state = "spickaxe" - item_state = "spickaxe" - origin_tech = "materials=3;engineering=4" - desc = "A silver-plated pickaxe that mines slightly faster than standard-issue." - toolspeed = 0.75 - -/obj/item/pickaxe/gold - name = "golden pickaxe" - icon_state = "gpickaxe" - item_state = "gpickaxe" - origin_tech = "materials=4;engineering=4" - desc = "A gold-plated pickaxe that mines faster than standard-issue." - toolspeed = 0.6 - -/obj/item/pickaxe/diamond - name = "diamond-tipped pickaxe" - icon_state = "dpickaxe" - item_state = "dpickaxe" - origin_tech = "materials=5;engineering=4" - desc = "A pickaxe with a diamond pick head. Extremely robust at cracking rock walls and digging up dirt." - toolspeed = 0.5 - -/obj/item/pickaxe/drill - name = "mining drill" - icon_state = "handdrill" - item_state = "jackhammer" - digsound = list('sound/weapons/drill.ogg') - hitsound = 'sound/weapons/drill.ogg' - usesound = 'sound/weapons/drill.ogg' - origin_tech = "materials=2;powerstorage=2;engineering=3" - desc = "An electric mining drill for the especially scrawny." - toolspeed = 0.5 - -/obj/item/pickaxe/drill/cyborg - name = "cyborg mining drill" - desc = "An integrated electric mining drill." - flags = NODROP - -/obj/item/pickaxe/drill/diamonddrill - name = "diamond-tipped mining drill" - icon_state = "diamonddrill" - origin_tech = "materials=6;powerstorage=4;engineering=4" - desc = "Yours is the drill that will pierce the heavens!" - toolspeed = 0.25 - -/obj/item/pickaxe/diamonddrill/traitor //Pocket-sized traitor diamond drill. - name = "supermatter drill" - icon_state = "smdrill" - origin_tech = "materials=6;powerstorage=4;engineering=4;syndicate=3" - desc = "Microscopic supermatter crystals cover the head of this tiny drill." - w_class = WEIGHT_CLASS_SMALL - -/obj/item/pickaxe/drill/cyborg/diamond //This is the BORG version! - name = "diamond-tipped cyborg mining drill" //To inherit the NODROP flag, and easier to change borg specific drill mechanics. - icon_state = "diamonddrill" - toolspeed = 0.25 - -/obj/item/pickaxe/drill/jackhammer - name = "sonic jackhammer" - icon_state = "jackhammer" - item_state = "jackhammer" - origin_tech = "materials=6;powerstorage=4;engineering=5;magnets=4" - digsound = list('sound/weapons/sonic_jackhammer.ogg') - hitsound = 'sound/weapons/sonic_jackhammer.ogg' - usesound = 'sound/weapons/sonic_jackhammer.ogg' - desc = "Cracks rocks with sonic blasts, and doubles as a demolition power tool for smashing walls." - toolspeed = 0.1 - -/*****************************Shovel********************************/ - -/obj/item/shovel - name = "shovel" - desc = "A large tool for digging and moving dirt." - icon = 'icons/obj/items.dmi' - icon_state = "shovel" - flags = CONDUCT - slot_flags = SLOT_BELT - force = 8 - throwforce = 4 - item_state = "shovel" - w_class = WEIGHT_CLASS_NORMAL - materials = list(MAT_METAL=50) - origin_tech = "materials=2;engineering=2" - attack_verb = list("bashed", "bludgeoned", "thrashed", "whacked") - usesound = 'sound/effects/shovel_dig.ogg' - toolspeed = 1 - -/obj/item/shovel/spade - name = "spade" - desc = "A small tool for digging and moving dirt." - icon_state = "spade" - item_state = "spade" - force = 5 - throwforce = 7 - w_class = WEIGHT_CLASS_SMALL - toolspeed = 2 - -/obj/item/shovel/safety - name = "safety shovel" - desc = "A large tool for digging and moving dirt. Was modified with extra safety, making it ineffective as a weapon." - force = 1 - throwforce = 1 - attack_verb = list("ineffectively hit") - /**********************Mining car (Crate like thing, not the rail car)**************************/ /obj/structure/closet/crate/miningcar @@ -236,60 +83,4 @@ icon_state = "miningcar" density = 1 icon_opened = "miningcaropen" - icon_closed = "miningcar" - -/*********************Mob Capsule*************************/ - -/obj/item/mobcapsule - name = "lazarus capsule" - desc = "It allows you to store and deploy lazarus-injected creatures easier." - icon = 'icons/obj/mobcap.dmi' - icon_state = "mobcap0" - w_class = WEIGHT_CLASS_TINY - throw_range = 20 - var/mob/living/simple_animal/captured = null - var/colorindex = 0 - -/obj/item/mobcapsule/Destroy() - if(captured) - captured.ghostize() - QDEL_NULL(captured) - return ..() - -/obj/item/mobcapsule/attack(var/atom/A, mob/user, prox_flag) - if(!istype(A, /mob/living/simple_animal) || isbot(A)) - return ..() - capture(A, user) - return 1 - -/obj/item/mobcapsule/proc/capture(var/mob/target, var/mob/U as mob) - var/mob/living/simple_animal/T = target - if(captured) - to_chat(U, "Capture failed!: The capsule already has a mob registered to it!") - else - if(istype(T) && "neutral" in T.faction) - T.forceMove(src) - T.name = "[U.name]'s [initial(T.name)]" - T.cancel_camera() - name = "Lazarus Capsule: [initial(T.name)]" - to_chat(U, "You placed a [T.name] inside the Lazarus Capsule!") - captured = T - else - to_chat(U, "You can't capture that mob!") - -/obj/item/mobcapsule/throw_impact(atom/A, mob/user) - ..() - if(captured) - dump_contents(user) - -/obj/item/mobcapsule/proc/dump_contents(mob/user) - if(captured) - captured.forceMove(get_turf(src)) - captured = null - -/obj/item/mobcapsule/attack_self(mob/user) - colorindex += 1 - if(colorindex >= 6) - colorindex = 0 - icon_state = "mobcap[colorindex]" - update_icon() + icon_closed = "miningcar" \ No newline at end of file diff --git a/code/modules/mining/minebot.dm b/code/modules/mining/minebot.dm index 5b20aad5047..e7036ad4f2f 100644 --- a/code/modules/mining/minebot.dm +++ b/code/modules/mining/minebot.dm @@ -5,6 +5,7 @@ /mob/living/simple_animal/hostile/mining_drone name = "nanotrasen minebot" desc = "The instructions printed on the side read: This is a small robot used to support miners, can be set to search and collect loose ore, or to help fend off wildlife. A mining scanner can instruct it to drop loose ore. Field repairs can be done with a welder." + gender = NEUTER icon = 'icons/obj/aibots.dmi' icon_state = "mining_drone" icon_living = "mining_drone" @@ -14,36 +15,31 @@ a_intent = INTENT_HARM atmos_requirements = list("min_oxy" = 0, "max_oxy" = 0, "min_tox" = 0, "max_tox" = 0, "min_co2" = 0, "max_co2" = 0, "min_n2" = 0, "max_n2" = 0) minbodytemp = 0 - wander = 0 idle_vision_range = 5 move_to_delay = 10 - retreat_distance = 1 - minimum_distance = 2 health = 125 maxHealth = 125 melee_damage_lower = 15 melee_damage_upper = 15 - obj_damage = 0 + obj_damage = 10 environment_smash = 0 - check_friendly_fire = 1 - stop_automated_movement_when_pulled = 1 + check_friendly_fire = TRUE + stop_automated_movement_when_pulled = TRUE attacktext = "drills" attack_sound = 'sound/weapons/circsawhit.ogg' - ranged = 1 sentience_type = SENTIENCE_MINEBOT - ranged_message = "shoots" - ranged_cooldown_time = 30 - projectiletype = /obj/item/projectile/kinetic - projectilesound = 'sound/weapons/gunshots/gunshot4.ogg' speak_emote = list("states") wanted_objects = list(/obj/item/stack/ore/diamond, /obj/item/stack/ore/gold, /obj/item/stack/ore/silver, /obj/item/stack/ore/plasma, /obj/item/stack/ore/uranium, /obj/item/stack/ore/iron, /obj/item/stack/ore/bananium, /obj/item/stack/ore/tranquillite, /obj/item/stack/ore/glass, /obj/item/stack/ore/titanium) healable = 0 + loot = list(/obj/effect/decal/cleanable/robot_debris) + del_on_death = TRUE var/mode = MINEDRONE_COLLECT var/light_on = 0 var/mesons_active + var/obj/item/gun/energy/kinetic_accelerator/minebot/stored_gun var/datum/action/innate/minedrone/toggle_light/toggle_light_action var/datum/action/innate/minedrone/toggle_meson_vision/toggle_meson_vision_action @@ -52,6 +48,8 @@ /mob/living/simple_animal/hostile/mining_drone/New() ..() + stored_gun = new(src) + zone_sel = new /obj/screen/zone_sel(src) //Gross, but necessary TO-DO; remove this. toggle_light_action = new() toggle_light_action.Grant(src) toggle_meson_vision_action = new() @@ -72,8 +70,27 @@ ..() check_friendly_fire = 0 +/mob/living/simple_animal/hostile/mining_drone/examine(mob/user) + . = ..() + var/t_He = p_they(TRUE) + var/t_him = p_them() + var/t_s = p_s() + if(health < maxHealth) + if(health >= maxHealth * 0.5) + . += "[t_He] look[t_s] slightly dented." + else + . += "[t_He] look[t_s] severely dented!" + . += {"Using a mining scanner on [t_him] will instruct [t_him] to drop stored ore. [max(0, LAZYLEN(contents) - 1)] Stored Ore\n + Field repairs can be done with a welder."} + if(stored_gun && stored_gun.max_mod_capacity) + . += "[stored_gun.get_remaining_mod_capacity()]% mod capacity remaining." + for(var/A in stored_gun.get_modkits()) + var/obj/item/borg/upgrade/modkit/M = A + . += "There is \a [M] installed, using [M.cost]% capacity." + + /mob/living/simple_animal/hostile/mining_drone/attackby(obj/item/I, mob/user, params) - if(istype(I, /obj/item/weldingtool) && user.a_intent == INTENT_HELP) + if(iswelder(I) && user.a_intent == INTENT_HELP) var/obj/item/weldingtool/W = I if(W.welding && !stat) if(AIStatus != AI_OFF && AIStatus != AI_IDLE) @@ -90,29 +107,18 @@ to_chat(user, "You instruct [src] to drop any collected ore.") DropOre() return + if(iscrowbar(I) || istype(I, /obj/item/borg/upgrade/modkit)) + I.melee_attack_chain(user, stored_gun, params) + return ..() /mob/living/simple_animal/hostile/mining_drone/death() - // Only execute the below if we successfully died - . = ..() - if(!.) - return FALSE - visible_message("[src] is destroyed!") - new /obj/effect/decal/cleanable/blood/gibs/robot(loc) DropOre(0) - qdel(src) - -/mob/living/simple_animal/hostile/mining_drone/Shoot(atom/targeted_atom) - var/obj/item/projectile/kinetic/K = ..() - var/turf/proj_turf = get_turf(K) - if(!isturf(proj_turf)) - return - var/datum/gas_mixture/environment = proj_turf.return_air() - var/pressure = environment.return_pressure() - if(pressure > 50) - K.name = "weakened [K.name]" - - K.damage *= K.pressure_decrease + if(stored_gun) + for(var/obj/item/borg/upgrade/modkit/M in stored_gun.modkits) + M.uninstall(stored_gun) + deathmessage = "blows apart!" + . = ..() /mob/living/simple_animal/hostile/mining_drone/attack_hand(mob/living/carbon/human/M) if(M.a_intent == INTENT_HELP) @@ -125,12 +131,24 @@ return ..() +/mob/living/simple_animal/hostile/mining_drone/CanPass(atom/movable/O) + if(istype(O, /obj/item/projectile/kinetic)) + var/obj/item/projectile/kinetic/K = O + if(K.kinetic_gun) + for(var/A in K.kinetic_gun.get_modkits()) + var/obj/item/borg/upgrade/modkit/M = A + if(istype(M, /obj/item/borg/upgrade/modkit/minebot_passthrough)) + return TRUE + if(istype(O, /obj/item/projectile/destabilizer)) + return TRUE + return ..() + /mob/living/simple_animal/hostile/mining_drone/proc/SetCollectBehavior() mode = MINEDRONE_COLLECT idle_vision_range = 9 search_objects = 2 - wander = 1 - ranged = 0 + wander = TRUE + ranged = FALSE minimum_distance = 1 retreat_distance = null icon_state = "mining_drone" @@ -140,18 +158,25 @@ mode = MINEDRONE_ATTACK idle_vision_range = 7 search_objects = 0 - wander = 0 - ranged = 1 - retreat_distance = 1 - minimum_distance = 2 + wander = FALSE + ranged = TRUE + retreat_distance = 2 + minimum_distance = 1 icon_state = "mining_drone_offense" to_chat(src, "You are set to attack mode. You can now attack from range.") /mob/living/simple_animal/hostile/mining_drone/AttackingTarget() - if(istype(target, /obj/item/stack/ore) && mode == MINEDRONE_COLLECT) + if(istype(target, /obj/item/stack/ore) && mode == MINEDRONE_COLLECT) CollectOre() return - ..() + if(isliving(target)) + SetOffenseBehavior() + return ..() + +/mob/living/simple_animal/hostile/mining_drone/OpenFire(atom/A) + if(CheckFriendlyFire(A)) + return + stored_gun.afterattack(A, src) //of the possible options to allow minebots to have KA mods, would you believe this is the best? /mob/living/simple_animal/hostile/mining_drone/proc/CollectOre() for(var/obj/item/stack/ore/O in range(1, src)) @@ -160,14 +185,12 @@ /mob/living/simple_animal/hostile/mining_drone/proc/DropOre(message = 1) if(!contents.len) if(message) - to_chat(src, "You attempt to dump your stored ore, but you have none.") + to_chat(src, "You attempt to dump your stored ore, but you have none.") return if(message) to_chat(src, "You dump your stored ore.") for(var/obj/item/stack/ore/O in contents) - contents -= O - O.forceMove(loc) - return + O.forceMove(drop_location()) /mob/living/simple_animal/hostile/mining_drone/adjustHealth(amount) if(mode != MINEDRONE_ATTACK && amount > 0) @@ -176,13 +199,10 @@ /mob/living/simple_animal/hostile/mining_drone/proc/toggle_mode() switch(mode) - if(MINEDRONE_COLLECT) - SetOffenseBehavior() if(MINEDRONE_ATTACK) SetCollectBehavior() - else //This should never happen. - mode = MINEDRONE_COLLECT - SetCollectBehavior() + else + SetOffenseBehavior() //Actions for sentient minebots @@ -264,42 +284,26 @@ if(M.melee_damage_upper != initial(M.melee_damage_upper)) to_chat(user, "[M] already has a combat upgrade installed!") return - M.melee_damage_lower = 22 - M.melee_damage_upper = 22 + M.melee_damage_lower += 7 + M.melee_damage_upper += 7 to_chat(user, "You upgrade [M]'s combat module.") qdel(src) //Health /obj/item/mine_bot_upgrade/health - name = "minebot chassis upgrade" + name = "minebot armor upgrade" /obj/item/mine_bot_upgrade/health/upgrade_bot(mob/living/simple_animal/hostile/mining_drone/M, mob/user) if(M.maxHealth != initial(M.maxHealth)) to_chat(user, "[M] already has a reinforced chassis!") return - var/previous = M.maxHealth - M.maxHealth = 170 - M.health += M.maxHealth - previous - to_chat(user, "You reinforce [M]'s chassis.") + M.maxHealth += 45 + M.updatehealth() qdel(src) - -//Cooldown - -/obj/item/mine_bot_upgrade/cooldown - name = "minebot cooldown upgrade" - -/obj/item/mine_bot_upgrade/cooldown/upgrade_bot(mob/living/simple_animal/hostile/mining_drone/M, mob/user) - if(M.ranged_cooldown_time != initial(M.ranged_cooldown_time)) - to_chat(user, "[M] already has a decreased weapon cooldown!") - return - M.ranged_cooldown_time = 10 - to_chat(user, "You upgrade [M]'s ranged weaponry, reducing its cooldown.") - qdel(src) - - //AI + /obj/item/slimepotion/sentience/mining name = "minebot AI upgrade" desc = "Can be used to grant sentience to minebots." @@ -307,6 +311,36 @@ icon = 'icons/obj/doors/door_assembly.dmi' sentience_type = SENTIENCE_MINEBOT origin_tech = "programming=6" + var/base_health_add = 5 //sentient minebots are penalized for beign sentient; they have their stats reset to normal plus these values + var/base_damage_add = 1 //this thus disables other minebot upgrades + var/base_speed_add = 1 + var/base_cooldown_add = 10 //base cooldown isn't reset to normal, it's just added on, since it's not practical to disable the cooldown module + +/obj/item/slimepotion/sentience/mining/after_success(mob/living/user, mob/living/simple_animal/SM) + if(istype(SM, /mob/living/simple_animal/hostile/mining_drone)) + var/mob/living/simple_animal/hostile/mining_drone/M = SM + M.maxHealth = initial(M.maxHealth) + base_health_add + M.melee_damage_lower = initial(M.melee_damage_lower) + base_damage_add + M.melee_damage_upper = initial(M.melee_damage_upper) + base_damage_add + M.move_to_delay = initial(M.move_to_delay) + base_speed_add + if(M.stored_gun) + M.stored_gun.overheat_time += base_cooldown_add + +/**********************Mining drone cube**********************/ + +/obj/item/mining_drone_cube + name = "mining drone cube" + desc = "Compressed mining drone, ready for deployment. Just press the button to activate!" + w_class = WEIGHT_CLASS_SMALL + icon = 'icons/obj/aibots.dmi' + icon_state = "minedronecube" + item_state = "electronic" + +/obj/item/mining_drone_cube/attack_self(mob/user) + user.visible_message("\The [src] suddenly expands into a fully functional mining drone!", \ + "You press center button on \the [src]. The device suddenly expands into a fully functional mining drone!") + new /mob/living/simple_animal/hostile/mining_drone(get_turf(src)) + qdel(src) #undef MINEDRONE_COLLECT -#undef MINEDRONE_ATTACK +#undef MINEDRONE_ATTACK \ No newline at end of file diff --git a/code/modules/mining/ore.dm b/code/modules/mining/ores_coins.dm similarity index 70% rename from code/modules/mining/ore.dm rename to code/modules/mining/ores_coins.dm index 236bcec1231..120dacad800 100644 --- a/code/modules/mining/ore.dm +++ b/code/modules/mining/ores_coins.dm @@ -303,8 +303,165 @@ GLOBAL_LIST_INIT(sand_recipes, list(\ qdel(src) -/obj/item/stack/ore/ex_act() - return +/obj/item/stack/ore/ex_act(severity) + if(!severity || severity >= 2) + return + qdel(src) + + +/*****************************Coin********************************/ + +/obj/item/coin + icon = 'icons/obj/economy.dmi' + name = "coin" + icon_state = "coin__heads" + flags = CONDUCT + force = 1 + throwforce = 2 + w_class = WEIGHT_CLASS_TINY + var/string_attached + var/list/sideslist = list("heads","tails") + var/cmineral = null + var/cooldown = 0 + var/credits = 10 + +/obj/item/coin/New() + pixel_x = rand(0,16)-8 + pixel_y = rand(0,8)-8 + + icon_state = "coin_[cmineral]_[sideslist[1]]" + if(cmineral) + name = "[cmineral] coin" + +/obj/item/coin/gold + cmineral = "gold" + icon_state = "coin_gold_heads" + materials = list(MAT_GOLD = 400) + credits = 160 + +/obj/item/coin/silver + cmineral = "silver" + icon_state = "coin_silver_heads" + materials = list(MAT_SILVER = 400) + credits = 40 + +/obj/item/coin/diamond + cmineral = "diamond" + icon_state = "coin_diamond_heads" + materials = list(MAT_DIAMOND = 400) + credits = 120 + +/obj/item/coin/iron + cmineral = "iron" + icon_state = "coin_iron_heads" + materials = list(MAT_METAL = 400) + credits = 20 + +/obj/item/coin/plasma + cmineral = "plasma" + icon_state = "coin_plasma_heads" + materials = list(MAT_PLASMA = 400) + credits = 80 + +/obj/item/coin/uranium + cmineral = "uranium" + icon_state = "coin_uranium_heads" + materials = list(MAT_URANIUM = 400) + credits = 160 + +/obj/item/coin/clown + cmineral = "bananium" + icon_state = "coin_bananium_heads" + materials = list(MAT_BANANIUM = 400) + credits = 600 //makes the clown cri + +/obj/item/coin/mime + cmineral = "tranquillite" + icon_state = "coin_tranquillite_heads" + materials = list(MAT_TRANQUILLITE = 400) + credits = 600 //makes the mime cri + +/obj/item/coin/adamantine + cmineral = "adamantine" + icon_state = "coin_adamantine_heads" + credits = 400 + +/obj/item/coin/mythril + cmineral = "mythril" + icon_state = "coin_mythril_heads" + credits = 400 + +/obj/item/coin/twoheaded + cmineral = "iron" + icon_state = "coin_iron_heads" + desc = "Hey, this coin's the same on both sides!" + sideslist = list("heads") + credits = 20 + +/obj/item/coin/antagtoken + name = "antag token" + icon_state = "coin_valid_valid" + cmineral = "valid" + desc = "A novelty coin that helps the heart know what hard evidence cannot prove." + sideslist = list("valid", "salad") + credits = 20 + +/obj/item/coin/antagtoken/syndicate + name = "syndicate coin" + credits = 160 + +/obj/item/coin/attackby(obj/item/W as obj, mob/user as mob, params) + if(istype(W, /obj/item/stack/cable_coil)) + var/obj/item/stack/cable_coil/CC = W + if(string_attached) + to_chat(user, "There already is a string attached to this coin.") + return + + if(CC.use(1)) + overlays += image('icons/obj/economy.dmi',"coin_string_overlay") + string_attached = 1 + to_chat(user, "You attach a string to the coin.") + else + to_chat(user, "You need one length of cable to attach a string to the coin.") + return + + else if(istype(W,/obj/item/wirecutters)) + if(!string_attached) + ..() + return + + var/obj/item/stack/cable_coil/CC = new/obj/item/stack/cable_coil(user.loc) + CC.amount = 1 + CC.update_icon() + overlays = list() + string_attached = null + to_chat(user, "You detach the string from the coin.") + else if(istype(W,/obj/item/weldingtool)) + var/obj/item/weldingtool/WT = W + if(WT.welding && WT.remove_fuel(0, user)) + var/typelist = list("iron" = /obj/item/clothing/gloves/ring, + "silver" = /obj/item/clothing/gloves/ring/silver, + "gold" = /obj/item/clothing/gloves/ring/gold, + "plasma" = /obj/item/clothing/gloves/ring/plasma, + "uranium" = /obj/item/clothing/gloves/ring/uranium) + var/typekey = typelist[cmineral] + if(ispath(typekey)) + to_chat(user, "You make [src] into a ring.") + new typekey(get_turf(loc)) + qdel(src) + else ..() + +/obj/item/coin/attack_self(mob/user as mob) + if(cooldown < world.time - 15) + var/coinflip = pick(sideslist) + cooldown = world.time + flick("coin_[cmineral]_flip", src) + icon_state = "coin_[cmineral]_[coinflip]" + playsound(user.loc, 'sound/items/coinflip.ogg', 50, 1) + if(do_after(user, 15, target = src)) + user.visible_message("[user] has flipped [src]. It lands on [coinflip].", \ + "You flip [src]. It lands on [coinflip].", \ + "You hear the clattering of loose change.") #undef GIBTONITE_QUALITY_LOW #undef GIBTONITE_QUALITY_MEDIUM diff --git a/code/modules/mob/dead/observer/observer.dm b/code/modules/mob/dead/observer/observer.dm index 731f53c7838..7c80b93e5ee 100644 --- a/code/modules/mob/dead/observer/observer.dm +++ b/code/modules/mob/dead/observer/observer.dm @@ -29,6 +29,7 @@ GLOBAL_VAR_INIT(observer_default_invisibility, INVISIBILITY_OBSERVER) var/seedarkness = TRUE var/data_hud_seen = FALSE //this should one of the defines in __DEFINES/hud.dm var/ghost_orbit = GHOST_ORBIT_CIRCLE + var/health_scan = FALSE //does the ghost have health scanner mode on? by default it should be off /mob/dead/observer/New(var/mob/body=null, var/flags=1) set_invisibility(GLOB.observer_default_invisibility) @@ -236,6 +237,7 @@ This is the proc mobs get to turn into a ghost. Forked from ghostize due to comp return 1 /mob/dead/observer/Move(NewLoc, direct) + update_parallax_contents() following = null setDir(direct) ghostimage.setDir(dir) @@ -417,6 +419,7 @@ This is the proc mobs get to turn into a ghost. Forked from ghostize due to comp return forceMove(pick(L)) + update_parallax_contents() following = null /mob/dead/observer/verb/follow() @@ -511,6 +514,8 @@ This is the proc mobs get to turn into a ghost. Forked from ghostize due to comp if(T && isturf(T)) //Make sure the turf exists, then move the source to that destination. A.forceMove(T) + M.update_parallax_contents() + following = null return to_chat(A, "This mob is not located in the game world.") @@ -537,6 +542,19 @@ This is the proc mobs get to turn into a ghost. Forked from ghostize due to comp set hidden = 1 to_chat(src, "You are dead! You have no mind to store memory!") + +/mob/dead/observer/verb/toggle_health_scan() + set name = "Toggle Health Scan" + set desc = "Toggles whether you health-scan living beings on click" + set category = "Ghost" + + if(health_scan) //remove old huds + to_chat(src, "Health scan disabled.") + health_scan = FALSE + else + to_chat(src, "Health scan enabled.") + health_scan = TRUE + /mob/dead/observer/verb/analyze_air() set name = "Analyze Air" set category = "Ghost" @@ -761,14 +779,17 @@ This is the proc mobs get to turn into a ghost. Forked from ghostize due to comp /mob/dead/observer/proc/incarnate_ghost() if(!client) return + var/mob/living/carbon/human/new_char = new(get_turf(src)) client.prefs.copy_to(new_char) if(mind) - mind.active = 1 + mind.active = TRUE mind.transfer_to(new_char) else new_char.key = key + return new_char + /mob/dead/observer/is_literate() return TRUE diff --git a/code/modules/mob/language.dm b/code/modules/mob/language.dm index 57725da8eb2..9391f24035a 100644 --- a/code/modules/mob/language.dm +++ b/code/modules/mob/language.dm @@ -762,6 +762,8 @@ desc = "Bark bark bark." key = "vu" - +/mob/proc/grant_all_languages() + for(var/la in GLOB.all_languages) + add_language(la) #undef SCRAMBLE_CACHE_LEN diff --git a/code/modules/mob/living/carbon/carbon.dm b/code/modules/mob/living/carbon/carbon.dm index a8dbaa7ac2f..82b98a3732e 100644 --- a/code/modules/mob/living/carbon/carbon.dm +++ b/code/modules/mob/living/carbon/carbon.dm @@ -1128,6 +1128,7 @@ so that different stomachs can handle things in different ways VB*/ var/obj/item/clothing/C = I if(C.tint || initial(C.tint)) update_tint() + update_sight() if(I.flags_inv & HIDEMASK || forced) update_inv_wear_mask() update_inv_head() diff --git a/code/modules/mob/living/carbon/carbon_defense.dm b/code/modules/mob/living/carbon/carbon_defense.dm index 7b8790076ce..c583d9873b6 100644 --- a/code/modules/mob/living/carbon/carbon_defense.dm +++ b/code/modules/mob/living/carbon/carbon_defense.dm @@ -16,7 +16,7 @@ /mob/living/carbon/water_act(volume, temperature, source, method = TOUCH) . = ..() - if(volume > 10) //anything over 10 volume will make the mob wetter. + if(volume > 10) // Anything over 10 volume will make the mob wetter. wetlevel = min(wetlevel + 1,5) /mob/living/carbon/attackby(obj/item/I, mob/user, params) diff --git a/code/modules/mob/living/carbon/human/examine.dm b/code/modules/mob/living/carbon/human/examine.dm index 4aef44444e9..1862fe5cffa 100644 --- a/code/modules/mob/living/carbon/human/examine.dm +++ b/code/modules/mob/living/carbon/human/examine.dm @@ -390,7 +390,7 @@ S = H.glasses return !istype(CIH,/obj/item/organ/internal/cyberimp/eyes/hud/security) && S && S.read_only if("medical") - return istype(H.glasses, /obj/item/clothing/glasses/hud/health) || istype(H.glasses, /obj/item/clothing/glasses/hud/health/health_advanced) || istype(CIH,/obj/item/organ/internal/cyberimp/eyes/hud/medical) + return istype(H.glasses, /obj/item/clothing/glasses/hud/health) || istype(CIH,/obj/item/organ/internal/cyberimp/eyes/hud/medical) else return 0 else if(isrobot(M) || isAI(M)) //Stand-in/Stopgap to prevent pAIs from freely altering records, pending a more advanced Records system diff --git a/code/modules/mob/living/carbon/human/human.dm b/code/modules/mob/living/carbon/human/human.dm index c0e4d8570a1..11d2e2b1395 100644 --- a/code/modules/mob/living/carbon/human/human.dm +++ b/code/modules/mob/living/carbon/human/human.dm @@ -106,6 +106,9 @@ /mob/living/carbon/human/diona/Initialize(mapload) ..(mapload, /datum/species/diona) +/mob/living/carbon/human/pod_diona/Initialize(mapload) + ..(mapload, /datum/species/diona/pod) + /mob/living/carbon/human/machine/Initialize(mapload) ..(mapload, /datum/species/machine) @@ -165,7 +168,11 @@ show_stat_emergency_shuttle_eta() if(client.statpanel == "Status") - if(locate(/obj/item/assembly/health) in src) + var/total_user_contents = GetAllContents() // cache it + if(locate(/obj/item/gps) in total_user_contents) + var/turf/T = get_turf(src) + stat(null, "GPS: [COORD(T)]") + if(locate(/obj/item/assembly/health) in total_user_contents) stat(null, "Health: [health]") if(internal) if(!internal.air_contents) @@ -849,7 +856,7 @@ return var/read = 0 var/perpname = get_visible_name(TRUE) - + for(var/datum/data/record/E in data_core.general) if(E.fields["name"] == perpname) for(var/datum/data/record/R in data_core.medical) @@ -1096,17 +1103,22 @@ var/limb_path = organ_data["path"] var/obj/item/organ/external/O = new limb_path(temp_holder) if(H.get_limb_by_name(O.name)) //Check to see if the user already has an limb with the same name as the 'missing limb'. If they do, skip regrowth. - continue //In an example, this will prevent duplication of the mob's right arm if the mob is a Human and they have a Diona right arm, since, - //while the limb with the name 'right_arm' the mob has may not be listed in their species' bodyparts definition, it is still viable and has the appropriate limb name. + continue //In an example, this will prevent duplication of the mob's right arm if the mob is a Human and they have a Diona right arm, since, + //while the limb with the name 'right_arm' the mob has may not be listed in their species' bodyparts definition, it is still viable and has the appropriate limb name. else O = new limb_path(H) //Create the limb on the player. O.owner = H H.bodyparts |= H.bodyparts_by_name[O.limb_name] + if(O.body_part == HEAD) //They're sprouting a fresh head so lets hook them up with their genetic stuff so their new head looks like the original. + H.UpdateAppearance() //Replacing lost organs with the species default. temp_holder = new /mob/living/carbon/human() - for(var/index in H.dna.species.has_organ) - var/organ = H.dna.species.has_organ[index] + var/list/species_organs = H.dna.species.has_organ.Copy() //Compile a list of species organs and tack on the mutantears afterward. + if(H.dna.species.mutantears) + species_organs["ears"] = H.dna.species.mutantears + for(var/index in species_organs) + var/organ = species_organs[index] if(!(organ in types_of_int_organs)) //If the mob is missing this particular organ... var/obj/item/organ/internal/I = new organ(temp_holder) //Create the organ inside our holder so we can check it before implantation. if(H.get_organ_slot(I.slot)) //Check to see if the user already has an organ in the slot the 'missing organ' belongs to. If they do, skip implantation. @@ -1470,12 +1482,12 @@ var/obj/item/organ/internal/eyes/eyes = get_int_organ(/obj/item/organ/internal/eyes) var/obj/item/organ/internal/cyberimp/eyes/eye_implant = get_int_organ(/obj/item/organ/internal/cyberimp/eyes) if(istype(dna.species) && dna.species.eyes) - var/icon/eyes_icon = new/icon('icons/mob/human_face.dmi', dna.species.eyes) + var/icon/eyes_icon = new /icon('icons/mob/human_face.dmi', dna.species.eyes) if(eye_implant) //Eye implants override native DNA eye colo(u)r eyes_icon = eye_implant.generate_icon() else if(eyes) eyes_icon = eyes.generate_icon() - else + else //Error 404: Eyes not found! eyes_icon.Blend("#800000", ICON_ADD) return eyes_icon @@ -1484,8 +1496,8 @@ var/obj/item/organ/external/head/head_organ = get_organ("head") var/datum/sprite_accessory/hair/hair_style = GLOB.hair_styles_full_list[head_organ.h_style] var/icon/hair = new /icon("icon" = hair_style.icon, "icon_state" = "[hair_style.icon_state]_s") - var/mutable_appearance/MA = mutable_appearance(get_icon_difference(get_eyecon(), hair), layer = LIGHTING_LAYER + 1) - MA.plane = LIGHTING_PLANE + var/mutable_appearance/MA = mutable_appearance(get_icon_difference(get_eyecon(), hair), layer = ABOVE_LIGHTING_LAYER) + MA.plane = ABOVE_LIGHTING_PLANE return MA //Cut the hair's pixels from the eyes icon so eyes covered by bangs stay hidden even while on a higher layer. /*Used to check if eyes should shine in the dark. Returns the image of the eyes on the layer where they will appear to shine. @@ -1877,6 +1889,7 @@ Eyes need to have significantly high darksight to shine unless the mob has the X . = ..() . += "---" .["Set Species"] = "?_src_=vars;setspecies=[UID()]" + .["Copy Outfit"] = "?_src_=vars;copyoutfit=[UID()]" .["Make AI"] = "?_src_=vars;makeai=[UID()]" .["Make cyborg"] = "?_src_=vars;makerobot=[UID()]" .["Make monkey"] = "?_src_=vars;makemonkey=[UID()]" diff --git a/code/modules/mob/living/carbon/human/human_damage.dm b/code/modules/mob/living/carbon/human/human_damage.dm index e106d214fd3..3d4aadf5746 100644 --- a/code/modules/mob/living/carbon/human/human_damage.dm +++ b/code/modules/mob/living/carbon/human/human_damage.dm @@ -202,6 +202,16 @@ amount = amount * dna.species.tox_mod . = ..() +/mob/living/carbon/human/adjustStaminaLoss(amount, updating = TRUE) + if(dna.species && amount > 0) + amount = amount * dna.species.stamina_mod + . = ..() + +/mob/living/carbon/human/setStaminaLoss(amount, updating = TRUE) + if(dna.species && amount > 0) + amount = amount * dna.species.stamina_mod + . = ..() + //////////////////////////////////////////// //Returns a list of damaged organs diff --git a/code/modules/mob/living/carbon/human/human_defense.dm b/code/modules/mob/living/carbon/human/human_defense.dm index b95920e688b..d172fabef00 100644 --- a/code/modules/mob/living/carbon/human/human_defense.dm +++ b/code/modules/mob/living/carbon/human/human_defense.dm @@ -141,19 +141,19 @@ emp_act if(l_hand && !istype(l_hand, /obj/item/clothing)) var/final_block_chance = l_hand.block_chance - (Clamp((armour_penetration-l_hand.armour_penetration)/2,0,100)) + block_chance_modifier //So armour piercing blades can still be parried by other blades, for example - if(l_hand.hit_reaction(src, attack_text, final_block_chance, damage, attack_type)) + if(l_hand.hit_reaction(src, attack_text, final_block_chance, damage, attack_type, AM)) return 1 if(r_hand && !istype(r_hand, /obj/item/clothing)) var/final_block_chance = r_hand.block_chance - (Clamp((armour_penetration-r_hand.armour_penetration)/2,0,100)) + block_chance_modifier //Need to reset the var so it doesn't carry over modifications between attempts - if(r_hand.hit_reaction(src, attack_text, final_block_chance, damage, attack_type)) + if(r_hand.hit_reaction(src, attack_text, final_block_chance, damage, attack_type, AM)) return 1 if(wear_suit) var/final_block_chance = wear_suit.block_chance - (Clamp((armour_penetration-wear_suit.armour_penetration)/2,0,100)) + block_chance_modifier - if(wear_suit.hit_reaction(src, attack_text, final_block_chance, damage, attack_type)) + if(wear_suit.hit_reaction(src, attack_text, final_block_chance, damage, attack_type, AM)) return 1 if(w_uniform) var/final_block_chance = w_uniform.block_chance - (Clamp((armour_penetration-w_uniform.armour_penetration)/2,0,100)) + block_chance_modifier - if(w_uniform.hit_reaction(src, attack_text, final_block_chance, damage, attack_type)) + if(w_uniform.hit_reaction(src, attack_text, final_block_chance, damage, attack_type, AM)) return 1 return 0 @@ -525,4 +525,4 @@ emp_act if(head) to_chat(src, "Your [head.name] protects you from the [hot ? "hot" : "cold"] liquid!") return FALSE - return TRUE \ No newline at end of file + return TRUE diff --git a/code/modules/mob/living/carbon/human/human_movement.dm b/code/modules/mob/living/carbon/human/human_movement.dm index 925e979c11d..b6bf5b34bac 100644 --- a/code/modules/mob/living/carbon/human/human_movement.dm +++ b/code/modules/mob/living/carbon/human/human_movement.dm @@ -11,10 +11,11 @@ //Do we have a working jetpack? var/obj/item/tank/jetpack/thrust - if(istype(back,/obj/item/tank/jetpack)) + if(istype(back, /obj/item/tank/jetpack)) thrust = back - else if(istype(s_store,/obj/item/tank/jetpack)) - thrust = s_store + else if(istype(wear_suit, /obj/item/clothing/suit/space/hardsuit)) + var/obj/item/clothing/suit/space/hardsuit/C = wear_suit + thrust = C.jetpack else if(istype(back,/obj/item/rig)) var/obj/item/rig/rig = back for(var/obj/item/rig_module/maneuvering_jets/module in rig.installed_modules) @@ -63,7 +64,8 @@ else //No oldFP or it's a different kind of blood S.bloody_shoes[S.blood_state] = max(0, S.bloody_shoes[S.blood_state] - BLOOD_LOSS_PER_STEP) - createFootprintsFrom(shoes, dir, T) + if(S.bloody_shoes[S.blood_state] > BLOOD_LOSS_IN_SPREAD) + createFootprintsFrom(shoes, dir, T) update_inv_shoes() else if(hasfeet) if(bloody_feet && bloody_feet[blood_state]) @@ -72,7 +74,8 @@ return else bloody_feet[blood_state] = max(0, bloody_feet[blood_state] - BLOOD_LOSS_PER_STEP) - createFootprintsFrom(src, dir, T) + if(bloody_feet[blood_state] > BLOOD_LOSS_IN_SPREAD) + createFootprintsFrom(src, dir, T) update_inv_shoes() //End bloody footprints if(S) diff --git a/code/modules/mob/living/carbon/human/inventory.dm b/code/modules/mob/living/carbon/human/inventory.dm index cf9fcfd632c..c4ceb829fff 100644 --- a/code/modules/mob/living/carbon/human/inventory.dm +++ b/code/modules/mob/living/carbon/human/inventory.dm @@ -567,3 +567,10 @@ return 0 return O.equip(src, visualsOnly) + +//delete all equipment without dropping anything +/mob/living/carbon/human/proc/delete_equipment() + for(var/slot in get_all_slots())//order matters, dependant slots go first + qdel(slot) + for(var/obj/item/I in l_hand, r_hand) + qdel(I) diff --git a/code/modules/mob/living/carbon/human/species/_species.dm b/code/modules/mob/living/carbon/human/species/_species.dm index 438d3386948..3e295eb9b4c 100644 --- a/code/modules/mob/living/carbon/human/species/_species.dm +++ b/code/modules/mob/living/carbon/human/species/_species.dm @@ -50,6 +50,7 @@ var/oxy_mod = 1 // Oxy damage reduction/amplification var/clone_mod = 1 // Clone damage reduction/amplification var/brain_mod = 1 // Brain damage damage reduction/amplification + var/stamina_mod = 1 var/stun_mod = 1 // If a species is more/less impacated by stuns/weakens/paralysis var/blood_damage_type = OXY //What type of damage does this species take if it's low on blood? @@ -733,8 +734,8 @@ It'll return null if the organ doesn't correspond, so include null checks when u H.sync_lighting_plane_alpha() /datum/species/proc/water_act(mob/living/carbon/human/M, volume, temperature, source, method = TOUCH) - if(abs(temperature - M.bodytemperature) > 10) //If our water and mob temperature varies by more than 10K, cool or/ heat them appropriately - M.bodytemperature = (temperature + M.bodytemperature) * 0.5 //Approximation for gradual heating or cooling + if(abs(temperature - M.bodytemperature) > 10) // If our water and mob temperature varies by more than 10K, cool or/ heat them appropriately. + M.bodytemperature = (temperature + M.bodytemperature) * 0.5 // Approximation for gradual heating or cooling. /datum/species/proc/bullet_act(obj/item/projectile/P, mob/living/carbon/human/H) //return TRUE if hit, FALSE if stopped/reflected/etc return TRUE diff --git a/code/modules/mob/living/carbon/human/species/diona.dm b/code/modules/mob/living/carbon/human/species/diona.dm index bccbeb6c5a7..518ee94f8f0 100644 --- a/code/modules/mob/living/carbon/human/species/diona.dm +++ b/code/modules/mob/living/carbon/human/species/diona.dm @@ -7,21 +7,11 @@ speech_sounds = list('sound/voice/dionatalk1.ogg') //Credit https://www.youtube.com/watch?v=ufnvlRjsOTI [0:13 - 0:16] speech_chance = 20 unarmed_type = /datum/unarmed_attack/diona - //primitive_form = "Nymph" - slowdown = 5 remains_type = /obj/effect/decal/cleanable/ash - - warning_low_pressure = 50 - hazard_low_pressure = -1 - - cold_level_1 = 50 - cold_level_2 = -1 - cold_level_3 = -1 - - heat_level_1 = 300 - heat_level_2 = 340 - heat_level_3 = 400 + burn_mod = 1.25 + heatmod = 1.5 + var/pod = FALSE //did they come from a pod? If so, they're stronger than normal Diona. blurb = "Commonly referred to (erroneously) as 'plant people', the Dionaea are a strange space-dwelling collective \ species hailing from Epsilon Ursae Minoris. Each 'diona' is a cluster of numerous cat-sized organisms called nymphs; \ @@ -31,16 +21,14 @@ even the simplest concepts of other minds. Their alien physiology allows them survive happily off a diet of nothing but light, \ water and other radiation." - species_traits = list(NO_BREATHE, RADIMMUNE, IS_PLANT, NO_BLOOD, NO_PAIN) - dies_at_threshold = TRUE + species_traits = list(IS_PLANT) clothing_flags = HAS_SOCKS default_hair_colour = "#000000" has_gender = FALSE - dietflags = 0 //Diona regenerate nutrition in light and water, no diet necessary - taste_sensitivity = TASTE_SENSITIVITY_NO_TASTE + dietflags = DIET_HERB //Diona regenerate nutrition in light and water, no diet necessary, but if they must, they eat other plants *scream + taste_sensitivity = TASTE_SENSITIVITY_DULL skinned_type = /obj/item/stack/sheet/wood - body_temperature = T0C + 15 //make the plant people have a bit lower body temperature, why not blood_color = "#004400" flesh_color = "#907E4A" butt_sprite = "diona" @@ -49,6 +37,7 @@ has_organ = list( "nutrient channel" = /obj/item/organ/internal/liver/diona, + "respiratory vacuoles" = /obj/item/organ/internal/lungs/diona, "neural strata" = /obj/item/organ/internal/heart/diona, "receptor node" = /obj/item/organ/internal/eyes/diona, //Default darksight of 2. "gas bladder" = /obj/item/organ/internal/brain/diona, @@ -85,29 +74,47 @@ ..() H.gender = NEUTER -/datum/species/diona/handle_life(mob/living/carbon/human/H) - H.radiation = Clamp(H.radiation, 0, 100) //We have to clamp this first, then decrease it, or there's a few edge cases of massive heals if we clamp and decrease at the same time. - var/rads = H.radiation / 25 - H.radiation = max(H.radiation-rads, 0) - H.nutrition = min(H.nutrition+rads, NUTRITION_LEVEL_WELL_FED+10) - H.adjustBruteLoss(-(rads)) - H.adjustToxLoss(-(rads)) +/datum/species/diona/handle_reagents(mob/living/carbon/human/H, datum/reagent/R) + if(R.id == "glyphosate" || R.id == "atrazine") + H.adjustToxLoss(3) //Deal aditional damage + return TRUE + return ..() +/datum/species/diona/handle_life(mob/living/carbon/human/H) + if(H.stat == DEAD) + return var/light_amount = 0 //how much light there is in the place, affects receiving nutrition and healing if(isturf(H.loc)) //else, there's considered to be no light var/turf/T = H.loc - light_amount = min(T.get_lumcount() * 10, 5) //hardcapped so it's not abused by having a ton of flashlights - H.nutrition = min(H.nutrition+light_amount, NUTRITION_LEVEL_WELL_FED+10) + light_amount = min(1, T.get_lumcount()) - 0.5 + if(light_amount > 0) + H.clear_alert("nolight") + else + H.throw_alert("nolight", /obj/screen/alert/nolight) + H.nutrition += light_amount * 10 + if(H.nutrition > NUTRITION_LEVEL_ALMOST_FULL) + H.nutrition = NUTRITION_LEVEL_ALMOST_FULL + if(light_amount > 0.2 && !H.suiciding) //if there's enough light, heal + if(!pod && H.health <= 0) + return + H.adjustBruteLoss(-1) + H.adjustFireLoss(-1) + H.adjustToxLoss(-1) + H.adjustOxyLoss(-1) - if(light_amount > 0) - H.clear_alert("nolight") - else - H.throw_alert("nolight", /obj/screen/alert/nolight) - - if((light_amount >= 5) && !H.suiciding) //if there's enough light, heal - - H.adjustBruteLoss(-(light_amount/2)) - H.adjustFireLoss(-(light_amount/4)) - if(H.nutrition < NUTRITION_LEVEL_STARVING+50) - H.take_overall_damage(10,0) + if(H.nutrition < NUTRITION_LEVEL_STARVING + 50) + H.adjustBruteLoss(2) ..() + +/datum/species/diona/pod //Same name and everything; we want the same limitations on them; we just want their regeneration to kick in at all times and them to have special factions + pod = TRUE + +/datum/species/diona/pod/on_species_gain(mob/living/carbon/C, datum/species/old_species) + . = ..() + C.faction |= "plants" + C.faction |= "vines" + +/datum/species/diona/pod/on_species_loss(mob/living/carbon/C) + . = ..() + C.faction -= "plants" + C.faction -= "vines" \ No newline at end of file diff --git a/code/modules/mob/living/carbon/human/species/golem.dm b/code/modules/mob/living/carbon/human/species/golem.dm index c1e416a8a48..9d74e7e2130 100644 --- a/code/modules/mob/living/carbon/human/species/golem.dm +++ b/code/modules/mob/living/carbon/human/species/golem.dm @@ -251,28 +251,44 @@ attack_verb = list("smash") attack_sound = 'sound/effects/meteorimpact.ogg' -//More resistant to burn damage -//Add ashstorm resistance if we ever port lavaland +//More resistant to burn damage and immune to ashstorm /datum/species/golem/titanium name = "Titanium Golem" golem_colour = rgb(255, 255, 255) skinned_type = /obj/item/stack/ore/titanium - info_text = "As a Titanium Golem, you are resistant to burn damage." + info_text = "As a Titanium Golem, you are resistant to burn damage and immune to ash storms." burn_mod = 0.3 prefix = "Titanium" special_names = list("Dioxide") -//Even more resistant to burn damage -//Add ashstorm and lava resistance if we ever port lavaland +/datum/species/golem/titanium/on_species_gain(mob/living/carbon/C, datum/species/old_species) + . = ..() + C.weather_immunities |= "ash" + +/datum/species/golem/titanium/on_species_loss(mob/living/carbon/C) + . = ..() + C.weather_immunities -= "ash" + +//Even more resistant to burn damage and immune to ashstorms and lava /datum/species/golem/plastitanium name = "Plastitanium Golem" golem_colour = rgb(136, 136, 136) skinned_type = /obj/item/stack/ore/titanium - info_text = "As a Plastitanium Golem, you are very resistant to burn damage." + info_text = "As a Plastitanium Golem, you are very resistant to burn damage and immune to both ash storms and lava." burn_mod = 0.15 prefix = "Plastitanium" special_names = null +/datum/species/golem/plastitanium/on_species_gain(mob/living/carbon/C, datum/species/old_species) + . = ..() + C.weather_immunities |= "lava" + C.weather_immunities |= "ash" + +/datum/species/golem/plastitanium/on_species_loss(mob/living/carbon/C) + . = ..() + C.weather_immunities -= "ash" + C.weather_immunities -= "lava" + //Fast and regenerates... but can only speak like an abductor /datum/species/golem/alloy name = "Alien Alloy Golem" @@ -357,10 +373,12 @@ /datum/species/golem/uranium/handle_life(mob/living/carbon/human/H) for(var/mob/living/L in range(2, H)) - if(isgolem(H)) - continue - to_chat(L, "You are enveloped by a soft green glow emanating from [H].") - L.apply_effect(10, IRRADIATE) + if(ishuman(L)) + var/mob/living/carbon/human/I = L + if(!(RADIMMUNE in I.dna.species.species_traits)) + L.apply_effect(10, IRRADIATE) + if(prob(25)) //reduce spam + to_chat(L, "You are enveloped by a soft green glow emanating from [H].") ..() //Ventcrawler @@ -592,7 +610,7 @@ punchdamagehigh = 0 punchstunthreshold = 1 //Harmless and can't stun skinned_type = /obj/item/stack/ore/bananium - info_text = "As a Bananium Golem, you are made for pranking. Your body emits natural honks, and you can barely even hurt people when punching them. Your skin also bleeds banana peels when damaged." + info_text = "As a Bananium Golem, you are made for pranking. Your body emits natural honks, and punching people will just harmlessly honk them. Your skin also bleeds banana peels when damaged." prefix = "Bananium" special_names = null unarmed_type = /datum/unarmed_attack/golem/bananium @@ -610,6 +628,12 @@ H.mutations.Add(COMIC) H.equip_to_slot_or_del(new /obj/item/reagent_containers/food/drinks/bottle/bottleofbanana(H), slot_r_store) H.equip_to_slot_or_del(new /obj/item/bikehorn(H), slot_l_store) + H.AddComponent(/datum/component/waddling) + +/datum/species/golem/bananium/on_species_loss(mob/living/carbon/C) + . = ..() + GET_COMPONENT_FROM(waddling, /datum/component/waddling, C) + waddling.Destroy() /datum/species/golem/bananium/get_random_name() var/clown_name = pick(GLOB.clown_names) diff --git a/code/modules/mob/living/carbon/human/species/grey.dm b/code/modules/mob/living/carbon/human/species/grey.dm index 3b8bbe34ffb..fd8fc09fd4d 100644 --- a/code/modules/mob/living/carbon/human/species/grey.dm +++ b/code/modules/mob/living/carbon/human/species/grey.dm @@ -40,15 +40,15 @@ . = ..() if(method == TOUCH) + if(H.wear_mask) + to_chat(H, "Your [H.wear_mask] protects you from the acid!") + return + + if(H.head) + to_chat(H, "Your [H.wear_mask] protects you from the acid!") + return + if(volume > 25) - if(H.wear_mask) - to_chat(H, "Your [H.wear_mask] protects you from the acid!") - return - - if(H.head) - to_chat(H, "Your [H.wear_mask] protects you from the acid!") - return - if(prob(75)) H.take_organ_damage(5, 10) H.emote("scream") @@ -65,9 +65,6 @@ H.adjustFireLoss(min(max(4, (volume - 10) * 2), 20)) H.emote("scream") to_chat(H, "The water stings[volume < 10 ? " you, but isn't concentrated enough to harm you" : null]!") - if(volume >= 10) - H.adjustFireLoss(min(max(4, (volume - 10) * 2), 20)) - H.emote("scream") /datum/species/grey/after_equip_job(datum/job/J, mob/living/carbon/human/H) var/translator_pref = H.client.prefs.speciesprefs diff --git a/code/modules/mob/living/carbon/human/species/plasmaman.dm b/code/modules/mob/living/carbon/human/species/plasmaman.dm index 785d737aec2..e4ba4349202 100644 --- a/code/modules/mob/living/carbon/human/species/plasmaman.dm +++ b/code/modules/mob/living/carbon/human/species/plasmaman.dm @@ -6,21 +6,19 @@ dangerous_existence = TRUE //So so much //language = "Clatter" - species_traits = list(IS_WHITELISTED, NO_BLOOD, NOTRANSSTING) + species_traits = list(IS_WHITELISTED, RADIMMUNE, NO_BLOOD, NOTRANSSTING) forced_heartattack = TRUE // Plasmamen have no blood, but they should still get heart-attacks skinned_type = /obj/item/stack/sheet/mineral/plasma // We're low on plasma, R&D! *eyes plasmaman co-worker intently* dietflags = DIET_OMNI reagent_tag = PROCESS_ORG - //default_mutations=list(SKELETON) // This screws things up - butt_sprite = "plasma" breathid = "tox" - heat_level_1 = 350 // Heat damage level 1 above this point. - heat_level_2 = 400 // Heat damage level 2 above this point. - heat_level_3 = 500 // Heat damage level 3 above this point. + burn_mod = 1.5 + heatmod = 1.5 + brute_mod = 1.5 //Has default darksight of 2. @@ -48,136 +46,118 @@ message = replacetext(message, "s", stutter("ss")) return message -/datum/species/plasmaman/after_equip_job(datum/job/J, mob/living/carbon/human/H) - var/assigned_role = H.mind && H.mind.assigned_role ? H.mind.assigned_role : "Civilian" - // Unequip existing suits and hats. - H.unEquip(H.wear_suit) - H.unEquip(H.head) - if(assigned_role != "Clown") - H.unEquip(H.wear_mask) - - H.equip_or_collect(new /obj/item/clothing/mask/breath(H), slot_wear_mask) - var/suit=/obj/item/clothing/suit/space/eva/plasmaman/assistant - var/helm=/obj/item/clothing/head/helmet/space/eva/plasmaman/assistant - var/tank_slot = slot_s_store - var/tank_slot_name = "suit storage" - - switch(assigned_role) - if("Scientist","Roboticist") - suit=/obj/item/clothing/suit/space/eva/plasmaman/science - helm=/obj/item/clothing/head/helmet/space/eva/plasmaman/science - if("Geneticist") - suit=/obj/item/clothing/suit/space/eva/plasmaman/science/geneticist - helm=/obj/item/clothing/head/helmet/space/eva/plasmaman/science/geneticist - if("Research Director") - suit=/obj/item/clothing/suit/space/eva/plasmaman/science/rd - helm=/obj/item/clothing/head/helmet/space/eva/plasmaman/science/rd - if("Station Engineer", "Mechanic") - suit=/obj/item/clothing/suit/space/eva/plasmaman/engineer - helm=/obj/item/clothing/head/helmet/space/eva/plasmaman/engineer - if("Chief Engineer") - suit=/obj/item/clothing/suit/space/eva/plasmaman/engineer/ce - helm=/obj/item/clothing/head/helmet/space/eva/plasmaman/engineer/ce - if("Life Support Specialist") - suit=/obj/item/clothing/suit/space/eva/plasmaman/atmostech - helm=/obj/item/clothing/head/helmet/space/eva/plasmaman/atmostech - if("Detective") - suit=/obj/item/clothing/suit/space/eva/plasmaman/security - helm=/obj/item/clothing/head/helmet/space/eva/plasmaman/security - if("Warden","Security Officer","Security Pod Pilot") - suit=/obj/item/clothing/suit/space/eva/plasmaman/security - helm=/obj/item/clothing/head/helmet/space/eva/plasmaman/security - if("Internal Affairs Agent") - suit=/obj/item/clothing/suit/space/eva/plasmaman/lawyer - helm=/obj/item/clothing/head/helmet/space/eva/plasmaman/lawyer - if("Magistrate") - suit=/obj/item/clothing/suit/space/eva/plasmaman/magistrate - helm=/obj/item/clothing/head/helmet/space/eva/plasmaman/magistrate - if("Head of Security", "Special Operations Officer") - suit=/obj/item/clothing/suit/space/eva/plasmaman/security/hos - helm=/obj/item/clothing/head/helmet/space/eva/plasmaman/security/hos - if("Captain", "Blueshield") - suit=/obj/item/clothing/suit/space/eva/plasmaman/security/captain - helm=/obj/item/clothing/head/helmet/space/eva/plasmaman/security/captain - if("Head of Personnel") - suit=/obj/item/clothing/suit/space/eva/plasmaman/security/hop - helm=/obj/item/clothing/head/helmet/space/eva/plasmaman/security/hop - if("Nanotrasen Representative", "Nanotrasen Navy Officer") - suit = /obj/item/clothing/suit/space/eva/plasmaman/nt_rep - helm = /obj/item/clothing/head/helmet/space/eva/plasmaman/nt_rep - if("Medical Doctor","Brig Physician","Virologist") - suit=/obj/item/clothing/suit/space/eva/plasmaman/medical - helm=/obj/item/clothing/head/helmet/space/eva/plasmaman/medical - if("Paramedic") - suit=/obj/item/clothing/suit/space/eva/plasmaman/medical/paramedic - helm=/obj/item/clothing/head/helmet/space/eva/plasmaman/medical/paramedic - if("Chemist") - suit=/obj/item/clothing/suit/space/eva/plasmaman/medical/chemist - helm=/obj/item/clothing/head/helmet/space/eva/plasmaman/medical/chemist - if("Chief Medical Officer") - suit=/obj/item/clothing/suit/space/eva/plasmaman/medical/cmo - helm=/obj/item/clothing/head/helmet/space/eva/plasmaman/medical/cmo - if("Coroner") - suit=/obj/item/clothing/suit/space/eva/plasmaman/medical/coroner - helm=/obj/item/clothing/head/helmet/space/eva/plasmaman/medical/coroner - if("Virologist") - suit=/obj/item/clothing/suit/space/eva/plasmaman/medical/virologist - helm=/obj/item/clothing/head/helmet/space/eva/plasmaman/medical/virologist - if("Bartender", "Chef") - suit=/obj/item/clothing/suit/space/eva/plasmaman/service - helm=/obj/item/clothing/head/helmet/space/eva/plasmaman/service - if("Cargo Technician", "Quartermaster") - suit=/obj/item/clothing/suit/space/eva/plasmaman/cargo - helm=/obj/item/clothing/head/helmet/space/eva/plasmaman/cargo - if("Shaft Miner") - suit=/obj/item/clothing/suit/space/eva/plasmaman/explorer - helm=/obj/item/clothing/head/helmet/space/eva/plasmaman/explorer - if("Botanist") - suit=/obj/item/clothing/suit/space/eva/plasmaman/botanist - helm=/obj/item/clothing/head/helmet/space/eva/plasmaman/botanist +/datum/species/plasmaman/before_equip_job(datum/job/J, mob/living/carbon/human/H, visualsOnly = FALSE) + var/current_job = J.title + var/datum/outfit/plasmaman/O = new /datum/outfit/plasmaman + switch(current_job) if("Chaplain") - suit=/obj/item/clothing/suit/space/eva/plasmaman/chaplain - helm=/obj/item/clothing/head/helmet/space/eva/plasmaman/chaplain - if("Janitor") - suit=/obj/item/clothing/suit/space/eva/plasmaman/janitor - helm=/obj/item/clothing/head/helmet/space/eva/plasmaman/janitor - if("Civilian", "Barber") - suit=/obj/item/clothing/suit/space/eva/plasmaman/assistant - helm=/obj/item/clothing/head/helmet/space/eva/plasmaman/assistant - if("Clown") - suit=/obj/item/clothing/suit/space/eva/plasmaman/clown - helm=/obj/item/clothing/head/helmet/space/eva/plasmaman/clown - if("Mime") - suit=/obj/item/clothing/suit/space/eva/plasmaman/mime - helm=/obj/item/clothing/head/helmet/space/eva/plasmaman/mime - if("Syndicate Officer") - suit=/obj/item/clothing/suit/space/eva/plasmaman/nuclear - helm=/obj/item/clothing/head/helmet/space/eva/plasmaman/nuclear + O = new /datum/outfit/plasmaman/chaplain - if((H.mind.special_role == SPECIAL_ROLE_WIZARD) || (H.mind.special_role == SPECIAL_ROLE_WIZARD_APPRENTICE)) - H.equip_to_slot(new /obj/item/clothing/suit/space/eva/plasmaman/wizard(H), slot_wear_suit) - H.equip_to_slot(new /obj/item/clothing/head/helmet/space/eva/plasmaman/wizard(H), slot_head) - else - H.equip_or_collect(new suit(H), slot_wear_suit) - H.equip_or_collect(new helm(H), slot_head) - H.equip_or_collect(new /obj/item/tank/plasma/plasmaman(H), tank_slot) // Bigger plasma tank from Raggy. - H.equip_or_collect(new /obj/item/plasmensuit_cartridge(H), slot_in_backpack) - H.equip_or_collect(new /obj/item/plasmensuit_cartridge(H), slot_in_backpack) //Two refill cartridges for their suit. Can fit in boxes. - to_chat(H, "You are now running on plasma internals from the [H.s_store] in your [tank_slot_name]. You must breathe plasma in order to survive, and are extremely flammable.") - H.internal = H.get_item_by_slot(tank_slot) + if("Librarian") + O = new /datum/outfit/plasmaman/librarian + + if("Janitor") + O = new /datum/outfit/plasmaman/janitor + + if("Botanist") + O = new /datum/outfit/plasmaman/botany + + if("Bartender", "Internal Affairs Agent", "Magistrate", "Nanotrasen Representative", "Nanotrasen Navy Officer") + O = new /datum/outfit/plasmaman/bar + + if("Chef") + O = new /datum/outfit/plasmaman/chef + + if("Security Officer", "Security Pod Pilot", "Special Operations Officer") + O = new /datum/outfit/plasmaman/security + + if("Detective") + O = new /datum/outfit/plasmaman/detective + + if("Warden") + O = new /datum/outfit/plasmaman/warden + + if("Head of Security") + O = new /datum/outfit/plasmaman/hos + + if("Cargo Technician", "Quartermaster") + O = new /datum/outfit/plasmaman/cargo + + if("Shaft Miner") + O = new /datum/outfit/plasmaman/mining + + if("Medical Doctor", "Brig Physician", "Paramedic", "Coroner") + O = new /datum/outfit/plasmaman/medical + + if("Chief Medical Officer") + O = new /datum/outfit/plasmaman/cmo + + if("Chemist") + O = new /datum/outfit/plasmaman/chemist + + if("Geneticist") + O = new /datum/outfit/plasmaman/genetics + + if("Roboticist") + O = new /datum/outfit/plasmaman/robotics + + if("Virologist") + O = new /datum/outfit/plasmaman/viro + + if("Scientist") + O = new /datum/outfit/plasmaman/science + + if("Research Director") + O = new /datum/outfit/plasmaman/rd + + if("Station Engineer", "Mechanic") + O = new /datum/outfit/plasmaman/engineering + + if("Chief Engineer") + O = new /datum/outfit/plasmaman/ce + + if("Life Support Specialist") + O = new /datum/outfit/plasmaman/atmospherics + + if("Mime") + O = new /datum/outfit/plasmaman/mime + + if("Clown") + O = new /datum/outfit/plasmaman/clown + + if("Head of Personnel") + O = new /datum/outfit/plasmaman/hop + + if("Captain") + O = new /datum/outfit/plasmaman/captain + + if("Blueshield") + O = new /datum/outfit/plasmaman/blueshield + + H.equipOutfit(O, visualsOnly) + H.internal = H.r_hand H.update_action_buttons_icon() + return FALSE /datum/species/plasmaman/handle_life(mob/living/carbon/human/H) - if(!istype(H.wear_suit, /obj/item/clothing/suit/space/eva/plasmaman) || !istype(H.head, /obj/item/clothing/head/helmet/space/eva/plasmaman)) - var/datum/gas_mixture/environment = H.loc.return_air() - if(environment && environment.oxygen && environment.oxygen >= OXYCONCEN_PLASMEN_IGNITION) //Plasmamen so long as there's enough oxygen (0.5 moles, same as it takes to burn gaseous plasma). - H.adjust_fire_stacks(0.5) - if(!H.on_fire && H.fire_stacks > 0) - H.visible_message("[H]'s body reacts with the atmosphere and bursts into flames!","Your body reacts with the atmosphere and bursts into flame!") - H.IgniteMob() + var/datum/gas_mixture/environment = H.loc.return_air() + var/atmos_sealed = FALSE + if (H.wear_suit && H.head && istype(H.wear_suit, /obj/item/clothing) && istype(H.head, /obj/item/clothing)) + var/obj/item/clothing/CS = H.wear_suit + var/obj/item/clothing/CH = H.head + if (CS.flags & CH.flags & STOPSPRESSUREDMAGE) + atmos_sealed = TRUE + if((!istype(H.w_uniform, /obj/item/clothing/under/plasmaman) || !istype(H.head, /obj/item/clothing/head/helmet/space/plasmaman)) && !atmos_sealed) + if(environment) + if(environment.total_moles()) + if(environment.oxygen && environment.oxygen >= OXYCONCEN_PLASMEN_IGNITION) //Same threshhold that extinguishes fire + H.adjust_fire_stacks(0.5) + if(!H.on_fire && H.fire_stacks > 0) + H.visible_message("[H]'s body reacts with the atmosphere and bursts into flames!","Your body reacts with the atmosphere and bursts into flame!") + H.IgniteMob() else - if(H.on_fire && H.fire_stacks > 0) - var/obj/item/clothing/suit/space/eva/plasmaman/P = H.wear_suit + if(H.fire_stacks) + var/obj/item/clothing/under/plasmaman/P = H.w_uniform if(istype(P)) P.Extinguish(H) H.update_fire() diff --git a/code/modules/mob/living/carbon/human/status_procs.dm b/code/modules/mob/living/carbon/human/status_procs.dm index 30653023751..379eb183292 100644 --- a/code/modules/mob/living/carbon/human/status_procs.dm +++ b/code/modules/mob/living/carbon/human/status_procs.dm @@ -7,19 +7,19 @@ /mob/living/carbon/human/SetStunned(amount, updating = 1, force = 0) if(dna.species) amount = amount * dna.species.stun_mod - ..() + return ..() /mob/living/carbon/human/SetWeakened(amount, updating = 1, force = 0) if(dna.species) amount = amount * dna.species.stun_mod - ..() + return ..() /mob/living/carbon/human/SetParalysis(amount, updating = 1, force = 0) if(dna.species) amount = amount * dna.species.stun_mod - ..() + return ..() /mob/living/carbon/human/SetSleeping(amount, updating = 1, no_alert = FALSE) if(dna.species) amount = amount * dna.species.stun_mod - ..() \ No newline at end of file + return ..() \ No newline at end of file diff --git a/code/modules/mob/living/carbon/human/update_icons.dm b/code/modules/mob/living/carbon/human/update_icons.dm index 73a76e00420..05dfbd0e302 100644 --- a/code/modules/mob/living/carbon/human/update_icons.dm +++ b/code/modules/mob/living/carbon/human/update_icons.dm @@ -586,7 +586,8 @@ var/global/list/damage_icon_parts = list() standing.overlays += image("icon" = A.sprite_sheets[dna.species.name], "icon_state" = "[A.icon_state]") else standing.overlays += image("icon" = 'icons/mob/ties.dmi', "icon_state" = "[tie_color]") - + standing.alpha = w_uniform.alpha + standing.color = w_uniform.color overlays_standing[UNIFORM_LAYER] = standing else // Automatically drop anything in store / id / belt if you're not wearing a uniform. //CHECK IF NECESARRY @@ -716,12 +717,13 @@ var/global/list/damage_icon_parts = list() l_ear.screen_loc = ui_l_ear //...draw the item in the inventory screen client.screen += l_ear //Either way, add the item to the HUD - var/t_type = l_ear.icon_state + var/t_type = l_ear.item_state + if(!t_type) + t_type = l_ear.icon_state if(l_ear.icon_override) t_type = "[t_type]_l" overlays_standing[EARS_LAYER] = mutable_appearance(l_ear.icon_override, "[t_type]", layer = -EARS_LAYER) else if(l_ear.sprite_sheets && l_ear.sprite_sheets[dna.species.name]) - t_type = "[t_type]_l" overlays_standing[EARS_LAYER] = mutable_appearance(l_ear.sprite_sheets[dna.species.name], "[t_type]", layer = -EARS_LAYER) else overlays_standing[EARS_LAYER] = mutable_appearance('icons/mob/ears.dmi', "[t_type]", layer = -EARS_LAYER) @@ -732,12 +734,13 @@ var/global/list/damage_icon_parts = list() r_ear.screen_loc = ui_r_ear //...draw the item in the inventory screen client.screen += r_ear //Either way, add the item to the HUD - var/t_type = r_ear.icon_state + var/t_type = r_ear.item_state + if(!t_type) + t_type = r_ear.icon_state if(r_ear.icon_override) t_type = "[t_type]_r" overlays_standing[EARS_LAYER] = mutable_appearance(r_ear.icon_override, "[t_type]", layer = -EARS_LAYER) else if(r_ear.sprite_sheets && r_ear.sprite_sheets[dna.species.name]) - t_type = "[t_type]_r" overlays_standing[EARS_LAYER] = mutable_appearance(r_ear.sprite_sheets[dna.species.name], "[t_type]", layer = -EARS_LAYER) else overlays_standing[EARS_LAYER] = mutable_appearance('icons/mob/ears.dmi', "[t_type]", layer = -EARS_LAYER) @@ -769,6 +772,8 @@ var/global/list/damage_icon_parts = list() var/image/bloodsies = image("icon" = dna.species.blood_mask, "icon_state" = "shoeblood") bloodsies.color = shoes.blood_color standing.overlays += bloodsies + standing.alpha = shoes.alpha + standing.color = shoes.color overlays_standing[SHOES_LAYER] = standing else if(feet_blood_DNA) @@ -819,6 +824,8 @@ var/global/list/damage_icon_parts = list() var/image/bloodsies = image("icon" = dna.species.blood_mask, "icon_state" = "helmetblood") bloodsies.color = head.blood_color standing.overlays += bloodsies + standing.alpha = head.alpha + standing.color = head.color overlays_standing[HEAD_LAYER] = standing apply_overlay(HEAD_LAYER) @@ -886,6 +893,8 @@ var/global/list/damage_icon_parts = list() bloodsies.color = wear_suit.blood_color standing.overlays += bloodsies + standing.alpha = wear_suit.alpha + standing.color = wear_suit.color overlays_standing[SUIT_LAYER] = standing apply_overlay(SUIT_LAYER) @@ -931,27 +940,31 @@ var/global/list/damage_icon_parts = list() if(inv) inv.update_icon() if(wear_mask && (istype(wear_mask, /obj/item/clothing/mask) || istype(wear_mask, /obj/item/clothing/accessory))) - var/obj/item/organ/external/head/head_organ = get_organ("head") - var/datum/sprite_accessory/alt_heads/alternate_head - if(head_organ.alt_head && head_organ.alt_head != "None") - alternate_head = GLOB.alt_heads_list[head_organ.alt_head] + if(!(slot_wear_mask in check_obscured_slots())) + var/obj/item/organ/external/head/head_organ = get_organ("head") + var/datum/sprite_accessory/alt_heads/alternate_head + if(head_organ.alt_head && head_organ.alt_head != "None") + alternate_head = GLOB.alt_heads_list[head_organ.alt_head] - var/mutable_appearance/standing - var/icon/mask_icon = new(wear_mask.icon) - if(wear_mask.icon_override) - mask_icon = new(wear_mask.icon_override) - standing = mutable_appearance(wear_mask.icon_override, "[wear_mask.icon_state][(alternate_head && ("[wear_mask.icon_state]_[alternate_head.suffix]" in mask_icon.IconStates())) ? "_[alternate_head.suffix]" : ""]", layer = -FACEMASK_LAYER) - else if(wear_mask.sprite_sheets && wear_mask.sprite_sheets[dna.species.name]) - mask_icon = new(wear_mask.sprite_sheets[dna.species.name]) - standing = mutable_appearance(wear_mask.sprite_sheets[dna.species.name], "[wear_mask.icon_state][(alternate_head && ("[wear_mask.icon_state]_[alternate_head.suffix]" in mask_icon.IconStates())) ? "_[alternate_head.suffix]" : ""]", layer = -FACEMASK_LAYER) - else - standing = mutable_appearance('icons/mob/mask.dmi', "[wear_mask.icon_state][(alternate_head && ("[wear_mask.icon_state]_[alternate_head.suffix]" in mask_icon.IconStates())) ? "_[alternate_head.suffix]" : ""]", layer = -FACEMASK_LAYER) + var/mutable_appearance/standing + var/icon/mask_icon = new(wear_mask.icon) + if(wear_mask.icon_override) + mask_icon = new(wear_mask.icon_override) + standing = mutable_appearance(wear_mask.icon_override, "[wear_mask.icon_state][(alternate_head && ("[wear_mask.icon_state]_[alternate_head.suffix]" in mask_icon.IconStates())) ? "_[alternate_head.suffix]" : ""]", layer = -FACEMASK_LAYER) + else if(wear_mask.sprite_sheets && wear_mask.sprite_sheets[dna.species.name]) + mask_icon = new(wear_mask.sprite_sheets[dna.species.name]) + standing = mutable_appearance(wear_mask.sprite_sheets[dna.species.name], "[wear_mask.icon_state][(alternate_head && ("[wear_mask.icon_state]_[alternate_head.suffix]" in mask_icon.IconStates())) ? "_[alternate_head.suffix]" : ""]", layer = -FACEMASK_LAYER) + else + standing = mutable_appearance('icons/mob/mask.dmi', "[wear_mask.icon_state][(alternate_head && ("[wear_mask.icon_state]_[alternate_head.suffix]" in mask_icon.IconStates())) ? "_[alternate_head.suffix]" : ""]", layer = -FACEMASK_LAYER) - if(!istype(wear_mask, /obj/item/clothing/mask/cigarette) && wear_mask.blood_DNA) - var/image/bloodsies = image("icon" = dna.species.blood_mask, "icon_state" = "maskblood") - bloodsies.color = wear_mask.blood_color - standing.overlays += bloodsies - overlays_standing[FACEMASK_LAYER] = standing + if(!istype(wear_mask, /obj/item/clothing/mask/cigarette) && wear_mask.blood_DNA) + var/image/bloodsies = image("icon" = dna.species.blood_mask, "icon_state" = "maskblood") + bloodsies.color = wear_mask.blood_color + standing.overlays += bloodsies + + standing.alpha = wear_mask.alpha + standing.color = wear_mask.color + overlays_standing[FACEMASK_LAYER] = standing apply_overlay(FACEMASK_LAYER) @@ -973,6 +986,8 @@ var/global/list/damage_icon_parts = list() standing = mutable_appearance('icons/mob/back.dmi', "[back.icon_state]", layer = -BACK_LAYER) //create the image + standing.alpha = back.alpha + standing.color = back.color overlays_standing[BACK_LAYER] = standing apply_overlay(BACK_LAYER) @@ -1006,9 +1021,14 @@ var/global/list/damage_icon_parts = list() if(!t_state) t_state = r_hand.icon_state - var/mutable_appearance/I = mutable_appearance(r_hand.righthand_file, "[t_state]", layer = -R_HAND_LAYER) - I = center_image(I, r_hand.inhand_x_dimension, r_hand.inhand_y_dimension) - overlays_standing[R_HAND_LAYER] = I + var/mutable_appearance/standing + if(r_hand.sprite_sheets_inhand && r_hand.sprite_sheets_inhand[dna.species.name]) + t_state = "[t_state]_r" + standing = mutable_appearance(r_hand.sprite_sheets_inhand[dna.species.name], "[t_state]", layer = -R_HAND_LAYER) + else + standing = mutable_appearance(r_hand.righthand_file, "[t_state]", layer = -R_HAND_LAYER) + standing = center_image(standing, r_hand.inhand_x_dimension, r_hand.inhand_y_dimension) + overlays_standing[R_HAND_LAYER] = standing apply_overlay(R_HAND_LAYER) @@ -1020,9 +1040,14 @@ var/global/list/damage_icon_parts = list() if(!t_state) t_state = l_hand.icon_state - var/mutable_appearance/I = mutable_appearance(l_hand.lefthand_file, "[t_state]", layer = -L_HAND_LAYER) - I = center_image(I, l_hand.inhand_x_dimension, l_hand.inhand_y_dimension) - overlays_standing[L_HAND_LAYER] = I + var/mutable_appearance/standing + if(l_hand.sprite_sheets_inhand && l_hand.sprite_sheets_inhand[dna.species.name]) + t_state = "[t_state]_l" + standing = mutable_appearance(l_hand.sprite_sheets_inhand[dna.species.name], "[t_state]", layer = -L_HAND_LAYER) + else + standing = mutable_appearance(l_hand.lefthand_file, "[t_state]", layer = -L_HAND_LAYER) + standing = center_image(standing, l_hand.inhand_x_dimension, l_hand.inhand_y_dimension) + overlays_standing[L_HAND_LAYER] = standing apply_overlay(L_HAND_LAYER) //human HUD updates for items in our inventory diff --git a/code/modules/mob/living/carbon/slime/slime.dm b/code/modules/mob/living/carbon/slime/slime.dm index 38dadbbbfa7..ddab7eae1ee 100644 --- a/code/modules/mob/living/carbon/slime/slime.dm +++ b/code/modules/mob/living/carbon/slime/slime.dm @@ -510,13 +510,15 @@ mob/living/carbon/slime/var/temperature_resistance = T0C+75 /mob/living/carbon/slime/toggle_throw_mode() return -/mob/living/carbon/slime/proc/apply_water() - adjustToxLoss(rand(15,20)) - if(!client) - if(Target) // Like cats - Target = null - ++Discipline - return +/mob/living/carbon/slime/water_act(volume, temperature, source, method = TOUCH) + . = ..() + + var/water_damage = rand(10, 15) * volume + adjustToxLoss(water_damage) + + if(!client && Target && volume >= 3) + Target = null + ++Discipline /mob/living/carbon/slime/can_use_vents() if(Victim) diff --git a/code/modules/mob/living/damage_procs.dm b/code/modules/mob/living/damage_procs.dm index afca9ad8798..4f2323e2025 100644 --- a/code/modules/mob/living/damage_procs.dm +++ b/code/modules/mob/living/damage_procs.dm @@ -44,6 +44,22 @@ if(BRAIN) return adjustBrainLoss(damage) +/mob/living/proc/get_damage_amount(damagetype = BRUTE) + switch(damagetype) + if(BRUTE) + return getBruteLoss() + if(BURN) + return getFireLoss() + if(TOX) + return getToxLoss() + if(OXY) + return getOxyLoss() + if(CLONE) + return getCloneLoss() + if(STAMINA) + return getStaminaLoss() + + /mob/living/proc/apply_damages(var/brute = 0, var/burn = 0, var/tox = 0, var/oxy = 0, var/clone = 0, var/def_zone = null, var/blocked = 0, var/stamina = 0) if(blocked >= 100) return 0 if(brute) apply_damage(brute, BRUTE, def_zone, blocked) @@ -309,4 +325,16 @@ updatehealth("take overall damage") /mob/living/proc/has_organic_damage() - return (maxHealth - health) \ No newline at end of file + return (maxHealth - health) + +//heal up to amount damage, in a given order +/mob/living/proc/heal_ordered_damage(amount, list/damage_types) + . = amount //we'll return the amount of damage healed + for(var/i in damage_types) + var/amount_to_heal = min(amount, get_damage_amount(i)) //heal only up to the amount of damage we have + if(amount_to_heal) + apply_damage_type(-amount_to_heal, i) + amount -= amount_to_heal //remove what we healed from our current amount + if(!amount) + break + . -= amount //if there's leftover healing, remove it from what we return \ No newline at end of file diff --git a/code/modules/mob/living/silicon/ai/freelook/eye.dm b/code/modules/mob/living/silicon/ai/freelook/eye.dm index 7344c6469c4..c3c47235b91 100644 --- a/code/modules/mob/living/silicon/ai/freelook/eye.dm +++ b/code/modules/mob/living/silicon/ai/freelook/eye.dm @@ -31,6 +31,7 @@ ai.camera_visibility(src) if(ai.client && !ai.multicam_on) ai.client.eye = src + update_parallax_contents() //Holopad if(ai.master_multicam) ai.master_multicam.refresh_view() diff --git a/code/modules/mob/living/silicon/ai/life.dm b/code/modules/mob/living/silicon/ai/life.dm index 06043025f7c..51d5820d2bf 100644 --- a/code/modules/mob/living/silicon/ai/life.dm +++ b/code/modules/mob/living/silicon/ai/life.dm @@ -107,6 +107,8 @@ aiRestorePowerRoutine = 0 update_blind_effects() update_sight() + to_chat(src, "Here are your current laws:") + show_laws() return switch(PRP) @@ -126,8 +128,6 @@ theAPC.attack_ai(src) apc_override = 0 aiRestorePowerRoutine = 3 - to_chat(src, "Here are your current laws:") - src.show_laws() //WHY THE FUCK IS THIS HERE sleep(50) theAPC = null diff --git a/code/modules/mob/living/silicon/laws.dm b/code/modules/mob/living/silicon/laws.dm index b49aa82625c..2eca24104cd 100644 --- a/code/modules/mob/living/silicon/laws.dm +++ b/code/modules/mob/living/silicon/laws.dm @@ -70,6 +70,13 @@ if(!silent && !isnull(usr)) log_and_message_admins("cleared the supplied laws of [src]") +/mob/living/silicon/proc/clear_zeroth_law(var/silent = FALSE) + throw_alert("newlaw", /obj/screen/alert/newlaw) + laws_sanity_check() + laws.clear_zeroth_laws() + if(!silent && !isnull(usr)) + log_and_message_admins("cleared the zeroth law of [src]") + /mob/living/silicon/proc/statelaws(var/datum/ai_laws/laws) var/prefix = "" if(MAIN_CHANNEL == lawchannel) diff --git a/code/modules/mob/living/silicon/robot/component.dm b/code/modules/mob/living/silicon/robot/component.dm index d584d5a50f5..0750e4ea3ed 100644 --- a/code/modules/mob/living/silicon/robot/component.dm +++ b/code/modules/mob/living/silicon/robot/component.dm @@ -235,6 +235,12 @@ to_chat(user, "Body Temperature: ???") return + user.visible_message("[user] has analyzed [M]'s components.","You have analyzed [M]'s components.") + robot_healthscan(user, M) + add_fingerprint(user) + + +proc/robot_healthscan(mob/user, mob/living/M) var/scan_type if(istype(M, /mob/living/silicon/robot)) scan_type = "robot" @@ -244,7 +250,7 @@ to_chat(user, "You can't analyze non-robotic things!") return - user.visible_message("[user] has analyzed [M]'s components.","You have analyzed [M]'s components.") + switch(scan_type) if("robot") var/BU = M.getFireLoss() > 50 ? "[M.getFireLoss()]" : M.getFireLoss() @@ -308,5 +314,3 @@ to_chat(user, "Internal Fluid Level:[H.blood_volume]/[H.max_blood]") if(H.bleed_rate) to_chat(user, "Warning:External component leak detected!") - - src.add_fingerprint(user) diff --git a/code/modules/mob/living/silicon/robot/robot.dm b/code/modules/mob/living/silicon/robot/robot.dm index b9ed81f7180..900705733ba 100644 --- a/code/modules/mob/living/silicon/robot/robot.dm +++ b/code/modules/mob/living/silicon/robot/robot.dm @@ -885,6 +885,8 @@ var/list/robot_verbs_default = list( /mob/living/silicon/robot/attack_ghost(mob/user) if(wiresexposed) wires.Interact(user) + else + ..() //this calls the /mob/living/attack_ghost proc for the ghost health/cyborg analyzer /mob/living/silicon/robot/proc/allowed(obj/item/I) var/obj/dummy = new /obj(null) // Create a dummy object to check access on as to avoid having to snowflake check_access on every mob diff --git a/code/modules/mob/living/simple_animal/friendly/corgi.dm b/code/modules/mob/living/simple_animal/friendly/corgi.dm index 90ed82ff395..d8f09f4cb78 100644 --- a/code/modules/mob/living/simple_animal/friendly/corgi.dm +++ b/code/modules/mob/living/simple_animal/friendly/corgi.dm @@ -165,7 +165,7 @@ /obj/item/clothing/suit/armor/vest, /obj/item/clothing/suit/armor/vest/blueshield, /obj/item/clothing/suit/space/deathsquad, - /obj/item/clothing/suit/space/hardsuit/engineering, + /obj/item/clothing/suit/space/hardsuit/engine, /obj/item/radio, /obj/item/radio/off, /obj/item/clothing/suit/cardborg, @@ -356,7 +356,7 @@ desc = "That's not red paint. That's real corgi blood." valid = 1 - if(/obj/item/clothing/head/helmet/space/hardsuit/engineering) + if(/obj/item/clothing/suit/space/hardsuit/engine) name = "Space Explorer [real_name]" desc = "That's one small step for a corgi. One giant yap for corgikind." valid = 1 diff --git a/code/modules/mob/living/simple_animal/friendly/mouse.dm b/code/modules/mob/living/simple_animal/friendly/mouse.dm index cbc125beeab..2c9cbc355f7 100644 --- a/code/modules/mob/living/simple_animal/friendly/mouse.dm +++ b/code/modules/mob/living/simple_animal/friendly/mouse.dm @@ -34,13 +34,29 @@ holder_type = /obj/item/holder/mouse can_collar = 1 gold_core_spawnable = CHEM_MOB_SPAWN_FRIENDLY + var/chew_probability = 1 /mob/living/simple_animal/mouse/Initialize(mapload) . = ..() AddComponent(/datum/component/squeak, list('sound/creatures/mousesqueak.ogg' = 1), 100) +/mob/living/simple_animal/mouse/handle_automated_action() + if(prob(chew_probability)) + var/turf/simulated/floor/F = get_turf(src) + if(istype(F) && !F.intact) + var/obj/structure/cable/C = locate() in F + if(C && prob(15)) + if(C.avail()) + visible_message("[src] chews through [C]. It's toast!") + playsound(src, 'sound/effects/sparks2.ogg', 100, 1) + C.deconstruct() + toast() // mmmm toasty. + else + C.deconstruct() + visible_message("[src] chews through [C].") + /mob/living/simple_animal/mouse/handle_automated_speech() - ..() + ..() if(prob(speak_chance)) for(var/mob/M in view()) M << squeak_sound @@ -98,7 +114,12 @@ to_chat(M, "[bicon(src)] Squeek!") ..() -/mob/living/simple_animal/mouse/death(gibbed) +/mob/living/simple_animal/mouse/proc/toast() + add_atom_colour("#3A3A3A", FIXED_COLOUR_PRIORITY) + desc = "It's toast." + death() + +/mob/living/simple_animal/mouse/death(gibbed) // Only execute the below if we successfully died playsound(src, squeak_sound, 40, 1) . = ..(gibbed) diff --git a/code/modules/mob/living/simple_animal/hostile/headcrab.dm b/code/modules/mob/living/simple_animal/hostile/headcrab.dm index c82a0ee7806..1ef6f06259f 100644 --- a/code/modules/mob/living/simple_animal/hostile/headcrab.dm +++ b/code/modules/mob/living/simple_animal/hostile/headcrab.dm @@ -1,100 +1,106 @@ -#define EGG_INCUBATION_TIME 120 - /mob/living/simple_animal/hostile/headcrab - name = "headslug" - desc = "Absolutely not de-beaked or harmless. Keep away from corpses." + name = "headcrab" + desc = "A small parasitic creature that would like to connect with your brain stem." + icon = 'icons/mob/headcrab.dmi' icon_state = "headcrab" icon_living = "headcrab" icon_dead = "headcrab_dead" - icon = 'icons/mob/mob.dmi' - health = 50 - maxHealth = 50 + health = 40 + maxHealth = 40 melee_damage_lower = 5 - melee_damage_upper = 5 - attacktext = "chomps" - attack_sound = 'sound/weapons/bite.ogg' - faction = list("creature") - robust_searching = 1 - stat_attack = 2 - obj_damage = 0 - environment_smash = 0 - speak_emote = list("squeaks") - ventcrawler = 2 - var/datum/mind/origin - var/egg_lain = 0 + melee_damage_upper = 10 + ranged = 1 + ranged_message = "leaps" + ranged_cooldown_time = 40 + var/jumpdistance = 4 + var/jumpspeed = 1 + attacktext = "bites" + attack_sound = 'sound/creatures/headcrab_attack.ogg' + speak_emote = list("hisses") + var/is_zombie = 0 + stat_attack = 1 //so they continue to attack when they are on the ground. + var/host_species = "" + var/list/human_overlays = list() -/mob/living/simple_animal/hostile/headcrab/examine(mob/user) +/mob/living/simple_animal/hostile/headcrab/Life(seconds, times_fired) + if(!is_zombie && isturf(src.loc) && stat != DEAD) + for(var/mob/living/carbon/human/H in oview(src, 1)) //Only for corpse right next to/on same tile + if(H.stat == DEAD || (!H.check_death_method() && H.health <= HEALTH_THRESHOLD_DEAD)) + Zombify(H) + break ..() - if(stat == DEAD) - to_chat(desc = "It appears to be dead.") -/mob/living/simple_animal/hostile/headcrab/proc/Infect(mob/living/carbon/victim) - var/obj/item/organ/internal/body_egg/changeling_egg/egg = new(victim) - egg.insert(victim) - if(origin) - egg.origin = origin - else if(mind) // Let's make this a feature - egg.origin = mind - for(var/obj/item/organ/internal/I in src) - I.loc = egg - visible_message("[src] plants something in [victim]'s flesh!", \ - "We inject our egg into [victim]'s body!") - egg_lain = 1 +/mob/living/simple_animal/hostile/headcrab/OpenFire(atom/A) + if(check_friendly_fire) + for(var/turf/T in getline(src,A)) // Not 100% reliable but this is faster than simulating actual trajectory + for(var/mob/living/L in T) + if(L == src || L == A) + continue + if(faction_check(L) && !attack_same) + return + visible_message("[src] [ranged_message] at [A]!") + throw_at(A, jumpdistance, jumpspeed, spin = FALSE, diagonals_first = TRUE) + ranged_cooldown = world.time + ranged_cooldown_time -/mob/living/simple_animal/hostile/headcrab/AttackingTarget() - if(egg_lain) - target.attack_animal(src) - return - if(iscarbon(target) && !issmall(target)) - // Changeling egg can survive in aliens! - var/mob/living/carbon/C = target - if(C.stat == DEAD) - if(C.status_flags & XENO_HOST) - to_chat(src, "A foreign presence repels us from this body. Perhaps we should try to infest another?") - return - Infect(target) - to_chat(src, "With our egg laid, our death approaches rapidly...") - spawn(100) - death() - return - target.attack_animal(src) +/mob/living/simple_animal/hostile/headcrab/proc/Zombify(mob/living/carbon/human/H) + if(!H.check_death_method()) + H.death() + var/obj/item/organ/external/head/head_organ = H.get_organ("head") + is_zombie = TRUE + if(H.wear_suit) + var/obj/item/clothing/suit/armor/A = H.wear_suit + if(A.armor && A.armor["melee"]) + maxHealth += A.armor["melee"] //That zombie's got armor, I want armor! + maxHealth += 50 + health = maxHealth + name = "zombie" + desc = "A corpse animated by the alien being on its head." + melee_damage_lower = 10 + melee_damage_upper = 15 + ranged = 0 + icon = H.icon + speak = list('sound/creatures/zombie_idle1.ogg','sound/creatures/zombie_idle2.ogg','sound/creatures/zombie_idle3.ogg') + speak_chance = 50 + speak_emote = list("groans") + attacktext = "bites" + attack_sound = 'sound/creatures/zombie_attack.ogg' + icon_state = "zombie2_s" + if(head_organ) + head_organ.h_style = null + H.update_hair() + host_species = H.dna.species.name + human_overlays = H.overlays + update_icons() + H.forceMove(src) + visible_message("The corpse of [H.name] suddenly rises!") -/obj/item/organ/internal/body_egg/changeling_egg - name = "changeling egg" - desc = "Twitching and disgusting." - origin_tech = "biotech=7" // You need to be really lucky to obtain it. - var/datum/mind/origin - var/time - -/obj/item/organ/internal/body_egg/changeling_egg/egg_process() - // Changeling eggs grow in dead people - time++ - if(time >= EGG_INCUBATION_TIME) - Pop() - remove(owner) +/mob/living/simple_animal/hostile/headcrab/death() + ..() + if(is_zombie) qdel(src) -/obj/item/organ/internal/body_egg/changeling_egg/proc/Pop() - var/mob/living/carbon/human/monkey/M = new(owner) - owner.stomach_contents += M - for(var/obj/item/organ/internal/I in src) - I.insert(M, 1) +/mob/living/simple_animal/hostile/headcrab/handle_automated_speech() // This way they have different screams when attacking, sometimes. Might be seen as sphagetthi code though. + if(speak_chance) + if(rand(0,200) < speak_chance) + if(speak && speak.len) + playsound(get_turf(src), pick(speak), 200, 1) - if(origin && origin.current && (origin.current.stat == DEAD)) - origin.transfer_to(M) - if(!origin.changeling) - M.make_changeling() - if(origin.changeling.can_absorb_dna(M, owner)) - origin.changeling.absorb_dna(owner, M) +/mob/living/simple_animal/hostile/headcrab/Destroy() + if(contents) + for(var/mob/M in contents) + M.loc = get_turf(src) + return ..() - var/datum/action/changeling/humanform/HF = new - HF.Grant(M) - for(var/power in origin.changeling.purchasedpowers) - var/datum/action/changeling/S = power - if(istype(S) && S.needs_button) - S.Grant(M) - M.key = origin.key - owner.gib() -#undef EGG_INCUBATION_TIME +/mob/living/simple_animal/hostile/headcrab/update_icons() + ..() + if(is_zombie) + overlays.Cut() + overlays = human_overlays + var/image/I = image('icons/mob/headcrab.dmi', icon_state = "headcrabpod") + if(host_species == "Vox") + I = image('icons/mob/headcrab.dmi', icon_state = "headcrabpod_vox") + else if(host_species == "Gray") + I = image('icons/mob/headcrab.dmi', icon_state = "headcrabpod_gray") + overlays += I diff --git a/code/modules/mob/living/simple_animal/hostile/headslug.dm b/code/modules/mob/living/simple_animal/hostile/headslug.dm new file mode 100644 index 00000000000..e2fc98c483f --- /dev/null +++ b/code/modules/mob/living/simple_animal/hostile/headslug.dm @@ -0,0 +1,100 @@ +#define EGG_INCUBATION_TIME 120 + +/mob/living/simple_animal/hostile/headslug + name = "headslug" + desc = "Absolutely not de-beaked or harmless. Keep away from corpses." + icon_state = "headslug" + icon_living = "headslug" + icon_dead = "headslug_dead" + icon = 'icons/mob/mob.dmi' + health = 50 + maxHealth = 50 + melee_damage_lower = 5 + melee_damage_upper = 5 + attacktext = "chomps" + attack_sound = 'sound/weapons/bite.ogg' + faction = list("creature") + robust_searching = 1 + stat_attack = 2 + obj_damage = 0 + environment_smash = 0 + speak_emote = list("squeaks") + ventcrawler = 2 + var/datum/mind/origin + var/egg_lain = 0 + +/mob/living/simple_animal/hostile/headslug/examine(mob/user) + ..() + if(stat == DEAD) + to_chat(desc = "It appears to be dead.") + +/mob/living/simple_animal/hostile/headslug/proc/Infect(mob/living/carbon/victim) + var/obj/item/organ/internal/body_egg/changeling_egg/egg = new(victim) + egg.insert(victim) + if(origin) + egg.origin = origin + else if(mind) // Let's make this a feature + egg.origin = mind + for(var/obj/item/organ/internal/I in src) + I.loc = egg + visible_message("[src] plants something in [victim]'s flesh!", \ + "We inject our egg into [victim]'s body!") + egg_lain = 1 + +/mob/living/simple_animal/hostile/headslug/AttackingTarget() + if(egg_lain) + target.attack_animal(src) + return + if(iscarbon(target) && !issmall(target)) + // Changeling egg can survive in aliens! + var/mob/living/carbon/C = target + if(C.stat == DEAD) + if(C.status_flags & XENO_HOST) + to_chat(src, "A foreign presence repels us from this body. Perhaps we should try to infest another?") + return + Infect(target) + to_chat(src, "With our egg laid, our death approaches rapidly...") + spawn(100) + death() + return + target.attack_animal(src) + +/obj/item/organ/internal/body_egg/changeling_egg + name = "changeling egg" + desc = "Twitching and disgusting." + origin_tech = "biotech=7" // You need to be really lucky to obtain it. + var/datum/mind/origin + var/time + +/obj/item/organ/internal/body_egg/changeling_egg/egg_process() + // Changeling eggs grow in dead people + time++ + if(time >= EGG_INCUBATION_TIME) + Pop() + remove(owner) + qdel(src) + +/obj/item/organ/internal/body_egg/changeling_egg/proc/Pop() + var/mob/living/carbon/human/monkey/M = new(owner) + owner.stomach_contents += M + + for(var/obj/item/organ/internal/I in src) + I.insert(M, 1) + + if(origin && origin.current && (origin.current.stat == DEAD)) + origin.transfer_to(M) + if(!origin.changeling) + M.make_changeling() + if(origin.changeling.can_absorb_dna(M, owner)) + origin.changeling.absorb_dna(owner, M) + + var/datum/action/changeling/humanform/HF = new + HF.Grant(M) + for(var/power in origin.changeling.purchasedpowers) + var/datum/action/changeling/S = power + if(istype(S) && S.needs_button) + S.Grant(M) + M.key = origin.key + owner.gib() + +#undef EGG_INCUBATION_TIME diff --git a/code/modules/mob/living/simple_animal/hostile/hostile.dm b/code/modules/mob/living/simple_animal/hostile/hostile.dm index 9c787639ba4..a96c78d09d6 100644 --- a/code/modules/mob/living/simple_animal/hostile/hostile.dm +++ b/code/modules/mob/living/simple_animal/hostile/hostile.dm @@ -309,14 +309,18 @@ else M.Goto(src,M.move_to_delay,M.minimum_distance) -/mob/living/simple_animal/hostile/proc/OpenFire(atom/A) +/mob/living/simple_animal/hostile/proc/CheckFriendlyFire(atom/A) if(check_friendly_fire) for(var/turf/T in getline(src,A)) // Not 100% reliable but this is faster than simulating actual trajectory for(var/mob/living/L in T) if(L == src || L == A) continue - if(faction_check(L) && !attack_same) - return + if(faction_check_mob(L) && !attack_same) + return TRUE + +/mob/living/simple_animal/hostile/proc/OpenFire(atom/A) + if(CheckFriendlyFire(A)) + return visible_message("[src] [ranged_message] at [A]!") if(rapid) diff --git a/code/modules/mob/living/simple_animal/hostile/megafauna/blood_drunk_miner.dm b/code/modules/mob/living/simple_animal/hostile/megafauna/blood_drunk_miner.dm index 7fd32bd71ec..d45e6f6ead8 100644 --- a/code/modules/mob/living/simple_animal/hostile/megafauna/blood_drunk_miner.dm +++ b/code/modules/mob/living/simple_animal/hostile/megafauna/blood_drunk_miner.dm @@ -37,6 +37,7 @@ Difficulty: Medium ranged = 1 ranged_cooldown_time = 16 pixel_x = -16 + crusher_loot = list(/obj/item/melee/energy/cleaving_saw, /obj/item/gun/energy/kinetic_accelerator, /obj/item/crusher_trophy/miner_eye) loot = list(/obj/item/melee/energy/cleaving_saw, /obj/item/gun/energy/kinetic_accelerator) wander = FALSE del_on_death = TRUE @@ -48,7 +49,7 @@ Difficulty: Medium var/guidance = FALSE deathmessage = "falls to the ground, decaying into glowing particles." death_sound = "bodyfall" - + /obj/item/gps/internal/miner icon_state = null gpstag = "Resonant Signal" diff --git a/code/modules/mob/living/simple_animal/hostile/megafauna/bubblegum.dm b/code/modules/mob/living/simple_animal/hostile/megafauna/bubblegum.dm index a53b8092e54..ac5e40025c6 100644 --- a/code/modules/mob/living/simple_animal/hostile/megafauna/bubblegum.dm +++ b/code/modules/mob/living/simple_animal/hostile/megafauna/bubblegum.dm @@ -42,6 +42,7 @@ Difficulty: Hard ranged = 1 pixel_x = -32 del_on_death = 1 + crusher_loot = list(/obj/structure/closet/crate/necropolis/bubblegum/crusher) loot = list(/obj/structure/closet/crate/necropolis/bubblegum) var/charging = 0 medal_type = BOSS_MEDAL_BUBBLEGUM diff --git a/code/modules/mob/living/simple_animal/hostile/megafauna/colossus.dm b/code/modules/mob/living/simple_animal/hostile/megafauna/colossus.dm index 5d66061335c..3ebea47e353 100644 --- a/code/modules/mob/living/simple_animal/hostile/megafauna/colossus.dm +++ b/code/modules/mob/living/simple_animal/hostile/megafauna/colossus.dm @@ -45,7 +45,8 @@ Difficulty: Very Hard del_on_death = 1 medal_type = BOSS_MEDAL_COLOSSUS score_type = COLOSSUS_SCORE - loot = list(/obj/machinery/anomalous_crystal/random, /obj/item/organ/internal/vocal_cords/colossus) + crusher_loot = list(/obj/structure/closet/crate/necropolis/colossus/crusher) + loot = list(/obj/structure/closet/crate/necropolis/colossus) butcher_results = list(/obj/item/stack/ore/diamond = 5, /obj/item/stack/sheet/sinew = 5, /obj/item/stack/sheet/animalhide/ashdrake = 10, /obj/item/stack/sheet/bone = 30) deathmessage = "disintegrates, leaving a glowing core in its wake." death_sound = 'sound/misc/demon_dies.ogg' diff --git a/code/modules/mob/living/simple_animal/hostile/megafauna/drake.dm b/code/modules/mob/living/simple_animal/hostile/megafauna/drake.dm index 68db8cb1274..0789d00832d 100644 --- a/code/modules/mob/living/simple_animal/hostile/megafauna/drake.dm +++ b/code/modules/mob/living/simple_animal/hostile/megafauna/drake.dm @@ -43,6 +43,7 @@ Difficulty: Medium move_to_delay = 10 ranged = 1 pixel_x = -16 + crusher_loot = list(/obj/structure/closet/crate/necropolis/dragon/crusher) loot = list(/obj/structure/closet/crate/necropolis/dragon) butcher_results = list(/obj/item/stack/ore/diamond = 5, /obj/item/stack/sheet/sinew = 5, /obj/item/stack/sheet/animalhide/ashdrake = 10, /obj/item/stack/sheet/bone = 30) var/swooping = 0 @@ -271,6 +272,7 @@ Difficulty: Medium melee_damage_lower = 30 damage_coeff = list(BRUTE = 1, BURN = 1, TOX = 1, CLONE = 1, STAMINA = 0, OXY = 1) loot = list() + crusher_loot = list() /mob/living/simple_animal/hostile/megafauna/dragon/lesser/grant_achievement(medaltype,scoretype) return \ No newline at end of file diff --git a/code/modules/mob/living/simple_animal/hostile/megafauna/hierophant.dm b/code/modules/mob/living/simple_animal/hostile/megafauna/hierophant.dm index 7f974149556..bb4e9297605 100644 --- a/code/modules/mob/living/simple_animal/hostile/megafauna/hierophant.dm +++ b/code/modules/mob/living/simple_animal/hostile/megafauna/hierophant.dm @@ -53,6 +53,7 @@ Difficulty: Hard ranged_cooldown_time = 40 aggro_vision_range = 23 loot = list(/obj/item/hierophant_staff) + crusher_loot = list(/obj/item/hierophant_staff, /obj/item/crusher_trophy/vortex_talisman) wander = FALSE var/burst_range = 3 //range on burst aoe var/beam_range = 5 //range on cross blast beams @@ -556,6 +557,37 @@ Difficulty: Hard playsound(M,'sound/weapons/sear.ogg', 50, 1, -4) M.take_damage(damage, BURN, 0, 0) +/obj/effect/temp_visual/hierophant/wall //smoothing and pooling were not friends, but pooling is dead. + name = "vortex wall" + icon = 'icons/turf/walls/hierophant_wall_temp.dmi' + icon_state = "wall" + light_range = MINIMUM_USEFUL_LIGHT_RANGE + duration = 100 + smooth = SMOOTH_TRUE + +/obj/effect/temp_visual/hierophant/wall/New(loc, new_caster) + ..() + queue_smooth_neighbors(src) + queue_smooth(src) + +/obj/effect/temp_visual/hierophant/wall/Destroy() + queue_smooth_neighbors(src) + return ..() + +/obj/effect/temp_visual/hierophant/wall/CanPass(atom/movable/mover, turf/target) + if(QDELETED(caster)) + return FALSE + if(mover == caster.pulledby) + return TRUE + if(istype(mover, /obj/item/projectile)) + var/obj/item/projectile/P = mover + if(P.firer == caster) + return TRUE + if(mover == caster) + return TRUE + return FALSE + + /obj/effect/hierophant name = "hierophant rune" desc = "A powerful magic mark allowing whomever attunes themself to it to return to it at will." diff --git a/code/modules/mob/living/simple_animal/hostile/megafauna/megafauna.dm b/code/modules/mob/living/simple_animal/hostile/megafauna/megafauna.dm index a32aceb33e3..f57559d549a 100644 --- a/code/modules/mob/living/simple_animal/hostile/megafauna/megafauna.dm +++ b/code/modules/mob/living/simple_animal/hostile/megafauna/megafauna.dm @@ -31,6 +31,7 @@ /obj/structure/barricade, /obj/machinery/field, /obj/machinery/power/emitter) + var/list/crusher_loot var/medal_type var/score_type = BOSS_SCORE var/elimination = 0 @@ -43,6 +44,10 @@ layer = LARGE_MOB_LAYER //Looks weird with them slipping under mineral walls and cameras and shit otherwise mouse_opacity = MOUSE_OPACITY_OPAQUE // Easier to click on in melee, they're giant targets anyway +/mob/living/simple_animal/hostile/megafauna/New() + ..() + apply_status_effect(STATUS_EFFECT_CRUSHERDAMAGETRACKING) + /mob/living/simple_animal/hostile/megafauna/Destroy() QDEL_NULL(internal_gps) . = ..() @@ -53,11 +58,17 @@ /mob/living/simple_animal/hostile/megafauna/death(gibbed) // this happens before the parent call because `del_on_death` may be set if(can_die() && !admin_spawned) - feedback_set_details("megafauna_kills","[initial(name)]") + var/datum/status_effect/crusher_damage/C = has_status_effect(STATUS_EFFECT_CRUSHERDAMAGETRACKING) + if(C && crusher_loot && C.total_damage >= maxHealth * 0.6) + spawn_crusher_loot() if(!elimination) //used so the achievment only occurs for the last legion to die. grant_achievement(medal_type,score_type) + feedback_set_details("megafauna_kills","[initial(name)]") return ..() +/mob/living/simple_animal/hostile/megafauna/proc/spawn_crusher_loot() + loot = crusher_loot + /mob/living/simple_animal/hostile/megafauna/AttackingTarget() ..() if(isliving(target)) diff --git a/code/modules/mob/living/simple_animal/hostile/mining/basilisk.dm b/code/modules/mob/living/simple_animal/hostile/mining/basilisk.dm index 28aacd37a73..ad8dcf44699 100644 --- a/code/modules/mob/living/simple_animal/hostile/mining/basilisk.dm +++ b/code/modules/mob/living/simple_animal/hostile/mining/basilisk.dm @@ -77,6 +77,7 @@ stat_attack = 1 flying = TRUE robust_searching = 1 + crusher_loot = /obj/item/crusher_trophy/watcher_wing loot = list() butcher_results = list(/obj/item/stack/ore/diamond = 2, /obj/item/stack/sheet/sinew = 2, /obj/item/stack/sheet/bone = 1) @@ -102,6 +103,8 @@ light_power = 2.5 light_color = LIGHT_COLOR_ORANGE projectiletype = /obj/item/projectile/temp/basilisk/magmawing + crusher_loot = /obj/item/crusher_trophy/blaster_tubes/magma_wing + crusher_drop_mod = 60 /mob/living/simple_animal/hostile/asteroid/basilisk/watcher/icewing name = "icewing watcher" @@ -114,6 +117,8 @@ health = 170 projectiletype = /obj/item/projectile/temp/basilisk/icewing butcher_results = list(/obj/item/stack/ore/diamond = 5, /obj/item/stack/sheet/bone = 1) //No sinew; the wings are too fragile to be usable + crusher_loot = /obj/item/crusher_trophy/watcher_wing/ice_wing + crusher_drop_mod = 30 /obj/item/projectile/temp/basilisk/magmawing name = "scorching blast" diff --git a/code/modules/mob/living/simple_animal/hostile/mining/goliath.dm b/code/modules/mob/living/simple_animal/hostile/mining/goliath.dm index a1c488b4068..dae7a688cb3 100644 --- a/code/modules/mob/living/simple_animal/hostile/mining/goliath.dm +++ b/code/modules/mob/living/simple_animal/hostile/mining/goliath.dm @@ -83,6 +83,7 @@ icon_dead = "goliath_dead" throw_message = "does nothing to the tough hide of the" pre_attack_icon = "goliath2" + crusher_loot = /obj/item/crusher_trophy/goliath_tentacle butcher_results = list(/obj/item/reagent_containers/food/snacks/goliath = 2, /obj/item/stack/sheet/animalhide/goliath_hide = 1, /obj/item/stack/sheet/bone = 2) loot = list() stat_attack = TRUE diff --git a/code/modules/mob/living/simple_animal/hostile/mining/hivelord.dm b/code/modules/mob/living/simple_animal/hostile/mining/hivelord.dm index d6b5a4e7149..55975188386 100644 --- a/code/modules/mob/living/simple_animal/hostile/mining/hivelord.dm +++ b/code/modules/mob/living/simple_animal/hostile/mining/hivelord.dm @@ -45,6 +45,9 @@ /mob/living/simple_animal/hostile/asteroid/hivelord/AttackingTarget() OpenFire() +/mob/living/simple_animal/hostile/asteroid/hivelord/spawn_crusher_loot() + loot += crusher_loot //we don't butcher + /mob/living/simple_animal/hostile/asteroid/hivelord/death(gibbed) // Only execute the below if we successfully died . = ..(gibbed) @@ -52,80 +55,6 @@ return FALSE mouse_opacity = MOUSE_OPACITY_ICON -/obj/item/organ/internal/hivelord_core - name = "hivelord remains" - desc = "All that remains of a hivelord, it seems to be what allows it to break pieces of itself off without being hurt... its healing properties will soon become inert if not used quickly." - icon_state = "roro core 2" - flags = NOBLUDGEON - slot = "hivecore" - force = 0 - actions_types = list(/datum/action/item_action/organ_action/use) - var/inert = 0 - var/preserved = 0 - -/obj/item/organ/internal/hivelord_core/New() - ..() - addtimer(CALLBACK(src, .proc/inert_check), 2400) - -/obj/item/organ/internal/hivelord_core/proc/inert_check() - if(owner) - preserved(implanted = 1) - else if(preserved) - preserved() - else - go_inert() - -/obj/item/organ/internal/hivelord_core/proc/preserved(implanted = 0) - inert = FALSE - preserved = TRUE - update_icon() - - if(implanted) - feedback_add_details("hivelord_core", "[type]|implanted") - else - feedback_add_details("hivelord_core", "[type]|stabilizer") - - -/obj/item/organ/internal/hivelord_core/proc/go_inert() - inert = TRUE - desc = "The remains of a hivelord that have become useless, having been left alone too long after being harvested." - feedback_add_details("hivelord_core", "[src.type]|inert") - update_icon() - -/obj/item/organ/internal/hivelord_core/ui_action_click() - owner.revive() - qdel(src) - -/obj/item/organ/internal/hivelord_core/on_life() - ..() - if(owner.health < HEALTH_THRESHOLD_CRIT) - ui_action_click() - -/obj/item/organ/internal/hivelord_core/afterattack(atom/target, mob/user, proximity_flag) - if(proximity_flag && ishuman(target)) - var/mob/living/carbon/human/H = target - if(inert) - to_chat(user, "[src] has become inert, its healing properties are no more.") - return - else - if(H.stat == DEAD) - to_chat(user, "[src] are useless on the dead.") - return - if(H != user) - H.visible_message("[user] forces [H] to apply [src]... They quickly regenerate all injuries!") - feedback_add_details("hivelord_core","[src.type]|used|other") - else - to_chat(user, "You start to smear [src] on yourself. It feels and smells disgusting, but you feel amazingly refreshed in mere moments.") - feedback_add_details("hivelord_core","[src.type]|used|self") - playsound(src.loc,'sound/items/eatfood.ogg', rand(10,50), 1) - H.revive() - user.drop_item() - qdel(src) - ..() - -/obj/item/organ/internal/hivelord_core/prepare_eat() - return null - /mob/living/simple_animal/hostile/asteroid/hivelordbrood name = "hivelord brood" desc = "A fragment of the original Hivelord, rallying behind its original. One isn't much of a threat, but..." @@ -231,6 +160,7 @@ speak_emote = list("echoes") attack_sound = 'sound/weapons/pierce.ogg' throw_message = "bounces harmlessly off of" + crusher_loot = /obj/item/crusher_trophy/legion_skull loot = list(/obj/item/organ/internal/hivelord_core/legion) brood_type = /mob/living/simple_animal/hostile/asteroid/hivelordbrood/legion del_on_death = 1 @@ -322,34 +252,6 @@ H.forceMove(L) qdel(src) -/obj/item/organ/internal/hivelord_core/legion - name = "legion's soul" - desc = "A strange rock that still crackles with power... its \ - healing properties will soon become inert if not used quickly." - icon_state = "legion_soul" - -/obj/item/organ/internal/hivelord_core/legion/New() - ..() - update_icon() - -/obj/item/organ/internal/hivelord_core/legion/update_icon() - icon_state = inert ? "legion_soul_inert" : "legion_soul" - overlays.Cut() - if(!inert && !preserved) - overlays += image(icon, "legion_soul_crackle") - for(var/X in actions) - var/datum/action/A = X - A.UpdateButtonIcon() - -/obj/item/organ/internal/hivelord_core/legion/go_inert() - . = ..() - desc = "[src] has become inert, it crackles no more and is useless for \ - healing injuries." - -/obj/item/organ/internal/hivelord_core/legion/preserved(implanted = 0) - ..() - desc = "[src] has been stabilized. It no longer crackles with power, but it's healing properties are preserved indefinitely." - /obj/item/legion_skull name = "legion's head" desc = "The once living, now empty eyes of the former human's skull cut deep into your soul." @@ -403,7 +305,7 @@ if(prob(95)) head = /obj/item/clothing/head/helmet/gladiator else - head = /obj/item/clothing/head/skullhelmet + head = /obj/item/clothing/head/helmet/skull suit = /obj/item/clothing/suit/armor/bone if(prob(5)) back = pickweight(list(/obj/item/twohanded/spear/bonespear = 3, /obj/item/twohanded/fireaxe/boneaxe = 2)) diff --git a/code/modules/mob/living/simple_animal/hostile/mining/mining.dm b/code/modules/mob/living/simple_animal/hostile/mining/mining.dm index e23624a5a9d..434869c1d6d 100644 --- a/code/modules/mob/living/simple_animal/hostile/mining/mining.dm +++ b/code/modules/mob/living/simple_animal/hostile/mining/mining.dm @@ -1,4 +1,4 @@ -/mob/living/simple_animal/hostile/asteroid/ +/mob/living/simple_animal/hostile/asteroid vision_range = 2 atmos_requirements = list("min_oxy" = 0, "max_oxy" = 0, "min_tox" = 0, "max_tox" = 0, "min_co2" = 0, "max_co2" = 0, "min_n2" = 0, "max_n2" = 0) unsuitable_atmos_damage = 15 @@ -13,12 +13,18 @@ response_harm = "strikes" status_flags = 0 a_intent = INTENT_HARM + var/crusher_loot var/throw_message = "bounces off of" var/icon_aggro = null // for swapping to when we get aggressive var/fromtendril = FALSE see_in_dark = 8 see_invisible = SEE_INVISIBLE_MINIMUM mob_size = MOB_SIZE_LARGE + var/crusher_drop_mod = 25 + +/mob/living/simple_animal/hostile/asteroid/New() + ..() + apply_status_effect(STATUS_EFFECT_CRUSHERDAMAGETRACKING) /mob/living/simple_animal/hostile/asteroid/Aggro() ..() @@ -46,3 +52,12 @@ visible_message("The [T.name] [src.throw_message] [src.name]!") return ..() + +/mob/living/simple_animal/hostile/asteroid/death(gibbed) + var/datum/status_effect/crusher_damage/C = has_status_effect(STATUS_EFFECT_CRUSHERDAMAGETRACKING) + if(C && crusher_loot && prob((C.total_damage/maxHealth) * crusher_drop_mod)) //on average, you'll need to kill 4 creatures before getting the item + spawn_crusher_loot() + ..(gibbed) + +/mob/living/simple_animal/hostile/asteroid/proc/spawn_crusher_loot() + butcher_results[crusher_loot] = 1 \ No newline at end of file diff --git a/code/modules/mob/living/simple_animal/hostile/mining/necropolis_tendril.dm b/code/modules/mob/living/simple_animal/hostile/mining/necropolis_tendril.dm index c6bc205627e..e910bac7ca3 100644 --- a/code/modules/mob/living/simple_animal/hostile/mining/necropolis_tendril.dm +++ b/code/modules/mob/living/simple_animal/hostile/mining/necropolis_tendril.dm @@ -17,6 +17,8 @@ atmos_requirements = list("min_oxy" = 0, "max_oxy" = 0, "min_tox" = 0, "max_tox" = 0, "min_co2" = 0, "max_co2" = 5, "min_n2" = 0, "max_n2" = 0) minbodytemp = 0 maxbodytemp = INFINITY + move_resist = INFINITY + anchored = TRUE loot = list(/obj/effect/collapse, /obj/structure/closet/crate/necropolis/tendril) del_on_death = 1 var/gps = null @@ -76,4 +78,4 @@ mob_types = list(/mob/living/simple_animal/hostile/asteroid/goliath/beast/tendril) /mob/living/simple_animal/hostile/spawner/lavaland/legion - mob_types = list(/mob/living/simple_animal/hostile/asteroid/hivelord/legion/tendril) \ No newline at end of file + mob_types = list(/mob/living/simple_animal/hostile/asteroid/hivelord/legion/tendril) diff --git a/code/modules/mob/living/simple_animal/hostile/skeleton.dm b/code/modules/mob/living/simple_animal/hostile/skeleton.dm new file mode 100644 index 00000000000..011c47b2c24 --- /dev/null +++ b/code/modules/mob/living/simple_animal/hostile/skeleton.dm @@ -0,0 +1,49 @@ +/mob/living/simple_animal/hostile/skeleton + name = "reanimated skeleton" + desc = "A real bonefied skeleton, doesn't seem like it wants to socialize." + icon = 'icons/mob/animal.dmi' + icon_state = "skeleton" + icon_living = "skeleton" + turns_per_move = 5 + speak_emote = list("rattles") + emote_see = list("rattles") + a_intent = INTENT_HARM + maxHealth = 40 + health = 40 + speed = 1 + harm_intent_damage = 5 + melee_damage_lower = 15 + melee_damage_upper = 15 + minbodytemp = 0 + maxbodytemp = 1500 + healable = FALSE //they're skeletons how would bruise packs help them?? + attacktext = "slashes" + attack_sound = 'sound/hallucinations/growl1.ogg' + atmos_requirements = list("min_oxy" = 0, "max_oxy" = 0, "min_tox" = 0, "max_tox" = 0, "min_co2" = 0, "max_co2" = 0, "min_n2" = 0, "max_n2" = 0) + unsuitable_atmos_damage = 10 + robust_searching = 1 + stat_attack = UNCONSCIOUS + gold_core_spawnable = CHEM_MOB_SPAWN_HOSTILE + faction = list("skeleton") + see_in_dark = 8 + lighting_alpha = LIGHTING_PLANE_ALPHA_MOSTLY_INVISIBLE + deathmessage = "collapses into a pile of bones!" + del_on_death = TRUE + loot = list(/obj/effect/decal/remains/human) + +/mob/living/simple_animal/hostile/skeleton/eskimo + name = "undead eskimo" + desc = "The reanimated remains of some poor traveler." + icon_state = "eskimo" + icon_living = "eskimo" + maxHealth = 55 + health = 55 + weather_immunities = list("snow") + gold_core_spawnable = CHEM_MOB_SPAWN_INVALID + melee_damage_lower = 17 + melee_damage_upper = 20 + deathmessage = "collapses into a pile of bones, its gear falling to the floor!" + loot = list(/obj/effect/decal/remains/human, + /obj/item/twohanded/spear, + /obj/item/clothing/shoes/winterboots, + /obj/item/clothing/suit/hooded/wintercoat) \ No newline at end of file diff --git a/code/modules/mob/living/status_procs.dm b/code/modules/mob/living/status_procs.dm index 1dded6c4e8c..0794b7d9c70 100644 --- a/code/modules/mob/living/status_procs.dm +++ b/code/modules/mob/living/status_procs.dm @@ -397,6 +397,9 @@ // STUN /mob/living/Stun(amount, updating = 1, force = 0) + if(status_flags & CANSTUN || force) + if(absorb_stun(amount, force)) + return FALSE return SetStunned(max(stunned, amount), updating, force) /mob/living/SetStunned(amount, updating = 1, force = 0) //if you REALLY need to set stun to a set amount without the whole "can't go below current stunned" @@ -434,6 +437,9 @@ // WEAKEN /mob/living/Weaken(amount, updating = 1, force = 0) + if(status_flags & CANWEAKEN || force) + if(absorb_stun(amount, force)) + return FALSE return SetWeakened(max(weakened, amount), updating, force) /mob/living/SetWeakened(amount, updating = 1, force = 0) diff --git a/code/modules/mob/mob.dm b/code/modules/mob/mob.dm index 02cb948c5c9..3c2f9fc732b 100644 --- a/code/modules/mob/mob.dm +++ b/code/modules/mob/mob.dm @@ -193,14 +193,7 @@ var/obj/item/W = get_active_hand() if(istype(W)) - if(istype(W, /obj/item/clothing)) - var/obj/item/clothing/C = W - if(C.hardsuit_restrict_helmet) - to_chat(src, "You must fasten the helmet to a hardsuit first. (Target the head and use on a hardsuit)")// Stop eva helms equipping. - else - equip_to_slot_if_possible(C, slot) - else - equip_to_slot_if_possible(W, slot) + equip_to_slot_if_possible(W, slot) else if(!restrained()) W = get_item_by_slot(slot) if(W) @@ -693,7 +686,7 @@ var/list/slot_equipment_priority = list( \ msg = copytext(msg, 1, MAX_MESSAGE_LEN) msg = sanitize_simple(html_encode(msg), list("\n" = "
      ")) - + var/combined = length(memory + msg) if(mind && (combined < MAX_PAPER_MESSAGE_LEN)) mind.store_memory(msg) diff --git a/code/modules/mob/mob_grab.dm b/code/modules/mob/mob_grab.dm index 077164be6b7..805d48fdd9f 100644 --- a/code/modules/mob/mob_grab.dm +++ b/code/modules/mob/mob_grab.dm @@ -409,12 +409,6 @@ qdel(src) /obj/item/grab/proc/checkvalid(var/mob/attacker, var/mob/prey) //does all the checking for the attack proc to see if a mob can eat another with the grab - if(ishuman(attacker) && (/datum/dna/gene/basic/grant_spell/mattereater in attacker.active_genes)) // MATTER EATER CARES NOT OF YOUR FORM - return 1 - - if(ishuman(attacker) && (FAT in attacker.mutations) && iscarbon(prey) && !isalien(prey)) //Fat people eating carbon mobs but not xenos - return 1 - if(isalien(attacker) && iscarbon(prey)) //Xenomorphs eating carbon mobs return 1 diff --git a/code/modules/nano/interaction/base.dm b/code/modules/nano/interaction/base.dm index e4e5dd1a33b..e7f06137781 100644 --- a/code/modules/nano/interaction/base.dm +++ b/code/modules/nano/interaction/base.dm @@ -24,6 +24,8 @@ return STATUS_UPDATE // Ghosts can view updates /mob/living/silicon/ai/shared_nano_interaction() + if(apc_override) + return STATUS_INTERACTIVE if(lacks_power()) return STATUS_CLOSE if(check_unable(1, 0)) diff --git a/code/modules/ninja/suit/gloves.dm b/code/modules/ninja/suit/gloves.dm index b4c0a5305b7..7f1059f062e 100644 --- a/code/modules/ninja/suit/gloves.dm +++ b/code/modules/ninja/suit/gloves.dm @@ -11,4 +11,4 @@ min_cold_protection_temperature = GLOVES_MIN_TEMP_PROTECT heat_protection = HANDS max_heat_protection_temperature = GLOVES_MAX_TEMP_PROTECT - transfer_prints = FALSE \ No newline at end of file + transfer_prints = FALSE diff --git a/code/modules/ninja/suit/head.dm b/code/modules/ninja/suit/head.dm index 6ed302feaad..a7a21f072f3 100644 --- a/code/modules/ninja/suit/head.dm +++ b/code/modules/ninja/suit/head.dm @@ -7,4 +7,4 @@ item_state = "s-ninja_hood" armor = list(melee = 60, bullet = 60, laser = 45, energy = 15, bomb = 30, bio = 30, rad = 25) unacidable = 1 - blockTracking = 1 \ No newline at end of file + blockTracking = 1 diff --git a/code/modules/ninja/suit/mask.dm b/code/modules/ninja/suit/mask.dm index 0ebec2e724f..2f76673ab13 100644 --- a/code/modules/ninja/suit/mask.dm +++ b/code/modules/ninja/suit/mask.dm @@ -28,4 +28,4 @@ Contents: /obj/item/clothing/mask/gas/space_ninja/Destroy() QDEL_NULL(voice_changer) - return ..() \ No newline at end of file + return ..() diff --git a/code/modules/ninja/suit/shoes.dm b/code/modules/ninja/suit/shoes.dm index 5cb67e73db6..af5f4d3ecc1 100644 --- a/code/modules/ninja/suit/shoes.dm +++ b/code/modules/ninja/suit/shoes.dm @@ -9,4 +9,4 @@ cold_protection = FEET min_cold_protection_temperature = SHOES_MIN_TEMP_PROTECT heat_protection = FEET - max_heat_protection_temperature = SHOES_MAX_TEMP_PROTECT \ No newline at end of file + max_heat_protection_temperature = SHOES_MAX_TEMP_PROTECT diff --git a/code/modules/ninja/suit/suit.dm b/code/modules/ninja/suit/suit.dm index 6e550e64893..365cc35cfc6 100644 --- a/code/modules/ninja/suit/suit.dm +++ b/code/modules/ninja/suit/suit.dm @@ -86,4 +86,4 @@ Contents: suitShoes = null suitOccupant = null - return 1 \ No newline at end of file + return 1 diff --git a/code/modules/paperwork/faxmachine.dm b/code/modules/paperwork/faxmachine.dm index 13d85941a79..176d2abc85c 100644 --- a/code/modules/paperwork/faxmachine.dm +++ b/code/modules/paperwork/faxmachine.dm @@ -2,6 +2,7 @@ var/list/obj/machinery/photocopier/faxmachine/allfaxes = list() var/list/admin_departments = list("Central Command") var/list/hidden_admin_departments = list("Syndicate") var/list/alldepartments = list() +var/list/hidden_departments = list() var/global/list/fax_blacklist = list() /obj/machinery/photocopier/faxmachine @@ -9,7 +10,9 @@ var/global/list/fax_blacklist = list() icon = 'icons/obj/library.dmi' icon_state = "fax" insert_anim = "faxsend" + pass_flags = PASSTABLE var/fax_network = "Local Fax Network" + var/syndie_restricted = FALSE //is it a syndicate base fax restricted from contacting NT assets? var/long_range_enabled = 0 // Can we send messages off the station? req_one_access = list(access_lawyer, access_heads, access_armory) @@ -35,7 +38,7 @@ var/global/list/fax_blacklist = list() /obj/machinery/photocopier/faxmachine/proc/update_network() if(department != "Unknown") - if(!(("[department]" in alldepartments) || ("[department]" in admin_departments) || ("[department]" in hidden_admin_departments))) + if(!(("[department]" in alldepartments) || ("[department]" in hidden_departments) || ("[department]" in admin_departments) || ("[department]" in hidden_admin_departments))) alldepartments |= department /obj/machinery/photocopier/faxmachine/longrange @@ -43,6 +46,17 @@ var/global/list/fax_blacklist = list() fax_network = "Central Command Quantum Entanglement Network" long_range_enabled = 1 +/obj/machinery/photocopier/faxmachine/longrange/syndie + name = "syndicate long range fax machine" + emagged = TRUE + syndie_restricted = TRUE + req_one_access = list(access_syndicate) + //No point setting fax network, being emagged overrides that anyway. + +/obj/machinery/photocopier/faxmachine/longrange/syndie/update_network() + if(department != "Unknown") + hidden_departments |= department + /obj/machinery/photocopier/faxmachine/attack_hand(mob/user) ui_interact(user) @@ -119,7 +133,7 @@ var/global/list/fax_blacklist = list() if((destination in admin_departments) || (destination in hidden_admin_departments)) send_admin_fax(usr, destination) else - sendfax(destination,usr) + sendfax(destination, usr) if(sendcooldown) spawn(sendcooldown) // cooldown time @@ -155,6 +169,14 @@ var/global/list/fax_blacklist = list() if(emagged) combineddepartments += hidden_admin_departments.Copy() + combineddepartments += hidden_departments.Copy() + + if(syndie_restricted) + combineddepartments = hidden_admin_departments.Copy() + combineddepartments += hidden_departments.Copy() + for(var/obj/machinery/photocopier/faxmachine/F in allfaxes) + if(F.emagged)//we can contact emagged faxes on the station + combineddepartments |= F.department destination = input(usr, "To which department?", "Choose a department", "") as null|anything in combineddepartments if(!destination) diff --git a/code/modules/power/smes.dm b/code/modules/power/smes.dm index 7ebc4f4471a..a6a83d07f10 100644 --- a/code/modules/power/smes.dm +++ b/code/modules/power/smes.dm @@ -158,9 +158,44 @@ to_chat(user, "You need more wires.") return - //build the terminal and link it to the network - make_terminal(user) - terminal.connect_to_network() + if(user.loc == loc) + to_chat(user, "You must not be on the same tile as the [src].") + return + + //Direction the terminal will face to + var/tempDir = get_dir(user, src) + switch(tempDir) + if(NORTHEAST, SOUTHEAST) + tempDir = EAST + if(NORTHWEST, SOUTHWEST) + tempDir = WEST + var/turf/tempLoc = get_step(src, reverse_direction(tempDir)) + if(istype(tempLoc, /turf/space)) + to_chat(user, "You can't build a terminal on space.") + return + else if(istype(tempLoc)) + if(tempLoc.intact) + to_chat(user, "You must remove the floor plating first.") + return + + to_chat(user, "You start adding cable to the [src].") + playsound(loc, C.usesound, 50, 1) + + if(do_after(user, 50, target = src)) + if(!terminal && panel_open) + T = get_turf(user) + var/obj/structure/cable/N = T.get_cable_node() //get the connecting node cable, if there's one + if(prob(50) && electrocute_mob(usr, N, N, 1, TRUE)) //animate the electrocution if uncautious and unlucky + do_sparks(5, 1, src) + return + + C.use(10) // make sure the cable gets used up + user.visible_message(\ + "[user.name] adds the cables and connects the power terminal.",\ + "You add the cables and connect the power terminal.") + + make_terminal(user, tempDir, tempLoc) + terminal.connect_to_network() return //disassembling the terminal @@ -174,18 +209,19 @@ playsound(src.loc, I.usesound, 50, 1) if(do_after(user, 50 * I.toolspeed, target = src)) - if(prob(50) && electrocute_mob(usr, terminal.powernet, terminal, 1, TRUE)) //animate the electrocution if uncautious and unlucky - do_sparks(5, 1, src) - return + if(terminal && panel_open) + if(prob(50) && electrocute_mob(usr, terminal.powernet, terminal, 1, TRUE)) //animate the electrocution if uncautious and unlucky + do_sparks(5, 1, src) + return - //give the wires back and delete the terminal - new /obj/item/stack/cable_coil(T,10) - user.visible_message(\ - "[user.name] cuts the cables and dismantles the power terminal.",\ - "You cut the cables and dismantle the power terminal.") - inputting = 0 //stop inputting, since we have don't have a terminal anymore - qdel(terminal) - return + //give the wires back and delete the terminal + new /obj/item/stack/cable_coil(T,10) + user.visible_message(\ + "[user.name] cuts the cables and dismantles the power terminal.",\ + "You cut the cables and dismantle the power terminal.") + inputting = 0 //stop inputting, since we have don't have a terminal anymore + qdel(terminal) + return //crowbarring it ! default_deconstruction_crowbar(I) @@ -197,6 +233,13 @@ return 1 return 0 +/obj/machinery/power/smes/proc/make_terminal(user, tempDir, tempLoc) + // create a terminal object at the same position as original turf loc + // wires will attach to this + terminal = new /obj/machinery/power/terminal(tempLoc) + terminal.dir = tempDir + terminal.master = src + /obj/machinery/power/smes/Destroy() if(SSticker && SSticker.current_state == GAME_STATE_PLAYING) var/area/area = get_area(src) @@ -299,45 +342,6 @@ update_icon() return -//Will return 1 on failure -/obj/machinery/power/smes/proc/make_terminal(const/mob/user) - if(user.loc == loc) - to_chat(user, "You must not be on the same tile as the [src].") - return 1 - - //Direction the terminal will face to - var/tempDir = get_dir(user, src) - switch(tempDir) - if(NORTHEAST, SOUTHEAST) - tempDir = EAST - if(NORTHWEST, SOUTHWEST) - tempDir = WEST - var/turf/tempLoc = get_step(src, reverse_direction(tempDir)) - if(istype(tempLoc, /turf/space)) - to_chat(user, "You can't build a terminal on space.") - return 1 - else if(istype(tempLoc)) - if(tempLoc.intact) - to_chat(user, "You must remove the floor plating first.") - return 1 - to_chat(user, "You start adding cable to the [src].") - if(do_after(user, 50, target = src)) - var/turf/T = get_turf(user) - var/obj/structure/cable/N = T.get_cable_node() //get the connecting node cable, if there's one - if(prob(50) && electrocute_mob(usr, N, N, 1, TRUE)) //animate the electrocution if uncautious and unlucky - do_sparks(5, 1, src) - return - - user.visible_message(\ - "[user.name] adds the cables and connects the power terminal.",\ - "You add the cables and connect the power terminal.") - - terminal = new /obj/machinery/power/terminal(tempLoc) - terminal.dir = tempDir - terminal.master = src - return 0 - return 1 - /obj/machinery/power/smes/attack_ai(mob/user) add_hiddenprint(user) ui_interact(user) diff --git a/code/modules/projectiles/firing.dm b/code/modules/projectiles/firing.dm index 9d16a9c2123..c2333da9107 100644 --- a/code/modules/projectiles/firing.dm +++ b/code/modules/projectiles/firing.dm @@ -40,14 +40,16 @@ if(!istype(targloc) || !istype(curloc) || !BB) return 0 BB.ammo_casing = src - + if(target && get_dist(user, target) <= 1) //Point blank shot must always hit + BB.prehit(target) target.bullet_act(BB, BB.def_zone) QDEL_NULL(BB) return 1 if(targloc == curloc) if(target) //if the target is right on our location we go straight to bullet_act() + BB.prehit(target) target.bullet_act(BB, BB.def_zone) QDEL_NULL(BB) return 1 diff --git a/code/modules/projectiles/gun.dm b/code/modules/projectiles/gun.dm index d5dfb454e09..fbc29da0391 100644 --- a/code/modules/projectiles/gun.dm +++ b/code/modules/projectiles/gun.dm @@ -50,6 +50,12 @@ var/obj/item/flashlight/gun_light = null var/can_flashlight = 0 + var/can_bayonet = FALSE //if a bayonet can be added or removed if it already has one. + var/obj/item/kitchen/knife/bayonet + var/mutable_appearance/knife_overlay + var/knife_x_offset = 0 + var/knife_y_offset = 0 + var/list/upgrades = list() var/ammo_x_offset = 0 //used for positioning ammo count overlay on sprite @@ -69,12 +75,27 @@ verbs += /obj/item/gun/proc/toggle_gunlight build_zooming() +/obj/item/gun/Destroy() + QDEL_NULL(bayonet) + return ..() + +/obj/item/gun/handle_atom_del(atom/A) + if(A == bayonet) + clear_bayonet() + return ..() + /obj/item/gun/examine(mob/user) ..() if(unique_reskin && !current_skin) to_chat(user, "Alt-click it to reskin it.") if(unique_rename) to_chat(user, "Use a pen on it to rename it.") + if(bayonet) + to_chat(user, "It has \a [bayonet] [can_bayonet ? "" : "permanently "]affixed to it.") + if(can_bayonet) //if it has a bayonet and this is false, the bayonet is permanent. + to_chat(user, "[bayonet] looks like it can be unscrewed from [src].") + else if(can_bayonet) + to_chat(user, "It has a bayonet lug on it.") /obj/item/gun/proc/process_chamber() return 0 @@ -103,12 +124,6 @@ else user.visible_message("[user] fires [src]!", "You fire [src]!", "You hear \a [fire_sound_text]!") - if(weapon_weight >= WEAPON_MEDIUM) - if(user.get_inactive_hand()) - if(prob(15)) - if(user.drop_item()) - user.visible_message("[src] flies out of [user]'s hands!", "[src] kicks out of your grip!") - /obj/item/gun/emp_act(severity) for(var/obj/O in contents) O.emp_act(severity) @@ -153,7 +168,20 @@ to_chat(user, "You need both hands free to fire \the [src]!") return - process_fire(target,user,1,params) + //DUAL WIELDING + var/bonus_spread = 0 + var/loop_counter = 0 + if(ishuman(user) && user.a_intent == INTENT_HARM) + var/mob/living/carbon/human/H = user + for(var/obj/item/gun/G in get_both_hands(H)) + if(G == src || G.weapon_weight >= WEAPON_MEDIUM) + continue + else if(G.can_trigger_gun(user)) + bonus_spread += 24 * G.weapon_weight + loop_counter++ + addtimer(CALLBACK(G, .proc/process_fire, target, user, 1, params, null, bonus_spread), loop_counter) + + process_fire(target,user,1,params, null, bonus_spread) /obj/item/gun/proc/can_trigger_gun(mob/living/user) if(!user.can_use_guns(src)) @@ -163,20 +191,20 @@ return 0 return 1 -obj/item/gun/proc/newshot() +/obj/item/gun/proc/newshot() return -/obj/item/gun/proc/process_fire(atom/target as mob|obj|turf, mob/living/user as mob|obj, message = 1, params, zone_override) +/obj/item/gun/proc/process_fire(atom/target as mob|obj|turf, mob/living/user as mob|obj, message = 1, params, zone_override, bonus_spread = 0) add_fingerprint(user) if(semicd) return - if(weapon_weight) - if(user.get_inactive_hand()) - recoil = 4 //one-handed kick - else - recoil = initial(recoil) + var/sprd = 0 + var/randomized_gun_spread = 0 + if(spread) + randomized_gun_spread = rand(0,spread) + var/randomized_bonus_spread = rand(0, bonus_spread) if(burst_size > 1) firing_burst = 1 @@ -187,11 +215,10 @@ obj/item/gun/proc/newshot() if( i>1 && !(src in get_both_hands(user))) //for burst firing break if(chambered) - var/sprd = 0 if(randomspread) - sprd = round((rand() - 0.5) * spread) + sprd = round((rand() - 0.5) * (randomized_gun_spread + randomized_bonus_spread)) else - sprd = round((i / burst_size - 0.5) * spread) + sprd = round((i / burst_size - 0.5) * (randomized_gun_spread + randomized_bonus_spread)) if(!chambered.fire(target, user, params, ,suppressed, zone_override, sprd)) shoot_with_empty_chamber(user) break @@ -209,7 +236,8 @@ obj/item/gun/proc/newshot() firing_burst = 0 else if(chambered) - if(!chambered.fire(target, user, params, , suppressed, zone_override, spread)) + sprd = round((pick(1,-1)) * (randomized_gun_spread + randomized_bonus_spread)) + if(!chambered.fire(target, user, params, , suppressed, zone_override, sprd)) shoot_with_empty_chamber(user) return else @@ -233,11 +261,19 @@ obj/item/gun/proc/newshot() user.update_inv_r_hand() feedback_add_details("gun_fired","[type]") -/obj/item/gun/attack(mob/M as mob, mob/user) +/obj/item/gun/attack(mob/M, mob/user) if(user.a_intent == INTENT_HARM) //Flogging - ..() - else - return + if(bayonet) + M.attackby(bayonet, user) + else + return ..() + +/obj/item/gun/attack_obj(obj/O, mob/user) + if(user.a_intent == INTENT_HARM) + if(bayonet) + O.attackby(bayonet, user) + return + return ..() /obj/item/gun/attackby(obj/item/I, mob/user, params) if(istype(I, /obj/item/flashlight/seclite)) @@ -257,7 +293,7 @@ obj/item/gun/proc/newshot() if(loc == user) A.Grant(user) - if(istype(I, /obj/item/screwdriver)) + if(isscrewdriver(I)) if(gun_light && can_flashlight) for(var/obj/item/flashlight/seclite/S in src) to_chat(user, "You unscrew the seclite from [src].") @@ -268,11 +304,32 @@ obj/item/gun/proc/newshot() update_icon() for(var/datum/action/item_action/toggle_gunlight/TGL in actions) qdel(TGL) + else if(bayonet && can_bayonet) //if it has a bayonet, and the bayonet can be removed + bayonet.forceMove(get_turf(user)) + clear_bayonet() if(unique_rename) if(istype(I, /obj/item/pen)) rename_gun(user) - ..() + if(istype(I, /obj/item/kitchen/knife)) + var/obj/item/kitchen/knife/K = I + if(!can_bayonet || !K.bayonet || bayonet) //ensure the gun has an attachment point available, and that the knife is compatible with it. + return ..() + if(!user.drop_item()) + return + K.forceMove(src) + to_chat(user, "You attach [K] to [src]'s bayonet lug.") + bayonet = K + var/state = "bayonet" //Generic state. + if(bayonet.icon_state in icon_states('icons/obj/guns/bayonets.dmi')) //Snowflake state? + state = bayonet.icon_state + var/icon/bayonet_icons = 'icons/obj/guns/bayonets.dmi' + knife_overlay = mutable_appearance(bayonet_icons, state) + knife_overlay.pixel_x = knife_x_offset + knife_overlay.pixel_y = knife_y_offset + overlays += knife_overlay + else + return ..() /obj/item/gun/proc/toggle_gunlight() set name = "Toggle Gun Light" @@ -305,6 +362,15 @@ obj/item/gun/proc/newshot() var/datum/action/A = X A.UpdateButtonIcon() +/obj/item/gun/proc/clear_bayonet() + if(!bayonet) + return + bayonet = null + if(knife_overlay) + overlays -= knife_overlay + knife_overlay = null + return TRUE + /obj/item/gun/extinguish_light() if(gun_light.on) toggle_gunlight() diff --git a/code/modules/projectiles/guns/alien.dm b/code/modules/projectiles/guns/alien.dm index 2a20e7e6c81..d9f149b3b17 100644 --- a/code/modules/projectiles/guns/alien.dm +++ b/code/modules/projectiles/guns/alien.dm @@ -80,6 +80,7 @@ ammo_type = list(/obj/item/ammo_casing/energy/sonic) cell_type = /obj/item/stock_parts/cell/super restricted_species = list(/datum/species/vox/armalis) + sprite_sheets_inhand = list("Vox Armalis" = 'icons/mob/species/armalis/held.dmi') //Big guns big birds. /obj/item/gun/energy/noisecannon/update_icon() return diff --git a/code/modules/projectiles/guns/dartgun.dm b/code/modules/projectiles/guns/dartgun.dm index 7b39bfa3be8..97f4eaebf1c 100644 --- a/code/modules/projectiles/guns/dartgun.dm +++ b/code/modules/projectiles/guns/dartgun.dm @@ -101,6 +101,8 @@ beakers += B to_chat(user, "You slot [B] into [src].") src.updateUsrDialog() + else + return ..() /obj/item/gun/dartgun/can_shoot() if(!cartridge) diff --git a/code/modules/projectiles/guns/energy.dm b/code/modules/projectiles/guns/energy.dm index cbc230c1e98..3fbfcdaa934 100644 --- a/code/modules/projectiles/guns/energy.dm +++ b/code/modules/projectiles/guns/energy.dm @@ -21,6 +21,12 @@ /obj/item/gun/energy/emp_act(severity) power_supply.use(round(power_supply.charge / severity)) + if(chambered)//phil235 + if(chambered.BB) + qdel(chambered.BB) + chambered.BB = null + chambered = null + newshot() //phil235 update_icon() /obj/item/gun/energy/get_cell() @@ -34,6 +40,7 @@ power_supply = new(src) power_supply.give(power_supply.maxcharge) update_ammo_types() + on_recharge() if(selfcharge) START_PROCESSING(SSobj, src) update_icon() @@ -67,8 +74,12 @@ if(!external || !external.use(E.e_cost)) //Take power from the borg... return //Note, uses /10 because of shitty mods to the cell system power_supply.give(100) //... to recharge the shot + on_recharge() update_icon() +/obj/item/gun/energy/proc/on_recharge() + newshot() + /obj/item/gun/energy/attack_self(mob/living/user as mob) if(ammo_type.len > 1) select_fire(user) @@ -78,10 +89,6 @@ H.update_inv_l_hand() H.update_inv_r_hand() -/obj/item/gun/energy/afterattack(atom/target as mob|obj|turf, mob/living/user as mob|obj, params) - newshot() //prepare a new shot - ..() - /obj/item/gun/energy/can_shoot() var/obj/item/ammo_casing/energy/shot = ammo_type[select] return power_supply.charge >= shot.e_cost @@ -89,18 +96,20 @@ /obj/item/gun/energy/newshot() if(!ammo_type || !power_supply) return - var/obj/item/ammo_casing/energy/shot = ammo_type[select] - if(power_supply.charge >= shot.e_cost) //if there's enough power in the power_supply cell... - chambered = shot //...prepare a new shot based on the current ammo type selected - chambered.newshot() - return + if(!chambered) + var/obj/item/ammo_casing/energy/shot = ammo_type[select] + if(power_supply.charge >= shot.e_cost) //if there's enough power in the power_supply cell... + chambered = shot //...prepare a new shot based on the current ammo type selected + if(!chambered.BB) + chambered.newshot() /obj/item/gun/energy/process_chamber() if(chambered && !chambered.BB) //if BB is null, i.e the shot has been fired... var/obj/item/ammo_casing/energy/shot = chambered power_supply.use(shot.e_cost)//... drain the power_supply cell + robocharge() chambered = null //either way, released the prepared shot - return + newshot() /obj/item/gun/energy/proc/select_fire(mob/living/user) select++ @@ -111,6 +120,12 @@ fire_delay = shot.delay if(shot.select_name) to_chat(user, "[src] is now set to [shot.select_name].") + if(chambered)//phil235 + if(chambered.BB) + qdel(chambered.BB) + chambered.BB = null + chambered = null + newshot() update_icon() return @@ -140,6 +155,8 @@ if(gun_light.on) iconF = "flight_on" overlays += image(icon = icon, icon_state = iconF, pixel_x = flight_x_offset, pixel_y = flight_y_offset) + if(bayonet && can_bayonet) + overlays += knife_overlay if(itemState) itemState += "[ratio]" item_state = itemState diff --git a/code/modules/projectiles/guns/energy/kinetic_accelerator.dm b/code/modules/projectiles/guns/energy/kinetic_accelerator.dm index fa483903012..b93ddefd0d5 100644 --- a/code/modules/projectiles/guns/energy/kinetic_accelerator.dm +++ b/code/modules/projectiles/guns/energy/kinetic_accelerator.dm @@ -16,10 +16,15 @@ var/holds_charge = FALSE var/unique_frequency = FALSE // modified by KA modkits var/overheat = FALSE + can_bayonet = TRUE + knife_x_offset = 20 + knife_y_offset = 12 var/max_mod_capacity = 100 var/list/modkits = list() + var/recharge_timerid + var/empty_state = "kineticgun_empty" /obj/item/gun/energy/kinetic_accelerator/examine(mob/user) @@ -30,20 +35,20 @@ var/obj/item/borg/upgrade/modkit/M = A to_chat(user, "There is a [M.name] mod installed, using [M.cost]% capacity.") -/obj/item/gun/energy/kinetic_accelerator/attackby(obj/item/A, mob/user) - if(istype(A, /obj/item/crowbar)) +/obj/item/gun/energy/kinetic_accelerator/attackby(obj/item/I, mob/user) + if(iscrowbar(I)) if(modkits.len) to_chat(user, "You pry the modifications out.") - playsound(loc, A.usesound, 100, 1) + playsound(loc, I.usesound, 100, 1) for(var/obj/item/borg/upgrade/modkit/M in modkits) M.uninstall(src) else to_chat(user, "There are no modifications currently installed.") - else if(istype(A, /obj/item/borg/upgrade/modkit)) - var/obj/item/borg/upgrade/modkit/MK = A + else if(istype(I, /obj/item/borg/upgrade/modkit)) + var/obj/item/borg/upgrade/modkit/MK = I MK.install(src, user) else - ..() + return ..() /obj/item/gun/energy/kinetic_accelerator/proc/get_remaining_mod_capacity() var/current_capacity_used = 0 @@ -58,6 +63,7 @@ . += A /obj/item/gun/energy/kinetic_accelerator/proc/modify_projectile(obj/item/projectile/kinetic/K) + K.kinetic_gun = src //do something special on-hit, easy! for(var/A in get_modkits()) var/obj/item/borg/upgrade/modkit/M = A M.modify_projectile(K) @@ -67,6 +73,12 @@ unique_frequency = TRUE max_mod_capacity = 80 +/obj/item/gun/energy/kinetic_accelerator/minebot + trigger_guard = TRIGGER_GUARD_ALLOW_ALL + overheat_time = 20 + holds_charge = TRUE + unique_frequency = TRUE + /obj/item/gun/energy/kinetic_accelerator/New() . = ..() if(!holds_charge) @@ -83,7 +95,7 @@ /obj/item/gun/energy/kinetic_accelerator/dropped() . = ..() - if(!holds_charge) + if(!QDELING(src) && !holds_charge) // Put it on a delay because moving item from slot to hand // calls dropped(). spawn(2) @@ -97,30 +109,32 @@ power_supply.use(500) update_icon() -/obj/item/gun/energy/kinetic_accelerator/proc/attempt_reload() +/obj/item/gun/energy/kinetic_accelerator/proc/attempt_reload(recharge_time) if(overheat) return + if(!recharge_time) + recharge_time = overheat_time overheat = TRUE var/carried = 0 if(!unique_frequency) - for(var/obj/item/gun/energy/kinetic_accelerator/K in \ - loc.GetAllContents()) - - carried++ + for(var/obj/item/gun/energy/kinetic_accelerator/K in loc.GetAllContents()) + if(!K.unique_frequency) + carried++ carried = max(carried, 1) else carried = 1 - spawn(overheat_time * carried) - reload() + deltimer(recharge_timerid) + recharge_timerid = addtimer(CALLBACK(src, .proc/reload), recharge_time * carried, TIMER_STOPPABLE) /obj/item/gun/energy/kinetic_accelerator/emp_act(severity) return /obj/item/gun/energy/kinetic_accelerator/proc/reload() power_supply.give(500) + on_recharge() if(!suppressed) playsound(loc, 'sound/weapons/kenetic_reload.ogg', 60, 1) else if(isliving(loc)) @@ -138,6 +152,8 @@ if(gun_light.on) iconF = "flight_on" overlays += image(icon = icon, icon_state = iconF, pixel_x = flight_x_offset, pixel_y = flight_y_offset) + if(bayonet && can_bayonet) + overlays += knife_overlay /obj/item/gun/energy/kinetic_accelerator/experimental @@ -161,16 +177,6 @@ var/obj/item/gun/energy/kinetic_accelerator/KA = loc KA.modify_projectile(BB) - var/turf/proj_turf = get_turf(BB) - if(!isturf(proj_turf)) - return - var/datum/gas_mixture/environment = proj_turf.return_air() - var/pressure = environment.return_pressure() - if(pressure > 50) - BB.name = "weakened [BB.name]" - var/obj/item/projectile/kinetic/K = BB - K.damage *= K.pressure_decrease - //Projectiles /obj/item/projectile/kinetic @@ -181,10 +187,9 @@ flag = "bomb" range = 3 + var/pressure_decrease_active = FALSE var/pressure_decrease = 0.25 - var/turf_aoe = FALSE - var/mob_aoe = FALSE - var/list/hit_overlays = list() + var/obj/item/gun/energy/kinetic_accelerator/kinetic_gun /obj/item/projectile/kinetic/pod range = 4 @@ -193,9 +198,22 @@ damage = 50 pressure_decrease = 0.5 -/obj/item/projectile/kinetic/pod/enhanced - turf_aoe = TRUE - mob_aoe = TRUE +/obj/item/projectile/kinetic/Destroy() + kinetic_gun = null + return ..() + +/obj/item/projectile/kinetic/prehit(atom/target) + . = ..() + if(.) + if(kinetic_gun) + var/list/mods = kinetic_gun.get_modkits() + for(var/obj/item/borg/upgrade/modkit/M in mods) + M.projectile_prehit(src, target, kinetic_gun) + if(!lavaland_equipment_pressure_check(get_turf(target))) + name = "weakened [name]" + damage = damage * pressure_decrease + pressure_decrease_active = TRUE + /obj/item/projectile/kinetic/on_range() strike_thing() @@ -209,30 +227,22 @@ var/turf/target_turf = get_turf(target) if(!target_turf) target_turf = get_turf(src) + if(kinetic_gun) //hopefully whoever shot this was not very, very unfortunate. + var/list/mods = kinetic_gun.get_modkits() + for(var/obj/item/borg/upgrade/modkit/M in mods) + M.projectile_strike_predamage(src, target_turf, target, kinetic_gun) + for(var/obj/item/borg/upgrade/modkit/M in mods) + M.projectile_strike(src, target_turf, target, kinetic_gun) if(ismineralturf(target_turf)) var/turf/simulated/mineral/M = target_turf M.gets_drilled(firer) var/obj/effect/temp_visual/kinetic_blast/K = new /obj/effect/temp_visual/kinetic_blast(target_turf) K.color = color - for(var/type in hit_overlays) - new type(target_turf) - if(turf_aoe) - for(var/T in RANGE_TURFS(1, target_turf) - target_turf) - if(ismineralturf(T)) - var/turf/simulated/mineral/M = T - M.gets_drilled(firer) - if(mob_aoe) - for(var/mob/living/L in range(1, target_turf) - firer - target) - var/armor = L.run_armor_check(def_zone, flag, "", "", armour_penetration) - L.apply_damage(damage*mob_aoe, damage_type, def_zone, armor) - L.visible_message("[L] is hit by \a [src]!", - "You are hit by \a [src]!") - add_attack_logs(firer, L, "Shot with a [type]") //Modkits /obj/item/borg/upgrade/modkit - name = "modification kit" + name = "kinetic accelerator modification kit" desc = "An upgrade for kinetic accelerators." icon = 'icons/obj/objects.dmi' icon_state = "modkit" @@ -244,6 +254,8 @@ var/maximum_of_type = 1 var/cost = 30 var/modifier = 1 //For use in any mod kit that has numerical modifiers + var/minebot_upgrade = TRUE + var/minebot_exclusive = FALSE /obj/item/borg/upgrade/modkit/examine(mob/user) if(..(user, 1)) @@ -253,7 +265,7 @@ if(istype(A, /obj/item/gun/energy/kinetic_accelerator) && !issilicon(user)) install(A, user) else - ..() + return ..() /obj/item/borg/upgrade/modkit/action(mob/living/silicon/robot/R) if(..()) @@ -264,6 +276,13 @@ /obj/item/borg/upgrade/modkit/proc/install(obj/item/gun/energy/kinetic_accelerator/KA, mob/user) . = TRUE + if(minebot_upgrade) + if(minebot_exclusive && !istype(KA.loc, /mob/living/simple_animal/hostile/mining_drone)) + to_chat(user, "The modkit you're trying to install is only rated for minebot use.") + return FALSE + else if(istype(KA.loc, /mob/living/simple_animal/hostile/mining_drone)) + to_chat(user, "The modkit you're trying to install is not rated for minebot use.") + return FALSE if(denied_type) var/number_of_denied = 0 for(var/A in KA.get_modkits()) @@ -292,6 +311,12 @@ /obj/item/borg/upgrade/modkit/proc/modify_projectile(obj/item/projectile/kinetic/K) +//use this one for effects you want to trigger before any damage is done at all and before damage is decreased by pressure +/obj/item/borg/upgrade/modkit/proc/projectile_prehit(obj/item/projectile/kinetic/K, atom/target, obj/item/gun/energy/kinetic_accelerator/KA) +//use this one for effects you want to trigger before mods that do damage +/obj/item/borg/upgrade/modkit/proc/projectile_strike_predamage(obj/item/projectile/kinetic/K, turf/target_turf, atom/target, obj/item/gun/energy/kinetic_accelerator/KA) +//and this one for things that don't need to trigger before other damage-dealing mods +/obj/item/borg/upgrade/modkit/proc/projectile_strike(obj/item/projectile/kinetic/K, turf/target_turf, atom/target, obj/item/gun/energy/kinetic_accelerator/KA) //Range /obj/item/borg/upgrade/modkit/range @@ -317,8 +342,9 @@ //Cooldown /obj/item/borg/upgrade/modkit/cooldown name = "cooldown decrease" - desc = "Decreases the cooldown of a kinetic accelerator." - modifier = 2.5 + desc = "Decreases the cooldown of a kinetic accelerator. Not rated for minebot use." + modifier = 3.2 + minebot_upgrade = FALSE /obj/item/borg/upgrade/modkit/cooldown/install(obj/item/gun/energy/kinetic_accelerator/KA, mob/user) . = ..() @@ -329,25 +355,61 @@ KA.overheat_time += modifier ..() +/obj/item/borg/upgrade/modkit/cooldown/minebot + name = "minebot cooldown decrease" + desc = "Decreases the cooldown of a kinetic accelerator. Only rated for minebot use." + icon_state = "door_electronics" + icon = 'icons/obj/module.dmi' + denied_type = /obj/item/borg/upgrade/modkit/cooldown/minebot + modifier = 10 + cost = 0 + minebot_upgrade = TRUE + minebot_exclusive = TRUE //AoE blasts /obj/item/borg/upgrade/modkit/aoe modifier = 0 + var/turf_aoe = FALSE + var/stats_stolen = FALSE -/obj/item/borg/upgrade/modkit/aoe/modify_projectile(obj/item/projectile/kinetic/K) - K.name = "kinetic explosion" - if(!K.turf_aoe && !K.mob_aoe) - K.hit_overlays += /obj/effect/temp_visual/explosion/fast - K.mob_aoe += modifier +/obj/item/borg/upgrade/modkit/aoe/install(obj/item/gun/energy/kinetic_accelerator/KA, mob/user) + if(..()) + return + for(var/obj/item/borg/upgrade/modkit/aoe/AOE in KA.modkits) //make sure only one of the aoe modules has values if somebody has multiple + if(AOE.stats_stolen || AOE == src) + continue + modifier += AOE.modifier //take its modifiers + AOE.modifier = 0 + turf_aoe += AOE.turf_aoe + AOE.turf_aoe = FALSE + AOE.stats_stolen = TRUE + +/obj/item/borg/upgrade/modkit/aoe/uninstall(obj/item/gun/energy/kinetic_accelerator/KA) + ..() + modifier = initial(modifier) //get our modifiers back + turf_aoe = initial(turf_aoe) + stats_stolen = FALSE + +/obj/item/borg/upgrade/modkit/aoe/projectile_strike(obj/item/projectile/kinetic/K, turf/target_turf, atom/target, obj/item/gun/energy/kinetic_accelerator/KA) + if(stats_stolen) + return + new /obj/effect/temp_visual/explosion/fast(target_turf) + if(turf_aoe) + for(var/T in RANGE_TURFS(1, target_turf) - target_turf) + if(ismineralturf(T)) + var/turf/simulated/mineral/M = T + M.gets_drilled(K.firer) + if(modifier) + for(var/mob/living/L in range(1, target_turf) - K.firer - target) + var/armor = L.run_armor_check(K.def_zone, K.flag, "", "", K.armour_penetration) + L.apply_damage(K.damage * modifier, K.damage_type, K.def_zone, armor) + to_chat(L, "You're struck by a [K.name]!") /obj/item/borg/upgrade/modkit/aoe/turfs name = "mining explosion" desc = "Causes the kinetic accelerator to destroy rock in an AoE." denied_type = /obj/item/borg/upgrade/modkit/aoe/turfs - -/obj/item/borg/upgrade/modkit/aoe/turfs/modify_projectile(obj/item/projectile/kinetic/K) - ..() - K.turf_aoe = TRUE + turf_aoe = TRUE /obj/item/borg/upgrade/modkit/aoe/turfs/andmobs name = "offensive mining explosion" @@ -360,15 +422,111 @@ desc = "Causes the kinetic accelerator to damage mobs in an AoE." modifier = 0.2 +//Minebot passthrough +/obj/item/borg/upgrade/modkit/minebot_passthrough + name = "minebot passthrough" + desc = "Causes kinetic accelerator shots to pass through minebots." + cost = 0 + +//Tendril-unique modules +/obj/item/borg/upgrade/modkit/cooldown/repeater + name = "rapid repeater" + desc = "Quarters the kinetic accelerator's cooldown on striking a living target, but greatly increases the base cooldown." + denied_type = /obj/item/borg/upgrade/modkit/cooldown/repeater + modifier = -14 //Makes the cooldown 3 seconds(with no cooldown mods) if you miss. Don't miss. + cost = 50 + +/obj/item/borg/upgrade/modkit/cooldown/repeater/projectile_strike_predamage(obj/item/projectile/kinetic/K, turf/target_turf, atom/target, obj/item/gun/energy/kinetic_accelerator/KA) + var/valid_repeat = FALSE + if(isliving(target)) + var/mob/living/L = target + if(L.stat != DEAD) + valid_repeat = TRUE + if(ismineralturf(target_turf)) + valid_repeat = TRUE + if(valid_repeat) + KA.overheat = FALSE + KA.attempt_reload(KA.overheat_time * 0.25) //If you hit, the cooldown drops to 0.75 seconds. + +/obj/item/borg/upgrade/modkit/lifesteal + name = "lifesteal crystal" + desc = "Causes kinetic accelerator shots to slightly heal the firer on striking a living target." + icon_state = "modkit_crystal" + modifier = 2.5 //Not a very effective method of healing. + cost = 20 + var/static/list/damage_heal_order = list(BRUTE, BURN, OXY) + +/obj/item/borg/upgrade/modkit/lifesteal/projectile_prehit(obj/item/projectile/kinetic/K, atom/target, obj/item/gun/energy/kinetic_accelerator/KA) + if(isliving(target) && isliving(K.firer)) + var/mob/living/L = target + if(L.stat == DEAD) + return + L = K.firer + L.heal_ordered_damage(modifier, damage_heal_order) + +/obj/item/borg/upgrade/modkit/resonator_blasts + name = "resonator blast" + desc = "Causes kinetic accelerator shots to leave and detonate resonator blasts." + denied_type = /obj/item/borg/upgrade/modkit/resonator_blasts + cost = 30 + modifier = 0.25 //A bonus 15 damage if you burst the field on a target, 60 if you lure them into it. + +/obj/item/borg/upgrade/modkit/resonator_blasts/projectile_strike(obj/item/projectile/kinetic/K, turf/target_turf, atom/target, obj/item/gun/energy/kinetic_accelerator/KA) + if(target_turf && !ismineralturf(target_turf)) //Don't make fields on mineral turfs. + var/obj/effect/temp_visual/resonance/R = locate(/obj/effect/temp_visual/resonance) in target_turf + if(R) + R.damage_multiplier = modifier + R.burst() + return + new /obj/effect/temp_visual/resonance(target_turf, K.firer, null, 30) + +/obj/item/borg/upgrade/modkit/bounty + name = "death syphon" + desc = "Killing or assisting in killing a creature permanently increases your damage against that type of creature." + denied_type = /obj/item/borg/upgrade/modkit/bounty + modifier = 1.25 + cost = 30 + var/maximum_bounty = 25 + var/list/bounties_reaped = list() + +/obj/item/borg/upgrade/modkit/bounty/projectile_prehit(obj/item/projectile/kinetic/K, atom/target, obj/item/gun/energy/kinetic_accelerator/KA) + if(isliving(target)) + var/mob/living/L = target + var/list/existing_marks = L.has_status_effect_list(STATUS_EFFECT_SYPHONMARK) + for(var/i in existing_marks) + var/datum/status_effect/syphon_mark/SM = i + if(SM.reward_target == src) //we want to allow multiple people with bounty modkits to use them, but we need to replace our own marks so we don't multi-reward + SM.reward_target = null + qdel(SM) + L.apply_status_effect(STATUS_EFFECT_SYPHONMARK, src) + +/obj/item/borg/upgrade/modkit/bounty/projectile_strike(obj/item/projectile/kinetic/K, turf/target_turf, atom/target, obj/item/gun/energy/kinetic_accelerator/KA) + if(isliving(target)) + var/mob/living/L = target + if(bounties_reaped[L.type]) + var/kill_modifier = 1 + if(K.pressure_decrease_active) + kill_modifier *= K.pressure_decrease + var/armor = L.run_armor_check(K.def_zone, K.flag, "", "", K.armour_penetration) + L.apply_damage(bounties_reaped[L.type]*kill_modifier, K.damage_type, K.def_zone, armor) + +/obj/item/borg/upgrade/modkit/bounty/proc/get_kill(mob/living/L) + var/bonus_mod = 1 + if(ismegafauna(L)) //megafauna reward + bonus_mod = 4 + if(!bounties_reaped[L.type]) + bounties_reaped[L.type] = min(modifier * bonus_mod, maximum_bounty) + else + bounties_reaped[L.type] = min(bounties_reaped[L.type] + (modifier * bonus_mod), maximum_bounty) //Indoors /obj/item/borg/upgrade/modkit/indoors name = "decrease pressure penalty" - desc = "Increases the damage a kinetic accelerator does in a high pressure environment." + desc = "A syndicate modification kit that increases the damage a kinetic accelerator does in high pressure environments." modifier = 2 denied_type = /obj/item/borg/upgrade/modkit/indoors maximum_of_type = 2 - cost = 40 + cost = 35 /obj/item/borg/upgrade/modkit/indoors/modify_projectile(obj/item/projectile/kinetic/K) K.pressure_decrease *= modifier @@ -431,7 +589,7 @@ /obj/item/borg/upgrade/modkit/tracer/adjustable name = "adjustable tracer bolts" - desc = "Causes kinetic accelerator bolts to have a adjustably-colored tracer trail and explosion. Use in-hand to change color." + desc = "Causes kinetic accelerator bolts to have an adjustable-colored tracer trail and explosion. Use in-hand to change color." /obj/item/borg/upgrade/modkit/tracer/adjustable/attack_self(mob/user) - bolt_color = input(user,"Choose Color") as color + bolt_color = input(user,"","Choose Color",bolt_color) as color|null \ No newline at end of file diff --git a/code/modules/projectiles/guns/energy/nuclear.dm b/code/modules/projectiles/guns/energy/nuclear.dm index 6cc27a08f09..949ee16fa06 100644 --- a/code/modules/projectiles/guns/energy/nuclear.dm +++ b/code/modules/projectiles/guns/energy/nuclear.dm @@ -79,7 +79,7 @@ slot_flags = null w_class = WEIGHT_CLASS_HUGE ammo_type = list(/obj/item/ammo_casing/energy/electrode, /obj/item/ammo_casing/energy/laser) - weapon_weight = WEAPON_MEDIUM + weapon_weight = WEAPON_HEAVY can_flashlight = 0 trigger_guard = TRIGGER_GUARD_NONE ammo_x_offset = 2 diff --git a/code/modules/projectiles/guns/energy/special.dm b/code/modules/projectiles/guns/energy/special.dm index fa34753c6a9..4499fca3797 100644 --- a/code/modules/projectiles/guns/energy/special.dm +++ b/code/modules/projectiles/guns/energy/special.dm @@ -168,14 +168,16 @@ var/obj/item/stack/sheet/S = A S.use(1) power_supply.give(1000) + on_recharge() to_chat(user, "You insert [A] in [src], recharging it.") else if(istype(A, /obj/item/stack/ore/plasma)) var/obj/item/stack/ore/S = A S.use(1) power_supply.give(500) + on_recharge() to_chat(user, "You insert [A] in [src], recharging it.") else - ..() + return ..() /obj/item/gun/energy/plasmacutter/update_icon() return @@ -251,10 +253,6 @@ /obj/item/gun/energy/printer/emp_act() return -/obj/item/gun/energy/printer/newshot() - ..() - robocharge() - // Instakill Lasers // /obj/item/gun/energy/laser/instakill name = "instakill rifle" diff --git a/code/modules/projectiles/guns/grenade_launcher.dm b/code/modules/projectiles/guns/grenade_launcher.dm index 0f05cfa32f6..81b8451eb77 100644 --- a/code/modules/projectiles/guns/grenade_launcher.dm +++ b/code/modules/projectiles/guns/grenade_launcher.dm @@ -28,6 +28,8 @@ to_chat(user, "[grenades.len] / [max_grenades] grenades.") else to_chat(user, "The grenade launcher cannot hold more grenades.") + else + return ..() /obj/item/gun/grenadelauncher/afterattack(obj/target, mob/user , flag) if(target == user) diff --git a/code/modules/projectiles/guns/projectile.dm b/code/modules/projectiles/guns/projectile.dm index 9defe7637d4..15efee700d2 100644 --- a/code/modules/projectiles/guns/projectile.dm +++ b/code/modules/projectiles/guns/projectile.dm @@ -24,6 +24,8 @@ icon_state = "[current_skin][suppressed ? "-suppressed" : ""][sawn_state ? "-sawn" : ""]" else icon_state = "[initial(icon_state)][suppressed ? "-suppressed" : ""][sawn_state ? "-sawn" : ""]" + if(bayonet && can_bayonet) + overlays += knife_overlay /obj/item/gun/projectile/process_chamber(eject_casing = 1, empty_chamber = 1) var/obj/item/ammo_casing/AC = chambered //Find chambered round @@ -66,7 +68,6 @@ return /obj/item/gun/projectile/attackby(var/obj/item/A as obj, mob/user as mob, params) - ..() if(istype(A, /obj/item/ammo_box/magazine)) var/obj/item/ammo_box/magazine/AM = A if(istype(AM, mag_type)) @@ -108,7 +109,8 @@ else to_chat(user, "You can't seem to figure out how to fit [S] on [src].") return - return 0 + else + return ..() /obj/item/gun/projectile/attack_hand(mob/user) if(loc == user) @@ -178,6 +180,9 @@ if(sawn_state == SAWN_OFF) to_chat(user, "\The [src] is already shortened!") return + if(bayonet) + to_chat(user, "You cannot saw-off [src] with [bayonet] attached!") + return user.changeNext_move(CLICK_CD_MELEE) user.visible_message("[user] begins to shorten \the [src].", "You begin to shorten \the [src]...") diff --git a/code/modules/projectiles/guns/projectile/automatic.dm b/code/modules/projectiles/guns/projectile/automatic.dm index 399925d0e8a..6601f75d52b 100644 --- a/code/modules/projectiles/guns/projectile/automatic.dm +++ b/code/modules/projectiles/guns/projectile/automatic.dm @@ -19,6 +19,8 @@ if(select == 1) overlays += "[initial(icon_state)]burst" icon_state = "[initial(icon_state)][magazine ? "-[magazine.max_ammo]" : ""][chambered ? "" : "-e"][suppressed ? "-suppressed" : ""]" + if(bayonet && can_bayonet) + overlays += knife_overlay /obj/item/gun/projectile/automatic/attackby(var/obj/item/A as obj, mob/user as mob, params) . = ..() @@ -96,6 +98,9 @@ fire_sound = 'sound/weapons/gunshots/gunshot_smg.ogg' fire_delay = 2 burst_size = 2 + can_bayonet = TRUE + knife_x_offset = 26 + knife_y_offset = 12 /obj/item/gun/projectile/automatic/c20r/New() ..() @@ -123,6 +128,9 @@ can_suppress = 0 burst_size = 1 actions_types = list() + can_bayonet = TRUE + knife_x_offset = 25 + knife_y_offset = 12 /obj/item/gun/projectile/automatic/wt550/update_icon() ..() @@ -172,7 +180,7 @@ underbarrel.attack_self() underbarrel.attackby(A, user, params) else - ..() + return ..() /obj/item/gun/projectile/automatic/m90/update_icon() ..() diff --git a/code/modules/projectiles/guns/projectile/revolver.dm b/code/modules/projectiles/guns/projectile/revolver.dm index 3cba868a379..6f977f2e024 100644 --- a/code/modules/projectiles/guns/projectile/revolver.dm +++ b/code/modules/projectiles/guns/projectile/revolver.dm @@ -115,7 +115,6 @@ ..() /obj/item/gun/projectile/revolver/detective/attackby(obj/item/A, mob/user, params) - ..() if(istype(A, /obj/item/screwdriver)) if(magazine.caliber == "38") to_chat(user, "You begin to reinforce the barrel of [src]...") @@ -143,6 +142,8 @@ magazine.caliber = "38" desc = initial(desc) to_chat(user, "You remove the modifications on [src]. Now it will fire .38 rounds.") + else + return ..() /obj/item/gun/projectile/revolver/fingergun //Summoned by the Finger Gun spell, from advanced mimery traitor item name = "\improper finger gun" @@ -347,7 +348,6 @@ options["Cancel"] = null /obj/item/gun/projectile/revolver/doublebarrel/attackby(obj/item/A, mob/user, params) - ..() if(istype(A, /obj/item/ammo_box) || istype(A, /obj/item/ammo_casing)) chamber_round() if(istype(A, /obj/item/melee/energy)) @@ -356,6 +356,8 @@ sawoff(user) if(istype(A, /obj/item/circular_saw) || istype(A, /obj/item/gun/energy/plasmacutter)) sawoff(user) + else + return ..() /obj/item/gun/projectile/revolver/doublebarrel/attack_self(mob/living/user) var/num_unloaded = 0 @@ -394,7 +396,6 @@ var/slung = 0 /obj/item/gun/projectile/revolver/doublebarrel/improvised/attackby(obj/item/A, mob/user, params) - ..() if(istype(A, /obj/item/stack/cable_coil) && !sawn_state) var/obj/item/stack/cable_coil/C = A if(C.use(10)) @@ -406,6 +407,8 @@ else to_chat(user, "You need at least ten lengths of cable if you want to make a sling.") return + else + return ..() /obj/item/gun/projectile/revolver/doublebarrel/improvised/update_icon() ..() @@ -450,9 +453,10 @@ return /obj/item/gun/projectile/revolver/doublebarrel/improvised/cane/attackby(obj/item/A, mob/user, params) - ..() if(istype(A, /obj/item/stack/cable_coil)) return + else + return ..() /obj/item/gun/projectile/revolver/doublebarrel/improvised/cane/examine(mob/user) // HAD TO REPEAT EXAMINE CODE BECAUSE GUN CODE DOESNT STEALTH var/f_name = "\a [src]." diff --git a/code/modules/projectiles/guns/projectile/saw.dm b/code/modules/projectiles/guns/projectile/saw.dm index 59bb2595714..5b70f2b3282 100644 --- a/code/modules/projectiles/guns/projectile/saw.dm +++ b/code/modules/projectiles/guns/projectile/saw.dm @@ -7,7 +7,7 @@ slot_flags = 0 origin_tech = "combat=6;engineering=3;syndicate=6" mag_type = /obj/item/ammo_box/magazine/mm556x45 - weapon_weight = WEAPON_MEDIUM + weapon_weight = WEAPON_HEAVY fire_sound = 'sound/weapons/gunshots/gunshot_mg.ogg' magin_sound = 'sound/weapons/gun_interactions/lmg_magin.ogg' magout_sound = 'sound/weapons/gun_interactions/lmg_magout.ogg' @@ -50,14 +50,14 @@ to_chat(user, "You remove the magazine from [src].") -/obj/item/gun/projectile/automatic/l6_saw/attackby(obj/item/A, mob/user, params) +/obj/item/gun/projectile/automatic/l6_saw/attackby(obj/item/A, mob/user, params) if(istype(A, /obj/item/ammo_box/magazine)) var/obj/item/ammo_box/magazine/AM = A if(istype(AM, mag_type)) if(!cover_open) to_chat(user, "[src]'s cover is closed! You can't insert a new mag.") return - ..() + return ..() //ammo// diff --git a/code/modules/projectiles/guns/projectile/shotgun.dm b/code/modules/projectiles/guns/projectile/shotgun.dm index 366b9b6579f..8b658911b3b 100644 --- a/code/modules/projectiles/guns/projectile/shotgun.dm +++ b/code/modules/projectiles/guns/projectile/shotgun.dm @@ -11,6 +11,7 @@ mag_type = /obj/item/ammo_box/magazine/internal/shot fire_sound = 'sound/weapons/gunshots/gunshot_shotgun.ogg' var/recentpump = 0 // to prevent spammage + weapon_weight = WEAPON_MEDIUM /obj/item/gun/projectile/shotgun/attackby(obj/item/A, mob/user, params) . = ..() @@ -86,7 +87,6 @@ sawn_state = SAWN_INTACT /obj/item/gun/projectile/shotgun/riot/attackby(obj/item/A, mob/user, params) - ..() if(istype(A, /obj/item/circular_saw) || istype(A, /obj/item/gun/energy/plasmacutter)) sawoff(user) if(istype(A, /obj/item/melee/energy)) @@ -95,6 +95,8 @@ sawoff(user) if(istype(A, /obj/item/pipe)) unsaw(A, user) + else + return ..() /obj/item/gun/projectile/shotgun/riot/sawoff(mob/user) if(sawn_state == SAWN_OFF) @@ -210,6 +212,9 @@ mag_type = /obj/item/ammo_box/magazine/internal/boltaction fire_sound = 'sound/weapons/gunshots/gunshot_rifle.ogg' var/bolt_open = 0 + can_bayonet = TRUE + knife_x_offset = 27 + knife_y_offset = 13 /obj/item/gun/projectile/shotgun/boltaction/pump(mob/M) playsound(M, 'sound/weapons/gun_interactions/rifle_load.ogg', 60, 1) @@ -242,6 +247,7 @@ desc = "Careful not to lose your head." var/guns_left = 30 mag_type = /obj/item/ammo_box/magazine/internal/boltaction/enchanted + can_bayonet = FALSE /obj/item/gun/projectile/shotgun/boltaction/enchanted/New() ..() diff --git a/code/modules/projectiles/guns/projectile/sniper.dm b/code/modules/projectiles/guns/projectile/sniper.dm index e030c9afb2a..b310ce6d884 100644 --- a/code/modules/projectiles/guns/projectile/sniper.dm +++ b/code/modules/projectiles/guns/projectile/sniper.dm @@ -4,7 +4,7 @@ icon_state = "sniper" item_state = "sniper" recoil = 2 - weapon_weight = WEAPON_MEDIUM + weapon_weight = WEAPON_HEAVY mag_type = /obj/item/ammo_box/magazine/sniper_rounds fire_sound = 'sound/weapons/gunshots/gunshot_sniper.ogg' magin_sound = 'sound/weapons/gun_interactions/batrifle_magin.ogg' diff --git a/code/modules/projectiles/guns/rocket.dm b/code/modules/projectiles/guns/rocket.dm index fa6dce3f448..983c6f319fd 100644 --- a/code/modules/projectiles/guns/rocket.dm +++ b/code/modules/projectiles/guns/rocket.dm @@ -37,6 +37,8 @@ to_chat(user, "[rockets.len] / [max_rockets] rockets.") else to_chat(usr, "[src] cannot hold more rockets.") + else + return ..() /obj/item/gun/rocketlauncher/can_shoot() return rockets.len diff --git a/code/modules/projectiles/guns/syringe_gun.dm b/code/modules/projectiles/guns/syringe_gun.dm index 21d44fa8634..ca18cdcd82e 100644 --- a/code/modules/projectiles/guns/syringe_gun.dm +++ b/code/modules/projectiles/guns/syringe_gun.dm @@ -76,7 +76,8 @@ return 1 else to_chat(user, "[src] cannot hold more syringes.") - return 0 + else + return ..() /obj/item/gun/syringe/rapidsyringe name = "rapid syringe gun" diff --git a/code/modules/projectiles/projectile.dm b/code/modules/projectiles/projectile.dm index a8d368d6aef..881635d0e21 100644 --- a/code/modules/projectiles/projectile.dm +++ b/code/modules/projectiles/projectile.dm @@ -30,9 +30,9 @@ var/spread = 0 //amount (in degrees) of projectile spread var/legacy = FALSE //legacy projectile system animate_movement = 0 - + var/ignore_source_check = FALSE - + var/damage = 10 var/tile_dropoff = 0 //how much damage should be decremented as the bullet moves var/tile_dropoff_s = 0 //same as above but for stamina @@ -56,6 +56,7 @@ var/jitter = 0 var/forcedodge = 0 //to pass through everything var/dismemberment = 0 //The higher the number, the greater the bonus to dismembering. 0 will not dismember at all. + var/impact_effect_type //what type of impact effect to show when hitting something var/ricochets = 0 var/ricochets_max = 2 var/ricochet_chance = 0 @@ -80,11 +81,31 @@ /obj/item/projectile/proc/on_range() //if we want there to be effects when they reach the end of their range qdel(src) +/obj/item/projectile/proc/prehit(atom/target) + return TRUE + /obj/item/projectile/proc/on_hit(atom/target, blocked = 0, hit_zone) var/turf/target_loca = get_turf(target) + var/hitx + var/hity + if(target == original) + hitx = target.pixel_x + p_x - 16 + hity = target.pixel_y + p_y - 16 + else + hitx = target.pixel_x + rand(-8, 8) + hity = target.pixel_y + rand(-8, 8) + if(!nodamage && (damage_type == BRUTE || damage_type == BURN) && iswallturf(target_loca) && prob(75)) + var/turf/simulated/wall/W = target_loca + if(impact_effect_type) + new impact_effect_type(target_loca, hitx, hity) + + W.add_dent(WALL_DENT_SHOT, hitx, hity) + return 0 if(alwayslog) add_attack_logs(firer, target, "Shot with a [type]") if(!isliving(target)) + if(impact_effect_type) + new impact_effect_type(target_loca, hitx, hity) return 0 var/mob/living/L = target var/mob/living/carbon/human/H @@ -115,7 +136,8 @@ M.bloody_hands(H) /* Uncomment when bloody_body stops randomly not transferring blood colour. M.bloody_body(H) */ - + else if(impact_effect_type) + new impact_effect_type(target_loca, hitx, hity) var/organ_hit_text = "" if(L.has_limbs) organ_hit_text = " in \the [parse_zone(def_zone)]" @@ -162,7 +184,7 @@ /obj/item/projectile/Bump(atom/A, yes) if(!yes) //prevents double bumps. return - + if(check_ricochet(A) && check_ricochet_flag(A) && ricochets < ricochets_max) ricochets++ if(A.handle_ricochet(src)) @@ -190,7 +212,7 @@ return var/turf/target_turf = get_turf(A) - + prehit(A) var/permutation = A.bullet_act(src, def_zone) // searches for return value, could be deleted after run so check A isn't null if(permutation == -1 || forcedodge)// the bullet passes through a dense object! loc = target_turf @@ -204,6 +226,7 @@ mobs_list += L if(mobs_list.len) var/mob/living/picked_mob = pick(mobs_list) + prehit(picked_mob) picked_mob.bullet_act(src, def_zone) qdel(src) @@ -293,7 +316,7 @@ obj/item/projectile/Crossed(atom/movable/AM, oldloc) //A mob moving on a tile wi /obj/item/projectile/proc/dumbfire(var/dir) current = get_ranged_target_turf(src, dir, world.maxx) //world.maxx is the range. Not sure how to handle this better. fire() - + /obj/item/projectile/proc/on_ricochet(atom/A) return @@ -307,7 +330,7 @@ obj/item/projectile/Crossed(atom/movable/AM, oldloc) //A mob moving on a tile wi if(A.flags_2 & CHECK_RICOCHET_1) return TRUE return FALSE - + /obj/item/projectile/proc/setAngle(new_angle) //wrapper for overrides. Angle = new_angle return TRUE diff --git a/code/modules/projectiles/projectile/beams.dm b/code/modules/projectiles/projectile/beams.dm index b34364c4c93..bad6b6db68b 100644 --- a/code/modules/projectiles/projectile/beams.dm +++ b/code/modules/projectiles/projectile/beams.dm @@ -8,6 +8,7 @@ hitsound_wall = 'sound/weapons/effects/searwall.ogg' flag = "laser" eyeblur = 2 + impact_effect_type = /obj/effect/temp_visual/impact_effect/red_laser is_reflectable = TRUE light_range = 2 light_color = LIGHT_COLOR_RED @@ -38,6 +39,7 @@ irradiate = 30 forcedodge = 1 range = 15 + impact_effect_type = /obj/effect/temp_visual/impact_effect/green_laser light_color = LIGHT_COLOR_GREEN /obj/item/projectile/beam/disabler @@ -48,12 +50,14 @@ flag = "energy" hitsound = 'sound/weapons/tap.ogg' eyeblur = 0 + impact_effect_type = /obj/effect/temp_visual/impact_effect/blue_laser light_color = LIGHT_COLOR_CYAN /obj/item/projectile/beam/pulse name = "pulse" icon_state = "u_laser" damage = 50 + impact_effect_type = /obj/effect/temp_visual/impact_effect/blue_laser light_color = LIGHT_COLOR_DARKBLUE /obj/item/projectile/beam/pulse/on_hit(var/atom/target, var/blocked = 0) @@ -70,6 +74,7 @@ damage = 30 legacy = 1 animate_movement = SLIDE_STEPS + impact_effect_type = /obj/effect/temp_visual/impact_effect/green_laser light_color = LIGHT_COLOR_GREEN /obj/item/projectile/beam/emitter/singularity_pull() @@ -84,6 +89,7 @@ flag = "laser" var/suit_types = list(/obj/item/clothing/suit/redtag, /obj/item/clothing/suit/bluetag) log_override = TRUE + impact_effect_type = /obj/effect/temp_visual/impact_effect/blue_laser light_color = LIGHT_COLOR_DARKBLUE /obj/item/projectile/beam/lasertag/on_hit(atom/target, blocked = 0) @@ -102,6 +108,7 @@ /obj/item/projectile/beam/lasertag/redtag icon_state = "laser" suit_types = list(/obj/item/clothing/suit/bluetag) + impact_effect_type = /obj/effect/temp_visual/impact_effect/red_laser light_color = LIGHT_COLOR_RED /obj/item/projectile/beam/lasertag/bluetag @@ -115,6 +122,7 @@ stun = 5 weaken = 5 stutter = 5 + impact_effect_type = /obj/effect/temp_visual/impact_effect/purple_laser light_color = LIGHT_COLOR_PINK /obj/item/projectile/beam/immolator @@ -142,14 +150,17 @@ icon_state = "purple_laser" damage = 200 damage_type = BURN + impact_effect_type = /obj/effect/temp_visual/impact_effect/purple_laser light_color = LIGHT_COLOR_PURPLE /obj/item/projectile/beam/instakill/blue icon_state = "blue_laser" + impact_effect_type = /obj/effect/temp_visual/impact_effect/blue_laser light_color = LIGHT_COLOR_DARKBLUE /obj/item/projectile/beam/instakill/red icon_state = "red_laser" + impact_effect_type = /obj/effect/temp_visual/impact_effect/red_laser light_color = LIGHT_COLOR_RED /obj/item/projectile/beam/instakill/on_hit(atom/target) diff --git a/code/modules/projectiles/projectile/bullets.dm b/code/modules/projectiles/projectile/bullets.dm index 1cde9ef5017..a973ce1dd87 100644 --- a/code/modules/projectiles/projectile/bullets.dm +++ b/code/modules/projectiles/projectile/bullets.dm @@ -5,6 +5,7 @@ damage_type = BRUTE flag = "bullet" hitsound_wall = "ricochet" + impact_effect_type = /obj/effect/temp_visual/impact_effect /obj/item/projectile/bullet/weakbullet //beanbag, heavy stamina damage name = "beanbag slug" diff --git a/code/modules/projectiles/projectile/energy.dm b/code/modules/projectiles/projectile/energy.dm index 5da56d179bd..e1ca470c95a 100644 --- a/code/modules/projectiles/projectile/energy.dm +++ b/code/modules/projectiles/projectile/energy.dm @@ -41,6 +41,7 @@ damage = 20 damage_type = CLONE irradiate = 10 + impact_effect_type = /obj/effect/temp_visual/impact_effect/green_laser /obj/item/projectile/energy/dart name = "dart" @@ -73,6 +74,7 @@ /obj/item/projectile/energy/shock_revolver name = "shock bolt" icon_state = "purple_laser" + impact_effect_type = /obj/effect/temp_visual/impact_effect/purple_laser var/chain /obj/item/ammo_casing/energy/shock_revolver/ready_proj(atom/target, mob/living/user, quiet, zone_override = "") diff --git a/code/modules/projectiles/projectile/magic.dm b/code/modules/projectiles/projectile/magic.dm index d5e26182ecc..5dabd8a9db6 100644 --- a/code/modules/projectiles/projectile/magic.dm +++ b/code/modules/projectiles/projectile/magic.dm @@ -184,8 +184,10 @@ var/randomize = pick("robot", "slime", "xeno", "human", "animal") switch(randomize) if("robot") + var/path if(prob(30)) - new_mob = new /mob/living/silicon/robot/syndicate(M.loc) + path = pick(typesof(/mob/living/silicon/robot/syndicate)) + new_mob = new path(M.loc) else new_mob = new /mob/living/silicon/robot(M.loc) new_mob.gender = M.gender @@ -193,6 +195,10 @@ new_mob.job = "Cyborg" var/mob/living/silicon/robot/Robot = new_mob Robot.mmi = new /obj/item/mmi(new_mob) + Robot.lawupdate = FALSE + Robot.connected_ai = null + Robot.clear_inherent_laws() + Robot.clear_zeroth_law() if(ishuman(M)) Robot.mmi.transfer_identity(M) //Does not transfer key/client. if("slime") diff --git a/code/modules/projectiles/projectile/reusable.dm b/code/modules/projectiles/projectile/reusable.dm index 1c23605f2b3..bd249037946 100644 --- a/code/modules/projectiles/projectile/reusable.dm +++ b/code/modules/projectiles/projectile/reusable.dm @@ -3,6 +3,7 @@ desc = "How do you even reuse a bullet?" var/ammo_type = /obj/item/ammo_casing/caseless/ var/dropped = 0 + impact_effect_type = null /obj/item/projectile/bullet/reusable/on_hit(atom/target, blocked = 0) . = ..() diff --git a/code/modules/projectiles/projectile/special.dm b/code/modules/projectiles/projectile/special.dm index d313195a40e..41646c114af 100644 --- a/code/modules/projectiles/projectile/special.dm +++ b/code/modules/projectiles/projectile/special.dm @@ -5,6 +5,7 @@ alwayslog = TRUE damage_type = BURN nodamage = 1 + impact_effect_type = /obj/effect/temp_visual/impact_effect/ion flag = "energy" /obj/item/projectile/ion/on_hit(var/atom/target, var/blocked = 0) @@ -129,6 +130,7 @@ damage = 0 damage_type = TOX nodamage = 1 + impact_effect_type = /obj/effect/temp_visual/impact_effect/green_laser flag = "energy" /obj/item/projectile/energy/floramut/on_hit(var/atom/target, var/blocked = 0) @@ -141,7 +143,6 @@ M.apply_effect((rand(30,80)),IRRADIATE) M.Weaken(5) M.visible_message("[M] writhes in pain as [M.p_their()] vacuoles boil.", "You writhe in pain as your vacuoles boil!", "You hear the crunching of leaves.") - if(prob(35)) if(prob(80)) randmutb(M) domutcheck(M,null) @@ -244,18 +245,7 @@ damage = 5 range = 3 dismemberment = 20 - -/obj/item/projectile/plasma/New() - var/turf/proj_turf = get_turf(src) - if(!istype(proj_turf, /turf)) - return - var/datum/gas_mixture/environment = proj_turf.return_air() - if(environment) - var/pressure = environment.return_pressure() - if(pressure < 30) - name = "full strength plasma blast" - damage *= 3 - ..() + impact_effect_type = /obj/effect/temp_visual/impact_effect/purple_laser /obj/item/projectile/plasma/on_hit(atom/target) . = ..() @@ -267,7 +257,8 @@ forcedodge = 0 /obj/item/projectile/plasma/adv - range = 6 + damage = 7 + range = 5 /obj/item/projectile/plasma/adv/mech damage = 10 diff --git a/code/modules/reagents/chemistry/machinery/reagentgrinder.dm b/code/modules/reagents/chemistry/machinery/reagentgrinder.dm index 9ea55dd5af7..1e3bcb92db5 100644 --- a/code/modules/reagents/chemistry/machinery/reagentgrinder.dm +++ b/code/modules/reagents/chemistry/machinery/reagentgrinder.dm @@ -9,8 +9,9 @@ active_power_usage = 100 pass_flags = PASSTABLE var/operating = 0 - var/obj/item/reagent_containers/beaker = null - var/limit = 10 + var/obj/item/reagent_containers/beaker = new /obj/item/reagent_containers/glass/beaker/large + var/limit = null + var/efficiency = null //IMPORTANT NOTE! A negative number is a multiplier, a positive number is a flat amount to add. 0 means equal to the amount of the original reagent var/list/blend_items = list ( @@ -88,10 +89,28 @@ var/list/holdingitems = list() +/obj/machinery/reagentgrinder/empty + icon_state = "juicer0" + beaker = null + /obj/machinery/reagentgrinder/New() ..() - beaker = new /obj/item/reagent_containers/glass/beaker/large(src) - return + component_parts = list() + component_parts += new /obj/item/circuitboard/reagentgrinder(null) + component_parts += new /obj/item/stock_parts/manipulator(null) + component_parts += new /obj/item/stock_parts/manipulator(null) + component_parts += new /obj/item/stock_parts/matter_bin(null) + RefreshParts() + +/obj/machinery/reagentgrinder/RefreshParts() + var/H + var/T + for(var/obj/item/stock_parts/matter_bin/M in component_parts) + H += M.rating + for(var/obj/item/stock_parts/manipulator/M in component_parts) + T += M.rating + limit = 10*H + efficiency = 0.8+T*0.1 /obj/machinery/reagentgrinder/Destroy() QDEL_NULL(beaker) @@ -112,16 +131,29 @@ if(default_unfasten_wrench(user, I)) return + if(exchange_parts(user, I)) + return + + if(anchored && !beaker) + if(default_deconstruction_screwdriver(user, "juicer_open", "juicer0", I)) + return + + if(panel_open && istype(I, /obj/item/crowbar)) + default_deconstruction_crowbar(I) + return + if (istype(I, /obj/item/reagent_containers) && (I.container_type & OPENCONTAINER) ) - if (!beaker) + if(beaker) + to_chat(user, "There's already a container inside.") + else if(panel_open) + to_chat(user, "Close the maintenance panel first.") + else if(!user.drop_item()) return 1 beaker = I beaker.loc = src update_icon() src.updateUsrDialog() - else - to_chat(user, "There's already a container inside.") return 1 //no afterattack if(is_type_in_list(I, dried_items)) @@ -331,7 +363,7 @@ var/space = beaker.reagents.maximum_volume - beaker.reagents.total_volume var/amount = get_juice_amount(O) - beaker.reagents.add_reagent(r_id, min(amount, space)) + beaker.reagents.add_reagent(r_id, min(amount*efficiency, space)) if (beaker.reagents.total_volume >= beaker.reagents.maximum_volume) break @@ -371,17 +403,17 @@ if(amount <= 0) if(amount == 0) if (O.reagents != null && O.reagents.has_reagent("nutriment")) - beaker.reagents.add_reagent(r_id, min(O.reagents.get_reagent_amount("nutriment"), space)) + beaker.reagents.add_reagent(r_id, min(O.reagents.get_reagent_amount("nutriment")*efficiency, space)) O.reagents.remove_reagent("nutriment", min(O.reagents.get_reagent_amount("nutriment"), space)) if (O.reagents != null && O.reagents.has_reagent("plantmatter")) - beaker.reagents.add_reagent(r_id, min(O.reagents.get_reagent_amount("plantmatter"), space)) + beaker.reagents.add_reagent(r_id, min(O.reagents.get_reagent_amount("plantmatter")*efficiency, space)) O.reagents.remove_reagent("plantmatter", min(O.reagents.get_reagent_amount("plantmatter"), space)) else if (O.reagents != null && O.reagents.has_reagent("nutriment")) - beaker.reagents.add_reagent(r_id, min(round(O.reagents.get_reagent_amount("nutriment")*abs(amount)), space)) + beaker.reagents.add_reagent(r_id, min(round(O.reagents.get_reagent_amount("nutriment")*abs(amount)*efficiency), space)) O.reagents.remove_reagent("nutriment", min(O.reagents.get_reagent_amount("nutriment"), space)) if (O.reagents != null && O.reagents.has_reagent("plantmatter")) - beaker.reagents.add_reagent(r_id, min(round(O.reagents.get_reagent_amount("plantmatter")*abs(amount)), space)) + beaker.reagents.add_reagent(r_id, min(round(O.reagents.get_reagent_amount("plantmatter")*abs(amount)*efficiency), space)) O.reagents.remove_reagent("plantmatter", min(O.reagents.get_reagent_amount("plantmatter"), space)) @@ -403,7 +435,7 @@ for (var/r_id in allowed) var/space = beaker.reagents.maximum_volume - beaker.reagents.total_volume var/amount = allowed[r_id] - beaker.reagents.add_reagent(r_id,min(amount, space)) + beaker.reagents.add_reagent(r_id,min(amount*efficiency, space)) if (space < amount) break if (i == round(O.amount, 1)) @@ -419,9 +451,9 @@ var/amount = allowed[r_id] if (amount == 0) if (O.reagents != null && O.reagents.has_reagent(r_id)) - beaker.reagents.add_reagent(r_id,min(O.reagents.get_reagent_amount(r_id), space)) + beaker.reagents.add_reagent(r_id,min(O.reagents.get_reagent_amount(r_id)*efficiency, space)) else - beaker.reagents.add_reagent(r_id,min(amount, space)) + beaker.reagents.add_reagent(r_id,min(amount*efficiency, space)) if (beaker.reagents.total_volume >= beaker.reagents.maximum_volume) break @@ -436,7 +468,7 @@ var/amount = O.reagents.total_volume O.reagents.trans_to(beaker, min(amount, space)) if (O.Uses > 0) - beaker.reagents.add_reagent("slimejelly",min(20, space)) + beaker.reagents.add_reagent("slimejelly",min(20*efficiency, space)) remove_object(O) //Everything else - Transfers reagents from it into beaker diff --git a/code/modules/reagents/chemistry/reagents/medicine.dm b/code/modules/reagents/chemistry/reagents/medicine.dm index 77118450aaa..21e015de9b7 100644 --- a/code/modules/reagents/chemistry/reagents/medicine.dm +++ b/code/modules/reagents/chemistry/reagents/medicine.dm @@ -668,6 +668,7 @@ color = "#A0E85E" metabolization_rate = 0.2 taste_message = "life" + var/revive_type = SENTIENCE_ORGANIC //So you can't revive boss monsters or robots with it /datum/reagent/medicine/strange_reagent/on_mob_life(mob/living/M) var/update_flags = STATUS_UPDATE_NONE @@ -680,13 +681,14 @@ if(volume < 1) // gotta pay to play return ..() - if(isanimal(M)) - if(method == TOUCH) - var/mob/living/simple_animal/SM = M - if(SM.stat == DEAD) - SM.revive() - SM.loot.Cut() //no abusing strange reagent for unlimited farming of resources - SM.visible_message("[M] seems to rise from the dead!") + if(isanimal(M) && method == TOUCH) + var/mob/living/simple_animal/SM = M + if(SM.sentience_type != revive_type) // No reviving Ash Drakes for you + return + if(SM.stat == DEAD) + SM.revive() + SM.loot.Cut() //no abusing strange reagent for farming unlimited resources + SM.visible_message("[SM] seems to rise from the dead!") if(iscarbon(M)) if(method == INGEST || (method == TOUCH && prob(25))) @@ -1149,24 +1151,19 @@ id = "lavaland_extract" description = "An extract of lavaland atmospheric and mineral elements. Heals the user in small doses, but is extremely toxic otherwise." color = "#C8A5DC" // rgb: 200, 165, 220 - metabolization_rate = 0.7 //VERY strong chemical overdose_threshold = 3 //To prevent people stacking massive amounts of a very strong healing reagent can_synth = FALSE /datum/reagent/medicine/lavaland_extract/on_mob_life(mob/living/carbon/M) var/update_flags = STATUS_UPDATE_NONE - update_flags |= M.adjustToxLoss(-3*REAGENTS_EFFECT_MULTIPLIER, FALSE) - update_flags |= M.adjustOxyLoss(-3*REAGENTS_EFFECT_MULTIPLIER, FALSE) - update_flags |= M.adjustBruteLoss(-6*REAGENTS_EFFECT_MULTIPLIER, FALSE) - update_flags |= M.adjustFireLoss(-6*REAGENTS_EFFECT_MULTIPLIER, FALSE) + update_flags |= M.adjustBruteLoss(-5*REAGENTS_EFFECT_MULTIPLIER, FALSE) + update_flags |= M.adjustFireLoss(-5*REAGENTS_EFFECT_MULTIPLIER, FALSE) return ..() | update_flags /datum/reagent/medicine/lavaland_extract/overdose_process(mob/living/M) // This WILL be brutal var/update_flags = STATUS_UPDATE_NONE M.AdjustConfused(5) - update_flags |= M.adjustBruteLoss(10*REAGENTS_EFFECT_MULTIPLIER, FALSE) - update_flags |= M.adjustFireLoss(10*REAGENTS_EFFECT_MULTIPLIER, FALSE) - update_flags |= M.adjustToxLoss(10*REAGENTS_EFFECT_MULTIPLIER, FALSE) - update_flags |= M.Stun(7, FALSE) - update_flags |= M.Weaken(7, FALSE) + update_flags |= M.adjustBruteLoss(3*REAGENTS_EFFECT_MULTIPLIER, FALSE) + update_flags |= M.adjustFireLoss(3*REAGENTS_EFFECT_MULTIPLIER, FALSE) + update_flags |= M.adjustToxLoss(3*REAGENTS_EFFECT_MULTIPLIER, FALSE) return ..() | update_flags diff --git a/code/modules/reagents/chemistry/reagents/toxins.dm b/code/modules/reagents/chemistry/reagents/toxins.dm index 8048c21a283..3a1ac5554a9 100644 --- a/code/modules/reagents/chemistry/reagents/toxins.dm +++ b/code/modules/reagents/chemistry/reagents/toxins.dm @@ -988,10 +988,10 @@ C.adjustToxLoss(lethality) if(ishuman(M)) var/mob/living/carbon/human/H = M - if(IS_PLANT in H.dna.species.species_traits) //plantmen take a LOT of damage - H.adjustToxLoss(50) + if(IS_PLANT in H.dna.species.species_traits) //plantmen take extra damage + H.adjustToxLoss(3) ..() - else if(istype(M, /mob/living/simple_animal/diona)) //plantmen monkeys (diona) take EVEN MORE damage + else if(istype(M, /mob/living/simple_animal/diona)) //nymphs take EVEN MORE damage var/mob/living/simple_animal/diona/D = M D.adjustHealth(100) ..() diff --git a/code/modules/reagents/reagent_containers/glass_containers.dm b/code/modules/reagents/reagent_containers/glass_containers.dm index d408db7f2f0..5221ae5e600 100644 --- a/code/modules/reagents/reagent_containers/glass_containers.dm +++ b/code/modules/reagents/reagent_containers/glass_containers.dm @@ -81,7 +81,7 @@ reagents.reaction(M, TOUCH) reagents.clear_reagents() - else + else if(M != user) M.visible_message("[user] attempts to feed something to [M].", \ "[user] attempts to feed something to you.") @@ -348,6 +348,13 @@ slot_flags = SLOT_HEAD container_type = OPENCONTAINER +/obj/item/reagent_containers/glass/bucket/wooden + name = "wooden bucket" + icon_state = "woodbucket" + item_state = "woodbucket" + materials = null + burn_state = FLAMMABLE + /obj/item/reagent_containers/glass/bucket/equipped(mob/user, slot) ..() if(slot == slot_head && reagents.total_volume) diff --git a/code/modules/reagents/reagent_containers/hypospray.dm b/code/modules/reagents/reagent_containers/hypospray.dm index dace5928b2e..3abfbfd0e19 100644 --- a/code/modules/reagents/reagent_containers/hypospray.dm +++ b/code/modules/reagents/reagent_containers/hypospray.dm @@ -155,9 +155,9 @@ name = "survival medipen" desc = "A medipen for surviving in the harshest of environments, heals and protects from environmental hazards.
      WARNING: Do not inject more than one pen in quick succession." icon_state = "stimpen" - volume = 22 - amount_per_transfer_from_this = 22 - list_reagents = list("salbutamol" = 10, "epinephrine" = 5, "lavaland_extract" = 2, "salglu_solution" = 5) //Short burst of healing, followed by minor healing from the saline + volume = 42 + amount_per_transfer_from_this = 42 + list_reagents = list("salbutamol" = 10, "teporone" = 15, "epinephrine" = 10, "lavaland_extract" = 2, "weak_omnizine" = 5) //Short burst of healing, followed by minor healing from the saline /obj/item/reagent_containers/hypospray/autoinjector/nanocalcium name = "nanocalcium autoinjector" diff --git a/code/modules/reagents/reagent_containers/iv_bag.dm b/code/modules/reagents/reagent_containers/iv_bag.dm index 825aa69632b..cfe84d10f2e 100644 --- a/code/modules/reagents/reagent_containers/iv_bag.dm +++ b/code/modules/reagents/reagent_containers/iv_bag.dm @@ -9,7 +9,7 @@ righthand_file = 'icons/goonstation/mob/inhands/items_righthand.dmi' icon_state = "ivbag" volume = 200 - possible_transfer_amounts = list(1,5,10) + possible_transfer_amounts = list(1,5,10,15,20,25,30,50) // Everything above 10 is NOT usable on a person and is instead used for transfering to other containers amount_per_transfer_from_this = 1 container_type = OPENCONTAINER var/label_text @@ -53,6 +53,11 @@ end_processing() return + if(amount_per_transfer_from_this > 10) // Prevents people from switching to illegal transfer values while the IV is already in someone, i.e. anything over 10 + visible_message("The IV bag's needle pops out of [injection_target]'s arm. The transfer amount is too high!") + end_processing() + return + if(get_dist(get_turf(src), get_turf(injection_target)) > 1) to_chat(injection_target, "The [src]'s' needle is ripped out of you!") injection_target.apply_damage(3, BRUTE, pick("r_arm", "l_arm")) @@ -98,6 +103,9 @@ else // Inserting the needle if(!L.can_inject(user, 1)) return + if(amount_per_transfer_from_this > 10) // We only want to be able to transfer 1, 5, or 10 units to people. Higher numbers are for transfering to other containers + to_chat(user, "The IV bag can only be used on someone with a transfer amount of 1, 5 or 10.") + return if(L != user) L.visible_message("[user] is trying to insert [src]'s needle into [L]'s arm!", \ "[user] is trying to insert [src]'s needle into [L]'s arm!") @@ -107,6 +115,22 @@ "[user] inserts [src]'s needle into [L]'s arm!") begin_processing(L) + else if(target.is_refillable() && is_drainable()) // Transferring from IV bag to other containers + if(!reagents.total_volume) + to_chat(user, "[src] is empty.") + return + + if(target.reagents.total_volume >= target.reagents.maximum_volume) + to_chat(user, "[target] is full.") + return + + var/trans = reagents.trans_to(target, amount_per_transfer_from_this) + to_chat(user, "You transfer [trans] units of the solution to [target].") + + else if(istype(target, /obj/item/reagent_containers/glass) && !target.is_open_container()) + to_chat(user, "You cannot fill [target] while it is sealed.") + return + /obj/item/reagent_containers/iv_bag/update_icon() overlays.Cut() diff --git a/code/modules/recycling/disposal.dm b/code/modules/recycling/disposal.dm index f7719c4fd54..6a5d85e0631 100644 --- a/code/modules/recycling/disposal.dm +++ b/code/modules/recycling/disposal.dm @@ -1036,6 +1036,7 @@ if(O.currTag > 0)// Tag set sortType = O.currTag + name = GLOB.TAGGERLOCATIONS[O.currTag] playsound(src.loc, 'sound/machines/twobeep.ogg', 100, 1) var/tag = uppertext(GLOB.TAGGERLOCATIONS[O.currTag]) to_chat(user, "Changed filter to [tag]") diff --git a/code/modules/research/designs/machine_designs.dm b/code/modules/research/designs/machine_designs.dm index c604105dc04..a6dfb7bd848 100644 --- a/code/modules/research/designs/machine_designs.dm +++ b/code/modules/research/designs/machine_designs.dm @@ -12,6 +12,16 @@ build_path = /obj/item/circuitboard/thermomachine category = list ("Engineering Machinery") +/datum/design/recharger + name = "Machine Board(Weapon Recharger)" + desc = "The circuit board for a weapon recharger" + id = "recharger" + build_path = /obj/item/circuitboard/recharger + materials = list(MAT_GLASS = 1000) + build_type = IMPRINTER + req_tech = list("powerstorage" = 3, "materials" = 3) + category = list("Misc. Machinery") + /datum/design/smes name = "Machine Board (SMES)" desc = "The circuit board for a SMES." @@ -182,6 +192,16 @@ build_path = /obj/item/circuitboard/chem_heater category = list ("Medical Machinery") +/datum/design/reagentgrinder + name = "Machine Design (All-In-One Grinder)" + desc = "The circuit board for an All-In-One Grinder." + id = "reagentgrinder" + req_tech = list("biotech" = 2, "materials" = 2, "programming" = 2) + build_type = IMPRINTER + materials = list(MAT_GLASS = 1000) + build_path = /obj/item/circuitboard/reagentgrinder + category = list ("Medical Machinery") + /datum/design/sleeper name = "Machine Board (Sleeper)" desc = "Allows for the construction of circuit boards used to build a Sleeper." diff --git a/code/modules/research/designs/mining_designs.dm b/code/modules/research/designs/mining_designs.dm index 14cd12c6837..76439c64987 100644 --- a/code/modules/research/designs/mining_designs.dm +++ b/code/modules/research/designs/mining_designs.dm @@ -1,16 +1,6 @@ ///////////////////////////////////////// /////////////////Mining////////////////// ///////////////////////////////////////// -/datum/design/drill_diamond - name = "Diamond Mining Drill" - desc = "Yours is the drill that will pierce the heavens!" - id = "drill_diamond" - req_tech = list("materials" = 6, "powerstorage" = 5, "engineering" = 5) - build_type = PROTOLATHE - materials = list(MAT_METAL = 3000, MAT_GLASS = 1000, MAT_DIAMOND = 2000) //Yes, a whole diamond is needed. - build_path = /obj/item/pickaxe/drill/diamonddrill - category = list("Mining") - /datum/design/drill name = "Mining Drill" desc = "Yours is the drill that will pierce through the rock walls." @@ -21,13 +11,23 @@ build_path = /obj/item/pickaxe/drill category = list("Mining") +/datum/design/drill_diamond + name = "Diamond Mining Drill" + desc = "Yours is the drill that will pierce the heavens!" + id = "drill_diamond" + req_tech = list("materials" = 6, "powerstorage" = 5, "engineering" = 5) + build_type = PROTOLATHE + materials = list(MAT_METAL = 3000, MAT_GLASS = 1000, MAT_DIAMOND = 2000) //Yes, a whole diamond is needed. + build_path = /obj/item/pickaxe/drill/diamonddrill + category = list("Mining") + /datum/design/plasmacutter name = "Plasma Cutter" desc = "You could use it to cut limbs off of xenos! Or, you know, mine stuff." id = "plasmacutter" req_tech = list("materials" = 3, "plasmatech" = 3, "magnets" = 2) build_type = PROTOLATHE - materials = list(MAT_METAL = 2000, MAT_GLASS = 1000, MAT_PLASMA = 1500) + materials = list(MAT_METAL = 1500, MAT_GLASS = 500, MAT_PLASMA = 400) build_path = /obj/item/gun/energy/plasmacutter category = list("Mining") @@ -37,7 +37,7 @@ id = "plasmacutter_adv" req_tech = list("materials" = 4, "plasmatech" = 4, "engineering" = 2, "combat" = 3, "magnets" = 3) build_type = PROTOLATHE - materials = list(MAT_METAL = 4000, MAT_GLASS = 1000, MAT_PLASMA = 4000, MAT_GOLD = 500) + materials = list(MAT_METAL = 3000, MAT_GLASS = 1000, MAT_PLASMA = 2000, MAT_GOLD = 500) build_path = /obj/item/gun/energy/plasmacutter/adv category = list("Mining") @@ -101,16 +101,6 @@ build_path = /obj/item/borg/upgrade/modkit/range category = list("Mining", "Cyborg Upgrade Modules") -/datum/design/superaccelerator - name = "Kinetic Accelerator Pressure Mod" - desc = "A modification kit which allows Kinetic Accelerators to do more damage while indoors." - id = "indoormod" - req_tech = list("materials" = 5, "powerstorage" = 4, "engineering" = 4, "magnets" = 4, "combat" = 3) - build_type = PROTOLATHE | MECHFAB - materials = list(MAT_METAL = 2000, MAT_GLASS = 1500, MAT_SILVER = 2000, MAT_URANIUM = 2000) - build_path = /obj/item/borg/upgrade/modkit/indoors - category = list("Mining", "Cyborg Upgrade Modules") - /datum/design/hyperaccelerator name = "Kinetic Accelerator Mining AoE Mod" desc = "A modification kit for Kinetic Accelerators which causes it to fire AoE blasts that destroy rock." @@ -119,4 +109,4 @@ build_type = PROTOLATHE | MECHFAB materials = list(MAT_METAL = 8000, MAT_GLASS = 1500, MAT_SILVER = 2000, MAT_GOLD = 2000, MAT_DIAMOND = 2000) build_path = /obj/item/borg/upgrade/modkit/aoe/turfs - category = list("Mining", "Cyborg Upgrade Modules") + category = list("Mining", "Cyborg Upgrade Modules") \ No newline at end of file diff --git a/code/modules/research/designs/spacepod_designs.dm b/code/modules/research/designs/spacepod_designs.dm index 44bef918678..9930426df86 100644 --- a/code/modules/research/designs/spacepod_designs.dm +++ b/code/modules/research/designs/spacepod_designs.dm @@ -149,17 +149,6 @@ build_path = /obj/item/spacepod_equipment/weaponry/mining_laser category = list("Pod_Weaponry") -/datum/design/pod_mining_laser_hyper - construction_time = 200 - name = "Enhanced Mining Laser" - desc = "Allows for the construction of an enhanced mining laser." - id = "pod_mining_laser_hyper" - req_tech = list("materials" = 7, "powerstorage" = 6, "engineering" = 5, "magnets" = 6, "combat" = 4) - build_type = PODFAB - materials = list(MAT_METAL = 10000, MAT_GLASS = 5000, MAT_SILVER = 4000, MAT_GOLD = 4000, MAT_DIAMOND = 4000) - build_path = /obj/item/spacepod_equipment/weaponry/mining_laser_hyper - category = list("Pod_Weaponry") - ////////////////////////////////////////// //////SPACEPOD MISC. ITEMS//////////////// ////////////////////////////////////////// diff --git a/code/modules/research/research.dm b/code/modules/research/research.dm index 4d1195e29ce..05786daed94 100644 --- a/code/modules/research/research.dm +++ b/code/modules/research/research.dm @@ -372,8 +372,9 @@ datum/tech/robotics var/default_desc = "A disk for storing device design data for construction in lathes." /obj/item/disk/design_disk/New() - src.pixel_x = rand(-5.0, 5) - src.pixel_y = rand(-5.0, 5) + ..() + pixel_x = rand(-5, 5) + pixel_y = rand(-5, 5) /obj/item/disk/design_disk/proc/load_blueprint(datum/design/D) name = "[default_name] \[[D]\]" diff --git a/code/modules/research/xenobiology/xenobiology.dm b/code/modules/research/xenobiology/xenobiology.dm index 0587f6e4f73..81ca4bfeb9b 100644 --- a/code/modules/research/xenobiology/xenobiology.dm +++ b/code/modules/research/xenobiology/xenobiology.dm @@ -211,12 +211,16 @@ if(SM.flags_2 & HOLOGRAM_2) //Check to see if it's a holodeck creature to_chat(SM, "You also become depressingly aware that you are not a real creature, but instead a holoform. Your existence is limited to the parameters of the holodeck.") to_chat(user, "[M] accepts the potion and suddenly becomes attentive and aware. It worked!") + after_success(user, SM) qdel(src) else to_chat(user, "[M] looks interested for a moment, but then looks back down. Maybe you should try again later.") being_used = 0 ..() +/obj/item/slimepotion/sentience/proc/after_success(mob/living/user, mob/living/simple_animal/SM) + return + /obj/item/slimepotion/transference name = "consciousness transference potion" desc = "A strange slime-based chemical that, when used, allows the user to transfer their consciousness to a lesser being." diff --git a/code/modules/response_team/ert.dm b/code/modules/response_team/ert.dm index 5570053d946..9c8d963fdcd 100644 --- a/code/modules/response_team/ert.dm +++ b/code/modules/response_team/ert.dm @@ -240,32 +240,21 @@ var/ert_request_answered = FALSE switch(officer_type) if("Engineer") M.equipOutfit(engineering_outfit) - M.job = "ERT Engineering" if("Security") M.equipOutfit(security_outfit) - M.job = "ERT Security" if("Medic") M.equipOutfit(medical_outfit) - M.job = "ERT Medical" if("Janitor") M.equipOutfit(janitor_outfit) - M.job = "ERT Janitor" if("Paranormal") M.equipOutfit(paranormal_outfit) - M.job = "ERT Paranormal" - M.mind.isholy = TRUE if("Commander") - // Override name and age for the commander - M.rename_character(null, "[pick("Lieutenant", "Captain", "Major")] [pick(GLOB.last_names)]") - M.age = rand(35,45) - M.equipOutfit(command_outfit) - M.job = "ERT Commander" /datum/response_team/proc/cannot_send_team() event_announcement.Announce("[station_name()], we are unfortunately unable to send you an Emergency Response Team at this time.", "ERT Unavailable") @@ -317,6 +306,7 @@ var/ert_request_answered = FALSE name = "Response team" var/rt_assignment = "Emergency Response Team Member" var/rt_job = "This is a bug" + var/rt_mob_job = "This is a bug" // The job set on the actual mob. allow_backbag_choice = FALSE allow_loadout = FALSE pda = /obj/item/pda/heads/ert diff --git a/code/modules/response_team/ert_outfits.dm b/code/modules/response_team/ert_outfits.dm index b287643901d..f4ab9561bd5 100644 --- a/code/modules/response_team/ert_outfits.dm +++ b/code/modules/response_team/ert_outfits.dm @@ -23,6 +23,10 @@ PDA.ownrank = rt_assignment PDA.name = "PDA-[H.real_name] ([PDA.ownjob])" +/datum/outfit/job/centcom/response_team/pre_equip(mob/living/carbon/human/H, visualsOnly = FALSE) + . = ..() + + H.job = rt_mob_job //////////////////// COMMANDER /////////////////// @@ -30,6 +34,7 @@ name = "RT Commander" rt_assignment = "Emergency Response Team Leader" rt_job = "Emergency Response Team Leader" + rt_mob_job = "ERT Commander" uniform = /obj/item/clothing/under/rank/centcom_officer back = /obj/item/storage/backpack/ert/commander @@ -39,6 +44,12 @@ l_pocket = /obj/item/pinpointer r_pocket = /obj/item/melee/classic_baton/telescopic +/datum/outfit/job/centcom/response_team/commander/pre_equip(mob/living/carbon/human/H, visualsOnly = FALSE) + . = ..() + + H.rename_character(null, "[pick("Lieutenant", "Captain", "Major")] [pick(GLOB.last_names)]") + H.age = rand(35,45) + /datum/outfit/job/centcom/response_team/commander/amber name = "RT Commander (Amber)" shoes = /obj/item/clothing/shoes/combat @@ -69,7 +80,6 @@ belt = /obj/item/gun/energy/gun/blueshield/pdw9 backpack_contents = list( - /obj/item/clothing/head/helmet/space/hardsuit/ert/commander = 1, /obj/item/clothing/mask/gas/sechailer/swat = 1, /obj/item/gun/energy/ionrifle/carbine = 1, /obj/item/restraints/handcuffs = 1, @@ -87,7 +97,6 @@ belt = /obj/item/gun/projectile/automatic/pistol/enforcer/lethal backpack_contents = list( - /obj/item/clothing/head/helmet/space/hardsuit/ert/commander/gamma = 1, /obj/item/clothing/mask/gas/sechailer/swat = 1, /obj/item/restraints/handcuffs = 1, /obj/item/storage/lockbox/mindshield = 1, @@ -107,6 +116,7 @@ /datum/outfit/job/centcom/response_team/security name = "RT Security" rt_job = "Emergency Response Team Officer" + rt_mob_job = "ERT Security" uniform = /obj/item/clothing/under/rank/security back = /obj/item/storage/backpack/ert/security belt = /obj/item/storage/belt/security/response_team @@ -149,7 +159,6 @@ ) backpack_contents = list( - /obj/item/clothing/head/helmet/space/hardsuit/ert/security = 1, /obj/item/clothing/mask/gas/sechailer = 1, /obj/item/clothing/shoes/magboots = 1, /obj/item/storage/box/handcuffs = 1, @@ -172,7 +181,6 @@ r_hand = /obj/item/gun/energy/immolator/multi backpack_contents = list( - /obj/item/clothing/head/helmet/space/hardsuit/ert/security/gamma = 1, /obj/item/clothing/mask/gas/sechailer/swat = 1, /obj/item/storage/box/handcuffs = 1, /obj/item/storage/box/flashbangs = 1, @@ -194,6 +202,7 @@ /datum/outfit/job/centcom/response_team/engineer name = "RT Engineer" rt_job = "Emergency Response Team Engineer" + rt_mob_job = "ERT Engineering" back = /obj/item/storage/backpack/ert/engineer uniform = /obj/item/clothing/under/rank/engineer @@ -213,7 +222,6 @@ r_pocket = /obj/item/melee/classic_baton/telescopic backpack_contents = list( - /obj/item/clothing/head/helmet/space/hardsuit/ert/engineer = 1, /obj/item/clothing/mask/gas = 1, /obj/item/t_scanner = 1, /obj/item/stack/sheet/glass/fifty = 1, @@ -237,7 +245,6 @@ r_pocket = /obj/item/melee/classic_baton/telescopic backpack_contents = list( - /obj/item/clothing/head/helmet/space/hardsuit/ert/engineer/gamma = 1, /obj/item/clothing/mask/gas = 1, /obj/item/rcd/preloaded = 1, /obj/item/rcd_ammo = 3, @@ -257,7 +264,6 @@ r_pocket = /obj/item/melee/classic_baton/telescopic backpack_contents = list( - /obj/item/clothing/head/helmet/space/hardsuit/ert/engineer/gamma = 1, /obj/item/clothing/mask/gas/sechailer/swat = 1, /obj/item/rcd/combat = 1, /obj/item/rcd_ammo/large = 3 @@ -276,6 +282,7 @@ /datum/outfit/job/centcom/response_team/medic name = "RT Medic" rt_job = "Emergency Response Team Medic" + rt_mob_job = "ERT Medical" uniform = /obj/item/clothing/under/rank/medical back = /obj/item/storage/backpack/ert/medical pda = /obj/item/pda/heads/ert/medical @@ -312,10 +319,11 @@ /datum/outfit/job/centcom/response_team/medic/red name = "RT Medic (Red)" + rt_mob_job = "ERT Medical" shoes = /obj/item/clothing/shoes/white gloves = /obj/item/clothing/gloves/color/latex/nitrile suit = /obj/item/clothing/suit/space/hardsuit/ert/medical - glasses = /obj/item/clothing/glasses/hud/health/health_advanced + glasses = /obj/item/clothing/glasses/hud/health/sunglasses suit_store = /obj/item/gun/energy/gun cybernetic_implants = list( /obj/item/organ/internal/cyberimp/arm/surgery, @@ -327,7 +335,6 @@ r_pocket = /obj/item/melee/classic_baton/telescopic backpack_contents = list( - /obj/item/clothing/head/helmet/space/hardsuit/ert/medical = 1, /obj/item/clothing/mask/surgical = 1, /obj/item/storage/firstaid/toxin = 1, /obj/item/storage/firstaid/brute = 1, @@ -354,7 +361,6 @@ r_pocket = /obj/item/reagent_containers/hypospray/autoinjector backpack_contents = list( - /obj/item/clothing/head/helmet/space/hardsuit/ert/medical/gamma = 1, /obj/item/clothing/mask/gas/sechailer/swat = 1, /obj/item/bodyanalyzer/advanced = 1, /obj/item/extinguisher/mini = 1, @@ -377,6 +383,7 @@ /datum/outfit/job/centcom/response_team/paranormal name = "RT Paranormal" rt_job = "Emergency Response Team Inquisitor" + rt_mob_job = "ERT Paranormal" uniform = /obj/item/clothing/under/rank/chaplain back = /obj/item/storage/backpack/ert/security gloves = /obj/item/clothing/gloves/color/black @@ -392,6 +399,11 @@ /obj/item/flashlight/seclite = 1 ) +/datum/outfit/job/centcom/response_team/paranormal/pre_equip(mob/living/carbon/human/H, visualsOnly = FALSE) + . = ..() + if(H.mind) + H.mind.isholy = TRUE + /datum/outfit/job/centcom/response_team/paranormal/amber name = "RT Paranormal (Amber)" suit = /obj/item/clothing/suit/armor/vest/ert/security/paranormal @@ -402,7 +414,6 @@ /datum/outfit/job/centcom/response_team/paranormal/red name = "RT Paranormal (Red)" suit = /obj/item/clothing/suit/space/hardsuit/ert/paranormal/inquisitor - head = /obj/item/clothing/head/helmet/space/hardsuit/ert/paranormal/inquisitor suit_store = /obj/item/gun/energy/gun r_pocket = /obj/item/nullrod/ert glasses = /obj/item/clothing/glasses/sunglasses @@ -415,7 +426,6 @@ /datum/outfit/job/centcom/response_team/paranormal/gamma name = "RT Paranormal (Gamma)" suit = /obj/item/clothing/suit/space/hardsuit/ert/paranormal/inquisitor - head = /obj/item/clothing/head/helmet/space/hardsuit/ert/paranormal/inquisitor suit_store = /obj/item/gun/energy/gun/nuclear l_pocket = /obj/item/grenade/clusterbuster/holy shoes = /obj/item/clothing/shoes/magboots/advance @@ -433,6 +443,7 @@ /datum/outfit/job/centcom/response_team/janitorial name = "RT Janitor" rt_job = "Emergency Response Team Janitor" + rt_mob_job = "ERT Janitor" uniform = /obj/item/clothing/under/color/purple back = /obj/item/storage/backpack/ert/janitor belt = /obj/item/storage/belt/janitor/full @@ -461,7 +472,6 @@ /datum/outfit/job/centcom/response_team/janitorial/red name = "RT Janitor (Red)" suit = /obj/item/clothing/suit/space/hardsuit/ert/janitor - head = /obj/item/clothing/head/helmet/space/hardsuit/ert/janitor glasses = /obj/item/clothing/glasses/hud/security/sunglasses r_pocket = /obj/item/scythe/tele @@ -483,7 +493,6 @@ shoes = /obj/item/clothing/shoes/magboots/advance backpack_contents = list( - /obj/item/clothing/head/helmet/space/hardsuit/ert/janitor/gamma = 1, /obj/item/grenade/chem_grenade/antiweed = 2, /obj/item/storage/box/lights/mixed = 1, /obj/item/storage/bag/trash/bluespace = 1, diff --git a/code/modules/ruins/lavalandruin_code/clown_planet.dm b/code/modules/ruins/lavalandruin_code/clown_planet.dm new file mode 100644 index 00000000000..6121c40d2af --- /dev/null +++ b/code/modules/ruins/lavalandruin_code/clown_planet.dm @@ -0,0 +1,7 @@ +//lavaland clown planet papers + +/obj/item/paper/crumpled/bloody/ruins/lavaland/clown_planet/escape + info = "If you dare not continue down this path of madness, escape can be found through the chute in this room." + +/obj/item/paper/crumpled/bloody/ruins/lavaland/clown_planet/hope + info = "Abandon hope, all ye who enter here." \ No newline at end of file diff --git a/code/modules/ruins/lavalandruin_code/seed_vault.dm b/code/modules/ruins/lavalandruin_code/seed_vault.dm index 21cf86b4a07..db16c7b3a71 100644 --- a/code/modules/ruins/lavalandruin_code/seed_vault.dm +++ b/code/modules/ruins/lavalandruin_code/seed_vault.dm @@ -17,7 +17,7 @@ density = TRUE roundstart = FALSE death = FALSE - mob_species = /datum/species/diona + mob_species = /datum/species/diona/pod flavour_text = "You are a sentient ecosystem, an example of the mastery over life that your creators possessed. Your masters, benevolent as they were, created uncounted \ seed vaults and spread them across the universe to every planet they could chart. You are in one such seed vault. Your goal is to cultivate and spread life wherever it will go while waiting \ for contact from your creators. Estimated time of last contact: Deployment, 5x10^3 millennia ago." diff --git a/code/modules/shuttle/on_move.dm b/code/modules/shuttle/on_move.dm index 67765ef8ac5..0a11a4397ad 100644 --- a/code/modules/shuttle/on_move.dm +++ b/code/modules/shuttle/on_move.dm @@ -30,17 +30,21 @@ if(id_tag == "s_docking_airlock") INVOKE_ASYNC(src, .proc/lock) -/mob/onShuttleMove() +/mob/onShuttleMove(turf/oldT, turf/T1, rotation) if(!move_on_shuttle) return 0 . = ..() if(!.) return - if(client) - if(buckled) - shake_camera(src, 2, 1) // turn it down a bit come on - else - shake_camera(src, 7, 1) + if(!client) + return + + if(buckled) + shake_camera(src, 2, 1) // turn it down a bit come on + else + shake_camera(src, 7, 1) + + update_parallax_contents() /mob/living/carbon/onShuttleMove() . = ..() @@ -54,8 +58,18 @@ if(smooth) queue_smooth(src) +/mob/postDock() + update_parallax_contents() + /obj/machinery/door/airlock/postDock(obj/docking_port/stationary/S1) . = ..() if(!S1.lock_shuttle_doors && id_tag == "s_docking_airlock") INVOKE_ASYNC(src, .proc/unlock) +/obj/structure/ladder/onShuttleMove() + if(resistance_flags & INDESTRUCTIBLE) + // simply don't be moved + return FALSE + disconnect() + LateInitialize() + return ..() \ No newline at end of file diff --git a/code/modules/shuttle/shuttle.dm b/code/modules/shuttle/shuttle.dm index 51ba6c6bad1..8c96837e9d5 100644 --- a/code/modules/shuttle/shuttle.dm +++ b/code/modules/shuttle/shuttle.dm @@ -189,7 +189,7 @@ /obj/docking_port/stationary/transit name = "In transit" turf_type = /turf/space/transit - + var/area/shuttle/transit/assigned_area lock_shuttle_doors = 1 /obj/docking_port/stationary/transit/register() @@ -210,8 +210,10 @@ var/list/shuttle_areas var/timer //used as a timer (if you want time left to complete move, use timeLeft proc) + var/last_timer_length var/mode = SHUTTLE_IDLE //current shuttle mode (see global defines) var/callTime = 50 //time spent in transit (deciseconds) + var/ignitionTime = 30 // time spent "starting the engines". Also rate limits how often we try to reserve transit space if its ever full of transiting shuttles. var/roundstart_move //id of port to send shuttle to at roundstart var/travelDir = 0 //direction the shuttle would travel in var/rebuildable = 0 //can build new shuttle consoles for this one @@ -325,23 +327,22 @@ switch(mode) if(SHUTTLE_CALL) if(S == destination) - if(world.time <= timer) - timer = world.time + if(timeLeft(1) < callTime) + setTimer(callTime) else destination = S - timer = world.time + setTimer(callTime) if(SHUTTLE_RECALL) if(S == destination) - timer = world.time - timeLeft(1) + setTimer(callTime - timeLeft(1)) else destination = S - timer = world.time + setTimer(callTime) mode = SHUTTLE_CALL - else + if(SHUTTLE_IDLE, SHUTTLE_IGNITING) destination = S - mode = SHUTTLE_CALL - timer = world.time - enterTransit() //hyperspace + mode = SHUTTLE_IGNITING + setTimer(ignitionTime) //recall the shuttle to where it was previously /obj/docking_port/mobile/proc/cancel() @@ -358,7 +359,7 @@ var/obj/docking_port/stationary/S0 = get_docked() var/obj/docking_port/stationary/S1 = findTransitDock() if(S1) - if(dock(S1)) + if(dock(S1, , TRUE)) WARNING("shuttle \"[id]\" could not enter transit space. Docked at [S0 ? S0.id : "null"]. Transit dock [S1 ? S1.id : "null"].") else previous = S0 @@ -429,7 +430,7 @@ //this is the main proc. It instantly moves our mobile port to stationary port S1 //it handles all the generic behaviour, such as sanity checks, closing doors on the shuttle, stunning mobs, etc -/obj/docking_port/mobile/proc/dock(obj/docking_port/stationary/S1, force=FALSE) +/obj/docking_port/mobile/proc/dock(obj/docking_port/stationary/S1, force=FALSE, transit=FALSE) // Crashing this ship with NO SURVIVORS if(S1.get_docked() == src) remove_ripples() @@ -492,6 +493,7 @@ var/turf/simulated/Ts1 = T1 Ts1.copy_air_with_tile(T0) + areaInstance.moving = TRUE //move mobile to new location for(var/atom/movable/AM in T0) AM.onShuttleMove(T0, T1, rotation) @@ -512,6 +514,7 @@ T0.CalculateAdjacentTurfs() SSair.add_to_active(T0,1) + areaInstance.moving = transit for(var/A1 in L1) var/turf/T1 = A1 T1.postDock(S1) @@ -630,6 +633,11 @@ if(dock(previous)) setTimer(20) //can't dock for some reason, try again in 2 seconds return + if(SHUTTLE_IGNITING) + mode = SHUTTLE_CALL + setTimer(callTime) + enterTransit() + return mode = SHUTTLE_IDLE timer = 0 destination = null @@ -646,6 +654,22 @@ timer = world.time timer += wait - timeLeft(1) +/obj/docking_port/mobile/proc/modTimer(multiple) + var/time_remaining = timer - world.time + if(time_remaining < 0 || !last_timer_length) + return + time_remaining *= multiple + last_timer_length *= multiple + setTimer(time_remaining) + +/obj/docking_port/mobile/proc/invertTimer() + if(!last_timer_length) + return + var/time_remaining = timer - world.time + if(time_remaining > 0) + var/time_passed = last_timer_length - time_remaining + setTimer(time_passed) + //returns timeLeft /obj/docking_port/mobile/proc/timeLeft(divisor) if(divisor <= 0) @@ -787,7 +811,7 @@ return switch(SSshuttle.moveShuttle(shuttleId, href_list["move"], 1)) if(0) - to_chat(usr, "Shuttle received message and will be sent shortly.") + atom_say("Shuttle departing! Please stand away from the doors.") if(1) to_chat(usr, "Invalid shuttle requested.") else diff --git a/code/modules/shuttle/supply.dm b/code/modules/shuttle/supply.dm index b6a7e7bb28f..9da43d08fbf 100644 --- a/code/modules/shuttle/supply.dm +++ b/code/modules/shuttle/supply.dm @@ -247,7 +247,8 @@ /obj/machinery/clonepod, /obj/effect/hierophant, /obj/item/warp_cube, - /obj/machinery/quantumpad + /obj/machinery/quantumpad, + /obj/structure/extraction_point ) if(A) if(is_type_in_list(A, blacklist)) diff --git a/code/modules/spacepods/equipment.dm b/code/modules/spacepods/equipment.dm index e64087d5561..d509b4f745c 100644 --- a/code/modules/spacepods/equipment.dm +++ b/code/modules/spacepods/equipment.dm @@ -131,16 +131,6 @@ fire_delay = 10 fire_sound = 'sound/weapons/kenetic_accel.ogg' -/obj/item/spacepod_equipment/weaponry/mining_laser_hyper - name = "enhanced mining laser system" - desc = "An enhanced mining laser system for space pods, fires bursts of energy that cut through rock." - icon = 'icons/goonstation/pods/ship.dmi' - icon_state = "pod_w_laser" - projectile_type = /obj/item/projectile/kinetic/pod/enhanced - shot_cost = 200 - fire_delay = 8 - fire_sound = 'sound/weapons/kenetic_accel.ogg' - /* /////////////////////////////////////// /////////Misc. System/////////////////// diff --git a/code/modules/surgery/organs/blood.dm b/code/modules/surgery/organs/blood.dm index 78264ca0329..6f1fb8fe293 100644 --- a/code/modules/surgery/organs/blood.dm +++ b/code/modules/surgery/organs/blood.dm @@ -99,11 +99,11 @@ /mob/living/carbon/proc/bleed_internal(amt) // Return 1 if we've coughed blood up, 2 if we're vomited it. if(blood_volume) blood_volume = max(blood_volume - amt, 0) - if (prob(10 * amt)) // +5% chance per internal bleeding site that we'll cough up blood on a given tick. + if(prob(10 * amt)) // +5% chance per internal bleeding site that we'll cough up blood on a given tick. custom_emote(1, "coughs up blood!") add_splatter_floor(loc, 1) return 1 - else if (amt >= 1 && prob(5 * amt)) // +2.5% chance per internal bleeding site that we'll cough up blood on a given tick. Must be bleeding internally in more than one place to have a chance at this. + else if(amt >= 1 && prob(5 * amt)) // +2.5% chance per internal bleeding site that we'll cough up blood on a given tick. Must be bleeding internally in more than one place to have a chance at this. vomit(0, 1) return 2 return 0 @@ -253,7 +253,7 @@ // Only a certain number of drips (or one large splatter) can be on a given turf. var/obj/effect/decal/cleanable/blood/drip/drop = locate() in T if(drop) - if(drop.drips < 3) + if(drop.drips < 5) drop.drips++ drop.overlays |= pick(drop.random_icon_states) drop.transfer_mob_blood_dna(src) @@ -278,7 +278,8 @@ B = locate() in bloods if(!B) B = new(T) - + if(B.bloodiness < MAX_SHOE_BLOODINESS) //add more blood, up to a limit + B.bloodiness += BLOOD_AMOUNT_PER_DECAL B.transfer_mob_blood_dna(src) //give blood info to the blood decal. if(temp_blood_DNA) B.blood_DNA |= temp_blood_DNA diff --git a/code/modules/surgery/organs/organ_icon.dm b/code/modules/surgery/organs/organ_icon.dm index f291f61c96d..ef2f729811c 100644 --- a/code/modules/surgery/organs/organ_icon.dm +++ b/code/modules/surgery/organs/organ_icon.dm @@ -87,67 +87,68 @@ var/global/list/limb_icon_cache = list() else if(s_col) mob_icon.Blend(s_col, ICON_ADD) + if(owner) //Maintains overlays on disembodied parts. + cut_overlays() + dir = EAST icon = mob_icon return mob_icon /obj/item/organ/external/head/get_icon() - ..() - overlays.Cut() if(!owner) return if(dna.species.has_organ["eyes"]) var/icon/eyes_icon = owner.get_eyecon() if(eyes_icon) - mob_icon.Blend(eyes_icon, ICON_OVERLAY) - overlays |= eyes_icon + mob_icon.Blend(eyes_icon, ICON_OVERLAY) //This is required since update_icons.dm relies on this proc to render non-shining eyes. + add_overlay(eyes_icon) if(owner.lip_style && (LIPS in dna.species.species_traits)) - var/icon/lip_icon = new/icon('icons/mob/human_face.dmi', "lips_[owner.lip_style]_s") - overlays |= lip_icon - mob_icon.Blend(lip_icon, ICON_OVERLAY) + add_overlay(mutable_appearance('icons/mob/human_face.dmi', "lips_[owner.lip_style]_s")) //Hefty icon not necessary. var/head_marking = owner.m_styles["head"] - if(head_marking && head_marking != "None") + if(head_marking) var/datum/sprite_accessory/head_marking_style = GLOB.marking_styles_list[head_marking] if(head_marking_style && head_marking_style.species_allowed && (dna.species.name in head_marking_style.species_allowed) && head_marking_style.marking_location == "head") - var/icon/h_marking_s = new/icon("icon" = head_marking_style.icon, "icon_state" = "[head_marking_style.icon_state]_s") + var/icon/h_marking_s = new /icon("icon" = head_marking_style.icon, "icon_state" = "[head_marking_style.icon_state]_s") if(head_marking_style.do_colouration) h_marking_s.Blend(owner.m_colours["head"], ICON_ADD) - overlays |= h_marking_s + add_overlay(h_marking_s) - if(ha_style) - var/datum/sprite_accessory/head_accessory_style = GLOB.head_accessory_styles_list[ha_style] - if(head_accessory_style && head_accessory_style.species_allowed && (dna.species.name in head_accessory_style.species_allowed)) - var/icon/head_accessory_s = new/icon("icon" = head_accessory_style.icon, "icon_state" = "[head_accessory_style.icon_state]_s") - if(head_accessory_style.do_colouration) - head_accessory_s.Blend(headacc_colour, ICON_ADD) - overlays |= head_accessory_s + if(!((owner.head && (owner.head.flags & BLOCKHAIR)) || (owner.wear_mask && (owner.wear_mask.flags & BLOCKHAIR)))) //Common restriction for all the below features. + if(ha_style) + var/datum/sprite_accessory/head_accessory_style = GLOB.head_accessory_styles_list[ha_style] + if(head_accessory_style && head_accessory_style.species_allowed && (dna.species.name in head_accessory_style.species_allowed)) + var/icon/head_accessory_s = new /icon("icon" = head_accessory_style.icon, "icon_state" = "[head_accessory_style.icon_state]_s") + if(head_accessory_style.do_colouration) + head_accessory_s.Blend(headacc_colour, ICON_ADD) + add_overlay(head_accessory_s) - if(f_style) - var/datum/sprite_accessory/facial_hair_style = GLOB.facial_hair_styles_list[f_style] - if(facial_hair_style && ((facial_hair_style.species_allowed && (dna.species.name in facial_hair_style.species_allowed)) || (dna.species.bodyflags & ALL_RPARTS))) - var/icon/facial_s = new/icon("icon" = facial_hair_style.icon, "icon_state" = "[facial_hair_style.icon_state]_s") - if(istype(dna.species, /datum/species/slime)) // I am el worstos - facial_s.Blend("[owner.skin_colour]A0", ICON_AND) //A0 = 160 alpha. - else if(facial_hair_style.do_colouration) - facial_s.Blend(facial_colour, ICON_ADD) - overlays |= facial_s + if(f_style) + var/datum/sprite_accessory/facial_hair_style = GLOB.facial_hair_styles_list[f_style] + if(facial_hair_style && ((facial_hair_style.species_allowed && (dna.species.name in facial_hair_style.species_allowed)) || (dna.species.bodyflags & ALL_RPARTS))) + var/icon/facial_s = new /icon("icon" = facial_hair_style.icon, "icon_state" = "[facial_hair_style.icon_state]_s") + if(istype(dna.species, /datum/species/slime)) // I am el worstos + facial_s.Blend("[owner.skin_colour]A0", ICON_AND) //A0 = 160 alpha. + else if(facial_hair_style.do_colouration) + facial_s.Blend(facial_colour, ICON_ADD) + add_overlay(facial_s) - if(h_style && !(owner.head && (owner.head.flags & BLOCKHEADHAIR))) - var/datum/sprite_accessory/hair_style = GLOB.hair_styles_full_list[h_style] - if(hair_style && ((dna.species.name in hair_style.species_allowed) || (dna.species.bodyflags & ALL_RPARTS))) - var/icon/hair_s = new/icon("icon" = hair_style.icon, "icon_state" = "[hair_style.icon_state]_s") - if(istype(dna.species, /datum/species/slime)) // I am el worstos - hair_s.Blend("[owner.skin_colour]A0", ICON_AND) //A0 = 160 alpha. - else if(hair_style.do_colouration) - hair_s.Blend(hair_colour, ICON_ADD) - overlays |= hair_s + if(h_style) + if(!owner.isSynthetic() || (owner.isSynthetic() && ((owner.head && (owner.head.flags & BLOCKHEADHAIR)) || (owner.wear_mask && (owner.wear_mask.flags & BLOCKHEADHAIR))))) + var/datum/sprite_accessory/hair_style = GLOB.hair_styles_full_list[h_style] + if(hair_style && ((dna.species.name in hair_style.species_allowed) || (dna.species.bodyflags & ALL_RPARTS))) + var/icon/hair_s = new /icon("icon" = hair_style.icon, "icon_state" = "[hair_style.icon_state]_s") + if(istype(dna.species, /datum/species/slime)) // I am el worstos + hair_s.Blend("[owner.skin_colour]A0", ICON_AND) //A0 = 160 alpha. + else if(hair_style.do_colouration) + hair_s.Blend(hair_colour, ICON_ADD) + add_overlay(hair_s) - return mob_icon + return mob_icon //Don't need to blend the above into this as it's handled in human/update_icons(). The overlays are for rendering stuff on disembodied heads. /obj/item/organ/external/proc/get_icon_state(skeletal) var/gender diff --git a/code/modules/surgery/organs/organ_internal.dm b/code/modules/surgery/organs/organ_internal.dm index 6dbc6f4febe..97c54c64e47 100644 --- a/code/modules/surgery/organs/organ_internal.dm +++ b/code/modules/surgery/organs/organ_internal.dm @@ -226,6 +226,8 @@ health = 3 var/organhonked = 0 var/suffering_delay = 900 + var/datum/component/waddle + var/datum/component/squeak /obj/item/organ/internal/honktumor/insert(mob/living/carbon/M, special = 0) ..() @@ -236,6 +238,8 @@ genemutcheck(M,CLUMSYBLOCK,null,MUTCHK_FORCED) genemutcheck(M,COMICBLOCK,null,MUTCHK_FORCED) organhonked = world.time + waddle = M.AddComponent(/datum/component/waddling) + squeak = M.AddComponent(/datum/component/squeak, list('sound/items/bikehorn.ogg' = 1), 50) /obj/item/organ/internal/honktumor/remove(mob/living/carbon/M, special = 0) . = ..() @@ -246,6 +250,8 @@ M.dna.SetSEState(COMICBLOCK,0) genemutcheck(M,CLUMSYBLOCK,null,MUTCHK_FORCED) genemutcheck(M,COMICBLOCK,null,MUTCHK_FORCED) + QDEL_NULL(waddle) + QDEL_NULL(squeak) qdel(src) /obj/item/organ/internal/honktumor/on_life() @@ -282,6 +288,28 @@ owner.nutrition = 9000 owner.overeatduration = 9000 + +/obj/item/organ/internal/honkbladder + name = "honk bladder" + desc = "a air filled sac that produces honking noises." + icon_state = "honktumor"//Not making a new icon + origin_tech = "biotech=1" + w_class = WEIGHT_CLASS_TINY + parent_organ = "groin" + slot = "honk_bladder" + health = 3 + var/datum/component/squeak + +/obj/item/organ/internal/honkbladder/insert(mob/living/carbon/M, special = 0) + + squeak = M.AddComponent(/datum/component/squeak, list('sound/effects/clownstep1.ogg'=1,'sound/effects/clownstep2.ogg'=1), 50) + +/obj/item/organ/internal/honkbladder/remove(mob/living/carbon/M, special = 0) + . = ..() + + QDEL_NULL(squeak) + qdel(src) + /obj/item/organ/internal/beard name = "beard organ" desc = "Let they who is worthy wear the beard of Thorbjorndottir." diff --git a/code/modules/surgery/organs/subtypes/diona.dm b/code/modules/surgery/organs/subtypes/diona.dm index be05b2917c3..0e76c8fe20b 100644 --- a/code/modules/surgery/organs/subtypes/diona.dm +++ b/code/modules/surgery/organs/subtypes/diona.dm @@ -2,7 +2,6 @@ name = "core trunk" max_damage = 200 min_broken_damage = 50 - cannot_break = 1 amputation_point = "trunk" encased = null gendered_icon = 0 @@ -10,7 +9,6 @@ /obj/item/organ/external/groin/diona name = "fork" min_broken_damage = 50 - cannot_break = 1 amputation_point = "lower trunk" gendered_icon = 0 @@ -18,58 +16,49 @@ name = "left upper tendril" max_damage = 35 min_broken_damage = 20 - cannot_break = 1 amputation_point = "upper left trunk" /obj/item/organ/external/arm/right/diona name = "right upper tendril" max_damage = 35 min_broken_damage = 20 - cannot_break = 1 amputation_point = "upper right trunk" /obj/item/organ/external/leg/diona name = "left lower tendril" max_damage = 35 min_broken_damage = 20 - cannot_break = 1 amputation_point = "lower left fork" /obj/item/organ/external/leg/right/diona name = "right lower tendril" max_damage = 35 min_broken_damage = 20 - cannot_break = 1 amputation_point = "lower right fork" /obj/item/organ/external/foot/diona name = "left foot" max_damage = 20 min_broken_damage = 10 - cannot_break = 1 amputation_point = "branch" /obj/item/organ/external/foot/right/diona name = "right foot" max_damage = 20 min_broken_damage = 10 - cannot_break = 1 amputation_point = "branch" /obj/item/organ/external/hand/diona name = "left grasper" - cannot_break = 1 amputation_point = "branch" /obj/item/organ/external/hand/right/diona name = "right grasper" - cannot_break = 1 amputation_point = "branch" /obj/item/organ/external/head/diona max_damage = 50 min_broken_damage = 25 - cannot_break = 1 encased = null amputation_point = "upper trunk" gendered_icon = 0 @@ -82,6 +71,11 @@ icon = 'icons/obj/objects.dmi' icon_state = "nymph" +/obj/item/organ/internal/lungs/diona + name = "respiratory vacuoles" + icon = 'icons/obj/objects.dmi' + icon_state = "nymph" + /obj/item/organ/internal/brain/diona // Turns into a nymph instantly, no transplanting possible. name = "gas bladder" icon = 'icons/obj/objects.dmi' diff --git a/code/modules/surgery/organs/vocal_cords.dm b/code/modules/surgery/organs/vocal_cords.dm index 94f6be4cc9a..9d91682f057 100644 --- a/code/modules/surgery/organs/vocal_cords.dm +++ b/code/modules/surgery/organs/vocal_cords.dm @@ -125,6 +125,9 @@ var/static/regex/multispin_words = regex("like a record baby") return owner.say(".x[command]") +/obj/item/organ/internal/vocal_cords/colossus/prepare_eat() + return + /obj/item/organ/internal/vocal_cords/colossus/can_speak_with() if(world.time < next_command) to_chat(owner, "You must wait [(next_command - world.time)/10] seconds before Speaking again.") diff --git a/code/modules/vehicle/ambulance.dm b/code/modules/vehicle/ambulance.dm index 6b15018de49..ac225003c52 100644 --- a/code/modules/vehicle/ambulance.dm +++ b/code/modules/vehicle/ambulance.dm @@ -102,6 +102,10 @@ anchored = FALSE throw_pressure_limit = INFINITY //Throwing an ambulance trolley can kill the process scheduler. +/obj/structure/bed/amb_trolley/examine(mob/user) + . = ..() + to_chat(user, "Drag [src]'s sprite over the ambulance to (de)attach it.") + /obj/structure/bed/amb_trolley/MouseDrop(obj/over_object as obj) ..() if(istype(over_object, /obj/vehicle/ambulance)) diff --git a/code/modules/vr/vr_outfits.dm b/code/modules/vr/vr_outfits.dm index ce8d52b4880..e61ea829b27 100644 --- a/code/modules/vr/vr_outfits.dm +++ b/code/modules/vr/vr_outfits.dm @@ -1,12 +1,12 @@ //place all the outfits for your levels in here. /datum/outfit/vr/vr_basic - name = "basic vr" + name = "Basic Virtual Reality" uniform = /obj/item/clothing/under/psysuit shoes = /obj/item/clothing/shoes/black /datum/outfit/vr/roman - name = "roman" + name = "Roman" uniform = /obj/item/clothing/under/roman shoes = /obj/item/clothing/shoes/roman l_hand = /obj/item/shield/riot/roman diff --git a/config/example/dbconfig.txt b/config/example/dbconfig.txt index 2404119d52f..ad859d92543 100644 --- a/config/example/dbconfig.txt +++ b/config/example/dbconfig.txt @@ -9,7 +9,7 @@ ## This value must be set to the version of the paradise schema in use. ## If this value does not match, the SQL database will not be loaded and an error will be generated. ## Roundstart will be delayed. -DB_VERSION 8 +DB_VERSION 9 ## Server the MySQL database can be found at. # Examples: localhost, 200.135.5.43, www.mysqldb.com, etc. diff --git a/config/example/lavaRuinBlacklist.txt b/config/example/lavaRuinBlacklist.txt index 934d86514b0..f8fb3fd196a 100644 --- a/config/example/lavaRuinBlacklist.txt +++ b/config/example/lavaRuinBlacklist.txt @@ -5,6 +5,8 @@ ##BIODOMES #_maps/map_files/RandomRuins/LavaRuins/lavaland_biodome_beach.dmm +#_maps/map_files/RandomRuins/LavaRuins/lavaland_biodome_clown_planet.dmm +#_maps/map_files/RandomRuins/LavaRuins/lavaland_biodome_winter.dmm ##RESPAWN #_maps/map_files/RandomRuins/LavaRuins/lavaland_surface_ash_walker1.dmm diff --git a/goon/code/datums/browserOutput.dm b/goon/code/datums/browserOutput.dm index 3456e0a2ce9..3359e7c6232 100644 --- a/goon/code/datums/browserOutput.dm +++ b/goon/code/datums/browserOutput.dm @@ -222,7 +222,7 @@ var/to_chat_filename var/to_chat_line var/to_chat_src // Call using macro: to_chat(target, message, flag) -/proc/__to_chat(target, message, flag) +/proc/to_chat_immediate(target, message, flag) if(!is_valid_tochat_message(message) || !is_valid_tochat_target(target)) target << message @@ -279,3 +279,9 @@ var/to_chat_src output_message += "&[url_encode(flag)]" target << output(output_message, "browseroutput:output") + +/proc/__to_chat(target, message, flag) + if(Master.current_runlevel == RUNLEVEL_INIT || !SSchat?.initialized) + to_chat_immediate(target, message, flag) + return + SSchat.queue(target, message, flag) diff --git a/html/changelog.html b/html/changelog.html index 2aef4e33f8f..270ef03dd3f 100644 --- a/html/changelog.html +++ b/html/changelog.html @@ -56,6 +56,413 @@ -->
      +

      30 August 2019

      +

      AffectedArc07 updated:

      +
        +
      • Fixes the changelog
      • +
      +

      Arkatos updated:

      +
        +
      • Added new icon for Charge spell
      • +
      • Added new icon for No Clothes spell
      • +
      • Added new icon for Wizard spellbook
      • +
      • Added new animations to 10 single-use spellbooks
      • +
      • Added new sprite for Bottle of Tickles
      • +
      • Added refunding functionality to the Bottle of Ooze akin to the other summoning bottles. Click with the bottle in hand on a wizard spellbook to refund its cost and limit slot.
      • +
      • Fixed an issue where Bottle of Tickles did not properly refund
      • +
      • Fixed an issue with alpha layering on Bottle of Ooze sprite
      • +
      • Very slightly adjusted brightness of the Boo! ghost spell icon
      • +
      • Wizard spellbook was completely reorganized, and new appropriate categories were added, each category is sorted by price, and if price of the two or more spells is the same, they are sorted alphabetically
      • +
      • Polymorph can now turn a mob into Syndicate medical or saboteur modules
      • +
      • Mobs made via polymorph into borgs are now unbounded free borgs
      • +
      • Repulse spell cost decreased from 2 to 1
      • +
      • Lighting bolt spell cost decreased from 2 to 1
      • +
      • Slaughter/Laughter demons and Magical Morphs now always have their second fluff objective considered as complete no matter the circumstances
      • +
      • Laughter Demons very slightly buffed, they are still a bit weaker than Slaughter Demons
      • +
      • Improved descriptions and wording regarding Wizard spellbook and Wizard spells
      • +
      • Traitor AI now uses action buttons for its malfunction abilities
      • +
      +

      AzuleUtama updated:

      +
        +
      • Adds false-bottomed briefcase from VG.
      • +
      +

      Couls updated:

      +
        +
      • Rechargers can now be crafted from science using one capacitor and a recharger board tweak:Smaller machines like microwaves and cell chargers can now be placed on tables(Fax machines included) tweak:can screwdriver open rechargers and then apply a crowbar to deconstruct them
      • +
      • Blood spread now depends on volume of the blood, requires more drips of blood to create a pool
      • +
      • DUAL WIELDING
      • +
      • new chatsubsystem from TG!
      • +
      • Update issue templates to latest version and clean up the current template
      • +
      • mining shuttle warning message and delay before launching
      • +
      • cardboard boxes are no longer sonic speed
      • +
      • shuttle timers now get set properly
      • +
      +

      EmanTheAlmighty updated:

      +
        +
      • Blobbernauts can now be controlled by players through a prompt which appears when they are spawned by blobs.
      • +
      • Blobbernauts and blobs can now communicate with each other.
      • +
      • Blobbernauts now regenerate health overtime when standing on blob structures.
      • +
      • Blobbernauts will slowly lose health if they are not standing on blob structures while not at full health. balance: Blobbernauts have been nerfed, they now have less health, deal less damage and cannot break walls anymore. balance: Blob's "Produce Blobbernaut" ability has been made more expensive to use, now costing 60 resources instead of 20.
      • +
      +

      Emanthealmighty updated:

      +
        +
      • The poll to play as a blobbernaut now lasts 10 seconds from 15.
      • +
      • Blobbernauts no longer chase after people while players are being polled to play as one.
      • +
      +

      Fox McCloud updated:

      +
        +
      • Plasmamen dramatically overhauled.
      • +
      • Plasmamen can be cloned without burning to death in the clonepod
      • +
      • Plasmamen no longer start with spacesuits
      • +
      • Plasmamen start off with jumpsuits that seal to protect against oxygen. This allows for you to customize their appearance more
      • +
      • Plasmamen helmets now allow you to see a Plasmaman's actual face; should be able to see their eye color and mouth color now
      • +
      • Plasmamen take 50% extra brute and burn
      • +
      • Plasmamen are immune to radiation
      • +
      • Plasmamen start out with a small tank that can fit on a belt or in a pocket; it should be enough to last an entire shift
      • +
      • Plasmaman helmets now have built in welding goggles
      • +
      • Plasmaman karma cost lowered from 100 to 45
      • +
      • Reworks Diona
      • +
      • Diona bleed (call it chlorophy; it's green)
      • +
      • Diona Breathe (plants do need to exchange gas after all)
      • +
      • Rad Immunity Removed
      • +
      • Diona regenerate 1 OXY, 1 BURN, 1 BRUTE, and 1 TOX if they are in a bright area; this effect does not kick in if they're in crit
      • +
      • Diona no longer have unbreakable bones (wood can crack ya know!)
      • +
      • Diona are no longer space proof
      • +
      • Diona are more vulnerable to fire and heat damage
      • +
      • Diona weakness to weedkiller dramatically nerfed
      • +
      • Diona now use Newcrit
      • +
      • Diona are no longer slow
      • +
      • Diona can wear spacesuits
      • +
      • Fixes stun absorbing not working
      • +
      • Fixes parallax insane setting not doing anything
      • +
      • Ores can be destroyed by devastating explosions
      • +
      • silver, gold, and diamond pickaxes do a bit more damage and mine faster than before
      • +
      • drills slightly slower, but diamond drills slightly faster
      • +
      • Spade is the same speed as a shovel
      • +
      • Hivelord stabilizer will now make a hivelord core/legion soul stabilize and be preserved, even if it was previously inert
      • +
      • can use a hivelord core in your active hand to apply it to yourself
      • +
      • soulstone in the abandoned locked crates can now be used by anyone
      • +
      • Adds firelemon seeds to the abandoned locked crates as potential loot
      • +
      • Hardsuits have an integrated helmet; you no longer have to attach helmets
      • +
      • Toggling up/down helmets is now done with an action button
      • +
      • can no longer attach magboots to a hardsuit
      • +
      • Hardsuit base melee armor increased from 10 to 30
      • +
      • Security and HoS hardsuit melee armor increased by 5
      • +
      • HoS hardsuit helmet armor matches his hardsuit
      • +
      • CE's hardsuit helmet armor for rads increased by 10 (should be fully rad proof now)
      • +
      • Elite syndicate suits can't be acided
      • +
      • Fixes stuns and weakens related to reagents
      • +
      • Fixes the displayed cost of Plasmamen
      • +
      • Adds jetpack hardsuit upgrades: get yours at mining for 2000 points
      • +
      • Removes mining carbon dioxide jetpack
      • +
      • Can no longer use jetpacks in your suit storage slot
      • +
      • Chief Engineer's hardsuit, Syndicate Hardsuit (normal and elite), and Shielded Syndicate Hardsuit all have built in jetpacks
      • +
      • Fixes random singularity releases from the grid check event
      • +
      • loadout costs for most things cut from 2 to 1
      • +
      • Adds fingerless gloves, eyepatch, prescription glasses, black shoes, brown shoes, white shoes, and ian's shirt to the loadout
      • +
      • moved hipster glasses from donator to general glasses
      • +
      • Adds in sandbags. Use them to deploy destructable barriers; miners start off with a few
      • +
      • Removes access based security barriers
      • +
      • Adds in security barrier grenade. When it goes off, it will deploy up to 3 barriers that will lock into place; should find 4 of these in the armory
      • +
      • can tear up bedsheet and gauze to get cloth--requires a sharp object
      • +
      • Fixes plasmamen atmos techs not getting their proper suit
      • +
      • Adds in a loom, craft one out of 10 wood
      • +
      • Adds in cotton and durathread cotton to botany to grow
      • +
      • Adds in a number of expanded items to create out of cloth, such as improvised gauze, beanies, and softcaps
      • +
      • Adds the ability to use personal crafting to make durathread jumpsuits, bandanas, armor, helmets, beanies and berets. Aside from the bandana, these all have minor armor on them
      • +
      • Adds a number of new items to personally craft, related to clothing: ability to make health, sec, diagnotic, and reagent sunglasses.
      • +
      • Can additionally craft cowboy boots, lizardskin cowboy boots, fannypacks, and a spooky ghost disguise
      • +
      • adds a whole range of beanies, find them in the clothing vendor or make them yourself
      • +
      • Updates the cowboy boots sprites
      • +
      • Unironically fixes about several thousand runtimes
      • +
      • Fixes jackets not keeping you warm
      • +
      • Chefs are now trained in the art of Close Quarters Cooking
      • +
      • Adds the Book of Babel as tendril loot
      • +
      • Adds Jacbo's Ladder as tendril loot
      • +
      • Fixes fungus, blood, and graffiti not showing up on a wall
      • +
      • Fixes the lavaland inquisitor and berserker hardsuits having incorrect armor and slowdown values
      • +
      • Fixes baseball bats throwing anchored things
      • +
      • Fixes blood drunk buff
      • +
      • Fixes using a crusher on a trophy to equip it causing you to drop the crusher
      • +
      • refactors lazarus capsules; no real behavioral change
      • +
      • Fixes being able to revive megafauna with strange reagent
      • +
      +

      Fox McCloud and FullOfSkittles updated:

      +
        +
      • Tweaks the gummy worm, gummy bear, jeallybean, toffee, and bacon sprites
      • +
      • Fixes telebacon not properly acting as...well, a bacon beacon
      • +
      +

      FreeStylaLT updated:

      +
        +
      • Added an Engine Picker, which uses new engine beacons.
      • +
      • Replaced the current two engine generators with one engine beacon.
      • +
      +

      Ionward updated:

      +
        +
      • Drask crewmembers now have properly fitting shoes.
      • +
      • Fixed some minor issues in Drasks uniforms
      • +
      • non-humans now have proper sprites for durathread goods
      • +
      +

      KasparoVy updated:

      +
        +
      • Adds sprites for all Vox & Armalis earwear.
      • +
      • Adds sprites for Armalis default backpack, nitrogen tank (old-style back & new-style belt) & all breath mask variations.
      • +
      • You can now species-fit in-hand icons: Use a single .dmi file and suffix the icon states with _l or _r.
      • +
      • Fixes an issue preventing Vox Armalis from being rendered with the proper in-hand icons for their massive noise cannons.
      • +
      • Fixes an issue preventing the species-fitting of earwear.
      • +
      • Fixes an issue preventing Vox Armalis from wearing the 'Vox' breath mask.
      • +
      • Picking up uniforms no longer renders a default grey jumpsuit on Vox.
      • +
      • Resolves an issue causing shining eyes to be rendered darker than intended.
      • +
      • Resolves an issue preventing appearance features (hair, eyes, etc.) from rendering on disembodied heads.
      • +
      • Resolves an issue preventing Admin-revived decapitated bodies from having appearance features or ears.
      • +
      • Non-shining eyes render the proper colour again.
      • +
      +

      Kurgis updated:

      +
        +
      • Beepsky now bumps around on its wheels when patrolling for crime.
      • +
      +

      Markolie updated:

      +
        +
      • A new outfit manager has been added for admins (under debug). It lets them save and load custom outfits on their computer and use these to equip players.
      • +
      • Upon transforming players into humans or reincarnating them through the player panel, admins will now directly be able to select their equipment.
      • +
      • The select equipment verb now works on observers: it'll create a human with the given equipment under the ghost.
      • +
      • A "Copy Outfit" button has been added to the View Variables dropdown, which lets admins instantly copy an outfit.
      • +
      • Outfits now support accessories and internal boxes.
      • +
      • The separate option to equip ERT members has been removed. It's been integrated into their regular outfits.
      • +
      • Water coming from sinks and certain water effects is now 10C instead of body temperature.
      • +
      +

      Shadow-Quill updated:

      +
        +
      • [Meta] Added buckshot and slugs to armoury.
      • +
      • [Meta] Added surgical tools, robotic first aid kits, and a photocopier to Robotics.
      • +
      • [Meta] R&D doors now has proper access requirements.
      • +
      • [Meta] Added RCS and telepad to cargo.
      • +
      • [Meta] Disposals sheet stacker and conveyor belts now works properly.
      • +
      • [Meta] One-way airlocks added in Medbay/Brig.
      • +
      • [Meta] Disposals sheet stacker disposals chute leads directly to the mailroom.
      • +
      • AIs not being able to restore their own power if in an area with an APC.
      • +
      • Fixed being able to talk in OOC under certain circumstances if it's disabled.
      • +
      • Lockers can no longer move around anchored mobs.
      • +
      +

      SteelSlayer updated:

      +
        +
      • You can no longer spam dismantle a SMES terminal and get 10 cable for every progress bar
      • +
      • The game will properly remove 10 cable from your stack after building a SMES terminal, instead of removing 0
      • +
      • A cable adding sound gets played when you add wires to create a terminal for a SMES
      • +
      • Rapid pipe dispensers can now place disposal sorting pipes
      • +
      • When changing the sort location of a disposal sorting pipe, the name of the pipe now also changes to the desired destination
      • +
      • Added a destination tagger to the atmosheric technician locker
      • +
      • Added atmospherics access to Engi-Vend's and Engineering checkpoint airlocks
      • +
      • Removed some random grey pixels from disposal sorting junction pipe sprites, and certain normal disposal junction pipe sprites
      • +
      • IV bags are able to transfer their contents to other containers by clicking on them with the bag
      • +
      • Adds a handheld defibrillator to the paramedic EVA closet
      • +
      • You can insert magazines into L6 SAWs again
      • +
      • Removed one of the high capacity tanks in hydroponics
      • +
      • Added a disk compartmentalizer to hydroponics
      • +
      • Delaying round start actually delays round start again
      • +
      +

      Terilia updated:

      +
        +
      • added headcrabs
      • +
      • adjusted the path's for headslugs. They are not called headcrab anymore
      • +
      +

      TheSardele updated:

      +
        +
      • Removes the ability of obese people and those with matter eater to swallow others.
      • +
      +

      Ty-Omaha updated:

      +
        +
      • Fixed a bug where hotwiring solar panels would allow for the station to remain powered in the Grid Check power failure event.
      • +
      +

      datlo updated:

      +
        +
      • Added ashstorm immunity to titanium and plastitanium golems.
      • +
      • Added lava immunity to plastitanium golems.
      • +
      • Bananium golems now slowly waddle around.
      • +
      • Uranium golems now properly irradiate nearby mobs that arent rad immune.
      • +
      • Tranquillite golems now properly get their miming powers.
      • +
      • Added the Clown and Winter biodomes as possible lavaland ruins.
      • +
      • Update a changeling error message to be clearer.
      • +
      +

      farie82 updated:

      +
        +
      • Items with NODROP that are dropped now lose the flag if they didn't get created with it
      • +
      • Adds tip text to the examine text of the ambulance trolley about how to attach it
      • +
      • Adds tip text to the nuke when trying to use the NAD before deploying it
      • +
      • Adds tip text to the fire axe cabinet about how to lock/unlock it
      • +
      • Adds tip text to airlocks if they have a note on them about how to remove the note
      • +
      • Can't put the NAD in the nuke now when it has the NODROP flag
      • +
      • Locking a fire axe cabinet is less weird now. No odd 5 seconds sleep
      • +
      • Can't put a nodrop fire axe in fire axe cabinets now. Duping them
      • +
      • Implants like the IPC charging work again. They won't get deleted after first use
      • +
      +

      variableundefined updated:

      +
        +
      • A proc's name got changed. That's it
      • +
      + +

      23 August 2019

      +

      AffectedArc07, Keekenox, Floyd/Qustinnus updated:

      +
        +
      • P A R A L L A X (That fancy space thing)
      • +
      • Adds a new Parallax layer that resembles Lavaland (Lava Planet), it spawns on a random location near the station. You need your parallax on high to see it.
      • +
      +

      Arkatos updated:

      +
        +
      • Added colored pillbottles
      • +
      • Added an option to change color of the pillbottles to ChemMaster3000
      • +
      • Added new description to patch packs
      • +
      • Jump to Node ability now shows a location of each Blob node
      • +
      • Added SlimeHUD when playing as a slime. This means slimes will have their own unique health doll and pull icon.
      • +
      • Action buttons can now be dragged onto each other to swap places
      • +
      • Fixed a case where dragging locked action buttons could result in white tooltip over the screen
      • +
      +

      AzuleUtama updated:

      +
        +
      • The Traitor thermal glasses and chameleon security HUD now use the updated chameleon code. balance: Traitor thermal glasses will no longer cause eye damage when hit with EMP.
      • +
      +

      Citinited updated:

      +
        +
      • Removes the big pipe dispensers from atmospherics, you can still find them elsewhere.
      • +
      +

      Couls updated:

      +
        +
      • After many complaints about being stuck in medbay. NT has modified all the airlocks on the station to allow leaving certain departments without requiring an respective ID. This new modification is indicated by a white light near the airlocks in the direction of unrestricted access.
      • +
      • New unrestricted access can be built by NT engineers through modification of the airlock electronics.
      • +
      • hit effects!
      • +
      • hit effect sprites for lasers, bullet hole and dent decals for walls
      • +
      • mice now have a very low chance of chewing through wires, this kills them if the wire is powered
      • +
      • You can now homerun things thrown at you with a baseball bat!
      • +
      • new baseball hit noise, new baseball sprite
      • +
      • there are much less one-way airlocks on station
      • +
      +

      DoctorDrugs updated:

      +
        +
      • removed the ability to eat the divine vocal cords
      • +
      +

      EmanTheAlmighty updated:

      +
        +
      • The AI can now change its intent by clicking on the new on-screen button or pressing 4 to switch to help or harm.
      • +
      • The AI can now toggle airlock safeties instead of toggling door bolt lights by pressing middle mouse.
      • +
      +

      Fox McCloud updated:

      +
        +
      • Majorly updates lavaland
      • +
      • Miner starting equipment altered. They now start with a kinetic accelerator
      • +
      • Miners start off with a mini pickaxe
      • +
      • Adds in the boxed implant kit, regular shelter capsule, and mining drone passthrough upgrade to the mining equipment vendor
      • +
      • re-ordered the equipment vendor, so things are grouped together more logically
      • +
      • Added a number of new kinetic accelerator upgrades acquirable through tendril chests
      • +
      • Mining bot now uses an actual kinetic accelerator as opposed to a "Look alike"; you can upgrade its internal gun with various kinetic accelerator modkits.
      • +
      • Sentient mining bot nerfed; you can no longer apply the armor or melee buff to them; offset by the fact you can upgrade their kinetic gun.
      • +
      • Indoor pressure mod removed from R&D and made into a miner traitor item
      • +
      • Resonators have an increased amount of fields and do more damage in low pressure. Additionally, if you place a field on a tile that already has a field, it'll cause it to detonate early
      • +
      • Plasmacutter no longer does increased damage in low pressure, Advanced plasma cutter does slightly more base damage but has a bit less range. Price has been cut at R&D
      • +
      • removed the AoE Mob+Turf upgrade for mining pods
      • +
      • Fixes ripleys being slow on lavaland
      • +
      • Fixes walking on lavaland sounding like walking on metal plating
      • +
      • Adds in kinetic crusher trophies
      • +
      • Kinetic crusher can be wielded/unwielded (but you can't attack with it unwielded)
      • +
      • Adds the HECK suit as Bubblegum loot
      • +
      • Adds the kinetic accelerator bounty mod as Tendril loot
      • +
      • Add fulton extract packs to the mining vendor; rescue precious valuable or dead miners!
      • +
      • Adds mini-fans to the mining, engineering, and security shuttles
      • +
      • Adds a number of primal recipes: rake (cultivator), wooden bucket, firebrand (long burning match), and bone bracers (armored arm protection that goes on your glove slot)
      • +
      • Can attach bayonets to C20rs, bolt action rifles, security auto-rifles, and kinetic accelerator; harm intent to stab with them
      • +
      • can craft ore boxes out of wood
      • +
      • Skull helmets are now proper helmets
      • +
      • Survival autoinjectors tweaked
      • +
      • Survival autoinjectors have 15 units of teporone in them
      • +
      • Survival autoinjectors have double the epinpehrine and weak omnizine instead of saline glucose.
      • +
      • lavaland extract altered; it no longer heals tox or oxy, and heals slightly less brute and burn, but has nearly halved the metabolization rate and has a less harsh overdose
      • +
      • Fixes airlocks spamming their open and close when you stand in them
      • +
      • Fixes overriden door timers not working
      • +
      +

      Fox McCloud and FullofSkittles updated:

      +
        +
      • Changes the Venus Human Flytrap sprite
      • +
      +

      Ionward updated:

      +
        +
      • Adjusted Greys uniforms and backpack sprites.
      • +
      • Added a bunch of Drask masks and glasses.
      • +
      • Added God Eye sprites for Greys, Drask, and Vox.
      • +
      +

      JKnutson101 updated:

      +
        +
      • Issue where Emergency NanoMed Vendors required Medical ID to Access.
      • +
      • Added the ability for cyborgs with zero battery to use the 'succumb' verb.
      • +
      +

      Markolie updated:

      +
        +
      • Players now have thirty seconds instead of just five seconds to select if they want to be somebody's butler through a die of fate roll.
      • +
      • The Netherworld portal is now properly destroyed upon being killed. In addition, its max health is now equal to its starting health.
      • +
      • The iron ore sprite that shows up when using the miner scanner no longer has a background, making it blend in better with the actual rock.
      • +
      • Tightening the bolts of a falsewall now works properly.
      • +
      • Deconstructing plating now requires it to be unfastened using a screwdriver first, in order to prevent it from being accidentally deconstructed with a welder.
      • +
      +

      Quantum-M updated:

      +
        +
      • Minor grammar edits to the text that tells you that your thirst is dealt with but no blood power is given. balance: Vampires are no longer able to drink get power from ckeyless humanoid monkeys, they will now need to hunt down actual characters with ckey to get power.
      • +
      +

      Shadow-Quill updated:

      +
        +
      • Mass drivers now need two rods/cable coil instead of three to construct.
      • +
      • The RD's office door can now be opened by the RD, instead of by just the Captain.
      • +
      • Science lockdown can now only be (de)activated by the RD, instead of any scientist.
      • +
      • Using a health analyzer in-hand will switch the verbosity.
      • +
      • You no longer have to unscrew a plating to repair it.
      • +
      • The shivering symptom in virology now properly chills people.
      • +
      +

      SteelSlayer updated:

      +
        +
      • Wizard rounds now end if all wizards and apprentices are either dead, inside cyborgs, or in MMIs
      • +
      • Re-enabled the wizard's hud. Wizards can now see their own antag icon along with seeing other wizard's and apprentice's icons
      • +
      • When a cult sacrifice target leaves the round via cryo, the game will reassign a new target for them
      • +
      • Added an alarm sound that plays for cultists when their sacrifice target leave the round via cryo
      • +
      • When a cult sacrifice target leaves the round via cryo, the game will update every cultist's notes to reflect the change
      • +
      • Adds a new verb named "Toggle Health Scan" to the ghost tab. While toggled on, ghosts can perform health scans on humanoids and cyborgs by left clicking on them
      • +
      +

      TDSSS updated:

      +
        +
      • syndicate fax machine to lavaland syndie base.
      • +
      • syndicate lavaland base self destruct now requires syndie access.
      • +
      • moved headsets in lavaland syndie base.
      • +
      • Gave the HoP fax long-ranged faxing capabilities.
      • +
      • midround event spawned xeno larva now need less time to grow up and evolve.
      • +
      • cult talisman got unique icons to tell them apart
      • +
      • mining hardsuits come with helmets now again
      • +
      +

      Tayyyyyyy updated:

      +
        +
      • Whether you join the ERT is no longer determined by how fast you click "yes" on the prompt.
      • +
      • Drag and drop support and 20 seconds to pick ERT role instead of 15
      • +
      • Fix extra newline after field and disable Github Flavored Markdown in papers (normal markdown still works)
      • +
      • autogenerated papers no longer appear as HTML code
      • +
      • message window links added to PM send receipt
      • +
      • Many shuttle flight directions fixed
      • +
      +

      TheSardele updated:

      +
        +
      • All-In-one Grinders can now be constructed and upgraded
      • +
      • All-In-one Grinders now produce more reagents when upgraded.
      • +
      • Icon for cybernetic eyes
      • +
      • Sleeping while drunk no longer makes you more drunk.
      • +
      +

      dovydas12345 updated:

      +
        +
      • Fixes being able to pick up chairs and stools when you have items in both hand or when you don't have hands.
      • +
      • Adds a ERT shuttle console which is accessible to ERT members
      • +
      +

      farie82 updated:

      +
        +
      • Rigging a crate now doesn't delete your coil stack anymore but instead uses 15 of it. Borgs can use it safely again
      • +
      +

      kazboo updated:

      +
        +
      • adjusts the hierophant blast layer to make for it to always be below the effect. this should be the case already due to mouse_opacity, though for some unknown reason, it just doesn't work sometimes, so this should fix it.
      • +
      +

      12 August 2019

      AffectedArc07 updated:

        diff --git a/html/changelogs/.all_changelog.yml b/html/changelogs/.all_changelog.yml index ef20fb58092..d03050e2258 100644 --- a/html/changelogs/.all_changelog.yml +++ b/html/changelogs/.all_changelog.yml @@ -10648,3 +10648,437 @@ DO NOT EDIT THIS FILE BY HAND! AUTOMATICALLY GENERATED BY ss13_genchangelog.py. kazboo: - tweak: changed the display name shown to a player upon being frozen in a manner that only the admins ckey is displayed, not the character name along with it +2019-08-23: + AffectedArc07, Keekenox, Floyd/Qustinnus: + - rscadd: P A R A L L A X (That fancy space thing) + - imageadd: Adds a new Parallax layer that resembles Lavaland (Lava Planet), it + spawns on a random location near the station. You need your parallax on high + to see it. + Arkatos: + - imageadd: Added colored pillbottles + - rscadd: Added an option to change color of the pillbottles to ChemMaster3000 + - rscadd: Added new description to patch packs + - tweak: Jump to Node ability now shows a location of each Blob node + - rscadd: Added SlimeHUD when playing as a slime. This means slimes will have their + own unique health doll and pull icon. + - rscadd: Action buttons can now be dragged onto each other to swap places + - bugfix: Fixed a case where dragging locked action buttons could result in white + tooltip over the screen + AzuleUtama: + - tweak: 'The Traitor thermal glasses and chameleon security HUD now use the updated + chameleon code. balance: Traitor thermal glasses will no longer cause eye damage + when hit with EMP.' + Citinited: + - rscdel: Removes the big pipe dispensers from atmospherics, you can still find + them elsewhere. + Couls: + - rscadd: After many complaints about being stuck in medbay. NT has modified all + the airlocks on the station to allow leaving certain departments without requiring + an respective ID. This new modification is indicated by a white light near the + airlocks in the direction of unrestricted access. + - rscadd: New unrestricted access can be built by NT engineers through modification + of the airlock electronics. + - rscadd: hit effects! + - imageadd: hit effect sprites for lasers, bullet hole and dent decals for walls + - tweak: mice now have a very low chance of chewing through wires, this kills them + if the wire is powered + - rscadd: You can now homerun things thrown at you with a baseball bat! + - tweak: new baseball hit noise, new baseball sprite + - tweak: there are much less one-way airlocks on station + DoctorDrugs: + - tweak: removed the ability to eat the divine vocal cords + EmanTheAlmighty: + - rscadd: The AI can now change its intent by clicking on the new on-screen button + or pressing 4 to switch to help or harm. + - tweak: The AI can now toggle airlock safeties instead of toggling door bolt lights + by pressing middle mouse. + Fox McCloud: + - rscadd: Majorly updates lavaland + - rscadd: Miner starting equipment altered. They now start with a kinetic accelerator + - rscadd: Miners start off with a mini pickaxe + - rscadd: Adds in the boxed implant kit, regular shelter capsule, and mining drone + passthrough upgrade to the mining equipment vendor + - tweak: re-ordered the equipment vendor, so things are grouped together more logically + - rscadd: Added a number of new kinetic accelerator upgrades acquirable through + tendril chests + - tweak: Mining bot now uses an actual kinetic accelerator as opposed to a "Look + alike"; you can upgrade its internal gun with various kinetic accelerator modkits. + - tweak: Sentient mining bot nerfed; you can no longer apply the armor or melee + buff to them; offset by the fact you can upgrade their kinetic gun. + - tweak: Indoor pressure mod removed from R&D and made into a miner traitor item + - tweak: Resonators have an increased amount of fields and do more damage in low + pressure. Additionally, if you place a field on a tile that already has a field, + it'll cause it to detonate early + - tweak: Plasmacutter no longer does increased damage in low pressure, Advanced + plasma cutter does slightly more base damage but has a bit less range. Price + has been cut at R&D + - rscdel: removed the AoE Mob+Turf upgrade for mining pods + - bugfix: Fixes ripleys being slow on lavaland + - bugfix: Fixes walking on lavaland sounding like walking on metal plating + - rscadd: Adds in kinetic crusher trophies + - tweak: Kinetic crusher can be wielded/unwielded (but you can't attack with it + unwielded) + - rscadd: Adds the HECK suit as Bubblegum loot + - rscadd: Adds the kinetic accelerator bounty mod as Tendril loot + - rscadd: Add fulton extract packs to the mining vendor; rescue precious valuable + or dead miners! + - tweak: Adds mini-fans to the mining, engineering, and security shuttles + - rscadd: 'Adds a number of primal recipes: rake (cultivator), wooden bucket, firebrand + (long burning match), and bone bracers (armored arm protection that goes on + your glove slot)' + - rscadd: Can attach bayonets to C20rs, bolt action rifles, security auto-rifles, + and kinetic accelerator; harm intent to stab with them + - rscadd: can craft ore boxes out of wood + - bugfix: Skull helmets are now proper helmets + - tweak: Survival autoinjectors tweaked + - rscadd: Survival autoinjectors have 15 units of teporone in them + - tweak: Survival autoinjectors have double the epinpehrine and weak omnizine instead + of saline glucose. + - tweak: lavaland extract altered; it no longer heals tox or oxy, and heals slightly + less brute and burn, but has nearly halved the metabolization rate and has a + less harsh overdose + - bugfix: Fixes airlocks spamming their open and close when you stand in them + - bugfix: Fixes overriden door timers not working + Fox McCloud and FullofSkittles: + - rscadd: Changes the Venus Human Flytrap sprite + Ionward: + - imageadd: Adjusted Greys uniforms and backpack sprites. + - imageadd: Added a bunch of Drask masks and glasses. + - imageadd: Added God Eye sprites for Greys, Drask, and Vox. + JKnutson101: + - bugfix: Issue where Emergency NanoMed Vendors required Medical ID to Access. + - rscadd: Added the ability for cyborgs with zero battery to use the 'succumb' verb. + Markolie: + - tweak: Players now have thirty seconds instead of just five seconds to select + if they want to be somebody's butler through a die of fate roll. + - bugfix: The Netherworld portal is now properly destroyed upon being killed. In + addition, its max health is now equal to its starting health. + - tweak: The iron ore sprite that shows up when using the miner scanner no longer + has a background, making it blend in better with the actual rock. + - bugfix: Tightening the bolts of a falsewall now works properly. + - tweak: Deconstructing plating now requires it to be unfastened using a screwdriver + first, in order to prevent it from being accidentally deconstructed with a welder. + Quantum-M: + - tweak: 'Minor grammar edits to the text that tells you that your thirst is dealt + with but no blood power is given. balance: Vampires are no longer able to drink + get power from ckeyless humanoid monkeys, they will now need to hunt down actual + characters with ckey to get power.' + Shadow-Quill: + - tweak: Mass drivers now need two rods/cable coil instead of three to construct. + - bugfix: The RD's office door can now be opened by the RD, instead of by just the + Captain. + - tweak: Science lockdown can now only be (de)activated by the RD, instead of any + scientist. + - tweak: Using a health analyzer in-hand will switch the verbosity. + - bugfix: You no longer have to unscrew a plating to repair it. + - bugfix: The shivering symptom in virology now properly chills people. + SteelSlayer: + - bugfix: Wizard rounds now end if all wizards and apprentices are either dead, + inside cyborgs, or in MMIs + - tweak: Re-enabled the wizard's hud. Wizards can now see their own antag icon along + with seeing other wizard's and apprentice's icons + - bugfix: When a cult sacrifice target leaves the round via cryo, the game will + reassign a new target for them + - rscadd: Added an alarm sound that plays for cultists when their sacrifice target + leave the round via cryo + - rscadd: When a cult sacrifice target leaves the round via cryo, the game will + update every cultist's notes to reflect the change + - rscadd: Adds a new verb named "Toggle Health Scan" to the ghost tab. While toggled + on, ghosts can perform health scans on humanoids and cyborgs by left clicking + on them + TDSSS: + - rscadd: syndicate fax machine to lavaland syndie base. + - tweak: syndicate lavaland base self destruct now requires syndie access. + - tweak: moved headsets in lavaland syndie base. + - tweak: Gave the HoP fax long-ranged faxing capabilities. + - tweak: midround event spawned xeno larva now need less time to grow up and evolve. + - tweak: cult talisman got unique icons to tell them apart + - bugfix: mining hardsuits come with helmets now again + Tayyyyyyy: + - tweak: Whether you join the ERT is no longer determined by how fast you click + "yes" on the prompt. + - tweak: Drag and drop support and 20 seconds to pick ERT role instead of 15 + - bugfix: Fix extra newline after field and disable Github Flavored Markdown in + papers (normal markdown still works) + - bugfix: autogenerated papers no longer appear as HTML code + - tweak: message window links added to PM send receipt + - bugfix: Many shuttle flight directions fixed + TheSardele: + - rscadd: All-In-one Grinders can now be constructed and upgraded + - rscadd: All-In-one Grinders now produce more reagents when upgraded. + - rscadd: Icon for cybernetic eyes + - bugfix: Sleeping while drunk no longer makes you more drunk. + dovydas12345: + - bugfix: Fixes being able to pick up chairs and stools when you have items in both + hand or when you don't have hands. + - rscadd: Adds a ERT shuttle console which is accessible to ERT members + farie82: + - bugfix: Rigging a crate now doesn't delete your coil stack anymore but instead + uses 15 of it. Borgs can use it safely again + kazboo: + - bugfix: adjusts the hierophant blast layer to make for it to always be below the + effect. this should be the case already due to mouse_opacity, though for some + unknown reason, it just doesn't work sometimes, so this should fix it. +2019-08-30: + AffectedArc07: + - bugfix: Fixes the changelog + Arkatos: + - imageadd: Added new icon for Charge spell + - imageadd: Added new icon for No Clothes spell + - imageadd: Added new icon for Wizard spellbook + - imageadd: Added new animations to 10 single-use spellbooks + - imageadd: Added new sprite for Bottle of Tickles + - rscadd: Added refunding functionality to the Bottle of Ooze akin to the other + summoning bottles. Click with the bottle in hand on a wizard spellbook to refund + its cost and limit slot. + - bugfix: Fixed an issue where Bottle of Tickles did not properly refund + - bugfix: Fixed an issue with alpha layering on Bottle of Ooze sprite + - tweak: Very slightly adjusted brightness of the Boo! ghost spell icon + - tweak: Wizard spellbook was completely reorganized, and new appropriate categories + were added, each category is sorted by price, and if price of the two or more + spells is the same, they are sorted alphabetically + - tweak: Polymorph can now turn a mob into Syndicate medical or saboteur modules + - tweak: Mobs made via polymorph into borgs are now unbounded free borgs + - tweak: Repulse spell cost decreased from 2 to 1 + - tweak: Lighting bolt spell cost decreased from 2 to 1 + - tweak: Slaughter/Laughter demons and Magical Morphs now always have their second + fluff objective considered as complete no matter the circumstances + - tweak: Laughter Demons very slightly buffed, they are still a bit weaker than + Slaughter Demons + - spellcheck: Improved descriptions and wording regarding Wizard spellbook and Wizard + spells + - rscadd: Traitor AI now uses action buttons for its malfunction abilities + AzuleUtama: + - rscadd: Adds false-bottomed briefcase from VG. + Couls: + - rscadd: Rechargers can now be crafted from science using one capacitor and a recharger + board tweak:Smaller machines like microwaves and cell chargers can now be placed + on tables(Fax machines included) tweak:can screwdriver open rechargers and then + apply a crowbar to deconstruct them + - tweak: Blood spread now depends on volume of the blood, requires more drips of + blood to create a pool + - rscadd: DUAL WIELDING + - rscadd: new chatsubsystem from TG! + - tweak: Update issue templates to latest version and clean up the current template + - rscadd: mining shuttle warning message and delay before launching + - bugfix: cardboard boxes are no longer sonic speed + - bugfix: shuttle timers now get set properly + EmanTheAlmighty: + - rscadd: Blobbernauts can now be controlled by players through a prompt which appears + when they are spawned by blobs. + - rscadd: Blobbernauts and blobs can now communicate with each other. + - rscadd: Blobbernauts now regenerate health overtime when standing on blob structures. + - rscadd: 'Blobbernauts will slowly lose health if they are not standing on blob + structures while not at full health. balance: Blobbernauts have been nerfed, + they now have less health, deal less damage and cannot break walls anymore. + balance: Blob''s "Produce Blobbernaut" ability has been made more expensive + to use, now costing 60 resources instead of 20.' + Emanthealmighty: + - tweak: The poll to play as a blobbernaut now lasts 10 seconds from 15. + - tweak: Blobbernauts no longer chase after people while players are being polled + to play as one. + Fox McCloud: + - tweak: Plasmamen dramatically overhauled. + - rscadd: Plasmamen can be cloned without burning to death in the clonepod + - rscdel: Plasmamen no longer start with spacesuits + - rscadd: Plasmamen start off with jumpsuits that seal to protect against oxygen. + This allows for you to customize their appearance more + - tweak: Plasmamen helmets now allow you to see a Plasmaman's actual face; should + be able to see their eye color and mouth color now + - tweak: Plasmamen take 50% extra brute and burn + - rscadd: Plasmamen are immune to radiation + - tweak: Plasmamen start out with a small tank that can fit on a belt or in a pocket; + it should be enough to last an entire shift + - rscadd: Plasmaman helmets now have built in welding goggles + - tweak: Plasmaman karma cost lowered from 100 to 45 + - tweak: Reworks Diona + - rscadd: Diona bleed (call it chlorophy; it's green) + - rscadd: Diona Breathe (plants do need to exchange gas after all) + - rscdel: Rad Immunity Removed + - tweak: Diona regenerate 1 OXY, 1 BURN, 1 BRUTE, and 1 TOX if they are in a bright + area; this effect does not kick in if they're in crit + - rscdel: Diona no longer have unbreakable bones (wood can crack ya know!) + - rscdel: Diona are no longer space proof + - tweak: Diona are more vulnerable to fire and heat damage + - tweak: Diona weakness to weedkiller dramatically nerfed + - rscadd: Diona now use Newcrit + - tweak: Diona are no longer slow + - rscadd: Diona can wear spacesuits + - bugfix: Fixes stun absorbing not working + - bugfix: Fixes parallax insane setting not doing anything + - tweak: Ores can be destroyed by devastating explosions + - tweak: silver, gold, and diamond pickaxes do a bit more damage and mine faster + than before + - tweak: drills slightly slower, but diamond drills slightly faster + - tweak: Spade is the same speed as a shovel + - tweak: Hivelord stabilizer will now make a hivelord core/legion soul stabilize + and be preserved, even if it was previously inert + - tweak: can use a hivelord core in your active hand to apply it to yourself + - rscadd: soulstone in the abandoned locked crates can now be used by anyone + - rscadd: Adds firelemon seeds to the abandoned locked crates as potential loot + - tweak: Hardsuits have an integrated helmet; you no longer have to attach helmets + - tweak: Toggling up/down helmets is now done with an action button + - rscdel: can no longer attach magboots to a hardsuit + - tweak: Hardsuit base melee armor increased from 10 to 30 + - tweak: Security and HoS hardsuit melee armor increased by 5 + - tweak: HoS hardsuit helmet armor matches his hardsuit + - tweak: CE's hardsuit helmet armor for rads increased by 10 (should be fully rad + proof now) + - tweak: Elite syndicate suits can't be acided + - bugfix: Fixes stuns and weakens related to reagents + - bugfix: Fixes the displayed cost of Plasmamen + - rscadd: 'Adds jetpack hardsuit upgrades: get yours at mining for 2000 points' + - rscdel: Removes mining carbon dioxide jetpack + - tweak: Can no longer use jetpacks in your suit storage slot + - rscadd: Chief Engineer's hardsuit, Syndicate Hardsuit (normal and elite), and + Shielded Syndicate Hardsuit all have built in jetpacks + - bugfix: Fixes random singularity releases from the grid check event + - tweak: loadout costs for most things cut from 2 to 1 + - rscadd: Adds fingerless gloves, eyepatch, prescription glasses, black shoes, brown + shoes, white shoes, and ian's shirt to the loadout + - tweak: moved hipster glasses from donator to general glasses + - rscadd: Adds in sandbags. Use them to deploy destructable barriers; miners start + off with a few + - rscdel: Removes access based security barriers + - rscadd: Adds in security barrier grenade. When it goes off, it will deploy up + to 3 barriers that will lock into place; should find 4 of these in the armory + - rscadd: can tear up bedsheet and gauze to get cloth--requires a sharp object + - bugfix: Fixes plasmamen atmos techs not getting their proper suit + - rscadd: Adds in a loom, craft one out of 10 wood + - rscadd: Adds in cotton and durathread cotton to botany to grow + - rscadd: Adds in a number of expanded items to create out of cloth, such as improvised + gauze, beanies, and softcaps + - rscadd: Adds the ability to use personal crafting to make durathread jumpsuits, + bandanas, armor, helmets, beanies and berets. Aside from the bandana, these + all have minor armor on them + - rscadd: 'Adds a number of new items to personally craft, related to clothing: + ability to make health, sec, diagnotic, and reagent sunglasses.' + - rscadd: Can additionally craft cowboy boots, lizardskin cowboy boots, fannypacks, + and a spooky ghost disguise + - rscadd: adds a whole range of beanies, find them in the clothing vendor or make + them yourself + - tweak: Updates the cowboy boots sprites + - bugfix: Unironically fixes about several thousand runtimes + - bugfix: Fixes jackets not keeping you warm + - rscadd: Chefs are now trained in the art of Close Quarters Cooking + - rscadd: Adds the Book of Babel as tendril loot + - rscadd: Adds Jacbo's Ladder as tendril loot + - bugfix: Fixes fungus, blood, and graffiti not showing up on a wall + - bugfix: Fixes the lavaland inquisitor and berserker hardsuits having incorrect + armor and slowdown values + - bugfix: Fixes baseball bats throwing anchored things + - bugfix: Fixes blood drunk buff + - bugfix: Fixes using a crusher on a trophy to equip it causing you to drop the + crusher + - tweak: refactors lazarus capsules; no real behavioral change + - bugfix: Fixes being able to revive megafauna with strange reagent + Fox McCloud and FullOfSkittles: + - tweak: Tweaks the gummy worm, gummy bear, jeallybean, toffee, and bacon sprites + - bugfix: Fixes telebacon not properly acting as...well, a bacon beacon + FreeStylaLT: + - rscadd: Added an Engine Picker, which uses new engine beacons. + - tweak: Replaced the current two engine generators with one engine beacon. + Ionward: + - imageadd: Drask crewmembers now have properly fitting shoes. + - imageadd: Fixed some minor issues in Drasks uniforms + - imageadd: non-humans now have proper sprites for durathread goods + KasparoVy: + - imageadd: Adds sprites for all Vox & Armalis earwear. + - imageadd: Adds sprites for Armalis default backpack, nitrogen tank (old-style + back & new-style belt) & all breath mask variations. + - rscadd: 'You can now species-fit in-hand icons: Use a single .dmi file and suffix + the icon states with _l or _r.' + - bugfix: Fixes an issue preventing Vox Armalis from being rendered with the proper + in-hand icons for their massive noise cannons. + - bugfix: Fixes an issue preventing the species-fitting of earwear. + - bugfix: Fixes an issue preventing Vox Armalis from wearing the 'Vox' breath mask. + - bugfix: Picking up uniforms no longer renders a default grey jumpsuit on Vox. + - bugfix: Resolves an issue causing shining eyes to be rendered darker than intended. + - bugfix: Resolves an issue preventing appearance features (hair, eyes, etc.) from + rendering on disembodied heads. + - bugfix: Resolves an issue preventing Admin-revived decapitated bodies from having + appearance features or ears. + - bugfix: Non-shining eyes render the proper colour again. + Kurgis: + - rscadd: Beepsky now bumps around on its wheels when patrolling for crime. + Markolie: + - rscadd: A new outfit manager has been added for admins (under debug). It lets + them save and load custom outfits on their computer and use these to equip players. + - rscadd: Upon transforming players into humans or reincarnating them through the + player panel, admins will now directly be able to select their equipment. + - rscadd: 'The select equipment verb now works on observers: it''ll create a human + with the given equipment under the ghost.' + - rscadd: A "Copy Outfit" button has been added to the View Variables dropdown, + which lets admins instantly copy an outfit. + - rscadd: Outfits now support accessories and internal boxes. + - rscdel: The separate option to equip ERT members has been removed. It's been integrated + into their regular outfits. + - tweak: Water coming from sinks and certain water effects is now 10C instead of + body temperature. + Shadow-Quill: + - rscadd: '[Meta] Added buckshot and slugs to armoury.' + - rscadd: '[Meta] Added surgical tools, robotic first aid kits, and a photocopier + to Robotics.' + - bugfix: '[Meta] R&D doors now has proper access requirements.' + - rscadd: '[Meta] Added RCS and telepad to cargo.' + - bugfix: '[Meta] Disposals sheet stacker and conveyor belts now works properly.' + - rscadd: '[Meta] One-way airlocks added in Medbay/Brig.' + - tweak: '[Meta] Disposals sheet stacker disposals chute leads directly to the mailroom.' + - bugfix: AIs not being able to restore their own power if in an area with an APC. + - bugfix: Fixed being able to talk in OOC under certain circumstances if it's disabled. + - bugfix: Lockers can no longer move around anchored mobs. + SteelSlayer: + - bugfix: You can no longer spam dismantle a SMES terminal and get 10 cable for + every progress bar + - bugfix: The game will properly remove 10 cable from your stack after building + a SMES terminal, instead of removing 0 + - rscadd: A cable adding sound gets played when you add wires to create a terminal + for a SMES + - rscadd: Rapid pipe dispensers can now place disposal sorting pipes + - tweak: When changing the sort location of a disposal sorting pipe, the name of + the pipe now also changes to the desired destination + - rscadd: Added a destination tagger to the atmosheric technician locker + - tweak: Added atmospherics access to Engi-Vend's and Engineering checkpoint airlocks + - tweak: Removed some random grey pixels from disposal sorting junction pipe sprites, + and certain normal disposal junction pipe sprites + - tweak: IV bags are able to transfer their contents to other containers by clicking + on them with the bag + - rscadd: Adds a handheld defibrillator to the paramedic EVA closet + - bugfix: You can insert magazines into L6 SAWs again + - rscdel: Removed one of the high capacity tanks in hydroponics + - rscadd: Added a disk compartmentalizer to hydroponics + - bugfix: Delaying round start actually delays round start again + Terilia: + - rscadd: added headcrabs + - tweak: adjusted the path's for headslugs. They are not called headcrab anymore + TheSardele: + - rscdel: Removes the ability of obese people and those with matter eater to swallow + others. + Ty-Omaha: + - bugfix: Fixed a bug where hotwiring solar panels would allow for the station to + remain powered in the Grid Check power failure event. + datlo: + - rscadd: Added ashstorm immunity to titanium and plastitanium golems. + - rscadd: Added lava immunity to plastitanium golems. + - rscadd: Bananium golems now slowly waddle around. + - bugfix: Uranium golems now properly irradiate nearby mobs that arent rad immune. + - bugfix: Tranquillite golems now properly get their miming powers. + - rscadd: Added the Clown and Winter biodomes as possible lavaland ruins. + - tweak: Update a changeling error message to be clearer. + farie82: + - bugfix: Items with NODROP that are dropped now lose the flag if they didn't get + created with it + - rscadd: Adds tip text to the examine text of the ambulance trolley about how to + attach it + - rscadd: Adds tip text to the nuke when trying to use the NAD before deploying + it + - rscadd: Adds tip text to the fire axe cabinet about how to lock/unlock it + - rscadd: Adds tip text to airlocks if they have a note on them about how to remove + the note + - bugfix: Can't put the NAD in the nuke now when it has the NODROP flag + - bugfix: Locking a fire axe cabinet is less weird now. No odd 5 seconds sleep + - bugfix: Can't put a nodrop fire axe in fire axe cabinets now. Duping them + - bugfix: Implants like the IPC charging work again. They won't get deleted after + first use + variableundefined: + - tweak: A proc's name got changed. That's it diff --git a/html/changelogs/AutoChangeLog-pr-11741.yml b/html/changelogs/AutoChangeLog-pr-11741.yml deleted file mode 100644 index f169e75b08a..00000000000 --- a/html/changelogs/AutoChangeLog-pr-11741.yml +++ /dev/null @@ -1,5 +0,0 @@ -author: "AzuleUtama" -delete-after: True -changes: - - tweak: "The Traitor thermal glasses and chameleon security HUD now use the updated chameleon code. -balance: Traitor thermal glasses will no longer cause eye damage when hit with EMP." diff --git a/html/changelogs/AutoChangeLog-pr-11767.yml b/html/changelogs/AutoChangeLog-pr-11767.yml deleted file mode 100644 index a1ab9b83753..00000000000 --- a/html/changelogs/AutoChangeLog-pr-11767.yml +++ /dev/null @@ -1,6 +0,0 @@ -author: "Arkatos" -delete-after: True -changes: - - imageadd: "Added colored pillbottles" - - rscadd: "Added an option to change color of the pillbottles to ChemMaster3000" - - rscadd: "Added new description to patch packs" diff --git a/html/changelogs/AutoChangeLog-pr-11769.yml b/html/changelogs/AutoChangeLog-pr-11769.yml deleted file mode 100644 index 610e9401fb5..00000000000 --- a/html/changelogs/AutoChangeLog-pr-11769.yml +++ /dev/null @@ -1,5 +0,0 @@ -author: "Couls" -delete-after: True -changes: - - rscadd: "After many complaints about being stuck in medbay. NT has modified all the airlocks on the station to allow leaving certain departments without requiring an respective ID. This new modification is indicated by a white light near the airlocks in the direction of unrestricted access." - - rscadd: "New unrestricted access can be built by NT engineers through modification of the airlock electronics." diff --git a/html/changelogs/AutoChangeLog-pr-11774.yml b/html/changelogs/AutoChangeLog-pr-11774.yml deleted file mode 100644 index 2671e0bd231..00000000000 --- a/html/changelogs/AutoChangeLog-pr-11774.yml +++ /dev/null @@ -1,4 +0,0 @@ -author: "Arkatos" -delete-after: True -changes: - - tweak: "Jump to Node ability now shows a location of each Blob node" diff --git a/html/changelogs/AutoChangeLog-pr-11776.yml b/html/changelogs/AutoChangeLog-pr-11776.yml deleted file mode 100644 index 6040b3f474a..00000000000 --- a/html/changelogs/AutoChangeLog-pr-11776.yml +++ /dev/null @@ -1,4 +0,0 @@ -author: "Arkatos" -delete-after: True -changes: - - rscadd: "Added SlimeHUD when playing as a slime. This means slimes will have their own unique health doll and pull icon." diff --git a/html/changelogs/AutoChangeLog-pr-11807.yml b/html/changelogs/AutoChangeLog-pr-11807.yml deleted file mode 100644 index 1dac37526db..00000000000 --- a/html/changelogs/AutoChangeLog-pr-11807.yml +++ /dev/null @@ -1,5 +0,0 @@ -author: "Tayyyyyyy" -delete-after: True -changes: - - tweak: "Whether you join the ERT is no longer determined by how fast you click \"yes\" on the prompt." - - tweak: "Drag and drop support and 20 seconds to pick ERT role instead of 15" diff --git a/html/changelogs/AutoChangeLog-pr-11810.yml b/html/changelogs/AutoChangeLog-pr-11810.yml deleted file mode 100644 index b87ad624c90..00000000000 --- a/html/changelogs/AutoChangeLog-pr-11810.yml +++ /dev/null @@ -1,5 +0,0 @@ -author: "Arkatos" -delete-after: True -changes: - - rscadd: "Action buttons can now be dragged onto each other to swap places" - - bugfix: "Fixed a case where dragging locked action buttons could result in white tooltip over the screen" diff --git a/html/changelogs/AutoChangeLog-pr-11830.yml b/html/changelogs/AutoChangeLog-pr-11830.yml deleted file mode 100644 index f64dd5490f1..00000000000 --- a/html/changelogs/AutoChangeLog-pr-11830.yml +++ /dev/null @@ -1,4 +0,0 @@ -author: "EmanTheAlmighty" -delete-after: True -changes: - - rscadd: "The AI can now change its intent by clicking on the new on-screen button or pressing 4 to switch to help or harm." diff --git a/html/changelogs/AutoChangeLog-pr-11833.yml b/html/changelogs/AutoChangeLog-pr-11833.yml deleted file mode 100644 index 2e7470e33cb..00000000000 --- a/html/changelogs/AutoChangeLog-pr-11833.yml +++ /dev/null @@ -1,4 +0,0 @@ -author: "dovydas12345" -delete-after: True -changes: - - bugfix: "Fixes being able to pick up chairs and stools when you have items in both hand or when you don't have hands." diff --git a/html/changelogs/AutoChangeLog-pr-11834.yml b/html/changelogs/AutoChangeLog-pr-11834.yml deleted file mode 100644 index 99a23206448..00000000000 --- a/html/changelogs/AutoChangeLog-pr-11834.yml +++ /dev/null @@ -1,4 +0,0 @@ -author: "dovydas12345" -delete-after: True -changes: - - rscadd: "Adds a ERT shuttle console which is accessible to ERT members" diff --git a/html/changelogs/AutoChangeLog-pr-11843.yml b/html/changelogs/AutoChangeLog-pr-11843.yml deleted file mode 100644 index ace0ff2485b..00000000000 --- a/html/changelogs/AutoChangeLog-pr-11843.yml +++ /dev/null @@ -1,4 +0,0 @@ -author: "JKnutson101" -delete-after: True -changes: - - bugfix: "Issue where Emergency NanoMed Vendors required Medical ID to Access." diff --git a/html/changelogs/AutoChangeLog-pr-11844.yml b/html/changelogs/AutoChangeLog-pr-11844.yml deleted file mode 100644 index 448d227c770..00000000000 --- a/html/changelogs/AutoChangeLog-pr-11844.yml +++ /dev/null @@ -1,4 +0,0 @@ -author: "JKnutson101" -delete-after: True -changes: - - rscadd: "Added the ability for cyborgs with zero battery to use the 'succumb' verb." diff --git a/html/changelogs/AutoChangeLog-pr-11845.yml b/html/changelogs/AutoChangeLog-pr-11845.yml deleted file mode 100644 index 2582e3c3752..00000000000 --- a/html/changelogs/AutoChangeLog-pr-11845.yml +++ /dev/null @@ -1,5 +0,0 @@ -author: "Tayyyyyyy" -delete-after: True -changes: - - bugfix: "Fix extra newline after field and disable Github Flavored Markdown in papers (normal markdown still works)" - - bugfix: "autogenerated papers no longer appear as HTML code" diff --git a/html/changelogs/AutoChangeLog-pr-11875.yml b/html/changelogs/AutoChangeLog-pr-11875.yml deleted file mode 100644 index 35009a885a0..00000000000 --- a/html/changelogs/AutoChangeLog-pr-11875.yml +++ /dev/null @@ -1,5 +0,0 @@ -author: "SteelSlayer" -delete-after: True -changes: - - bugfix: "Wizard rounds now end if all wizards and apprentices are either dead, inside cyborgs, or in MMIs" - - tweak: "Re-enabled the wizard's hud. Wizards can now see their own antag icon along with seeing other wizard's and apprentice's icons" diff --git a/html/changelogs/AutoChangeLog-pr-11899.yml b/html/changelogs/AutoChangeLog-pr-11899.yml deleted file mode 100644 index 95579acd428..00000000000 --- a/html/changelogs/AutoChangeLog-pr-11899.yml +++ /dev/null @@ -1,6 +0,0 @@ -author: "SteelSlayer" -delete-after: True -changes: - - bugfix: "When a cult sacrifice target leaves the round via cryo, the game will reassign a new target for them" - - rscadd: "Added an alarm sound that plays for cultists when their sacrifice target leave the round via cryo" - - rscadd: "When a cult sacrifice target leaves the round via cryo, the game will update every cultist's notes to reflect the change" diff --git a/html/changelogs/AutoChangeLog-pr-11932.yml b/html/changelogs/AutoChangeLog-pr-11932.yml deleted file mode 100644 index 787271cc390..00000000000 --- a/html/changelogs/AutoChangeLog-pr-11932.yml +++ /dev/null @@ -1,4 +0,0 @@ -author: "TheSardele" -delete-after: True -changes: - - rscadd: "Icon for cybernetic eyes" diff --git a/html/changelogs/AutoChangeLog-pr-11949.yml b/html/changelogs/AutoChangeLog-pr-11949.yml deleted file mode 100644 index 12b6be236a3..00000000000 --- a/html/changelogs/AutoChangeLog-pr-11949.yml +++ /dev/null @@ -1,4 +0,0 @@ -author: "kazboo" -delete-after: True -changes: - - bugfix: "adjusts the hierophant blast layer to make for it to always be below the effect. this should be the case already due to mouse_opacity, though for some unknown reason, it just doesn't work sometimes, so this should fix it." diff --git a/html/changelogs/AutoChangeLog-pr-11965.yml b/html/changelogs/AutoChangeLog-pr-11965.yml deleted file mode 100644 index f70891de781..00000000000 --- a/html/changelogs/AutoChangeLog-pr-11965.yml +++ /dev/null @@ -1,4 +0,0 @@ -author: "TDSSS" -delete-after: True -changes: - - tweak: "cult talisman got unique icons to tell them apart" diff --git a/html/changelogs/AutoChangeLog-pr-11980.yml b/html/changelogs/AutoChangeLog-pr-11980.yml deleted file mode 100644 index 55028f62e4d..00000000000 --- a/html/changelogs/AutoChangeLog-pr-11980.yml +++ /dev/null @@ -1,4 +0,0 @@ -author: "TheSardele" -delete-after: True -changes: - - bugfix: "Sleeping while drunk no longer makes you more drunk." diff --git a/html/changelogs/AutoChangeLog-pr-11984.yml b/html/changelogs/AutoChangeLog-pr-11984.yml deleted file mode 100644 index 49600d2025b..00000000000 --- a/html/changelogs/AutoChangeLog-pr-11984.yml +++ /dev/null @@ -1,5 +0,0 @@ -author: "Markolie" -delete-after: True -changes: - - tweak: "Players now have thirty seconds instead of just five seconds to select if they want to be somebody's butler through a die of fate roll." - - bugfix: "The Netherworld portal is now properly destroyed upon being killed. In addition, its max health is now equal to its starting health." diff --git a/html/changelogs/AutoChangeLog-pr-11995.yml b/html/changelogs/AutoChangeLog-pr-11995.yml deleted file mode 100644 index 63e511de1e9..00000000000 --- a/html/changelogs/AutoChangeLog-pr-11995.yml +++ /dev/null @@ -1,4 +0,0 @@ -author: "Markolie" -delete-after: True -changes: - - tweak: "The iron ore sprite that shows up when using the miner scanner no longer has a background, making it blend in better with the actual rock." diff --git a/icons/effects/effects.dmi b/icons/effects/effects.dmi index 26526f68951..bea6f281f7a 100644 Binary files a/icons/effects/effects.dmi and b/icons/effects/effects.dmi differ diff --git a/icons/effects/parallax.dmi b/icons/effects/parallax.dmi new file mode 100644 index 00000000000..22f091ff11a Binary files /dev/null and b/icons/effects/parallax.dmi differ diff --git a/icons/mob/actions/actions.dmi b/icons/mob/actions/actions.dmi index d3976bfff61..66795e14830 100644 Binary files a/icons/mob/actions/actions.dmi and b/icons/mob/actions/actions.dmi differ diff --git a/icons/mob/animal.dmi b/icons/mob/animal.dmi index 0167380d885..eb80e41a87f 100644 Binary files a/icons/mob/animal.dmi and b/icons/mob/animal.dmi differ diff --git a/icons/mob/back.dmi b/icons/mob/back.dmi index c58a6b635f4..36025c083b4 100644 Binary files a/icons/mob/back.dmi and b/icons/mob/back.dmi differ diff --git a/icons/mob/belt.dmi b/icons/mob/belt.dmi index a1e80aa5e65..5c272f8c8e9 100644 Binary files a/icons/mob/belt.dmi and b/icons/mob/belt.dmi differ diff --git a/icons/mob/eyes.dmi b/icons/mob/eyes.dmi index 09b1f1f79ba..6f3e3f0ea2e 100644 Binary files a/icons/mob/eyes.dmi and b/icons/mob/eyes.dmi differ diff --git a/icons/mob/feet.dmi b/icons/mob/feet.dmi index fcfef35c38b..e6f132a73a5 100644 Binary files a/icons/mob/feet.dmi and b/icons/mob/feet.dmi differ diff --git a/icons/mob/hands.dmi b/icons/mob/hands.dmi index a5a14094fd6..6d6165509c8 100644 Binary files a/icons/mob/hands.dmi and b/icons/mob/hands.dmi differ diff --git a/icons/mob/head.dmi b/icons/mob/head.dmi index 7f84b29d04e..0fe42126ef0 100644 Binary files a/icons/mob/head.dmi and b/icons/mob/head.dmi differ diff --git a/icons/mob/headcrab.dmi b/icons/mob/headcrab.dmi new file mode 100644 index 00000000000..4db08f13e76 Binary files /dev/null and b/icons/mob/headcrab.dmi differ diff --git a/icons/mob/human_races/r_grey.dmi b/icons/mob/human_races/r_grey.dmi index b243f88e401..1f66332a577 100644 Binary files a/icons/mob/human_races/r_grey.dmi and b/icons/mob/human_races/r_grey.dmi differ diff --git a/icons/mob/inhands/items_lefthand.dmi b/icons/mob/inhands/items_lefthand.dmi index 47cb86a2c89..03f57f19a92 100644 Binary files a/icons/mob/inhands/items_lefthand.dmi and b/icons/mob/inhands/items_lefthand.dmi differ diff --git a/icons/mob/inhands/items_righthand.dmi b/icons/mob/inhands/items_righthand.dmi index e4630c2764e..b11f98e74ed 100644 Binary files a/icons/mob/inhands/items_righthand.dmi and b/icons/mob/inhands/items_righthand.dmi differ diff --git a/icons/mob/mask.dmi b/icons/mob/mask.dmi index 8027568e31b..99be80fb681 100644 Binary files a/icons/mob/mask.dmi and b/icons/mob/mask.dmi differ diff --git a/icons/mob/mob.dmi b/icons/mob/mob.dmi index 014242b9d90..ed193927004 100644 Binary files a/icons/mob/mob.dmi and b/icons/mob/mob.dmi differ diff --git a/icons/mob/screen_alert.dmi b/icons/mob/screen_alert.dmi index b18cb799817..cb6a2c6bd64 100644 Binary files a/icons/mob/screen_alert.dmi and b/icons/mob/screen_alert.dmi differ diff --git a/icons/mob/species/armalis/back.dmi b/icons/mob/species/armalis/back.dmi new file mode 100644 index 00000000000..31f4f21f812 Binary files /dev/null and b/icons/mob/species/armalis/back.dmi differ diff --git a/icons/mob/species/armalis/belt.dmi b/icons/mob/species/armalis/belt.dmi new file mode 100644 index 00000000000..2aba8e97d8a Binary files /dev/null and b/icons/mob/species/armalis/belt.dmi differ diff --git a/icons/mob/species/armalis/ears.dmi b/icons/mob/species/armalis/ears.dmi new file mode 100644 index 00000000000..f88c03feae5 Binary files /dev/null and b/icons/mob/species/armalis/ears.dmi differ diff --git a/icons/mob/species/armalis/mask.dmi b/icons/mob/species/armalis/mask.dmi new file mode 100644 index 00000000000..e97eb74f8e0 Binary files /dev/null and b/icons/mob/species/armalis/mask.dmi differ diff --git a/icons/mob/species/drask/eyes.dmi b/icons/mob/species/drask/eyes.dmi index 918f6e5ef71..818c719a541 100644 Binary files a/icons/mob/species/drask/eyes.dmi and b/icons/mob/species/drask/eyes.dmi differ diff --git a/icons/mob/species/drask/helmet.dmi b/icons/mob/species/drask/helmet.dmi index f6ade8dca0d..72b614bd3f2 100644 Binary files a/icons/mob/species/drask/helmet.dmi and b/icons/mob/species/drask/helmet.dmi differ diff --git a/icons/mob/species/drask/mask.dmi b/icons/mob/species/drask/mask.dmi index 9b9c341feb3..27fa4502ad7 100644 Binary files a/icons/mob/species/drask/mask.dmi and b/icons/mob/species/drask/mask.dmi differ diff --git a/icons/mob/species/drask/shoes.dmi b/icons/mob/species/drask/shoes.dmi new file mode 100644 index 00000000000..e51947fdd35 Binary files /dev/null and b/icons/mob/species/drask/shoes.dmi differ diff --git a/icons/mob/species/drask/uniform.dmi b/icons/mob/species/drask/uniform.dmi index ab315263ed9..bb350b0a3d8 100644 Binary files a/icons/mob/species/drask/uniform.dmi and b/icons/mob/species/drask/uniform.dmi differ diff --git a/icons/mob/species/grey/back.dmi b/icons/mob/species/grey/back.dmi new file mode 100644 index 00000000000..e73a9798d65 Binary files /dev/null and b/icons/mob/species/grey/back.dmi differ diff --git a/icons/mob/species/grey/eyes.dmi b/icons/mob/species/grey/eyes.dmi index 8c732aa782d..937474d97dc 100644 Binary files a/icons/mob/species/grey/eyes.dmi and b/icons/mob/species/grey/eyes.dmi differ diff --git a/icons/mob/species/grey/head.dmi b/icons/mob/species/grey/head.dmi index 201e1032562..ca3737c75a8 100644 Binary files a/icons/mob/species/grey/head.dmi and b/icons/mob/species/grey/head.dmi differ diff --git a/icons/mob/species/grey/helmet.dmi b/icons/mob/species/grey/helmet.dmi index b81d6617e17..b8942e8fd7f 100644 Binary files a/icons/mob/species/grey/helmet.dmi and b/icons/mob/species/grey/helmet.dmi differ diff --git a/icons/mob/species/grey/mask.dmi b/icons/mob/species/grey/mask.dmi index 6d13b33c4bf..cbbd722ae69 100644 Binary files a/icons/mob/species/grey/mask.dmi and b/icons/mob/species/grey/mask.dmi differ diff --git a/icons/mob/species/grey/uniform.dmi b/icons/mob/species/grey/uniform.dmi index ddf0250fdc5..c1e21d5fa11 100644 Binary files a/icons/mob/species/grey/uniform.dmi and b/icons/mob/species/grey/uniform.dmi differ diff --git a/icons/mob/species/plasmaman/helmet.dmi b/icons/mob/species/plasmaman/helmet.dmi index bd5465857d8..ebcb096aa7b 100644 Binary files a/icons/mob/species/plasmaman/helmet.dmi and b/icons/mob/species/plasmaman/helmet.dmi differ diff --git a/icons/mob/species/plasmaman/mask.dmi b/icons/mob/species/plasmaman/mask.dmi index 1acdc5e581f..73ff04e9288 100644 Binary files a/icons/mob/species/plasmaman/mask.dmi and b/icons/mob/species/plasmaman/mask.dmi differ diff --git a/icons/mob/species/plasmaman/suit.dmi b/icons/mob/species/plasmaman/suit.dmi deleted file mode 100644 index c4d1a7a2b3c..00000000000 Binary files a/icons/mob/species/plasmaman/suit.dmi and /dev/null differ diff --git a/icons/mob/species/plasmaman/uniform.dmi b/icons/mob/species/plasmaman/uniform.dmi new file mode 100644 index 00000000000..6667746c438 Binary files /dev/null and b/icons/mob/species/plasmaman/uniform.dmi differ diff --git a/icons/mob/species/tajaran/mask.dmi b/icons/mob/species/tajaran/mask.dmi index f73989fe9b0..d579a1c8384 100644 Binary files a/icons/mob/species/tajaran/mask.dmi and b/icons/mob/species/tajaran/mask.dmi differ diff --git a/icons/mob/species/unathi/mask.dmi b/icons/mob/species/unathi/mask.dmi index ba9be383855..535bec089f8 100644 Binary files a/icons/mob/species/unathi/mask.dmi and b/icons/mob/species/unathi/mask.dmi differ diff --git a/icons/mob/species/vox/ears.dmi b/icons/mob/species/vox/ears.dmi new file mode 100644 index 00000000000..b09c349cae9 Binary files /dev/null and b/icons/mob/species/vox/ears.dmi differ diff --git a/icons/mob/species/vox/eyes.dmi b/icons/mob/species/vox/eyes.dmi index 3d9a6c77bf8..3e3705d2a90 100644 Binary files a/icons/mob/species/vox/eyes.dmi and b/icons/mob/species/vox/eyes.dmi differ diff --git a/icons/mob/species/vox/helmet.dmi b/icons/mob/species/vox/helmet.dmi index a7186d611b6..74bd0762ff8 100644 Binary files a/icons/mob/species/vox/helmet.dmi and b/icons/mob/species/vox/helmet.dmi differ diff --git a/icons/mob/species/vox/mask.dmi b/icons/mob/species/vox/mask.dmi index 7023b2c3247..3e3a074c629 100644 Binary files a/icons/mob/species/vox/mask.dmi and b/icons/mob/species/vox/mask.dmi differ diff --git a/icons/mob/species/vox/shoes.dmi b/icons/mob/species/vox/shoes.dmi index 0a65993e240..99eac81e3a9 100644 Binary files a/icons/mob/species/vox/shoes.dmi and b/icons/mob/species/vox/shoes.dmi differ diff --git a/icons/mob/species/vox/suit.dmi b/icons/mob/species/vox/suit.dmi index 0716073b931..a088466564f 100644 Binary files a/icons/mob/species/vox/suit.dmi and b/icons/mob/species/vox/suit.dmi differ diff --git a/icons/mob/species/vox/uniform.dmi b/icons/mob/species/vox/uniform.dmi index f4d3eda8896..6334c7c7555 100644 Binary files a/icons/mob/species/vox/uniform.dmi and b/icons/mob/species/vox/uniform.dmi differ diff --git a/icons/mob/species/vulpkanin/mask.dmi b/icons/mob/species/vulpkanin/mask.dmi index e50c3421fb0..c839ee98e2d 100644 Binary files a/icons/mob/species/vulpkanin/mask.dmi and b/icons/mob/species/vulpkanin/mask.dmi differ diff --git a/icons/mob/suit.dmi b/icons/mob/suit.dmi index f79ca1fb338..1427b5aaf10 100644 Binary files a/icons/mob/suit.dmi and b/icons/mob/suit.dmi differ diff --git a/icons/mob/uniform.dmi b/icons/mob/uniform.dmi index 69f9e04895e..1d96c0b9676 100644 Binary files a/icons/mob/uniform.dmi and b/icons/mob/uniform.dmi differ diff --git a/icons/obj/aibots.dmi b/icons/obj/aibots.dmi index 9299c999342..a45ff1546da 100644 Binary files a/icons/obj/aibots.dmi and b/icons/obj/aibots.dmi differ diff --git a/icons/obj/basketball.dmi b/icons/obj/basketball.dmi index a26c3935719..7b34fda1a32 100644 Binary files a/icons/obj/basketball.dmi and b/icons/obj/basketball.dmi differ diff --git a/icons/obj/clothing/glasses.dmi b/icons/obj/clothing/glasses.dmi index 0f6aa860754..c0501f9bb36 100644 Binary files a/icons/obj/clothing/glasses.dmi and b/icons/obj/clothing/glasses.dmi differ diff --git a/icons/obj/clothing/gloves.dmi b/icons/obj/clothing/gloves.dmi index 42f1eda0e74..f7f54357fdb 100644 Binary files a/icons/obj/clothing/gloves.dmi and b/icons/obj/clothing/gloves.dmi differ diff --git a/icons/obj/clothing/hats.dmi b/icons/obj/clothing/hats.dmi index a20cf61eb33..76be29d247d 100644 Binary files a/icons/obj/clothing/hats.dmi and b/icons/obj/clothing/hats.dmi differ diff --git a/icons/obj/clothing/masks.dmi b/icons/obj/clothing/masks.dmi index b3a04ce73bf..5650a792d01 100644 Binary files a/icons/obj/clothing/masks.dmi and b/icons/obj/clothing/masks.dmi differ diff --git a/icons/obj/clothing/shoes.dmi b/icons/obj/clothing/shoes.dmi index b008f3139cc..30cdfae56ef 100644 Binary files a/icons/obj/clothing/shoes.dmi and b/icons/obj/clothing/shoes.dmi differ diff --git a/icons/obj/clothing/species/plasmaman/hats.dmi b/icons/obj/clothing/species/plasmaman/hats.dmi index fc76e521d55..60282c030fe 100644 Binary files a/icons/obj/clothing/species/plasmaman/hats.dmi and b/icons/obj/clothing/species/plasmaman/hats.dmi differ diff --git a/icons/obj/clothing/species/plasmaman/suits.dmi b/icons/obj/clothing/species/plasmaman/suits.dmi deleted file mode 100644 index 78ddd94dedb..00000000000 Binary files a/icons/obj/clothing/species/plasmaman/suits.dmi and /dev/null differ diff --git a/icons/obj/clothing/species/plasmaman/uniform.dmi b/icons/obj/clothing/species/plasmaman/uniform.dmi new file mode 100644 index 00000000000..bc3f4d59a50 Binary files /dev/null and b/icons/obj/clothing/species/plasmaman/uniform.dmi differ diff --git a/icons/obj/clothing/suits.dmi b/icons/obj/clothing/suits.dmi index 8e5a4b8e879..95e515f9f86 100644 Binary files a/icons/obj/clothing/suits.dmi and b/icons/obj/clothing/suits.dmi differ diff --git a/icons/obj/clothing/uniforms.dmi b/icons/obj/clothing/uniforms.dmi index 78586b72dfc..2a9fca9c57e 100644 Binary files a/icons/obj/clothing/uniforms.dmi and b/icons/obj/clothing/uniforms.dmi differ diff --git a/icons/obj/device.dmi b/icons/obj/device.dmi index f48f0e9f07a..b5c25d474d1 100644 Binary files a/icons/obj/device.dmi and b/icons/obj/device.dmi differ diff --git a/icons/obj/food/candy.dmi b/icons/obj/food/candy.dmi index 89714f5b5b3..66795d6ec95 100644 Binary files a/icons/obj/food/candy.dmi and b/icons/obj/food/candy.dmi differ diff --git a/icons/obj/food/food.dmi b/icons/obj/food/food.dmi index ebabdcf2ef5..aea237f5bed 100644 Binary files a/icons/obj/food/food.dmi and b/icons/obj/food/food.dmi differ diff --git a/icons/obj/fulton.dmi b/icons/obj/fulton.dmi new file mode 100644 index 00000000000..c56c275b3b1 Binary files /dev/null and b/icons/obj/fulton.dmi differ diff --git a/icons/obj/fulton_balloon.dmi b/icons/obj/fulton_balloon.dmi new file mode 100644 index 00000000000..5a1fa98e148 Binary files /dev/null and b/icons/obj/fulton_balloon.dmi differ diff --git a/icons/obj/guns/bayonets.dmi b/icons/obj/guns/bayonets.dmi new file mode 100644 index 00000000000..32b5448b8ed Binary files /dev/null and b/icons/obj/guns/bayonets.dmi differ diff --git a/icons/obj/hydroponics/equipment.dmi b/icons/obj/hydroponics/equipment.dmi index f9e4f6bfbfc..9ad33b40e9d 100644 Binary files a/icons/obj/hydroponics/equipment.dmi and b/icons/obj/hydroponics/equipment.dmi differ diff --git a/icons/obj/hydroponics/growing.dmi b/icons/obj/hydroponics/growing.dmi index 5b63f0553bd..d66cdc2c0dd 100644 Binary files a/icons/obj/hydroponics/growing.dmi and b/icons/obj/hydroponics/growing.dmi differ diff --git a/icons/obj/hydroponics/harvest.dmi b/icons/obj/hydroponics/harvest.dmi index 53033eb8f48..3059eabe629 100644 Binary files a/icons/obj/hydroponics/harvest.dmi and b/icons/obj/hydroponics/harvest.dmi differ diff --git a/icons/obj/hydroponics/seeds.dmi b/icons/obj/hydroponics/seeds.dmi index a2415a71a8a..353d2811e67 100644 Binary files a/icons/obj/hydroponics/seeds.dmi and b/icons/obj/hydroponics/seeds.dmi differ diff --git a/icons/obj/items.dmi b/icons/obj/items.dmi index 05a5768ce89..03f835232ac 100644 Binary files a/icons/obj/items.dmi and b/icons/obj/items.dmi differ diff --git a/icons/obj/janitor.dmi b/icons/obj/janitor.dmi index 83cb94a5ca3..730431590ae 100644 Binary files a/icons/obj/janitor.dmi and b/icons/obj/janitor.dmi differ diff --git a/icons/obj/kitchen.dmi b/icons/obj/kitchen.dmi index b39c3668294..0e9ee4649ac 100644 Binary files a/icons/obj/kitchen.dmi and b/icons/obj/kitchen.dmi differ diff --git a/icons/obj/lavaland/artefacts.dmi b/icons/obj/lavaland/artefacts.dmi index cd2c6da08ee..8e91b20368f 100644 Binary files a/icons/obj/lavaland/artefacts.dmi and b/icons/obj/lavaland/artefacts.dmi differ diff --git a/icons/obj/library.dmi b/icons/obj/library.dmi index f28e5f83a33..edb8d7cb2c5 100644 Binary files a/icons/obj/library.dmi and b/icons/obj/library.dmi differ diff --git a/icons/obj/mining.dmi b/icons/obj/mining.dmi index 29196e625ae..82ab4786c37 100644 Binary files a/icons/obj/mining.dmi and b/icons/obj/mining.dmi differ diff --git a/icons/obj/objects.dmi b/icons/obj/objects.dmi index f9c13a5c332..f3cff7fbd9a 100644 Binary files a/icons/obj/objects.dmi and b/icons/obj/objects.dmi differ diff --git a/icons/obj/pipes/disposal.dmi b/icons/obj/pipes/disposal.dmi index f2dd62c9393..18d97345686 100644 Binary files a/icons/obj/pipes/disposal.dmi and b/icons/obj/pipes/disposal.dmi differ diff --git a/icons/obj/smooth_structures/sandbags.dmi b/icons/obj/smooth_structures/sandbags.dmi new file mode 100644 index 00000000000..8ac099555a8 Binary files /dev/null and b/icons/obj/smooth_structures/sandbags.dmi differ diff --git a/icons/obj/stationobjs.dmi b/icons/obj/stationobjs.dmi index c8a9abd40f3..c33efec0f5f 100755 Binary files a/icons/obj/stationobjs.dmi and b/icons/obj/stationobjs.dmi differ diff --git a/icons/obj/structures.dmi b/icons/obj/structures.dmi index f30ecfe94d1..d1b6b267f8a 100644 Binary files a/icons/obj/structures.dmi and b/icons/obj/structures.dmi differ diff --git a/icons/obj/tank.dmi b/icons/obj/tank.dmi index 72cce42bd79..7496d65027c 100644 Binary files a/icons/obj/tank.dmi and b/icons/obj/tank.dmi differ diff --git a/icons/obj/wizard.dmi b/icons/obj/wizard.dmi index 07c8be38ed9..83a80d2f408 100644 Binary files a/icons/obj/wizard.dmi and b/icons/obj/wizard.dmi differ diff --git a/icons/turf/floors/ice_turfs.dmi b/icons/turf/floors/ice_turfs.dmi new file mode 100644 index 00000000000..2bee5887fe8 Binary files /dev/null and b/icons/turf/floors/ice_turfs.dmi differ diff --git a/icons/turf/walls/hierophant_wall_temp.dmi b/icons/turf/walls/hierophant_wall_temp.dmi new file mode 100644 index 00000000000..9f0d4b8d23c Binary files /dev/null and b/icons/turf/walls/hierophant_wall_temp.dmi differ diff --git a/paradise.dme b/paradise.dme index 86eb2825b04..7e67e6dde23 100644 --- a/paradise.dme +++ b/paradise.dme @@ -143,6 +143,7 @@ #include "code\_onclick\hud\monkey.dm" #include "code\_onclick\hud\movable_screen_objects.dm" #include "code\_onclick\hud\other_mobs.dm" +#include "code\_onclick\hud\parallax.dm" #include "code\_onclick\hud\picture_in_picture.dm" #include "code\_onclick\hud\plane_master.dm" #include "code\_onclick\hud\radial.dm" @@ -204,6 +205,7 @@ #include "code\controllers\subsystem\alarm.dm" #include "code\controllers\subsystem\assets.dm" #include "code\controllers\subsystem\atoms.dm" +#include "code\controllers\subsystem\chat.dm" #include "code\controllers\subsystem\events.dm" #include "code\controllers\subsystem\fires.dm" #include "code\controllers\subsystem\garbage.dm" @@ -223,6 +225,7 @@ #include "code\controllers\subsystem\nightshift.dm" #include "code\controllers\subsystem\npcpool.dm" #include "code\controllers\subsystem\overlays.dm" +#include "code\controllers\subsystem\parallax.dm" #include "code\controllers\subsystem\radio.dm" #include "code\controllers\subsystem\shuttles.dm" #include "code\controllers\subsystem\spacedrift.dm" @@ -278,6 +281,7 @@ #include "code\datums\components\ducttape.dm" #include "code\datums\components\jestosterone.dm" #include "code\datums\components\material_container.dm" +#include "code\datums\components\paintable.dm" #include "code\datums\components\squeak.dm" #include "code\datums\components\waddling.dm" #include "code\datums\diseases\_disease.dm" @@ -350,6 +354,8 @@ #include "code\datums\looping_sounds\weather.dm" #include "code\datums\outfits\outfit.dm" #include "code\datums\outfits\outfit_admin.dm" +#include "code\datums\outfits\plasmamen.dm" +#include "code\datums\outfits\vv_outfit.dm" #include "code\datums\ruins\lavaland.dm" #include "code\datums\ruins\space.dm" #include "code\datums\spells\area_teleport.dm" @@ -482,7 +488,7 @@ #include "code\game\gamemodes\changeling\powers\epinephrine.dm" #include "code\game\gamemodes\changeling\powers\fakedeath.dm" #include "code\game\gamemodes\changeling\powers\fleshmend.dm" -#include "code\game\gamemodes\changeling\powers\headcrab.dm" +#include "code\game\gamemodes\changeling\powers\headslug.dm" #include "code\game\gamemodes\changeling\powers\hivemind.dm" #include "code\game\gamemodes\changeling\powers\humanform.dm" #include "code\game\gamemodes\changeling\powers\lesserform.dm" @@ -846,6 +852,7 @@ #include "code\game\objects\items\devices\autopsy.dm" #include "code\game\objects\items\devices\camera_bug.dm" #include "code\game\objects\items\devices\chameleonproj.dm" +#include "code\game\objects\items\devices\enginepicker.dm" #include "code\game\objects\items\devices\flash.dm" #include "code\game\objects\items\devices\flashlight.dm" #include "code\game\objects\items\devices\floor_painter.dm" @@ -1044,6 +1051,7 @@ #include "code\game\objects\structures\ladders.dm" #include "code\game\objects\structures\lamarr_cage.dm" #include "code\game\objects\structures\lattice.dm" +#include "code\game\objects\structures\loom.dm" #include "code\game\objects\structures\mineral_doors.dm" #include "code\game\objects\structures\mirror.dm" #include "code\game\objects\structures\misc.dm" @@ -1157,6 +1165,7 @@ #include "code\modules\admin\IsBanned.dm" #include "code\modules\admin\machine_upgrade.dm" #include "code\modules\admin\NewBan.dm" +#include "code\modules\admin\outfits.dm" #include "code\modules\admin\player_panel.dm" #include "code\modules\admin\secrets.dm" #include "code\modules\admin\sql_notes.dm" @@ -1315,6 +1324,8 @@ #include "code\modules\client\preference\loadout\loadout_cosmetics.dm" #include "code\modules\client\preference\loadout\loadout_donor.dm" #include "code\modules\client\preference\loadout\loadout_general.dm" +#include "code\modules\client\preference\loadout\loadout_glasses.dm" +#include "code\modules\client\preference\loadout\loadout_gloves.dm" #include "code\modules\client\preference\loadout\loadout_hat.dm" #include "code\modules\client\preference\loadout\loadout_racial.dm" #include "code\modules\client\preference\loadout\loadout_shoes.dm" @@ -1329,6 +1340,7 @@ #include "code\modules\clothing\gloves\color.dm" #include "code\modules\clothing\gloves\miscellaneous.dm" #include "code\modules\clothing\gloves\rings.dm" +#include "code\modules\clothing\head\beanie.dm" #include "code\modules\clothing\head\collectable.dm" #include "code\modules\clothing\head\hardhat.dm" #include "code\modules\clothing\head\helmet.dm" @@ -1380,6 +1392,7 @@ #include "code\modules\clothing\suits\labcoat.dm" #include "code\modules\clothing\suits\miscellaneous.dm" #include "code\modules\clothing\suits\storage.dm" +#include "code\modules\clothing\suits\toggles.dm" #include "code\modules\clothing\suits\utility.dm" #include "code\modules\clothing\suits\wiz_robe.dm" #include "code\modules\clothing\under\color.dm" @@ -1396,10 +1409,16 @@ #include "code\modules\clothing\under\jobs\engineering.dm" #include "code\modules\clothing\under\jobs\medsci.dm" #include "code\modules\clothing\under\jobs\security.dm" +#include "code\modules\clothing\under\jobs\plasmamen\_plasmamen.dm" +#include "code\modules\clothing\under\jobs\plasmamen\civilian_service.dm" +#include "code\modules\clothing\under\jobs\plasmamen\engineering.dm" +#include "code\modules\clothing\under\jobs\plasmamen\medsci.dm" +#include "code\modules\clothing\under\jobs\plasmamen\security.dm" #include "code\modules\countdown\countdown.dm" #include "code\modules\crafting\craft.dm" #include "code\modules\crafting\guncrafting.dm" #include "code\modules\crafting\recipes.dm" +#include "code\modules\crafting\tailoring.dm" #include "code\modules\customitems\item_defines.dm" #include "code\modules\customitems\item_spawning.dm" #include "code\modules\detective_work\detective_work.dm" @@ -1441,6 +1460,7 @@ #include "code\modules\events\false_alarm.dm" #include "code\modules\events\floorcluwne.dm" #include "code\modules\events\grid_check.dm" +#include "code\modules\events\headcrabs.dm" #include "code\modules\events\immovable_rod.dm" #include "code\modules\events\infestation.dm" #include "code\modules\events\ion_storm.dm" @@ -1569,6 +1589,7 @@ #include "code\modules\hydroponics\grown\citrus.dm" #include "code\modules\hydroponics\grown\cocoa_vanilla.dm" #include "code\modules\hydroponics\grown\corn.dm" +#include "code\modules\hydroponics\grown\cotton.dm" #include "code\modules\hydroponics\grown\eggplant.dm" #include "code\modules\hydroponics\grown\flowers.dm" #include "code\modules\hydroponics\grown\grass_carpet.dm" @@ -1638,21 +1659,30 @@ #include "code\modules\martial_arts\sleeping_carp.dm" #include "code\modules\martial_arts\wrestleing.dm" #include "code\modules\mining\abandonedcrates.dm" -#include "code\modules\mining\coins.dm" -#include "code\modules\mining\equipment_locker.dm" -#include "code\modules\mining\explorer_gear.dm" +#include "code\modules\mining\fulton.dm" #include "code\modules\mining\machine_processing.dm" +#include "code\modules\mining\machine_redemption.dm" #include "code\modules\mining\machine_stacking.dm" #include "code\modules\mining\machine_unloading.dm" +#include "code\modules\mining\machine_vending.dm" #include "code\modules\mining\mine_items.dm" #include "code\modules\mining\minebot.dm" #include "code\modules\mining\mint.dm" #include "code\modules\mining\money_bag.dm" -#include "code\modules\mining\ore.dm" +#include "code\modules\mining\ores_coins.dm" #include "code\modules\mining\satchel_ore_boxdm.dm" #include "code\modules\mining\shelters.dm" +#include "code\modules\mining\equipment\explorer_gear.dm" +#include "code\modules\mining\equipment\kinetic_crusher.dm" +#include "code\modules\mining\equipment\lazarus_injector.dm" #include "code\modules\mining\equipment\marker_beacons.dm" +#include "code\modules\mining\equipment\mineral_scanner.dm" +#include "code\modules\mining\equipment\mining_tools.dm" +#include "code\modules\mining\equipment\regenerative_core.dm" +#include "code\modules\mining\equipment\resonator.dm" #include "code\modules\mining\equipment\survival_pod.dm" +#include "code\modules\mining\equipment\vendor_items.dm" +#include "code\modules\mining\equipment\wormhole_jaunter.dm" #include "code\modules\mining\laborcamp\laborshuttle.dm" #include "code\modules\mining\laborcamp\laborstacker.dm" #include "code\modules\mining\lavaland\ash_flora.dm" @@ -1919,6 +1949,7 @@ #include "code\modules\mob\living\simple_animal\hostile\floorcluwne.dm" #include "code\modules\mob\living\simple_animal\hostile\giant_spider.dm" #include "code\modules\mob\living\simple_animal\hostile\headcrab.dm" +#include "code\modules\mob\living\simple_animal\hostile\headslug.dm" #include "code\modules\mob\living\simple_animal\hostile\hellhound.dm" #include "code\modules\mob\living\simple_animal\hostile\hivebot.dm" #include "code\modules\mob\living\simple_animal\hostile\hostile.dm" @@ -1930,6 +1961,7 @@ #include "code\modules\mob\living\simple_animal\hostile\netherworld.dm" #include "code\modules\mob\living\simple_animal\hostile\pirate.dm" #include "code\modules\mob\living\simple_animal\hostile\russian.dm" +#include "code\modules\mob\living\simple_animal\hostile\skeleton.dm" #include "code\modules\mob\living\simple_animal\hostile\spaceworms.dm" #include "code\modules\mob\living\simple_animal\hostile\statue.dm" #include "code\modules\mob\living\simple_animal\hostile\syndicate.dm" @@ -2310,6 +2342,7 @@ #include "code\modules\ruins\ruin_areas.dm" #include "code\modules\ruins\lavalandruin_code\animal_hospital.dm" #include "code\modules\ruins\lavalandruin_code\ash_walker_den.dm" +#include "code\modules\ruins\lavalandruin_code\clown_planet.dm" #include "code\modules\ruins\lavalandruin_code\dead_ratvar.dm" #include "code\modules\ruins\lavalandruin_code\fountain_hall.dm" #include "code\modules\ruins\lavalandruin_code\hermit.dm" diff --git a/sound/creatures/headcrab_attack.ogg b/sound/creatures/headcrab_attack.ogg new file mode 100644 index 00000000000..4f6d114aa75 Binary files /dev/null and b/sound/creatures/headcrab_attack.ogg differ diff --git a/sound/creatures/zombie_attack.ogg b/sound/creatures/zombie_attack.ogg new file mode 100644 index 00000000000..1e9b2a63024 Binary files /dev/null and b/sound/creatures/zombie_attack.ogg differ diff --git a/sound/creatures/zombie_idle1.ogg b/sound/creatures/zombie_idle1.ogg new file mode 100644 index 00000000000..851c88deff4 Binary files /dev/null and b/sound/creatures/zombie_idle1.ogg differ diff --git a/sound/creatures/zombie_idle2.ogg b/sound/creatures/zombie_idle2.ogg new file mode 100644 index 00000000000..04e75da9b22 Binary files /dev/null and b/sound/creatures/zombie_idle2.ogg differ diff --git a/sound/creatures/zombie_idle3.ogg b/sound/creatures/zombie_idle3.ogg new file mode 100644 index 00000000000..b4cd2600757 Binary files /dev/null and b/sound/creatures/zombie_idle3.ogg differ diff --git a/sound/items/fultext_deploy.ogg b/sound/items/fultext_deploy.ogg new file mode 100644 index 00000000000..2433b9e0fe3 Binary files /dev/null and b/sound/items/fultext_deploy.ogg differ diff --git a/sound/items/fultext_launch.ogg b/sound/items/fultext_launch.ogg new file mode 100644 index 00000000000..2c874419927 Binary files /dev/null and b/sound/items/fultext_launch.ogg differ diff --git a/sound/weapons/baseball_hit.ogg b/sound/weapons/baseball_hit.ogg new file mode 100644 index 00000000000..6530945b6c1 Binary files /dev/null and b/sound/weapons/baseball_hit.ogg differ