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..36a5e25bbfd 100644 --- a/_maps/map_files/Delta/delta.dmm +++ b/_maps/map_files/Delta/delta.dmm @@ -31407,6 +31407,7 @@ id_tag = "s_docking_airlock"; req_access_txt = "48" }, +/obj/structure/fans/tiny, /turf/simulated/shuttle/floor, /area/shuttle/mining) "bgZ" = ( @@ -31431,6 +31432,7 @@ name = "mining shuttle bay"; width = 7 }, +/obj/structure/fans/tiny, /turf/simulated/shuttle/floor, /area/shuttle/mining) "bha" = ( @@ -34038,6 +34040,7 @@ name = "Mining Dock Airlock"; req_access_txt = "48" }, +/obj/structure/fans/tiny, /turf/simulated/floor/plasteel, /area/quartermaster/miningdock) "blH" = ( @@ -38843,6 +38846,7 @@ name = "Labor Shuttle Airlock"; req_access_txt = "2" }, +/obj/structure/fans/tiny, /turf/simulated/shuttle/floor{ icon_state = "floor4" }, @@ -38864,6 +38868,7 @@ name = "Labor Camp Airlock"; req_access_txt = "2" }, +/obj/structure/fans/tiny, /turf/simulated/floor/plasteel, /area/security/prisonershuttle) "btT" = ( @@ -41958,6 +41963,7 @@ name = "fore bay 1"; width = 9 }, +/obj/structure/fans/tiny, /turf/simulated/shuttle/floor, /area/shuttle/siberia) "bzg" = ( diff --git a/_maps/map_files/MetaStation/MetaStation.v41A.II.dmm b/_maps/map_files/MetaStation/MetaStation.v41A.II.dmm index 8bf89da81b2..0a054feb801 100644 --- a/_maps/map_files/MetaStation/MetaStation.v41A.II.dmm +++ b/_maps/map_files/MetaStation/MetaStation.v41A.II.dmm @@ -11722,6 +11722,7 @@ name = "Labor Camp Shuttle Airlock"; req_access_txt = "2" }, +/obj/structure/fans/tiny, /turf/simulated/floor/plasteel{ icon_state = "dark" }, @@ -14760,6 +14761,7 @@ id_tag = "s_docking_airlock"; name = "Labor Shuttle Airlock" }, +/obj/structure/fans/tiny, /turf/simulated/shuttle/floor{ icon_state = "floor4" }, @@ -14769,6 +14771,7 @@ id_tag = "laborcamp_home"; name = "Labor Camp Shuttle Airlock" }, +/obj/structure/fans/tiny, /turf/simulated/floor/plasteel{ icon_state = "dark" }, @@ -15638,6 +15641,7 @@ pixel_y = -25; req_access_txt = "2" }, +/obj/structure/fans/tiny, /turf/simulated/floor/plasteel{ icon_state = "dark" }, @@ -17546,6 +17550,7 @@ name = "mining shuttle bay"; width = 7 }, +/obj/structure/fans/tiny, /turf/simulated/shuttle/plating, /area/shuttle/mining) "aEJ" = ( @@ -17554,6 +17559,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 +17574,7 @@ name = "Mining Dock"; req_access_txt = "48" }, +/obj/structure/fans/tiny, /turf/simulated/floor/plasteel, /area/quartermaster/miningdock{ name = "\improper Mining Office" @@ -17814,6 +17821,7 @@ id_tag = "s_docking_airlock"; name = "Labor Shuttle Airlock" }, +/obj/structure/fans/tiny, /turf/simulated/shuttle/floor, /area/shuttle/siberia) "aFe" = ( @@ -17821,6 +17829,7 @@ id_tag = "laborcamp_home"; name = "Labor Camp Shuttle Airlock" }, +/obj/structure/fans/tiny, /turf/simulated/floor/plasteel{ icon_state = "dark" }, diff --git a/_maps/map_files/cyberiad/cyberiad.dmm b/_maps/map_files/cyberiad/cyberiad.dmm index f40f82a6ff3..73a88d1df69 100644 --- a/_maps/map_files/cyberiad/cyberiad.dmm +++ b/_maps/map_files/cyberiad/cyberiad.dmm @@ -2225,6 +2225,7 @@ icon_state = "1-2"; pixel_y = 0 }, +/obj/structure/fans/tiny, /turf/simulated/floor/plating, /area/security/prisonershuttle) "aeG" = ( @@ -11418,10 +11419,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 +11426,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 +12159,7 @@ name = "Labor Camp Airlock"; req_access_txt = "2" }, +/obj/structure/fans/tiny, /turf/simulated/floor/plating, /area/security/prisonershuttle) "auz" = ( @@ -12174,6 +12168,7 @@ name = "Labor Shuttle Airlock"; req_access_txt = "2" }, +/obj/structure/fans/tiny, /turf/simulated/shuttle/floor{ icon_state = "floor4" }, @@ -13181,16 +13176,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 +13199,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 +14333,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 +14529,7 @@ name = "fore bay 1"; width = 9 }, +/obj/structure/fans/tiny, /turf/simulated/shuttle/floor, /area/shuttle/siberia) "ayi" = ( @@ -17788,10 +17760,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 +18977,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 +20029,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 +20117,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 +20696,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 +20769,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 +21089,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 +21127,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 +21165,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 +22006,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 +22381,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 +22480,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 +22798,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 +22825,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 +22920,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" = ( @@ -23105,10 +22996,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 +23305,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 +23359,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 +25117,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 +25918,6 @@ d2 = 2; icon_state = "1-2" }, -/obj/effect/mapping_helpers/airlock/unres, /turf/simulated/floor/plating, /area/maintenance/fpmaint) "aVc" = ( @@ -26512,10 +26386,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 +27499,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{ @@ -29496,16 +29359,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"; @@ -30068,10 +29921,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" = ( @@ -31210,10 +31059,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" = ( @@ -31513,10 +31358,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; @@ -31587,10 +31428,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" = ( @@ -33844,7 +33681,6 @@ name = "Clown's Office"; req_access_txt = "46" }, -/obj/effect/mapping_helpers/airlock/unres, /turf/simulated/floor/wood, /area/clownoffice) "bjf" = ( @@ -33858,10 +33694,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" = ( @@ -33875,10 +33707,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" = ( @@ -37146,7 +36974,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" = ( @@ -37426,10 +37253,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" = ( @@ -40033,10 +39856,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" }, @@ -40313,10 +40132,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" = ( @@ -40719,10 +40534,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" = ( @@ -41516,10 +41327,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" = ( @@ -43424,10 +43231,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" = ( @@ -48801,20 +48604,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, @@ -48859,10 +48648,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" }, @@ -49728,7 +49513,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" = ( @@ -50010,7 +49794,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" = ( @@ -50671,7 +50454,6 @@ icon_state = "1-2"; tag = "" }, -/obj/effect/mapping_helpers/airlock/unres, /turf/simulated/floor/plating, /area/storage/emergency2) "bPs" = ( @@ -50730,10 +50512,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" = ( @@ -50928,10 +50706,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"; @@ -52146,10 +51920,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" = ( @@ -52632,7 +52402,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" }, @@ -52658,10 +52427,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" = ( @@ -54255,10 +54020,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" = ( @@ -54273,10 +54034,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" = ( @@ -54545,10 +54302,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" = ( @@ -55262,10 +55015,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" = ( @@ -55486,7 +55235,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" = ( @@ -56536,9 +56284,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 @@ -56551,6 +56296,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" = ( @@ -57305,7 +57053,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 @@ -57321,7 +57069,7 @@ normaldoorcontrol = 1; pixel_x = -4; pixel_y = -4; - req_access_txt = "20" + req_access_txt = "30" }, /turf/simulated/floor/plasteel{ dir = 2; @@ -58287,10 +58035,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" @@ -58368,10 +58112,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" @@ -58389,10 +58129,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" = ( @@ -63286,10 +63022,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" = ( @@ -63341,7 +63073,6 @@ tag = "" }, /obj/machinery/atmospherics/pipe/simple/hidden/supply, -/obj/effect/mapping_helpers/airlock/unres, /turf/simulated/floor/plating, /area/maintenance/apmaint) "cjE" = ( @@ -63728,6 +63459,7 @@ name = "mining shuttle bay"; width = 7 }, +/obj/structure/fans/tiny, /turf/simulated/shuttle/floor, /area/shuttle/mining) "ckl" = ( @@ -63736,6 +63468,7 @@ name = "Mining Dock Airlock"; req_access_txt = "48" }, +/obj/structure/fans/tiny, /turf/simulated/floor/plating, /area/quartermaster/miningdock) "ckm" = ( @@ -63744,6 +63477,7 @@ name = "Mining Dock Airlock"; req_access_txt = "48" }, +/obj/structure/fans/tiny, /turf/simulated/floor/plasteel, /area/quartermaster/miningdock) "ckn" = ( @@ -64006,7 +63740,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" = ( @@ -64050,7 +63783,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" = ( @@ -64066,7 +63798,6 @@ req_access_txt = "26" }, /obj/structure/disposalpipe/segment, -/obj/effect/mapping_helpers/airlock/unres, /turf/simulated/floor/plasteel, /area/janitor) "ckQ" = ( @@ -64100,7 +63831,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" = ( @@ -64188,7 +63918,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" = ( @@ -64964,10 +64693,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" = ( @@ -65387,7 +65112,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" @@ -66670,10 +66395,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" = ( @@ -67411,10 +67132,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" }, @@ -67598,10 +67315,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" }, @@ -67683,7 +67396,6 @@ /obj/machinery/door/airlock/maintenance{ req_access_txt = "12" }, -/obj/effect/mapping_helpers/airlock/unres, /turf/simulated/floor/plating, /area/maintenance/apmaint) "cqG" = ( @@ -69561,13 +69273,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{ @@ -69651,16 +69356,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; @@ -71702,10 +71397,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"; @@ -72359,16 +72050,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'"; @@ -72505,10 +72186,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" = ( @@ -72646,10 +72323,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" }, @@ -72956,10 +72629,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" = ( @@ -73660,10 +73329,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" = ( @@ -74106,10 +73771,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" = ( @@ -74707,16 +74368,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; @@ -74755,10 +74406,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" = ( @@ -75216,7 +74863,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" }, @@ -76078,10 +75724,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" = ( @@ -76615,10 +76257,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" = ( @@ -77116,7 +76754,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" = ( @@ -77623,10 +77260,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" = ( @@ -77779,10 +77412,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" = ( @@ -79008,10 +78637,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" }, @@ -80231,10 +79856,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" = ( @@ -81304,7 +80925,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" = ( @@ -84378,10 +83998,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" = ( @@ -88573,7 +88189,6 @@ /obj/machinery/door/airlock/maintenance{ req_access_txt = "12" }, -/obj/effect/mapping_helpers/airlock/unres, /turf/simulated/floor/plating, /area/maintenance/aft) "dbi" = ( @@ -88639,7 +88254,6 @@ tag = "" }, /obj/structure/disposalpipe/segment, -/obj/effect/mapping_helpers/airlock/unres, /turf/simulated/floor/plating, /area/maintenance/aft) "dbq" = ( @@ -89110,10 +88724,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" = ( @@ -89450,6 +89060,7 @@ req_access_txt = "0"; req_one_access_txt = "10;24" }, +/obj/structure/fans/tiny, /turf/simulated/floor/plating, /area/maintenance/engi_shuttle) "dcV" = ( @@ -89966,7 +89577,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" = ( @@ -89982,13 +89592,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{ @@ -90162,10 +89765,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" = ( @@ -90176,7 +89775,6 @@ icon_state = "1-2"; tag = "" }, -/obj/effect/mapping_helpers/airlock/unres, /turf/simulated/floor/plating, /area/maintenance/genetics) "deq" = ( @@ -90578,10 +90176,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" = ( @@ -91018,16 +90612,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{ @@ -91066,6 +90650,7 @@ name = "engineering dock"; width = 7 }, +/obj/structure/fans/tiny, /turf/simulated/floor/plating, /area/shuttle/constructionsite) "dga" = ( @@ -91098,15 +90683,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" = ( @@ -114518,7 +114098,7 @@ aaa cng coL coL -ctK +cqF coL cvk cwx @@ -115239,7 +114819,7 @@ aGn aGn aGn aGn -bbx +aLk aGn aGn aUy @@ -115289,7 +114869,7 @@ aaa cng coL coL -ctK +cqF coL coL cwx @@ -117093,7 +116673,7 @@ ctU cgQ cgQ cgQ -cCF +cqF cgQ cgQ cgQ @@ -118375,7 +117955,7 @@ cam aab cgQ ctU -ctK +cqF coL coL coL @@ -121980,7 +121560,7 @@ czN cyg cCH coL -ctK +cqF cEQ cGj cJZ @@ -126806,7 +126386,7 @@ avq avq avq avq -axN +aHp aRx aUw aDN @@ -128909,7 +128489,7 @@ cPd cos cPd cqY -ctD +cmt csL csL cvI @@ -130710,7 +130290,7 @@ csL cqD csL chf -cyu +cmt chf chf chf @@ -132958,7 +132538,7 @@ aIq avq aAc aBt -aGv +aHp aCh aEw aFI @@ -133723,7 +133303,7 @@ ajb awl arR awl -avU +aHp aqc aya awl @@ -135269,7 +134849,7 @@ avb aAQ awF aye -axN +aHp avq aAS atG @@ -137340,7 +136920,7 @@ aFJ aPq aRv aTb -aXT +aMn aGY aGY aGY @@ -139904,7 +139484,7 @@ aGX aHc aIv aGX -aOa +aMn aGX aGX aGX @@ -140417,10 +139997,10 @@ aCy aMf aNf aGY -aNe +aMn aGY aGY -aNe +aMn aGY aGY aPK @@ -140933,7 +140513,7 @@ aJI aGY aGX aGX -aKp +aMn aGX aGX aGY @@ -142470,14 +142050,14 @@ aab aAf aAf aAf -aKp +aMn aAf aHb aMz aMz aIE aGX -aKp +aMn aMz aGX aOG @@ -143520,7 +143100,7 @@ bcu ber bga bis -bMz +bvN bcD bld blw @@ -147194,7 +146774,7 @@ bGH bGG dgy bGG -dfW +cjA dia cuQ djQ @@ -148470,7 +148050,7 @@ aab bGH bGG bGG -ddY +cjA bGG dcJ ddJ @@ -148735,7 +148315,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 d04bf394f26..d3417ba50f3 100644 --- a/_maps/map_files/cyberiad/z2.dmm +++ b/_maps/map_files/cyberiad/z2.dmm @@ -12230,6 +12230,12 @@ "FL" = ( /turf/simulated/wall/r_wall, /area/adminconstruction) +"Ga" = ( +/obj/machinery/computer/shuttle/ert, +/turf/unsimulated/floor{ + icon_state = "dark" + }, +/area/centcom/specops) "GP" = ( /turf/unsimulated/floor{ icon_state = "gcircuit" @@ -31701,7 +31707,7 @@ pb uj uj uj -uj +Ga sX we we 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/code/__DEFINES/atmospherics.dm b/code/__DEFINES/atmospherics.dm index 67eea12291a..1ccb0cd0786 100644 --- a/code/__DEFINES/atmospherics.dm +++ b/code/__DEFINES/atmospherics.dm @@ -128,3 +128,6 @@ #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/misc.dm b/code/__DEFINES/misc.dm index 8491c589751..e29e5be1c56 100644 --- a/code/__DEFINES/misc.dm +++ b/code/__DEFINES/misc.dm @@ -57,6 +57,89 @@ #define MAX_STACK_AMOUNT_GLASS 50 #define MAX_STACK_AMOUNT_RODS 60 +//Colors +#define COLOR_RED "#FF0000" +#define COLOR_GREEN "#00FF00" +#define COLOR_BLUE "#0000FF" +#define COLOR_CYAN "#00FFFF" +#define COLOR_PINK "#FF00FF" +#define COLOR_YELLOW "#FFFF00" +#define COLOR_ORANGE "#FF9900" +#define COLOR_WHITE "#FFFFFF" +#define COLOR_GRAY "#808080" +#define COLOR_BLACK "#000000" +#define COLOR_NAVY_BLUE "#000080" +#define COLOR_LIGHT_GREEN "#008000" +#define COLOR_DARK_GRAY "#404040" +#define COLOR_MAROON "#800000" +#define COLOR_PURPLE "#800080" +#define COLOR_VIOLET "#9933ff" +#define COLOR_OLIVE "#808000" +#define COLOR_BROWN_ORANGE "#824b28" +#define COLOR_DARK_ORANGE "#b95a00" +#define COLOR_GRAY40 "#666666" +#define COLOR_GRAY20 "#333333" +#define COLOR_GRAY15 "#151515" +#define COLOR_SEDONA "#cc6600" +#define COLOR_DARK_BROWN "#917448" +#define COLOR_DEEP_SKY_BLUE "#00e1ff" +#define COLOR_LIME "#00ff00" +#define COLOR_TEAL "#33cccc" +#define COLOR_PALE_PINK "#bf89ba" +#define COLOR_YELLOW_GRAY "#c9a344" +#define COLOR_PALE_YELLOW "#c1bb7a" +#define COLOR_WARM_YELLOW "#b3863c" +#define COLOR_RED_GRAY "#aa5f61" +#define COLOR_BROWN "#b19664" +#define COLOR_GREEN_GRAY "#8daf6a" +#define COLOR_DARK_GREEN_GRAY "#54654c" +#define COLOR_BLUE_GRAY "#6a97b0" +#define COLOR_DARK_BLUE_GRAY "#3e4855" +#define COLOR_SUN "#ec8b2f" +#define COLOR_PURPLE_GRAY "#a2819e" +#define COLOR_BLUE_LIGHT "#33ccff" +#define COLOR_RED_LIGHT "#ff3333" +#define COLOR_BEIGE "#ceb689" +#define COLOR_BABY_BLUE "#89cff0" +#define COLOR_PALE_GREEN_GRAY "#aed18b" +#define COLOR_PALE_RED_GRAY "#cc9090" +#define COLOR_PALE_PURPLE_GRAY "#bda2ba" +#define COLOR_PALE_BLUE_GRAY "#8bbbd5" +#define COLOR_LUMINOL "#66ffff" +#define COLOR_SILVER "#c0c0c0" +#define COLOR_GRAY80 "#cccccc" +#define COLOR_OFF_WHITE "#eeeeee" +#define COLOR_GOLD "#6d6133" +#define COLOR_NT_RED "#9d2300" +#define COLOR_BOTTLE_GREEN "#1f6b4f" +#define COLOR_PALE_BTL_GREEN "#57967f" +#define COLOR_GUNMETAL "#545c68" +#define COLOR_WALL_GUNMETAL "#353a42" +#define COLOR_STEEL "#a8b0b2" +#define COLOR_MUZZLE_FLASH "#ffffb2" +#define COLOR_CHESTNUT "#996633" +#define COLOR_BEASTY_BROWN "#663300" +#define COLOR_WHEAT "#ffff99" +#define COLOR_CYAN_BLUE "#3366cc" +#define COLOR_LIGHT_CYAN "#66ccff" +#define COLOR_PAKISTAN_GREEN "#006600" +#define COLOR_HULL "#436b8e" +#define COLOR_AMBER "#ffbf00" +#define COLOR_COMMAND_BLUE "#46698c" +#define COLOR_SKY_BLUE "#5ca1cc" +#define COLOR_PALE_ORANGE "#b88a3b" +#define COLOR_CIVIE_GREEN "#b7f27d" +#define COLOR_TITANIUM "#d1e6e3" +#define COLOR_DARK_GUNMETAL "#4c535b" +#define COLOR_BRONZE "#8c7853" +#define COLOR_BRASS "#b99d71" +#define COLOR_INDIGO "#4b0082" +#define COLOR_ALUMINIUM "#bbbbbb" +#define COLOR_CRYSTAL "#00c8a5" +#define COLOR_ASTEROID_ROCK "#735555" +#define COLOR_NULLGLASS "#ff6088" +#define COLOR_DIAMOND "#d8d4ea" + //FONTS: // Used by Paper and PhotoCopier (and PaperBin once a year). // Used by PDA's Notekeeper. @@ -320,7 +403,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 @@ -404,6 +487,12 @@ #define DICE_BASICALLY_RIGGED 2 #define DICE_TOTALLY_RIGGED 3 +// 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" 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..a28d68a392b 100644 --- a/code/__DEFINES/preferences.dm +++ b/code/__DEFINES/preferences.dm @@ -63,3 +63,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/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/__HELPERS/game.dm b/code/__HELPERS/game.dm index 27b69284a3d..3bb6b742a04 100644 --- a/code/__HELPERS/game.dm +++ b/code/__HELPERS/game.dm @@ -19,6 +19,12 @@ return A return 0 +/proc/get_location_name(atom/X, format_text = FALSE) + var/area/A = isarea(X) ? X : get_area(X) + if(!A) + return null + return format_text ? format_text(A.name) : A.name + /proc/get_areas_in_range(dist=0, atom/center=usr) if(!dist) var/turf/T = get_turf(center) @@ -429,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/text.dm b/code/__HELPERS/text.dm index 04d63e0e862..08af11a128c 100644 --- a/code/__HELPERS/text.dm +++ b/code/__HELPERS/text.dm @@ -545,6 +545,43 @@ proc/checkhtml(var/t) text = copytext(text, 1, MAX_PAPER_MESSAGE_LEN) return text +/proc/convert_pencode_arg(text, tag, arg) + arg = sanitize_simple(html_encode(arg), list("''"="","\""="", "?"="")) + // https://cheatsheetseries.owasp.org/cheatsheets/Cross_Site_Scripting_Prevention_Cheat_Sheet.html#rule-4---css-escape-and-strictly-validate-before-inserting-untrusted-data-into-html-style-property-values + var/list/style_attacks = list("javascript:", "expression", "byond:", "file:") + + for(var/style_attack in style_attacks) + if(findtext(arg, style_attack)) + // Do not attempt to render dangerous things + return text + + if(tag == "class") + return "" + + if(tag == "style") + return "" + + if(tag == "img") + var/list/img_props = splittext(arg, ";") + if(img_props.len == 3) + return "" + if(img_props.len == 2) + return "" + return "" + + return text + +/proc/admin_pencode_to_html() + var/text = pencode_to_html(arglist(args)) + var/regex/R = new(@"\[(.*?) (.*?)\]", "ge") + text = R.Replace(text, /proc/convert_pencode_arg) + + text = replacetext(text, "\[/class\]", "") + text = replacetext(text, "\[/style\]", "") + text = replacetext(text, "\[/img\]", "") + + return text + /proc/html_to_pencode(text) text = replacetext(text, "
", "\n") text = replacetext(text, "
", "\[center\]") 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/_defines.dm b/code/_onclick/hud/_defines.dm index e3d423130e5..58e82733abe 100644 --- a/code/_onclick/hud/_defines.dm +++ b/code/_onclick/hud/_defines.dm @@ -107,14 +107,20 @@ #define ui_healthdoll "EAST-1:28,CENTER-1:15" #define ui_health "EAST-1:28,CENTER:17" #define ui_internal "EAST-1:28,CENTER+1:19" - //borgs + +//borgs #define ui_borg_health "EAST-1:28,CENTER-1:15" //borgs have the health display where humans have the pressure damage indicator. + +//aliens #define ui_alien_health "EAST-1:28,CENTER-1:15" //aliens have the health display where humans have the pressure damage indicator. - +//constructs #define ui_construct_pull "EAST-1:28,SOUTH+1:10" //above the zone_sel icon #define ui_construct_health "EAST,CENTER:15" //same height as humans, hugging the right border +//slimes +#define ui_slime_health "EAST,CENTER:15" //same as borgs, constructs and humans + //Pop-up inventory #define ui_shoes "WEST+1:8,SOUTH:5" diff --git a/code/_onclick/hud/action_button.dm b/code/_onclick/hud/action_button.dm index 15ed4429965..b70c98908f5 100644 --- a/code/_onclick/hud/action_button.dm +++ b/code/_onclick/hud/action_button.dm @@ -2,6 +2,25 @@ var/datum/action/linked_action screen_loc = null +/obj/screen/movable/action_button/MouseDrop(over_object) + if((istype(over_object, /obj/screen/movable/action_button) && !istype(over_object, /obj/screen/movable/action_button/hide_toggle))) + if(locked) + to_chat(usr, "Action button \"[name]\" is locked, unlock it first.") + closeToolTip(usr) + return + var/obj/screen/movable/action_button/B = over_object + var/list/actions = usr.actions + actions.Swap(actions.Find(linked_action), actions.Find(B.linked_action)) + moved = FALSE + B.moved = FALSE + closeToolTip(usr) + usr.update_action_buttons() + else if(istype(over_object, /obj/screen/movable/action_button/hide_toggle)) + closeToolTip(usr) + else + closeToolTip(usr) + return ..() + /obj/screen/movable/action_button/Click(location,control,params) var/list/modifiers = params2list(params) if(modifiers["shift"]) @@ -29,6 +48,13 @@ icon_state = "bg_default" var/hidden = 0 +/obj/screen/movable/action_button/hide_toggle/MouseDrop(over_object) + if(istype(over_object, /obj/screen/movable/action_button)) + closeToolTip(usr) + else + closeToolTip(usr) + return ..() + /obj/screen/movable/action_button/hide_toggle/Click(location,control,params) var/list/modifiers = params2list(params) if(modifiers["shift"]) @@ -83,9 +109,9 @@ var/image/img = image(icon, src, hidden ? "show" : "hide") overlays += img -/obj/screen/movable/action_button/MouseEntered(location,control,params) - openToolTip(usr,src,params,title = name,content = desc) - +/obj/screen/movable/action_button/MouseEntered(location, control, params) + if(!QDELETED(src)) + openToolTip(usr, src, params, title = name, content = desc) /obj/screen/movable/action_button/MouseExited() closeToolTip(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..46fe7331dbe --- /dev/null +++ b/code/_onclick/hud/parallax.dm @@ -0,0 +1,311 @@ +/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 = 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) + 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/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/hud/screen_objects.dm b/code/_onclick/hud/screen_objects.dm index a0274c30616..8bc65fcf691 100644 --- a/code/_onclick/hud/screen_objects.dm +++ b/code/_onclick/hud/screen_objects.dm @@ -456,6 +456,12 @@ /obj/screen/healths/corgi icon = 'icons/mob/screen_corgi.dmi' +/obj/screen/healths/slime + icon = 'icons/mob/screen_slime.dmi' + icon_state = "slime_health0" + screen_loc = ui_slime_health + mouse_opacity = MOUSE_OPACITY_TRANSPARENT + /obj/screen/healths/guardian name = "summoner health" icon = 'icons/mob/guardian.dmi' diff --git a/code/_onclick/hud/slime.dm b/code/_onclick/hud/slime.dm new file mode 100644 index 00000000000..9f5621b75ee --- /dev/null +++ b/code/_onclick/hud/slime.dm @@ -0,0 +1,18 @@ +/mob/living/carbon/slime/create_mob_hud() + if(client && !hud_used) + hud_used = new /datum/hud/slime(src) + +/mob/living/simple_animal/slime/create_mob_hud() + if(client && !hud_used) + hud_used = new /datum/hud/slime(src) + +/datum/hud/slime/New(mob/owner) + ..() + mymob.healths = new /obj/screen/healths/slime() + infodisplay += mymob.healths + + mymob.pullin = new /obj/screen/pull() + mymob.pullin.icon = 'icons/mob/screen_slime.dmi' + mymob.pullin.update_icon(mymob) + mymob.pullin.screen_loc = ui_construct_pull + hotkeybuttons += mymob.pullin diff --git a/code/_onclick/observer.dm b/code/_onclick/observer.dm index 797384b8336..a988277012b 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) 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/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/status_effects/buffs.dm b/code/datums/status_effects/buffs.dm index 387cc70f992..fb336192b38 100644 --- a/code/datums/status_effects/buffs.dm +++ b/code/datums/status_effects/buffs.dm @@ -40,6 +40,132 @@ 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 + var/last_health = 0 + var/last_bruteloss = 0 + var/last_fireloss = 0 + var/last_toxloss = 0 + var/last_oxyloss = 0 + var/last_cloneloss = 0 + var/last_staminaloss = 0 + +/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(.) + owner.maxHealth *= 10 + owner.bruteloss *= 10 + owner.fireloss *= 10 + if(ishuman(owner)) + var/mob/living/carbon/human/H = owner + for(var/X in H.bodyparts) + var/obj/item/organ/external/BP = X + BP.max_damage *= 10 + BP.min_broken_damage *= 10 + BP.brute_dam *= 10 + BP.burn_dam *= 10 + owner.toxloss *= 10 + owner.oxyloss *= 10 + owner.cloneloss *= 10 + owner.staminaloss *= 10 + owner.updatehealth() + last_health = owner.health + last_bruteloss = owner.getBruteLoss() + last_fireloss = owner.getFireLoss() + last_toxloss = owner.getToxLoss() + last_oxyloss = owner.getOxyLoss() + last_cloneloss = owner.getCloneLoss() + last_staminaloss = owner.getStaminaLoss() + 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/tick() //multiply the effect of healing by 10 + if(owner.health > last_health) + var/needs_health_update = FALSE + var/new_bruteloss = owner.getBruteLoss() + if(new_bruteloss < last_bruteloss) + var/heal_amount = (new_bruteloss - last_bruteloss) * 10 + owner.adjustBruteLoss(heal_amount, updating_health = FALSE) + new_bruteloss = owner.getBruteLoss() + needs_health_update = TRUE + last_bruteloss = new_bruteloss + + var/new_fireloss = owner.getFireLoss() + if(new_fireloss < last_fireloss) + var/heal_amount = (new_fireloss - last_fireloss) * 10 + owner.adjustFireLoss(heal_amount, updating_health = FALSE) + new_fireloss = owner.getFireLoss() + needs_health_update = TRUE + last_fireloss = new_fireloss + + var/new_toxloss = owner.getToxLoss() + if(new_toxloss < last_toxloss) + var/heal_amount = (new_toxloss - last_toxloss) * 10 + owner.adjustToxLoss(heal_amount, updating_health = FALSE) + new_toxloss = owner.getToxLoss() + needs_health_update = TRUE + last_toxloss = new_toxloss + + var/new_oxyloss = owner.getOxyLoss() + if(new_oxyloss < last_oxyloss) + var/heal_amount = (new_oxyloss - last_oxyloss) * 10 + owner.adjustOxyLoss(heal_amount, updating_health = FALSE) + new_oxyloss = owner.getOxyLoss() + needs_health_update = TRUE + last_oxyloss = new_oxyloss + + var/new_cloneloss = owner.getCloneLoss() + if(new_cloneloss < last_cloneloss) + var/heal_amount = (new_cloneloss - last_cloneloss) * 10 + owner.adjustCloneLoss(heal_amount, updating_health = FALSE) + new_cloneloss = owner.getCloneLoss() + needs_health_update = TRUE + last_cloneloss = new_cloneloss + + var/new_staminaloss = owner.getStaminaLoss() + if(new_staminaloss < last_staminaloss) + var/heal_amount = (new_staminaloss - last_staminaloss) * 10 + owner.adjustStaminaLoss(heal_amount, updating_health = FALSE) + new_staminaloss = owner.getStaminaLoss() + needs_health_update = TRUE + last_staminaloss = new_staminaloss + + if(needs_health_update) + owner.updatehealth() + owner.playsound_local(get_turf(owner), 'sound/effects/singlebeat.ogg', 40, 1) + last_health = owner.health + +/datum/status_effect/blooddrunk/on_remove() + tick() + owner.maxHealth *= 0.1 + owner.bruteloss *= 0.1 + owner.fireloss *= 0.1 + 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_dam *= 0.1 + BP.burn_dam *= 0.1 + BP.max_damage /= 10 + BP.min_broken_damage /= 10 + owner.toxloss *= 0.1 + owner.oxyloss *= 0.1 + owner.cloneloss *= 0.1 + owner.staminaloss *= 0.1 + owner.updatehealth() + 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/uplink_item.dm b/code/datums/uplink_item.dm index 4c1fb437046..f0ba75d5e10 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" 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/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/powers.dm b/code/game/gamemodes/blob/powers.dm index e7751ffcd8a..d6d4a91cf19 100644 --- a/code/game/gamemodes/blob/powers.dm +++ b/code/game/gamemodes/blob/powers.dm @@ -25,7 +25,8 @@ if(blob_nodes.len) var/list/nodes = list() for(var/i = 1; i <= blob_nodes.len; i++) - nodes["Blob Node #[i]"] = blob_nodes[i] + var/obj/structure/blob/node/B = blob_nodes[i] + nodes["Blob Node #[i] ([get_location_name(B)])"] = B var/node_name = input(src, "Choose a node to jump to.", "Node Jump") in nodes var/obj/structure/blob/node/chosen_node = nodes[node_name] if(chosen_node) diff --git a/code/game/gamemodes/cult/cult.dm b/code/game/gamemodes/cult/cult.dm index 021eb7461f5..9442c319dcb 100644 --- a/code/game/gamemodes/cult/cult.dm +++ b/code/game/gamemodes/cult/cult.dm @@ -29,7 +29,7 @@ var/global/list/all_cults = list() return 1 /proc/is_sacrifice_target(datum/mind/mind) - if(istype(SSticker.mode.name, "cult")) + if(SSticker.mode.name == "cult") var/datum/game_mode/cult/cult_mode = SSticker.mode if(mind == cult_mode.sacrifice_target) return 1 diff --git a/code/game/gamemodes/cult/cult_objectives.dm b/code/game/gamemodes/cult/cult_objectives.dm index da4e190cb7f..c31ebaf9b84 100644 --- a/code/game/gamemodes/cult/cult_objectives.dm +++ b/code/game/gamemodes/cult/cult_objectives.dm @@ -163,6 +163,16 @@ possible_sac_targets += player.mind return possible_sac_targets +// Handles the updating of sacrifice objectives after the sacrifice target goes to cryo and ghosts +/datum/game_mode/cult/proc/update_sac_objective(previous_target, previous_role) + for(var/datum/mind/cult_mind in cult) + if(cult_mind) + var/updated_memory = cult_mind.memory + updated_memory = replacetext("[cult_mind.memory]", "[previous_target]", "[sacrifice_target]") + updated_memory = replacetext("[updated_memory]", "[previous_role]", "[sacrifice_target.assigned_role]") + cult_mind.memory = updated_memory + + /datum/game_mode/cult/proc/pick_objective() var/list/possible_objectives = list() diff --git a/code/game/gamemodes/cult/talisman.dm b/code/game/gamemodes/cult/talisman.dm index 92fc09490ec..08633ef92f4 100644 --- a/code/game/gamemodes/cult/talisman.dm +++ b/code/game/gamemodes/cult/talisman.dm @@ -1,4 +1,5 @@ /obj/item/paper/talisman + icon = 'icons/obj/paper.dmi' icon_state = "paper_talisman" var/cultist_name = "talisman" var/cultist_desc = "A basic talisman. It serves no purpose." @@ -7,6 +8,9 @@ var/uses = 1 var/health_cost = 0 //The amount of health taken from the user when invoking the talisman +/obj/item/paper/talisman/update_icon()//overriding this so the update_icon doesn't turn them into normal looking paper + SEND_SIGNAL(src, COMSIG_OBJ_UPDATE_ICON) + /obj/item/paper/talisman/examine(mob/user) if(iscultist(user) || user.stat == DEAD) to_chat(user, "Name: [cultist_name]") @@ -49,6 +53,7 @@ //Supply Talisman: Has a few unique effects. Granted only to starter cultists. /obj/item/paper/talisman/supply cultist_name = "Supply Talisman" + icon_state = "supply" cultist_desc = "A multi-use talisman that can create various objects. Intended to increase the cult's strength early on." invocation = null uses = 3 @@ -117,6 +122,7 @@ //Rite of Translocation: Same as rune /obj/item/paper/talisman/teleport cultist_name = "Talisman of Teleportation" + icon_state = "teleport" cultist_desc = "A single-use talisman that will teleport a user to a random rune of the same keyword." invocation = "Sas'so c'arta forbici!" health_cost = 5 @@ -159,6 +165,7 @@ /obj/item/paper/talisman/summon_tome cultist_name = "Talisman of Tome Summoning" + icon_state = "tome" cultist_desc = "A one-use talisman that will call an untranslated tome from the archives of a cult." invocation = "N'ath reth sh'yro eth d'raggathnor!" health_cost = 1 @@ -173,6 +180,7 @@ /obj/item/paper/talisman/true_sight cultist_name = "Talisman of Veiling" + icon_state = "veil" cultist_desc = "A multi-use talisman that hides nearby runes. On its second use, will reveal nearby runes." invocation = "Kla'atu barada nikt'o!" health_cost = 1 @@ -197,6 +205,7 @@ //Rite of False Truths: Same as rune /obj/item/paper/talisman/make_runes_fake cultist_name = "Talisman of Disguising" + icon_state = "disguising" cultist_desc = "A talisman that will make nearby runes appear fake." invocation = "By'o nar'nar!" @@ -212,6 +221,7 @@ //Rite of Disruption: Weaker than rune /obj/item/paper/talisman/emp cultist_name = "Talisman of Electromagnetic Pulse" + icon_state = "emp" cultist_desc = "A talisman that will cause a moderately-sized electromagnetic pulse." invocation = "Ta'gh fara'qha fel d'amar det!" health_cost = 5 @@ -226,6 +236,7 @@ //Rite of Disorientation: Stuns and inhibit speech on a single target for quite some time /obj/item/paper/talisman/stun cultist_name = "Talisman of Stunning" + icon_state = "stunning" cultist_desc = "A talisman that will stun and inhibit speech on a single target. To use, attack target directly." invocation = "Dream sign:Evil sealing talisman!" health_cost = 10 @@ -271,6 +282,7 @@ //Rite of Arming: Equips cultist armor on the user, where available /obj/item/paper/talisman/armor cultist_name = "Talisman of Arming" + icon_state = "arming" cultist_desc = "A talisman that will equip the invoker with cultist equipment if there is a slot to equip it to." invocation = "N'ath reth sh'yro eth draggathnor!" @@ -301,6 +313,7 @@ //Talisman of Horrors: Breaks the mind of the victim with nightmarish hallucinations /obj/item/paper/talisman/horror cultist_name = "Talisman of Horrors" + icon_state = "horror" cultist_desc = "A talisman that will break the mind of the victim with nightmarish hallucinations." invocation = "Lo'Nab Na'Dm!" @@ -316,6 +329,7 @@ //Talisman of Fabrication: Creates a construct shell out of 25 metal sheets. /obj/item/paper/talisman/construction cultist_name = "Talisman of Construction" + icon_state = "construction" cultist_desc = "Use this talisman on at least twenty-five metal sheets to create an empty construct shell or on plasteel to make runed metal" invocation = "Ethra p'ni dedol!" uses = 25 @@ -360,6 +374,7 @@ //Talisman of Shackling: Applies special cuffs directly from the talisman /obj/item/paper/talisman/shackle cultist_name = "Talisman of Shackling" + icon_state = "shackling" cultist_desc = "Use this talisman on a victim to handcuff them with dark bindings." invocation = "In'totum Lig'abis!" uses = 4 diff --git a/code/game/gamemodes/wizard/wizard.dm b/code/game/gamemodes/wizard/wizard.dm index 5ac62401d23..131afd84fff 100644 --- a/code/game/gamemodes/wizard/wizard.dm +++ b/code/game/gamemodes/wizard/wizard.dm @@ -7,7 +7,8 @@ required_players = 20 required_enemies = 1 recommended_enemies = 1 - var/use_huds = 0 + var/use_huds = 1 + var/finished = 0 var/but_wait_theres_more = 0 @@ -157,22 +158,30 @@ wizard_mob.gene_stability += DEFAULT_GENE_STABILITY //magic return 1 +// Checks if the game should end due to all wizards and apprentices being dead, or MMI'd/Borged /datum/game_mode/wizard/check_finished() var/wizards_alive = 0 var/traitors_alive = 0 + + // Wizards for(var/datum/mind/wizard in wizards) if(!istype(wizard.current,/mob/living/carbon)) continue if(wizard.current.stat==DEAD) continue + if(istype(wizard.current, /obj/item/mmi)) // wizard is in an MMI, don't count them as alive + continue wizards_alive++ + // Apprentices - classified as "traitors" if(!wizards_alive) for(var/datum/mind/traitor in traitors) if(!istype(traitor.current,/mob/living/carbon)) continue if(traitor.current.stat==DEAD) continue + if(istype(traitor.current, /obj/item/mmi)) // apprentice is in an MMI, don't count them as alive + continue traitors_alive++ if(wizards_alive || traitors_alive || but_wait_theres_more) diff --git a/code/game/jobs/job/support.dm b/code/game/jobs/job/support.dm index 22c2d47e3b9..aac1c291355 100644 --- a/code/game/jobs/job/support.dm +++ b/code/game/jobs/job/support.dm @@ -175,23 +175,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 +211,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/constructable_frame.dm b/code/game/machinery/constructable_frame.dm index 9e91e254950..411a2d68d84 100644 --- a/code/game/machinery/constructable_frame.dm +++ b/code/game/machinery/constructable_frame.dm @@ -591,6 +591,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/cryopod.dm b/code/game/machinery/cryopod.dm index 17965c12f4c..f9d708a6200 100644 --- a/code/game/machinery/cryopod.dm +++ b/code/game/machinery/cryopod.dm @@ -371,6 +371,8 @@ for(var/datum/mind/H in SSticker.mode.cult) if(H.current) to_chat(H.current, "[SSticker.cultdat.entity_name] murmurs, [occupant] is beyond your reach. Sacrifice [cult_mode.sacrifice_target.current] instead...") + H.current << 'sound/ambience/alarm4.ogg' + cult_mode.update_sac_objective(occupant.mind, occupant.mind.assigned_role) else cult_mode.bypass_phase() diff --git a/code/game/machinery/doors/airlock.dm b/code/game/machinery/doors/airlock.dm index 17b6f9e55c8..b8c0f3d02f4 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 @@ -645,7 +639,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 +1097,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 +1115,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 +1131,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..ca9639319e3 100644 --- a/code/game/machinery/doors/door.dm +++ b/code/game/machinery/doors/door.dm @@ -14,7 +14,6 @@ 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 @@ -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/vending.dm b/code/game/machinery/vending.dm index 04e78e937aa..cf7937474c8 100644 --- a/code/game/machinery/vending.dm +++ b/code/game/machinery/vending.dm @@ -1132,7 +1132,6 @@ product_ads = "Go save some lives!;The best stuff for your medbay.;Only the finest tools.;Natural chemicals!;This stuff saves lives.;Don't you want some?" icon_state = "wallmed" icon_deny = "wallmed-deny" - req_access = list(access_medical) density = FALSE //It is wall-mounted, and thus, not dense. --Superxpdude products = list(/obj/item/stack/medical/bruise_pack = 2, /obj/item/stack/medical/ointment = 2, /obj/item/reagent_containers/hypospray/autoinjector = 4, /obj/item/healthanalyzer = 1) contraband = list(/obj/item/reagent_containers/syringe/charcoal = 4, /obj/item/reagent_containers/syringe/antiviral = 4, /obj/item/reagent_containers/food/pill/tox = 1) @@ -1143,7 +1142,6 @@ desc = "Wall-mounted Medical Equipment dispenser." icon_state = "wallmed" icon_deny = "wallmed-deny" - req_access = list(access_medical) density = FALSE //It is wall-mounted, and thus, not dense. --Superxpdude products = list(/obj/item/reagent_containers/hypospray/autoinjector = 5, /obj/item/reagent_containers/syringe/charcoal = 3, /obj/item/stack/medical/bruise_pack = 3, /obj/item/stack/medical/ointment = 3, /obj/item/healthanalyzer = 3) 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/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/contraband.dm b/code/game/objects/items/contraband.dm index 7ce7b07193d..77aef9bb71d 100644 --- a/code/game/objects/items/contraband.dm +++ b/code/game/objects/items/contraband.dm @@ -4,6 +4,7 @@ /obj/item/storage/pill_bottle/happy name = "Happy pills" desc = "Highly illegal drug. When you want to see the rainbow." + wrapper_color = COLOR_PINK /obj/item/storage/pill_bottle/happy/New() ..() @@ -18,6 +19,7 @@ /obj/item/storage/pill_bottle/zoom name = "Zoom pills" desc = "Highly illegal drug. Trade brain for speed." + wrapper_color = COLOR_BLUE /obj/item/storage/pill_bottle/zoom/New() ..() @@ -49,15 +51,12 @@ adulterants-- reagents.add_reagent(pick_list("chemistry_tools.json", "CYBERPUNK_drug_adulterants"), 3) - - /obj/item/storage/pill_bottle/random_drug_bottle name = "pill bottle (???)" desc = "Huh." + allow_wrap = FALSE /obj/item/storage/pill_bottle/random_drug_bottle/New() ..() for(var/i in 1 to 5) new /obj/item/reagent_containers/food/pill/random_drugs(src) - - diff --git a/code/game/objects/items/devices/scanners.dm b/code/game/objects/items/devices/scanners.dm index cad4ae25ac8..0400763b7f2 100644 --- a/code/game/objects/items/devices/scanners.dm +++ b/code/game/objects/items/devices/scanners.dm @@ -273,6 +273,8 @@ REAGENT SCANNER 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 587b1d27d14..e51bac10005 100644 --- a/code/game/objects/items/random_items.dm +++ b/code/game/objects/items/random_items.dm @@ -123,6 +123,7 @@ /obj/item/storage/pill_bottle/random_meds name = "unlabelled pillbottle" desc = "The sheer recklessness of this bottle's existence astounds you." + allow_wrap = FALSE var/labelled = FALSE /obj/item/storage/pill_bottle/random_meds/New() diff --git a/code/game/objects/items/stacks/sheets/sheet_types.dm b/code/game/objects/items/stacks/sheets/sheet_types.dm index 9ec921fef92..f7df69cad2f 100644 --- a/code/game/objects/items/stacks/sheets/sheet_types.dm +++ b/code/game/objects/items/stacks/sheets/sheet_types.dm @@ -178,8 +178,12 @@ 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("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 diff --git a/code/game/objects/items/weapons/dice.dm b/code/game/objects/items/weapons/dice.dm index 084dac30a60..736ba1cc767 100644 --- a/code/game/objects/items/weapons/dice.dm +++ b/code/game/objects/items/weapons/dice.dm @@ -4,6 +4,7 @@ icon = 'icons/obj/dice.dmi' icon_state = "dicebag" can_hold = list(/obj/item/dice) + allow_wrap = FALSE /obj/item/storage/pill_bottle/dice/New() ..() 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/boxes.dm b/code/game/objects/items/weapons/storage/boxes.dm index e7342774619..3fe5c140407 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." diff --git a/code/game/objects/items/weapons/storage/firstaid.dm b/code/game/objects/items/weapons/storage/firstaid.dm index fab82df4b4e..8d8cb77e597 100644 --- a/code/game/objects/items/weapons/storage/firstaid.dm +++ b/code/game/objects/items/weapons/storage/firstaid.dm @@ -254,10 +254,21 @@ var/applying_meds = FALSE //To Prevent spam clicking and generating runtimes from apply a deleting pill multiple times. var/rapid_intake_message = "unscrews the cap on the pill bottle and begins dumping the entire contents down their throat!" var/rapid_post_instake_message = "downs the entire bottle of pills in one go!" + var/allow_wrap = TRUE + var/wrapper_color = null /obj/item/storage/pill_bottle/New() ..() base_name = name + if(allow_wrap) + apply_wrap() + +/obj/item/storage/pill_bottle/proc/apply_wrap() + if(wrapper_color) + overlays.Cut() + var/image/I = image(icon, "pillbottle_wrap") + I.color = wrapper_color + overlays += I /obj/item/storage/pill_bottle/attack(mob/M, mob/user) if(iscarbon(M) && contents.len) @@ -274,6 +285,9 @@ else return ..() +/obj/item/storage/pill_bottle/ert + wrapper_color = COLOR_MAROON + /obj/item/storage/pill_bottle/ert/New() ..() new /obj/item/reagent_containers/food/pill/salicylic(src) @@ -319,15 +333,18 @@ /obj/item/storage/pill_bottle/patch_pack name = "Patch Pack" + desc = "It's a container for storing medical patches." icon_state = "patch_pack" can_hold = list(/obj/item/reagent_containers/food/pill/patch) cant_hold = list() rapid_intake_message = "flips the lid of the Patch Pack open and begins rapidly stamping patches on themselves!" rapid_post_instake_message = "stamps the entire contents of the Patch Pack all over their entire body!" + allow_wrap = FALSE /obj/item/storage/pill_bottle/charcoal name = "Pill bottle (Charcoal)" desc = "Contains pills used to counter toxins." + wrapper_color = COLOR_GREEN New() ..() @@ -342,6 +359,7 @@ /obj/item/storage/pill_bottle/painkillers name = "Pill Bottle (Salicylic Acid)" desc = "Contains various pills for minor pain relief." + wrapper_color = COLOR_RED /obj/item/storage/pill_bottle/painkillers/New() ..() @@ -354,8 +372,11 @@ new /obj/item/reagent_containers/food/pill/salicylic(src) new /obj/item/reagent_containers/food/pill/salicylic(src) +/obj/item/storage/pill_bottle/fakedeath + allow_wrap = FALSE + /obj/item/storage/pill_bottle/fakedeath/New() ..() new /obj/item/reagent_containers/food/pill/fakedeath(src) new /obj/item/reagent_containers/food/pill/fakedeath(src) - new /obj/item/reagent_containers/food/pill/fakedeath(src) \ No newline at end of file + new /obj/item/reagent_containers/food/pill/fakedeath(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 f998cbff801..189cbc5893d 100644 --- a/code/game/objects/structures/crates_lockers/closets/secure/medical.dm +++ b/code/game/objects/structures/crates_lockers/closets/secure/medical.dm @@ -110,6 +110,7 @@ /obj/item/storage/pill_bottle/psychiatrist name = "psychiatrist's pill bottle" desc = "Contains various pills to calm or sedate patients." + wrapper_color = COLOR_PALE_BTL_GREEN /obj/item/storage/pill_bottle/psychiatrist/New() ..() 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/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/stool_bed_chair_nest/chairs.dm b/code/game/objects/structures/stool_bed_chair_nest/chairs.dm index 005f0e721fb..15e578ed88f 100644 --- a/code/game/objects/structures/stool_bed_chair_nest/chairs.dm +++ b/code/game/objects/structures/stool_bed_chair_nest/chairs.dm @@ -64,6 +64,12 @@ if(usr.incapacitated()) to_chat(usr, "You can't do that right now!") return + if(!usr.has_right_hand() && !usr.has_left_hand()) + to_chat(usr, "You try to grab the chair, but you are missing both of your hands!") + return + if(usr.get_active_hand() && usr.get_inactive_hand()) + to_chat(usr, "You try to grab the chair, but your hands are already full!") + return if(!ishuman(usr)) return usr.visible_message("[usr] grabs \the [src.name].", "You grab \the [src.name].") 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..12b1654994c 100644 --- a/code/game/turfs/simulated/floor/fancy_floor.dm +++ b/code/game/turfs/simulated/floor/fancy_floor.dm @@ -117,6 +117,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 +130,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 +141,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/plating.dm b/code/game/turfs/simulated/floor/plating.dm index 2ef4602d268..9ff6ddb8876 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,7 +72,16 @@ to_chat(user, "This section is too damaged to support a tile! Use a welder to fix the damage.") return TRUE - else if(iswelder(C)) + 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) && unfastened) var/obj/item/weldingtool/welder = C if(welder.isOn()) if(!welder.remove_fuel(0, user)) 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/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..51285932f00 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 diff --git a/code/modules/admin/admin_verbs.dm b/code/modules/admin/admin_verbs.dm index 7687b22f71c..1176e733dde 100644 --- a/code/modules/admin/admin_verbs.dm +++ b/code/modules/admin/admin_verbs.dm @@ -644,7 +644,7 @@ var/list/admin_verbs_ticket = list( if(!message) return for(var/mob/V in hearers(O)) - V.show_message(message, 2) + V.show_message(admin_pencode_to_html(message), 2) log_admin("[key_name(usr)] made [O] at [O.x], [O.y], [O.z] make a sound") message_admins("[key_name_admin(usr)] made [O] at [O.x], [O.y], [O.z] make a sound") feedback_add_details("admin_verb","MS") //If you are copy-pasting this, ensure the 2nd parameter is unique to the new proc! diff --git a/code/modules/admin/topic.dm b/code/modules/admin/topic.dm index e45224b175b..be136204739 100644 --- a/code/modules/admin/topic.dm +++ b/code/modules/admin/topic.dm @@ -2186,7 +2186,7 @@ if(!input) qdel(P) return - input = P.parsepencode(input) // Encode everything from pencode to html + input = admin_pencode_to_html(html_encode(input)) // Encode everything from pencode to html var/customname = clean_input("Pick a title for the fax.", "Fax Title", , owner) if(!customname) diff --git a/code/modules/admin/verbs/adminpm.dm b/code/modules/admin/verbs/adminpm.dm index 2352c442313..1069e981c37 100644 --- a/code/modules/admin/verbs/adminpm.dm +++ b/code/modules/admin/verbs/adminpm.dm @@ -110,7 +110,7 @@ if(!msg) return else - msg = pencode_to_html(msg) + msg = admin_pencode_to_html(msg) var/recieve_span = "playerreply" var/send_pm_type = " " @@ -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/randomverbs.dm b/code/modules/admin/verbs/randomverbs.dm index b8d93950843..2c7c6181b1d 100644 --- a/code/modules/admin/verbs/randomverbs.dm +++ b/code/modules/admin/verbs/randomverbs.dm @@ -58,6 +58,9 @@ if(!msg) return + + msg = admin_pencode_to_html(msg) + if(usr) if(usr.client) if(usr.client.holder) @@ -136,7 +139,7 @@ if( !msg ) return - msg = pencode_to_html(msg) + msg = admin_pencode_to_html(msg) to_chat(M, msg) log_admin("DirectNarrate: [key_name(usr)] to ([key_name(M)]): [msg]") diff --git a/code/modules/awaymissions/mission_code/academy.dm b/code/modules/awaymissions/mission_code/academy.dm index d15b3e3075d..e41e29a747f 100644 --- a/code/modules/awaymissions/mission_code/academy.dm +++ b/code/modules/awaymissions/mission_code/academy.dm @@ -193,7 +193,7 @@ servant_mind.objectives += O servant_mind.transfer_to(H) - var/list/mob/dead/observer/candidates = pollCandidates("Do you want to play as the servant of [user.real_name]?", ROLE_WIZARD, poll_time = 50) + var/list/mob/dead/observer/candidates = pollCandidates("Do you want to play as the servant of [user.real_name]?", ROLE_WIZARD, poll_time = 300) if(LAZYLEN(candidates)) var/mob/dead/observer/C = pick(candidates) message_admins("[ADMIN_LOOKUPFLW(C)] was spawned as Dice Servant") diff --git a/code/modules/client/client procs.dm b/code/modules/client/client procs.dm index 95f6c16ba97..2d4092ff159 100644 --- a/code/modules/client/client procs.dm +++ b/code/modules/client/client procs.dm @@ -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/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/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/suits/armor.dm b/code/modules/clothing/suits/armor.dm index 96c2ed46f7a..ae8502f7246 100644 --- a/code/modules/clothing/suits/armor.dm +++ b/code/modules/clothing/suits/armor.dm @@ -527,14 +527,15 @@ 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) + 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 -/obj/item/clothing/head/skullhelmet +/obj/item/clothing/head/helmet/skull name = "skull helmet" desc = "An intimidating tribal helmet, it doesn't look very comfortable." - flags = BLOCKHAIR + 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, "fire" = 40, "acid" = 20) + armor = list(melee = 25, bullet = 25, laser = 25, energy = 10, bomb = 10, bio = 5, rad = 20) icon_state = "skull" - item_state = "skull" \ No newline at end of file + item_state = "skull" + strip_delay = 100 \ No newline at end of file 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/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/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/mining/equipment/kinetic_crusher.dm b/code/modules/mining/equipment/kinetic_crusher.dm new file mode 100644 index 00000000000..47b3fb01501 --- /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.drop_item()) + 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_locker.dm b/code/modules/mining/equipment_locker.dm index 1001a2aa514..37569b7b58e 100644 --- a/code/modules/mining/equipment_locker.dm +++ b/code/modules/mining/equipment_locker.dm @@ -400,54 +400,57 @@ 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), + 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", /obj/item/tank/jetpack/carbondioxide/mining, 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 @@ -599,16 +602,14 @@ ..() /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/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 = loc + var/drop_location = drop_location() 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") @@ -618,13 +619,15 @@ 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/required/kinetic_crusher(drop_location) + new /obj/item/twohanded/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) @@ -688,14 +691,16 @@ /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/clothing/suit/hooded/explorer(src) new /obj/item/encryptionkey/headset_cargo(src) - new /obj/item/clothing/mask/gas(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) /**********************Jaunter**********************/ @@ -786,30 +791,20 @@ 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 + force = 15 throwforce = 10 - var/cooldown = 0 - var/fieldsactive = 0 - var/burst_time = 50 - var/fieldlimit = 3 + 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 = 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-- + fieldlimit = 6 + quick_burst_mod = 1 /obj/item/resonator/attack_self(mob/user) if(burst_time == 50) @@ -819,48 +814,88 @@ 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/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/effect/resonance +/obj/item/resonator/pre_attackby(atom/target, mob/user, params) + if(check_allowed_items(target, 1)) + CreateResonance(target, user) + return TRUE + +/obj/effect/temp_visual/resonance name = "resonance field" - desc = "A resonating field that significantly damages anything inside of it when the field eventually ruptures." + 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 = 4.1 - mouse_opacity = MOUSE_OPACITY_TRANSPARENT + duration = 50 var/resonance_damage = 20 + var/damage_multiplier = 1 + var/creator + var/obj/item/resonator/res -/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) +/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 - 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) + 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) /**********************Facehugger toy**********************/ @@ -1113,103 +1148,4 @@ 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) + qdel(src) \ No newline at end of file diff --git a/code/modules/mining/explorer_gear.dm b/code/modules/mining/explorer_gear.dm index a9464efe959..566694d480d 100644 --- a/code/modules/mining/explorer_gear.dm +++ b/code/modules/mining/explorer_gear.dm @@ -41,4 +41,57 @@ "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 + ) + +/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/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/necropolis_chests.dm b/code/modules/mining/lavaland/necropolis_chests.dm index 7eed5577aeb..ab9b7979d03 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,25) + switch(loot) if(1) new /obj/item/shared_storage/red(src) if(2) @@ -37,7 +37,10 @@ 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) @@ -54,7 +57,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) @@ -73,6 +79,9 @@ 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/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/mine_items.dm b/code/modules/mining/mine_items.dm index f10b78dc526..87b919ea238 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**************************/ @@ -122,6 +111,15 @@ 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" diff --git a/code/modules/mining/minebot.dm b/code/modules/mining/minebot.dm index 5b20aad5047..2ff2a686439 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,41 +284,24 @@ 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" @@ -307,6 +310,20 @@ 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 #undef MINEDRONE_COLLECT #undef MINEDRONE_ATTACK diff --git a/code/modules/mob/dead/observer/observer.dm b/code/modules/mob/dead/observer/observer.dm index 731f53c7838..ab855b5dc80 100644 --- a/code/modules/mob/dead/observer/observer.dm +++ b/code/modules/mob/dead/observer/observer.dm @@ -236,6 +236,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 +418,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 +513,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.") diff --git a/code/modules/mob/living/carbon/human/update_icons.dm b/code/modules/mob/living/carbon/human/update_icons.dm index 73a76e00420..d573d2a8191 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 @@ -769,6 +770,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 +822,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 +891,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) @@ -951,6 +958,8 @@ var/global/list/damage_icon_parts = list() 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 +982,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) diff --git a/code/modules/mob/living/carbon/slime/slime.dm b/code/modules/mob/living/carbon/slime/slime.dm index 914c810da27..38dadbbbfa7 100644 --- a/code/modules/mob/living/carbon/slime/slime.dm +++ b/code/modules/mob/living/carbon/slime/slime.dm @@ -146,6 +146,44 @@ stat(null,"Power Level: [powerlevel]") +/mob/living/carbon/slime/updatehealth(reason) + . = ..() + update_health_hud() + +/mob/living/carbon/slime/proc/update_health_hud() + if(hud_used) + var/severity = 0 + var/healthpercent = (health/maxHealth) * 100 + if(stat != DEAD) + switch(healthpercent) + if(100 to INFINITY) + healths.icon_state = "slime_health0" + if(80 to 100) + healths.icon_state = "slime_health1" + severity = 1 + if(60 to 80) + healths.icon_state = "slime_health2" + severity = 2 + if(40 to 60) + healths.icon_state = "slime_health3" + severity = 3 + if(20 to 40) + healths.icon_state = "slime_health4" + severity = 4 + if(0 to 20) + healths.icon_state = "slime_health5" + severity = 5 + if(-199 to 0) + healths.icon_state = "slime_health6" + severity = 6 + else + healths.icon_state = "slime_health7" + severity = 6 + if(severity > 0) + overlay_fullscreen("brute", /obj/screen/fullscreen/brute, severity) + else + clear_fullscreen("brute") + /mob/living/carbon/slime/adjustFireLoss(amount) ..(-abs(amount)) // Heals them return 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/living.dm b/code/modules/mob/living/living.dm index f9dba949b4b..57c67f5fd61 100644 --- a/code/modules/mob/living/living.dm +++ b/code/modules/mob/living/living.dm @@ -256,8 +256,10 @@ death() to_chat(src, "You have given up life and succumbed to death.") + /mob/living/proc/InCritical() return (health < HEALTH_THRESHOLD_CRIT && health > HEALTH_THRESHOLD_DEAD && stat == UNCONSCIOUS) + /mob/living/ex_act(severity) ..() 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/robot/robot.dm b/code/modules/mob/living/silicon/robot/robot.dm index 131477d086e..b9ed81f7180 100644 --- a/code/modules/mob/living/silicon/robot/robot.dm +++ b/code/modules/mob/living/silicon/robot/robot.dm @@ -576,6 +576,8 @@ var/list/robot_verbs_default = list( /mob/living/silicon/robot/restrained() return 0 +/mob/living/silicon/robot/InCritical() + return low_power_mode /mob/living/silicon/robot/ex_act(severity) switch(severity) diff --git a/code/modules/mob/living/silicon/silicon.dm b/code/modules/mob/living/silicon/silicon.dm index 2cb9ddf6252..bac58d8f124 100644 --- a/code/modules/mob/living/silicon/silicon.dm +++ b/code/modules/mob/living/silicon/silicon.dm @@ -337,4 +337,5 @@ /////////////////////////////////// EAR DAMAGE //////////////////////////////////// /mob/living/silicon/can_hear() - . = TRUE \ No newline at end of file + . = TRUE + diff --git a/code/modules/mob/living/simple_animal/friendly/slime.dm b/code/modules/mob/living/simple_animal/friendly/slime.dm index 13e7c893d86..ac913170c86 100644 --- a/code/modules/mob/living/simple_animal/friendly/slime.dm +++ b/code/modules/mob/living/simple_animal/friendly/slime.dm @@ -12,8 +12,8 @@ response_disarm = "shoos" response_harm = "stomps on" emote_see = list("jiggles", "bounces in place") - var/colour = "grey" pass_flags = PASSTABLE + var/colour = "grey" /mob/living/simple_animal/slime/adult health = 200 @@ -24,3 +24,37 @@ /mob/living/simple_animal/slime/New() ..() overlays += "aslime-:33" + +/mob/living/simple_animal/slime/updatehealth(reason) + . = ..() + update_health_hud() + +/mob/living/simple_animal/slime/proc/update_health_hud() + if(hud_used) + var/severity = 0 + var/healthpercent = (health/maxHealth) * 100 + switch(healthpercent) + if(100 to INFINITY) + healths.icon_state = "slime_health0" + if(80 to 100) + healths.icon_state = "slime_health1" + severity = 1 + if(60 to 80) + healths.icon_state = "slime_health2" + severity = 2 + if(40 to 60) + healths.icon_state = "slime_health3" + severity = 3 + if(20 to 40) + healths.icon_state = "slime_health4" + severity = 4 + if(1 to 20) + healths.icon_state = "slime_health5" + severity = 5 + else + healths.icon_state = "slime_health7" + severity = 6 + if(severity > 0) + overlay_fullscreen("brute", /obj/screen/fullscreen/brute, severity) + else + clear_fullscreen("brute") 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 60c1f5e08e7..c90a06a9fb8 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) @@ -231,6 +234,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 @@ -403,7 +407,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/netherworld.dm b/code/modules/mob/living/simple_animal/hostile/netherworld.dm index fc39035618e..70d279fd400 100644 --- a/code/modules/mob/living/simple_animal/hostile/netherworld.dm +++ b/code/modules/mob/living/simple_animal/hostile/netherworld.dm @@ -69,6 +69,7 @@ desc = null //see examine() icon_state = "nether" health = 50 + maxHealth = 50 spawn_time = 600 //1 minute max_mobs = 15 icon = 'icons/mob/nest.dmi' @@ -76,9 +77,9 @@ mob_types = list(/mob/living/simple_animal/hostile/netherworld/migo, /mob/living/simple_animal/hostile/netherworld, /mob/living/simple_animal/hostile/netherworld/blankbody) faction = list("nether") -/mob/living/simple_animal/hostile/spawner/nether/Initialize() - .=..() - START_PROCESSING(SSprocessing, src) +/mob/living/simple_animal/hostile/spawner/nether/death() + . = ..() + qdel(src) /mob/living/simple_animal/hostile/spawner/nether/examine(mob/user) ..() @@ -96,7 +97,8 @@ "Touching the portal, you are quickly pulled through into a world of unimaginable horror!") contents.Add(user) -/mob/living/simple_animal/hostile/spawner/nether/process() +/mob/living/simple_animal/hostile/spawner/nether/Life() + . = ..() for(var/mob/living/M in contents) if(M) playsound(src, 'sound/magic/demon_consume.ogg', 50, 1) diff --git a/code/modules/paperwork/paper.dm b/code/modules/paperwork/paper.dm index cf021cb2618..9e844d6cf21 100644 --- a/code/modules/paperwork/paper.dm +++ b/code/modules/paperwork/paper.dm @@ -54,8 +54,6 @@ /obj/item/paper/update_icon() ..() - if(icon_state == "paper_talisman") - return if(info) icon_state = "paper_words" return 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..eea2c2253e8 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 @@ -233,11 +254,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 +286,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 +297,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 +355,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/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..6e4de3c49fa 100644 --- a/code/modules/projectiles/guns/energy.dm +++ b/code/modules/projectiles/guns/energy.dm @@ -140,6 +140,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..d214309728e 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,24 +109,25 @@ 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 @@ -138,6 +151,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 +176,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 +186,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 +197,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 +226,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 +253,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 +264,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 +275,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 +310,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 +341,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 +354,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 +421,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 +588,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/special.dm b/code/modules/projectiles/guns/energy/special.dm index fa34753c6a9..be60248cded 100644 --- a/code/modules/projectiles/guns/energy/special.dm +++ b/code/modules/projectiles/guns/energy/special.dm @@ -175,7 +175,7 @@ power_supply.give(500) to_chat(user, "You insert [A] in [src], recharging it.") else - ..() + return ..() /obj/item/gun/energy/plasmacutter/update_icon() return 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..b9bdb0c9701 100644 --- a/code/modules/projectiles/guns/projectile/saw.dm +++ b/code/modules/projectiles/guns/projectile/saw.dm @@ -50,14 +50,15 @@ 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 - ..() + else + return ..() //ammo// diff --git a/code/modules/projectiles/guns/projectile/shotgun.dm b/code/modules/projectiles/guns/projectile/shotgun.dm index 366b9b6579f..46286bef2af 100644 --- a/code/modules/projectiles/guns/projectile/shotgun.dm +++ b/code/modules/projectiles/guns/projectile/shotgun.dm @@ -86,7 +86,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 +94,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 +211,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 +246,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/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/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..de11cb557a9 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) @@ -244,18 +246,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 +258,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/chem_master.dm b/code/modules/reagents/chemistry/machinery/chem_master.dm index 36605867781..48b76b0de98 100644 --- a/code/modules/reagents/chemistry/machinery/chem_master.dm +++ b/code/modules/reagents/chemistry/machinery/chem_master.dm @@ -133,6 +133,39 @@ if(loaded_pill_bottle) loaded_pill_bottle.forceMove(loc) loaded_pill_bottle = null + else if(href_list["change_pillbottle"]) + if(loaded_pill_bottle) + var/list/wrappers = list("Default wrapper", "Red wrapper", "Green wrapper", "Pale green wrapper", "Blue wrapper", "Light blue wrapper", "Teal wrapper", "Yellow wrapper", "Orange wrapper", "Pink wrapper", "Brown wrapper") + var/chosen = input(usr, "Select a pillbottle wrapper", "Pillbottle wrapper", wrappers[1]) as null|anything in wrappers + if(!chosen) + return + var/color + switch(chosen) + if("Default wrapper") + loaded_pill_bottle.cut_overlays() + return + if("Red wrapper") + color = COLOR_RED + if("Green wrapper") + color = COLOR_GREEN + if("Pink wrapper") + color = COLOR_PINK + if("Teal wrapper") + color = COLOR_TEAL + if("Blue wrapper") + color = COLOR_BLUE + if("Brown wrapper") + color = COLOR_MAROON + if("Light blue wrapper") + color = COLOR_CYAN_BLUE + if("Yellow wrapper") + color = COLOR_YELLOW + if("Pale green wrapper") + color = COLOR_PALE_BTL_GREEN + if("Orange wrapper") + color = COLOR_ORANGE + loaded_pill_bottle.wrapper_color = color; + loaded_pill_bottle.apply_wrap(); else if(href_list["close"]) usr << browse(null, "window=chem_master") onclose(usr, "chem_master") @@ -185,7 +218,7 @@ dat += "(Back)" else dat += "Condimaster 3000Condiment infos:

Name:
[href_list["name"]]

Description:
[href_list["desc"]]


(Back)" - usr << browse(dat, "window=chem_master;size=575x400") + usr << browse(dat, "window=chem_master;size=575x500") return else if(href_list["add"]) @@ -388,7 +421,7 @@ ui = SSnanoui.try_update_ui(user, src, ui_key, ui, force_open) if(!ui) - ui = new(user, src, ui_key, "chem_master.tmpl", name, 575, 400) + ui = new(user, src, ui_key, "chem_master.tmpl", name, 575, 500) ui.open() /obj/machinery/chem_master/ui_data(mob/user, ui_key = "main", datum/topic_state/state = default_state) 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..59d15cf50bd 100644 --- a/code/modules/reagents/chemistry/reagents/medicine.dm +++ b/code/modules/reagents/chemistry/reagents/medicine.dm @@ -1149,24 +1149,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/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/research/designs/machine_designs.dm b/code/modules/research/designs/machine_designs.dm index c604105dc04..f50b3527aa2 100644 --- a/code/modules/research/designs/machine_designs.dm +++ b/code/modules/research/designs/machine_designs.dm @@ -182,6 +182,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/shuttle/on_move.dm b/code/modules/shuttle/on_move.dm index 67765ef8ac5..42e710d0cf6 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,10 @@ 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) - diff --git a/code/modules/shuttle/shuttle.dm b/code/modules/shuttle/shuttle.dm index 51ba6c6bad1..2d68c3db292 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() @@ -358,7 +358,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 +429,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 +492,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 +513,7 @@ T0.CalculateAdjacentTurfs() SSair.add_to_active(T0,1) + areaInstance.moving = transit for(var/A1 in L1) var/turf/T1 = A1 T1.postDock(S1) 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/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/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/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/html/browser/marked.js b/html/browser/marked.js index 6fe0e1e4e41..fa151b6befd 100644 --- a/html/browser/marked.js +++ b/html/browser/marked.js @@ -11,16 +11,26 @@ function parse(node) { parse(node.childNodes[i]); } - if(!node.innerHTML) { + if (!node.innerHTML || node.tagName === 'A') { return; } - node.innerHTML = marked(node.innerHTML.replace(/
/gi, '\n'), { breaks: true }); + + node.innerHTML = marked(node.innerHTML.replace(/
/gi, '\n').replace(/\t/gi, ''), { breaks: true, gfm: false }); } -function main() { +window.onload = function() { + var para = marked.Renderer.prototype.paragraph; + var field = ''; + marked.Renderer.prototype.paragraph = function(text) { + if (text.slice(0, field.length) === field || + text.slice(0, 2) === '= 0) { + return text; + } + return para(text); + }; + if ($('#markdown')) { parse($('#markdown')); } } - -window.onload = main; diff --git a/html/changelogs/AutoChangeLog-pr-11615.yml b/html/changelogs/AutoChangeLog-pr-11615.yml new file mode 100644 index 00000000000..1c7cb32141e --- /dev/null +++ b/html/changelogs/AutoChangeLog-pr-11615.yml @@ -0,0 +1,5 @@ +author: "AffectedArc07, Keekenox, Floyd/Qustinnus" +delete-after: True +changes: + - 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." diff --git a/html/changelogs/AutoChangeLog-pr-11767.yml b/html/changelogs/AutoChangeLog-pr-11767.yml new file mode 100644 index 00000000000..a1ab9b83753 --- /dev/null +++ b/html/changelogs/AutoChangeLog-pr-11767.yml @@ -0,0 +1,6 @@ +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-11774.yml b/html/changelogs/AutoChangeLog-pr-11774.yml new file mode 100644 index 00000000000..2671e0bd231 --- /dev/null +++ b/html/changelogs/AutoChangeLog-pr-11774.yml @@ -0,0 +1,4 @@ +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 new file mode 100644 index 00000000000..6040b3f474a --- /dev/null +++ b/html/changelogs/AutoChangeLog-pr-11776.yml @@ -0,0 +1,4 @@ +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-11783.yml b/html/changelogs/AutoChangeLog-pr-11783.yml new file mode 100644 index 00000000000..11c3bec4ac4 --- /dev/null +++ b/html/changelogs/AutoChangeLog-pr-11783.yml @@ -0,0 +1,5 @@ +author: "Couls" +delete-after: True +changes: + - rscadd: "hit effects!" + - imageadd: "hit effect sprites for lasers, bullet hole and dent decals for walls" diff --git a/html/changelogs/AutoChangeLog-pr-11810.yml b/html/changelogs/AutoChangeLog-pr-11810.yml new file mode 100644 index 00000000000..b87ad624c90 --- /dev/null +++ b/html/changelogs/AutoChangeLog-pr-11810.yml @@ -0,0 +1,5 @@ +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-11827.yml b/html/changelogs/AutoChangeLog-pr-11827.yml new file mode 100644 index 00000000000..584dfed8901 --- /dev/null +++ b/html/changelogs/AutoChangeLog-pr-11827.yml @@ -0,0 +1,4 @@ +author: "TDSSS" +delete-after: True +changes: + - tweak: "Gave the HoP fax long-ranged faxing capabilities." diff --git a/html/changelogs/AutoChangeLog-pr-11833.yml b/html/changelogs/AutoChangeLog-pr-11833.yml new file mode 100644 index 00000000000..2e7470e33cb --- /dev/null +++ b/html/changelogs/AutoChangeLog-pr-11833.yml @@ -0,0 +1,4 @@ +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 new file mode 100644 index 00000000000..99a23206448 --- /dev/null +++ b/html/changelogs/AutoChangeLog-pr-11834.yml @@ -0,0 +1,4 @@ +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 new file mode 100644 index 00000000000..ace0ff2485b --- /dev/null +++ b/html/changelogs/AutoChangeLog-pr-11843.yml @@ -0,0 +1,4 @@ +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 new file mode 100644 index 00000000000..448d227c770 --- /dev/null +++ b/html/changelogs/AutoChangeLog-pr-11844.yml @@ -0,0 +1,4 @@ +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 new file mode 100644 index 00000000000..2582e3c3752 --- /dev/null +++ b/html/changelogs/AutoChangeLog-pr-11845.yml @@ -0,0 +1,5 @@ +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-11863.yml b/html/changelogs/AutoChangeLog-pr-11863.yml new file mode 100644 index 00000000000..ebbb86a7e35 --- /dev/null +++ b/html/changelogs/AutoChangeLog-pr-11863.yml @@ -0,0 +1,4 @@ +author: "EmanTheAlmighty" +delete-after: True +changes: + - tweak: "The AI can now toggle airlock safeties instead of toggling door bolt lights by pressing middle mouse." diff --git a/html/changelogs/AutoChangeLog-pr-11875.yml b/html/changelogs/AutoChangeLog-pr-11875.yml new file mode 100644 index 00000000000..35009a885a0 --- /dev/null +++ b/html/changelogs/AutoChangeLog-pr-11875.yml @@ -0,0 +1,5 @@ +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-11894.yml b/html/changelogs/AutoChangeLog-pr-11894.yml new file mode 100644 index 00000000000..1257ab8f981 --- /dev/null +++ b/html/changelogs/AutoChangeLog-pr-11894.yml @@ -0,0 +1,5 @@ +author: "TheSardele" +delete-after: True +changes: + - rscadd: "All-In-one Grinders can now be constructed and upgraded" + - rscadd: "All-In-one Grinders now produce more reagents when upgraded." diff --git a/html/changelogs/AutoChangeLog-pr-11899.yml b/html/changelogs/AutoChangeLog-pr-11899.yml new file mode 100644 index 00000000000..95579acd428 --- /dev/null +++ b/html/changelogs/AutoChangeLog-pr-11899.yml @@ -0,0 +1,6 @@ +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-11924.yml b/html/changelogs/AutoChangeLog-pr-11924.yml new file mode 100644 index 00000000000..1c237842514 --- /dev/null +++ b/html/changelogs/AutoChangeLog-pr-11924.yml @@ -0,0 +1,4 @@ +author: "TDSSS" +delete-after: True +changes: + - tweak: "midround event spawned xeno larva now need less time to grow up and evolve." diff --git a/html/changelogs/AutoChangeLog-pr-11937.yml b/html/changelogs/AutoChangeLog-pr-11937.yml new file mode 100644 index 00000000000..6c4eb842bda --- /dev/null +++ b/html/changelogs/AutoChangeLog-pr-11937.yml @@ -0,0 +1,4 @@ +author: "farie82" +delete-after: True +changes: + - bugfix: "Rigging a crate now doesn't delete your coil stack anymore but instead uses 15 of it. Borgs can use it safely again" diff --git a/html/changelogs/AutoChangeLog-pr-11965.yml b/html/changelogs/AutoChangeLog-pr-11965.yml new file mode 100644 index 00000000000..f70891de781 --- /dev/null +++ b/html/changelogs/AutoChangeLog-pr-11965.yml @@ -0,0 +1,4 @@ +author: "TDSSS" +delete-after: True +changes: + - tweak: "cult talisman got unique icons to tell them apart" diff --git a/html/changelogs/AutoChangeLog-pr-11981.yml b/html/changelogs/AutoChangeLog-pr-11981.yml new file mode 100644 index 00000000000..2e17430b9a9 --- /dev/null +++ b/html/changelogs/AutoChangeLog-pr-11981.yml @@ -0,0 +1,16 @@ +author: "Fox McCloud" +delete-after: True +changes: + - 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" diff --git a/html/changelogs/AutoChangeLog-pr-11984.yml b/html/changelogs/AutoChangeLog-pr-11984.yml new file mode 100644 index 00000000000..49600d2025b --- /dev/null +++ b/html/changelogs/AutoChangeLog-pr-11984.yml @@ -0,0 +1,5 @@ +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 new file mode 100644 index 00000000000..63e511de1e9 --- /dev/null +++ b/html/changelogs/AutoChangeLog-pr-11995.yml @@ -0,0 +1,4 @@ +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/html/changelogs/AutoChangeLog-pr-11998.yml b/html/changelogs/AutoChangeLog-pr-11998.yml new file mode 100644 index 00000000000..b431624ce94 --- /dev/null +++ b/html/changelogs/AutoChangeLog-pr-11998.yml @@ -0,0 +1,4 @@ +author: "Tayyyyyyy" +delete-after: True +changes: + - tweak: "message window links added to PM send receipt" diff --git a/html/changelogs/AutoChangeLog-pr-12002.yml b/html/changelogs/AutoChangeLog-pr-12002.yml new file mode 100644 index 00000000000..00cad9242aa --- /dev/null +++ b/html/changelogs/AutoChangeLog-pr-12002.yml @@ -0,0 +1,5 @@ +author: "Markolie" +delete-after: True +changes: + - 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." diff --git a/html/changelogs/AutoChangeLog-pr-12007.yml b/html/changelogs/AutoChangeLog-pr-12007.yml new file mode 100644 index 00000000000..e6599f791f1 --- /dev/null +++ b/html/changelogs/AutoChangeLog-pr-12007.yml @@ -0,0 +1,4 @@ +author: "Couls" +delete-after: True +changes: + - tweak: "there are much less one-way airlocks on station" diff --git a/html/changelogs/AutoChangeLog-pr-12011.yml b/html/changelogs/AutoChangeLog-pr-12011.yml new file mode 100644 index 00000000000..c9df4ed1d3f --- /dev/null +++ b/html/changelogs/AutoChangeLog-pr-12011.yml @@ -0,0 +1,4 @@ +author: "Shadow-Quill" +delete-after: True +changes: + - tweak: "Mass drivers now need two rods/cable coil instead of three to construct." diff --git a/html/changelogs/AutoChangeLog-pr-12014.yml b/html/changelogs/AutoChangeLog-pr-12014.yml new file mode 100644 index 00000000000..f0af236a0cb --- /dev/null +++ b/html/changelogs/AutoChangeLog-pr-12014.yml @@ -0,0 +1,5 @@ +author: "Shadow-Quill" +delete-after: True +changes: + - 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." diff --git a/html/changelogs/AutoChangeLog-pr-12017.yml b/html/changelogs/AutoChangeLog-pr-12017.yml new file mode 100644 index 00000000000..050f27f75d4 --- /dev/null +++ b/html/changelogs/AutoChangeLog-pr-12017.yml @@ -0,0 +1,4 @@ +author: "Fox McCloud" +delete-after: True +changes: + - bugfix: "Fixes walking on lavaland sounding like walking on metal plating" diff --git a/html/changelogs/AutoChangeLog-pr-12024.yml b/html/changelogs/AutoChangeLog-pr-12024.yml new file mode 100644 index 00000000000..d0affbcd67b --- /dev/null +++ b/html/changelogs/AutoChangeLog-pr-12024.yml @@ -0,0 +1,7 @@ +author: "Fox McCloud" +delete-after: True +changes: + - 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" diff --git a/html/changelogs/AutoChangeLog-pr-12028.yml b/html/changelogs/AutoChangeLog-pr-12028.yml new file mode 100644 index 00000000000..6574e9a042d --- /dev/null +++ b/html/changelogs/AutoChangeLog-pr-12028.yml @@ -0,0 +1,4 @@ +author: "Shadow-Quill" +delete-after: True +changes: + - tweak: "Using a health analyzer in-hand will switch the verbosity." diff --git a/html/changelogs/AutoChangeLog-pr-12033.yml b/html/changelogs/AutoChangeLog-pr-12033.yml new file mode 100644 index 00000000000..3f9312b4e16 --- /dev/null +++ b/html/changelogs/AutoChangeLog-pr-12033.yml @@ -0,0 +1,4 @@ +author: "Fox McCloud" +delete-after: True +changes: + - rscadd: "Add fulton extract packs to the mining vendor; rescue precious valuable or dead miners!" diff --git a/html/changelogs/AutoChangeLog-pr-12035.yml b/html/changelogs/AutoChangeLog-pr-12035.yml new file mode 100644 index 00000000000..4bf80bf148f --- /dev/null +++ b/html/changelogs/AutoChangeLog-pr-12035.yml @@ -0,0 +1,4 @@ +author: "Fox McCloud" +delete-after: True +changes: + - tweak: "Adds mini-fans to the mining, engineering, and security shuttles" diff --git a/html/changelogs/AutoChangeLog-pr-12039.yml b/html/changelogs/AutoChangeLog-pr-12039.yml new file mode 100644 index 00000000000..551c136207f --- /dev/null +++ b/html/changelogs/AutoChangeLog-pr-12039.yml @@ -0,0 +1,7 @@ +author: "Fox McCloud" +delete-after: True +changes: + - 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" diff --git a/html/changelogs/AutoChangeLog-pr-12040.yml b/html/changelogs/AutoChangeLog-pr-12040.yml new file mode 100644 index 00000000000..51542da25c9 --- /dev/null +++ b/html/changelogs/AutoChangeLog-pr-12040.yml @@ -0,0 +1,4 @@ +author: "Tayyyyyyy" +delete-after: True +changes: + - bugfix: "Many shuttle flight directions fixed" diff --git a/html/changelogs/AutoChangeLog-pr-12043.yml b/html/changelogs/AutoChangeLog-pr-12043.yml new file mode 100644 index 00000000000..51b0dbb1e35 --- /dev/null +++ b/html/changelogs/AutoChangeLog-pr-12043.yml @@ -0,0 +1,7 @@ +author: "Fox McCloud" +delete-after: True +changes: + - 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" diff --git a/html/changelogs/AutoChangeLog-pr-12044.yml b/html/changelogs/AutoChangeLog-pr-12044.yml new file mode 100644 index 00000000000..7b9b664464e --- /dev/null +++ b/html/changelogs/AutoChangeLog-pr-12044.yml @@ -0,0 +1,4 @@ +author: "DoctorDrugs" +delete-after: True +changes: + - tweak: "removed the ability to eat the divine vocal cords" diff --git a/html/changelogs/AutoChangeLog-pr-12047.yml b/html/changelogs/AutoChangeLog-pr-12047.yml new file mode 100644 index 00000000000..2d7ad050a64 --- /dev/null +++ b/html/changelogs/AutoChangeLog-pr-12047.yml @@ -0,0 +1,4 @@ +author: "Fox McCloud" +delete-after: True +changes: + - bugfix: "Fixes airlocks spamming their open and close when you stand in them" 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/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/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..4bc39d8f80b 100644 Binary files a/icons/mob/head.dmi and b/icons/mob/head.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/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/screen_slime.dmi b/icons/mob/screen_slime.dmi new file mode 100644 index 00000000000..d5786f3ca69 Binary files /dev/null and b/icons/mob/screen_slime.dmi differ diff --git a/icons/mob/suit.dmi b/icons/mob/suit.dmi index f79ca1fb338..abce25ab86f 100644 Binary files a/icons/mob/suit.dmi and b/icons/mob/suit.dmi differ diff --git a/icons/obj/chemical.dmi b/icons/obj/chemical.dmi index 9c9f6d38e94..f007687d568 100644 Binary files a/icons/obj/chemical.dmi and b/icons/obj/chemical.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..a3d66d4d921 100644 Binary files a/icons/obj/clothing/hats.dmi and b/icons/obj/clothing/hats.dmi differ diff --git a/icons/obj/clothing/suits.dmi b/icons/obj/clothing/suits.dmi index 8e5a4b8e879..8371295985f 100644 Binary files a/icons/obj/clothing/suits.dmi and b/icons/obj/clothing/suits.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/items.dmi b/icons/obj/items.dmi index 05a5768ce89..23e49287922 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/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/paper.dmi b/icons/obj/paper.dmi index ce3c79adc73..55781076833 100644 Binary files a/icons/obj/paper.dmi and b/icons/obj/paper.dmi differ diff --git a/icons/turf/mining.dmi b/icons/turf/mining.dmi index 9621ef05d5c..f648883072a 100644 Binary files a/icons/turf/mining.dmi and b/icons/turf/mining.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/nano/templates/chem_master.tmpl b/nano/templates/chem_master.tmpl index 385237727db..1d040d52af7 100644 --- a/nano/templates/chem_master.tmpl +++ b/nano/templates/chem_master.tmpl @@ -80,10 +80,27 @@ {{else}} No beaker loaded
{{/if}} - - {{if data.loaded_pill_bottle}} - {{:helper.link('Pill Bottle (' + data.loaded_pill_bottle_contents_len + '/' + data.loaded_pill_bottle_storage_slots + ')', 'eject', {'ejectp': 1})}} - {{else}} - {{:helper.link('No Pill Bottle', 'eject', {}, 'disabled')}} - {{/if}} - \ No newline at end of file +
+ + {{if data.loaded_pill_bottle}} + + + + + +
+ {{:helper.link('Pill Bottle (' + data.loaded_pill_bottle_contents_len + '/' + data.loaded_pill_bottle_storage_slots + ')', 'eject', {'ejectp': 1})}} + + {{:helper.link('Change Wrapper', 'pencil', {'change_pillbottle': 1})}} +
+ {{else}} + + + + +
+ {{:helper.link('No Pill Bottle', 'eject', {}, 'disabled')}} +
+ {{/if}} +
+
\ No newline at end of file diff --git a/paradise.dme b/paradise.dme index 7661fc9ac81..43192705d89 100644 --- a/paradise.dme +++ b/paradise.dme @@ -143,11 +143,13 @@ #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" #include "code\_onclick\hud\robot.dm" #include "code\_onclick\hud\screen_objects.dm" +#include "code\_onclick\hud\slime.dm" #include "code\_onclick\hud\swarmer.dm" #include "code\ATMOSPHERICS\atmospherics.dm" #include "code\ATMOSPHERICS\datum_icon_manager.dm" @@ -222,6 +224,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" @@ -277,6 +280,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" @@ -1641,6 +1645,7 @@ #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_stacking.dm" #include "code\modules\mining\machine_unloading.dm" @@ -1651,6 +1656,7 @@ #include "code\modules\mining\ore.dm" #include "code\modules\mining\satchel_ore_boxdm.dm" #include "code\modules\mining\shelters.dm" +#include "code\modules\mining\equipment\kinetic_crusher.dm" #include "code\modules\mining\equipment\marker_beacons.dm" #include "code\modules\mining\equipment\survival_pod.dm" #include "code\modules\mining\laborcamp\laborshuttle.dm" 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